(sim_csize): Initialize cpu.cache.
[external/binutils.git] / sim / h8300 / compile.c
1 /*
2  * Simulator for the Hitachi H8/300 architecture.
3  *
4  * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
5  *
6  * This file is part of H8/300 sim
7  *
8  *
9  * THIS SOFTWARE IS NOT COPYRIGHTED
10  *
11  * Cygnus offers the following for use in the public domain.  Cygnus makes no
12  * warranty with regard to the software or its performance and the user
13  * accepts the software "AS IS" with all faults.
14  *
15  * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS
16  * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE.
18  *
19  */
20
21 #include <signal.h>
22 #include "sysdep.h"
23 #include <sys/times.h>
24 #include <sys/param.h>
25
26
27 int debug;
28
29
30 #define X(op, size)  op*4+size
31
32 #define SP (Hmode ? SL:SW)
33 #define SB 0
34 #define SW 1
35 #define SL 2
36 #define OP_REG 1
37 #define OP_DEC 2
38 #define OP_DISP 3
39 #define OP_INC 4
40 #define OP_PCREL 5
41 #define OP_MEM 6
42 #define OP_CCR 7
43 #define OP_IMM 8
44 #define OP_ABS 10
45 #define h8_opcodes ops
46 #define DEFINE_TABLE
47 #include "opcode/h8300.h"
48
49 #include "inst.h"
50
51 #define LOW_BYTE(x) ((x) & 0xff)
52 #define HIGH_BYTE(x) (((x)>>8) & 0xff)
53 #define P(X,Y) ((X<<8) | Y)
54
55 #define BUILDSR()   cpu.ccr = (N << 3) | (Z << 2) | (V<<1) | C;
56
57 #define GETSR()             \
58   c = (cpu.ccr >> 0) & 1;\
59   v = (cpu.ccr >> 1) & 1;\
60   nz = !((cpu.ccr >> 2) & 1);\
61   n = (cpu.ccr >> 3) & 1;
62
63 #ifdef __CHAR_IS_SIGNED__
64 #define SEXTCHAR(x) ((char)(x))
65 #endif
66
67 #ifndef SEXTCHAR
68 #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x)
69 #endif
70
71 #define UEXTCHAR(x) ((x) & 0xff)
72 #define UEXTSHORT(x) ((x) & 0xffff)
73 #define SEXTSHORT(x) ((short)(x))
74
75 static cpu_state_type cpu;
76
77 int Hmode;
78
79
80 static int
81 get_now ()
82 {
83   struct tms b;
84   times (&b);
85   return b.tms_utime + b.tms_stime;
86 }
87
88 static int
89 now_persec ()
90 {
91   return 50;
92 }
93
94
95 static int
96 bitfrom (x)
97 {
98
99   switch (x & SIZE)
100     {
101     case L_8:
102       return SB;
103     case L_16:
104       return SW;
105     case L_32:
106       return SL;
107     case L_P:
108       return Hmode ? SL : SW;
109     }
110
111 }
112
113 static
114 unsigned int
115 lvalue (x, rn)
116 {
117   switch (x / 4)
118     {
119     case OP_DISP:
120       if (rn == 8) 
121         {
122           return X(OP_IMM,SP);
123         }
124       return  X(OP_REG,SP);
125       
126     case OP_MEM:
127
128       return X (OP_MEM, SP);
129     default:
130       abort ();
131     }
132 }
133
134 static unsigned int
135 decode (addr, data, dst)
136      int addr;
137      unsigned char *data;
138      decoded_inst *dst;
139
140 {
141   int rs = 0;
142   int rd = 0;
143   int rdisp = 0;
144   int abs = 0;
145   int plen = 0;
146
147   struct h8_opcode *q = h8_opcodes;
148   int size = 0;
149   dst->dst.type = -1;
150   dst->src.type = -1;
151   /* Find the exact opcode/arg combo */
152   while (q->name)
153     {
154       op_type *nib;
155       unsigned int len = 0;
156
157       nib = q->data.nib;
158
159       while (1)
160         {
161           op_type looking_for = *nib;
162           int thisnib = data[len >> 1];
163
164           thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
165
166           if (looking_for < 16)
167             {
168
169               if (looking_for != thisnib)
170                 goto fail;
171             }
172           else
173             {
174
175               if ((int) looking_for & (int) B31)
176                 {
177                   if (!(((int) thisnib & 0x8) != 0))
178                     goto fail;
179                   looking_for = (op_type) ((int) looking_for & ~(int)
180                                            B31);
181                   thisnib &= 0x7;
182
183                 }
184               if ((int) looking_for & (int) B30)
185                 {
186                   if (!(((int) thisnib & 0x8) == 0))
187                     goto fail;
188                   looking_for = (op_type) ((int) looking_for & ~(int) B30);
189                 }
190               if (looking_for & DBIT)
191                 {
192                   if ((looking_for & 5) != (thisnib &5)) goto fail;
193                   abs = (thisnib & 0x8) ? 2 : 1;
194                 }
195               else if (looking_for & (REG | IND | INC | DEC))
196                 {
197                   if (looking_for & REG)
198                     {
199                       /*
200                        * Can work out size from the
201                        * register
202                        */
203                       size = bitfrom (looking_for);
204                     }
205                   if (looking_for & SRC)
206                     {
207                       rs = thisnib;
208                     }
209                   else
210                     {
211                       rd = thisnib;
212                     }
213                 }
214               else if (looking_for & L_16)
215                 {
216                   abs = (data[len >> 1]) * 256 + data[(len + 2) >> 1];
217                   plen = 16;
218                   if (looking_for & (PCREL|DISP))
219                     {
220                       abs = (short) (abs);
221                     }
222                 }
223               else if (looking_for & ABSJMP)
224                 {
225                   abs =
226                     (data[1] << 16)
227                     | (data[2] << 8)
228                     | (data[3]);
229                 }
230               else if (looking_for & L_32)
231                 {
232                   int i = len >> 1;
233                   abs = (data[i] << 24)
234                     | (data[i + 1] << 16)
235                     | (data[i + 2] << 8)
236                     | (data[i + 3]);
237
238                   plen = 32;
239
240                 }
241               else if (looking_for & L_24)
242                 {
243                   int i = len >> 1;
244                   abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i +
245                                                                      2]);
246                   plen = 24;
247                 }
248               else if (looking_for & IGNORE)
249                 {
250
251                 }
252               else if (looking_for & DISPREG)
253                 {
254                   rdisp = thisnib & 0x7;
255                 }
256               else if (looking_for & KBIT)
257                 {
258                   switch (thisnib)
259                     {
260                     case 9:
261                       abs = 4;
262                       break;
263                     case 8:
264                       abs = 2;
265                       break;
266                     case 0:
267                       abs = 1;
268                       break;
269                     }
270                 }
271               else if (looking_for & L_8)
272                 {
273                   plen = 8;
274
275                   if (looking_for & PCREL)
276                     {
277                       abs = SEXTCHAR (data[len >> 1]);
278                     }
279                   else
280                     {
281                       abs = data[len >> 1] & 0xff;
282                     }
283                 }
284               else if (looking_for & L_3)
285                 {
286                   plen = 3;
287
288                   abs = thisnib;
289                 }
290               else if (looking_for == E)
291                 {
292                   dst->op = q;
293
294                   /* Fill in the args */
295                   {
296                     op_type *args = q->args.nib;
297                     int hadone = 0;
298
299
300                     while (*args != E)
301                       {
302                         int x = *args;
303                         int rn = (x & DST) ? rd : rs;
304                         ea_type *p;
305
306                         if (x & DST)
307                           {
308                             p = &(dst->dst);
309                           }
310                         else
311                           {
312                             p = &(dst->src);
313                           }
314
315
316                         if (x & (IMM | KBIT | DBIT))
317                           {
318                             p->type = X (OP_IMM, size);
319                             p->literal = abs;
320                           }
321                         else if (x & REG)
322                           {
323                             /*
324                          Reset the size, some
325                          ops (like mul) have two sizes */
326                             
327                             size = bitfrom (x);
328                             p->type = X (OP_REG, size);
329                             p->reg = rn;
330                           }
331                         else if (x & INC)
332                           {
333                             p->type = X (OP_INC, size);
334                             p->reg = rn & 0x7;
335                           }
336                         else if (x & DEC)
337                           {
338                             p->type = X (OP_DEC, size);
339                             p->reg = rn & 0x7;
340                           }
341                         else if (x & IND)
342                           {
343                             p->type = X (OP_DISP, size);
344                             p->reg = rn & 0x7;
345                             p->literal = 0;
346                           }
347                         else if (x & (ABS | ABSJMP | ABSMOV))
348                           {
349                             p->type = X (OP_DISP, size);
350                             p->literal = abs;
351                             p->reg = 8;
352                           }
353                         else if (x & MEMIND)
354                           {
355                             p->type = X (OP_MEM, size);
356                             p->literal = abs;
357                           }
358                         else if (x & PCREL)
359                           {
360                             p->type = X (OP_PCREL, size);
361                             p->literal = abs + addr + 2;
362                           }
363                         else if (x & ABSJMP)
364                           {
365                             p->type = X (OP_IMM, SP);
366                             p->literal = abs;
367                           }
368                         else if (x & DISP)
369                           {
370                             p->type = X (OP_DISP, size);
371                             p->literal = abs;
372                             p->reg = rdisp & 0x7;
373                           }
374                         else if (x & CCR)
375                           {
376                             p->type = OP_CCR;
377                           }
378                         else
379                           printf ("Hmmmm %x", x);
380
381
382                         args++;
383                       }
384                   }
385
386                   /*
387                  * But a jmp or a jsr gets
388                  * automagically lvalued, since we
389                  * branch to their address not their
390                  * contents
391                  */
392                   if (q->how == O (O_JSR, SB)
393                       || q->how == O (O_JMP, SB))
394                     {
395                       dst->src.type = lvalue (dst->src.type, dst->src.reg);
396                     }
397
398
399                   if (dst->dst.type == -1)
400                     dst->dst = dst->src;
401                   
402                   dst->opcode = q->how;
403                   dst->cycles = q->time;
404
405                   /* And a jsr to 0xc4 is turned into a magic trap */
406                   
407                   if (dst->opcode == O(O_JSR, SB)) 
408                     {
409                       if(dst->src.literal == 0xc4)
410                         {
411                           dst->opcode = O(O_SYSCALL,SB);
412                         }
413                     }
414                   
415                   dst->next_pc = addr + len / 2;
416                   return;
417                 }
418               else
419                 {
420                   printf ("Dont understand %x \n", looking_for);
421                 }
422             }
423           
424           len++;
425           nib++;
426         }
427       
428     fail:
429       q++;
430     }
431   
432   dst->opcode = O (O_ILL, SB);
433 }
434
435
436 static void
437 compile (pc)
438 {
439   int idx;
440   
441   /* find the next cache entry to use */
442   
443   idx = cpu.cache_top + 1;
444   cpu.compiles++;
445   if (idx >= cpu.csize)
446     {
447       idx = 1;
448     }
449   cpu.cache_top = idx;
450   
451   /* Throw away its old meaning */
452   cpu.cache_idx[cpu.cache[idx].oldpc] = 0;
453   
454   /* set to new address */
455   cpu.cache[idx].oldpc = pc;
456   
457   /* fill in instruction info */
458   decode (pc, cpu.memory + pc, cpu.cache + idx);
459   
460   /* point to new cache entry */
461   cpu.cache_idx[pc] = idx;
462 }
463
464
465 static unsigned char *breg[18];
466 static unsigned short *wreg[18];
467 static unsigned int *lreg[18];
468
469 #define GET_B_REG(x) *(breg[x])
470 #define SET_B_REG(x,y) (*(breg[x])) = (y)
471 #define GET_W_REG(x) *(wreg[x])
472 #define SET_W_REG(x,y) (*(wreg[x])) = (y)
473
474 #define GET_L_REG(x) *(lreg[x])
475 #define SET_L_REG(x,y) (*(lreg[x])) = (y)
476
477 #define GET_MEMORY_L(x) \
478   ((cpu.memory[x+0] << 24) | (cpu.memory[x+1] << 16) | (cpu.memory[x+2] << 8) | cpu.memory[x+3])
479
480 #define GET_MEMORY_W(x) \
481   ((cpu.memory[x+0] << 8) | (cpu.memory[x+1] << 0))
482
483
484 #define SET_MEMORY_B(x,y) \
485   (cpu.memory[(x)] = y)
486
487 #define SET_MEMORY_W(x,y) \
488 {register unsigned char *_p = cpu.memory+x;\
489    register int __y = y;\
490      _p[0] = (__y)>>8;\
491        _p[1] =(__y);     }
492
493 #define SET_MEMORY_L(x,y)  \
494 {register unsigned char *_p = cpu.memory+x;register int __y = y;\
495    _p[0] = (__y)>>24;    _p[1] = (__y)>>16;      _p[2] = (__y)>>8;       _p[3] = (__y)>>0;}
496
497 #define GET_MEMORY_B(x)  (cpu.memory[x])
498
499 int
500   fetch (arg, n)
501 ea_type *arg;
502 {
503   int rn = arg->reg;
504   int abs = arg->literal;
505   int r;
506   int t;
507   
508   switch (arg->type)
509     {
510     case X (OP_REG, SB):
511       return GET_B_REG (rn);
512     case X (OP_REG, SW):
513       return GET_W_REG (rn);
514     case X (OP_REG, SL):
515       return GET_L_REG (rn);
516     case X (OP_IMM, SB):
517     case X (OP_IMM, SW):
518     case X (OP_IMM, SL):
519       return abs;
520     case X (OP_DEC, SB):
521       abort();
522
523     case X(OP_INC,SB):
524       t = GET_L_REG(rn);
525       t &= cpu.mask;
526       r = GET_MEMORY_B(t);
527       t ++;
528       t = t & cpu.mask;
529       SET_L_REG(rn,t);
530       return r;
531       break;
532     case X(OP_INC,SW):
533       t = GET_L_REG(rn);
534       t &= cpu.mask;
535       r = GET_MEMORY_W(t);
536       t +=2;
537       t = t & cpu.mask;
538       SET_L_REG(rn,t);
539       return r;
540     case X(OP_INC,SL):
541       t = GET_L_REG(rn);
542       t &= cpu.mask;
543       r = GET_MEMORY_L(t);
544       
545       t +=4;
546       t = t & cpu.mask;
547       SET_L_REG(rn,t);
548       return r;
549       
550     case X (OP_DISP, SB):
551       t = GET_L_REG (rn) + abs;
552       t &= cpu.mask;
553       return GET_MEMORY_B (t);
554       
555     case X (OP_DISP, SW):
556       t = GET_L_REG (rn) + abs;
557       t &= cpu.mask;
558       return GET_MEMORY_W (t);
559       
560     case X (OP_DISP, SL):
561       t = GET_L_REG (rn) + abs;
562       t &= cpu.mask;
563       return GET_MEMORY_L (t);
564       
565     default:
566       abort ();
567       
568     }
569 }
570
571
572
573
574
575 static 
576 void store (arg, n)
577 ea_type *arg;
578 int n;
579 {
580   int rn = arg->reg;
581   int abs = arg->literal;
582   int t;
583   
584   switch (arg->type)
585     {
586     case X (OP_REG, SB):
587       SET_B_REG (rn, n);
588       break;
589     case X (OP_REG, SW):
590       SET_W_REG (rn, n);
591       break;
592     case X (OP_REG, SL):
593       SET_L_REG (rn, n);
594       break;
595       
596     case X (OP_DEC, SB):
597       t =  GET_L_REG (rn) - 1;
598       t &= cpu.mask;
599       SET_L_REG (rn,t);
600       SET_MEMORY_B (t, n);
601
602       break;
603     case X (OP_DEC, SW):
604       t= (GET_L_REG (rn) - 2 ) & cpu.mask;
605       SET_L_REG (rn, t);
606       SET_MEMORY_W (t, n);
607       break;
608
609     case X (OP_DEC, SL):
610       t = (GET_L_REG(rn) -4 ) & cpu.mask;
611       SET_MEMORY_L (t,n);
612       break;
613
614       
615     case X (OP_DISP, SB):
616       t = GET_L_REG (rn) + abs;
617       t &= cpu.mask;
618       SET_MEMORY_B (t, n);
619       break;
620
621     case X (OP_DISP, SW):
622       t = GET_L_REG (rn) + abs;
623       t &= cpu.mask;
624       SET_MEMORY_W (t, n);
625       break;
626
627     case X (OP_DISP, SL):
628       t = GET_L_REG (rn) + abs;
629       t &= cpu.mask;
630       SET_MEMORY_L (t, n);
631       break;
632     default:
633       abort ();
634     }
635 }
636
637
638 static union
639   {
640     short int i;
641     struct
642       {
643         char low;
644         char high;
645       }
646     u;
647   }
648
649 littleendian;
650
651 static
652 void
653 init_pointers ()
654 {
655   static int init;
656
657   if (!init)
658     {
659       int i;
660
661       init = 1;
662       littleendian.i = 1;
663
664       cpu.memory = (unsigned char *) calloc (sizeof (char), MSIZE);
665       cpu.cache_idx = (unsigned short *) calloc (sizeof (short), MSIZE);
666       cpu.mask =  (1<<MPOWER)-1;
667       
668       for (i = 0; i < 9; i++)
669         {
670           cpu.regs[i] = 0;
671         }
672
673       for (i = 0; i < 8; i++)
674         {
675           unsigned char *p = (unsigned char *) (cpu.regs + i);
676           unsigned char *e = (unsigned char *) (cpu.regs + i + 1);
677           unsigned short *q = (unsigned short *) (cpu.regs + i);
678           unsigned short *u = (unsigned short *) (cpu.regs + i + 1);
679           cpu.regs[i] = 0x00112233;
680           while (p < e)
681             {
682               if (*p == 0x22)
683                 {
684                   breg[i] = p;
685                 }
686               if (*p == 0x33)
687                 {
688                   breg[i+8] = p;
689                 }
690               p++;
691             }
692           while (q < u)
693             {
694               if (*q == 0x2233)
695                 {
696                   wreg[i] = q;
697                 }
698               if (*q == 0x0011)
699                 {
700                   wreg[i + 8] = q;
701                 }
702               q++;
703             }
704           cpu.regs[i] = 0;
705           lreg[i] = &cpu.regs[i];
706         }
707
708
709       lreg[8] = &cpu.regs[8];
710       
711       /* initialize the seg registers */
712       if (!cpu.cache)
713         sim_csize (CSIZE);
714
715     }
716 }
717
718 static void
719 control_c (sig, code, scp, addr)
720      int sig;
721      int code;
722      char *scp;
723      char *addr;
724 {
725   cpu.exception = SIGINT;
726 }
727
728 #define C (c != 0)
729 #define Z (nz == 0)
730 #define V (v != 0)
731 #define N (n != 0)
732
733 int
734 sim_resume (step)
735 {
736   static int init1;
737   int cycles = 0;
738   int insts = 0;
739   int tick_start = get_now ();
740   void (*prev) ();
741
742   int res;
743   int tmp;
744   int rd;
745   int ea;
746   int bit;
747   int pc;
748   int c, nz, v, n;
749
750   init_pointers ();
751
752   prev = signal (SIGINT, control_c);
753
754   if (step)
755     {
756       cpu.exception = SIGTRAP;
757     }
758   else
759     {
760       cpu.exception = 0;
761     }
762
763   pc = cpu.pc;
764
765   GETSR ();
766
767   do
768     {
769       int cidx;
770       decoded_inst *code;
771
772     top:
773       cidx = cpu.cache_idx[pc];
774       code = cpu.cache + cidx;
775
776
777 #define ALUOP(STORE, NAME, HOW) \
778     case O(NAME,SB):  HOW; if(STORE)goto alu8;else goto just_flags_alu8;  \
779     case O(NAME, SW): HOW; if(STORE)goto alu16;else goto just_flags_alu16; \
780     case O(NAME,SL):  HOW; if(STORE)goto alu32;else goto just_flags_alu32;
781
782
783 #define LOGOP(NAME, HOW) \
784     case O(NAME,SB): HOW; goto log8;\
785     case O(NAME, SW): HOW; goto log16;\
786     case O(NAME,SL): HOW; goto log32;
787
788
789
790 #if ADEBUG
791       if (debug)
792         {
793           printf ("%x %d %s\n", pc, code->opcode,
794                   code->op ? code->op->name : "**");
795         }
796       cpu.stats[code->opcode]++;
797       
798 #endif
799
800       cycles += code->cycles;
801       insts++;
802       switch (code->opcode)
803         {
804         case 0:
805           /*
806            * This opcode is a fake for when we get to an
807            * instruction which hasnt been compiled
808            */
809           compile (pc);
810           goto top;
811           break;
812
813
814         case O (O_SUBX, SB):
815           rd = fetch (&code->dst);
816           ea = fetch (&code->src);
817           ea = -( ea + C);
818           res = rd + ea;
819           goto alu8;
820
821         case O (O_ADDX, SB):
822           rd = fetch (&code->dst);
823           ea = fetch (&code->src);
824           ea = C + ea;
825           res = rd + ea;
826           goto alu8;
827
828 #define RD    rd = fetch(&code->src);
829 #define RD_EA rd =  fetch(&code->dst); ea = fetch(&code->src);
830
831           ALUOP (1, O_SUB,       RD_EA;  ea = -ea ;      res = rd + ea);
832           ALUOP (1, O_NEG,       RD;     ea = -ea ;rd = 0; res = rd + ea);
833
834         case O(O_ADD,SB):
835           rd = GET_B_REG(code->dst.reg);
836           ea = fetch(&code->src);
837           res = rd + ea;
838           goto alu8;
839         case O(O_ADD,SW):
840           rd = GET_W_REG(code->dst.reg);
841           ea = fetch(&code->src);
842           res = rd + ea;
843           goto alu16;
844         case O(O_ADD,SL):
845           rd = GET_L_REG(code->dst.reg);
846           ea = fetch(&code->src);
847           res = rd + ea;
848           goto alu32;
849           
850
851           LOGOP (O_AND, RD_EA;           res = rd & ea);
852
853           LOGOP (O_OR, RD_EA;            res = rd | ea);
854
855           LOGOP (O_XOR, RD_EA;           res = rd ^ ea);
856
857
858         case O(O_MOV_TO_MEM,SB):
859           res = GET_B_REG(code->src.reg);
860           goto log8;
861         case O(O_MOV_TO_MEM,SW):
862           res = GET_W_REG(code->src.reg);
863           goto log16;
864         case O(O_MOV_TO_MEM,SL):
865           res = GET_L_REG(code->src.reg);
866           goto log32;
867
868
869         case O(O_MOV_TO_REG,SB):
870           res = fetch(&code->src);
871           SET_B_REG(code->dst.reg, res);
872           goto just_flags_log8;
873         case O(O_MOV_TO_REG,SW):
874           res = fetch(&code->src);
875           SET_W_REG(code->dst.reg, res);
876           goto just_flags_log16;
877         case O(O_MOV_TO_REG,SL):
878           res = fetch(&code->src);
879           SET_L_REG(code->dst.reg, res);
880           goto just_flags_log32;
881
882
883         case O(O_ADDS,SL):
884           SET_L_REG(code->dst.reg,
885                     GET_L_REG(code->dst.reg) 
886                     + code->src.literal);
887           
888           goto next;
889
890         case O(O_SUBS,SL):
891           SET_L_REG(code->dst.reg,
892                     GET_L_REG(code->dst.reg) 
893                     - code->src.literal);
894           goto next;
895           
896         case O (O_CMP, SB):
897           rd = fetch (&code->dst);
898           ea = fetch (&code->src);
899           ea = -ea;
900           res = rd + ea;
901           goto just_flags_alu8;
902
903         case O (O_CMP, SW):
904           rd = fetch (&code->dst);
905           ea = fetch (&code->src);
906           ea = -ea;
907           res = rd + ea;
908           goto just_flags_alu16;
909
910         case O (O_CMP, SL):
911           rd = fetch (&code->dst);
912           ea = fetch (&code->src);
913           ea = -ea;
914           res = rd + ea;
915           goto just_flags_alu32;
916
917
918         case O (O_DEC, SB):
919           rd = GET_B_REG (code->src.reg);
920           ea = -1;
921           res = rd + ea;
922           SET_B_REG (code->src.reg, res);
923           goto just_flags_inc8;
924
925         case O (O_DEC, SW):
926           rd = GET_W_REG (code->dst.reg);
927           ea = - code->src.literal;
928           res = rd + ea;
929           SET_W_REG (code->dst.reg, res);
930           goto just_flags_inc16;
931
932         case O (O_DEC, SL):
933           rd = GET_L_REG (code->dst.reg);
934           ea = -code->src.literal;
935           res = rd + ea;
936           SET_L_REG (code->dst.reg, res);
937           goto just_flags_inc32;
938
939
940         case O (O_INC, SB):
941           rd = GET_B_REG (code->src.reg);
942           ea = 1;
943           res = rd + ea;
944           SET_B_REG (code->src.reg, res);
945           goto just_flags_inc8;
946
947         case O (O_INC, SW):
948           rd = GET_W_REG (code->dst.reg);
949           ea = code->src.literal;
950           res = rd + ea;
951           SET_W_REG (code->dst.reg, res);
952           goto just_flags_inc16;
953
954         case O (O_INC, SL):
955           rd = GET_L_REG (code->dst.reg);
956           ea = code->src.literal;
957           res = rd + ea;
958           SET_L_REG (code->dst.reg, res);
959           goto just_flags_inc32;
960
961
962 #define GET_CCR(x) BUILDSR();x = cpu.ccr
963           
964         case O (O_ANDC, SB):
965           GET_CCR (rd);
966           ea = code->src.literal;
967           res = rd & ea;
968           goto setc;
969
970
971         case O (O_BRA, SB):
972           if (1)
973             goto condtrue;
974           goto next;
975
976         case O (O_BRN, SB):
977           if (0)
978             goto condtrue;
979           goto next;
980
981         case O (O_BHI, SB):
982           if ((C || Z) == 0)
983             goto condtrue;
984           goto next;
985
986
987         case O (O_BLS, SB):
988           if ((C || Z))
989             goto condtrue;
990           goto next;
991
992         case O (O_BCS, SB):
993           if ((C == 1))
994             goto condtrue;
995           goto next;
996
997         case O (O_BCC, SB):
998           if ((C == 0))
999             goto condtrue;
1000           goto next;
1001
1002         case O (O_BEQ, SB):
1003           if (Z)
1004             goto condtrue;
1005           goto next;
1006         case O (O_BGT, SB):
1007           if (((Z || (N ^ V)) == 0))
1008             goto condtrue;
1009           goto next;
1010
1011
1012         case O (O_BLE, SB):
1013           if (((Z || (N ^ V)) == 1))
1014             goto condtrue;
1015           goto next;
1016
1017         case O (O_BGE, SB):
1018           if ((N ^ V) == 0)
1019             goto condtrue;
1020           goto next;
1021         case O (O_BLT, SB):
1022           if ((N ^ V))
1023             goto condtrue;
1024           goto next;
1025         case O (O_BMI, SB):
1026           if ((N))
1027             goto condtrue;
1028           goto next;
1029         case O (O_BNE, SB):
1030           if ((Z == 0))
1031             goto condtrue;
1032           goto next;
1033
1034         case O (O_BPL, SB):
1035           if (N == 0)
1036             goto condtrue;
1037           goto next;
1038         case O (O_BVC, SB):
1039           if ((V == 0))
1040             goto condtrue;
1041           goto next;
1042         case O (O_BVS, SB):
1043           if ((V == 1))
1044             goto condtrue;
1045           goto next;
1046
1047         case O(O_SYSCALL, SB):
1048           printf("%c", cpu.regs[2]);
1049           goto next;
1050           
1051           
1052
1053 #define OSHIFTS(name, how) \
1054 case O(name, SB):{ int t;int hm = 0x80; rd = GET_B_REG(code->src.reg);how; goto shift8;} \
1055 case O(name, SW):{ int t;int hm = 0x8000; rd = GET_W_REG(code->src.reg); how; goto shift16;} \
1056 case O(name, SL):{ int t;int hm = 0x80000000; rd = GET_L_REG(code->src.reg);how; goto shift32;}
1057
1058
1059           OSHIFTS(O_NOT, rd = ~rd);
1060           OSHIFTS(O_SHLL, c = rd & hm; rd<<=1);
1061           OSHIFTS(O_SHLR, c = rd & 1; rd>>=1);
1062           OSHIFTS(O_SHAL, c = rd & hm; rd<<=1);
1063           OSHIFTS(O_SHAR, t = rd & hm; c = rd&1;rd>>=1;rd|=t;);
1064           OSHIFTS(O_ROTL, c = rd & hm; rd <<=1; rd|= C);
1065           OSHIFTS(O_ROTR, c = rd &1 ; rd >>=1; if (c) rd|= hm;);          
1066           OSHIFTS(O_ROTXL,t = rd & hm; rd<<=1; rd|=C; c=t;);
1067           OSHIFTS(O_ROTXR,t = rd & 1; rd>>=1; if (C) rd|=hm; c=t;);       
1068
1069         case O(O_JMP, SB):
1070           {
1071             pc = fetch (&code->src);
1072             goto end;
1073             
1074           }
1075           
1076         case O (O_JSR, SB):
1077           {
1078             int tmp;
1079             pc = fetch (&code->src);
1080           call:
1081             tmp = cpu.regs[7];
1082
1083             if (Hmode)
1084               {
1085                 tmp -= 4;
1086                 SET_MEMORY_L (tmp, code->next_pc);
1087               }
1088             else
1089               {
1090                 tmp -= 2;
1091                 SET_MEMORY_W (tmp, code->next_pc);
1092               }
1093             cpu.regs[7] = tmp;
1094
1095             goto end;
1096           }
1097         case O(O_BSR, SB):
1098           pc = code->src.literal;
1099           goto call;
1100           
1101         case O (O_RTS, SB):
1102           {
1103             int tmp;
1104
1105
1106             tmp = cpu.regs[7];
1107
1108             if (Hmode)
1109               {
1110                 pc = GET_MEMORY_L (tmp);
1111                 tmp += 4;
1112
1113               }
1114             else
1115               {
1116                 pc = GET_MEMORY_W (tmp);
1117                 tmp += 2;
1118               }
1119
1120             cpu.regs[7] = tmp;
1121             goto end;
1122           }
1123
1124         case O (O_ILL, SB):
1125           cpu.exception = SIGILL;
1126           goto end;
1127
1128         case O(O_BPT,SB):
1129           cpu.exception = SIGTRAP;
1130           goto end;
1131
1132 #define OBITOP(name,f, s, op) \
1133         case  O(name, SB): {int m;int b; \
1134               if (f) ea = fetch(&code->dst);\
1135                 m=1<<code->src.literal;\
1136                   op;\
1137                     if(s) store(&code->dst,ea); goto next;\
1138                     }
1139       OBITOP(O_BNOT,1,1,ea ^= m);
1140       OBITOP(O_BTST,1,0,nz = ea & m);
1141       OBITOP(O_BLD,1,0, c = ea & m);
1142       OBITOP(O_BILD,1,0, c = !(ea & m));
1143       OBITOP(O_BST,1,1, ea &= ~m; if (C) ea |=m);
1144       OBITOP(O_BIST,1,1, ea &= ~m; if (!C) ea |=m);       
1145       OBITOP(O_BAND,1,1, b = (ea & m) && C; ea &= ~m; if (b) ea |=m);
1146       OBITOP(O_BIAND,1,1, b = (ea & m) && C; ea &= ~m; if (!b) ea |=m);
1147       OBITOP(O_BOR,1,1, b = (ea & m) || C; ea &= ~m; if (b) ea |=m);
1148       OBITOP(O_BIOR,1,1, b = (ea & m) || C; ea &= ~m; if (!b) ea |=m);
1149       OBITOP(O_BXOR,1,1, b = (ea & m) != C; ea &= ~m; if (b) ea |=m);
1150       OBITOP(O_BIXOR,1,1, b = (ea & m) != C; ea &= ~m; if (!b) ea |=m);
1151       OBITOP(O_BCLR,1,1, ea &= ~m; );
1152       OBITOP(O_BSET,1,1, ea |= m; );
1153
1154
1155 #define MOP(bsize, signed)                                                      \
1156       {                                                                         \
1157         int multiplier;                                                         \
1158         int multiplicand;                                                       \
1159         int result;                                                             \
1160                                                                                 \
1161         if (signed)                                                             \
1162           {                                                                     \
1163             multiplicand =                                                      \
1164               bsize ? SEXTCHAR(GET_W_REG(code->dst.reg)):                       \
1165             SEXTSHORT(GET_W_REG(code->dst.reg));                                \
1166             multiplier =                                                        \
1167               bsize ? SEXTCHAR(GET_B_REG(code->src.reg)):                       \
1168             SEXTSHORT(GET_B_REG(code->src.reg));                                \
1169           }                                                                     \
1170         else                                                                    \
1171           {                                                                     \
1172             multiplicand = bsize ? UEXTCHAR(GET_W_REG(code->dst.reg)):          \
1173             UEXTSHORT(GET_W_REG(code->dst.reg));                                \
1174             multiplier =                                                        \
1175               bsize ? UEXTCHAR(GET_B_REG(code->src.reg)):                       \
1176             UEXTSHORT(GET_B_REG(code->src.reg));                                \
1177                                                                                 \
1178           }                                                                     \
1179         result = multiplier * multiplicand;                                     \
1180                                                                                 \
1181         if (signed)                                                             \
1182           {                                                                     \
1183             n = result & (bsize ? 0x8000: 0x80000000);                          \
1184             nz = result & (bsize ? 0xffff: 0xffffffff);                         \
1185           }                                                                     \
1186         if (bsize)                                                              \
1187           {                                                                     \
1188             SET_W_REG(code->dst.reg, result);                                   \
1189           }                                                                     \
1190         else                                                                    \
1191           {                                                                     \
1192             SET_L_REG(code->dst.reg, result);                                   \
1193           }                                                                     \
1194         goto next;                                                              \
1195  }                                                                              \
1196                                                                                  
1197     case O(O_MULS, SB): MOP(1,1);break;
1198     case O(O_MULS, SW): MOP(0,1); break;
1199     case O(O_MULU, SB): MOP(1,0);break;
1200     case O(O_MULU, SW): MOP(0,0); break;
1201
1202
1203     case O(O_DIVU,SB):
1204       {
1205
1206         rd = GET_W_REG(code->dst.reg);
1207         ea = GET_B_REG(code->src.reg);
1208         if (ea) {
1209           tmp = rd % ea;
1210           rd = rd / ea;
1211
1212         }
1213         SET_W_REG(code->dst.reg, (rd & 0xff) | (tmp << 8));
1214         n = ea & 0x80;
1215         nz = ea & 0xff;
1216
1217         goto next;
1218       }
1219     case O(O_DIVU,SW):
1220       {
1221
1222         rd = GET_L_REG(code->dst.reg);
1223         ea = GET_W_REG(code->src.reg);
1224         n = ea & 0x8000;
1225         nz = ea & 0xffff;
1226         if (ea) {
1227           tmp = rd % ea;
1228           rd = rd / ea;
1229
1230         }
1231         SET_L_REG(code->dst.reg, (rd & 0xffff) | (tmp << 16));
1232         goto next;
1233       }
1234           
1235
1236
1237     case O(O_DIVS,SB):
1238       {
1239
1240         rd = SEXTSHORT(GET_W_REG(code->dst.reg));
1241         ea = SEXTCHAR(GET_B_REG(code->src.reg));
1242         if (ea) {
1243
1244           tmp = (int)rd % (int)ea;
1245           rd = (int)rd / (int)ea;
1246           n = rd & 0x8000;
1247           nz = 1;
1248
1249         }
1250         else
1251           nz = 0;
1252         SET_W_REG(code->dst.reg, (rd & 0xff) | (tmp << 8));
1253         goto next;
1254       }
1255     case O(O_DIVS,SW):
1256       {
1257
1258         rd = GET_L_REG(code->dst.reg);
1259         ea = SEXTSHORT(GET_W_REG(code->src.reg));
1260         if (ea) {
1261
1262           tmp = (int)rd % (int)ea;
1263           rd = (int)rd / (int)ea;
1264           n = rd & 0x80000000;
1265           nz = 1;
1266       
1267         }
1268         else nz =0;
1269         SET_L_REG(code->dst.reg, (rd & 0xffff) | (tmp << 16));
1270         goto next;
1271       }
1272           
1273           
1274   
1275     default:
1276       cpu.exception = 123;
1277       goto end;
1278
1279     }
1280   abort ();
1281
1282  setc:
1283   GETSR();
1284   goto next;
1285       
1286  condtrue:
1287   /* When a branch works */
1288   pc = code->src.literal;
1289   goto end;
1290       
1291   /* Set the cond codes from res */
1292  bitop:
1293
1294   /* Set the flags after an 8 bit inc/dec operation */
1295  just_flags_inc8:
1296   n = res & 0x80;
1297   nz = res & 0xff;
1298   v = (rd & 0x7f) == 0x7f;
1299   goto next;
1300
1301
1302   /* Set the flags after an 16 bit inc/dec operation */
1303  just_flags_inc16:
1304   n = res & 0x8000;
1305   nz = res & 0xffff;
1306   v = (rd & 0x7fff) == 0x7fff;
1307   goto next;
1308
1309
1310   /* Set the flags after an 32 bit inc/dec operation */
1311  just_flags_inc32:
1312   n = res & 0x80000000;
1313   nz = res & 0xffffffff;
1314   v = (rd & 0x7fffffff) == 0x7fffffff;
1315   goto next;
1316
1317
1318  shift8:
1319   /* Set flags after an 8 bit shift op, carry set in insn */
1320   n = (rd & 0x80);
1321   v = 0;
1322   nz = rd & 0xff;
1323   SET_B_REG(code->src.reg, rd);
1324   goto next;
1325
1326
1327  shift16:
1328   /* Set flags after an 16 bit shift op, carry set in insn */
1329   n = (rd & 0x8000);
1330   v = 0;
1331   nz = rd & 0xffff;
1332       
1333   SET_W_REG(code->src.reg, rd);
1334   goto next;
1335
1336
1337  shift32:
1338   /* Set flags after an 32 bit shift op, carry set in insn */
1339   n = (rd & 0x80000000);
1340   v = 0;
1341   nz = rd & 0xffffffff;
1342   SET_L_REG(code->src.reg, rd);
1343   goto next;
1344
1345       
1346  log32:
1347   store (&code->dst, res);
1348  just_flags_log32:
1349   /* flags after a 32bit logical operation */
1350   n = res & 0x80000000;
1351   nz = res & 0xffffffff;
1352   v = 0;
1353   goto next;
1354       
1355  log16:
1356   store (&code->dst, res);
1357  just_flags_log16:
1358   /* flags after a 16bit logical operation */
1359   n = res & 0x8000;
1360   nz = res & 0xffff;
1361   v = 0;
1362   goto next;
1363
1364
1365  log8:
1366   store (&code->dst, res);
1367  just_flags_log8:
1368   n = res & 0x80;
1369   nz = res & 0xff;
1370   v = 0;
1371   goto next;
1372
1373  alu8:
1374   SET_B_REG (code->dst.reg, res);
1375  just_flags_alu8:
1376   n = res & 0x80;
1377   nz = res & 0xff;
1378   v = ((ea & 0x80) == (rd & 0x80)) && ((ea & 0x80) != (res & 0x80));
1379   c = (res & 0x100);
1380   goto next;
1381
1382  alu16:
1383   SET_W_REG (code->dst.reg, res);
1384  just_flags_alu16:
1385   n = res & 0x8000;
1386   nz = res & 0xffff;
1387   v = ((ea & 0x8000) == (rd & 0x8000)) && ((ea & 0x8000) != (res & 0x8000));
1388   c = (res & 0x10000);
1389   goto next;
1390
1391  alu32: 
1392   SET_L_REG (code->dst.reg, res);
1393  just_flags_alu32:
1394   n = res & 0x80000000;
1395   nz = res & 0xffffffff;
1396   v = ((ea & 0x80000000) == (rd & 0x80000000)) 
1397     && ((ea & 0x80000000) != (res & 0x80000000));
1398   c = (res < rd) || (res < ea);
1399   goto next;
1400
1401  next:;
1402   pc = code->next_pc;
1403
1404  end:
1405   if (cpu.regs[8] ) abort();
1406       
1407   ;
1408
1409 }
1410   while (!cpu.exception);
1411   cpu.ticks += get_now () - tick_start;
1412   cpu.cycles += cycles;
1413   cpu.insts += insts;
1414   cpu.pc = pc;
1415   BUILDSR ();
1416
1417   signal (SIGINT, prev);
1418 }
1419
1420
1421
1422
1423 void
1424 sim_write (addr, buffer, size)
1425      long int addr;
1426      unsigned char *buffer;
1427      int size;
1428 {
1429   int i;
1430
1431   init_pointers ();
1432   if (addr < 0 || addr + size > MSIZE)
1433     return;
1434   for (i = 0; i < size; i++)
1435     {
1436       cpu.memory[addr + i] = buffer[i];
1437       cpu.cache_idx[addr + i] = 0;
1438     }
1439 }
1440
1441 void
1442 sim_read (addr, buffer, size)
1443      long int addr;
1444      char *buffer;
1445      int size;
1446 {
1447   init_pointers ();
1448   if (addr < 0 || addr + size > MSIZE)
1449     return;
1450   memcpy (buffer, cpu.memory + addr, size);
1451 }
1452
1453
1454
1455 #define R0_REGNUM       0
1456 #define R1_REGNUM       1
1457 #define R2_REGNUM       2
1458 #define R3_REGNUM       3
1459 #define R4_REGNUM       4
1460 #define R5_REGNUM       5
1461 #define R6_REGNUM       6
1462 #define R7_REGNUM       7
1463
1464 #define SP_REGNUM       R7_REGNUM       /* Contains address of top of stack */
1465 #define FP_REGNUM       R6_REGNUM       /* Contains address of executing
1466                                          * stack frame */
1467
1468 #define CCR_REGNUM      8       /* Contains processor status */
1469 #define PC_REGNUM       9       /* Contains program counter */
1470
1471 #define CYCLE_REGNUM    10
1472 #define INST_REGNUM     11
1473 #define TICK_REGNUM     12
1474
1475
1476 void
1477 sim_store_register (rn, value)
1478      int rn;
1479      int value;
1480 {
1481
1482   init_pointers ();
1483   switch (rn)
1484     {
1485     case PC_REGNUM:
1486       cpu.pc = value;
1487       break;
1488     default:
1489       abort ();
1490     case R0_REGNUM:
1491     case R1_REGNUM:
1492     case R2_REGNUM:
1493     case R3_REGNUM:
1494     case R4_REGNUM:
1495     case R5_REGNUM:
1496     case R6_REGNUM:
1497     case R7_REGNUM:
1498       cpu.regs[rn] = value;
1499       break;
1500     case CCR_REGNUM:
1501       cpu.ccr = value;
1502       break;
1503     case CYCLE_REGNUM:
1504       cpu.cycles = value;
1505       break;
1506
1507     case INST_REGNUM:
1508       cpu.insts = value;
1509       break;
1510
1511     case TICK_REGNUM:
1512       cpu.ticks = value;
1513       break;
1514     }
1515 }
1516
1517 void
1518 sim_fetch_register (rn, buf)
1519      int rn;
1520      char *buf;
1521 {
1522   int v;
1523   int longreg = 0;
1524
1525   init_pointers ();
1526
1527   switch (rn)
1528     {
1529     default:
1530       abort ();
1531     case 8:
1532       v = cpu.ccr;
1533       break;
1534     case 9:
1535       v = cpu.pc;
1536       break;
1537     case R0_REGNUM:
1538     case R1_REGNUM:
1539     case R2_REGNUM:
1540     case R3_REGNUM:
1541     case R4_REGNUM:
1542     case R5_REGNUM:
1543     case R6_REGNUM:
1544     case R7_REGNUM:
1545       v = cpu.regs[rn];
1546       break;
1547     case 10:
1548       v = cpu.cycles;
1549       longreg = 1;
1550
1551       break;
1552     case 11:
1553       v = cpu.ticks;
1554       longreg = 1;
1555       break;
1556     case 12:
1557       v = cpu.insts;
1558       longreg = 1;
1559       break;
1560
1561     }
1562   if (Hmode || longreg)
1563     {
1564       buf[0] = v >> 24;
1565       buf[1] = v >> 16;
1566       buf[2] = v >> 8;
1567       buf[3] = v >> 0;
1568     }
1569   else
1570     {
1571       buf[0] = v >> 8;
1572       buf[1] = v;
1573     }
1574 }
1575
1576 int
1577 sim_trace ()
1578 {
1579   return 0;
1580 }
1581
1582 sim_stop_signal ()
1583 {
1584   return cpu.exception;
1585 }
1586
1587 sim_set_pc (n)
1588 {
1589   sim_store_register (PC_REGNUM, n);
1590 }
1591
1592
1593 sim_csize (n)
1594 {
1595   if (cpu.cache)
1596     free (cpu.cache);
1597   if (n < 2)
1598     n = 2;
1599   cpu.cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n);
1600   memset (cpu.cache, 0, sizeof (decoded_inst) * n);
1601   cpu.csize = n;
1602 }
1603
1604
1605
1606 void
1607 sim_info (verbose)
1608      int verbose;
1609      
1610 {
1611   double timetaken = (double) cpu.ticks / (double) now_persec ();
1612   double virttime = cpu.cycles / 10.0e6;
1613
1614
1615   printf ("\n\n#instructions executed  %10d\n", cpu.insts);
1616   printf ("#cycles (v approximate) %10d\n", cpu.cycles);
1617   printf ("#real time taken        %10.4f\n", timetaken);
1618   printf ("#virtual time taked     %10.4f\n", virttime);
1619   if (timetaken != 0.0) 
1620   printf ("#simulation ratio       %10.4f\n", virttime / timetaken);
1621   printf ("#compiles               %10d\n", cpu.compiles);
1622   printf ("#cache size             %10d\n", cpu.csize);
1623
1624
1625 #ifdef ADEBUG
1626   if  (verbose)
1627     {
1628       int i;
1629       for (i= 0; i < O_LAST; i++) 
1630         {
1631           if (cpu.stats[i])
1632             printf("%d: %d\n", i, cpu.stats[i]);
1633         }
1634     }
1635 #endif
1636 }
1637