standard.isa (12234:78ece221f9f5) standard.isa (12236:126ac9da6050)
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//
36output header {{
37 /**
38 * Base class for operations that work only on registers
39 */
40 class RegOp : public RiscvStaticInst
41 {
42 protected:
43 /// Constructor
44 RegOp(const char *mnem, MachInst _machInst, OpClass __opClass)
45 : RiscvStaticInst(mnem, _machInst, __opClass)
46 {}
47
48 std::string
49 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
50 };
51
52 /**
53 * Base class for operations with signed immediates
54 */
55 class ImmOp : public RiscvStaticInst
56 {
57 protected:
58 int64_t imm;
59
60 /// Constructor
61 ImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
62 : RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
63 {}
64
65 virtual std::string
66 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
67 };
68
69 /**
70 * Base class for operations with unsigned immediates
71 */
72 class UImmOp : public RiscvStaticInst
73 {
74 protected:
75 uint64_t imm;
76
77 /// Constructor
78 UImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
79 : RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
80 {}
81
82 virtual std::string
83 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
84 };
85
86 /**
87 * Base class for operations with branching
88 */
89 class BranchOp : public ImmOp
90 {
91 protected:
92 /// Constructor
93 BranchOp(const char *mnem, MachInst _machInst, OpClass __opClass)
94 : ImmOp(mnem, _machInst, __opClass)
95 {}
96
97 using StaticInst::branchTarget;
98
99 virtual RiscvISA::PCState
100 branchTarget(ThreadContext *tc) const
101 {
102 return StaticInst::branchTarget(tc);
103 }
104
105 virtual RiscvISA::PCState
106 branchTarget(const RiscvISA::PCState &branchPC) const
107 {
108 return StaticInst::branchTarget(branchPC);
109 }
110
111 virtual std::string
112 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
113 };
114
115 /**
116 * Base class for system operations
117 */
118 class SystemOp : public RiscvStaticInst
119 {
120 public:
121 /// Constructor
122 SystemOp(const char *mnem, MachInst _machInst, OpClass __opClass)
123 : RiscvStaticInst(mnem, _machInst, __opClass)
124 {}
125
126 std::string
127 generateDisassembly(Addr pc, const SymbolTable *symtab) const
128 {
129 return mnemonic;
130 }
131 };
132
133 /**
134 * Base class for CSR operations
135 */
136 class CSROp : public RiscvStaticInst
137 {
138 protected:
139 uint64_t csr;
140 uint64_t uimm;
141
142 public:
143 /// Constructor
144 CSROp(const char *mnem, MachInst _machInst, OpClass __opClass)
145 : RiscvStaticInst(mnem, _machInst, __opClass),
146 csr(FUNCT12), uimm(CSRIMM)
147 {}
148
149 std::string
150 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
151 };
152}};
153
154//Outputs to decoder.cc
155output decoder {{
156 std::string
157 RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
158 {
159 std::stringstream ss;
160 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " <<
161 registerName(_srcRegIdx[0]) << ", " <<
162 registerName(_srcRegIdx[1]);
163 return ss.str();
164 }
165
166 std::string
167 CSROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
168 {
169 std::stringstream ss;
170 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", ";
171 if (_numSrcRegs > 0)
172 ss << registerName(_srcRegIdx[0]) << ", ";
173 ss << MiscRegNames.at(csr);
174 return ss.str();
175 }
176}};
177
178def template ImmDeclare {{
179 //
180 // Static instruction class for "%(mnemonic)s".
181 //
182 class %(class_name)s : public %(base_class)s
183 {
184 public:
185 /// Constructor.
186 %(class_name)s(MachInst machInst);
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//
36output header {{
37 /**
38 * Base class for operations that work only on registers
39 */
40 class RegOp : public RiscvStaticInst
41 {
42 protected:
43 /// Constructor
44 RegOp(const char *mnem, MachInst _machInst, OpClass __opClass)
45 : RiscvStaticInst(mnem, _machInst, __opClass)
46 {}
47
48 std::string
49 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
50 };
51
52 /**
53 * Base class for operations with signed immediates
54 */
55 class ImmOp : public RiscvStaticInst
56 {
57 protected:
58 int64_t imm;
59
60 /// Constructor
61 ImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
62 : RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
63 {}
64
65 virtual std::string
66 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
67 };
68
69 /**
70 * Base class for operations with unsigned immediates
71 */
72 class UImmOp : public RiscvStaticInst
73 {
74 protected:
75 uint64_t imm;
76
77 /// Constructor
78 UImmOp(const char *mnem, MachInst _machInst, OpClass __opClass)
79 : RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
80 {}
81
82 virtual std::string
83 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
84 };
85
86 /**
87 * Base class for operations with branching
88 */
89 class BranchOp : public ImmOp
90 {
91 protected:
92 /// Constructor
93 BranchOp(const char *mnem, MachInst _machInst, OpClass __opClass)
94 : ImmOp(mnem, _machInst, __opClass)
95 {}
96
97 using StaticInst::branchTarget;
98
99 virtual RiscvISA::PCState
100 branchTarget(ThreadContext *tc) const
101 {
102 return StaticInst::branchTarget(tc);
103 }
104
105 virtual RiscvISA::PCState
106 branchTarget(const RiscvISA::PCState &branchPC) const
107 {
108 return StaticInst::branchTarget(branchPC);
109 }
110
111 virtual std::string
112 generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0;
113 };
114
115 /**
116 * Base class for system operations
117 */
118 class SystemOp : public RiscvStaticInst
119 {
120 public:
121 /// Constructor
122 SystemOp(const char *mnem, MachInst _machInst, OpClass __opClass)
123 : RiscvStaticInst(mnem, _machInst, __opClass)
124 {}
125
126 std::string
127 generateDisassembly(Addr pc, const SymbolTable *symtab) const
128 {
129 return mnemonic;
130 }
131 };
132
133 /**
134 * Base class for CSR operations
135 */
136 class CSROp : public RiscvStaticInst
137 {
138 protected:
139 uint64_t csr;
140 uint64_t uimm;
141
142 public:
143 /// Constructor
144 CSROp(const char *mnem, MachInst _machInst, OpClass __opClass)
145 : RiscvStaticInst(mnem, _machInst, __opClass),
146 csr(FUNCT12), uimm(CSRIMM)
147 {}
148
149 std::string
150 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
151 };
152}};
153
154//Outputs to decoder.cc
155output decoder {{
156 std::string
157 RegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
158 {
159 std::stringstream ss;
160 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", " <<
161 registerName(_srcRegIdx[0]) << ", " <<
162 registerName(_srcRegIdx[1]);
163 return ss.str();
164 }
165
166 std::string
167 CSROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
168 {
169 std::stringstream ss;
170 ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", ";
171 if (_numSrcRegs > 0)
172 ss << registerName(_srcRegIdx[0]) << ", ";
173 ss << MiscRegNames.at(csr);
174 return ss.str();
175 }
176}};
177
178def template ImmDeclare {{
179 //
180 // Static instruction class for "%(mnemonic)s".
181 //
182 class %(class_name)s : public %(base_class)s
183 {
184 public:
185 /// Constructor.
186 %(class_name)s(MachInst machInst);
187 %(BasicExecDeclare)s
187 Fault execute(ExecContext *, Trace::InstRecord *) const;
188 std::string generateDisassembly(Addr pc,
189 const SymbolTable *symtab) const override;
190 };
191}};
192
193def template ImmConstructor {{
194 %(class_name)s::%(class_name)s(MachInst machInst)
195 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
196 {
197 %(constructor)s;
198 %(imm_code)s;
199 }
200}};
201
202def template ImmExecute {{
203 Fault
204 %(class_name)s::execute(
205 ExecContext *xc, Trace::InstRecord *traceData) const
206 {
207 Fault fault = NoFault;
208
209 %(op_decl)s;
210 %(op_rd)s;
211 if (fault == NoFault) {
212 %(code)s;
213 if (fault == NoFault) {
214 %(op_wb)s;
215 }
216 }
217 return fault;
218 }
219
220 std::string
221 %(class_name)s::generateDisassembly(Addr pc,
222 const SymbolTable *symtab) const
223 {
224 std::vector<RegId> indices = {%(regs)s};
225 std::stringstream ss;
226 ss << mnemonic << ' ';
227 for (const RegId& idx: indices)
228 ss << registerName(idx) << ", ";
229 ss << imm;
230 return ss.str();
231 }
232}};
233
234def template BranchDeclare {{
235 //
236 // Static instruction class for "%(mnemonic)s".
237 //
238 class %(class_name)s : public %(base_class)s
239 {
240 public:
241 /// Constructor.
242 %(class_name)s(MachInst machInst);
188 std::string generateDisassembly(Addr pc,
189 const SymbolTable *symtab) const override;
190 };
191}};
192
193def template ImmConstructor {{
194 %(class_name)s::%(class_name)s(MachInst machInst)
195 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
196 {
197 %(constructor)s;
198 %(imm_code)s;
199 }
200}};
201
202def template ImmExecute {{
203 Fault
204 %(class_name)s::execute(
205 ExecContext *xc, Trace::InstRecord *traceData) const
206 {
207 Fault fault = NoFault;
208
209 %(op_decl)s;
210 %(op_rd)s;
211 if (fault == NoFault) {
212 %(code)s;
213 if (fault == NoFault) {
214 %(op_wb)s;
215 }
216 }
217 return fault;
218 }
219
220 std::string
221 %(class_name)s::generateDisassembly(Addr pc,
222 const SymbolTable *symtab) const
223 {
224 std::vector<RegId> indices = {%(regs)s};
225 std::stringstream ss;
226 ss << mnemonic << ' ';
227 for (const RegId& idx: indices)
228 ss << registerName(idx) << ", ";
229 ss << imm;
230 return ss.str();
231 }
232}};
233
234def template BranchDeclare {{
235 //
236 // Static instruction class for "%(mnemonic)s".
237 //
238 class %(class_name)s : public %(base_class)s
239 {
240 public:
241 /// Constructor.
242 %(class_name)s(MachInst machInst);
243 %(BasicExecDeclare)s
243 Fault execute(ExecContext *, Trace::InstRecord *) const;
244
245 std::string
246 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
247
248 RiscvISA::PCState
249 branchTarget(const RiscvISA::PCState &branchPC) const override;
250
251 using StaticInst::branchTarget;
252 };
253}};
254
255def template BranchExecute {{
256 Fault
257 %(class_name)s::execute(ExecContext *xc,
258 Trace::InstRecord *traceData) const
259 {
260 Fault fault = NoFault;
261
262 %(op_decl)s;
263 %(op_rd)s;
264 if (fault == NoFault) {
265 %(code)s;
266 if (fault == NoFault) {
267 %(op_wb)s;
268 }
269 }
270 return fault;
271 }
272
273 RiscvISA::PCState
274 %(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
275 {
276 return branchPC.pc() + imm;
277 }
278
279 std::string
280 %(class_name)s::generateDisassembly(Addr pc,
281 const SymbolTable *symtab) const
282 {
283 std::vector<RegId> indices = {%(regs)s};
284 std::stringstream ss;
285 ss << mnemonic << ' ';
286 for (const RegId& idx: indices)
287 ss << registerName(idx) << ", ";
288 ss << imm;
289 return ss.str();
290 }
291}};
292
293def template JumpDeclare {{
294 //
295 // Static instruction class for "%(mnemonic)s".
296 //
297 class %(class_name)s : public %(base_class)s
298 {
299 public:
300 /// Constructor.
301 %(class_name)s(MachInst machInst);
244
245 std::string
246 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
247
248 RiscvISA::PCState
249 branchTarget(const RiscvISA::PCState &branchPC) const override;
250
251 using StaticInst::branchTarget;
252 };
253}};
254
255def template BranchExecute {{
256 Fault
257 %(class_name)s::execute(ExecContext *xc,
258 Trace::InstRecord *traceData) const
259 {
260 Fault fault = NoFault;
261
262 %(op_decl)s;
263 %(op_rd)s;
264 if (fault == NoFault) {
265 %(code)s;
266 if (fault == NoFault) {
267 %(op_wb)s;
268 }
269 }
270 return fault;
271 }
272
273 RiscvISA::PCState
274 %(class_name)s::branchTarget(const RiscvISA::PCState &branchPC) const
275 {
276 return branchPC.pc() + imm;
277 }
278
279 std::string
280 %(class_name)s::generateDisassembly(Addr pc,
281 const SymbolTable *symtab) const
282 {
283 std::vector<RegId> indices = {%(regs)s};
284 std::stringstream ss;
285 ss << mnemonic << ' ';
286 for (const RegId& idx: indices)
287 ss << registerName(idx) << ", ";
288 ss << imm;
289 return ss.str();
290 }
291}};
292
293def template JumpDeclare {{
294 //
295 // Static instruction class for "%(mnemonic)s".
296 //
297 class %(class_name)s : public %(base_class)s
298 {
299 public:
300 /// Constructor.
301 %(class_name)s(MachInst machInst);
302 %(BasicExecDeclare)s
302 Fault execute(ExecContext *, Trace::InstRecord *) const;
303
304 std::string
305 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
306
307 RiscvISA::PCState
308 branchTarget(ThreadContext *tc) const override;
309
310 using StaticInst::branchTarget;
311 };
312}};
313
314def template JumpExecute {{
315 Fault
316 %(class_name)s::execute(
317 ExecContext *xc, Trace::InstRecord *traceData) const
318 {
319 Fault fault = NoFault;
320
321 %(op_decl)s;
322 %(op_rd)s;
323 if (fault == NoFault) {
324 %(code)s;
325 if (fault == NoFault) {
326 %(op_wb)s;
327 }
328 }
329 return fault;
330 }
331
332 RiscvISA::PCState
333 %(class_name)s::branchTarget(ThreadContext *tc) const
334 {
335 PCState pc = tc->pcState();
336 pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
337 return pc;
338 }
339
340 std::string
341 %(class_name)s::generateDisassembly(Addr pc,
342 const SymbolTable *symtab) const
343 {
344 std::vector<RegId> indices = {%(regs)s};
345 std::stringstream ss;
346 ss << mnemonic << ' ';
347 for (const RegId& idx: indices)
348 ss << registerName(idx) << ", ";
349 ss << imm;
350 return ss.str();
351 }
352}};
353
354def format ROp(code, *opt_flags) {{
355 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
356 header_output = BasicDeclare.subst(iop)
357 decoder_output = BasicConstructor.subst(iop)
358 decode_block = BasicDecode.subst(iop)
359 exec_output = BasicExecute.subst(iop)
360}};
361
362def format IOp(code, *opt_flags) {{
363 imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
364 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
365 iop = InstObjParams(name, Name, 'ImmOp',
366 {'code': code, 'imm_code': imm_code,
367 'regs': ','.join(regs)}, opt_flags)
368 header_output = ImmDeclare.subst(iop)
369 decoder_output = ImmConstructor.subst(iop)
370 decode_block = BasicDecode.subst(iop)
371 exec_output = ImmExecute.subst(iop)
372}};
373
374def format BOp(code, *opt_flags) {{
375 imm_code = """
376 imm |= BIMM12BIT11 << 11;
377 imm |= BIMM12BITS4TO1 << 1;
378 imm |= BIMM12BITS10TO5 << 5;
379 if (IMMSIGN > 0)
380 imm |= ~((uint64_t)0xFFF);
381 """
382 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
383 iop = InstObjParams(name, Name, 'BranchOp',
384 {'code': code, 'imm_code': imm_code,
385 'regs': ','.join(regs)}, opt_flags)
386 header_output = BranchDeclare.subst(iop)
387 decoder_output = ImmConstructor.subst(iop)
388 decode_block = BasicDecode.subst(iop)
389 exec_output = BranchExecute.subst(iop)
390}};
391
392def format Jump(code, *opt_flags) {{
393 imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
394 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
395 iop = InstObjParams(name, Name, 'BranchOp',
396 {'code': code, 'imm_code': imm_code,
397 'regs': ','.join(regs)}, opt_flags)
398 header_output = JumpDeclare.subst(iop)
399 decoder_output = ImmConstructor.subst(iop)
400 decode_block = BasicDecode.subst(iop)
401 exec_output = JumpExecute.subst(iop)
402}};
403
404def format UOp(code, *opt_flags) {{
405 imm_code = 'imm = (int32_t)(IMM20 << 12);'
406 regs = ['_destRegIdx[0]']
407 iop = InstObjParams(name, Name, 'ImmOp',
408 {'code': code, 'imm_code': imm_code,
409 'regs': ','.join(regs)}, opt_flags)
410 header_output = ImmDeclare.subst(iop)
411 decoder_output = ImmConstructor.subst(iop)
412 decode_block = BasicDecode.subst(iop)
413 exec_output = ImmExecute.subst(iop)
414}};
415
416def format JOp(code, *opt_flags) {{
417 imm_code = """
418 imm |= UJIMMBITS19TO12 << 12;
419 imm |= UJIMMBIT11 << 11;
420 imm |= UJIMMBITS10TO1 << 1;
421 if (IMMSIGN > 0)
422 imm |= ~((uint64_t)0xFFFFF);
423 """
424 pc = 'pc.set(pc.pc() + imm);'
425 regs = ['_destRegIdx[0]']
426 iop = InstObjParams(name, Name, 'BranchOp',
427 {'code': code, 'imm_code': imm_code,
428 'regs': ','.join(regs)}, opt_flags)
429 header_output = BranchDeclare.subst(iop)
430 decoder_output = ImmConstructor.subst(iop)
431 decode_block = BasicDecode.subst(iop)
432 exec_output = BranchExecute.subst(iop)
433}};
434
435def format SystemOp(code, *opt_flags) {{
436 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
437 header_output = BasicDeclare.subst(iop)
438 decoder_output = BasicConstructor.subst(iop)
439 decode_block = BasicDecode.subst(iop)
440 exec_output = BasicExecute.subst(iop)
441}};
442
443def format CSROp(code, *opt_flags) {{
444 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
445 header_output = BasicDeclare.subst(iop)
446 decoder_output = BasicConstructor.subst(iop)
447 decode_block = BasicDecode.subst(iop)
448 exec_output = BasicExecute.subst(iop)
449}};
303
304 std::string
305 generateDisassembly(Addr pc, const SymbolTable *symtab) const override;
306
307 RiscvISA::PCState
308 branchTarget(ThreadContext *tc) const override;
309
310 using StaticInst::branchTarget;
311 };
312}};
313
314def template JumpExecute {{
315 Fault
316 %(class_name)s::execute(
317 ExecContext *xc, Trace::InstRecord *traceData) const
318 {
319 Fault fault = NoFault;
320
321 %(op_decl)s;
322 %(op_rd)s;
323 if (fault == NoFault) {
324 %(code)s;
325 if (fault == NoFault) {
326 %(op_wb)s;
327 }
328 }
329 return fault;
330 }
331
332 RiscvISA::PCState
333 %(class_name)s::branchTarget(ThreadContext *tc) const
334 {
335 PCState pc = tc->pcState();
336 pc.set((tc->readIntReg(_srcRegIdx[0].index()) + imm)&~0x1);
337 return pc;
338 }
339
340 std::string
341 %(class_name)s::generateDisassembly(Addr pc,
342 const SymbolTable *symtab) const
343 {
344 std::vector<RegId> indices = {%(regs)s};
345 std::stringstream ss;
346 ss << mnemonic << ' ';
347 for (const RegId& idx: indices)
348 ss << registerName(idx) << ", ";
349 ss << imm;
350 return ss.str();
351 }
352}};
353
354def format ROp(code, *opt_flags) {{
355 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
356 header_output = BasicDeclare.subst(iop)
357 decoder_output = BasicConstructor.subst(iop)
358 decode_block = BasicDecode.subst(iop)
359 exec_output = BasicExecute.subst(iop)
360}};
361
362def format IOp(code, *opt_flags) {{
363 imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
364 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
365 iop = InstObjParams(name, Name, 'ImmOp',
366 {'code': code, 'imm_code': imm_code,
367 'regs': ','.join(regs)}, opt_flags)
368 header_output = ImmDeclare.subst(iop)
369 decoder_output = ImmConstructor.subst(iop)
370 decode_block = BasicDecode.subst(iop)
371 exec_output = ImmExecute.subst(iop)
372}};
373
374def format BOp(code, *opt_flags) {{
375 imm_code = """
376 imm |= BIMM12BIT11 << 11;
377 imm |= BIMM12BITS4TO1 << 1;
378 imm |= BIMM12BITS10TO5 << 5;
379 if (IMMSIGN > 0)
380 imm |= ~((uint64_t)0xFFF);
381 """
382 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
383 iop = InstObjParams(name, Name, 'BranchOp',
384 {'code': code, 'imm_code': imm_code,
385 'regs': ','.join(regs)}, opt_flags)
386 header_output = BranchDeclare.subst(iop)
387 decoder_output = ImmConstructor.subst(iop)
388 decode_block = BasicDecode.subst(iop)
389 exec_output = BranchExecute.subst(iop)
390}};
391
392def format Jump(code, *opt_flags) {{
393 imm_code = 'imm = IMM12; if (IMMSIGN > 0) imm |= ~((uint64_t)0x7FF);'
394 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
395 iop = InstObjParams(name, Name, 'BranchOp',
396 {'code': code, 'imm_code': imm_code,
397 'regs': ','.join(regs)}, opt_flags)
398 header_output = JumpDeclare.subst(iop)
399 decoder_output = ImmConstructor.subst(iop)
400 decode_block = BasicDecode.subst(iop)
401 exec_output = JumpExecute.subst(iop)
402}};
403
404def format UOp(code, *opt_flags) {{
405 imm_code = 'imm = (int32_t)(IMM20 << 12);'
406 regs = ['_destRegIdx[0]']
407 iop = InstObjParams(name, Name, 'ImmOp',
408 {'code': code, 'imm_code': imm_code,
409 'regs': ','.join(regs)}, opt_flags)
410 header_output = ImmDeclare.subst(iop)
411 decoder_output = ImmConstructor.subst(iop)
412 decode_block = BasicDecode.subst(iop)
413 exec_output = ImmExecute.subst(iop)
414}};
415
416def format JOp(code, *opt_flags) {{
417 imm_code = """
418 imm |= UJIMMBITS19TO12 << 12;
419 imm |= UJIMMBIT11 << 11;
420 imm |= UJIMMBITS10TO1 << 1;
421 if (IMMSIGN > 0)
422 imm |= ~((uint64_t)0xFFFFF);
423 """
424 pc = 'pc.set(pc.pc() + imm);'
425 regs = ['_destRegIdx[0]']
426 iop = InstObjParams(name, Name, 'BranchOp',
427 {'code': code, 'imm_code': imm_code,
428 'regs': ','.join(regs)}, opt_flags)
429 header_output = BranchDeclare.subst(iop)
430 decoder_output = ImmConstructor.subst(iop)
431 decode_block = BasicDecode.subst(iop)
432 exec_output = BranchExecute.subst(iop)
433}};
434
435def format SystemOp(code, *opt_flags) {{
436 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
437 header_output = BasicDeclare.subst(iop)
438 decoder_output = BasicConstructor.subst(iop)
439 decode_block = BasicDecode.subst(iop)
440 exec_output = BasicExecute.subst(iop)
441}};
442
443def format CSROp(code, *opt_flags) {{
444 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
445 header_output = BasicDeclare.subst(iop)
446 decoder_output = BasicConstructor.subst(iop)
447 decode_block = BasicDecode.subst(iop)
448 exec_output = BasicExecute.subst(iop)
449}};