1use super::{
2 super::{machine::Machine, Error},
3 common, extract_opcode, instruction_length,
4 utils::update_register,
5 Instruction, InstructionOpcode, Itype, R4type, R5type, Register, Rtype, Stype, Utype,
6};
7use crate::memory::Memory;
8use ckb_vm_definitions::{
9 for_each_inst_array1, for_each_inst_match2,
10 instructions::{self as insts, paste},
11 registers::RA,
12};
13
14pub fn handle_sub<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
15 let i = Rtype(inst);
16 common::sub(machine, i.rd(), i.rs1(), i.rs2());
17 Ok(())
18}
19
20pub fn handle_subw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
21 let i = Rtype(inst);
22 common::subw(machine, i.rd(), i.rs1(), i.rs2());
23 Ok(())
24}
25
26pub fn handle_add<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
27 let i = Rtype(inst);
28 common::add(machine, i.rd(), i.rs1(), i.rs2());
29 Ok(())
30}
31
32pub fn handle_addw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
33 let i = Rtype(inst);
34 common::addw(machine, i.rd(), i.rs1(), i.rs2());
35 Ok(())
36}
37
38pub fn handle_xor<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
39 let i = Rtype(inst);
40 common::xor(machine, i.rd(), i.rs1(), i.rs2());
41 Ok(())
42}
43
44pub fn handle_or<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
45 let i = Rtype(inst);
46 common::or(machine, i.rd(), i.rs1(), i.rs2());
47 Ok(())
48}
49
50pub fn handle_and<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
51 let i = Rtype(inst);
52 common::and(machine, i.rd(), i.rs1(), i.rs2());
53 Ok(())
54}
55
56pub fn handle_sll<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
57 let i = Rtype(inst);
58 let shift_value =
59 machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
60 let value = machine.registers()[i.rs1()].clone() << shift_value;
61 update_register(machine, i.rd(), value);
62
63 Ok(())
64}
65
66pub fn handle_sllw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
67 let i = Rtype(inst);
68 let shift_value = machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(0x1F);
69 let value = machine.registers()[i.rs1()].clone() << shift_value;
70 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
71 Ok(())
72}
73
74pub fn handle_srl<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
75 let i = Rtype(inst);
76 let shift_value =
77 machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
78 let value = machine.registers()[i.rs1()].clone() >> shift_value;
79 update_register(machine, i.rd(), value);
80 Ok(())
81}
82
83pub fn handle_srlw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
84 let i = Rtype(inst);
85 let shift_value = machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(0x1F);
86 let value = machine.registers()[i.rs1()].zero_extend(&Mac::REG::from_u8(32)) >> shift_value;
87 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
88 Ok(())
89}
90
91pub fn handle_sra<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
92 let i = Rtype(inst);
93 let shift_value =
94 machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
95 let value = machine.registers()[i.rs1()].signed_shr(&shift_value);
96 update_register(machine, i.rd(), value);
97 Ok(())
98}
99
100pub fn handle_sraw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
101 let i = Rtype(inst);
102 let shift_value = machine.registers()[i.rs2()].clone() & Mac::REG::from_u8(0x1F);
103 let value = machine.registers()[i.rs1()]
104 .sign_extend(&Mac::REG::from_u8(32))
105 .signed_shr(&shift_value);
106 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
107 Ok(())
108}
109
110pub fn handle_slt<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
111 let i = Rtype(inst);
112 let rs1_value = &machine.registers()[i.rs1()];
113 let rs2_value = &machine.registers()[i.rs2()];
114 let value = rs1_value.lt_s(rs2_value);
115 update_register(machine, i.rd(), value);
116 Ok(())
117}
118
119pub fn handle_sltu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
120 let i = Rtype(inst);
121 let rs1_value = &machine.registers()[i.rs1()];
122 let rs2_value = &machine.registers()[i.rs2()];
123 let value = rs1_value.lt(rs2_value);
124 update_register(machine, i.rd(), value);
125 Ok(())
126}
127
128pub fn handle_lb_version0<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
129 let i = Itype(inst);
130 common::lb(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
131 Ok(())
132}
133
134pub fn handle_lb_version1<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
135 let i = Itype(inst);
136 common::lb(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
137 Ok(())
138}
139
140pub fn handle_lh_version0<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
141 let i = Itype(inst);
142 common::lh(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
143 Ok(())
144}
145
146pub fn handle_lh_version1<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
147 let i = Itype(inst);
148 common::lh(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
149 Ok(())
150}
151
152pub fn handle_lw_version0<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
153 let i = Itype(inst);
154 common::lw(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
155 Ok(())
156}
157
158pub fn handle_lw_version1<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
159 let i = Itype(inst);
160 common::lw(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
161 Ok(())
162}
163
164pub fn handle_ld_version0<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
165 let i = Itype(inst);
166 common::ld(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
167 Ok(())
168}
169
170pub fn handle_ld_version1<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
171 let i = Itype(inst);
172 common::ld(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
173 Ok(())
174}
175
176pub fn handle_lbu_version0<Mac: Machine>(
177 machine: &mut Mac,
178 inst: Instruction,
179) -> Result<(), Error> {
180 let i = Itype(inst);
181 common::lbu(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
182 Ok(())
183}
184
185pub fn handle_lbu_version1<Mac: Machine>(
186 machine: &mut Mac,
187 inst: Instruction,
188) -> Result<(), Error> {
189 let i = Itype(inst);
190 common::lbu(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
191 Ok(())
192}
193
194pub fn handle_lhu_version0<Mac: Machine>(
195 machine: &mut Mac,
196 inst: Instruction,
197) -> Result<(), Error> {
198 let i = Itype(inst);
199 common::lhu(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
200 Ok(())
201}
202
203pub fn handle_lhu_version1<Mac: Machine>(
204 machine: &mut Mac,
205 inst: Instruction,
206) -> Result<(), Error> {
207 let i = Itype(inst);
208 common::lhu(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
209 Ok(())
210}
211
212pub fn handle_lwu_version0<Mac: Machine>(
213 machine: &mut Mac,
214 inst: Instruction,
215) -> Result<(), Error> {
216 let i = Itype(inst);
217 common::lwu(machine, i.rd(), i.rs1(), i.immediate_s(), true)?;
218 Ok(())
219}
220
221pub fn handle_lwu_version1<Mac: Machine>(
222 machine: &mut Mac,
223 inst: Instruction,
224) -> Result<(), Error> {
225 let i = Itype(inst);
226 common::lwu(machine, i.rd(), i.rs1(), i.immediate_s(), false)?;
227 Ok(())
228}
229
230pub fn handle_addi<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
231 let i = Itype(inst);
232 common::addi(machine, i.rd(), i.rs1(), i.immediate_s());
233 Ok(())
234}
235
236pub fn handle_addiw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
237 let i = Itype(inst);
238 common::addiw(machine, i.rd(), i.rs1(), i.immediate_s());
239 Ok(())
240}
241
242pub fn handle_xori<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
243 let i = Itype(inst);
244 common::xori(machine, i.rd(), i.rs1(), i.immediate_s());
245 Ok(())
246}
247
248pub fn handle_lr_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
249 let i = Rtype(inst);
250 let address = machine.registers()[i.rs1()].clone();
251 let value = machine.memory_mut().load32(&address)?;
252 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
253 machine.memory_mut().set_lr(&address);
254 Ok(())
255}
256
257pub fn handle_sc_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
258 let i = Rtype(inst);
259 let address = machine.registers()[i.rs1()].clone();
260 let condition = address.eq(machine.memory().lr());
261 let mem_value = condition.cond(
262 &machine.registers()[i.rs2()].clone(),
263 &machine.memory_mut().load32(&address)?,
264 );
265 let rd_value = condition.cond(&Mac::REG::from_u8(0), &Mac::REG::from_u8(1));
266 machine.memory_mut().store32(&address, &mem_value)?;
267 update_register(machine, i.rd(), rd_value);
268 machine.memory_mut().set_lr(&Mac::REG::from_u64(u64::MAX));
269 Ok(())
270}
271
272pub fn handle_amoswap_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
273 let i = Rtype(inst);
274 let rs1_value = machine.registers()[i.rs1()].clone();
275 let rs2_value = machine.registers()[i.rs2()].clone();
276 let mem_value = machine.memory_mut().load32(&rs1_value)?;
277 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
278 update_register(machine, i.rd(), mem_value);
279 machine.memory_mut().store32(&rs1_value, &rs2_value)?;
280 Ok(())
281}
282
283pub fn handle_amoadd_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
284 let i = Rtype(inst);
285 let rs1_value = machine.registers()[i.rs1()].clone();
286 let rs2_value = machine.registers()[i.rs2()].clone();
287 let mem_value = machine.memory_mut().load32(&rs1_value)?;
288 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
289 update_register(machine, i.rd(), mem_value.clone());
290 let mem_value = rs2_value.overflowing_add(&mem_value);
291 machine.memory_mut().store32(&rs1_value, &mem_value)?;
292 Ok(())
293}
294
295pub fn handle_amoxor_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
296 let i = Rtype(inst);
297 let rs1_value = machine.registers()[i.rs1()].clone();
298 let rs2_value = machine.registers()[i.rs2()].clone();
299 let mem_value = machine.memory_mut().load32(&rs1_value)?;
300 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
301 update_register(machine, i.rd(), mem_value.clone());
302 let mem_value = rs2_value ^ mem_value;
303 machine.memory_mut().store32(&rs1_value, &mem_value)?;
304 Ok(())
305}
306
307pub fn handle_amoand_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
308 let i = Rtype(inst);
309 let rs1_value = machine.registers()[i.rs1()].clone();
310 let rs2_value = machine.registers()[i.rs2()].clone();
311 let mem_value = machine.memory_mut().load32(&rs1_value)?;
312 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
313 update_register(machine, i.rd(), mem_value.clone());
314 let mem_value = rs2_value & mem_value;
315 machine.memory_mut().store32(&rs1_value, &mem_value)?;
316 Ok(())
317}
318
319pub fn handle_amoor_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
320 let i = Rtype(inst);
321 let rs1_value = machine.registers()[i.rs1()].clone();
322 let rs2_value = machine.registers()[i.rs2()].clone();
323 let mem_value = machine.memory_mut().load32(&rs1_value)?;
324 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
325 update_register(machine, i.rd(), mem_value.clone());
326 let mem_value = rs2_value | mem_value;
327 machine.memory_mut().store32(&rs1_value, &mem_value)?;
328 Ok(())
329}
330
331pub fn handle_amomin_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
332 let i = Rtype(inst);
333 let rs1_value = machine.registers()[i.rs1()].clone();
334 let rs2_value = machine.registers()[i.rs2()].sign_extend(&Mac::REG::from_u8(32));
335 let mem_value = machine.memory_mut().load32(&rs1_value)?;
336 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
337 update_register(machine, i.rd(), mem_value.clone());
338 let mem_value = rs2_value.lt_s(&mem_value).cond(&rs2_value, &mem_value);
339 machine.memory_mut().store32(&rs1_value, &mem_value)?;
340 Ok(())
341}
342
343pub fn handle_amomax_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
344 let i = Rtype(inst);
345 let rs1_value = machine.registers()[i.rs1()].clone();
346 let rs2_value = machine.registers()[i.rs2()].sign_extend(&Mac::REG::from_u8(32));
347 let mem_value = machine.memory_mut().load32(&rs1_value)?;
348 let mem_value = mem_value.sign_extend(&Mac::REG::from_u8(32));
349 update_register(machine, i.rd(), mem_value.clone());
350 let mem_value = rs2_value.ge_s(&mem_value).cond(&rs2_value, &mem_value);
351 machine.memory_mut().store32(&rs1_value, &mem_value)?;
352 Ok(())
353}
354
355pub fn handle_amominu_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
356 let i = Rtype(inst);
357 let rs1_value = machine.registers()[i.rs1()].clone();
358 let rs2_value = machine.registers()[i.rs2()].zero_extend(&Mac::REG::from_u8(32));
359 let mem_value = machine.memory_mut().load32(&rs1_value)?;
360 let mem_value_sext = mem_value.sign_extend(&Mac::REG::from_u8(32));
361 update_register(machine, i.rd(), mem_value_sext);
362 let mem_value = rs2_value.lt(&mem_value).cond(&rs2_value, &mem_value);
363 machine.memory_mut().store32(&rs1_value, &mem_value)?;
364 Ok(())
365}
366
367pub fn handle_amomaxu_w<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
368 let i = Rtype(inst);
369 let rs1_value = machine.registers()[i.rs1()].clone();
370 let rs2_value = machine.registers()[i.rs2()].zero_extend(&Mac::REG::from_u8(32));
371 let mem_value = machine.memory_mut().load32(&rs1_value)?;
372 let mem_value_sext = mem_value.sign_extend(&Mac::REG::from_u8(32));
373 update_register(machine, i.rd(), mem_value_sext);
374 let mem_value = rs2_value.ge(&mem_value).cond(&rs2_value, &mem_value);
375 machine.memory_mut().store32(&rs1_value, &mem_value)?;
376 Ok(())
377}
378
379pub fn handle_lr_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
380 let i = Rtype(inst);
381 let address = machine.registers()[i.rs1()].clone();
382 let value = machine.memory_mut().load64(&address)?;
383 update_register(machine, i.rd(), value);
384 machine.memory_mut().set_lr(&address);
385 Ok(())
386}
387
388pub fn handle_sc_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
389 let i = Rtype(inst);
390 let address = machine.registers()[i.rs1()].clone();
391 let condition = address.eq(machine.memory().lr());
392 let mem_value = condition.cond(
393 &machine.registers()[i.rs2()].clone(),
394 &machine.memory_mut().load64(&address)?,
395 );
396 let rd_value = condition.cond(&Mac::REG::from_u8(0), &Mac::REG::from_u8(1));
397 machine.memory_mut().store64(&address, &mem_value)?;
398 update_register(machine, i.rd(), rd_value);
399 machine.memory_mut().set_lr(&Mac::REG::from_u64(u64::MAX));
400 Ok(())
401}
402
403pub fn handle_amoswap_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
404 let i = Rtype(inst);
405 let rs1_value = machine.registers()[i.rs1()].clone();
406 let rs2_value = machine.registers()[i.rs2()].clone();
407 let mem_value = machine.memory_mut().load64(&rs1_value)?;
408 update_register(machine, i.rd(), mem_value);
409 machine.memory_mut().store64(&rs1_value, &rs2_value)?;
410 Ok(())
411}
412
413pub fn handle_amoadd_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
414 let i = Rtype(inst);
415 let rs1_value = machine.registers()[i.rs1()].clone();
416 let rs2_value = machine.registers()[i.rs2()].clone();
417 let mem_value = machine.memory_mut().load64(&rs1_value)?;
418 update_register(machine, i.rd(), mem_value.clone());
419 let mem_value = rs2_value.overflowing_add(&mem_value);
420 machine.memory_mut().store64(&rs1_value, &mem_value)?;
421 Ok(())
422}
423
424pub fn handle_amoxor_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
425 let i = Rtype(inst);
426 let rs1_value = machine.registers()[i.rs1()].clone();
427 let rs2_value = machine.registers()[i.rs2()].clone();
428 let mem_value = machine.memory_mut().load64(&rs1_value)?;
429 update_register(machine, i.rd(), mem_value.clone());
430 let mem_value = rs2_value ^ mem_value;
431 machine.memory_mut().store64(&rs1_value, &mem_value)?;
432 Ok(())
433}
434
435pub fn handle_amoand_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
436 let i = Rtype(inst);
437 let rs1_value = machine.registers()[i.rs1()].clone();
438 let rs2_value = machine.registers()[i.rs2()].clone();
439 let mem_value = machine.memory_mut().load64(&rs1_value)?;
440 update_register(machine, i.rd(), mem_value.clone());
441 let mem_value = rs2_value & mem_value;
442 machine.memory_mut().store64(&rs1_value, &mem_value)?;
443 Ok(())
444}
445
446pub fn handle_amoor_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
447 let i = Rtype(inst);
448 let rs1_value = machine.registers()[i.rs1()].clone();
449 let rs2_value = machine.registers()[i.rs2()].clone();
450 let mem_value = machine.memory_mut().load64(&rs1_value)?;
451 update_register(machine, i.rd(), mem_value.clone());
452 let mem_value = rs2_value | mem_value;
453 machine.memory_mut().store64(&rs1_value, &mem_value)?;
454 Ok(())
455}
456
457pub fn handle_amomin_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
458 let i = Rtype(inst);
459 let rs1_value = machine.registers()[i.rs1()].clone();
460 let rs2_value = machine.registers()[i.rs2()].clone();
461 let mem_value = machine.memory_mut().load64(&rs1_value)?;
462 update_register(machine, i.rd(), mem_value.clone());
463 let mem_value = rs2_value.lt_s(&mem_value).cond(&rs2_value, &mem_value);
464 machine.memory_mut().store64(&rs1_value, &mem_value)?;
465 Ok(())
466}
467
468pub fn handle_amomax_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
469 let i = Rtype(inst);
470 let rs1_value = machine.registers()[i.rs1()].clone();
471 let rs2_value = machine.registers()[i.rs2()].clone();
472 let mem_value = machine.memory_mut().load64(&rs1_value)?;
473 update_register(machine, i.rd(), mem_value.clone());
474 let mem_value = rs2_value.ge_s(&mem_value).cond(&rs2_value, &mem_value);
475 machine.memory_mut().store64(&rs1_value, &mem_value)?;
476 Ok(())
477}
478
479pub fn handle_amominu_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
480 let i = Rtype(inst);
481 let rs1_value = machine.registers()[i.rs1()].clone();
482 let rs2_value = machine.registers()[i.rs2()].clone();
483 let mem_value = machine.memory_mut().load64(&rs1_value)?;
484 update_register(machine, i.rd(), mem_value.clone());
485 let mem_value = rs2_value.lt(&mem_value).cond(&rs2_value, &mem_value);
486 machine.memory_mut().store64(&rs1_value, &mem_value)?;
487 Ok(())
488}
489
490pub fn handle_amomaxu_d<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
491 let i = Rtype(inst);
492 let rs1_value = machine.registers()[i.rs1()].clone();
493 let rs2_value = machine.registers()[i.rs2()].clone();
494 let mem_value = machine.memory_mut().load64(&rs1_value)?;
495 update_register(machine, i.rd(), mem_value.clone());
496 let mem_value = rs2_value.ge(&mem_value).cond(&rs2_value, &mem_value);
497 machine.memory_mut().store64(&rs1_value, &mem_value)?;
498 Ok(())
499}
500
501pub fn handle_ori<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
502 let i = Itype(inst);
503 common::ori(machine, i.rd(), i.rs1(), i.immediate_s());
504 Ok(())
505}
506
507pub fn handle_andi<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
508 let i = Itype(inst);
509 common::andi(machine, i.rd(), i.rs1(), i.immediate_s());
510 Ok(())
511}
512
513pub fn handle_slti<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
514 let i = Itype(inst);
515 let rs1_value = &machine.registers()[i.rs1()];
516 let imm_value = Mac::REG::from_i32(i.immediate_s());
517 let value = rs1_value.lt_s(&imm_value);
518 update_register(machine, i.rd(), value);
519 Ok(())
520}
521
522pub fn handle_sltiu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
523 let i = Itype(inst);
524 let rs1_value = &machine.registers()[i.rs1()];
525 let imm_value = Mac::REG::from_i32(i.immediate_s());
526 let value = rs1_value.lt(&imm_value);
527 update_register(machine, i.rd(), value);
528 Ok(())
529}
530
531pub fn handle_jalr_version0<Mac: Machine>(
532 machine: &mut Mac,
533 inst: Instruction,
534) -> Result<(), Error> {
535 let i = Itype(inst);
536 let size = instruction_length(inst);
537 let link = machine.pc().overflowing_add(&Mac::REG::from_u8(size));
538 update_register(machine, i.rd(), link);
539 let mut next_pc =
540 machine.registers()[i.rs1()].overflowing_add(&Mac::REG::from_i32(i.immediate_s()));
541 next_pc = next_pc & (!Mac::REG::one());
542 machine.update_pc(next_pc);
543 Ok(())
544}
545
546pub fn handle_jalr_version1<Mac: Machine>(
547 machine: &mut Mac,
548 inst: Instruction,
549) -> Result<(), Error> {
550 let i = Itype(inst);
551 let size = instruction_length(inst);
552 let link = machine.pc().overflowing_add(&Mac::REG::from_u8(size));
553 let mut next_pc =
554 machine.registers()[i.rs1()].overflowing_add(&Mac::REG::from_i32(i.immediate_s()));
555 next_pc = next_pc & (!Mac::REG::one());
556 update_register(machine, i.rd(), link);
557 machine.update_pc(next_pc);
558 Ok(())
559}
560
561pub fn handle_slli<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
562 let i = Itype(inst);
563 common::slli(machine, i.rd(), i.rs1(), i.immediate_u());
564 Ok(())
565}
566
567pub fn handle_srli<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
568 let i = Itype(inst);
569 common::srli(machine, i.rd(), i.rs1(), i.immediate_u());
570 Ok(())
571}
572
573pub fn handle_srai<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
574 let i = Itype(inst);
575 common::srai(machine, i.rd(), i.rs1(), i.immediate_u());
576 Ok(())
577}
578
579pub fn handle_slliw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
580 let i = Itype(inst);
581 common::slliw(machine, i.rd(), i.rs1(), i.immediate_u());
582 Ok(())
583}
584
585pub fn handle_srliw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
586 let i = Itype(inst);
587 common::srliw(machine, i.rd(), i.rs1(), i.immediate_u());
588 Ok(())
589}
590
591pub fn handle_sraiw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
592 let i = Itype(inst);
593 common::sraiw(machine, i.rd(), i.rs1(), i.immediate_u());
594 Ok(())
595}
596
597pub fn handle_sb<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
598 let i = Stype(inst);
599 common::sb(machine, i.rs1(), i.rs2(), i.immediate_s())?;
600 Ok(())
601}
602
603pub fn handle_sh<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
604 let i = Stype(inst);
605 common::sh(machine, i.rs1(), i.rs2(), i.immediate_s())?;
606 Ok(())
607}
608
609pub fn handle_sw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
610 let i = Stype(inst);
611 common::sw(machine, i.rs1(), i.rs2(), i.immediate_s())?;
612 Ok(())
613}
614
615pub fn handle_sd<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
616 let i = Stype(inst);
617 common::sd(machine, i.rs1(), i.rs2(), i.immediate_s())?;
618 Ok(())
619}
620
621pub fn handle_beq<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
622 let i = Stype(inst);
623 let pc = machine.pc();
624 let rs1_value = &machine.registers()[i.rs1()];
625 let rs2_value = &machine.registers()[i.rs2()];
626 let condition = rs1_value.eq(rs2_value);
627 let new_pc = condition.cond(
628 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
629 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
630 );
631 machine.update_pc(new_pc);
632 Ok(())
633}
634
635pub fn handle_bne<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
636 let i = Stype(inst);
637 let pc = machine.pc();
638 let rs1_value = &machine.registers()[i.rs1()];
639 let rs2_value = &machine.registers()[i.rs2()];
640 let condition = rs1_value.ne(rs2_value);
641 let new_pc = condition.cond(
642 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
643 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
644 );
645 machine.update_pc(new_pc);
646 Ok(())
647}
648
649pub fn handle_blt<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
650 let i = Stype(inst);
651 let pc = machine.pc();
652 let rs1_value = &machine.registers()[i.rs1()];
653 let rs2_value = &machine.registers()[i.rs2()];
654 let condition = rs1_value.lt_s(rs2_value);
655 let new_pc = condition.cond(
656 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
657 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
658 );
659 machine.update_pc(new_pc);
660 Ok(())
661}
662
663pub fn handle_bge<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
664 let i = Stype(inst);
665 let pc = machine.pc();
666 let rs1_value = &machine.registers()[i.rs1()];
667 let rs2_value = &machine.registers()[i.rs2()];
668 let condition = rs1_value.ge_s(rs2_value);
669 let new_pc = condition.cond(
670 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
671 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
672 );
673 machine.update_pc(new_pc);
674 Ok(())
675}
676
677pub fn handle_bltu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
678 let i = Stype(inst);
679 let pc = machine.pc();
680 let rs1_value = &machine.registers()[i.rs1()];
681 let rs2_value = &machine.registers()[i.rs2()];
682 let condition = rs1_value.lt(rs2_value);
683 let new_pc = condition.cond(
684 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
685 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
686 );
687 machine.update_pc(new_pc);
688 Ok(())
689}
690
691pub fn handle_bgeu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
692 let i = Stype(inst);
693 let pc = machine.pc();
694 let rs1_value = &machine.registers()[i.rs1()];
695 let rs2_value = &machine.registers()[i.rs2()];
696 let condition = rs1_value.ge(rs2_value);
697 let new_pc = condition.cond(
698 &Mac::REG::from_i32(i.immediate_s()).overflowing_add(pc),
699 &Mac::REG::from_u8(instruction_length(inst)).overflowing_add(pc),
700 );
701 machine.update_pc(new_pc);
702 Ok(())
703}
704
705pub fn handle_lui<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
706 let i = Utype(inst);
707 update_register(machine, i.rd(), Mac::REG::from_i32(i.immediate_s()));
708 Ok(())
709}
710
711pub fn handle_auipc<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
712 let i = Utype(inst);
713 let value = machine
714 .pc()
715 .overflowing_add(&Mac::REG::from_i32(i.immediate_s()));
716 update_register(machine, i.rd(), value);
717 Ok(())
718}
719
720pub fn handle_ecall<Mac: Machine>(machine: &mut Mac, _inst: Instruction) -> Result<(), Error> {
721 machine.ecall()?;
726 Ok(())
727}
728
729pub fn handle_ebreak<Mac: Machine>(machine: &mut Mac, _inst: Instruction) -> Result<(), Error> {
730 machine.ebreak()?;
731 Ok(())
732}
733
734pub fn handle_fencei<Mac: Machine>(_machine: &mut Mac, _inst: Instruction) -> Result<(), Error> {
735 Ok(())
736}
737
738pub fn handle_fence<Mac: Machine>(_machine: &mut Mac, _inst: Instruction) -> Result<(), Error> {
739 Ok(())
740}
741
742pub fn handle_jal<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
743 let i = Utype(inst);
744 common::jal(machine, i.rd(), i.immediate_s(), instruction_length(inst));
745 Ok(())
746}
747
748pub fn handle_mul<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
749 let i = Rtype(inst);
750 let rs1_value = &machine.registers()[i.rs1()];
751 let rs2_value = &machine.registers()[i.rs2()];
752 let value = rs1_value.overflowing_mul(rs2_value);
753 update_register(machine, i.rd(), value);
754 Ok(())
755}
756
757pub fn handle_mulw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
758 let i = Rtype(inst);
759 let rs1_value = &machine.registers()[i.rs1()];
760 let rs2_value = &machine.registers()[i.rs2()];
761 let value = rs1_value
762 .zero_extend(&Mac::REG::from_u8(32))
763 .overflowing_mul(&rs2_value.zero_extend(&Mac::REG::from_u8(32)));
764 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
765 Ok(())
766}
767
768pub fn handle_mulh<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
769 let i = Rtype(inst);
770 let rs1_value = &machine.registers()[i.rs1()];
771 let rs2_value = &machine.registers()[i.rs2()];
772 let value = rs1_value.overflowing_mul_high_signed(rs2_value);
773 update_register(machine, i.rd(), value);
774 Ok(())
775}
776
777pub fn handle_mulhsu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
778 let i = Rtype(inst);
779 let rs1_value = &machine.registers()[i.rs1()];
780 let rs2_value = &machine.registers()[i.rs2()];
781 let value = rs1_value.overflowing_mul_high_signed_unsigned(rs2_value);
782 update_register(machine, i.rd(), value);
783 Ok(())
784}
785
786pub fn handle_mulhu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
787 let i = Rtype(inst);
788 let rs1_value = &machine.registers()[i.rs1()];
789 let rs2_value = &machine.registers()[i.rs2()];
790 let value = rs1_value.overflowing_mul_high_unsigned(rs2_value);
791 update_register(machine, i.rd(), value);
792 Ok(())
793}
794
795pub fn handle_div<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
796 let i = Rtype(inst);
797 let rs1_value = &machine.registers()[i.rs1()];
798 let rs2_value = &machine.registers()[i.rs2()];
799 let value = rs1_value.overflowing_div_signed(rs2_value);
800 update_register(machine, i.rd(), value);
801 Ok(())
802}
803
804pub fn handle_divw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
805 let i = Rtype(inst);
806 let rs1_value = &machine.registers()[i.rs1()];
807 let rs2_value = &machine.registers()[i.rs2()];
808 let rs1_value = rs1_value.sign_extend(&Mac::REG::from_u8(32));
809 let rs2_value = rs2_value.sign_extend(&Mac::REG::from_u8(32));
810 let value = rs1_value.overflowing_div_signed(&rs2_value);
811 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
812 Ok(())
813}
814
815pub fn handle_divu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
816 let i = Rtype(inst);
817 let rs1_value = &machine.registers()[i.rs1()];
818 let rs2_value = &machine.registers()[i.rs2()];
819 let value = rs1_value.overflowing_div(rs2_value);
820 update_register(machine, i.rd(), value);
821 Ok(())
822}
823
824pub fn handle_divuw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
825 let i = Rtype(inst);
826 let rs1_value = &machine.registers()[i.rs1()];
827 let rs2_value = &machine.registers()[i.rs2()];
828 let rs1_value = rs1_value.zero_extend(&Mac::REG::from_u8(32));
829 let rs2_value = rs2_value.zero_extend(&Mac::REG::from_u8(32));
830 let value = rs1_value.overflowing_div(&rs2_value);
831 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
832 Ok(())
833}
834
835pub fn handle_rem<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
836 let i = Rtype(inst);
837 let rs1_value = &machine.registers()[i.rs1()];
838 let rs2_value = &machine.registers()[i.rs2()];
839 let value = rs1_value.overflowing_rem_signed(rs2_value);
840 update_register(machine, i.rd(), value);
841 Ok(())
842}
843
844pub fn handle_remw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
845 let i = Rtype(inst);
846 let rs1_value = &machine.registers()[i.rs1()];
847 let rs2_value = &machine.registers()[i.rs2()];
848 let rs1_value = rs1_value.sign_extend(&Mac::REG::from_u8(32));
849 let rs2_value = rs2_value.sign_extend(&Mac::REG::from_u8(32));
850 let value = rs1_value.overflowing_rem_signed(&rs2_value);
851 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
852 Ok(())
853}
854
855pub fn handle_remu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
856 let i = Rtype(inst);
857 let rs1_value = &machine.registers()[i.rs1()];
858 let rs2_value = &machine.registers()[i.rs2()];
859 let value = rs1_value.overflowing_rem(rs2_value);
860 update_register(machine, i.rd(), value);
861 Ok(())
862}
863
864pub fn handle_remuw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
865 let i = Rtype(inst);
866 let rs1_value = &machine.registers()[i.rs1()];
867 let rs2_value = &machine.registers()[i.rs2()];
868 let rs1_value = rs1_value.zero_extend(&Mac::REG::from_u8(32));
869 let rs2_value = rs2_value.zero_extend(&Mac::REG::from_u8(32));
870 let value = rs1_value.overflowing_rem(&rs2_value);
871 update_register(machine, i.rd(), value.sign_extend(&Mac::REG::from_u8(32)));
872 Ok(())
873}
874
875pub fn handle_adduw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
876 let i = Rtype(inst);
877 let rs1_value = &machine.registers()[i.rs1()];
878 let rs2_value = &machine.registers()[i.rs2()];
879 let rs1_u = rs1_value.zero_extend(&Mac::REG::from_u8(32));
880 let value = rs2_value.overflowing_add(&rs1_u);
881 update_register(machine, i.rd(), value);
882 Ok(())
883}
884
885pub fn handle_andn<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
886 let i = Rtype(inst);
887 let rs1_value = &machine.registers()[i.rs1()];
888 let rs2_value = &machine.registers()[i.rs2()];
889 let value = rs1_value.clone() & !rs2_value.clone();
890 update_register(machine, i.rd(), value);
891 Ok(())
892}
893
894pub fn handle_bclr<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
895 let i = Rtype(inst);
896 let rs1_value = &machine.registers()[i.rs1()];
897 let rs2_value = &machine.registers()[i.rs2()];
898 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
899 let value = rs1_value.clone() & !(Mac::REG::one() << shamt);
900 update_register(machine, i.rd(), value);
901 Ok(())
902}
903
904pub fn handle_bclri<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
905 let i = Itype(inst);
906 let rs1_value = &machine.registers()[i.rs1()];
907 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
908 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
909 let value = rs1_value.clone() & !(Mac::REG::one() << shamt);
910 update_register(machine, i.rd(), value);
911 Ok(())
912}
913
914pub fn handle_bext<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
915 let i = Rtype(inst);
916 let rs1_value = &machine.registers()[i.rs1()];
917 let rs2_value = &machine.registers()[i.rs2()];
918 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
919 let value = Mac::REG::one() & (rs1_value.clone() >> shamt);
920 update_register(machine, i.rd(), value);
921 Ok(())
922}
923
924pub fn handle_bexti<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
925 let i = Itype(inst);
926 let rs1_value = &machine.registers()[i.rs1()];
927 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
928 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
929 let value = Mac::REG::one() & (rs1_value.clone() >> shamt);
930 update_register(machine, i.rd(), value);
931 Ok(())
932}
933
934pub fn handle_binv<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
935 let i = Rtype(inst);
936 let rs1_value = &machine.registers()[i.rs1()];
937 let rs2_value = &machine.registers()[i.rs2()];
938 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
939 let value = rs1_value.clone() ^ (Mac::REG::one() << shamt);
940 update_register(machine, i.rd(), value);
941 Ok(())
942}
943
944pub fn handle_binvi<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
945 let i = Itype(inst);
946 let rs1_value = &machine.registers()[i.rs1()];
947 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
948 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
949 let value = rs1_value.clone() ^ (Mac::REG::one() << shamt);
950 update_register(machine, i.rd(), value);
951 Ok(())
952}
953
954pub fn handle_bset<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
955 let i = Rtype(inst);
956 let rs1_value = &machine.registers()[i.rs1()];
957 let rs2_value = &machine.registers()[i.rs2()];
958 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
959 let value = rs1_value.clone() | (Mac::REG::one() << shamt);
960 update_register(machine, i.rd(), value);
961 Ok(())
962}
963
964pub fn handle_bseti<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
965 let i = Itype(inst);
966 let rs1_value = &machine.registers()[i.rs1()];
967 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
968 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
969 let value = rs1_value.clone() | (Mac::REG::one() << shamt);
970 update_register(machine, i.rd(), value);
971 Ok(())
972}
973
974pub fn handle_clmul<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
975 let i = Rtype(inst);
976 let rs1_value = &machine.registers()[i.rs1()];
977 let rs2_value = &machine.registers()[i.rs2()];
978 let value = rs1_value.clmul(rs2_value);
979 update_register(machine, i.rd(), value);
980 Ok(())
981}
982
983pub fn handle_clmulh<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
984 let i = Rtype(inst);
985 let rs1_value = &machine.registers()[i.rs1()];
986 let rs2_value = &machine.registers()[i.rs2()];
987 let value = rs1_value.clmulh(rs2_value);
988 update_register(machine, i.rd(), value);
989 Ok(())
990}
991
992pub fn handle_clmulr<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
993 let i = Rtype(inst);
994 let rs1_value = &machine.registers()[i.rs1()];
995 let rs2_value = &machine.registers()[i.rs2()];
996 let value = rs1_value.clmulr(rs2_value);
997 update_register(machine, i.rd(), value);
998 Ok(())
999}
1000
1001pub fn handle_clz<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1002 let i = Rtype(inst);
1003 let rs1_value = &machine.registers()[i.rs1()];
1004 let value = rs1_value.clz();
1005 update_register(machine, i.rd(), value);
1006 Ok(())
1007}
1008
1009pub fn handle_clzw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1010 let i = Rtype(inst);
1011 let rs1_value = &machine.registers()[i.rs1()];
1012 let value = rs1_value
1013 .zero_extend(&Mac::REG::from_u8(32))
1014 .clz()
1015 .overflowing_sub(&Mac::REG::from_u8(32));
1016 update_register(machine, i.rd(), value);
1017 Ok(())
1018}
1019
1020pub fn handle_cpop<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1021 let i = Rtype(inst);
1022 let rs1_value = &machine.registers()[i.rs1()];
1023 let value = rs1_value.cpop();
1024 update_register(machine, i.rd(), value);
1025 Ok(())
1026}
1027
1028pub fn handle_cpopw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1029 let i = Rtype(inst);
1030 let rs1_value = &machine.registers()[i.rs1()];
1031 let value = rs1_value.zero_extend(&Mac::REG::from_u8(32)).cpop();
1032 update_register(machine, i.rd(), value);
1033 Ok(())
1034}
1035
1036pub fn handle_ctz<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1037 let i = Rtype(inst);
1038 let rs1_value = &machine.registers()[i.rs1()];
1039 let value = rs1_value.ctz();
1040 update_register(machine, i.rd(), value);
1041 Ok(())
1042}
1043
1044pub fn handle_ctzw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1045 let i = Rtype(inst);
1046 let rs1_value = &machine.registers()[i.rs1()];
1047 let value = (rs1_value.clone() | Mac::REG::from_u64(0xffff_ffff_0000_0000)).ctz();
1048 update_register(machine, i.rd(), value);
1049 Ok(())
1050}
1051
1052pub fn handle_max<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1053 let i = Rtype(inst);
1054 let rs1_value = &machine.registers()[i.rs1()];
1055 let rs2_value = &machine.registers()[i.rs2()];
1056 let value = rs1_value.ge_s(rs2_value).cond(rs1_value, rs2_value);
1057 update_register(machine, i.rd(), value);
1058 Ok(())
1059}
1060
1061pub fn handle_maxu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1062 let i = Rtype(inst);
1063 let rs1_value = &machine.registers()[i.rs1()];
1064 let rs2_value = &machine.registers()[i.rs2()];
1065 let value = rs1_value.ge(rs2_value).cond(rs1_value, rs2_value);
1066 update_register(machine, i.rd(), value);
1067 Ok(())
1068}
1069
1070pub fn handle_min<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1071 let i = Rtype(inst);
1072 let rs1_value = &machine.registers()[i.rs1()];
1073 let rs2_value = &machine.registers()[i.rs2()];
1074 let value = rs1_value.lt_s(rs2_value).cond(rs1_value, rs2_value);
1075 update_register(machine, i.rd(), value);
1076 Ok(())
1077}
1078
1079pub fn handle_minu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1080 let i = Rtype(inst);
1081 let rs1_value = &machine.registers()[i.rs1()];
1082 let rs2_value = &machine.registers()[i.rs2()];
1083 let value = rs1_value.lt(rs2_value).cond(rs1_value, rs2_value);
1084 update_register(machine, i.rd(), value);
1085 Ok(())
1086}
1087
1088pub fn handle_orcb<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1089 let i = Rtype(inst);
1090 let rs1_value = &machine.registers()[i.rs1()];
1091 let value = rs1_value.orcb();
1092 update_register(machine, i.rd(), value);
1093 Ok(())
1094}
1095
1096pub fn handle_orn<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1097 let i = Rtype(inst);
1098 let rs1_value = &machine.registers()[i.rs1()];
1099 let rs2_value = &machine.registers()[i.rs2()];
1100 let value = rs1_value.clone() | !rs2_value.clone();
1101 update_register(machine, i.rd(), value);
1102 Ok(())
1103}
1104
1105pub fn handle_rev8<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1106 let i = Rtype(inst);
1107 let rs1_value = &machine.registers()[i.rs1()];
1108 let value = rs1_value.rev8();
1109 update_register(machine, i.rd(), value);
1110 Ok(())
1111}
1112
1113pub fn handle_rol<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1114 let i = Rtype(inst);
1115 let rs1_value = &machine.registers()[i.rs1()];
1116 let rs2_value = &machine.registers()[i.rs2()];
1117 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
1118 let value = rs1_value.rol(&shamt);
1119 update_register(machine, i.rd(), value);
1120 Ok(())
1121}
1122
1123pub fn handle_rolw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1124 let i = Rtype(inst);
1125 let rs1_value = &machine.registers()[i.rs1()];
1126 let rs2_value = &machine.registers()[i.rs2()];
1127 let shamt = rs2_value.clone() & Mac::REG::from_u8(31);
1128 let twins = rs1_value
1129 .zero_extend(&Mac::REG::from_u8(32))
1130 .overflowing_mul(&Mac::REG::from_u64(0x_0000_0001_0000_0001));
1131 let value = twins.rol(&shamt).sign_extend(&Mac::REG::from_u8(32));
1132 update_register(machine, i.rd(), value);
1133 Ok(())
1134}
1135
1136pub fn handle_ror<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1137 let i = Rtype(inst);
1138 let rs1_value = &machine.registers()[i.rs1()];
1139 let rs2_value = &machine.registers()[i.rs2()];
1140 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
1141 let value = rs1_value.ror(&shamt);
1142 update_register(machine, i.rd(), value);
1143 Ok(())
1144}
1145
1146pub fn handle_rori<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1147 let i = Itype(inst);
1148 let rs1_value = &machine.registers()[i.rs1()];
1149 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
1150 let shamt = rs2_value.clone() & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
1151 let value = rs1_value.ror(&shamt);
1152 update_register(machine, i.rd(), value);
1153 Ok(())
1154}
1155
1156pub fn handle_roriw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1157 let i = Itype(inst);
1158 let rs1_value = &machine.registers()[i.rs1()];
1159 let rs2_value = &Mac::REG::from_u32(i.immediate_u());
1160 let shamt = rs2_value.clone() & Mac::REG::from_u8(31);
1161 let twins = rs1_value
1162 .zero_extend(&Mac::REG::from_u8(32))
1163 .overflowing_mul(&Mac::REG::from_u64(0x_0000_0001_0000_0001));
1164 let value = twins.ror(&shamt).sign_extend(&Mac::REG::from_u8(32));
1165 update_register(machine, i.rd(), value);
1166 Ok(())
1167}
1168
1169pub fn handle_rorw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1170 let i = Rtype(inst);
1171 let rs1_value = &machine.registers()[i.rs1()];
1172 let rs2_value = &machine.registers()[i.rs2()];
1173 let shamt = rs2_value.clone() & Mac::REG::from_u8(31);
1174 let twins = rs1_value
1175 .zero_extend(&Mac::REG::from_u8(32))
1176 .overflowing_mul(&Mac::REG::from_u64(0x_0000_0001_0000_0001));
1177 let value = twins.ror(&shamt).sign_extend(&Mac::REG::from_u8(32));
1178 update_register(machine, i.rd(), value);
1179 Ok(())
1180}
1181
1182pub fn handle_sextb<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1183 let i = Rtype(inst);
1184 let rs1_value = &machine.registers()[i.rs1()];
1185 let shift = &Mac::REG::from_u8(Mac::REG::BITS - 8);
1186 let value = rs1_value.signed_shl(shift).signed_shr(shift);
1187 update_register(machine, i.rd(), value);
1188 Ok(())
1189}
1190
1191pub fn handle_sexth<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1192 let i = Rtype(inst);
1193 let rs1_value = &machine.registers()[i.rs1()];
1194 let shift = &Mac::REG::from_u8(Mac::REG::BITS - 16);
1195 let value = rs1_value.signed_shl(shift).signed_shr(shift);
1196 update_register(machine, i.rd(), value);
1197 Ok(())
1198}
1199
1200pub fn handle_sh1add<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1201 let i = Rtype(inst);
1202 let rs1_value = &machine.registers()[i.rs1()];
1203 let rs2_value = &machine.registers()[i.rs2()];
1204 let value = (rs1_value.clone() << Mac::REG::from_u32(1)).overflowing_add(rs2_value);
1205 update_register(machine, i.rd(), value);
1206 Ok(())
1207}
1208
1209pub fn handle_sh1adduw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1210 let i = Rtype(inst);
1211 let rs1_value = &machine.registers()[i.rs1()];
1212 let rs2_value = &machine.registers()[i.rs2()];
1213 let rs1_z = rs1_value.clone().zero_extend(&Mac::REG::from_u8(32));
1214 let value = (rs1_z << Mac::REG::from_u32(1)).overflowing_add(rs2_value);
1215 update_register(machine, i.rd(), value);
1216 Ok(())
1217}
1218
1219pub fn handle_sh2add<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1220 let i = Rtype(inst);
1221 let rs1_value = &machine.registers()[i.rs1()];
1222 let rs2_value = &machine.registers()[i.rs2()];
1223 let value = (rs1_value.clone() << Mac::REG::from_u32(2)).overflowing_add(rs2_value);
1224 update_register(machine, i.rd(), value);
1225 Ok(())
1226}
1227
1228pub fn handle_sh2adduw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1229 let i = Rtype(inst);
1230 let rs1_value = &machine.registers()[i.rs1()];
1231 let rs2_value = &machine.registers()[i.rs2()];
1232 let rs1_z = rs1_value.clone().zero_extend(&Mac::REG::from_u8(32));
1233 let value = (rs1_z << Mac::REG::from_u32(2)).overflowing_add(rs2_value);
1234 update_register(machine, i.rd(), value);
1235 Ok(())
1236}
1237
1238pub fn handle_sh3add<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1239 let i = Rtype(inst);
1240 let rs1_value = &machine.registers()[i.rs1()];
1241 let rs2_value = &machine.registers()[i.rs2()];
1242 let value = (rs1_value.clone() << Mac::REG::from_u32(3)).overflowing_add(rs2_value);
1243 update_register(machine, i.rd(), value);
1244 Ok(())
1245}
1246
1247pub fn handle_sh3adduw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1248 let i = Rtype(inst);
1249 let rs1_value = &machine.registers()[i.rs1()];
1250 let rs2_value = &machine.registers()[i.rs2()];
1251 let rs1_z = rs1_value.clone().zero_extend(&Mac::REG::from_u8(32));
1252 let value = (rs1_z << Mac::REG::from_u32(3)).overflowing_add(rs2_value);
1253 update_register(machine, i.rd(), value);
1254 Ok(())
1255}
1256
1257pub fn handle_slliuw<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1258 let i = Itype(inst);
1259 let rs1_value = &machine.registers()[i.rs1()];
1260 let rs2_value = Mac::REG::from_u32(i.immediate_u());
1261 let rs1_u = rs1_value.clone().zero_extend(&Mac::REG::from_u8(32));
1262 let shamt = rs2_value & Mac::REG::from_u8(Mac::REG::SHIFT_MASK);
1263 let value = rs1_u << shamt;
1264 update_register(machine, i.rd(), value);
1265 Ok(())
1266}
1267
1268pub fn handle_xnor<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1269 let i = Rtype(inst);
1270 let rs1_value = &machine.registers()[i.rs1()];
1271 let rs2_value = &machine.registers()[i.rs2()];
1272 let value = rs1_value.clone() ^ !rs2_value.clone();
1273 update_register(machine, i.rd(), value);
1274 Ok(())
1275}
1276
1277pub fn handle_zexth<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1278 let i = Rtype(inst);
1279 let rs1_value = &machine.registers()[i.rs1()];
1280 let value = rs1_value.zero_extend(&Mac::REG::from_u8(16));
1281 update_register(machine, i.rd(), value);
1282 Ok(())
1283}
1284
1285pub fn handle_wide_mul<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1286 let i = R4type(inst);
1287 let rs1_value = &machine.registers()[i.rs1()];
1288 let rs2_value = &machine.registers()[i.rs2()];
1289 let value_h = rs1_value.overflowing_mul_high_signed(rs2_value);
1290 let value_l = rs1_value.overflowing_mul(rs2_value);
1291 update_register(machine, i.rd(), value_h);
1292 update_register(machine, i.rs3(), value_l);
1293 Ok(())
1294}
1295
1296pub fn handle_wide_mulu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1297 let i = R4type(inst);
1298 let rs1_value = &machine.registers()[i.rs1()];
1299 let rs2_value = &machine.registers()[i.rs2()];
1300 let value_h = rs1_value.overflowing_mul_high_unsigned(rs2_value);
1301 let value_l = rs1_value.overflowing_mul(rs2_value);
1302 update_register(machine, i.rd(), value_h);
1303 update_register(machine, i.rs3(), value_l);
1304 Ok(())
1305}
1306
1307pub fn handle_wide_mulsu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1308 let i = R4type(inst);
1309 let rs1_value = &machine.registers()[i.rs1()];
1310 let rs2_value = &machine.registers()[i.rs2()];
1311 let value_h = rs1_value.overflowing_mul_high_signed_unsigned(rs2_value);
1312 let value_l = rs1_value.overflowing_mul(rs2_value);
1313 update_register(machine, i.rd(), value_h);
1314 update_register(machine, i.rs3(), value_l);
1315 Ok(())
1316}
1317
1318pub fn handle_wide_div<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1319 let i = R4type(inst);
1320 let rs1_value = &machine.registers()[i.rs1()];
1321 let rs2_value = &machine.registers()[i.rs2()];
1322 let value_h = rs1_value.overflowing_div_signed(rs2_value);
1323 let value_l = rs1_value.overflowing_rem_signed(rs2_value);
1324 update_register(machine, i.rd(), value_h);
1325 update_register(machine, i.rs3(), value_l);
1326 Ok(())
1327}
1328
1329pub fn handle_wide_divu<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1330 let i = R4type(inst);
1331 let rs1_value = &machine.registers()[i.rs1()];
1332 let rs2_value = &machine.registers()[i.rs2()];
1333 let value_h = rs1_value.overflowing_div(rs2_value);
1334 let value_l = rs1_value.overflowing_rem(rs2_value);
1335 update_register(machine, i.rd(), value_h);
1336 update_register(machine, i.rs3(), value_l);
1337 Ok(())
1338}
1339
1340pub fn handle_far_jump_rel<Mac: Machine>(
1341 machine: &mut Mac,
1342 inst: Instruction,
1343) -> Result<(), Error> {
1344 let i = Utype(inst);
1345 let size = instruction_length(inst);
1346 let link = machine.pc().overflowing_add(&Mac::REG::from_u8(size));
1347 let next_pc = machine
1348 .pc()
1349 .overflowing_add(&Mac::REG::from_i32(i.immediate_s()))
1350 & (!Mac::REG::one());
1351 update_register(machine, RA, link);
1352 machine.update_pc(next_pc);
1353 Ok(())
1354}
1355
1356pub fn handle_far_jump_abs<Mac: Machine>(
1357 machine: &mut Mac,
1358 inst: Instruction,
1359) -> Result<(), Error> {
1360 let i = Utype(inst);
1361 let size = instruction_length(inst);
1362 let link = machine.pc().overflowing_add(&Mac::REG::from_u8(size));
1363 let next_pc = Mac::REG::from_i32(i.immediate_s()) & (!Mac::REG::one());
1364 update_register(machine, RA, link);
1365 machine.update_pc(next_pc);
1366 Ok(())
1367}
1368
1369pub fn handle_adc<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1370 let i = Rtype(inst);
1371 let rd_value = &machine.registers()[i.rd()];
1372 let rs1_value = &machine.registers()[i.rs1()];
1373 let r = rd_value.overflowing_add(rs1_value);
1374 update_register(machine, i.rd(), r);
1375 let rd_value = &machine.registers()[i.rd()];
1376 let rs1_value = &machine.registers()[i.rs1()];
1377 let r = rd_value.lt(rs1_value);
1378 update_register(machine, i.rs1(), r);
1379 let rd_value = &machine.registers()[i.rd()];
1380 let rs2_value = &machine.registers()[i.rs2()];
1381 let r = rd_value.overflowing_add(rs2_value);
1382 update_register(machine, i.rd(), r);
1383 let rd_value = &machine.registers()[i.rd()];
1384 let rs2_value = &machine.registers()[i.rs2()];
1385 let r = rd_value.lt(rs2_value);
1386 update_register(machine, i.rs2(), r);
1387 let rs1_value = machine.registers()[i.rs1()].clone();
1388 let rs2_value = machine.registers()[i.rs2()].clone();
1389 let r = rs1_value | rs2_value;
1390 update_register(machine, i.rs1(), r);
1391 Ok(())
1392}
1393
1394pub fn handle_sbb<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1395 let i = R4type(inst);
1396 let rd_value = &machine.registers()[i.rd()];
1397 let rs1_value = &machine.registers()[i.rs1()];
1398 let r = rd_value.overflowing_sub(rs1_value);
1399 update_register(machine, i.rs1(), r);
1400 let rd_value = &machine.registers()[i.rd()];
1401 let rs1_value = &machine.registers()[i.rs1()];
1402 let r = rd_value.lt(rs1_value);
1403 update_register(machine, i.rs3(), r);
1404 let rs1_value = &machine.registers()[i.rs1()];
1405 let rs2_value = &machine.registers()[i.rs2()];
1406 let r = rs1_value.overflowing_sub(rs2_value);
1407 update_register(machine, i.rd(), r);
1408 let rd_value = &machine.registers()[i.rd()];
1409 let rs1_value = &machine.registers()[i.rs1()];
1410 let r = rs1_value.lt(rd_value);
1411 update_register(machine, i.rs2(), r);
1412 let rs2_value = machine.registers()[i.rs2()].clone();
1413 let rs3_value = machine.registers()[i.rs3()].clone();
1414 let r = rs2_value | rs3_value;
1415 update_register(machine, i.rs1(), r);
1416 Ok(())
1417}
1418
1419pub fn handle_adcs<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1420 let i = R4type(inst);
1421 let rs1_value = machine.registers()[i.rs1()].clone();
1422 let rs2_value = machine.registers()[i.rs2()].clone();
1423 let r = rs1_value.overflowing_add(&rs2_value);
1424 update_register(machine, i.rd(), r.clone());
1425 let r = r.lt(&rs1_value);
1426 update_register(machine, i.rs3(), r);
1427 Ok(())
1428}
1429
1430pub fn handle_sbbs<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1431 let i = R4type(inst);
1432 let rs1_value = machine.registers()[i.rs1()].clone();
1433 let rs2_value = machine.registers()[i.rs2()].clone();
1434 let r = rs1_value.overflowing_sub(&rs2_value);
1435 update_register(machine, i.rd(), r);
1436 let r = rs1_value.lt(&rs2_value);
1437 update_register(machine, i.rs3(), r);
1438 Ok(())
1439}
1440
1441pub fn handle_add3a<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1442 let i = R5type(inst);
1443 {
1444 let rd_value = machine.registers()[i.rd()].clone();
1445 let rs1_value = machine.registers()[i.rs1()].clone();
1446 let r = rd_value.overflowing_add(&rs1_value);
1447 update_register(machine, i.rd(), r);
1448 }
1449 {
1450 let rd_value = &machine.registers()[i.rd()];
1451 let rs1_value = &machine.registers()[i.rs1()];
1452 let r = rd_value.lt(rs1_value);
1453 update_register(machine, i.rs2(), r);
1454 }
1455 {
1456 let rs2_value = &machine.registers()[i.rs2()];
1457 let rs4_value = &machine.registers()[i.rs4()];
1458 let r = rs2_value.overflowing_add(rs4_value);
1459 update_register(machine, i.rs3(), r);
1460 }
1461 Ok(())
1462}
1463
1464pub fn handle_add3b<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1465 let i = R5type(inst);
1466 {
1467 let rs1_value = machine.registers()[i.rs1()].clone();
1468 let rs2_value = machine.registers()[i.rs2()].clone();
1469 let r = rs1_value.overflowing_add(&rs2_value);
1470 update_register(machine, i.rd(), r);
1471 }
1472 {
1473 let rd_value = &machine.registers()[i.rd()];
1474 let rs1_value = &machine.registers()[i.rs1()];
1475 let r = rd_value.lt(rs1_value);
1476 update_register(machine, i.rs1(), r);
1477 }
1478 {
1479 let rs1_value = &machine.registers()[i.rs1()];
1480 let rs4_value = &machine.registers()[i.rs4()];
1481 let r = rs1_value.overflowing_add(rs4_value);
1482 update_register(machine, i.rs3(), r);
1483 }
1484 Ok(())
1485}
1486
1487pub fn handle_add3c<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1488 let i = R5type(inst);
1489 {
1490 let rs1_value = machine.registers()[i.rs1()].clone();
1491 let rs2_value = machine.registers()[i.rs2()].clone();
1492 let r = rs1_value.overflowing_add(&rs2_value);
1493 update_register(machine, i.rd(), r);
1494 }
1495 {
1496 let rd_value = &machine.registers()[i.rd()];
1497 let rs1_value = &machine.registers()[i.rs1()];
1498 let rs4_value = &machine.registers()[i.rs4()];
1499 let r = rd_value.lt(rs1_value);
1500 let r = r.overflowing_add(rs4_value);
1501 update_register(machine, i.rs3(), r);
1502 }
1503 Ok(())
1504}
1505
1506pub fn handle_custom_load_uimm<Mac: Machine>(
1507 machine: &mut Mac,
1508 inst: Instruction,
1509) -> Result<(), Error> {
1510 let i = Utype(inst);
1511 update_register(machine, i.rd(), Mac::REG::from_u32(i.immediate_u()));
1512 Ok(())
1513}
1514
1515pub fn handle_custom_load_imm<Mac: Machine>(
1516 machine: &mut Mac,
1517 inst: Instruction,
1518) -> Result<(), Error> {
1519 let i = Utype(inst);
1520 let value = Mac::REG::from_i32(i.immediate_s());
1521 update_register(machine, i.rd(), value);
1522 Ok(())
1523}
1524
1525pub fn handle_unloaded<Mac: Machine>(machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1526 handle_invalid_op(machine, inst)
1527}
1528
1529pub fn handle_custom_trace_end<Mac: Machine>(
1530 machine: &mut Mac,
1531 inst: Instruction,
1532) -> Result<(), Error> {
1533 handle_invalid_op(machine, inst)
1534}
1535
1536pub fn handle_invalid_op<Mac: Machine>(_machine: &mut Mac, inst: Instruction) -> Result<(), Error> {
1537 Err(Error::InvalidOp(extract_opcode(inst)))
1538}
1539
1540macro_rules! handle_single_opcode {
1541 ($name:ident, $real_name:ident, $code:expr, $machine:ident, $inst:ident) => {
1542 paste! {
1543 Ok([< handle_ $real_name:lower >]($machine, $inst)?)
1544 }
1545 };
1546}
1547
1548pub fn execute_instruction<Mac: Machine>(
1549 inst: Instruction,
1550 machine: &mut Mac,
1551) -> Result<(), Error> {
1552 let op = extract_opcode(inst);
1553 for_each_inst_match2!(
1554 handle_single_opcode,
1555 op,
1556 handle_invalid_op(machine, inst),
1557 machine,
1558 inst
1559 )
1560}
1561
1562pub fn execute<Mac: Machine>(inst: Instruction, machine: &mut Mac) -> Result<(), Error> {
1563 let instruction_size = instruction_length(inst);
1564 let next_pc = machine
1565 .pc()
1566 .overflowing_add(&Mac::REG::from_u8(instruction_size));
1567 machine.update_pc(next_pc);
1568 let r = execute_instruction(inst, machine);
1569 machine.commit_pc();
1570 r
1571}
1572
1573pub fn execute_with_thread<Mac: Machine>(
1574 inst: Instruction,
1575 machine: &mut Mac,
1576 thread: &Thread<Mac>,
1577) -> Result<(), Error> {
1578 let instruction_size = instruction_length(inst);
1579 let next_pc = machine
1580 .pc()
1581 .overflowing_add(&Mac::REG::from_u8(instruction_size));
1582 machine.update_pc(next_pc);
1583 let r = thread(machine, inst);
1584 machine.commit_pc();
1585 r
1586}
1587
1588pub type Thread<Mac> = fn(&mut Mac, Instruction) -> Result<(), Error>;
1589
1590const FASTPATH_THREADS: usize = insts::MAXIMUM_OPCODE as usize + 1 - insts::MINIMAL_OPCODE as usize;
1591
1592pub struct ThreadFactory<Mac: Machine> {
1593 threads: [Thread<Mac>; FASTPATH_THREADS],
1596}
1597
1598macro_rules! thread_func_item {
1599 ($name:ident, $real_name:ident, $code:expr, $t:ident) => {
1600 paste! {
1601 [< handle_ $real_name:lower >]::<$t> as Thread<$t>
1602 }
1603 };
1604}
1605
1606impl<Mac: Machine> ThreadFactory<Mac> {
1607 pub fn create() -> Self {
1608 let threads = for_each_inst_array1!(thread_func_item, Mac);
1609 Self { threads }
1610 }
1611
1612 pub fn get(&self, op: InstructionOpcode) -> Option<&Thread<Mac>> {
1613 self.threads
1614 .get((op as usize).wrapping_sub(insts::MINIMAL_OPCODE as usize))
1615 }
1616
1617 pub fn get_cloned(&self, op: InstructionOpcode) -> Option<Thread<Mac>> {
1618 self.get(op).cloned()
1619 }
1620}
1621
1622impl<Mac: Machine> std::ops::Index<InstructionOpcode> for ThreadFactory<Mac> {
1623 type Output = Thread<Mac>;
1624
1625 fn index(&self, opcode: InstructionOpcode) -> &Thread<Mac> {
1626 self.get(opcode).unwrap()
1627 }
1628}