1 // Copyright (c) 2006 The Regents of The University of Michigan
2 // All rights reserved.
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.
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.
31 ////////////////////////////////////////////////////////////////////
33 // Integer operate instructions
38 * Base class for integer operations.
40 class IntOp : public SparcStaticInst
44 IntOp(const char *mnem, ExtMachInst _machInst,
46 SparcStaticInst(mnem, _machInst, __opClass)
50 std::string generateDisassembly(Addr pc,
51 const SymbolTable *symtab) const;
53 virtual bool printPseudoOps(std::ostream &os, Addr pc,
54 const SymbolTable *symtab) const;
58 * Base class for immediate integer operations.
60 class IntOpImm : public IntOp
64 IntOpImm(const char *mnem, ExtMachInst _machInst,
66 IntOp(mnem, _machInst, __opClass)
72 std::string generateDisassembly(Addr pc,
73 const SymbolTable *symtab) const;
75 virtual bool printPseudoOps(std::ostream &os, Addr pc,
76 const SymbolTable *symtab) const;
80 * Base class for 10 bit immediate integer operations.
82 class IntOpImm10 : public IntOpImm
86 IntOpImm10(const char *mnem, ExtMachInst _machInst,
88 IntOpImm(mnem, _machInst, __opClass)
90 imm = sext<10>(SIMM10);
95 * Base class for 11 bit immediate integer operations.
97 class IntOpImm11 : public IntOpImm
101 IntOpImm11(const char *mnem, ExtMachInst _machInst,
103 IntOpImm(mnem, _machInst, __opClass)
105 imm = sext<11>(SIMM11);
110 * Base class for 13 bit immediate integer operations.
112 class IntOpImm13 : public IntOpImm
116 IntOpImm13(const char *mnem, ExtMachInst _machInst,
118 IntOpImm(mnem, _machInst, __opClass)
120 imm = sext<13>(SIMM13);
125 * Base class for sethi.
127 class SetHi : public IntOpImm
131 SetHi(const char *mnem, ExtMachInst _machInst,
133 IntOpImm(mnem, _machInst, __opClass)
135 imm = (IMM22 & 0x3FFFFF) << 10;
138 std::string generateDisassembly(Addr pc,
139 const SymbolTable *symtab) const;
143 def template SetHiDecode {{
145 if(RD == 0 && IMM22 == 0)
146 return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
148 return (SparcStaticInst *)(new %(class_name)s(machInst));
154 bool IntOp::printPseudoOps(std::ostream &os, Addr pc,
155 const SymbolTable *symbab) const
157 if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
159 printMnemonic(os, "mov");
168 bool IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
169 const SymbolTable *symbab) const
171 if(!strcmp(mnemonic, "or"))
173 if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
176 printMnemonic(os, "clr");
179 printMnemonic(os, "mov");
180 ccprintf(os, " 0x%x, ", imm);
187 printMnemonic(os, "mov");
197 std::string IntOp::generateDisassembly(Addr pc,
198 const SymbolTable *symtab) const
200 std::stringstream response;
202 if(printPseudoOps(response, pc, symtab))
203 return response.str();
204 printMnemonic(response, mnemonic);
205 printRegArray(response, _srcRegIdx, _numSrcRegs);
206 if(_numDestRegs && _numSrcRegs)
208 printDestReg(response, 0);
209 return response.str();
212 std::string IntOpImm::generateDisassembly(Addr pc,
213 const SymbolTable *symtab) const
215 std::stringstream response;
217 if(printPseudoOps(response, pc, symtab))
218 return response.str();
219 printMnemonic(response, mnemonic);
220 printRegArray(response, _srcRegIdx, _numSrcRegs);
223 ccprintf(response, "0x%x", imm);
226 printDestReg(response, 0);
227 return response.str();
230 std::string SetHi::generateDisassembly(Addr pc,
231 const SymbolTable *symtab) const
233 std::stringstream response;
235 printMnemonic(response, mnemonic);
236 ccprintf(response, "%%hi(0x%x), ", imm);
237 printDestReg(response, 0);
238 return response.str();
242 def template IntOpExecute {{
243 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
244 Trace::InstRecord *traceData) const
246 Fault fault = NoFault;
252 //Write the resulting state to the execution context
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)
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)
279 decode_block = BasicDecode.subst(iop)
280 return (header_output, decoder_output, exec_output, decode_block)
283 uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
285 _in = (Rd >> 31) & 1;
286 _iz = ((Rd & 0xFFFFFFFF) == 0);
287 _xn = (Rd >> 63) & 1;
289 _iv = %(ivValue)s & 1;
290 _ic = %(icValue)s & 1;
291 _xv = %(xvValue)s & 1;
292 _xc = %(xcValue)s & 1;
294 Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
295 _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
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);
309 // Primary format for integer operate instructions:
310 def format IntOp(code, *opt_flags) {{
315 decode_block) = doIntFormat(code, ccCode,
316 name, Name, opt_flags)
319 // Primary format for integer operate instructions:
320 def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
321 ccCode = calcCcCode % vars()
325 decode_block) = doIntFormat(code, ccCode,
326 name, Name, opt_flags)
329 // Primary format for integer operate instructions:
330 def format IntOpCcRes(code, *opt_flags) {{
331 ccCode = calcCcCode % {"icValue":"0",
338 decode_block) = doIntFormat(code, ccCode,
339 name, Name, opt_flags)
342 def 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)