1// -*- mode:c++ -*- 2 3// Copyright (c) 2007 MIPS Technologies, Inc. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Korey Sewell 30 31//////////////////////////////////////////////////////////////////// 32// 33// MT instructions 34// 35 36output header {{ 37 /** 38 * Base class for MIPS MT ASE operations. 39 */ 40 class MTOp : public MipsStaticInst 41 { 42 protected: 43 44 /// Constructor 45 MTOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 46 MipsStaticInst(mnem, _machInst, __opClass), user_mode(false) 47 { 48 } 49 50 std::string generateDisassembly( 51 Addr pc, const SymbolTable *symtab) const override; 52 53 bool user_mode; 54 }; 55 56 class MTUserModeOp : public MTOp 57 { 58 protected: 59 60 /// Constructor 61 MTUserModeOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 62 MTOp(mnem, _machInst, __opClass) 63 { 64 user_mode = true; 65 } 66 }; 67}}; 68 69output decoder {{ 70 std::string MTOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 71 { 72 std::stringstream ss; 73 74 if (strcmp(mnemonic,"mttc0") == 0 || strcmp(mnemonic,"mftc0") == 0) { 75 ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL); 76 } else if (strcmp(mnemonic,"mftgpr") == 0) { 77 ccprintf(ss, "%-10s r%d, r%d", mnemonic, RD, RT); 78 } else { 79 ccprintf(ss, "%-10s r%d, r%d", mnemonic, RT, RD); 80 } 81 82 return ss.str(); 83 } 84}}; 85 86output header {{ 87 void getThrRegExValues(ExecContext *xc, 88 MipsISA::VPEConf0Reg &vpe_conf0, 89 MipsISA::TCBindReg &tc_bind_mt, 90 MipsISA::TCBindReg &tc_bind, 91 MipsISA::VPEControlReg &vpe_control, 92 MipsISA::MVPConf0Reg &mvp_conf0); 93 94 void getMTExValues(ExecContext *xc, MipsISA::Config3Reg &config3); 95}}; 96 97output exec {{ 98 void getThrRegExValues(ExecContext *xc, 99 VPEConf0Reg &vpe_conf0, TCBindReg &tc_bind_mt, 100 TCBindReg &tc_bind, VPEControlReg &vpe_control, 101 MVPConf0Reg &mvp_conf0) 102 { 103 vpe_conf0 = xc->readMiscReg(MISCREG_VPE_CONF0); 104 tc_bind_mt = readRegOtherThread(xc, RegId(MiscRegClass, 105 MISCREG_TC_BIND)); 106 tc_bind = xc->readMiscReg(MISCREG_TC_BIND); 107 vpe_control = xc->readMiscReg(MISCREG_VPE_CONTROL); 108 mvp_conf0 = xc->readMiscReg(MISCREG_MVP_CONF0); 109 } 110 111 void getMTExValues(ExecContext *xc, Config3Reg &config3) 112 { 113 config3 = xc->readMiscReg(MISCREG_CONFIG3); 114 } 115}}; 116 117def template ThreadRegisterExecute {{ 118 Fault %(class_name)s::execute( 119 ExecContext *xc, Trace::InstRecord *traceData) const 120 { 121 Fault fault = NoFault; 122 int64_t data M5_VAR_USED; 123 %(op_decl)s; 124 %(op_rd)s; 125 126 VPEConf0Reg vpeConf0; 127 TCBindReg tcBindMT; 128 TCBindReg tcBind; 129 VPEControlReg vpeControl; 130 MVPConf0Reg mvpConf0; 131 132 getThrRegExValues(xc, vpeConf0, tcBindMT, 133 tcBind, vpeControl, mvpConf0); 134 135 if (isCoprocessorEnabled(xc, 0)) { 136 if (vpeConf0.mvp == 0 && tcBindMT.curVPE != tcBind.curVPE) { 137 data = -1; 138 } else if (vpeControl.targTC > mvpConf0.ptc) { 139 data = -1; 140 } else { 141 %(code)s; 142 } 143 } else { 144 fault = std::make_shared<CoprocessorUnusableFault>(0); 145 } 146 147 if(fault == NoFault) 148 { 149 %(op_wb)s; 150 } 151 152 return fault; 153 } 154}}; 155 156def template MTExecute{{ 157 Fault %(class_name)s::execute( 158 ExecContext *xc, Trace::InstRecord *traceData) const 159 { 160 Fault fault = NoFault; 161 %(op_decl)s; 162 %(op_rd)s; 163 164 Config3Reg config3; 165 166 getMTExValues(xc, config3); 167 168 if (isCoprocessorEnabled(xc, 0)) { 169 if (config3.mt == 1) { 170 %(code)s; 171 } else { 172 fault = std::make_shared<ReservedInstructionFault>(); 173 } 174 } else { 175 fault = std::make_shared<CoprocessorUnusableFault>(0); 176 } 177 178 if(fault == NoFault) 179 { 180 %(op_wb)s; 181 } 182 return fault; 183 } 184}}; 185 186// Primary format for integer operate instructions: 187def format MT_Control(code, *opt_flags) {{ 188 inst_flags = ('IsNonSpeculative', ) 189 op_type = 'MTOp' 190 191 for x in opt_flags: 192 if x == 'UserMode': 193 op_type = 'MTUserModeOp' 194 else: 195 inst_flags += (x, ) 196 197 iop = InstObjParams(name, Name, op_type, code, inst_flags) 198 header_output = BasicDeclare.subst(iop) 199 decoder_output = BasicConstructor.subst(iop) 200 decode_block = BasicDecode.subst(iop) 201 exec_output = MTExecute.subst(iop) 202}}; 203 204def format MT_MFTR(code, *flags) {{ 205 flags += ('IsNonSpeculative', ) 206# code = 'std::cerr << curTick() << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code 207 208 code += ''' 209 if (MT_H) 210 data = bits(data, 63, 32); 211 Rd = data; 212 ''' 213 214 iop = InstObjParams(name, Name, 'MTOp', code, flags) 215 header_output = BasicDeclare.subst(iop) 216 decoder_output = BasicConstructor.subst(iop) 217 decode_block = BasicDecode.subst(iop) 218 exec_output = ThreadRegisterExecute.subst(iop) 219}}; 220 221def format MT_MTTR(code, *flags) {{ 222 flags += ('IsNonSpeculative', ) 223# code = 'std::cerr << curTick() << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code 224 iop = InstObjParams(name, Name, 'MTOp', code, flags) 225 header_output = BasicDeclare.subst(iop) 226 decoder_output = BasicConstructor.subst(iop) 227 decode_block = BasicDecode.subst(iop) 228 exec_output = ThreadRegisterExecute.subst(iop) 229}}; 230