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