Пример #1
0
has_bmi1 = BoolSetting("BMI1: CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]")
has_bmi2 = BoolSetting("BMI2: CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]")

# CPUID.EAX=80000001H:ECX
has_lzcnt = BoolSetting("LZCNT: CPUID.EAX=80000001H:ECX.LZCNT[bit 5]")

# The use_* settings here are used to determine if a feature can be used.

use_sse41 = And(has_sse41)
use_sse42 = And(has_sse42, use_sse41)
use_popcnt = And(has_popcnt, has_sse42)
use_bmi1 = And(has_bmi1)
use_lzcnt = And(has_lzcnt)

is_pic = And(shared.is_pic)
not_is_pic = Not(shared.is_pic)
all_ones_funcaddrs_and_not_is_pic = And(shared.allones_funcaddrs,
                                        Not(shared.is_pic))
not_all_ones_funcaddrs_and_not_is_pic = And(Not(shared.allones_funcaddrs),
                                            Not(shared.is_pic))

# Presets corresponding to x86 CPUs.

baseline = Preset()

nehalem = Preset(has_sse3, has_ssse3, has_sse41, has_sse42, has_popcnt)
haswell = Preset(nehalem, has_bmi1, has_bmi2, has_lzcnt)
broadwell = Preset(haswell)
skylake = Preset(broadwell)
cannonlake = Preset(skylake)
icelake = Preset(cannonlake)
Пример #2
0
enc_both(base.fill.f64, r.ffillSib32, 0xf2, 0x0f, 0x10)
enc_both(base.regfill.f64, r.fregfill32, 0xf2, 0x0f, 0x10)

enc_both(base.spill.f32, r.fspillSib32, 0xf3, 0x0f, 0x11)
enc_both(base.regspill.f32, r.fregspill32, 0xf3, 0x0f, 0x11)
enc_both(base.spill.f64, r.fspillSib32, 0xf2, 0x0f, 0x11)
enc_both(base.regspill.f64, r.fregspill32, 0xf2, 0x0f, 0x11)

#
# Function addresses.
#

# Non-PIC, all-ones funcaddresses.
X86_32.enc(base.func_addr.i32,
           *r.fnaddr4(0xb8),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))
X86_64.enc(base.func_addr.i64,
           *r.fnaddr8.rex(0xb8, w=1),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))

# Non-PIC, all-zeros funcaddresses.
X86_32.enc(base.func_addr.i32,
           *r.allones_fnaddr4(0xb8),
           isap=And(allones_funcaddrs, Not(is_pic)))
X86_64.enc(base.func_addr.i64,
           *r.allones_fnaddr8.rex(0xb8, w=1),
           isap=And(allones_funcaddrs, Not(is_pic)))

# 64-bit, colocated, both PIC and non-PIC. Use the lea instruction's
# pc-relative field.
X86_64.enc(base.func_addr.i64,
Пример #3
0
enc_both(base.fill.f64, r.ffillSib32, 0xf2, 0x0f, 0x10)
enc_both(base.regfill.f64, r.fregfill32, 0xf2, 0x0f, 0x10)

enc_both(base.spill.f32, r.fspillSib32, 0xf3, 0x0f, 0x11)
enc_both(base.regspill.f32, r.fregspill32, 0xf3, 0x0f, 0x11)
enc_both(base.spill.f64, r.fspillSib32, 0xf2, 0x0f, 0x11)
enc_both(base.regspill.f64, r.fregspill32, 0xf2, 0x0f, 0x11)

#
# Function addresses.
#

# Non-PIC, all-ones funcaddresses.
X86_32.enc(base.func_addr.i32,
           *r.fnaddr4(0xb8),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))
X86_64.enc(base.func_addr.i64,
           *r.fnaddr8.rex(0xb8, w=1),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))

# Non-PIC, all-zeros funcaddresses.
X86_32.enc(base.func_addr.i32,
           *r.allones_fnaddr4(0xb8),
           isap=And(allones_funcaddrs, Not(is_pic)))
X86_64.enc(base.func_addr.i64,
           *r.allones_fnaddr8.rex(0xb8, w=1),
           isap=And(allones_funcaddrs, Not(is_pic)))

# 64-bit, colocated, both PIC and non-PIC. Use the lea instruction's
# pc-relative field.
X86_64.enc(base.func_addr.i64,
Пример #4
0
enc_both(base.fill.f32, r.ffillSib32, 0x66, 0x0f, 0x6e)
enc_both(base.regfill.f32, r.fregfill32, 0x66, 0x0f, 0x6e)
enc_both(base.fill.f64, r.ffillSib32, 0xf3, 0x0f, 0x7e)
enc_both(base.regfill.f64, r.fregfill32, 0xf3, 0x0f, 0x7e)

enc_both(base.spill.f32, r.fspillSib32, 0x66, 0x0f, 0x7e)
enc_both(base.regspill.f32, r.fregspill32, 0x66, 0x0f, 0x7e)
enc_both(base.spill.f64, r.fspillSib32, 0x66, 0x0f, 0xd6)
enc_both(base.regspill.f64, r.fregspill32, 0x66, 0x0f, 0xd6)

#
# Function addresses.
#

X86_32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), isap=Not(allones_funcaddrs))
X86_64.enc(base.func_addr.i64,
           *r.fnaddr8.rex(0xb8, w=1),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))

X86_32.enc(base.func_addr.i32,
           *r.allones_fnaddr4(0xb8),
           isap=allones_funcaddrs)
X86_64.enc(base.func_addr.i64,
           *r.allones_fnaddr8.rex(0xb8, w=1),
           isap=And(allones_funcaddrs, Not(is_pic)))

X86_64.enc(base.func_addr.i64, *r.got_fnaddr8.rex(0x8b, w=1), isap=is_pic)

#
# Global addresses.
Пример #5
0
enc_both(base.fill.f32, r.ffiSib32, 0x66, 0x0f, 0x6e)
enc_both(base.regfill.f32, r.frfi32, 0x66, 0x0f, 0x6e)
enc_both(base.fill.f64, r.ffiSib32, 0xf3, 0x0f, 0x7e)
enc_both(base.regfill.f64, r.frfi32, 0xf3, 0x0f, 0x7e)

enc_both(base.spill.f32, r.fspSib32, 0x66, 0x0f, 0x7e)
enc_both(base.regspill.f32, r.frsp32, 0x66, 0x0f, 0x7e)
enc_both(base.spill.f64, r.fspSib32, 0x66, 0x0f, 0xd6)
enc_both(base.regspill.f64, r.frsp32, 0x66, 0x0f, 0xd6)

#
# Function addresses.
#

I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), isap=Not(allones_funcaddrs))
I64.enc(base.func_addr.i64,
        *r.fnaddr8.rex(0xb8, w=1),
        isap=And(Not(allones_funcaddrs), Not(is_pic)))

I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8), isap=allones_funcaddrs)
I64.enc(base.func_addr.i64,
        *r.allones_fnaddr8.rex(0xb8, w=1),
        isap=And(allones_funcaddrs, Not(is_pic)))

I64.enc(base.func_addr.i64, *r.got_fnaddr8.rex(0x8b, w=1), isap=is_pic)

#
# Global addresses.
#
enc_both(base.regfill.f32, r.fregfill32, 0xf3, 0x0f, 0x10)
enc_both(base.fill.f64, r.ffillSib32, 0xf2, 0x0f, 0x10)
enc_both(base.regfill.f64, r.fregfill32, 0xf2, 0x0f, 0x10)

enc_both(base.spill.f32, r.fspillSib32, 0xf3, 0x0f, 0x11)
enc_both(base.regspill.f32, r.fregspill32, 0xf3, 0x0f, 0x11)
enc_both(base.spill.f64, r.fspillSib32, 0xf2, 0x0f, 0x11)
enc_both(base.regspill.f64, r.fregspill32, 0xf2, 0x0f, 0x11)

#
# Function addresses.
#

# Non-PIC, all-ones funcaddresses.
X86_32.enc(base.func_addr.i32, *r.fnaddr4(0xb8),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))
X86_64.enc(base.func_addr.i64, *r.fnaddr8.rex(0xb8, w=1),
           isap=And(Not(allones_funcaddrs), Not(is_pic)))

# Non-PIC, all-zeros funcaddresses.
X86_32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8),
           isap=And(allones_funcaddrs, Not(is_pic)))
X86_64.enc(base.func_addr.i64, *r.allones_fnaddr8.rex(0xb8, w=1),
           isap=And(allones_funcaddrs, Not(is_pic)))

# 64-bit, colocated, both PIC and non-PIC. Use the lea instruction's
# pc-relative field.
X86_64.enc(base.func_addr.i64, *r.pcrel_fnaddr8.rex(0x8d, w=1),
           instp=IsColocatedFunc(FuncAddr.func_ref))

# 64-bit, non-colocated, PIC.
Пример #7
0
enc_both(base.fill.f32, r.ffiSib32, 0x66, 0x0f, 0x6e)
enc_both(base.regfill.f32, r.frfi32, 0x66, 0x0f, 0x6e)
enc_both(base.fill.f64, r.ffiSib32, 0xf3, 0x0f, 0x7e)
enc_both(base.regfill.f64, r.frfi32, 0xf3, 0x0f, 0x7e)

enc_both(base.spill.f32, r.fspSib32, 0x66, 0x0f, 0x7e)
enc_both(base.regspill.f32, r.frsp32, 0x66, 0x0f, 0x7e)
enc_both(base.spill.f64, r.fspSib32, 0x66, 0x0f, 0xd6)
enc_both(base.regspill.f64, r.frsp32, 0x66, 0x0f, 0xd6)

#
# Function addresses.
#

I32.enc(base.func_addr.i32, *r.fnaddr4(0xb8), isap=Not(allones_funcaddrs))
I64.enc(base.func_addr.i64,
        *r.fnaddr8.rex(0xb8, w=1),
        isap=Not(allones_funcaddrs))

I32.enc(base.func_addr.i32, *r.allones_fnaddr4(0xb8), isap=allones_funcaddrs)
I64.enc(base.func_addr.i64,
        *r.allones_fnaddr8.rex(0xb8, w=1),
        isap=allones_funcaddrs)

#
# Global addresses.
#

I32.enc(base.globalsym_addr.i32, *r.gvaddr4(0xb8))
I64.enc(base.globalsym_addr.i64, *r.gvaddr8.rex(0xb8, w=1))