📄 compile.c
字号:
goto log16; case O (O_AND, SL): /* and.l */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd & ea; goto log32; case O (O_OR, SB): /* or.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_OR, SW): /* or.w */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd | ea; goto log16; case O (O_OR, SL): /* or.l */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd | ea; goto log32; case O (O_XOR, SB): /* xor.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_XOR, SW): /* xor.w */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd ^ ea; goto log16; case O (O_XOR, SL): /* xor.l */ /* Fetch rd and ea. */ if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) goto end; res = rd ^ ea; goto log32; case O (O_MOV, SB): if (fetch (sd, &code->src, &res)) goto end; if (store (sd, &code->dst, res)) goto end; goto just_flags_log8; case O (O_MOV, SW): if (fetch (sd, &code->src, &res)) goto end; if (store (sd, &code->dst, res)) goto end; goto just_flags_log16; case O (O_MOV, SL): if (fetch (sd, &code->src, &res)) goto end; if (store (sd, &code->dst, res)) goto end; goto just_flags_log32; case O (O_MOVMD, SB): /* movmd.b */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; while (ea--) { rd = GET_MEMORY_B (GET_L_REG (5)); SET_MEMORY_B (GET_L_REG (6), rd); SET_L_REG (5, GET_L_REG (5) + 1); SET_L_REG (6, GET_L_REG (6) + 1); SET_W_REG (4, ea); } goto next; case O (O_MOVMD, SW): /* movmd.w */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; while (ea--) { rd = GET_MEMORY_W (GET_L_REG (5)); SET_MEMORY_W (GET_L_REG (6), rd); SET_L_REG (5, GET_L_REG (5) + 2); SET_L_REG (6, GET_L_REG (6) + 2); SET_W_REG (4, ea); } goto next; case O (O_MOVMD, SL): /* movmd.l */ ea = GET_W_REG (4); if (ea == 0) ea = 0x10000; while (ea--) { rd = GET_MEMORY_L (GET_L_REG (5)); SET_MEMORY_L (GET_L_REG (6), rd); SET_L_REG (5, GET_L_REG (5) + 4); SET_L_REG (6, GET_L_REG (6) + 4); SET_W_REG (4, ea); } goto next; case O (O_MOVSD, SB): /* movsd.b */ /* This instruction implements strncpy, with a conditional branch. r4 contains n, r5 contains src, and r6 contains dst. The 16-bit displacement operand is added to the pc if and only if the end of string is reached before n bytes are transferred. */ ea = GET_L_REG (4) & 0xffff; if (ea == 0) ea = 0x10000; while (ea--) { rd = GET_MEMORY_B (GET_L_REG (5)); SET_MEMORY_B (GET_L_REG (6), rd); SET_L_REG (5, GET_L_REG (5) + 1); SET_L_REG (6, GET_L_REG (6) + 1); SET_W_REG (4, ea); if (rd == 0) goto condtrue; } goto next; case O (O_EEPMOV, SB): /* eepmov.b */ case O (O_EEPMOV, SW): /* eepmov.w */ if (h8300hmode || h8300smode) { register unsigned char *_src, *_dst; unsigned int count = ((code->opcode == O (O_EEPMOV, SW)) ? h8_get_reg (sd, R4_REGNUM) & 0xffff : h8_get_reg (sd, R4_REGNUM) & 0xff); _src = (h8_get_reg (sd, R5_REGNUM) < memory_size ? h8_get_memory_buf (sd) + h8_get_reg (sd, R5_REGNUM) : h8_get_eightbit_buf (sd) + (h8_get_reg (sd, R5_REGNUM) & 0xff)); if ((_src + count) >= (h8_get_memory_buf (sd) + memory_size)) { if ((_src + count) >= (h8_get_eightbit_buf (sd) + 0x100)) goto illegal; } _dst = (h8_get_reg (sd, R6_REGNUM) < memory_size ? h8_get_memory_buf (sd) + h8_get_reg (sd, R6_REGNUM) : h8_get_eightbit_buf (sd) + (h8_get_reg (sd, R6_REGNUM) & 0xff)); if ((_dst + count) >= (h8_get_memory_buf (sd) + memory_size)) { if ((_dst + count) >= (h8_get_eightbit_buf (sd) + 0x100)) goto illegal; } memcpy (_dst, _src, count); h8_set_reg (sd, R5_REGNUM, h8_get_reg (sd, R5_REGNUM) + count); h8_set_reg (sd, R6_REGNUM, h8_get_reg (sd, R6_REGNUM) + count); h8_set_reg (sd, R4_REGNUM, h8_get_reg (sd, R4_REGNUM) & ((code->opcode == O (O_EEPMOV, SW)) ? (~0xffff) : (~0xff))); cycles += 2 * count; goto next; } goto illegal; case O (O_ADDS, SL): /* adds (.l) */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ SET_L_REG (code->dst.reg, GET_L_REG (code->dst.reg) + code->src.literal); goto next; case O (O_SUBS, SL): /* subs (.l) */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ SET_L_REG (code->dst.reg, GET_L_REG (code->dst.reg) - code->src.literal); goto next; case O (O_CMP, SB): /* cmp.b */ if (fetch (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -ea; res = rd + ea; goto just_flags_alu8; case O (O_CMP, SW): /* cmp.w */ if (fetch (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -ea; res = rd + ea; goto just_flags_alu16; case O (O_CMP, SL): /* cmp.l */ if (fetch (sd, &code->dst, &rd)) goto end; if (fetch (sd, &code->src, &ea)) goto end; ea = -ea; res = rd + ea; goto just_flags_alu32; case O (O_DEC, SB): /* dec.b */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_B_REG (code->src.reg); ea = -1; res = rd + ea; SET_B_REG (code->src.reg, res); goto just_flags_inc8; case O (O_DEC, SW): /* dec.w */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_W_REG (code->dst.reg); ea = -code->src.literal; res = rd + ea; SET_W_REG (code->dst.reg, res); goto just_flags_inc16; case O (O_DEC, SL): /* dec.l */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_L_REG (code->dst.reg); ea = -code->src.literal; res = rd + ea; SET_L_REG (code->dst.reg, res); goto just_flags_inc32; case O (O_INC, SB): /* inc.b */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_B_REG (code->src.reg); ea = 1; res = rd + ea; SET_B_REG (code->src.reg, res); goto just_flags_inc8; case O (O_INC, SW): /* inc.w */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_W_REG (code->dst.reg); ea = code->src.literal; res = rd + ea; SET_W_REG (code->dst.reg, res); goto just_flags_inc16; case O (O_INC, SL): /* inc.l */ /* FIXME fetch. * This insn only uses register operands, but still * it would be cleaner to use fetch and store... */ rd = GET_L_REG (code->dst.reg); ea = code->src.literal; res = rd + ea; SET_L_REG (code->dst.reg, res); goto just_flags_inc32; case O (O_LDC, SB): /* ldc.b */ if (fetch (sd, &code->src, &res)) goto end; goto setc; case O (O_LDC, SW): /* ldc.w */ if (fetch (sd, &code->src, &res)) goto end; /* Word operand, value from MSB, must be shifted. */ res >>= 8; goto setc; case O (O_LDC, SL): /* ldc.l */ if (fetch (sd, &code->src, &res)) goto end; switch (code->dst.type) { case X (OP_SBR, SL): h8_set_sbr (sd, res); break; case X (OP_VBR, SL): h8_set_vbr (sd, res); break; default: goto illegal; } goto next; case O (O_STC, SW): /* stc.w */ case O (O_STC, SB): /* stc.b */ if (code->src.type == X (OP_CCR, SB)) { BUILDSR (sd); res = h8_get_ccr (sd); } else if (code->src.type == X (OP_EXR, SB) && h8300smode) { if (h8300smode) h8_set_exr (sd, (trace << 7) | intMask); res = h8_get_exr (sd); } else goto illegal; /* Word operand, value to MSB, must be shifted. */ if (code->opcode == X (O_STC, SW)) res <<= 8; if (store (sd, &code->dst, res)) goto end; goto next; case O (O_STC, SL): /* stc.l */ switch (code->src.type) { case X (OP_SBR, SL): res = h8_get_sbr (sd); break; case X (OP_VBR, SL): res = h8_get_vbr (sd); break; default: goto illegal; } if (store (sd, &code->dst, res)) goto end; goto next; case O (O_ANDC, SB): /* andc.b */ if (code->dst.type == X (OP_CCR, SB)) { BUILDSR (sd); rd = h8_get_ccr (sd); } else if (code->dst.type == X (OP_EXR, SB) && h8300smode) { if (h8300smode) h8_set_exr (sd, (trace << 7) | intMask); rd = h8_get_exr (sd); } else goto illegal; ea = code->src.literal; res = rd & ea; goto setc; case O (O_ORC, SB): /* orc.b */ if (code->dst.type == X (OP_CCR, SB)) { BUILDSR (sd); rd = h8_get_ccr (sd); } else if (code->dst.type == X (OP_EXR, SB) && h8300smode) { if (h8300smode) h8_set_exr (sd, (trace << 7) | intMask); rd = h8_get_exr (sd); } else goto illegal; ea = code->src.literal; res = rd | ea; goto setc; case O (O_XORC, SB): /* xorc.b */ if (code->dst.type == X (OP_CCR, SB)) { BUILDSR (sd); rd = h8_get_ccr (sd); } else if (code->dst.type == X (OP_EXR, SB) && h8300smode) { if (h8300smode) h8_set_exr (sd, (trace << 7) | intMask); rd = h8_get_exr (sd); } else goto illegal; ea = code->src.literal; res = rd ^ ea; goto setc; case O (O_BRAS, SB): /* bra/s */ /* This is basically an ordinary branch, with a delay slot. */ if (fetch (sd, &code->src, &res)) goto end; if ((res & 1) == 0) goto illegal; res -= 1; /* Execution continues at next instruction, but delayed_branch is set up for next cycle. */ h8_set_delayed_branch (sd, code->next_pc + res); pc = code->next_pc; goto end; case O (O_BRAB, SB): /* bra rd.b */ case O (O_BRAW, SW): /* bra rd.w */ case O (O_BRAL, SL): /* bra erd.l */ if (fetch (sd, &code->src, &rd)) goto end; switch (OP_SIZE (code->opcode)) { case SB: rd &= 0xff; break; case SW: rd &= 0xffff; break; case SL: rd &= 0xffffffff; break; } pc = code->next_pc + rd; goto end; case O (O_BRABC, SB): /* bra/bc, branch if bit clear */ case O (O_BRABS, SB): /* bra/bs, branch if bit set */ case O (O_BSRBC, SB): /* bsr/bc, call if bit clear */ case O (O_BSRBS, SB): /* bsr/bs, call if bit set */ if (fetch (sd, &code->dst, &rd) || fetch (sd, &code->src, &bit)) goto end; if (code->opcode == O (O_BRABC, SB) || /* branch if clear */ code->opcode == O (O_BSRBC, SB)) /* call if clear */ { if ((rd & (1 << bit))) /* no branch */ goto next; } else /* branch/call if set */ { if (!(rd & (1 << bit))) /* no branch */ goto next; } if (fetch (sd, &code->op3, &res)) /* branch */ goto end; pc = code->next_pc + res; if (code->opcode == O (O_BRABC, SB) || code->opcode == O (O_BRABS, SB)) /* branch */ goto end; else /* call */ goto call; case O (O_BRA, SN): case O (O_BRA, SL): case O (O_BRA, SW): case O (O_BRA, SB): /* bra, branch always */ if (1) goto condtrue; goto next; case O (O_BRN, SB): /* brn, ;-/ branch never? */ if (0) goto condtrue; goto next; case O (O_BHI, SB): /* bhi */ if ((C || Z) == 0) goto condtrue; goto next; case O (O_BLS, SB): /* bls */ if ((C || Z)) goto condtrue; goto next; case O (O_BCS, SB): /* bcs, branch if carry set */ if ((C == 1)) goto condtrue; goto next; case O (O_BCC, SB): /* bcc, branch if carry clear */ if ((C == 0)) goto condtrue; goto next; case O (O_BEQ, SB): /* beq, branch if zero set */ if (Z) goto condtrue; goto next; case O (O_BGT, SB): /* bgt */ if (((Z || (N ^ V)) == 0)) goto condtrue; goto next; case O (O_BLE, SB): /* ble */ if (((Z || (N ^ V)) == 1)) goto condtrue; goto next; case O (O_BGE, SB): /* bge */ if ((N ^ V) == 0) goto condtrue; goto next; case O (O_BLT, SB): /* blt */ if ((N ^ V)) goto condtrue; goto next; case O (O_BMI, SB): /* bmi */ if ((N)) goto condtrue; goto next; case O (O_BNE, SB): /* bne, branch if zero clear */ if ((Z == 0)) goto condtrue; goto next; case O (O_BPL, SB): /* bpl */ if (N == 0) goto condtrue; goto next; case O (O_BVC, SB): /* bvc */ if ((V == 0)) goto condtrue; goto next; case O (O_BVS, SB): /* bvs */ if ((V == 1)) goto condtrue; goto next; /* Trap for Command Line setup. */ case O (O_SYS_CMDLINE, SB): { int i = 0; /* Loop counter. */ int j = 0; /* Loop counter. */ int ind_arg_len = 0; /* Length of each argument. */ int no_of_args = 0; /* The no. or cmdline args. */ int current_location = 0; /* Location of string. */ int old_sp = 0; /* The Initial Stack Pointer. */ int no_of_slots = 0; /* No. of slots required on the stack for storing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -