1// Copyright (c) 2006 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// Base class for sparc instructions, and some support functions 34// 35 36output header {{ 37 38 union CondCodes 39 { 40 struct 41 { 42 uint8_t c:1; 43 uint8_t v:1; 44 uint8_t z:1; 45 uint8_t n:1; 46 }; 47 uint32_t bits; 48 }; 49 50 enum CondTest 51 { 52 Always=0x8, 53 Never=0x0, 54 NotEqual=0x9, 55 Equal=0x1, 56 Greater=0xA, 57 LessOrEqual=0x2, 58 GreaterOrEqual=0xB, 59 Less=0x3, 60 GreaterUnsigned=0xC, 61 LessOrEqualUnsigned=0x4, 62 CarryClear=0xD, 63 CarrySet=0x5, 64 Positive=0xE, 65 Negative=0x6, 66 OverflowClear=0xF, 67 OverflowSet=0x7 68 }; 69 70 extern char * CondTestAbbrev[]; 71 72 /** 73 * Base class for all SPARC static instructions. 74 */ 75 class SparcStaticInst : public StaticInst 76 { 77 protected: 78 // Constructor. 79 SparcStaticInst(const char *mnem, 80 MachInst _machInst, OpClass __opClass) 81 : StaticInst(mnem, _machInst, __opClass) 82 { 83 } 84 85 std::string generateDisassembly(Addr pc, 86 const SymbolTable *symtab) const; 87
| 1// Copyright (c) 2006 The Regents of The University of Michigan 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the 10// documentation and/or other materials provided with the distribution; 11// neither the name of the copyright holders nor the names of its 12// contributors may be used to endorse or promote products derived from 13// this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26// 27// Authors: Ali Saidi 28// Gabe Black 29// Steve Reinhardt 30 31//////////////////////////////////////////////////////////////////// 32// 33// Base class for sparc instructions, and some support functions 34// 35 36output header {{ 37 38 union CondCodes 39 { 40 struct 41 { 42 uint8_t c:1; 43 uint8_t v:1; 44 uint8_t z:1; 45 uint8_t n:1; 46 }; 47 uint32_t bits; 48 }; 49 50 enum CondTest 51 { 52 Always=0x8, 53 Never=0x0, 54 NotEqual=0x9, 55 Equal=0x1, 56 Greater=0xA, 57 LessOrEqual=0x2, 58 GreaterOrEqual=0xB, 59 Less=0x3, 60 GreaterUnsigned=0xC, 61 LessOrEqualUnsigned=0x4, 62 CarryClear=0xD, 63 CarrySet=0x5, 64 Positive=0xE, 65 Negative=0x6, 66 OverflowClear=0xF, 67 OverflowSet=0x7 68 }; 69 70 extern char * CondTestAbbrev[]; 71 72 /** 73 * Base class for all SPARC static instructions. 74 */ 75 class SparcStaticInst : public StaticInst 76 { 77 protected: 78 // Constructor. 79 SparcStaticInst(const char *mnem, 80 MachInst _machInst, OpClass __opClass) 81 : StaticInst(mnem, _machInst, __opClass) 82 { 83 } 84 85 std::string generateDisassembly(Addr pc, 86 const SymbolTable *symtab) const; 87
|
88 void printReg(std::ostream &os, int reg) const;
| 88 void printReg(std::ostream &os, RegIndex reg) const; 89 void printSrcReg(std::ostream &os, int reg) const; 90 void printDestReg(std::ostream &os, int reg) const; 91 92 void printRegArray(std::ostream &os, 93 const RegIndex indexArray[], int num) const;
|
89 }; 90 91 bool passesCondition(uint32_t codes, uint32_t condition); 92 93 inline int64_t sign_ext(uint64_t data, int origWidth) 94 { 95 int shiftAmount = 64 - origWidth; 96 return (((int64_t)data) << shiftAmount) >> shiftAmount; 97 } 98}}; 99 100output decoder {{ 101 102 char * CondTestAbbrev[] = 103 { 104 "nev", //Never 105 "e", //Equal 106 "le", //Less or Equal 107 "l", //Less 108 "leu", //Less or Equal Unsigned 109 "c", //Carry set 110 "n", //Negative 111 "o", //Overflow set 112 "a", //Always 113 "ne", //Not Equal 114 "g", //Greater 115 "ge", //Greater or Equal 116 "gu", //Greater Unsigned 117 "cc", //Carry clear 118 "p", //Positive 119 "oc" //Overflow Clear 120 }; 121}}; 122 123def template ROrImmDecode {{ 124 { 125 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 126 : (SparcStaticInst *)(new %(class_name)s(machInst))); 127 } 128}}; 129 130let {{ 131 def splitOutImm(code): 132 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 133 rOrImmMatch = matcher.search(code) 134 if (rOrImmMatch == None): 135 return (False, code, '', '', '') 136 rString = rOrImmMatch.group("rNum") 137 if (rOrImmMatch.group("typeQual") != None): 138 rString += rOrImmMatch.group("typeQual") 139 iString = rOrImmMatch.group("iNum") 140 orig_code = code 141 code = matcher.sub('Rs' + rString, orig_code) 142 imm_code = matcher.sub('imm', orig_code) 143 return (True, code, imm_code, rString, iString) 144}}; 145 146output decoder {{ 147 148 inline void printMnemonic(std::ostream &os, const char * mnemonic) 149 { 150 ccprintf(os, "\t%s ", mnemonic); 151 } 152
| 94 }; 95 96 bool passesCondition(uint32_t codes, uint32_t condition); 97 98 inline int64_t sign_ext(uint64_t data, int origWidth) 99 { 100 int shiftAmount = 64 - origWidth; 101 return (((int64_t)data) << shiftAmount) >> shiftAmount; 102 } 103}}; 104 105output decoder {{ 106 107 char * CondTestAbbrev[] = 108 { 109 "nev", //Never 110 "e", //Equal 111 "le", //Less or Equal 112 "l", //Less 113 "leu", //Less or Equal Unsigned 114 "c", //Carry set 115 "n", //Negative 116 "o", //Overflow set 117 "a", //Always 118 "ne", //Not Equal 119 "g", //Greater 120 "ge", //Greater or Equal 121 "gu", //Greater Unsigned 122 "cc", //Carry clear 123 "p", //Positive 124 "oc" //Overflow Clear 125 }; 126}}; 127 128def template ROrImmDecode {{ 129 { 130 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst)) 131 : (SparcStaticInst *)(new %(class_name)s(machInst))); 132 } 133}}; 134 135let {{ 136 def splitOutImm(code): 137 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?') 138 rOrImmMatch = matcher.search(code) 139 if (rOrImmMatch == None): 140 return (False, code, '', '', '') 141 rString = rOrImmMatch.group("rNum") 142 if (rOrImmMatch.group("typeQual") != None): 143 rString += rOrImmMatch.group("typeQual") 144 iString = rOrImmMatch.group("iNum") 145 orig_code = code 146 code = matcher.sub('Rs' + rString, orig_code) 147 imm_code = matcher.sub('imm', orig_code) 148 return (True, code, imm_code, rString, iString) 149}}; 150 151output decoder {{ 152 153 inline void printMnemonic(std::ostream &os, const char * mnemonic) 154 { 155 ccprintf(os, "\t%s ", mnemonic); 156 } 157
|
| 158 void SparcStaticInst::printRegArray(std::ostream &os, 159 const RegIndex indexArray[], int num) const 160 { 161 if(num <= 0) 162 return; 163 printReg(os, indexArray[0]); 164 for(int x = 1; x < num; x++) 165 { 166 os << ", "; 167 printReg(os, indexArray[x]); 168 } 169 } 170
|
153 void
| 171 void
|
154 SparcStaticInst::printReg(std::ostream &os, int reg) const
| 172 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
|
155 {
| 173 {
|
| 174 if(_numSrcRegs > reg) 175 printReg(os, _srcRegIdx[reg]); 176 } 177 178 void 179 SparcStaticInst::printDestReg(std::ostream &os, int reg) const 180 { 181 if(_numDestRegs > reg) 182 printReg(os, _destRegIdx[reg]); 183 } 184 185 void 186 SparcStaticInst::printReg(std::ostream &os, RegIndex reg) const 187 {
|
156 const int MaxGlobal = 8; 157 const int MaxOutput = 16; 158 const int MaxLocal = 24; 159 const int MaxInput = 32; 160 if (reg == FramePointerReg) 161 ccprintf(os, "%%fp"); 162 else if (reg == StackPointerReg) 163 ccprintf(os, "%%sp"); 164 else if(reg < MaxGlobal) 165 ccprintf(os, "%%g%d", reg); 166 else if(reg < MaxOutput) 167 ccprintf(os, "%%o%d", reg - MaxGlobal); 168 else if(reg < MaxLocal) 169 ccprintf(os, "%%l%d", reg - MaxOutput); 170 else if(reg < MaxInput) 171 ccprintf(os, "%%i%d", reg - MaxLocal); 172 else { 173 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 174 } 175 } 176 177 std::string SparcStaticInst::generateDisassembly(Addr pc, 178 const SymbolTable *symtab) const 179 { 180 std::stringstream ss; 181 182 printMnemonic(ss, mnemonic); 183 184 // just print the first two source regs... if there's 185 // a third one, it's a read-modify-write dest (Rc), 186 // e.g. for CMOVxx 187 if(_numSrcRegs > 0) 188 { 189 printReg(ss, _srcRegIdx[0]); 190 } 191 if(_numSrcRegs > 1) 192 { 193 ss << ","; 194 printReg(ss, _srcRegIdx[1]); 195 } 196 197 // just print the first dest... if there's a second one, 198 // it's generally implicit 199 if(_numDestRegs > 0) 200 { 201 if(_numSrcRegs > 0) 202 ss << ","; 203 printReg(ss, _destRegIdx[0]); 204 } 205 206 return ss.str(); 207 } 208 209 bool passesCondition(uint32_t codes, uint32_t condition) 210 { 211 CondCodes condCodes; 212 condCodes.bits = codes; 213 switch(condition) 214 { 215 case Always: 216 return true; 217 case Never: 218 return false; 219 case NotEqual: 220 return !condCodes.z; 221 case Equal: 222 return condCodes.z; 223 case Greater: 224 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 225 case LessOrEqual: 226 return condCodes.z | (condCodes.n ^ condCodes.v); 227 case GreaterOrEqual: 228 return !(condCodes.n ^ condCodes.v); 229 case Less: 230 return (condCodes.n ^ condCodes.v); 231 case GreaterUnsigned: 232 return !(condCodes.c | condCodes.z); 233 case LessOrEqualUnsigned: 234 return (condCodes.c | condCodes.z); 235 case CarryClear: 236 return !condCodes.c; 237 case CarrySet: 238 return condCodes.c; 239 case Positive: 240 return !condCodes.n; 241 case Negative: 242 return condCodes.n; 243 case OverflowClear: 244 return !condCodes.v; 245 case OverflowSet: 246 return condCodes.v; 247 } 248 panic("Tried testing condition nonexistant " 249 "condition code %d", condition); 250 } 251}}; 252
| 188 const int MaxGlobal = 8; 189 const int MaxOutput = 16; 190 const int MaxLocal = 24; 191 const int MaxInput = 32; 192 if (reg == FramePointerReg) 193 ccprintf(os, "%%fp"); 194 else if (reg == StackPointerReg) 195 ccprintf(os, "%%sp"); 196 else if(reg < MaxGlobal) 197 ccprintf(os, "%%g%d", reg); 198 else if(reg < MaxOutput) 199 ccprintf(os, "%%o%d", reg - MaxGlobal); 200 else if(reg < MaxLocal) 201 ccprintf(os, "%%l%d", reg - MaxOutput); 202 else if(reg < MaxInput) 203 ccprintf(os, "%%i%d", reg - MaxLocal); 204 else { 205 ccprintf(os, "%%f%d", reg - FP_Base_DepTag); 206 } 207 } 208 209 std::string SparcStaticInst::generateDisassembly(Addr pc, 210 const SymbolTable *symtab) const 211 { 212 std::stringstream ss; 213 214 printMnemonic(ss, mnemonic); 215 216 // just print the first two source regs... if there's 217 // a third one, it's a read-modify-write dest (Rc), 218 // e.g. for CMOVxx 219 if(_numSrcRegs > 0) 220 { 221 printReg(ss, _srcRegIdx[0]); 222 } 223 if(_numSrcRegs > 1) 224 { 225 ss << ","; 226 printReg(ss, _srcRegIdx[1]); 227 } 228 229 // just print the first dest... if there's a second one, 230 // it's generally implicit 231 if(_numDestRegs > 0) 232 { 233 if(_numSrcRegs > 0) 234 ss << ","; 235 printReg(ss, _destRegIdx[0]); 236 } 237 238 return ss.str(); 239 } 240 241 bool passesCondition(uint32_t codes, uint32_t condition) 242 { 243 CondCodes condCodes; 244 condCodes.bits = codes; 245 switch(condition) 246 { 247 case Always: 248 return true; 249 case Never: 250 return false; 251 case NotEqual: 252 return !condCodes.z; 253 case Equal: 254 return condCodes.z; 255 case Greater: 256 return !(condCodes.z | (condCodes.n ^ condCodes.v)); 257 case LessOrEqual: 258 return condCodes.z | (condCodes.n ^ condCodes.v); 259 case GreaterOrEqual: 260 return !(condCodes.n ^ condCodes.v); 261 case Less: 262 return (condCodes.n ^ condCodes.v); 263 case GreaterUnsigned: 264 return !(condCodes.c | condCodes.z); 265 case LessOrEqualUnsigned: 266 return (condCodes.c | condCodes.z); 267 case CarryClear: 268 return !condCodes.c; 269 case CarrySet: 270 return condCodes.c; 271 case Positive: 272 return !condCodes.n; 273 case Negative: 274 return condCodes.n; 275 case OverflowClear: 276 return !condCodes.v; 277 case OverflowSet: 278 return condCodes.v; 279 } 280 panic("Tried testing condition nonexistant " 281 "condition code %d", condition); 282 } 283}}; 284
|