integerop.isa revision 7799:5d0f62927d75
12SN/A// Copyright (c) 2006-2007 The Regents of The University of Michigan 21762SN/A// All rights reserved. 32SN/A// 42SN/A// Redistribution and use in source and binary forms, with or without 52SN/A// modification, are permitted provided that the following conditions are 62SN/A// met: redistributions of source code must retain the above copyright 72SN/A// notice, this list of conditions and the following disclaimer; 82SN/A// redistributions in binary form must reproduce the above copyright 92SN/A// notice, this list of conditions and the following disclaimer in the 102SN/A// documentation and/or other materials provided with the distribution; 112SN/A// neither the name of the copyright holders nor the names of its 122SN/A// contributors may be used to endorse or promote products derived from 132SN/A// this software without specific prior written permission. 142SN/A// 152SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 182SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 192SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 202SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 212SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 252SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262SN/A// 272665Ssaidi@eecs.umich.edu// Authors: Ali Saidi 282665Ssaidi@eecs.umich.edu// Gabe Black 292665Ssaidi@eecs.umich.edu// Steve Reinhardt 302SN/A 312SN/A//////////////////////////////////////////////////////////////////// 324997Sgblack@eecs.umich.edu// 331110SN/A// Integer operate instructions 344997Sgblack@eecs.umich.edu// 358229Snate@binkert.org 368229Snate@binkert.orgoutput header {{ 372680Sktlim@umich.edu /** 388229Snate@binkert.org * Base class for integer operations. 392800Ssaidi@eecs.umich.edu */ 408780Sgblack@eecs.umich.edu class IntOp : public SparcStaticInst 412SN/A { 425569Snate@binkert.org protected: 432167SN/A // Constructor 442203SN/A IntOp(const char *mnem, ExtMachInst _machInst, 452203SN/A OpClass __opClass) : 462222SN/A SparcStaticInst(mnem, _machInst, __opClass) 472166SN/A { 482203SN/A } 492203SN/A 502222SN/A std::string generateDisassembly(Addr pc, 512166SN/A const SymbolTable *symtab) const; 522147SN/A 532147SN/A virtual bool printPseudoOps(std::ostream &os, Addr pc, 542222SN/A const SymbolTable *symtab) const; 552147SN/A }; 562147SN/A 572147SN/A /** 582222SN/A * Base class for immediate integer operations. 592147SN/A */ 602147SN/A class IntOpImm : public IntOp 612147SN/A { 622222SN/A protected: 632147SN/A // Constructor 642147SN/A IntOpImm(const char *mnem, ExtMachInst _machInst, 652147SN/A OpClass __opClass) : 662222SN/A IntOp(mnem, _machInst, __opClass) 672147SN/A { 682147SN/A } 692147SN/A 702222SN/A int64_t imm; 712147SN/A 728405Sksewell@umich.edu std::string generateDisassembly(Addr pc, 732147SN/A const SymbolTable *symtab) const; 742222SN/A 752147SN/A virtual bool printPseudoOps(std::ostream &os, Addr pc, 768405Sksewell@umich.edu const SymbolTable *symtab) const; 772147SN/A }; 782222SN/A 792147SN/A /** 802289SN/A * Base class for 10 bit immediate integer operations. 812289SN/A */ 822289SN/A class IntOpImm10 : public IntOpImm 832289SN/A { 842147SN/A protected: 852147SN/A // Constructor 862222SN/A IntOpImm10(const char *mnem, ExtMachInst _machInst, 872147SN/A OpClass __opClass) : 882147SN/A IntOpImm(mnem, _machInst, __opClass) 892147SN/A { 902222SN/A imm = sext<10>(SIMM10); 912147SN/A } 922147SN/A }; 932147SN/A 942222SN/A /** 952147SN/A * Base class for 11 bit immediate integer operations. 962147SN/A */ 972147SN/A class IntOpImm11 : public IntOpImm 982222SN/A { 992147SN/A protected: 1002147SN/A // Constructor 1012147SN/A IntOpImm11(const char *mnem, ExtMachInst _machInst, 1022222SN/A OpClass __opClass) : 1032147SN/A IntOpImm(mnem, _machInst, __opClass) 1042147SN/A { 1052147SN/A imm = sext<11>(SIMM11); 1062222SN/A } 1072147SN/A }; 1085569Snate@binkert.org 10910417Sandreas.hansson@arm.com /** 1102174SN/A * Base class for 13 bit immediate integer operations. 1112680Sktlim@umich.edu */ 1128780Sgblack@eecs.umich.edu class IntOpImm13 : public IntOpImm 1138780Sgblack@eecs.umich.edu { 1142222SN/A protected: 1152174SN/A // Constructor 1167720Sgblack@eecs.umich.edu IntOpImm13(const char *mnem, ExtMachInst _machInst, 1177720Sgblack@eecs.umich.edu OpClass __opClass) : 1182196SN/A IntOpImm(mnem, _machInst, __opClass) 1197720Sgblack@eecs.umich.edu { 1207720Sgblack@eecs.umich.edu imm = sext<13>(SIMM13); 1212196SN/A } 1222201SN/A }; 1232196SN/A 1245568Snate@binkert.org /** 1255568Snate@binkert.org * Base class for sethi. 1262196SN/A */ 1272196SN/A class SetHi : public IntOpImm 1287720Sgblack@eecs.umich.edu { 1297720Sgblack@eecs.umich.edu protected: 1302174SN/A // Constructor 1312174SN/A SetHi(const char *mnem, ExtMachInst _machInst, 1325569Snate@binkert.org OpClass __opClass) : 13310417Sandreas.hansson@arm.com IntOpImm(mnem, _machInst, __opClass) 1342201SN/A { 1352680Sktlim@umich.edu imm = (IMM22 & 0x3FFFFF) << 10; 1368780Sgblack@eecs.umich.edu } 1378780Sgblack@eecs.umich.edu 1382201SN/A std::string generateDisassembly(Addr pc, 1392201SN/A const SymbolTable *symtab) const; 1402201SN/A }; 1415569Snate@binkert.org}}; 14210417Sandreas.hansson@arm.com 1432289SN/Adef template SetHiDecode {{ 1448780Sgblack@eecs.umich.edu { 1458780Sgblack@eecs.umich.edu if (RD == 0 && IMM22 == 0) 1468780Sgblack@eecs.umich.edu return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass)); 1478780Sgblack@eecs.umich.edu else 1488780Sgblack@eecs.umich.edu return (SparcStaticInst *)(new %(class_name)s(machInst)); 1498780Sgblack@eecs.umich.edu } 15010664SAli.Saidi@ARM.com}}; 1518780Sgblack@eecs.umich.edu 1528780Sgblack@eecs.umich.eduoutput decoder {{ 1532289SN/A 1548780Sgblack@eecs.umich.edu bool 1558780Sgblack@eecs.umich.edu IntOp::printPseudoOps(std::ostream &os, Addr pc, 1568780Sgblack@eecs.umich.edu const SymbolTable *symbab) const 1578780Sgblack@eecs.umich.edu { 1588780Sgblack@eecs.umich.edu if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) { 1598780Sgblack@eecs.umich.edu printMnemonic(os, "mov"); 1602289SN/A printSrcReg(os, 1); 1618780Sgblack@eecs.umich.edu ccprintf(os, ", "); 1628780Sgblack@eecs.umich.edu printDestReg(os, 0); 1638780Sgblack@eecs.umich.edu return true; 1648780Sgblack@eecs.umich.edu } 1652289SN/A return false; 1662289SN/A } 1672680Sktlim@umich.edu 1682289SN/A bool 1692289SN/A IntOpImm::printPseudoOps(std::ostream &os, Addr pc, 1705569Snate@binkert.org const SymbolTable *symbab) const 17110417Sandreas.hansson@arm.com { 1722289SN/A if (!std::strcmp(mnemonic, "or")) { 1738780Sgblack@eecs.umich.edu if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) { 17410664SAli.Saidi@ARM.com if (imm == 0) { 17510664SAli.Saidi@ARM.com printMnemonic(os, "clr"); 17610664SAli.Saidi@ARM.com } else { 1772289SN/A printMnemonic(os, "mov"); 1782289SN/A ccprintf(os, " 0x%x, ", imm); 1792680Sktlim@umich.edu } 1802289SN/A printDestReg(os, 0); 1812289SN/A return true; 1825569Snate@binkert.org } else if (imm == 0) { 18310417Sandreas.hansson@arm.com printMnemonic(os, "mov"); 1844997Sgblack@eecs.umich.edu printSrcReg(os, 0); 1858780Sgblack@eecs.umich.edu ccprintf(os, ", "); 1868780Sgblack@eecs.umich.edu printDestReg(os, 0); 1878806Sgblack@eecs.umich.edu return true; 1888806Sgblack@eecs.umich.edu } 1898806Sgblack@eecs.umich.edu } 1908806Sgblack@eecs.umich.edu return false; 1918806Sgblack@eecs.umich.edu } 1928806Sgblack@eecs.umich.edu 1938806Sgblack@eecs.umich.edu std::string 1948806Sgblack@eecs.umich.edu IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1954997Sgblack@eecs.umich.edu { 1968806Sgblack@eecs.umich.edu std::stringstream response; 1978806Sgblack@eecs.umich.edu 1984997Sgblack@eecs.umich.edu if (printPseudoOps(response, pc, symtab)) 1994997Sgblack@eecs.umich.edu return response.str(); 2004997Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 2015569Snate@binkert.org printRegArray(response, _srcRegIdx, _numSrcRegs); 20210417Sandreas.hansson@arm.com if (_numDestRegs && _numSrcRegs) 2034997Sgblack@eecs.umich.edu response << ", "; 2048780Sgblack@eecs.umich.edu printDestReg(response, 0); 2058780Sgblack@eecs.umich.edu return response.str(); 2068806Sgblack@eecs.umich.edu } 2078806Sgblack@eecs.umich.edu 2088806Sgblack@eecs.umich.edu std::string 2098806Sgblack@eecs.umich.edu IntOpImm::generateDisassembly(Addr pc, 2108806Sgblack@eecs.umich.edu const SymbolTable *symtab) const 2118806Sgblack@eecs.umich.edu { 2128806Sgblack@eecs.umich.edu std::stringstream response; 2138806Sgblack@eecs.umich.edu 2148806Sgblack@eecs.umich.edu if (printPseudoOps(response, pc, symtab)) 2158806Sgblack@eecs.umich.edu return response.str(); 2168806Sgblack@eecs.umich.edu printMnemonic(response, mnemonic); 2178806Sgblack@eecs.umich.edu printRegArray(response, _srcRegIdx, _numSrcRegs); 2184997Sgblack@eecs.umich.edu if (_numSrcRegs > 0) 2198806Sgblack@eecs.umich.edu response << ", "; 2204997Sgblack@eecs.umich.edu ccprintf(response, "0x%x", imm); 2214997Sgblack@eecs.umich.edu if (_numDestRegs > 0) 2224997Sgblack@eecs.umich.edu response << ", "; 2232167SN/A printDestReg(response, 0); 2242167SN/A 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)s *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