standard.isa revision 12428
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 22112428Sar4jc@virginia.edudef format IOp(code, imm_type='int64_t', *opt_flags) {{ 22212119Sar4jc@virginia.edu regs = ['_destRegIdx[0]','_srcRegIdx[0]'] 22312428Sar4jc@virginia.edu iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type, 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