standard.isa revision 12320
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);
4612236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
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);
10212236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
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);
16112236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
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
21312119Sar4jc@virginia.edudef format ROp(code, *opt_flags) {{
21412119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
21512119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
21612119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
21712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
21812119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
21912119Sar4jc@virginia.edu}};
22012119Sar4jc@virginia.edu
22112119Sar4jc@virginia.edudef format IOp(code, *opt_flags) {{
22212119Sar4jc@virginia.edu    imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
22312119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]','_srcRegIdx[0]']
22412320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
22512119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
22612119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
22712119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
22812119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
22912119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
23012119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
23112119Sar4jc@virginia.edu}};
23212119Sar4jc@virginia.edu
23312119Sar4jc@virginia.edudef format BOp(code, *opt_flags) {{
23412119Sar4jc@virginia.edu    imm_code = """
23512119Sar4jc@virginia.edu                imm |= BIMM12BIT11 << 11;
23612119Sar4jc@virginia.edu                imm |= BIMM12BITS4TO1 << 1;
23712119Sar4jc@virginia.edu                imm |= BIMM12BITS10TO5 << 5;
23812119Sar4jc@virginia.edu                if (IMMSIGN > 0)
23912119Sar4jc@virginia.edu                    imm |= ~((uint64_t)0xFFF);
24012119Sar4jc@virginia.edu               """
24112119Sar4jc@virginia.edu    regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
24212320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
24312119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
24412119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
24512119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
24612119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
24712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
24812119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
24912119Sar4jc@virginia.edu}};
25012119Sar4jc@virginia.edu
25112119Sar4jc@virginia.edudef format Jump(code, *opt_flags) {{
25212119Sar4jc@virginia.edu    imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
25312119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]','_srcRegIdx[0]']
25412320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
25512119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
25612119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
25712119Sar4jc@virginia.edu    header_output = JumpDeclare.subst(iop)
25812119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
25912119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
26012119Sar4jc@virginia.edu    exec_output = JumpExecute.subst(iop)
26112119Sar4jc@virginia.edu}};
26212119Sar4jc@virginia.edu
26312119Sar4jc@virginia.edudef format UOp(code, *opt_flags) {{
26412119Sar4jc@virginia.edu    imm_code = 'imm = (int32_t)(IMM20 << 12);'
26512119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
26612320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
26712119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
26812119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
26912119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
27012119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
27112119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
27212119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
27312119Sar4jc@virginia.edu}};
27412119Sar4jc@virginia.edu
27512119Sar4jc@virginia.edudef format JOp(code, *opt_flags) {{
27612119Sar4jc@virginia.edu    imm_code = """
27712119Sar4jc@virginia.edu                imm |= UJIMMBITS19TO12 << 12;
27812119Sar4jc@virginia.edu                imm |= UJIMMBIT11 << 11;
27912119Sar4jc@virginia.edu                imm |= UJIMMBITS10TO1 << 1;
28012119Sar4jc@virginia.edu                if (IMMSIGN > 0)
28112119Sar4jc@virginia.edu                    imm |= ~((uint64_t)0xFFFFF);
28212119Sar4jc@virginia.edu               """
28312119Sar4jc@virginia.edu    pc = 'pc.set(pc.pc() + imm);'
28412119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
28512320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
28612119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
28712119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
28812119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
28912119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
29012119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
29112119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
29212119Sar4jc@virginia.edu}};
29312119Sar4jc@virginia.edu
29412119Sar4jc@virginia.edudef format SystemOp(code, *opt_flags) {{
29512119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
29612119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
29712119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
29812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
29912119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
30012119Sar4jc@virginia.edu}};
30112119Sar4jc@virginia.edu
30212119Sar4jc@virginia.edudef format CSROp(code, *opt_flags) {{
30312119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
30412119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
30512119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
30612119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
30712119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
30812234Sgabeblack@google.com}};
309