base.isa revision 2516
110086Snilay@cs.wisc.edu//////////////////////////////////////////////////////////////////// 210086Snilay@cs.wisc.edu// 310086Snilay@cs.wisc.edu// Base class for sparc instructions, and some support functions 410086Snilay@cs.wisc.edu// 510086Snilay@cs.wisc.edu 610086Snilay@cs.wisc.eduoutput header {{ 710086Snilay@cs.wisc.edu 810086Snilay@cs.wisc.edu union CondCodes 910086Snilay@cs.wisc.edu { 1010086Snilay@cs.wisc.edu struct 1110086Snilay@cs.wisc.edu { 1210086Snilay@cs.wisc.edu uint8_t c:1; 1310086Snilay@cs.wisc.edu uint8_t v:1; 1410086Snilay@cs.wisc.edu uint8_t z:1; 1510086Snilay@cs.wisc.edu uint8_t n:1; 1610086Snilay@cs.wisc.edu }; 1710086Snilay@cs.wisc.edu uint32_t bits; 1810086Snilay@cs.wisc.edu }; 1910086Snilay@cs.wisc.edu 2010086Snilay@cs.wisc.edu enum CondTest 2110086Snilay@cs.wisc.edu { 2210086Snilay@cs.wisc.edu Always=0x8, 2310086Snilay@cs.wisc.edu Never=0x0, 2410086Snilay@cs.wisc.edu NotEqual=0x9, 2510086Snilay@cs.wisc.edu Equal=0x1, 2610086Snilay@cs.wisc.edu Greater=0xA, 2710086Snilay@cs.wisc.edu LessOrEqual=0x2, 2810086Snilay@cs.wisc.edu GreaterOrEqual=0xB, 2911793Sbrandon.potter@amd.com Less=0x3, 3011793Sbrandon.potter@amd.com GreaterUnsigned=0xC, 318092Snilay@cs.wisc.edu LessOrEqualUnsigned=0x4, 328092Snilay@cs.wisc.edu CarryClear=0xD, 338092Snilay@cs.wisc.edu CarrySet=0x5, 348092Snilay@cs.wisc.edu Positive=0xE, 358174Snilay@cs.wisc.edu Negative=0x6, 368174Snilay@cs.wisc.edu OverflowClear=0xF, 378092Snilay@cs.wisc.edu OverflowSet=0x7 388174Snilay@cs.wisc.edu }; 3911118Snilay@cs.wisc.edu 4011118Snilay@cs.wisc.edu /** 418174Snilay@cs.wisc.edu * Base class for all SPARC static instructions. 4211118Snilay@cs.wisc.edu */ 438174Snilay@cs.wisc.edu class SparcStaticInst : public StaticInst 448174Snilay@cs.wisc.edu { 458174Snilay@cs.wisc.edu protected: 468174Snilay@cs.wisc.edu // Constructor. 478174Snilay@cs.wisc.edu SparcStaticInst(const char *mnem, 488092Snilay@cs.wisc.edu MachInst _machInst, OpClass __opClass) 499302Snilay@cs.wisc.edu : StaticInst(mnem, _machInst, __opClass) 509302Snilay@cs.wisc.edu { 519302Snilay@cs.wisc.edu } 529302Snilay@cs.wisc.edu 539302Snilay@cs.wisc.edu std::string generateDisassembly(Addr pc, 549302Snilay@cs.wisc.edu const SymbolTable *symtab) const; 559302Snilay@cs.wisc.edu 569302Snilay@cs.wisc.edu void printReg(std::ostream &os, int reg) const; 579302Snilay@cs.wisc.edu }; 589302Snilay@cs.wisc.edu 599302Snilay@cs.wisc.edu bool passesCondition(uint32_t codes, uint32_t condition); 609302Snilay@cs.wisc.edu 619302Snilay@cs.wisc.edu inline int64_t sign_ext(uint64_t data, int origWidth) 629302Snilay@cs.wisc.edu { 639302Snilay@cs.wisc.edu int shiftAmount = sizeof(uint64_t) - origWidth; 649302Snilay@cs.wisc.edu return (((int64_t)data) << shiftAmount) >> shiftAmount; 659302Snilay@cs.wisc.edu } 669302Snilay@cs.wisc.edu}}; 679302Snilay@cs.wisc.edu 689302Snilay@cs.wisc.edudef template ROrImmDecode {{ 699302Snilay@cs.wisc.edu { 709572Sbah13@duke.edu return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 719572Sbah13@duke.edu : (SparcStaticInst *)(new %(class_name)s(machInst))); 7211025Snilay@cs.wisc.edu } 739572Sbah13@duke.edu}}; 749302Snilay@cs.wisc.edu 7510563Sandreas.hansson@arm.comlet {{ 769302Snilay@cs.wisc.edu def splitOutImm(code): 779572Sbah13@duke.edu matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)') 789572Sbah13@duke.edu rOrImmMatch = matcher.search(code) 799302Snilay@cs.wisc.edu if (rOrImmMatch == None): 809572Sbah13@duke.edu return (False, code, '', '', '') 819572Sbah13@duke.edu rString = rOrImmMatch.group("rNum") 829302Snilay@cs.wisc.edu iString = rOrImmMatch.group("iNum") 839572Sbah13@duke.edu orig_code = code 849572Sbah13@duke.edu code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code) 859302Snilay@cs.wisc.edu imm_code = matcher.sub('imm', orig_code) 86 return (True, code, imm_code, rString, iString) 87 88 def genCompositeIop(code, name, Name, parent, opt_flags, **extras): 89 origBlock = CodeBlock(code) 90 composite = code 91 for snippet in extras.values(): 92 composite += ('\n' + snippet) 93 compositeBlock = CodeBlock(composite) 94 iop = InstObjParams(name, Name, parent, compositeBlock, opt_flags) 95 iop.code = origBlock.code 96 iop.orig_code = origBlock.orig_code 97 for (name, snippet) in extras.items(): 98 exec "iop.%s = CodeBlock(snippet).code" % name 99 return iop 100}}; 101 102output decoder {{ 103 104 inline void printMnemonic(std::ostream &os, const char * mnemonic) 105 { 106 ccprintf(os, "\t%s ", mnemonic); 107 } 108 109 void 110 SparcStaticInst::printReg(std::ostream &os, int reg) const 111 { 112 const int MaxGlobal = 8; 113 const int MaxOutput = 16; 114 const int MaxLocal = 24; 115 const int MaxInput = 32; 116 if (reg == FramePointerReg) 117 ccprintf(os, "%%fp"); 118 else if (reg == StackPointerReg) 119 ccprintf(os, "%%sp"); 120 else if(reg < MaxGlobal) 121 ccprintf(os, "%%g%d", reg); 122 else if(reg < MaxOutput) 123 ccprintf(os, "%%o%d", reg - MaxGlobal); 124 else if(reg < MaxLocal) 125 ccprintf(os, "%%l%d", reg - MaxOutput); 126 else if(reg < MaxInput) 127 ccprintf(os, "%%i%d", reg - MaxLocal); 128 else { 129 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 130 } 131 } 132 133 std::string SparcStaticInst::generateDisassembly(Addr pc, 134 const SymbolTable *symtab) const 135 { 136 std::stringstream ss; 137 138 printMnemonic(ss, mnemonic); 139 140 // just print the first two source regs... if there's 141 // a third one, it's a read-modify-write dest (Rc), 142 // e.g. for CMOVxx 143 if(_numSrcRegs > 0) 144 { 145 printReg(ss, _srcRegIdx[0]); 146 } 147 if(_numSrcRegs > 1) 148 { 149 ss << ","; 150 printReg(ss, _srcRegIdx[1]); 151 } 152 153 // just print the first dest... if there's a second one, 154 // it's generally implicit 155 if(_numDestRegs > 0) 156 { 157 if(_numSrcRegs > 0) 158 ss << ","; 159 printReg(ss, _destRegIdx[0]); 160 } 161 162 return ss.str(); 163 } 164 165 bool passesCondition(uint32_t codes, uint32_t condition) 166 { 167 CondCodes condCodes; 168 condCodes.bits = codes; 169 switch(condition) 170 { 171 case Always: 172 return true; 173 case Never: 174 return false; 175 case NotEqual: 176 return !condCodes.z; 177 case Equal: 178 return condCodes.z; 179 case Greater: 180 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 181 case LessOrEqual: 182 return condCodes.z | (condCodes.n ^ condCodes.v); 183 case GreaterOrEqual: 184 return !(condCodes.n ^ condCodes.v); 185 case Less: 186 return (condCodes.n ^ condCodes.v); 187 case GreaterUnsigned: 188 return !(condCodes.c | condCodes.z); 189 case LessOrEqualUnsigned: 190 return (condCodes.c | condCodes.z); 191 case CarryClear: 192 return !condCodes.c; 193 case CarrySet: 194 return condCodes.c; 195 case Positive: 196 return !condCodes.n; 197 case Negative: 198 return condCodes.n; 199 case OverflowClear: 200 return !condCodes.v; 201 case OverflowSet: 202 return condCodes.v; 203 } 204 panic("Tried testing condition nonexistant " 205 "condition code %d", condition); 206 } 207}}; 208 209