111725Sar4jc@virginia.edu// -*- mode:c++ -*-
211725Sar4jc@virginia.edu
311725Sar4jc@virginia.edu// Copyright (c) 2015 Riscv Developers
412119Sar4jc@virginia.edu// Copyright (c) 2016-2017 The University of Virginia
511725Sar4jc@virginia.edu// All rights reserved.
611725Sar4jc@virginia.edu//
711725Sar4jc@virginia.edu// Redistribution and use in source and binary forms, with or without
811725Sar4jc@virginia.edu// modification, are permitted provided that the following conditions are
911725Sar4jc@virginia.edu// met: redistributions of source code must retain the above copyright
1011725Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer;
1111725Sar4jc@virginia.edu// redistributions in binary form must reproduce the above copyright
1211725Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer in the
1311725Sar4jc@virginia.edu// documentation and/or other materials provided with the distribution;
1411725Sar4jc@virginia.edu// neither the name of the copyright holders nor the names of its
1511725Sar4jc@virginia.edu// contributors may be used to endorse or promote products derived from
1611725Sar4jc@virginia.edu// this software without specific prior written permission.
1711725Sar4jc@virginia.edu//
1811725Sar4jc@virginia.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1911725Sar4jc@virginia.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2011725Sar4jc@virginia.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2111725Sar4jc@virginia.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2211725Sar4jc@virginia.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2311725Sar4jc@virginia.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2411725Sar4jc@virginia.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2511725Sar4jc@virginia.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2611725Sar4jc@virginia.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2711725Sar4jc@virginia.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2811725Sar4jc@virginia.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2911725Sar4jc@virginia.edu//
3011725Sar4jc@virginia.edu// Authors: Alec Roelke
3111725Sar4jc@virginia.edu
3211725Sar4jc@virginia.edu////////////////////////////////////////////////////////////////////
3311725Sar4jc@virginia.edu//
3411725Sar4jc@virginia.edu// Floating point operation instructions
3511725Sar4jc@virginia.edu//
3611725Sar4jc@virginia.edudef template FloatExecute {{
3712234Sgabeblack@google.com    Fault %(class_name)s::execute(ExecContext *xc,
3811725Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
3911725Sar4jc@virginia.edu    {
4011725Sar4jc@virginia.edu        Fault fault = NoFault;
4111725Sar4jc@virginia.edu
4211725Sar4jc@virginia.edu        %(op_decl)s;
4311725Sar4jc@virginia.edu        %(op_rd)s;
4411725Sar4jc@virginia.edu        if (fault == NoFault) {
4511725Sar4jc@virginia.edu            switch (ROUND_MODE) {
4611725Sar4jc@virginia.edu            case 0x0:
4711725Sar4jc@virginia.edu                std::fesetround(FE_TONEAREST);
4811725Sar4jc@virginia.edu                break;
4911725Sar4jc@virginia.edu            case 0x1:
5011725Sar4jc@virginia.edu                std::fesetround(FE_TOWARDZERO);
5111725Sar4jc@virginia.edu                break;
5211725Sar4jc@virginia.edu            case 0x2:
5311725Sar4jc@virginia.edu                std::fesetround(FE_DOWNWARD);
5411725Sar4jc@virginia.edu                break;
5511725Sar4jc@virginia.edu            case 0x3:
5611725Sar4jc@virginia.edu                std::fesetround(FE_UPWARD);
5711725Sar4jc@virginia.edu                break;
5811725Sar4jc@virginia.edu            case 0x4:
5912136Sar4jc@virginia.edu                // Round to nearest, ties to max magnitude not implemented
6012849Sar4jc@virginia.edu                fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
6111725Sar4jc@virginia.edu                break;
6211725Sar4jc@virginia.edu            case 0x7: {
6311725Sar4jc@virginia.edu                uint8_t frm = xc->readMiscReg(MISCREG_FRM);
6411725Sar4jc@virginia.edu                switch (frm) {
6511725Sar4jc@virginia.edu                case 0x0:
6611725Sar4jc@virginia.edu                    std::fesetround(FE_TONEAREST);
6711725Sar4jc@virginia.edu                    break;
6811725Sar4jc@virginia.edu                case 0x1:
6911725Sar4jc@virginia.edu                    std::fesetround(FE_TOWARDZERO);
7011725Sar4jc@virginia.edu                    break;
7111725Sar4jc@virginia.edu                case 0x2:
7211725Sar4jc@virginia.edu                    std::fesetround(FE_DOWNWARD);
7311725Sar4jc@virginia.edu                    break;
7411725Sar4jc@virginia.edu                case 0x3:
7511725Sar4jc@virginia.edu                    std::fesetround(FE_UPWARD);
7611725Sar4jc@virginia.edu                    break;
7711725Sar4jc@virginia.edu                case 0x4:
7812136Sar4jc@virginia.edu                    // Round to nearest, ties to max magnitude not implemented
7912849Sar4jc@virginia.edu                    fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
8011725Sar4jc@virginia.edu                    break;
8111725Sar4jc@virginia.edu                default:
8212849Sar4jc@virginia.edu                    fault = std::make_shared<IllegalFrmFault>(frm, machInst);
8311725Sar4jc@virginia.edu                    break;
8411725Sar4jc@virginia.edu                }
8511725Sar4jc@virginia.edu                break;
8611725Sar4jc@virginia.edu            }
8711725Sar4jc@virginia.edu            default:
8812849Sar4jc@virginia.edu                fault = std::make_shared<IllegalFrmFault>(ROUND_MODE,
8912849Sar4jc@virginia.edu                                                          machInst);
9011725Sar4jc@virginia.edu                break;
9111725Sar4jc@virginia.edu            }
9211725Sar4jc@virginia.edu
9311725Sar4jc@virginia.edu            if (fault == NoFault) {
9413612Sgabeblack@google.com                RegVal FFLAGS = xc->readMiscReg(MISCREG_FFLAGS);
9511725Sar4jc@virginia.edu                std::feclearexcept(FE_ALL_EXCEPT);
9611725Sar4jc@virginia.edu                %(code)s;
9711725Sar4jc@virginia.edu                if (std::fetestexcept(FE_INEXACT)) {
9811725Sar4jc@virginia.edu                    FFLAGS |= FloatInexact;
9911725Sar4jc@virginia.edu                }
10011725Sar4jc@virginia.edu                if (std::fetestexcept(FE_UNDERFLOW)) {
10111725Sar4jc@virginia.edu                    FFLAGS |= FloatUnderflow;
10211725Sar4jc@virginia.edu                }
10311725Sar4jc@virginia.edu                if (std::fetestexcept(FE_OVERFLOW)) {
10411725Sar4jc@virginia.edu                    FFLAGS |= FloatOverflow;
10511725Sar4jc@virginia.edu                }
10611725Sar4jc@virginia.edu                if (std::fetestexcept(FE_DIVBYZERO)) {
10711725Sar4jc@virginia.edu                    FFLAGS |= FloatDivZero;
10811725Sar4jc@virginia.edu                }
10911725Sar4jc@virginia.edu                if (std::fetestexcept(FE_INVALID)) {
11011725Sar4jc@virginia.edu                    FFLAGS |= FloatInvalid;
11111725Sar4jc@virginia.edu                }
11211725Sar4jc@virginia.edu                xc->setMiscReg(MISCREG_FFLAGS, FFLAGS);
11311725Sar4jc@virginia.edu            }
11411725Sar4jc@virginia.edu
11511725Sar4jc@virginia.edu            if (fault == NoFault) {
11611725Sar4jc@virginia.edu                %(op_wb)s;
11711725Sar4jc@virginia.edu            }
11811725Sar4jc@virginia.edu        }
11911725Sar4jc@virginia.edu        return fault;
12011725Sar4jc@virginia.edu    }
12111725Sar4jc@virginia.edu}};
12211725Sar4jc@virginia.edu
12311725Sar4jc@virginia.edudef format FPROp(code, *opt_flags) {{
12412119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
12511725Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
12611725Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
12711725Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
12811725Sar4jc@virginia.edu    exec_output = FloatExecute.subst(iop)
12911725Sar4jc@virginia.edu}};
130