📄 tc-m68k.c
字号:
*pdotmove = pdotmove[-1]; *pdot = '.'; ++p; } if (opcode == NULL) { the_ins.error = _("Unknown operator"); return; } /* found a legitimate opcode, start matching operands */ while (*p == ' ') ++p; if (opcode->m_operands == 0) { char *old = input_line_pointer; *old = '\n'; input_line_pointer = p; /* Ahh - it's a motorola style psuedo op */ mote_pseudo_table[opcode->m_opnum].poc_handler (mote_pseudo_table[opcode->m_opnum].poc_val); input_line_pointer = old; *old = 0; return; } if (flag_mri && opcode->m_opnum == 0) { /* In MRI mode, random garbage is allowed after an instruction which accepts no operands. */ the_ins.args = opcode->m_operands; the_ins.numargs = opcode->m_opnum; the_ins.numo = opcode->m_codenum; the_ins.opcode[0] = getone (opcode); the_ins.opcode[1] = gettwo (opcode); return; } for (opP = &the_ins.operands[0]; *p; opP++) { p = crack_operand (p, opP); if (opP->error) { the_ins.error = opP->error; return; } } opsfound = opP - &the_ins.operands[0]; /* This ugly hack is to support the floating pt opcodes in their standard form. Essentially, we fake a first enty of type COP#1 */ if (opcode->m_operands[0] == 'I') { int n; for (n = opsfound; n > 0; --n) the_ins.operands[n] = the_ins.operands[n - 1]; memset ((char *) (&the_ins.operands[0]), '\0', sizeof (the_ins.operands[0])); the_ins.operands[0].mode = CONTROL; the_ins.operands[0].reg = m68k_float_copnum; opsfound++; } /* We've got the operands. Find an opcode that'll accept them */ for (losing = 0;;) { /* If we didn't get the right number of ops, or we have no common model with this pattern then reject this pattern. */ ok_arch |= opcode->m_arch; if (opsfound != opcode->m_opnum || ((opcode->m_arch & current_architecture) == 0)) ++losing; else { for (s = opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++) { /* Warning: this switch is huge! */ /* I've tried to organize the cases into this order: non-alpha first, then alpha by letter. Lower-case goes directly before uppercase counterpart. */ /* Code with multiple case ...: gets sorted by the lowest case ... it belongs to. I hope this makes sense. */ switch (*s) { case '!': switch (opP->mode) { case IMMED: case DREG: case AREG: case FPREG: case CONTROL: case AINC: case ADEC: case REGLST: losing++; break; default: break; } break; case '<': switch (opP->mode) { case DREG: case AREG: case FPREG: case CONTROL: case IMMED: case ADEC: case REGLST: losing++; break; default: break; } break; case '>': switch (opP->mode) { case DREG: case AREG: case FPREG: case CONTROL: case IMMED: case AINC: case REGLST: losing++; break; case ABSL: break; default: if (opP->reg == PC || opP->reg == ZPC) losing++; break; } break; case 'm': switch (opP->mode) { case DREG: case AREG: case AINDR: case AINC: case ADEC: break; default: losing++; } break; case 'n': switch (opP->mode) { case DISP: break; default: losing++; } break; case 'o': switch (opP->mode) { case BASE: case ABSL: case IMMED: break; default: losing++; } break; case 'p': switch (opP->mode) { case DREG: case AREG: case AINDR: case AINC: case ADEC: break; case DISP: if (opP->reg == PC || opP->reg == ZPC) losing++; break; default: losing++; } break; case 'q': switch (opP->mode) { case DREG: case AINDR: case AINC: case ADEC: break; case DISP: if (opP->reg == PC || opP->reg == ZPC) losing++; break; default: losing++; break; } break; case 'v': switch (opP->mode) { case DREG: case AINDR: case AINC: case ADEC: case ABSL: break; case DISP: if (opP->reg == PC || opP->reg == ZPC) losing++; break; default: losing++; break; } break; case '#': if (opP->mode != IMMED) losing++; else if (s[1] == 'b' && ! isvar (&opP->disp) && (opP->disp.exp.X_op != O_constant || ! isbyte (opP->disp.exp.X_add_number))) losing++; else if (s[1] == 'B' && ! isvar (&opP->disp) && (opP->disp.exp.X_op != O_constant || ! issbyte (opP->disp.exp.X_add_number))) losing++; else if (s[1] == 'w' && ! isvar (&opP->disp) && (opP->disp.exp.X_op != O_constant || ! isword (opP->disp.exp.X_add_number))) losing++; else if (s[1] == 'W' && ! isvar (&opP->disp) && (opP->disp.exp.X_op != O_constant || ! issword (opP->disp.exp.X_add_number))) losing++; break; case '^': case 'T': if (opP->mode != IMMED) losing++; break; case '$': if (opP->mode == AREG || opP->mode == CONTROL || opP->mode == FPREG || opP->mode == IMMED || opP->mode == REGLST || (opP->mode != ABSL && (opP->reg == PC || opP->reg == ZPC))) losing++; break; case '%': if (opP->mode == CONTROL || opP->mode == FPREG || opP->mode == REGLST || opP->mode == IMMED || (opP->mode != ABSL && (opP->reg == PC || opP->reg == ZPC))) losing++; break; case '&': switch (opP->mode) { case DREG: case AREG: case FPREG: case CONTROL: case IMMED: case AINC: case ADEC: case REGLST: losing++; break; case ABSL: break; default: if (opP->reg == PC || opP->reg == ZPC) losing++; break; } break; case '*': if (opP->mode == CONTROL || opP->mode == FPREG || opP->mode == REGLST) losing++; break; case '+': if (opP->mode != AINC) losing++; break; case '-': if (opP->mode != ADEC) losing++; break; case '/': switch (opP->mode) { case AREG: case CONTROL: case FPREG: case AINC: case ADEC: case IMMED: case REGLST: losing++; break; default: break; } break; case ';': switch (opP->mode) { case AREG: case CONTROL: case FPREG: case REGLST: losing++; break; default: break; } break; case '?': switch (opP->mode) { case AREG: case CONTROL: case FPREG: case AINC: case ADEC: case IMMED: case REGLST: losing++; break; case ABSL: break; default: if (opP->reg == PC || opP->reg == ZPC) losing++; break; } break; case '@': switch (opP->mode) { case AREG: case CONTROL: case FPREG: case IMMED: case REGLST: losing++; break; default: break; } break; case '~': /* For now! (JF FOO is this right?) */ switch (opP->mode) { case DREG: case AREG: case CONTROL: case FPREG: case IMMED: case REGLST: losing++; break; case ABSL: break; default: if (opP->reg == PC || opP->reg == ZPC) losing++; break; } break; case '3': if (opP->mode != CONTROL || (opP->reg != TT0 && opP->reg != TT1)) losing++; break; case 'A': if (opP->mode != AREG) losing++; break; case 'a': if (opP->mode != AINDR) ++losing; break; case 'B': /* FOO */ if (opP->mode != ABSL || (flag_long_jumps && strncmp (instring, "jbsr", 4) == 0)) losing++; break; case 'C': if (opP->mode != CONTROL || opP->reg != CCR) losing++; break; case 'd': if (opP->mode != DISP || opP->reg < ADDR0 || opP->reg > ADDR7) losing++; break; case 'D': if (opP->mode != DREG) losing++; break; case 'E': if (opP->reg != ACC) losing++; break; case 'F': if (opP->mode != FPREG) losing++; break; case 'G': if (opP->reg != MACSR) losing++; break; case 'H': if (opP->reg != MASK) losing++; break; case 'I': if (opP->mode != CONTROL || opP->reg < COP0 || opP->reg > COP7) losing++; break; case 'J': if (opP->mode != CONTROL || opP->reg < USP || opP->reg > last_movec_reg) losing++; else { const enum m68k_register *rp; for (rp = control_regs; *rp; rp++) if (*rp == opP->reg) break; if (*rp == 0) losing++; } break; case 'k': if (opP->mode != IMMED) losing++; break; case 'l': case 'L': if (opP->mode == DREG || opP->mode == AREG || opP->mode == FPREG) { if (s[1] == '8') losing++; else { switch (opP->mode) { case DREG: opP->mask = 1 << (opP->reg - DATA0); break; case AREG: opP->mask = 1 << (opP->reg - ADDR0 + 8); break; case FPREG:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -