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