Unlocks the x86 family end-to-end and makes the write-loop detector precise enough for statically-linked binaries. x86 SLEIGH: - Vendor Ghidra's x86 language specs (specs/x86, x86:LE:64:default + :32:default); add x86-64/x86 .sla build targets. archSpecFor maps x86/64 + x86/32. - ghidra_lifter: set the x86-64 decode context (longMode/addrsize/opsize) in the raw path, and bound decompiler flow at the function end (0xC3 tail fill) so variable-length x86 does not run away into zero padding. Precise SSA def-use (benefits all arches): - ir::pcode::PcodeOp gains in_def (defining-op index per input); the SSA lifter records real def-use. summarizePointerWrites now resolves the store-address base via def-use instead of a last-write heuristic — essential on x86 where arg registers are reused as scratch (RAX) and sub-registers are written (SIL). - paramIndexOf is arch-aware (AArch64 x0–x7; SysV x86-64 RDI/RSI/RDX/RCX/R8/R9). Precision (the key fix at scale): - A copy bounded by a size *parameter* (memcpy-like `for i<n`) is suppressed: if the loop index is `<`-compared against a pure parameter input, the function is size-bounded and not flagged. baby_bof's decode_base64 bounds on strlen(input) (a computed value, not a param) so it still fires. This cut a statically-linked x86-64 binary from 101 findings (≈100 glibc/libstdc++ FPs) to 1 — the real decode_base64 → 264-byte overflow. Perf + reach: - Cache the pre-pass SSA lift and reuse it in the main pass (re-lifting only the few callers of a write-loop callee that need the injected prototype). - Give whole-binary r2 analysis a generous timeout (FOLD_R2_ANALYSIS_TIMEOUT_MS, default 120s) so large static binaries actually analyze (the 3s per-command watchdog left them with an empty function list). Validated: decode_base64 overflow fires on x86-64 (index_amd64.cgi) and AArch64 (index_nocanary.cgi); AArch64 corpus BOF counts unchanged (3/1/1); x86-64 static FP 101→1. Unit: test_pcode_summary +x86-64 case (9 assertions). meson test 77/77. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1386 lines
32 KiB
Text
1386 lines
32 KiB
Text
# The LOCK prefix is only valid for certain instructions, otherwise, from the
|
|
# Intel instruction manual:
|
|
# An undefined opcode exception will also be generated if the LOCK prefix
|
|
# is used with any instruction not in the above list.
|
|
# The instructions in this file have their non-lockable counterparts in ia.sinc
|
|
|
|
:ADC^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=2 ... ; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
addCarryFlags(m8, imm8:1);
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:ADC^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=2 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addCarryFlags(m16, imm16:2);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADC^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=2 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addCarryFlags(m32, imm32:4);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADC^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=2 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addCarryFlags(m64,simm32);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:ADC^lockx m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=2 ...; simm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addCarryFlags(m16,simm8_16);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADC^lockx m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=2 ...; simm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addCarryFlags(m32,simm8_32);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADC^lockx m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=2 ...; simm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addCarryFlags(m64,simm8_64);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:ADC^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x10; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
addCarryFlags(m8, Reg8);
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:ADC^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x11; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addCarryFlags(m16, Reg16);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADC^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x11; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addCarryFlags(m32, Reg32);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADC^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x11; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addCarryFlags(m64, Reg64);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:ADD^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=0 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
addflags(m8,imm8);
|
|
m8 = m8 + imm8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:ADD^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=0 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addflags(m16,imm16);
|
|
m16 = m16 + imm16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADD^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=0 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addflags(m32,imm32);
|
|
m32 = m32 + imm32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADD^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=0 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addflags(m64,simm32);
|
|
m64 = m64 + simm32;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:ADD^lockx m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=0 ...; simm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addflags(m16,simm8_16);
|
|
m16 = m16 + simm8_16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADD^lockx m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=0 ...; simm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addflags(m32,simm8_32);
|
|
m32 = m32 + simm8_32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADD^lockx m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=0 ...; simm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addflags(m64,simm8_64);
|
|
m64 = m64 + simm8_64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:ADD^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x00; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
addflags(m8,Reg8);
|
|
m8 = m8 + Reg8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:ADD^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x1; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addflags(m16,Reg16);
|
|
m16 = m16 + Reg16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:ADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x1; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addflags(m32,Reg32);
|
|
m32 = m32 + Reg32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:ADD^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x1; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addflags(m64,Reg64);
|
|
m64 = m64 + Reg64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:AND^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=4 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 & imm8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:AND^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=4 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 & imm16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:AND^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=4 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 & imm32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:AND^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=4 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 & simm32;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:AND^lockx m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=4 ...; usimm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 & usimm8_16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:AND^lockx m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=4 ...; usimm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 & usimm8_32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:AND^lockx m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=4 ...; usimm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 & usimm8_64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:AND^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x20; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 & Reg8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:AND^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x21; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 & Reg16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:AND^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x21; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 & Reg32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:AND^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x21; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 & Reg64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTC^lockx Mem,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xbb; Mem & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
|
|
:BTC^lockx Mem,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xbb; Mem & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
@ifdef IA64
|
|
local ptr = Mem + (sext(Reg32) s>> 3);
|
|
@else
|
|
local ptr = Mem + (Reg32 s>> 3);
|
|
@endif
|
|
local bit=Reg32&7;
|
|
local val = (*:1 ptr >> bit) & 1;
|
|
*:1 ptr = *:1 ptr ^ (1<<bit);
|
|
CF = (val != 0);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTC^lockx Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xbb; Mem & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTC^lockx m16,imm8 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xba; m16 & reg_opcode=7 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
local bit=imm8&0xf;
|
|
local val=(m16>>bit)&1;
|
|
m16=m16^(1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
|
|
:BTC^lockx m32,imm8 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xba; m32 & reg_opcode=7 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
local bit=imm8&0x1f;
|
|
local val=(m32>>bit)&1;
|
|
CF=(val!=0);
|
|
m32=m32^(1<<bit);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTC^lockx m64,imm8 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xba; m64 & reg_opcode=7 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
local bit=imm8&0x3f;
|
|
local val=(m64>>bit)&1;
|
|
m64=m64^(1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTR^lockx Mem,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xb3; Mem & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
|
|
:BTR^lockx Mem,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xb3; Mem & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
@ifdef IA64
|
|
local ptr = Mem + (sext(Reg32) s>> 3);
|
|
@else
|
|
local ptr = Mem + (Reg32 s>> 3);
|
|
@endif
|
|
local bit = Reg32 & 7;
|
|
local val = (*:1 ptr >> bit) & 1;
|
|
*:1 ptr = *:1 ptr & ~(1<<bit);
|
|
CF = (val!=0);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTR^lockx Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xb3; Mem & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTR^lockx m16,imm8 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xba; m16 & reg_opcode=6 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
local bit=imm8&0xf;
|
|
local val=(m16>>bit)&1;
|
|
m16=m16 & ~(1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
|
|
:BTR^lockx m32,imm8 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xba; m32 & reg_opcode=6 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
local bit=imm8&0x1f;
|
|
local val=(m32>>bit)&1;
|
|
CF=(val!=0);
|
|
m32=m32 & ~(1<<bit);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTR^lockx m64,imm8 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xba; m64 & reg_opcode=6 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
local bit=imm8&0x3f;
|
|
local val=(m64>>bit)&1;
|
|
m64=m64 & ~(1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTS^lockx Mem,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xab; Mem & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
|
|
:BTS^lockx Mem,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xab; Mem & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
@ifdef IA64
|
|
local ptr = Mem + (sext(Reg32) s>>3);
|
|
@else
|
|
local ptr = Mem + (Reg32 s>>3);
|
|
@endif
|
|
local bit = Reg32 & 7;
|
|
local val = (*:1 ptr >> bit) & 1;
|
|
*:1 ptr = *:1 ptr | (1<<bit);
|
|
CF = (val != 0);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTS^lockx Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xab; Mem & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build Mem;
|
|
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);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:BTS^lockx m16,imm8 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xba; m16 & reg_opcode=5 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
local bit=imm8&0xf;
|
|
local val=(m16>>bit)&1;
|
|
m16=m16 | (1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
|
|
:BTS^lockx m32,imm8 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xba; m32 & reg_opcode=5 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
local bit=imm8&0x1f;
|
|
local val=(m32>>bit)&1;
|
|
CF=(val!=0);
|
|
m32=m32 | (1<<bit);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:BTS^lockx m64,imm8 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xba; m64 & reg_opcode=5 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
local bit=imm8&0x3f;
|
|
local val=(m64>>bit)&1;
|
|
m64=m64 | (1<<bit);
|
|
CF=(val!=0);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:CMPXCHG^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0xf; byte=0xb0; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
local dest = m8;
|
|
subflags(AL,dest);
|
|
local diff = AL-dest;
|
|
resultflags(diff);
|
|
if (ZF) goto <equal>;
|
|
AL = dest;
|
|
goto <inst_end>;
|
|
<equal>
|
|
m8 = Reg8;
|
|
<inst_end>
|
|
build unlock;
|
|
}
|
|
|
|
:CMPXCHG^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf; byte=0xb1; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
local dest = m16;
|
|
subflags(AX,dest);
|
|
local diff = AX-dest;
|
|
resultflags(diff);
|
|
if (ZF) goto <equal>;
|
|
AX = dest;
|
|
goto <inst_end>;
|
|
<equal>
|
|
m16 = Reg16;
|
|
<inst_end>
|
|
build unlock;
|
|
}
|
|
|
|
:CMPXCHG^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf; byte=0xb1; m32 & Reg32 ... & check_EAX_dest ...
|
|
{
|
|
build lockx;
|
|
#this instruction writes to either EAX or Rmr32
|
|
#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
|
|
local dest = m32;
|
|
subflags(EAX,dest);
|
|
local diff = EAX-dest;
|
|
resultflags(diff);
|
|
if (ZF) goto <equal>;
|
|
EAX = dest;
|
|
build check_EAX_dest;
|
|
goto <inst_end>;
|
|
<equal>
|
|
m32 = Reg32;
|
|
<inst_end>
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:CMPXCHG^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xb1; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
local dest = m64;
|
|
subflags(RAX,dest);
|
|
local diff = RAX-dest;
|
|
resultflags(diff);
|
|
if (ZF) goto <equal>;
|
|
RAX = dest;
|
|
goto <inst_end>;
|
|
<equal>
|
|
m64 = Reg64;
|
|
<inst_end>
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:CMPXCHG8B^lockx m64 is vexMode=0 & lockx & unlock & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 ) ... & m64
|
|
{
|
|
build lockx;
|
|
local dest = m64;
|
|
ZF = ((zext(EDX) << 32) | zext(EAX)) == dest;
|
|
if (ZF == 1) goto <equal>;
|
|
EDX = dest(4);
|
|
EAX = dest:4;
|
|
goto <done>;
|
|
<equal>
|
|
m64 = (zext(ECX) << 32) | zext(EBX);
|
|
<done>
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:CMPXCHG16B^lockx m128 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf; byte=0xc7; ( mod != 0b11 & reg_opcode=1 ) ... & ( m128 ) {
|
|
build lockx;
|
|
local dest = m128;
|
|
ZF = ((zext(RDX) << 64) | zext(RAX)) == dest;
|
|
if (ZF == 1) goto <equal>;
|
|
RDX = dest(8);
|
|
RAX = dest:8;
|
|
goto <done>;
|
|
<equal>
|
|
m128 = ((zext(RCX) << 64) | zext(RBX));
|
|
<done>
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:DEC^lockx m8 is vexMode=0 & lockx & unlock & byte=0xfe; m8 & reg_opcode=1 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
OF = sborrow(m8,1);
|
|
m8 = m8 - 1;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:DEC^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xff; m16 & reg_opcode=1 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
OF = sborrow(m16,1);
|
|
m16 = m16 - 1;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:DEC^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xff; m32 & reg_opcode=1 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
OF = sborrow(m32,1);
|
|
m32 = m32 - 1;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:DEC^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xff; m64 & reg_opcode=1 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
OF = sborrow(m64,1);
|
|
m64 = m64 - 1;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:INC^lockx m8 is vexMode=0 & lockx & unlock & byte=0xfe; m8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
OF = scarry(m8,1);
|
|
m8 = m8 + 1;
|
|
resultflags( m8);
|
|
build unlock;
|
|
}
|
|
|
|
:INC^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xff; m16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
OF = scarry(m16,1);
|
|
m16 = m16 + 1;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:INC^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xff; m32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
OF = scarry(m32,1);
|
|
m32 = m32 + 1;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:INC^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xff; m64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
OF = scarry(m64,1);
|
|
m64 = m64 + 1;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:NEG^lockx m8 is vexMode=0 & lockx & unlock & byte=0xf6; m8 & reg_opcode=3 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
negflags(m8);
|
|
m8 = -m8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:NEG^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf7; m16 & reg_opcode=3 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
negflags(m16);
|
|
m16 = -m16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:NEG^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf7; m32 & reg_opcode=3 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
negflags(m32);
|
|
m32 = -m32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:NEG^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf7; m64 & reg_opcode=3 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
negflags(m64);
|
|
m64 = -m64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:NOT^lockx m8 is vexMode=0 & lockx & unlock & byte=0xf6; m8 & reg_opcode=2 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
m8 = ~m8;
|
|
build unlock;
|
|
}
|
|
|
|
:NOT^lockx m16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0xf7; m16 & reg_opcode=2 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
m16 = ~m16;
|
|
build unlock;
|
|
}
|
|
|
|
:NOT^lockx m32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0xf7; m32 & reg_opcode=2 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
m32 = ~m32;
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:NOT^lockx m64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0xf7; m64 & reg_opcode=2 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
m64 = ~m64;
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:OR^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=1 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 | imm8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:OR^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=1 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 | imm16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:OR^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=1 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 | imm32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:OR^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=1 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
tmp:8 = m64;
|
|
m64 = tmp | simm32;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:OR^lockx m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=1 ...; usimm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 | usimm8_16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:OR^lockx m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=1 ...; usimm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 | usimm8_32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:OR^lockx m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=1 ...; usimm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 | usimm8_64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:OR^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x8; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 | Reg8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:OR^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x9; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 | Reg16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:OR^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x9; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 | Reg32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:OR^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x9; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 | Reg64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SBB^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=3 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
subCarryFlags(m8, imm8);
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:SBB^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=3 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subCarryFlags(m16, imm16);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SBB^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=3 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subCarryFlags(m32, imm32);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SBB^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=3 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subCarryFlags(m64, simm32);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SBB^lockx m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=3 ...; simm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subCarryFlags(m16, simm8_16);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SBB^lockx m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=3 ...; simm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subCarryFlags(m32, simm8_32);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SBB^lockx m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=3 ...; simm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subCarryFlags(m64, simm8_64);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SBB^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x18; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
subCarryFlags(m8, Reg8);
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:SBB^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x19; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subCarryFlags(m16, Reg16);
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SBB^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x19; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subCarryFlags(m32, Reg32);
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SBB^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x19; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subCarryFlags(m64, Reg64);
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SUB^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=5 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
subflags(m8,imm8);
|
|
m8 = m8 - imm8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:SUB^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=5 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subflags(m16,imm16);
|
|
m16 = m16 - imm16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SUB^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=5 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subflags(m32,imm32);
|
|
m32 = m32 - imm32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SUB^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=5 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subflags(m64,simm32);
|
|
m64 = m64 - simm32;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SUB^lockx m16,simm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=5 ...; simm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subflags(m16,simm8_16);
|
|
m16 = m16 - simm8_16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SUB^lockx m32,simm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=5 ...; simm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subflags(m32,simm8_32);
|
|
m32 = m32 - simm8_32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SUB^lockx m64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=5 ...; simm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subflags(m64,simm8_64);
|
|
m64 = m64 - simm8_64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:SUB^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x28; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
subflags(m8,Reg8);
|
|
m8 = m8 - Reg8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:SUB^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x29; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
subflags(m16,Reg16);
|
|
m16 = m16 - Reg16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:SUB^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x29; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
subflags(m32,Reg32);
|
|
m32 = m32 - Reg32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:SUB^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x29; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
subflags(m64,Reg64);
|
|
m64 = m64 - Reg64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:XADD^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x0F; byte=0xC0; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
addflags( m8,Reg8);
|
|
local tmp = m8 + Reg8;
|
|
Reg8 = m8;
|
|
m8 = tmp;
|
|
resultflags(tmp);
|
|
build unlock;
|
|
}
|
|
|
|
:XADD^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x0F; byte=0xC1; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
addflags(m16,Reg16);
|
|
local tmp = m16 + Reg16;
|
|
Reg16 = m16;
|
|
m16 = tmp;
|
|
resultflags(tmp);
|
|
build unlock;
|
|
}
|
|
|
|
:XADD^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x0F; byte=0xC1; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
addflags(m32,Reg32);
|
|
local tmp = m32 + Reg32;
|
|
Reg32 = m32;
|
|
m32 = tmp;
|
|
resultflags(tmp);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:XADD^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x0F; byte=0xC1; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
addflags(m64,Reg64);
|
|
local tmp = m64 + Reg64;
|
|
Reg64 = m64;
|
|
m64 = tmp;
|
|
resultflags(tmp);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
# XCHG with memory operands always asserts a lock signal regardless of prefix presence
|
|
:XCHG^xacq_xrel_prefx^alwaysLock m8,Reg8 is vexMode=0 & xacq_xrel_prefx & alwaysLock & byte=0x86; m8 & Reg8 ...
|
|
{
|
|
build xacq_xrel_prefx;
|
|
build alwaysLock;
|
|
build m8;
|
|
local tmp = m8;
|
|
m8 = Reg8;
|
|
Reg8 = tmp;
|
|
UNLOCK();
|
|
}
|
|
|
|
:XCHG^xacq_xrel_prefx^alwaysLock m16,Reg16 is vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=0 & byte=0x87; m16 & Reg16 ...
|
|
{
|
|
build xacq_xrel_prefx;
|
|
build alwaysLock;
|
|
build m16;
|
|
local tmp = m16;
|
|
m16 = Reg16;
|
|
Reg16 = tmp;
|
|
UNLOCK();
|
|
}
|
|
|
|
:XCHG^xacq_xrel_prefx^alwaysLock m32,Reg32 is vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=1 & byte=0x87; m32 & Reg32 ...
|
|
{
|
|
build xacq_xrel_prefx;
|
|
build alwaysLock;
|
|
build m32;
|
|
local tmp = m32;
|
|
m32 = Reg32;
|
|
Reg32 = tmp;
|
|
UNLOCK();
|
|
}
|
|
|
|
@ifdef IA64
|
|
:XCHG^xacq_xrel_prefx^alwaysLock m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & xacq_xrel_prefx & alwaysLock & opsize=2 & byte=0x87; m64 & Reg64 ...
|
|
{
|
|
build xacq_xrel_prefx;
|
|
build alwaysLock;
|
|
build m64;
|
|
local tmp = m64;
|
|
m64 = Reg64;
|
|
Reg64 = tmp;
|
|
UNLOCK();
|
|
}
|
|
@endif
|
|
|
|
:XOR^lockx m8,imm8 is vexMode=0 & lockx & unlock & $(BYTE_80_82); m8 & reg_opcode=6 ...; imm8
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 ^ imm8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:XOR^lockx m16,imm16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x81; m16 & reg_opcode=6 ...; imm16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 ^ imm16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:XOR^lockx m32,imm32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x81; m32 & reg_opcode=6 ...; imm32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 ^ imm32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:XOR^lockx m64,simm32 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x81; m64 & reg_opcode=6 ...; simm32
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 ^ simm32;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:XOR^lockx m16,usimm8_16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x83; m16 & reg_opcode=6 ...; usimm8_16
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 ^ usimm8_16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:XOR^lockx m32,usimm8_32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x83; m32 & reg_opcode=6 ...; usimm8_32
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 ^ usimm8_32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:XOR^lockx m64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x83; m64 & reg_opcode=6 ...; usimm8_64
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 ^ usimm8_64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|
|
|
|
:XOR^lockx m8,Reg8 is vexMode=0 & lockx & unlock & byte=0x30; m8 & Reg8 ...
|
|
{
|
|
build lockx;
|
|
build m8;
|
|
logicalflags();
|
|
m8 = m8 ^ Reg8;
|
|
resultflags(m8);
|
|
build unlock;
|
|
}
|
|
|
|
:XOR^lockx m16,Reg16 is vexMode=0 & lockx & unlock & opsize=0 & byte=0x31; m16 & Reg16 ...
|
|
{
|
|
build lockx;
|
|
build m16;
|
|
logicalflags();
|
|
m16 = m16 ^ Reg16;
|
|
resultflags(m16);
|
|
build unlock;
|
|
}
|
|
|
|
:XOR^lockx m32,Reg32 is vexMode=0 & lockx & unlock & opsize=1 & byte=0x31; m32 & Reg32 ...
|
|
{
|
|
build lockx;
|
|
build m32;
|
|
logicalflags();
|
|
m32 = m32 ^ Reg32;
|
|
resultflags(m32);
|
|
build unlock;
|
|
}
|
|
|
|
@ifdef IA64
|
|
:XOR^lockx m64,Reg64 is $(LONGMODE_ON) & vexMode=0 & lockx & unlock & opsize=2 & byte=0x31; m64 & Reg64 ...
|
|
{
|
|
build lockx;
|
|
build m64;
|
|
logicalflags();
|
|
m64 = m64 ^ Reg64;
|
|
resultflags(m64);
|
|
build unlock;
|
|
}
|
|
@endif
|