base.isa revision 2526
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 /** 41 * Base class for all SPARC static instructions. 42 */ 43 class SparcStaticInst : public StaticInst 44 { 45 protected: 46 // Constructor. 47 SparcStaticInst(const char *mnem, 48 MachInst _machInst, OpClass __opClass) 49 : StaticInst(mnem, _machInst, __opClass) 50 { 51 } 52 53 std::string generateDisassembly(Addr pc, 54 const SymbolTable *symtab) const; 55 56 void printReg(std::ostream &os, int reg) const; 57 }; 58 59 bool passesCondition(uint32_t codes, uint32_t condition); 60 61 inline int64_t sign_ext(uint64_t data, int origWidth) 62 { 63 int shiftAmount = 64 - origWidth; 64 return (((int64_t)data) << shiftAmount) >> shiftAmount; 65 } 66}}; 67 68def template ROrImmDecode {{ 69 { 70 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 71 : (SparcStaticInst *)(new %(class_name)s(machInst))); 72 } 73}}; 74 75let {{ 76 def splitOutImm(code): 77 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)') 78 rOrImmMatch = matcher.search(code) 79 if (rOrImmMatch == None): 80 return (False, code, '', '', '') 81 rString = rOrImmMatch.group("rNum") 82 iString = rOrImmMatch.group("iNum") 83 orig_code = code 84 code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code) 85 imm_code = matcher.sub('imm', orig_code) 86 return (True, code, imm_code, rString, iString) 87}}; 88 89output decoder {{ 90 91 inline void printMnemonic(std::ostream &os, const char * mnemonic) 92 { 93 ccprintf(os, "\t%s ", mnemonic); 94 } 95 96 void 97 SparcStaticInst::printReg(std::ostream &os, int reg) const 98 { 99 const int MaxGlobal = 8; 100 const int MaxOutput = 16; 101 const int MaxLocal = 24; 102 const int MaxInput = 32; 103 if (reg == FramePointerReg) 104 ccprintf(os, "%%fp"); 105 else if (reg == StackPointerReg) 106 ccprintf(os, "%%sp"); 107 else if(reg < MaxGlobal) 108 ccprintf(os, "%%g%d", reg); 109 else if(reg < MaxOutput) 110 ccprintf(os, "%%o%d", reg - MaxGlobal); 111 else if(reg < MaxLocal) 112 ccprintf(os, "%%l%d", reg - MaxOutput); 113 else if(reg < MaxInput) 114 ccprintf(os, "%%i%d", reg - MaxLocal); 115 else { 116 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 117 } 118 } 119 120 std::string SparcStaticInst::generateDisassembly(Addr pc, 121 const SymbolTable *symtab) const 122 { 123 std::stringstream ss; 124 125 printMnemonic(ss, mnemonic); 126 127 // just print the first two source regs... if there's 128 // a third one, it's a read-modify-write dest (Rc), 129 // e.g. for CMOVxx 130 if(_numSrcRegs > 0) 131 { 132 printReg(ss, _srcRegIdx[0]); 133 } 134 if(_numSrcRegs > 1) 135 { 136 ss << ","; 137 printReg(ss, _srcRegIdx[1]); 138 } 139 140 // just print the first dest... if there's a second one, 141 // it's generally implicit 142 if(_numDestRegs > 0) 143 { 144 if(_numSrcRegs > 0) 145 ss << ","; 146 printReg(ss, _destRegIdx[0]); 147 } 148 149 return ss.str(); 150 } 151 152 bool passesCondition(uint32_t codes, uint32_t condition) 153 { 154 CondCodes condCodes; 155 condCodes.bits = codes; 156 switch(condition) 157 { 158 case Always: 159 return true; 160 case Never: 161 return false; 162 case NotEqual: 163 return !condCodes.z; 164 case Equal: 165 return condCodes.z; 166 case Greater: 167 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 168 case LessOrEqual: 169 return condCodes.z | (condCodes.n ^ condCodes.v); 170 case GreaterOrEqual: 171 return !(condCodes.n ^ condCodes.v); 172 case Less: 173 return (condCodes.n ^ condCodes.v); 174 case GreaterUnsigned: 175 return !(condCodes.c | condCodes.z); 176 case LessOrEqualUnsigned: 177 return (condCodes.c | condCodes.z); 178 case CarryClear: 179 return !condCodes.c; 180 case CarrySet: 181 return condCodes.c; 182 case Positive: 183 return !condCodes.n; 184 case Negative: 185 return condCodes.n; 186 case OverflowClear: 187 return !condCodes.v; 188 case OverflowSet: 189 return condCodes.v; 190 } 191 panic("Tried testing condition nonexistant " 192 "condition code %d", condition); 193 } 194}}; 195 196