standard.isa revision 12328
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    regs = ['_destRegIdx[0]','_srcRegIdx[0]']
22312320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
22412328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
22512119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
22612119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
22712119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
22812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
22912119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
23012119Sar4jc@virginia.edu}};
23112119Sar4jc@virginia.edu
23212119Sar4jc@virginia.edudef format BOp(code, *opt_flags) {{
23312119Sar4jc@virginia.edu    imm_code = """
23412328Sar4jc@virginia.edu                imm = BIMM12BITS4TO1 << 1  |
23512328Sar4jc@virginia.edu                      BIMM12BITS10TO5 << 5 |
23612328Sar4jc@virginia.edu                      BIMM12BIT11 << 11    |
23712328Sar4jc@virginia.edu                      IMMSIGN << 12;
23812328Sar4jc@virginia.edu                imm = sext<13>(imm);
23912119Sar4jc@virginia.edu               """
24012119Sar4jc@virginia.edu    regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
24112320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
24212119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
24312119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
24412119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
24512119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
24612119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
24712119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
24812119Sar4jc@virginia.edu}};
24912119Sar4jc@virginia.edu
25012119Sar4jc@virginia.edudef format Jump(code, *opt_flags) {{
25112328Sar4jc@virginia.edu    regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
25212320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
25312328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
25412119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
25512119Sar4jc@virginia.edu    header_output = JumpDeclare.subst(iop)
25612119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
25712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
25812119Sar4jc@virginia.edu    exec_output = JumpExecute.subst(iop)
25912119Sar4jc@virginia.edu}};
26012119Sar4jc@virginia.edu
26112119Sar4jc@virginia.edudef format UOp(code, *opt_flags) {{
26212119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
26312320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
26412328Sar4jc@virginia.edu        {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
26512119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
26612119Sar4jc@virginia.edu    header_output = ImmDeclare.subst(iop)
26712119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
26812119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
26912119Sar4jc@virginia.edu    exec_output = ImmExecute.subst(iop)
27012119Sar4jc@virginia.edu}};
27112119Sar4jc@virginia.edu
27212119Sar4jc@virginia.edudef format JOp(code, *opt_flags) {{
27312119Sar4jc@virginia.edu    imm_code = """
27412328Sar4jc@virginia.edu                imm = UJIMMBITS10TO1 << 1   |
27512328Sar4jc@virginia.edu                      UJIMMBIT11 << 11      |
27612328Sar4jc@virginia.edu                      UJIMMBITS19TO12 << 12 |
27712328Sar4jc@virginia.edu                      IMMSIGN << 20;
27812328Sar4jc@virginia.edu                imm = sext<21>(imm);
27912119Sar4jc@virginia.edu               """
28012119Sar4jc@virginia.edu    pc = 'pc.set(pc.pc() + imm);'
28112119Sar4jc@virginia.edu    regs = ['_destRegIdx[0]']
28212320Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
28312119Sar4jc@virginia.edu        {'code': code, 'imm_code': imm_code,
28412119Sar4jc@virginia.edu         'regs': ','.join(regs)}, opt_flags)
28512119Sar4jc@virginia.edu    header_output = BranchDeclare.subst(iop)
28612119Sar4jc@virginia.edu    decoder_output = ImmConstructor.subst(iop)
28712119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
28812119Sar4jc@virginia.edu    exec_output = BranchExecute.subst(iop)
28912119Sar4jc@virginia.edu}};
29012119Sar4jc@virginia.edu
29112119Sar4jc@virginia.edudef format SystemOp(code, *opt_flags) {{
29212119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
29312119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
29412119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
29512119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
29612119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
29712119Sar4jc@virginia.edu}};
29812119Sar4jc@virginia.edu
29912119Sar4jc@virginia.edudef format CSROp(code, *opt_flags) {{
30012119Sar4jc@virginia.edu    iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
30112119Sar4jc@virginia.edu    header_output = BasicDeclare.subst(iop)
30212119Sar4jc@virginia.edu    decoder_output = BasicConstructor.subst(iop)
30312119Sar4jc@virginia.edu    decode_block = BasicDecode.subst(iop)
30412119Sar4jc@virginia.edu    exec_output = BasicExecute.subst(iop)
30512234Sgabeblack@google.com}};
306