| 1 | /* MIPS Simulator definition. |
| 2 | Copyright (C) 1997 Free Software Foundation, Inc. |
| 3 | Contributed by Cygnus Support. |
| 4 | |
| 5 | This file is part of GDB, the GNU debugger. |
| 6 | |
| 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation; either version 2, or (at your option) |
| 10 | any later version. |
| 11 | |
| 12 | This program is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License along |
| 18 | with this program; if not, write to the Free Software Foundation, Inc., |
| 19 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
| 20 | |
| 21 | #ifndef SIM_MAIN_H |
| 22 | #define SIM_MAIN_H |
| 23 | |
| 24 | /* This simulator doesn't cache the Current Instruction Address */ |
| 25 | /* #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) */ |
| 26 | /* #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) */ |
| 27 | |
| 28 | #define SIM_HAVE_BIENDIAN |
| 29 | |
| 30 | |
| 31 | /* hobble some common features for moment */ |
| 32 | #define WITH_WATCHPOINTS 1 |
| 33 | #define WITH_MODULO_MEMORY 1 |
| 34 | |
| 35 | #include "sim-basics.h" |
| 36 | |
| 37 | typedef address_word sim_cia; |
| 38 | |
| 39 | #if (WITH_IGEN) |
| 40 | /* Get the number of instructions. FIXME: must be a more elegant way |
| 41 | of doing this. */ |
| 42 | #include "itable.h" |
| 43 | #define MAX_INSNS (nr_itable_entries) |
| 44 | #define INSN_NAME(i) itable[(i)].name |
| 45 | #endif |
| 46 | |
| 47 | #include "sim-base.h" |
| 48 | |
| 49 | |
| 50 | /* Depreciated macros and types for manipulating 64bit values. Use |
| 51 | ../common/sim-bits.h and ../common/sim-endian.h macros instead. */ |
| 52 | |
| 53 | typedef signed64 word64; |
| 54 | typedef unsigned64 uword64; |
| 55 | |
| 56 | #define WORD64LO(t) (unsigned int)((t)&0xFFFFFFFF) |
| 57 | #define WORD64HI(t) (unsigned int)(((uword64)(t))>>32) |
| 58 | #define SET64LO(t) (((uword64)(t))&0xFFFFFFFF) |
| 59 | #define SET64HI(t) (((uword64)(t))<<32) |
| 60 | #define WORD64(h,l) ((word64)((SET64HI(h)|SET64LO(l)))) |
| 61 | #define UWORD64(h,l) (SET64HI(h)|SET64LO(l)) |
| 62 | |
| 63 | /* Sign-extend the given value (e) as a value (b) bits long. We cannot |
| 64 | assume the HI32bits of the operand are zero, so we must perform a |
| 65 | mask to ensure we can use the simple subtraction to sign-extend. */ |
| 66 | #define SIGNEXTEND(e,b) \ |
| 67 | ((unsigned_word) \ |
| 68 | (((e) & ((uword64) 1 << ((b) - 1))) \ |
| 69 | ? (((e) & (((uword64) 1 << (b)) - 1)) - ((uword64)1 << (b))) \ |
| 70 | : ((e) & (((((uword64) 1 << ((b) - 1)) - 1) << 1) | 1)))) |
| 71 | |
| 72 | /* Check if a value will fit within a halfword: */ |
| 73 | #define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1)) |
| 74 | |
| 75 | |
| 76 | |
| 77 | /* Floating-point operations: */ |
| 78 | |
| 79 | #include "sim-fpu.h" |
| 80 | |
| 81 | /* FPU registers must be one of the following types. All other values |
| 82 | are reserved (and undefined). */ |
| 83 | typedef enum { |
| 84 | fmt_single = 0, |
| 85 | fmt_double = 1, |
| 86 | fmt_word = 4, |
| 87 | fmt_long = 5, |
| 88 | /* The following are well outside the normal acceptable format |
| 89 | range, and are used in the register status vector. */ |
| 90 | fmt_unknown = 0x10000000, |
| 91 | fmt_uninterpreted = 0x20000000, |
| 92 | fmt_uninterpreted_32 = 0x40000000, |
| 93 | fmt_uninterpreted_64 = 0x80000000, |
| 94 | } FP_formats; |
| 95 | |
| 96 | unsigned64 value_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats)); |
| 97 | #define ValueFPR(FPR,FMT) value_fpr (SD, CPU, cia, (FPR), (FMT)) |
| 98 | |
| 99 | void store_fpr PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int fpr, FP_formats fmt, unsigned64 value)); |
| 100 | #define StoreFPR(FPR,FMT,VALUE) store_fpr (SD, CPU, cia, (FPR), (FMT), (VALUE)) |
| 101 | |
| 102 | int NaN PARAMS ((unsigned64 op, FP_formats fmt)); |
| 103 | int Infinity PARAMS ((unsigned64 op, FP_formats fmt)); |
| 104 | int Less PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 105 | int Equal PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 106 | unsigned64 AbsoluteValue PARAMS ((unsigned64 op, FP_formats fmt)); |
| 107 | unsigned64 Negate PARAMS ((unsigned64 op, FP_formats fmt)); |
| 108 | unsigned64 Add PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 109 | unsigned64 Sub PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 110 | unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 111 | unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 112 | unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt)); |
| 113 | unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt)); |
| 114 | unsigned64 Max PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 115 | unsigned64 Min PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt)); |
| 116 | unsigned64 convert PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int rm, unsigned64 op, FP_formats from, FP_formats to)); |
| 117 | #define Convert(rm,op,from,to) \ |
| 118 | convert (SD, CPU, cia, rm, op, from, to) |
| 119 | |
| 120 | /* Macro to update FPSR condition-code field. This is complicated by |
| 121 | the fact that there is a hole in the index range of the bits within |
| 122 | the FCSR register. Also, the number of bits visible depends on the |
| 123 | MIPS ISA version being supported. */ |
| 124 | |
| 125 | #define SETFCC(cc,v) {\ |
| 126 | int bit = ((cc == 0) ? 23 : (24 + (cc)));\ |
| 127 | FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\ |
| 128 | } |
| 129 | #define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1U : 0) |
| 130 | |
| 131 | /* This should be the COC1 value at the start of the preceding |
| 132 | instruction: */ |
| 133 | #define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0) |
| 134 | |
| 135 | #if 1 |
| 136 | #define SizeFGR() (WITH_TARGET_FLOATING_POINT_BITSIZE) |
| 137 | #else |
| 138 | /* They depend on the CPU being simulated */ |
| 139 | #define SizeFGR() ((WITH_TARGET_WORD_BITSIZE == 64 && ((SR & status_FR) == 1)) ? 64 : 32) |
| 140 | #endif |
| 141 | |
| 142 | /* Standard FCRS bits: */ |
| 143 | #define IR (0) /* Inexact Result */ |
| 144 | #define UF (1) /* UnderFlow */ |
| 145 | #define OF (2) /* OverFlow */ |
| 146 | #define DZ (3) /* Division by Zero */ |
| 147 | #define IO (4) /* Invalid Operation */ |
| 148 | #define UO (5) /* Unimplemented Operation */ |
| 149 | |
| 150 | /* Get masks for individual flags: */ |
| 151 | #if 1 /* SAFE version */ |
| 152 | #define FP_FLAGS(b) (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0) |
| 153 | #define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0) |
| 154 | #define FP_CAUSE(b) (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0) |
| 155 | #else |
| 156 | #define FP_FLAGS(b) (1 << ((b) + 2)) |
| 157 | #define FP_ENABLE(b) (1 << ((b) + 7)) |
| 158 | #define FP_CAUSE(b) (1 << ((b) + 12)) |
| 159 | #endif |
| 160 | |
| 161 | #define FP_FS (1 << 24) /* MIPS III onwards : Flush to Zero */ |
| 162 | |
| 163 | #define FP_MASK_RM (0x3) |
| 164 | #define FP_SH_RM (0) |
| 165 | #define FP_RM_NEAREST (0) /* Round to nearest (Round) */ |
| 166 | #define FP_RM_TOZERO (1) /* Round to zero (Trunc) */ |
| 167 | #define FP_RM_TOPINF (2) /* Round to Plus infinity (Ceil) */ |
| 168 | #define FP_RM_TOMINF (3) /* Round to Minus infinity (Floor) */ |
| 169 | #define GETRM() (int)((FCSR >> FP_SH_RM) & FP_MASK_RM) |
| 170 | |
| 171 | |
| 172 | |
| 173 | /* Integer ALU operations: */ |
| 174 | |
| 175 | #include "sim-alu.h" |
| 176 | |
| 177 | #define ALU32_END(ANS) \ |
| 178 | if (ALU32_HAD_OVERFLOW) \ |
| 179 | SignalExceptionIntegerOverflow (); \ |
| 180 | (ANS) = ALU32_OVERFLOW_RESULT |
| 181 | |
| 182 | |
| 183 | #define ALU64_END(ANS) \ |
| 184 | if (ALU64_HAD_OVERFLOW) \ |
| 185 | SignalExceptionIntegerOverflow (); \ |
| 186 | (ANS) = ALU64_OVERFLOW_RESULT; |
| 187 | |
| 188 | |
| 189 | /* start-sanitize-r5900 */ |
| 190 | |
| 191 | /* Figure 10-5 FPU Control/Status Register. |
| 192 | Note: some of these bits are different to what is found in a |
| 193 | standard MIPS manual. */ |
| 194 | enum { |
| 195 | R5900_FCSR_C = BIT (23), /* OK */ |
| 196 | R5900_FCSR_I = BIT (17), |
| 197 | R5900_FCSR_D = BIT (16), |
| 198 | R5900_FCSR_O = BIT (15), |
| 199 | R5900_FCSR_U = BIT (14), |
| 200 | R5900_FCSR_CAUSE = MASK (16,14), |
| 201 | R5900_FCSR_SI = BIT (6), |
| 202 | R5900_FCSR_SD = BIT (5), |
| 203 | R5900_FCSR_SO = BIT (4), |
| 204 | R5900_FCSR_SU = BIT (3), |
| 205 | }; |
| 206 | |
| 207 | typedef struct _sim_r5900_cpu { |
| 208 | |
| 209 | /* The R5900 has 32 x 128bit general purpose registers. |
| 210 | Fortunatly, the high 64 bits are only touched by multimedia (MMI) |
| 211 | instructions. The normal mips instructions just use the lower 64 |
| 212 | bits. To avoid changing the older parts of the simulator to |
| 213 | handle this weirdness, the high 64 bits of each register are kept |
| 214 | in a separate array (registers1). The high 64 bits of any |
| 215 | register are by convention refered by adding a '1' to the end of |
| 216 | the normal register's name. So LO still refers to the low 64 |
| 217 | bits of the LO register, LO1 refers to the high 64 bits of that |
| 218 | same register. */ |
| 219 | signed_word gpr1[32]; |
| 220 | #define GPR1 ((CPU)->r5900.gpr1) |
| 221 | signed_word lo1; |
| 222 | signed_word hi1; |
| 223 | #define LO1 ((CPU)->r5900.lo1) |
| 224 | #define HI1 ((CPU)->r5900.hi1) |
| 225 | |
| 226 | /* The R5900 defines a shift amount register, that controls the |
| 227 | amount of certain shift instructions */ |
| 228 | unsigned_word sa; /* the shift amount register */ |
| 229 | #define REGISTER_SA (124) /* GET RID IF THIS! */ |
| 230 | #define SA ((CPU)->r5900.sa) |
| 231 | |
| 232 | /* The R5900, in addition to the (almost) standard floating point |
| 233 | registers, defines a 32 bit accumulator. This is used in |
| 234 | multiply/accumulate style instructions */ |
| 235 | fp_word acc; /* floating-point accumulator */ |
| 236 | #define ACC ((CPU)->r5900.acc) |
| 237 | |
| 238 | /* See comments below about needing to count cycles between updating |
| 239 | and setting HI/LO registers */ |
| 240 | int hi1access; |
| 241 | int lo1access; |
| 242 | #define HI1ACCESS ((CPU)->r5900.hi1access) |
| 243 | #define LO1ACCESS ((CPU)->r5900.lo1access) |
| 244 | #if 0 |
| 245 | #define CHECKHILO(s) {\ |
| 246 | if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\ |
| 247 | sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\ |
| 248 | } |
| 249 | #endif |
| 250 | |
| 251 | } sim_r5900_cpu; |
| 252 | |
| 253 | #define BYTES_IN_MMI_REGS (sizeof(signed_word) + sizeof(signed_word)) |
| 254 | #define HALFWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/2) |
| 255 | #define WORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/4) |
| 256 | #define DOUBLEWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/8) |
| 257 | |
| 258 | #define BYTES_IN_MIPS_REGS (sizeof(signed_word)) |
| 259 | #define HALFWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/2) |
| 260 | #define WORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/4) |
| 261 | #define DOUBLEWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/8) |
| 262 | |
| 263 | /* SUB_REG_FETCH - return as lvalue some sub-part of a "register" |
| 264 | T - type of the sub part |
| 265 | TC - # of T's in the mips part of the "register" |
| 266 | I - index (from 0) of desired sub part |
| 267 | A - low part of "register" |
| 268 | A1 - high part of register |
| 269 | */ |
| 270 | #define SUB_REG_FETCH(T,TC,A,A1,I) \ |
| 271 | (*(((I) < (TC) ? (T*)(A) : (T*)(A1)) \ |
| 272 | + (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN \ |
| 273 | ? ((TC) - 1 - (I) % (TC)) \ |
| 274 | : ((I) % (TC)) \ |
| 275 | ) \ |
| 276 | ) \ |
| 277 | ) |
| 278 | |
| 279 | /* |
| 280 | GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R |
| 281 | where <type> has two letters: |
| 282 | 1 is S=signed or U=unsigned |
| 283 | 2 is B=byte H=halfword W=word D=doubleword |
| 284 | */ |
| 285 | |
| 286 | #define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed8, BYTES_IN_MIPS_REGS, A, A1, I) |
| 287 | #define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed16, HALFWORDS_IN_MIPS_REGS, A, A1, I) |
| 288 | #define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed32, WORDS_IN_MIPS_REGS, A, A1, I) |
| 289 | #define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I) |
| 290 | |
| 291 | #define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned8, BYTES_IN_MIPS_REGS, A, A1, I) |
| 292 | #define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned16, HALFWORDS_IN_MIPS_REGS, A, A1, I) |
| 293 | #define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned32, WORDS_IN_MIPS_REGS, A, A1, I) |
| 294 | #define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I) |
| 295 | |
| 296 | #define GPR_SB(R,I) SUB_REG_SB(&GPR[R], &GPR1[R], I) |
| 297 | #define GPR_SH(R,I) SUB_REG_SH(&GPR[R], &GPR1[R], I) |
| 298 | #define GPR_SW(R,I) SUB_REG_SW(&GPR[R], &GPR1[R], I) |
| 299 | #define GPR_SD(R,I) SUB_REG_SD(&GPR[R], &GPR1[R], I) |
| 300 | |
| 301 | #define GPR_UB(R,I) SUB_REG_UB(&GPR[R], &GPR1[R], I) |
| 302 | #define GPR_UH(R,I) SUB_REG_UH(&GPR[R], &GPR1[R], I) |
| 303 | #define GPR_UW(R,I) SUB_REG_UW(&GPR[R], &GPR1[R], I) |
| 304 | #define GPR_UD(R,I) SUB_REG_UD(&GPR[R], &GPR1[R], I) |
| 305 | |
| 306 | |
| 307 | #define RS_SB(I) SUB_REG_SB(&rs_reg, &rs_reg1, I) |
| 308 | #define RS_SH(I) SUB_REG_SH(&rs_reg, &rs_reg1, I) |
| 309 | #define RS_SW(I) SUB_REG_SW(&rs_reg, &rs_reg1, I) |
| 310 | #define RS_SD(I) SUB_REG_SD(&rs_reg, &rs_reg1, I) |
| 311 | |
| 312 | #define RS_UB(I) SUB_REG_UB(&rs_reg, &rs_reg1, I) |
| 313 | #define RS_UH(I) SUB_REG_UH(&rs_reg, &rs_reg1, I) |
| 314 | #define RS_UW(I) SUB_REG_UW(&rs_reg, &rs_reg1, I) |
| 315 | #define RS_UD(I) SUB_REG_UD(&rs_reg, &rs_reg1, I) |
| 316 | |
| 317 | #define RT_SB(I) SUB_REG_SB(&rt_reg, &rt_reg1, I) |
| 318 | #define RT_SH(I) SUB_REG_SH(&rt_reg, &rt_reg1, I) |
| 319 | #define RT_SW(I) SUB_REG_SW(&rt_reg, &rt_reg1, I) |
| 320 | #define RT_SD(I) SUB_REG_SD(&rt_reg, &rt_reg1, I) |
| 321 | |
| 322 | #define RT_UB(I) SUB_REG_UB(&rt_reg, &rt_reg1, I) |
| 323 | #define RT_UH(I) SUB_REG_UH(&rt_reg, &rt_reg1, I) |
| 324 | #define RT_UW(I) SUB_REG_UW(&rt_reg, &rt_reg1, I) |
| 325 | #define RT_UD(I) SUB_REG_UD(&rt_reg, &rt_reg1, I) |
| 326 | |
| 327 | |
| 328 | |
| 329 | #define LO_SB(I) SUB_REG_SB(&LO, &LO1, I) |
| 330 | #define LO_SH(I) SUB_REG_SH(&LO, &LO1, I) |
| 331 | #define LO_SW(I) SUB_REG_SW(&LO, &LO1, I) |
| 332 | #define LO_SD(I) SUB_REG_SD(&LO, &LO1, I) |
| 333 | |
| 334 | #define LO_UB(I) SUB_REG_UB(&LO, &LO1, I) |
| 335 | #define LO_UH(I) SUB_REG_UH(&LO, &LO1, I) |
| 336 | #define LO_UW(I) SUB_REG_UW(&LO, &LO1, I) |
| 337 | #define LO_UD(I) SUB_REG_UD(&LO, &LO1, I) |
| 338 | |
| 339 | #define HI_SB(I) SUB_REG_SB(&HI, &HI1, I) |
| 340 | #define HI_SH(I) SUB_REG_SH(&HI, &HI1, I) |
| 341 | #define HI_SW(I) SUB_REG_SW(&HI, &HI1, I) |
| 342 | #define HI_SD(I) SUB_REG_SD(&HI, &HI1, I) |
| 343 | |
| 344 | #define HI_UB(I) SUB_REG_UB(&HI, &HI1, I) |
| 345 | #define HI_UH(I) SUB_REG_UH(&HI, &HI1, I) |
| 346 | #define HI_UW(I) SUB_REG_UW(&HI, &HI1, I) |
| 347 | #define HI_UD(I) SUB_REG_UD(&HI, &HI1, I) |
| 348 | |
| 349 | /* end-sanitize-r5900 */ |
| 350 | |
| 351 | |
| 352 | |
| 353 | /* The following is probably not used for MIPS IV onwards: */ |
| 354 | /* Slots for delayed register updates. For the moment we just have a |
| 355 | fixed number of slots (rather than a more generic, dynamic |
| 356 | system). This keeps the simulator fast. However, we only allow |
| 357 | for the register update to be delayed for a single instruction |
| 358 | cycle. */ |
| 359 | #define PSLOTS (8) /* Maximum number of instruction cycles */ |
| 360 | |
| 361 | typedef struct _pending_write_queue { |
| 362 | int in; |
| 363 | int out; |
| 364 | int total; |
| 365 | int slot_delay[PSLOTS]; |
| 366 | int slot_size[PSLOTS]; |
| 367 | int slot_bit[PSLOTS]; |
| 368 | void *slot_dest[PSLOTS]; |
| 369 | unsigned64 slot_value[PSLOTS]; |
| 370 | } pending_write_queue; |
| 371 | |
| 372 | #ifndef PENDING_TRACE |
| 373 | #define PENDING_TRACE 0 |
| 374 | #endif |
| 375 | #define PENDING_IN ((CPU)->pending.in) |
| 376 | #define PENDING_OUT ((CPU)->pending.out) |
| 377 | #define PENDING_TOTAL ((CPU)->pending.total) |
| 378 | #define PENDING_SLOT_SIZE ((CPU)->pending.slot_size) |
| 379 | #define PENDING_SLOT_BIT ((CPU)->pending.slot_size) |
| 380 | #define PENDING_SLOT_DELAY ((CPU)->pending.slot_delay) |
| 381 | #define PENDING_SLOT_DEST ((CPU)->pending.slot_dest) |
| 382 | #define PENDING_SLOT_VALUE ((CPU)->pending.slot_value) |
| 383 | |
| 384 | /* Invalidate the pending write queue, all pending writes are |
| 385 | discarded. */ |
| 386 | |
| 387 | #define PENDING_INVALIDATE() \ |
| 388 | memset (&(CPU)->pending, 0, sizeof ((CPU)->pending)) |
| 389 | |
| 390 | /* Schedule a write to DEST for N cycles time. For 64 bit |
| 391 | destinations, schedule two writes. For floating point registers, |
| 392 | the caller should schedule a write to both the dest register and |
| 393 | the FPR_STATE register. When BIT is non-negative, only BIT of DEST |
| 394 | is updated. */ |
| 395 | |
| 396 | #define PENDING_SCHED(DEST,VAL,DELAY,BIT) \ |
| 397 | do { \ |
| 398 | if (PENDING_SLOT_DEST[PENDING_IN] != NULL) \ |
| 399 | sim_engine_abort (SD, CPU, cia, \ |
| 400 | "PENDING_SCHED - buffer overflow\n"); \ |
| 401 | if (PENDING_TRACE) \ |
| 402 | sim_io_printf (SD, "PENDING_SCHED - dest 0x%lx, val 0x%lx, pending_in %d, pending_out %d, pending_total %d\n", (unsigned long) (DEST), (unsigned long) (VAL), PENDING_IN, PENDING_OUT, PENDING_TOTAL); \ |
| 403 | PENDING_SLOT_DELAY[PENDING_IN] = (DELAY) + 1; \ |
| 404 | PENDING_SLOT_DEST[PENDING_IN] = &(DEST); \ |
| 405 | PENDING_SLOT_VALUE[PENDING_IN] = (VAL); \ |
| 406 | PENDING_SLOT_SIZE[PENDING_IN] = sizeof (DEST); \ |
| 407 | PENDING_SLOT_BIT[PENDING_IN] = (BIT); \ |
| 408 | } while (0) |
| 409 | |
| 410 | #define PENDING_WRITE(DEST,VAL,DELAY) PENDING_SCHED(DEST,VAL,DELAY,-1) |
| 411 | #define PENDING_BIT(DEST,VAL,DELAY,BIT) PENDING_SCHED(DEST,VAL,DELAY,BIT) |
| 412 | |
| 413 | #define PENDING_TICK() pending_tick (SD, CPU, cia) |
| 414 | |
| 415 | #define PENDING_FLUSH() abort () /* think about this one */ |
| 416 | #define PENDING_FP() abort () /* think about this one */ |
| 417 | |
| 418 | /* For backward compatibility */ |
| 419 | #define PENDING_FILL(R,VAL) \ |
| 420 | { \ |
| 421 | if ((R) >= FGRIDX && (R) < FGRIDX + NR_FGR) \ |
| 422 | PENDING_SCHED(FGR[(R) - FGRIDX], VAL, 2, -1); \ |
| 423 | else \ |
| 424 | PENDING_SCHED(GPR[(R)], VAL, 2, -1); \ |
| 425 | } |
| 426 | |
| 427 | |
| 428 | |
| 429 | struct _sim_cpu { |
| 430 | |
| 431 | |
| 432 | /* The following are internal simulator state variables: */ |
| 433 | #define CIA_GET(CPU) ((CPU)->registers[PCIDX] + 0) |
| 434 | #define CIA_SET(CPU,CIA) ((CPU)->registers[PCIDX] = (CIA)) |
| 435 | address_word dspc; /* delay-slot PC */ |
| 436 | #define DSPC ((CPU)->dspc) |
| 437 | |
| 438 | /* Issue a delay slot instruction immediatly by re-calling |
| 439 | idecode_issue */ |
| 440 | #define DELAY_SLOT(TARGET) \ |
| 441 | do { \ |
| 442 | address_word target = (TARGET); \ |
| 443 | instruction_word delay_insn; \ |
| 444 | sim_events_slip (SD, 1); \ |
| 445 | CIA = CIA + 4; /* NOTE not mips16 */ \ |
| 446 | STATE |= simDELAYSLOT; \ |
| 447 | delay_insn = IMEM32 (CIA); /* NOTE not mips16 */ \ |
| 448 | idecode_issue (CPU_, delay_insn, (CIA)); \ |
| 449 | STATE &= ~simDELAYSLOT; \ |
| 450 | NIA = target; \ |
| 451 | } while (0) |
| 452 | #define NULLIFY_NEXT_INSTRUCTION() \ |
| 453 | do { \ |
| 454 | sim_events_slip (SD, 1); \ |
| 455 | dotrace (SD, CPU, tracefh, 2, NIA, 4, "load instruction"); \ |
| 456 | NIA = CIA + 8; \ |
| 457 | } while (0) |
| 458 | |
| 459 | |
| 460 | |
| 461 | /* State of the simulator */ |
| 462 | unsigned int state; |
| 463 | unsigned int dsstate; |
| 464 | #define STATE ((CPU)->state) |
| 465 | #define DSSTATE ((CPU)->dsstate) |
| 466 | |
| 467 | /* Flags in the "state" variable: */ |
| 468 | #define simHALTEX (1 << 2) /* 0 = run; 1 = halt on exception */ |
| 469 | #define simHALTIN (1 << 3) /* 0 = run; 1 = halt on interrupt */ |
| 470 | #define simTRACE (1 << 8) /* 0 = do nothing; 1 = trace address activity */ |
| 471 | #define simPCOC0 (1 << 17) /* COC[1] from current */ |
| 472 | #define simPCOC1 (1 << 18) /* COC[1] from previous */ |
| 473 | #define simDELAYSLOT (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */ |
| 474 | #define simSKIPNEXT (1 << 25) /* 0 = do nothing; 1 = skip instruction */ |
| 475 | #define simSIGINT (1 << 28) /* 0 = do nothing; 1 = SIGINT has occured */ |
| 476 | #define simJALDELAYSLOT (1 << 29) /* 1 = in jal delay slot */ |
| 477 | |
| 478 | #define ENGINE_ISSUE_PREFIX_HOOK() \ |
| 479 | { \ |
| 480 | /* Perform any pending writes */ \ |
| 481 | PENDING_TICK(); \ |
| 482 | /* Set previous flag, depending on current: */ \ |
| 483 | if (STATE & simPCOC0) \ |
| 484 | STATE |= simPCOC1; \ |
| 485 | else \ |
| 486 | STATE &= ~simPCOC1; \ |
| 487 | /* and update the current value: */ \ |
| 488 | if (GETFCC(0)) \ |
| 489 | STATE |= simPCOC0; \ |
| 490 | else \ |
| 491 | STATE &= ~simPCOC0; \ |
| 492 | } |
| 493 | |
| 494 | |
| 495 | /* This is nasty, since we have to rely on matching the register |
| 496 | numbers used by GDB. Unfortunately, depending on the MIPS target |
| 497 | GDB uses different register numbers. We cannot just include the |
| 498 | relevant "gdb/tm.h" link, since GDB may not be configured before |
| 499 | the sim world, and also the GDB header file requires too much other |
| 500 | state. */ |
| 501 | |
| 502 | #ifndef TM_MIPS_H |
| 503 | #define LAST_EMBED_REGNUM (89) |
| 504 | #define NUM_REGS (LAST_EMBED_REGNUM + 1) |
| 505 | /* start-sanitize-r5900 */ |
| 506 | #undef NUM_REGS |
| 507 | #define NUM_REGS (128) |
| 508 | /* end-sanitize-r5900 */ |
| 509 | #endif |
| 510 | |
| 511 | /* start-sanitize-sky */ |
| 512 | #ifdef TARGET_SKY |
| 513 | #ifndef TM_TXVU_H |
| 514 | |
| 515 | /* Number of machine registers */ |
| 516 | #define NUM_VU_REGS 152 |
| 517 | |
| 518 | #define NUM_R5900_REGS 128 |
| 519 | |
| 520 | #undef NUM_REGS |
| 521 | #define NUM_REGS (NUM_R5900_REGS + 2*(NUM_VU_REGS)) |
| 522 | #endif /* no tm-txvu.h */ |
| 523 | #endif |
| 524 | /* end-sanitize-sky */ |
| 525 | |
| 526 | /* To keep this default simulator simple, and fast, we use a direct |
| 527 | vector of registers. The internal simulator engine then uses |
| 528 | manifests to access the correct slot. */ |
| 529 | |
| 530 | unsigned_word registers[LAST_EMBED_REGNUM + 1]; |
| 531 | int register_widths[NUM_REGS]; |
| 532 | #define REGISTERS ((CPU)->registers) |
| 533 | |
| 534 | #define GPR (®ISTERS[0]) |
| 535 | #define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL)) |
| 536 | |
| 537 | /* While space is allocated for the floating point registers in the |
| 538 | main registers array, they are stored separatly. This is because |
| 539 | their size may not necessarily match the size of either the |
| 540 | general-purpose or system specific registers */ |
| 541 | #define NR_FGR (32) |
| 542 | #define FGRIDX (38) |
| 543 | fp_word fgr[NR_FGR]; |
| 544 | #define FGR ((CPU)->fgr) |
| 545 | |
| 546 | #define LO (REGISTERS[33]) |
| 547 | #define HI (REGISTERS[34]) |
| 548 | #define PCIDX 37 |
| 549 | #define PC (REGISTERS[PCIDX]) |
| 550 | #define CAUSE (REGISTERS[36]) |
| 551 | #define SRIDX (32) |
| 552 | #define SR (REGISTERS[SRIDX]) /* CPU status register */ |
| 553 | #define FCR0IDX (71) |
| 554 | #define FCR0 (REGISTERS[FCR0IDX]) /* really a 32bit register */ |
| 555 | #define FCR31IDX (70) |
| 556 | #define FCR31 (REGISTERS[FCR31IDX]) /* really a 32bit register */ |
| 557 | #define FCSR (FCR31) |
| 558 | #define Debug (REGISTERS[86]) |
| 559 | #define DEPC (REGISTERS[87]) |
| 560 | #define EPC (REGISTERS[88]) |
| 561 | #define COCIDX (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */ |
| 562 | |
| 563 | unsigned_word c0_config_reg; |
| 564 | #define C0_CONFIG ((CPU)->c0_config_reg) |
| 565 | |
| 566 | /* The following are pseudonyms for standard registers */ |
| 567 | #define ZERO (REGISTERS[0]) |
| 568 | #define V0 (REGISTERS[2]) |
| 569 | #define A0 (REGISTERS[4]) |
| 570 | #define A1 (REGISTERS[5]) |
| 571 | #define A2 (REGISTERS[6]) |
| 572 | #define A3 (REGISTERS[7]) |
| 573 | #define SP (REGISTERS[29]) |
| 574 | #define RA (REGISTERS[31]) |
| 575 | |
| 576 | /* Keep the current format state for each register: */ |
| 577 | FP_formats fpr_state[32]; |
| 578 | #define FPR_STATE ((CPU)->fpr_state) |
| 579 | |
| 580 | pending_write_queue pending; |
| 581 | |
| 582 | /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic |
| 583 | read-write instructions. It is set when a linked load occurs. It |
| 584 | is tested and cleared by the conditional store. It is cleared |
| 585 | (during other CPU operations) when a store to the location would |
| 586 | no longer be atomic. In particular, it is cleared by exception |
| 587 | return instructions. */ |
| 588 | int llbit; |
| 589 | #define LLBIT ((CPU)->llbit) |
| 590 | |
| 591 | |
| 592 | /* The HIACCESS and LOACCESS counts are used to ensure that |
| 593 | corruptions caused by using the HI or LO register to close to a |
| 594 | following operation are spotted. */ |
| 595 | |
| 596 | int hiaccess; |
| 597 | int loaccess; |
| 598 | #define HIACCESS ((CPU)->hiaccess) |
| 599 | #define LOACCESS ((CPU)->loaccess) |
| 600 | |
| 601 | #if 0 |
| 602 | unsigned_word HLPC; |
| 603 | /* If either of the preceding two instructions have accessed the HI |
| 604 | or LO registers, then the values they see should be |
| 605 | undefined. However, to keep the simulator world simple, we just |
| 606 | let them use the value read and raise a warning to notify the |
| 607 | user: */ |
| 608 | #define CHECKHILO(s) {\ |
| 609 | if ((HIACCESS != 0) || (LOACCESS != 0)) \ |
| 610 | sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\ |
| 611 | } |
| 612 | #endif |
| 613 | |
| 614 | #if !defined CHECKHILO |
| 615 | /* The 4300 and a few other processors have interlocks on hi/lo |
| 616 | register reads, and hence do not have this problem. To avoid |
| 617 | spurious warnings, we just disable this always. */ |
| 618 | #define CHECKHILO(s) |
| 619 | #endif |
| 620 | |
| 621 | /* start-sanitize-r5900 */ |
| 622 | sim_r5900_cpu r5900; |
| 623 | |
| 624 | /* end-sanitize-r5900 */ |
| 625 | /* start-sanitize-vr5400 */ |
| 626 | |
| 627 | /* The MDMX ISA has a very very large accumulator */ |
| 628 | unsigned8 acc[3 * 8]; |
| 629 | /* end-sanitize-vr5400 */ |
| 630 | |
| 631 | sim_cpu_base base; |
| 632 | }; |
| 633 | |
| 634 | |
| 635 | /* MIPS specific simulator watch config */ |
| 636 | |
| 637 | void watch_options_install PARAMS ((SIM_DESC sd)); |
| 638 | |
| 639 | struct swatch { |
| 640 | sim_event *pc; |
| 641 | sim_event *clock; |
| 642 | sim_event *cycles; |
| 643 | }; |
| 644 | |
| 645 | |
| 646 | /* FIXME: At present much of the simulator is still static */ |
| 647 | struct sim_state { |
| 648 | |
| 649 | struct swatch watch; |
| 650 | |
| 651 | sim_cpu cpu[MAX_NR_PROCESSORS]; |
| 652 | #if (WITH_SMP) |
| 653 | #define STATE_CPU(sd,n) (&(sd)->cpu[n]) |
| 654 | #else |
| 655 | #define STATE_CPU(sd,n) (&(sd)->cpu[0]) |
| 656 | #endif |
| 657 | |
| 658 | sim_state_base base; |
| 659 | }; |
| 660 | |
| 661 | |
| 662 | |
| 663 | /* Status information: */ |
| 664 | |
| 665 | /* TODO : these should be the bitmasks for these bits within the |
| 666 | status register. At the moment the following are VR4300 |
| 667 | bit-positions: */ |
| 668 | #define status_KSU_mask (0x3) /* mask for KSU bits */ |
| 669 | #define status_KSU_shift (3) /* shift for field */ |
| 670 | #define ksu_kernel (0x0) |
| 671 | #define ksu_supervisor (0x1) |
| 672 | #define ksu_user (0x2) |
| 673 | #define ksu_unknown (0x3) |
| 674 | |
| 675 | #define status_IE (1 << 0) /* Interrupt enable */ |
| 676 | #define status_EXL (1 << 1) /* Exception level */ |
| 677 | #define status_RE (1 << 25) /* Reverse Endian in user mode */ |
| 678 | #define status_FR (1 << 26) /* enables MIPS III additional FP registers */ |
| 679 | #define status_SR (1 << 20) /* soft reset or NMI */ |
| 680 | #define status_BEV (1 << 22) /* Location of general exception vectors */ |
| 681 | #define status_TS (1 << 21) /* TLB shutdown has occurred */ |
| 682 | #define status_ERL (1 << 2) /* Error level */ |
| 683 | #define status_RP (1 << 27) /* Reduced Power mode */ |
| 684 | |
| 685 | #define cause_BD ((unsigned)1 << 31) /* Exception in branch delay slot */ |
| 686 | |
| 687 | /* NOTE: We keep the following status flags as bit values (1 for true, |
| 688 | 0 for false). This allows them to be used in binary boolean |
| 689 | operations without worrying about what exactly the non-zero true |
| 690 | value is. */ |
| 691 | |
| 692 | /* UserMode */ |
| 693 | #define UserMode ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0) |
| 694 | |
| 695 | /* BigEndianMem */ |
| 696 | /* Hardware configuration. Affects endianness of LoadMemory and |
| 697 | StoreMemory and the endianness of Kernel and Supervisor mode |
| 698 | execution. The value is 0 for little-endian; 1 for big-endian. */ |
| 699 | #define BigEndianMem (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN) |
| 700 | /*(state & simBE) ? 1 : 0)*/ |
| 701 | |
| 702 | /* ReverseEndian */ |
| 703 | /* This mode is selected if in User mode with the RE bit being set in |
| 704 | SR (Status Register). It reverses the endianness of load and store |
| 705 | instructions. */ |
| 706 | #define ReverseEndian (((SR & status_RE) && UserMode) ? 1 : 0) |
| 707 | |
| 708 | /* BigEndianCPU */ |
| 709 | /* The endianness for load and store instructions (0=little;1=big). In |
| 710 | User mode this endianness may be switched by setting the state_RE |
| 711 | bit in the SR register. Thus, BigEndianCPU may be computed as |
| 712 | (BigEndianMem EOR ReverseEndian). */ |
| 713 | #define BigEndianCPU (BigEndianMem ^ ReverseEndian) /* Already bits */ |
| 714 | |
| 715 | |
| 716 | |
| 717 | /* Exceptions: */ |
| 718 | |
| 719 | /* NOTE: These numbers depend on the processor architecture being |
| 720 | simulated: */ |
| 721 | #define Interrupt (0) |
| 722 | #define TLBModification (1) |
| 723 | #define TLBLoad (2) |
| 724 | #define TLBStore (3) |
| 725 | #define AddressLoad (4) |
| 726 | #define AddressStore (5) |
| 727 | #define InstructionFetch (6) |
| 728 | #define DataReference (7) |
| 729 | #define SystemCall (8) |
| 730 | #define BreakPoint (9) |
| 731 | #define ReservedInstruction (10) |
| 732 | #define CoProcessorUnusable (11) |
| 733 | #define IntegerOverflow (12) /* Arithmetic overflow (IDT monitor raises SIGFPE) */ |
| 734 | #define Trap (13) |
| 735 | #define FPE (15) |
| 736 | #define DebugBreakPoint (16) |
| 737 | #define Watch (23) |
| 738 | |
| 739 | /* The following exception code is actually private to the simulator |
| 740 | world. It is *NOT* a processor feature, and is used to signal |
| 741 | run-time errors in the simulator. */ |
| 742 | #define SimulatorFault (0xFFFFFFFF) |
| 743 | |
| 744 | void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...); |
| 745 | #define SignalException(exc,instruction) signal_exception (SD, CPU, cia, (exc), (instruction)) |
| 746 | #define SignalExceptionInterrupt() signal_exception (SD, CPU, NULL_CIA, Interrupt) |
| 747 | #define SignalExceptionInstructionFetch() signal_exception (SD, CPU, cia, InstructionFetch) |
| 748 | #define SignalExceptionAddressStore() signal_exception (SD, CPU, cia, AddressStore) |
| 749 | #define SignalExceptionAddressLoad() signal_exception (SD, CPU, cia, AddressLoad) |
| 750 | #define SignalExceptionSimulatorFault(buf) signal_exception (SD, CPU, cia, SimulatorFault, buf) |
| 751 | #define SignalExceptionFPE() signal_exception (SD, CPU, cia, FPE) |
| 752 | #define SignalExceptionIntegerOverflow() signal_exception (SD, CPU, cia, IntegerOverflow) |
| 753 | #define SignalExceptionCoProcessorUnusable() signal_exception (SD, CPU, cia, CoProcessorUnusable) |
| 754 | |
| 755 | |
| 756 | /* Co-processor accesses */ |
| 757 | |
| 758 | void cop_lw PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, unsigned int memword)); |
| 759 | void cop_ld PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg, uword64 memword)); |
| 760 | unsigned int cop_sw PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg)); |
| 761 | uword64 cop_sd PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int coproc_num, int coproc_reg)); |
| 762 | |
| 763 | #define COP_LW(coproc_num,coproc_reg,memword) \ |
| 764 | cop_lw (SD, CPU, cia, coproc_num, coproc_reg, memword) |
| 765 | #define COP_LD(coproc_num,coproc_reg,memword) \ |
| 766 | cop_ld (SD, CPU, cia, coproc_num, coproc_reg, memword) |
| 767 | #define COP_SW(coproc_num,coproc_reg) \ |
| 768 | cop_sw (SD, CPU, cia, coproc_num, coproc_reg) |
| 769 | #define COP_SD(coproc_num,coproc_reg) \ |
| 770 | cop_sd (SD, CPU, cia, coproc_num, coproc_reg) |
| 771 | |
| 772 | void decode_coproc PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, unsigned int instruction)); |
| 773 | #define DecodeCoproc(instruction) \ |
| 774 | decode_coproc (SD, CPU, cia, (instruction)) |
| 775 | |
| 776 | |
| 777 | |
| 778 | /* Memory accesses */ |
| 779 | |
| 780 | /* The following are generic to all versions of the MIPS architecture |
| 781 | to date: */ |
| 782 | |
| 783 | /* Memory Access Types (for CCA): */ |
| 784 | #define Uncached (0) |
| 785 | #define CachedNoncoherent (1) |
| 786 | #define CachedCoherent (2) |
| 787 | #define Cached (3) |
| 788 | |
| 789 | #define isINSTRUCTION (1 == 0) /* FALSE */ |
| 790 | #define isDATA (1 == 1) /* TRUE */ |
| 791 | #define isLOAD (1 == 0) /* FALSE */ |
| 792 | #define isSTORE (1 == 1) /* TRUE */ |
| 793 | #define isREAL (1 == 0) /* FALSE */ |
| 794 | #define isRAW (1 == 1) /* TRUE */ |
| 795 | /* The parameter HOST (isTARGET / isHOST) is ignored */ |
| 796 | #define isTARGET (1 == 0) /* FALSE */ |
| 797 | /* #define isHOST (1 == 1) TRUE */ |
| 798 | |
| 799 | /* The "AccessLength" specifications for Loads and Stores. NOTE: This |
| 800 | is the number of bytes minus 1. */ |
| 801 | #define AccessLength_BYTE (0) |
| 802 | #define AccessLength_HALFWORD (1) |
| 803 | #define AccessLength_TRIPLEBYTE (2) |
| 804 | #define AccessLength_WORD (3) |
| 805 | #define AccessLength_QUINTIBYTE (4) |
| 806 | #define AccessLength_SEXTIBYTE (5) |
| 807 | #define AccessLength_SEPTIBYTE (6) |
| 808 | #define AccessLength_DOUBLEWORD (7) |
| 809 | #define AccessLength_QUADWORD (15) |
| 810 | |
| 811 | int address_translation PARAMS ((SIM_DESC sd, sim_cpu *, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw)); |
| 812 | #define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \ |
| 813 | address_translation (SD, CPU, cia, vAddr, IorD, LorS, pAddr, CCA, raw) |
| 814 | |
| 815 | void load_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD)); |
| 816 | #define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \ |
| 817 | load_memory (SD, CPU, cia, memvalp, memval1p, CCA, AccessLength, pAddr, vAddr, IorD) |
| 818 | |
| 819 | void store_memory PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr)); |
| 820 | #define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \ |
| 821 | store_memory (SD, CPU, cia, CCA, AccessLength, MemElem, MemElem1, pAddr, vAddr) |
| 822 | |
| 823 | void cache_op PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction)); |
| 824 | #define CacheOp(op,pAddr,vAddr,instruction) \ |
| 825 | cache_op (SD, CPU, cia, op, pAddr, vAddr, instruction) |
| 826 | |
| 827 | void sync_operation PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int stype)); |
| 828 | #define SyncOperation(stype) \ |
| 829 | sync_operation (SD, CPU, cia, (stype)) |
| 830 | |
| 831 | void prefetch PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint)); |
| 832 | #define Prefetch(CCA,pAddr,vAddr,DATA,hint) \ |
| 833 | prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint) |
| 834 | |
| 835 | unsigned32 ifetch32 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr)); |
| 836 | #define IMEM32(CIA) ifetch32 (SD, CPU, (CIA), (CIA)) |
| 837 | unsigned16 ifetch16 PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia, address_word vaddr)); |
| 838 | #define IMEM16(CIA,NR) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1) + 2 * (NR)) |
| 839 | #define IMEM16_IMMED(CIA,NR) ifetch16 (SD, CPU, (CIA), ((CIA) & ~1) + 2 * (NR)) |
| 840 | |
| 841 | void dotrace PARAMS ((SIM_DESC sd, sim_cpu *cpu, FILE *tracefh, int type, SIM_ADDR address, int width, char *comment, ...)); |
| 842 | FILE *tracefh; |
| 843 | |
| 844 | void pending_tick PARAMS ((SIM_DESC sd, sim_cpu *cpu, address_word cia)); |
| 845 | |
| 846 | #endif |