Browse Source

x86-asm: Fix lar opcode operands

lar can accept multiple sizes as well (wlx), like lsl.  When using
autosize it's important to look at the destination operand first;
when it's a register that one determines the size, not the input
operand.
master
Michael Matz 8 years ago
parent
commit
5692716770
  1. 6
      i386-asm.c
  2. 2
      i386-asm.h
  3. 1
      i386-tok.h
  4. 7
      tests/asmtest.S
  5. 2
      x86_64-asm.h

6
i386-asm.c

@ -733,7 +733,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
autosize = NBWLX-2;
#endif
if (s == autosize) {
for(i = 0; s == autosize && i < nb_ops; i++) {
/* Check for register operands providing hints about the size.
Start from the end, i.e. destination operands. This matters
only for opcodes accepting different sized registers, lar and lsl
are such opcodes. */
for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
s = reg_to_size[ops[i].type & OP_REG];
}

2
i386-asm.h

@ -341,7 +341,7 @@ ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
/* segments */
DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)

1
i386-tok.h

@ -185,6 +185,7 @@
DEF_WLX(btr)
DEF_WLX(btc)
DEF_WLX(lar)
DEF_WLX(lsl)
/* generic FP ops */

7
tests/asmtest.S

@ -625,8 +625,15 @@ int $0x10
clflush 0x1000(%rax,%rcx)
fxsaveq (%rdx)
fxrstorq (%rcx)
#endif
lar %ax,%dx
lar %eax,%dx
lar %ax,%edx
lar %eax,%edx
lar %ax,%rdx
lar %eax,%rdx
emms
movd %edx, %mm3
movd 0x1000, %mm2

2
x86_64-asm.h

@ -359,7 +359,7 @@ ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
/* segments */
DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)

Loading…
Cancel
Save