Add some ISA predicates for Intel CPUID features.

Guard the popcnt instruction on the proper CPUID bits.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-12 16:05:20 -07:00
parent 435a15b88d
commit 5cbcd59cf0
5 changed files with 41 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
; binary emission of 32-bit code. ; binary emission of 32-bit code.
test binemit test binemit
isa intel isa intel has_sse42 has_popcnt
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -1,7 +1,7 @@
; binary emission of 64-bit code. ; binary emission of 64-bit code.
test binemit test binemit
set is_64bit set is_64bit
isa intel isa intel has_sse42 has_popcnt
; The binary encodings can be verified with the command: ; The binary encodings can be verified with the command:
; ;

View File

@@ -2,10 +2,10 @@
test compile test compile
set is_64bit=0 set is_64bit=0
isa intel isa intel has_sse42 has_popcnt
set is_64bit=1 set is_64bit=1
isa intel isa intel has_sse42 has_popcnt
; Constants. ; Constants.

View File

@@ -7,6 +7,7 @@ from base import instructions as base
from base.formats import UnaryImm from base.formats import UnaryImm
from .defs import I32, I64 from .defs import I32, I64
from . import recipes as r from . import recipes as r
from . import settings as cfg
for inst, opc in [ for inst, opc in [
(base.iadd, 0x01), (base.iadd, 0x01),
@@ -81,10 +82,11 @@ for inst, rrr in [
I64.enc(inst.i32.i32, *r.rc(0xd3, rrr=rrr)) I64.enc(inst.i32.i32, *r.rc(0xd3, rrr=rrr))
# Population count. # Population count.
I32.enc(base.popcnt.i32, *r.urm(0xf3, 0x0f, 0xb8)) I32.enc(base.popcnt.i32, *r.urm(0xf3, 0x0f, 0xb8), isap=cfg.use_popcnt)
I64.enc(base.popcnt.i64, *r.urm.rex(0xf3, 0x0f, 0xb8, w=1)) I64.enc(base.popcnt.i64, *r.urm.rex(0xf3, 0x0f, 0xb8, w=1),
I64.enc(base.popcnt.i32, *r.urm.rex(0xf3, 0x0f, 0xb8)) isap=cfg.use_popcnt)
I64.enc(base.popcnt.i32, *r.urm(0xf3, 0x0f, 0xb8)) I64.enc(base.popcnt.i32, *r.urm.rex(0xf3, 0x0f, 0xb8), isap=cfg.use_popcnt)
I64.enc(base.popcnt.i32, *r.urm(0xf3, 0x0f, 0xb8), isap=cfg.use_popcnt)
# Loads and stores. # Loads and stores.
I32.enc(base.store.i32.i32, *r.st(0x89)) I32.enc(base.store.i32.i32, *r.st(0x89))

View File

@@ -2,10 +2,40 @@
Intel settings. Intel settings.
""" """
from __future__ import absolute_import from __future__ import absolute_import
from cdsl.settings import SettingGroup from cdsl.settings import SettingGroup, BoolSetting
from cdsl.predicates import And
import base.settings as shared import base.settings as shared
from .defs import ISA from .defs import ISA
ISA.settings = SettingGroup('intel', parent=shared.group) ISA.settings = SettingGroup('intel', parent=shared.group)
# The has_* settings here correspond to CPUID bits.
# CPUID.01H:EDX
has_sse2 = BoolSetting("SSE2: CPUID.01H:EDX.SSE2[bit 26]")
# CPUID.01H:ECX
has_sse3 = BoolSetting("SSE3: CPUID.01H:ECX.SSE3[bit 0]")
has_ssse3 = BoolSetting("SSSE3: CPUID.01H:ECX.SSSE3[bit 9]")
has_sse41 = BoolSetting("SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]")
has_sse42 = BoolSetting("SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]")
has_popcnt = BoolSetting("POPCNT: CPUID.01H:ECX.POPCNT[bit 23]")
has_avx = BoolSetting("AVX: CPUID.01H:ECX.AVX[bit 28]")
# CPUID.(EAX=07H, ECX=0H):EBX
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)
ISA.settings.close(globals()) ISA.settings.close(globals())