1 1.1 christos /* 2 1.1 christos * Simulator for the Renesas (formerly Hitachi) H8/300 architecture. 3 1.1 christos * 4 1.1 christos * Written by Steve Chamberlain of Cygnus Support. sac (at) cygnus.com 5 1.1 christos * 6 1.1 christos * This file is part of H8/300 sim 7 1.1 christos * 8 1.1 christos * 9 1.1 christos * THIS SOFTWARE IS NOT COPYRIGHTED 10 1.1 christos * 11 1.1 christos * Cygnus offers the following for use in the public domain. Cygnus makes no 12 1.1 christos * warranty with regard to the software or its performance and the user 13 1.1 christos * accepts the software "AS IS" with all faults. 14 1.1 christos * 15 1.1 christos * CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS 16 1.1 christos * SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY 17 1.1 christos * AND FITNESS FOR A PARTICULAR PURPOSE. 18 1.1 christos */ 19 1.1 christos 20 1.7 christos /* This must come before any other includes. */ 21 1.7 christos #include "defs.h" 22 1.7 christos 23 1.1 christos #include <signal.h> 24 1.1 christos #include <time.h> 25 1.1 christos #include <stdlib.h> 26 1.1 christos #ifdef HAVE_SYS_PARAM_H 27 1.1 christos #include <sys/param.h> 28 1.1 christos #endif 29 1.8 christos #include <sys/stat.h> 30 1.1 christos 31 1.1 christos #include "bfd.h" 32 1.1 christos #include "sim-main.h" 33 1.8 christos #include "sim/sim-h8300.h" 34 1.1 christos #include "sys/types.h" 35 1.5 christos #include "sim-options.h" 36 1.7 christos #include "sim-signal.h" 37 1.7 christos #include "sim/callback.h" 38 1.1 christos 39 1.8 christos #include "h8300-sim.h" 40 1.8 christos 41 1.1 christos #ifndef SIGTRAP 42 1.1 christos # define SIGTRAP 5 43 1.1 christos #endif 44 1.1 christos 45 1.1 christos int debug; 46 1.1 christos 47 1.8 christos /* Each entry in this array is an index into the main opcode 48 1.8 christos array for the first instruction starting with the given 49 1.8 christos 4 bit nibble. */ 50 1.8 christos static int nib_indices[16]; 51 1.8 christos 52 1.7 christos static int memory_size; 53 1.1 christos 54 1.1 christos #define X(op, size) (op * 4 + size) 55 1.1 christos 56 1.1 christos #define SP (h8300hmode && !h8300_normal_mode ? SL : SW) 57 1.1 christos 58 1.1 christos #define h8_opcodes ops 59 1.1 christos #define DEFINE_TABLE 60 1.1 christos #include "opcode/h8300.h" 61 1.1 christos 62 1.1 christos /* CPU data object: */ 63 1.1 christos 64 1.1 christos static unsigned int 65 1.7 christos h8_get_reg (sim_cpu *cpu, int regnum) 66 1.1 christos { 67 1.8 christos return H8300_SIM_CPU (cpu)->regs[regnum]; 68 1.1 christos } 69 1.1 christos 70 1.1 christos static void 71 1.7 christos h8_set_reg (sim_cpu *cpu, int regnum, int val) 72 1.1 christos { 73 1.8 christos H8300_SIM_CPU (cpu)->regs[regnum] = val; 74 1.1 christos } 75 1.1 christos 76 1.7 christos #define h8_get_ccr(cpu) h8_get_reg (cpu, CCR_REGNUM) 77 1.7 christos #define h8_set_ccr(cpu, val) h8_set_reg (cpu, CCR_REGNUM, val) 78 1.7 christos #define h8_get_exr(cpu) h8_get_reg (cpu, EXR_REGNUM) 79 1.7 christos #define h8_set_exr(cpu, val) h8_set_reg (cpu, EXR_REGNUM, val) 80 1.7 christos #define h8_get_sbr(cpu) h8_get_reg (cpu, SBR_REGNUM) 81 1.7 christos #define h8_set_sbr(cpu, val) h8_set_reg (cpu, SBR_REGNUM, val) 82 1.7 christos #define h8_get_vbr(cpu) h8_get_reg (cpu, VBR_REGNUM) 83 1.7 christos #define h8_set_vbr(cpu, val) h8_set_reg (cpu, VBR_REGNUM, val) 84 1.7 christos #define h8_get_cycles(cpu) h8_get_reg (cpu, CYCLE_REGNUM) 85 1.7 christos #define h8_set_cycles(cpu, val) h8_set_reg (cpu, CYCLE_REGNUM, val) 86 1.7 christos #define h8_get_insts(cpu) h8_get_reg (cpu, INST_REGNUM) 87 1.7 christos #define h8_set_insts(cpu, val) h8_set_reg (cpu, INST_REGNUM, val) 88 1.7 christos #define h8_get_ticks(cpu) h8_get_reg (cpu, TICK_REGNUM) 89 1.7 christos #define h8_set_ticks(cpu, val) h8_set_reg (cpu, TICK_REGNUM, val) 90 1.7 christos #define h8_get_mach(cpu) h8_get_reg (cpu, MACH_REGNUM) 91 1.7 christos #define h8_set_mach(cpu, val) h8_set_reg (cpu, MACH_REGNUM, val) 92 1.7 christos #define h8_get_macl(cpu) h8_get_reg (cpu, MACL_REGNUM) 93 1.7 christos #define h8_set_macl(cpu, val) h8_set_reg (cpu, MACL_REGNUM, val) 94 1.1 christos 95 1.1 christos static int 96 1.7 christos h8_get_mask (sim_cpu *cpu) 97 1.1 christos { 98 1.8 christos return H8300_SIM_CPU (cpu)->mask; 99 1.1 christos } 100 1.1 christos 101 1.1 christos static void 102 1.7 christos h8_set_mask (sim_cpu *cpu, int val) 103 1.1 christos { 104 1.8 christos H8300_SIM_CPU (cpu)->mask = val; 105 1.1 christos } 106 1.1 christos #if 0 107 1.1 christos static int 108 1.7 christos h8_get_exception (sim_cpu *cpu) 109 1.1 christos { 110 1.8 christos return H8300_SIM_CPU (cpu)->exception; 111 1.1 christos } 112 1.1 christos 113 1.1 christos static void 114 1.7 christos h8_set_exception (sim_cpu *cpu, int val) 115 1.1 christos { 116 1.8 christos H8300_SIM_CPU (cpu)->exception = val; 117 1.1 christos } 118 1.1 christos 119 1.1 christos static enum h8300_sim_state 120 1.1 christos h8_get_state (SIM_DESC sd) 121 1.1 christos { 122 1.7 christos return H8300_SIM_STATE (sd)->state; 123 1.1 christos } 124 1.1 christos 125 1.1 christos static void 126 1.1 christos h8_set_state (SIM_DESC sd, enum h8300_sim_state val) 127 1.1 christos { 128 1.7 christos H8300_SIM_STATE (sd)->state = val; 129 1.1 christos } 130 1.1 christos #endif 131 1.1 christos 132 1.1 christos static unsigned int * 133 1.7 christos h8_get_reg_buf (sim_cpu *cpu) 134 1.1 christos { 135 1.8 christos return &H8300_SIM_CPU (cpu)->regs[0]; 136 1.1 christos } 137 1.1 christos 138 1.1 christos #ifdef ADEBUG 139 1.1 christos static int 140 1.1 christos h8_get_stats (SIM_DESC sd, int idx) 141 1.1 christos { 142 1.7 christos return H8300_SIM_STATE (sd)->stats[idx]; 143 1.1 christos } 144 1.1 christos 145 1.1 christos static void 146 1.1 christos h8_increment_stats (SIM_DESC sd, int idx) 147 1.1 christos { 148 1.7 christos H8300_SIM_STATE (sd)->stats[idx] ++; 149 1.1 christos } 150 1.1 christos #endif /* ADEBUG */ 151 1.1 christos 152 1.1 christos static unsigned char * 153 1.7 christos h8_get_memory_buf (sim_cpu *cpu) 154 1.1 christos { 155 1.8 christos return H8300_SIM_CPU (cpu)->memory; 156 1.1 christos } 157 1.1 christos 158 1.1 christos static void 159 1.7 christos h8_set_memory_buf (sim_cpu *cpu, unsigned char *ptr) 160 1.1 christos { 161 1.8 christos H8300_SIM_CPU (cpu)->memory = ptr; 162 1.1 christos } 163 1.1 christos 164 1.1 christos static unsigned char 165 1.7 christos h8_get_memory (sim_cpu *cpu, int idx) 166 1.1 christos { 167 1.7 christos ASSERT (idx < memory_size); 168 1.8 christos return H8300_SIM_CPU (cpu)->memory[idx]; 169 1.1 christos } 170 1.1 christos 171 1.1 christos static void 172 1.7 christos h8_set_memory (sim_cpu *cpu, int idx, unsigned int val) 173 1.1 christos { 174 1.7 christos ASSERT (idx < memory_size); 175 1.8 christos H8300_SIM_CPU (cpu)->memory[idx] = (unsigned char) val; 176 1.1 christos } 177 1.1 christos 178 1.1 christos static unsigned int 179 1.7 christos h8_get_delayed_branch (sim_cpu *cpu) 180 1.1 christos { 181 1.8 christos return H8300_SIM_CPU (cpu)->delayed_branch; 182 1.1 christos } 183 1.1 christos 184 1.1 christos static void 185 1.7 christos h8_set_delayed_branch (sim_cpu *cpu, unsigned int dest) 186 1.1 christos { 187 1.8 christos H8300_SIM_CPU (cpu)->delayed_branch = dest; 188 1.1 christos } 189 1.1 christos 190 1.1 christos static char ** 191 1.7 christos h8_get_command_line (sim_cpu *cpu) 192 1.1 christos { 193 1.8 christos return H8300_SIM_CPU (cpu)->command_line; 194 1.1 christos } 195 1.1 christos 196 1.1 christos static void 197 1.7 christos h8_set_command_line (sim_cpu *cpu, char ** val) 198 1.1 christos { 199 1.8 christos H8300_SIM_CPU (cpu)->command_line = val; 200 1.1 christos } 201 1.1 christos 202 1.1 christos static char * 203 1.7 christos h8_get_cmdline_arg (sim_cpu *cpu, int index) 204 1.1 christos { 205 1.8 christos return H8300_SIM_CPU (cpu)->command_line[index]; 206 1.1 christos } 207 1.1 christos 208 1.1 christos static void 209 1.7 christos h8_set_cmdline_arg (sim_cpu *cpu, int index, char * val) 210 1.1 christos { 211 1.8 christos H8300_SIM_CPU (cpu)->command_line[index] = val; 212 1.1 christos } 213 1.1 christos 214 1.1 christos /* MAC Saturation Mode */ 215 1.1 christos static int 216 1.7 christos h8_get_macS (sim_cpu *cpu) 217 1.1 christos { 218 1.8 christos return H8300_SIM_CPU (cpu)->macS; 219 1.1 christos } 220 1.1 christos 221 1.7 christos #if 0 222 1.1 christos static void 223 1.7 christos h8_set_macS (sim_cpu *cpu, int val) 224 1.1 christos { 225 1.8 christos H8300_SIM_CPU (cpu)->macS = (val != 0); 226 1.1 christos } 227 1.7 christos #endif 228 1.1 christos 229 1.1 christos /* MAC Zero Flag */ 230 1.1 christos static int 231 1.7 christos h8_get_macZ (sim_cpu *cpu) 232 1.1 christos { 233 1.8 christos return H8300_SIM_CPU (cpu)->macZ; 234 1.1 christos } 235 1.1 christos 236 1.1 christos static void 237 1.7 christos h8_set_macZ (sim_cpu *cpu, int val) 238 1.1 christos { 239 1.8 christos H8300_SIM_CPU (cpu)->macZ = (val != 0); 240 1.1 christos } 241 1.1 christos 242 1.1 christos /* MAC Negative Flag */ 243 1.1 christos static int 244 1.7 christos h8_get_macN (sim_cpu *cpu) 245 1.1 christos { 246 1.8 christos return H8300_SIM_CPU (cpu)->macN; 247 1.1 christos } 248 1.1 christos 249 1.1 christos static void 250 1.7 christos h8_set_macN (sim_cpu *cpu, int val) 251 1.1 christos { 252 1.8 christos H8300_SIM_CPU (cpu)->macN = (val != 0); 253 1.1 christos } 254 1.1 christos 255 1.1 christos /* MAC Overflow Flag */ 256 1.1 christos static int 257 1.7 christos h8_get_macV (sim_cpu *cpu) 258 1.1 christos { 259 1.8 christos return H8300_SIM_CPU (cpu)->macV; 260 1.1 christos } 261 1.1 christos 262 1.1 christos static void 263 1.7 christos h8_set_macV (sim_cpu *cpu, int val) 264 1.1 christos { 265 1.8 christos H8300_SIM_CPU (cpu)->macV = (val != 0); 266 1.1 christos } 267 1.1 christos 268 1.1 christos /* End CPU data object. */ 269 1.1 christos 270 1.1 christos /* The rate at which to call the host's poll_quit callback. */ 271 1.1 christos 272 1.1 christos enum { POLL_QUIT_INTERVAL = 0x80000 }; 273 1.1 christos 274 1.1 christos #define LOW_BYTE(x) ((x) & 0xff) 275 1.1 christos #define HIGH_BYTE(x) (((x) >> 8) & 0xff) 276 1.1 christos #define P(X, Y) ((X << 8) | Y) 277 1.1 christos 278 1.1 christos #define C (c != 0) 279 1.1 christos #define Z (nz == 0) 280 1.1 christos #define V (v != 0) 281 1.1 christos #define N (n != 0) 282 1.1 christos #define U (u != 0) 283 1.1 christos #define H (h != 0) 284 1.1 christos #define UI (ui != 0) 285 1.1 christos #define I (intMaskBit != 0) 286 1.1 christos 287 1.7 christos #define BUILDSR(cpu) \ 288 1.7 christos h8_set_ccr (cpu, (I << 7) | (UI << 6) | (H << 5) | (U << 4) \ 289 1.1 christos | (N << 3) | (Z << 2) | (V << 1) | C) 290 1.1 christos 291 1.7 christos #define GETSR(cpu) \ 292 1.1 christos /* Get Status Register (flags). */ \ 293 1.7 christos c = (h8_get_ccr (cpu) >> 0) & 1; \ 294 1.7 christos v = (h8_get_ccr (cpu) >> 1) & 1; \ 295 1.7 christos nz = !((h8_get_ccr (cpu) >> 2) & 1); \ 296 1.7 christos n = (h8_get_ccr (cpu) >> 3) & 1; \ 297 1.7 christos u = (h8_get_ccr (cpu) >> 4) & 1; \ 298 1.7 christos h = (h8_get_ccr (cpu) >> 5) & 1; \ 299 1.7 christos ui = ((h8_get_ccr (cpu) >> 6) & 1); \ 300 1.7 christos intMaskBit = (h8_get_ccr (cpu) >> 7) & 1 301 1.1 christos 302 1.1 christos 303 1.1 christos #ifdef __CHAR_IS_SIGNED__ 304 1.1 christos #define SEXTCHAR(x) ((char) (x)) 305 1.1 christos #endif 306 1.1 christos 307 1.1 christos #ifndef SEXTCHAR 308 1.1 christos #define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff) 309 1.1 christos #endif 310 1.1 christos 311 1.1 christos #define UEXTCHAR(x) ((x) & 0xff) 312 1.1 christos #define UEXTSHORT(x) ((x) & 0xffff) 313 1.1 christos #define SEXTSHORT(x) ((short) (x)) 314 1.1 christos 315 1.1 christos int h8300hmode = 0; 316 1.1 christos int h8300smode = 0; 317 1.1 christos int h8300_normal_mode = 0; 318 1.1 christos int h8300sxmode = 0; 319 1.1 christos 320 1.1 christos static int 321 1.1 christos get_now (void) 322 1.1 christos { 323 1.1 christos return time (0); /* WinXX HAS UNIX like 'time', so why not use it? */ 324 1.1 christos } 325 1.1 christos 326 1.1 christos static int 327 1.1 christos now_persec (void) 328 1.1 christos { 329 1.1 christos return 1; 330 1.1 christos } 331 1.1 christos 332 1.1 christos static int 333 1.1 christos bitfrom (int x) 334 1.1 christos { 335 1.1 christos switch (x & SIZE) 336 1.1 christos { 337 1.1 christos case L_8: 338 1.1 christos return SB; 339 1.1 christos case L_16: 340 1.1 christos case L_16U: 341 1.1 christos return SW; 342 1.1 christos case L_32: 343 1.1 christos return SL; 344 1.1 christos case L_P: 345 1.1 christos return (h8300hmode && !h8300_normal_mode)? SL : SW; 346 1.1 christos } 347 1.1 christos return 0; 348 1.1 christos } 349 1.1 christos 350 1.1 christos /* Simulate an indirection / dereference. 351 1.1 christos return 0 for success, -1 for failure. 352 1.1 christos */ 353 1.1 christos 354 1.1 christos static unsigned int 355 1.7 christos lvalue (SIM_DESC sd, sim_cpu *cpu, int x, int rn, unsigned int *val) 356 1.1 christos { 357 1.1 christos if (val == NULL) /* Paranoia. */ 358 1.1 christos return -1; 359 1.1 christos 360 1.1 christos switch (x / 4) 361 1.1 christos { 362 1.1 christos case OP_DISP: 363 1.1 christos if (rn == ZERO_REGNUM) 364 1.1 christos *val = X (OP_IMM, SP); 365 1.1 christos else 366 1.1 christos *val = X (OP_REG, SP); 367 1.1 christos break; 368 1.1 christos case OP_MEM: 369 1.1 christos *val = X (OP_MEM, SP); 370 1.1 christos break; 371 1.1 christos default: 372 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV); 373 1.1 christos return -1; 374 1.1 christos } 375 1.1 christos return 0; 376 1.1 christos } 377 1.1 christos 378 1.1 christos static int 379 1.7 christos cmdline_location(void) 380 1.1 christos { 381 1.1 christos if (h8300smode && !h8300_normal_mode) 382 1.1 christos return 0xffff00L; 383 1.1 christos else if (h8300hmode && !h8300_normal_mode) 384 1.1 christos return 0x2ff00L; 385 1.1 christos else 386 1.1 christos return 0xff00L; 387 1.1 christos } 388 1.1 christos 389 1.1 christos static void 390 1.7 christos decode (SIM_DESC sd, sim_cpu *cpu, int addr, unsigned char *data, decoded_inst *dst) 391 1.1 christos { 392 1.1 christos int cst[3] = {0, 0, 0}; 393 1.1 christos int reg[3] = {0, 0, 0}; 394 1.1 christos int rdisp[3] = {0, 0, 0}; 395 1.1 christos int opnum; 396 1.8 christos int index; 397 1.1 christos const struct h8_opcode *q; 398 1.1 christos 399 1.1 christos dst->dst.type = -1; 400 1.1 christos dst->src.type = -1; 401 1.7 christos dst->op3.type = -1; 402 1.1 christos 403 1.8 christos /* We speed up instruction decoding by caching an index into 404 1.8 christos the main opcode array for the first instruction with the 405 1.8 christos given 4 bit nibble. */ 406 1.8 christos index = nib_indices[(data[0] & 0xf0) >> 4]; 407 1.8 christos 408 1.8 christos /* Find the exact opcode/arg combo, starting with the precomputed 409 1.8 christos index. Note this loop is performance sensitive. */ 410 1.8 christos for (q = &h8_opcodes[index]; q->name; q++) 411 1.1 christos { 412 1.1 christos const op_type *nib = q->data.nib; 413 1.1 christos unsigned int len = 0; 414 1.1 christos 415 1.1 christos if ((q->available == AV_H8SX && !h8300sxmode) || 416 1.1 christos (q->available == AV_H8S && !h8300smode) || 417 1.1 christos (q->available == AV_H8H && !h8300hmode)) 418 1.1 christos continue; 419 1.1 christos 420 1.1 christos cst[0] = cst[1] = cst[2] = 0; 421 1.1 christos reg[0] = reg[1] = reg[2] = 0; 422 1.1 christos rdisp[0] = rdisp[1] = rdisp[2] = 0; 423 1.1 christos 424 1.1 christos while (1) 425 1.1 christos { 426 1.1 christos op_type looking_for = *nib; 427 1.1 christos int thisnib = data[len / 2]; 428 1.1 christos 429 1.1 christos thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf); 430 1.1 christos opnum = ((looking_for & OP3) ? 2 : 431 1.1 christos (looking_for & DST) ? 1 : 0); 432 1.1 christos 433 1.1 christos if (looking_for < 16 && looking_for >= 0) 434 1.1 christos { 435 1.1 christos if (looking_for != thisnib) 436 1.1 christos goto fail; 437 1.1 christos } 438 1.1 christos else 439 1.1 christos { 440 1.1 christos if (looking_for & B31) 441 1.1 christos { 442 1.1 christos if (!((thisnib & 0x8) != 0)) 443 1.1 christos goto fail; 444 1.1 christos 445 1.1 christos looking_for = (op_type) (looking_for & ~B31); 446 1.1 christos thisnib &= 0x7; 447 1.1 christos } 448 1.1 christos else if (looking_for & B30) 449 1.1 christos { 450 1.1 christos if (!((thisnib & 0x8) == 0)) 451 1.1 christos goto fail; 452 1.1 christos 453 1.1 christos looking_for = (op_type) (looking_for & ~B30); 454 1.1 christos } 455 1.1 christos 456 1.1 christos if (looking_for & B21) 457 1.1 christos { 458 1.1 christos if (!((thisnib & 0x4) != 0)) 459 1.1 christos goto fail; 460 1.1 christos 461 1.1 christos looking_for = (op_type) (looking_for & ~B21); 462 1.1 christos thisnib &= 0xb; 463 1.1 christos } 464 1.1 christos else if (looking_for & B20) 465 1.1 christos { 466 1.1 christos if (!((thisnib & 0x4) == 0)) 467 1.1 christos goto fail; 468 1.1 christos 469 1.1 christos looking_for = (op_type) (looking_for & ~B20); 470 1.1 christos } 471 1.1 christos 472 1.1 christos if (looking_for & B11) 473 1.1 christos { 474 1.1 christos if (!((thisnib & 0x2) != 0)) 475 1.1 christos goto fail; 476 1.1 christos 477 1.1 christos looking_for = (op_type) (looking_for & ~B11); 478 1.1 christos thisnib &= 0xd; 479 1.1 christos } 480 1.1 christos else if (looking_for & B10) 481 1.1 christos { 482 1.1 christos if (!((thisnib & 0x2) == 0)) 483 1.1 christos goto fail; 484 1.1 christos 485 1.1 christos looking_for = (op_type) (looking_for & ~B10); 486 1.1 christos } 487 1.1 christos 488 1.1 christos if (looking_for & B01) 489 1.1 christos { 490 1.1 christos if (!((thisnib & 0x1) != 0)) 491 1.1 christos goto fail; 492 1.1 christos 493 1.1 christos looking_for = (op_type) (looking_for & ~B01); 494 1.1 christos thisnib &= 0xe; 495 1.1 christos } 496 1.1 christos else if (looking_for & B00) 497 1.1 christos { 498 1.1 christos if (!((thisnib & 0x1) == 0)) 499 1.1 christos goto fail; 500 1.1 christos 501 1.1 christos looking_for = (op_type) (looking_for & ~B00); 502 1.1 christos } 503 1.1 christos 504 1.1 christos if (looking_for & IGNORE) 505 1.1 christos { 506 1.1 christos /* Hitachi has declared that IGNORE must be zero. */ 507 1.1 christos if (thisnib != 0) 508 1.1 christos goto fail; 509 1.1 christos } 510 1.1 christos else if ((looking_for & MODE) == DATA) 511 1.1 christos { 512 1.1 christos ; /* Skip embedded data. */ 513 1.1 christos } 514 1.1 christos else if ((looking_for & MODE) == DBIT) 515 1.1 christos { 516 1.1 christos /* Exclude adds/subs by looking at bit 0 and 2, and 517 1.1 christos make sure the operand size, either w or l, 518 1.1 christos matches by looking at bit 1. */ 519 1.1 christos if ((looking_for & 7) != (thisnib & 7)) 520 1.1 christos goto fail; 521 1.1 christos 522 1.1 christos cst[opnum] = (thisnib & 0x8) ? 2 : 1; 523 1.1 christos } 524 1.1 christos else if ((looking_for & MODE) == REG || 525 1.1 christos (looking_for & MODE) == LOWREG || 526 1.1 christos (looking_for & MODE) == IND || 527 1.1 christos (looking_for & MODE) == PREINC || 528 1.1 christos (looking_for & MODE) == POSTINC || 529 1.1 christos (looking_for & MODE) == PREDEC || 530 1.1 christos (looking_for & MODE) == POSTDEC) 531 1.1 christos { 532 1.1 christos reg[opnum] = thisnib; 533 1.1 christos } 534 1.1 christos else if (looking_for & CTRL) 535 1.1 christos { 536 1.1 christos thisnib &= 7; 537 1.1 christos if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) || 538 1.1 christos ((looking_for & MODE) == EXR && (thisnib != C_EXR)) || 539 1.1 christos ((looking_for & MODE) == MACH && (thisnib != C_MACH)) || 540 1.1 christos ((looking_for & MODE) == MACL && (thisnib != C_MACL)) || 541 1.1 christos ((looking_for & MODE) == VBR && (thisnib != C_VBR)) || 542 1.1 christos ((looking_for & MODE) == SBR && (thisnib != C_SBR))) 543 1.1 christos goto fail; 544 1.1 christos if (((looking_for & MODE) == CCR_EXR && 545 1.1 christos (thisnib != C_CCR && thisnib != C_EXR)) || 546 1.1 christos ((looking_for & MODE) == VBR_SBR && 547 1.1 christos (thisnib != C_VBR && thisnib != C_SBR)) || 548 1.1 christos ((looking_for & MODE) == MACREG && 549 1.1 christos (thisnib != C_MACH && thisnib != C_MACL))) 550 1.1 christos goto fail; 551 1.1 christos if (((looking_for & MODE) == CC_EX_VB_SB && 552 1.1 christos (thisnib != C_CCR && thisnib != C_EXR && 553 1.1 christos thisnib != C_VBR && thisnib != C_SBR))) 554 1.1 christos goto fail; 555 1.1 christos 556 1.1 christos reg[opnum] = thisnib; 557 1.1 christos } 558 1.1 christos else if ((looking_for & MODE) == ABS) 559 1.1 christos { 560 1.1 christos /* Absolute addresses are unsigned. */ 561 1.1 christos switch (looking_for & SIZE) 562 1.1 christos { 563 1.1 christos case L_8: 564 1.1 christos cst[opnum] = UEXTCHAR (data[len / 2]); 565 1.1 christos break; 566 1.1 christos case L_16: 567 1.1 christos case L_16U: 568 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; 569 1.1 christos break; 570 1.1 christos case L_32: 571 1.1 christos cst[opnum] = 572 1.1 christos (data[len / 2 + 0] << 24) + 573 1.1 christos (data[len / 2 + 1] << 16) + 574 1.1 christos (data[len / 2 + 2] << 8) + 575 1.1 christos (data[len / 2 + 3]); 576 1.1 christos break; 577 1.1 christos default: 578 1.1 christos printf ("decode: bad size ABS: %d\n", 579 1.1 christos (looking_for & SIZE)); 580 1.1 christos goto end; 581 1.1 christos } 582 1.1 christos } 583 1.1 christos else if ((looking_for & MODE) == DISP || 584 1.1 christos (looking_for & MODE) == PCREL || 585 1.1 christos (looking_for & MODE) == INDEXB || 586 1.1 christos (looking_for & MODE) == INDEXW || 587 1.1 christos (looking_for & MODE) == INDEXL) 588 1.1 christos { 589 1.1 christos switch (looking_for & SIZE) 590 1.1 christos { 591 1.1 christos case L_2: 592 1.1 christos cst[opnum] = thisnib & 3; 593 1.1 christos break; 594 1.1 christos case L_8: 595 1.1 christos cst[opnum] = SEXTCHAR (data[len / 2]); 596 1.1 christos break; 597 1.1 christos case L_16: 598 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; 599 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */ 600 1.1 christos break; 601 1.1 christos case L_16U: 602 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; 603 1.1 christos break; 604 1.1 christos case L_32: 605 1.1 christos cst[opnum] = 606 1.1 christos (data[len / 2 + 0] << 24) + 607 1.1 christos (data[len / 2 + 1] << 16) + 608 1.1 christos (data[len / 2 + 2] << 8) + 609 1.1 christos (data[len / 2 + 3]); 610 1.1 christos break; 611 1.1 christos default: 612 1.1 christos printf ("decode: bad size DISP/PCREL/INDEX: %d\n", 613 1.1 christos (looking_for & SIZE)); 614 1.1 christos goto end; 615 1.1 christos } 616 1.1 christos } 617 1.1 christos else if ((looking_for & SIZE) == L_16 || 618 1.1 christos (looking_for & SIZE) == L_16U) 619 1.1 christos { 620 1.1 christos cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; 621 1.1 christos /* Immediates are always unsigned. */ 622 1.1 christos if ((looking_for & SIZE) != L_16U && 623 1.1 christos (looking_for & MODE) != IMM) 624 1.1 christos cst[opnum] = (short) cst[opnum]; /* Sign extend. */ 625 1.1 christos } 626 1.1 christos else if (looking_for & ABSJMP) 627 1.1 christos { 628 1.1 christos switch (looking_for & SIZE) { 629 1.1 christos case L_24: 630 1.1 christos cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]); 631 1.1 christos break; 632 1.1 christos case L_32: 633 1.1 christos cst[opnum] = 634 1.1 christos (data[len / 2 + 0] << 24) + 635 1.1 christos (data[len / 2 + 1] << 16) + 636 1.1 christos (data[len / 2 + 2] << 8) + 637 1.1 christos (data[len / 2 + 3]); 638 1.1 christos break; 639 1.1 christos default: 640 1.1 christos printf ("decode: bad size ABSJMP: %d\n", 641 1.1 christos (looking_for & SIZE)); 642 1.1 christos goto end; 643 1.1 christos } 644 1.1 christos } 645 1.1 christos else if ((looking_for & MODE) == MEMIND) 646 1.1 christos { 647 1.1 christos cst[opnum] = data[1]; 648 1.1 christos } 649 1.1 christos else if ((looking_for & MODE) == VECIND) 650 1.1 christos { 651 1.1 christos if(h8300_normal_mode) 652 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2; 653 1.1 christos else 654 1.1 christos cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4; 655 1.7 christos cst[opnum] += h8_get_vbr (cpu); /* Add vector base reg. */ 656 1.1 christos } 657 1.1 christos else if ((looking_for & SIZE) == L_32) 658 1.1 christos { 659 1.1 christos int i = len / 2; 660 1.1 christos 661 1.1 christos cst[opnum] = 662 1.1 christos (data[i + 0] << 24) | 663 1.1 christos (data[i + 1] << 16) | 664 1.1 christos (data[i + 2] << 8) | 665 1.1 christos (data[i + 3]); 666 1.1 christos } 667 1.1 christos else if ((looking_for & SIZE) == L_24) 668 1.1 christos { 669 1.1 christos int i = len / 2; 670 1.1 christos 671 1.1 christos cst[opnum] = 672 1.1 christos (data[i + 0] << 16) | 673 1.1 christos (data[i + 1] << 8) | 674 1.1 christos (data[i + 2]); 675 1.1 christos } 676 1.1 christos else if (looking_for & DISPREG) 677 1.1 christos { 678 1.1 christos rdisp[opnum] = thisnib & 0x7; 679 1.1 christos } 680 1.1 christos else if ((looking_for & MODE) == KBIT) 681 1.1 christos { 682 1.1 christos switch (thisnib) 683 1.1 christos { 684 1.1 christos case 9: 685 1.1 christos cst[opnum] = 4; 686 1.1 christos break; 687 1.1 christos case 8: 688 1.1 christos cst[opnum] = 2; 689 1.1 christos break; 690 1.1 christos case 0: 691 1.1 christos cst[opnum] = 1; 692 1.1 christos break; 693 1.1 christos default: 694 1.1 christos goto fail; 695 1.1 christos } 696 1.1 christos } 697 1.1 christos else if ((looking_for & SIZE) == L_8) 698 1.1 christos { 699 1.1 christos if ((looking_for & MODE) == ABS) 700 1.1 christos { 701 1.1 christos /* Will be combined with contents of SBR_REGNUM 702 1.1 christos by fetch (). For all modes except h8sx, this 703 1.1 christos will always contain the value 0xFFFFFF00. */ 704 1.1 christos cst[opnum] = data[len / 2] & 0xff; 705 1.1 christos } 706 1.1 christos else 707 1.1 christos { 708 1.1 christos cst[opnum] = data[len / 2] & 0xff; 709 1.1 christos } 710 1.1 christos } 711 1.1 christos else if ((looking_for & SIZE) == L_2) 712 1.1 christos { 713 1.1 christos cst[opnum] = thisnib & 3; 714 1.1 christos } 715 1.1 christos else if ((looking_for & SIZE) == L_3 || 716 1.1 christos (looking_for & SIZE) == L_3NZ) 717 1.1 christos { 718 1.1 christos cst[opnum] = thisnib & 7; 719 1.1 christos if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ) 720 1.1 christos goto fail; 721 1.1 christos } 722 1.1 christos else if ((looking_for & SIZE) == L_4) 723 1.1 christos { 724 1.1 christos cst[opnum] = thisnib & 15; 725 1.1 christos } 726 1.1 christos else if ((looking_for & SIZE) == L_5) 727 1.1 christos { 728 1.1 christos cst[opnum] = data[len / 2] & 0x1f; 729 1.1 christos } 730 1.1 christos else if (looking_for == E) 731 1.1 christos { 732 1.1 christos #ifdef ADEBUG 733 1.1 christos dst->op = q; 734 1.1 christos #endif 735 1.1 christos /* Fill in the args. */ 736 1.1 christos { 737 1.1 christos const op_type *args = q->args.nib; 738 1.1 christos int nargs; 739 1.1 christos 740 1.1 christos for (nargs = 0; 741 1.1 christos nargs < 3 && *args != E; 742 1.1 christos nargs++) 743 1.1 christos { 744 1.1 christos int x = *args; 745 1.1 christos ea_type *p; 746 1.1 christos 747 1.1 christos opnum = ((x & OP3) ? 2 : 748 1.1 christos (x & DST) ? 1 : 0); 749 1.1 christos if (x & DST) 750 1.1 christos p = &dst->dst; 751 1.1 christos else if (x & OP3) 752 1.1 christos p = &dst->op3; 753 1.1 christos else 754 1.1 christos p = &dst->src; 755 1.1 christos 756 1.1 christos if ((x & MODE) == IMM || 757 1.1 christos (x & MODE) == KBIT || 758 1.1 christos (x & MODE) == DBIT) 759 1.1 christos { 760 1.1 christos /* Use the instruction to determine 761 1.1 christos the operand size. */ 762 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how)); 763 1.1 christos p->literal = cst[opnum]; 764 1.1 christos } 765 1.1 christos else if ((x & MODE) == CONST_2 || 766 1.1 christos (x & MODE) == CONST_4 || 767 1.1 christos (x & MODE) == CONST_8 || 768 1.1 christos (x & MODE) == CONST_16) 769 1.1 christos { 770 1.1 christos /* Use the instruction to determine 771 1.1 christos the operand size. */ 772 1.1 christos p->type = X (OP_IMM, OP_SIZE (q->how)); 773 1.1 christos switch (x & MODE) { 774 1.1 christos case CONST_2: p->literal = 2; break; 775 1.1 christos case CONST_4: p->literal = 4; break; 776 1.1 christos case CONST_8: p->literal = 8; break; 777 1.1 christos case CONST_16: p->literal = 16; break; 778 1.1 christos } 779 1.1 christos } 780 1.1 christos else if ((x & MODE) == REG) 781 1.1 christos { 782 1.1 christos p->type = X (OP_REG, bitfrom (x)); 783 1.1 christos p->reg = reg[opnum]; 784 1.1 christos } 785 1.1 christos else if ((x & MODE) == LOWREG) 786 1.1 christos { 787 1.1 christos p->type = X (OP_LOWREG, bitfrom (x)); 788 1.1 christos p->reg = reg[opnum]; 789 1.1 christos } 790 1.1 christos else if ((x & MODE) == PREINC) 791 1.1 christos { 792 1.1 christos /* Use the instruction to determine 793 1.1 christos the operand size. */ 794 1.1 christos p->type = X (OP_PREINC, OP_SIZE (q->how)); 795 1.1 christos p->reg = reg[opnum] & 0x7; 796 1.1 christos } 797 1.1 christos else if ((x & MODE) == POSTINC) 798 1.1 christos { 799 1.1 christos /* Use the instruction to determine 800 1.1 christos the operand size. */ 801 1.1 christos p->type = X (OP_POSTINC, OP_SIZE (q->how)); 802 1.1 christos p->reg = reg[opnum] & 0x7; 803 1.1 christos } 804 1.1 christos else if ((x & MODE) == PREDEC) 805 1.1 christos { 806 1.1 christos /* Use the instruction to determine 807 1.1 christos the operand size. */ 808 1.1 christos p->type = X (OP_PREDEC, OP_SIZE (q->how)); 809 1.1 christos p->reg = reg[opnum] & 0x7; 810 1.1 christos } 811 1.1 christos else if ((x & MODE) == POSTDEC) 812 1.1 christos { 813 1.1 christos /* Use the instruction to determine 814 1.1 christos the operand size. */ 815 1.1 christos p->type = X (OP_POSTDEC, OP_SIZE (q->how)); 816 1.1 christos p->reg = reg[opnum] & 0x7; 817 1.1 christos } 818 1.1 christos else if ((x & MODE) == IND) 819 1.1 christos { 820 1.1 christos /* Note: an indirect is transformed into 821 1.1 christos a displacement of zero. 822 1.1 christos */ 823 1.1 christos /* Use the instruction to determine 824 1.1 christos the operand size. */ 825 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how)); 826 1.1 christos p->reg = reg[opnum] & 0x7; 827 1.1 christos p->literal = 0; 828 1.1 christos if (OP_KIND (q->how) == O_JSR || 829 1.1 christos OP_KIND (q->how) == O_JMP) 830 1.7 christos if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type)) 831 1.1 christos goto end; 832 1.1 christos } 833 1.1 christos else if ((x & MODE) == ABS) 834 1.1 christos { 835 1.1 christos /* Note: a 16 or 32 bit ABS is transformed into a 836 1.1 christos displacement from pseudo-register ZERO_REGNUM, 837 1.1 christos which is always zero. An 8 bit ABS becomes 838 1.1 christos a displacement from SBR_REGNUM. 839 1.1 christos */ 840 1.1 christos /* Use the instruction to determine 841 1.1 christos the operand size. */ 842 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how)); 843 1.1 christos p->literal = cst[opnum]; 844 1.1 christos 845 1.1 christos /* 8-bit ABS is displacement from SBR. 846 1.1 christos 16 and 32-bit ABS are displacement from ZERO. 847 1.1 christos (SBR will always be zero except for h8/sx) 848 1.1 christos */ 849 1.1 christos if ((x & SIZE) == L_8) 850 1.1 christos p->reg = SBR_REGNUM; 851 1.1 christos else 852 1.1 christos p->reg = ZERO_REGNUM;; 853 1.1 christos } 854 1.1 christos else if ((x & MODE) == MEMIND || 855 1.1 christos (x & MODE) == VECIND) 856 1.1 christos { 857 1.1 christos /* Size doesn't matter. */ 858 1.1 christos p->type = X (OP_MEM, SB); 859 1.1 christos p->literal = cst[opnum]; 860 1.1 christos if (OP_KIND (q->how) == O_JSR || 861 1.1 christos OP_KIND (q->how) == O_JMP) 862 1.7 christos if (lvalue (sd, cpu, p->type, p->reg, (unsigned int *)&p->type)) 863 1.1 christos goto end; 864 1.1 christos } 865 1.1 christos else if ((x & MODE) == PCREL) 866 1.1 christos { 867 1.1 christos /* Size doesn't matter. */ 868 1.1 christos p->type = X (OP_PCREL, SB); 869 1.1 christos p->literal = cst[opnum]; 870 1.1 christos } 871 1.1 christos else if (x & ABSJMP) 872 1.1 christos { 873 1.1 christos p->type = X (OP_IMM, SP); 874 1.1 christos p->literal = cst[opnum]; 875 1.1 christos } 876 1.1 christos else if ((x & MODE) == INDEXB) 877 1.1 christos { 878 1.1 christos p->type = X (OP_INDEXB, OP_SIZE (q->how)); 879 1.1 christos p->literal = cst[opnum]; 880 1.1 christos p->reg = rdisp[opnum]; 881 1.1 christos } 882 1.1 christos else if ((x & MODE) == INDEXW) 883 1.1 christos { 884 1.1 christos p->type = X (OP_INDEXW, OP_SIZE (q->how)); 885 1.1 christos p->literal = cst[opnum]; 886 1.1 christos p->reg = rdisp[opnum]; 887 1.1 christos } 888 1.1 christos else if ((x & MODE) == INDEXL) 889 1.1 christos { 890 1.1 christos p->type = X (OP_INDEXL, OP_SIZE (q->how)); 891 1.1 christos p->literal = cst[opnum]; 892 1.1 christos p->reg = rdisp[opnum]; 893 1.1 christos } 894 1.1 christos else if ((x & MODE) == DISP) 895 1.1 christos { 896 1.1 christos /* Yuck -- special for mova args. */ 897 1.1 christos if (strncmp (q->name, "mova", 4) == 0 && 898 1.1 christos (x & SIZE) == L_2) 899 1.1 christos { 900 1.1 christos /* Mova can have a DISP2 dest, with an 901 1.1 christos INDEXB or INDEXW src. The multiplier 902 1.1 christos for the displacement value is determined 903 1.1 christos by the src operand, not by the insn. */ 904 1.1 christos 905 1.1 christos switch (OP_KIND (dst->src.type)) 906 1.1 christos { 907 1.1 christos case OP_INDEXB: 908 1.1 christos p->type = X (OP_DISP, SB); 909 1.1 christos p->literal = cst[opnum]; 910 1.1 christos break; 911 1.1 christos case OP_INDEXW: 912 1.1 christos p->type = X (OP_DISP, SW); 913 1.1 christos p->literal = cst[opnum] * 2; 914 1.1 christos break; 915 1.1 christos default: 916 1.1 christos goto fail; 917 1.1 christos } 918 1.1 christos } 919 1.1 christos else 920 1.1 christos { 921 1.1 christos p->type = X (OP_DISP, OP_SIZE (q->how)); 922 1.1 christos p->literal = cst[opnum]; 923 1.1 christos /* DISP2 is special. */ 924 1.1 christos if ((x & SIZE) == L_2) 925 1.1 christos switch (OP_SIZE (q->how)) 926 1.1 christos { 927 1.1 christos case SB: break; 928 1.1 christos case SW: p->literal *= 2; break; 929 1.1 christos case SL: p->literal *= 4; break; 930 1.1 christos } 931 1.1 christos } 932 1.1 christos p->reg = rdisp[opnum]; 933 1.1 christos } 934 1.1 christos else if (x & CTRL) 935 1.1 christos { 936 1.1 christos switch (reg[opnum]) 937 1.1 christos { 938 1.1 christos case C_CCR: 939 1.1 christos p->type = X (OP_CCR, SB); 940 1.1 christos break; 941 1.1 christos case C_EXR: 942 1.1 christos p->type = X (OP_EXR, SB); 943 1.1 christos break; 944 1.1 christos case C_MACH: 945 1.1 christos p->type = X (OP_MACH, SL); 946 1.1 christos break; 947 1.1 christos case C_MACL: 948 1.1 christos p->type = X (OP_MACL, SL); 949 1.1 christos break; 950 1.1 christos case C_VBR: 951 1.1 christos p->type = X (OP_VBR, SL); 952 1.1 christos break; 953 1.1 christos case C_SBR: 954 1.1 christos p->type = X (OP_SBR, SL); 955 1.1 christos break; 956 1.1 christos } 957 1.1 christos } 958 1.1 christos else if ((x & MODE) == CCR) 959 1.1 christos { 960 1.1 christos p->type = OP_CCR; 961 1.1 christos } 962 1.1 christos else if ((x & MODE) == EXR) 963 1.1 christos { 964 1.1 christos p->type = OP_EXR; 965 1.1 christos } 966 1.1 christos else 967 1.1 christos printf ("Hmmmm 0x%x...\n", x); 968 1.1 christos 969 1.1 christos args++; 970 1.1 christos } 971 1.1 christos } 972 1.1 christos 973 1.1 christos /* Unary operators: treat src and dst as equivalent. */ 974 1.1 christos if (dst->dst.type == -1) 975 1.1 christos dst->dst = dst->src; 976 1.1 christos if (dst->src.type == -1) 977 1.1 christos dst->src = dst->dst; 978 1.1 christos 979 1.1 christos dst->opcode = q->how; 980 1.1 christos dst->cycles = q->time; 981 1.1 christos 982 1.1 christos /* And jsr's to these locations are turned into 983 1.1 christos magic traps. */ 984 1.1 christos 985 1.1 christos if (OP_KIND (dst->opcode) == O_JSR) 986 1.1 christos { 987 1.1 christos switch (dst->src.literal) 988 1.1 christos { 989 1.1 christos case 0xc5: 990 1.1 christos dst->opcode = O (O_SYS_OPEN, SB); 991 1.1 christos break; 992 1.1 christos case 0xc6: 993 1.1 christos dst->opcode = O (O_SYS_READ, SB); 994 1.1 christos break; 995 1.1 christos case 0xc7: 996 1.1 christos dst->opcode = O (O_SYS_WRITE, SB); 997 1.1 christos break; 998 1.1 christos case 0xc8: 999 1.1 christos dst->opcode = O (O_SYS_LSEEK, SB); 1000 1.1 christos break; 1001 1.1 christos case 0xc9: 1002 1.1 christos dst->opcode = O (O_SYS_CLOSE, SB); 1003 1.1 christos break; 1004 1.1 christos case 0xca: 1005 1.1 christos dst->opcode = O (O_SYS_STAT, SB); 1006 1.1 christos break; 1007 1.1 christos case 0xcb: 1008 1.1 christos dst->opcode = O (O_SYS_FSTAT, SB); 1009 1.1 christos break; 1010 1.1 christos case 0xcc: 1011 1.1 christos dst->opcode = O (O_SYS_CMDLINE, SB); 1012 1.1 christos break; 1013 1.1 christos } 1014 1.1 christos /* End of Processing for system calls. */ 1015 1.1 christos } 1016 1.1 christos 1017 1.7 christos /* Use same register is specified for source 1018 1.7 christos and destination. 1019 1.7 christos The value of source will be the value after 1020 1.7 christos address calculation. */ 1021 1.7 christos if (OP_KIND (dst->opcode) != O_CMP && 1022 1.7 christos OP_KIND (dst->src.type) == OP_REG && 1023 1.7 christos (dst->src.reg & 7) == dst->dst.reg) { 1024 1.7 christos switch (OP_KIND (dst->dst.type)) 1025 1.7 christos { 1026 1.7 christos case OP_POSTDEC: 1027 1.7 christos dst->src.type = X (OP_REG_DEC, 1028 1.7 christos OP_SIZE (dst->dst.type)); 1029 1.7 christos break; 1030 1.7 christos case OP_POSTINC: 1031 1.7 christos dst->src.type = X (OP_REG_INC, 1032 1.7 christos OP_SIZE (dst->dst.type)); 1033 1.7 christos break; 1034 1.7 christos case OP_PREINC: 1035 1.7 christos if (OP_KIND (dst->opcode) == O_MOV) 1036 1.7 christos dst->src.type = X (OP_REG_INC, 1037 1.7 christos OP_SIZE (dst->dst.type)); 1038 1.7 christos break; 1039 1.7 christos case OP_PREDEC: 1040 1.7 christos if (OP_KIND (dst->opcode) == O_MOV) 1041 1.7 christos dst->src.type = X (OP_REG_DEC, 1042 1.7 christos OP_SIZE (dst->dst.type)); 1043 1.7 christos break; 1044 1.7 christos } 1045 1.7 christos } 1046 1.1 christos dst->next_pc = addr + len / 2; 1047 1.1 christos return; 1048 1.1 christos } 1049 1.1 christos else 1050 1.1 christos printf ("Don't understand 0x%x \n", looking_for); 1051 1.1 christos } 1052 1.1 christos 1053 1.1 christos len++; 1054 1.1 christos nib++; 1055 1.1 christos } 1056 1.1 christos 1057 1.1 christos fail: 1058 1.1 christos ; 1059 1.1 christos } 1060 1.1 christos end: 1061 1.1 christos /* Fell off the end. */ 1062 1.1 christos dst->opcode = O (O_ILL, SB); 1063 1.1 christos } 1064 1.1 christos 1065 1.1 christos static unsigned char *breg[32]; 1066 1.1 christos static unsigned short *wreg[16]; 1067 1.1 christos 1068 1.1 christos #define GET_B_REG(X) *(breg[X]) 1069 1.1 christos #define SET_B_REG(X, Y) (*(breg[X])) = (Y) 1070 1.1 christos #define GET_W_REG(X) *(wreg[X]) 1071 1.1 christos #define SET_W_REG(X, Y) (*(wreg[X])) = (Y) 1072 1.7 christos #define GET_L_REG(X) h8_get_reg (cpu, X) 1073 1.7 christos #define SET_L_REG(X, Y) h8_set_reg (cpu, X, Y) 1074 1.1 christos 1075 1.1 christos #define GET_MEMORY_L(X) \ 1076 1.1 christos ((X) < memory_size \ 1077 1.7 christos ? ((h8_get_memory (cpu, (X)+0) << 24) | (h8_get_memory (cpu, (X)+1) << 16) \ 1078 1.7 christos | (h8_get_memory (cpu, (X)+2) << 8) | (h8_get_memory (cpu, (X)+3) << 0)) \ 1079 1.7 christos : 0) 1080 1.1 christos 1081 1.1 christos #define GET_MEMORY_W(X) \ 1082 1.1 christos ((X) < memory_size \ 1083 1.7 christos ? ((h8_get_memory (cpu, (X)+0) << 8) | (h8_get_memory (cpu, (X)+1) << 0)) \ 1084 1.7 christos : 0) 1085 1.1 christos 1086 1.1 christos #define GET_MEMORY_B(X) \ 1087 1.7 christos ((X) < memory_size ? h8_get_memory (cpu, (X)) : 0) 1088 1.1 christos 1089 1.1 christos #define SET_MEMORY_L(X, Y) \ 1090 1.1 christos { register unsigned char *_p; register int __y = (Y); \ 1091 1.7 christos _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \ 1092 1.1 christos _p[0] = __y >> 24; _p[1] = __y >> 16; \ 1093 1.1 christos _p[2] = __y >> 8; _p[3] = __y >> 0; \ 1094 1.1 christos } 1095 1.1 christos 1096 1.1 christos #define SET_MEMORY_W(X, Y) \ 1097 1.1 christos { register unsigned char *_p; register int __y = (Y); \ 1098 1.7 christos _p = ((X) < memory_size ? h8_get_memory_buf (cpu) + (X) : 0); \ 1099 1.1 christos _p[0] = __y >> 8; _p[1] = __y; \ 1100 1.1 christos } 1101 1.1 christos 1102 1.1 christos #define SET_MEMORY_B(X, Y) \ 1103 1.7 christos ((X) < memory_size ? h8_set_memory (cpu, (X), (Y)) : 0) 1104 1.1 christos 1105 1.1 christos /* Simulate a memory fetch. 1106 1.1 christos Return 0 for success, -1 for failure. 1107 1.1 christos */ 1108 1.1 christos 1109 1.1 christos static int 1110 1.1 christos fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice) 1111 1.1 christos { 1112 1.6 christos SIM_CPU *cpu = STATE_CPU (sd, 0); 1113 1.1 christos int rn = arg->reg; 1114 1.1 christos int abs = arg->literal; 1115 1.1 christos int r; 1116 1.1 christos int t; 1117 1.1 christos 1118 1.1 christos if (val == NULL) 1119 1.1 christos return -1; /* Paranoia. */ 1120 1.1 christos 1121 1.1 christos switch (arg->type) 1122 1.1 christos { 1123 1.1 christos /* Indexed register plus displacement mode: 1124 1.1 christos 1125 1.1 christos This new family of addressing modes are similar to OP_DISP 1126 1.1 christos (register plus displacement), with two differences: 1127 1.1 christos 1) INDEXB uses only the least significant byte of the register, 1128 1.1 christos INDEXW uses only the least significant word, and 1129 1.1 christos INDEXL uses the entire register (just like OP_DISP). 1130 1.1 christos and 1131 1.1 christos 2) The displacement value in abs is multiplied by two 1132 1.1 christos for SW-sized operations, and by four for SL-size. 1133 1.1 christos 1134 1.1 christos This gives nine possible variations. 1135 1.1 christos */ 1136 1.1 christos 1137 1.1 christos case X (OP_INDEXB, SB): 1138 1.1 christos case X (OP_INDEXB, SW): 1139 1.1 christos case X (OP_INDEXB, SL): 1140 1.1 christos case X (OP_INDEXW, SB): 1141 1.1 christos case X (OP_INDEXW, SW): 1142 1.1 christos case X (OP_INDEXW, SL): 1143 1.1 christos case X (OP_INDEXL, SB): 1144 1.1 christos case X (OP_INDEXL, SW): 1145 1.1 christos case X (OP_INDEXL, SL): 1146 1.1 christos t = GET_L_REG (rn); 1147 1.1 christos switch (OP_KIND (arg->type)) { 1148 1.1 christos case OP_INDEXB: t &= 0xff; break; 1149 1.1 christos case OP_INDEXW: t &= 0xffff; break; 1150 1.1 christos case OP_INDEXL: 1151 1.1 christos default: break; 1152 1.1 christos } 1153 1.1 christos switch (OP_SIZE (arg->type)) { 1154 1.1 christos case SB: 1155 1.7 christos *val = GET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu)); 1156 1.1 christos break; 1157 1.1 christos case SW: 1158 1.7 christos *val = GET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu)); 1159 1.1 christos break; 1160 1.1 christos case SL: 1161 1.7 christos *val = GET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu)); 1162 1.1 christos break; 1163 1.1 christos } 1164 1.1 christos break; 1165 1.1 christos 1166 1.1 christos case X (OP_LOWREG, SB): 1167 1.1 christos *val = GET_L_REG (rn) & 0xff; 1168 1.1 christos break; 1169 1.1 christos case X (OP_LOWREG, SW): 1170 1.1 christos *val = GET_L_REG (rn) & 0xffff; 1171 1.1 christos break; 1172 1.1 christos 1173 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */ 1174 1.1 christos *val = GET_B_REG (rn); 1175 1.1 christos break; 1176 1.1 christos case X (OP_REG, SW): /* Register direct, word. */ 1177 1.1 christos *val = GET_W_REG (rn); 1178 1.1 christos break; 1179 1.1 christos case X (OP_REG, SL): /* Register direct, long. */ 1180 1.1 christos *val = GET_L_REG (rn); 1181 1.1 christos break; 1182 1.1 christos case X (OP_IMM, SB): /* Immediate, byte. */ 1183 1.1 christos case X (OP_IMM, SW): /* Immediate, word. */ 1184 1.1 christos case X (OP_IMM, SL): /* Immediate, long. */ 1185 1.1 christos *val = abs; 1186 1.1 christos break; 1187 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr: byte. */ 1188 1.1 christos t = GET_L_REG (rn); 1189 1.7 christos r = GET_MEMORY_B (t & h8_get_mask (cpu)); 1190 1.1 christos if (!twice) 1191 1.1 christos t += 1; 1192 1.1 christos SET_L_REG (rn, t); 1193 1.1 christos *val = r; 1194 1.1 christos break; 1195 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr: word. */ 1196 1.1 christos t = GET_L_REG (rn); 1197 1.7 christos r = GET_MEMORY_W (t & h8_get_mask (cpu)); 1198 1.1 christos if (!twice) 1199 1.1 christos t += 2; 1200 1.1 christos SET_L_REG (rn, t); 1201 1.1 christos *val = r; 1202 1.1 christos break; 1203 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr: long. */ 1204 1.1 christos t = GET_L_REG (rn); 1205 1.7 christos r = GET_MEMORY_L (t & h8_get_mask (cpu)); 1206 1.1 christos if (!twice) 1207 1.1 christos t += 4; 1208 1.1 christos SET_L_REG (rn, t); 1209 1.1 christos *val = r; 1210 1.1 christos break; 1211 1.1 christos 1212 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr: byte. */ 1213 1.1 christos t = GET_L_REG (rn); 1214 1.7 christos r = GET_MEMORY_B (t & h8_get_mask (cpu)); 1215 1.1 christos if (!twice) 1216 1.1 christos t -= 1; 1217 1.1 christos SET_L_REG (rn, t); 1218 1.1 christos *val = r; 1219 1.1 christos break; 1220 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr: word. */ 1221 1.1 christos t = GET_L_REG (rn); 1222 1.7 christos r = GET_MEMORY_W (t & h8_get_mask (cpu)); 1223 1.1 christos if (!twice) 1224 1.1 christos t -= 2; 1225 1.1 christos SET_L_REG (rn, t); 1226 1.1 christos *val = r; 1227 1.1 christos break; 1228 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr: long. */ 1229 1.1 christos t = GET_L_REG (rn); 1230 1.7 christos r = GET_MEMORY_L (t & h8_get_mask (cpu)); 1231 1.1 christos if (!twice) 1232 1.1 christos t -= 4; 1233 1.1 christos SET_L_REG (rn, t); 1234 1.1 christos *val = r; 1235 1.1 christos break; 1236 1.1 christos 1237 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr: byte. */ 1238 1.1 christos t = GET_L_REG (rn) - 1; 1239 1.1 christos SET_L_REG (rn, t); 1240 1.7 christos t &= h8_get_mask (cpu); 1241 1.1 christos *val = GET_MEMORY_B (t); 1242 1.1 christos break; 1243 1.1 christos 1244 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr: word. */ 1245 1.1 christos t = GET_L_REG (rn) - 2; 1246 1.1 christos SET_L_REG (rn, t); 1247 1.7 christos t &= h8_get_mask (cpu); 1248 1.1 christos *val = GET_MEMORY_W (t); 1249 1.1 christos break; 1250 1.1 christos 1251 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr: long. */ 1252 1.1 christos t = GET_L_REG (rn) - 4; 1253 1.1 christos SET_L_REG (rn, t); 1254 1.7 christos t &= h8_get_mask (cpu); 1255 1.1 christos *val = GET_MEMORY_L (t); 1256 1.1 christos break; 1257 1.1 christos 1258 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr: byte. */ 1259 1.1 christos t = GET_L_REG (rn) + 1; 1260 1.1 christos SET_L_REG (rn, t); 1261 1.7 christos t &= h8_get_mask (cpu); 1262 1.1 christos *val = GET_MEMORY_B (t); 1263 1.1 christos break; 1264 1.1 christos 1265 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr: long. */ 1266 1.1 christos t = GET_L_REG (rn) + 2; 1267 1.1 christos SET_L_REG (rn, t); 1268 1.7 christos t &= h8_get_mask (cpu); 1269 1.1 christos *val = GET_MEMORY_W (t); 1270 1.1 christos break; 1271 1.1 christos 1272 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr: long. */ 1273 1.1 christos t = GET_L_REG (rn) + 4; 1274 1.1 christos SET_L_REG (rn, t); 1275 1.7 christos t &= h8_get_mask (cpu); 1276 1.1 christos *val = GET_MEMORY_L (t); 1277 1.1 christos break; 1278 1.1 christos 1279 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement: byte. */ 1280 1.1 christos t = GET_L_REG (rn) + abs; 1281 1.7 christos t &= h8_get_mask (cpu); 1282 1.1 christos *val = GET_MEMORY_B (t); 1283 1.1 christos break; 1284 1.1 christos 1285 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement: word. */ 1286 1.1 christos t = GET_L_REG (rn) + abs; 1287 1.7 christos t &= h8_get_mask (cpu); 1288 1.1 christos *val = GET_MEMORY_W (t); 1289 1.1 christos break; 1290 1.1 christos 1291 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement: long. */ 1292 1.1 christos t = GET_L_REG (rn) + abs; 1293 1.7 christos t &= h8_get_mask (cpu); 1294 1.1 christos *val =GET_MEMORY_L (t); 1295 1.1 christos break; 1296 1.1 christos 1297 1.1 christos case X (OP_MEM, SL): /* Absolute memory address, long. */ 1298 1.1 christos t = GET_MEMORY_L (abs); 1299 1.7 christos t &= h8_get_mask (cpu); 1300 1.1 christos *val = t; 1301 1.1 christos break; 1302 1.1 christos 1303 1.1 christos case X (OP_MEM, SW): /* Absolute memory address, word. */ 1304 1.1 christos t = GET_MEMORY_W (abs); 1305 1.7 christos t &= h8_get_mask (cpu); 1306 1.1 christos *val = t; 1307 1.1 christos break; 1308 1.1 christos 1309 1.1 christos case X (OP_PCREL, SB): /* PC relative (for jump, branch etc). */ 1310 1.1 christos case X (OP_PCREL, SW): 1311 1.1 christos case X (OP_PCREL, SL): 1312 1.1 christos case X (OP_PCREL, SN): 1313 1.1 christos *val = abs; 1314 1.1 christos break; 1315 1.1 christos 1316 1.7 christos case X (OP_REG_DEC, SB): /* Register direct, affected decrement byte. */ 1317 1.7 christos *val = GET_B_REG (rn) - 1; 1318 1.7 christos break; 1319 1.7 christos case X (OP_REG_DEC, SW): /* Register direct, affected decrement word. */ 1320 1.7 christos *val = GET_W_REG (rn) - 2; 1321 1.7 christos break; 1322 1.7 christos case X (OP_REG_DEC, SL): /* Register direct, affected decrement long. */ 1323 1.7 christos *val = GET_L_REG (rn) - 4; 1324 1.7 christos break; 1325 1.7 christos case X (OP_REG_INC, SB): /* Register direct, affected increment byte. */ 1326 1.7 christos *val = GET_B_REG (rn) + 1; 1327 1.7 christos break; 1328 1.7 christos case X (OP_REG_INC, SW): /* Register direct, affected increment word. */ 1329 1.7 christos *val = GET_W_REG (rn) + 2; 1330 1.7 christos break; 1331 1.7 christos case X (OP_REG_INC, SL): /* Register direct, affected increment long. */ 1332 1.7 christos *val = GET_L_REG (rn) + 4; 1333 1.7 christos break; 1334 1.7 christos 1335 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */ 1336 1.1 christos default: 1337 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV); 1338 1.1 christos return -1; 1339 1.1 christos } 1340 1.1 christos return 0; /* Success. */ 1341 1.1 christos } 1342 1.1 christos 1343 1.1 christos /* Normal fetch. */ 1344 1.1 christos 1345 1.1 christos static int 1346 1.1 christos fetch (SIM_DESC sd, ea_type *arg, int *val) 1347 1.1 christos { 1348 1.1 christos return fetch_1 (sd, arg, val, 0); 1349 1.1 christos } 1350 1.1 christos 1351 1.1 christos /* Fetch which will be followed by a store to the same location. 1352 1.1 christos The difference being that we don't want to do a post-increment 1353 1.1 christos or post-decrement at this time: we'll do it when we store. */ 1354 1.1 christos 1355 1.1 christos static int 1356 1.1 christos fetch2 (SIM_DESC sd, ea_type *arg, int *val) 1357 1.1 christos { 1358 1.1 christos return fetch_1 (sd, arg, val, 1); 1359 1.1 christos } 1360 1.1 christos 1361 1.1 christos /* Simulate a memory store. 1362 1.1 christos Return 0 for success, -1 for failure. 1363 1.1 christos */ 1364 1.1 christos 1365 1.1 christos static int 1366 1.1 christos store_1 (SIM_DESC sd, ea_type *arg, int n, int twice) 1367 1.1 christos { 1368 1.6 christos SIM_CPU *cpu = STATE_CPU (sd, 0); 1369 1.1 christos int rn = arg->reg; 1370 1.1 christos int abs = arg->literal; 1371 1.1 christos int t; 1372 1.1 christos 1373 1.1 christos switch (arg->type) 1374 1.1 christos { 1375 1.1 christos /* Indexed register plus displacement mode: 1376 1.1 christos 1377 1.1 christos This new family of addressing modes are similar to OP_DISP 1378 1.1 christos (register plus displacement), with two differences: 1379 1.1 christos 1) INDEXB uses only the least significant byte of the register, 1380 1.1 christos INDEXW uses only the least significant word, and 1381 1.1 christos INDEXL uses the entire register (just like OP_DISP). 1382 1.1 christos and 1383 1.1 christos 2) The displacement value in abs is multiplied by two 1384 1.1 christos for SW-sized operations, and by four for SL-size. 1385 1.1 christos 1386 1.1 christos This gives nine possible variations. 1387 1.1 christos */ 1388 1.1 christos 1389 1.1 christos case X (OP_INDEXB, SB): 1390 1.1 christos case X (OP_INDEXB, SW): 1391 1.1 christos case X (OP_INDEXB, SL): 1392 1.1 christos case X (OP_INDEXW, SB): 1393 1.1 christos case X (OP_INDEXW, SW): 1394 1.1 christos case X (OP_INDEXW, SL): 1395 1.1 christos case X (OP_INDEXL, SB): 1396 1.1 christos case X (OP_INDEXL, SW): 1397 1.1 christos case X (OP_INDEXL, SL): 1398 1.1 christos t = GET_L_REG (rn); 1399 1.1 christos switch (OP_KIND (arg->type)) { 1400 1.1 christos case OP_INDEXB: t &= 0xff; break; 1401 1.1 christos case OP_INDEXW: t &= 0xffff; break; 1402 1.1 christos case OP_INDEXL: 1403 1.1 christos default: break; 1404 1.1 christos } 1405 1.1 christos switch (OP_SIZE (arg->type)) { 1406 1.1 christos case SB: 1407 1.7 christos SET_MEMORY_B ((t * 1 + abs) & h8_get_mask (cpu), n); 1408 1.1 christos break; 1409 1.1 christos case SW: 1410 1.7 christos SET_MEMORY_W ((t * 2 + abs) & h8_get_mask (cpu), n); 1411 1.1 christos break; 1412 1.1 christos case SL: 1413 1.7 christos SET_MEMORY_L ((t * 4 + abs) & h8_get_mask (cpu), n); 1414 1.1 christos break; 1415 1.1 christos } 1416 1.1 christos break; 1417 1.1 christos 1418 1.1 christos case X (OP_REG, SB): /* Register direct, byte. */ 1419 1.1 christos SET_B_REG (rn, n); 1420 1.1 christos break; 1421 1.1 christos case X (OP_REG, SW): /* Register direct, word. */ 1422 1.1 christos SET_W_REG (rn, n); 1423 1.1 christos break; 1424 1.1 christos case X (OP_REG, SL): /* Register direct, long. */ 1425 1.1 christos SET_L_REG (rn, n); 1426 1.1 christos break; 1427 1.1 christos 1428 1.1 christos case X (OP_PREDEC, SB): /* Register indirect w/pre-decr, byte. */ 1429 1.1 christos t = GET_L_REG (rn); 1430 1.1 christos if (!twice) 1431 1.1 christos t -= 1; 1432 1.1 christos SET_L_REG (rn, t); 1433 1.7 christos t &= h8_get_mask (cpu); 1434 1.1 christos SET_MEMORY_B (t, n); 1435 1.1 christos 1436 1.1 christos break; 1437 1.1 christos case X (OP_PREDEC, SW): /* Register indirect w/pre-decr, word. */ 1438 1.1 christos t = GET_L_REG (rn); 1439 1.1 christos if (!twice) 1440 1.1 christos t -= 2; 1441 1.1 christos SET_L_REG (rn, t); 1442 1.7 christos t &= h8_get_mask (cpu); 1443 1.1 christos SET_MEMORY_W (t, n); 1444 1.1 christos break; 1445 1.1 christos 1446 1.1 christos case X (OP_PREDEC, SL): /* Register indirect w/pre-decr, long. */ 1447 1.1 christos t = GET_L_REG (rn); 1448 1.1 christos if (!twice) 1449 1.1 christos t -= 4; 1450 1.1 christos SET_L_REG (rn, t); 1451 1.7 christos t &= h8_get_mask (cpu); 1452 1.1 christos SET_MEMORY_L (t, n); 1453 1.1 christos break; 1454 1.1 christos 1455 1.1 christos case X (OP_PREINC, SB): /* Register indirect w/pre-incr, byte. */ 1456 1.1 christos t = GET_L_REG (rn); 1457 1.1 christos if (!twice) 1458 1.1 christos t += 1; 1459 1.1 christos SET_L_REG (rn, t); 1460 1.7 christos t &= h8_get_mask (cpu); 1461 1.1 christos SET_MEMORY_B (t, n); 1462 1.1 christos 1463 1.1 christos break; 1464 1.1 christos case X (OP_PREINC, SW): /* Register indirect w/pre-incr, word. */ 1465 1.1 christos t = GET_L_REG (rn); 1466 1.1 christos if (!twice) 1467 1.1 christos t += 2; 1468 1.1 christos SET_L_REG (rn, t); 1469 1.7 christos t &= h8_get_mask (cpu); 1470 1.1 christos SET_MEMORY_W (t, n); 1471 1.1 christos break; 1472 1.1 christos 1473 1.1 christos case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */ 1474 1.1 christos t = GET_L_REG (rn); 1475 1.1 christos if (!twice) 1476 1.1 christos t += 4; 1477 1.1 christos SET_L_REG (rn, t); 1478 1.7 christos t &= h8_get_mask (cpu); 1479 1.1 christos SET_MEMORY_L (t, n); 1480 1.1 christos break; 1481 1.1 christos 1482 1.1 christos case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */ 1483 1.1 christos t = GET_L_REG (rn); 1484 1.1 christos SET_L_REG (rn, t - 1); 1485 1.7 christos t &= h8_get_mask (cpu); 1486 1.1 christos SET_MEMORY_B (t, n); 1487 1.1 christos break; 1488 1.1 christos 1489 1.1 christos case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */ 1490 1.1 christos t = GET_L_REG (rn); 1491 1.1 christos SET_L_REG (rn, t - 2); 1492 1.7 christos t &= h8_get_mask (cpu); 1493 1.1 christos SET_MEMORY_W (t, n); 1494 1.1 christos break; 1495 1.1 christos 1496 1.1 christos case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */ 1497 1.1 christos t = GET_L_REG (rn); 1498 1.1 christos SET_L_REG (rn, t - 4); 1499 1.7 christos t &= h8_get_mask (cpu); 1500 1.1 christos SET_MEMORY_L (t, n); 1501 1.1 christos break; 1502 1.1 christos 1503 1.1 christos case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */ 1504 1.1 christos t = GET_L_REG (rn); 1505 1.1 christos SET_L_REG (rn, t + 1); 1506 1.7 christos t &= h8_get_mask (cpu); 1507 1.1 christos SET_MEMORY_B (t, n); 1508 1.1 christos break; 1509 1.1 christos 1510 1.1 christos case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */ 1511 1.1 christos t = GET_L_REG (rn); 1512 1.1 christos SET_L_REG (rn, t + 2); 1513 1.7 christos t &= h8_get_mask (cpu); 1514 1.1 christos SET_MEMORY_W (t, n); 1515 1.1 christos break; 1516 1.1 christos 1517 1.1 christos case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */ 1518 1.1 christos t = GET_L_REG (rn); 1519 1.1 christos SET_L_REG (rn, t + 4); 1520 1.7 christos t &= h8_get_mask (cpu); 1521 1.1 christos SET_MEMORY_L (t, n); 1522 1.1 christos break; 1523 1.1 christos 1524 1.1 christos case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */ 1525 1.1 christos t = GET_L_REG (rn) + abs; 1526 1.7 christos t &= h8_get_mask (cpu); 1527 1.1 christos SET_MEMORY_B (t, n); 1528 1.1 christos break; 1529 1.1 christos 1530 1.1 christos case X (OP_DISP, SW): /* Register indirect w/displacement, word. */ 1531 1.1 christos t = GET_L_REG (rn) + abs; 1532 1.7 christos t &= h8_get_mask (cpu); 1533 1.1 christos SET_MEMORY_W (t, n); 1534 1.1 christos break; 1535 1.1 christos 1536 1.1 christos case X (OP_DISP, SL): /* Register indirect w/displacement, long. */ 1537 1.1 christos t = GET_L_REG (rn) + abs; 1538 1.7 christos t &= h8_get_mask (cpu); 1539 1.1 christos SET_MEMORY_L (t, n); 1540 1.1 christos break; 1541 1.1 christos 1542 1.1 christos 1543 1.1 christos case X (OP_MEM, SB): /* Why isn't this implemented? */ 1544 1.1 christos case X (OP_MEM, SW): /* Why isn't this implemented? */ 1545 1.1 christos case X (OP_MEM, SL): /* Why isn't this implemented? */ 1546 1.1 christos default: 1547 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV); 1548 1.1 christos return -1; 1549 1.1 christos } 1550 1.1 christos return 0; 1551 1.1 christos } 1552 1.1 christos 1553 1.1 christos /* Normal store. */ 1554 1.1 christos 1555 1.1 christos static int 1556 1.1 christos store (SIM_DESC sd, ea_type *arg, int n) 1557 1.1 christos { 1558 1.1 christos return store_1 (sd, arg, n, 0); 1559 1.1 christos } 1560 1.1 christos 1561 1.1 christos /* Store which follows a fetch from the same location. 1562 1.1 christos The difference being that we don't want to do a pre-increment 1563 1.1 christos or pre-decrement at this time: it was already done when we fetched. */ 1564 1.1 christos 1565 1.1 christos static int 1566 1.1 christos store2 (SIM_DESC sd, ea_type *arg, int n) 1567 1.1 christos { 1568 1.1 christos return store_1 (sd, arg, n, 1); 1569 1.1 christos } 1570 1.1 christos 1571 1.9 christos /* Callback for qsort. We sort first based on availability 1572 1.8 christos (available instructions sort lower). When availability state 1573 1.8 christos is the same, then we use the first 4 bit nibble as a secondary 1574 1.8 christos sort key. 1575 1.8 christos 1576 1.8 christos We don't really care about 100% stability here, just that the 1577 1.8 christos available instructions come first and all instrutions with 1578 1.8 christos the same starting nibble are consecutive. 1579 1.8 christos 1580 1.8 christos We could do even better by recording frequency information into the 1581 1.8 christos main table and using that to sort within a nibble's group with the 1582 1.8 christos highest frequency instructions appearing first. */ 1583 1.8 christos 1584 1.8 christos static int 1585 1.8 christos instruction_comparator (const void *p1_, const void *p2_) 1586 1.8 christos { 1587 1.8 christos struct h8_opcode *p1 = (struct h8_opcode *)p1_; 1588 1.8 christos struct h8_opcode *p2 = (struct h8_opcode *)p2_; 1589 1.8 christos 1590 1.8 christos /* The 1st sort key is based on whether or not the 1591 1.8 christos instruction is even available. This reduces the 1592 1.8 christos number of entries we have to look at in the common 1593 1.8 christos case. */ 1594 1.8 christos bool p1_available = !((p1->available == AV_H8SX && !h8300sxmode) 1595 1.8 christos || (p1->available == AV_H8S && !h8300smode) 1596 1.8 christos || (p1->available == AV_H8H && !h8300hmode)); 1597 1.8 christos 1598 1.8 christos bool p2_available = !((p2->available == AV_H8SX && !h8300sxmode) 1599 1.8 christos || (p2->available == AV_H8S && !h8300smode) 1600 1.8 christos || (p2->available == AV_H8H && !h8300hmode)); 1601 1.8 christos 1602 1.8 christos /* Sort so that available instructions come before unavailable 1603 1.8 christos instructions. */ 1604 1.8 christos if (p1_available != p2_available) 1605 1.8 christos return p2_available - p1_available; 1606 1.8 christos 1607 1.8 christos /* Secondarily sort based on the first opcode nibble. */ 1608 1.8 christos return p1->data.nib[0] - p2->data.nib[0]; 1609 1.8 christos } 1610 1.8 christos 1611 1.8 christos 1612 1.8 christos /* OPS is the opcode array, which is initially sorted by mnenomic. 1613 1.8 christos 1614 1.8 christos Sort the array so that the instructions for the sub-architecture 1615 1.8 christos are at the start and unavailable instructions are at the end. 1616 1.8 christos 1617 1.8 christos Within the set of available instructions, further sort them based 1618 1.8 christos on the first 4 bit nibble. 1619 1.8 christos 1620 1.8 christos Then find the first index into OPS for each of the 16 possible 1621 1.8 christos nibbles and record that into NIB_INDICES to speed up decoding. */ 1622 1.8 christos 1623 1.8 christos static void 1624 1.8 christos sort_opcodes_and_setup_nibble_indices (struct h8_opcode *ops) 1625 1.8 christos { 1626 1.8 christos const struct h8_opcode *q; 1627 1.8 christos int i; 1628 1.8 christos 1629 1.8 christos /* First sort the OPS array. */ 1630 1.8 christos for (i = 0, q = ops; q->name; q++, i++) 1631 1.8 christos ; 1632 1.8 christos qsort (ops, i, sizeof (struct h8_opcode), instruction_comparator); 1633 1.8 christos 1634 1.8 christos /* Now walk the array caching the index of the first 1635 1.8 christos occurrence of each 4 bit nibble. */ 1636 1.8 christos memset (nib_indices, -1, sizeof (nib_indices)); 1637 1.8 christos for (i = 0, q = ops; q->name; q++, i++) 1638 1.8 christos { 1639 1.8 christos int nib = q->data.nib[0]; 1640 1.8 christos 1641 1.8 christos /* Record the location of the first entry with the right 1642 1.8 christos nibble count. */ 1643 1.8 christos if (nib_indices[nib] == -1) 1644 1.8 christos nib_indices[nib] = i; 1645 1.8 christos } 1646 1.8 christos } 1647 1.8 christos 1648 1.8 christos 1649 1.1 christos /* Flag to be set whenever a new SIM_DESC object is created. */ 1650 1.1 christos static int init_pointers_needed = 1; 1651 1.1 christos 1652 1.1 christos static void 1653 1.1 christos init_pointers (SIM_DESC sd) 1654 1.1 christos { 1655 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0); 1656 1.7 christos struct h8300_sim_state *state = H8300_SIM_STATE (sd); 1657 1.7 christos 1658 1.1 christos if (init_pointers_needed) 1659 1.1 christos { 1660 1.1 christos int i; 1661 1.1 christos 1662 1.1 christos if (h8300smode && !h8300_normal_mode) 1663 1.1 christos memory_size = H8300S_MSIZE; 1664 1.1 christos else if (h8300hmode && !h8300_normal_mode) 1665 1.1 christos memory_size = H8300H_MSIZE; 1666 1.1 christos else 1667 1.1 christos memory_size = H8300_MSIZE; 1668 1.1 christos /* `msize' must be a power of two. */ 1669 1.1 christos if ((memory_size & (memory_size - 1)) != 0) 1670 1.1 christos { 1671 1.6 christos sim_io_printf 1672 1.6 christos (sd, 1673 1.1 christos "init_pointers: bad memory size %d, defaulting to %d.\n", 1674 1.7 christos memory_size, H8300S_MSIZE); 1675 1.7 christos memory_size = H8300S_MSIZE; 1676 1.1 christos } 1677 1.1 christos 1678 1.7 christos if (h8_get_memory_buf (cpu)) 1679 1.7 christos free (h8_get_memory_buf (cpu)); 1680 1.1 christos 1681 1.7 christos h8_set_memory_buf (cpu, (unsigned char *) 1682 1.1 christos calloc (sizeof (char), memory_size)); 1683 1.7 christos state->memory_size = memory_size; 1684 1.1 christos 1685 1.7 christos h8_set_mask (cpu, memory_size - 1); 1686 1.1 christos 1687 1.8 christos memset (h8_get_reg_buf (cpu), 0, sizeof (H8300_SIM_CPU (cpu)->regs)); 1688 1.1 christos 1689 1.1 christos for (i = 0; i < 8; i++) 1690 1.1 christos { 1691 1.1 christos /* FIXME: rewrite using local buffer. */ 1692 1.7 christos unsigned char *p = (unsigned char *) (h8_get_reg_buf (cpu) + i); 1693 1.7 christos unsigned char *e = (unsigned char *) (h8_get_reg_buf (cpu) + i + 1); 1694 1.7 christos unsigned short *q = (unsigned short *) (h8_get_reg_buf (cpu) + i); 1695 1.7 christos unsigned short *u = (unsigned short *) (h8_get_reg_buf (cpu) + i + 1); 1696 1.7 christos h8_set_reg (cpu, i, 0x00112233); 1697 1.1 christos 1698 1.1 christos while (p < e) 1699 1.1 christos { 1700 1.1 christos if (*p == 0x22) 1701 1.1 christos breg[i] = p; 1702 1.1 christos if (*p == 0x33) 1703 1.1 christos breg[i + 8] = p; 1704 1.1 christos if (*p == 0x11) 1705 1.1 christos breg[i + 16] = p; 1706 1.1 christos if (*p == 0x00) 1707 1.1 christos breg[i + 24] = p; 1708 1.1 christos p++; 1709 1.1 christos } 1710 1.1 christos 1711 1.1 christos wreg[i] = wreg[i + 8] = 0; 1712 1.1 christos while (q < u) 1713 1.1 christos { 1714 1.1 christos if (*q == 0x2233) 1715 1.1 christos { 1716 1.1 christos wreg[i] = q; 1717 1.1 christos } 1718 1.1 christos if (*q == 0x0011) 1719 1.1 christos { 1720 1.1 christos wreg[i + 8] = q; 1721 1.1 christos } 1722 1.1 christos q++; 1723 1.1 christos } 1724 1.1 christos 1725 1.1 christos if (wreg[i] == 0 || wreg[i + 8] == 0) 1726 1.6 christos sim_io_printf (sd, "init_pointers: internal error.\n"); 1727 1.1 christos 1728 1.7 christos h8_set_reg (cpu, i, 0); 1729 1.1 christos } 1730 1.1 christos 1731 1.8 christos /* Sort the opcode table and create indices to speed up decode. */ 1732 1.8 christos sort_opcodes_and_setup_nibble_indices (ops); 1733 1.8 christos 1734 1.1 christos init_pointers_needed = 0; 1735 1.1 christos } 1736 1.1 christos } 1737 1.1 christos 1738 1.1 christos #define OBITOP(name, f, s, op) \ 1739 1.1 christos case O (name, SB): \ 1740 1.1 christos { \ 1741 1.8 christos int m; \ 1742 1.1 christos \ 1743 1.1 christos if (f) \ 1744 1.1 christos if (fetch (sd, &code->dst, &ea)) \ 1745 1.1 christos goto end; \ 1746 1.1 christos if (fetch (sd, &code->src, &tmp)) \ 1747 1.1 christos goto end; \ 1748 1.1 christos m = 1 << (tmp & 7); \ 1749 1.1 christos op; \ 1750 1.1 christos if (s) \ 1751 1.1 christos if (store (sd, &code->dst,ea)) \ 1752 1.1 christos goto end; \ 1753 1.1 christos goto next; \ 1754 1.1 christos } 1755 1.1 christos 1756 1.6 christos static void 1757 1.6 christos step_once (SIM_DESC sd, SIM_CPU *cpu) 1758 1.1 christos { 1759 1.1 christos int cycles = 0; 1760 1.1 christos int insts = 0; 1761 1.1 christos int tick_start = get_now (); 1762 1.1 christos int res; 1763 1.1 christos int tmp; 1764 1.1 christos int rd; 1765 1.1 christos int ea; 1766 1.1 christos int bit; 1767 1.1 christos int pc; 1768 1.1 christos int c, nz, v, n, u, h, ui, intMaskBit; 1769 1.7 christos int trace = 0; 1770 1.7 christos int intMask = 0; 1771 1.1 christos int oldmask; 1772 1.6 christos host_callback *sim_callback = STATE_CALLBACK (sd); 1773 1.1 christos 1774 1.1 christos init_pointers (sd); 1775 1.1 christos 1776 1.7 christos pc = cpu_get_pc (cpu); 1777 1.1 christos 1778 1.1 christos /* The PC should never be odd. */ 1779 1.1 christos if (pc & 0x1) 1780 1.1 christos { 1781 1.6 christos sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGBUS); 1782 1.1 christos return; 1783 1.1 christos } 1784 1.1 christos 1785 1.1 christos /* Get Status Register (flags). */ 1786 1.7 christos GETSR (cpu); 1787 1.1 christos 1788 1.1 christos if (h8300smode) /* Get exr. */ 1789 1.1 christos { 1790 1.7 christos trace = (h8_get_exr (cpu) >> 7) & 1; 1791 1.7 christos intMask = h8_get_exr (cpu) & 7; 1792 1.1 christos } 1793 1.1 christos 1794 1.7 christos oldmask = h8_get_mask (cpu); 1795 1.1 christos if (!h8300hmode || h8300_normal_mode) 1796 1.7 christos h8_set_mask (cpu, 0xffff); 1797 1.1 christos do 1798 1.1 christos { 1799 1.7 christos decoded_inst _code, *code = &_code; 1800 1.7 christos memset (code, 0, sizeof (*code)); 1801 1.7 christos decode (sd, cpu, pc, h8_get_memory_buf (cpu) + pc, code); 1802 1.7 christos code->oldpc = pc; 1803 1.1 christos 1804 1.1 christos #if ADEBUG 1805 1.1 christos if (debug) 1806 1.1 christos { 1807 1.1 christos printf ("%x %d %s\n", pc, code->opcode, 1808 1.1 christos code->op ? code->op->name : "**"); 1809 1.1 christos } 1810 1.1 christos h8_increment_stats (sd, code->opcode); 1811 1.1 christos #endif 1812 1.1 christos 1813 1.1 christos if (code->opcode) 1814 1.1 christos { 1815 1.1 christos cycles += code->cycles; 1816 1.1 christos insts++; 1817 1.1 christos } 1818 1.1 christos 1819 1.1 christos switch (code->opcode) 1820 1.1 christos { 1821 1.1 christos case O (O_MOVAB, SL): 1822 1.1 christos case O (O_MOVAW, SL): 1823 1.1 christos case O (O_MOVAL, SL): 1824 1.1 christos /* 1) Evaluate 2nd argument (dst). 1825 1.1 christos 2) Mask / zero extend according to whether 1st argument (src) 1826 1.1 christos is INDEXB, INDEXW, or INDEXL. 1827 1.1 christos 3) Left-shift the result by 0, 1 or 2, according to size of mova 1828 1.1 christos (mova/b, mova/w, mova/l). 1829 1.1 christos 4) Add literal value of 1st argument (src). 1830 1.1 christos 5) Store result in 3rd argument (op3). 1831 1.1 christos */ 1832 1.1 christos 1833 1.1 christos /* Alas, since this is the only instruction with 3 arguments, 1834 1.1 christos decode doesn't handle them very well. Some fix-up is required. 1835 1.1 christos 1836 1.1 christos a) The size of dst is determined by whether src is 1837 1.1 christos INDEXB or INDEXW. */ 1838 1.1 christos 1839 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB) 1840 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SB); 1841 1.1 christos else if (OP_KIND (code->src.type) == OP_INDEXW) 1842 1.1 christos code->dst.type = X (OP_KIND (code->dst.type), SW); 1843 1.1 christos 1844 1.1 christos /* b) If op3 == null, then this is the short form of the insn. 1845 1.1 christos Dst is the dispreg of src, and op3 is the 32-bit form 1846 1.1 christos of the same register. 1847 1.1 christos */ 1848 1.1 christos 1849 1.7 christos if (code->op3.type == -1) 1850 1.1 christos { 1851 1.1 christos /* Short form: src == INDEXB/INDEXW, dst == op3 == 0. 1852 1.1 christos We get to compose dst and op3 as follows: 1853 1.1 christos 1854 1.1 christos op3 is a 32-bit register, ID == src.reg. 1855 1.1 christos dst is the same register, but 8 or 16 bits 1856 1.1 christos depending on whether src is INDEXB or INDEXW. 1857 1.1 christos */ 1858 1.1 christos 1859 1.1 christos code->op3.type = X (OP_REG, SL); 1860 1.1 christos code->op3.reg = code->src.reg; 1861 1.1 christos code->op3.literal = 0; 1862 1.1 christos 1863 1.1 christos if (OP_KIND (code->src.type) == OP_INDEXB) 1864 1.1 christos { 1865 1.1 christos code->dst.type = X (OP_REG, SB); 1866 1.1 christos code->dst.reg = code->op3.reg + 8; 1867 1.1 christos } 1868 1.1 christos else 1869 1.1 christos code->dst.type = X (OP_REG, SW); 1870 1.1 christos } 1871 1.1 christos 1872 1.1 christos if (fetch (sd, &code->dst, &ea)) 1873 1.1 christos goto end; 1874 1.1 christos 1875 1.1 christos switch (OP_KIND (code->src.type)) { 1876 1.1 christos case OP_INDEXB: ea = ea & 0xff; break; 1877 1.1 christos case OP_INDEXW: ea = ea & 0xffff; break; 1878 1.1 christos case OP_INDEXL: break; 1879 1.1 christos default: goto illegal; 1880 1.1 christos } 1881 1.1 christos 1882 1.1 christos switch (code->opcode) { 1883 1.1 christos case O (O_MOVAB, SL): break; 1884 1.1 christos case O (O_MOVAW, SL): ea = ea << 1; break; 1885 1.1 christos case O (O_MOVAL, SL): ea = ea << 2; break; 1886 1.1 christos default: goto illegal; 1887 1.1 christos } 1888 1.1 christos 1889 1.1 christos ea = ea + code->src.literal; 1890 1.1 christos 1891 1.1 christos if (store (sd, &code->op3, ea)) 1892 1.1 christos goto end; 1893 1.1 christos 1894 1.1 christos goto next; 1895 1.1 christos 1896 1.1 christos case O (O_SUBX, SB): /* subx, extended sub */ 1897 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1898 1.1 christos goto end; 1899 1.1 christos if (fetch (sd, &code->src, &ea)) 1900 1.1 christos goto end; 1901 1.1 christos ea = -(ea + C); 1902 1.1 christos res = rd + ea; 1903 1.1 christos goto alu8; 1904 1.1 christos 1905 1.1 christos case O (O_SUBX, SW): /* subx, extended sub */ 1906 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1907 1.1 christos goto end; 1908 1.1 christos if (fetch (sd, &code->src, &ea)) 1909 1.1 christos goto end; 1910 1.1 christos ea = -(ea + C); 1911 1.1 christos res = rd + ea; 1912 1.1 christos goto alu16; 1913 1.1 christos 1914 1.1 christos case O (O_SUBX, SL): /* subx, extended sub */ 1915 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1916 1.1 christos goto end; 1917 1.1 christos if (fetch (sd, &code->src, &ea)) 1918 1.1 christos goto end; 1919 1.1 christos ea = -(ea + C); 1920 1.1 christos res = rd + ea; 1921 1.1 christos goto alu32; 1922 1.1 christos 1923 1.1 christos case O (O_ADDX, SB): /* addx, extended add */ 1924 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1925 1.1 christos goto end; 1926 1.1 christos if (fetch (sd, &code->src, &ea)) 1927 1.1 christos goto end; 1928 1.1 christos ea = ea + C; 1929 1.1 christos res = rd + ea; 1930 1.1 christos goto alu8; 1931 1.1 christos 1932 1.1 christos case O (O_ADDX, SW): /* addx, extended add */ 1933 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1934 1.1 christos goto end; 1935 1.1 christos if (fetch (sd, &code->src, &ea)) 1936 1.1 christos goto end; 1937 1.1 christos ea = ea + C; 1938 1.1 christos res = rd + ea; 1939 1.1 christos goto alu16; 1940 1.1 christos 1941 1.1 christos case O (O_ADDX, SL): /* addx, extended add */ 1942 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 1943 1.1 christos goto end; 1944 1.1 christos if (fetch (sd, &code->src, &ea)) 1945 1.1 christos goto end; 1946 1.1 christos ea = ea + C; 1947 1.1 christos res = rd + ea; 1948 1.1 christos goto alu32; 1949 1.1 christos 1950 1.1 christos case O (O_SUB, SB): /* sub.b */ 1951 1.1 christos /* Fetch rd and ea. */ 1952 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 1953 1.1 christos goto end; 1954 1.1 christos ea = -ea; 1955 1.1 christos res = rd + ea; 1956 1.1 christos goto alu8; 1957 1.1 christos 1958 1.1 christos case O (O_SUB, SW): /* sub.w */ 1959 1.1 christos /* Fetch rd and ea. */ 1960 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 1961 1.1 christos goto end; 1962 1.1 christos ea = -ea; 1963 1.1 christos res = rd + ea; 1964 1.1 christos goto alu16; 1965 1.1 christos 1966 1.1 christos case O (O_SUB, SL): /* sub.l */ 1967 1.1 christos /* Fetch rd and ea. */ 1968 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 1969 1.1 christos goto end; 1970 1.1 christos ea = -ea; 1971 1.1 christos res = rd + ea; 1972 1.1 christos goto alu32; 1973 1.1 christos 1974 1.1 christos case O (O_NEG, SB): /* neg.b */ 1975 1.1 christos /* Fetch ea. */ 1976 1.1 christos if (fetch2 (sd, &code->src, &ea)) 1977 1.1 christos goto end; 1978 1.1 christos ea = -ea; 1979 1.1 christos rd = 0; 1980 1.1 christos res = rd + ea; 1981 1.1 christos goto alu8; 1982 1.1 christos 1983 1.1 christos case O (O_NEG, SW): /* neg.w */ 1984 1.1 christos /* Fetch ea. */ 1985 1.1 christos if (fetch2 (sd, &code->src, &ea)) 1986 1.1 christos goto end; 1987 1.1 christos ea = -ea; 1988 1.1 christos rd = 0; 1989 1.1 christos res = rd + ea; 1990 1.1 christos goto alu16; 1991 1.1 christos 1992 1.1 christos case O (O_NEG, SL): /* neg.l */ 1993 1.1 christos /* Fetch ea. */ 1994 1.1 christos if (fetch2 (sd, &code->src, &ea)) 1995 1.1 christos goto end; 1996 1.1 christos ea = -ea; 1997 1.1 christos rd = 0; 1998 1.1 christos res = rd + ea; 1999 1.1 christos goto alu32; 2000 1.1 christos 2001 1.1 christos case O (O_ADD, SB): /* add.b */ 2002 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 2003 1.1 christos goto end; 2004 1.1 christos if (fetch (sd, &code->src, &ea)) 2005 1.1 christos goto end; 2006 1.1 christos res = rd + ea; 2007 1.1 christos goto alu8; 2008 1.1 christos 2009 1.1 christos case O (O_ADD, SW): /* add.w */ 2010 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 2011 1.1 christos goto end; 2012 1.1 christos if (fetch (sd, &code->src, &ea)) 2013 1.1 christos goto end; 2014 1.1 christos res = rd + ea; 2015 1.1 christos goto alu16; 2016 1.1 christos 2017 1.1 christos case O (O_ADD, SL): /* add.l */ 2018 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 2019 1.1 christos goto end; 2020 1.1 christos if (fetch (sd, &code->src, &ea)) 2021 1.1 christos goto end; 2022 1.1 christos res = rd + ea; 2023 1.1 christos goto alu32; 2024 1.1 christos 2025 1.1 christos case O (O_AND, SB): /* and.b */ 2026 1.1 christos /* Fetch rd and ea. */ 2027 1.7 christos if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea)) 2028 1.1 christos goto end; 2029 1.1 christos res = rd & ea; 2030 1.1 christos goto log8; 2031 1.1 christos 2032 1.1 christos case O (O_AND, SW): /* and.w */ 2033 1.1 christos /* Fetch rd and ea. */ 2034 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2035 1.1 christos goto end; 2036 1.1 christos res = rd & ea; 2037 1.1 christos goto log16; 2038 1.1 christos 2039 1.1 christos case O (O_AND, SL): /* and.l */ 2040 1.1 christos /* Fetch rd and ea. */ 2041 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2042 1.1 christos goto end; 2043 1.1 christos res = rd & ea; 2044 1.1 christos goto log32; 2045 1.1 christos 2046 1.1 christos case O (O_OR, SB): /* or.b */ 2047 1.1 christos /* Fetch rd and ea. */ 2048 1.7 christos if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea)) 2049 1.1 christos goto end; 2050 1.1 christos res = rd | ea; 2051 1.1 christos goto log8; 2052 1.1 christos 2053 1.1 christos case O (O_OR, SW): /* or.w */ 2054 1.1 christos /* Fetch rd and ea. */ 2055 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2056 1.1 christos goto end; 2057 1.1 christos res = rd | ea; 2058 1.1 christos goto log16; 2059 1.1 christos 2060 1.1 christos case O (O_OR, SL): /* or.l */ 2061 1.1 christos /* Fetch rd and ea. */ 2062 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2063 1.1 christos goto end; 2064 1.1 christos res = rd | ea; 2065 1.1 christos goto log32; 2066 1.1 christos 2067 1.1 christos case O (O_XOR, SB): /* xor.b */ 2068 1.1 christos /* Fetch rd and ea. */ 2069 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2070 1.1 christos goto end; 2071 1.1 christos res = rd ^ ea; 2072 1.1 christos goto log8; 2073 1.1 christos 2074 1.1 christos case O (O_XOR, SW): /* xor.w */ 2075 1.1 christos /* Fetch rd and ea. */ 2076 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2077 1.1 christos goto end; 2078 1.1 christos res = rd ^ ea; 2079 1.1 christos goto log16; 2080 1.1 christos 2081 1.1 christos case O (O_XOR, SL): /* xor.l */ 2082 1.1 christos /* Fetch rd and ea. */ 2083 1.1 christos if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 2084 1.1 christos goto end; 2085 1.1 christos res = rd ^ ea; 2086 1.1 christos goto log32; 2087 1.1 christos 2088 1.1 christos case O (O_MOV, SB): 2089 1.1 christos if (fetch (sd, &code->src, &res)) 2090 1.1 christos goto end; 2091 1.1 christos if (store (sd, &code->dst, res)) 2092 1.1 christos goto end; 2093 1.1 christos goto just_flags_log8; 2094 1.1 christos case O (O_MOV, SW): 2095 1.1 christos if (fetch (sd, &code->src, &res)) 2096 1.1 christos goto end; 2097 1.1 christos if (store (sd, &code->dst, res)) 2098 1.1 christos goto end; 2099 1.1 christos goto just_flags_log16; 2100 1.1 christos case O (O_MOV, SL): 2101 1.1 christos if (fetch (sd, &code->src, &res)) 2102 1.1 christos goto end; 2103 1.1 christos if (store (sd, &code->dst, res)) 2104 1.1 christos goto end; 2105 1.1 christos goto just_flags_log32; 2106 1.1 christos 2107 1.1 christos case O (O_MOVMD, SB): /* movmd.b */ 2108 1.1 christos ea = GET_W_REG (4); 2109 1.1 christos if (ea == 0) 2110 1.1 christos ea = 0x10000; 2111 1.1 christos 2112 1.1 christos while (ea--) 2113 1.1 christos { 2114 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5)); 2115 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd); 2116 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1); 2117 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1); 2118 1.1 christos SET_W_REG (4, ea); 2119 1.1 christos } 2120 1.1 christos goto next; 2121 1.1 christos 2122 1.1 christos case O (O_MOVMD, SW): /* movmd.w */ 2123 1.1 christos ea = GET_W_REG (4); 2124 1.1 christos if (ea == 0) 2125 1.1 christos ea = 0x10000; 2126 1.1 christos 2127 1.1 christos while (ea--) 2128 1.1 christos { 2129 1.1 christos rd = GET_MEMORY_W (GET_L_REG (5)); 2130 1.1 christos SET_MEMORY_W (GET_L_REG (6), rd); 2131 1.1 christos SET_L_REG (5, GET_L_REG (5) + 2); 2132 1.1 christos SET_L_REG (6, GET_L_REG (6) + 2); 2133 1.1 christos SET_W_REG (4, ea); 2134 1.1 christos } 2135 1.1 christos goto next; 2136 1.1 christos 2137 1.1 christos case O (O_MOVMD, SL): /* movmd.l */ 2138 1.1 christos ea = GET_W_REG (4); 2139 1.1 christos if (ea == 0) 2140 1.1 christos ea = 0x10000; 2141 1.1 christos 2142 1.1 christos while (ea--) 2143 1.1 christos { 2144 1.1 christos rd = GET_MEMORY_L (GET_L_REG (5)); 2145 1.1 christos SET_MEMORY_L (GET_L_REG (6), rd); 2146 1.1 christos SET_L_REG (5, GET_L_REG (5) + 4); 2147 1.1 christos SET_L_REG (6, GET_L_REG (6) + 4); 2148 1.1 christos SET_W_REG (4, ea); 2149 1.1 christos } 2150 1.1 christos goto next; 2151 1.1 christos 2152 1.1 christos case O (O_MOVSD, SB): /* movsd.b */ 2153 1.1 christos /* This instruction implements strncpy, with a conditional branch. 2154 1.1 christos r4 contains n, r5 contains src, and r6 contains dst. 2155 1.1 christos The 16-bit displacement operand is added to the pc 2156 1.1 christos if and only if the end of string is reached before 2157 1.1 christos n bytes are transferred. */ 2158 1.1 christos 2159 1.1 christos ea = GET_L_REG (4) & 0xffff; 2160 1.1 christos if (ea == 0) 2161 1.1 christos ea = 0x10000; 2162 1.1 christos 2163 1.1 christos while (ea--) 2164 1.1 christos { 2165 1.1 christos rd = GET_MEMORY_B (GET_L_REG (5)); 2166 1.1 christos SET_MEMORY_B (GET_L_REG (6), rd); 2167 1.1 christos SET_L_REG (5, GET_L_REG (5) + 1); 2168 1.1 christos SET_L_REG (6, GET_L_REG (6) + 1); 2169 1.1 christos SET_W_REG (4, ea); 2170 1.1 christos if (rd == 0) 2171 1.1 christos goto condtrue; 2172 1.1 christos } 2173 1.1 christos goto next; 2174 1.1 christos 2175 1.1 christos case O (O_EEPMOV, SB): /* eepmov.b */ 2176 1.1 christos case O (O_EEPMOV, SW): /* eepmov.w */ 2177 1.1 christos if (h8300hmode || h8300smode) 2178 1.1 christos { 2179 1.1 christos register unsigned char *_src, *_dst; 2180 1.1 christos unsigned int count = ((code->opcode == O (O_EEPMOV, SW)) 2181 1.7 christos ? h8_get_reg (cpu, R4_REGNUM) & 0xffff 2182 1.7 christos : h8_get_reg (cpu, R4_REGNUM) & 0xff); 2183 1.1 christos 2184 1.7 christos _src = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R5_REGNUM); 2185 1.7 christos if ((_src + count) >= (h8_get_memory_buf (cpu) + memory_size)) 2186 1.7 christos goto illegal; 2187 1.7 christos _dst = h8_get_memory_buf (cpu) + h8_get_reg (cpu, R6_REGNUM); 2188 1.7 christos if ((_dst + count) >= (h8_get_memory_buf (cpu) + memory_size)) 2189 1.7 christos goto illegal; 2190 1.1 christos memcpy (_dst, _src, count); 2191 1.1 christos 2192 1.7 christos h8_set_reg (cpu, R5_REGNUM, h8_get_reg (cpu, R5_REGNUM) + count); 2193 1.7 christos h8_set_reg (cpu, R6_REGNUM, h8_get_reg (cpu, R6_REGNUM) + count); 2194 1.7 christos h8_set_reg (cpu, R4_REGNUM, h8_get_reg (cpu, R4_REGNUM) & 2195 1.1 christos ((code->opcode == O (O_EEPMOV, SW)) 2196 1.1 christos ? (~0xffff) : (~0xff))); 2197 1.1 christos cycles += 2 * count; 2198 1.1 christos goto next; 2199 1.1 christos } 2200 1.1 christos goto illegal; 2201 1.1 christos 2202 1.1 christos case O (O_ADDS, SL): /* adds (.l) */ 2203 1.1 christos /* FIXME fetch. 2204 1.1 christos * This insn only uses register operands, but still 2205 1.1 christos * it would be cleaner to use fetch and store... */ 2206 1.1 christos SET_L_REG (code->dst.reg, 2207 1.1 christos GET_L_REG (code->dst.reg) 2208 1.1 christos + code->src.literal); 2209 1.1 christos 2210 1.1 christos goto next; 2211 1.1 christos 2212 1.1 christos case O (O_SUBS, SL): /* subs (.l) */ 2213 1.1 christos /* FIXME fetch. 2214 1.1 christos * This insn only uses register operands, but still 2215 1.1 christos * it would be cleaner to use fetch and store... */ 2216 1.1 christos SET_L_REG (code->dst.reg, 2217 1.1 christos GET_L_REG (code->dst.reg) 2218 1.1 christos - code->src.literal); 2219 1.1 christos goto next; 2220 1.1 christos 2221 1.1 christos case O (O_CMP, SB): /* cmp.b */ 2222 1.1 christos if (fetch (sd, &code->dst, &rd)) 2223 1.1 christos goto end; 2224 1.1 christos if (fetch (sd, &code->src, &ea)) 2225 1.1 christos goto end; 2226 1.1 christos ea = -ea; 2227 1.1 christos res = rd + ea; 2228 1.1 christos goto just_flags_alu8; 2229 1.1 christos 2230 1.1 christos case O (O_CMP, SW): /* cmp.w */ 2231 1.1 christos if (fetch (sd, &code->dst, &rd)) 2232 1.1 christos goto end; 2233 1.1 christos if (fetch (sd, &code->src, &ea)) 2234 1.1 christos goto end; 2235 1.1 christos ea = -ea; 2236 1.1 christos res = rd + ea; 2237 1.1 christos goto just_flags_alu16; 2238 1.1 christos 2239 1.1 christos case O (O_CMP, SL): /* cmp.l */ 2240 1.1 christos if (fetch (sd, &code->dst, &rd)) 2241 1.1 christos goto end; 2242 1.1 christos if (fetch (sd, &code->src, &ea)) 2243 1.1 christos goto end; 2244 1.1 christos ea = -ea; 2245 1.1 christos res = rd + ea; 2246 1.1 christos goto just_flags_alu32; 2247 1.1 christos 2248 1.1 christos case O (O_DEC, SB): /* dec.b */ 2249 1.1 christos /* FIXME fetch. 2250 1.1 christos * This insn only uses register operands, but still 2251 1.1 christos * it would be cleaner to use fetch and store... */ 2252 1.1 christos rd = GET_B_REG (code->src.reg); 2253 1.1 christos ea = -1; 2254 1.1 christos res = rd + ea; 2255 1.1 christos SET_B_REG (code->src.reg, res); 2256 1.1 christos goto just_flags_inc8; 2257 1.1 christos 2258 1.1 christos case O (O_DEC, SW): /* dec.w */ 2259 1.1 christos /* FIXME fetch. 2260 1.1 christos * This insn only uses register operands, but still 2261 1.1 christos * it would be cleaner to use fetch and store... */ 2262 1.1 christos rd = GET_W_REG (code->dst.reg); 2263 1.1 christos ea = -code->src.literal; 2264 1.1 christos res = rd + ea; 2265 1.1 christos SET_W_REG (code->dst.reg, res); 2266 1.1 christos goto just_flags_inc16; 2267 1.1 christos 2268 1.1 christos case O (O_DEC, SL): /* dec.l */ 2269 1.1 christos /* FIXME fetch. 2270 1.1 christos * This insn only uses register operands, but still 2271 1.1 christos * it would be cleaner to use fetch and store... */ 2272 1.1 christos rd = GET_L_REG (code->dst.reg); 2273 1.1 christos ea = -code->src.literal; 2274 1.1 christos res = rd + ea; 2275 1.1 christos SET_L_REG (code->dst.reg, res); 2276 1.1 christos goto just_flags_inc32; 2277 1.1 christos 2278 1.1 christos case O (O_INC, SB): /* inc.b */ 2279 1.1 christos /* FIXME fetch. 2280 1.1 christos * This insn only uses register operands, but still 2281 1.1 christos * it would be cleaner to use fetch and store... */ 2282 1.1 christos rd = GET_B_REG (code->src.reg); 2283 1.1 christos ea = 1; 2284 1.1 christos res = rd + ea; 2285 1.1 christos SET_B_REG (code->src.reg, res); 2286 1.1 christos goto just_flags_inc8; 2287 1.1 christos 2288 1.1 christos case O (O_INC, SW): /* inc.w */ 2289 1.1 christos /* FIXME fetch. 2290 1.1 christos * This insn only uses register operands, but still 2291 1.1 christos * it would be cleaner to use fetch and store... */ 2292 1.1 christos rd = GET_W_REG (code->dst.reg); 2293 1.1 christos ea = code->src.literal; 2294 1.1 christos res = rd + ea; 2295 1.1 christos SET_W_REG (code->dst.reg, res); 2296 1.1 christos goto just_flags_inc16; 2297 1.1 christos 2298 1.1 christos case O (O_INC, SL): /* inc.l */ 2299 1.1 christos /* FIXME fetch. 2300 1.1 christos * This insn only uses register operands, but still 2301 1.1 christos * it would be cleaner to use fetch and store... */ 2302 1.1 christos rd = GET_L_REG (code->dst.reg); 2303 1.1 christos ea = code->src.literal; 2304 1.1 christos res = rd + ea; 2305 1.1 christos SET_L_REG (code->dst.reg, res); 2306 1.1 christos goto just_flags_inc32; 2307 1.1 christos 2308 1.1 christos case O (O_LDC, SB): /* ldc.b */ 2309 1.1 christos if (fetch (sd, &code->src, &res)) 2310 1.1 christos goto end; 2311 1.1 christos goto setc; 2312 1.1 christos 2313 1.1 christos case O (O_LDC, SW): /* ldc.w */ 2314 1.1 christos if (fetch (sd, &code->src, &res)) 2315 1.1 christos goto end; 2316 1.1 christos 2317 1.1 christos /* Word operand, value from MSB, must be shifted. */ 2318 1.1 christos res >>= 8; 2319 1.1 christos goto setc; 2320 1.1 christos 2321 1.1 christos case O (O_LDC, SL): /* ldc.l */ 2322 1.1 christos if (fetch (sd, &code->src, &res)) 2323 1.1 christos goto end; 2324 1.1 christos switch (code->dst.type) { 2325 1.1 christos case X (OP_SBR, SL): 2326 1.7 christos h8_set_sbr (cpu, res); 2327 1.1 christos break; 2328 1.1 christos case X (OP_VBR, SL): 2329 1.7 christos h8_set_vbr (cpu, res); 2330 1.1 christos break; 2331 1.1 christos default: 2332 1.1 christos goto illegal; 2333 1.1 christos } 2334 1.1 christos goto next; 2335 1.1 christos 2336 1.1 christos case O (O_STC, SW): /* stc.w */ 2337 1.1 christos case O (O_STC, SB): /* stc.b */ 2338 1.1 christos if (code->src.type == X (OP_CCR, SB)) 2339 1.1 christos { 2340 1.7 christos BUILDSR (cpu); 2341 1.7 christos res = h8_get_ccr (cpu); 2342 1.1 christos } 2343 1.1 christos else if (code->src.type == X (OP_EXR, SB) && h8300smode) 2344 1.1 christos { 2345 1.1 christos if (h8300smode) 2346 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask); 2347 1.7 christos res = h8_get_exr (cpu); 2348 1.1 christos } 2349 1.1 christos else 2350 1.1 christos goto illegal; 2351 1.1 christos 2352 1.1 christos /* Word operand, value to MSB, must be shifted. */ 2353 1.1 christos if (code->opcode == X (O_STC, SW)) 2354 1.1 christos res <<= 8; 2355 1.1 christos if (store (sd, &code->dst, res)) 2356 1.1 christos goto end; 2357 1.1 christos goto next; 2358 1.1 christos case O (O_STC, SL): /* stc.l */ 2359 1.1 christos switch (code->src.type) { 2360 1.1 christos case X (OP_SBR, SL): 2361 1.7 christos res = h8_get_sbr (cpu); 2362 1.1 christos break; 2363 1.1 christos case X (OP_VBR, SL): 2364 1.7 christos res = h8_get_vbr (cpu); 2365 1.1 christos break; 2366 1.1 christos default: 2367 1.1 christos goto illegal; 2368 1.1 christos } 2369 1.1 christos if (store (sd, &code->dst, res)) 2370 1.1 christos goto end; 2371 1.1 christos goto next; 2372 1.1 christos 2373 1.1 christos case O (O_ANDC, SB): /* andc.b */ 2374 1.1 christos if (code->dst.type == X (OP_CCR, SB)) 2375 1.1 christos { 2376 1.7 christos BUILDSR (cpu); 2377 1.7 christos rd = h8_get_ccr (cpu); 2378 1.1 christos } 2379 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode) 2380 1.1 christos { 2381 1.1 christos if (h8300smode) 2382 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask); 2383 1.7 christos rd = h8_get_exr (cpu); 2384 1.1 christos } 2385 1.1 christos else 2386 1.1 christos goto illegal; 2387 1.1 christos ea = code->src.literal; 2388 1.1 christos res = rd & ea; 2389 1.1 christos goto setc; 2390 1.1 christos 2391 1.1 christos case O (O_ORC, SB): /* orc.b */ 2392 1.1 christos if (code->dst.type == X (OP_CCR, SB)) 2393 1.1 christos { 2394 1.7 christos BUILDSR (cpu); 2395 1.7 christos rd = h8_get_ccr (cpu); 2396 1.1 christos } 2397 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode) 2398 1.1 christos { 2399 1.1 christos if (h8300smode) 2400 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask); 2401 1.7 christos rd = h8_get_exr (cpu); 2402 1.1 christos } 2403 1.1 christos else 2404 1.1 christos goto illegal; 2405 1.1 christos ea = code->src.literal; 2406 1.1 christos res = rd | ea; 2407 1.1 christos goto setc; 2408 1.1 christos 2409 1.1 christos case O (O_XORC, SB): /* xorc.b */ 2410 1.1 christos if (code->dst.type == X (OP_CCR, SB)) 2411 1.1 christos { 2412 1.7 christos BUILDSR (cpu); 2413 1.7 christos rd = h8_get_ccr (cpu); 2414 1.1 christos } 2415 1.1 christos else if (code->dst.type == X (OP_EXR, SB) && h8300smode) 2416 1.1 christos { 2417 1.1 christos if (h8300smode) 2418 1.7 christos h8_set_exr (cpu, (trace << 7) | intMask); 2419 1.7 christos rd = h8_get_exr (cpu); 2420 1.1 christos } 2421 1.1 christos else 2422 1.1 christos goto illegal; 2423 1.1 christos ea = code->src.literal; 2424 1.1 christos res = rd ^ ea; 2425 1.1 christos goto setc; 2426 1.1 christos 2427 1.1 christos case O (O_BRAS, SB): /* bra/s */ 2428 1.1 christos /* This is basically an ordinary branch, with a delay slot. */ 2429 1.1 christos if (fetch (sd, &code->src, &res)) 2430 1.1 christos goto end; 2431 1.1 christos 2432 1.1 christos if ((res & 1) == 0) 2433 1.1 christos goto illegal; 2434 1.1 christos 2435 1.1 christos res -= 1; 2436 1.1 christos 2437 1.1 christos /* Execution continues at next instruction, but 2438 1.1 christos delayed_branch is set up for next cycle. */ 2439 1.7 christos h8_set_delayed_branch (cpu, code->next_pc + res); 2440 1.1 christos pc = code->next_pc; 2441 1.1 christos goto end; 2442 1.1 christos 2443 1.1 christos case O (O_BRAB, SB): /* bra rd.b */ 2444 1.1 christos case O (O_BRAW, SW): /* bra rd.w */ 2445 1.1 christos case O (O_BRAL, SL): /* bra erd.l */ 2446 1.1 christos if (fetch (sd, &code->src, &rd)) 2447 1.1 christos goto end; 2448 1.1 christos switch (OP_SIZE (code->opcode)) { 2449 1.1 christos case SB: rd &= 0xff; break; 2450 1.1 christos case SW: rd &= 0xffff; break; 2451 1.1 christos case SL: rd &= 0xffffffff; break; 2452 1.1 christos } 2453 1.1 christos pc = code->next_pc + rd; 2454 1.1 christos goto end; 2455 1.1 christos 2456 1.1 christos case O (O_BRABC, SB): /* bra/bc, branch if bit clear */ 2457 1.1 christos case O (O_BRABS, SB): /* bra/bs, branch if bit set */ 2458 1.1 christos case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */ 2459 1.1 christos case O (O_BSRBS, SB): /* bsr/bs, call if bit set */ 2460 1.1 christos if (fetch (sd, &code->dst, &rd) || 2461 1.1 christos fetch (sd, &code->src, &bit)) 2462 1.1 christos goto end; 2463 1.1 christos 2464 1.1 christos if (code->opcode == O (O_BRABC, SB) || /* branch if clear */ 2465 1.1 christos code->opcode == O (O_BSRBC, SB)) /* call if clear */ 2466 1.1 christos { 2467 1.1 christos if ((rd & (1 << bit))) /* no branch */ 2468 1.1 christos goto next; 2469 1.1 christos } 2470 1.1 christos else /* branch/call if set */ 2471 1.1 christos { 2472 1.1 christos if (!(rd & (1 << bit))) /* no branch */ 2473 1.1 christos goto next; 2474 1.1 christos } 2475 1.1 christos 2476 1.1 christos if (fetch (sd, &code->op3, &res)) /* branch */ 2477 1.1 christos goto end; 2478 1.1 christos pc = code->next_pc + res; 2479 1.1 christos 2480 1.1 christos if (code->opcode == O (O_BRABC, SB) || 2481 1.1 christos code->opcode == O (O_BRABS, SB)) /* branch */ 2482 1.1 christos goto end; 2483 1.1 christos else /* call */ 2484 1.1 christos goto call; 2485 1.1 christos 2486 1.1 christos case O (O_BRA, SN): 2487 1.1 christos case O (O_BRA, SL): 2488 1.1 christos case O (O_BRA, SW): 2489 1.1 christos case O (O_BRA, SB): /* bra, branch always */ 2490 1.1 christos if (1) 2491 1.1 christos goto condtrue; 2492 1.1 christos goto next; 2493 1.1 christos 2494 1.1 christos case O (O_BRN, SB): /* brn, ;-/ branch never? */ 2495 1.1 christos if (0) 2496 1.1 christos goto condtrue; 2497 1.1 christos goto next; 2498 1.1 christos 2499 1.1 christos case O (O_BHI, SB): /* bhi */ 2500 1.1 christos if ((C || Z) == 0) 2501 1.1 christos goto condtrue; 2502 1.1 christos goto next; 2503 1.1 christos 2504 1.1 christos 2505 1.1 christos case O (O_BLS, SB): /* bls */ 2506 1.1 christos if ((C || Z)) 2507 1.1 christos goto condtrue; 2508 1.1 christos goto next; 2509 1.1 christos 2510 1.1 christos case O (O_BCS, SB): /* bcs, branch if carry set */ 2511 1.1 christos if ((C == 1)) 2512 1.1 christos goto condtrue; 2513 1.1 christos goto next; 2514 1.1 christos 2515 1.1 christos case O (O_BCC, SB): /* bcc, branch if carry clear */ 2516 1.1 christos if ((C == 0)) 2517 1.1 christos goto condtrue; 2518 1.1 christos goto next; 2519 1.1 christos 2520 1.1 christos case O (O_BEQ, SB): /* beq, branch if zero set */ 2521 1.1 christos if (Z) 2522 1.1 christos goto condtrue; 2523 1.1 christos goto next; 2524 1.1 christos case O (O_BGT, SB): /* bgt */ 2525 1.1 christos if (((Z || (N ^ V)) == 0)) 2526 1.1 christos goto condtrue; 2527 1.1 christos goto next; 2528 1.1 christos 2529 1.1 christos case O (O_BLE, SB): /* ble */ 2530 1.1 christos if (((Z || (N ^ V)) == 1)) 2531 1.1 christos goto condtrue; 2532 1.1 christos goto next; 2533 1.1 christos 2534 1.1 christos case O (O_BGE, SB): /* bge */ 2535 1.1 christos if ((N ^ V) == 0) 2536 1.1 christos goto condtrue; 2537 1.1 christos goto next; 2538 1.1 christos case O (O_BLT, SB): /* blt */ 2539 1.1 christos if ((N ^ V)) 2540 1.1 christos goto condtrue; 2541 1.1 christos goto next; 2542 1.1 christos case O (O_BMI, SB): /* bmi */ 2543 1.1 christos if ((N)) 2544 1.1 christos goto condtrue; 2545 1.1 christos goto next; 2546 1.1 christos case O (O_BNE, SB): /* bne, branch if zero clear */ 2547 1.1 christos if ((Z == 0)) 2548 1.1 christos goto condtrue; 2549 1.1 christos goto next; 2550 1.1 christos 2551 1.1 christos case O (O_BPL, SB): /* bpl */ 2552 1.1 christos if (N == 0) 2553 1.1 christos goto condtrue; 2554 1.1 christos goto next; 2555 1.1 christos case O (O_BVC, SB): /* bvc */ 2556 1.1 christos if ((V == 0)) 2557 1.1 christos goto condtrue; 2558 1.1 christos goto next; 2559 1.1 christos case O (O_BVS, SB): /* bvs */ 2560 1.1 christos if ((V == 1)) 2561 1.1 christos goto condtrue; 2562 1.1 christos goto next; 2563 1.1 christos 2564 1.1 christos /* Trap for Command Line setup. */ 2565 1.1 christos case O (O_SYS_CMDLINE, SB): 2566 1.1 christos { 2567 1.1 christos int i = 0; /* Loop counter. */ 2568 1.1 christos int j = 0; /* Loop counter. */ 2569 1.1 christos int ind_arg_len = 0; /* Length of each argument. */ 2570 1.1 christos int no_of_args = 0; /* The no. or cmdline args. */ 2571 1.1 christos int current_location = 0; /* Location of string. */ 2572 1.1 christos int old_sp = 0; /* The Initial Stack Pointer. */ 2573 1.1 christos int sp_move = 0; /* No. of locations by which the stack needs 2574 1.1 christos to grow. */ 2575 1.1 christos int new_sp = 0; /* The final stack pointer location passed 2576 1.1 christos back. */ 2577 1.1 christos int *argv_ptrs; /* Pointers of argv strings to be stored. */ 2578 1.1 christos int argv_ptrs_location = 0; /* Location of pointers to cmdline 2579 1.1 christos args on the stack. */ 2580 1.1 christos int char_ptr_size = 0; /* Size of a character pointer on 2581 1.1 christos target machine. */ 2582 1.1 christos int addr_cmdline = 0; /* Memory location where cmdline has 2583 1.1 christos to be stored. */ 2584 1.1 christos int size_cmdline = 0; /* Size of cmdline. */ 2585 1.1 christos 2586 1.1 christos /* Set the address of 256 free locations where command line is 2587 1.1 christos stored. */ 2588 1.1 christos addr_cmdline = cmdline_location(); 2589 1.7 christos h8_set_reg (cpu, 0, addr_cmdline); 2590 1.1 christos 2591 1.1 christos /* Counting the no. of commandline arguments. */ 2592 1.7 christos for (i = 0; h8_get_cmdline_arg (cpu, i) != NULL; i++) 2593 1.1 christos continue; 2594 1.1 christos 2595 1.1 christos /* No. of arguments in the command line. */ 2596 1.1 christos no_of_args = i; 2597 1.1 christos 2598 1.1 christos /* Current location is just a temporary variable,which we are 2599 1.1 christos setting to the point to the start of our commandline string. */ 2600 1.1 christos current_location = addr_cmdline; 2601 1.1 christos 2602 1.1 christos /* Allocating space for storing pointers of the command line 2603 1.1 christos arguments. */ 2604 1.1 christos argv_ptrs = (int *) malloc (sizeof (int) * no_of_args); 2605 1.1 christos 2606 1.1 christos /* Setting char_ptr_size to the sizeof (char *) on the different 2607 1.1 christos architectures. */ 2608 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode) 2609 1.1 christos { 2610 1.1 christos char_ptr_size = 4; 2611 1.1 christos } 2612 1.1 christos else 2613 1.1 christos { 2614 1.1 christos char_ptr_size = 2; 2615 1.1 christos } 2616 1.1 christos 2617 1.1 christos for (i = 0; i < no_of_args; i++) 2618 1.1 christos { 2619 1.1 christos ind_arg_len = 0; 2620 1.1 christos 2621 1.1 christos /* The size of the commandline argument. */ 2622 1.7 christos ind_arg_len = strlen (h8_get_cmdline_arg (cpu, i)) + 1; 2623 1.1 christos 2624 1.1 christos /* The total size of the command line string. */ 2625 1.1 christos size_cmdline += ind_arg_len; 2626 1.1 christos 2627 1.1 christos /* As we have only 256 bytes, we need to provide a graceful 2628 1.1 christos exit. Anyways, a program using command line arguments 2629 1.1 christos where we cannot store all the command line arguments 2630 1.1 christos given may behave unpredictably. */ 2631 1.1 christos if (size_cmdline >= 256) 2632 1.1 christos { 2633 1.7 christos h8_set_reg (cpu, 0, 0); 2634 1.1 christos goto next; 2635 1.1 christos } 2636 1.1 christos else 2637 1.1 christos { 2638 1.1 christos /* current_location points to the memory where the next 2639 1.1 christos commandline argument is stored. */ 2640 1.1 christos argv_ptrs[i] = current_location; 2641 1.1 christos for (j = 0; j < ind_arg_len; j++) 2642 1.1 christos { 2643 1.1 christos SET_MEMORY_B ((current_location + 2644 1.1 christos (sizeof (char) * j)), 2645 1.7 christos *(h8_get_cmdline_arg (cpu, i) + 2646 1.1 christos sizeof (char) * j)); 2647 1.1 christos } 2648 1.1 christos 2649 1.1 christos /* Setting current_location to the starting of next 2650 1.1 christos argument. */ 2651 1.1 christos current_location += ind_arg_len; 2652 1.1 christos } 2653 1.1 christos } 2654 1.1 christos 2655 1.1 christos /* This is the original position of the stack pointer. */ 2656 1.7 christos old_sp = h8_get_reg (cpu, SP_REGNUM); 2657 1.1 christos 2658 1.1 christos /* We need space from the stack to store the pointers to argvs. */ 2659 1.1 christos /* As we will infringe on the stack, we need to shift the stack 2660 1.1 christos pointer so that the data is not overwritten. We calculate how 2661 1.1 christos much space is required. */ 2662 1.1 christos sp_move = (no_of_args) * (char_ptr_size); 2663 1.1 christos 2664 1.1 christos /* The final position of stack pointer, we have thus taken some 2665 1.1 christos space from the stack. */ 2666 1.1 christos new_sp = old_sp - sp_move; 2667 1.1 christos 2668 1.1 christos /* Temporary variable holding value where the argv pointers need 2669 1.1 christos to be stored. */ 2670 1.1 christos argv_ptrs_location = new_sp; 2671 1.1 christos 2672 1.1 christos /* The argv pointers are stored at sequential locations. As per 2673 1.1 christos the H8300 ABI. */ 2674 1.1 christos for (i = 0; i < no_of_args; i++) 2675 1.1 christos { 2676 1.1 christos /* Saving the argv pointer. */ 2677 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode) 2678 1.1 christos { 2679 1.1 christos SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]); 2680 1.1 christos } 2681 1.1 christos else 2682 1.1 christos { 2683 1.1 christos SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]); 2684 1.1 christos } 2685 1.1 christos 2686 1.1 christos /* The next location where the pointer to the next argv 2687 1.1 christos string has to be stored. */ 2688 1.1 christos argv_ptrs_location += char_ptr_size; 2689 1.1 christos } 2690 1.1 christos 2691 1.1 christos /* Required by POSIX, Setting 0x0 at the end of the list of argv 2692 1.1 christos pointers. */ 2693 1.1 christos if ((h8300hmode || h8300smode) && !h8300_normal_mode) 2694 1.1 christos { 2695 1.1 christos SET_MEMORY_L (old_sp, 0x0); 2696 1.1 christos } 2697 1.1 christos else 2698 1.1 christos { 2699 1.1 christos SET_MEMORY_W (old_sp, 0x0); 2700 1.1 christos } 2701 1.1 christos 2702 1.1 christos /* Freeing allocated memory. */ 2703 1.1 christos free (argv_ptrs); 2704 1.1 christos for (i = 0; i <= no_of_args; i++) 2705 1.1 christos { 2706 1.7 christos free (h8_get_cmdline_arg (cpu, i)); 2707 1.1 christos } 2708 1.7 christos free (h8_get_command_line (cpu)); 2709 1.1 christos 2710 1.1 christos /* The no. of argv arguments are returned in Reg 0. */ 2711 1.7 christos h8_set_reg (cpu, 0, no_of_args); 2712 1.1 christos /* The Pointer to argv in Register 1. */ 2713 1.7 christos h8_set_reg (cpu, 1, new_sp); 2714 1.1 christos /* Setting the stack pointer to the new value. */ 2715 1.7 christos h8_set_reg (cpu, SP_REGNUM, new_sp); 2716 1.1 christos } 2717 1.1 christos goto next; 2718 1.1 christos 2719 1.1 christos /* System call processing starts. */ 2720 1.1 christos case O (O_SYS_OPEN, SB): 2721 1.1 christos { 2722 1.1 christos int len = 0; /* Length of filename. */ 2723 1.1 christos char *filename; /* Filename would go here. */ 2724 1.1 christos char temp_char; /* Temporary character */ 2725 1.1 christos int mode = 0; /* Mode bits for the file. */ 2726 1.1 christos int open_return; /* Return value of open, file descriptor. */ 2727 1.1 christos int i; /* Loop counter */ 2728 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */ 2729 1.1 christos 2730 1.1 christos /* Setting filename_ptr to first argument of open, */ 2731 1.1 christos /* and trying to get mode. */ 2732 1.1 christos if ((h8300sxmode || h8300hmode || h8300smode) && !h8300_normal_mode) 2733 1.1 christos { 2734 1.1 christos filename_ptr = GET_L_REG (0); 2735 1.7 christos mode = GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM) + 4); 2736 1.1 christos } 2737 1.1 christos else 2738 1.1 christos { 2739 1.1 christos filename_ptr = GET_W_REG (0); 2740 1.7 christos mode = GET_MEMORY_W (h8_get_reg (cpu, SP_REGNUM) + 2); 2741 1.1 christos } 2742 1.1 christos 2743 1.1 christos /* Trying to find the length of the filename. */ 2744 1.7 christos temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0)); 2745 1.1 christos 2746 1.1 christos len = 1; 2747 1.1 christos while (temp_char != '\0') 2748 1.1 christos { 2749 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len); 2750 1.1 christos len++; 2751 1.1 christos } 2752 1.1 christos 2753 1.1 christos /* Allocating space for the filename. */ 2754 1.1 christos filename = (char *) malloc (sizeof (char) * len); 2755 1.1 christos 2756 1.1 christos /* String copying the filename from memory. */ 2757 1.1 christos for (i = 0; i < len; i++) 2758 1.1 christos { 2759 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i); 2760 1.1 christos filename[i] = temp_char; 2761 1.1 christos } 2762 1.1 christos 2763 1.1 christos /* Callback to open and return the file descriptor. */ 2764 1.1 christos open_return = sim_callback->open (sim_callback, filename, mode); 2765 1.1 christos 2766 1.1 christos /* Return value in register 0. */ 2767 1.7 christos h8_set_reg (cpu, 0, open_return); 2768 1.1 christos 2769 1.1 christos /* Freeing memory used for filename. */ 2770 1.1 christos free (filename); 2771 1.1 christos } 2772 1.1 christos goto next; 2773 1.1 christos 2774 1.1 christos case O (O_SYS_READ, SB): 2775 1.1 christos { 2776 1.1 christos char *char_ptr; /* Where characters read would be stored. */ 2777 1.1 christos int fd; /* File descriptor */ 2778 1.1 christos int buf_size; /* BUF_SIZE parameter in read. */ 2779 1.1 christos int i = 0; /* Temporary Loop counter */ 2780 1.1 christos int read_return = 0; /* Return value from callback to 2781 1.1 christos read. */ 2782 1.1 christos 2783 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2784 1.1 christos buf_size = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); 2785 1.1 christos 2786 1.1 christos char_ptr = (char *) malloc (sizeof (char) * buf_size); 2787 1.1 christos 2788 1.1 christos /* Callback to read and return the no. of characters read. */ 2789 1.1 christos read_return = 2790 1.1 christos sim_callback->read (sim_callback, fd, char_ptr, buf_size); 2791 1.1 christos 2792 1.1 christos /* The characters read are stored in cpu memory. */ 2793 1.1 christos for (i = 0; i < buf_size; i++) 2794 1.1 christos { 2795 1.7 christos SET_MEMORY_B ((h8_get_reg (cpu, 1) + (sizeof (char) * i)), 2796 1.1 christos *(char_ptr + (sizeof (char) * i))); 2797 1.1 christos } 2798 1.1 christos 2799 1.1 christos /* Return value in Register 0. */ 2800 1.7 christos h8_set_reg (cpu, 0, read_return); 2801 1.1 christos 2802 1.1 christos /* Freeing memory used as buffer. */ 2803 1.1 christos free (char_ptr); 2804 1.1 christos } 2805 1.1 christos goto next; 2806 1.1 christos 2807 1.1 christos case O (O_SYS_WRITE, SB): 2808 1.1 christos { 2809 1.1 christos int fd; /* File descriptor */ 2810 1.1 christos char temp_char; /* Temporary character */ 2811 1.1 christos int len; /* Length of write, Parameter II to write. */ 2812 1.1 christos int char_ptr; /* Character Pointer, Parameter I of write. */ 2813 1.1 christos char *ptr; /* Where characters to be written are stored. 2814 1.1 christos */ 2815 1.1 christos int write_return; /* Return value from callback to write. */ 2816 1.1 christos int i = 0; /* Loop counter */ 2817 1.1 christos 2818 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2819 1.1 christos char_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); 2820 1.1 christos len = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); 2821 1.1 christos 2822 1.1 christos /* Allocating space for the characters to be written. */ 2823 1.1 christos ptr = (char *) malloc (sizeof (char) * len); 2824 1.1 christos 2825 1.1 christos /* Fetching the characters from cpu memory. */ 2826 1.1 christos for (i = 0; i < len; i++) 2827 1.1 christos { 2828 1.1 christos temp_char = GET_MEMORY_B (char_ptr + i); 2829 1.1 christos ptr[i] = temp_char; 2830 1.1 christos } 2831 1.1 christos 2832 1.1 christos /* Callback write and return the no. of characters written. */ 2833 1.1 christos write_return = sim_callback->write (sim_callback, fd, ptr, len); 2834 1.1 christos 2835 1.1 christos /* Return value in Register 0. */ 2836 1.7 christos h8_set_reg (cpu, 0, write_return); 2837 1.1 christos 2838 1.1 christos /* Freeing memory used as buffer. */ 2839 1.1 christos free (ptr); 2840 1.1 christos } 2841 1.1 christos goto next; 2842 1.1 christos 2843 1.1 christos case O (O_SYS_LSEEK, SB): 2844 1.1 christos { 2845 1.1 christos int fd; /* File descriptor */ 2846 1.1 christos int offset; /* Offset */ 2847 1.1 christos int origin; /* Origin */ 2848 1.1 christos int lseek_return; /* Return value from callback to lseek. */ 2849 1.1 christos 2850 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2851 1.1 christos offset = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); 2852 1.1 christos origin = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (2) : GET_W_REG (2); 2853 1.1 christos 2854 1.1 christos /* Callback lseek and return offset. */ 2855 1.1 christos lseek_return = 2856 1.1 christos sim_callback->lseek (sim_callback, fd, offset, origin); 2857 1.1 christos 2858 1.1 christos /* Return value in register 0. */ 2859 1.7 christos h8_set_reg (cpu, 0, lseek_return); 2860 1.1 christos } 2861 1.1 christos goto next; 2862 1.1 christos 2863 1.1 christos case O (O_SYS_CLOSE, SB): 2864 1.1 christos { 2865 1.1 christos int fd; /* File descriptor */ 2866 1.1 christos int close_return; /* Return value from callback to close. */ 2867 1.1 christos 2868 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2869 1.1 christos 2870 1.1 christos /* Callback close and return. */ 2871 1.1 christos close_return = sim_callback->close (sim_callback, fd); 2872 1.1 christos 2873 1.1 christos /* Return value in register 0. */ 2874 1.7 christos h8_set_reg (cpu, 0, close_return); 2875 1.1 christos } 2876 1.1 christos goto next; 2877 1.1 christos 2878 1.1 christos case O (O_SYS_FSTAT, SB): 2879 1.1 christos { 2880 1.1 christos int fd; /* File descriptor */ 2881 1.1 christos struct stat stat_rec; /* Stat record */ 2882 1.1 christos int fstat_return; /* Return value from callback to stat. */ 2883 1.1 christos int stat_ptr; /* Pointer to stat record. */ 2884 1.1 christos 2885 1.1 christos fd = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2886 1.1 christos 2887 1.1 christos /* Setting stat_ptr to second argument of stat. */ 2888 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); 2889 1.1 christos 2890 1.1 christos /* Callback stat and return. */ 2891 1.3 christos fstat_return = sim_callback->to_fstat (sim_callback, fd, 2892 1.3 christos &stat_rec); 2893 1.1 christos 2894 1.1 christos /* Setting up the stat structure returned. */ 2895 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev); 2896 1.1 christos stat_ptr += 2; 2897 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino); 2898 1.1 christos stat_ptr += 2; 2899 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode); 2900 1.1 christos stat_ptr += 4; 2901 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink); 2902 1.1 christos stat_ptr += 2; 2903 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid); 2904 1.1 christos stat_ptr += 2; 2905 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid); 2906 1.1 christos stat_ptr += 2; 2907 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev); 2908 1.1 christos stat_ptr += 2; 2909 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size); 2910 1.1 christos stat_ptr += 4; 2911 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime); 2912 1.1 christos stat_ptr += 8; 2913 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime); 2914 1.1 christos stat_ptr += 8; 2915 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime); 2916 1.1 christos 2917 1.1 christos /* Return value in register 0. */ 2918 1.7 christos h8_set_reg (cpu, 0, fstat_return); 2919 1.1 christos } 2920 1.1 christos goto next; 2921 1.1 christos 2922 1.1 christos case O (O_SYS_STAT, SB): 2923 1.1 christos { 2924 1.1 christos int len = 0; /* Length of filename. */ 2925 1.1 christos char *filename; /* Filename would go here. */ 2926 1.1 christos char temp_char; /* Temporary character */ 2927 1.1 christos int filename_ptr; /* Pointer to filename in cpu memory. */ 2928 1.1 christos struct stat stat_rec; /* Stat record */ 2929 1.1 christos int stat_return; /* Return value from callback to stat */ 2930 1.1 christos int stat_ptr; /* Pointer to stat record. */ 2931 1.1 christos int i = 0; /* Loop Counter */ 2932 1.1 christos 2933 1.1 christos /* Setting filename_ptr to first argument of open. */ 2934 1.1 christos filename_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (0) : GET_W_REG (0); 2935 1.1 christos 2936 1.1 christos /* Trying to find the length of the filename. */ 2937 1.7 christos temp_char = GET_MEMORY_B (h8_get_reg (cpu, 0)); 2938 1.1 christos 2939 1.1 christos len = 1; 2940 1.1 christos while (temp_char != '\0') 2941 1.1 christos { 2942 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + len); 2943 1.1 christos len++; 2944 1.1 christos } 2945 1.1 christos 2946 1.1 christos /* Allocating space for the filename. */ 2947 1.1 christos filename = (char *) malloc (sizeof (char) * len); 2948 1.1 christos 2949 1.1 christos /* String copying the filename from memory. */ 2950 1.1 christos for (i = 0; i < len; i++) 2951 1.1 christos { 2952 1.1 christos temp_char = GET_MEMORY_B (filename_ptr + i); 2953 1.1 christos filename[i] = temp_char; 2954 1.1 christos } 2955 1.1 christos 2956 1.1 christos /* Setting stat_ptr to second argument of stat. */ 2957 1.7 christos /* stat_ptr = h8_get_reg (cpu, 1); */ 2958 1.1 christos stat_ptr = (h8300hmode && !h8300_normal_mode) ? GET_L_REG (1) : GET_W_REG (1); 2959 1.1 christos 2960 1.1 christos /* Callback stat and return. */ 2961 1.1 christos stat_return = 2962 1.3 christos sim_callback->to_stat (sim_callback, filename, &stat_rec); 2963 1.1 christos 2964 1.1 christos /* Freeing memory used for filename. */ 2965 1.1 christos free (filename); 2966 1.1 christos 2967 1.1 christos /* Setting up the stat structure returned. */ 2968 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_dev); 2969 1.1 christos stat_ptr += 2; 2970 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_ino); 2971 1.1 christos stat_ptr += 2; 2972 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mode); 2973 1.1 christos stat_ptr += 4; 2974 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_nlink); 2975 1.1 christos stat_ptr += 2; 2976 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_uid); 2977 1.1 christos stat_ptr += 2; 2978 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_gid); 2979 1.1 christos stat_ptr += 2; 2980 1.1 christos SET_MEMORY_W (stat_ptr, stat_rec.st_rdev); 2981 1.1 christos stat_ptr += 2; 2982 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_size); 2983 1.1 christos stat_ptr += 4; 2984 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_atime); 2985 1.1 christos stat_ptr += 8; 2986 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_mtime); 2987 1.1 christos stat_ptr += 8; 2988 1.1 christos SET_MEMORY_L (stat_ptr, stat_rec.st_ctime); 2989 1.1 christos 2990 1.1 christos /* Return value in register 0. */ 2991 1.7 christos h8_set_reg (cpu, 0, stat_return); 2992 1.1 christos } 2993 1.1 christos goto next; 2994 1.1 christos /* End of system call processing. */ 2995 1.1 christos 2996 1.1 christos case O (O_NOT, SB): /* not.b */ 2997 1.1 christos if (fetch2 (sd, &code->src, &rd)) 2998 1.1 christos goto end; 2999 1.1 christos rd = ~rd; 3000 1.1 christos v = 0; 3001 1.1 christos goto shift8; 3002 1.1 christos 3003 1.1 christos case O (O_NOT, SW): /* not.w */ 3004 1.1 christos if (fetch2 (sd, &code->src, &rd)) 3005 1.1 christos goto end; 3006 1.1 christos rd = ~rd; 3007 1.1 christos v = 0; 3008 1.1 christos goto shift16; 3009 1.1 christos 3010 1.1 christos case O (O_NOT, SL): /* not.l */ 3011 1.1 christos if (fetch2 (sd, &code->src, &rd)) 3012 1.1 christos goto end; 3013 1.1 christos rd = ~rd; 3014 1.1 christos v = 0; 3015 1.1 christos goto shift32; 3016 1.1 christos 3017 1.1 christos case O (O_SHLL, SB): /* shll.b */ 3018 1.1 christos case O (O_SHLR, SB): /* shlr.b */ 3019 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3020 1.1 christos goto end; 3021 1.1 christos 3022 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) 3023 1.1 christos ea = 1; /* unary op */ 3024 1.1 christos else /* binary op */ 3025 1.1 christos fetch (sd, &code->src, &ea); 3026 1.1 christos 3027 1.1 christos if (code->opcode == O (O_SHLL, SB)) 3028 1.1 christos { 3029 1.1 christos v = (ea > 8); 3030 1.1 christos c = rd & (0x80 >> (ea - 1)); 3031 1.1 christos rd <<= ea; 3032 1.1 christos } 3033 1.1 christos else 3034 1.1 christos { 3035 1.1 christos v = 0; 3036 1.1 christos c = rd & (1 << (ea - 1)); 3037 1.1 christos rd = (unsigned char) rd >> ea; 3038 1.1 christos } 3039 1.1 christos goto shift8; 3040 1.1 christos 3041 1.1 christos case O (O_SHLL, SW): /* shll.w */ 3042 1.1 christos case O (O_SHLR, SW): /* shlr.w */ 3043 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3044 1.1 christos goto end; 3045 1.1 christos 3046 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) 3047 1.1 christos ea = 1; /* unary op */ 3048 1.1 christos else 3049 1.1 christos fetch (sd, &code->src, &ea); 3050 1.1 christos 3051 1.1 christos if (code->opcode == O (O_SHLL, SW)) 3052 1.1 christos { 3053 1.1 christos v = (ea > 16); 3054 1.1 christos c = rd & (0x8000 >> (ea - 1)); 3055 1.1 christos rd <<= ea; 3056 1.1 christos } 3057 1.1 christos else 3058 1.1 christos { 3059 1.1 christos v = 0; 3060 1.1 christos c = rd & (1 << (ea - 1)); 3061 1.1 christos rd = (unsigned short) rd >> ea; 3062 1.1 christos } 3063 1.1 christos goto shift16; 3064 1.1 christos 3065 1.1 christos case O (O_SHLL, SL): /* shll.l */ 3066 1.1 christos case O (O_SHLR, SL): /* shlr.l */ 3067 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3068 1.1 christos goto end; 3069 1.1 christos 3070 1.1 christos if (memcmp (&code->src, &code->dst, sizeof (code->src)) == 0) 3071 1.1 christos ea = 1; /* unary op */ 3072 1.1 christos else 3073 1.1 christos fetch (sd, &code->src, &ea); 3074 1.1 christos 3075 1.1 christos if (code->opcode == O (O_SHLL, SL)) 3076 1.1 christos { 3077 1.1 christos v = (ea > 32); 3078 1.1 christos c = rd & (0x80000000 >> (ea - 1)); 3079 1.1 christos rd <<= ea; 3080 1.1 christos } 3081 1.1 christos else 3082 1.1 christos { 3083 1.1 christos v = 0; 3084 1.1 christos c = rd & (1 << (ea - 1)); 3085 1.1 christos rd = (unsigned int) rd >> ea; 3086 1.1 christos } 3087 1.1 christos goto shift32; 3088 1.1 christos 3089 1.1 christos case O (O_SHAL, SB): 3090 1.1 christos case O (O_SHAR, SB): 3091 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3092 1.1 christos goto end; 3093 1.1 christos 3094 1.1 christos if (code->src.type == X (OP_IMM, SB)) 3095 1.1 christos fetch (sd, &code->src, &ea); 3096 1.1 christos else 3097 1.1 christos ea = 1; 3098 1.1 christos 3099 1.1 christos if (code->opcode == O (O_SHAL, SB)) 3100 1.1 christos { 3101 1.1 christos c = rd & (0x80 >> (ea - 1)); 3102 1.1 christos res = rd >> (7 - ea); 3103 1.1 christos v = ((res & 1) && !(res & 2)) 3104 1.1 christos || (!(res & 1) && (res & 2)); 3105 1.1 christos rd <<= ea; 3106 1.1 christos } 3107 1.1 christos else 3108 1.1 christos { 3109 1.1 christos c = rd & (1 << (ea - 1)); 3110 1.1 christos v = 0; 3111 1.1 christos rd = ((signed char) rd) >> ea; 3112 1.1 christos } 3113 1.1 christos goto shift8; 3114 1.1 christos 3115 1.1 christos case O (O_SHAL, SW): 3116 1.1 christos case O (O_SHAR, SW): 3117 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3118 1.1 christos goto end; 3119 1.1 christos 3120 1.1 christos if (code->src.type == X (OP_IMM, SW)) 3121 1.1 christos fetch (sd, &code->src, &ea); 3122 1.1 christos else 3123 1.1 christos ea = 1; 3124 1.1 christos 3125 1.1 christos if (code->opcode == O (O_SHAL, SW)) 3126 1.1 christos { 3127 1.1 christos c = rd & (0x8000 >> (ea - 1)); 3128 1.1 christos res = rd >> (15 - ea); 3129 1.1 christos v = ((res & 1) && !(res & 2)) 3130 1.1 christos || (!(res & 1) && (res & 2)); 3131 1.1 christos rd <<= ea; 3132 1.1 christos } 3133 1.1 christos else 3134 1.1 christos { 3135 1.1 christos c = rd & (1 << (ea - 1)); 3136 1.1 christos v = 0; 3137 1.1 christos rd = ((signed short) rd) >> ea; 3138 1.1 christos } 3139 1.1 christos goto shift16; 3140 1.1 christos 3141 1.1 christos case O (O_SHAL, SL): 3142 1.1 christos case O (O_SHAR, SL): 3143 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3144 1.1 christos goto end; 3145 1.1 christos 3146 1.1 christos if (code->src.type == X (OP_IMM, SL)) 3147 1.1 christos fetch (sd, &code->src, &ea); 3148 1.1 christos else 3149 1.1 christos ea = 1; 3150 1.1 christos 3151 1.1 christos if (code->opcode == O (O_SHAL, SL)) 3152 1.1 christos { 3153 1.1 christos c = rd & (0x80000000 >> (ea - 1)); 3154 1.1 christos res = rd >> (31 - ea); 3155 1.1 christos v = ((res & 1) && !(res & 2)) 3156 1.1 christos || (!(res & 1) && (res & 2)); 3157 1.1 christos rd <<= ea; 3158 1.1 christos } 3159 1.1 christos else 3160 1.1 christos { 3161 1.1 christos c = rd & (1 << (ea - 1)); 3162 1.1 christos v = 0; 3163 1.1 christos rd = ((signed int) rd) >> ea; 3164 1.1 christos } 3165 1.1 christos goto shift32; 3166 1.1 christos 3167 1.1 christos case O (O_ROTL, SB): 3168 1.1 christos case O (O_ROTR, SB): 3169 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3170 1.1 christos goto end; 3171 1.1 christos 3172 1.1 christos if (code->src.type == X (OP_IMM, SB)) 3173 1.1 christos fetch (sd, &code->src, &ea); 3174 1.1 christos else 3175 1.1 christos ea = 1; 3176 1.1 christos 3177 1.1 christos while (ea--) 3178 1.1 christos if (code->opcode == O (O_ROTL, SB)) 3179 1.1 christos { 3180 1.1 christos c = rd & 0x80; 3181 1.1 christos rd <<= 1; 3182 1.1 christos if (c) 3183 1.1 christos rd |= 1; 3184 1.1 christos } 3185 1.1 christos else 3186 1.1 christos { 3187 1.1 christos c = rd & 1; 3188 1.1 christos rd = ((unsigned char) rd) >> 1; 3189 1.1 christos if (c) 3190 1.1 christos rd |= 0x80; 3191 1.1 christos } 3192 1.1 christos 3193 1.1 christos v = 0; 3194 1.1 christos goto shift8; 3195 1.1 christos 3196 1.1 christos case O (O_ROTL, SW): 3197 1.1 christos case O (O_ROTR, SW): 3198 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3199 1.1 christos goto end; 3200 1.1 christos 3201 1.1 christos if (code->src.type == X (OP_IMM, SW)) 3202 1.1 christos fetch (sd, &code->src, &ea); 3203 1.1 christos else 3204 1.1 christos ea = 1; 3205 1.1 christos 3206 1.1 christos while (ea--) 3207 1.1 christos if (code->opcode == O (O_ROTL, SW)) 3208 1.1 christos { 3209 1.1 christos c = rd & 0x8000; 3210 1.1 christos rd <<= 1; 3211 1.1 christos if (c) 3212 1.1 christos rd |= 1; 3213 1.1 christos } 3214 1.1 christos else 3215 1.1 christos { 3216 1.1 christos c = rd & 1; 3217 1.1 christos rd = ((unsigned short) rd) >> 1; 3218 1.1 christos if (c) 3219 1.1 christos rd |= 0x8000; 3220 1.1 christos } 3221 1.1 christos 3222 1.1 christos v = 0; 3223 1.1 christos goto shift16; 3224 1.1 christos 3225 1.1 christos case O (O_ROTL, SL): 3226 1.1 christos case O (O_ROTR, SL): 3227 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3228 1.1 christos goto end; 3229 1.1 christos 3230 1.1 christos if (code->src.type == X (OP_IMM, SL)) 3231 1.1 christos fetch (sd, &code->src, &ea); 3232 1.1 christos else 3233 1.1 christos ea = 1; 3234 1.1 christos 3235 1.1 christos while (ea--) 3236 1.1 christos if (code->opcode == O (O_ROTL, SL)) 3237 1.1 christos { 3238 1.1 christos c = rd & 0x80000000; 3239 1.1 christos rd <<= 1; 3240 1.1 christos if (c) 3241 1.1 christos rd |= 1; 3242 1.1 christos } 3243 1.1 christos else 3244 1.1 christos { 3245 1.1 christos c = rd & 1; 3246 1.1 christos rd = ((unsigned int) rd) >> 1; 3247 1.1 christos if (c) 3248 1.1 christos rd |= 0x80000000; 3249 1.1 christos } 3250 1.1 christos 3251 1.1 christos v = 0; 3252 1.1 christos goto shift32; 3253 1.1 christos 3254 1.1 christos case O (O_ROTXL, SB): 3255 1.1 christos case O (O_ROTXR, SB): 3256 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3257 1.1 christos goto end; 3258 1.1 christos 3259 1.1 christos if (code->src.type == X (OP_IMM, SB)) 3260 1.1 christos fetch (sd, &code->src, &ea); 3261 1.1 christos else 3262 1.1 christos ea = 1; 3263 1.1 christos 3264 1.1 christos while (ea--) 3265 1.1 christos if (code->opcode == O (O_ROTXL, SB)) 3266 1.1 christos { 3267 1.1 christos res = rd & 0x80; 3268 1.1 christos rd <<= 1; 3269 1.1 christos if (C) 3270 1.1 christos rd |= 1; 3271 1.1 christos c = res; 3272 1.1 christos } 3273 1.1 christos else 3274 1.1 christos { 3275 1.1 christos res = rd & 1; 3276 1.1 christos rd = ((unsigned char) rd) >> 1; 3277 1.1 christos if (C) 3278 1.1 christos rd |= 0x80; 3279 1.1 christos c = res; 3280 1.1 christos } 3281 1.1 christos 3282 1.1 christos v = 0; 3283 1.1 christos goto shift8; 3284 1.1 christos 3285 1.1 christos case O (O_ROTXL, SW): 3286 1.1 christos case O (O_ROTXR, SW): 3287 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3288 1.1 christos goto end; 3289 1.1 christos 3290 1.1 christos if (code->src.type == X (OP_IMM, SW)) 3291 1.1 christos fetch (sd, &code->src, &ea); 3292 1.1 christos else 3293 1.1 christos ea = 1; 3294 1.1 christos 3295 1.1 christos while (ea--) 3296 1.1 christos if (code->opcode == O (O_ROTXL, SW)) 3297 1.1 christos { 3298 1.1 christos res = rd & 0x8000; 3299 1.1 christos rd <<= 1; 3300 1.1 christos if (C) 3301 1.1 christos rd |= 1; 3302 1.1 christos c = res; 3303 1.1 christos } 3304 1.1 christos else 3305 1.1 christos { 3306 1.1 christos res = rd & 1; 3307 1.1 christos rd = ((unsigned short) rd) >> 1; 3308 1.1 christos if (C) 3309 1.1 christos rd |= 0x8000; 3310 1.1 christos c = res; 3311 1.1 christos } 3312 1.1 christos 3313 1.1 christos v = 0; 3314 1.1 christos goto shift16; 3315 1.1 christos 3316 1.1 christos case O (O_ROTXL, SL): 3317 1.1 christos case O (O_ROTXR, SL): 3318 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 3319 1.1 christos goto end; 3320 1.1 christos 3321 1.1 christos if (code->src.type == X (OP_IMM, SL)) 3322 1.1 christos fetch (sd, &code->src, &ea); 3323 1.1 christos else 3324 1.1 christos ea = 1; 3325 1.1 christos 3326 1.1 christos while (ea--) 3327 1.1 christos if (code->opcode == O (O_ROTXL, SL)) 3328 1.1 christos { 3329 1.1 christos res = rd & 0x80000000; 3330 1.1 christos rd <<= 1; 3331 1.1 christos if (C) 3332 1.1 christos rd |= 1; 3333 1.1 christos c = res; 3334 1.1 christos } 3335 1.1 christos else 3336 1.1 christos { 3337 1.1 christos res = rd & 1; 3338 1.1 christos rd = ((unsigned int) rd) >> 1; 3339 1.1 christos if (C) 3340 1.1 christos rd |= 0x80000000; 3341 1.1 christos c = res; 3342 1.1 christos } 3343 1.1 christos 3344 1.1 christos v = 0; 3345 1.1 christos goto shift32; 3346 1.1 christos 3347 1.1 christos case O (O_JMP, SN): 3348 1.1 christos case O (O_JMP, SL): 3349 1.1 christos case O (O_JMP, SB): /* jmp */ 3350 1.1 christos case O (O_JMP, SW): 3351 1.1 christos fetch (sd, &code->src, &pc); 3352 1.1 christos goto end; 3353 1.1 christos 3354 1.1 christos case O (O_JSR, SN): 3355 1.1 christos case O (O_JSR, SL): 3356 1.1 christos case O (O_JSR, SB): /* jsr, jump to subroutine */ 3357 1.1 christos case O (O_JSR, SW): 3358 1.1 christos if (fetch (sd, &code->src, &pc)) 3359 1.1 christos goto end; 3360 1.1 christos call: 3361 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM); 3362 1.1 christos 3363 1.1 christos if (h8300hmode && !h8300_normal_mode) 3364 1.1 christos { 3365 1.1 christos tmp -= 4; 3366 1.1 christos SET_MEMORY_L (tmp, code->next_pc); 3367 1.1 christos } 3368 1.1 christos else 3369 1.1 christos { 3370 1.1 christos tmp -= 2; 3371 1.1 christos SET_MEMORY_W (tmp, code->next_pc); 3372 1.1 christos } 3373 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp); 3374 1.1 christos 3375 1.1 christos goto end; 3376 1.1 christos 3377 1.1 christos case O (O_BSR, SW): 3378 1.1 christos case O (O_BSR, SL): 3379 1.1 christos case O (O_BSR, SB): /* bsr, branch to subroutine */ 3380 1.1 christos if (fetch (sd, &code->src, &res)) 3381 1.1 christos goto end; 3382 1.1 christos pc = code->next_pc + res; 3383 1.1 christos goto call; 3384 1.1 christos 3385 1.1 christos case O (O_RTE, SN): /* rte, return from exception */ 3386 1.1 christos rte: 3387 1.1 christos /* Pops exr and ccr before pc -- otherwise identical to rts. */ 3388 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM); 3389 1.1 christos 3390 1.1 christos if (h8300smode) /* pop exr */ 3391 1.1 christos { 3392 1.7 christos h8_set_exr (cpu, GET_MEMORY_L (tmp)); 3393 1.1 christos tmp += 4; 3394 1.1 christos } 3395 1.1 christos if (h8300hmode && !h8300_normal_mode) 3396 1.1 christos { 3397 1.7 christos h8_set_ccr (cpu, GET_MEMORY_L (tmp)); 3398 1.1 christos tmp += 4; 3399 1.1 christos pc = GET_MEMORY_L (tmp); 3400 1.1 christos tmp += 4; 3401 1.1 christos } 3402 1.1 christos else 3403 1.1 christos { 3404 1.7 christos h8_set_ccr (cpu, GET_MEMORY_W (tmp)); 3405 1.1 christos tmp += 2; 3406 1.1 christos pc = GET_MEMORY_W (tmp); 3407 1.1 christos tmp += 2; 3408 1.1 christos } 3409 1.1 christos 3410 1.7 christos GETSR (cpu); 3411 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp); 3412 1.1 christos goto end; 3413 1.1 christos 3414 1.1 christos case O (O_RTS, SN): /* rts, return from subroutine */ 3415 1.1 christos rts: 3416 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM); 3417 1.1 christos 3418 1.1 christos if (h8300hmode && !h8300_normal_mode) 3419 1.1 christos { 3420 1.1 christos pc = GET_MEMORY_L (tmp); 3421 1.1 christos tmp += 4; 3422 1.1 christos } 3423 1.1 christos else 3424 1.1 christos { 3425 1.1 christos pc = GET_MEMORY_W (tmp); 3426 1.1 christos tmp += 2; 3427 1.1 christos } 3428 1.1 christos 3429 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp); 3430 1.1 christos goto end; 3431 1.1 christos 3432 1.1 christos case O (O_ILL, SB): /* illegal */ 3433 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL); 3434 1.1 christos goto end; 3435 1.1 christos 3436 1.1 christos case O (O_SLEEP, SN): /* sleep */ 3437 1.1 christos /* Check for magic numbers in r1 and r2. */ 3438 1.7 christos if ((h8_get_reg (cpu, R1_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC1 && 3439 1.7 christos (h8_get_reg (cpu, R2_REGNUM) & 0xffff) == LIBC_EXIT_MAGIC2 && 3440 1.7 christos SIM_WIFEXITED (h8_get_reg (cpu, 0))) 3441 1.1 christos { 3442 1.1 christos /* This trap comes from _exit, not from gdb. */ 3443 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_exited, 3444 1.7 christos SIM_WEXITSTATUS (h8_get_reg (cpu, 0))); 3445 1.1 christos } 3446 1.1 christos #if 0 3447 1.1 christos /* Unfortunately this won't really work, because 3448 1.1 christos when we take a breakpoint trap, R0 has a "random", 3449 1.1 christos user-defined value. Don't see any immediate solution. */ 3450 1.7 christos else if (SIM_WIFSTOPPED (h8_get_reg (cpu, 0))) 3451 1.1 christos { 3452 1.1 christos /* Pass the stop signal up to gdb. */ 3453 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, 3454 1.7 christos SIM_WSTOPSIG (h8_get_reg (cpu, 0))); 3455 1.1 christos } 3456 1.1 christos #endif 3457 1.1 christos else 3458 1.1 christos { 3459 1.1 christos /* Treat it as a sigtrap. */ 3460 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); 3461 1.1 christos } 3462 1.1 christos goto end; 3463 1.1 christos 3464 1.1 christos case O (O_TRAPA, SB): /* trapa */ 3465 1.1 christos if (fetch (sd, &code->src, &res)) 3466 1.1 christos goto end; /* res is vector number. */ 3467 1.1 christos 3468 1.7 christos tmp = h8_get_reg (cpu, SP_REGNUM); 3469 1.1 christos if(h8300_normal_mode) 3470 1.1 christos { 3471 1.1 christos tmp -= 2; 3472 1.1 christos SET_MEMORY_W (tmp, code->next_pc); 3473 1.1 christos tmp -= 2; 3474 1.7 christos SET_MEMORY_W (tmp, h8_get_ccr (cpu)); 3475 1.1 christos } 3476 1.1 christos else 3477 1.1 christos { 3478 1.1 christos tmp -= 4; 3479 1.1 christos SET_MEMORY_L (tmp, code->next_pc); 3480 1.1 christos tmp -= 4; 3481 1.7 christos SET_MEMORY_L (tmp, h8_get_ccr (cpu)); 3482 1.1 christos } 3483 1.1 christos intMaskBit = 1; 3484 1.7 christos BUILDSR (cpu); 3485 1.1 christos 3486 1.1 christos if (h8300smode) 3487 1.1 christos { 3488 1.1 christos tmp -= 4; 3489 1.7 christos SET_MEMORY_L (tmp, h8_get_exr (cpu)); 3490 1.1 christos } 3491 1.1 christos 3492 1.7 christos h8_set_reg (cpu, SP_REGNUM, tmp); 3493 1.1 christos 3494 1.1 christos if(h8300_normal_mode) 3495 1.1 christos pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */ 3496 1.1 christos else 3497 1.1 christos pc = GET_MEMORY_L (0x20 + res * 4); 3498 1.1 christos goto end; 3499 1.1 christos 3500 1.1 christos case O (O_BPT, SN): 3501 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); 3502 1.1 christos goto end; 3503 1.1 christos 3504 1.1 christos case O (O_BSETEQ, SB): 3505 1.1 christos if (Z) 3506 1.1 christos goto bset; 3507 1.1 christos goto next; 3508 1.1 christos 3509 1.1 christos case O (O_BSETNE, SB): 3510 1.1 christos if (!Z) 3511 1.1 christos goto bset; 3512 1.1 christos goto next; 3513 1.1 christos 3514 1.1 christos case O (O_BCLREQ, SB): 3515 1.1 christos if (Z) 3516 1.1 christos goto bclr; 3517 1.1 christos goto next; 3518 1.1 christos 3519 1.1 christos case O (O_BCLRNE, SB): 3520 1.1 christos if (!Z) 3521 1.1 christos goto bclr; 3522 1.1 christos goto next; 3523 1.1 christos 3524 1.1 christos OBITOP (O_BNOT, 1, 1, ea ^= m); /* bnot */ 3525 1.1 christos OBITOP (O_BTST, 1, 0, nz = ea & m); /* btst */ 3526 1.1 christos bset: 3527 1.1 christos OBITOP (O_BSET, 1, 1, ea |= m); /* bset */ 3528 1.1 christos bclr: 3529 1.1 christos OBITOP (O_BCLR, 1, 1, ea &= ~m); /* bclr */ 3530 1.1 christos OBITOP (O_BLD, 1, 0, c = ea & m); /* bld */ 3531 1.1 christos OBITOP (O_BILD, 1, 0, c = !(ea & m)); /* bild */ 3532 1.1 christos OBITOP (O_BST, 1, 1, ea &= ~m; 3533 1.1 christos if (C) ea |= m); /* bst */ 3534 1.1 christos OBITOP (O_BIST, 1, 1, ea &= ~m; 3535 1.1 christos if (!C) ea |= m); /* bist */ 3536 1.1 christos OBITOP (O_BSTZ, 1, 1, ea &= ~m; 3537 1.1 christos if (Z) ea |= m); /* bstz */ 3538 1.1 christos OBITOP (O_BISTZ, 1, 1, ea &= ~m; 3539 1.1 christos if (!Z) ea |= m); /* bistz */ 3540 1.1 christos OBITOP (O_BAND, 1, 0, c = (ea & m) && C); /* band */ 3541 1.1 christos OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); /* biand */ 3542 1.1 christos OBITOP (O_BOR, 1, 0, c = (ea & m) || C); /* bor */ 3543 1.1 christos OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); /* bior */ 3544 1.1 christos OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0)!= C); /* bxor */ 3545 1.1 christos OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); /* bixor */ 3546 1.1 christos 3547 1.1 christos case O (O_BFLD, SB): /* bfld */ 3548 1.1 christos /* bitfield load */ 3549 1.1 christos ea = 0; 3550 1.1 christos if (fetch (sd, &code->src, &bit)) 3551 1.1 christos goto end; 3552 1.1 christos 3553 1.1 christos if (bit != 0) 3554 1.1 christos { 3555 1.1 christos if (fetch (sd, &code->dst, &ea)) 3556 1.1 christos goto end; 3557 1.1 christos 3558 1.1 christos ea &= bit; 3559 1.1 christos while (!(bit & 1)) 3560 1.1 christos { 3561 1.1 christos ea >>= 1; 3562 1.1 christos bit >>= 1; 3563 1.1 christos } 3564 1.1 christos } 3565 1.1 christos if (store (sd, &code->op3, ea)) 3566 1.1 christos goto end; 3567 1.1 christos 3568 1.1 christos goto next; 3569 1.1 christos 3570 1.1 christos case O(O_BFST, SB): /* bfst */ 3571 1.1 christos /* bitfield store */ 3572 1.1 christos /* NOTE: the imm8 value is in dst, and the ea value 3573 1.1 christos (which is actually the destination) is in op3. 3574 1.1 christos It has to be that way, to avoid breaking the assembler. */ 3575 1.1 christos 3576 1.1 christos if (fetch (sd, &code->dst, &bit)) /* imm8 */ 3577 1.1 christos goto end; 3578 1.1 christos if (bit == 0) /* noop -- nothing to do. */ 3579 1.1 christos goto next; 3580 1.1 christos 3581 1.1 christos if (fetch (sd, &code->src, &rd)) /* reg8 src */ 3582 1.1 christos goto end; 3583 1.1 christos 3584 1.1 christos if (fetch2 (sd, &code->op3, &ea)) /* ea dst */ 3585 1.1 christos goto end; 3586 1.1 christos 3587 1.1 christos /* Left-shift the register data into position. */ 3588 1.1 christos for (tmp = bit; !(tmp & 1); tmp >>= 1) 3589 1.1 christos rd <<= 1; 3590 1.1 christos 3591 1.1 christos /* Combine it with the neighboring bits. */ 3592 1.1 christos ea = (ea & ~bit) | (rd & bit); 3593 1.1 christos 3594 1.1 christos /* Put it back. */ 3595 1.1 christos if (store2 (sd, &code->op3, ea)) 3596 1.1 christos goto end; 3597 1.1 christos goto next; 3598 1.1 christos 3599 1.1 christos case O (O_CLRMAC, SN): /* clrmac */ 3600 1.7 christos h8_set_mach (cpu, 0); 3601 1.7 christos h8_set_macl (cpu, 0); 3602 1.7 christos h8_set_macZ (cpu, 1); 3603 1.7 christos h8_set_macV (cpu, 0); 3604 1.7 christos h8_set_macN (cpu, 0); 3605 1.1 christos goto next; 3606 1.1 christos 3607 1.1 christos case O (O_STMAC, SL): /* stmac, 260 */ 3608 1.1 christos switch (code->src.type) { 3609 1.1 christos case X (OP_MACH, SL): 3610 1.7 christos res = h8_get_mach (cpu); 3611 1.1 christos if (res & 0x200) /* sign extend */ 3612 1.1 christos res |= 0xfffffc00; 3613 1.1 christos break; 3614 1.1 christos case X (OP_MACL, SL): 3615 1.7 christos res = h8_get_macl (cpu); 3616 1.1 christos break; 3617 1.1 christos default: goto illegal; 3618 1.1 christos } 3619 1.7 christos nz = !h8_get_macZ (cpu); 3620 1.7 christos n = h8_get_macN (cpu); 3621 1.7 christos v = h8_get_macV (cpu); 3622 1.1 christos 3623 1.1 christos if (store (sd, &code->dst, res)) 3624 1.1 christos goto end; 3625 1.1 christos 3626 1.1 christos goto next; 3627 1.1 christos 3628 1.1 christos case O (O_LDMAC, SL): /* ldmac, 179 */ 3629 1.1 christos if (fetch (sd, &code->src, &rd)) 3630 1.1 christos goto end; 3631 1.1 christos 3632 1.1 christos switch (code->dst.type) { 3633 1.1 christos case X (OP_MACH, SL): 3634 1.1 christos rd &= 0x3ff; /* Truncate to 10 bits */ 3635 1.7 christos h8_set_mach (cpu, rd); 3636 1.1 christos break; 3637 1.1 christos case X (OP_MACL, SL): 3638 1.7 christos h8_set_macl (cpu, rd); 3639 1.1 christos break; 3640 1.1 christos default: goto illegal; 3641 1.1 christos } 3642 1.7 christos h8_set_macV (cpu, 0); 3643 1.1 christos goto next; 3644 1.1 christos 3645 1.1 christos case O (O_MAC, SW): 3646 1.1 christos if (fetch (sd, &code->src, &rd) || 3647 1.1 christos fetch (sd, &code->dst, &res)) 3648 1.1 christos goto end; 3649 1.1 christos 3650 1.1 christos /* Ye gods, this is non-portable! 3651 1.1 christos However, the existing mul/div code is similar. */ 3652 1.1 christos res = SEXTSHORT (res) * SEXTSHORT (rd); 3653 1.1 christos 3654 1.7 christos if (h8_get_macS (cpu)) /* Saturating mode */ 3655 1.1 christos { 3656 1.7 christos long long mac = h8_get_macl (cpu); 3657 1.1 christos 3658 1.1 christos if (mac & 0x80000000) /* sign extend */ 3659 1.1 christos mac |= 0xffffffff00000000LL; 3660 1.1 christos 3661 1.1 christos mac += res; 3662 1.1 christos if (mac > 0x7fffffff || mac < 0xffffffff80000000LL) 3663 1.7 christos h8_set_macV (cpu, 1); 3664 1.7 christos h8_set_macZ (cpu, (mac == 0)); 3665 1.7 christos h8_set_macN (cpu, (mac < 0)); 3666 1.7 christos h8_set_macl (cpu, (int) mac); 3667 1.1 christos } 3668 1.1 christos else /* "Less Saturating" mode */ 3669 1.1 christos { 3670 1.7 christos long long mac = h8_get_mach (cpu); 3671 1.1 christos mac <<= 32; 3672 1.7 christos mac += h8_get_macl (cpu); 3673 1.1 christos 3674 1.1 christos if (mac & 0x20000000000LL) /* sign extend */ 3675 1.1 christos mac |= 0xfffffc0000000000LL; 3676 1.1 christos 3677 1.1 christos mac += res; 3678 1.1 christos if (mac > 0x1ffffffffffLL || 3679 1.1 christos mac < (long long) 0xfffffe0000000000LL) 3680 1.7 christos h8_set_macV (cpu, 1); 3681 1.7 christos h8_set_macZ (cpu, (mac == 0)); 3682 1.7 christos h8_set_macN (cpu, (mac < 0)); 3683 1.7 christos h8_set_macl (cpu, (int) mac); 3684 1.1 christos mac >>= 32; 3685 1.7 christos h8_set_mach (cpu, (int) (mac & 0x3ff)); 3686 1.1 christos } 3687 1.1 christos goto next; 3688 1.1 christos 3689 1.1 christos case O (O_MULS, SW): /* muls.w */ 3690 1.1 christos if (fetch (sd, &code->src, &ea) || 3691 1.1 christos fetch (sd, &code->dst, &rd)) 3692 1.1 christos goto end; 3693 1.1 christos 3694 1.1 christos ea = SEXTSHORT (ea); 3695 1.1 christos res = SEXTSHORT (ea * SEXTSHORT (rd)); 3696 1.1 christos 3697 1.1 christos n = res & 0x8000; 3698 1.1 christos nz = res & 0xffff; 3699 1.1 christos if (store (sd, &code->dst, res)) 3700 1.1 christos goto end; 3701 1.1 christos 3702 1.1 christos goto next; 3703 1.1 christos 3704 1.1 christos case O (O_MULS, SL): /* muls.l */ 3705 1.1 christos if (fetch (sd, &code->src, &ea) || 3706 1.1 christos fetch (sd, &code->dst, &rd)) 3707 1.1 christos goto end; 3708 1.1 christos 3709 1.1 christos res = ea * rd; 3710 1.1 christos 3711 1.1 christos n = res & 0x80000000; 3712 1.1 christos nz = res & 0xffffffff; 3713 1.1 christos if (store (sd, &code->dst, res)) 3714 1.1 christos goto end; 3715 1.1 christos goto next; 3716 1.1 christos 3717 1.1 christos case O (O_MULSU, SL): /* muls/u.l */ 3718 1.1 christos if (fetch (sd, &code->src, &ea) || 3719 1.1 christos fetch (sd, &code->dst, &rd)) 3720 1.1 christos goto end; 3721 1.1 christos 3722 1.1 christos /* Compute upper 32 bits of the 64-bit result. */ 3723 1.1 christos res = (((long long) ea) * ((long long) rd)) >> 32; 3724 1.1 christos 3725 1.1 christos n = res & 0x80000000; 3726 1.1 christos nz = res & 0xffffffff; 3727 1.1 christos if (store (sd, &code->dst, res)) 3728 1.1 christos goto end; 3729 1.1 christos goto next; 3730 1.1 christos 3731 1.1 christos case O (O_MULU, SW): /* mulu.w */ 3732 1.1 christos if (fetch (sd, &code->src, &ea) || 3733 1.1 christos fetch (sd, &code->dst, &rd)) 3734 1.1 christos goto end; 3735 1.1 christos 3736 1.1 christos res = UEXTSHORT ((UEXTSHORT (ea) * UEXTSHORT (rd))); 3737 1.1 christos 3738 1.1 christos /* Don't set Z or N. */ 3739 1.1 christos if (store (sd, &code->dst, res)) 3740 1.1 christos goto end; 3741 1.1 christos 3742 1.1 christos goto next; 3743 1.1 christos 3744 1.1 christos case O (O_MULU, SL): /* mulu.l */ 3745 1.1 christos if (fetch (sd, &code->src, &ea) || 3746 1.1 christos fetch (sd, &code->dst, &rd)) 3747 1.1 christos goto end; 3748 1.1 christos 3749 1.1 christos res = ea * rd; 3750 1.1 christos 3751 1.1 christos /* Don't set Z or N. */ 3752 1.1 christos if (store (sd, &code->dst, res)) 3753 1.1 christos goto end; 3754 1.1 christos 3755 1.1 christos goto next; 3756 1.1 christos 3757 1.1 christos case O (O_MULUU, SL): /* mulu/u.l */ 3758 1.1 christos if (fetch (sd, &code->src, &ea) || 3759 1.1 christos fetch (sd, &code->dst, &rd)) 3760 1.1 christos goto end; 3761 1.1 christos 3762 1.1 christos /* Compute upper 32 bits of the 64-bit result. */ 3763 1.1 christos res = (((unsigned long long) (unsigned) ea) * 3764 1.1 christos ((unsigned long long) (unsigned) rd)) >> 32; 3765 1.1 christos 3766 1.1 christos /* Don't set Z or N. */ 3767 1.1 christos if (store (sd, &code->dst, res)) 3768 1.1 christos goto end; 3769 1.1 christos 3770 1.1 christos goto next; 3771 1.1 christos 3772 1.1 christos case O (O_MULXS, SB): /* mulxs.b */ 3773 1.1 christos if (fetch (sd, &code->src, &ea) || 3774 1.1 christos fetch (sd, &code->dst, &rd)) 3775 1.1 christos goto end; 3776 1.1 christos 3777 1.1 christos ea = SEXTCHAR (ea); 3778 1.1 christos res = ea * SEXTCHAR (rd); 3779 1.1 christos 3780 1.1 christos n = res & 0x8000; 3781 1.1 christos nz = res & 0xffff; 3782 1.1 christos if (store (sd, &code->dst, res)) 3783 1.1 christos goto end; 3784 1.1 christos 3785 1.1 christos goto next; 3786 1.1 christos 3787 1.1 christos case O (O_MULXS, SW): /* mulxs.w */ 3788 1.1 christos if (fetch (sd, &code->src, &ea) || 3789 1.1 christos fetch (sd, &code->dst, &rd)) 3790 1.1 christos goto end; 3791 1.1 christos 3792 1.1 christos ea = SEXTSHORT (ea); 3793 1.1 christos res = ea * SEXTSHORT (rd & 0xffff); 3794 1.1 christos 3795 1.1 christos n = res & 0x80000000; 3796 1.1 christos nz = res & 0xffffffff; 3797 1.1 christos if (store (sd, &code->dst, res)) 3798 1.1 christos goto end; 3799 1.1 christos 3800 1.1 christos goto next; 3801 1.1 christos 3802 1.1 christos case O (O_MULXU, SB): /* mulxu.b */ 3803 1.1 christos if (fetch (sd, &code->src, &ea) || 3804 1.1 christos fetch (sd, &code->dst, &rd)) 3805 1.1 christos goto end; 3806 1.1 christos 3807 1.1 christos res = UEXTCHAR (ea) * UEXTCHAR (rd); 3808 1.1 christos 3809 1.1 christos if (store (sd, &code->dst, res)) 3810 1.1 christos goto end; 3811 1.1 christos 3812 1.1 christos goto next; 3813 1.1 christos 3814 1.1 christos case O (O_MULXU, SW): /* mulxu.w */ 3815 1.1 christos if (fetch (sd, &code->src, &ea) || 3816 1.1 christos fetch (sd, &code->dst, &rd)) 3817 1.1 christos goto end; 3818 1.1 christos 3819 1.1 christos res = UEXTSHORT (ea) * UEXTSHORT (rd); 3820 1.1 christos 3821 1.1 christos if (store (sd, &code->dst, res)) 3822 1.1 christos goto end; 3823 1.1 christos 3824 1.1 christos goto next; 3825 1.1 christos 3826 1.1 christos case O (O_TAS, SB): /* tas (test and set) */ 3827 1.1 christos if (!h8300sxmode) /* h8sx can use any register. */ 3828 1.1 christos switch (code->src.reg) 3829 1.1 christos { 3830 1.1 christos case R0_REGNUM: 3831 1.1 christos case R1_REGNUM: 3832 1.1 christos case R4_REGNUM: 3833 1.1 christos case R5_REGNUM: 3834 1.1 christos break; 3835 1.1 christos default: 3836 1.1 christos goto illegal; 3837 1.1 christos } 3838 1.1 christos 3839 1.1 christos if (fetch (sd, &code->src, &res)) 3840 1.1 christos goto end; 3841 1.1 christos if (store (sd, &code->src, res | 0x80)) 3842 1.1 christos goto end; 3843 1.1 christos 3844 1.1 christos goto just_flags_log8; 3845 1.1 christos 3846 1.1 christos case O (O_DIVU, SW): /* divu.w */ 3847 1.1 christos if (fetch (sd, &code->src, &ea) || 3848 1.1 christos fetch (sd, &code->dst, &rd)) 3849 1.1 christos goto end; 3850 1.1 christos 3851 1.1 christos n = ea & 0x8000; 3852 1.1 christos nz = ea & 0xffff; 3853 1.1 christos if (ea) 3854 1.1 christos res = (unsigned) (UEXTSHORT (rd) / UEXTSHORT (ea)); 3855 1.1 christos else 3856 1.1 christos res = 0; 3857 1.1 christos 3858 1.1 christos if (store (sd, &code->dst, res)) 3859 1.1 christos goto end; 3860 1.1 christos goto next; 3861 1.1 christos 3862 1.1 christos case O (O_DIVU, SL): /* divu.l */ 3863 1.1 christos if (fetch (sd, &code->src, &ea) || 3864 1.1 christos fetch (sd, &code->dst, &rd)) 3865 1.1 christos goto end; 3866 1.1 christos 3867 1.1 christos n = ea & 0x80000000; 3868 1.1 christos nz = ea & 0xffffffff; 3869 1.1 christos if (ea) 3870 1.1 christos res = (unsigned) rd / ea; 3871 1.1 christos else 3872 1.1 christos res = 0; 3873 1.1 christos 3874 1.1 christos if (store (sd, &code->dst, res)) 3875 1.1 christos goto end; 3876 1.1 christos goto next; 3877 1.1 christos 3878 1.1 christos case O (O_DIVS, SW): /* divs.w */ 3879 1.1 christos if (fetch (sd, &code->src, &ea) || 3880 1.1 christos fetch (sd, &code->dst, &rd)) 3881 1.1 christos goto end; 3882 1.1 christos 3883 1.1 christos if (ea) 3884 1.1 christos { 3885 1.1 christos res = SEXTSHORT (rd) / SEXTSHORT (ea); 3886 1.1 christos nz = 1; 3887 1.1 christos } 3888 1.1 christos else 3889 1.1 christos { 3890 1.1 christos res = 0; 3891 1.1 christos nz = 0; 3892 1.1 christos } 3893 1.1 christos 3894 1.1 christos n = res & 0x8000; 3895 1.1 christos if (store (sd, &code->dst, res)) 3896 1.1 christos goto end; 3897 1.1 christos goto next; 3898 1.1 christos 3899 1.1 christos case O (O_DIVS, SL): /* divs.l */ 3900 1.1 christos if (fetch (sd, &code->src, &ea) || 3901 1.1 christos fetch (sd, &code->dst, &rd)) 3902 1.1 christos goto end; 3903 1.1 christos 3904 1.1 christos if (ea) 3905 1.1 christos { 3906 1.1 christos res = rd / ea; 3907 1.1 christos nz = 1; 3908 1.1 christos } 3909 1.1 christos else 3910 1.1 christos { 3911 1.1 christos res = 0; 3912 1.1 christos nz = 0; 3913 1.1 christos } 3914 1.1 christos 3915 1.1 christos n = res & 0x80000000; 3916 1.1 christos if (store (sd, &code->dst, res)) 3917 1.1 christos goto end; 3918 1.1 christos goto next; 3919 1.1 christos 3920 1.1 christos case O (O_DIVXU, SB): /* divxu.b */ 3921 1.1 christos if (fetch (sd, &code->src, &ea) || 3922 1.1 christos fetch (sd, &code->dst, &rd)) 3923 1.1 christos goto end; 3924 1.1 christos 3925 1.1 christos rd = UEXTSHORT (rd); 3926 1.1 christos ea = UEXTCHAR (ea); 3927 1.1 christos 3928 1.1 christos n = ea & 0x80; 3929 1.1 christos nz = ea & 0xff; 3930 1.1 christos if (ea) 3931 1.1 christos { 3932 1.1 christos tmp = (unsigned) rd % ea; 3933 1.1 christos res = (unsigned) rd / ea; 3934 1.1 christos } 3935 1.1 christos else 3936 1.1 christos { 3937 1.1 christos tmp = 0; 3938 1.1 christos res = 0; 3939 1.1 christos } 3940 1.1 christos 3941 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8))) 3942 1.1 christos goto end; 3943 1.1 christos goto next; 3944 1.1 christos 3945 1.1 christos case O (O_DIVXU, SW): /* divxu.w */ 3946 1.1 christos if (fetch (sd, &code->src, &ea) || 3947 1.1 christos fetch (sd, &code->dst, &rd)) 3948 1.1 christos goto end; 3949 1.1 christos 3950 1.1 christos ea = UEXTSHORT (ea); 3951 1.1 christos 3952 1.1 christos n = ea & 0x8000; 3953 1.1 christos nz = ea & 0xffff; 3954 1.1 christos if (ea) 3955 1.1 christos { 3956 1.1 christos tmp = (unsigned) rd % ea; 3957 1.1 christos res = (unsigned) rd / ea; 3958 1.1 christos } 3959 1.1 christos else 3960 1.1 christos { 3961 1.1 christos tmp = 0; 3962 1.1 christos res = 0; 3963 1.1 christos } 3964 1.1 christos 3965 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16))) 3966 1.1 christos goto end; 3967 1.1 christos goto next; 3968 1.1 christos 3969 1.1 christos case O (O_DIVXS, SB): /* divxs.b */ 3970 1.1 christos if (fetch (sd, &code->src, &ea) || 3971 1.1 christos fetch (sd, &code->dst, &rd)) 3972 1.1 christos goto end; 3973 1.1 christos 3974 1.1 christos rd = SEXTSHORT (rd); 3975 1.1 christos ea = SEXTCHAR (ea); 3976 1.1 christos 3977 1.1 christos if (ea) 3978 1.1 christos { 3979 1.1 christos tmp = (int) rd % (int) ea; 3980 1.1 christos res = (int) rd / (int) ea; 3981 1.1 christos nz = 1; 3982 1.1 christos } 3983 1.1 christos else 3984 1.1 christos { 3985 1.1 christos tmp = 0; 3986 1.1 christos res = 0; 3987 1.1 christos nz = 0; 3988 1.1 christos } 3989 1.1 christos 3990 1.1 christos n = res & 0x8000; 3991 1.1 christos if (store (sd, &code->dst, (res & 0xff) | (tmp << 8))) 3992 1.1 christos goto end; 3993 1.1 christos goto next; 3994 1.1 christos 3995 1.1 christos case O (O_DIVXS, SW): /* divxs.w */ 3996 1.1 christos if (fetch (sd, &code->src, &ea) || 3997 1.1 christos fetch (sd, &code->dst, &rd)) 3998 1.1 christos goto end; 3999 1.1 christos 4000 1.1 christos ea = SEXTSHORT (ea); 4001 1.1 christos 4002 1.1 christos if (ea) 4003 1.1 christos { 4004 1.1 christos tmp = (int) rd % (int) ea; 4005 1.1 christos res = (int) rd / (int) ea; 4006 1.1 christos nz = 1; 4007 1.1 christos } 4008 1.1 christos else 4009 1.1 christos { 4010 1.1 christos tmp = 0; 4011 1.1 christos res = 0; 4012 1.1 christos nz = 0; 4013 1.1 christos } 4014 1.1 christos 4015 1.1 christos n = res & 0x80000000; 4016 1.1 christos if (store (sd, &code->dst, (res & 0xffff) | (tmp << 16))) 4017 1.1 christos goto end; 4018 1.1 christos goto next; 4019 1.1 christos 4020 1.1 christos case O (O_EXTS, SW): /* exts.w, signed extend */ 4021 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 4022 1.1 christos goto end; 4023 1.1 christos ea = rd & 0x80 ? -256 : 0; 4024 1.1 christos res = (rd & 0xff) + ea; 4025 1.1 christos goto log16; 4026 1.1 christos 4027 1.1 christos case O (O_EXTS, SL): /* exts.l, signed extend */ 4028 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 4029 1.1 christos goto end; 4030 1.1 christos if (code->src.type == X (OP_IMM, SL)) 4031 1.1 christos { 4032 1.1 christos if (fetch (sd, &code->src, &ea)) 4033 1.1 christos goto end; 4034 1.1 christos 4035 1.1 christos if (ea == 2) /* exts.l #2, nn */ 4036 1.1 christos { 4037 1.1 christos /* Sign-extend from 8-bit to 32-bit. */ 4038 1.1 christos ea = rd & 0x80 ? -256 : 0; 4039 1.1 christos res = (rd & 0xff) + ea; 4040 1.1 christos goto log32; 4041 1.1 christos } 4042 1.1 christos } 4043 1.1 christos /* Sign-extend from 16-bit to 32-bit. */ 4044 1.1 christos ea = rd & 0x8000 ? -65536 : 0; 4045 1.1 christos res = (rd & 0xffff) + ea; 4046 1.1 christos goto log32; 4047 1.1 christos 4048 1.1 christos case O (O_EXTU, SW): /* extu.w, unsigned extend */ 4049 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 4050 1.1 christos goto end; 4051 1.1 christos ea = 0; 4052 1.1 christos res = (rd & 0xff) + ea; 4053 1.1 christos goto log16; 4054 1.1 christos 4055 1.1 christos case O (O_EXTU, SL): /* extu.l, unsigned extend */ 4056 1.1 christos if (fetch2 (sd, &code->dst, &rd)) 4057 1.1 christos goto end; 4058 1.1 christos if (code->src.type == X (OP_IMM, SL)) 4059 1.1 christos { 4060 1.1 christos if (fetch (sd, &code->src, &ea)) 4061 1.1 christos goto end; 4062 1.1 christos 4063 1.1 christos if (ea == 2) /* extu.l #2, nn */ 4064 1.1 christos { 4065 1.1 christos /* Zero-extend from 8-bit to 32-bit. */ 4066 1.1 christos ea = 0; 4067 1.1 christos res = (rd & 0xff) + ea; 4068 1.1 christos goto log32; 4069 1.1 christos } 4070 1.1 christos } 4071 1.1 christos /* Zero-extend from 16-bit to 32-bit. */ 4072 1.1 christos ea = 0; 4073 1.1 christos res = (rd & 0xffff) + ea; 4074 1.1 christos goto log32; 4075 1.1 christos 4076 1.1 christos case O (O_NOP, SN): /* nop */ 4077 1.1 christos goto next; 4078 1.1 christos 4079 1.1 christos case O (O_STM, SL): /* stm, store to memory */ 4080 1.1 christos { 4081 1.1 christos int nregs, firstreg, i; 4082 1.1 christos 4083 1.1 christos nregs = GET_MEMORY_B (pc + 1); 4084 1.1 christos nregs >>= 4; 4085 1.1 christos nregs &= 0xf; 4086 1.1 christos firstreg = code->src.reg; 4087 1.1 christos firstreg &= 0xf; 4088 1.1 christos for (i = firstreg; i <= firstreg + nregs; i++) 4089 1.1 christos { 4090 1.7 christos h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) - 4); 4091 1.7 christos SET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM), h8_get_reg (cpu, i)); 4092 1.1 christos } 4093 1.1 christos } 4094 1.1 christos goto next; 4095 1.1 christos 4096 1.1 christos case O (O_LDM, SL): /* ldm, load from memory */ 4097 1.1 christos case O (O_RTEL, SN): /* rte/l, ldm plus rte */ 4098 1.1 christos case O (O_RTSL, SN): /* rts/l, ldm plus rts */ 4099 1.1 christos { 4100 1.1 christos int nregs, firstreg, i; 4101 1.1 christos 4102 1.1 christos nregs = ((GET_MEMORY_B (pc + 1) >> 4) & 0xf); 4103 1.1 christos firstreg = code->dst.reg & 0xf; 4104 1.1 christos for (i = firstreg; i >= firstreg - nregs; i--) 4105 1.1 christos { 4106 1.7 christos h8_set_reg (cpu, i, GET_MEMORY_L (h8_get_reg (cpu, SP_REGNUM))); 4107 1.7 christos h8_set_reg (cpu, SP_REGNUM, h8_get_reg (cpu, SP_REGNUM) + 4); 4108 1.1 christos } 4109 1.1 christos } 4110 1.1 christos switch (code->opcode) { 4111 1.1 christos case O (O_RTEL, SN): 4112 1.1 christos goto rte; 4113 1.1 christos case O (O_RTSL, SN): 4114 1.1 christos goto rts; 4115 1.1 christos case O (O_LDM, SL): 4116 1.1 christos goto next; 4117 1.1 christos default: 4118 1.1 christos goto illegal; 4119 1.1 christos } 4120 1.1 christos 4121 1.1 christos case O (O_DAA, SB): 4122 1.1 christos /* Decimal Adjust Addition. This is for BCD arithmetic. */ 4123 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch? */ 4124 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) && 4125 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) 4126 1.7 christos /* Nothing. */; /* Value added == 0. */ 4127 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) && 4128 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) 4129 1.1 christos res = res + 0x6; /* Value added == 6. */ 4130 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) && 4131 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) 4132 1.1 christos res = res + 0x6; /* Value added == 6. */ 4133 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) && 4134 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) 4135 1.1 christos res = res + 0x60; /* Value added == 60. */ 4136 1.1 christos else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) && 4137 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) 4138 1.1 christos res = res + 0x66; /* Value added == 66. */ 4139 1.1 christos else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) && 4140 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) 4141 1.1 christos res = res + 0x66; /* Value added == 66. */ 4142 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) && 4143 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) 4144 1.1 christos res = res + 0x60; /* Value added == 60. */ 4145 1.1 christos else if ( c && (1 <= (res >> 4) && (res >> 4) <= 2) && 4146 1.1 christos !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) 4147 1.1 christos res = res + 0x66; /* Value added == 66. */ 4148 1.1 christos else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) && 4149 1.1 christos h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) 4150 1.1 christos res = res + 0x66; /* Value added == 66. */ 4151 1.1 christos 4152 1.1 christos goto alu8; 4153 1.1 christos 4154 1.1 christos case O (O_DAS, SB): 4155 1.1 christos /* Decimal Adjust Subtraction. This is for BCD arithmetic. */ 4156 1.1 christos res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */ 4157 1.1 christos if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) && 4158 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) 4159 1.7 christos /* Nothing. */; /* Value added == 0. */ 4160 1.1 christos else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) && 4161 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15)) 4162 1.1 christos res = res + 0xfa; /* Value added == 0xfa. */ 4163 1.1 christos else if ( c && (7 <= (res >> 4) && (res >> 4) <= 15) && 4164 1.1 christos !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) 4165 1.1 christos res = res + 0xa0; /* Value added == 0xa0. */ 4166 1.1 christos else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) && 4167 1.1 christos h && (6 <= (res & 0xf) && (res & 0xf) <= 15)) 4168 1.1 christos res = res + 0x9a; /* Value added == 0x9a. */ 4169 1.1 christos 4170 1.1 christos goto alu8; 4171 1.1 christos 4172 1.1 christos default: 4173 1.1 christos illegal: 4174 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL); 4175 1.1 christos goto end; 4176 1.1 christos 4177 1.1 christos } 4178 1.1 christos 4179 1.6 christos sim_io_printf (sd, "sim_resume: internal error.\n"); 4180 1.6 christos sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL); 4181 1.1 christos goto end; 4182 1.1 christos 4183 1.1 christos setc: 4184 1.1 christos if (code->dst.type == X (OP_CCR, SB) || 4185 1.1 christos code->dst.type == X (OP_CCR, SW)) 4186 1.1 christos { 4187 1.7 christos h8_set_ccr (cpu, res); 4188 1.7 christos GETSR (cpu); 4189 1.1 christos } 4190 1.1 christos else if (h8300smode && 4191 1.1 christos (code->dst.type == X (OP_EXR, SB) || 4192 1.1 christos code->dst.type == X (OP_EXR, SW))) 4193 1.1 christos { 4194 1.7 christos h8_set_exr (cpu, res); 4195 1.1 christos if (h8300smode) /* Get exr. */ 4196 1.1 christos { 4197 1.7 christos trace = (h8_get_exr (cpu) >> 7) & 1; 4198 1.7 christos intMask = h8_get_exr (cpu) & 7; 4199 1.1 christos } 4200 1.1 christos } 4201 1.1 christos else 4202 1.1 christos goto illegal; 4203 1.1 christos 4204 1.1 christos goto next; 4205 1.1 christos 4206 1.1 christos condtrue: 4207 1.1 christos /* When a branch works */ 4208 1.1 christos if (fetch (sd, &code->src, &res)) 4209 1.1 christos goto end; 4210 1.1 christos if (res & 1) /* bad address */ 4211 1.1 christos goto illegal; 4212 1.1 christos pc = code->next_pc + res; 4213 1.1 christos goto end; 4214 1.1 christos 4215 1.1 christos /* Set the cond codes from res */ 4216 1.1 christos bitop: 4217 1.1 christos 4218 1.1 christos /* Set the flags after an 8 bit inc/dec operation */ 4219 1.1 christos just_flags_inc8: 4220 1.1 christos n = res & 0x80; 4221 1.1 christos nz = res & 0xff; 4222 1.1 christos v = (rd & 0x7f) == 0x7f; 4223 1.1 christos goto next; 4224 1.1 christos 4225 1.1 christos /* Set the flags after an 16 bit inc/dec operation */ 4226 1.1 christos just_flags_inc16: 4227 1.1 christos n = res & 0x8000; 4228 1.1 christos nz = res & 0xffff; 4229 1.1 christos v = (rd & 0x7fff) == 0x7fff; 4230 1.1 christos goto next; 4231 1.1 christos 4232 1.1 christos /* Set the flags after an 32 bit inc/dec operation */ 4233 1.1 christos just_flags_inc32: 4234 1.1 christos n = res & 0x80000000; 4235 1.1 christos nz = res & 0xffffffff; 4236 1.1 christos v = (rd & 0x7fffffff) == 0x7fffffff; 4237 1.1 christos goto next; 4238 1.1 christos 4239 1.1 christos shift8: 4240 1.1 christos /* Set flags after an 8 bit shift op, carry,overflow set in insn */ 4241 1.1 christos n = (rd & 0x80); 4242 1.1 christos nz = rd & 0xff; 4243 1.1 christos if (store2 (sd, &code->dst, rd)) 4244 1.1 christos goto end; 4245 1.1 christos goto next; 4246 1.1 christos 4247 1.1 christos shift16: 4248 1.1 christos /* Set flags after an 16 bit shift op, carry,overflow set in insn */ 4249 1.1 christos n = (rd & 0x8000); 4250 1.1 christos nz = rd & 0xffff; 4251 1.1 christos if (store2 (sd, &code->dst, rd)) 4252 1.1 christos goto end; 4253 1.1 christos goto next; 4254 1.1 christos 4255 1.1 christos shift32: 4256 1.1 christos /* Set flags after an 32 bit shift op, carry,overflow set in insn */ 4257 1.1 christos n = (rd & 0x80000000); 4258 1.1 christos nz = rd & 0xffffffff; 4259 1.1 christos if (store2 (sd, &code->dst, rd)) 4260 1.1 christos goto end; 4261 1.1 christos goto next; 4262 1.1 christos 4263 1.1 christos log32: 4264 1.1 christos if (store2 (sd, &code->dst, res)) 4265 1.1 christos goto end; 4266 1.1 christos 4267 1.1 christos just_flags_log32: 4268 1.1 christos /* flags after a 32bit logical operation */ 4269 1.1 christos n = res & 0x80000000; 4270 1.1 christos nz = res & 0xffffffff; 4271 1.1 christos v = 0; 4272 1.1 christos goto next; 4273 1.1 christos 4274 1.1 christos log16: 4275 1.1 christos if (store2 (sd, &code->dst, res)) 4276 1.1 christos goto end; 4277 1.1 christos 4278 1.1 christos just_flags_log16: 4279 1.1 christos /* flags after a 16bit logical operation */ 4280 1.1 christos n = res & 0x8000; 4281 1.1 christos nz = res & 0xffff; 4282 1.1 christos v = 0; 4283 1.1 christos goto next; 4284 1.1 christos 4285 1.1 christos log8: 4286 1.1 christos if (store2 (sd, &code->dst, res)) 4287 1.1 christos goto end; 4288 1.1 christos 4289 1.1 christos just_flags_log8: 4290 1.1 christos n = res & 0x80; 4291 1.1 christos nz = res & 0xff; 4292 1.1 christos v = 0; 4293 1.1 christos goto next; 4294 1.1 christos 4295 1.1 christos alu8: 4296 1.1 christos if (store2 (sd, &code->dst, res)) 4297 1.1 christos goto end; 4298 1.1 christos 4299 1.1 christos just_flags_alu8: 4300 1.1 christos n = res & 0x80; 4301 1.1 christos nz = res & 0xff; 4302 1.1 christos c = (res & 0x100); 4303 1.1 christos switch (code->opcode / 4) 4304 1.1 christos { 4305 1.1 christos case O_ADD: 4306 1.1 christos case O_ADDX: 4307 1.1 christos v = ((rd & 0x80) == (ea & 0x80) 4308 1.1 christos && (rd & 0x80) != (res & 0x80)); 4309 1.1 christos break; 4310 1.1 christos case O_SUB: 4311 1.1 christos case O_SUBX: 4312 1.1 christos case O_CMP: 4313 1.1 christos v = ((rd & 0x80) != (-ea & 0x80) 4314 1.1 christos && (rd & 0x80) != (res & 0x80)); 4315 1.1 christos break; 4316 1.1 christos case O_NEG: 4317 1.1 christos v = (rd == 0x80); 4318 1.1 christos break; 4319 1.1 christos case O_DAA: 4320 1.1 christos case O_DAS: 4321 1.1 christos break; /* No effect on v flag. */ 4322 1.1 christos } 4323 1.1 christos goto next; 4324 1.1 christos 4325 1.1 christos alu16: 4326 1.1 christos if (store2 (sd, &code->dst, res)) 4327 1.1 christos goto end; 4328 1.1 christos 4329 1.1 christos just_flags_alu16: 4330 1.1 christos n = res & 0x8000; 4331 1.1 christos nz = res & 0xffff; 4332 1.1 christos c = (res & 0x10000); 4333 1.1 christos switch (code->opcode / 4) 4334 1.1 christos { 4335 1.1 christos case O_ADD: 4336 1.1 christos case O_ADDX: 4337 1.1 christos v = ((rd & 0x8000) == (ea & 0x8000) 4338 1.1 christos && (rd & 0x8000) != (res & 0x8000)); 4339 1.1 christos break; 4340 1.1 christos case O_SUB: 4341 1.1 christos case O_SUBX: 4342 1.1 christos case O_CMP: 4343 1.1 christos v = ((rd & 0x8000) != (-ea & 0x8000) 4344 1.1 christos && (rd & 0x8000) != (res & 0x8000)); 4345 1.1 christos break; 4346 1.1 christos case O_NEG: 4347 1.1 christos v = (rd == 0x8000); 4348 1.1 christos break; 4349 1.1 christos } 4350 1.1 christos goto next; 4351 1.1 christos 4352 1.1 christos alu32: 4353 1.1 christos if (store2 (sd, &code->dst, res)) 4354 1.1 christos goto end; 4355 1.1 christos 4356 1.1 christos just_flags_alu32: 4357 1.1 christos n = res & 0x80000000; 4358 1.1 christos nz = res & 0xffffffff; 4359 1.1 christos switch (code->opcode / 4) 4360 1.1 christos { 4361 1.1 christos case O_ADD: 4362 1.1 christos case O_ADDX: 4363 1.1 christos v = ((rd & 0x80000000) == (ea & 0x80000000) 4364 1.1 christos && (rd & 0x80000000) != (res & 0x80000000)); 4365 1.1 christos c = ((unsigned) res < (unsigned) rd) || 4366 1.1 christos ((unsigned) res < (unsigned) ea); 4367 1.1 christos break; 4368 1.1 christos case O_SUB: 4369 1.1 christos case O_SUBX: 4370 1.1 christos case O_CMP: 4371 1.1 christos v = ((rd & 0x80000000) != (-ea & 0x80000000) 4372 1.1 christos && (rd & 0x80000000) != (res & 0x80000000)); 4373 1.1 christos c = (unsigned) rd < (unsigned) -ea; 4374 1.1 christos break; 4375 1.1 christos case O_NEG: 4376 1.1 christos v = (rd == 0x80000000); 4377 1.1 christos c = res != 0; 4378 1.1 christos break; 4379 1.1 christos } 4380 1.1 christos goto next; 4381 1.1 christos 4382 1.1 christos next: 4383 1.7 christos if ((res = h8_get_delayed_branch (cpu)) != 0) 4384 1.1 christos { 4385 1.1 christos pc = res; 4386 1.7 christos h8_set_delayed_branch (cpu, 0); 4387 1.1 christos } 4388 1.1 christos else 4389 1.1 christos pc = code->next_pc; 4390 1.1 christos 4391 1.6 christos } while (0); 4392 1.1 christos 4393 1.6 christos end: 4394 1.7 christos h8_set_ticks (cpu, h8_get_ticks (cpu) + get_now () - tick_start); 4395 1.7 christos h8_set_cycles (cpu, h8_get_cycles (cpu) + cycles); 4396 1.7 christos h8_set_insts (cpu, h8_get_insts (cpu) + insts); 4397 1.7 christos cpu_set_pc (cpu, pc); 4398 1.7 christos BUILDSR (cpu); 4399 1.1 christos 4400 1.1 christos if (h8300smode) 4401 1.7 christos h8_set_exr (cpu, (trace<<7) | intMask); 4402 1.1 christos 4403 1.7 christos h8_set_mask (cpu, oldmask); 4404 1.1 christos } 4405 1.1 christos 4406 1.6 christos void 4407 1.6 christos sim_engine_run (SIM_DESC sd, 4408 1.6 christos int next_cpu_nr, /* ignore */ 4409 1.6 christos int nr_cpus, /* ignore */ 4410 1.6 christos int siggnal) 4411 1.6 christos { 4412 1.6 christos sim_cpu *cpu; 4413 1.6 christos 4414 1.6 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 4415 1.6 christos 4416 1.6 christos cpu = STATE_CPU (sd, 0); 4417 1.6 christos 4418 1.6 christos while (1) 4419 1.6 christos { 4420 1.6 christos step_once (sd, cpu); 4421 1.6 christos if (sim_events_tick (sd)) 4422 1.6 christos sim_events_process (sd); 4423 1.6 christos } 4424 1.6 christos } 4425 1.6 christos 4426 1.8 christos uint64_t 4427 1.8 christos sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t size) 4428 1.1 christos { 4429 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0); 4430 1.1 christos int i; 4431 1.7 christos const unsigned char *data = buffer; 4432 1.1 christos 4433 1.1 christos init_pointers (sd); 4434 1.1 christos if (addr < 0) 4435 1.1 christos return 0; 4436 1.1 christos for (i = 0; i < size; i++) 4437 1.1 christos { 4438 1.1 christos if (addr < memory_size) 4439 1.1 christos { 4440 1.7 christos h8_set_memory (cpu, addr + i, data[i]); 4441 1.1 christos } 4442 1.1 christos else 4443 1.7 christos break; 4444 1.1 christos } 4445 1.7 christos return i; 4446 1.1 christos } 4447 1.1 christos 4448 1.8 christos uint64_t 4449 1.8 christos sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t size) 4450 1.1 christos { 4451 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0); 4452 1.7 christos 4453 1.1 christos init_pointers (sd); 4454 1.1 christos if (addr < 0) 4455 1.1 christos return 0; 4456 1.7 christos if (addr + size < memory_size) 4457 1.7 christos memcpy (buffer, h8_get_memory_buf (cpu) + addr, size); 4458 1.1 christos else 4459 1.7 christos return 0; 4460 1.1 christos return size; 4461 1.1 christos } 4462 1.1 christos 4463 1.6 christos static int 4464 1.7 christos h8300_reg_store (SIM_CPU *cpu, int rn, const void *buf, int length) 4465 1.1 christos { 4466 1.7 christos const unsigned char *value = buf; 4467 1.1 christos int longval; 4468 1.1 christos int shortval; 4469 1.1 christos int intval; 4470 1.7 christos 4471 1.1 christos longval = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; 4472 1.1 christos shortval = (value[0] << 8) | (value[1]); 4473 1.1 christos intval = h8300hmode ? longval : shortval; 4474 1.1 christos 4475 1.6 christos init_pointers (CPU_STATE (cpu)); 4476 1.1 christos switch (rn) 4477 1.1 christos { 4478 1.1 christos case PC_REGNUM: 4479 1.1 christos if(h8300_normal_mode) 4480 1.7 christos cpu_set_pc (cpu, shortval); /* PC for Normal mode is 2 bytes */ 4481 1.1 christos else 4482 1.7 christos cpu_set_pc (cpu, intval); 4483 1.1 christos break; 4484 1.1 christos default: 4485 1.6 christos return -1; 4486 1.1 christos case R0_REGNUM: 4487 1.1 christos case R1_REGNUM: 4488 1.1 christos case R2_REGNUM: 4489 1.1 christos case R3_REGNUM: 4490 1.1 christos case R4_REGNUM: 4491 1.1 christos case R5_REGNUM: 4492 1.1 christos case R6_REGNUM: 4493 1.1 christos case R7_REGNUM: 4494 1.1 christos case CCR_REGNUM: 4495 1.1 christos case EXR_REGNUM: 4496 1.1 christos case SBR_REGNUM: 4497 1.1 christos case VBR_REGNUM: 4498 1.1 christos case MACH_REGNUM: 4499 1.1 christos case MACL_REGNUM: 4500 1.7 christos h8_set_reg (cpu, rn, intval); 4501 1.1 christos break; 4502 1.1 christos case CYCLE_REGNUM: 4503 1.1 christos case INST_REGNUM: 4504 1.1 christos case TICK_REGNUM: 4505 1.7 christos h8_set_reg (cpu, rn, longval); 4506 1.1 christos break; 4507 1.1 christos } 4508 1.1 christos return length; 4509 1.1 christos } 4510 1.1 christos 4511 1.6 christos static int 4512 1.7 christos h8300_reg_fetch (SIM_CPU *cpu, int rn, void *buf, int length) 4513 1.1 christos { 4514 1.7 christos unsigned char *value = buf; 4515 1.1 christos int v; 4516 1.1 christos int longreg = 0; 4517 1.1 christos 4518 1.6 christos init_pointers (CPU_STATE (cpu)); 4519 1.1 christos 4520 1.1 christos if (!h8300smode && rn >= EXR_REGNUM) 4521 1.1 christos rn++; 4522 1.1 christos switch (rn) 4523 1.1 christos { 4524 1.1 christos default: 4525 1.6 christos return -1; 4526 1.6 christos case PC_REGNUM: 4527 1.7 christos v = cpu_get_pc (cpu); 4528 1.1 christos break; 4529 1.1 christos case CCR_REGNUM: 4530 1.1 christos case EXR_REGNUM: 4531 1.1 christos case SBR_REGNUM: 4532 1.1 christos case VBR_REGNUM: 4533 1.1 christos case MACH_REGNUM: 4534 1.1 christos case MACL_REGNUM: 4535 1.1 christos case R0_REGNUM: 4536 1.1 christos case R1_REGNUM: 4537 1.1 christos case R2_REGNUM: 4538 1.1 christos case R3_REGNUM: 4539 1.1 christos case R4_REGNUM: 4540 1.1 christos case R5_REGNUM: 4541 1.1 christos case R6_REGNUM: 4542 1.1 christos case R7_REGNUM: 4543 1.7 christos v = h8_get_reg (cpu, rn); 4544 1.1 christos break; 4545 1.1 christos case CYCLE_REGNUM: 4546 1.1 christos case TICK_REGNUM: 4547 1.6 christos case INST_REGNUM: 4548 1.7 christos v = h8_get_reg (cpu, rn); 4549 1.1 christos longreg = 1; 4550 1.1 christos break; 4551 1.6 christos case ZERO_REGNUM: 4552 1.6 christos v = 0; 4553 1.1 christos break; 4554 1.1 christos } 4555 1.1 christos /* In Normal mode PC is 2 byte, but other registers are 4 byte */ 4556 1.1 christos if ((h8300hmode || longreg) && !(rn == PC_REGNUM && h8300_normal_mode)) 4557 1.1 christos { 4558 1.7 christos value[0] = v >> 24; 4559 1.7 christos value[1] = v >> 16; 4560 1.7 christos value[2] = v >> 8; 4561 1.7 christos value[3] = v >> 0; 4562 1.6 christos return 4; 4563 1.1 christos } 4564 1.1 christos else 4565 1.1 christos { 4566 1.7 christos value[0] = v >> 8; 4567 1.7 christos value[1] = v; 4568 1.6 christos return 2; 4569 1.1 christos } 4570 1.1 christos } 4571 1.1 christos 4572 1.1 christos void 4573 1.8 christos sim_info (SIM_DESC sd, bool verbose) 4574 1.1 christos { 4575 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0); 4576 1.7 christos double timetaken = (double) h8_get_ticks (cpu) / (double) now_persec (); 4577 1.7 christos double virttime = h8_get_cycles (cpu) / 10.0e6; 4578 1.1 christos 4579 1.7 christos sim_io_printf (sd, "\n\n#instructions executed %10d\n", h8_get_insts (cpu)); 4580 1.7 christos sim_io_printf (sd, "#cycles (v approximate) %10d\n", h8_get_cycles (cpu)); 4581 1.6 christos sim_io_printf (sd, "#real time taken %10.4f\n", timetaken); 4582 1.6 christos sim_io_printf (sd, "#virtual time taken %10.4f\n", virttime); 4583 1.1 christos if (timetaken != 0.0) 4584 1.6 christos sim_io_printf (sd, "#simulation ratio %10.4f\n", virttime / timetaken); 4585 1.1 christos 4586 1.1 christos #ifdef ADEBUG 4587 1.1 christos /* This to be conditional on `what' (aka `verbose'), 4588 1.1 christos however it was never passed as non-zero. */ 4589 1.1 christos if (1) 4590 1.1 christos { 4591 1.1 christos int i; 4592 1.1 christos for (i = 0; i < O_LAST; i++) 4593 1.1 christos { 4594 1.1 christos if (h8_get_stats (sd, i)) 4595 1.6 christos sim_io_printf (sd, "%d: %d\n", i, h8_get_stats (sd, i)); 4596 1.1 christos } 4597 1.1 christos } 4598 1.1 christos #endif 4599 1.1 christos } 4600 1.1 christos 4601 1.1 christos /* Indicate whether the cpu is an H8/300 or H8/300H. 4602 1.1 christos FLAG is non-zero for the H8/300H. */ 4603 1.1 christos 4604 1.7 christos static void 4605 1.1 christos set_h8300h (unsigned long machine) 4606 1.1 christos { 4607 1.1 christos /* FIXME: Much of the code in sim_load can be moved to sim_open. 4608 1.1 christos This function being replaced by a sim_open:ARGV configuration 4609 1.1 christos option. */ 4610 1.1 christos 4611 1.1 christos h8300hmode = h8300smode = h8300sxmode = h8300_normal_mode = 0; 4612 1.1 christos 4613 1.1 christos if (machine == bfd_mach_h8300sx || machine == bfd_mach_h8300sxn) 4614 1.1 christos h8300sxmode = 1; 4615 1.1 christos 4616 1.1 christos if (machine == bfd_mach_h8300s || machine == bfd_mach_h8300sn || h8300sxmode) 4617 1.1 christos h8300smode = 1; 4618 1.1 christos 4619 1.1 christos if (machine == bfd_mach_h8300h || machine == bfd_mach_h8300hn || h8300smode) 4620 1.1 christos h8300hmode = 1; 4621 1.1 christos 4622 1.1 christos if(machine == bfd_mach_h8300hn || machine == bfd_mach_h8300sn || machine == bfd_mach_h8300sxn) 4623 1.1 christos h8300_normal_mode = 1; 4624 1.1 christos } 4625 1.1 christos 4626 1.6 christos /* H8300-specific options. 4627 1.6 christos TODO: These really should be merged into the common model modules. */ 4628 1.6 christos typedef enum { 4629 1.6 christos OPTION_H8300H, 4630 1.6 christos OPTION_H8300S, 4631 1.6 christos OPTION_H8300SX 4632 1.6 christos } H8300_OPTIONS; 4633 1.6 christos 4634 1.6 christos static SIM_RC 4635 1.6 christos h8300_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt, 4636 1.6 christos char *arg, int is_command ATTRIBUTE_UNUSED) 4637 1.6 christos { 4638 1.6 christos switch ((H8300_OPTIONS) opt) 4639 1.6 christos { 4640 1.6 christos case OPTION_H8300H: 4641 1.6 christos set_h8300h (bfd_mach_h8300h); 4642 1.6 christos break; 4643 1.6 christos case OPTION_H8300S: 4644 1.6 christos set_h8300h (bfd_mach_h8300s); 4645 1.6 christos break; 4646 1.6 christos case OPTION_H8300SX: 4647 1.6 christos set_h8300h (bfd_mach_h8300sx); 4648 1.6 christos break; 4649 1.6 christos 4650 1.6 christos default: 4651 1.6 christos /* We'll actually never get here; the caller handles the error 4652 1.6 christos case. */ 4653 1.6 christos sim_io_eprintf (sd, "Unknown option `%s'\n", arg); 4654 1.6 christos return SIM_RC_FAIL; 4655 1.6 christos } 4656 1.6 christos 4657 1.6 christos return SIM_RC_OK; 4658 1.6 christos } 4659 1.6 christos 4660 1.6 christos static const OPTION h8300_options[] = 4661 1.6 christos { 4662 1.6 christos { {"h8300h", no_argument, NULL, OPTION_H8300H}, 4663 1.6 christos 'h', NULL, "Indicate the CPU is H8/300H", 4664 1.6 christos h8300_option_handler }, 4665 1.6 christos { {"h8300s", no_argument, NULL, OPTION_H8300S}, 4666 1.6 christos 'S', NULL, "Indicate the CPU is H8S", 4667 1.6 christos h8300_option_handler }, 4668 1.6 christos { {"h8300sx", no_argument, NULL, OPTION_H8300SX}, 4669 1.6 christos 'x', NULL, "Indicate the CPU is H8SX", 4670 1.6 christos h8300_option_handler }, 4671 1.6 christos { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL } 4672 1.6 christos }; 4673 1.6 christos 4674 1.5 christos static sim_cia 4675 1.5 christos h8300_pc_get (sim_cpu *cpu) 4676 1.5 christos { 4677 1.8 christos return H8300_SIM_CPU (cpu)->pc; 4678 1.5 christos } 4679 1.5 christos 4680 1.5 christos static void 4681 1.5 christos h8300_pc_set (sim_cpu *cpu, sim_cia pc) 4682 1.5 christos { 4683 1.8 christos H8300_SIM_CPU (cpu)->pc = pc; 4684 1.5 christos } 4685 1.5 christos 4686 1.1 christos /* Cover function of sim_state_free to free the cpu buffers as well. */ 4687 1.1 christos 4688 1.1 christos static void 4689 1.1 christos free_state (SIM_DESC sd) 4690 1.1 christos { 4691 1.1 christos if (STATE_MODULES (sd) != NULL) 4692 1.1 christos sim_module_uninstall (sd); 4693 1.1 christos 4694 1.1 christos /* Fixme: free buffers in _sim_cpu. */ 4695 1.1 christos sim_state_free (sd); 4696 1.1 christos } 4697 1.1 christos 4698 1.1 christos SIM_DESC 4699 1.1 christos sim_open (SIM_OPEN_KIND kind, 4700 1.1 christos struct host_callback_struct *callback, 4701 1.1 christos struct bfd *abfd, 4702 1.6 christos char * const *argv) 4703 1.1 christos { 4704 1.5 christos int i; 4705 1.1 christos SIM_DESC sd; 4706 1.1 christos sim_cpu *cpu; 4707 1.1 christos 4708 1.7 christos sd = sim_state_alloc_extra (kind, callback, sizeof (struct h8300_sim_state)); 4709 1.7 christos 4710 1.7 christos /* Set default options before parsing user options. */ 4711 1.7 christos current_target_byte_order = BFD_ENDIAN_BIG; 4712 1.5 christos 4713 1.5 christos /* The cpu data is kept in a separately allocated chunk of memory. */ 4714 1.8 christos if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct h8300_sim_cpu)) 4715 1.8 christos != SIM_RC_OK) 4716 1.5 christos { 4717 1.5 christos free_state (sd); 4718 1.5 christos return 0; 4719 1.5 christos } 4720 1.5 christos 4721 1.1 christos cpu = STATE_CPU (sd, 0); 4722 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 4723 1.7 christos h8_set_reg (cpu, SBR_REGNUM, 0xFFFFFF00); 4724 1.1 christos /* sim_cpu object is new, so some initialization is needed. */ 4725 1.1 christos init_pointers_needed = 1; 4726 1.1 christos 4727 1.6 christos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 4728 1.6 christos { 4729 1.6 christos free_state (sd); 4730 1.6 christos return 0; 4731 1.6 christos } 4732 1.1 christos 4733 1.6 christos if (sim_add_option_table (sd, NULL, h8300_options) != SIM_RC_OK) 4734 1.1 christos { 4735 1.1 christos free_state (sd); 4736 1.1 christos return 0; 4737 1.1 christos } 4738 1.1 christos 4739 1.6 christos /* The parser will print an error message for us, so we silently return. */ 4740 1.1 christos if (sim_parse_args (sd, argv) != SIM_RC_OK) 4741 1.1 christos { 4742 1.1 christos /* Uninstall the modules to avoid memory leaks, 4743 1.1 christos file descriptor leaks, etc. */ 4744 1.1 christos free_state (sd); 4745 1.1 christos return 0; 4746 1.1 christos } 4747 1.1 christos 4748 1.1 christos /* Check for/establish the a reference program image. */ 4749 1.7 christos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 4750 1.1 christos { 4751 1.1 christos free_state (sd); 4752 1.1 christos return 0; 4753 1.1 christos } 4754 1.1 christos 4755 1.1 christos /* Establish any remaining configuration options. */ 4756 1.1 christos if (sim_config (sd) != SIM_RC_OK) 4757 1.1 christos { 4758 1.1 christos free_state (sd); 4759 1.1 christos return 0; 4760 1.1 christos } 4761 1.1 christos 4762 1.1 christos if (sim_post_argv_init (sd) != SIM_RC_OK) 4763 1.1 christos { 4764 1.1 christos /* Uninstall the modules to avoid memory leaks, 4765 1.1 christos file descriptor leaks, etc. */ 4766 1.1 christos free_state (sd); 4767 1.1 christos return 0; 4768 1.1 christos } 4769 1.1 christos 4770 1.5 christos /* CPU specific initialization. */ 4771 1.5 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 4772 1.5 christos { 4773 1.8 christos cpu = STATE_CPU (sd, i); 4774 1.5 christos 4775 1.6 christos CPU_REG_FETCH (cpu) = h8300_reg_fetch; 4776 1.6 christos CPU_REG_STORE (cpu) = h8300_reg_store; 4777 1.5 christos CPU_PC_FETCH (cpu) = h8300_pc_get; 4778 1.5 christos CPU_PC_STORE (cpu) = h8300_pc_set; 4779 1.5 christos } 4780 1.5 christos 4781 1.1 christos /* sim_hw_configure (sd); */ 4782 1.1 christos 4783 1.1 christos /* FIXME: Much of the code in sim_load can be moved here. */ 4784 1.1 christos 4785 1.1 christos return sd; 4786 1.1 christos } 4787 1.1 christos 4788 1.1 christos /* Called by gdb to load a program into memory. */ 4789 1.1 christos 4790 1.1 christos SIM_RC 4791 1.3 christos sim_load (SIM_DESC sd, const char *prog, bfd *abfd, int from_tty) 4792 1.1 christos { 4793 1.7 christos sim_cpu *cpu = STATE_CPU (sd, 0); 4794 1.7 christos struct h8300_sim_state *state = H8300_SIM_STATE (sd); 4795 1.1 christos bfd *prog_bfd; 4796 1.1 christos 4797 1.1 christos /* FIXME: The code below that sets a specific variant of the H8/300 4798 1.1 christos being simulated should be moved to sim_open(). */ 4799 1.1 christos 4800 1.1 christos /* See if the file is for the H8/300 or H8/300H. */ 4801 1.1 christos /* ??? This may not be the most efficient way. The z8k simulator 4802 1.1 christos does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */ 4803 1.1 christos if (abfd != NULL) 4804 1.1 christos prog_bfd = abfd; 4805 1.1 christos else 4806 1.1 christos prog_bfd = bfd_openr (prog, NULL); 4807 1.1 christos if (prog_bfd != NULL) 4808 1.1 christos { 4809 1.1 christos /* Set the cpu type. We ignore failure from bfd_check_format 4810 1.1 christos and bfd_openr as sim_load_file checks too. */ 4811 1.1 christos if (bfd_check_format (prog_bfd, bfd_object)) 4812 1.1 christos { 4813 1.1 christos set_h8300h (bfd_get_mach (prog_bfd)); 4814 1.1 christos } 4815 1.1 christos } 4816 1.1 christos 4817 1.1 christos /* If we're using gdb attached to the simulator, then we have to 4818 1.1 christos reallocate memory for the simulator. 4819 1.1 christos 4820 1.1 christos When gdb first starts, it calls fetch_registers (among other 4821 1.1 christos functions), which in turn calls init_pointers, which allocates 4822 1.1 christos simulator memory. 4823 1.1 christos 4824 1.1 christos The problem is when we do that, we don't know whether we're 4825 1.1 christos debugging an H8/300 or H8/300H program. 4826 1.1 christos 4827 1.1 christos This is the first point at which we can make that determination, 4828 1.1 christos so we just reallocate memory now; this will also allow us to handle 4829 1.1 christos switching between H8/300 and H8/300H programs without exiting 4830 1.1 christos gdb. */ 4831 1.1 christos 4832 1.1 christos if (h8300smode && !h8300_normal_mode) 4833 1.1 christos memory_size = H8300S_MSIZE; 4834 1.1 christos else if (h8300hmode && !h8300_normal_mode) 4835 1.1 christos memory_size = H8300H_MSIZE; 4836 1.1 christos else 4837 1.1 christos memory_size = H8300_MSIZE; 4838 1.1 christos 4839 1.7 christos if (h8_get_memory_buf (cpu)) 4840 1.7 christos free (h8_get_memory_buf (cpu)); 4841 1.1 christos 4842 1.7 christos h8_set_memory_buf (cpu, (unsigned char *) 4843 1.1 christos calloc (sizeof (char), memory_size)); 4844 1.7 christos state->memory_size = memory_size; 4845 1.1 christos 4846 1.1 christos /* `msize' must be a power of two. */ 4847 1.1 christos if ((memory_size & (memory_size - 1)) != 0) 4848 1.1 christos { 4849 1.6 christos sim_io_printf (sd, "sim_load: bad memory size.\n"); 4850 1.1 christos return SIM_RC_FAIL; 4851 1.1 christos } 4852 1.7 christos h8_set_mask (cpu, memory_size - 1); 4853 1.1 christos 4854 1.6 christos if (sim_load_file (sd, STATE_MY_NAME (sd), STATE_CALLBACK (sd), prog, 4855 1.6 christos prog_bfd, STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG, 4856 1.1 christos 0, sim_write) 4857 1.1 christos == NULL) 4858 1.1 christos { 4859 1.1 christos /* Close the bfd if we opened it. */ 4860 1.1 christos if (abfd == NULL && prog_bfd != NULL) 4861 1.1 christos bfd_close (prog_bfd); 4862 1.1 christos return SIM_RC_FAIL; 4863 1.1 christos } 4864 1.1 christos 4865 1.1 christos /* Close the bfd if we opened it. */ 4866 1.1 christos if (abfd == NULL && prog_bfd != NULL) 4867 1.1 christos bfd_close (prog_bfd); 4868 1.1 christos return SIM_RC_OK; 4869 1.1 christos } 4870 1.1 christos 4871 1.1 christos SIM_RC 4872 1.6 christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd, 4873 1.6 christos char * const *argv, char * const *env) 4874 1.1 christos { 4875 1.7 christos SIM_CPU *cpu = STATE_CPU (sd, 0); 4876 1.1 christos int i = 0; 4877 1.1 christos int no_of_args = 0; 4878 1.1 christos 4879 1.1 christos if (abfd != NULL) 4880 1.7 christos cpu_set_pc (cpu, bfd_get_start_address (abfd)); 4881 1.1 christos else 4882 1.7 christos cpu_set_pc (cpu, 0); 4883 1.1 christos 4884 1.1 christos /* Command Line support. */ 4885 1.1 christos if (argv != NULL) 4886 1.1 christos { 4887 1.1 christos /* Counting the no. of commandline arguments. */ 4888 1.1 christos for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++) 4889 1.1 christos continue; 4890 1.1 christos 4891 1.1 christos /* Allocating memory for the argv pointers. */ 4892 1.7 christos h8_set_command_line (cpu, (char **) malloc ((sizeof (char *)) 4893 1.1 christos * (no_of_args + 1))); 4894 1.1 christos 4895 1.1 christos for (i = 0; i < no_of_args; i++) 4896 1.1 christos { 4897 1.1 christos /* Copying the argument string. */ 4898 1.7 christos h8_set_cmdline_arg (cpu, i, (char *) strdup (argv[i])); 4899 1.1 christos } 4900 1.7 christos h8_set_cmdline_arg (cpu, i, NULL); 4901 1.1 christos } 4902 1.1 christos 4903 1.1 christos return SIM_RC_OK; 4904 1.1 christos } 4905