1 /* reg.c --- register set model for RX simulator.
3 Copyright (C) 2005, 2007, 2008, 2009, 2010 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/>. */
32 int enable_counting = 0;
43 unsigned int heapbottom = 0;
44 unsigned int heaptop = 0;
47 /* general registers */
48 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
49 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
50 /* control register */
51 "psw", "pc", "usp", "fpsw", "RES", "RES", "RES", "RES",
52 "bpsw", "bpc", "isp", "fintv", "intb", "RES", "RES", "RES",
53 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
54 "RES", "RES", "RES", "RES", "RES", "RES", "RES", "RES",
55 "temp", "acc", "acchi", "accmi", "acclo"
58 unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
59 unsigned int b2signbit[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
60 int b2maxsigned[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
61 int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
63 static regs_type oldregs;
68 memset (®s, 0, sizeof (regs));
69 memset (&oldregs, 0, sizeof (oldregs));
76 return regs.r_psw & FLAGBIT_U ? regs.r_usp : regs.r_isp;
78 if (id >= 1 && id <= 15)
104 return (SI)(regs.r_acc >> 32);
106 return (SI)(regs.r_acc >> 16);
108 return (SI)regs.r_acc;
116 unsigned int rv = get_reg_i (id);
117 if (trace > ((id != pc && id != sp) ? 0 : 1))
118 printf ("get_reg (%s) = %08x\n", reg_names[id], rv);
122 static unsigned long long
137 unsigned long long rv = get_reg64_i (id);
138 if (trace > ((id != pc && id != sp) ? 0 : 1))
139 printf ("get_reg (%s) = %016llx\n", reg_names[id], rv);
143 static int highest_sp = 0, lowest_sp = 0xffffff;
148 if (heapbottom < heaptop)
149 printf ("heap: %08x - %08x (%d bytes)\n", heapbottom, heaptop,
150 heaptop - heapbottom);
151 if (lowest_sp < highest_sp)
152 printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp, highest_sp,
153 highest_sp - lowest_sp);
157 put_reg (int id, unsigned int v)
159 if (trace > ((id != pc) ? 0 : 1))
160 printf ("put_reg (%s) = %08x\n", reg_names[id], v);
171 /* This is an odd one - The Cx flags are AND'd, and the FS flag
173 anded = regs.r_fpsw & v;
174 anded |= ~ FPSWBITS_CMASK;
175 regs.r_fpsw = v & anded;
176 if (regs.r_fpsw & FPSWBITS_FMASK)
177 regs.r_fpsw |= FPSWBITS_FSUM;
179 regs.r_fpsw &= ~FPSWBITS_FSUM;
205 regs.r_acc = (regs.r_acc & 0xffffffffULL) | ((DI)v << 32);
208 regs.r_acc = (regs.r_acc & ~0xffffffff0000ULL) | ((DI)v << 16);
211 regs.r_acc = (regs.r_acc & ~0xffffffffULL) | ((DI)v);
214 case 0: /* Stack pointer is "in" R0. */
220 const char * fname = NULL;
222 sim_get_current_source_location (& dummy, & fname, &line);
224 /* The setjmp and longjmp functions play tricks with the stack pointer. */
226 || (strcmp (fname, "_setjmp") != 0
227 && strcmp (fname, "_longjmp") != 0))
229 printf ("collision in %s: pc %08x heap %08x stack %08x\n",
230 fname, (unsigned int) regs.r_pc, heaptop, v);
242 if (regs.r_psw & FLAGBIT_U)
250 if (id >= 1 || id <= 15)
258 put_reg64 (int id, unsigned long long v)
260 if (trace > ((id != pc) ? 0 : 1))
261 printf ("put_reg (%s) = %016llx\n", reg_names[id], v);
274 condition_true (int cond_id)
278 static const char *cond_name[] = {
296 switch (cond_id & 15)
311 f = FLAG_C & !FLAG_Z;
314 f = !(FLAG_C & !FLAG_Z);
324 f = !(FLAG_S ^ FLAG_O);
330 f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
333 f = (FLAG_S ^ FLAG_O) | FLAG_Z;
348 if (trace && ((cond_id & 15) != 14))
349 printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
350 f ? "true" : "false");
355 set_flags (int mask, int newbits)
357 regs.r_psw &= rx_flagand;
358 regs.r_psw |= rx_flagor;
359 regs.r_psw |= (newbits & mask & rx_flagmask);
364 printf ("flags now \033[32m %d", (int)((regs.r_psw >> 24) & 7));
365 for (i = 17; i >= 0; i--)
366 if (0x3000f & (1 << i))
368 if (regs.r_psw & (1 << i))
369 putchar ("CZSO------------IU"[i]);
373 printf ("\033[0m\n");
378 set_oszc (long long value, int b, int c)
380 unsigned int mask = b2mask[b];
385 if ((value & mask) == 0)
387 if (value & b2signbit[b])
389 if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
391 set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
395 set_szc (long long value, int b, int c)
397 unsigned int mask = b2mask[b];
402 if ((value & mask) == 0)
404 if (value & b2signbit[b])
406 set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
410 set_osz (long long value, int b)
412 unsigned int mask = b2mask[b];
415 if ((value & mask) == 0)
417 if (value & b2signbit[b])
419 if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
421 set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
425 set_sz (long long value, int b)
427 unsigned int mask = b2mask[b];
430 if ((value & mask) == 0)
432 if (value & b2signbit[b])
434 set_flags (FLAGBIT_Z | FLAGBIT_S, f);
438 set_zc (int z, int c)
440 set_flags (FLAGBIT_C | FLAGBIT_Z,
441 (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
447 set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
457 ipl = (rpsw & FLAGBITS_IPL) >> FLAGSHIFT_IPL;
460 *bp++ = (ipl / 10) + '0';
464 for (i = 20; i >= 0; i--)
465 if (0x13000f & (1 << i))
468 *bp++ = "CZSO------------IU--P"[i];
479 static char buf[100];
481 int i; /* ---+---+---+---+---+---+---+---+ */
482 const char s1[] = "FFFFFF-----------EEEEE-DCCCCCCRR";
483 const char s2[] = "SXUZOV-----------XUZOV-NEXUZOV01";
484 const char rm[4][3] = { "RC", "RZ", "RP", "RN" };
486 for (i = 31; i >= 0; i--)
487 if (0xfc007dfc & (1 << i))
499 strcpy (bp, rm[rpsw&3]);
504 if (oldregs.f != regs.f) \
506 if (tag) { printf (tag); tag = 0; } \
507 printf(" %s %08x:%08x", n, \
508 (unsigned int)oldregs.f, \
509 (unsigned int)regs.f); \
510 oldregs.f = regs.f; \
514 trace_register_changes (void)
516 char *tag = "\033[36mREGS:";
522 TRC (r[i], reg_names[i]);
523 TRC (r_intb, "intb");
526 if (oldregs.r_psw != regs.r_psw)
528 if (tag) { printf (tag); tag = 0; }
529 printf(" psw %s:", psw2str(oldregs.r_psw));
530 printf("%s", psw2str(regs.r_psw));
531 oldregs.r_psw = regs.r_psw;
534 if (oldregs.r_fpsw != regs.r_fpsw)
536 if (tag) { printf (tag); tag = 0; }
537 printf(" fpsw %s:", fpsw2str(oldregs.r_fpsw));
538 printf("%s", fpsw2str(regs.r_fpsw));
539 oldregs.r_fpsw = regs.r_fpsw;
542 if (oldregs.r_acc != regs.r_acc)
544 if (tag) { printf (tag); tag = 0; }
545 printf(" acc %016llx:", oldregs.r_acc);
546 printf("%016llx", regs.r_acc);
547 oldregs.r_acc = regs.r_acc;
551 printf ("\033[0m\n");