OSDN Git Service

Copyright updates for 2007.
[pf3gnuchains/pf3gnuchains3x.git] / sim / m32c / reg.c
1 /* reg.c --- register set model for M32C simulator.
2
3 Copyright (C) 2005, 2007 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5
6 This file is part of the GNU simulators.
7
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.
12
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.
17
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
21 02110-1301, USA  */
22
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "cpu.h"
29
30 int verbose = 0;
31 int trace = 0;
32 int enable_counting = 0;
33
34 regs_type regs;
35 int addr_mask = 0xffff;
36 int membus_mask = 0xfffff;
37 int m32c_cpu = 0;
38 int step_result;
39 unsigned int heapbottom = 0;
40 unsigned int heaptop = 0;
41
42 char *reg_names[] = {
43   "mem",
44   "r0", "r0h", "r0l",
45   "r1", "r1h", "r1l",
46   "r2", "r2r0",
47   "r3", "r3r1",
48   "r3r1r2r0",
49   "r3r2r1r0",
50   "a0",
51   "a1", "a1a0",
52   "sb", "fb",
53   "intb", "intbl", "intbh",
54   "sp", "usp", "isp", "pc", "flags"
55 };
56
57 int reg_bytes[] = {
58   0,
59   2, 1, 1,
60   2, 1, 1,
61   2, 4,
62   2, 4,
63   8,
64   8,
65   2,
66   2, 4,
67   2, 2,
68   2, 1, 3,
69   2, 2, 2, 3, 2
70 };
71
72
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 };
77
78 static regs_type oldregs;
79
80 void
81 init_regs (void)
82 {
83   memset (&regs, 0, sizeof (regs));
84   memset (&oldregs, 0, sizeof (oldregs));
85 }
86
87 void
88 set_pointer_width (int bytes)
89 {
90   if (bytes == 2)
91     {
92       addr_mask = 0xffff;
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;
96     }
97   else
98     {
99       addr_mask = 0xffffff;
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;
103     }
104 }
105
106 void
107 m32c_set_cpu (int cpu)
108 {
109   switch (cpu)
110     {
111     case CPU_R8C:
112     case CPU_M16C:
113       set_pointer_width (2);
114       decode_opcode = decode_r8c;
115       break;
116     case CPU_M32CM:
117     case CPU_M32C:
118       set_pointer_width (3);
119       decode_opcode = decode_m32c;
120       break;
121     default:
122       abort ();
123     }
124   m32c_cpu = cpu;
125 }
126
127 static unsigned int
128 get_reg_i (reg_id id)
129 {
130   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
131
132   switch (id)
133     {
134     case r0:
135       return b->r_r0;
136     case r0h:
137       return b->r_r0 >> 8;
138     case r0l:
139       return b->r_r0 & 0xff;
140     case r1:
141       return b->r_r1;
142     case r1h:
143       return b->r_r1 >> 8;
144     case r1l:
145       return b->r_r1 & 0xff;
146     case r2:
147       return b->r_r2;
148     case r2r0:
149       return b->r_r2 * 65536 + b->r_r0;
150     case r3:
151       return b->r_r3;
152     case r3r1:
153       return b->r_r3 * 65536 + b->r_r1;
154
155     case a0:
156       return b->r_a0 & addr_mask;
157     case a1:
158       return b->r_a1 & addr_mask;
159     case a1a0:
160       return (b->r_a1 & 0xffff) * 65536 | (b->r_a0 & 0xffff);
161
162     case sb:
163       return b->r_sb & addr_mask;
164     case fb:
165       return b->r_fb & addr_mask;
166
167     case intb:
168       return regs.r_intbh * 65536 + regs.r_intbl;
169     case intbl:
170       return regs.r_intbl;
171     case intbh:
172       return regs.r_intbh;
173
174     case sp:
175       return ((regs.r_flags & FLAGBIT_U) ? regs.r_usp : regs.
176               r_isp) & addr_mask;
177     case usp:
178       return regs.r_usp & addr_mask;
179     case isp:
180       return regs.r_isp & addr_mask;
181
182     case pc:
183       return regs.r_pc & membus_mask;
184     case flags:
185       return regs.r_flags;
186     default:
187       abort ();
188     }
189 }
190
191 unsigned int
192 get_reg (reg_id id)
193 {
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);
197   return rv;
198 }
199
200 DI
201 get_reg_ll (reg_id id)
202 {
203   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
204
205   switch (id)
206     {
207     case r3r1r2r0:
208       return ((DI) b->r_r3 << 48
209               | (DI) b->r_r1 << 32 | (DI) b->r_r2 << 16 | (DI) b->r_r0);
210     case r3r2r1r0:
211       return ((DI) b->r_r3 << 48
212               | (DI) b->r_r2 << 32 | (DI) b->r_r1 << 16 | (DI) b->r_r0);
213     default:
214       return get_reg (id);
215     }
216 }
217
218 static int highest_sp = 0, lowest_sp = 0xffffff;
219
220 void
221 stack_heap_stats ()
222 {
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);
227 }
228
229 void
230 put_reg (reg_id id, unsigned int v)
231 {
232   if (trace > ((id != pc) ? 0 : 1))
233     printf ("put_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id] * 2, v);
234
235   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
236   switch (id)
237     {
238     case r0:
239       b->r_r0 = v;
240       break;
241     case r0h:
242       b->r_r0 = (b->r_r0 & 0xff) | (v << 8);
243       break;
244     case r0l:
245       b->r_r0 = (b->r_r0 & 0xff00) | (v & 0xff);
246       break;
247     case r1:
248       b->r_r1 = v;
249       break;
250     case r1h:
251       b->r_r1 = (b->r_r1 & 0xff) | (v << 8);
252       break;
253     case r1l:
254       b->r_r1 = (b->r_r1 & 0xff00) | (v & 0xff);
255       break;
256     case r2:
257       b->r_r2 = v;
258       break;
259     case r2r0:
260       b->r_r0 = v & 0xffff;
261       b->r_r2 = v >> 16;
262       break;
263     case r3:
264       b->r_r3 = v;
265       break;
266     case r3r1:
267       b->r_r1 = v & 0xffff;
268       b->r_r3 = v >> 16;
269       break;
270
271     case a0:
272       b->r_a0 = v & addr_mask;
273       break;
274     case a1:
275       b->r_a1 = v & addr_mask;
276       break;
277     case a1a0:
278       b->r_a0 = v & 0xffff;
279       b->r_a1 = v >> 16;
280       break;
281
282     case sb:
283       b->r_sb = v & addr_mask;
284       break;
285     case fb:
286       b->r_fb = v & addr_mask;
287       break;
288
289     case intb:
290       regs.r_intbl = v & 0xffff;
291       regs.r_intbh = v >> 16;
292       break;
293     case intbl:
294       regs.r_intbl = v & 0xffff;
295       break;
296     case intbh:
297       regs.r_intbh = v & 0xff;
298       break;
299
300     case sp:
301       {
302         SI *spp;
303         if (regs.r_flags & FLAGBIT_U)
304           spp = &regs.r_usp;
305         else
306           spp = &regs.r_isp;
307         *spp = v & addr_mask;
308         if (*spp < heaptop)
309           {
310             printf ("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc,
311                     heaptop, *spp);
312             exit (1);
313           }
314         if (*spp < lowest_sp)
315           lowest_sp = *spp;
316         if (*spp > highest_sp)
317           highest_sp = *spp;
318         break;
319       }
320     case usp:
321       regs.r_usp = v & addr_mask;
322       break;
323     case isp:
324       regs.r_isp = v & addr_mask;
325       break;
326
327     case pc:
328       regs.r_pc = v & membus_mask;
329       break;
330     case flags:
331       regs.r_flags = v;
332       break;
333     default:
334       abort ();
335     }
336 }
337
338 int
339 condition_true (int cond_id)
340 {
341   int f;
342   if (A16)
343     {
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"
349       };
350       switch (cond_id & 15)
351         {
352         case 0:
353           f = FLAG_C;
354           break;                /* GEU/C */
355         case 1:
356           f = FLAG_C & !FLAG_Z;
357           break;                /* GTU */
358         case 2:
359           f = FLAG_Z;
360           break;                /* EQ/Z */
361         case 3:
362           f = FLAG_S;
363           break;                /* N */
364         case 4:
365           f = !FLAG_C;
366           break;                /* LTU/NC */
367         case 5:
368           f = !(FLAG_C & !FLAG_Z);
369           break;                /* LEU */
370         case 6:
371           f = !FLAG_Z;
372           break;                /* NE/NZ */
373         case 7:
374           f = !FLAG_S;
375           break;                /* PZ */
376
377         case 8:
378           f = (FLAG_S ^ FLAG_O) | FLAG_Z;
379           break;                /* LE */
380         case 9:
381           f = FLAG_O;
382           break;                /* O */
383         case 10:
384           f = !(FLAG_S ^ FLAG_O);
385           break;                /* GE */
386         case 12:
387           f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
388           break;                /* GT */
389         case 13:
390           f = !FLAG_O;
391           break;                /* NO */
392         case 14:
393           f = FLAG_S ^ FLAG_O;
394           break;                /* LT */
395
396         default:
397           f = 0;
398           break;
399         }
400       if (trace)
401         printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
402                 f ? "true" : "false");
403     }
404   else
405     {
406       static const char *cond_name[] = {
407         "!C", "LEU", "!Z", "PZ",
408         "!O", "GT", "GE", "?",
409         "C", "GTU", "Z", "N",
410         "O", "LE", "LT", "!?"
411       };
412       switch (cond_id & 15)
413         {
414         case 0:
415           f = !FLAG_C;
416           break;                /* LTU/NC */
417         case 1:
418           f = !(FLAG_C & !FLAG_Z);
419           break;                /* LEU */
420         case 2:
421           f = !FLAG_Z;
422           break;                /* NE/NZ */
423         case 3:
424           f = !FLAG_S;
425           break;                /* PZ */
426
427         case 4:
428           f = !FLAG_O;
429           break;                /* NO */
430         case 5:
431           f = !((FLAG_S ^ FLAG_O) | FLAG_Z);
432           break;                /* GT */
433         case 6:
434           f = !(FLAG_S ^ FLAG_O);
435           break;                /* GE */
436
437         case 8:
438           f = FLAG_C;
439           break;                /* GEU/C */
440         case 9:
441           f = FLAG_C & !FLAG_Z;
442           break;                /* GTU */
443         case 10:
444           f = FLAG_Z;
445           break;                /* EQ/Z */
446         case 11:
447           f = FLAG_S;
448           break;                /* N */
449
450         case 12:
451           f = FLAG_O;
452           break;                /* O */
453         case 13:
454           f = (FLAG_S ^ FLAG_O) | FLAG_Z;
455           break;                /* LE */
456         case 14:
457           f = FLAG_S ^ FLAG_O;
458           break;                /* LT */
459
460         default:
461           f = 0;
462           break;
463         }
464       if (trace)
465         printf ("cond[%d] %s = %s\n", cond_id, cond_name[cond_id & 15],
466                 f ? "true" : "false");
467     }
468   return f;
469 }
470
471 void
472 set_flags (int mask, int newbits)
473 {
474   int i;
475   regs.r_flags &= ~mask;
476   regs.r_flags |= newbits & mask;
477   if (trace)
478     {
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]);
483         else
484           putchar ('-');
485       printf ("\033[0m\n");
486     }
487 }
488
489 void
490 set_oszc (int value, int b, int c)
491 {
492   int mask = b2mask[b];
493   int f = 0;
494
495   if (c)
496     f |= FLAGBIT_C;
497   if ((value & mask) == 0)
498     f |= FLAGBIT_Z;
499   if (value & b2signbit[b])
500     f |= FLAGBIT_S;
501   if ((value > b2maxsigned[b]) || (value < b2minsigned[b]))
502     f |= FLAGBIT_O;
503   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
504 }
505
506 void
507 set_szc (int value, int b, int c)
508 {
509   int mask = b2mask[b];
510   int f = 0;
511
512   if (c)
513     f |= FLAGBIT_C;
514   if ((value & mask) == 0)
515     f |= FLAGBIT_Z;
516   if (value & b2signbit[b])
517     f |= FLAGBIT_S;
518   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
519 }
520
521 void
522 set_osz (int value, int b)
523 {
524   int mask = b2mask[b];
525   int f = 0;
526
527   if ((value & mask) == 0)
528     f |= FLAGBIT_Z;
529   if (value & b2signbit[b])
530     f |= FLAGBIT_S;
531   if (value & ~mask && (value & ~mask) != ~mask)
532     f |= FLAGBIT_O;
533   set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
534 }
535
536 void
537 set_sz (int value, int b)
538 {
539   int mask = b2mask[b];
540   int f = 0;
541
542   if ((value & mask) == 0)
543     f |= FLAGBIT_Z;
544   if (value & b2signbit[b])
545     f |= FLAGBIT_S;
546   set_flags (FLAGBIT_Z | FLAGBIT_S, f);
547 }
548
549 void
550 set_zc (int z, int c)
551 {
552   set_flags (FLAGBIT_C | FLAGBIT_Z,
553              (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
554 }
555
556 void
557 set_c (int c)
558 {
559   set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
560 }
561
562 void
563 put_reg_ll (reg_id id, DI v)
564 {
565   reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
566
567   switch (id)
568     {
569     case r3r1r2r0:
570       b->r_r3 = v >> 48;
571       b->r_r1 = v >> 32;
572       b->r_r2 = v >> 16;
573       b->r_r0 = v;
574       break;
575     case r3r2r1r0:
576       b->r_r3 = v >> 48;
577       b->r_r2 = v >> 32;
578       b->r_r1 = v >> 16;
579       b->r_r0 = v;
580       break;
581     default:
582       put_reg (id, v);
583     }
584 }
585
586 #define TRC(f,n, id) \
587   if (oldregs.f != regs.f) \
588     { \
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; \
593     }
594
595 void
596 trace_register_changes ()
597 {
598   if (!trace)
599     return;
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");
624 }