]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/h8300/compile.c
2 * Simulator for the Hitachi H8/300 architecture.
4 * Written by Steve Chamberlain of Cygnus Support. sac@cygnus.com
6 * This file is part of H8/300 sim
9 * THIS SOFTWARE IS NOT COPYRIGHTED
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.
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.
22 #include <sys/times.h>
23 #include <sys/param.h>
24 #include "remote-sim.h"
29 #define X(op, size) op*4+size
31 #define SP (h8300hmode ? SL:SW)
44 #define h8_opcodes ops
46 #include "opcode/h8300.h"
50 #define LOW_BYTE(x) ((x) & 0xff)
51 #define HIGH_BYTE(x) (((x)>>8) & 0xff)
52 #define P(X,Y) ((X<<8) | Y)
54 #define BUILDSR() cpu.ccr = (N << 3) | (Z << 2) | (V<<1) | C;
57 c = (cpu.ccr >> 0) & 1;\
58 v = (cpu.ccr >> 1) & 1;\
59 nz = !((cpu.ccr >> 2) & 1);\
60 n = (cpu.ccr >> 3) & 1;
62 #ifdef __CHAR_IS_SIGNED__
63 #define SEXTCHAR(x) ((char)(x))
67 #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x)
70 #define UEXTCHAR(x) ((x) & 0xff)
71 #define UEXTSHORT(x) ((x) & 0xffff)
72 #define SEXTSHORT(x) ((short)(x))
74 static cpu_state_type cpu
;
87 return b
.tms_utime
+ b
.tms_stime
;
110 return h8300hmode
? SL
: SW
;
129 return X (OP_MEM
, SP
);
136 decode (addr
, data
, dst
)
148 struct h8_opcode
*q
= h8_opcodes
;
152 /* Find the exact opcode/arg combo */
156 unsigned int len
= 0;
162 op_type looking_for
= *nib
;
163 int thisnib
= data
[len
>> 1];
165 thisnib
= (len
& 1) ? (thisnib
& 0xf) : ((thisnib
>> 4) & 0xf);
167 if (looking_for
< 16)
170 if (looking_for
!= thisnib
)
176 if ((int) looking_for
& (int) B31
)
178 if (!(((int) thisnib
& 0x8) != 0))
180 looking_for
= (op_type
) ((int) looking_for
& ~(int)
185 if ((int) looking_for
& (int) B30
)
187 if (!(((int) thisnib
& 0x8) == 0))
189 looking_for
= (op_type
) ((int) looking_for
& ~(int) B30
);
191 if (looking_for
& DBIT
)
193 if ((looking_for
& 5) != (thisnib
&5)) goto fail
;
194 abs
= (thisnib
& 0x8) ? 2 : 1;
196 else if (looking_for
& (REG
| IND
| INC
| DEC
))
198 if (looking_for
& REG
)
201 * Can work out size from the
204 size
= bitfrom (looking_for
);
206 if (looking_for
& SRC
)
215 else if (looking_for
& L_16
)
217 abs
= (data
[len
>> 1]) * 256 + data
[(len
+ 2) >> 1];
219 if (looking_for
& (PCREL
|DISP
))
224 else if (looking_for
& ABSJMP
)
231 else if (looking_for
& L_32
)
234 abs
= (data
[i
] << 24)
235 | (data
[i
+ 1] << 16)
242 else if (looking_for
& L_24
)
245 abs
= (data
[i
] << 16) | (data
[i
+ 1] << 8) | (data
[i
+
249 else if (looking_for
& IGNORE
)
253 else if (looking_for
& DISPREG
)
255 rdisp
= thisnib
& 0x7;
257 else if (looking_for
& KBIT
)
272 else if (looking_for
& L_8
)
276 if (looking_for
& PCREL
)
278 abs
= SEXTCHAR (data
[len
>> 1]);
282 abs
= data
[len
>> 1] & 0xff;
285 else if (looking_for
& L_3
)
291 else if (looking_for
== E
)
295 /* Fill in the args */
297 op_type
*args
= q
->args
.nib
;
304 int rn
= (x
& DST
) ? rd
: rs
;
317 if (x
& (IMM
| KBIT
| DBIT
))
319 p
->type
= X (OP_IMM
, size
);
326 ops (like mul) have two sizes */
329 p
->type
= X (OP_REG
, size
);
334 p
->type
= X (OP_INC
, size
);
339 p
->type
= X (OP_DEC
, size
);
344 p
->type
= X (OP_DISP
, size
);
348 else if (x
& (ABS
| ABSJMP
| ABSMOV
))
350 p
->type
= X (OP_DISP
, size
);
356 p
->type
= X (OP_MEM
, size
);
361 p
->type
= X (OP_PCREL
, size
);
362 p
->literal
= abs
+ addr
+ 2;
366 p
->type
= X (OP_IMM
, SP
);
371 p
->type
= X (OP_DISP
, size
);
373 p
->reg
= rdisp
& 0x7;
380 printf ("Hmmmm %x", x
);
388 * But a jmp or a jsr gets
389 * automagically lvalued, since we
390 * branch to their address not their
393 if (q
->how
== O (O_JSR
, SB
)
394 || q
->how
== O (O_JMP
, SB
))
396 dst
->src
.type
= lvalue (dst
->src
.type
, dst
->src
.reg
);
400 if (dst
->dst
.type
== -1)
403 dst
->opcode
= q
->how
;
404 dst
->cycles
= q
->time
;
406 /* And a jsr to 0xc4 is turned into a magic trap */
408 if (dst
->opcode
== O(O_JSR
, SB
))
410 if(dst
->src
.literal
== 0xc4)
412 dst
->opcode
= O(O_SYSCALL
,SB
);
416 dst
->next_pc
= addr
+ len
/ 2;
421 printf ("Dont understand %x \n", looking_for
);
433 dst
->opcode
= O (O_ILL
, SB
);
442 /* find the next cache entry to use */
444 idx
= cpu
.cache_top
+ 1;
446 if (idx
>= cpu
.csize
)
452 /* Throw away its old meaning */
453 cpu
.cache_idx
[cpu
.cache
[idx
].oldpc
] = 0;
455 /* set to new address */
456 cpu
.cache
[idx
].oldpc
= pc
;
458 /* fill in instruction info */
459 decode (pc
, cpu
.memory
+ pc
, cpu
.cache
+ idx
);
461 /* point to new cache entry */
462 cpu
.cache_idx
[pc
] = idx
;
466 static unsigned char *breg
[18];
467 static unsigned short *wreg
[18];
468 static unsigned int *lreg
[18];
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)
475 #define GET_L_REG(x) *(lreg[x])
476 #define SET_L_REG(x,y) (*(lreg[x])) = (y)
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])
481 #define GET_MEMORY_W(x) \
482 ((cpu.memory[x+0] << 8) | (cpu.memory[x+1] << 0))
485 #define SET_MEMORY_B(x,y) \
486 (cpu.memory[(x)] = y)
488 #define SET_MEMORY_W(x,y) \
489 {register unsigned char *_p = cpu.memory+x;\
490 register int __y = y;\
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;}
498 #define GET_MEMORY_B(x) (cpu.memory[x])
505 int abs
= arg
->literal
;
512 return GET_B_REG (rn
);
514 return GET_W_REG (rn
);
516 return GET_L_REG (rn
);
551 case X (OP_DISP
, SB
):
552 t
= GET_L_REG (rn
) + abs
;
554 return GET_MEMORY_B (t
);
556 case X (OP_DISP
, SW
):
557 t
= GET_L_REG (rn
) + abs
;
559 return GET_MEMORY_W (t
);
561 case X (OP_DISP
, SL
):
562 t
= GET_L_REG (rn
) + abs
;
564 return GET_MEMORY_L (t
);
582 int abs
= arg
->literal
;
598 t
= GET_L_REG (rn
) - 1;
605 t
= (GET_L_REG (rn
) - 2 ) & cpu
.mask
;
611 t
= (GET_L_REG(rn
) -4 ) & cpu
.mask
;
617 case X (OP_DISP
, SB
):
618 t
= GET_L_REG (rn
) + abs
;
623 case X (OP_DISP
, SW
):
624 t
= GET_L_REG (rn
) + abs
;
629 case X (OP_DISP
, SL
):
630 t
= GET_L_REG (rn
) + abs
;
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;
670 for (i
= 0; i
< 9; i
++)
675 for (i
= 0; i
< 8; i
++)
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;
707 lreg
[i
] = &cpu
.regs
[i
];
711 lreg
[8] = &cpu
.regs
[8];
713 /* initialize the seg registers */
721 control_c (sig
, code
, scp
, addr
)
727 cpu
.exception
= SIGINT
;
736 mop(code
, bsize
, sign
)
748 bsize
? SEXTCHAR(GET_W_REG(code
->dst
.reg
)):
749 SEXTSHORT(GET_W_REG(code
->dst
.reg
));
751 bsize
? SEXTCHAR(GET_B_REG(code
->src
.reg
)):
752 SEXTSHORT(GET_W_REG(code
->src
.reg
));
756 multiplicand
= bsize
? UEXTCHAR(GET_W_REG(code
->dst
.reg
)):
757 UEXTSHORT(GET_W_REG(code
->dst
.reg
));
759 bsize
? UEXTCHAR(GET_B_REG(code
->src
.reg
)):
760 UEXTSHORT(GET_W_REG(code
->src
.reg
));
763 result
= multiplier
* multiplicand
;
767 n
= result
& (bsize
? 0x8000: 0x80000000);
768 nz
= result
& (bsize
? 0xffff: 0xffffffff);
772 SET_W_REG(code
->dst
.reg
, result
);
776 SET_L_REG(code
->dst
.reg
, result
);
778 /* return ((n==1) << 1) | (nz==1);*/
783 sim_resume (step
, siggnal
)
788 int tick_start
= get_now ();
801 prev
= signal (SIGINT
, control_c
);
805 cpu
.exception
= SIGTRAP
;
822 cidx
= cpu
.cache_idx
[pc
];
823 code
= cpu
.cache
+ cidx
;
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;
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;
842 printf ("%x %d %s\n", pc
, code
->opcode
,
843 code
->op
? code
->op
->name
: "**");
845 cpu
.stats
[code
->opcode
]++;
849 cycles
+= code
->cycles
;
851 switch (code
->opcode
)
855 * This opcode is a fake for when we get to an
856 * instruction which hasnt been compiled
864 rd
= fetch (&code
->dst
);
865 ea
= fetch (&code
->src
);
871 rd
= fetch (&code
->dst
);
872 ea
= fetch (&code
->src
);
877 #define EA ea = fetch(&code->src);
878 #define RD_EA ea = fetch(&code->src); rd = fetch(&code->dst);
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
);
884 rd
= GET_B_REG(code
->dst
.reg
);
885 ea
= fetch(&code
->src
);
889 rd
= GET_W_REG(code
->dst
.reg
);
890 ea
= fetch(&code
->src
);
894 rd
= GET_L_REG(code
->dst
.reg
);
895 ea
= fetch(&code
->src
);
900 LOGOP (O_AND
, RD_EA
; res
= rd
& ea
);
902 LOGOP (O_OR
, RD_EA
; res
= rd
| ea
);
904 LOGOP (O_XOR
, RD_EA
; res
= rd
^ ea
);
907 case O(O_MOV_TO_MEM
,SB
):
908 res
= GET_B_REG(code
->src
.reg
);
910 case O(O_MOV_TO_MEM
,SW
):
911 res
= GET_W_REG(code
->src
.reg
);
913 case O(O_MOV_TO_MEM
,SL
):
914 res
= GET_L_REG(code
->src
.reg
);
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
;
933 SET_L_REG(code
->dst
.reg
,
934 GET_L_REG(code
->dst
.reg
)
935 + code
->src
.literal
);
940 SET_L_REG(code
->dst
.reg
,
941 GET_L_REG(code
->dst
.reg
)
942 - code
->src
.literal
);
946 rd
= fetch (&code
->dst
);
947 ea
= fetch (&code
->src
);
950 goto just_flags_alu8
;
953 rd
= fetch (&code
->dst
);
954 ea
= fetch (&code
->src
);
957 goto just_flags_alu16
;
960 rd
= fetch (&code
->dst
);
961 ea
= fetch (&code
->src
);
964 goto just_flags_alu32
;
968 rd
= GET_B_REG (code
->src
.reg
);
971 SET_B_REG (code
->src
.reg
, res
);
972 goto just_flags_inc8
;
975 rd
= GET_W_REG (code
->dst
.reg
);
976 ea
= - code
->src
.literal
;
978 SET_W_REG (code
->dst
.reg
, res
);
979 goto just_flags_inc16
;
982 rd
= GET_L_REG (code
->dst
.reg
);
983 ea
= -code
->src
.literal
;
985 SET_L_REG (code
->dst
.reg
, res
);
986 goto just_flags_inc32
;
990 rd
= GET_B_REG (code
->src
.reg
);
993 SET_B_REG (code
->src
.reg
, res
);
994 goto just_flags_inc8
;
997 rd
= GET_W_REG (code
->dst
.reg
);
998 ea
= code
->src
.literal
;
1000 SET_W_REG (code
->dst
.reg
, res
);
1001 goto just_flags_inc16
;
1004 rd
= GET_L_REG (code
->dst
.reg
);
1005 ea
= code
->src
.literal
;
1007 SET_L_REG (code
->dst
.reg
, res
);
1008 goto just_flags_inc32
;
1011 #define GET_CCR(x) BUILDSR();x = cpu.ccr
1013 case O (O_ANDC
, SB
):
1015 ea
= code
->src
.literal
;
1056 if (((Z
|| (N
^ V
)) == 0))
1062 if (((Z
|| (N
^ V
)) == 1))
1096 case O(O_SYSCALL
, SB
):
1097 printf("%c", cpu
.regs
[2]);
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;}
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
;);
1120 pc
= fetch (&code
->src
);
1128 pc
= fetch (&code
->src
);
1135 SET_MEMORY_L (tmp
, code
->next_pc
);
1140 SET_MEMORY_W (tmp
, code
->next_pc
);
1147 pc
= code
->src
.literal
;
1159 pc
= GET_MEMORY_L (tmp
);
1165 pc
= GET_MEMORY_W (tmp
);
1174 cpu
.exception
= SIGILL
;
1178 cpu
.exception
= SIGTRAP
;
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;\
1186 if(s) store(&code->dst,ea); goto next;\
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*/
1204 #define MOP(bsize, signed) mop(code, bsize,signed); goto next;
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;
1215 rd
= GET_W_REG(code
->dst
.reg
);
1216 ea
= GET_B_REG(code
->src
.reg
);
1222 SET_W_REG(code
->dst
.reg
, (rd
& 0xff) | (tmp
<< 8));
1231 rd
= GET_L_REG(code
->dst
.reg
);
1232 ea
= GET_W_REG(code
->src
.reg
);
1240 SET_L_REG(code
->dst
.reg
, (rd
& 0xffff) | (tmp
<< 16));
1249 rd
= SEXTSHORT(GET_W_REG(code
->dst
.reg
));
1250 ea
= SEXTCHAR(GET_B_REG(code
->src
.reg
));
1253 tmp
= (int)rd
% (int)ea
;
1254 rd
= (int)rd
/ (int)ea
;
1261 SET_W_REG(code
->dst
.reg
, (rd
& 0xff) | (tmp
<< 8));
1267 rd
= GET_L_REG(code
->dst
.reg
);
1268 ea
= SEXTSHORT(GET_W_REG(code
->src
.reg
));
1271 tmp
= (int)rd
% (int)ea
;
1272 rd
= (int)rd
/ (int)ea
;
1273 n
= rd
& 0x80000000;
1278 SET_L_REG(code
->dst
.reg
, (rd
& 0xffff) | (tmp
<< 16));
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;
1286 case O (O_EXTS
, SL
):
1287 rd
= GET_W_REG (code
->src
.reg
) & 0xffff;
1288 ea
= rd
& 0x8000 ? -65536 : 0;
1291 case O (O_EXTU
, SW
):
1292 rd
= GET_B_REG (code
->src
.reg
+ 8) & 0xff;
1296 case O (O_EXTU
, SL
):
1297 rd
= GET_W_REG (code
->src
.reg
) & 0xffff;
1306 cpu
.exception
= 123;
1317 /* When a branch works */
1318 pc
= code
->src
.literal
;
1321 /* Set the cond codes from res */
1324 /* Set the flags after an 8 bit inc/dec operation */
1328 v
= (rd
& 0x7f) == 0x7f;
1332 /* Set the flags after an 16 bit inc/dec operation */
1336 v
= (rd
& 0x7fff) == 0x7fff;
1340 /* Set the flags after an 32 bit inc/dec operation */
1342 n
= res
& 0x80000000;
1343 nz
= res
& 0xffffffff;
1344 v
= (rd
& 0x7fffffff) == 0x7fffffff;
1349 /* Set flags after an 8 bit shift op, carry set in insn */
1353 SET_B_REG(code
->src
.reg
, rd
);
1358 /* Set flags after an 16 bit shift op, carry set in insn */
1363 SET_W_REG(code
->src
.reg
, rd
);
1367 /* Set flags after an 32 bit shift op, carry set in insn */
1368 n
= (rd
& 0x80000000);
1370 nz
= rd
& 0xffffffff;
1371 SET_L_REG(code
->src
.reg
, rd
);
1375 store (&code
->dst
, res
);
1377 /* flags after a 32bit logical operation */
1378 n
= res
& 0x80000000;
1379 nz
= res
& 0xffffffff;
1384 store (&code
->dst
, res
);
1386 /* flags after a 16bit logical operation */
1394 store (&code
->dst
, res
);
1402 SET_B_REG (code
->dst
.reg
, res
);
1406 v
= ((ea
& 0x80) == (rd
& 0x80)) && ((ea
& 0x80) != (res
& 0x80));
1411 SET_W_REG (code
->dst
.reg
, res
);
1415 v
= ((ea
& 0x8000) == (rd
& 0x8000)) && ((ea
& 0x8000) != (res
& 0x8000));
1416 c
= (res
& 0x10000);
1420 SET_L_REG (code
->dst
.reg
, res
);
1422 n
= res
& 0x80000000;
1423 nz
= res
& 0xffffffff;
1424 v
= ((ea
& 0x80000000) == (rd
& 0x80000000))
1425 && ((ea
& 0x80000000) != (res
& 0x80000000));
1426 switch (code
->opcode
/ 4)
1429 c
= ((unsigned) res
< (unsigned) rd
) || ((unsigned) res
< (unsigned) ea
);
1433 c
= (unsigned) rd
< (unsigned) -ea
;
1445 if (cpu
.regs
[8] ) abort();
1450 while (!cpu
.exception
);
1451 cpu
.ticks
+= get_now () - tick_start
;
1452 cpu
.cycles
+= cycles
;
1457 signal (SIGINT
, prev
);
1464 sim_write (addr
, buffer
, size
)
1466 unsigned char *buffer
;
1472 if (addr
< 0 || addr
+ size
> MSIZE
)
1474 for (i
= 0; i
< size
; i
++)
1476 cpu
.memory
[addr
+ i
] = buffer
[i
];
1477 cpu
.cache_idx
[addr
+ i
] = 0;
1483 sim_read (addr
, buffer
, size
)
1485 unsigned char *buffer
;
1489 if (addr
< 0 || addr
+ size
> MSIZE
)
1491 memcpy (buffer
, cpu
.memory
+ addr
, size
);
1506 #define SP_REGNUM R7_REGNUM /* Contains address of top of stack */
1507 #define FP_REGNUM R6_REGNUM /* Contains address of executing
1510 #define CCR_REGNUM 8 /* Contains processor status */
1511 #define PC_REGNUM 9 /* Contains program counter */
1513 #define CYCLE_REGNUM 10
1514 #define INST_REGNUM 11
1515 #define TICK_REGNUM 12
1519 sim_store_register (rn
, value
)
1521 unsigned char *value
;
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
;
1546 cpu
.regs
[rn
] = intval
;
1552 cpu
.cycles
= longval
;
1556 cpu
.insts
= longval
;
1560 cpu
.ticks
= longval
;
1567 sim_fetch_register (rn
, buf
)
1609 if (h8300hmode
|| longreg
)
1631 sim_stop_reason (reason
, sigrc
)
1632 enum sim_stop
*reason
;
1635 *reason
= sim_stopped
;
1636 *sigrc
= cpu
.exception
;
1655 cpu
.cache
= (decoded_inst
*) malloc (sizeof (decoded_inst
) * n
);
1656 memset (cpu
.cache
, 0, sizeof (decoded_inst
) * n
);
1663 sim_info (printf_fn
, verbose
)
1664 void (*printf_fn
)();
1668 double timetaken
= (double) cpu
.ticks
/ (double) now_persec ();
1669 double virttime
= cpu
.cycles
/ 10.0e6
;
1672 printf ("\n\n#instructions executed %10d\n", cpu
.insts
);
1673 printf ("#cycles (v approximate) %10d\n", cpu
.cycles
);
1674 printf ("#real time taken %10.4f\n", timetaken
);
1675 printf ("#virtual time taked %10.4f\n", virttime
);
1676 if (timetaken
!= 0.0)
1677 printf ("#simulation ratio %10.4f\n", virttime
/ timetaken
);
1678 printf ("#compiles %10d\n", cpu
.compiles
);
1679 printf ("#cache size %10d\n", cpu
.csize
);
1686 for (i
= 0; i
< O_LAST
; i
++)
1689 printf("%d: %d\n", i
, cpu
.stats
[i
]);
1715 sim_set_args(argv
, env
)