|
|
|
@ -77,8 +77,8 @@ static const template i386_optab[] = { |
|
|
|
#define MOV_AX_DISP32 0xa0 |
|
|
|
{ "mov", 2, 0xa0, X, 0, bwl_Suf|D|W, { Disp16|Disp32, Acc, 0 } }, |
|
|
|
{ "mov", 2, 0x88, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0 } }, |
|
|
|
{ "mov", 2, 0xb0, X, 0, bwl_Suf|W|ShortForm, { Imm, Reg, 0 } }, |
|
|
|
{ "mov", 2, 0xc6, X, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0 } }, |
|
|
|
{ "mov", 2, 0xb0, X, 0, bwl_Suf|W|ShortForm, { EncImm, Reg, 0 } }, |
|
|
|
{ "mov", 2, 0xc6, X, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0 } }, |
|
|
|
/* The segment register moves accept WordReg so that a segment register
|
|
|
|
can be copied to a 32 bit register, and vice versa, without using a |
|
|
|
size prefix. When moving to a 32 bit register, the upper 16 bits |
|
|
|
@ -171,57 +171,57 @@ static const template i386_optab[] = { |
|
|
|
/* Arithmetic. */ |
|
|
|
{"add", 2, 0x00, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"add", 2, 0x83, 0, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"add", 2, 0x04, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"add", 2, 0x80, 0, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"add", 2, 0x04, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"add", 2, 0x80, 0, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"inc", 1, 0x40, X, 0, wl_Suf|ShortForm, { WordReg, 0, 0} }, |
|
|
|
{"inc", 1, 0xfe, 0, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, |
|
|
|
|
|
|
|
{"sub", 2, 0x28, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"sub", 2, 0x83, 5, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"sub", 2, 0x2c, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"sub", 2, 0x80, 5, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"sub", 2, 0x2c, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"sub", 2, 0x80, 5, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"dec", 1, 0x48, X, 0, wl_Suf|ShortForm, { WordReg, 0, 0} }, |
|
|
|
{"dec", 1, 0xfe, 1, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, |
|
|
|
|
|
|
|
{"sbb", 2, 0x18, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"sbb", 2, 0x83, 3, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"sbb", 2, 0x1c, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"sbb", 2, 0x80, 3, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"sbb", 2, 0x1c, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"sbb", 2, 0x80, 3, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"cmp", 2, 0x38, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"cmp", 2, 0x83, 7, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"cmp", 2, 0x3c, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"cmp", 2, 0x80, 7, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"cmp", 2, 0x3c, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"cmp", 2, 0x80, 7, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"test", 2, 0x84, X, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, Reg, 0} }, |
|
|
|
{"test", 2, 0x84, X, 0, bwl_Suf|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"test", 2, 0xa8, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"test", 2, 0xf6, 0, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"test", 2, 0xa8, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"test", 2, 0xf6, 0, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"and", 2, 0x20, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"and", 2, 0x83, 4, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"and", 2, 0x24, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"and", 2, 0x80, 4, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"and", 2, 0x24, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"and", 2, 0x80, 4, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"or", 2, 0x08, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"or", 2, 0x83, 1, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"or", 2, 0x0c, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"or", 2, 0x80, 1, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"or", 2, 0x0c, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"or", 2, 0x80, 1, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"xor", 2, 0x30, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"xor", 2, 0x83, 6, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"xor", 2, 0x34, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"xor", 2, 0x80, 6, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"xor", 2, 0x34, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"xor", 2, 0x80, 6, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
/* clr with 1 operand is really xor with 2 operands. */ |
|
|
|
{"clr", 1, 0x30, X, 0, bwl_Suf|W|Modrm|regKludge, { Reg, 0, 0 } }, |
|
|
|
|
|
|
|
{"adc", 2, 0x10, X, 0, bwl_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, |
|
|
|
{"adc", 2, 0x83, 2, 0, wl_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, |
|
|
|
{"adc", 2, 0x14, X, 0, bwl_Suf|W, { Imm, Acc, 0} }, |
|
|
|
{"adc", 2, 0x80, 2, 0, bwl_Suf|W|Modrm, { Imm, Reg|AnyMem, 0} }, |
|
|
|
{"adc", 2, 0x14, X, 0, bwl_Suf|W, { EncImm, Acc, 0} }, |
|
|
|
{"adc", 2, 0x80, 2, 0, bwl_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, |
|
|
|
|
|
|
|
{"neg", 1, 0xf6, 3, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, |
|
|
|
{"not", 1, 0xf6, 2, 0, bwl_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, |
|
|
|
@ -1085,104 +1085,104 @@ static const template i386_optab[] = { |
|
|
|
|
|
|
|
static const reg_entry i386_regtab[] = { |
|
|
|
/* make %st first as we test for it */ |
|
|
|
{"st", FloatReg|FloatAcc, 0}, |
|
|
|
{"st", FloatReg|FloatAcc, 0, 0}, |
|
|
|
/* 8 bit regs */ |
|
|
|
{"al", Reg8|Acc, 0}, |
|
|
|
{"cl", Reg8|ShiftCount, 1}, |
|
|
|
{"dl", Reg8, 2}, |
|
|
|
{"bl", Reg8, 3}, |
|
|
|
{"ah", Reg8, 4}, |
|
|
|
{"ch", Reg8, 5}, |
|
|
|
{"dh", Reg8, 6}, |
|
|
|
{"bh", Reg8, 7}, |
|
|
|
{"al", Reg8|Acc, 0, 0}, |
|
|
|
{"cl", Reg8|ShiftCount, 0, 1}, |
|
|
|
{"dl", Reg8, 0, 2}, |
|
|
|
{"bl", Reg8, 0, 3}, |
|
|
|
{"ah", Reg8, 0, 4}, |
|
|
|
{"ch", Reg8, 0, 5}, |
|
|
|
{"dh", Reg8, 0, 6}, |
|
|
|
{"bh", Reg8, 0, 7}, |
|
|
|
/* 16 bit regs */ |
|
|
|
{"ax", Reg16|Acc, 0}, |
|
|
|
{"cx", Reg16, 1}, |
|
|
|
{"dx", Reg16|InOutPortReg, 2}, |
|
|
|
{"bx", Reg16|BaseIndex, 3}, |
|
|
|
{"sp", Reg16, 4}, |
|
|
|
{"bp", Reg16|BaseIndex, 5}, |
|
|
|
{"si", Reg16|BaseIndex, 6}, |
|
|
|
{"di", Reg16|BaseIndex, 7}, |
|
|
|
{"ax", Reg16|Acc, 0, 0}, |
|
|
|
{"cx", Reg16, 0, 1}, |
|
|
|
{"dx", Reg16|InOutPortReg, 0, 2}, |
|
|
|
{"bx", Reg16|BaseIndex, 0, 3}, |
|
|
|
{"sp", Reg16, 0, 4}, |
|
|
|
{"bp", Reg16|BaseIndex, 0, 5}, |
|
|
|
{"si", Reg16|BaseIndex, 0, 6}, |
|
|
|
{"di", Reg16|BaseIndex, 0, 7}, |
|
|
|
/* 32 bit regs */ |
|
|
|
{"eax", Reg32|BaseIndex|Acc, 0}, |
|
|
|
{"ecx", Reg32|BaseIndex, 1}, |
|
|
|
{"edx", Reg32|BaseIndex, 2}, |
|
|
|
{"ebx", Reg32|BaseIndex, 3}, |
|
|
|
{"esp", Reg32, 4}, |
|
|
|
{"ebp", Reg32|BaseIndex, 5}, |
|
|
|
{"esi", Reg32|BaseIndex, 6}, |
|
|
|
{"edi", Reg32|BaseIndex, 7}, |
|
|
|
{"eax", Reg32|BaseIndex|Acc, 0, 0}, |
|
|
|
{"ecx", Reg32|BaseIndex, 0, 1}, |
|
|
|
{"edx", Reg32|BaseIndex, 0, 2}, |
|
|
|
{"ebx", Reg32|BaseIndex, 0, 3}, |
|
|
|
{"esp", Reg32, 0, 4}, |
|
|
|
{"ebp", Reg32|BaseIndex, 0, 5}, |
|
|
|
{"esi", Reg32|BaseIndex, 0, 6}, |
|
|
|
{"edi", Reg32|BaseIndex, 0, 7}, |
|
|
|
/* segment registers */ |
|
|
|
{"es", SReg2, 0}, |
|
|
|
{"cs", SReg2, 1}, |
|
|
|
{"ss", SReg2, 2}, |
|
|
|
{"ds", SReg2, 3}, |
|
|
|
{"fs", SReg3, 4}, |
|
|
|
{"gs", SReg3, 5}, |
|
|
|
{"es", SReg2, 0, 0}, |
|
|
|
{"cs", SReg2, 0, 1}, |
|
|
|
{"ss", SReg2, 0, 2}, |
|
|
|
{"ds", SReg2, 0, 3}, |
|
|
|
{"fs", SReg3, 0, 4}, |
|
|
|
{"gs", SReg3, 0, 5}, |
|
|
|
/* control registers */ |
|
|
|
{"cr0", Control, 0}, |
|
|
|
{"cr1", Control, 1}, |
|
|
|
{"cr2", Control, 2}, |
|
|
|
{"cr3", Control, 3}, |
|
|
|
{"cr4", Control, 4}, |
|
|
|
{"cr5", Control, 5}, |
|
|
|
{"cr6", Control, 6}, |
|
|
|
{"cr7", Control, 7}, |
|
|
|
{"cr0", Control, 0, 0}, |
|
|
|
{"cr1", Control, 0, 1}, |
|
|
|
{"cr2", Control, 0, 2}, |
|
|
|
{"cr3", Control, 0, 3}, |
|
|
|
{"cr4", Control, 0, 4}, |
|
|
|
{"cr5", Control, 0, 5}, |
|
|
|
{"cr6", Control, 0, 6}, |
|
|
|
{"cr7", Control, 0, 7}, |
|
|
|
/* debug registers */ |
|
|
|
{"db0", Debug, 0}, |
|
|
|
{"db1", Debug, 1}, |
|
|
|
{"db2", Debug, 2}, |
|
|
|
{"db3", Debug, 3}, |
|
|
|
{"db4", Debug, 4}, |
|
|
|
{"db5", Debug, 5}, |
|
|
|
{"db6", Debug, 6}, |
|
|
|
{"db7", Debug, 7}, |
|
|
|
{"dr0", Debug, 0}, |
|
|
|
{"dr1", Debug, 1}, |
|
|
|
{"dr2", Debug, 2}, |
|
|
|
{"dr3", Debug, 3}, |
|
|
|
{"dr4", Debug, 4}, |
|
|
|
{"dr5", Debug, 5}, |
|
|
|
{"dr6", Debug, 6}, |
|
|
|
{"dr7", Debug, 7}, |
|
|
|
{"db0", Debug, 0, 0}, |
|
|
|
{"db1", Debug, 0, 1}, |
|
|
|
{"db2", Debug, 0, 2}, |
|
|
|
{"db3", Debug, 0, 3}, |
|
|
|
{"db4", Debug, 0, 4}, |
|
|
|
{"db5", Debug, 0, 5}, |
|
|
|
{"db6", Debug, 0, 6}, |
|
|
|
{"db7", Debug, 0, 7}, |
|
|
|
{"dr0", Debug, 0, 0}, |
|
|
|
{"dr1", Debug, 0, 1}, |
|
|
|
{"dr2", Debug, 0, 2}, |
|
|
|
{"dr3", Debug, 0, 3}, |
|
|
|
{"dr4", Debug, 0, 4}, |
|
|
|
{"dr5", Debug, 0, 5}, |
|
|
|
{"dr6", Debug, 0, 6}, |
|
|
|
{"dr7", Debug, 0, 7}, |
|
|
|
/* test registers */ |
|
|
|
{"tr0", Test, 0}, |
|
|
|
{"tr1", Test, 1}, |
|
|
|
{"tr2", Test, 2}, |
|
|
|
{"tr3", Test, 3}, |
|
|
|
{"tr4", Test, 4}, |
|
|
|
{"tr5", Test, 5}, |
|
|
|
{"tr6", Test, 6}, |
|
|
|
{"tr7", Test, 7}, |
|
|
|
{"tr0", Test, 0, 0}, |
|
|
|
{"tr1", Test, 0, 1}, |
|
|
|
{"tr2", Test, 0, 2}, |
|
|
|
{"tr3", Test, 0, 3}, |
|
|
|
{"tr4", Test, 0, 4}, |
|
|
|
{"tr5", Test, 0, 5}, |
|
|
|
{"tr6", Test, 0, 6}, |
|
|
|
{"tr7", Test, 0, 7}, |
|
|
|
/* mmx and simd registers */ |
|
|
|
{"mm0", RegMMX, 0}, |
|
|
|
{"mm1", RegMMX, 1}, |
|
|
|
{"mm2", RegMMX, 2}, |
|
|
|
{"mm3", RegMMX, 3}, |
|
|
|
{"mm4", RegMMX, 4}, |
|
|
|
{"mm5", RegMMX, 5}, |
|
|
|
{"mm6", RegMMX, 6}, |
|
|
|
{"mm7", RegMMX, 7}, |
|
|
|
{"xmm0", RegXMM, 0}, |
|
|
|
{"xmm1", RegXMM, 1}, |
|
|
|
{"xmm2", RegXMM, 2}, |
|
|
|
{"xmm3", RegXMM, 3}, |
|
|
|
{"xmm4", RegXMM, 4}, |
|
|
|
{"xmm5", RegXMM, 5}, |
|
|
|
{"xmm6", RegXMM, 6}, |
|
|
|
{"xmm7", RegXMM, 7} |
|
|
|
{"mm0", RegMMX, 0, 0}, |
|
|
|
{"mm1", RegMMX, 0, 1}, |
|
|
|
{"mm2", RegMMX, 0, 2}, |
|
|
|
{"mm3", RegMMX, 0, 3}, |
|
|
|
{"mm4", RegMMX, 0, 4}, |
|
|
|
{"mm5", RegMMX, 0, 5}, |
|
|
|
{"mm6", RegMMX, 0, 6}, |
|
|
|
{"mm7", RegMMX, 0, 7}, |
|
|
|
{"xmm0", RegXMM, 0, 0}, |
|
|
|
{"xmm1", RegXMM, 0, 1}, |
|
|
|
{"xmm2", RegXMM, 0, 2}, |
|
|
|
{"xmm3", RegXMM, 0, 3}, |
|
|
|
{"xmm4", RegXMM, 0, 4}, |
|
|
|
{"xmm5", RegXMM, 0, 5}, |
|
|
|
{"xmm6", RegXMM, 0, 6}, |
|
|
|
{"xmm7", RegXMM, 0, 7} |
|
|
|
}; |
|
|
|
|
|
|
|
static const reg_entry i386_float_regtab[] = { |
|
|
|
{"st(0)", FloatReg|FloatAcc, 0}, |
|
|
|
{"st(1)", FloatReg, 1}, |
|
|
|
{"st(2)", FloatReg, 2}, |
|
|
|
{"st(3)", FloatReg, 3}, |
|
|
|
{"st(4)", FloatReg, 4}, |
|
|
|
{"st(5)", FloatReg, 5}, |
|
|
|
{"st(6)", FloatReg, 6}, |
|
|
|
{"st(7)", FloatReg, 7} |
|
|
|
{"st(0)", FloatReg|FloatAcc, 0, 0}, |
|
|
|
{"st(1)", FloatReg, 0, 1}, |
|
|
|
{"st(2)", FloatReg, 0, 2}, |
|
|
|
{"st(3)", FloatReg, 0, 3}, |
|
|
|
{"st(4)", FloatReg, 0, 4}, |
|
|
|
{"st(5)", FloatReg, 0, 5}, |
|
|
|
{"st(6)", FloatReg, 0, 6}, |
|
|
|
{"st(7)", FloatReg, 0, 7} |
|
|
|
}; |
|
|
|
|
|
|
|
#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */ |
|
|
|
|