blob: 445ba607d3ca0814ccab6fd6d53d89dddbaf5b20 [file] [log] [blame]
Stefan Wallentowitz0731d512020-07-14 21:55:14 +02001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +01005from typing import Dict
Stefan Wallentowitz0731d512020-07-14 21:55:14 +02006
Rupert Swarbrick8e016022020-11-19 16:59:02 +00007from .flags import FlagReg
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +01008from .isa import (OTBNInsn, RV32RegReg, RV32RegImm, RV32ImmShift,
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +01009 insn_for_mnemonic, logical_byte_shift)
Rupert Swarbrick8e016022020-11-19 16:59:02 +000010from .state import OTBNState
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020011
12
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010013class ADD(RV32RegReg):
14 insn = insn_for_mnemonic('add', 3)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020015
Rupert Swarbrickce970752020-09-18 12:09:24 +010016 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010017 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
18 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
19 result = (val1 + val2) & ((1 << 32) - 1)
20 state.gprs.get_reg(self.grd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020021
22
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010023class ADDI(RV32RegImm):
24 insn = insn_for_mnemonic('addi', 3)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020025
Rupert Swarbrickce970752020-09-18 12:09:24 +010026 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010027 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
28 result = (val1 + self.imm) & ((1 << 32) - 1)
29 state.gprs.get_reg(self.grd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020030
31
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010032class LUI(OTBNInsn):
33 insn = insn_for_mnemonic('lui', 2)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020034
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010035 def __init__(self, op_vals: Dict[str, int]):
36 super().__init__(op_vals)
37 self.grd = op_vals['grd']
38 self.imm = op_vals['imm']
39
Rupert Swarbrickce970752020-09-18 12:09:24 +010040 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010041 state.gprs.get_reg(self.grd).write_unsigned(self.imm << 12)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010042
43
44class SUB(RV32RegReg):
45 insn = insn_for_mnemonic('sub', 3)
46
Rupert Swarbrickce970752020-09-18 12:09:24 +010047 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010048 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
49 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
50 result = (val1 - val2) & ((1 << 32) - 1)
51 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010052
53
54class SLL(RV32RegReg):
55 insn = insn_for_mnemonic('sll', 3)
56
Rupert Swarbrickce970752020-09-18 12:09:24 +010057 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010058 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
59 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
60 result = (val1 << val2) & ((1 << 32) - 1)
61 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010062
63
64class SLLI(RV32ImmShift):
65 insn = insn_for_mnemonic('slli', 3)
66
Rupert Swarbrickce970752020-09-18 12:09:24 +010067 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010068 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
69 result = (val1 << self.shamt) & ((1 << 32) - 1)
70 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010071
72
73class SRL(RV32RegReg):
74 insn = insn_for_mnemonic('srl', 3)
75
Rupert Swarbrickce970752020-09-18 12:09:24 +010076 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010077 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
78 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
79 result = val1 >> val2
80 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010081
82
83class SRLI(RV32ImmShift):
84 insn = insn_for_mnemonic('srli', 3)
85
Rupert Swarbrickce970752020-09-18 12:09:24 +010086 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010087 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
88 result = val1 >> self.shamt
89 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010090
91
92class SRA(RV32RegReg):
93 insn = insn_for_mnemonic('sra', 3)
94
Rupert Swarbrickce970752020-09-18 12:09:24 +010095 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010096 val1 = state.gprs.get_reg(self.grs1).read_signed()
97 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
98 result = val1 >> val2
99 state.gprs.get_reg(self.grd).write_signed(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100100
101
102class SRAI(RV32ImmShift):
103 insn = insn_for_mnemonic('srai', 3)
104
Rupert Swarbrickce970752020-09-18 12:09:24 +0100105 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100106 val1 = state.gprs.get_reg(self.grs1).read_signed()
107 val2 = self.shamt
108 result = val1 >> val2
109 state.gprs.get_reg(self.grd).write_signed(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100110
111
112class AND(RV32RegReg):
113 insn = insn_for_mnemonic('and', 3)
114
Rupert Swarbrickce970752020-09-18 12:09:24 +0100115 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100116 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
117 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
118 result = val1 & val2
119 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100120
121
122class ANDI(RV32RegImm):
123 insn = insn_for_mnemonic('andi', 3)
124
Rupert Swarbrickce970752020-09-18 12:09:24 +0100125 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100126 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000127 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100128 result = val1 & val2
129 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100130
131
132class OR(RV32RegReg):
133 insn = insn_for_mnemonic('or', 3)
134
Rupert Swarbrickce970752020-09-18 12:09:24 +0100135 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100136 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
137 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
138 result = val1 | val2
139 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100140
141
142class ORI(RV32RegImm):
143 insn = insn_for_mnemonic('ori', 3)
144
Rupert Swarbrickce970752020-09-18 12:09:24 +0100145 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100146 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000147 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100148 result = val1 | val2
149 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100150
151
152class XOR(RV32RegReg):
153 insn = insn_for_mnemonic('xor', 3)
154
Rupert Swarbrickce970752020-09-18 12:09:24 +0100155 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100156 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
157 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
158 result = val1 ^ val2
159 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100160
161
162class XORI(RV32RegImm):
163 insn = insn_for_mnemonic('xori', 3)
164
Rupert Swarbrickce970752020-09-18 12:09:24 +0100165 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100166 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000167 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100168 result = val1 ^ val2
169 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100170
171
172class LW(OTBNInsn):
173 insn = insn_for_mnemonic('lw', 3)
174
175 def __init__(self, op_vals: Dict[str, int]):
176 super().__init__(op_vals)
177 self.grd = op_vals['grd']
178 self.offset = op_vals['offset']
179 self.grs1 = op_vals['grs1']
180
Rupert Swarbrickce970752020-09-18 12:09:24 +0100181 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100182 base = state.gprs.get_reg(self.grs1).read_unsigned()
183 addr = (base + self.offset) & ((1 << 32) - 1)
184 result = state.dmem.load_u32(addr)
185 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100186
187
188class SW(OTBNInsn):
189 insn = insn_for_mnemonic('sw', 3)
190
191 def __init__(self, op_vals: Dict[str, int]):
192 super().__init__(op_vals)
193 self.grs2 = op_vals['grs2']
194 self.offset = op_vals['offset']
195 self.grs1 = op_vals['grs1']
196
Rupert Swarbrickce970752020-09-18 12:09:24 +0100197 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100198 base = state.gprs.get_reg(self.grs1).read_unsigned()
199 addr = (base + self.offset) & ((1 << 32) - 1)
200 value = state.gprs.get_reg(self.grs2).read_unsigned()
201 state.dmem.store_u32(addr, value)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100202
203
204class BEQ(OTBNInsn):
205 insn = insn_for_mnemonic('beq', 3)
206
207 def __init__(self, op_vals: Dict[str, int]):
208 super().__init__(op_vals)
209 self.grs1 = op_vals['grs1']
210 self.grs2 = op_vals['grs2']
211 self.offset = op_vals['offset']
212
Rupert Swarbrickce970752020-09-18 12:09:24 +0100213 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100214 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
215 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100216 if val1 == val2:
Rupert Swarbrickce970752020-09-18 12:09:24 +0100217 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100218
219
220class BNE(OTBNInsn):
221 insn = insn_for_mnemonic('bne', 3)
222
223 def __init__(self, op_vals: Dict[str, int]):
224 super().__init__(op_vals)
225 self.grs1 = op_vals['grs1']
226 self.grs2 = op_vals['grs2']
227 self.offset = op_vals['offset']
228
Rupert Swarbrickce970752020-09-18 12:09:24 +0100229 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100230 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
231 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100232 if val1 != val2:
Rupert Swarbrickce970752020-09-18 12:09:24 +0100233 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100234
235
236class JAL(OTBNInsn):
237 insn = insn_for_mnemonic('jal', 2)
238
239 def __init__(self, op_vals: Dict[str, int]):
240 super().__init__(op_vals)
241 self.grd = op_vals['grd']
242 self.offset = op_vals['offset']
243
Rupert Swarbrickce970752020-09-18 12:09:24 +0100244 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100245 link_pc = (state.pc + 4) & ((1 << 32) - 1)
246 state.gprs.get_reg(self.grd).write_unsigned(link_pc)
Rupert Swarbrickce970752020-09-18 12:09:24 +0100247 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100248
249
250class JALR(OTBNInsn):
251 insn = insn_for_mnemonic('jalr', 3)
252
253 def __init__(self, op_vals: Dict[str, int]):
254 super().__init__(op_vals)
255 self.grd = op_vals['grd']
256 self.grs1 = op_vals['grs1']
257 self.offset = op_vals['offset']
258
Rupert Swarbrickce970752020-09-18 12:09:24 +0100259 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100260 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
261 link_pc = (state.pc + 4) & ((1 << 32) - 1)
262
263 state.gprs.get_reg(self.grd).write_unsigned(link_pc)
264 state.pc_next = (val1 + self.offset) & ((1 << 32) - 1)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100265
266
267class CSRRS(OTBNInsn):
268 insn = insn_for_mnemonic('csrrs', 3)
269
270 def __init__(self, op_vals: Dict[str, int]):
271 super().__init__(op_vals)
272 self.grd = op_vals['grd']
273 self.csr = op_vals['csr']
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100274 self.grs1 = op_vals['grs1']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100275
Rupert Swarbrickce970752020-09-18 12:09:24 +0100276 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100277 old_val = state.read_csr(self.csr)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100278 bits_to_set = state.gprs.get_reg(self.grs1).read_unsigned()
279 new_val = old_val | bits_to_set
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100280
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100281 state.gprs.get_reg(self.grd).write_unsigned(old_val)
282 state.write_csr(self.csr, new_val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100283
284
285class CSRRW(OTBNInsn):
286 insn = insn_for_mnemonic('csrrw', 3)
287
288 def __init__(self, op_vals: Dict[str, int]):
289 super().__init__(op_vals)
290 self.grd = op_vals['grd']
291 self.csr = op_vals['csr']
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100292 self.grs1 = op_vals['grs1']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100293
Rupert Swarbrickce970752020-09-18 12:09:24 +0100294 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100295 new_val = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100296
Rupert Swarbrickb35a77d2020-10-01 17:44:25 +0100297 if self.grd != 0:
298 old_val = state.read_csr(self.csr)
299 state.gprs.get_reg(self.grd).write_unsigned(old_val)
300
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100301 state.write_csr(self.csr, new_val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100302
303
304class ECALL(OTBNInsn):
305 insn = insn_for_mnemonic('ecall', 0)
306
307 def __init__(self, op_vals: Dict[str, int]):
308 super().__init__(op_vals)
309 pass
310
Rupert Swarbrickce970752020-09-18 12:09:24 +0100311 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick18cb5e22020-11-19 13:03:44 +0000312 # Set INTR_STATE.done and STATUS, reflecting the fact we've stopped.
313 state.stop(None)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100314
315
316class LOOP(OTBNInsn):
317 insn = insn_for_mnemonic('loop', 2)
318
319 def __init__(self, op_vals: Dict[str, int]):
320 super().__init__(op_vals)
321 self.grs = op_vals['grs']
322 self.bodysize = op_vals['bodysize']
323
Rupert Swarbrickce970752020-09-18 12:09:24 +0100324 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100325 num_iters = state.gprs.get_reg(self.grs).read_unsigned()
Rupert Swarbrickce970752020-09-18 12:09:24 +0100326 state.loop_start(num_iters, self.bodysize)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100327
328
329class LOOPI(OTBNInsn):
330 insn = insn_for_mnemonic('loopi', 2)
331
332 def __init__(self, op_vals: Dict[str, int]):
333 super().__init__(op_vals)
334 self.iterations = op_vals['iterations']
335 self.bodysize = op_vals['bodysize']
336
Rupert Swarbrickce970752020-09-18 12:09:24 +0100337 def execute(self, state: OTBNState) -> None:
338 state.loop_start(self.iterations, self.bodysize)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100339
340
341class BNADD(OTBNInsn):
342 insn = insn_for_mnemonic('bn.add', 6)
343
344 def __init__(self, op_vals: Dict[str, int]):
345 super().__init__(op_vals)
346 self.wrd = op_vals['wrd']
347 self.wrs1 = op_vals['wrs1']
348 self.wrs2 = op_vals['wrs2']
349 self.shift_type = op_vals['shift_type']
350 self.shift_bytes = op_vals['shift_bytes']
351 self.flag_group = op_vals['flag_group']
352
Rupert Swarbrickce970752020-09-18 12:09:24 +0100353 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100354 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
355 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
356 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
357
Rupert Swarbrickce970752020-09-18 12:09:24 +0100358 (result, flags) = state.add_with_carry(a, b_shifted, 0)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100359 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100360 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200361
362
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100363class BNADDC(OTBNInsn):
364 insn = insn_for_mnemonic('bn.addc', 6)
365
366 def __init__(self, op_vals: Dict[str, int]):
367 super().__init__(op_vals)
368 self.wrd = op_vals['wrd']
369 self.wrs1 = op_vals['wrs1']
370 self.wrs2 = op_vals['wrs2']
371 self.shift_type = op_vals['shift_type']
372 self.shift_bytes = op_vals['shift_bytes']
373 self.flag_group = op_vals['flag_group']
374
Rupert Swarbrickce970752020-09-18 12:09:24 +0100375 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100376 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
377 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
378 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
379
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100380 carry = int(state.csrs.flags[self.flag_group].C)
381 (result, flags) = state.add_with_carry(a, b_shifted, carry)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100382 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100383 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200384
385
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100386class BNADDI(OTBNInsn):
387 insn = insn_for_mnemonic('bn.addi', 4)
388
389 def __init__(self, op_vals: Dict[str, int]):
390 super().__init__(op_vals)
391 self.wrd = op_vals['wrd']
392 self.wrs = op_vals['wrs']
393 self.imm = op_vals['imm']
394 self.flag_group = op_vals['flag_group']
395
Rupert Swarbrickce970752020-09-18 12:09:24 +0100396 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100397 a = state.wdrs.get_reg(self.wrs).read_unsigned()
398 b = self.imm
399
Rupert Swarbrickce970752020-09-18 12:09:24 +0100400 (result, flags) = state.add_with_carry(a, b, 0)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100401 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100402 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200403
404
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100405class BNADDM(OTBNInsn):
406 insn = insn_for_mnemonic('bn.addm', 3)
407
408 def __init__(self, op_vals: Dict[str, int]):
409 super().__init__(op_vals)
410 self.wrd = op_vals['wrd']
411 self.wrs1 = op_vals['wrs1']
412 self.wrs2 = op_vals['wrs2']
413
Rupert Swarbrickce970752020-09-18 12:09:24 +0100414 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100415 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
416 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
Rupert Swarbrick840e3292020-10-02 08:43:18 +0100417 result = a + b
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100418
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100419 mod_val = state.wsrs.MOD.read_unsigned()
420 if result >= mod_val:
421 result -= mod_val
422
Rupert Swarbrick840e3292020-10-02 08:43:18 +0100423 result = result & ((1 << 256) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100424 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200425
426
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100427class BNMULQACC(OTBNInsn):
428 insn = insn_for_mnemonic('bn.mulqacc', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200429
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100430 def __init__(self, op_vals: Dict[str, int]):
431 super().__init__(op_vals)
432 self.zero_acc = op_vals['zero_acc']
433 self.wrs1 = op_vals['wrs1']
434 self.wrs1_qwsel = op_vals['wrs1_qwsel']
435 self.wrs2 = op_vals['wrs2']
436 self.wrs2_qwsel = op_vals['wrs2_qwsel']
437 self.acc_shift_imm = op_vals['acc_shift_imm']
438
Rupert Swarbrickce970752020-09-18 12:09:24 +0100439 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100440 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
441 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200442
443 mul_res = a_qw * b_qw
444
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100445 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100446 if self.zero_acc:
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200447 acc = 0
448
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100449 acc += (mul_res << self.acc_shift_imm)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200450
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100451 truncated = acc & ((1 << 256) - 1)
452 state.wsrs.ACC.write_unsigned(truncated)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200453
454
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100455class BNMULQACCWO(OTBNInsn):
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000456 insn = insn_for_mnemonic('bn.mulqacc.wo', 8)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100457
458 def __init__(self, op_vals: Dict[str, int]):
459 super().__init__(op_vals)
460 self.zero_acc = op_vals['zero_acc']
461 self.wrd = op_vals['wrd']
462 self.wrs1 = op_vals['wrs1']
463 self.wrs1_qwsel = op_vals['wrs1_qwsel']
464 self.wrs2 = op_vals['wrs2']
465 self.wrs2_qwsel = op_vals['wrs2_qwsel']
466 self.acc_shift_imm = op_vals['acc_shift_imm']
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000467 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100468
Rupert Swarbrickce970752020-09-18 12:09:24 +0100469 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100470 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
471 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100472
473 mul_res = a_qw * b_qw
474
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100475 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100476 if self.zero_acc:
477 acc = 0
478
479 acc += (mul_res << self.acc_shift_imm)
480
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100481 truncated = acc & ((1 << 256) - 1)
482 state.wdrs.get_reg(self.wrd).write_unsigned(truncated)
483 state.wsrs.ACC.write_unsigned(truncated)
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000484 state.set_mlz_flags(self.flag_group, truncated)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100485
486
487class BNMULQACCSO(OTBNInsn):
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000488 insn = insn_for_mnemonic('bn.mulqacc.so', 9)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100489
490 def __init__(self, op_vals: Dict[str, int]):
491 super().__init__(op_vals)
492 self.zero_acc = op_vals['zero_acc']
493 self.wrd = op_vals['wrd']
494 self.wrd_hwsel = op_vals['wrd_hwsel']
495 self.wrs1 = op_vals['wrs1']
496 self.wrs1_qwsel = op_vals['wrs1_qwsel']
497 self.wrs2 = op_vals['wrs2']
498 self.wrs2_qwsel = op_vals['wrs2_qwsel']
499 self.acc_shift_imm = op_vals['acc_shift_imm']
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000500 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100501
Rupert Swarbrickce970752020-09-18 12:09:24 +0100502 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100503 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
504 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100505
506 mul_res = a_qw * b_qw
507
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100508 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100509 if self.zero_acc:
510 acc = 0
511
512 acc += (mul_res << self.acc_shift_imm)
513
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100514 lo_part = acc & ((1 << 128) - 1)
515 hi_part = acc >> 128
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100516
Felix Millerb57138e2020-09-28 22:24:39 +0200517 state.set_half_word_unsigned(self.wrd, self.wrd_hwsel, lo_part)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100518 state.wsrs.ACC.write_unsigned(hi_part)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100519
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000520 old_flags = state.csrs.flags[self.flag_group]
521 if self.wrd_hwsel:
522 new_flags = FlagReg(C=old_flags.C,
523 M=bool((lo_part >> 127) & 1),
524 L=old_flags.L,
525 Z=old_flags.Z and lo_part == 0)
526 else:
527 new_flags = FlagReg(C=old_flags.C,
528 M=old_flags.M,
529 L=bool(lo_part & 1),
530 Z=lo_part == 0)
531 state.csrs.flags[self.flag_group] = new_flags
532
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100533
534class BNSUB(OTBNInsn):
535 insn = insn_for_mnemonic('bn.sub', 6)
536
537 def __init__(self, op_vals: Dict[str, int]):
538 super().__init__(op_vals)
539 self.wrd = op_vals['wrd']
540 self.wrs1 = op_vals['wrs1']
541 self.wrs2 = op_vals['wrs2']
542 self.shift_type = op_vals['shift_type']
543 self.shift_bytes = op_vals['shift_bytes']
544 self.flag_group = op_vals['flag_group']
545
Rupert Swarbrickce970752020-09-18 12:09:24 +0100546 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100547 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
548 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
549 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
550
551 (result, flags) = state.sub_with_borrow(a, b_shifted, 0)
552 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100553 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200554
555
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100556class BNSUBB(OTBNInsn):
557 insn = insn_for_mnemonic('bn.subb', 6)
558
559 def __init__(self, op_vals: Dict[str, int]):
560 super().__init__(op_vals)
561 self.wrd = op_vals['wrd']
562 self.wrs1 = op_vals['wrs1']
563 self.wrs2 = op_vals['wrs2']
564 self.shift_type = op_vals['shift_type']
565 self.shift_bytes = op_vals['shift_bytes']
566 self.flag_group = op_vals['flag_group']
567
Rupert Swarbrickce970752020-09-18 12:09:24 +0100568 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100569 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
570 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
571 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100572 borrow = int(state.csrs.flags[self.flag_group].C)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100573
574 (result, flags) = state.sub_with_borrow(a, b_shifted, borrow)
575 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100576 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200577
578
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100579class BNSUBI(OTBNInsn):
580 insn = insn_for_mnemonic('bn.subi', 4)
581
582 def __init__(self, op_vals: Dict[str, int]):
583 super().__init__(op_vals)
584 self.wrd = op_vals['wrd']
585 self.wrs = op_vals['wrs']
586 self.imm = op_vals['imm']
587 self.flag_group = op_vals['flag_group']
588
Rupert Swarbrickce970752020-09-18 12:09:24 +0100589 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100590 a = state.wdrs.get_reg(self.wrs).read_unsigned()
591 b = self.imm
592
593 (result, flags) = state.sub_with_borrow(a, b, 0)
594 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100595 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200596
597
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100598class BNSUBM(OTBNInsn):
599 insn = insn_for_mnemonic('bn.subm', 3)
600
601 def __init__(self, op_vals: Dict[str, int]):
602 super().__init__(op_vals)
603 self.wrd = op_vals['wrd']
604 self.wrs1 = op_vals['wrs1']
605 self.wrs2 = op_vals['wrs2']
606
Rupert Swarbrickce970752020-09-18 12:09:24 +0100607 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100608 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
609 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
610
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100611 mod_val = state.wsrs.MOD.read_unsigned()
612
Rupert Swarbrick31ffc1d2020-10-02 10:13:55 +0100613 diff = a - b
614 if diff < 0:
615 diff += mod_val
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100616
Rupert Swarbrick31ffc1d2020-10-02 10:13:55 +0100617 result = diff & ((1 << 256) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100618 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200619
620
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100621class BNAND(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100622 insn = insn_for_mnemonic('bn.and', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200623
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100624 def __init__(self, op_vals: Dict[str, int]):
625 super().__init__(op_vals)
626 self.wrd = op_vals['wrd']
627 self.wrs1 = op_vals['wrs1']
628 self.wrs2 = op_vals['wrs2']
629 self.shift_type = op_vals['shift_type']
630 self.shift_bytes = op_vals['shift_bytes']
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100631 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100632
Rupert Swarbrickce970752020-09-18 12:09:24 +0100633 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100634 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
635 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
636 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
637
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100638 result = a & b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100639 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100640 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200641
642
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100643class BNOR(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100644 insn = insn_for_mnemonic('bn.or', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200645
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100646 def __init__(self, op_vals: Dict[str, int]):
647 super().__init__(op_vals)
648 self.wrd = op_vals['wrd']
649 self.wrs1 = op_vals['wrs1']
650 self.wrs2 = op_vals['wrs2']
651 self.shift_type = op_vals['shift_type']
652 self.shift_bytes = op_vals['shift_bytes']
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100653 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100654
Rupert Swarbrickce970752020-09-18 12:09:24 +0100655 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100656 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
657 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
658 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
659
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100660 result = a | b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100661 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100662 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200663
664
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100665class BNNOT(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100666 insn = insn_for_mnemonic('bn.not', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200667
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100668 def __init__(self, op_vals: Dict[str, int]):
669 super().__init__(op_vals)
670 self.wrd = op_vals['wrd']
671 self.wrs = op_vals['wrs']
672 self.shift_type = op_vals['shift_type']
673 self.shift_bytes = op_vals['shift_bytes']
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100674 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100675
Rupert Swarbrickce970752020-09-18 12:09:24 +0100676 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100677 a = state.wdrs.get_reg(self.wrs).read_unsigned()
678 a_shifted = logical_byte_shift(a, self.shift_type, self.shift_bytes)
679
680 result = a_shifted ^ ((1 << 256) - 1)
681 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100682 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200683
684
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100685class BNXOR(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100686 insn = insn_for_mnemonic('bn.xor', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200687
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100688 def __init__(self, op_vals: Dict[str, int]):
689 super().__init__(op_vals)
690 self.wrd = op_vals['wrd']
691 self.wrs1 = op_vals['wrs1']
692 self.wrs2 = op_vals['wrs2']
693 self.shift_type = op_vals['shift_type']
694 self.shift_bytes = op_vals['shift_bytes']
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100695 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100696
Rupert Swarbrickce970752020-09-18 12:09:24 +0100697 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100698 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
699 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
700 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
701
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100702 result = a ^ b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100703 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100704 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200705
706
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100707class BNRSHI(OTBNInsn):
708 insn = insn_for_mnemonic('bn.rshi', 4)
709
710 def __init__(self, op_vals: Dict[str, int]):
711 super().__init__(op_vals)
712 self.wrd = op_vals['wrd']
713 self.wrs1 = op_vals['wrs1']
714 self.wrs2 = op_vals['wrs2']
715 self.imm = op_vals['imm']
716
Rupert Swarbrickce970752020-09-18 12:09:24 +0100717 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100718 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
719 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
720
721 result = (((a << 256) | b) >> self.imm) & ((1 << 256) - 1)
722 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200723
724
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100725class BNRSEL(OTBNInsn):
726 insn = insn_for_mnemonic('bn.sel', 5)
727
728 def __init__(self, op_vals: Dict[str, int]):
729 super().__init__(op_vals)
730 self.wrd = op_vals['wrd']
731 self.wrs1 = op_vals['wrs1']
732 self.wrs2 = op_vals['wrs2']
733 self.flag_group = op_vals['flag_group']
734 self.flag = op_vals['flag']
735
Rupert Swarbrickce970752020-09-18 12:09:24 +0100736 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100737 flag_is_set = state.csrs.flags[self.flag_group].get_by_idx(self.flag)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100738 wrs = self.wrs1 if flag_is_set else self.wrs2
739 value = state.wdrs.get_reg(wrs).read_unsigned()
740 state.wdrs.get_reg(self.wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200741
742
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100743class BNCMP(OTBNInsn):
744 insn = insn_for_mnemonic('bn.cmp', 5)
745
746 def __init__(self, op_vals: Dict[str, int]):
747 super().__init__(op_vals)
748 self.wrs1 = op_vals['wrs1']
749 self.wrs2 = op_vals['wrs2']
750 self.shift_type = op_vals['shift_type']
751 self.shift_bytes = op_vals['shift_bytes']
752 self.flag_group = op_vals['flag_group']
753
Rupert Swarbrickce970752020-09-18 12:09:24 +0100754 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100755 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
756 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
757 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
758
759 (_, flags) = state.sub_with_borrow(a, b_shifted, 0)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100760 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200761
762
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100763class BNCMPB(OTBNInsn):
764 insn = insn_for_mnemonic('bn.cmpb', 5)
765
766 def __init__(self, op_vals: Dict[str, int]):
767 super().__init__(op_vals)
768 self.wrs1 = op_vals['wrs1']
769 self.wrs2 = op_vals['wrs2']
770 self.shift_type = op_vals['shift_type']
771 self.shift_bytes = op_vals['shift_bytes']
772 self.flag_group = op_vals['flag_group']
773
Rupert Swarbrickce970752020-09-18 12:09:24 +0100774 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100775 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
776 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
777 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100778 borrow = int(state.csrs.flags[self.flag_group].C)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100779
780 (_, flags) = state.sub_with_borrow(a, b_shifted, borrow)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100781 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200782
783
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100784class BNLID(OTBNInsn):
785 insn = insn_for_mnemonic('bn.lid', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200786
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100787 def __init__(self, op_vals: Dict[str, int]):
788 super().__init__(op_vals)
789 self.grd = op_vals['grd']
790 self.grd_inc = op_vals['grd_inc']
791 self.offset = op_vals['offset']
792 self.grs1 = op_vals['grs1']
793 self.grs1_inc = op_vals['grs1_inc']
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200794
Rupert Swarbrickce970752020-09-18 12:09:24 +0100795 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100796 grs1_val = state.gprs.get_reg(self.grs1).read_unsigned()
797 addr = (grs1_val + self.offset) & ((1 << 32) - 1)
798 grd_val = state.gprs.get_reg(self.grd).read_unsigned()
799
800 wrd = grd_val & 0x1f
801 value = state.dmem.load_u256(addr)
802 state.wdrs.get_reg(wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200803
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100804 if self.grd_inc:
Rupert Swarbrick9ea7ad42020-09-28 17:37:04 +0100805 new_grd_val = (grd_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100806 state.gprs.get_reg(self.grd).write_unsigned(new_grd_val)
807
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100808 if self.grs1_inc:
Felix Miller05616102020-10-06 00:13:44 +0200809 new_grs1_val = (grs1_val + 32) & ((1 << 32) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100810 state.gprs.get_reg(self.grs1).write_unsigned(new_grs1_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200811
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200812
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100813class BNSID(OTBNInsn):
814 insn = insn_for_mnemonic('bn.sid', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200815
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100816 def __init__(self, op_vals: Dict[str, int]):
817 super().__init__(op_vals)
818 self.grs2 = op_vals['grs2']
819 self.grs2_inc = op_vals['grs2_inc']
820 self.offset = op_vals['offset']
821 self.grs1 = op_vals['grs1']
822 self.grs1_inc = op_vals['grs1_inc']
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200823
Rupert Swarbrickce970752020-09-18 12:09:24 +0100824 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100825 grs1_val = state.gprs.get_reg(self.grs1).read_unsigned()
826 addr = (grs1_val + self.offset) & ((1 << 32) - 1)
Rupert Swarbrick992f0b92020-09-08 12:24:52 +0100827
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100828 grs2_val = state.gprs.get_reg(self.grs2).read_unsigned()
829 wrs = grs2_val & 0x1f
830 wrs_val = state.wdrs.get_reg(wrs).read_unsigned()
831
832 state.dmem.store_u256(addr, wrs_val)
833
834 if self.grs1_inc:
Felix Miller05616102020-10-06 00:13:44 +0200835 new_grs1_val = (grs1_val + 32) & ((1 << 32) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100836 state.gprs.get_reg(self.grs1).write_unsigned(new_grs1_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200837
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100838 if self.grs2_inc:
Rupert Swarbrick9ea7ad42020-09-28 17:37:04 +0100839 new_grs2_val = (grs2_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100840 state.gprs.get_reg(self.grs2).write_unsigned(new_grs2_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200841
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100842
843class BNMOV(OTBNInsn):
844 insn = insn_for_mnemonic('bn.mov', 2)
845
846 def __init__(self, op_vals: Dict[str, int]):
847 super().__init__(op_vals)
848 self.wrd = op_vals['wrd']
849 self.wrs = op_vals['wrs']
850
Rupert Swarbrickce970752020-09-18 12:09:24 +0100851 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100852 value = state.wdrs.get_reg(self.wrs).read_unsigned()
853 state.wdrs.get_reg(self.wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200854
855
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100856class BNMOVR(OTBNInsn):
857 insn = insn_for_mnemonic('bn.movr', 4)
858
859 def __init__(self, op_vals: Dict[str, int]):
860 super().__init__(op_vals)
861 self.grd = op_vals['grd']
862 self.grd_inc = op_vals['grd_inc']
863 self.grs = op_vals['grs']
864 self.grs_inc = op_vals['grs_inc']
865
Rupert Swarbrickce970752020-09-18 12:09:24 +0100866 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100867 grd_val = state.gprs.get_reg(self.grd).read_unsigned()
868 grs_val = state.gprs.get_reg(self.grs).read_unsigned()
869
870 wrd = grd_val & 0x1f
871 wrs = grs_val & 0x1f
872
873 value = state.wdrs.get_reg(wrs).read_unsigned()
874 state.wdrs.get_reg(wrd).write_unsigned(value)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100875
876 if self.grd_inc:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100877 new_grd_val = (grd_val + 1) & ((1 << 32) - 1)
878 state.gprs.get_reg(self.grd).write_unsigned(new_grd_val)
879
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100880 if self.grs_inc:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100881 new_grs_val = (grs_val + 1) & ((1 << 32) - 1)
882 state.gprs.get_reg(self.grs).write_unsigned(new_grs_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200883
884
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000885class BNWSRR(OTBNInsn):
886 insn = insn_for_mnemonic('bn.wsrr', 2)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100887
888 def __init__(self, op_vals: Dict[str, int]):
889 super().__init__(op_vals)
890 self.wrd = op_vals['wrd']
891 self.wsr = op_vals['wsr']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100892
Rupert Swarbrickce970752020-09-18 12:09:24 +0100893 def execute(self, state: OTBNState) -> None:
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000894 val = state.wsrs.read_at_idx(self.wsr)
895 state.wdrs.get_reg(self.wrd).write_unsigned(val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200896
897
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000898class BNWSRW(OTBNInsn):
899 insn = insn_for_mnemonic('bn.wsrw', 2)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100900
901 def __init__(self, op_vals: Dict[str, int]):
902 super().__init__(op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100903 self.wsr = op_vals['wsr']
904 self.wrs = op_vals['wrs']
905
Rupert Swarbrickce970752020-09-18 12:09:24 +0100906 def execute(self, state: OTBNState) -> None:
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000907 val = state.wdrs.get_reg(self.wrs).read_unsigned()
908 state.wsrs.write_at_idx(self.wsr, val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100909
910
911INSN_CLASSES = [
912 ADD, ADDI, LUI, SUB, SLL, SLLI, SRL, SRLI, SRA, SRAI,
913 AND, ANDI, OR, ORI, XOR, XORI,
914 LW, SW,
915 BEQ, BNE, JAL, JALR,
916 CSRRS, CSRRW,
917 ECALL,
918 LOOP, LOOPI,
919
920 BNADD, BNADDC, BNADDI, BNADDM,
921 BNMULQACC, BNMULQACCWO, BNMULQACCSO,
922 BNSUB, BNSUBB, BNSUBI, BNSUBM,
923 BNAND, BNOR, BNNOT, BNXOR,
924 BNRSHI,
925 BNRSEL,
926 BNCMP, BNCMPB,
927 BNLID, BNSID,
928 BNMOV, BNMOVR,
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000929 BNWSRR, BNWSRW
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100930]