1 /* reg.c --- register set model for M32C simulator.
3 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This must come before any other includes. */
32 int enable_counting
= 0;
36 int addr_mask
= 0xffff;
37 int membus_mask
= 0xfffff;
40 unsigned int heapbottom
= 0;
41 unsigned int heaptop
= 0;
54 "intb", "intbl", "intbh",
55 "sp", "usp", "isp", "pc", "flags"
74 unsigned int b2mask
[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
75 unsigned int b2signbit
[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
76 int b2maxsigned
[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
77 int b2minsigned
[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
79 static regs_type oldregs
;
86 memset (®s
, 0, sizeof (regs
));
87 memset (&oldregs
, 0, sizeof (oldregs
));
91 set_pointer_width (int bytes
)
96 membus_mask
= 0x000fffff;
97 reg_bytes
[a0
] = reg_bytes
[a1
] = reg_bytes
[sb
] = reg_bytes
[fb
] =
98 reg_bytes
[sp
] = reg_bytes
[usp
] = reg_bytes
[isp
] = 2;
102 addr_mask
= 0xffffff;
103 membus_mask
= 0x00ffffff;
104 reg_bytes
[a0
] = reg_bytes
[a1
] = reg_bytes
[sb
] = reg_bytes
[fb
] =
105 reg_bytes
[sp
] = reg_bytes
[usp
] = reg_bytes
[isp
] = 3;
110 m32c_set_cpu (int cpu
)
116 set_pointer_width (2);
117 decode_opcode
= decode_r8c
;
121 set_pointer_width (3);
122 decode_opcode
= decode_m32c
;
131 get_reg_i (reg_id id
)
133 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
142 return b
->r_r0
& 0xff;
148 return b
->r_r1
& 0xff;
152 return b
->r_r2
* 65536 + b
->r_r0
;
156 return b
->r_r3
* 65536 + b
->r_r1
;
159 return b
->r_a0
& addr_mask
;
161 return b
->r_a1
& addr_mask
;
163 return (b
->r_a1
& 0xffff) * 65536 | (b
->r_a0
& 0xffff);
166 return b
->r_sb
& addr_mask
;
168 return b
->r_fb
& addr_mask
;
171 return regs
.r_intbh
* 65536 + regs
.r_intbl
;
178 return ((regs
.r_flags
& FLAGBIT_U
) ? regs
.r_usp
: regs
.
181 return regs
.r_usp
& addr_mask
;
183 return regs
.r_isp
& addr_mask
;
186 return regs
.r_pc
& membus_mask
;
197 unsigned int rv
= get_reg_i (id
);
198 if (trace
> ((id
!= pc
&& id
!= fb
&& id
!= sp
) ? 0 : 1))
199 printf ("get_reg (%s) = %0*x\n", reg_names
[id
], reg_bytes
[id
] * 2, rv
);
204 get_reg_ll (reg_id id
)
206 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
211 return ((DI
) b
->r_r3
<< 48
212 | (DI
) b
->r_r1
<< 32 | (DI
) b
->r_r2
<< 16 | (DI
) b
->r_r0
);
214 return ((DI
) b
->r_r3
<< 48
215 | (DI
) b
->r_r2
<< 32 | (DI
) b
->r_r1
<< 16 | (DI
) b
->r_r0
);
221 static int highest_sp
= 0, lowest_sp
= 0xffffff;
224 stack_heap_stats (void)
226 printf ("heap: %08x - %08x (%d bytes)\n", heapbottom
, heaptop
,
227 heaptop
- heapbottom
);
228 printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp
, highest_sp
,
229 highest_sp
- lowest_sp
);
233 put_reg (reg_id id
, unsigned int v
)
235 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
237 if (trace
> ((id
!= pc
) ? 0 : 1))
238 printf ("put_reg (%s) = %0*x\n", reg_names
[id
], reg_bytes
[id
] * 2, v
);
246 b
->r_r0
= (b
->r_r0
& 0xff) | (v
<< 8);
249 b
->r_r0
= (b
->r_r0
& 0xff00) | (v
& 0xff);
255 b
->r_r1
= (b
->r_r1
& 0xff) | (v
<< 8);
258 b
->r_r1
= (b
->r_r1
& 0xff00) | (v
& 0xff);
264 b
->r_r0
= v
& 0xffff;
271 b
->r_r1
= v
& 0xffff;
276 b
->r_a0
= v
& addr_mask
;
279 b
->r_a1
= v
& addr_mask
;
282 b
->r_a0
= v
& 0xffff;
287 b
->r_sb
= v
& addr_mask
;
290 b
->r_fb
= v
& addr_mask
;
294 regs
.r_intbl
= v
& 0xffff;
295 regs
.r_intbh
= v
>> 16;
298 regs
.r_intbl
= v
& 0xffff;
301 regs
.r_intbh
= v
& 0xff;
307 if (regs
.r_flags
& FLAGBIT_U
)
311 *spp
= v
& addr_mask
;
314 printf ("collision: pc %08lx heap %08x stack %08lx\n", regs
.r_pc
,
318 if (*spp
< lowest_sp
)
320 if (*spp
> highest_sp
)
325 regs
.r_usp
= v
& addr_mask
;
328 regs
.r_isp
= v
& addr_mask
;
332 regs
.r_pc
= v
& membus_mask
;
343 condition_true (int cond_id
)
348 static const char *cond_name
[] = {
349 "C", "C&!Z", "Z", "S",
350 "!C", "!(C&!Z)", "!Z", "!S",
351 "(S^O)|Z", "O", "!(S^O)", "unk",
352 "!((S^O)|Z)", "!O", "S^O", "unk"
354 switch (cond_id
& 15)
360 f
= FLAG_C
& !FLAG_Z
;
372 f
= !(FLAG_C
& !FLAG_Z
);
382 f
= (FLAG_S
^ FLAG_O
) | FLAG_Z
;
388 f
= !(FLAG_S
^ FLAG_O
);
391 f
= !((FLAG_S
^ FLAG_O
) | FLAG_Z
);
405 printf ("cond[%d] %s = %s\n", cond_id
, cond_name
[cond_id
& 15],
406 f
? "true" : "false");
410 static const char *cond_name
[] = {
411 "!C", "LEU", "!Z", "PZ",
412 "!O", "GT", "GE", "?",
413 "C", "GTU", "Z", "N",
414 "O", "LE", "LT", "!?"
416 switch (cond_id
& 15)
422 f
= !(FLAG_C
& !FLAG_Z
);
435 f
= !((FLAG_S
^ FLAG_O
) | FLAG_Z
);
438 f
= !(FLAG_S
^ FLAG_O
);
445 f
= FLAG_C
& !FLAG_Z
;
458 f
= (FLAG_S
^ FLAG_O
) | FLAG_Z
;
469 printf ("cond[%d] %s = %s\n", cond_id
, cond_name
[cond_id
& 15],
470 f
? "true" : "false");
476 set_flags (int mask
, int newbits
)
479 regs
.r_flags
&= ~mask
;
480 regs
.r_flags
|= newbits
& mask
;
483 printf ("flags now \033[32m %d", (regs
.r_flags
>> (A16
? 8 : 12)) & 7);
484 for (i
= 7; i
>= 0; i
--)
485 if (regs
.r_flags
& (1 << i
))
486 putchar ("CDZSBOIU"[i
]);
489 printf ("\033[0m\n");
494 set_oszc (int value
, int b
, int c
)
496 int mask
= b2mask
[b
];
501 if ((value
& mask
) == 0)
503 if (value
& b2signbit
[b
])
505 if ((value
> b2maxsigned
[b
]) || (value
< b2minsigned
[b
]))
507 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
| FLAGBIT_C
, f
);
511 set_szc (int value
, int b
, int c
)
513 int mask
= b2mask
[b
];
518 if ((value
& mask
) == 0)
520 if (value
& b2signbit
[b
])
522 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_C
, f
);
526 set_osz (int value
, int b
)
528 int mask
= b2mask
[b
];
531 if ((value
& mask
) == 0)
533 if (value
& b2signbit
[b
])
535 if (value
& ~mask
&& (value
& ~mask
) != ~mask
)
537 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
, f
);
541 set_sz (int value
, int b
)
543 int mask
= b2mask
[b
];
546 if ((value
& mask
) == 0)
548 if (value
& b2signbit
[b
])
550 set_flags (FLAGBIT_Z
| FLAGBIT_S
, f
);
554 set_zc (int z
, int c
)
556 set_flags (FLAGBIT_C
| FLAGBIT_Z
,
557 (c
? FLAGBIT_C
: 0) | (z
? FLAGBIT_Z
: 0));
563 set_flags (FLAGBIT_C
, c
? FLAGBIT_C
: 0);
567 put_reg_ll (reg_id id
, DI v
)
569 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
594 static char fn
[] = "CDZSBOIU";
595 printf ("%d.", (f
>> 12) & 7);
596 for (i
= 7; i
>= 0; i
--)
601 #define TRC(f,n, id) \
602 if (oldregs.f != regs.f) \
604 printf(" %s %0*x:%0*x", n, \
605 reg_bytes[id]*2, (unsigned int)oldregs.f, \
606 reg_bytes[id]*2, (unsigned int)regs.f); \
607 oldregs.f = regs.f; \
611 trace_register_changes (void)
615 printf ("\033[36mREGS:");
616 TRC (r
[0].r_r0
, "r0", r0
);
617 TRC (r
[0].r_r1
, "r1", r1
);
618 TRC (r
[0].r_r2
, "r2", r2
);
619 TRC (r
[0].r_r3
, "r3", r3
);
620 TRC (r
[0].r_a0
, "a0", a0
);
621 TRC (r
[0].r_a1
, "a1", a1
);
622 TRC (r
[0].r_sb
, "sb", sb
);
623 TRC (r
[0].r_fb
, "fb", fb
);
624 TRC (r
[1].r_r0
, "r0'", r0
);
625 TRC (r
[1].r_r1
, "r1'", r1
);
626 TRC (r
[1].r_r2
, "r2'", r2
);
627 TRC (r
[1].r_r3
, "r3'", r3
);
628 TRC (r
[1].r_a0
, "a0'", a0
);
629 TRC (r
[1].r_a1
, "a1'", a1
);
630 TRC (r
[1].r_sb
, "sb'", sb
);
631 TRC (r
[1].r_fb
, "fb'", fb
);
632 TRC (r_intbh
, "intbh", intbh
);
633 TRC (r_intbl
, "intbl", intbl
);
634 TRC (r_usp
, "usp", usp
);
635 TRC (r_isp
, "isp", isp
);
636 TRC (r_pc
, "pc", pc
);
637 if (oldregs
.r_flags
!= regs
.r_flags
)
640 print_flags (oldregs
.r_flags
);
642 print_flags (regs
.r_flags
);
644 printf ("\033[0m\n");
647 #define DRC(f, n, id) \
648 printf(" %-3s %0*x", n, \
649 reg_bytes[id]*2, (unsigned int)regs.f); \
652 m32c_dump_all_registers (void)
654 printf ("\033[36mREGS:");
655 DRC (r
[0].r_r0
, "r0", r0
);
656 DRC (r
[0].r_r1
, "r1", r1
);
657 DRC (r
[0].r_r2
, "r2", r2
);
658 DRC (r
[0].r_r3
, "r3", r3
);
659 DRC (r
[0].r_a0
, "a0", a0
);
660 DRC (r
[0].r_a1
, "a1", a1
);
661 DRC (r
[0].r_sb
, "sb", sb
);
662 DRC (r
[0].r_fb
, "fb", fb
);
664 DRC (r
[1].r_r0
, "r0'", r0
);
665 DRC (r
[1].r_r1
, "r1'", r1
);
666 DRC (r
[1].r_r2
, "r2'", r2
);
667 DRC (r
[1].r_r3
, "r3'", r3
);
668 DRC (r
[1].r_a0
, "a0'", a0
);
669 DRC (r
[1].r_a1
, "a1'", a1
);
670 DRC (r
[1].r_sb
, "sb'", sb
);
671 DRC (r
[1].r_fb
, "fb'", fb
);
673 DRC (r_intbh
, "intbh", intbh
);
674 DRC (r_intbl
, "intbl", intbl
);
675 DRC (r_usp
, "usp", usp
);
676 DRC (r_isp
, "isp", isp
);
677 DRC (r_pc
, "pc", pc
);
679 print_flags (regs
.r_flags
);
680 printf ("\033[0m\n");
681 /*sim_disasm_one (); */