base.isa revision 2482
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 62def template ROrImmDecode {{ 63 { 64 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 65 : (SparcStaticInst *)(new %(class_name)s(machInst))); 66 } 67}}; 68 69let {{ 70 def splitOutImm(code): 71 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>d{0,2})') 72 rOrImmMatch = matcher.search(code) 73 if (rOrImmMatch == None): 74 return (False, CodeBlock(code), None, '', '') 75 rString = matcher.sub(r'(?P=rNum)', rOrImmMatch.string) 76 iString = matcher.sub(r'(?P=iNum)', rOrImmMatch.string) 77 orig_code = code 78 code = matcher.sub(r'Rs(?P<rNum>)', orig_code) 79 imm_code = matcher.sub('imm', orig_code) 80 return (True, CodeBlock(code), CodeBlock(imm_code), rString, iString) 81}}; 82 83output decoder {{ 84 85 void 86 SparcStaticInst::printReg(std::ostream &os, int reg) const 87 { 88 if (reg < FP_Base_DepTag) { 89 ccprintf(os, "r%d", reg); 90 } 91 else { 92 ccprintf(os, "f%d", reg - FP_Base_DepTag); 93 } 94 } 95 96 std::string SparcStaticInst::generateDisassembly(Addr pc, 97 const SymbolTable *symtab) const 98 { 99 std::stringstream ss; 100 101 ccprintf(ss, "%-10s ", mnemonic); 102 103 // just print the first two source regs... if there's 104 // a third one, it's a read-modify-write dest (Rc), 105 // e.g. for CMOVxx 106 if(_numSrcRegs > 0) 107 { 108 printReg(ss, _srcRegIdx[0]); 109 } 110 if(_numSrcRegs > 1) 111 { 112 ss << ","; 113 printReg(ss, _srcRegIdx[1]); 114 } 115 116 // just print the first dest... if there's a second one, 117 // it's generally implicit 118 if(_numDestRegs > 0) 119 { 120 if(_numSrcRegs > 0) 121 ss << ","; 122 printReg(ss, _destRegIdx[0]); 123 } 124 125 return ss.str(); 126 } 127 128 bool passesCondition(uint32_t codes, uint32_t condition) 129 { 130 CondCodes condCodes; 131 condCodes.bits = codes; 132 switch(condition) 133 { 134 case Always: 135 return true; 136 case Never: 137 return false; 138 case NotEqual: 139 return !condCodes.z; 140 case Equal: 141 return condCodes.z; 142 case Greater: 143 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 144 case LessOrEqual: 145 return condCodes.z | (condCodes.n ^ condCodes.v); 146 case GreaterOrEqual: 147 return !(condCodes.n ^ condCodes.v); 148 case Less: 149 return (condCodes.n ^ condCodes.v); 150 case GreaterUnsigned: 151 return !(condCodes.c | condCodes.z); 152 case LessOrEqualUnsigned: 153 return (condCodes.c | condCodes.z); 154 case CarryClear: 155 return !condCodes.c; 156 case CarrySet: 157 return condCodes.c; 158 case Positive: 159 return !condCodes.n; 160 case Negative: 161 return condCodes.n; 162 case OverflowClear: 163 return !condCodes.v; 164 case OverflowSet: 165 return condCodes.v; 166 } 167 panic("Tried testing condition nonexistant " 168 "condition code %d", condition); 169 } 170}}; 171 172