| 1 | #include <stdio.h> |
| 2 | #include <ctype.h> |
| 3 | #include <limits.h> |
| 4 | #include "ansidecl.h" |
| 5 | #include "callback.h" |
| 6 | #include "opcode/d10v.h" |
| 7 | |
| 8 | #define DEBUG_TRACE 0x00000001 |
| 9 | #define DEBUG_VALUES 0x00000002 |
| 10 | #define DEBUG_LINE_NUMBER 0x00000004 |
| 11 | #define DEBUG_MEMSIZE 0x00000008 |
| 12 | #define DEBUG_INSTRUCTION 0x00000010 |
| 13 | |
| 14 | #ifndef DEBUG |
| 15 | #define DEBUG (DEBUG_TRACE | DEBUG_VALUES | DEBUG_LINE_NUMBER) |
| 16 | #endif |
| 17 | |
| 18 | extern int d10v_debug; |
| 19 | |
| 20 | #if UCHAR_MAX == 255 |
| 21 | typedef unsigned char uint8; |
| 22 | typedef signed char int8; |
| 23 | #else |
| 24 | #error "Char is not an 8-bit type" |
| 25 | #endif |
| 26 | |
| 27 | #if SHRT_MAX == 32767 |
| 28 | typedef unsigned short uint16; |
| 29 | typedef signed short int16; |
| 30 | #else |
| 31 | #error "Short is not a 16-bit type" |
| 32 | #endif |
| 33 | |
| 34 | #if INT_MAX == 2147483647 |
| 35 | typedef unsigned int uint32; |
| 36 | typedef signed int int32; |
| 37 | |
| 38 | #elif LONG_MAX == 2147483647 |
| 39 | typedef unsigned long uint32; |
| 40 | typedef signed long int32; |
| 41 | |
| 42 | #else |
| 43 | #error "Neither int nor long is a 32-bit type" |
| 44 | #endif |
| 45 | |
| 46 | #if LONG_MAX > 2147483647 |
| 47 | typedef unsigned long uint64; |
| 48 | typedef signed long int64; |
| 49 | |
| 50 | #elif __GNUC__ |
| 51 | typedef unsigned long long uint64; |
| 52 | typedef signed long long int64; |
| 53 | |
| 54 | #else |
| 55 | #error "Can't find an appropriate 64-bit type" |
| 56 | #endif |
| 57 | |
| 58 | /* FIXME: D10V defines */ |
| 59 | typedef uint16 reg_t; |
| 60 | |
| 61 | struct simops |
| 62 | { |
| 63 | long opcode; |
| 64 | long mask; |
| 65 | int format; |
| 66 | int cycles; |
| 67 | int unit; |
| 68 | int exec_type; |
| 69 | void (*func)(); |
| 70 | int numops; |
| 71 | int operands[9]; |
| 72 | }; |
| 73 | |
| 74 | enum _ins_type |
| 75 | { |
| 76 | INS_UNKNOWN, |
| 77 | INS_LEFT, |
| 78 | INS_RIGHT, |
| 79 | INS_LEFT_PARALLEL, |
| 80 | INS_RIGHT_PARALLEL, |
| 81 | INS_LONG, |
| 82 | INS_MAX |
| 83 | }; |
| 84 | |
| 85 | extern long ins_type_counters[ (int)INS_MAX ]; |
| 86 | extern long left_nops, right_nops; |
| 87 | |
| 88 | struct _state |
| 89 | { |
| 90 | reg_t regs[16]; /* general-purpose registers */ |
| 91 | reg_t cregs[16]; /* control registers */ |
| 92 | int64 a[2]; /* accumulators */ |
| 93 | uint8 SM; |
| 94 | uint8 EA; |
| 95 | uint8 DB; |
| 96 | uint8 IE; |
| 97 | uint8 RP; |
| 98 | uint8 MD; |
| 99 | uint8 FX; |
| 100 | uint8 ST; |
| 101 | uint8 F0; |
| 102 | uint8 F1; |
| 103 | uint8 C; |
| 104 | uint8 exe; |
| 105 | uint8 *imem; |
| 106 | uint8 *dmem; |
| 107 | uint32 mem_min; |
| 108 | uint32 mem_max; |
| 109 | int exception; |
| 110 | enum _ins_type ins_type; |
| 111 | } State; |
| 112 | |
| 113 | extern host_callback *d10v_callback; |
| 114 | extern uint16 OP[4]; |
| 115 | extern struct simops Simops[]; |
| 116 | |
| 117 | #define PC (State.cregs[2]) |
| 118 | #define PSW (State.cregs[0]) |
| 119 | #define BPSW (State.cregs[1]) |
| 120 | #define BPC (State.cregs[3]) |
| 121 | #define RPT_C (State.cregs[7]) |
| 122 | #define RPT_S (State.cregs[8]) |
| 123 | #define RPT_E (State.cregs[9]) |
| 124 | #define MOD_S (State.cregs[10]) |
| 125 | #define MOD_E (State.cregs[11]) |
| 126 | #define IBA (State.cregs[14]) |
| 127 | |
| 128 | #define SIG_D10V_STOP -1 |
| 129 | #define SIG_D10V_EXIT -2 |
| 130 | |
| 131 | #define SEXT3(x) ((((x)&0x7)^(~3))+4) |
| 132 | |
| 133 | /* sign-extend a 4-bit number */ |
| 134 | #define SEXT4(x) ((((x)&0xf)^(~7))+8) |
| 135 | |
| 136 | /* sign-extend an 8-bit number */ |
| 137 | #define SEXT8(x) ((((x)&0xff)^(~0x7f))+0x80) |
| 138 | |
| 139 | /* sign-extend a 16-bit number */ |
| 140 | #define SEXT16(x) ((((x)&0xffff)^(~0x7fff))+0x8000) |
| 141 | |
| 142 | /* sign-extend a 32-bit number */ |
| 143 | #define SEXT32(x) ((((x)&0xffffffffLL)^(~0x7fffffffLL))+0x80000000LL) |
| 144 | |
| 145 | /* sign extend a 40 bit number */ |
| 146 | #define SEXT40(x) ((((x)&0xffffffffffLL)^(~0x7fffffffffLL))+0x8000000000LL) |
| 147 | |
| 148 | /* sign extend a 44 bit number */ |
| 149 | #define SEXT44(x) ((((x)&0xfffffffffffLL)^(~0x7ffffffffffLL))+0x80000000000LL) |
| 150 | |
| 151 | /* sign extend a 60 bit number */ |
| 152 | #define SEXT60(x) ((((x)&0xfffffffffffffffLL)^(~0x7ffffffffffffffLL))+0x800000000000000LL) |
| 153 | |
| 154 | #define MAX32 0x7fffffffLL |
| 155 | #define MIN32 0xff80000000LL |
| 156 | #define MASK32 0xffffffffLL |
| 157 | #define MASK40 0xffffffffffLL |
| 158 | |
| 159 | #define INC_ADDR(x,i) x = ((State.MD && x == MOD_E) ? MOD_S : (x)+(i)) |
| 160 | |
| 161 | #define RB(x) (*((uint8 *)((x)+State.imem))) |
| 162 | #define SB(addr,data) ( RB(addr) = (data & 0xff)) |
| 163 | |
| 164 | #if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE) |
| 165 | #define ENDIAN_INLINE static __inline__ |
| 166 | #include "endian.c" |
| 167 | #undef ENDIAN_INLINE |
| 168 | |
| 169 | #else |
| 170 | uint32 get_longword PARAMS ((uint8 *)); |
| 171 | uint16 get_word PARAMS ((uint8 *)); |
| 172 | int64 get_longlong PARAMS ((uint8 *)); |
| 173 | void write_word PARAMS ((uint8 *addr, uint16 data)); |
| 174 | void write_longword PARAMS ((uint8 *addr, uint32 data)); |
| 175 | void write_longlong PARAMS ((uint8 *addr, int64 data)); |
| 176 | #endif |
| 177 | |
| 178 | #define SW(addr,data) write_word((long)(addr)+State.imem,data) |
| 179 | #define RW(x) get_word((long)(x)+State.imem) |
| 180 | #define SLW(addr,data) write_longword((long)(addr)+State.imem,data) |
| 181 | #define RLW(x) get_longword((long)(x)+State.imem) |
| 182 | #define READ_16(x) get_word(x) |
| 183 | #define WRITE_16(addr,data) write_word(addr,data) |
| 184 | #define READ_64(x) get_longlong(x) |
| 185 | #define WRITE_64(addr,data) write_longlong(addr,data) |