112119Sar4jc@virginia.edu// -*- mode:c++ -*-
212119Sar4jc@virginia.edu
312119Sar4jc@virginia.edu// Copyright (c) 2015 RISC-V Foundation
412119Sar4jc@virginia.edu// Copyright (c) 2016-2017 The University of Virginia
512119Sar4jc@virginia.edu// All rights reserved.
612119Sar4jc@virginia.edu//
712119Sar4jc@virginia.edu// Redistribution and use in source and binary forms, with or without
812119Sar4jc@virginia.edu// modification, are permitted provided that the following conditions are
912119Sar4jc@virginia.edu// met: redistributions of source code must retain the above copyright
1012119Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer;
1112119Sar4jc@virginia.edu// redistributions in binary form must reproduce the above copyright
1212119Sar4jc@virginia.edu// notice, this list of conditions and the following disclaimer in the
1312119Sar4jc@virginia.edu// documentation and/or other materials provided with the distribution;
1412119Sar4jc@virginia.edu// neither the name of the copyright holders nor the names of its
1512119Sar4jc@virginia.edu// contributors may be used to endorse or promote products derived from
1612119Sar4jc@virginia.edu// this software without specific prior written permission.
1712119Sar4jc@virginia.edu//
1812119Sar4jc@virginia.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1912119Sar4jc@virginia.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2012119Sar4jc@virginia.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2112119Sar4jc@virginia.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2212119Sar4jc@virginia.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2312119Sar4jc@virginia.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2412119Sar4jc@virginia.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2512119Sar4jc@virginia.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2612119Sar4jc@virginia.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2712119Sar4jc@virginia.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2812119Sar4jc@virginia.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2912119Sar4jc@virginia.edu//
3012119Sar4jc@virginia.edu// Authors: Alec Roelke
3112119Sar4jc@virginia.edu
3212119Sar4jc@virginia.edu////////////////////////////////////////////////////////////////////
3312119Sar4jc@virginia.edu//
3412119Sar4jc@virginia.edu// Integer instructions
3512119Sar4jc@virginia.edu//
3612119Sar4jc@virginia.edu
3712119Sar4jc@virginia.edudef template ImmDeclare {{
3812119Sar4jc@virginia.edu    //
3912119Sar4jc@virginia.edu    // Static instruction class for "%(mnemonic)s".
4012119Sar4jc@virginia.edu    //
4112119Sar4jc@virginia.edu    class %(class_name)s : public %(base_class)s
4212119Sar4jc@virginia.edu    {
4312119Sar4jc@virginia.edu      public:
4412119Sar4jc@virginia.edu        /// Constructor.
4512119Sar4jc@virginia.edu        %(class_name)s(MachInst machInst);
4612482Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
4712119Sar4jc@virginia.edu        std::string generateDisassembly(Addr pc,
4812119Sar4jc@virginia.edu            const SymbolTable *symtab) const override;
4912119Sar4jc@virginia.edu    };
5012119Sar4jc@virginia.edu}};
5112119Sar4jc@virginia.edu
5212119Sar4jc@virginia.edudef template ImmConstructor {{
5312119Sar4jc@virginia.edu    %(class_name)s::%(class_name)s(MachInst machInst)
5412119Sar4jc@virginia.edu        : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
5512119Sar4jc@virginia.edu    {
5612119Sar4jc@virginia.edu        %(constructor)s;
5712119Sar4jc@virginia.edu        %(imm_code)s;
5812119Sar4jc@virginia.edu    }
5912119Sar4jc@virginia.edu}};
6012119Sar4jc@virginia.edu
6112119Sar4jc@virginia.edudef template ImmExecute {{
6212119Sar4jc@virginia.edu    Fault
6312234Sgabeblack@google.com    %(class_name)s::execute(
6412234Sgabeblack@google.com        ExecContext *xc, Trace::InstRecord *traceData) const
6512119Sar4jc@virginia.edu    {
6612119Sar4jc@virginia.edu        Fault fault = NoFault;
6712119Sar4jc@virginia.edu
6812119Sar4jc@virginia.edu        %(op_decl)s;
6912119Sar4jc@virginia.edu        %(op_rd)s;
7012119Sar4jc@virginia.edu        if (fault == NoFault) {
7112119Sar4jc@virginia.edu            %(code)s;
7212119Sar4jc@virginia.edu            if (fault == NoFault) {
7312119Sar4jc@virginia.edu                %(op_wb)s;
7412119Sar4jc@virginia.edu            }
7512119Sar4jc@virginia.edu        }
7612119Sar4jc@virginia.edu        return fault;
7712119Sar4jc@virginia.edu    }
7812119Sar4jc@virginia.edu
7912119Sar4jc@virginia.edu    std::string
8012119Sar4jc@virginia.edu    %(class_name)s::generateDisassembly(Addr pc,
8112119Sar4jc@virginia.edu            const SymbolTable *symtab) const
8212119Sar4jc@virginia.edu    {
8312119Sar4jc@virginia.edu        std::vector<RegId> indices = {%(regs)s};
8412119Sar4jc@virginia.edu        std::stringstream ss;
8512119Sar4jc@virginia.edu        ss << mnemonic << ' ';
8612119Sar4jc@virginia.edu        for (const RegId& idx: indices)
8712119Sar4jc@virginia.edu            ss << registerName(idx) << ", ";
8812119Sar4jc@virginia.edu        ss << imm;
8912119Sar4jc@virginia.edu        return ss.str();
9012119Sar4jc@virginia.edu    }
9112119Sar4jc@virginia.edu}};
9212119Sar4jc@virginia.edu
9312119Sar4jc@virginia.edudef template BranchDeclare {{
9412119Sar4jc@virginia.edu    //
9512119Sar4jc@virginia.edu    // Static instruction class for "%(mnemonic)s".
9612119Sar4jc@virginia.edu    //
9712119Sar4jc@virginia.edu    class %(class_name)s : public %(base_class)s
9812119Sar4jc@virginia.edu    {
9912119Sar4jc@virginia.edu      public:
10012119Sar4jc@virginia.edu        /// Constructor.
10112119Sar4jc@virginia.edu        %(class_name)s(MachInst machInst);
10212482Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
10312119Sar4jc@virginia.edu
10412119Sar4jc@virginia.edu        std::string
10512119Sar4jc@virginia.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
10612119Sar4jc@virginia.edu
10712119Sar4jc@virginia.edu        RiscvISA::PCState
10812119Sar4jc@virginia.edu        branchTarget(const RiscvISA::PCState &branchPC) const override;
10912119Sar4jc@virginia.edu
11012119Sar4jc@virginia.edu        using StaticInst::branchTarget;
11112119Sar4jc@virginia.edu    };
11212119Sar4jc@virginia.edu}};
11312119Sar4jc@virginia.edu
11412119Sar4jc@virginia.edudef template BranchExecute {{
11512119Sar4jc@virginia.edu    Fault
11612234Sgabeblack@google.com    %(class_name)s::execute(ExecContext *xc,
11712119Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
11812119Sar4jc@virginia.edu    {
11912119Sar4jc@virginia.edu        Fault fault = NoFault;
12012119Sar4jc@virginia.edu
12112119Sar4jc@virginia.edu        %(op_decl)s;
12212119Sar4jc@virginia.edu        %(op_rd)s;
12312119Sar4jc@virginia.edu        if (fault == NoFault) {
12412119Sar4jc@virginia.edu            %(code)s;
12512119Sar4jc@virginia.edu            if (fault == NoFault) {
12612119Sar4jc@virginia.edu                %(op_wb)s;
12712119Sar4jc@virginia.edu            }
12812119Sar4jc@virginia.edu        }
12912119Sar4jc@virginia.edu        return fault;
13012119Sar4jc@virginia.edu    }
13112119Sar4jc@virginia.edu
13212119Sar4jc@virginia.edu    RiscvISA::PCState
13312119Sar4jc@virginia.edu    %(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
13412119Sar4jc@virginia.edu    {
13512119Sar4jc@virginia.edu        return branchPC.pc() + imm;
13612119Sar4jc@virginia.edu    }
13712119Sar4jc@virginia.edu
13812119Sar4jc@virginia.edu    std::string
13912119Sar4jc@virginia.edu    %(class_name)s::generateDisassembly(Addr pc,
14012119Sar4jc@virginia.edu            const SymbolTable *symtab) const
14112119Sar4jc@virginia.edu    {
14212119Sar4jc@virginia.edu        std::vector<RegId> indices = {%(regs)s};
14312119Sar4jc@virginia.edu        std::stringstream ss;
14412119Sar4jc@virginia.edu        ss << mnemonic << ' ';
14512119Sar4jc@virginia.edu        for (const RegId& idx: indices)
14612119Sar4jc@virginia.edu            ss << registerName(idx) << ", ";
14712119Sar4jc@virginia.edu        ss << imm;
14812119Sar4jc@virginia.edu        return ss.str();
14912119Sar4jc@virginia.edu    }
15012119Sar4jc@virginia.edu}};
15112119Sar4jc@virginia.edu
15212119Sar4jc@virginia.edudef template JumpDeclare {{
15312119Sar4jc@virginia.edu    //
15412119Sar4jc@virginia.edu    // Static instruction class for "%(mnemonic)s".
15512119Sar4jc@virginia.edu    //
15612119Sar4jc@virginia.edu    class %(class_name)s : public %(base_class)s
15712119Sar4jc@virginia.edu    {
15812119Sar4jc@virginia.edu      public:
15912119Sar4jc@virginia.edu        /// Constructor.
16012119Sar4jc@virginia.edu        %(class_name)s(MachInst machInst);
16112482Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const override;
16212119Sar4jc@virginia.edu
16312119Sar4jc@virginia.edu        std::string
16412119Sar4jc@virginia.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
16512119Sar4jc@virginia.edu
16612119Sar4jc@virginia.edu        RiscvISA::PCState
16712119Sar4jc@virginia.edu        branchTarget(ThreadContext *tc) const override;
16812119Sar4jc@virginia.edu
16912119Sar4jc@virginia.edu        using StaticInst::branchTarget;
17012119Sar4jc@virginia.edu    };
17112119Sar4jc@virginia.edu}};
17212119Sar4jc@virginia.edu
17312119Sar4jc@virginia.edudef template JumpExecute {{
17412119Sar4jc@virginia.edu    Fault
17512234Sgabeblack@google.com    %(class_name)s::execute(
17612234Sgabeblack@google.com        ExecContext *xc, Trace::InstRecord *traceData) const
17712119Sar4jc@virginia.edu    {
17812119Sar4jc@virginia.edu        Fault fault = NoFault;
17912119Sar4jc@virginia.edu
18012119Sar4jc@virginia.edu        %(op_decl)s;
18112119Sar4jc@virginia.edu        %(op_rd)s;
18212119Sar4jc@virginia.edu        if (fault == NoFault) {
18312119Sar4jc@virginia.edu            %(code)s;
18412119Sar4jc@virginia.edu            if (fault == NoFault) {
18512119Sar4jc@virginia.edu                %(op_wb)s;
18612119Sar4jc@virginia.edu            }
18712119Sar4jc@virginia.edu        }
18812119Sar4jc@virginia.edu        return fault;
18912119Sar4jc@virginia.edu    }
19012119Sar4jc@virginia.edu
19112119Sar4jc@virginia.edu    RiscvISA::PCState
19212119Sar4jc@virginia.edu    %(class_name)s::branchTarget(ThreadContext *tc) const
19312119Sar4jc@virginia.edu    {
19412119Sar4jc@virginia.edu        PCState pc = tc->pcState();
19512119Sar4jc@virginia.edu        pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
19612119Sar4jc@virginia.edu        return pc;
19712119Sar4jc@virginia.edu    }
19812119Sar4jc@virginia.edu
19912119Sar4jc@virginia.edu    std::string
20012119Sar4jc@virginia.edu    %(class_name)s::generateDisassembly(Addr pc,
20112119Sar4jc@virginia.edu            const SymbolTable *symtab) const
20212119Sar4jc@virginia.edu    {
20312119Sar4jc@virginia.edu        std::vector<RegId> indices = {%(regs)s};
20412119Sar4jc@virginia.edu        std::stringstream ss;
20512119Sar4jc@virginia.edu        ss << mnemonic << ' ';
20612119Sar4jc@virginia.edu        for (const RegId& idx: indices)
20712119Sar4jc@virginia.edu            ss << registerName(idx) << ", ";
20812119Sar4jc@virginia.edu        ss << imm;
20912119Sar4jc@virginia.edu        return ss.str();
21012119Sar4jc@virginia.edu    }
21112119Sar4jc@virginia.edu}};
21212119Sar4jc@virginia.edu
21312695Sar4jc@virginia.edudef template CSRExecute {{
21412695Sar4jc@virginia.edu    Fault
21512695Sar4jc@virginia.edu    %(class_name)s::execute(ExecContext *xc,
21612695Sar4jc@virginia.edu        Trace::InstRecord *traceData) const
21712695Sar4jc@virginia.edu    {
21812695Sar4jc@virginia.edu        Fault fault = NoFault;
21912695Sar4jc@virginia.edu
22012695Sar4jc@virginia.edu        %(op_decl)s;
22112695Sar4jc@virginia.edu        %(op_rd)s;
22212695Sar4jc@virginia.edu
22313612Sgabeblack@google.com        RegVal data, olddata;
22412695Sar4jc@virginia.edu        switch (csr) {
22512695Sar4jc@virginia.edu          case CSR_FCSR:
22612695Sar4jc@virginia.edu            olddata = xc->readMiscReg(MISCREG_FFLAGS) |
22712695Sar4jc@virginia.edu                      (xc->readMiscReg(MISCREG_FRM) << FRM_OFFSET);
22812695Sar4jc@virginia.edu            break;
22912695Sar4jc@virginia.edu          default:
23012695Sar4jc@virginia.edu            if (CSRData.find(csr) != CSRData.end()) {
23112695Sar4jc@virginia.edu                olddata = xc->readMiscReg(CSRData.at(csr).physIndex);
23212695Sar4jc@virginia.edu            } else {
23312695Sar4jc@virginia.edu                std::string error = csprintf("Illegal CSR index %#x\n", csr);
23412849Sar4jc@virginia.edu                fault = make_shared<IllegalInstFault>(error, machInst);
23512695Sar4jc@virginia.edu                olddata = 0;
23612695Sar4jc@virginia.edu            }
23712695Sar4jc@virginia.edu            break;
23812695Sar4jc@virginia.edu        }
23912695Sar4jc@virginia.edu        auto mask = CSRMasks.find(csr);
24012695Sar4jc@virginia.edu        if (mask != CSRMasks.end())
24112695Sar4jc@virginia.edu            olddata &= mask->second;
24212695Sar4jc@virginia.edu        DPRINTF(RiscvMisc, "Reading CSR %s: %#x\n", CSRData.at(csr).name,
24312695Sar4jc@virginia.edu                olddata);
24412695Sar4jc@virginia.edu        data = olddata;
24512695Sar4jc@virginia.edu
24612695Sar4jc@virginia.edu        if (fault == NoFault) {
24712695Sar4jc@virginia.edu            %(code)s;
24812695Sar4jc@virginia.edu            if (fault == NoFault) {
24912695Sar4jc@virginia.edu                if (mask != CSRMasks.end())
25012695Sar4jc@virginia.edu                    data &= mask->second;
25112695Sar4jc@virginia.edu                if (data != olddata) {
25212695Sar4jc@virginia.edu                    if (bits(csr, 11, 10) == 0x3) {
25312695Sar4jc@virginia.edu                        std::string error = csprintf("CSR %s is read-only\n",
25412695Sar4jc@virginia.edu                                                     CSRData.at(csr).name);
25512849Sar4jc@virginia.edu                        fault = make_shared<IllegalInstFault>(error, machInst);
25612695Sar4jc@virginia.edu                    } else {
25712695Sar4jc@virginia.edu                        DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data,
25812695Sar4jc@virginia.edu                                CSRData.at(csr).name);
25913548Salec.roelke@gmail.com                        INTERRUPT oldinterrupt = olddata;
26013548Salec.roelke@gmail.com                        INTERRUPT newinterrupt = data;
26112695Sar4jc@virginia.edu                        switch (csr) {
26212695Sar4jc@virginia.edu                          case CSR_FCSR:
26312695Sar4jc@virginia.edu                            xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0));
26412695Sar4jc@virginia.edu                            xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5));
26512695Sar4jc@virginia.edu                            break;
26613548Salec.roelke@gmail.com                          case CSR_MIP: case CSR_MIE:
26713548Salec.roelke@gmail.com                            if (oldinterrupt.mei == newinterrupt.mei &&
26813548Salec.roelke@gmail.com                                oldinterrupt.mti == newinterrupt.mti &&
26913548Salec.roelke@gmail.com                                oldinterrupt.msi == newinterrupt.msi) {
27013548Salec.roelke@gmail.com                                xc->setMiscReg(CSRData.at(csr).physIndex,data);
27113548Salec.roelke@gmail.com                            } else {
27213548Salec.roelke@gmail.com                                std::string error = "Interrupt m bits are "
27313548Salec.roelke@gmail.com                                                    "read-only\n";
27413548Salec.roelke@gmail.com                                fault = make_shared<IllegalInstFault>(error,
27513548Salec.roelke@gmail.com                                                                     machInst);
27613548Salec.roelke@gmail.com                            }
27713548Salec.roelke@gmail.com                            break;
27812695Sar4jc@virginia.edu                          default:
27912695Sar4jc@virginia.edu                            xc->setMiscReg(CSRData.at(csr).physIndex, data);
28012695Sar4jc@virginia.edu                            break;
28112695Sar4jc@virginia.edu                        }
28212695Sar4jc@virginia.edu                    }
28312695Sar4jc@virginia.edu                }
28412695Sar4jc@virginia.edu            }
28512695Sar4jc@virginia.edu            if (fault == NoFault) {
28612695Sar4jc@virginia.edu                %(op_wb)s;
28712695Sar4jc@virginia.edu            }
28812695Sar4jc@virginia.edu        }
28912695Sar4jc@virginia.edu        return fault;
29012695Sar4jc@virginia.edu    }
29112695Sar4jc@virginia.edu}};
29212695Sar4jc@virginia.edu
29312119Sar4jc@virginia.edudef format ROp(code, *opt_flags) {{
29412119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
29512119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
29612119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
29712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
29812119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
29912119Sar4jc@virginia.edu}};
30012119Sar4jc@virginia.edu
30112428Sar4jc@virginia.edudef format IOp(code, imm_type='int64_t', *opt_flags) {{
30212119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]','_srcRegIdx[0]']
30312428Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
30412328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
30512119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
30612119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
30712119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
30812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
30912119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
31012119Sar4jc@virginia.edu}};
31112119Sar4jc@virginia.edu
31212119Sar4jc@virginia.edudef format BOp(code, *opt_flags) {{
31312119Sar4jc@virginia.edu    imm_code = """
31412328Sar4jc@virginia.edu                imm = BIMM12BITS4TO1 << 1  |
31512328Sar4jc@virginia.edu                      BIMM12BITS10TO5 << 5 |
31612328Sar4jc@virginia.edu                      BIMM12BIT11 << 11    |
31712328Sar4jc@virginia.edu                      IMMSIGN << 12;
31812328Sar4jc@virginia.edu                imm = sext<13>(imm);
31912119Sar4jc@virginia.edu               """
32012119Sar4jc@virginia.edu    regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
32112320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
32212119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
32312119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
32412119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
32512119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
32612119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
32712119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
32812119Sar4jc@virginia.edu}};
32912119Sar4jc@virginia.edu
33012119Sar4jc@virginia.edudef format Jump(code, *opt_flags) {{
33112328Sar4jc@virginia.edu    regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
33212320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
33312328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
33412119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
33512119Sar4jc@virginia.edu    header_output = JumpDeclare.subst(iop)
33612119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
33712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
33812119Sar4jc@virginia.edu    exec_output = JumpExecute.subst(iop)
33912119Sar4jc@virginia.edu}};
34012119Sar4jc@virginia.edu
34112119Sar4jc@virginia.edudef format UOp(code, *opt_flags) {{
34212119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
34312320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
34412328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
34512119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
34612119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
34712119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
34812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
34912119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
35012119Sar4jc@virginia.edu}};
35112119Sar4jc@virginia.edu
35212119Sar4jc@virginia.edudef format JOp(code, *opt_flags) {{
35312119Sar4jc@virginia.edu    imm_code = """
35412328Sar4jc@virginia.edu                imm = UJIMMBITS10TO1 << 1   |
35512328Sar4jc@virginia.edu                      UJIMMBIT11 << 11      |
35612328Sar4jc@virginia.edu                      UJIMMBITS19TO12 << 12 |
35712328Sar4jc@virginia.edu                      IMMSIGN << 20;
35812328Sar4jc@virginia.edu                imm = sext<21>(imm);
35912119Sar4jc@virginia.edu               """
36012119Sar4jc@virginia.edu    pc = 'pc.set(pc.pc() + imm);'
36112119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
36212320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
36312119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
36412119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
36512119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
36612119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
36712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
36812119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
36912119Sar4jc@virginia.edu}};
37012119Sar4jc@virginia.edu
37112119Sar4jc@virginia.edudef format SystemOp(code, *opt_flags) {{
37212119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
37312119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
37412119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
37512119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
37612119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
37712119Sar4jc@virginia.edu}};
37812119Sar4jc@virginia.edu
37912119Sar4jc@virginia.edudef format CSROp(code, *opt_flags) {{
38012119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
38112119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
38212119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
38312119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
38412695Sar4jc@virginia.edu    exec_output = CSRExecute.subst(iop)
38512234Sgabeblack@google.com}};
386