Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/newmem
[gem5.git] / src / arch / sparc / isa / formats / integerop.isa
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
36 output 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 int64_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 = sext<10>(SIMM10);
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 = sext<11>(SIMM11);
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 = sext<13>(SIMM13);
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 & 0x3FFFFF) << 10;
136 }
137
138 std::string generateDisassembly(Addr pc,
139 const SymbolTable *symtab) const;
140 };
141 }};
142
143 def 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
152 output 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 printSrcReg(os, 1);
161 ccprintf(os, ", ");
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 {
173 if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
174 {
175 if(imm == 0)
176 printMnemonic(os, "clr");
177 else
178 {
179 printMnemonic(os, "mov");
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");
188 printSrcReg(os, 0);
189 ccprintf(os, ", ");
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
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
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);
236 ccprintf(response, "%%hi(0x%x), ", imm);
237 printDestReg(response, 0);
238 return response.str();
239 }
240 }};
241
242 def 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
262 let {{
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 = '''
283 uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
284
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
294 Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
295 _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
296
297
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:
310 def 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:
320 def 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:
330 def 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
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)
349 }};
350