integerop.isa revision 2646:c5f20661d9f3
1// Copyright (c) 2006 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 int32_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 = sign_ext(SIMM10, 10); 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 = sign_ext(SIMM11, 11); 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 = sign_ext(SIMM13, 13); 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 << 10) & 0xFFFFFC00; 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 IntOp::printPseudoOps(std::ostream &os, Addr pc, 155 const SymbolTable *symbab) const 156 { 157 if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) 158 { 159 printMnemonic(os, "mov"); 160 if(_numSrcRegs > 0) 161 printReg(os, _srcRegIdx[1]); 162 ccprintf(os, ", "); 163 if(_numDestRegs > 0) 164 printReg(os, _destRegIdx[0]); 165 166 return true; 167 } 168 return false; 169 } 170 171 bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc, 172 const SymbolTable *symbab) const 173 { 174 if(!strcmp(mnemonic, "or")) 175 { 176 if(_srcRegIdx[0] == 0) 177 { 178 if(imm == 0) 179 { 180 printMnemonic(os, "clr"); 181 if(_numDestRegs > 0) 182 printReg(os, _destRegIdx[0]); 183 return true; 184 } 185 else 186 { 187 printMnemonic(os, "mov"); 188 ccprintf(os, ", 0x%x, ", imm); 189 if(_numDestRegs > 0) 190 printReg(os, _destRegIdx[0]); 191 return true; 192 } 193 } 194 else if(imm == 0) 195 { 196 printMnemonic(os, "mov"); 197 if(_numSrcRegs > 0) 198 printReg(os, _srcRegIdx[0]); 199 ccprintf(os, ", "); 200 if(_numDestRegs > 0) 201 printReg(os, _destRegIdx[0]); 202 return true; 203 } 204 } 205 return false; 206 } 207 208 std::string IntOp::generateDisassembly(Addr pc, 209 const SymbolTable *symtab) const 210 { 211 std::stringstream response; 212 213 if(!printPseudoOps(response, pc, symtab)) 214 { 215 printMnemonic(response, mnemonic); 216 if (_numSrcRegs > 0) 217 { 218 printReg(response, _srcRegIdx[0]); 219 for(int x = 1; x < _numSrcRegs; x++) 220 { 221 response << ", "; 222 printReg(response, _srcRegIdx[x]); 223 } 224 } 225 if (_numDestRegs > 0) 226 { 227 if(_numSrcRegs > 0) 228 response << ", "; 229 printReg(response, _destRegIdx[0]); 230 } 231 } 232 return response.str(); 233 } 234 235 std::string IntOpImm::generateDisassembly(Addr pc, 236 const SymbolTable *symtab) const 237 { 238 std::stringstream response; 239 240 if(!printPseudoOps(response, pc, symtab)) 241 { 242 printMnemonic(response, mnemonic); 243 if (_numSrcRegs > 0) 244 { 245 printReg(response, _srcRegIdx[0]); 246 for(int x = 1; x < _numSrcRegs - 1; x++) 247 { 248 response << ", "; 249 printReg(response, _srcRegIdx[x]); 250 } 251 } 252 if(_numSrcRegs > 0) 253 response << ", "; 254 ccprintf(response, "0x%x", imm); 255 if (_numDestRegs > 0) 256 { 257 response << ", "; 258 printReg(response, _destRegIdx[0]); 259 } 260 } 261 return response.str(); 262 } 263 264 std::string SetHi::generateDisassembly(Addr pc, 265 const SymbolTable *symtab) const 266 { 267 std::stringstream response; 268 269 printMnemonic(response, mnemonic); 270 if(_numSrcRegs > 0) 271 response << ", "; 272 ccprintf(response, "%%hi(0x%x), ", imm); 273 printReg(response, _destRegIdx[0]); 274 return response.str(); 275 } 276}}; 277 278def template IntOpExecute {{ 279 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 280 Trace::InstRecord *traceData) const 281 { 282 Fault fault = NoFault; 283 284 %(op_decl)s; 285 %(op_rd)s; 286 %(code)s; 287 288 //Write the resulting state to the execution context 289 if(fault == NoFault) 290 { 291 %(cc_code)s; 292 %(op_wb)s; 293 } 294 return fault; 295 } 296}}; 297 298let {{ 299 def doIntFormat(code, ccCode, name, Name, opt_flags): 300 (usesImm, code, immCode, 301 rString, iString) = splitOutImm(code) 302 iop = InstObjParams(name, Name, 'IntOp', code, 303 opt_flags, ("cc_code", ccCode)) 304 header_output = BasicDeclare.subst(iop) 305 decoder_output = BasicConstructor.subst(iop) 306 exec_output = IntOpExecute.subst(iop) 307 if usesImm: 308 imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, 309 immCode, opt_flags, ("cc_code", ccCode)) 310 header_output += BasicDeclare.subst(imm_iop) 311 decoder_output += BasicConstructor.subst(imm_iop) 312 exec_output += IntOpExecute.subst(imm_iop) 313 decode_block = ROrImmDecode.subst(iop) 314 else: 315 decode_block = BasicDecode.subst(iop) 316 return (header_output, decoder_output, exec_output, decode_block) 317 318 calcCcCode = ''' 319 uint8_t tmp_ccriccc; 320 uint8_t tmp_ccriccv; 321 uint8_t tmp_ccriccz; 322 uint8_t tmp_ccriccn; 323 uint8_t tmp_ccrxccc; 324 uint8_t tmp_ccrxccv; 325 uint8_t tmp_ccrxccz; 326 uint8_t tmp_ccrxccn; 327 328 tmp_ccriccn = (Rd >> 31) & 1; 329 tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0); 330 tmp_ccrxccn = (Rd >> 63) & 1; 331 tmp_ccrxccz = (Rd == 0); 332 tmp_ccriccv = %(ivValue)s & 1; 333 tmp_ccriccc = %(icValue)s & 1; 334 tmp_ccrxccv = %(xvValue)s & 1; 335 tmp_ccrxccc = %(xcValue)s & 1; 336 337 Ccr = tmp_ccriccc | tmp_ccriccv << 1 | 338 tmp_ccriccz << 2 | tmp_ccriccn << 3| 339 tmp_ccrxccc << 4 | tmp_ccrxccv << 5| 340 tmp_ccrxccz << 6| tmp_ccrxccn << 7; 341 342 343 DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn); 344 DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz); 345 DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn); 346 DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz); 347 DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv); 348 DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc); 349 DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv); 350 DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc); 351 ''' 352}}; 353 354// Primary format for integer operate instructions: 355def format IntOp(code, *opt_flags) {{ 356 ccCode = '' 357 (header_output, 358 decoder_output, 359 exec_output, 360 decode_block) = doIntFormat(code, ccCode, 361 name, Name, opt_flags) 362}}; 363 364// Primary format for integer operate instructions: 365def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ 366 ccCode = calcCcCode % vars() 367 (header_output, 368 decoder_output, 369 exec_output, 370 decode_block) = doIntFormat(code, ccCode, 371 name, Name, opt_flags) 372}}; 373 374// Primary format for integer operate instructions: 375def format IntOpCcRes(code, *opt_flags) {{ 376 ccCode = calcCcCode % {"icValue":"0", 377 "ivValue":"0", 378 "xcValue":"0", 379 "xvValue":"0"} 380 (header_output, 381 decoder_output, 382 exec_output, 383 decode_block) = doIntFormat(code, ccCode, 384 name, Name, opt_flags) 385}}; 386 387def format SetHi(code, *opt_flags) {{ 388 iop = InstObjParams(name, Name, 'SetHi', 389 code, opt_flags, ("cc_code", '')) 390 header_output = BasicDeclare.subst(iop) 391 decoder_output = BasicConstructor.subst(iop) 392 exec_output = IntOpExecute.subst(iop) 393 decode_block = SetHiDecode.subst(iop) 394}}; 395 396