base.isa revision 2561
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+)') 103 rOrImmMatch = matcher.search(code) 104 if (rOrImmMatch == None): 105 return (False, code, '', '', '') 106 rString = rOrImmMatch.group("rNum") 107 iString = rOrImmMatch.group("iNum") 108 orig_code = code 109 code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code) 110 imm_code = matcher.sub('imm', orig_code) 111 return (True, code, imm_code, rString, iString) 112}}; 113 114output decoder {{ 115 116 inline void printMnemonic(std::ostream &os, const char * mnemonic) 117 { 118 ccprintf(os, "\t%s ", mnemonic); 119 } 120 121 void 122 SparcStaticInst::printReg(std::ostream &os, int reg) const 123 { 124 const int MaxGlobal = 8; 125 const int MaxOutput = 16; 126 const int MaxLocal = 24; 127 const int MaxInput = 32; 128 if (reg == FramePointerReg) 129 ccprintf(os, "%%fp"); 130 else if (reg == StackPointerReg) 131 ccprintf(os, "%%sp"); 132 else if(reg < MaxGlobal) 133 ccprintf(os, "%%g%d", reg); 134 else if(reg < MaxOutput) 135 ccprintf(os, "%%o%d", reg - MaxGlobal); 136 else if(reg < MaxLocal) 137 ccprintf(os, "%%l%d", reg - MaxOutput); 138 else if(reg < MaxInput) 139 ccprintf(os, "%%i%d", reg - MaxLocal); 140 else { 141 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 142 } 143 } 144 145 std::string SparcStaticInst::generateDisassembly(Addr pc, 146 const SymbolTable *symtab) const 147 { 148 std::stringstream ss; 149 150 printMnemonic(ss, mnemonic); 151 152 // just print the first two source regs... if there's 153 // a third one, it's a read-modify-write dest (Rc), 154 // e.g. for CMOVxx 155 if(_numSrcRegs > 0) 156 { 157 printReg(ss, _srcRegIdx[0]); 158 } 159 if(_numSrcRegs > 1) 160 { 161 ss << ","; 162 printReg(ss, _srcRegIdx[1]); 163 } 164 165 // just print the first dest... if there's a second one, 166 // it's generally implicit 167 if(_numDestRegs > 0) 168 { 169 if(_numSrcRegs > 0) 170 ss << ","; 171 printReg(ss, _destRegIdx[0]); 172 } 173 174 return ss.str(); 175 } 176 177 bool passesCondition(uint32_t codes, uint32_t condition) 178 { 179 CondCodes condCodes; 180 condCodes.bits = codes; 181 switch(condition) 182 { 183 case Always: 184 return true; 185 case Never: 186 return false; 187 case NotEqual: 188 return !condCodes.z; 189 case Equal: 190 return condCodes.z; 191 case Greater: 192 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 193 case LessOrEqual: 194 return condCodes.z | (condCodes.n ^ condCodes.v); 195 case GreaterOrEqual: 196 return !(condCodes.n ^ condCodes.v); 197 case Less: 198 return (condCodes.n ^ condCodes.v); 199 case GreaterUnsigned: 200 return !(condCodes.c | condCodes.z); 201 case LessOrEqualUnsigned: 202 return (condCodes.c | condCodes.z); 203 case CarryClear: 204 return !condCodes.c; 205 case CarrySet: 206 return condCodes.c; 207 case Positive: 208 return !condCodes.n; 209 case Negative: 210 return condCodes.n; 211 case OverflowClear: 212 return !condCodes.v; 213 case OverflowSet: 214 return condCodes.v; 215 } 216 panic("Tried testing condition nonexistant " 217 "condition code %d", condition); 218 } 219}}; 220 221