base,arch,sim,cpu: Move object file loader components into a namespace.
[gem5.git] / src / arch / mips / isa / formats / int.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2007 MIPS Technologies, Inc.
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met: redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer;
10 // redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution;
13 // neither the name of the copyright holders nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 ////////////////////////////////////////////////////////////////////
30 //
31 // Integer operate instructions
32 //
33 output header {{
34 #include <iostream>
35 using namespace std;
36 /**
37 * Base class for integer operations.
38 */
39 class IntOp : public MipsStaticInst
40 {
41 protected:
42 using MipsStaticInst::MipsStaticInst;
43
44 std::string generateDisassembly(
45 Addr pc, const Loader::SymbolTable *symtab) const override;
46 };
47
48
49 class HiLoOp: public IntOp
50 {
51 protected:
52 using IntOp::IntOp;
53
54 std::string generateDisassembly(
55 Addr pc, const Loader::SymbolTable *symtab) const override;
56 };
57
58 class HiLoRsSelOp: public HiLoOp
59 {
60 protected:
61 using HiLoOp::HiLoOp;
62
63 std::string generateDisassembly(
64 Addr pc, const Loader::SymbolTable *symtab) const override;
65 };
66
67 class HiLoRdSelOp: public HiLoOp
68 {
69 protected:
70 using HiLoOp::HiLoOp;
71
72 std::string generateDisassembly(
73 Addr pc, const Loader::SymbolTable *symtab) const override;
74 };
75
76 class HiLoRdSelValOp: public HiLoOp
77 {
78 protected:
79 using HiLoOp::HiLoOp;
80
81 std::string generateDisassembly(
82 Addr pc, const Loader::SymbolTable *symtab) const override;
83 };
84
85 class IntImmOp : public MipsStaticInst
86 {
87 protected:
88 int16_t imm;
89 int32_t sextImm;
90 uint32_t zextImm;
91
92 IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
93 MipsStaticInst(mnem, _machInst, __opClass), imm(INTIMM),
94 sextImm(INTIMM), zextImm(0x0000FFFF & INTIMM)
95 {
96 // If Bit 15 is 1 then sign extend.
97 int32_t temp = sextImm & 0x00008000;
98 if (temp > 0 && strcmp(mnemonic,"lui") != 0) {
99 sextImm |= 0xFFFF0000;
100 }
101 }
102
103 std::string generateDisassembly(
104 Addr pc, const Loader::SymbolTable *symtab) const override;
105 };
106
107 }};
108
109 // HiLo instruction class execute method template.
110 def template HiLoExecute {{
111 Fault
112 %(class_name)s::execute(
113 ExecContext *xc, Trace::InstRecord *traceData) const
114 {
115 Fault fault = NoFault;
116
117 %(fp_enable_check)s;
118 %(op_decl)s;
119 %(op_rd)s;
120 %(code)s;
121
122 if(fault == NoFault) {
123 %(op_wb)s;
124 }
125 return fault;
126 }
127 }};
128
129 // HiLoRsSel instruction class execute method template.
130 def template HiLoRsSelExecute {{
131 Fault
132 %(class_name)s::execute(
133 ExecContext *xc, Trace::InstRecord *traceData) const
134 {
135 Fault fault = NoFault;
136
137 %(op_decl)s;
138
139 if (ACSRC > 0 && !isDspEnabled(xc)) {
140 fault = std::make_shared<DspStateDisabledFault>();
141 } else {
142 %(op_rd)s;
143 %(code)s;
144 }
145
146 if (fault == NoFault) {
147 %(op_wb)s;
148 }
149 return fault;
150 }
151 }};
152
153 // HiLoRdSel instruction class execute method template.
154 def template HiLoRdSelExecute {{
155 Fault
156 %(class_name)s::execute(
157 ExecContext *xc, Trace::InstRecord *traceData) const
158 {
159 Fault fault = NoFault;
160
161 %(op_decl)s;
162
163 if (ACDST > 0 && !isDspEnabled(xc)) {
164 fault = std::make_shared<DspStateDisabledFault>();
165 } else {
166 %(op_rd)s;
167 %(code)s;
168 }
169
170 if (fault == NoFault) {
171 %(op_wb)s;
172 }
173 return fault;
174 }
175 }};
176
177 //Outputs to decoder.cc
178 output decoder {{
179 std::string
180 IntOp::generateDisassembly(
181 Addr pc, const Loader::SymbolTable *symtab) const
182 {
183 std::stringstream ss;
184
185 ccprintf(ss, "%-10s ", mnemonic);
186
187 // just print the first dest... if there's a second one,
188 // it's generally implicit
189 if (_numDestRegs > 0) {
190 printReg(ss, _destRegIdx[0]);
191 ss << ", ";
192 }
193
194 // just print the first two source regs... if there's
195 // a third one, it's a read-modify-write dest (Rc),
196 // e.g. for CMOVxx
197 if (_numSrcRegs > 0) {
198 printReg(ss, _srcRegIdx[0]);
199 }
200
201 if (_numSrcRegs > 1) {
202 ss << ", ";
203 printReg(ss, _srcRegIdx[1]);
204 }
205
206 return ss.str();
207 }
208
209 std::string
210 HiLoOp::generateDisassembly(
211 Addr pc, const Loader::SymbolTable *symtab) const
212 {
213 std::stringstream ss;
214
215 ccprintf(ss, "%-10s ", mnemonic);
216
217 // Destination Registers are implicit for HI/LO ops
218 if (_numSrcRegs > 0) {
219 printReg(ss, _srcRegIdx[0]);
220 }
221
222 if (_numSrcRegs > 1) {
223 ss << ", ";
224 printReg(ss, _srcRegIdx[1]);
225 }
226
227 return ss.str();
228 }
229
230 std::string
231 HiLoRsSelOp::generateDisassembly(
232 Addr pc, const Loader::SymbolTable *symtab) const
233 {
234 std::stringstream ss;
235
236 ccprintf(ss, "%-10s ", mnemonic);
237
238 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
239 printReg(ss, _destRegIdx[0]);
240 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
241 printReg(ss, _srcRegIdx[0]);
242 }
243
244 return ss.str();
245 }
246
247 std::string
248 HiLoRdSelOp::generateDisassembly(
249 Addr pc, const Loader::SymbolTable *symtab) const
250 {
251 std::stringstream ss;
252
253 ccprintf(ss, "%-10s ", mnemonic);
254
255 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
256 printReg(ss, _destRegIdx[0]);
257 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
258 printReg(ss, _srcRegIdx[0]);
259 }
260
261 return ss.str();
262 }
263
264 std::string
265 HiLoRdSelValOp::generateDisassembly(
266 Addr pc, const Loader::SymbolTable *symtab) const
267 {
268 std::stringstream ss;
269
270 ccprintf(ss, "%-10s ", mnemonic);
271
272 if (_numDestRegs > 0 && _destRegIdx[0].index() < 32) {
273 printReg(ss, _destRegIdx[0]);
274 } else if (_numSrcRegs > 0 && _srcRegIdx[0].index() < 32) {
275 printReg(ss, _srcRegIdx[0]);
276 }
277
278 return ss.str();
279 }
280
281 std::string
282 IntImmOp::generateDisassembly(
283 Addr pc, const Loader::SymbolTable *symtab) const
284 {
285 std::stringstream ss;
286
287 ccprintf(ss, "%-10s ", mnemonic);
288
289 if (_numDestRegs > 0) {
290 printReg(ss, _destRegIdx[0]);
291 }
292
293 ss << ", ";
294
295 if (_numSrcRegs > 0) {
296 printReg(ss, _srcRegIdx[0]);
297 ss << ", ";
298 }
299
300 if(strcmp(mnemonic,"lui") == 0)
301 ccprintf(ss, "0x%x ", sextImm);
302 else
303 ss << (int) sextImm;
304
305 return ss.str();
306 }
307
308 }};
309
310 def format IntOp(code, *opt_flags) {{
311 iop = InstObjParams(name, Name, 'IntOp', code, opt_flags)
312 header_output = BasicDeclare.subst(iop)
313 decoder_output = BasicConstructor.subst(iop)
314 decode_block = RegNopCheckDecode.subst(iop)
315 exec_output = BasicExecute.subst(iop)
316 }};
317
318 def format IntImmOp(code, *opt_flags) {{
319 iop = InstObjParams(name, Name, 'IntImmOp', code, opt_flags)
320 header_output = BasicDeclare.subst(iop)
321 decoder_output = BasicConstructor.subst(iop)
322 decode_block = ImmNopCheckDecode.subst(iop)
323 exec_output = BasicExecute.subst(iop)
324 }};
325
326 def format HiLoRsSelOp(code, *opt_flags) {{
327 iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
328 header_output = BasicDeclare.subst(iop)
329 decoder_output = BasicConstructor.subst(iop)
330 decode_block = BasicDecode.subst(iop)
331 exec_output = HiLoRsSelExecute.subst(iop)
332 }};
333
334 def format HiLoRdSelOp(code, *opt_flags) {{
335 iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
336 header_output = BasicDeclare.subst(iop)
337 decoder_output = BasicConstructor.subst(iop)
338 decode_block = BasicDecode.subst(iop)
339 exec_output = HiLoRdSelExecute.subst(iop)
340 }};
341
342 def format HiLoRdSelValOp(code, *opt_flags) {{
343
344 if '_sd' in code:
345 code = 'int64_t ' + code
346 elif '_ud' in code:
347 code = 'uint64_t ' + code
348
349 code += 'HI_RD_SEL = val<63:32>;\n'
350 code += 'LO_RD_SEL = val<31:0>;\n'
351
352 iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
353 header_output = BasicDeclare.subst(iop)
354 decoder_output = BasicConstructor.subst(iop)
355 decode_block = BasicDecode.subst(iop)
356 exec_output = HiLoRdSelExecute.subst(iop)
357 }};
358
359 def format HiLoOp(code, *opt_flags) {{
360 iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
361 header_output = BasicDeclare.subst(iop)
362 decoder_output = BasicConstructor.subst(iop)
363 decode_block = BasicDecode.subst(iop)
364 exec_output = HiLoExecute.subst(iop)
365 }};