- if (i.tm.opcode_modifier & ShortForm)
- {
- /* The register or float register operand is in operand 0 or 1. */
- unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
- /* Register goes in low 3 bits of opcode. */
- i.tm.base_opcode |= i.op[op].regs->reg_num;
- if (i.op[op].regs->reg_flags & RegRex)
- i.rex.extZ=1;
- if (!quiet_warnings && (i.tm.opcode_modifier & Ugh) != 0)
- {
- /* Warn about some common errors, but press on regardless.
- The first case can be generated by gcc (<= 2.8.1). */
- if (i.operands == 2)
- {
- /* Reversed arguments on faddp, fsubp, etc. */
- as_warn (_("translating to `%s %%%s,%%%s'"), i.tm.name,
- i.op[1].regs->reg_name,
- i.op[0].regs->reg_name);
- }
- else
- {
- /* Extraneous `l' suffix on fp insn. */
- as_warn (_("translating to `%s %%%s'"), i.tm.name,
- i.op[0].regs->reg_name);
- }
- }
- }
- else if (i.tm.opcode_modifier & Modrm)
- {
- /* The opcode is completed (modulo i.tm.extension_opcode which
- must be put into the modrm byte).
- Now, we make the modrm & index base bytes based on all the
- info we've collected. */
-
- /* i.reg_operands MUST be the number of real register operands;
- implicit registers do not count. */
- if (i.reg_operands == 2)
- {
- unsigned int source, dest;
- source = ((i.types[0]
- & (Reg | RegMMX | RegXMM
- | SReg2 | SReg3
- | Control | Debug | Test))
- ? 0 : 1);
- dest = source + 1;
-
- i.rm.mode = 3;
- /* One of the register operands will be encoded in the
- i.tm.reg field, the other in the combined i.tm.mode
- and i.tm.regmem fields. If no form of this
- instruction supports a memory destination operand,
- then we assume the source operand may sometimes be
- a memory operand and so we need to store the
- destination in the i.rm.reg field. */
- if ((i.tm.operand_types[dest] & AnyMem) == 0)
- {
- i.rm.reg = i.op[dest].regs->reg_num;
- i.rm.regmem = i.op[source].regs->reg_num;
- if (i.op[dest].regs->reg_flags & RegRex)
- i.rex.extX=1;
- if (i.op[source].regs->reg_flags & RegRex)
- i.rex.extZ=1;
- }
- else
- {
- i.rm.reg = i.op[source].regs->reg_num;
- i.rm.regmem = i.op[dest].regs->reg_num;
- if (i.op[dest].regs->reg_flags & RegRex)
- i.rex.extZ=1;
- if (i.op[source].regs->reg_flags & RegRex)
- i.rex.extX=1;
- }
- }
- else
- { /* If it's not 2 reg operands... */
- if (i.mem_operands)
- {
- unsigned int fake_zero_displacement = 0;
- unsigned int op = ((i.types[0] & AnyMem)
- ? 0
- : (i.types[1] & AnyMem) ? 1 : 2);
-
- default_seg = &ds;
-
- if (! i.base_reg)
- {
- i.rm.mode = 0;
- if (! i.disp_operands)
- fake_zero_displacement = 1;
- if (! i.index_reg)
- {
- /* Operand is just <disp> */
- if ((flag_code == CODE_16BIT) ^ (i.prefix[ADDR_PREFIX] != 0))
- {
- i.rm.regmem = NO_BASE_REGISTER_16;
- i.types[op] &= ~Disp;
- i.types[op] |= Disp16;
- }
- else if (flag_code != CODE_64BIT)
- {
- i.rm.regmem = NO_BASE_REGISTER;
- i.types[op] &= ~Disp;
- i.types[op] |= Disp32;
- }
- else
- {
- /* 64bit mode overwrites the 32bit absolute addressing
- by RIP relative addressing and absolute addressing
- is encoded by one of the redundant SIB forms. */
-
- i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
- i.sib.base = NO_BASE_REGISTER;
- i.sib.index = NO_INDEX_REGISTER;
- i.types[op] &= ~Disp;
- i.types[op] |= Disp32S;
- }
- }
- else /* ! i.base_reg && i.index_reg */
- {
- i.sib.index = i.index_reg->reg_num;
- i.sib.base = NO_BASE_REGISTER;
- i.sib.scale = i.log2_scale_factor;
- i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
- i.types[op] &= ~Disp;
- if (flag_code != CODE_64BIT)
- i.types[op] |= Disp32; /* Must be 32 bit */
- else
- i.types[op] |= Disp32S;
- if (i.index_reg->reg_flags & RegRex)
- i.rex.extY=1;
- }
- }
- /* RIP addressing for 64bit mode. */
- else if (i.base_reg->reg_type == BaseIndex)
- {
- i.rm.regmem = NO_BASE_REGISTER;
- i.types[op] &= ~Disp;
- i.types[op] |= Disp32S;
- i.flags[op] = Operand_PCrel;
- }
- else if (i.base_reg->reg_type & Reg16)
- {
- switch (i.base_reg->reg_num)
- {
- case 3: /* (%bx) */
- if (! i.index_reg)
- i.rm.regmem = 7;
- else /* (%bx,%si) -> 0, or (%bx,%di) -> 1 */
- i.rm.regmem = i.index_reg->reg_num - 6;
- break;
- case 5: /* (%bp) */
- default_seg = &ss;
- if (! i.index_reg)
- {
- i.rm.regmem = 6;
- if ((i.types[op] & Disp) == 0)
- {
- /* fake (%bp) into 0(%bp) */
- i.types[op] |= Disp8;
- fake_zero_displacement = 1;
- }
- }
- else /* (%bp,%si) -> 2, or (%bp,%di) -> 3 */
- i.rm.regmem = i.index_reg->reg_num - 6 + 2;
- break;
- default: /* (%si) -> 4 or (%di) -> 5 */
- i.rm.regmem = i.base_reg->reg_num - 6 + 4;
- }
- i.rm.mode = mode_from_disp_size (i.types[op]);
- }
- else /* i.base_reg and 32/64 bit mode */
- {
- if (flag_code == CODE_64BIT
- && (i.types[op] & Disp))
- {
- if (i.types[op] & Disp8)
- i.types[op] = Disp8 | Disp32S;
- else
- i.types[op] = Disp32S;
- }
- i.rm.regmem = i.base_reg->reg_num;
- if (i.base_reg->reg_flags & RegRex)
- i.rex.extZ=1;
- i.sib.base = i.base_reg->reg_num;
- /* x86-64 ignores REX prefix bit here to avoid
- decoder complications. */
- if ((i.base_reg->reg_num & 7) == EBP_REG_NUM)
- {
- default_seg = &ss;
- if (i.disp_operands == 0)
- {
- fake_zero_displacement = 1;
- i.types[op] |= Disp8;
- }
- }
- else if (i.base_reg->reg_num == ESP_REG_NUM)
- {
- default_seg = &ss;
- }
- i.sib.scale = i.log2_scale_factor;
- if (! i.index_reg)
- {
- /* <disp>(%esp) becomes two byte modrm
- with no index register. We've already
- stored the code for esp in i.rm.regmem
- ie. ESCAPE_TO_TWO_BYTE_ADDRESSING. Any
- base register besides %esp will not use
- the extra modrm byte. */
- i.sib.index = NO_INDEX_REGISTER;
-#if ! SCALE1_WHEN_NO_INDEX
- /* Another case where we force the second
- modrm byte. */
- if (i.log2_scale_factor)
- i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
-#endif
- }
- else
- {
- i.sib.index = i.index_reg->reg_num;
- i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
- if (i.index_reg->reg_flags & RegRex)
- i.rex.extY=1;
- }
- i.rm.mode = mode_from_disp_size (i.types[op]);
- }