base.isa revision 2614
1//////////////////////////////////////////////////////////////////// 2// 3// Base class for sparc instructions, and some support functions 4// 5 6output header {{ 7 8 union CondCodes 9 { 10 struct 11 { 12 uint8_t c:1; 13 uint8_t v:1; 14 uint8_t z:1; 15 uint8_t n:1; 16 }; 17 uint32_t bits; 18 }; 19 20 enum CondTest 21 { 22 Always=0x8, 23 Never=0x0, 24 NotEqual=0x9, 25 Equal=0x1, 26 Greater=0xA, 27 LessOrEqual=0x2, 28 GreaterOrEqual=0xB, 29 Less=0x3, 30 GreaterUnsigned=0xC, 31 LessOrEqualUnsigned=0x4, 32 CarryClear=0xD, 33 CarrySet=0x5, 34 Positive=0xE, 35 Negative=0x6, 36 OverflowClear=0xF, 37 OverflowSet=0x7 38 }; 39 40 extern char * CondTestAbbrev[]; 41 42 /** 43 * Base class for all SPARC static instructions. 44 */ 45 class SparcStaticInst : public StaticInst 46 { 47 protected: 48 // Constructor. 49 SparcStaticInst(const char *mnem, 50 MachInst _machInst, OpClass __opClass) 51 : StaticInst(mnem, _machInst, __opClass) 52 { 53 } 54 55 std::string generateDisassembly(Addr pc, 56 const SymbolTable *symtab) const; 57 58 void printReg(std::ostream &os, int reg) const; 59 }; 60 61 bool passesCondition(uint32_t codes, uint32_t condition); 62 63 inline int64_t sign_ext(uint64_t data, int origWidth) 64 { 65 int shiftAmount = 64 - origWidth; 66 return (((int64_t)data) << shiftAmount) >> shiftAmount; 67 } 68}}; 69 70output decoder {{ 71 72 char * CondTestAbbrev[] = 73 { 74 "nev", //Never 75 "e", //Equal 76 "le", //Less or Equal 77 "l", //Less 78 "leu", //Less or Equal Unsigned 79 "c", //Carry set 80 "n", //Negative 81 "o", //Overflow set 82 "a", //Always 83 "ne", //Not Equal 84 "g", //Greater 85 "ge", //Greater or Equal 86 "gu", //Greater Unsigned 87 "cc", //Carry clear 88 "p", //Positive 89 "oc" //Overflow Clear 90 }; 91}}; 92 93def template ROrImmDecode {{ 94 { 95 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 96 : (SparcStaticInst *)(new %(class_name)s(machInst))); 97 } 98}}; 99 100let {{ 101 def splitOutImm(code): 102 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 103 rOrImmMatch = matcher.search(code) 104 if (rOrImmMatch == None): 105 return (False, code, '', '', '') 106 rString = rOrImmMatch.group("rNum") 107 if (rOrImmMatch.group("typeQual") != None): 108 rString += rOrImmMatch.group("typeQual") 109 iString = rOrImmMatch.group("iNum") 110 orig_code = code 111 code = matcher.sub('Rs' + rString, orig_code) 112 imm_code = matcher.sub('imm', orig_code) 113 return (True, code, imm_code, rString, iString) 114}}; 115 116output decoder {{ 117 118 inline void printMnemonic(std::ostream &os, const char * mnemonic) 119 { 120 ccprintf(os, "\t%s ", mnemonic); 121 } 122 123 void 124 SparcStaticInst::printReg(std::ostream &os, int reg) const 125 { 126 const int MaxGlobal = 8; 127 const int MaxOutput = 16; 128 const int MaxLocal = 24; 129 const int MaxInput = 32; 130 if (reg == FramePointerReg) 131 ccprintf(os, "%%fp"); 132 else if (reg == StackPointerReg) 133 ccprintf(os, "%%sp"); 134 else if(reg < MaxGlobal) 135 ccprintf(os, "%%g%d", reg); 136 else if(reg < MaxOutput) 137 ccprintf(os, "%%o%d", reg - MaxGlobal); 138 else if(reg < MaxLocal) 139 ccprintf(os, "%%l%d", reg - MaxOutput); 140 else if(reg < MaxInput) 141 ccprintf(os, "%%i%d", reg - MaxLocal); 142 else { 143 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 144 } 145 } 146 147 std::string SparcStaticInst::generateDisassembly(Addr pc, 148 const SymbolTable *symtab) const 149 { 150 std::stringstream ss; 151 152 printMnemonic(ss, mnemonic); 153 154 // just print the first two source regs... if there's 155 // a third one, it's a read-modify-write dest (Rc), 156 // e.g. for CMOVxx 157 if(_numSrcRegs > 0) 158 { 159 printReg(ss, _srcRegIdx[0]); 160 } 161 if(_numSrcRegs > 1) 162 { 163 ss << ","; 164 printReg(ss, _srcRegIdx[1]); 165 } 166 167 // just print the first dest... if there's a second one, 168 // it's generally implicit 169 if(_numDestRegs > 0) 170 { 171 if(_numSrcRegs > 0) 172 ss << ","; 173 printReg(ss, _destRegIdx[0]); 174 } 175 176 return ss.str(); 177 } 178 179 bool passesCondition(uint32_t codes, uint32_t condition) 180 { 181 CondCodes condCodes; 182 condCodes.bits = codes; 183 switch(condition) 184 { 185 case Always: 186 return true; 187 case Never: 188 return false; 189 case NotEqual: 190 return !condCodes.z; 191 case Equal: 192 return condCodes.z; 193 case Greater: 194 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 195 case LessOrEqual: 196 return condCodes.z | (condCodes.n ^ condCodes.v); 197 case GreaterOrEqual: 198 return !(condCodes.n ^ condCodes.v); 199 case Less: 200 return (condCodes.n ^ condCodes.v); 201 case GreaterUnsigned: 202 return !(condCodes.c | condCodes.z); 203 case LessOrEqualUnsigned: 204 return (condCodes.c | condCodes.z); 205 case CarryClear: 206 return !condCodes.c; 207 case CarrySet: 208 return condCodes.c; 209 case Positive: 210 return !condCodes.n; 211 case Negative: 212 return condCodes.n; 213 case OverflowClear: 214 return !condCodes.v; 215 case OverflowSet: 216 return condCodes.v; 217 } 218 panic("Tried testing condition nonexistant " 219 "condition code %d", condition); 220 } 221}}; 222 223