mirror of
https://github.com/frida/tinycc
synced 2024-11-23 16:19:35 +03:00
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.
This commit is contained in:
parent
e3f2a68311
commit
5692716770
@ -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];
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -185,6 +185,7 @@
|
||||
DEF_WLX(btr)
|
||||
DEF_WLX(btc)
|
||||
|
||||
DEF_WLX(lar)
|
||||
DEF_WLX(lsl)
|
||||
|
||||
/* generic FP ops */
|
||||
|
@ -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
|
||||
|
@ -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…
Reference in New Issue
Block a user