From 88620971c25cd136434ac5e708ebe1dfb0571f7c Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 28 Oct 2006 18:19:39 +0000 Subject: [PATCH] Fix prefix order for "3-byte" instructions like the SIMD instructions. While the F2/F3/66 prefix used by these instructions should precede the REX prefix in 64-bit mode, they should probably not precede the segment override. The processor specifications seem to be unclear on this point, so play it safe. This change has a minor side-effect of reversing the segreg/size override ordering on things like "fs cmpsd" in 16-bit mode; this is okay as those prefixes can be in any order. This is due to the way Yasm implements segreg overrides for instructions with no EA. Reported by: Danny Reeves svn path=/trunk/yasm/; revision=1666 --- modules/arch/x86/tests/Makefile.inc | 2 + modules/arch/x86/tests/sse-prefix.asm | 39 +++++++++++ modules/arch/x86/tests/sse-prefix.hex | 81 ++++++++++++++++++++++ modules/arch/x86/tests/sse4.hex | 96 +++++++++++++-------------- modules/arch/x86/tests/stringseg.hex | 2 +- modules/arch/x86/x86bc.c | 4 +- modules/arch/x86/x86id.c | 4 +- 7 files changed, 176 insertions(+), 52 deletions(-) create mode 100644 modules/arch/x86/tests/sse-prefix.asm create mode 100644 modules/arch/x86/tests/sse-prefix.hex diff --git a/modules/arch/x86/tests/Makefile.inc b/modules/arch/x86/tests/Makefile.inc index 95010f7b..cf3be932 100644 --- a/modules/arch/x86/tests/Makefile.inc +++ b/modules/arch/x86/tests/Makefile.inc @@ -132,6 +132,8 @@ EXTRA_DIST += modules/arch/x86/tests/simd64-1.asm EXTRA_DIST += modules/arch/x86/tests/simd64-1.hex EXTRA_DIST += modules/arch/x86/tests/simd64-2.asm EXTRA_DIST += modules/arch/x86/tests/simd64-2.hex +EXTRA_DIST += modules/arch/x86/tests/sse-prefix.asm +EXTRA_DIST += modules/arch/x86/tests/sse-prefix.hex EXTRA_DIST += modules/arch/x86/tests/sse3.asm EXTRA_DIST += modules/arch/x86/tests/sse3.hex EXTRA_DIST += modules/arch/x86/tests/sse4.asm diff --git a/modules/arch/x86/tests/sse-prefix.asm b/modules/arch/x86/tests/sse-prefix.asm new file mode 100644 index 00000000..3c19960e --- /dev/null +++ b/modules/arch/x86/tests/sse-prefix.asm @@ -0,0 +1,39 @@ +[bits 32] +movsw +es movsw +rep movsw +rep fs movsw +fs rep movsw + +movsd +es movsd +rep movsd +rep fs movsd +fs rep movsd + +cmpss xmm0, [eax], 0 +cmpss xmm0, [es:eax], 0 + +cmpsd +fs cmpsd +rep fs cmpsd +fs rep cmpsd + +cmpsd xmm0, [eax], 0 +cmpsd xmm0, [es:eax], 0 + +[bits 64] +movsw +rep movsw + +movsd +rep movsd + +cmpss xmm0, [r8], 0 + +cmpsd +rep cmpsd + +cmpsd xmm0, [r8], 0 + + diff --git a/modules/arch/x86/tests/sse-prefix.hex b/modules/arch/x86/tests/sse-prefix.hex new file mode 100644 index 00000000..d7c78130 --- /dev/null +++ b/modules/arch/x86/tests/sse-prefix.hex @@ -0,0 +1,81 @@ +66 +a5 +66 +26 +a5 +f3 +66 +a5 +f3 +66 +64 +a5 +f3 +66 +64 +a5 +a5 +26 +a5 +f3 +a5 +f3 +64 +a5 +f3 +64 +a5 +f3 +0f +c2 +00 +00 +26 +f3 +0f +c2 +00 +00 +a7 +64 +a7 +f3 +64 +a7 +f3 +64 +a7 +f2 +0f +c2 +00 +00 +26 +f2 +0f +c2 +00 +00 +66 +a5 +f3 +66 +a5 +a5 +f3 +a5 +f3 +41 +0f +c2 +00 +00 +a7 +f3 +a7 +f2 +41 +0f +c2 +00 +00 diff --git a/modules/arch/x86/tests/sse4.hex b/modules/arch/x86/tests/sse4.hex index eaa26c65..43699ffa 100644 --- a/modules/arch/x86/tests/sse4.hex +++ b/modules/arch/x86/tests/sse4.hex @@ -97,13 +97,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -112,8 +112,8 @@ f3 38 1c c1 -f3 67 +f3 0f 7f 02 @@ -130,13 +130,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -145,8 +145,8 @@ f3 38 1d c1 -f3 67 +f3 0f 7f 02 @@ -163,13 +163,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -178,8 +178,8 @@ f3 38 1e c1 -f3 67 +f3 0f 7f 02 @@ -283,13 +283,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -298,8 +298,8 @@ f3 38 08 c1 -f3 67 +f3 0f 7f 02 @@ -316,13 +316,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -331,8 +331,8 @@ f3 38 09 c1 -f3 67 +f3 0f 7f 02 @@ -349,13 +349,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -364,8 +364,8 @@ f3 38 0a c1 -f3 67 +f3 0f 7f 02 @@ -469,13 +469,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -484,8 +484,8 @@ f3 38 01 c1 -f3 67 +f3 0f 7f 02 @@ -502,13 +502,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -517,8 +517,8 @@ f3 38 03 c1 -f3 67 +f3 0f 7f 02 @@ -535,13 +535,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -550,8 +550,8 @@ f3 38 02 c1 -f3 67 +f3 0f 7f 02 @@ -655,13 +655,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -670,8 +670,8 @@ f3 38 05 c1 -f3 67 +f3 0f 7f 02 @@ -688,13 +688,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -703,8 +703,8 @@ f3 38 07 c1 -f3 67 +f3 0f 7f 02 @@ -721,13 +721,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -736,8 +736,8 @@ f3 38 06 c1 -f3 67 +f3 0f 7f 02 @@ -783,13 +783,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -798,8 +798,8 @@ f3 38 0b c1 -f3 67 +f3 0f 7f 02 @@ -845,13 +845,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -860,8 +860,8 @@ f3 38 04 c1 -f3 67 +f3 0f 7f 02 @@ -907,13 +907,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -922,8 +922,8 @@ f3 38 00 c1 -f3 67 +f3 0f 7f 02 @@ -970,13 +970,13 @@ c3 44 24 08 -f3 67 +f3 0f 6f 02 -f3 67 +f3 0f 6f 08 @@ -986,8 +986,8 @@ f3 0f c1 03 -f3 67 +f3 0f 7f 02 diff --git a/modules/arch/x86/tests/stringseg.hex b/modules/arch/x86/tests/stringseg.hex index cf982469..9b8ef854 100644 --- a/modules/arch/x86/tests/stringseg.hex +++ b/modules/arch/x86/tests/stringseg.hex @@ -2,8 +2,8 @@ aa 26 ab -64 66 +64 ab 65 a4 diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index 4cc19a0c..91544c80 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -793,10 +793,10 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, unsigned char *bufp_orig = *bufp; /* Prefixes */ - if (insn->special_prefix != 0) - YASM_WRITE_8(*bufp, insn->special_prefix); x86_common_tobytes(&insn->common, bufp, x86_ea ? (x86_ea->ea.segreg>>8) : 0); + if (insn->special_prefix != 0) + YASM_WRITE_8(*bufp, insn->special_prefix); if (insn->rex != 0xff) { if (insn->common.mode_bits == 64 && insn->common.opersize == 64 && insn->def_opersize_64 != 64) diff --git a/modules/arch/x86/x86id.c b/modules/arch/x86/x86id.c index e44a7a59..b9aba1c9 100644 --- a/modules/arch/x86/x86id.c +++ b/modules/arch/x86/x86id.c @@ -2929,7 +2929,9 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, yasm_warn_set(YASM_WARN_GENERAL, N_("multiple segment overrides, using leftmost")); insn->special_prefix = segregs[num_segregs-1]>>8; - } + } else if (num_segregs > 0) + yasm_internal_error(N_("unhandled segment prefix")); + if (imm) { insn->imm = yasm_imm_create_expr(imm); insn->imm->val.size = im_len; -- 2.40.0