389b5cf05d29e595b112422cc2a75857fb378187
[gem5.git] / src / arch / riscv / isa / formats / fp.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2015 Riscv Developers
4 // Copyright (c) 2016-2017 The University of Virginia
5 // Copyright (c) 2020 Barkhausen Institut
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met: redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer;
12 // redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution;
15 // neither the name of the copyright holders nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 ////////////////////////////////////////////////////////////////////
32 //
33 // Floating point operation instructions
34 //
35 def template FloatExecute {{
36 Fault %(class_name)s::execute(ExecContext *xc,
37 Trace::InstRecord *traceData) const
38 {
39 Fault fault = NoFault;
40
41 STATUS status = xc->readMiscReg(MISCREG_STATUS);
42 if (status.fs == FPUStatus::OFF)
43 fault = make_shared<IllegalInstFault>("FPU is off", machInst);
44
45 %(op_decl)s;
46 %(op_rd)s;
47 if (fault == NoFault) {
48 switch (ROUND_MODE) {
49 case 0x0:
50 std::fesetround(FE_TONEAREST);
51 break;
52 case 0x1:
53 std::fesetround(FE_TOWARDZERO);
54 break;
55 case 0x2:
56 std::fesetround(FE_DOWNWARD);
57 break;
58 case 0x3:
59 std::fesetround(FE_UPWARD);
60 break;
61 case 0x4:
62 // Round to nearest, ties to max magnitude not implemented
63 fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
64 break;
65 case 0x7: {
66 uint8_t frm = xc->readMiscReg(MISCREG_FRM);
67 switch (frm) {
68 case 0x0:
69 std::fesetround(FE_TONEAREST);
70 break;
71 case 0x1:
72 std::fesetround(FE_TOWARDZERO);
73 break;
74 case 0x2:
75 std::fesetround(FE_DOWNWARD);
76 break;
77 case 0x3:
78 std::fesetround(FE_UPWARD);
79 break;
80 case 0x4:
81 // Round to nearest, ties to max magnitude not implemented
82 fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
83 break;
84 default:
85 fault = std::make_shared<IllegalFrmFault>(frm, machInst);
86 break;
87 }
88 break;
89 }
90 default:
91 fault = std::make_shared<IllegalFrmFault>(ROUND_MODE,
92 machInst);
93 break;
94 }
95
96 if (fault == NoFault) {
97 RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS);
98 std::feclearexcept(FE_ALL_EXCEPT);
99 %(code)s;
100 if (std::fetestexcept(FE_INEXACT)) {
101 FFLAGS |= FloatInexact;
102 }
103 if (std::fetestexcept(FE_UNDERFLOW)) {
104 FFLAGS |= FloatUnderflow;
105 }
106 if (std::fetestexcept(FE_OVERFLOW)) {
107 FFLAGS |= FloatOverflow;
108 }
109 if (std::fetestexcept(FE_DIVBYZERO)) {
110 FFLAGS |= FloatDivZero;
111 }
112 if (std::fetestexcept(FE_INVALID)) {
113 FFLAGS |= FloatInvalid;
114 }
115 xc->setMiscReg(MISCREG_FFLAGS, FFLAGS);
116 }
117
118 if (fault == NoFault) {
119 %(op_wb)s;
120 }
121 }
122 return fault;
123 }
124 }};
125
126 def format FPROp(code, *opt_flags) {{
127 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
128 header_output = BasicDeclare.subst(iop)
129 decoder_output = BasicConstructor.subst(iop)
130 decode_block = BasicDecode.subst(iop)
131 exec_output = FloatExecute.subst(iop)
132 }};