integerop.isa revision 12104:edd63f9c6184
1// Copyright (c) 2006-2007 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// Integer operate instructions 34// 35 36output header {{ 37 /** 38 * Base class for integer operations. 39 */ 40 class IntOp : public SparcStaticInst 41 { 42 protected: 43 // Constructor 44 IntOp(const char *mnem, ExtMachInst _machInst, 45 OpClass __opClass) : 46 SparcStaticInst(mnem, _machInst, __opClass) 47 { 48 } 49 50 std::string generateDisassembly(Addr pc, 51 const SymbolTable *symtab) const; 52 53 virtual bool printPseudoOps(std::ostream &os, Addr pc, 54 const SymbolTable *symtab) const; 55 }; 56 57 /** 58 * Base class for immediate integer operations. 59 */ 60 class IntOpImm : public IntOp 61 { 62 protected: 63 // Constructor 64 IntOpImm(const char *mnem, ExtMachInst _machInst, 65 OpClass __opClass) : 66 IntOp(mnem, _machInst, __opClass) 67 { 68 } 69 70 int64_t imm; 71 72 std::string generateDisassembly(Addr pc, 73 const SymbolTable *symtab) const; 74 75 virtual bool printPseudoOps(std::ostream &os, Addr pc, 76 const SymbolTable *symtab) const; 77 }; 78 79 /** 80 * Base class for 10 bit immediate integer operations. 81 */ 82 class IntOpImm10 : public IntOpImm 83 { 84 protected: 85 // Constructor 86 IntOpImm10(const char *mnem, ExtMachInst _machInst, 87 OpClass __opClass) : 88 IntOpImm(mnem, _machInst, __opClass) 89 { 90 imm = sext<10>(SIMM10); 91 } 92 }; 93 94 /** 95 * Base class for 11 bit immediate integer operations. 96 */ 97 class IntOpImm11 : public IntOpImm 98 { 99 protected: 100 // Constructor 101 IntOpImm11(const char *mnem, ExtMachInst _machInst, 102 OpClass __opClass) : 103 IntOpImm(mnem, _machInst, __opClass) 104 { 105 imm = sext<11>(SIMM11); 106 } 107 }; 108 109 /** 110 * Base class for 13 bit immediate integer operations. 111 */ 112 class IntOpImm13 : public IntOpImm 113 { 114 protected: 115 // Constructor 116 IntOpImm13(const char *mnem, ExtMachInst _machInst, 117 OpClass __opClass) : 118 IntOpImm(mnem, _machInst, __opClass) 119 { 120 imm = sext<13>(SIMM13); 121 } 122 }; 123 124 /** 125 * Base class for sethi. 126 */ 127 class SetHi : public IntOpImm 128 { 129 protected: 130 // Constructor 131 SetHi(const char *mnem, ExtMachInst _machInst, 132 OpClass __opClass) : 133 IntOpImm(mnem, _machInst, __opClass) 134 { 135 imm = (IMM22 & 0x3FFFFF) << 10; 136 } 137 138 std::string generateDisassembly(Addr pc, 139 const SymbolTable *symtab) const; 140 }; 141}}; 142 143def template SetHiDecode {{ 144 { 145 if (RD == 0 && IMM22 == 0) 146 return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass)); 147 else 148 return (SparcStaticInst *)(new %(class_name)s(machInst)); 149 } 150}}; 151 152output decoder {{ 153 154 bool 155 IntOp::printPseudoOps(std::ostream &os, Addr pc, 156 const SymbolTable *symbab) const 157 { 158 if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0].regIdx == 0) { 159 printMnemonic(os, "mov"); 160 printSrcReg(os, 1); 161 ccprintf(os, ", "); 162 printDestReg(os, 0); 163 return true; 164 } 165 return false; 166 } 167 168 bool 169 IntOpImm::printPseudoOps(std::ostream &os, Addr pc, 170 const SymbolTable *symbab) const 171 { 172 if (!std::strcmp(mnemonic, "or")) { 173 if (_numSrcRegs > 0 && _srcRegIdx[0].regIdx == 0) { 174 if (imm == 0) { 175 printMnemonic(os, "clr"); 176 } else { 177 printMnemonic(os, "mov"); 178 ccprintf(os, " 0x%x, ", imm); 179 } 180 printDestReg(os, 0); 181 return true; 182 } else if (imm == 0) { 183 printMnemonic(os, "mov"); 184 printSrcReg(os, 0); 185 ccprintf(os, ", "); 186 printDestReg(os, 0); 187 return true; 188 } 189 } 190 return false; 191 } 192 193 std::string 194 IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 195 { 196 std::stringstream response; 197 198 if (printPseudoOps(response, pc, symtab)) 199 return response.str(); 200 printMnemonic(response, mnemonic); 201 printRegArray(response, _srcRegIdx, _numSrcRegs); 202 if (_numDestRegs && _numSrcRegs) 203 response << ", "; 204 printDestReg(response, 0); 205 return response.str(); 206 } 207 208 std::string 209 IntOpImm::generateDisassembly(Addr pc, 210 const SymbolTable *symtab) const 211 { 212 std::stringstream response; 213 214 if (printPseudoOps(response, pc, symtab)) 215 return response.str(); 216 printMnemonic(response, mnemonic); 217 printRegArray(response, _srcRegIdx, _numSrcRegs); 218 if (_numSrcRegs > 0) 219 response << ", "; 220 ccprintf(response, "0x%x", imm); 221 if (_numDestRegs > 0) 222 response << ", "; 223 printDestReg(response, 0); 224 return response.str(); 225 } 226 227 std::string 228 SetHi::generateDisassembly(Addr pc, const SymbolTable *symtab) const 229 { 230 std::stringstream response; 231 232 printMnemonic(response, mnemonic); 233 ccprintf(response, "%%hi(0x%x), ", imm); 234 printDestReg(response, 0); 235 return response.str(); 236 } 237}}; 238 239def template IntOpExecute {{ 240 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 241 Trace::InstRecord *traceData) const 242 { 243 Fault fault = NoFault; 244 245 %(op_decl)s; 246 %(op_rd)s; 247 %(code)s; 248 249 // Write the resulting state to the execution context 250 if (fault == NoFault) { 251 %(cc_code)s; 252 %(op_wb)s; 253 } 254 return fault; 255 } 256}}; 257 258let {{ 259 def doIntFormat(code, ccCode, name, Name, opt_flags): 260 (usesImm, code, immCode, 261 rString, iString) = splitOutImm(code) 262 iop = InstObjParams(name, Name, 'IntOp', 263 {"code": code, "cc_code": ccCode}, 264 opt_flags) 265 header_output = BasicDeclare.subst(iop) 266 decoder_output = BasicConstructor.subst(iop) 267 exec_output = IntOpExecute.subst(iop) 268 if usesImm: 269 imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, 270 {"code": immCode, "cc_code": ccCode}, opt_flags) 271 header_output += BasicDeclare.subst(imm_iop) 272 decoder_output += BasicConstructor.subst(imm_iop) 273 exec_output += IntOpExecute.subst(imm_iop) 274 decode_block = ROrImmDecode.subst(iop) 275 else: 276 decode_block = BasicDecode.subst(iop) 277 return (header_output, decoder_output, exec_output, decode_block) 278 279 calcCcCode = ''' 280 uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn; 281 282 _in = (Rd >> 31) & 1; 283 _iz = ((Rd & 0xFFFFFFFF) == 0); 284 _xn = (Rd >> 63) & 1; 285 _xz = (Rd == 0); 286 _iv = %(iv)s & 1; 287 _ic = %(ic)s & 1; 288 _xv = %(xv)s & 1; 289 _xc = %(xc)s & 1; 290 291 Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 | 292 _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7; 293 294 295 DPRINTF(Sparc, "in = %%d\\n", _in); 296 DPRINTF(Sparc, "iz = %%d\\n", _iz); 297 DPRINTF(Sparc, "xn = %%d\\n", _xn); 298 DPRINTF(Sparc, "xz = %%d\\n", _xz); 299 DPRINTF(Sparc, "iv = %%d\\n", _iv); 300 DPRINTF(Sparc, "ic = %%d\\n", _ic); 301 DPRINTF(Sparc, "xv = %%d\\n", _xv); 302 DPRINTF(Sparc, "xc = %%d\\n", _xc); 303 ''' 304 305 default_ic = "findCarry(32, res, op1, op2)" 306 default_iv = "findOverflow(32, res, op1, op2)" 307 default_xc = "findCarry(64, res, op1, op2)" 308 default_xv = "findOverflow(64, res, op1, op2)" 309 default_sub_ic = "!findCarry(32, res, op1, ~op2)" 310 default_sub_iv = "findOverflow(32, res, op1, ~op2)" 311 default_sub_xc = "!findCarry(64, res, op1, ~op2)" 312 default_sub_xv = "findOverflow(64, res, op1, ~op2)" 313}}; 314 315// Primary format for integer operate instructions: 316def format IntOp(code, *opt_flags) {{ 317 ccCode = '' 318 (header_output, 319 decoder_output, 320 exec_output, 321 decode_block) = doIntFormat(code, ccCode, 322 name, Name, opt_flags) 323}}; 324 325// Primary format for integer operate instructions: 326def format IntOpCc(code, ic=default_ic, iv=default_iv, 327 xc=default_xc, xv=default_xv, 328 sub=False, *opt_flags) {{ 329 330 if sub == "False": 331 (def_ic, def_iv, def_xc, def_xv) = \ 332 (default_ic, default_iv, default_xc, default_xv) 333 else: 334 (def_ic, def_iv, def_xc, def_xv) = \ 335 (default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv) 336 if ic == "default_ic": 337 ic = def_ic 338 if iv == "default_iv": 339 iv = def_iv 340 if xc == "default_xc": 341 xc = def_xc 342 if xv == "default_xv": 343 xv = def_xv 344 ccCode = calcCcCode % vars() 345 (header_output, 346 decoder_output, 347 exec_output, 348 decode_block) = doIntFormat(code, ccCode, 349 name, Name, opt_flags) 350}}; 351 352// Primary format for integer operate instructions: 353def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{ 354 ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv} 355 (header_output, 356 decoder_output, 357 exec_output, 358 decode_block) = doIntFormat(code, ccCode, 359 name, Name, opt_flags) 360}}; 361 362def format SetHi(code, *opt_flags) {{ 363 iop = InstObjParams(name, Name, 'SetHi', 364 {"code": code, "cc_code": ''}, opt_flags) 365 header_output = BasicDeclare.subst(iop) 366 decoder_output = BasicConstructor.subst(iop) 367 exec_output = IntOpExecute.subst(iop) 368 decode_block = SetHiDecode.subst(iop) 369}}; 370 371