1 /* reg.c --- register set model for M32C simulator.
3 Copyright (C) 2005 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 The GNU simulators are free software; you can redistribute them and/or
9 modify them under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 The GNU simulators are distributed in the hope that they will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the GNU simulators; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 int enable_counting
= 0;
35 int addr_mask
= 0xffff;
36 int membus_mask
= 0xfffff;
39 unsigned int heapbottom
= 0;
40 unsigned int heaptop
= 0;
53 "intb", "intbl", "intbh",
54 "sp", "usp", "isp", "pc", "flags"
73 unsigned int b2mask
[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
74 unsigned int b2signbit
[] = { 0, (1 << 7), (1 << 15), (1 << 24), (1 << 31) };
75 int b2maxsigned
[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
76 int b2minsigned
[] = { 0, -128, -32768, -8388608, -2147483647 - 1 };
78 static regs_type oldregs
;
83 memset (®s
, 0, sizeof (regs
));
84 memset (&oldregs
, 0, sizeof (oldregs
));
88 set_pointer_width (int bytes
)
93 membus_mask
= 0x000fffff;
94 reg_bytes
[a0
] = reg_bytes
[a1
] = reg_bytes
[sb
] = reg_bytes
[fb
] =
95 reg_bytes
[sp
] = reg_bytes
[usp
] = reg_bytes
[isp
] = 2;
100 membus_mask
= 0x00ffffff;
101 reg_bytes
[a0
] = reg_bytes
[a1
] = reg_bytes
[sb
] = reg_bytes
[fb
] =
102 reg_bytes
[sp
] = reg_bytes
[usp
] = reg_bytes
[isp
] = 3;
107 m32c_set_cpu (int cpu
)
113 set_pointer_width (2);
114 decode_opcode
= decode_r8c
;
118 set_pointer_width (3);
119 decode_opcode
= decode_m32c
;
128 get_reg_i (reg_id id
)
130 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
139 return b
->r_r0
& 0xff;
145 return b
->r_r1
& 0xff;
149 return b
->r_r2
* 65536 + b
->r_r0
;
153 return b
->r_r3
* 65536 + b
->r_r1
;
156 return b
->r_a0
& addr_mask
;
158 return b
->r_a1
& addr_mask
;
160 return (b
->r_a1
& 0xffff) * 65536 | (b
->r_a0
& 0xffff);
163 return b
->r_sb
& addr_mask
;
165 return b
->r_fb
& addr_mask
;
168 return regs
.r_intbh
* 65536 + regs
.r_intbl
;
175 return ((regs
.r_flags
& FLAGBIT_U
) ? regs
.r_usp
: regs
.
178 return regs
.r_usp
& addr_mask
;
180 return regs
.r_isp
& addr_mask
;
183 return regs
.r_pc
& membus_mask
;
194 unsigned int rv
= get_reg_i (id
);
195 if (trace
> ((id
!= pc
&& id
!= fb
&& id
!= sp
) ? 0 : 1))
196 printf ("get_reg (%s) = %0*x\n", reg_names
[id
], reg_bytes
[id
] * 2, rv
);
201 get_reg_ll (reg_id id
)
203 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
208 return ((DI
) b
->r_r3
<< 48
209 | (DI
) b
->r_r1
<< 32 | (DI
) b
->r_r2
<< 16 | (DI
) b
->r_r0
);
211 return ((DI
) b
->r_r3
<< 48
212 | (DI
) b
->r_r2
<< 32 | (DI
) b
->r_r1
<< 16 | (DI
) b
->r_r0
);
218 static int highest_sp
= 0, lowest_sp
= 0xffffff;
223 printf ("heap: %08x - %08x (%d bytes)\n", heapbottom
, heaptop
,
224 heaptop
- heapbottom
);
225 printf ("stack: %08x - %08x (%d bytes)\n", lowest_sp
, highest_sp
,
226 highest_sp
- lowest_sp
);
230 put_reg (reg_id id
, unsigned int v
)
232 if (trace
> ((id
!= pc
) ? 0 : 1))
233 printf ("put_reg (%s) = %0*x\n", reg_names
[id
], reg_bytes
[id
] * 2, v
);
235 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
242 b
->r_r0
= (b
->r_r0
& 0xff) | (v
<< 8);
245 b
->r_r0
= (b
->r_r0
& 0xff00) | (v
& 0xff);
251 b
->r_r1
= (b
->r_r1
& 0xff) | (v
<< 8);
254 b
->r_r1
= (b
->r_r1
& 0xff00) | (v
& 0xff);
260 b
->r_r0
= v
& 0xffff;
267 b
->r_r1
= v
& 0xffff;
272 b
->r_a0
= v
& addr_mask
;
275 b
->r_a1
= v
& addr_mask
;
278 b
->r_a0
= v
& 0xffff;
283 b
->r_sb
= v
& addr_mask
;
286 b
->r_fb
= v
& addr_mask
;
290 regs
.r_intbl
= v
& 0xffff;
291 regs
.r_intbh
= v
>> 16;
294 regs
.r_intbl
= v
& 0xffff;
297 regs
.r_intbh
= v
& 0xff;
303 if (regs
.r_flags
& FLAGBIT_U
)
307 *spp
= v
& addr_mask
;
310 printf ("collision: pc %08lx heap %08x stack %08lx\n", regs
.r_pc
,
314 if (*spp
< lowest_sp
)
316 if (*spp
> highest_sp
)
321 regs
.r_usp
= v
& addr_mask
;
324 regs
.r_isp
= v
& addr_mask
;
328 regs
.r_pc
= v
& membus_mask
;
339 condition_true (int cond_id
)
344 static const char *cond_name
[] = {
345 "C", "C&!Z", "Z", "S",
346 "!C", "!(C&!Z)", "!Z", "!S",
347 "(S^O)|Z", "O", "!(S^O)", "unk",
348 "!((S^O)|Z)", "!O", "S^O", "unk"
350 switch (cond_id
& 15)
356 f
= FLAG_C
& !FLAG_Z
;
368 f
= !(FLAG_C
& !FLAG_Z
);
378 f
= (FLAG_S
^ FLAG_O
) | FLAG_Z
;
384 f
= !(FLAG_S
^ FLAG_O
);
387 f
= !((FLAG_S
^ FLAG_O
) | FLAG_Z
);
401 printf ("cond[%d] %s = %s\n", cond_id
, cond_name
[cond_id
& 15],
402 f
? "true" : "false");
406 static const char *cond_name
[] = {
407 "!C", "LEU", "!Z", "PZ",
408 "!O", "GT", "GE", "?",
409 "C", "GTU", "Z", "N",
410 "O", "LE", "LT", "!?"
412 switch (cond_id
& 15)
418 f
= !(FLAG_C
& !FLAG_Z
);
431 f
= !((FLAG_S
^ FLAG_O
) | FLAG_Z
);
434 f
= !(FLAG_S
^ FLAG_O
);
441 f
= FLAG_C
& !FLAG_Z
;
454 f
= (FLAG_S
^ FLAG_O
) | FLAG_Z
;
465 printf ("cond[%d] %s = %s\n", cond_id
, cond_name
[cond_id
& 15],
466 f
? "true" : "false");
472 set_flags (int mask
, int newbits
)
475 regs
.r_flags
&= ~mask
;
476 regs
.r_flags
|= newbits
& mask
;
479 printf ("flags now \033[32m %d", (regs
.r_flags
>> (A16
? 8 : 12)) & 7);
480 for (i
= 7; i
>= 0; i
--)
481 if (regs
.r_flags
& (1 << i
))
482 putchar ("CDZSBOIU"[i
]);
485 printf ("\033[0m\n");
490 set_oszc (int value
, int b
, int c
)
492 int mask
= b2mask
[b
];
497 if ((value
& mask
) == 0)
499 if (value
& b2signbit
[b
])
501 if ((value
> b2maxsigned
[b
]) || (value
< b2minsigned
[b
]))
503 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
| FLAGBIT_C
, f
);
507 set_szc (int value
, int b
, int c
)
509 int mask
= b2mask
[b
];
514 if ((value
& mask
) == 0)
516 if (value
& b2signbit
[b
])
518 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_C
, f
);
522 set_osz (int value
, int b
)
524 int mask
= b2mask
[b
];
527 if ((value
& mask
) == 0)
529 if (value
& b2signbit
[b
])
531 if (value
& ~mask
&& (value
& ~mask
) != ~mask
)
533 set_flags (FLAGBIT_Z
| FLAGBIT_S
| FLAGBIT_O
, f
);
537 set_sz (int value
, int b
)
539 int mask
= b2mask
[b
];
542 if ((value
& mask
) == 0)
544 if (value
& b2signbit
[b
])
546 set_flags (FLAGBIT_Z
| FLAGBIT_S
, f
);
550 set_zc (int z
, int c
)
552 set_flags (FLAGBIT_C
| FLAGBIT_Z
,
553 (c
? FLAGBIT_C
: 0) | (z
? FLAGBIT_Z
: 0));
559 set_flags (FLAGBIT_C
, c
? FLAGBIT_C
: 0);
563 put_reg_ll (reg_id id
, DI v
)
565 reg_bank_type
*b
= regs
.r
+ (FLAG_B
? 1 : 0);
586 #define TRC(f,n, id) \
587 if (oldregs.f != regs.f) \
589 printf(" %s %0*x:%0*x", n, \
590 reg_bytes[id]*2, (unsigned int)oldregs.f, \
591 reg_bytes[id]*2, (unsigned int)regs.f); \
592 oldregs.f = regs.f; \
596 trace_register_changes ()
600 printf ("\033[36mREGS:");
601 TRC (r
[0].r_r0
, "r0", r0
);
602 TRC (r
[0].r_r1
, "r1", r1
);
603 TRC (r
[0].r_r2
, "r2", r2
);
604 TRC (r
[0].r_r3
, "r3", r3
);
605 TRC (r
[0].r_a0
, "a0", a0
);
606 TRC (r
[0].r_a1
, "a1", a1
);
607 TRC (r
[0].r_sb
, "sb", sb
);
608 TRC (r
[0].r_fb
, "fb", fb
);
609 TRC (r
[1].r_r0
, "r0'", r0
);
610 TRC (r
[1].r_r1
, "r1'", r1
);
611 TRC (r
[1].r_r2
, "r2'", r2
);
612 TRC (r
[1].r_r3
, "r3'", r3
);
613 TRC (r
[1].r_a0
, "a0'", a0
);
614 TRC (r
[1].r_a1
, "a1'", a1
);
615 TRC (r
[1].r_sb
, "sb'", sb
);
616 TRC (r
[1].r_fb
, "fb'", fb
);
617 TRC (r_intbh
, "intbh", intbh
);
618 TRC (r_intbl
, "intbl", intbl
);
619 TRC (r_usp
, "usp", usp
);
620 TRC (r_isp
, "isp", isp
);
621 TRC (r_pc
, "pc", pc
);
622 TRC (r_flags
, "flags", flags
);
623 printf ("\033[0m\n");