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// Integer operate instructions 34// 35 36output header {{ 37 /** 38 * Base class for integer operations. 39 */ 40 class IntOp : public SparcStaticInst 41 { 42 protected: 43 // Constructor 44 IntOp(const char *mnem, ExtMachInst _machInst, 45 OpClass __opClass) : 46 SparcStaticInst(mnem, _machInst, __opClass) 47 { 48 } 49 50 std::string generateDisassembly(Addr pc, 51 const SymbolTable *symtab) const; 52 53 virtual bool printPseudoOps(std::ostream &os, Addr pc, 54 const SymbolTable *symtab) const; 55 }; 56 57 /** 58 * Base class for immediate integer operations. 59 */ 60 class IntOpImm : public IntOp 61 { 62 protected: 63 // Constructor 64 IntOpImm(const char *mnem, ExtMachInst _machInst, 65 OpClass __opClass) : 66 IntOp(mnem, _machInst, __opClass) 67 { 68 } 69 70 int32_t imm; 71 72 std::string generateDisassembly(Addr pc, 73 const SymbolTable *symtab) const; 74 75 virtual bool printPseudoOps(std::ostream &os, Addr pc, 76 const SymbolTable *symtab) const; 77 }; 78 79 /** 80 * Base class for 10 bit immediate integer operations. 81 */ 82 class IntOpImm10 : public IntOpImm 83 { 84 protected: 85 // Constructor 86 IntOpImm10(const char *mnem, ExtMachInst _machInst, 87 OpClass __opClass) : 88 IntOpImm(mnem, _machInst, __opClass) 89 { 90 imm = sign_ext(SIMM10, 10); 91 } 92 }; 93 94 /** 95 * Base class for 11 bit immediate integer operations. 96 */ 97 class IntOpImm11 : public IntOpImm 98 { 99 protected: 100 // Constructor 101 IntOpImm11(const char *mnem, ExtMachInst _machInst, 102 OpClass __opClass) : 103 IntOpImm(mnem, _machInst, __opClass) 104 { 105 imm = sign_ext(SIMM11, 11); 106 } 107 }; 108 109 /** 110 * Base class for 13 bit immediate integer operations. 111 */ 112 class IntOpImm13 : public IntOpImm 113 { 114 protected: 115 // Constructor 116 IntOpImm13(const char *mnem, ExtMachInst _machInst, 117 OpClass __opClass) : 118 IntOpImm(mnem, _machInst, __opClass) 119 { 120 imm = sign_ext(SIMM13, 13); 121 } 122 }; 123 124 /** 125 * Base class for sethi. 126 */ 127 class SetHi : public IntOpImm 128 { 129 protected: 130 // Constructor 131 SetHi(const char *mnem, ExtMachInst _machInst, 132 OpClass __opClass) : 133 IntOpImm(mnem, _machInst, __opClass) 134 {
|
135 imm = (IMM22 << 10) & 0xFFFFFC00;
|
135 imm = (IMM22 & 0x3FFFFF) << 10; |
136 } 137 138 std::string generateDisassembly(Addr pc, 139 const SymbolTable *symtab) const; 140 }; 141}}; 142 143def template SetHiDecode {{ 144 { 145 if(RD == 0 && IMM22 == 0) 146 return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass)); 147 else 148 return (SparcStaticInst *)(new %(class_name)s(machInst)); 149 } 150}}; 151 152output decoder {{ 153 154 bool IntOp::printPseudoOps(std::ostream &os, Addr pc, 155 const SymbolTable *symbab) const 156 { 157 if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) 158 { 159 printMnemonic(os, "mov");
|
160 if(_numSrcRegs > 0)
161 printReg(os, _srcRegIdx[1]);
|
160 printSrcReg(os, 1); |
161 ccprintf(os, ", ");
|
163 if(_numDestRegs > 0)
164 printReg(os, _destRegIdx[0]);
165
|
162 printDestReg(os, 0); |
163 return true; 164 } 165 return false; 166 } 167 168 bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc, 169 const SymbolTable *symbab) const 170 { 171 if(!strcmp(mnemonic, "or")) 172 {
|
176 if(_srcRegIdx[0] == 0)
|
173 if(_numSrcRegs > 0 && _srcRegIdx[0] == 0) |
174 { 175 if(imm == 0)
|
179 {
|
176 printMnemonic(os, "clr");
|
181 if(_numDestRegs > 0)
182 printReg(os, _destRegIdx[0]);
183 return true;
184 }
|
177 else 178 { 179 printMnemonic(os, "mov");
|
188 ccprintf(os, ", 0x%x, ", imm);
189 if(_numDestRegs > 0)
190 printReg(os, _destRegIdx[0]);
191 return true;
|
180 ccprintf(os, " 0x%x, ", imm); |
181 }
|
182 printDestReg(os, 0); 183 return true; |
184 } 185 else if(imm == 0) 186 { 187 printMnemonic(os, "mov");
|
197 if(_numSrcRegs > 0)
198 printReg(os, _srcRegIdx[0]);
|
188 printSrcReg(os, 0); |
189 ccprintf(os, ", ");
|
200 if(_numDestRegs > 0)
201 printReg(os, _destRegIdx[0]);
|
190 printDestReg(os, 0); |
191 return true; 192 } 193 } 194 return false; 195 } 196 197 std::string IntOp::generateDisassembly(Addr pc, 198 const SymbolTable *symtab) const 199 { 200 std::stringstream response; 201
|
213 if(!printPseudoOps(response, pc, symtab))
214 {
215 printMnemonic(response, mnemonic);
216 if (_numSrcRegs > 0)
217 {
218 printReg(response, _srcRegIdx[0]);
219 for(int x = 1; x < _numSrcRegs; x++)
220 {
221 response << ", ";
222 printReg(response, _srcRegIdx[x]);
223 }
224 }
225 if (_numDestRegs > 0)
226 {
227 if(_numSrcRegs > 0)
228 response << ", ";
229 printReg(response, _destRegIdx[0]);
230 }
231 }
|
202 if(printPseudoOps(response, pc, symtab)) 203 return response.str(); 204 printMnemonic(response, mnemonic); 205 printRegArray(response, _srcRegIdx, _numSrcRegs); 206 if(_numDestRegs && _numSrcRegs) 207 response << ", "; 208 printDestReg(response, 0); |
209 return response.str(); 210 } 211 212 std::string IntOpImm::generateDisassembly(Addr pc, 213 const SymbolTable *symtab) const 214 { 215 std::stringstream response; 216
|
240 if(!printPseudoOps(response, pc, symtab))
241 {
242 printMnemonic(response, mnemonic);
243 if (_numSrcRegs > 0)
244 {
245 printReg(response, _srcRegIdx[0]);
246 for(int x = 1; x < _numSrcRegs - 1; x++)
247 {
248 response << ", ";
249 printReg(response, _srcRegIdx[x]);
250 }
251 }
252 if(_numSrcRegs > 0)
253 response << ", ";
254 ccprintf(response, "0x%x", imm);
255 if (_numDestRegs > 0)
256 {
257 response << ", ";
258 printReg(response, _destRegIdx[0]);
259 }
260 }
|
217 if(printPseudoOps(response, pc, symtab)) 218 return response.str(); 219 printMnemonic(response, mnemonic); 220 printRegArray(response, _srcRegIdx, _numSrcRegs); 221 if(_numSrcRegs > 0) 222 response << ", "; 223 ccprintf(response, "0x%x", imm); 224 if(_numDestRegs > 0) 225 response << ", "; 226 printDestReg(response, 0); |
227 return response.str(); 228 } 229 230 std::string SetHi::generateDisassembly(Addr pc, 231 const SymbolTable *symtab) const 232 { 233 std::stringstream response; 234 235 printMnemonic(response, mnemonic);
|
270 if(_numSrcRegs > 0)
271 response << ", ";
|
236 ccprintf(response, "%%hi(0x%x), ", imm);
|
273 printReg(response, _destRegIdx[0]);
|
237 printDestReg(response, 0); |
238 return response.str(); 239 } 240}}; 241 242def template IntOpExecute {{ 243 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 244 Trace::InstRecord *traceData) const 245 { 246 Fault fault = NoFault; 247 248 %(op_decl)s; 249 %(op_rd)s; 250 %(code)s; 251 252 //Write the resulting state to the execution context 253 if(fault == NoFault) 254 { 255 %(cc_code)s; 256 %(op_wb)s; 257 } 258 return fault; 259 } 260}}; 261 262let {{ 263 def doIntFormat(code, ccCode, name, Name, opt_flags): 264 (usesImm, code, immCode, 265 rString, iString) = splitOutImm(code) 266 iop = InstObjParams(name, Name, 'IntOp', code, 267 opt_flags, ("cc_code", ccCode)) 268 header_output = BasicDeclare.subst(iop) 269 decoder_output = BasicConstructor.subst(iop) 270 exec_output = IntOpExecute.subst(iop) 271 if usesImm: 272 imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString, 273 immCode, opt_flags, ("cc_code", ccCode)) 274 header_output += BasicDeclare.subst(imm_iop) 275 decoder_output += BasicConstructor.subst(imm_iop) 276 exec_output += IntOpExecute.subst(imm_iop) 277 decode_block = ROrImmDecode.subst(iop) 278 else: 279 decode_block = BasicDecode.subst(iop) 280 return (header_output, decoder_output, exec_output, decode_block) 281 282 calcCcCode = '''
|
319 uint8_t tmp_ccriccc;
320 uint8_t tmp_ccriccv;
321 uint8_t tmp_ccriccz;
322 uint8_t tmp_ccriccn;
323 uint8_t tmp_ccrxccc;
324 uint8_t tmp_ccrxccv;
325 uint8_t tmp_ccrxccz;
326 uint8_t tmp_ccrxccn;
|
283 uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn; |
284
|
328 tmp_ccriccn = (Rd >> 31) & 1;
329 tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0);
330 tmp_ccrxccn = (Rd >> 63) & 1;
331 tmp_ccrxccz = (Rd == 0);
332 tmp_ccriccv = %(ivValue)s & 1;
333 tmp_ccriccc = %(icValue)s & 1;
334 tmp_ccrxccv = %(xvValue)s & 1;
335 tmp_ccrxccc = %(xcValue)s & 1;
|
285 _in = (Rd >> 31) & 1; 286 _iz = ((Rd & 0xFFFFFFFF) == 0); 287 _xn = (Rd >> 63) & 1; 288 _xz = (Rd == 0); 289 _iv = %(ivValue)s & 1; 290 _ic = %(icValue)s & 1; 291 _xv = %(xvValue)s & 1; 292 _xc = %(xcValue)s & 1; |
293
|
337 Ccr = tmp_ccriccc | tmp_ccriccv << 1 |
338 tmp_ccriccz << 2 | tmp_ccriccn << 3|
339 tmp_ccrxccc << 4 | tmp_ccrxccv << 5|
340 tmp_ccrxccz << 6| tmp_ccrxccn << 7;
|
294 Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 | 295 _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7; |
296 297
|
343 DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn);
344 DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz);
345 DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn);
346 DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz);
347 DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv);
348 DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc);
349 DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv);
350 DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc);
|
298 DPRINTF(Sparc, "in = %%d\\n", _in); 299 DPRINTF(Sparc, "iz = %%d\\n", _iz); 300 DPRINTF(Sparc, "xn = %%d\\n", _xn); 301 DPRINTF(Sparc, "xz = %%d\\n", _xz); 302 DPRINTF(Sparc, "iv = %%d\\n", _iv); 303 DPRINTF(Sparc, "ic = %%d\\n", _ic); 304 DPRINTF(Sparc, "xv = %%d\\n", _xv); 305 DPRINTF(Sparc, "xc = %%d\\n", _xc); |
306 ''' 307}}; 308 309// Primary format for integer operate instructions: 310def format IntOp(code, *opt_flags) {{ 311 ccCode = '' 312 (header_output, 313 decoder_output, 314 exec_output, 315 decode_block) = doIntFormat(code, ccCode, 316 name, Name, opt_flags) 317}}; 318 319// Primary format for integer operate instructions: 320def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ 321 ccCode = calcCcCode % vars() 322 (header_output, 323 decoder_output, 324 exec_output, 325 decode_block) = doIntFormat(code, ccCode, 326 name, Name, opt_flags) 327}}; 328 329// Primary format for integer operate instructions: 330def format IntOpCcRes(code, *opt_flags) {{ 331 ccCode = calcCcCode % {"icValue":"0", 332 "ivValue":"0", 333 "xcValue":"0", 334 "xvValue":"0"} 335 (header_output, 336 decoder_output, 337 exec_output, 338 decode_block) = doIntFormat(code, ccCode, 339 name, Name, opt_flags) 340}}; 341 342def format SetHi(code, *opt_flags) {{ 343 iop = InstObjParams(name, Name, 'SetHi', 344 code, opt_flags, ("cc_code", '')) 345 header_output = BasicDeclare.subst(iop) 346 decoder_output = BasicConstructor.subst(iop) 347 exec_output = IntOpExecute.subst(iop) 348 decode_block = SetHiDecode.subst(iop) 349}}; 350
|