blob: 2f2cc61060b679a00005d6ffdeb2bc96e3e5075e [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 Swarbrick0b60b5d2021-01-27 16:16:57 +00007from .alert import ERR_CODE_NO_ERROR, LoopError
Rupert Swarbrick8e016022020-11-19 16:59:02 +00008from .flags import FlagReg
Rupert Swarbrickc1bf4912021-01-22 11:42:51 +00009from .isa import (DecodeError, OTBNInsn, RV32RegReg, RV32RegImm, RV32ImmShift,
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010010 insn_for_mnemonic, logical_byte_shift)
Rupert Swarbrick8e016022020-11-19 16:59:02 +000011from .state import OTBNState
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020012
13
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010014class ADD(RV32RegReg):
15 insn = insn_for_mnemonic('add', 3)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020016
Rupert Swarbrickce970752020-09-18 12:09:24 +010017 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010018 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
19 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
20 result = (val1 + val2) & ((1 << 32) - 1)
21 state.gprs.get_reg(self.grd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020022
23
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010024class ADDI(RV32RegImm):
25 insn = insn_for_mnemonic('addi', 3)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020026
Rupert Swarbrickce970752020-09-18 12:09:24 +010027 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010028 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
29 result = (val1 + self.imm) & ((1 << 32) - 1)
30 state.gprs.get_reg(self.grd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020031
32
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010033class LUI(OTBNInsn):
34 insn = insn_for_mnemonic('lui', 2)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +020035
Rupert Swarbrick660baa92020-12-15 17:00:55 +000036 def __init__(self, raw: int, op_vals: Dict[str, int]):
37 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010038 self.grd = op_vals['grd']
39 self.imm = op_vals['imm']
40
Rupert Swarbrickce970752020-09-18 12:09:24 +010041 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010042 state.gprs.get_reg(self.grd).write_unsigned(self.imm << 12)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010043
44
45class SUB(RV32RegReg):
46 insn = insn_for_mnemonic('sub', 3)
47
Rupert Swarbrickce970752020-09-18 12:09:24 +010048 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010049 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
50 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
51 result = (val1 - val2) & ((1 << 32) - 1)
52 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010053
54
55class SLL(RV32RegReg):
56 insn = insn_for_mnemonic('sll', 3)
57
Rupert Swarbrickce970752020-09-18 12:09:24 +010058 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010059 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
60 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
61 result = (val1 << val2) & ((1 << 32) - 1)
62 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010063
64
65class SLLI(RV32ImmShift):
66 insn = insn_for_mnemonic('slli', 3)
67
Rupert Swarbrickce970752020-09-18 12:09:24 +010068 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010069 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
70 result = (val1 << self.shamt) & ((1 << 32) - 1)
71 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010072
73
74class SRL(RV32RegReg):
75 insn = insn_for_mnemonic('srl', 3)
76
Rupert Swarbrickce970752020-09-18 12:09:24 +010077 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010078 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
79 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
80 result = val1 >> val2
81 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010082
83
84class SRLI(RV32ImmShift):
85 insn = insn_for_mnemonic('srli', 3)
86
Rupert Swarbrickce970752020-09-18 12:09:24 +010087 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010088 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
89 result = val1 >> self.shamt
90 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +010091
92
93class SRA(RV32RegReg):
94 insn = insn_for_mnemonic('sra', 3)
95
Rupert Swarbrickce970752020-09-18 12:09:24 +010096 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +010097 val1 = state.gprs.get_reg(self.grs1).read_signed()
98 val2 = state.gprs.get_reg(self.grs2).read_unsigned() & 0x1f
99 result = val1 >> val2
100 state.gprs.get_reg(self.grd).write_signed(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100101
102
103class SRAI(RV32ImmShift):
104 insn = insn_for_mnemonic('srai', 3)
105
Rupert Swarbrickce970752020-09-18 12:09:24 +0100106 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100107 val1 = state.gprs.get_reg(self.grs1).read_signed()
108 val2 = self.shamt
109 result = val1 >> val2
110 state.gprs.get_reg(self.grd).write_signed(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100111
112
113class AND(RV32RegReg):
114 insn = insn_for_mnemonic('and', 3)
115
Rupert Swarbrickce970752020-09-18 12:09:24 +0100116 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100117 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
118 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
119 result = val1 & val2
120 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100121
122
123class ANDI(RV32RegImm):
124 insn = insn_for_mnemonic('andi', 3)
125
Rupert Swarbrickce970752020-09-18 12:09:24 +0100126 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100127 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000128 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100129 result = val1 & val2
130 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100131
132
133class OR(RV32RegReg):
134 insn = insn_for_mnemonic('or', 3)
135
Rupert Swarbrickce970752020-09-18 12:09:24 +0100136 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100137 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
138 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
139 result = val1 | val2
140 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100141
142
143class ORI(RV32RegImm):
144 insn = insn_for_mnemonic('ori', 3)
145
Rupert Swarbrickce970752020-09-18 12:09:24 +0100146 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100147 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000148 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100149 result = val1 | val2
150 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100151
152
153class XOR(RV32RegReg):
154 insn = insn_for_mnemonic('xor', 3)
155
Rupert Swarbrickce970752020-09-18 12:09:24 +0100156 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100157 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
158 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
159 result = val1 ^ val2
160 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100161
162
163class XORI(RV32RegImm):
164 insn = insn_for_mnemonic('xori', 3)
165
Rupert Swarbrickce970752020-09-18 12:09:24 +0100166 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100167 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick986990c2020-11-10 14:39:52 +0000168 val2 = self.as_u32(self.imm)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100169 result = val1 ^ val2
170 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100171
172
173class LW(OTBNInsn):
174 insn = insn_for_mnemonic('lw', 3)
175
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000176 def __init__(self, raw: int, op_vals: Dict[str, int]):
177 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100178 self.grd = op_vals['grd']
179 self.offset = op_vals['offset']
180 self.grs1 = op_vals['grs1']
181
Rupert Swarbrickce970752020-09-18 12:09:24 +0100182 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100183 base = state.gprs.get_reg(self.grs1).read_unsigned()
184 addr = (base + self.offset) & ((1 << 32) - 1)
185 result = state.dmem.load_u32(addr)
186 state.gprs.get_reg(self.grd).write_unsigned(result)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100187
188
189class SW(OTBNInsn):
190 insn = insn_for_mnemonic('sw', 3)
191
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000192 def __init__(self, raw: int, op_vals: Dict[str, int]):
193 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100194 self.grs2 = op_vals['grs2']
195 self.offset = op_vals['offset']
196 self.grs1 = op_vals['grs1']
197
Rupert Swarbrickce970752020-09-18 12:09:24 +0100198 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100199 base = state.gprs.get_reg(self.grs1).read_unsigned()
200 addr = (base + self.offset) & ((1 << 32) - 1)
201 value = state.gprs.get_reg(self.grs2).read_unsigned()
202 state.dmem.store_u32(addr, value)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100203
204
205class BEQ(OTBNInsn):
206 insn = insn_for_mnemonic('beq', 3)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000207 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100208
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000209 def __init__(self, raw: int, op_vals: Dict[str, int]):
210 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100211 self.grs1 = op_vals['grs1']
212 self.grs2 = op_vals['grs2']
213 self.offset = op_vals['offset']
214
Rupert Swarbrickce970752020-09-18 12:09:24 +0100215 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100216 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
217 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100218 if val1 == val2:
Rupert Swarbrickce970752020-09-18 12:09:24 +0100219 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100220
221
222class BNE(OTBNInsn):
223 insn = insn_for_mnemonic('bne', 3)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000224 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100225
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000226 def __init__(self, raw: int, op_vals: Dict[str, int]):
227 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100228 self.grs1 = op_vals['grs1']
229 self.grs2 = op_vals['grs2']
230 self.offset = op_vals['offset']
231
Rupert Swarbrickce970752020-09-18 12:09:24 +0100232 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100233 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
234 val2 = state.gprs.get_reg(self.grs2).read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100235 if val1 != val2:
Rupert Swarbrickce970752020-09-18 12:09:24 +0100236 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100237
238
239class JAL(OTBNInsn):
240 insn = insn_for_mnemonic('jal', 2)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000241 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100242
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000243 def __init__(self, raw: int, op_vals: Dict[str, int]):
244 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100245 self.grd = op_vals['grd']
246 self.offset = op_vals['offset']
247
Rupert Swarbrickce970752020-09-18 12:09:24 +0100248 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100249 link_pc = (state.pc + 4) & ((1 << 32) - 1)
250 state.gprs.get_reg(self.grd).write_unsigned(link_pc)
Rupert Swarbrickce970752020-09-18 12:09:24 +0100251 state.pc_next = self.offset
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100252
253
254class JALR(OTBNInsn):
255 insn = insn_for_mnemonic('jalr', 3)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000256 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100257
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000258 def __init__(self, raw: int, op_vals: Dict[str, int]):
259 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100260 self.grd = op_vals['grd']
261 self.grs1 = op_vals['grs1']
262 self.offset = op_vals['offset']
263
Rupert Swarbrickce970752020-09-18 12:09:24 +0100264 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100265 val1 = state.gprs.get_reg(self.grs1).read_unsigned()
266 link_pc = (state.pc + 4) & ((1 << 32) - 1)
267
268 state.gprs.get_reg(self.grd).write_unsigned(link_pc)
269 state.pc_next = (val1 + self.offset) & ((1 << 32) - 1)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100270
271
272class CSRRS(OTBNInsn):
273 insn = insn_for_mnemonic('csrrs', 3)
274
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000275 def __init__(self, raw: int, op_vals: Dict[str, int]):
276 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100277 self.grd = op_vals['grd']
278 self.csr = op_vals['csr']
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100279 self.grs1 = op_vals['grs1']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100280
Rupert Swarbrickce970752020-09-18 12:09:24 +0100281 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100282 old_val = state.read_csr(self.csr)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100283 bits_to_set = state.gprs.get_reg(self.grs1).read_unsigned()
284 new_val = old_val | bits_to_set
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100285
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100286 state.gprs.get_reg(self.grd).write_unsigned(old_val)
287 state.write_csr(self.csr, new_val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100288
289
290class CSRRW(OTBNInsn):
291 insn = insn_for_mnemonic('csrrw', 3)
292
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000293 def __init__(self, raw: int, op_vals: Dict[str, int]):
294 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100295 self.grd = op_vals['grd']
296 self.csr = op_vals['csr']
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100297 self.grs1 = op_vals['grs1']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100298
Rupert Swarbrickce970752020-09-18 12:09:24 +0100299 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100300 new_val = state.gprs.get_reg(self.grs1).read_unsigned()
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100301
Rupert Swarbrickb35a77d2020-10-01 17:44:25 +0100302 if self.grd != 0:
303 old_val = state.read_csr(self.csr)
304 state.gprs.get_reg(self.grd).write_unsigned(old_val)
305
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100306 state.write_csr(self.csr, new_val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100307
308
309class ECALL(OTBNInsn):
310 insn = insn_for_mnemonic('ecall', 0)
311
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000312 def __init__(self, raw: int, op_vals: Dict[str, int]):
313 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100314 pass
315
Rupert Swarbrickce970752020-09-18 12:09:24 +0100316 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick18cb5e22020-11-19 13:03:44 +0000317 # Set INTR_STATE.done and STATUS, reflecting the fact we've stopped.
Rupert Swarbrick0b60b5d2021-01-27 16:16:57 +0000318 state._stop(ERR_CODE_NO_ERROR)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100319
320
321class LOOP(OTBNInsn):
322 insn = insn_for_mnemonic('loop', 2)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000323 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100324
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000325 def __init__(self, raw: int, op_vals: Dict[str, int]):
326 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100327 self.grs = op_vals['grs']
328 self.bodysize = op_vals['bodysize']
329
Rupert Swarbrickce970752020-09-18 12:09:24 +0100330 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100331 num_iters = state.gprs.get_reg(self.grs).read_unsigned()
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000332 if num_iters == 0:
Rupert Swarbrick0b60b5d2021-01-27 16:16:57 +0000333 state.on_error(LoopError('loop count in x{} was zero'
334 .format(self.grs)))
335 return
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000336
Rupert Swarbrickce970752020-09-18 12:09:24 +0100337 state.loop_start(num_iters, self.bodysize)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100338
339
340class LOOPI(OTBNInsn):
341 insn = insn_for_mnemonic('loopi', 2)
Rupert Swarbrickfb6692e2020-12-07 11:51:32 +0000342 affects_control = True
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100343
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000344 def __init__(self, raw: int, op_vals: Dict[str, int]):
345 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100346 self.iterations = op_vals['iterations']
347 self.bodysize = op_vals['bodysize']
348
Rupert Swarbrickce970752020-09-18 12:09:24 +0100349 def execute(self, state: OTBNState) -> None:
350 state.loop_start(self.iterations, self.bodysize)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100351
352
353class BNADD(OTBNInsn):
354 insn = insn_for_mnemonic('bn.add', 6)
355
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000356 def __init__(self, raw: int, op_vals: Dict[str, int]):
357 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100358 self.wrd = op_vals['wrd']
359 self.wrs1 = op_vals['wrs1']
360 self.wrs2 = op_vals['wrs2']
361 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000362 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100363 self.flag_group = op_vals['flag_group']
364
Rupert Swarbrickce970752020-09-18 12:09:24 +0100365 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100366 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
367 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
368 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
369
Rupert Swarbrickce970752020-09-18 12:09:24 +0100370 (result, flags) = state.add_with_carry(a, b_shifted, 0)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100371 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100372 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200373
374
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100375class BNADDC(OTBNInsn):
376 insn = insn_for_mnemonic('bn.addc', 6)
377
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000378 def __init__(self, raw: int, op_vals: Dict[str, int]):
379 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100380 self.wrd = op_vals['wrd']
381 self.wrs1 = op_vals['wrs1']
382 self.wrs2 = op_vals['wrs2']
383 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000384 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100385 self.flag_group = op_vals['flag_group']
386
Rupert Swarbrickce970752020-09-18 12:09:24 +0100387 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100388 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
389 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
390 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
391
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100392 carry = int(state.csrs.flags[self.flag_group].C)
393 (result, flags) = state.add_with_carry(a, b_shifted, carry)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100394 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100395 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200396
397
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100398class BNADDI(OTBNInsn):
399 insn = insn_for_mnemonic('bn.addi', 4)
400
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000401 def __init__(self, raw: int, op_vals: Dict[str, int]):
402 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100403 self.wrd = op_vals['wrd']
404 self.wrs = op_vals['wrs']
405 self.imm = op_vals['imm']
406 self.flag_group = op_vals['flag_group']
407
Rupert Swarbrickce970752020-09-18 12:09:24 +0100408 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100409 a = state.wdrs.get_reg(self.wrs).read_unsigned()
410 b = self.imm
411
Rupert Swarbrickce970752020-09-18 12:09:24 +0100412 (result, flags) = state.add_with_carry(a, b, 0)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100413 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100414 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200415
416
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100417class BNADDM(OTBNInsn):
418 insn = insn_for_mnemonic('bn.addm', 3)
419
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000420 def __init__(self, raw: int, op_vals: Dict[str, int]):
421 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100422 self.wrd = op_vals['wrd']
423 self.wrs1 = op_vals['wrs1']
424 self.wrs2 = op_vals['wrs2']
425
Rupert Swarbrickce970752020-09-18 12:09:24 +0100426 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100427 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
428 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
Rupert Swarbrick840e3292020-10-02 08:43:18 +0100429 result = a + b
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100430
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100431 mod_val = state.wsrs.MOD.read_unsigned()
432 if result >= mod_val:
433 result -= mod_val
434
Rupert Swarbrick840e3292020-10-02 08:43:18 +0100435 result = result & ((1 << 256) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100436 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200437
438
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100439class BNMULQACC(OTBNInsn):
440 insn = insn_for_mnemonic('bn.mulqacc', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200441
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000442 def __init__(self, raw: int, op_vals: Dict[str, int]):
443 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100444 self.zero_acc = op_vals['zero_acc']
445 self.wrs1 = op_vals['wrs1']
446 self.wrs1_qwsel = op_vals['wrs1_qwsel']
447 self.wrs2 = op_vals['wrs2']
448 self.wrs2_qwsel = op_vals['wrs2_qwsel']
449 self.acc_shift_imm = op_vals['acc_shift_imm']
450
Rupert Swarbrickce970752020-09-18 12:09:24 +0100451 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100452 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
453 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200454
455 mul_res = a_qw * b_qw
456
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100457 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100458 if self.zero_acc:
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200459 acc = 0
460
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100461 acc += (mul_res << self.acc_shift_imm)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200462
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100463 truncated = acc & ((1 << 256) - 1)
464 state.wsrs.ACC.write_unsigned(truncated)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200465
466
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100467class BNMULQACCWO(OTBNInsn):
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000468 insn = insn_for_mnemonic('bn.mulqacc.wo', 8)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100469
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000470 def __init__(self, raw: int, op_vals: Dict[str, int]):
471 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100472 self.zero_acc = op_vals['zero_acc']
473 self.wrd = op_vals['wrd']
474 self.wrs1 = op_vals['wrs1']
475 self.wrs1_qwsel = op_vals['wrs1_qwsel']
476 self.wrs2 = op_vals['wrs2']
477 self.wrs2_qwsel = op_vals['wrs2_qwsel']
478 self.acc_shift_imm = op_vals['acc_shift_imm']
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000479 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100480
Rupert Swarbrickce970752020-09-18 12:09:24 +0100481 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100482 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
483 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100484
485 mul_res = a_qw * b_qw
486
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100487 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100488 if self.zero_acc:
489 acc = 0
490
491 acc += (mul_res << self.acc_shift_imm)
492
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100493 truncated = acc & ((1 << 256) - 1)
494 state.wdrs.get_reg(self.wrd).write_unsigned(truncated)
495 state.wsrs.ACC.write_unsigned(truncated)
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000496 state.set_mlz_flags(self.flag_group, truncated)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100497
498
499class BNMULQACCSO(OTBNInsn):
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000500 insn = insn_for_mnemonic('bn.mulqacc.so', 9)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100501
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000502 def __init__(self, raw: int, op_vals: Dict[str, int]):
503 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100504 self.zero_acc = op_vals['zero_acc']
505 self.wrd = op_vals['wrd']
506 self.wrd_hwsel = op_vals['wrd_hwsel']
507 self.wrs1 = op_vals['wrs1']
508 self.wrs1_qwsel = op_vals['wrs1_qwsel']
509 self.wrs2 = op_vals['wrs2']
510 self.wrs2_qwsel = op_vals['wrs2_qwsel']
511 self.acc_shift_imm = op_vals['acc_shift_imm']
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000512 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100513
Rupert Swarbrickce970752020-09-18 12:09:24 +0100514 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100515 a_qw = state.get_quarter_word_unsigned(self.wrs1, self.wrs1_qwsel)
516 b_qw = state.get_quarter_word_unsigned(self.wrs2, self.wrs2_qwsel)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100517
518 mul_res = a_qw * b_qw
519
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100520 acc = state.wsrs.ACC.read_unsigned()
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100521 if self.zero_acc:
522 acc = 0
523
524 acc += (mul_res << self.acc_shift_imm)
Rupert Swarbrick8c9947a2021-01-04 11:40:26 +0000525 truncated = acc & ((1 << 256) - 1)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100526
Rupert Swarbrick8c9947a2021-01-04 11:40:26 +0000527 lo_part = truncated & ((1 << 128) - 1)
528 hi_part = truncated >> 128
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100529
Felix Millerb57138e2020-09-28 22:24:39 +0200530 state.set_half_word_unsigned(self.wrd, self.wrd_hwsel, lo_part)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100531 state.wsrs.ACC.write_unsigned(hi_part)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100532
Rupert Swarbrick8e016022020-11-19 16:59:02 +0000533 old_flags = state.csrs.flags[self.flag_group]
534 if self.wrd_hwsel:
535 new_flags = FlagReg(C=old_flags.C,
536 M=bool((lo_part >> 127) & 1),
537 L=old_flags.L,
538 Z=old_flags.Z and lo_part == 0)
539 else:
540 new_flags = FlagReg(C=old_flags.C,
541 M=old_flags.M,
542 L=bool(lo_part & 1),
543 Z=lo_part == 0)
544 state.csrs.flags[self.flag_group] = new_flags
545
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100546
547class BNSUB(OTBNInsn):
548 insn = insn_for_mnemonic('bn.sub', 6)
549
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000550 def __init__(self, raw: int, op_vals: Dict[str, int]):
551 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100552 self.wrd = op_vals['wrd']
553 self.wrs1 = op_vals['wrs1']
554 self.wrs2 = op_vals['wrs2']
555 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000556 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100557 self.flag_group = op_vals['flag_group']
558
Rupert Swarbrickce970752020-09-18 12:09:24 +0100559 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100560 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
561 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
562 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
563
564 (result, flags) = state.sub_with_borrow(a, b_shifted, 0)
565 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100566 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200567
568
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100569class BNSUBB(OTBNInsn):
570 insn = insn_for_mnemonic('bn.subb', 6)
571
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000572 def __init__(self, raw: int, op_vals: Dict[str, int]):
573 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100574 self.wrd = op_vals['wrd']
575 self.wrs1 = op_vals['wrs1']
576 self.wrs2 = op_vals['wrs2']
577 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000578 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100579 self.flag_group = op_vals['flag_group']
580
Rupert Swarbrickce970752020-09-18 12:09:24 +0100581 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100582 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
583 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
584 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100585 borrow = int(state.csrs.flags[self.flag_group].C)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100586
587 (result, flags) = state.sub_with_borrow(a, b_shifted, borrow)
588 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100589 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200590
591
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100592class BNSUBI(OTBNInsn):
593 insn = insn_for_mnemonic('bn.subi', 4)
594
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000595 def __init__(self, raw: int, op_vals: Dict[str, int]):
596 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100597 self.wrd = op_vals['wrd']
598 self.wrs = op_vals['wrs']
599 self.imm = op_vals['imm']
600 self.flag_group = op_vals['flag_group']
601
Rupert Swarbrickce970752020-09-18 12:09:24 +0100602 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100603 a = state.wdrs.get_reg(self.wrs).read_unsigned()
604 b = self.imm
605
606 (result, flags) = state.sub_with_borrow(a, b, 0)
607 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100608 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200609
610
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100611class BNSUBM(OTBNInsn):
612 insn = insn_for_mnemonic('bn.subm', 3)
613
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000614 def __init__(self, raw: int, op_vals: Dict[str, int]):
615 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100616 self.wrd = op_vals['wrd']
617 self.wrs1 = op_vals['wrs1']
618 self.wrs2 = op_vals['wrs2']
619
Rupert Swarbrickce970752020-09-18 12:09:24 +0100620 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100621 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
622 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
623
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100624 mod_val = state.wsrs.MOD.read_unsigned()
625
Rupert Swarbrick31ffc1d2020-10-02 10:13:55 +0100626 diff = a - b
627 if diff < 0:
628 diff += mod_val
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100629
Rupert Swarbrick31ffc1d2020-10-02 10:13:55 +0100630 result = diff & ((1 << 256) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100631 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200632
633
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100634class BNAND(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100635 insn = insn_for_mnemonic('bn.and', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200636
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000637 def __init__(self, raw: int, op_vals: Dict[str, int]):
638 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100639 self.wrd = op_vals['wrd']
640 self.wrs1 = op_vals['wrs1']
641 self.wrs2 = op_vals['wrs2']
642 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000643 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100644 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100645
Rupert Swarbrickce970752020-09-18 12:09:24 +0100646 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100647 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
648 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
649 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
650
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100651 result = a & b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100652 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100653 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200654
655
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100656class BNOR(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100657 insn = insn_for_mnemonic('bn.or', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200658
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000659 def __init__(self, raw: int, op_vals: Dict[str, int]):
660 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100661 self.wrd = op_vals['wrd']
662 self.wrs1 = op_vals['wrs1']
663 self.wrs2 = op_vals['wrs2']
664 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000665 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100666 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100667
Rupert Swarbrickce970752020-09-18 12:09:24 +0100668 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100669 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
670 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
671 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
672
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100673 result = a | b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100674 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100675 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200676
677
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100678class BNNOT(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100679 insn = insn_for_mnemonic('bn.not', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200680
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000681 def __init__(self, raw: int, op_vals: Dict[str, int]):
682 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100683 self.wrd = op_vals['wrd']
684 self.wrs = op_vals['wrs']
685 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000686 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100687 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100688
Rupert Swarbrickce970752020-09-18 12:09:24 +0100689 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100690 a = state.wdrs.get_reg(self.wrs).read_unsigned()
691 a_shifted = logical_byte_shift(a, self.shift_type, self.shift_bytes)
692
693 result = a_shifted ^ ((1 << 256) - 1)
694 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100695 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200696
697
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100698class BNXOR(OTBNInsn):
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100699 insn = insn_for_mnemonic('bn.xor', 6)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200700
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000701 def __init__(self, raw: int, op_vals: Dict[str, int]):
702 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100703 self.wrd = op_vals['wrd']
704 self.wrs1 = op_vals['wrs1']
705 self.wrs2 = op_vals['wrs2']
706 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000707 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrick2398dc12020-09-23 10:06:45 +0100708 self.flag_group = op_vals['flag_group']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100709
Rupert Swarbrickce970752020-09-18 12:09:24 +0100710 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100711 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
712 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
713 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
714
Rupert Swarbricke53d8fe2020-09-21 15:32:51 +0100715 result = a ^ b_shifted
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100716 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100717 state.set_mlz_flags(self.flag_group, result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200718
719
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100720class BNRSHI(OTBNInsn):
721 insn = insn_for_mnemonic('bn.rshi', 4)
722
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000723 def __init__(self, raw: int, op_vals: Dict[str, int]):
724 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100725 self.wrd = op_vals['wrd']
726 self.wrs1 = op_vals['wrs1']
727 self.wrs2 = op_vals['wrs2']
728 self.imm = op_vals['imm']
729
Rupert Swarbrickce970752020-09-18 12:09:24 +0100730 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100731 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
732 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
733
734 result = (((a << 256) | b) >> self.imm) & ((1 << 256) - 1)
735 state.wdrs.get_reg(self.wrd).write_unsigned(result)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200736
737
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100738class BNRSEL(OTBNInsn):
739 insn = insn_for_mnemonic('bn.sel', 5)
740
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000741 def __init__(self, raw: int, op_vals: Dict[str, int]):
742 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100743 self.wrd = op_vals['wrd']
744 self.wrs1 = op_vals['wrs1']
745 self.wrs2 = op_vals['wrs2']
746 self.flag_group = op_vals['flag_group']
747 self.flag = op_vals['flag']
748
Rupert Swarbrickce970752020-09-18 12:09:24 +0100749 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100750 flag_is_set = state.csrs.flags[self.flag_group].get_by_idx(self.flag)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100751 wrs = self.wrs1 if flag_is_set else self.wrs2
752 value = state.wdrs.get_reg(wrs).read_unsigned()
753 state.wdrs.get_reg(self.wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200754
755
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100756class BNCMP(OTBNInsn):
757 insn = insn_for_mnemonic('bn.cmp', 5)
758
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000759 def __init__(self, raw: int, op_vals: Dict[str, int]):
760 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100761 self.wrs1 = op_vals['wrs1']
762 self.wrs2 = op_vals['wrs2']
763 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000764 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100765 self.flag_group = op_vals['flag_group']
766
Rupert Swarbrickce970752020-09-18 12:09:24 +0100767 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100768 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
769 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
770 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
771
772 (_, flags) = state.sub_with_borrow(a, b_shifted, 0)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100773 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200774
775
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100776class BNCMPB(OTBNInsn):
777 insn = insn_for_mnemonic('bn.cmpb', 5)
778
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000779 def __init__(self, raw: int, op_vals: Dict[str, int]):
780 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100781 self.wrs1 = op_vals['wrs1']
782 self.wrs2 = op_vals['wrs2']
783 self.shift_type = op_vals['shift_type']
Rupert Swarbrick30a9c2f2020-12-08 09:28:14 +0000784 self.shift_bytes = op_vals['shift_bits'] // 8
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100785 self.flag_group = op_vals['flag_group']
786
Rupert Swarbrickce970752020-09-18 12:09:24 +0100787 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100788 a = state.wdrs.get_reg(self.wrs1).read_unsigned()
789 b = state.wdrs.get_reg(self.wrs2).read_unsigned()
790 b_shifted = logical_byte_shift(b, self.shift_type, self.shift_bytes)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100791 borrow = int(state.csrs.flags[self.flag_group].C)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100792
793 (_, flags) = state.sub_with_borrow(a, b_shifted, borrow)
Rupert Swarbrick2f6cc462020-09-24 15:19:41 +0100794 state.set_flags(self.flag_group, flags)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200795
796
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100797class BNLID(OTBNInsn):
798 insn = insn_for_mnemonic('bn.lid', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200799
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000800 def __init__(self, raw: int, op_vals: Dict[str, int]):
801 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100802 self.grd = op_vals['grd']
803 self.grd_inc = op_vals['grd_inc']
804 self.offset = op_vals['offset']
805 self.grs1 = op_vals['grs1']
806 self.grs1_inc = op_vals['grs1_inc']
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200807
Rupert Swarbrickc1bf4912021-01-22 11:42:51 +0000808 if self.grd_inc and self.grs1_inc:
809 raise DecodeError('grd_inc and grs1_inc both set')
810
Rupert Swarbrickce970752020-09-18 12:09:24 +0100811 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100812 grs1_val = state.gprs.get_reg(self.grs1).read_unsigned()
813 addr = (grs1_val + self.offset) & ((1 << 32) - 1)
814 grd_val = state.gprs.get_reg(self.grd).read_unsigned()
815
816 wrd = grd_val & 0x1f
817 value = state.dmem.load_u256(addr)
818 state.wdrs.get_reg(wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200819
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100820 if self.grd_inc:
Rupert Swarbrick9ea7ad42020-09-28 17:37:04 +0100821 new_grd_val = (grd_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100822 state.gprs.get_reg(self.grd).write_unsigned(new_grd_val)
823
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100824 if self.grs1_inc:
Felix Miller05616102020-10-06 00:13:44 +0200825 new_grs1_val = (grs1_val + 32) & ((1 << 32) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100826 state.gprs.get_reg(self.grs1).write_unsigned(new_grs1_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200827
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200828
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100829class BNSID(OTBNInsn):
830 insn = insn_for_mnemonic('bn.sid', 5)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200831
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000832 def __init__(self, raw: int, op_vals: Dict[str, int]):
833 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100834 self.grs2 = op_vals['grs2']
835 self.grs2_inc = op_vals['grs2_inc']
836 self.offset = op_vals['offset']
837 self.grs1 = op_vals['grs1']
838 self.grs1_inc = op_vals['grs1_inc']
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200839
Rupert Swarbrickc1bf4912021-01-22 11:42:51 +0000840 if self.grs1_inc and self.grs2_inc:
841 raise DecodeError('grs1_inc and grs2_inc both set')
842
Rupert Swarbrickce970752020-09-18 12:09:24 +0100843 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100844 grs1_val = state.gprs.get_reg(self.grs1).read_unsigned()
845 addr = (grs1_val + self.offset) & ((1 << 32) - 1)
Rupert Swarbrick992f0b92020-09-08 12:24:52 +0100846
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100847 grs2_val = state.gprs.get_reg(self.grs2).read_unsigned()
848 wrs = grs2_val & 0x1f
849 wrs_val = state.wdrs.get_reg(wrs).read_unsigned()
850
851 state.dmem.store_u256(addr, wrs_val)
852
853 if self.grs1_inc:
Felix Miller05616102020-10-06 00:13:44 +0200854 new_grs1_val = (grs1_val + 32) & ((1 << 32) - 1)
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100855 state.gprs.get_reg(self.grs1).write_unsigned(new_grs1_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200856
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100857 if self.grs2_inc:
Rupert Swarbrick9ea7ad42020-09-28 17:37:04 +0100858 new_grs2_val = (grs2_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100859 state.gprs.get_reg(self.grs2).write_unsigned(new_grs2_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200860
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100861
862class BNMOV(OTBNInsn):
863 insn = insn_for_mnemonic('bn.mov', 2)
864
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000865 def __init__(self, raw: int, op_vals: Dict[str, int]):
866 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100867 self.wrd = op_vals['wrd']
868 self.wrs = op_vals['wrs']
869
Rupert Swarbrickce970752020-09-18 12:09:24 +0100870 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100871 value = state.wdrs.get_reg(self.wrs).read_unsigned()
872 state.wdrs.get_reg(self.wrd).write_unsigned(value)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200873
874
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100875class BNMOVR(OTBNInsn):
876 insn = insn_for_mnemonic('bn.movr', 4)
877
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000878 def __init__(self, raw: int, op_vals: Dict[str, int]):
879 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100880 self.grd = op_vals['grd']
881 self.grd_inc = op_vals['grd_inc']
882 self.grs = op_vals['grs']
883 self.grs_inc = op_vals['grs_inc']
884
Rupert Swarbrickc1bf4912021-01-22 11:42:51 +0000885 if self.grd_inc and self.grs_inc:
886 raise DecodeError('grd_inc and grs_inc both set')
887
Rupert Swarbrickce970752020-09-18 12:09:24 +0100888 def execute(self, state: OTBNState) -> None:
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100889 grd_val = state.gprs.get_reg(self.grd).read_unsigned()
890 grs_val = state.gprs.get_reg(self.grs).read_unsigned()
891
892 wrd = grd_val & 0x1f
893 wrs = grs_val & 0x1f
894
895 value = state.wdrs.get_reg(wrs).read_unsigned()
896 state.wdrs.get_reg(wrd).write_unsigned(value)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100897
898 if self.grd_inc:
Rupert Swarbrick6e95ec62021-01-05 17:06:24 +0000899 new_grd_val = (grd_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100900 state.gprs.get_reg(self.grd).write_unsigned(new_grd_val)
901
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100902 if self.grs_inc:
Rupert Swarbrick6e95ec62021-01-05 17:06:24 +0000903 new_grs_val = (grs_val + 1) & 0x1f
Rupert Swarbrick7ffe17d2020-09-25 15:23:04 +0100904 state.gprs.get_reg(self.grs).write_unsigned(new_grs_val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200905
906
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000907class BNWSRR(OTBNInsn):
908 insn = insn_for_mnemonic('bn.wsrr', 2)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100909
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000910 def __init__(self, raw: int, op_vals: Dict[str, int]):
911 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100912 self.wrd = op_vals['wrd']
913 self.wsr = op_vals['wsr']
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100914
Rupert Swarbrickce970752020-09-18 12:09:24 +0100915 def execute(self, state: OTBNState) -> None:
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000916 val = state.wsrs.read_at_idx(self.wsr)
917 state.wdrs.get_reg(self.wrd).write_unsigned(val)
Stefan Wallentowitz0731d512020-07-14 21:55:14 +0200918
919
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000920class BNWSRW(OTBNInsn):
921 insn = insn_for_mnemonic('bn.wsrw', 2)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100922
Rupert Swarbrick660baa92020-12-15 17:00:55 +0000923 def __init__(self, raw: int, op_vals: Dict[str, int]):
924 super().__init__(raw, op_vals)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100925 self.wsr = op_vals['wsr']
926 self.wrs = op_vals['wrs']
927
Rupert Swarbrickce970752020-09-18 12:09:24 +0100928 def execute(self, state: OTBNState) -> None:
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000929 val = state.wdrs.get_reg(self.wrs).read_unsigned()
930 state.wsrs.write_at_idx(self.wsr, val)
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100931
932
933INSN_CLASSES = [
934 ADD, ADDI, LUI, SUB, SLL, SLLI, SRL, SRLI, SRA, SRAI,
935 AND, ANDI, OR, ORI, XOR, XORI,
936 LW, SW,
937 BEQ, BNE, JAL, JALR,
938 CSRRS, CSRRW,
939 ECALL,
940 LOOP, LOOPI,
941
942 BNADD, BNADDC, BNADDI, BNADDM,
943 BNMULQACC, BNMULQACCWO, BNMULQACCSO,
944 BNSUB, BNSUBB, BNSUBI, BNSUBM,
945 BNAND, BNOR, BNNOT, BNXOR,
946 BNRSHI,
947 BNRSEL,
948 BNCMP, BNCMPB,
949 BNLID, BNSID,
950 BNMOV, BNMOVR,
Rupert Swarbricka2c05e72020-11-20 08:46:25 +0000951 BNWSRR, BNWSRW
Rupert Swarbrickaadb1e32020-08-28 17:16:28 +0100952]