load.rsannotatedload.rssource634 lines · 22.6 KB · raw
1//! SH-2 load and store instructions
2
3use crate::Sh2;
4use crate::bus::BusInterface;
5use crate::instructions::{extend_i8, extend_i16, rm, rn};
6
7impl Sh2 {
8    // MOV Rm, Rn
9    // Load from a register
10    pub(crate) fn mov_rm_rn(&mut self, opcode: u16) {
11        let m = rm(opcode);
12        let n = rn(opcode);
13        self.registers.gpr[n] = self.registers.gpr[m];
14    }
15
16    // MOV #imm, Rn
17    // Loads an 8-bit immediate (sign extended) into a register
18    pub(crate) fn mov_b_immediate_rn(&mut self, opcode: u16) {
19        let n = rn(opcode);
20        self.registers.gpr[n] = opcode as i8 as u32;
21    }
22
23    // MOV.B @Rm, Rn
24    // Loads a byte from memory using indirect register addressing
25    pub(crate) fn mov_b_indirect_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
26        let m = rm(opcode);
27        let n = rn(opcode);
28
29        let value = self.read_byte(self.registers.gpr[m], bus);
30        self.registers.gpr[n] = extend_i8(value);
31    }
32
33    // MOV.W @Rm, Rn
34    // Loads a word from memory using indirect register addressing
35    pub(crate) fn mov_w_indirect_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
36        let m = rm(opcode);
37        let n = rn(opcode);
38
39        let value = self.read_word(self.registers.gpr[m], bus);
40        self.registers.gpr[n] = extend_i16(value);
41    }
42
43    // MOV.L @Rm, Rn
44    // Loads a longword from memory using indirect register addressing
45    pub(crate) fn mov_l_indirect_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
46        let m = rm(opcode);
47        let n = rn(opcode);
48
49        self.registers.gpr[n] = self.read_longword(self.registers.gpr[m], bus);
50    }
51
52    // MOV.B Rm, @Rn
53    // Stores a byte into memory using indirect register addressing
54    pub(crate) fn mov_b_rm_indirect(&mut self, opcode: u16, bus: &mut impl BusInterface) {
55        let m = rm(opcode);
56        let n = rn(opcode);
57
58        let value = self.registers.gpr[m] as u8;
59        self.write_byte(self.registers.gpr[n], value, bus);
60    }
61
62    // MOV.W Rm, @Rn
63    // Stores a word into memory using indirect register addressing
64    pub(crate) fn mov_w_rm_indirect(&mut self, opcode: u16, bus: &mut impl BusInterface) {
65        let m = rm(opcode);
66        let n = rn(opcode);
67
68        let value = self.registers.gpr[m] as u16;
69        self.write_word(self.registers.gpr[n], value, bus);
70    }
71
72    // MOV.L Rm, @Rn
73    // Stores a longword into memory using indirect register addressing
74    pub(crate) fn mov_l_rm_indirect(&mut self, opcode: u16, bus: &mut impl BusInterface) {
75        let m = rm(opcode);
76        let n = rn(opcode);
77
78        let value = self.registers.gpr[m];
79        self.write_longword(self.registers.gpr[n], value, bus);
80    }
81
82    // MOV.B @Rm+, Rn
83    // Loads a byte into a register using post-increment indirect register addressing
84    pub(crate) fn mov_b_postinc_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
85        let m = rm(opcode);
86        let n = rn(opcode);
87
88        let value = self.read_byte(self.registers.gpr[m], bus);
89        self.registers.gpr[m] = self.registers.gpr[m].wrapping_add(1);
90
91        self.registers.gpr[n] = extend_i8(value);
92    }
93
94    // MOV.W @Rm+, Rn
95    // Loads a word into a register using post-increment indirect register addressing
96    pub(crate) fn mov_w_postinc_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
97        let m = rm(opcode);
98        let n = rn(opcode);
99
100        let value = self.read_word(self.registers.gpr[m], bus);
101        self.registers.gpr[m] = self.registers.gpr[m].wrapping_add(2);
102
103        self.registers.gpr[n] = extend_i16(value);
104    }
105
106    // MOV.L @Rm+, Rn
107    // Loads a longword into a register using post-increment indirect register addressing
108    pub(crate) fn mov_l_postinc_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
109        let m = rm(opcode);
110        let n = rn(opcode);
111
112        let value = self.read_longword(self.registers.gpr[m], bus);
113        self.registers.gpr[m] = self.registers.gpr[m].wrapping_add(4);
114
115        self.registers.gpr[n] = value;
116    }
117
118    // MOV.B Rm, @-Rn
119    // Stores a byte into memory using pre-decrement indirect register addressing
120    pub(crate) fn mov_b_rm_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
121        let m = rm(opcode);
122        let n = rn(opcode);
123
124        let value = self.registers.gpr[m] as u8;
125
126        let address = self.registers.gpr[n].wrapping_sub(1);
127        self.registers.gpr[n] = address;
128
129        self.write_byte(address, value, bus);
130    }
131
132    // MOV.W Rm, @-Rn
133    // Stores a word into memory using pre-decrement indirect register addressing
134    pub(crate) fn mov_w_rm_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
135        let m = rm(opcode);
136        let n = rn(opcode);
137
138        let value = self.registers.gpr[m] as u16;
139
140        let address = self.registers.gpr[n].wrapping_sub(2);
141        self.registers.gpr[n] = address;
142
143        self.write_word(address, value, bus);
144    }
145
146    // MOV.L Rm, @-Rn
147    // Stores a longword into memory using pre-decrement indirect register addressing
148    pub(crate) fn mov_l_rm_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
149        let m = rm(opcode);
150        let n = rn(opcode);
151
152        let value = self.registers.gpr[m];
153
154        let address = self.registers.gpr[n].wrapping_sub(4);
155        self.registers.gpr[n] = address;
156
157        self.write_longword(address, value, bus);
158    }
159
160    // MOV.W @(disp,PC), Rn
161    // Loads a word (sign extended) into a register using PC relative with displacement addressing
162    pub(crate) fn mov_w_immediate_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
163        let disp = (opcode & 0xFF) << 1;
164        let address = self.registers.next_pc.wrapping_add(disp.into());
165        let value = self.read_word(address, bus);
166
167        let n = rn(opcode);
168        self.registers.gpr[n] = extend_i16(value);
169    }
170
171    // MOV.L @(disp,PC), Rn
172    // Loads a longword into a register using PC relative with displacement addressing
173    pub(crate) fn mov_l_immediate_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
174        let disp = (opcode & 0xFF) << 2;
175        let address = (self.registers.next_pc & !3).wrapping_add(disp.into());
176        let value = self.read_longword(address, bus);
177
178        let n = rn(opcode);
179        self.registers.gpr[n] = value;
180    }
181
182    // MOV.B R0, @(disp,Rn)
183    // Stores a byte into memory using indirect register with displacement addressing
184    pub(crate) fn mov_b_r0_rn_displacement(&mut self, opcode: u16, bus: &mut impl BusInterface) {
185        let disp = opcode & 0xF;
186        let n = rm(opcode);
187        let address = self.registers.gpr[n].wrapping_add(disp.into());
188        self.write_byte(address, self.registers.gpr[0] as u8, bus);
189    }
190
191    // MOV.W R0, @(disp,Rn)
192    // Stores a word into memory using indirect register with displacement addressing
193    pub(crate) fn mov_w_r0_rn_displacement(&mut self, opcode: u16, bus: &mut impl BusInterface) {
194        let disp = (opcode & 0xF) << 1;
195        let n = rm(opcode);
196        let address = self.registers.gpr[n].wrapping_add(disp.into());
197        self.write_word(address, self.registers.gpr[0] as u16, bus);
198    }
199
200    // MOV.B @(disp,Rm), R0
201    // Load a byte from memory using indirect register with displacement addressing
202    pub(crate) fn mov_b_rm_displacement_r0(&mut self, opcode: u16, bus: &mut impl BusInterface) {
203        let disp = opcode & 0xF;
204        let m = rm(opcode);
205
206        let address = self.registers.gpr[m].wrapping_add(disp.into());
207        let value = self.read_byte(address, bus);
208        self.registers.gpr[0] = extend_i8(value);
209    }
210
211    // MOV.W @(disp,Rm), R0
212    // Load a word from memory using indirect register with displacement addressing
213    pub(crate) fn mov_w_rm_displacement_r0(&mut self, opcode: u16, bus: &mut impl BusInterface) {
214        let disp = (opcode & 0xF) << 1;
215        let m = rm(opcode);
216
217        let address = self.registers.gpr[m].wrapping_add(disp.into());
218        let value = self.read_word(address, bus);
219        self.registers.gpr[0] = extend_i16(value);
220    }
221
222    // MOV.L Rm, @(disp,Rn)
223    // Stores a longword into memory using indirect register with displacement addressing
224    pub(crate) fn mov_l_rm_rn_displacement(&mut self, opcode: u16, bus: &mut impl BusInterface) {
225        let m = rm(opcode);
226        let n = rn(opcode);
227
228        let disp = (opcode & 0xF) << 2;
229        let address = self.registers.gpr[n].wrapping_add(disp.into());
230        self.write_longword(address, self.registers.gpr[m], bus);
231    }
232
233    // MOV.L @(disp,Rm), Rn
234    // Loads a longword from memory using indirect register with displacement addressing
235    pub(crate) fn mov_l_rm_displacement_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
236        let m = rm(opcode);
237        let n = rn(opcode);
238
239        let disp = (opcode & 0xF) << 2;
240        let address = self.registers.gpr[m].wrapping_add(disp.into());
241        self.registers.gpr[n] = self.read_longword(address, bus);
242    }
243
244    // MOV.B Rm, @(R0,Rn)
245    // Stores a byte into memory using indirect indexed register addressing
246    pub(crate) fn mov_b_rm_indirect_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
247        let m = rm(opcode);
248        let n = rn(opcode);
249
250        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[n]);
251        self.write_byte(address, self.registers.gpr[m] as u8, bus);
252    }
253
254    // MOV.W Rm, @(R0,Rn)
255    // Stores a word into memory using indirect indexed register addressing
256    pub(crate) fn mov_w_rm_indirect_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
257        let m = rm(opcode);
258        let n = rn(opcode);
259
260        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[n]);
261        self.write_word(address, self.registers.gpr[m] as u16, bus);
262    }
263
264    // MOV.L Rm, @(R0,Rn)
265    // Stores a longword into memory using indirect indexed register addressing
266    pub(crate) fn mov_l_rm_indirect_indexed(&mut self, opcode: u16, bus: &mut impl BusInterface) {
267        let m = rm(opcode);
268        let n = rn(opcode);
269
270        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[n]);
271        self.write_longword(address, self.registers.gpr[m], bus);
272    }
273
274    // MOV.B @(R0,Rm), Rn
275    // Loads a byte from memory using indirect indexed register addressing
276    pub(crate) fn mov_b_indirect_indexed_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
277        let m = rm(opcode);
278        let n = rn(opcode);
279
280        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[m]);
281        let value = self.read_byte(address, bus);
282        self.registers.gpr[n] = extend_i8(value);
283    }
284
285    // MOV.W @(R0,Rm), Rn
286    // Loads a word from memory using indirect indexed register addressing
287    pub(crate) fn mov_w_indirect_indexed_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
288        let m = rm(opcode);
289        let n = rn(opcode);
290
291        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[m]);
292        let value = self.read_word(address, bus);
293        self.registers.gpr[n] = extend_i16(value);
294    }
295
296    // MOV.L @(R0,Rm), Rn
297    // Loads a longword from memory using indirect indexed register addressing
298    pub(crate) fn mov_l_indirect_indexed_rn(&mut self, opcode: u16, bus: &mut impl BusInterface) {
299        let m = rm(opcode);
300        let n = rn(opcode);
301
302        let address = self.registers.gpr[0].wrapping_add(self.registers.gpr[m]);
303        self.registers.gpr[n] = self.read_longword(address, bus);
304    }
305
306    // MOV.B @(disp,GBR), R0
307    // Loads a byte into R0 using indirect GBR with displacement addressing
308    pub(crate) fn mov_b_disp_gbr_r0(&mut self, opcode: u16, bus: &mut impl BusInterface) {
309        let disp = opcode & 0xFF;
310        let address = self.registers.gbr.wrapping_add(disp.into());
311        let value = self.read_byte(address, bus);
312        self.registers.gpr[0] = extend_i8(value);
313    }
314
315    // MOV.W @(disp,GBR), R0
316    // Loads a word into R0 using indirect GBR with displacement addressing
317    pub(crate) fn mov_w_disp_gbr_r0(&mut self, opcode: u16, bus: &mut impl BusInterface) {
318        let disp = (opcode & 0xFF) << 1;
319        let address = self.registers.gbr.wrapping_add(disp.into());
320        let value = self.read_word(address, bus);
321        self.registers.gpr[0] = extend_i16(value);
322    }
323
324    // MOV.L @(disp,GBR), R0
325    // Loads a longword into R0 using indirect GBR with displacement addressing
326    pub(crate) fn mov_l_disp_gbr_r0(&mut self, opcode: u16, bus: &mut impl BusInterface) {
327        let disp = (opcode & 0xFF) << 2;
328        let address = self.registers.gbr.wrapping_add(disp.into());
329        self.registers.gpr[0] = self.read_longword(address, bus);
330    }
331
332    // MOV.B R0, @(disp,GBR)
333    // Stores a byte into memory using indirect GBR with displacement addressing
334    pub(crate) fn mov_b_r0_disp_gbr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
335        let disp = opcode & 0xFF;
336        let address = self.registers.gbr.wrapping_add(disp.into());
337        self.write_byte(address, self.registers.gpr[0] as u8, bus);
338    }
339
340    // MOV.W R0, @(disp,GBR)
341    // Stores a word into memory using indirect GBR with displacement addressing
342    pub(crate) fn mov_w_r0_disp_gbr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
343        let disp = (opcode & 0xFF) << 1;
344        let address = self.registers.gbr.wrapping_add(disp.into());
345        self.write_word(address, self.registers.gpr[0] as u16, bus);
346    }
347
348    // MOV.L R0, @(disp,GBR)
349    // Stores a longword into memory using indirect GBR with displacement addressing
350    pub(crate) fn mov_l_r0_disp_gbr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
351        let disp = (opcode & 0xFF) << 2;
352        let address = self.registers.gbr.wrapping_add(disp.into());
353        self.write_longword(address, self.registers.gpr[0], bus);
354    }
355
356    // MOVA @(disp,PC), R0
357    // Move effective address
358    pub(crate) fn mova(&mut self, opcode: u16) {
359        let disp = (opcode & 0xFF) << 2;
360        self.registers.gpr[0] = (self.registers.next_pc & !3).wrapping_add(disp.into());
361    }
362
363    // MOVT Rn
364    // Loads T into a general-purpose register
365    pub(crate) fn movt(&mut self, opcode: u16) {
366        let n = rn(opcode);
367        self.registers.gpr[n] = self.registers.sr.t.into();
368    }
369
370    // LDC Rm, SR
371    // Loads the status register from a general-purpose register
372    pub(crate) fn ldc_rm_sr(&mut self, opcode: u16) {
373        let n = rn(opcode);
374        self.registers.sr = self.registers.gpr[n].into();
375    }
376
377    // LDC Rm, GBR
378    // Loads GBR from a general-purpose register
379    pub(crate) fn ldc_rm_gbr(&mut self, opcode: u16) {
380        let n = rn(opcode);
381        self.registers.gbr = self.registers.gpr[n];
382    }
383
384    // LDC Rm, VBR
385    // Loads VBR from a general-purpose register
386    pub(crate) fn ldc_rm_vbr(&mut self, opcode: u16) {
387        let n = rn(opcode);
388        self.registers.vbr = self.registers.gpr[n];
389    }
390
391    // LDC.L @Rm+, SR
392    // Load SR from memory using post-increment register indirect addressing
393    pub(crate) fn ldc_postinc_sr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
394        let m = rn(opcode);
395        let address = self.registers.gpr[m];
396        self.registers.gpr[m] = address.wrapping_add(4);
397
398        self.registers.sr = self.read_longword(address, bus).into();
399
400        bus.increment_cycle_counter(2);
401    }
402
403    // LDC.L @Rm+, GBR
404    // Load GBR from memory using post-increment register indirect addressing
405    pub(crate) fn ldc_postinc_gbr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
406        let m = rn(opcode);
407        let address = self.registers.gpr[m];
408        self.registers.gpr[m] = address.wrapping_add(4);
409
410        self.registers.gbr = self.read_longword(address, bus);
411
412        bus.increment_cycle_counter(2);
413    }
414
415    // LDC.L @Rm+, VBR
416    // Load VBR from memory using post-increment register indirect addressing
417    pub(crate) fn ldc_postinc_vbr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
418        let m = rn(opcode);
419        let address = self.registers.gpr[m];
420        self.registers.gpr[m] = address.wrapping_add(4);
421
422        self.registers.vbr = self.read_longword(address, bus);
423
424        bus.increment_cycle_counter(2);
425    }
426
427    // LDS Rm, MACH
428    // Loads MACH from a general-purpose register
429    pub(crate) fn lds_rm_mach(&mut self, opcode: u16) {
430        let n = rn(opcode);
431        self.registers.mach = self.registers.gpr[n];
432    }
433
434    // LDS Rm, MACL
435    // Loads MACL from a general-purpose register
436    pub(crate) fn lds_rm_macl(&mut self, opcode: u16) {
437        let n = rn(opcode);
438        self.registers.macl = self.registers.gpr[n];
439    }
440
441    // LDS Rm, PR
442    // Loads PR from a general-purpose register
443    pub(crate) fn lds_rm_pr(&mut self, opcode: u16) {
444        let n = rn(opcode);
445        self.registers.pr = self.registers.gpr[n];
446    }
447
448    // LDS.L @Rm+, MACH
449    // Loads MACH from memory using post-increment indirect register addressing
450    pub(crate) fn lds_postinc_mach(&mut self, opcode: u16, bus: &mut impl BusInterface) {
451        let n = rn(opcode);
452        let address = self.registers.gpr[n];
453        self.registers.gpr[n] = address.wrapping_add(4);
454
455        self.registers.mach = self.read_longword(address, bus);
456    }
457
458    // LDS.L @Rm+, MACL
459    // Loads MACL from memory using post-increment indirect register addressing
460    pub(crate) fn lds_postinc_macl(&mut self, opcode: u16, bus: &mut impl BusInterface) {
461        let n = rn(opcode);
462        let address = self.registers.gpr[n];
463        self.registers.gpr[n] = address.wrapping_add(4);
464
465        self.registers.macl = self.read_longword(address, bus);
466    }
467
468    // LDS.L @Rm+, PR
469    // Loads PR from memory using post-increment indirect register addressing
470    pub(crate) fn lds_postinc_pr(&mut self, opcode: u16, bus: &mut impl BusInterface) {
471        let n = rn(opcode);
472        let address = self.registers.gpr[n];
473        self.registers.gpr[n] = address.wrapping_add(4);
474
475        self.registers.pr = self.read_longword(address, bus);
476    }
477
478    // STC SR, Rn
479    // Store SR into a general-purpose register
480    pub(crate) fn stc_sr_rn(&mut self, opcode: u16) {
481        let n = rn(opcode);
482        self.registers.gpr[n] = self.registers.sr.into();
483    }
484
485    // STC GBR, Rn
486    // Store GBR into a general-purpose register
487    pub(crate) fn stc_gbr_rn(&mut self, opcode: u16) {
488        let n = rn(opcode);
489        self.registers.gpr[n] = self.registers.gbr;
490    }
491
492    // STC VBR, Rn
493    // Store VBR into a general-purpose register
494    pub(crate) fn stc_vbr_rn(&mut self, opcode: u16) {
495        let n = rn(opcode);
496        self.registers.gpr[n] = self.registers.vbr;
497    }
498
499    // STC.L SR, @-Rn
500    // Store SR in memory using pre-decrement register addressing
501    pub(crate) fn stc_sr_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
502        let n = rn(opcode);
503        let address = self.registers.gpr[n].wrapping_sub(4);
504        self.registers.gpr[n] = address;
505
506        self.write_longword(address, self.registers.sr.into(), bus);
507
508        bus.increment_cycle_counter(1);
509    }
510
511    // STC.L GBR, @-Rn
512    // Store GBR in memory using pre-decrement register addressing
513    pub(crate) fn stc_gbr_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
514        let n = rn(opcode);
515        let address = self.registers.gpr[n].wrapping_sub(4);
516        self.registers.gpr[n] = address;
517
518        self.write_longword(address, self.registers.gbr, bus);
519
520        bus.increment_cycle_counter(1);
521    }
522
523    // STC.L VBR, @-Rn
524    // Store VBR in memory using pre-decrement register addressing
525    pub(crate) fn stc_vbr_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
526        let n = rn(opcode);
527        let address = self.registers.gpr[n].wrapping_sub(4);
528        self.registers.gpr[n] = address;
529
530        self.write_longword(address, self.registers.vbr, bus);
531
532        bus.increment_cycle_counter(1);
533    }
534
535    // STS MACH, Rn
536    // Store MACH into a general-purpose register
537    pub(crate) fn sts_mach_rn(&mut self, opcode: u16) {
538        let n = rn(opcode);
539        self.registers.gpr[n] = self.registers.mach;
540    }
541
542    // STS MACL, Rn
543    // Store MACL into a general-purpose register
544    pub(crate) fn sts_macl_rn(&mut self, opcode: u16) {
545        let n = rn(opcode);
546        self.registers.gpr[n] = self.registers.macl;
547    }
548
549    // STS PR, Rn
550    // Store PR into a general-purpose register
551    pub(crate) fn sts_pr_rn(&mut self, opcode: u16) {
552        let n = rn(opcode);
553        self.registers.gpr[n] = self.registers.pr;
554    }
555
556    // STS.L MACH, @-Rn
557    // Store MACH in memory using pre-decrement register addressing
558    pub(crate) fn sts_mach_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
559        let n = rn(opcode);
560        let address = self.registers.gpr[n].wrapping_sub(4);
561        self.registers.gpr[n] = address;
562
563        self.write_longword(address, self.registers.mach, bus);
564    }
565
566    // STS.L MACL, @-Rn
567    // Store MACL in memory using pre-decrement register addressing
568    pub(crate) fn sts_macl_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
569        let n = rn(opcode);
570        let address = self.registers.gpr[n].wrapping_sub(4);
571        self.registers.gpr[n] = address;
572
573        self.write_longword(address, self.registers.macl, bus);
574    }
575
576    // STS.L PR, @-Rn
577    // Store PR in memory using pre-decrement indirect register addressing
578    pub(crate) fn sts_pr_rn_predec(&mut self, opcode: u16, bus: &mut impl BusInterface) {
579        let n = rn(opcode);
580        let address = self.registers.gpr[n].wrapping_sub(4);
581        self.registers.gpr[n] = address;
582
583        self.write_longword(address, self.registers.pr, bus);
584    }
585
586    // CLRT
587    // Clear the T flag
588    pub(crate) fn clrt(&mut self) {
589        self.registers.sr.t = false;
590    }
591
592    // SETT
593    // Set the T flag
594    pub(crate) fn sett(&mut self) {
595        self.registers.sr.t = true;
596    }
597
598    // CLRMAC
599    // Clear the MAC registers
600    pub(crate) fn clrmac(&mut self) {
601        self.registers.macl = 0;
602        self.registers.mach = 0;
603    }
604
605    // SWAP.B Rm, Rn
606    // Swaps the lowest two bytes of a register
607    pub(crate) fn swap_b(&mut self, opcode: u16) {
608        let m = rm(opcode);
609        let n = rn(opcode);
610
611        let value = self.registers.gpr[m];
612        self.registers.gpr[n] =
613            (value & 0xFFFF0000) | ((value & 0xFF) << 8) | ((value >> 8) & 0xFF);
614    }
615
616    // SWAP.W Rm, Rn
617    // Swaps the words of a register
618    pub(crate) fn swap_w(&mut self, opcode: u16) {
619        let m = rm(opcode);
620        let n = rn(opcode);
621
622        let value = self.registers.gpr[m];
623        self.registers.gpr[n] = value.rotate_left(16);
624    }
625
626    // XTRCT Rm, Rn
627    // Extract the center 32 bits of the 64-bit value formed by Rm and Rn
628    pub(crate) fn xtrct(&mut self, opcode: u16) {
629        let m = rm(opcode);
630        let n = rn(opcode);
631
632        self.registers.gpr[n] = (self.registers.gpr[m] << 16) | (self.registers.gpr[n] >> 16);
633    }
634}