standard.isa (13548:b76f99d052bb) standard.isa (13612:12ae022f3a30)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016-2017 The University of Virginia
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// Integer instructions
35//
36
37def template ImmDeclare {{
38 //
39 // Static instruction class for "%(mnemonic)s".
40 //
41 class %(class_name)s : public %(base_class)s
42 {
43 public:
44 /// Constructor.
45 %(class_name)s(MachInst machInst);
46 Fault execute(ExecContext *, Trace::InstRecord *) const override;
47 std::string generateDisassembly(Addr pc,
48 const SymbolTable *symtab) const override;
49 };
50}};
51
52def template ImmConstructor {{
53 %(class_name)s::%(class_name)s(MachInst machInst)
54 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
55 {
56 %(constructor)s;
57 %(imm_code)s;
58 }
59}};
60
61def template ImmExecute {{
62 Fault
63 %(class_name)s::execute(
64 ExecContext *xc, Trace::InstRecord *traceData) const
65 {
66 Fault fault = NoFault;
67
68 %(op_decl)s;
69 %(op_rd)s;
70 if (fault == NoFault) {
71 %(code)s;
72 if (fault == NoFault) {
73 %(op_wb)s;
74 }
75 }
76 return fault;
77 }
78
79 std::string
80 %(class_name)s::generateDisassembly(Addr pc,
81 const SymbolTable *symtab) const
82 {
83 std::vector<RegId> indices = {%(regs)s};
84 std::stringstream ss;
85 ss << mnemonic << ' ';
86 for (const RegId& idx: indices)
87 ss << registerName(idx) << ", ";
88 ss << imm;
89 return ss.str();
90 }
91}};
92
93def template BranchDeclare {{
94 //
95 // Static instruction class for "%(mnemonic)s".
96 //
97 class %(class_name)s : public %(base_class)s
98 {
99 public:
100 /// Constructor.
101 %(class_name)s(MachInst machInst);
102 Fault execute(ExecContext *, Trace::InstRecord *) const override;
103
104 std::string
105 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
106
107 RiscvISA::PCState
108 branchTarget(const RiscvISA::PCState &branchPC) const override;
109
110 using StaticInst::branchTarget;
111 };
112}};
113
114def template BranchExecute {{
115 Fault
116 %(class_name)s::execute(ExecContext *xc,
117 Trace::InstRecord *traceData) const
118 {
119 Fault fault = NoFault;
120
121 %(op_decl)s;
122 %(op_rd)s;
123 if (fault == NoFault) {
124 %(code)s;
125 if (fault == NoFault) {
126 %(op_wb)s;
127 }
128 }
129 return fault;
130 }
131
132 RiscvISA::PCState
133 %(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
134 {
135 return branchPC.pc() + imm;
136 }
137
138 std::string
139 %(class_name)s::generateDisassembly(Addr pc,
140 const SymbolTable *symtab) const
141 {
142 std::vector<RegId> indices = {%(regs)s};
143 std::stringstream ss;
144 ss << mnemonic << ' ';
145 for (const RegId& idx: indices)
146 ss << registerName(idx) << ", ";
147 ss << imm;
148 return ss.str();
149 }
150}};
151
152def template JumpDeclare {{
153 //
154 // Static instruction class for "%(mnemonic)s".
155 //
156 class %(class_name)s : public %(base_class)s
157 {
158 public:
159 /// Constructor.
160 %(class_name)s(MachInst machInst);
161 Fault execute(ExecContext *, Trace::InstRecord *) const override;
162
163 std::string
164 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
165
166 RiscvISA::PCState
167 branchTarget(ThreadContext *tc) const override;
168
169 using StaticInst::branchTarget;
170 };
171}};
172
173def template JumpExecute {{
174 Fault
175 %(class_name)s::execute(
176 ExecContext *xc, Trace::InstRecord *traceData) const
177 {
178 Fault fault = NoFault;
179
180 %(op_decl)s;
181 %(op_rd)s;
182 if (fault == NoFault) {
183 %(code)s;
184 if (fault == NoFault) {
185 %(op_wb)s;
186 }
187 }
188 return fault;
189 }
190
191 RiscvISA::PCState
192 %(class_name)s::branchTarget(ThreadContext *tc) const
193 {
194 PCState pc = tc->pcState();
195 pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
196 return pc;
197 }
198
199 std::string
200 %(class_name)s::generateDisassembly(Addr pc,
201 const SymbolTable *symtab) const
202 {
203 std::vector<RegId> indices = {%(regs)s};
204 std::stringstream ss;
205 ss << mnemonic << ' ';
206 for (const RegId& idx: indices)
207 ss << registerName(idx) << ", ";
208 ss << imm;
209 return ss.str();
210 }
211}};
212
213def template CSRExecute {{
214 Fault
215 %(class_name)s::execute(ExecContext *xc,
216 Trace::InstRecord *traceData) const
217 {
218 Fault fault = NoFault;
219
220 %(op_decl)s;
221 %(op_rd)s;
222
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2016-2017 The University of Virginia
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met: redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer;
11// redistributions in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution;
14// neither the name of the copyright holders nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Authors: Alec Roelke
31
32////////////////////////////////////////////////////////////////////
33//
34// Integer instructions
35//
36
37def template ImmDeclare {{
38 //
39 // Static instruction class for "%(mnemonic)s".
40 //
41 class %(class_name)s : public %(base_class)s
42 {
43 public:
44 /// Constructor.
45 %(class_name)s(MachInst machInst);
46 Fault execute(ExecContext *, Trace::InstRecord *) const override;
47 std::string generateDisassembly(Addr pc,
48 const SymbolTable *symtab) const override;
49 };
50}};
51
52def template ImmConstructor {{
53 %(class_name)s::%(class_name)s(MachInst machInst)
54 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
55 {
56 %(constructor)s;
57 %(imm_code)s;
58 }
59}};
60
61def template ImmExecute {{
62 Fault
63 %(class_name)s::execute(
64 ExecContext *xc, Trace::InstRecord *traceData) const
65 {
66 Fault fault = NoFault;
67
68 %(op_decl)s;
69 %(op_rd)s;
70 if (fault == NoFault) {
71 %(code)s;
72 if (fault == NoFault) {
73 %(op_wb)s;
74 }
75 }
76 return fault;
77 }
78
79 std::string
80 %(class_name)s::generateDisassembly(Addr pc,
81 const SymbolTable *symtab) const
82 {
83 std::vector<RegId> indices = {%(regs)s};
84 std::stringstream ss;
85 ss << mnemonic << ' ';
86 for (const RegId& idx: indices)
87 ss << registerName(idx) << ", ";
88 ss << imm;
89 return ss.str();
90 }
91}};
92
93def template BranchDeclare {{
94 //
95 // Static instruction class for "%(mnemonic)s".
96 //
97 class %(class_name)s : public %(base_class)s
98 {
99 public:
100 /// Constructor.
101 %(class_name)s(MachInst machInst);
102 Fault execute(ExecContext *, Trace::InstRecord *) const override;
103
104 std::string
105 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
106
107 RiscvISA::PCState
108 branchTarget(const RiscvISA::PCState &branchPC) const override;
109
110 using StaticInst::branchTarget;
111 };
112}};
113
114def template BranchExecute {{
115 Fault
116 %(class_name)s::execute(ExecContext *xc,
117 Trace::InstRecord *traceData) const
118 {
119 Fault fault = NoFault;
120
121 %(op_decl)s;
122 %(op_rd)s;
123 if (fault == NoFault) {
124 %(code)s;
125 if (fault == NoFault) {
126 %(op_wb)s;
127 }
128 }
129 return fault;
130 }
131
132 RiscvISA::PCState
133 %(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
134 {
135 return branchPC.pc() + imm;
136 }
137
138 std::string
139 %(class_name)s::generateDisassembly(Addr pc,
140 const SymbolTable *symtab) const
141 {
142 std::vector<RegId> indices = {%(regs)s};
143 std::stringstream ss;
144 ss << mnemonic << ' ';
145 for (const RegId& idx: indices)
146 ss << registerName(idx) << ", ";
147 ss << imm;
148 return ss.str();
149 }
150}};
151
152def template JumpDeclare {{
153 //
154 // Static instruction class for "%(mnemonic)s".
155 //
156 class %(class_name)s : public %(base_class)s
157 {
158 public:
159 /// Constructor.
160 %(class_name)s(MachInst machInst);
161 Fault execute(ExecContext *, Trace::InstRecord *) const override;
162
163 std::string
164 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
165
166 RiscvISA::PCState
167 branchTarget(ThreadContext *tc) const override;
168
169 using StaticInst::branchTarget;
170 };
171}};
172
173def template JumpExecute {{
174 Fault
175 %(class_name)s::execute(
176 ExecContext *xc, Trace::InstRecord *traceData) const
177 {
178 Fault fault = NoFault;
179
180 %(op_decl)s;
181 %(op_rd)s;
182 if (fault == NoFault) {
183 %(code)s;
184 if (fault == NoFault) {
185 %(op_wb)s;
186 }
187 }
188 return fault;
189 }
190
191 RiscvISA::PCState
192 %(class_name)s::branchTarget(ThreadContext *tc) const
193 {
194 PCState pc = tc->pcState();
195 pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
196 return pc;
197 }
198
199 std::string
200 %(class_name)s::generateDisassembly(Addr pc,
201 const SymbolTable *symtab) const
202 {
203 std::vector<RegId> indices = {%(regs)s};
204 std::stringstream ss;
205 ss << mnemonic << ' ';
206 for (const RegId& idx: indices)
207 ss << registerName(idx) << ", ";
208 ss << imm;
209 return ss.str();
210 }
211}};
212
213def template CSRExecute {{
214 Fault
215 %(class_name)s::execute(ExecContext *xc,
216 Trace::InstRecord *traceData) const
217 {
218 Fault fault = NoFault;
219
220 %(op_decl)s;
221 %(op_rd)s;
222
223 MiscReg data, olddata;
223 RegVal data, olddata;
224 switch (csr) {
225 case CSR_FCSR:
226 olddata = xc->readMiscReg(MISCREG_FFLAGS) |
227 (xc->readMiscReg(MISCREG_FRM) << FRM_OFFSET);
228 break;
229 default:
230 if (CSRData.find(csr) != CSRData.end()) {
231 olddata = xc->readMiscReg(CSRData.at(csr).physIndex);
232 } else {
233 std::string error = csprintf("Illegal CSR index %#x\n", csr);
234 fault = make_shared<IllegalInstFault>(error, machInst);
235 olddata = 0;
236 }
237 break;
238 }
239 auto mask = CSRMasks.find(csr);
240 if (mask != CSRMasks.end())
241 olddata &= mask->second;
242 DPRINTF(RiscvMisc, "Reading CSR %s: %#x\n", CSRData.at(csr).name,
243 olddata);
244 data = olddata;
245
246 if (fault == NoFault) {
247 %(code)s;
248 if (fault == NoFault) {
249 if (mask != CSRMasks.end())
250 data &= mask->second;
251 if (data != olddata) {
252 if (bits(csr, 11, 10) == 0x3) {
253 std::string error = csprintf("CSR %s is read-only\n",
254 CSRData.at(csr).name);
255 fault = make_shared<IllegalInstFault>(error, machInst);
256 } else {
257 DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data,
258 CSRData.at(csr).name);
259 INTERRUPT oldinterrupt = olddata;
260 INTERRUPT newinterrupt = data;
261 switch (csr) {
262 case CSR_FCSR:
263 xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0));
264 xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5));
265 break;
266 case CSR_MIP: case CSR_MIE:
267 if (oldinterrupt.mei == newinterrupt.mei &&
268 oldinterrupt.mti == newinterrupt.mti &&
269 oldinterrupt.msi == newinterrupt.msi) {
270 xc->setMiscReg(CSRData.at(csr).physIndex,data);
271 } else {
272 std::string error = "Interrupt m bits are "
273 "read-only\n";
274 fault = make_shared<IllegalInstFault>(error,
275 machInst);
276 }
277 break;
278 default:
279 xc->setMiscReg(CSRData.at(csr).physIndex, data);
280 break;
281 }
282 }
283 }
284 }
285 if (fault == NoFault) {
286 %(op_wb)s;
287 }
288 }
289 return fault;
290 }
291}};
292
293def format ROp(code, *opt_flags) {{
294 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
295 header_output = BasicDeclare.subst(iop)
296 decoder_output = BasicConstructor.subst(iop)
297 decode_block = BasicDecode.subst(iop)
298 exec_output = BasicExecute.subst(iop)
299}};
300
301def format IOp(code, imm_type='int64_t', *opt_flags) {{
302 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
303 iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
304 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
305 'regs': ','.join(regs)}, opt_flags)
306 header_output = ImmDeclare.subst(iop)
307 decoder_output = ImmConstructor.subst(iop)
308 decode_block = BasicDecode.subst(iop)
309 exec_output = ImmExecute.subst(iop)
310}};
311
312def format BOp(code, *opt_flags) {{
313 imm_code = """
314 imm = BIMM12BITS4TO1 << 1 |
315 BIMM12BITS10TO5 << 5 |
316 BIMM12BIT11 << 11 |
317 IMMSIGN << 12;
318 imm = sext<13>(imm);
319 """
320 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
321 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
322 {'code': code, 'imm_code': imm_code,
323 'regs': ','.join(regs)}, opt_flags)
324 header_output = BranchDeclare.subst(iop)
325 decoder_output = ImmConstructor.subst(iop)
326 decode_block = BasicDecode.subst(iop)
327 exec_output = BranchExecute.subst(iop)
328}};
329
330def format Jump(code, *opt_flags) {{
331 regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
332 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
333 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
334 'regs': ','.join(regs)}, opt_flags)
335 header_output = JumpDeclare.subst(iop)
336 decoder_output = ImmConstructor.subst(iop)
337 decode_block = BasicDecode.subst(iop)
338 exec_output = JumpExecute.subst(iop)
339}};
340
341def format UOp(code, *opt_flags) {{
342 regs = ['_destRegIdx[0]']
343 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
344 {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
345 'regs': ','.join(regs)}, opt_flags)
346 header_output = ImmDeclare.subst(iop)
347 decoder_output = ImmConstructor.subst(iop)
348 decode_block = BasicDecode.subst(iop)
349 exec_output = ImmExecute.subst(iop)
350}};
351
352def format JOp(code, *opt_flags) {{
353 imm_code = """
354 imm = UJIMMBITS10TO1 << 1 |
355 UJIMMBIT11 << 11 |
356 UJIMMBITS19TO12 << 12 |
357 IMMSIGN << 20;
358 imm = sext<21>(imm);
359 """
360 pc = 'pc.set(pc.pc() + imm);'
361 regs = ['_destRegIdx[0]']
362 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
363 {'code': code, 'imm_code': imm_code,
364 'regs': ','.join(regs)}, opt_flags)
365 header_output = BranchDeclare.subst(iop)
366 decoder_output = ImmConstructor.subst(iop)
367 decode_block = BasicDecode.subst(iop)
368 exec_output = BranchExecute.subst(iop)
369}};
370
371def format SystemOp(code, *opt_flags) {{
372 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
373 header_output = BasicDeclare.subst(iop)
374 decoder_output = BasicConstructor.subst(iop)
375 decode_block = BasicDecode.subst(iop)
376 exec_output = BasicExecute.subst(iop)
377}};
378
379def format CSROp(code, *opt_flags) {{
380 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
381 header_output = BasicDeclare.subst(iop)
382 decoder_output = BasicConstructor.subst(iop)
383 decode_block = BasicDecode.subst(iop)
384 exec_output = CSRExecute.subst(iop)
385}};
224 switch (csr) {
225 case CSR_FCSR:
226 olddata = xc->readMiscReg(MISCREG_FFLAGS) |
227 (xc->readMiscReg(MISCREG_FRM) << FRM_OFFSET);
228 break;
229 default:
230 if (CSRData.find(csr) != CSRData.end()) {
231 olddata = xc->readMiscReg(CSRData.at(csr).physIndex);
232 } else {
233 std::string error = csprintf("Illegal CSR index %#x\n", csr);
234 fault = make_shared<IllegalInstFault>(error, machInst);
235 olddata = 0;
236 }
237 break;
238 }
239 auto mask = CSRMasks.find(csr);
240 if (mask != CSRMasks.end())
241 olddata &= mask->second;
242 DPRINTF(RiscvMisc, "Reading CSR %s: %#x\n", CSRData.at(csr).name,
243 olddata);
244 data = olddata;
245
246 if (fault == NoFault) {
247 %(code)s;
248 if (fault == NoFault) {
249 if (mask != CSRMasks.end())
250 data &= mask->second;
251 if (data != olddata) {
252 if (bits(csr, 11, 10) == 0x3) {
253 std::string error = csprintf("CSR %s is read-only\n",
254 CSRData.at(csr).name);
255 fault = make_shared<IllegalInstFault>(error, machInst);
256 } else {
257 DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data,
258 CSRData.at(csr).name);
259 INTERRUPT oldinterrupt = olddata;
260 INTERRUPT newinterrupt = data;
261 switch (csr) {
262 case CSR_FCSR:
263 xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0));
264 xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5));
265 break;
266 case CSR_MIP: case CSR_MIE:
267 if (oldinterrupt.mei == newinterrupt.mei &&
268 oldinterrupt.mti == newinterrupt.mti &&
269 oldinterrupt.msi == newinterrupt.msi) {
270 xc->setMiscReg(CSRData.at(csr).physIndex,data);
271 } else {
272 std::string error = "Interrupt m bits are "
273 "read-only\n";
274 fault = make_shared<IllegalInstFault>(error,
275 machInst);
276 }
277 break;
278 default:
279 xc->setMiscReg(CSRData.at(csr).physIndex, data);
280 break;
281 }
282 }
283 }
284 }
285 if (fault == NoFault) {
286 %(op_wb)s;
287 }
288 }
289 return fault;
290 }
291}};
292
293def format ROp(code, *opt_flags) {{
294 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
295 header_output = BasicDeclare.subst(iop)
296 decoder_output = BasicConstructor.subst(iop)
297 decode_block = BasicDecode.subst(iop)
298 exec_output = BasicExecute.subst(iop)
299}};
300
301def format IOp(code, imm_type='int64_t', *opt_flags) {{
302 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
303 iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
304 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
305 'regs': ','.join(regs)}, opt_flags)
306 header_output = ImmDeclare.subst(iop)
307 decoder_output = ImmConstructor.subst(iop)
308 decode_block = BasicDecode.subst(iop)
309 exec_output = ImmExecute.subst(iop)
310}};
311
312def format BOp(code, *opt_flags) {{
313 imm_code = """
314 imm = BIMM12BITS4TO1 << 1 |
315 BIMM12BITS10TO5 << 5 |
316 BIMM12BIT11 << 11 |
317 IMMSIGN << 12;
318 imm = sext<13>(imm);
319 """
320 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
321 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
322 {'code': code, 'imm_code': imm_code,
323 'regs': ','.join(regs)}, opt_flags)
324 header_output = BranchDeclare.subst(iop)
325 decoder_output = ImmConstructor.subst(iop)
326 decode_block = BasicDecode.subst(iop)
327 exec_output = BranchExecute.subst(iop)
328}};
329
330def format Jump(code, *opt_flags) {{
331 regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
332 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
333 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
334 'regs': ','.join(regs)}, opt_flags)
335 header_output = JumpDeclare.subst(iop)
336 decoder_output = ImmConstructor.subst(iop)
337 decode_block = BasicDecode.subst(iop)
338 exec_output = JumpExecute.subst(iop)
339}};
340
341def format UOp(code, *opt_flags) {{
342 regs = ['_destRegIdx[0]']
343 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
344 {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
345 'regs': ','.join(regs)}, opt_flags)
346 header_output = ImmDeclare.subst(iop)
347 decoder_output = ImmConstructor.subst(iop)
348 decode_block = BasicDecode.subst(iop)
349 exec_output = ImmExecute.subst(iop)
350}};
351
352def format JOp(code, *opt_flags) {{
353 imm_code = """
354 imm = UJIMMBITS10TO1 << 1 |
355 UJIMMBIT11 << 11 |
356 UJIMMBITS19TO12 << 12 |
357 IMMSIGN << 20;
358 imm = sext<21>(imm);
359 """
360 pc = 'pc.set(pc.pc() + imm);'
361 regs = ['_destRegIdx[0]']
362 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
363 {'code': code, 'imm_code': imm_code,
364 'regs': ','.join(regs)}, opt_flags)
365 header_output = BranchDeclare.subst(iop)
366 decoder_output = ImmConstructor.subst(iop)
367 decode_block = BasicDecode.subst(iop)
368 exec_output = BranchExecute.subst(iop)
369}};
370
371def format SystemOp(code, *opt_flags) {{
372 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
373 header_output = BasicDeclare.subst(iop)
374 decoder_output = BasicConstructor.subst(iop)
375 decode_block = BasicDecode.subst(iop)
376 exec_output = BasicExecute.subst(iop)
377}};
378
379def format CSROp(code, *opt_flags) {{
380 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
381 header_output = BasicDeclare.subst(iop)
382 decoder_output = BasicConstructor.subst(iop)
383 decode_block = BasicDecode.subst(iop)
384 exec_output = CSRExecute.subst(iop)
385}};