arch: [Patch 1/5] Added RISC-V base instruction set RV64I
[gem5.git] / src / arch / riscv / isa / formats / type.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2016 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 output header {{
37 #include <iostream>
38 /**
39 * Base class for R-type operations
40 */
41 class ROp : public RiscvStaticInst
42 {
43 protected:
44 /// Constructor
45 ROp(const char *mnem, MachInst _machInst, OpClass __opClass)
46 : RiscvStaticInst(mnem, _machInst, __opClass)
47 {}
48
49 std::string
50 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
51 };
52
53 /**
54 * Base class for I-type operations
55 */
56 class IOp : public RiscvStaticInst
57 {
58 protected:
59 int64_t imm;
60
61 /// Constructor
62 IOp(const char *mnem, MachInst _machInst, OpClass __opClass)
63 : RiscvStaticInst(mnem, _machInst, __opClass),imm(IMM12)
64 {
65 if (IMMSIGN > 0)
66 imm |= ~((uint64_t)0x7FF);
67 }
68
69 std::string
70 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
71 };
72
73 /**
74 * Class for jalr instructions
75 */
76 class Jump : public IOp
77 {
78 protected:
79 Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
80 : IOp(mnem, _machInst, __opClass)
81 {}
82
83 RiscvISA::PCState
84 branchTarget(ThreadContext *tc) const;
85
86 using StaticInst::branchTarget;
87 using IOp::generateDisassembly;
88 };
89
90 /**
91 * Base class for S-type operations
92 */
93 class SOp : public RiscvStaticInst
94 {
95 protected:
96 int64_t imm;
97
98 /// Constructor
99 SOp(const char *mnem, MachInst _machInst, OpClass __opClass)
100 : RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
101 {
102 imm |= IMM5;
103 imm |= IMM7 << 5;
104 if (IMMSIGN > 0)
105 imm |= ~((uint64_t)0x7FF);
106 }
107
108 std::string
109 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
110 };
111
112 /**
113 * Base class for SB-type operations
114 */
115 class SBOp : public RiscvStaticInst
116 {
117 protected:
118 int64_t imm;
119
120 /// Constructor
121 SBOp(const char *mnem, MachInst _machInst, OpClass __opClass)
122 : RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
123 {
124 imm |= BIMM12BIT11 << 11;
125 imm |= BIMM12BITS4TO1 << 1;
126 imm |= BIMM12BITS10TO5 << 5;
127 if (IMMSIGN > 0)
128 imm |= ~((uint64_t)0xFFF);
129 }
130
131 RiscvISA::PCState
132 branchTarget(const RiscvISA::PCState &branchPC) const;
133
134 using StaticInst::branchTarget;
135
136 std::string
137 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
138 };
139
140 /**
141 * Base class for U-type operations
142 */
143 class UOp : public RiscvStaticInst
144 {
145 protected:
146 int64_t imm;
147
148 /// Constructor
149 UOp(const char *mnem, MachInst _machInst, OpClass __opClass)
150 : RiscvStaticInst(mnem, _machInst, __opClass), imm(0)
151 {
152 int32_t temp = IMM20 << 12;
153 imm = temp;
154 }
155
156 std::string
157 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
158 };
159
160 /**
161 * Base class for UJ-type operations
162 */
163 class UJOp : public RiscvStaticInst
164 {
165 protected:
166 int64_t imm;
167
168 /// Constructor
169 UJOp(const char *mnem, MachInst _machInst, OpClass __opClass)
170 : RiscvStaticInst(mnem, _machInst, __opClass),imm(0)
171 {
172 imm |= UJIMMBITS19TO12 << 12;
173 imm |= UJIMMBIT11 << 11;
174 imm |= UJIMMBITS10TO1 << 1;
175 if (IMMSIGN > 0)
176 imm |= ~((uint64_t)0xFFFFF);
177 }
178
179 RiscvISA::PCState
180 branchTarget(const RiscvISA::PCState &branchPC) const;
181
182 using StaticInst::branchTarget;
183
184 std::string
185 generateDisassembly(Addr pc, const SymbolTable *symtab) const;
186 };
187 }};
188
189 //Outputs to decoder.cc
190 output decoder {{
191 std::string
192 ROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
193 {
194 std::stringstream ss;
195 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " <<
196 regName(_srcRegIdx[0]) << ", " << regName(_srcRegIdx[1]);
197 return ss.str();
198 }
199
200 std::string
201 IOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
202 {
203 std::stringstream ss;
204 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " <<
205 regName(_srcRegIdx[0]) << ", " << imm;
206 return ss.str();
207 }
208
209 RiscvISA::PCState
210 Jump::branchTarget(ThreadContext *tc) const
211 {
212 PCState pc = tc->pcState();
213 IntReg Rs1 = tc->readIntReg(_srcRegIdx[0]);
214 pc.set((Rs1 + imm)&~0x1);
215 return pc;
216 }
217
218 std::string
219 SOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
220 {
221 std::stringstream ss;
222 ss << mnemonic << ' ' << regName(_srcRegIdx[1]) << ", " << imm <<
223 '(' << regName(_srcRegIdx[0]) << ')';
224 return ss.str();
225 }
226
227 RiscvISA::PCState
228 SBOp::branchTarget(const RiscvISA::PCState &branchPC) const
229 {
230 return branchPC.pc() + imm;
231 }
232
233 std::string
234 SBOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
235 {
236 std::stringstream ss;
237 ss << mnemonic << ' ' << regName(_srcRegIdx[0]) << ", " <<
238 regName(_srcRegIdx[1]) << ", " << imm;
239 return ss.str();
240 }
241
242 std::string
243 UOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
244 {
245 std::stringstream ss;
246 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << imm;
247 return ss.str();
248 }
249
250 RiscvISA::PCState
251 UJOp::branchTarget(const RiscvISA::PCState &branchPC) const
252 {
253 return branchPC.pc() + imm;
254 }
255
256 std::string
257 UJOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
258 {
259 std::stringstream ss;
260 ss << mnemonic << ' ' << regName(_destRegIdx[0]) << ", " << imm;
261 return ss.str();
262 }
263 }};
264
265 def format ROp(code, *opt_flags) {{
266 iop = InstObjParams(name, Name, 'ROp', code, opt_flags)
267 header_output = BasicDeclare.subst(iop)
268 decoder_output = BasicConstructor.subst(iop)
269 decode_block = BasicDecode.subst(iop)
270 exec_output = BasicExecute.subst(iop)
271 }};
272
273 def format IOp(code, *opt_flags) {{
274 iop = InstObjParams(name, Name, 'IOp', code, opt_flags)
275 header_output = BasicDeclare.subst(iop)
276 decoder_output = BasicConstructor.subst(iop)
277 decode_block = BasicDecode.subst(iop)
278 exec_output = BasicExecute.subst(iop)
279 }};
280
281 def format Jump(code, *opt_flags) {{
282 iop = InstObjParams(name, Name, 'Jump', code, opt_flags)
283 header_output = BasicDeclare.subst(iop)
284 decoder_output = BasicConstructor.subst(iop)
285 decode_block = BasicDecode.subst(iop)
286 exec_output = BasicExecute.subst(iop)
287 }};
288
289 def format SOp(code, *opt_flags) {{
290 iop = InstObjParams(name, Name, 'SOp', code, opt_flags)
291 header_output = BasicDeclare.subst(iop)
292 decoder_output = BasicConstructor.subst(iop)
293 decode_block = BasicDecode.subst(iop)
294 exec_output = BasicExecute.subst(iop)
295 }};
296
297 def format SBOp(code, *opt_flags) {{
298 iop = InstObjParams(name, Name, 'SBOp', code, opt_flags)
299 header_output = BasicDeclare.subst(iop)
300 decoder_output = BasicConstructor.subst(iop)
301 decode_block = BasicDecode.subst(iop)
302 exec_output = BasicExecute.subst(iop)
303 }};
304
305 def format UOp(code, *opt_flags) {{
306 iop = InstObjParams(name, Name, 'UOp', code, opt_flags)
307 header_output = BasicDeclare.subst(iop)
308 decoder_output = BasicConstructor.subst(iop)
309 decode_block = BasicDecode.subst(iop)
310 exec_output = BasicExecute.subst(iop)
311 }};
312
313 def format UJOp(code, *opt_flags) {{
314 iop = InstObjParams(name, Name, 'UJOp', code, opt_flags)
315 header_output = BasicDeclare.subst(iop)
316 decoder_output = BasicConstructor.subst(iop)
317 decode_block = BasicDecode.subst(iop)
318 exec_output = BasicExecute.subst(iop)
319 }};