📄 compile.c
字号:
t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_W (t, n); break; case X (OP_PREINC, SL): /* Register indirect w/pre-incr, long. */ t = GET_L_REG (rn); if (!twice) t += 4; t &= h8_get_mask (sd); SET_L_REG (rn, t); SET_MEMORY_L (t, n); break; case X (OP_POSTDEC, SB): /* Register indirect w/post-decr, byte. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_B (t, n); SET_L_REG (rn, t - 1); break; case X (OP_POSTDEC, SW): /* Register indirect w/post-decr, word. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_W (t, n); SET_L_REG (rn, t - 2); break; case X (OP_POSTDEC, SL): /* Register indirect w/post-decr, long. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_L (t, n); SET_L_REG (rn, t - 4); break; case X (OP_POSTINC, SB): /* Register indirect w/post-incr, byte. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_B (t, n); SET_L_REG (rn, t + 1); break; case X (OP_POSTINC, SW): /* Register indirect w/post-incr, word. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_W (t, n); SET_L_REG (rn, t + 2); break; case X (OP_POSTINC, SL): /* Register indirect w/post-incr, long. */ t = GET_L_REG (rn) & h8_get_mask (sd); SET_MEMORY_L (t, n); SET_L_REG (rn, t + 4); break; case X (OP_DISP, SB): /* Register indirect w/displacement, byte. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); SET_MEMORY_B (t, n); break; case X (OP_DISP, SW): /* Register indirect w/displacement, word. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); SET_MEMORY_W (t, n); break; case X (OP_DISP, SL): /* Register indirect w/displacement, long. */ t = GET_L_REG (rn) + abs; t &= h8_get_mask (sd); SET_MEMORY_L (t, n); break; case X (OP_MEM, SB): /* Why isn't this implemented? */ case X (OP_MEM, SW): /* Why isn't this implemented? */ case X (OP_MEM, SL): /* Why isn't this implemented? */ default: sim_engine_set_run_state (sd, sim_stopped, SIGSEGV); return -1; } return 0;}/* Normal store. */static intstore (SIM_DESC sd, ea_type *arg, int n){ return store_1 (sd, arg, n, 0);}/* Store which follows a fetch from the same location. The difference being that we don't want to do a pre-increment or pre-decrement at this time: it was already done when we fetched. */static intstore2 (SIM_DESC sd, ea_type *arg, int n){ return store_1 (sd, arg, n, 1);}static union{ short int i; struct { char low; char high; } u;} littleendian;/* Flag to be set whenever a new SIM_DESC object is created. */static int init_pointers_needed = 1;static voidinit_pointers (SIM_DESC sd){ if (init_pointers_needed) { int i; littleendian.i = 1; if (h8300smode && !h8300_normal_mode) memory_size = H8300S_MSIZE; else if (h8300hmode && !h8300_normal_mode) memory_size = H8300H_MSIZE; else memory_size = H8300_MSIZE; /* `msize' must be a power of two. */ if ((memory_size & (memory_size - 1)) != 0) { (*sim_callback->printf_filtered) (sim_callback, "init_pointers: bad memory size %d, defaulting to %d.\n", memory_size, memory_size = H8300S_MSIZE); } if (h8_get_memory_buf (sd)) free (h8_get_memory_buf (sd)); if (h8_get_cache_idx_buf (sd)) free (h8_get_cache_idx_buf (sd)); if (h8_get_eightbit_buf (sd)) free (h8_get_eightbit_buf (sd)); h8_set_memory_buf (sd, (unsigned char *) calloc (sizeof (char), memory_size)); h8_set_cache_idx_buf (sd, (unsigned short *) calloc (sizeof (short), memory_size)); sd->memory_size = memory_size; h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256)); h8_set_mask (sd, memory_size - 1); memset (h8_get_reg_buf (sd), 0, sizeof (((STATE_CPU (sd, 0))->regs))); for (i = 0; i < 8; i++) { /* FIXME: rewrite using local buffer. */ unsigned char *p = (unsigned char *) (h8_get_reg_buf (sd) + i); unsigned char *e = (unsigned char *) (h8_get_reg_buf (sd) + i + 1); unsigned short *q = (unsigned short *) (h8_get_reg_buf (sd) + i); unsigned short *u = (unsigned short *) (h8_get_reg_buf (sd) + i + 1); h8_set_reg (sd, i, 0x00112233); while (p < e) { if (*p == 0x22) breg[i] = p; if (*p == 0x33) breg[i + 8] = p; if (*p == 0x11) breg[i + 16] = p; if (*p == 0x00) breg[i + 24] = p; p++; } wreg[i] = wreg[i + 8] = 0; while (q < u) { if (*q == 0x2233) { wreg[i] = q; } if (*q == 0x0011) { wreg[i + 8] = q; } q++; } if (wreg[i] == 0 || wreg[i + 8] == 0) (*sim_callback->printf_filtered) (sim_callback, "init_pointers: internal error.\n"); h8_set_reg (sd, i, 0); lreg[i] = h8_get_reg_buf (sd) + i; } /* Note: sim uses pseudo-register ZERO as a zero register. */ lreg[ZERO_REGNUM] = h8_get_reg_buf (sd) + ZERO_REGNUM; init_pointers_needed = 0; /* Initialize the seg registers. */ if (!sd->sim_cache) set_simcache_size (sd, CSIZE); }}/* Grotty global variable for use by control_c signal handler. */static SIM_DESC control_c_sim_desc;static voidcontrol_c (int sig){ sim_engine_set_run_state (control_c_sim_desc, sim_stopped, SIGINT);}intsim_stop (SIM_DESC sd){ /* FIXME: use a real signal value. */ sim_engine_set_run_state (sd, sim_stopped, SIGINT); return 1;}#define OBITOP(name, f, s, op) \case O (name, SB): \{ \ int m, tmp; \ \ if (f) \ if (fetch (sd, &code->dst, &ea)) \ goto end; \ if (fetch (sd, &code->src, &tmp)) \ goto end; \ m = 1 << tmp; \ op; \ if (s) \ if (store (sd, &code->dst,ea)) \ goto end; \ goto next; \}voidsim_resume (SIM_DESC sd, int step, int siggnal){ static int init1; int cycles = 0; int insts = 0; int tick_start = get_now (); void (*prev) (); int poll_count = 0; int res; int tmp; int rd; int ea; int bit; int pc; int c, nz, v, n, u, h, ui, intMaskBit; int trace, intMask; int oldmask; enum sim_stop reason; int sigrc; init_pointers (sd); control_c_sim_desc = sd; prev = signal (SIGINT, control_c); if (step) { sim_engine_set_run_state (sd, sim_stopped, SIGTRAP); } else { sim_engine_set_run_state (sd, sim_running, 0); } pc = h8_get_pc (sd); /* The PC should never be odd. */ if (pc & 0x1) { sim_engine_set_run_state (sd, sim_stopped, SIGBUS); return; } /* Get Status Register (flags). */ GETSR (sd); if (h8300smode) /* Get exr. */ { trace = (h8_get_exr (sd) >> 7) & 1; intMask = h8_get_exr (sd) & 7; } oldmask = h8_get_mask (sd); if (!h8300hmode || h8300_normal_mode) h8_set_mask (sd, 0xffff); do { unsigned short cidx; decoded_inst *code; top: cidx = h8_get_cache_idx (sd, pc); if (cidx == (unsigned short) -1 || cidx >= sd->sim_cache_size) goto illegal; code = sd->sim_cache + cidx;#if ADEBUG if (debug) { printf ("%x %d %s\n", pc, code->opcode, code->op ? code->op->name : "**"); } h8_increment_stats (sd, code->opcode);#endif if (code->opcode) { cycles += code->cycles; insts++; } switch (code->opcode) { case 0: /* * This opcode is a fake for when we get to an * instruction which hasnt been compiled */ compile (sd, pc); goto top; break; case O (O_MOVAB, SL): case O (O_MOVAW, SL): case O (O_MOVAL, SL): /* 1) Evaluate 2nd argument (dst). 2) Mask / zero extend according to whether 1st argument (src) is INDEXB, INDEXW, or INDEXL. 3) Left-shift the result by 0, 1 or 2, according to size of mova (mova/b, mova/w, mova/l). 4) Add literal value of 1st argument (src). 5) Store result in 3rd argument (op3). */ /* Alas, since this is the only instruction with 3 arguments, decode doesn't handle them very well. Some fix-up is required. a) The size of dst is determined by whether src is INDEXB or INDEXW. */ if (OP_KIND (code->src.type) == OP_INDEXB) code->dst.type = X (OP_KIND (code->dst.type), SB); else if (OP_KIND (code->src.type) == OP_INDEXW) code->dst.type = X (OP_KIND (code->dst.type), SW); /* b) If op3 == null, then this is the short form of the insn. Dst is the dispreg of src, and op3 is the 32-bit form of the same register. */ if (code->op3.type == 0) { /* Short form: src == INDEXB/INDEXW, dst == op3 == 0. We get to compose dst and op3 as follows: op3 is a 32-bit register, ID == src.reg. dst is the same register, but 8 or 16 bits depending on whether src is INDEXB or INDEXW. */ code->op3.type = X (OP_REG, SL); code->op3.reg = code->src.reg; code->op3.literal = 0; if (OP_KIND (code->src.type) == OP_INDEXB) { code->dst.type = X (OP_REG, SB); code->dst.reg = code->op3.reg + 8; } else code->dst.type = X (OP_REG, SW); } if (fetch (sd, &code->dst, &ea)) goto end; switch (OP_KIND (code->src.type)) { case OP_INDEXB: ea = ea & 0xff; break; case OP_INDEXW: ea = ea & 0xffff; break; case OP_INDEXL: break; default: goto illegal; } switch (code->opcode) { case O (O_MOVAB, SL): break; case O (O_MOVAW, SL): ea = ea << 1; break; case O (O_MOVAL, SL): ea = ea << 2; break; default: goto illegal; } ea = ea + code->src.literal; if (store (sd, &code->op3, ea)) goto end; goto next; case O (O_SUBX, SB): /* subx, extended sub */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -(ea + C); res = rd + ea; goto alu8; case O (O_SUBX, SW): /* subx, extended sub */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -(ea + C); res = rd + ea; goto alu16; case O (O_SUBX, SL): /* subx, extended sub */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -(ea + C); res = rd + ea; goto alu32; case O (O_ADDX, SB): /* addx, extended add */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = ea + C; res = rd + ea; goto alu8; case O (O_ADDX, SW): /* addx, extended add */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = ea + C; res = rd + ea; goto alu16; case O (O_ADDX, SL): /* addx, extended add */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = ea + C; res = rd + ea; goto alu32; case O (O_SUB, SB): /* sub.b */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; ea = -ea; res = rd + ea; goto alu8; case O (O_SUB, SW): /* sub.w */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; ea = -ea; res = rd + ea; goto alu16; case O (O_SUB, SL): /* sub.l */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; ea = -ea; res = rd + ea; goto alu32; case O (O_NEG, SB): /* neg.b */ /* Fetch ea. */ if (fetch2 (sd, &code->src, &ea)) goto end; ea = -ea; rd = 0; res = rd + ea; goto alu8; case O (O_NEG, SW): /* neg.w */ /* Fetch ea. */ if (fetch2 (sd, &code->src, &ea)) goto end; ea = -ea; rd = 0; res = rd + ea; goto alu16; case O (O_NEG, SL): /* neg.l */ /* Fetch ea. */ if (fetch2 (sd, &code->src, &ea)) goto end; ea = -ea; rd = 0; res = rd + ea; goto alu32; case O (O_ADD, SB): /* add.b */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; res = rd + ea; goto alu8; case O (O_ADD, SW): /* add.w */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; res = rd + ea; goto alu16; case O (O_ADD, SL): /* add.l */ if (fetch2 (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; res = rd + ea; goto alu32; case O (O_AND, SB): /* and.b */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd & ea; goto log8; case O (O_AND, SW): /* and.w */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd & ea;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -