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