1 2XEN_ROOT ?= $(CURDIR)/../../.. 3include $(XEN_ROOT)/tools/Rules.mk 4 5TARGET := test_x86_emulator 6 7.PHONY: all 8all: 9 10.PHONY: run 11run: $(TARGET) 12 ./$(TARGET) 13 14# Add libx86 to the build 15vpath %.c $(XEN_ROOT)/xen/lib/x86 16 17CFLAGS += $(CFLAGS_xeninclude) 18 19SIMD := 3dnow sse sse2 sse4 avx avx2 xop avx512f avx512bw avx512dq avx512er avx512vbmi 20FMA := fma4 fma 21SG := avx2-sg avx512f-sg avx512vl-sg 22AES := ssse3-aes avx-aes avx2-vaes avx512bw-vaes 23CLMUL := ssse3-pclmul avx-pclmul avx2-vpclmulqdq avx512bw-vpclmulqdq avx512vbmi2-vpclmulqdq 24SHA := sse4-sha avx-sha avx512f-sha 25GF := sse2-gf avx2-gf avx512bw-gf 26TESTCASES := blowfish $(SIMD) $(FMA) $(SG) $(AES) $(CLMUL) $(SHA) $(GF) 27 28OPMASK := avx512f avx512dq avx512bw 29 30ifeq ($(origin XEN_COMPILE_ARCH),override) 31 32HOSTCFLAGS += -m32 33 34else 35 36blowfish-cflags := "" 37blowfish-cflags-x86_32 := "-mno-accumulate-outgoing-args -Dstatic=" 38 393dnow-vecs := 8 403dnow-ints := 413dnow-flts := 4 42sse-vecs := 16 43sse-ints := 44sse-flts := 4 45sse2-vecs := $(sse-vecs) 46sse2-ints := 1 2 4 8 47sse2-flts := 4 8 48sse4-vecs := $(sse2-vecs) 49sse4-ints := $(sse2-ints) 50sse4-flts := $(sse2-flts) 51avx-vecs := 16 32 52avx-ints := 53avx-flts := 4 8 54fma4-vecs := $(avx-vecs) 55fma4-ints := 56fma4-flts := $(avx-flts) 57fma-vecs := $(avx-vecs) 58fma-ints := 59fma-flts := $(avx-flts) 60avx2-vecs := $(avx-vecs) 61avx2-ints := 1 2 4 8 62avx2-flts := 4 8 63avx2-sg-vecs := $(avx2-vecs) 64avx2-sg-idxs := 4 8 65avx2-sg-ints := 4 8 66avx2-sg-flts := 4 8 67xop-vecs := $(avx-vecs) 68xop-ints := 1 2 4 8 69xop-flts := $(avx-flts) 70avx512f-vecs := 64 16 32 71avx512f-ints := 4 8 72avx512f-flts := 4 8 73avx512f-sg-vecs := 64 74avx512f-sg-idxs := 4 8 75avx512f-sg-ints := $(avx512f-ints) 76avx512f-sg-flts := $(avx512f-flts) 77avx512vl-sg-vecs := 16 32 78avx512vl-sg-idxs := $(avx512f-sg-idxs) 79avx512vl-sg-ints := $(avx512f-ints) 80avx512vl-sg-flts := $(avx512f-flts) 81avx512bw-vecs := $(avx512f-vecs) 82avx512bw-ints := 1 2 83avx512bw-flts := 84avx512dq-vecs := $(avx512f-vecs) 85avx512dq-ints := $(avx512f-ints) 86avx512dq-flts := $(avx512f-flts) 87avx512er-vecs := 64 88avx512er-ints := 89avx512er-flts := 4 8 90avx512vbmi-vecs := $(avx512bw-vecs) 91avx512vbmi-ints := $(avx512bw-ints) 92avx512vbmi-flts := $(avx512bw-flts) 93avx512vbmi2-vecs := $(avx512bw-vecs) 94 95avx512f-opmask-vecs := 2 96avx512dq-opmask-vecs := 1 2 97avx512bw-opmask-vecs := 4 8 98 99# Suppress building by default of the harness if the compiler can't deal 100# with some of the extensions used. Don't alter the "run" target dependencies 101# though, as this target needs to be specified manually, and things may work 102# partially even with older compilers. 103TARGET-y := $(TARGET) 104 105ifeq ($(filter run%,$(MAKECMDGOALS)),) 106 107define simd-check-cc 108TARGET-$(shell echo 'int i;' | $(CC) -x c -c -o /dev/null -m$(1) - || echo y) := 109endef 110 111$(foreach flavor,$(SIMD) $(FMA),$(eval $(call simd-check-cc,$(flavor)))) 112 113# Also explicitly check for {evex} pseudo-prefix support, which got introduced 114# only after AVX512F and some of its extensions. 115TARGET-$(shell echo 'asm("{evex} vmovaps %xmm0$(comma)%xmm0");' | $(CC) -x c -c -o /dev/null - || echo y) := 116 117ifeq ($(TARGET-y),) 118$(warning Test harness not built, use newer compiler than "$(CC)" (version $(shell $(CC) -dumpversion)) and an "{evex}" capable assembler) 119endif 120 121endif 122 123all: $(TARGET-y) 124 125# For AVX and later, have the compiler avoid XMM0 to widen coverage of 126# the VEX.vvvv checks in the emulator. For 3DNow!, however, force SSE 127# use for floating point operations, to avoid mixing MMX and FPU register 128# uses. Also enable 3DNow! extensions, but note that we can't use 3dnowa 129# as the test flavor right away since -m3dnowa is being understood only 130# by gcc 7.x and newer (older ones want a specific machine model instead). 1313dnowa := $(call cc-option,$(CC),-m3dnowa,-march=k8) 132non-sse = $(if $(filter sse%,$(1)),,$(if $(filter 3dnow%,$(1)),-msse -mfpmath=sse $(3dnowa),-ffixed-xmm0)) 133 134define simd-defs 135$(1)-cflags := \ 136 $(foreach vec,$($(1)-vecs), \ 137 $(foreach int,$($(1)-ints), \ 138 "-D_$(vec)i$(int) -m$(1) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec) -DINT_SIZE=$(int)" \ 139 "-D_$(vec)u$(int) -m$(1) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec) -DUINT_SIZE=$(int)") \ 140 $(foreach flt,$($(1)-flts), \ 141 "-D_$(vec)f$(flt) -m$(1) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec) -DFLOAT_SIZE=$(flt)")) \ 142 $(foreach flt,$($(1)-flts), \ 143 "-D_f$(flt) -m$(1) $(call non-sse,$(1)) -mfpmath=sse -Os -DFLOAT_SIZE=$(flt)") 144endef 145define simd-sg-defs 146$(1)-cflags := \ 147 $(foreach vec,$($(1)-vecs), \ 148 $(foreach idx,$($(1)-idxs), \ 149 $(foreach int,$($(1)-ints), \ 150 "-D_$(vec)x$(idx)i$(int) -m$(1:-sg=) $(call non-sse,$(1)) -Os -DVEC_MAX=$(vec) -DIDX_SIZE=$(idx) -DINT_SIZE=$(int)") \ 151 $(foreach flt,$($(1)-flts), \ 152 "-D_$(vec)x$(idx)f$(flt) -m$(1:-sg=) $(call non-sse,$(1)) -Os -DVEC_MAX=$(vec) -DIDX_SIZE=$(idx) -DFLOAT_SIZE=$(flt)"))) 153endef 154define simd-aes-defs 155$(1)-cflags := $(foreach vec,$($(patsubst %-aes,sse,$(1))-vecs) $($(patsubst %-vaes,%,$(1))-vecs), \ 156 "-D_$(vec) -maes $(addprefix -m,$(subst -,$(space),$(1))) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec)") 157endef 158define simd-clmul-defs 159$(1)-cflags := $(foreach vec,$($(patsubst %-pclmul,sse,$(1))-vecs) $($(patsubst %-vpclmulqdq,%,$(1))-vecs), \ 160 "-D_$(vec) -mpclmul $(addprefix -m,$(subst -,$(space),$(1))) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec)") 161endef 162define simd-sha-defs 163$(1)-cflags := $(foreach vec,$(sse-vecs), \ 164 "-D_$(vec) $(addprefix -m,$(subst -,$(space),$(1))) -Os -DVEC_SIZE=$(vec)") 165endef 166define simd-gf-defs 167$(1)-cflags := $(foreach vec,$($(1:-gf=)-vecs), \ 168 "-D_$(vec) -mgfni -m$(1:-gf=) $(call non-sse,$(1)) -Os -DVEC_SIZE=$(vec)") 169endef 170define opmask-defs 171$(1)-opmask-cflags := $(foreach vec,$($(1)-opmask-vecs), "-D_$(vec) -m$(1) -Os -DSIZE=$(vec)") 172endef 173 174$(foreach flavor,$(SIMD) $(FMA),$(eval $(call simd-defs,$(flavor)))) 175$(foreach flavor,$(SG),$(eval $(call simd-sg-defs,$(flavor)))) 176$(foreach flavor,$(AES),$(eval $(call simd-aes-defs,$(flavor)))) 177$(foreach flavor,$(CLMUL),$(eval $(call simd-clmul-defs,$(flavor)))) 178$(foreach flavor,$(SHA),$(eval $(call simd-sha-defs,$(flavor)))) 179$(foreach flavor,$(GF),$(eval $(call simd-gf-defs,$(flavor)))) 180$(foreach flavor,$(OPMASK),$(eval $(call opmask-defs,$(flavor)))) 181 182first-string = $(shell for s in $(1); do echo "$$s"; break; done) 183 184avx2-sg-cflags-x86_64 := "-D_high $(foreach n,7 6 5 4 3 2 1,-ffixed-ymm$(n)) $(call first-string,$(avx2-sg-cflags))" 185avx512f-sg-cflags-x86_64 := "-D_higher $(foreach n,7 6 5 4 3 2 1,-ffixed-zmm$(n)) $(call first-string,$(avx512f-sg-cflags))" 186avx512f-sg-cflags-x86_64 += "-D_highest $(foreach n,15 14 13 12 11 10 9 8,-ffixed-zmm$(n)) $(call first-string,$(avx512f-sg-cflags-x86_64))" 187 188$(addsuffix .h,$(TESTCASES)): %.h: %.c testcase.mk Makefile 189 rm -f $@.new $*.bin 190 $(foreach arch,$(filter-out $(XEN_COMPILE_ARCH),x86_32) $(XEN_COMPILE_ARCH), \ 191 for cflags in $($*-cflags) $($*-cflags-$(arch)); do \ 192 $(MAKE) -f testcase.mk TESTCASE=$* XEN_TARGET_ARCH=$(arch) $*-cflags="$$cflags" all; \ 193 prefix=$(shell echo $(subst -,_,$*) | sed -e 's,^\([0-9]\),_\1,'); \ 194 flavor=$$(echo $${cflags} | sed -e 's, .*,,' -e 'y,-=,__,') ; \ 195 (echo 'static const unsigned int __attribute__((section(".test, \"ax\", @progbits #")))' \ 196 "$${prefix}_$(arch)$${flavor}[] = {"; \ 197 od -v -t x $*.bin | sed -e 's/^[0-9]* /0x/' -e 's/ /, 0x/g' -e 's/$$/,/'; \ 198 echo "};"; \ 199 echo "asm(\".type $${prefix}_$(arch)$${flavor}, STT_NOTYPE;\");"; \ 200 echo "asm(\".type $${prefix}_$(arch)$${flavor}, STT_FUNC;\");"; \ 201 ) >>$@.new; \ 202 rm -f $*.bin; \ 203 done; \ 204 ) 205 mv $@.new $@ 206 207$(addsuffix -opmask.h,$(OPMASK)): %.h: opmask.S testcase.mk Makefile 208 rm -f $@.new $*.bin 209 $(foreach arch,$(filter-out $(XEN_COMPILE_ARCH),x86_32) $(XEN_COMPILE_ARCH), \ 210 for cflags in $($*-cflags) $($*-cflags-$(arch)); do \ 211 $(MAKE) -f testcase.mk TESTCASE=$* XEN_TARGET_ARCH=$(arch) $*-cflags="$$cflags" all; \ 212 prefix=$(shell echo $(subst -,_,$*) | sed -e 's,^\([0-9]\),_\1,'); \ 213 flavor=$$(echo $${cflags} | sed -e 's, .*,,' -e 'y,-=,__,') ; \ 214 (echo 'static const unsigned int __attribute__((section(".test, \"ax\", @progbits #")))' \ 215 "$${prefix}_$(arch)$${flavor}[] = {"; \ 216 od -v -t x $*.bin | sed -e 's/^[0-9]* /0x/' -e 's/ /, 0x/g' -e 's/$$/,/'; \ 217 echo "};"; \ 218 echo "asm(\".type $${prefix}_$(arch)$${flavor}, STT_NOTYPE;\");"; \ 219 echo "asm(\".type $${prefix}_$(arch)$${flavor}, STT_FUNC;\");"; \ 220 ) >>$@.new; \ 221 rm -f $*.bin; \ 222 done; \ 223 ) 224 mv $@.new $@ 225 226$(addsuffix .c,$(SIMD)): 227 ln -sf simd.c $@ 228 229$(addsuffix .c,$(FMA)): 230 ln -sf simd-fma.c $@ 231 232$(addsuffix .c,$(SG)): 233 ln -sf simd-sg.c $@ 234 235$(addsuffix .c,$(AES)): 236 ln -sf simd-aes.c $@ 237 238$(addsuffix .c,$(CLMUL)): 239 ln -sf simd-clmul.c $@ 240 241$(addsuffix .c,$(SHA)): 242 ln -sf simd-sha.c $@ 243 244$(addsuffix .c,$(GF)): 245 ln -sf simd-gf.c $@ 246 247$(addsuffix .h,$(SIMD) $(FMA) $(SG) $(AES) $(CLMUL) $(SHA) $(GF)): simd.h 248 249xop.h avx512f.h: simd-fma.c 250 251endif # 32-bit override 252 253$(TARGET): x86-emulate.o cpuid.o test_x86_emulator.o evex-disp8.o predicates.o wrappers.o 254 $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ 255 256.PHONY: clean 257clean: 258 rm -rf $(TARGET) *.o *~ core *.bin x86_emulate 259 rm -rf $(TARGET) $(addsuffix .h,$(TESTCASES)) $(addsuffix -opmask.h,$(OPMASK)) 260 261.PHONY: distclean 262distclean: clean 263 264.PHONY: install uninstall 265install uninstall: 266 267.PHONY: run32 clean32 268ifeq ($(XEN_COMPILE_ARCH),x86_64) 269run32: $(addsuffix .h,$(TESTCASES)) $(addsuffix -opmask.h,$(OPMASK)) 270run32 clean32: %32: 271 $(MAKE) -C 32 HOSTCC=$(HOSTCC) $* 272clean: clean32 273else 274run32 clean32: %32: % 275endif 276 277x86_emulate: 278 [ -L $@ ] || ln -sf $(XEN_ROOT)/xen/arch/x86/$@ 279 280x86_emulate/%: x86_emulate ; 281 282HOSTCFLAGS-x86_64 := -fno-PIE 283$(call cc-option-add,HOSTCFLAGS-x86_64,HOSTCC,-no-pie) 284HOSTCFLAGS += $(CFLAGS_xeninclude) -I. $(HOSTCFLAGS-$(XEN_COMPILE_ARCH)) 285 286x86.h := $(addprefix $(XEN_ROOT)/tools/include/xen/asm/,\ 287 x86-vendors.h x86-defns.h msr-index.h) \ 288 $(addprefix $(XEN_ROOT)/tools/include/xen/lib/x86/, \ 289 cpuid.h cpuid-autogen.h) 290x86_emulate.h := x86-emulate.h x86_emulate/x86_emulate.h $(x86.h) 291 292x86-emulate.o cpuid.o test_x86_emulator.o evex-disp8.o predicates.o wrappers.o: %.o: %.c $(x86_emulate.h) 293 $(HOSTCC) $(HOSTCFLAGS) -c -g -o $@ $< 294 295x86-emulate.o: x86_emulate/x86_emulate.c 296x86-emulate.o: HOSTCFLAGS += -D__XEN_TOOLS__ 297 298test_x86_emulator.o: $(addsuffix .h,$(TESTCASES)) $(addsuffix -opmask.h,$(OPMASK)) 299