Merge remote-tracking branch

'origin/GP-181_James_x64_zero_extend_32_bit_results' into Ghidra_9.2
This commit is contained in:
ghidra1 2020-10-29 18:24:48 -04:00
commit 40a55b0d6b
4 changed files with 76 additions and 38 deletions

View File

@ -10,12 +10,13 @@ macro tzcntflags(input, output) {
####
# TODO remove ANDN from ia.sinc ?????
:ANDN Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf2; Reg32 ... & rm32
:ANDN Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf2; Reg32 ... & check_Reg32_dest ... &rm32
{
Reg32 = ~(vexVVVV_r32) & rm32;
resultflags(Reg32);
OF = 0;
CF = 0;
build check_Reg32_dest;
}
@ifdef IA64
@ -30,12 +31,13 @@ macro tzcntflags(input, output) {
@endif
:BEXTR Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & rm32
:BEXTR Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
{
sourceTmp:1 = vexVVVV_r32[0,8];
lengthTmp:1 = vexVVVV_r32[8,8];
Reg32 = (rm32 >> sourceTmp) & ((1 << lengthTmp) - 1);
build check_Reg32_dest;
ZF = (Reg32 == 0);
OF = 0;
@ -59,9 +61,10 @@ macro tzcntflags(input, output) {
@endif
:BLSI vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=3 ... & rm32
:BLSI vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=3 ... & check_vexVVVV_r32_dest ... & rm32
{
vexVVVV_r32 = -rm32 & rm32;
build check_vexVVVV_r32_dest;
ZF = (vexVVVV_r32 == 0);
SF = (vexVVVV_r32 s< 0);
@ -84,12 +87,13 @@ macro tzcntflags(input, output) {
@endif
:BLSMSK vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=2 ... & rm32
:BLSMSK vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=2 ... & check_vexVVVV_r32_dest ... &rm32
{
CF = (rm32 == 0);
vexVVVV_r32 = (rm32 - 1) ^ rm32;
SF = (vexVVVV_r32 s< 0);
build check_vexVVVV_r32_dest;
ZF = 0;
OF = 0;
# AF and PF are undefined
@ -109,10 +113,11 @@ macro tzcntflags(input, output) {
@endif
:BLSR vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=1 ... & rm32
:BLSR vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf3; reg_opcode=1 ... & check_vexVVVV_r32_dest ... &rm32
{
CF = (rm32 == 0);
vexVVVV_r32 = (rm32 - 1) & rm32;
build check_vexVVVV_r32_dest;
ZF = (vexVVVV_r32 == 0);
SF = (vexVVVV_r32 s< 0);
@ -152,7 +157,7 @@ macro tzcntflags(input, output) {
}
:TZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg32 ... & rm32 {
:TZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBC; Reg32 ... & check_Reg32_dest ... & rm32 {
countTmp:4 = 0;
inputTmp:4 = rm32;
@ -167,6 +172,7 @@ macro tzcntflags(input, output) {
<loopend>
tzcntflags(rm32, countTmp);
Reg32 = countTmp;
build check_Reg32_dest;
}
@ifdef IA64

View File

@ -3,7 +3,7 @@
####
:BZHI Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & rm32
:BZHI Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
{
indexTmp:1 = vexVVVV_r32:1;
@ -12,6 +12,7 @@
# clear the upper bits
Reg32 = (rm32 << shift) >> shift;
build check_Reg32_dest;
ZF = (Reg32 == 0);
SF = (Reg32 s< 0);
@ -40,12 +41,14 @@
@endif
:MULX Reg32, vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf6; Reg32 ... & rm32
:MULX Reg32, vexVVVV_r32, rm32 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf6; Reg32 ... & check_Reg32_dest ... & check_vexVVVV_r32_dest ... & rm32
{
temp:8 = zext(EDX) * zext(rm32);
vexVVVV_r32 = temp:4;
build check_vexVVVV_r32_dest;
Reg32 = temp(4);
build check_Reg32_dest;
}
@ifdef IA64
@ -59,7 +62,7 @@
@endif
:PDEP Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & rm32
:PDEP Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
{
sourceTmp:4 = vexVVVV_r32;
@ -78,6 +81,7 @@
if (indexTmp != 0) goto <loop>;
Reg32 = resultTmp;
build check_Reg32_dest;
}
@ifdef IA64
@ -104,7 +108,7 @@
@endif
:PEXT Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & rm32
:PEXT Reg32, vexVVVV_r32, rm32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf5; Reg32 ... & check_Reg32_dest ... & rm32
{
indexTmp:4 = 0x80000000;
resultTmp:4 = 0;
@ -119,6 +123,7 @@
indexTmp = indexTmp >> 1;
if (indexTmp != 0) goto <loop>;
build check_Reg32_dest;
Reg32 = resultTmp;
}
@ -143,11 +148,12 @@
@endif
:RORX Reg32, rm32, imm8 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W0); byte=0xf0; Reg32 ... & rm32; imm8
:RORX Reg32, rm32, imm8 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W0); byte=0xf0; Reg32 ... & check_Reg32_dest ... & rm32; imm8
{
shiftTmp:1 = (imm8:1 & 0x1F);
Reg32 = (rm32 >> shiftTmp) | ( rm32 << (32 - shiftTmp));
build check_Reg32_dest;
}
@ifdef IA64
@ -160,9 +166,10 @@
@endif
:SARX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & rm32
:SARX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
{
Reg32 = rm32 s>> (vexVVVV_r32 & 0x0000001F);
build check_Reg32_dest;
}
@ifdef IA64
@ -173,9 +180,10 @@
@endif
:SHLX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & rm32
:SHLX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
{
Reg32 = rm32 << (vexVVVV_r32 & 0x0000001F);
build check_Reg32_dest;
}
@ifdef IA64
@ -186,9 +194,10 @@
@endif
:SHRX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & rm32
:SHRX Reg32, rm32, vexVVVV_r32 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_r32; byte=0xf7; Reg32 ... & check_Reg32_dest ... & rm32
{
Reg32 = rm32 >> (vexVVVV_r32 & 0x0000001F);
build check_Reg32_dest;
}
@ifdef IA64

View File

@ -965,18 +965,22 @@ spec_rm64: "qword ptr "^Mem is Mem { export *:8 Mem; }
n1: "1" is epsilon { tmp:1 = 1; export tmp; }
@ifdef IA64
# Handle sign extension in 64-bit mode for 32-bit destination registers
# Handle zero extension in 64-bit mode for 32-bit destination registers
check_Reg32_dest: is bit64=1 & rexRprefix=0 & reg32 & reg64 { reg64 = zext(reg32); }
check_Reg32_dest: is bit64=1 & rexRprefix=1 & reg32_x & reg64_x { reg64_x = zext(reg32_x); }
check_Rmr32_dest: is bit64=1 & rexBprefix=0 & r32 & r64 { r64 = zext(r32); }
check_Rmr32_dest: is bit64=1 & rexBprefix=1 & r32_x & r64_x { r64_x = zext(r32_x); }
check_rm32_dest: is bit64=1 & mod=3 & check_Rmr32_dest { build check_Rmr32_dest; }
check_EAX_dest: is bit64=1 { RAX = zext(EAX); }
check_EDX_dest: is bit64=1 { RDX = zext(EDX); }
check_vexVVVV_r32_dest: is bit64=1 & vexVVVV_r64 & vexVVVV_r32 { vexVVVV_r64 = zext(vexVVVV_r32);}
@endif
check_Reg32_dest: is epsilon { }
check_Rmr32_dest: is epsilon { }
check_rm32_dest: is epsilon { }
check_EAX_dest: is epsilon { }
check_EDX_dest: is epsilon { }
check_vexVVVV_r32_dest: is epsilon { }
ptr1616: reloc is protectedMode=0 & imm16; j16 [ reloc = j16*0x10 + imm16; ] { CS = j16; export *[ram]:4 reloc; }
ptr1616: reloc is protectedMode=1 & imm16; j16 [ reloc = j16*0x10000 + imm16; ] { CS = j16; export *[ram]:4 reloc; }
@ -1968,7 +1972,7 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { }
:BTC Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbb; mod=3 & Rmr16 & Reg16 { local bit=Reg16&0xf; local val=(Rmr16>>bit)&1; Rmr16=Rmr16^(1<<bit); CF=(val!=0); }
:BTC Mem,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbb; Mem & Reg16 ... { local ptr = Mem + (sext(Reg16) s>> 3); local bit=Reg16&7; local val = (*:1 ptr >> bit) & 1; *:1 ptr= *:1 ptr ^(1<<bit); CF=(val!=0); }
:BTC Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbb; mod=3 & Rmr32 & Reg32 { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; Rmr32=Rmr32^(1<<bit); CF=(val!=0); }
:BTC Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbb; mod=3 & Rmr32 & Reg32 & check_Rmr32_dest { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; CF=(val!=0); Rmr32=Rmr32^(1<<bit); build check_Rmr32_dest; }
:BTC Mem,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbb; Mem & Reg32 ... {
@ifdef IA64
local ptr = Mem + (sext(Reg32) s>> 3);
@ -1985,14 +1989,14 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { }
:BTC Mem,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbb; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>> 3); local bit=Reg64&7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr ^ (1<<bit); CF = (val != 0); }
@endif
:BTC rm16,imm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xba; (rm16 & reg_opcode=7 ...); imm8 { local bit=imm8&0xf; local val=(rm16>>bit)&1; rm16=rm16^(1<<bit); CF=(val!=0); }
:BTC rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=7 ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; rm32=rm32^(1<<bit); CF=(val!=0); }
:BTC rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & check_rm32_dest ... & reg_opcode=7 ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; CF=(val!=0); rm32=rm32^(1<<bit); build check_rm32_dest; }
@ifdef IA64
:BTC rm64,imm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=7 ...); imm8 { local bit=imm8&0x3f; local val=(rm64>>bit)&1; rm64=rm64^(1<<bit); CF=(val!=0); }
@endif
:BTR Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xb3; mod=3 & Rmr16 & Reg16 { local bit=Reg16&0xf; local val=(Rmr16>>bit)&1; Rmr16=Rmr16 & ~(1<<bit); CF=(val!=0); }
:BTR Mem,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xb3; Mem & Reg16 ... { local ptr = Mem + (sext(Reg16) s>> 3); local bit=Reg16&7; local val=(*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr & ~(1<<bit); CF = (val!=0); }
:BTR Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb3; mod=3 & Rmr32 & Reg32 { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; Rmr32=Rmr32 & ~(1<<bit); CF=(val!=0); }
:BTR Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb3; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; CF=(val!=0); Rmr32=Rmr32 & ~(1<<bit); build check_Rmr32_dest; }
:BTR Mem,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb3; Mem & Reg32 ... {
@ifdef IA64
local ptr = Mem + (sext(Reg32) s>> 3);
@ -2009,14 +2013,14 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { }
:BTR Mem,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xb3; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>> 3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr & ~(1<<bit); CF = (val!=0); }
@endif
:BTR rm16,imm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xba; (rm16 & reg_opcode=6 ...); imm8 { local bit=imm8&0xf; local val=(rm16>>bit)&1; rm16=rm16 & ~(1<<bit); CF=(val!=0); }
:BTR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=6 ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; rm32=rm32 & ~(1<<bit); CF=(val!=0); }
:BTR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=6 ... & check_rm32_dest ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; CF=(val!=0); rm32=rm32 & ~(1<<bit); build check_rm32_dest; }
@ifdef IA64
:BTR rm64,imm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=6 ...); imm8 { local bit=imm8&0x3f; local val=(rm64>>bit)&1; rm64=rm64 & ~(1<<bit); CF=(val!=0); }
@endif
:BTS Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xab; mod=3 & Rmr16 & Reg16 { local bit=Reg16&0xf; local val=(Rmr16>>bit)&1; Rmr16=Rmr16 | (1<<bit); CF=(val!=0); }
:BTS Mem,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xab; Mem & Reg16 ... { local ptr = Mem + (sext(Reg16) s>> 3); local bit = Reg16&7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr | (1<<bit); CF = (val != 0); }
:BTS Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xab; mod=3 & Rmr32 & Reg32 { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; Rmr32=Rmr32 | (1<<bit); CF=(val!=0); }
:BTS Rmr32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xab; mod=3 & Rmr32 & check_Rmr32_dest & Reg32 { local bit=Reg32&0x1f; local val=(Rmr32>>bit)&1; CF=(val!=0); Rmr32=Rmr32 | (1<<bit); build check_Rmr32_dest; }
:BTS Mem,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xab; Mem & Reg32 ... {
@ifdef IA64
local ptr = Mem + (sext(Reg32) s>>3);
@ -2033,7 +2037,7 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { }
:BTS Mem,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xab; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>>3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr | (1<<bit); CF = (val != 0); }
@endif
:BTS rm16,imm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xba; (rm16 & reg_opcode=5 ...); imm8 { local bit=imm8&0xf; local val=(rm16>>bit)&1; rm16=rm16 | (1<<bit); CF=(val!=0); }
:BTS rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=5 ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; rm32=rm32 | (1<<bit); CF=(val!=0); }
:BTS rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=5 ... & check_rm32_dest ...); imm8 { local bit=imm8&0x1f; local val=(rm32>>bit)&1; CF=(val!=0); rm32=rm32 | (1<<bit); build check_rm32_dest; }
@ifdef IA64
:BTS rm64,imm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=5 ...); imm8 { local bit=imm8&0x3f; local val=(rm64>>bit)&1; rm64=rm64 | (1<<bit); CF=(val!=0); }
@endif
@ -2090,13 +2094,13 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { }
@endif
:CBW is vexMode=0 & opsize=0 & byte=0x98 { AX = sext(AL); }
:CWDE is vexMode=0 & opsize=1 & byte=0x98 { EAX = sext(AX); }
:CWDE is vexMode=0 & opsize=1 & byte=0x98 & check_EAX_dest { EAX = sext(AX); build check_EAX_dest;}
@ifdef IA64
:CDQE is vexMode=0 & opsize=2 & byte=0x98 { RAX = sext(EAX); }
@endif
:CWD is vexMode=0 & opsize=0 & byte=0x99 { tmp:4 = sext(AX); DX = tmp(2); }
:CDQ is vexMode=0 & opsize=1 & byte=0x99 { tmp:8 = sext(EAX); EDX = tmp(4); }
:CDQ is vexMode=0 & opsize=1 & byte=0x99 & check_EDX_dest { tmp:8 = sext(EAX); EDX = tmp(4); build check_EDX_dest;}
@ifdef IA64
:CQO is vexMode=0 & opsize=2 & byte=0x99 { tmp:16 = sext(RAX); RDX = tmp(8); }
@endif
@ -2179,9 +2183,23 @@ define pcodeop clzero;
:CMPXCHG rm16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xb1; rm16 & Reg16 ... { subflags(AX,rm16); local tmp=AX-rm16; resultflags(tmp);
local diff = rm16^Reg16; rm16 = rm16 ^ (zext(ZF) * diff);
diff = AX ^ rm16; AX = AX ^ (zext(ZF==0) * diff); }
:CMPXCHG rm32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb1; rm32 & Reg32 ... { subflags(EAX,rm32); local tmp=EAX-rm32; resultflags(tmp);
local diff = rm32^Reg32; rm32 = rm32 ^ (zext(ZF) * diff);
diff = EAX ^ rm32; EAX = EAX ^ (zext(ZF==0) * diff); }
:CMPXCHG rm32,Reg32 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb1; rm32 & Reg32 ... & check_EAX_dest ... & check_rm32_dest ...
{
#this instruction writes to either EAX or rm32
#in 64-bit mode, a 32-bit register that is written to
#(and only the register that is written to)
#must be zero-extended to 64 bits
subflags(EAX,rm32);
local tmp=EAX-rm32;
resultflags(tmp);
if (ZF==1) goto <equal>;
EAX = rm32;
build check_EAX_dest;
goto inst_next;
<equal>
rm32 = Reg32;
build check_rm32_dest;
}
@ifdef IA64
:CMPXCHG rm64,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xb1; rm64 & Reg64 ... { subflags(RAX,rm64); local tmp=RAX-rm64; resultflags(tmp);
local diff = rm64^Reg64; rm64 = rm64 ^ (zext(ZF) * diff);
@ -2369,12 +2387,14 @@ define pcodeop cpuid_brand_part3_info;
AX = quotient:2;
local rem = tmp % rm16ext;
DX = rem:2; }
:DIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=6 ... { rm32ext:8 = zext(rm32);
:DIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EDX_dest ... & check_EAX_dest ... & reg_opcode=6 ... { rm32ext:8 = zext(rm32);
tmp:8 = (zext(EDX) << 32) | zext(EAX); # DE exception if quotient doesn't fit in EAX
local quotient = tmp / rm32ext;
EAX = quotient:4;
build check_EAX_dest;
local rem = tmp % rm32ext;
EDX = rem:4; }
EDX = rem:4;
build check_EDX_dest; }
@ifdef IA64
:DIV rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=6 ... { rm64ext:16 = zext(rm64);
tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX
@ -2627,12 +2647,14 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
AX = quotient:2;
local rem = tmp s% rm16ext;
DX = rem:2; }
:IDIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=7 ... { rm32ext:8 = sext(rm32);
:IDIV rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=7 ... { rm32ext:8 = sext(rm32);
tmp:8 = (zext(EDX) << 32) | zext(EAX); # DE exception if quotient doesn't fit in EAX
local quotient = tmp s/ rm32ext;
EAX = quotient:4;
build check_EAX_dest;
local rem = tmp s% rm32ext;
EDX = rem:4; }
EDX = rem:4;
build check_EDX_dest; }
@ifdef IA64
:IDIV rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=7 ... { rm64ext:16 = sext(rm64);
tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX
@ -2645,12 +2667,12 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
:IMUL rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=5 ... { AX = sext(AL) * sext(rm8); imultflags(AL,AX); }
:IMUL rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=5 ... { tmp:4 = sext(AX) * sext(rm16);
DX = tmp(2); AX = tmp(0); imultflags(AX,tmp); }
:IMUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=5 ... { tmp:8 = sext(EAX) * sext(rm32);
EDX = tmp(4); EAX = tmp(0); imultflags(EAX,tmp); }
:IMUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=5 ... { tmp:8 = sext(EAX) * sext(rm32);
EDX = tmp(4); build check_EDX_dest; EAX = tmp(0); build check_EAX_dest; imultflags(EAX,tmp); }
@ifdef IA64
# We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct
:IMUL rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=5 ... { tmp:16 = sext(RAX) * sext(rm64);
RDX = tmp(8); RAX = RAX * rm64; imultflags(RAX,tmp); }
RAX = RAX * rm64; RDX = tmp(8); imultflags(RAX,tmp); }
@endif
:IMUL Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xaf; rm16 & Reg16 ... { tmp:4 = sext(Reg16) * sext(rm16);
Reg16 = tmp(0); high:2 = tmp(2); imultflags(Reg16,tmp);}
@ -2841,6 +2863,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; }
Reg32 = addr32;
build check_Reg32_dest;
}
@ifdef IA64
:LEA Reg16,addr64 is vexMode=0 & opsize=0 & addrsize=2 & byte=0x8D; addr64 & Reg16 ... { Reg16 = addr64(0); }
:LEA Reg32,addr64 is vexMode=0 & opsize=1 & addrsize=2 & byte=0x8D; addr64 & Reg32 ... & check_Reg32_dest ... {
@ -3115,7 +3138,7 @@ define pcodeop swap_bytes;
:MUL rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=4 ... { AX=zext(AL)*zext(rm8); multflags(AH); }
:MUL rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=4 ... { tmp:4=zext(AX)*zext(rm16); DX=tmp(2); AX=tmp(0); multflags(DX); }
:MUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=4 ... { tmp:8=zext(EAX)*zext(rm32); EDX=tmp(4); EAX=tmp(0); multflags(EDX); }
:MUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=4 ... { tmp:8=zext(EAX)*zext(rm32); EDX=tmp(4); build check_EDX_dest; multflags(EDX); EAX=tmp(0); build check_EAX_dest; }
@ifdef IA64
:MUL rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=4 ... { tmp:16=zext(RAX)*zext(rm64); RDX=tmp(8); RAX=tmp(0); multflags(RDX); }
@endif
@ -3127,7 +3150,7 @@ define pcodeop swap_bytes;
:NEG rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=3 ... { negflags(rm8); rm8 = -rm8; resultflags(rm8 ); }
:NEG rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=3 ... { negflags(rm16); rm16 = -rm16; resultflags(rm16); }
:NEG rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=3 ... { negflags(rm32); rm32 = -rm32; resultflags(rm32); }
:NEG rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_rm32_dest ... & reg_opcode=3 ... { negflags(rm32); rm32 = -rm32; resultflags(rm32); build check_rm32_dest;}
@ifdef IA64
:NEG rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=3 ... { negflags(rm64); rm64 = -rm64; resultflags(rm64); }
@endif
@ -3143,7 +3166,7 @@ define pcodeop swap_bytes;
:NOT rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=2 ... { rm8 = ~rm8; }
:NOT rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=2 ... { rm16 = ~rm16; }
:NOT rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & reg_opcode=2 ... { rm32 = ~rm32; }
:NOT rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_rm32_dest ... & reg_opcode=2 ... { rm32 = ~rm32; build check_rm32_dest;}
@ifdef IA64
:NOT rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=2 ... { rm64 = ~rm64; }
@endif

View File

@ -27,7 +27,7 @@ macro lzcntflags(input, output) {
}
:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & rm32 {
:LZCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xBD; Reg32 ... & check_Reg32_dest ... & rm32 {
countTmp:4 = 0;
inputTmp:4 = rm32;
@ -42,7 +42,7 @@ macro lzcntflags(input, output) {
<loopend>
lzcntflags(rm32, countTmp);
Reg32 = countTmp;
build check_Reg32_dest;
}
@ifdef IA64