standard.isa (12428:ddc6b7179c81) standard.isa (12482:35461496d012)
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);
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;
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);
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;
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);
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;
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 format ROp(code, *opt_flags) {{
214 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
215 header_output = BasicDeclare.subst(iop)
216 decoder_output = BasicConstructor.subst(iop)
217 decode_block = BasicDecode.subst(iop)
218 exec_output = BasicExecute.subst(iop)
219}};
220
221def format IOp(code, imm_type='int64_t', *opt_flags) {{
222 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
223 iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
224 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
225 'regs': ','.join(regs)}, opt_flags)
226 header_output = ImmDeclare.subst(iop)
227 decoder_output = ImmConstructor.subst(iop)
228 decode_block = BasicDecode.subst(iop)
229 exec_output = ImmExecute.subst(iop)
230}};
231
232def format BOp(code, *opt_flags) {{
233 imm_code = """
234 imm = BIMM12BITS4TO1 << 1 |
235 BIMM12BITS10TO5 << 5 |
236 BIMM12BIT11 << 11 |
237 IMMSIGN << 12;
238 imm = sext<13>(imm);
239 """
240 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
241 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
242 {'code': code, 'imm_code': imm_code,
243 'regs': ','.join(regs)}, opt_flags)
244 header_output = BranchDeclare.subst(iop)
245 decoder_output = ImmConstructor.subst(iop)
246 decode_block = BasicDecode.subst(iop)
247 exec_output = BranchExecute.subst(iop)
248}};
249
250def format Jump(code, *opt_flags) {{
251 regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
252 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
253 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
254 'regs': ','.join(regs)}, opt_flags)
255 header_output = JumpDeclare.subst(iop)
256 decoder_output = ImmConstructor.subst(iop)
257 decode_block = BasicDecode.subst(iop)
258 exec_output = JumpExecute.subst(iop)
259}};
260
261def format UOp(code, *opt_flags) {{
262 regs = ['_destRegIdx[0]']
263 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
264 {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
265 'regs': ','.join(regs)}, opt_flags)
266 header_output = ImmDeclare.subst(iop)
267 decoder_output = ImmConstructor.subst(iop)
268 decode_block = BasicDecode.subst(iop)
269 exec_output = ImmExecute.subst(iop)
270}};
271
272def format JOp(code, *opt_flags) {{
273 imm_code = """
274 imm = UJIMMBITS10TO1 << 1 |
275 UJIMMBIT11 << 11 |
276 UJIMMBITS19TO12 << 12 |
277 IMMSIGN << 20;
278 imm = sext<21>(imm);
279 """
280 pc = 'pc.set(pc.pc() + imm);'
281 regs = ['_destRegIdx[0]']
282 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
283 {'code': code, 'imm_code': imm_code,
284 'regs': ','.join(regs)}, opt_flags)
285 header_output = BranchDeclare.subst(iop)
286 decoder_output = ImmConstructor.subst(iop)
287 decode_block = BasicDecode.subst(iop)
288 exec_output = BranchExecute.subst(iop)
289}};
290
291def format SystemOp(code, *opt_flags) {{
292 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
293 header_output = BasicDeclare.subst(iop)
294 decoder_output = BasicConstructor.subst(iop)
295 decode_block = BasicDecode.subst(iop)
296 exec_output = BasicExecute.subst(iop)
297}};
298
299def format CSROp(code, *opt_flags) {{
300 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
301 header_output = BasicDeclare.subst(iop)
302 decoder_output = BasicConstructor.subst(iop)
303 decode_block = BasicDecode.subst(iop)
304 exec_output = BasicExecute.subst(iop)
305}};
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 format ROp(code, *opt_flags) {{
214 iop = InstObjParams(name, Name, 'RegOp', code, opt_flags)
215 header_output = BasicDeclare.subst(iop)
216 decoder_output = BasicConstructor.subst(iop)
217 decode_block = BasicDecode.subst(iop)
218 exec_output = BasicExecute.subst(iop)
219}};
220
221def format IOp(code, imm_type='int64_t', *opt_flags) {{
222 regs = ['_destRegIdx[0]','_srcRegIdx[0]']
223 iop = InstObjParams(name, Name, 'ImmOp<%s>' % imm_type,
224 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
225 'regs': ','.join(regs)}, opt_flags)
226 header_output = ImmDeclare.subst(iop)
227 decoder_output = ImmConstructor.subst(iop)
228 decode_block = BasicDecode.subst(iop)
229 exec_output = ImmExecute.subst(iop)
230}};
231
232def format BOp(code, *opt_flags) {{
233 imm_code = """
234 imm = BIMM12BITS4TO1 << 1 |
235 BIMM12BITS10TO5 << 5 |
236 BIMM12BIT11 << 11 |
237 IMMSIGN << 12;
238 imm = sext<13>(imm);
239 """
240 regs = ['_srcRegIdx[0]','_srcRegIdx[1]']
241 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
242 {'code': code, 'imm_code': imm_code,
243 'regs': ','.join(regs)}, opt_flags)
244 header_output = BranchDeclare.subst(iop)
245 decoder_output = ImmConstructor.subst(iop)
246 decode_block = BasicDecode.subst(iop)
247 exec_output = BranchExecute.subst(iop)
248}};
249
250def format Jump(code, *opt_flags) {{
251 regs = ['_destRegIdx[0]', '_srcRegIdx[0]']
252 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
253 {'code': code, 'imm_code': 'imm = sext<12>(IMM12);',
254 'regs': ','.join(regs)}, opt_flags)
255 header_output = JumpDeclare.subst(iop)
256 decoder_output = ImmConstructor.subst(iop)
257 decode_block = BasicDecode.subst(iop)
258 exec_output = JumpExecute.subst(iop)
259}};
260
261def format UOp(code, *opt_flags) {{
262 regs = ['_destRegIdx[0]']
263 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
264 {'code': code, 'imm_code': 'imm = sext<20>(IMM20) << 12;',
265 'regs': ','.join(regs)}, opt_flags)
266 header_output = ImmDeclare.subst(iop)
267 decoder_output = ImmConstructor.subst(iop)
268 decode_block = BasicDecode.subst(iop)
269 exec_output = ImmExecute.subst(iop)
270}};
271
272def format JOp(code, *opt_flags) {{
273 imm_code = """
274 imm = UJIMMBITS10TO1 << 1 |
275 UJIMMBIT11 << 11 |
276 UJIMMBITS19TO12 << 12 |
277 IMMSIGN << 20;
278 imm = sext<21>(imm);
279 """
280 pc = 'pc.set(pc.pc() + imm);'
281 regs = ['_destRegIdx[0]']
282 iop = InstObjParams(name, Name, 'ImmOp<int64_t>',
283 {'code': code, 'imm_code': imm_code,
284 'regs': ','.join(regs)}, opt_flags)
285 header_output = BranchDeclare.subst(iop)
286 decoder_output = ImmConstructor.subst(iop)
287 decode_block = BasicDecode.subst(iop)
288 exec_output = BranchExecute.subst(iop)
289}};
290
291def format SystemOp(code, *opt_flags) {{
292 iop = InstObjParams(name, Name, 'SystemOp', code, opt_flags)
293 header_output = BasicDeclare.subst(iop)
294 decoder_output = BasicConstructor.subst(iop)
295 decode_block = BasicDecode.subst(iop)
296 exec_output = BasicExecute.subst(iop)
297}};
298
299def format CSROp(code, *opt_flags) {{
300 iop = InstObjParams(name, Name, 'CSROp', code, opt_flags)
301 header_output = BasicDeclare.subst(iop)
302 decoder_output = BasicConstructor.subst(iop)
303 decode_block = BasicDecode.subst(iop)
304 exec_output = BasicExecute.subst(iop)
305}};