1 /* Simulator for the Hitachi H8/500 architecture.
3 Written by Steve Chamberlain of Cygnus Support.
6 This file is part of H8/500 sim
9 THIS SOFTWARE IS NOT COPYRIGHTED
11 Cygnus offers the following for use in the public domain. Cygnus
12 makes no warranty with regard to the software or it's performance
13 and the user accepts the software "AS IS" with all faults.
15 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 #include <sys/param.h>
34 #include "gdb/callback.h"
35 #include "gdb/remote-sim.h"
37 #define O_RECOMPILE 85
39 #define DISASSEMBLER_TABLE
41 /* FIXME: Needs to live in header file.
42 This header should also include the things in remote-sim.h.
43 One could move this to remote-sim.h but this function isn't needed
45 void sim_set_simcache_size
PARAMS ((int));
49 host_callback
*sim_callback
;
51 static SIM_OPEN_KIND sim_kind
;
54 /* This code can be compiled with any old C compiler, in which case
55 four or five switch statements will be executed for each
56 instruction simulated. It can be compiled with GCC, then the
57 simulated instructions thread through the code fragments, and
58 everything goes much faster.
60 These definitions make the code work either way
63 #define DISPATCH(X) goto *(X); do
64 #define LABEL(X) X##_L
65 #define LABELN(X,N) X##_L##N
66 #define LABEL_REF(X) &&X##_L
67 #define LABEL_REFN(X,N) &&X##_L##N
68 #define ENDDISPATCH while (0);
69 #define fastref void *
72 #define INLINE __inline__
74 #define DEFAULT default :
75 #define DISPATCH(X) switch (X)
76 #define LABEL(X) case X
77 #define LABELN(X,N) case X
78 #define LABEL_REF(X) X
79 #define LABEL_REFN(X,N) X
92 #define STORE_DISP_B 7
93 #define STORE_DISP_W 8
96 #define STORE_REG_L 11
100 #define FETCH_REG_B 10
101 #define FETCH_REG_W 11
102 #define FETCH_INC_B 12
103 #define FETCH_INC_W 13
104 #define FETCH_DEC_B 14
105 #define FETCH_DEC_W 15
106 #define FETCH_DISP_B 16
107 #define FETCH_DISP_W 17
111 #define FETCH_LVAL 21
112 #define FETCH_LVAL24 22
113 #define FETCH_REG_L 23
119 #define FLAG_NOSTORE 24
120 #define FLAG_CLEAR 25
122 #define FLAG_BRANCH 27
123 #define FLAG_special 28
125 #define FLAG_shiftword 29
126 #define FLAG_shiftbyte 30
128 #define FLAG_multword 31
129 #define FLAG_multbyte 32
133 #define h8500_table h8500_compile_table
134 #include "../opcodes/h8500-opc.h"
138 #define LOW_BYTE(x) ((x) & 0xff)
139 #define HIGH_BYTE(x) (((x)>>8) & 0xff)
140 #define NORMAL_CP ((cpu.regs[R_CP].c - cpu.memory)>>16)
141 #define NORMAL_DP ((cpu.regs[R_DP].c - cpu.memory)>>16)
142 #define NORMAL_EP ((cpu.regs[R_EP].c - cpu.memory)>>16)
143 #define NORMAL_TP ((cpu.regs[R_TP].c - cpu.memory)>>16)
144 #define SET_NORMREG(x,y) ((cpu.regs[x].l = (y)))
145 #define GET_NORMREG(x) (cpu.regs[x].l)
146 #define SET_SEGREG(x,y) { cpu.regs[x].c = ((y) & 0xff0000) + cpu.memory;}
147 #define GET_SEGREG(x) ( (cpu.regs[x].c - cpu.memory ) >> 16)
148 #define SET_NORMAL_CPPC(x) { pc = (x) & 0xffff; SET_SEGREG(R_CP, (x));}
149 #define NORMAL_SR ((N<<3)|(Z<<2)|(V<<1)|(C))
150 #define P(X,Y) ((X<<8) | Y)
152 #define BUILDSR() cpu.regs[R_SR].s[LOW] = (N << 3) | (Z << 2) | (V<<1) | C;
155 C = (cpu.regs[R_SR].s[LOW] >> 0) & 1;\
156 V = (cpu.regs[R_SR].s[LOW] >> 1) & 1;\
157 Z = (cpu.regs[R_SR].s[LOW] >> 2) & 1;\
158 N = (cpu.regs[R_SR].s[LOW] >> 3) & 1;
160 #ifdef __CHAR_IS_SIGNED__
161 #define SEXTCHAR(x) ((char)(x))
165 #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x)
168 #define SEXTSHORT(x) ((short)(x))
170 /* Which segment registers go with which pointer registers */
171 static unsigned char **segmap
[R_LAST
];
172 static unsigned char *(regptr
[R_LAST
][3]);
173 static unsigned char *(segregptr
[R_LAST
][3]);
174 static cpu_state_type cpu
;
176 static int segforreg
[] = {R_DP
, R_DP
, R_DP
, R_DP
,
177 R_EP
, R_EP
, R_TP
, R_TP
,
178 R_DP
, R_DP
, R_DP
, R_DP
,
179 R_EP
, R_EP
, R_TP
, R_TP
};
183 /* routines for getting and storing args */
184 #define elval(struct, lit) \
185 (((*(struct.reg.wptr) + lit) & 0xffff) + (*(struct.r2.segreg)))
187 #define displval(s) elval((s),(s).literal)
189 #define ireglval(struct) elval(struct, 0)
190 #define wordat(x) (((x)[0] << 8) | (x)[1])
191 #define longat(x) ((wordat((x))<<16)|(wordat((x)+2)))
192 #define byteat(x) ((x)[0])
194 #define setwordat(x,y) {x[0] =( y)>>8; x[1] = y;}
195 #define setbyteat(x,y) {x[0] = y;}
197 /*#define setalignedwordat(x,y) {((short *)x)[0] =y;}*/
260 #define N_EATYPES (sizeof(struct ea_struct) / sizeof(size_ptr))
261 size_ptr a
[N_EATYPES
];
264 /* This function takes an ea structure filled in for the 1st source
265 operand and modifies it to be for either the 1st, 2nd or dst operand */
268 howto_workout (encoded
, semiencoded
, n
)
270 ea_type
*semiencoded
;
274 *encoded
= *semiencoded
;
276 for (i
= 0; i
< N_EATYPES
; i
++)
278 if (encoded
->type
== eas
.a
[i
].s
.srcabyte
)
280 encoded
->type
= eas
.a
[i
].a
[n
].byte
;
283 else if (encoded
->type
== eas
.a
[i
].s
.srcaword
)
285 encoded
->type
= eas
.a
[i
].a
[n
].word
;
288 else if (encoded
->type
== eas
.a
[i
].s
.srcalong
)
290 encoded
->type
= eas
.a
[i
].a
[n
].lon
;
298 fastref flag_shiftword
;
299 fastref flag_shiftbyte
;
300 fastref flag_multword
;
301 fastref flag_multbyte
;
303 fastref flag_special
;
308 fastref flag_nostorep
;
311 fastref exec_dispatch
[100];
338 ptr
->type
= eas
.s
.ea_cr
.j
[JBYTE
];
339 ptr
->reg
.bptr
= segregptr
[n
][JLONG
];
343 gotreg (ptr
, n
, size
)
349 ptr
->type
= eas
.s
.ea_reg
.j
[size
];
350 ptr
->reg
.bptr
= regptr
[n
][size
];
354 gotinc (ptr
, n
, inc
, size
)
362 ptr
->type
= eas
.s
.ea_inc
.j
[size
];
366 ptr
->type
= eas
.s
.ea_dec
.j
[size
];
368 ptr
->reg
.bptr
= regptr
[n
][JWORD
];
369 ptr
->r2
.segreg
= segmap
[n
];
374 gotabs (ptr
, disp
, reg
, size
)
380 ptr
->type
= eas
.s
.ea_disp
.j
[size
];
381 ptr
->reg
.bptr
= regptr
[reg
][JWORD
];
382 ptr
->r2
.segreg
= segmap
[reg
];
387 gotind (ptr
, disp
, reg
, size
)
393 gotabs (ptr
, disp
, reg
& 0x7, size
);
401 ptr
->type
= eas
.s
.ea_imm
.j
[0];
410 for (i
= 0; i
< 6; i
++)
412 if (ptr
->type
== eas
.s
.ea_disp
.j
[i
])
414 ptr
->type
= eas
.s
.ea_lval
.j
[i
];
420 thinkabout_shifts (d
, bytesized
)
426 /* Got a byte shift, fake up second arg */
427 d
->srcb
.type
= eas
.s
.ea_imm
.s
.srcbword
;
432 /* got a word shift, fake up second arg */
433 d
->srcb
.type
= eas
.s
.ea_imm
.s
.srcbword
;
434 d
->srcb
.literal
= 16;
438 /* Calculate the number of cycles required to run this
442 compcycles (dst
, opcode
)
444 h8500_opcode_info
*opcode
;
447 /* Guess for the time being - 1 cycle for the first two bytes in the
448 opcode - to fecth the operand, and 3 cycles for all the rest of
449 the bytes, since they mean that there is probably an operand to
452 switch (opcode
->length
)
456 cycles
+= opcode
->length
;
459 cycles
+= opcode
->length
* 3;
463 dst
->cycles
= cycles
;
467 translate (ptr
, from
, to
)
472 if (ptr
->reg
.wptr
== &cpu
.regs
[7].s
[LOW
]
473 && ptr
->type
== from
)
484 if (dst
->dst
.type
== eas
.s
.ea_inc
.s
.dstbyte
485 && (dst
->srca
.type
== eas
.s
.ea_inc
.s
.srcabyte
486 || dst
->srcb
.type
== eas
.s
.ea_inc
.s
.srcbbyte
))
488 dst
->dst
.type
= eas
.s
.ea_disp
.s
.dstbyte
;
491 if (dst
->dst
.type
== eas
.s
.ea_inc
.s
.dstword
492 && (dst
->srca
.type
== eas
.s
.ea_inc
.s
.srcaword
493 || dst
->srcb
.type
== eas
.s
.ea_inc
.s
.srcbword
))
495 dst
->dst
.type
= eas
.s
.ea_disp
.s
.dstword
;
498 if (dst
->dst
.type
== eas
.s
.ea_dec
.s
.dstbyte
499 || dst
->dst
.type
== eas
.s
.ea_dec
.s
.dstword
)
501 if (dst
->srca
.type
== eas
.s
.ea_dec
.s
.srcabyte
)
503 dst
->srca
.type
= eas
.s
.ea_disp
.s
.srcabyte
;
505 else if (dst
->srca
.type
== eas
.s
.ea_dec
.s
.srcaword
)
507 dst
->srca
.type
= eas
.s
.ea_disp
.s
.srcaword
;
509 else if (dst
->srcb
.type
== eas
.s
.ea_dec
.s
.srcbbyte
)
511 dst
->srcb
.type
= eas
.s
.ea_disp
.s
.srcbbyte
;
513 else if (dst
->srcb
.type
== eas
.s
.ea_dec
.s
.srcbword
)
515 dst
->srcb
.type
= eas
.s
.ea_disp
.s
.srcbword
;
520 /* Turn a byte ops from the sp into word ops */
521 translate (&dst
->dst
, eas
.s
.ea_dec
.s
.dstbyte
, eas
.s
.ea_dec
.s
.dstword
);
522 translate (&dst
->dst
, eas
.s
.ea_inc
.s
.dstbyte
, eas
.s
.ea_inc
.s
.dstword
);
524 translate (&dst
->srca
, eas
.s
.ea_dec
.s
.srcabyte
, eas
.s
.ea_dec
.s
.srcaword
);
525 translate (&dst
->srca
, eas
.s
.ea_inc
.s
.srcabyte
, eas
.s
.ea_inc
.s
.srcaword
);
527 translate (&dst
->srcb
, eas
.s
.ea_dec
.s
.srcbbyte
, eas
.s
.ea_dec
.s
.srcbword
);
528 translate (&dst
->srcb
, eas
.s
.ea_inc
.s
.srcbbyte
, eas
.s
.ea_inc
.s
.srcbword
);
535 find (pc
, buffer
, dst
)
537 unsigned char *buffer
;
540 h8500_opcode_info
*opcode
;
544 dst
->srca
.reg
.rptr
= 0;
546 /* Run down the table to find the one which matches */
547 for (opcode
= h8500_table
; opcode
->name
; opcode
++)
562 dst
->opcode
= exec_dispatch
[opcode
->flavor
& 0x7f];
564 for (byte
= 0; byte
< opcode
->length
; byte
++)
566 if ((buffer
[byte
] & opcode
->bytes
[byte
].mask
)
567 != (opcode
->bytes
[byte
].contents
))
573 /* extract any info parts */
574 switch (opcode
->bytes
[byte
].insert
)
583 rn
= buffer
[byte
] & 0x7;
586 rs
= buffer
[byte
] & 0x7;
589 cr
= buffer
[byte
] & 0x7;
594 cr
= buffer
[byte
] & 0x7;
599 disp
= (buffer
[byte
] << 8) | (buffer
[byte
+ 1]);
603 disp
= ((char) (buffer
[byte
]));
607 rd
= buffer
[byte
] & 0x7;
612 | (buffer
[byte
+ 1] << 8)
613 | (buffer
[byte
+ 2]);
616 abs
= (buffer
[byte
] << 8) | (buffer
[byte
+ 1]);
619 abs
= (buffer
[byte
]);
622 imm
= (buffer
[byte
] << 8) | (buffer
[byte
+ 1]);
625 imm
= (buffer
[byte
]) & 0xf;
629 imm
= SEXTCHAR (buffer
[byte
]);
632 pcrel
= SEXTSHORT ((buffer
[byte
] << 8) | (buffer
[byte
+ 1]));
635 pcrel
= SEXTCHAR ((buffer
[byte
]));
638 switch (buffer
[byte
] & 0x7)
658 if (opcode
->flavor
& O_BYTE
)
661 switch (opcode
->flags
)
664 dst
->flags
= flag_shiftbyte
;
667 dst
->flags
= flag_multbyte
;
670 dst
->flags
= flag_branch
;
673 dst
->flags
= flag_mp
;
676 dst
->flags
= flag_ap
;
679 dst
->flags
= flag_nonep
;
682 dst
->flags
= flag_nostorep
;
685 dst
->flags
= flag_clearp
;
689 dst
->flags
= flag_special
;
695 switch (opcode
->flags
)
698 dst
->flags
= flag_shiftword
;
701 dst
->flags
= flag_multword
;
704 dst
->flags
= flag_branch
;
707 dst
->flags
= flag_Mp
;
710 dst
->flags
= flag_Ap
;
713 dst
->flags
= flag_nonep
;
716 dst
->flags
= flag_nostorep
;
719 dst
->flags
= flag_clearp
;
723 dst
->flags
= flag_special
;
728 for (i
= 0; i
< opcode
->nargs
; i
++)
730 ea_type
*p
= eavector
+ i
;
732 switch (opcode
->arg_type
[i
])
744 gotind (p
, disp
, rn
, idx
);
751 gotind (p
, disp
, rd
, idx
);
754 gotind (p
, disp
, 6, idx
);
770 gotinc (p
, rn
, -1, idx
);
773 gotinc (p
, rn
, 1, idx
);
776 gotinc (p
, 7, 1, idx
);
779 gotinc (p
, 7, -1, idx
);
783 gotabs (p
, abs
, R_HARD_0
, idx
);
786 gotabs (p
, abs
, R_HARD8_0
, idx
);
798 ((pcrel
+ pc
+ opcode
->length
) & 0xffff) | (pc
& 0xff0000),
804 /* Finished and done - turn from two operand stuff into three */
806 dst
->srca
.type
= eas
.s
.ea_nop
.s
.srcabyte
;
807 dst
->srcb
.type
= eas
.s
.ea_nop
.s
.srcbbyte
;
808 dst
->dst
.type
= eas
.s
.ea_nop
.s
.dstbyte
;
812 switch (opcode
->nargs
)
815 howto_workout (&dst
->srca
, &eavector
[0], 0);
816 if (opcode
->dst
!= '!')
817 howto_workout (&dst
->dst
, &eavector
[0], 2);
820 if (opcode
->src2
== '!')
822 howto_workout (&dst
->srca
, &eavector
[0], 0);
823 howto_workout (&dst
->dst
, &eavector
[1], 2);
827 howto_workout (&dst
->srca
, &eavector
[0], 0);
828 howto_workout (&dst
->srcb
, &eavector
[1], 1);
829 if (opcode
->dst
!= '!')
831 howto_workout (&dst
->dst
, &eavector
[1], 2);
839 /* Some extra stuff with pre inc and post dec,
840 make sure that if the same ea is there twice, only one of the
841 ops is auto inc/dec */
846 /* Some special cases */
847 if (dst
->opcode
== exec_dispatch
[O_PJSR
]
848 || dst
->opcode
== exec_dispatch
[O_PJMP
])
850 /* Both the @abs:24 and @rn turn into a disp word,
851 chose the right a mode since @abs:24 is 4 bytes
854 if (opcode
->length
== 4)
856 dst
->srca
.type
= eas
.s
.ea_lval24
.s
.srcabyte
;
860 dst
->srca
.type
= eas
.s
.ea_reg
.s
.srcalong
;
863 dst
->srca
.r2
.rptr
= &cpu
.regs
[R_HARD_0
];
865 /* For [P]JSR, keep return address precomputed */
866 dst
->srcb
.literal
= pc
+ opcode
->length
;
867 dst
->srcb
.type
= eas
.s
.ea_imm
.s
.srcbword
;
869 else if (dst
->opcode
== exec_dispatch
[O_MULXU
])
871 /* This is a multiply -fix the destination op */
872 if (dst
->dst
.type
== eas
.s
.ea_reg
.s
.dstword
)
874 dst
->dst
.type
= eas
.s
.ea_reg
.s
.dstlong
;
878 dst
->dst
.type
= eas
.s
.ea_reg
.s
.dstword
;
880 dst
->dst
.reg
.bptr
= regptr
[rd
][JWORD
];
882 else if (dst
->opcode
== exec_dispatch
[O_DIVXU
])
884 /* This is a wider than normal, fix the source operand */
886 = (dst
->srcb
.type
== eas
.s
.ea_reg
.s
.srcbword
)
887 ? eas
.s
.ea_reg
.s
.srcblong
888 : eas
.s
.ea_reg
.s
.srcbword
;
891 = (dst
->dst
.type
== eas
.s
.ea_reg
.s
.dstword
)
892 ? eas
.s
.ea_reg
.s
.dstlong
893 : eas
.s
.ea_reg
.s
.dstword
;
897 else if (dst
->opcode
== exec_dispatch
[O_LDM
])
899 /* Turn of the stack ref */
900 dst
->srca
.type
= eas
.s
.ea_nop
.s
.srcabyte
;
902 else if (dst
->opcode
== exec_dispatch
[O_STM
])
904 /* Turn of the stack ref */
905 dst
->srcb
.type
= eas
.s
.ea_nop
.s
.srcbbyte
;
909 /* extends read one size and write another */
910 else if (dst
->opcode
== exec_dispatch
[O_EXTS
]
911 || dst
->opcode
== exec_dispatch
[O_EXTU
])
913 dst
->dst
.type
= eas
.s
.ea_reg
.s
.dstword
;
914 dst
->dst
.reg
.bptr
= regptr
[rd
][JWORD
];
915 dst
->flags
= flag_Ap
;
919 if (opcode
->flags
== 'h')
920 thinkabout_shifts (dst
, opcode
->flavor
& O_BYTE
);
923 /* For a branch, turn off one level of indirection */
924 if (opcode
->src1
== 'B')
926 indoff (&dst
->srca
, 0);
930 dst
->next_pc
= pc
+ opcode
->length
;
932 compcycles (dst
, opcode
);
940 /* Couldn't understand anything */
941 dst
->opcode
= exec_dispatch
[O_TRAPA
];
942 dst
->next_pc
= pc
+ 1;
950 /* find the next cache entry to use */
952 idx
= cpu
.cache_top
+ 1;
954 if (idx
>= cpu
.csize
)
960 /* Throw away its old meaning */
961 cpu
.cache_idx
[cpu
.cache
[idx
].oldpc
] = 0;
963 /* set to new address */
964 cpu
.cache
[idx
].oldpc
= pc
;
966 /* fill in instruction info */
967 find (pc
, cpu
.memory
+ pc
, cpu
.cache
+ idx
);
969 /* point to new cache entry */
970 cpu
.cache_idx
[pc
] = idx
;
975 printf ("bad default %d\n", x
);
978 static int fetch_l (arg
)
983 int h
= *(arg
->reg
.wptr
);
984 r
= (union rtype
*) (arg
->reg
.wptr
) - &cpu
.regs
[0];
987 l
= cpu
.regs
[r
].s
[LOW
];
988 return (h
<< 16) | l
;
992 #define FETCH(dst, arg, n) \
994 int r; unsigned char*lval; \
995 DISPATCH((arg).type) \
996 { LABELN(FETCH_NOP,n): \
999 DEFAULT baddefault((arg).type); break; \
1000 LABELN(FETCH_LVAL,n): \
1001 dst = (*(((arg).reg.wptr)) + (arg.literal)) ; \
1003 LABELN(FETCH_LVAL24,n): \
1004 dst = (*(((arg).reg.wptr)) + *(((arg).r2.wptr)) + (arg.literal)) &0xffffff; \
1006 LABELN(FETCH_CRB,n): \
1007 dst = (*((arg).reg.segptr) - cpu.memory)>>16; \
1009 LABELN(FETCH_CRW,n): \
1012 LABELN(FETCH_REG_B,n): \
1013 dst = *((arg).reg.bptr); \
1015 LABELN(FETCH_REG_W,n): \
1016 dst = *((arg).reg.wptr); \
1018 LABELN(FETCH_REG_L,n): \
1019 dst = fetch_l(&(arg));\
1021 LABELN(FETCH_INC_B,n): \
1022 lval = elval ((arg), 0); \
1023 dst = byteat (lval); \
1024 (*((arg).reg.wptr))++; \
1026 LABELN(FETCH_INC_W,n): \
1027 lval = elval ((arg), 0); \
1028 dst = wordat (lval); \
1029 (*(((arg).reg.wptr))) += 2; \
1031 LABELN(FETCH_DEC_B, n): \
1032 (*(arg).reg.wptr)--; \
1033 lval = elval ((arg), 0); \
1034 r = byteat (lval); \
1037 LABELN(FETCH_DEC_W, n): \
1038 (*((arg).reg.wptr)) -= 2; \
1039 lval = elval ((arg), 0); \
1040 r = wordat (lval); \
1043 LABELN(FETCH_DISP_B,n): \
1044 lval = displval ((arg)); \
1045 dst = byteat (lval); \
1047 LABELN(FETCH_DISP_W,n): \
1048 lval = displval ((arg)); \
1049 dst = wordat (lval); \
1051 LABELN(FETCH_IMM, n): \
1052 dst = (arg).literal; \
1084 for (i
= 0; i
< (int) R_LAST
; i
++)
1086 if (littleendian
.u
.high
)
1088 /* big endian host */
1094 regptr
[i
][0] = ((unsigned char *) (cpu
.regs
+ i
)) + 3;
1095 regptr
[i
][1] = ((unsigned char *) (cpu
.regs
+ i
)) + 2;
1102 regptr
[i
][0] = (unsigned char *) &(cpu
.regs
[i
]);
1103 regptr
[i
][1] = (unsigned char *) (&(cpu
.regs
[i
]));
1106 regptr
[i
][2] = (unsigned char *) &(cpu
.regs
[i
]);
1109 memcpy (segregptr
+ 0, regptr
+ R_SR
, sizeof (segregptr
[0]));
1110 memcpy (segregptr
+ 1, regptr
+ R_TP
, sizeof (segregptr
[1]));
1111 memcpy (segregptr
+ 3, regptr
+ R_BR
, sizeof (segregptr
[3]));
1112 memcpy (segregptr
+ 4, regptr
+ R_EP
, sizeof (segregptr
[4]));
1113 memcpy (segregptr
+ 5, regptr
+ R_DP
, sizeof (segregptr
[5]));
1114 memcpy (segregptr
+ 6, regptr
+ R_CP
, sizeof (segregptr
[6]));
1115 memcpy (segregptr
+ 7, regptr
+ R_TP
, sizeof (segregptr
[7]));
1117 /* Pointers to into the cpu state for the seg registers */
1119 segmap
[R0
] = &cpu
.regs
[R_DP
].c
;
1120 segmap
[R1
] = &cpu
.regs
[R_DP
].c
;
1121 segmap
[R2
] = &cpu
.regs
[R_DP
].c
;
1122 segmap
[R3
] = &cpu
.regs
[R_DP
].c
;
1123 segmap
[R4
] = &cpu
.regs
[R_EP
].c
;
1124 segmap
[R5
] = &cpu
.regs
[R_EP
].c
;
1125 segmap
[R6
] = &cpu
.regs
[R_TP
].c
;
1126 segmap
[R7
] = &cpu
.regs
[R_TP
].c
;
1127 segmap
[R_HARD_0
] = &cpu
.regs
[R_DP
].c
;
1128 segmap
[R_HARD8_0
] = &cpu
.regs
[R_BP
].c
;
1130 cpu
.memory
= (unsigned char *) calloc (sizeof (char), H8500_MSIZE
);
1131 cpu
.cache_idx
= (unsigned short *) calloc (sizeof (short), H8500_MSIZE
);
1133 /* initialize the seg registers */
1135 cpu
.regs
[R_DP
].c
= cpu
.memory
;
1136 cpu
.regs
[R_TP
].c
= cpu
.memory
;
1137 cpu
.regs
[R_CP
].c
= cpu
.memory
;
1138 cpu
.regs
[R_BP
].c
= cpu
.memory
;
1139 cpu
.regs
[R_EP
].c
= cpu
.memory
;
1140 cpu
.regs
[R7
].s
[LOW
] = 0xfffe;
1141 cpu
.regs
[R6
].s
[LOW
] = 0xfffe;
1143 sim_set_simcache_size (CSIZE
);
1147 #define PUSHWORD(x) \
1149 int sp = cpu.regs[R7].s[LOW]; \
1153 p = (sp & 0xffff) + (cpu.regs[R_TP].c); \
1154 cpu.regs[R7].s[LOW] = sp; \
1158 #define POPWORD(d) \
1160 int spx= cpu.regs[R7].s[LOW]; \
1163 p = (spx& 0xffff) + (cpu.regs[R_TP].c); \
1165 cpu.regs[R7].s[LOW] = spx; \
1169 /* simulate a monitor trap */
1172 switch (cpu
.regs
[R3
].s
[LOW
] & 0xff)
1176 cpu
.exception
= SIGQUIT
;
1180 cpu
.exception
= SIGABRT
;
1183 /* print char in r0 */
1184 printf ("%c", cpu
.regs
[R0
].s
[LOW
]);
1189 control_c (sig
, code
, scp
, addr
)
1195 cpu
.exception
= SIGINT
;
1198 static jmp_buf jbuf
;
1202 cpu
.exception
= SIGSEGV
;
1210 cpu
.exception
= SIGINT
;
1215 sim_resume (sd
, step
, siggnal
)
1228 int tick_start
= get_now ();
1230 void (*prev_seg
) ();
1239 for (i
= 0; i
< N_EATYPES
; i
++)
1241 eas
.a
[i
].s
.srcabyte
= LABEL_REFN (FETCH_NOP
, 0);
1242 eas
.a
[i
].s
.srcaword
= LABEL_REFN (FETCH_NOP
, 0);
1243 eas
.a
[i
].s
.srcalong
= LABEL_REFN (FETCH_NOP
, 0);
1245 eas
.a
[i
].s
.srcbbyte
= LABEL_REFN (FETCH_NOP
, 1);
1246 eas
.a
[i
].s
.srcbword
= LABEL_REFN (FETCH_NOP
, 1);
1247 eas
.a
[i
].s
.srcblong
= LABEL_REFN (FETCH_NOP
, 1);
1249 eas
.a
[i
].s
.dstbyte
= LABEL_REF (STORE_NOP
);
1250 eas
.a
[i
].s
.dstword
= LABEL_REF (STORE_NOP
);
1251 eas
.a
[i
].s
.dstlong
= LABEL_REF (STORE_NOP
);
1254 eas
.s
.ea_lval
.s
.srcabyte
= LABEL_REFN (FETCH_LVAL
, 0);
1255 eas
.s
.ea_lval
.s
.srcaword
= LABEL_REFN (FETCH_LVAL
, 0);
1256 eas
.s
.ea_lval24
.s
.srcabyte
= LABEL_REFN (FETCH_LVAL24
, 0);
1257 eas
.s
.ea_lval24
.s
.srcaword
= LABEL_REFN (FETCH_LVAL24
, 0);
1259 eas
.s
.ea_nop
.s
.srcabyte
= LABEL_REFN (FETCH_NOP
, 0);
1260 eas
.s
.ea_nop
.s
.srcaword
= LABEL_REFN (FETCH_NOP
, 0);
1261 eas
.s
.ea_nop
.s
.srcbbyte
= LABEL_REFN (FETCH_NOP
, 1);
1262 eas
.s
.ea_nop
.s
.srcbword
= LABEL_REFN (FETCH_NOP
, 1);
1263 eas
.s
.ea_nop
.s
.dstbyte
= LABEL_REF (STORE_NOP
);
1264 eas
.s
.ea_nop
.s
.dstword
= LABEL_REF (STORE_NOP
);
1266 eas
.s
.ea_cr
.s
.srcabyte
= LABEL_REFN (FETCH_CRB
, 0);
1267 eas
.s
.ea_cr
.s
.srcaword
= LABEL_REFN (FETCH_CRW
, 0);
1269 eas
.s
.ea_cr
.s
.srcbbyte
= LABEL_REFN (FETCH_CRB
, 1);
1270 eas
.s
.ea_cr
.s
.srcbword
= LABEL_REFN (FETCH_CRW
, 1);
1272 eas
.s
.ea_cr
.s
.dstbyte
= LABEL_REF (STORE_CRB
);
1273 eas
.s
.ea_cr
.s
.dstword
= LABEL_REF (STORE_CRW
);
1275 eas
.s
.ea_reg
.s
.srcabyte
= LABEL_REFN (FETCH_REG_B
, 0);
1276 eas
.s
.ea_reg
.s
.srcaword
= LABEL_REFN (FETCH_REG_W
, 0);
1277 eas
.s
.ea_reg
.s
.srcalong
= LABEL_REFN (FETCH_REG_L
, 0);
1279 eas
.s
.ea_reg
.s
.srcbbyte
= LABEL_REFN (FETCH_REG_B
, 1);
1280 eas
.s
.ea_reg
.s
.srcbword
= LABEL_REFN (FETCH_REG_W
, 1);
1281 eas
.s
.ea_reg
.s
.srcblong
= LABEL_REFN (FETCH_REG_L
, 1);
1283 eas
.s
.ea_reg
.s
.dstbyte
= LABEL_REF (STORE_REG_B
);
1284 eas
.s
.ea_reg
.s
.dstword
= LABEL_REF (STORE_REG_W
);
1285 eas
.s
.ea_reg
.s
.dstlong
= LABEL_REF (STORE_REG_L
);
1287 eas
.s
.ea_inc
.s
.srcabyte
= LABEL_REFN (FETCH_INC_B
, 0);
1288 eas
.s
.ea_inc
.s
.srcaword
= LABEL_REFN (FETCH_INC_W
, 0);
1289 eas
.s
.ea_inc
.s
.srcbbyte
= LABEL_REFN (FETCH_INC_B
, 1);
1290 eas
.s
.ea_inc
.s
.srcbword
= LABEL_REFN (FETCH_INC_W
, 1);
1291 eas
.s
.ea_inc
.s
.dstbyte
= LABEL_REF (STORE_INC_B
);
1292 eas
.s
.ea_inc
.s
.dstword
= LABEL_REF (STORE_INC_W
);
1294 eas
.s
.ea_dec
.s
.srcabyte
= LABEL_REFN (FETCH_DEC_B
, 0);
1295 eas
.s
.ea_dec
.s
.srcaword
= LABEL_REFN (FETCH_DEC_W
, 0);
1296 eas
.s
.ea_dec
.s
.srcbbyte
= LABEL_REFN (FETCH_DEC_B
, 1);
1297 eas
.s
.ea_dec
.s
.srcbword
= LABEL_REFN (FETCH_DEC_W
, 1);
1298 eas
.s
.ea_dec
.s
.dstbyte
= LABEL_REF (STORE_DEC_B
);
1299 eas
.s
.ea_dec
.s
.dstword
= LABEL_REF (STORE_DEC_W
);
1301 eas
.s
.ea_disp
.s
.srcabyte
= LABEL_REFN (FETCH_DISP_B
, 0);
1302 eas
.s
.ea_disp
.s
.srcaword
= LABEL_REFN (FETCH_DISP_W
, 0);
1303 eas
.s
.ea_disp
.s
.srcbbyte
= LABEL_REFN (FETCH_DISP_B
, 1);
1304 eas
.s
.ea_disp
.s
.srcbword
= LABEL_REFN (FETCH_DISP_W
, 1);
1305 eas
.s
.ea_disp
.s
.dstbyte
= LABEL_REF (STORE_DISP_B
);
1306 eas
.s
.ea_disp
.s
.dstword
= LABEL_REF (STORE_DISP_W
);
1308 eas
.s
.ea_imm
.s
.srcabyte
= LABEL_REFN (FETCH_IMM
, 0);
1309 eas
.s
.ea_imm
.s
.srcaword
= LABEL_REFN (FETCH_IMM
, 0);
1310 eas
.s
.ea_imm
.s
.srcbbyte
= LABEL_REFN (FETCH_IMM
, 1);
1311 eas
.s
.ea_imm
.s
.srcbword
= LABEL_REFN (FETCH_IMM
, 1);
1313 flag_special
= LABEL_REF (FLAG_special
);
1314 flag_mp
= LABEL_REF (FLAG_m
);
1315 flag_Mp
= LABEL_REF (FLAG_M
);
1316 flag_ap
= LABEL_REF (FLAG_a
);
1317 flag_Ap
= LABEL_REF (FLAG_A
);
1318 flag_nonep
= LABEL_REF (FLAG_NONE
);
1319 flag_nostorep
= LABEL_REF (FLAG_NOSTORE
);
1320 flag_clearp
= LABEL_REF (FLAG_CLEAR
);
1321 flag_shiftbyte
= LABEL_REF (FLAG_shiftbyte
);
1322 flag_shiftword
= LABEL_REF (FLAG_shiftword
);
1323 flag_multbyte
= LABEL_REF (FLAG_multbyte
);
1324 flag_multword
= LABEL_REF (FLAG_multword
);
1327 exec_dispatch
[O_ADDS
] = LABEL_REF (O_ADDS
);
1328 exec_dispatch
[O_ADDX
] = LABEL_REF (O_ADDX
);
1329 exec_dispatch
[O_ADD
] = LABEL_REF (O_ADD
);
1330 exec_dispatch
[O_ANDC
] = LABEL_REF (O_ANDC
);
1331 exec_dispatch
[O_AND
] = LABEL_REF (O_AND
);
1332 exec_dispatch
[O_BCC
] = LABEL_REF (O_BCC
);
1333 exec_dispatch
[O_BCLR
] = LABEL_REF (O_BCLR
);
1334 exec_dispatch
[O_BCS
] = LABEL_REF (O_BCS
);
1335 exec_dispatch
[O_BEQ
] = LABEL_REF (O_BEQ
);
1336 exec_dispatch
[O_BF
] = LABEL_REF (O_BF
);
1337 exec_dispatch
[O_BGE
] = LABEL_REF (O_BGE
);
1338 exec_dispatch
[O_BGT
] = LABEL_REF (O_BGT
);
1339 exec_dispatch
[O_BHI
] = LABEL_REF (O_BHI
);
1340 exec_dispatch
[O_BHS
] = LABEL_REF (O_BHS
);
1341 exec_dispatch
[O_BLE
] = LABEL_REF (O_BLE
);
1342 exec_dispatch
[O_BLO
] = LABEL_REF (O_BLO
);
1343 exec_dispatch
[O_BLS
] = LABEL_REF (O_BLS
);
1344 exec_dispatch
[O_BLT
] = LABEL_REF (O_BLT
);
1345 exec_dispatch
[O_BMI
] = LABEL_REF (O_BMI
);
1346 exec_dispatch
[O_BNE
] = LABEL_REF (O_BNE
);
1347 exec_dispatch
[O_BNOT
] = LABEL_REF (O_BNOT
);
1348 exec_dispatch
[O_BPL
] = LABEL_REF (O_BPL
);
1349 exec_dispatch
[O_BPT
] = LABEL_REF (O_BPT
);
1350 exec_dispatch
[O_BRA
] = LABEL_REF (O_BRA
);
1351 exec_dispatch
[O_BRN
] = LABEL_REF (O_BRN
);
1352 exec_dispatch
[O_BSET
] = LABEL_REF (O_BSET
);
1353 exec_dispatch
[O_BSR
] = LABEL_REF (O_BSR
);
1354 exec_dispatch
[O_BTST
] = LABEL_REF (O_BTST
);
1355 exec_dispatch
[O_BT
] = LABEL_REF (O_BT
);
1356 exec_dispatch
[O_BVC
] = LABEL_REF (O_BVC
);
1357 exec_dispatch
[O_BVS
] = LABEL_REF (O_BVS
);
1358 exec_dispatch
[O_CLR
] = LABEL_REF (O_CLR
);
1359 exec_dispatch
[O_CMP
] = LABEL_REF (O_CMP
);
1360 exec_dispatch
[O_DADD
] = LABEL_REF (O_DADD
);
1361 exec_dispatch
[O_DIVXU
] = LABEL_REF (O_DIVXU
);
1362 exec_dispatch
[O_DSUB
] = LABEL_REF (O_DSUB
);
1363 exec_dispatch
[O_EXTS
] = LABEL_REF (O_EXTS
);
1364 exec_dispatch
[O_EXTU
] = LABEL_REF (O_EXTU
);
1365 exec_dispatch
[O_JMP
] = LABEL_REF (O_JMP
);
1366 exec_dispatch
[O_JSR
] = LABEL_REF (O_JSR
);
1367 exec_dispatch
[O_LDC
] = LABEL_REF (O_LDC
);
1368 exec_dispatch
[O_LDM
] = LABEL_REF (O_LDM
);
1369 exec_dispatch
[O_LINK
] = LABEL_REF (O_LINK
);
1370 exec_dispatch
[O_MOVFPE
] = LABEL_REF (O_MOVFPE
);
1371 exec_dispatch
[O_MOVTPE
] = LABEL_REF (O_MOVTPE
);
1372 exec_dispatch
[O_MOV
] = LABEL_REF (O_MOV
);
1373 exec_dispatch
[O_MULXU
] = LABEL_REF (O_MULXU
);
1374 exec_dispatch
[O_NEG
] = LABEL_REF (O_NEG
);
1375 exec_dispatch
[O_NOP
] = LABEL_REF (O_NOP
);
1376 exec_dispatch
[O_NOT
] = LABEL_REF (O_NOT
);
1377 exec_dispatch
[O_ORC
] = LABEL_REF (O_ORC
);
1378 exec_dispatch
[O_OR
] = LABEL_REF (O_OR
);
1379 exec_dispatch
[O_PJMP
] = LABEL_REF (O_PJMP
);
1380 exec_dispatch
[O_PJSR
] = LABEL_REF (O_PJSR
);
1381 exec_dispatch
[O_PRTD
] = LABEL_REF (O_PRTD
);
1382 exec_dispatch
[O_PRTS
] = LABEL_REF (O_PRTS
);
1383 exec_dispatch
[O_RECOMPILE
] = LABEL_REF (O_RECOMPILE
);
1385 exec_dispatch
[O_ROTL
] = LABEL_REF (O_ROTL
);
1386 exec_dispatch
[O_ROTR
] = LABEL_REF (O_ROTR
);
1387 exec_dispatch
[O_ROTXL
] = LABEL_REF (O_ROTXL
);
1388 exec_dispatch
[O_ROTXR
] = LABEL_REF (O_ROTXR
);
1390 exec_dispatch
[O_RTD
] = LABEL_REF (O_RTD
);
1391 exec_dispatch
[O_RTS
] = LABEL_REF (O_RTS
);
1392 exec_dispatch
[O_SCB_EQ
] = LABEL_REF (O_SCB_EQ
);
1393 exec_dispatch
[O_SCB_F
] = LABEL_REF (O_SCB_F
);
1394 exec_dispatch
[O_SCB_NE
] = LABEL_REF (O_SCB_NE
);
1395 exec_dispatch
[O_SHAL
] = LABEL_REF (O_SHAL
);
1396 exec_dispatch
[O_SHAR
] = LABEL_REF (O_SHAR
);
1397 exec_dispatch
[O_SHLL
] = LABEL_REF (O_SHLL
);
1398 exec_dispatch
[O_SHLR
] = LABEL_REF (O_SHLR
);
1400 exec_dispatch
[O_SLEEP
] = LABEL_REF (O_SLEEP
);
1401 exec_dispatch
[O_STC
] = LABEL_REF (O_STC
);
1402 exec_dispatch
[O_STM
] = LABEL_REF (O_STM
);
1403 exec_dispatch
[O_SUBS
] = LABEL_REF (O_SUBS
);
1404 exec_dispatch
[O_SUBX
] = LABEL_REF (O_SUBX
);
1405 exec_dispatch
[O_SUB
] = LABEL_REF (O_SUB
);
1406 exec_dispatch
[O_SWAP
] = LABEL_REF (O_SWAP
);
1407 exec_dispatch
[O_TAS
] = LABEL_REF (O_TAS
);
1408 exec_dispatch
[O_TRAPA
] = LABEL_REF (O_TRAPA
);
1409 exec_dispatch
[O_TRAP_VS
] = LABEL_REF (O_TRAP_VS
);
1410 exec_dispatch
[O_TST
] = LABEL_REF (O_TST
);
1411 exec_dispatch
[O_UNLK
] = LABEL_REF (O_UNLK
);
1412 exec_dispatch
[O_XCH
] = LABEL_REF (O_XCH
);
1413 exec_dispatch
[O_XORC
] = LABEL_REF (O_XORC
);
1414 exec_dispatch
[O_XOR
] = LABEL_REF (O_XOR
);
1415 nop
.type
= eas
.s
.ea_nop
.s
.srcabyte
;
1416 cpu
.cache
[0].opcode
= exec_dispatch
[O_RECOMPILE
];
1417 cpu
.cache
[0].srca
.type
= eas
.s
.ea_nop
.s
.srcabyte
;
1418 cpu
.cache
[0].srcb
.type
= eas
.s
.ea_nop
.s
.srcbbyte
;
1421 prev
= signal (SIGINT
, control_c
);
1422 prev_seg
= signal (SIGSEGV
, segv
);
1426 cpu
.exception
= SIGTRAP
;
1433 pc
= cpu
.regs
[R_PC
].s
[LOW
] + (NORMAL_CP
<< 16);
1437 if (setjmp (jbuf
) == 0) {
1444 cidx
= cpu
.cache_idx
[pc
];
1445 code
= cpu
.cache
+ cidx
;
1447 FETCH (arga
, code
->srca
, 0);
1448 FETCH (argb
, code
->srcb
, 1);
1455 printf ("%x %d %s\n", pc
, code
->opcode
,
1456 code
->op
? code
->op
->name
: "**");
1460 cycles
+= code
->cycles
;
1462 DISPATCH (code
->opcode
)
1464 LABEL (O_RECOMPILE
):
1465 /* This opcode is a fake for when we get to an instruction which
1466 hasn't been compiled */
1486 res
= arga
+ argb
+ C
;
1497 bit
= (argb
& (1 << arga
));
1498 res
= argb
& ~(1 << arga
);
1540 if (((Z
|| (N
^ V
)) == 0))
1546 if (((Z
|| (N
^ V
)) == 1))
1581 bit
= argb
& (1<<(arga
& 0xf));
1582 res
= argb
^ (1<<(arga
& 0xf));
1587 arga
= 1 << (arga
& 0xf);
1600 SET_NORMREG (R7
, GET_NORMREG (R6
));
1602 SET_NORMREG (R6
, t
);
1609 int cp
= pc
& 0xff0000;
1623 SET_SEGREG (R_CP
, cp
);
1629 PUSHWORD (argb
& 0xffff);
1630 PUSHWORD (argb
>> 16);
1631 pc
= (arga
& 0xffffff);
1636 PUSHWORD (code
->next_pc
);
1637 pc
= arga
| (pc
& 0xff0000);
1641 Z
= (((argb
>> (arga
& 0xf)) & 1) == 0);
1655 res
= arga
+ argb
+ C
;
1665 Z
= Z
&& (res
== 0);
1670 res
= argb
- arga
- C
;
1680 Z
= Z
&& (res
== 0);
1684 res
= SEXTCHAR (arga
);
1688 res
= (unsigned char) arga
;
1692 pc
= arga
| (pc
& 0xff0000);
1698 for (tmp
= 0; tmp
< 7; tmp
++)
1700 if (argb
& (1 << tmp
))
1702 POPWORD (cpu
.regs
[tmp
].s
[LOW
]);
1706 POPWORD (tmp
); /* dummy ready for sp */
1711 PUSHWORD (cpu
.regs
[R6
].s
[LOW
]);
1712 cpu
.regs
[R6
].s
[LOW
] = cpu
.regs
[R7
].s
[LOW
];
1713 cpu
.regs
[R7
].s
[LOW
] += argb
;
1732 PUSHWORD (pc
& 0xffff);
1735 PUSHWORD (NORMAL_CP
);
1737 PUSHWORD (NORMAL_SR
);
1740 arga
= arga
* 4 + 0x40;
1741 SET_NORMAL_CPPC (longat (cpu
.memory
+ arga
));
1745 arga
= arga
* 2 + 0x20;
1746 SET_NORMAL_CPPC (wordat (cpu
.memory
+ arga
));
1765 code
->srca
.reg
.wptr
[0] = res
;
1787 /* If only they were all as simple as this */
1792 C
= (res
>> argb
) & 1;
1800 res
|= (C
<< (argb
- 1));
1806 C
= (res
>> argb
) & 1;
1811 res
|= (C
<< (argb
- 1));
1819 C
= (res
>> (16)) & 1;
1820 Z
= ((res
& 0xffff) == 0);
1821 N
= ((res
& 0x8000) != 0);
1826 C
= (res
>> (8)) & 1;
1827 Z
= ((res
& 0xff) == 0);
1828 N
= ((res
& 0x80) != 0);
1838 res
= ((short) arga
) >> 1;
1842 res
= (SEXTCHAR (arga
)) >> 1;
1848 C
= (res
>> argb
) & 1;
1861 cpu
.exception
= SIGILL
;
1865 int d
= argb
/ arga
;
1866 int m
= argb
% arga
;
1867 if (code
->dst
.type
== eas
.s
.ea_reg
.s
.dstlong
)
1869 res
= (m
<< 16) | (d
& 0xffff);
1873 res
= (m
<< 8) | (d
& 0xff);
1888 res
= ((arga
>> 8) & 0xff) | ((arga
<< 8) & 0xff00);
1893 for (tmp
= 7; tmp
>= 0; tmp
--)
1895 if (arga
& (1 << tmp
))
1897 PUSHWORD (cpu
.regs
[tmp
].s
[LOW
]);
1913 cpu
.exception
= SIGILL
;
1919 cpu
.exception
= SIGTRAP
;
1926 DISPATCH (code
->flags
)
1929 Z
= (res
& bit
) == 0;
1932 LABEL (FLAG_multword
):
1933 Z
= (res
& 0xffff) == 0;
1934 N
= (res
& 0x8000) != 0;
1940 LABEL (FLAG_multbyte
):
1942 Z
= (res
& 0xff) == 0;
1943 N
= (res
& 0x80) != 0;
1949 LABEL (FLAG_shiftword
):
1950 N
= (res
& 0x8000) != 0;
1951 Z
= (res
& 0xffff) == 0;
1956 LABEL (FLAG_shiftbyte
):
1957 N
= (res
& 0x80) != 0;
1958 Z
= (res
& 0xff) == 0;
1963 LABEL (FLAG_special
):
1968 /* Move byte flags */
1969 /* after a logical instruction */
1970 N
= (res
& 0x80) != 0;
1971 Z
= (res
& 0xff) == 0;
1972 V
= (((~arga
& ~argb
& res
) | (arga
& argb
& ~res
)) & 0x80) != 0;
1977 /* Move word flags */
1978 /* after a logical instruction */
1979 N
= (res
& 0x8000) != 0;
1980 Z
= (res
& 0xffff) == 0;
1981 V
= (((~arga
& ~argb
& res
) | (arga
& argb
& ~res
)) & 0x8000) != 0;
1986 /* after byte sized arith */
1987 C
= (res
& 0x100) != 0;
1988 N
= (res
& 0x80) != 0;
1989 Z
= (res
& 0xff) == 0;
1990 V
= (((~arga
& ~argb
& res
) | (arga
& argb
& ~res
)) & 0x80) != 0;
1995 /* after word sized arith */
1996 C
= (res
& 0x10000) != 0;
1997 N
= (res
& 0x8000) != 0;
1998 Z
= (res
& 0xffff) == 0;
1999 V
= (((~arga
& ~argb
& res
) | (arga
& argb
& ~res
)) & 0x8000) != 0;
2005 /* no flags but store */
2008 LABEL (FLAG_NOSTORE
):
2009 /* no flags and no store */
2026 DISPATCH (code
->dst
.type
)
2028 unsigned char *lval
;
2031 (*(code
->dst
.reg
.segptr
)) = cpu
.memory
+ (res
<< 16);
2037 LABEL (STORE_REG_B
):
2038 (*(code
->dst
.reg
.bptr
)) = res
;
2041 LABEL (STORE_REG_W
):
2042 (*(code
->dst
.reg
.wptr
)) = res
;
2045 LABEL (STORE_REG_L
):
2049 r
= (union rtype
*) (code
->dst
.reg
.wptr
) - &cpu
.regs
[0];
2051 *(code
->dst
.reg
.wptr
) = res
>> 16;
2052 cpu
.regs
[r
].s
[LOW
] = res
& 0xffff;
2058 LABEL (STORE_DISP_W
):
2059 lval
= displval (code
->dst
);
2060 setwordat (lval
, res
);
2063 LABEL (STORE_DISP_B
):
2064 lval
= displval (code
->dst
);
2065 setbyteat (lval
, res
);
2068 LABEL (STORE_INC_B
):
2069 lval
= elval (code
->dst
, 0);
2070 setbyteat (lval
, res
);
2071 (*(code
->dst
.reg
.wptr
))++;
2074 LABEL (STORE_INC_W
):
2075 lval
= elval (code
->dst
, 0);
2076 setwordat (lval
, res
);
2077 (*(code
->dst
.reg
.wptr
)) += 2;
2080 LABEL (STORE_DEC_B
):
2081 (*(code
->dst
.reg
.wptr
))--;
2082 lval
= elval (code
->dst
, 0);
2083 setbyteat (lval
, res
);
2087 /* Make an up to date sr from the flag state */
2088 cpu
.regs
[R_SR
].s
[LOW
] = res
;
2092 LABEL (STORE_DEC_W
):
2093 (*(code
->dst
.reg
.wptr
)) -= 2;
2094 lval
= elval (code
->dst
, 0);
2095 setwordat (lval
, res
);
2106 while (!cpu
.exception
);
2109 cpu
.ticks
+= get_now () - tick_start
;
2110 cpu
.cycles
+= cycles
;
2112 cpu
.regs
[R_PC
].s
[LOW
] = pc
;
2115 signal (SIGINT
, prev
);
2116 signal (SIGSEGV
, prev_seg
);
2123 sim_write (sd
, addr
, buffer
, size
)
2126 unsigned char *buffer
;
2132 if (addr
< 0 || addr
+ size
> H8500_MSIZE
)
2134 for (i
= 0; i
< size
; i
++)
2136 cpu
.memory
[addr
+ i
] = buffer
[i
];
2137 cpu
.cache_idx
[addr
+ i
] = 0;
2143 sim_read (sd
, addr
, buffer
, size
)
2146 unsigned char *buffer
;
2150 if (addr
< 0 || addr
+ size
> H8500_MSIZE
)
2152 memcpy (buffer
, cpu
.memory
+ addr
, size
);
2156 /* Ripped off from tm-h8500.h */
2167 /* As above, but with correct seg register glued on */
2168 #define PR0_REGNUM 8
2169 #define PR1_REGNUM 9
2170 #define PR2_REGNUM 10
2171 #define PR3_REGNUM 11
2172 #define PR4_REGNUM 12
2173 #define PR5_REGNUM 13
2174 #define PR6_REGNUM 14
2175 #define PR7_REGNUM 15
2177 #define SP_REGNUM PR7_REGNUM /* Contains address of top of stack */
2178 #define FP_REGNUM PR6_REGNUM /* Contains address of executing stack frame */
2181 #define SEG_C_REGNUM 16 /* Segment registers */
2182 #define SEG_D_REGNUM 17
2183 #define SEG_E_REGNUM 18
2184 #define SEG_T_REGNUM 19
2186 #define CCR_REGNUM 20 /* Contains processor status */
2187 #define PC_REGNUM 21 /* Contains program counter */
2189 #define CYCLE_REGNUM 22
2190 #define INST_REGNUM 23
2191 #define TICK_REGNUM 24
2194 sim_store_register (sd
, rn
, value
, length
)
2197 unsigned char *value
;
2207 SET_SEGREG (R_CP
, (value
[1]<<16));
2208 cpu
.regs
[R_PC
].s
[LOW
] = (value
[2] << 8) | value
[3];
2214 seg
= rn
- SEG_C_REGNUM
+ R_CP
;
2228 reg
= rn
- R0_REGNUM
;
2235 cpu
.cycles
= (value
[0] << 24) | (value
[1] << 16) | (value
[2] << 8) | value
[3];
2238 cpu
.insts
= (value
[0] << 24) | (value
[1] << 16) | (value
[2] << 8) | value
[3];
2241 cpu
.ticks
= (value
[0] << 24) | (value
[1] << 16) | (value
[2] << 8) | value
[3];
2251 SET_SEGREG (segforreg
[rn
], value
[1]);
2252 reg
= rn
- PR0_REGNUM
;
2253 cpu
.regs
[reg
].s
[LOW
] = (value
[2] << 8) | value
[3];
2258 SET_SEGREG (seg
, value
[0] << 16);
2262 cpu
.regs
[reg
].s
[LOW
] = (value
[0] << 8) | value
[1];
2268 sim_fetch_register (sd
, rn
, buf
, length
)
2284 buf
[0] = GET_SEGREG(rn
- SEG_C_REGNUM
+ R_CP
);
2287 buf
[0] = cpu
.regs
[R_SR
].s
[HIGH
];
2288 buf
[1] = cpu
.regs
[R_SR
].s
[LOW
];
2292 buf
[1] = GET_SEGREG(R_CP
);
2293 buf
[2] = HIGH_BYTE (cpu
.regs
[R_PC
].s
[LOW
]);
2294 buf
[3] = LOW_BYTE (cpu
.regs
[R_PC
].s
[LOW
]);
2307 buf
[1] = GET_SEGREG(segforreg
[rn
]);
2308 buf
[2] = HIGH_BYTE (cpu
.regs
[rn
].s
[LOW
]);
2309 buf
[3] = LOW_BYTE (cpu
.regs
[rn
].s
[LOW
]);
2319 buf
[0] = HIGH_BYTE (cpu
.regs
[rn
].s
[LOW
]);
2320 buf
[1] = LOW_BYTE (cpu
.regs
[rn
].s
[LOW
]);
2323 buf
[0] = cpu
.cycles
>> 24;
2324 buf
[1] = cpu
.cycles
>> 16;
2325 buf
[2] = cpu
.cycles
>> 8;
2326 buf
[3] = cpu
.cycles
>> 0;
2330 buf
[0] = cpu
.ticks
>> 24;
2331 buf
[1] = cpu
.ticks
>> 16;
2332 buf
[2] = cpu
.ticks
>> 8;
2333 buf
[3] = cpu
.ticks
>> 0;
2337 buf
[0] = cpu
.insts
>> 24;
2338 buf
[1] = cpu
.insts
>> 16;
2339 buf
[2] = cpu
.insts
>> 8;
2340 buf
[3] = cpu
.insts
>> 0;
2353 for (i
= 0; i
< 12; i
+= 2)
2355 unsigned char *p
= cpu
.regs
[R_TP
].c
+ ((cpu
.regs
[R6
].s
[LOW
] + i
) & 0xffff);
2356 unsigned short *j
= (unsigned short *) p
;
2358 printf ("%04x ", *j
);
2361 printf ("%02x %02x %02x %02x:%04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
2366 cpu
.regs
[R_PC
].s
[LOW
],
2374 cpu
.regs
[7].s
[LOW
]);
2375 sim_resume (sd
, 1, 0);
2380 sim_stop_reason (sd
, reason
, sigrc
)
2382 enum sim_stop
*reason
;
2385 *reason
= sim_stopped
;
2386 *sigrc
= cpu
.exception
;
2390 sim_set_simcache_size (n
)
2396 cpu
.cache
= (decoded_inst
*) malloc (sizeof (decoded_inst
) * n
);
2408 sim_info (sd
, verbose
)
2412 double timetaken
= (double) cpu
.ticks
/ (double) now_persec ();
2413 double virttime
= cpu
.cycles
/ 10.0e6
;
2415 (*sim_callback
->printf_filtered
) (sim_callback
,
2416 "\n\ninstructions executed %10d\n",
2418 (*sim_callback
->printf_filtered
) (sim_callback
,
2419 "cycles (v approximate) %10d\n",
2421 (*sim_callback
->printf_filtered
) (sim_callback
,
2422 "real time taken %10.4f\n",
2424 (*sim_callback
->printf_filtered
) (sim_callback
,
2425 "virtual time taked %10.4f\n",
2429 (*sim_callback
->printf_filtered
) (sim_callback
,
2430 "simulation ratio %10.4f\n",
2431 virttime
/ timetaken
);
2434 (*sim_callback
->printf_filtered
) (sim_callback
,
2437 (*sim_callback
->printf_filtered
) (sim_callback
,
2438 "cache size %10d\n",
2443 sim_open (kind
, cb
, abfd
, argv
)
2452 /* fudge our descriptor */
2453 return (SIM_DESC
) 1;
2457 sim_close (sd
, quitting
)
2465 sim_load (sd
, prog
, abfd
, from_tty
)
2471 extern bfd
*sim_load_file (); /* ??? Don't know where this should live. */
2474 prog_bfd
= sim_load_file (sd
, myname
, sim_callback
, prog
, abfd
,
2475 sim_kind
== SIM_OPEN_DEBUG
,
2477 if (prog_bfd
== NULL
)
2480 bfd_close (prog_bfd
);
2485 sim_create_inferior (sd
, abfd
, argv
, env
)
2492 bfd_vma start_address
;
2494 start_address
= bfd_get_start_address (abfd
);
2498 /* ??? We assume this is a 4 byte quantity. */
2501 sim_store_register (sd
, PC_REGNUM
, (unsigned char *) &pc
, 4);
2506 sim_do_command (sd
, cmd
)
2510 (*sim_callback
->printf_filtered
) (sim_callback
,
2511 "This simulator does not accept any commands.\n");
2515 sim_set_callbacks (ptr
)
2516 struct host_callback_struct
*ptr
;
This page took 0.117615 seconds and 4 git commands to generate.