📄 compile.c
字号:
{ if (val == NULL) /* Paranoia. */ return -1; switch (x / 4) { case OP_DISP: if (rn == ZERO_REGNUM) *val = X (OP_IMM, SP); else *val = X (OP_REG, SP); break; case OP_MEM: *val = X (OP_MEM, SP); break; default: sim_engine_set_run_state (sd, sim_stopped, SIGSEGV); return -1; } return 0;}static intcmdline_location(){ if (h8300smode && !h8300_normal_mode) return 0xffff00L; else if (h8300hmode && !h8300_normal_mode) return 0x2ff00L; else return 0xff00L;}static voiddecode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst){ int cst[3] = {0, 0, 0}; int reg[3] = {0, 0, 0}; int rdisp[3] = {0, 0, 0}; int opnum; const struct h8_opcode *q; dst->dst.type = -1; dst->src.type = -1; /* Find the exact opcode/arg combo. */ for (q = h8_opcodes; q->name; q++) { op_type *nib = q->data.nib; unsigned int len = 0; if ((q->available == AV_H8SX && !h8300sxmode) || (q->available == AV_H8S && !h8300smode) || (q->available == AV_H8H && !h8300hmode)) continue; cst[0] = cst[1] = cst[2] = 0; reg[0] = reg[1] = reg[2] = 0; rdisp[0] = rdisp[1] = rdisp[2] = 0; while (1) { op_type looking_for = *nib; int thisnib = data[len / 2]; thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf); opnum = ((looking_for & OP3) ? 2 : (looking_for & DST) ? 1 : 0); if (looking_for < 16 && looking_for >= 0) { if (looking_for != thisnib) goto fail; } else { if (looking_for & B31) { if (!((thisnib & 0x8) != 0)) goto fail; looking_for = (op_type) (looking_for & ~B31); thisnib &= 0x7; } else if (looking_for & B30) { if (!((thisnib & 0x8) == 0)) goto fail; looking_for = (op_type) (looking_for & ~B30); } if (looking_for & B21) { if (!((thisnib & 0x4) != 0)) goto fail; looking_for = (op_type) (looking_for & ~B21); thisnib &= 0xb; } else if (looking_for & B20) { if (!((thisnib & 0x4) == 0)) goto fail; looking_for = (op_type) (looking_for & ~B20); } if (looking_for & B11) { if (!((thisnib & 0x2) != 0)) goto fail; looking_for = (op_type) (looking_for & ~B11); thisnib &= 0xd; } else if (looking_for & B10) { if (!((thisnib & 0x2) == 0)) goto fail; looking_for = (op_type) (looking_for & ~B10); } if (looking_for & B01) { if (!((thisnib & 0x1) != 0)) goto fail; looking_for = (op_type) (looking_for & ~B01); thisnib &= 0xe; } else if (looking_for & B00) { if (!((thisnib & 0x1) == 0)) goto fail; looking_for = (op_type) (looking_for & ~B00); } if (looking_for & IGNORE) { /* Hitachi has declared that IGNORE must be zero. */ if (thisnib != 0) goto fail; } else if ((looking_for & MODE) == DATA) { ; /* Skip embedded data. */ } else if ((looking_for & MODE) == DBIT) { /* Exclude adds/subs by looking at bit 0 and 2, and make sure the operand size, either w or l, matches by looking at bit 1. */ if ((looking_for & 7) != (thisnib & 7)) goto fail; cst[opnum] = (thisnib & 0x8) ? 2 : 1; } else if ((looking_for & MODE) == REG || (looking_for & MODE) == LOWREG || (looking_for & MODE) == IND || (looking_for & MODE) == PREINC || (looking_for & MODE) == POSTINC || (looking_for & MODE) == PREDEC || (looking_for & MODE) == POSTDEC) { reg[opnum] = thisnib; } else if (looking_for & CTRL) { thisnib &= 7; if (((looking_for & MODE) == CCR && (thisnib != C_CCR)) || ((looking_for & MODE) == EXR && (thisnib != C_EXR)) || ((looking_for & MODE) == MACH && (thisnib != C_MACH)) || ((looking_for & MODE) == MACL && (thisnib != C_MACL)) || ((looking_for & MODE) == VBR && (thisnib != C_VBR)) || ((looking_for & MODE) == SBR && (thisnib != C_SBR))) goto fail; if (((looking_for & MODE) == CCR_EXR && (thisnib != C_CCR && thisnib != C_EXR)) || ((looking_for & MODE) == VBR_SBR && (thisnib != C_VBR && thisnib != C_SBR)) || ((looking_for & MODE) == MACREG && (thisnib != C_MACH && thisnib != C_MACL))) goto fail; if (((looking_for & MODE) == CC_EX_VB_SB && (thisnib != C_CCR && thisnib != C_EXR && thisnib != C_VBR && thisnib != C_SBR))) goto fail; reg[opnum] = thisnib; } else if ((looking_for & MODE) == ABS) { /* Absolute addresses are unsigned. */ switch (looking_for & SIZE) { case L_8: cst[opnum] = UEXTCHAR (data[len / 2]); break; case L_16: case L_16U: cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; break; case L_32: cst[opnum] = (data[len / 2 + 0] << 24) + (data[len / 2 + 1] << 16) + (data[len / 2 + 2] << 8) + (data[len / 2 + 3]); break; default: printf ("decode: bad size ABS: %d\n", (looking_for & SIZE)); goto end; } } else if ((looking_for & MODE) == DISP || (looking_for & MODE) == PCREL || (looking_for & MODE) == INDEXB || (looking_for & MODE) == INDEXW || (looking_for & MODE) == INDEXL) { switch (looking_for & SIZE) { case L_2: cst[opnum] = thisnib & 3; break; case L_8: cst[opnum] = SEXTCHAR (data[len / 2]); break; case L_16: cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; cst[opnum] = (short) cst[opnum]; /* Sign extend. */ break; case L_16U: cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; break; case L_32: cst[opnum] = (data[len / 2 + 0] << 24) + (data[len / 2 + 1] << 16) + (data[len / 2 + 2] << 8) + (data[len / 2 + 3]); break; default: printf ("decode: bad size DISP/PCREL/INDEX: %d\n", (looking_for & SIZE)); goto end; } } else if ((looking_for & SIZE) == L_16 || (looking_for & SIZE) == L_16U) { cst[opnum] = (data[len / 2] << 8) + data[len / 2 + 1]; /* Immediates are always unsigned. */ if ((looking_for & SIZE) != L_16U && (looking_for & MODE) != IMM) cst[opnum] = (short) cst[opnum]; /* Sign extend. */ } else if (looking_for & ABSJMP) { switch (looking_for & SIZE) { case L_24: cst[opnum] = (data[1] << 16) | (data[2] << 8) | (data[3]); break; case L_32: cst[opnum] = (data[len / 2 + 0] << 24) + (data[len / 2 + 1] << 16) + (data[len / 2 + 2] << 8) + (data[len / 2 + 3]); break; default: printf ("decode: bad size ABSJMP: %d\n", (looking_for & SIZE)); goto end; } } else if ((looking_for & MODE) == MEMIND) { cst[opnum] = data[1]; } else if ((looking_for & MODE) == VECIND) { if(h8300_normal_mode) cst[opnum] = ((data[1] & 0x7f) + 0x80) * 2; else cst[opnum] = ((data[1] & 0x7f) + 0x80) * 4; cst[opnum] += h8_get_vbr (sd); /* Add vector base reg. */ } else if ((looking_for & SIZE) == L_32) { int i = len / 2; cst[opnum] = (data[i + 0] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) | (data[i + 3]); } else if ((looking_for & SIZE) == L_24) { int i = len / 2; cst[opnum] = (data[i + 0] << 16) | (data[i + 1] << 8) | (data[i + 2]); } else if (looking_for & DISPREG) { rdisp[opnum] = thisnib & 0x7; } else if ((looking_for & MODE) == KBIT) { switch (thisnib) { case 9: cst[opnum] = 4; break; case 8: cst[opnum] = 2; break; case 0: cst[opnum] = 1; break; default: goto fail; } } else if ((looking_for & SIZE) == L_8) { if ((looking_for & MODE) == ABS) { /* Will be combined with contents of SBR_REGNUM by fetch (). For all modes except h8sx, this will always contain the value 0xFFFFFF00. */ cst[opnum] = data[len / 2] & 0xff; } else { cst[opnum] = data[len / 2] & 0xff; } } else if ((looking_for & SIZE) == L_2) { cst[opnum] = thisnib & 3; } else if ((looking_for & SIZE) == L_3 || (looking_for & SIZE) == L_3NZ) { cst[opnum] = thisnib & 7; if (cst[opnum] == 0 && (looking_for & SIZE) == L_3NZ) goto fail; } else if ((looking_for & SIZE) == L_4) { cst[opnum] = thisnib & 15; } else if ((looking_for & SIZE) == L_5) { cst[opnum] = data[len / 2] & 0x1f; } else if (looking_for == E) {#ifdef ADEBUG dst->op = q;#endif /* Fill in the args. */ { op_type *args = q->args.nib; int hadone = 0; int nargs; for (nargs = 0; nargs < 3 && *args != E; nargs++) { int x = *args; ea_type *p; opnum = ((x & OP3) ? 2 : (x & DST) ? 1 : 0); if (x & DST) p = &dst->dst; else if (x & OP3) p = &dst->op3; else p = &dst->src; if ((x & MODE) == IMM || (x & MODE) == KBIT || (x & MODE) == DBIT) { /* Use the instruction to determine the operand size. */ p->type = X (OP_IMM, OP_SIZE (q->how)); p->literal = cst[opnum]; } else if ((x & MODE) == CONST_2 || (x & MODE) == CONST_4 || (x & MODE) == CONST_8 || (x & MODE) == CONST_16) { /* Use the instruction to determine the operand size. */ p->type = X (OP_IMM, OP_SIZE (q->how)); switch (x & MODE) { case CONST_2: p->literal = 2; break; case CONST_4: p->literal = 4; break; case CONST_8: p->literal = 8; break; case CONST_16: p->literal = 16; break; } } else if ((x & MODE) == REG) { p->type = X (OP_REG, bitfrom (x)); p->reg = reg[opnum]; } else if ((x & MODE) == LOWREG) { p->type = X (OP_LOWREG, bitfrom (x)); p->reg = reg[opnum]; } else if ((x & MODE) == PREINC) { /* Use the instruction to determine the operand size. */ p->type = X (OP_PREINC, OP_SIZE (q->how)); p->reg = reg[opnum] & 0x7; } else if ((x & MODE) == POSTINC) { /* Use the instruction to determine the operand size. */ p->type = X (OP_POSTINC, OP_SIZE (q->how)); p->reg = reg[opnum] & 0x7; } else if ((x & MODE) == PREDEC) { /* Use the instruction to determine the operand size. */ p->type = X (OP_PREDEC, OP_SIZE (q->how)); p->reg = reg[opnum] & 0x7; } else if ((x & MODE) == POSTDEC) { /* Use the instruction to determine the operand size. */ p->type = X (OP_POSTDEC, OP_SIZE (q->how)); p->reg = reg[opnum] & 0x7; } else if ((x & MODE) == IND) { /* Note: an indirect is transformed into a displacement of zero. */ /* Use the instruction to determine the operand size. */ p->type = X (OP_DISP, OP_SIZE (q->how)); p->reg = reg[opnum] & 0x7; p->literal = 0; if (OP_KIND (q->how) == O_JSR || OP_KIND (q->how) == O_JMP) if (lvalue (sd, p->type, p->reg, &p->type)) goto end; } else if ((x & MODE) == ABS) { /* Note: a 16 or 32 bit ABS is transformed into a displacement from pseudo-register ZERO_REGNUM, which is always zero. An 8 bit ABS becomes a displacement from SBR_REGNUM. */ /* Use the instruction to determine the operand size. */ p->type = X (OP_DISP, OP_SIZE (q->how)); p->literal = cst[opnum]; /* 8-bit ABS is displacement from SBR. 16 and 32-bit ABS are displacement from ZERO. (SBR will always be zero except for h8/sx) */ if ((x & SIZE) == L_8) p->reg = SBR_REGNUM; else p->reg = ZERO_REGNUM;; } else if ((x & MODE) == MEMIND || (x & MODE) == VECIND) { /* Size doesn't matter. */ p->type = X (OP_MEM, SB); p->literal = cst[opnum]; if (OP_KIND (q->how) == O_JSR || OP_KIND (q->how) == O_JMP) if (lvalue (sd, p->type, p->reg, &p->type)) goto end; } else if ((x & MODE) == PCREL) { /* Size doesn't matter. */ p->type = X (OP_PCREL, SB); p->literal = cst[opnum]; } else if (x & ABSJMP) { p->type = X (OP_IMM, SP); p->literal = cst[opnum]; } else if ((x & MODE) == INDEXB) { p->type = X (OP_INDEXB, OP_SIZE (q->how)); p->literal = cst[opnum]; p->reg = rdisp[opnum]; } else if ((x & MODE) == INDEXW) { p->type = X (OP_INDEXW, OP_SIZE (q->how)); p->literal = cst[opnum]; p->reg = rdisp[opnum]; } else if ((x & MODE) == INDEXL) { p->type = X (OP_INDEXL, OP_SIZE (q->how)); p->literal = cst[opnum]; p->reg = rdisp[opnum]; } else if ((x & MODE) == DISP) { /* Yuck -- special for mova args. */ if (strncmp (q->name, "mova", 4) == 0 && (x & SIZE) == L_2) { /* Mova can have a DISP2 dest, with an INDEXB or INDEXW src. The multiplier for the displacement value is determined by the src operand, not by the insn. */ switch (OP_KIND (dst->src.type)) { case OP_INDEXB: p->type = X (OP_DISP, SB); p->literal = cst[opnum]; break; case OP_INDEXW: p->type = X (OP_DISP, SW); p->literal = cst[opnum] * 2; break; default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -