1 /* reg.c --- register set model for RX 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. */
34 int enable_counting
= 0;
45 unsigned int heapbottom
= 0;
46 unsigned int heaptop
= 0;
49 /* general registers */
50 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
51 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
52 /* control register */
53 "psw", "pc", "usp", "fpsw", "RES", "RES", "RES", "RES",
54 "bpsw", "bpc", "isp", "fintv", "intb", "RES", "RES", "RES",
55 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
56 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
57 "temp", "acc", "acchi", "accmi", "acclo"
60 unsigned int b2mask
[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
61 unsigned int b2signbit
[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
62 int b2maxsigned
[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
63 int b2minsigned
[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
65 static regs_type oldregs
;
70 memset (®s
, 0, sizeof (regs
));
71 memset (&oldregs
, 0, sizeof (oldregs
));
83 return regs
.r_psw
& FLAGBIT_U
? regs
.r_usp
: regs
.r_isp
;
85 if (id
>= 1 && id
<= 15)
111 return (SI
)(regs
.r_acc
>> 32);
113 return (SI
)(regs
.r_acc
>> 16);
115 return (SI
)regs
.r_acc
;
123 unsigned int rv
= get_reg_i (id
);
124 if (trace
> ((id
!= pc
&& id
!= sp
) ? 0 : 1))
125 printf ("get_reg (%s) = %08x\n", reg_names
[id
], rv
);
129 static unsigned long long
144 unsigned long long rv
= get_reg64_i (id
);
145 if (trace
> ((id
!= pc
&& id
!= sp
) ? 0 : 1))
146 printf ("get_reg (%s) = %016llx\n", reg_names
[id
], rv
);
150 static int highest_sp
= 0, lowest_sp
= 0xffffff;
153 stack_heap_stats (void)
155 if (heapbottom
< heaptop
)
156 printf ("heap: %08x - %08x (%d bytes)\n", heapbottom
, heaptop
,
157 heaptop
- heapbottom
);
158 if (lowest_sp
< highest_sp
)
159 printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp
, highest_sp
,
160 highest_sp
- lowest_sp
);
164 put_reg (int id
, unsigned int v
)
166 if (trace
> ((id
!= pc
) ? 0 : 1))
167 printf ("put_reg (%s) = %08x\n", reg_names
[id
], v
);
178 /* This is an odd one - The Cx flags are AND'd, and the FS flag
180 anded
= regs
.r_fpsw
& v
;
181 anded
|= ~ FPSWBITS_CMASK
;
182 regs
.r_fpsw
= v
& anded
;
183 if (regs
.r_fpsw
& FPSWBITS_FMASK
)
184 regs
.r_fpsw
|= FPSWBITS_FSUM
;
186 regs
.r_fpsw
&= ~FPSWBITS_FSUM
;
212 regs
.r_acc
= (regs
.r_acc
& 0xffffffffULL
) | ((DI
)v
<< 32);
215 regs
.r_acc
= (regs
.r_acc
& ~0xffffffff0000ULL
) | ((DI
)v
<< 16);
218 regs
.r_acc
= (regs
.r_acc
& ~0xffffffffULL
) | ((DI
)v
);
221 case 0: /* Stack pointer is "in" R0. */
227 const char * fname
= NULL
;
229 sim_get_current_source_location (& dummy
, & fname
, &line
);
231 /* The setjmp and longjmp functions play tricks with the stack pointer. */
233 || (strcmp (fname
, "_setjmp") != 0
234 && strcmp (fname
, "_longjmp") != 0))
236 printf ("collision in %s: pc %08x heap %08x stack %08x\n",
237 fname
, (unsigned int) regs
.r_pc
, heaptop
, v
);
249 if (regs
.r_psw
& FLAGBIT_U
)
257 if (id
>= 1 && id
<= 15)
265 put_reg64 (int id
, unsigned long long v
)
267 if (trace
> ((id
!= pc
) ? 0 : 1))
268 printf ("put_reg (%s) = %016llx\n", reg_names
[id
], v
);
281 condition_true (int cond_id
)
285 static const char *cond_name
[] = {
303 switch (cond_id
& 15)
318 f
= FLAG_C
& !FLAG_Z
;
321 f
= !(FLAG_C
& !FLAG_Z
);
331 f
= !(FLAG_S
^ FLAG_O
);
337 f
= !((FLAG_S
^ FLAG_O
) | FLAG_Z
);
340 f
= (FLAG_S
^ FLAG_O
) | FLAG_Z
;
355 if (trace
&& ((cond_id
& 15) != 14))
356 printf ("cond[%d] %s = %s\n", cond_id
, cond_name
[cond_id
& 15],
357 f
? "true" : "false");
362 set_flags (int mask
, int newbits
)
364 regs
.r_psw
&= rx_flagand
;
365 regs
.r_psw
|= rx_flagor
;
366 regs
.r_psw
|= (newbits
& mask
& rx_flagmask
);
371 printf ("flags now \033[32m %d", (int)((regs
.r_psw
>> 24) & 7));
372 for (i
= 17; i
>= 0; i
--)
373 if (0x3000f & (1 << i
))
375 if (regs
.r_psw
& (1 << i
))
376 putchar ("CZSO------------IU"[i
]);
380 printf ("\033[0m\n");
385 set_oszc (long long value
, int b
, int c
)
387 unsigned int mask
= b2mask
[b
];
392 if ((value
& mask
) == 0)
394 if (value
& b2signbit
[b
])
396 if ((value
> b2maxsigned
[b
]) || (value
< b2minsigned
[b
]))
398 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
| FLAGBIT_C
, f
);
402 set_szc (long long value
, int b
, int c
)
404 unsigned int mask
= b2mask
[b
];
409 if ((value
& mask
) == 0)
411 if (value
& b2signbit
[b
])
413 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_C
, f
);
417 set_osz (long long value
, int b
)
419 unsigned int mask
= b2mask
[b
];
422 if ((value
& mask
) == 0)
424 if (value
& b2signbit
[b
])
426 if ((value
> b2maxsigned
[b
]) || (value
< b2minsigned
[b
]))
428 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
, f
);
432 set_sz (long long value
, int b
)
434 unsigned int mask
= b2mask
[b
];
437 if ((value
& mask
) == 0)
439 if (value
& b2signbit
[b
])
441 set_flags (FLAGBIT_Z
| FLAGBIT_S
, f
);
445 set_zc (int z
, int c
)
447 set_flags (FLAGBIT_C
| FLAGBIT_Z
,
448 (c
? FLAGBIT_C
: 0) | (z
? FLAGBIT_Z
: 0));
454 set_flags (FLAGBIT_C
, c
? FLAGBIT_C
: 0);
464 ipl
= (rpsw
& FLAGBITS_IPL
) >> FLAGSHIFT_IPL
;
467 *bp
++ = (ipl
/ 10) + '0';
471 for (i
= 20; i
>= 0; i
--)
472 if (0x13000f & (1 << i
))
475 *bp
++ = "CZSO------------IU--P"[i
];
486 static char buf
[100];
488 int i
; /* ---+---+---+---+---+---+---+---+ */
489 const char s1
[] = "FFFFFF-----------EEEEE-DCCCCCCRR";
490 const char s2
[] = "SXUZOV-----------XUZOV-NEXUZOV01";
491 const char rm
[4][3] = { "RC", "RZ", "RP", "RN" };
493 for (i
= 31; i
>= 0; i
--)
494 if (0xfc007dfc & (1 << i
))
506 strcpy (bp
, rm
[rpsw
&3]);
511 if (oldregs.f != regs.f) \
513 if (tag) { printf ("%s", tag); tag = 0; } \
514 printf(" %s %08x:%08x", n, \
515 (unsigned int)oldregs.f, \
516 (unsigned int)regs.f); \
517 oldregs.f = regs.f; \
521 trace_register_changes (void)
523 char *tag
= "\033[36mREGS:";
529 TRC (r
[i
], reg_names
[i
]);
530 TRC (r_intb
, "intb");
533 if (oldregs
.r_psw
!= regs
.r_psw
)
535 if (tag
) { printf ("%s", tag
); tag
= 0; }
536 printf(" psw %s:", psw2str(oldregs
.r_psw
));
537 printf("%s", psw2str(regs
.r_psw
));
538 oldregs
.r_psw
= regs
.r_psw
;
541 if (oldregs
.r_fpsw
!= regs
.r_fpsw
)
543 if (tag
) { printf ("%s", tag
); tag
= 0; }
544 printf(" fpsw %s:", fpsw2str(oldregs
.r_fpsw
));
545 printf("%s", fpsw2str(regs
.r_fpsw
));
546 oldregs
.r_fpsw
= regs
.r_fpsw
;
549 if (oldregs
.r_acc
!= regs
.r_acc
)
551 if (tag
) { printf ("%s", tag
); tag
= 0; }
552 printf(" acc %016" PRIx64
":", oldregs
.r_acc
);
553 printf("%016" PRIx64
, regs
.r_acc
);
554 oldregs
.r_acc
= regs
.r_acc
;
558 printf ("\033[0m\n");