From 68f8b061c3141cf621254478bb00e3f45fb18a85 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Mon, 26 Sep 2005 04:17:09 +0000 Subject: [PATCH] * x86expr.c (yasm_x86__expr_checkea): Add address16_op parameter to avoid errors when using enter in 64-bit mode. * x86arch.h (yasm_x86__expr_checkea): Update prototype. * x86bc.c (x86_bc_insn_resolve, x86_bc_insn_tobytes): Pass flag to above. * x86id.re: Implement mul, imul, div, idiv, enter, leave for GAS mode. Add tests for above. svn path=/trunk/yasm/; revision=1245 --- modules/arch/x86/tests/gas64/Makefile.inc | 9 + modules/arch/x86/tests/gas64/gas-muldiv.asm | 36 + .../arch/x86/tests/gas64/gas-muldiv.errwarn | 0 modules/arch/x86/tests/gas64/gas-muldiv.hex | 624 ++++++++++++++++++ modules/arch/x86/tests/gas64/gas-retenter.asm | 16 + .../arch/x86/tests/gas64/gas-retenter.errwarn | 0 modules/arch/x86/tests/gas64/gas-retenter.hex | 528 +++++++++++++++ modules/arch/x86/tests/gas64/gas-shift.asm | 26 + .../arch/x86/tests/gas64/gas-shift.errwarn | 0 modules/arch/x86/tests/gas64/gas-shift.hex | 576 ++++++++++++++++ modules/arch/x86/x86arch.h | 9 +- modules/arch/x86/x86bc.c | 11 +- modules/arch/x86/x86expr.c | 14 +- modules/arch/x86/x86id.re | 230 ++++--- 14 files changed, 1989 insertions(+), 90 deletions(-) create mode 100644 modules/arch/x86/tests/gas64/gas-muldiv.asm create mode 100644 modules/arch/x86/tests/gas64/gas-muldiv.errwarn create mode 100644 modules/arch/x86/tests/gas64/gas-muldiv.hex create mode 100644 modules/arch/x86/tests/gas64/gas-retenter.asm create mode 100644 modules/arch/x86/tests/gas64/gas-retenter.errwarn create mode 100644 modules/arch/x86/tests/gas64/gas-retenter.hex create mode 100644 modules/arch/x86/tests/gas64/gas-shift.asm create mode 100644 modules/arch/x86/tests/gas64/gas-shift.errwarn create mode 100644 modules/arch/x86/tests/gas64/gas-shift.hex diff --git a/modules/arch/x86/tests/gas64/Makefile.inc b/modules/arch/x86/tests/gas64/Makefile.inc index 4ad4ccca..fd635a30 100644 --- a/modules/arch/x86/tests/gas64/Makefile.inc +++ b/modules/arch/x86/tests/gas64/Makefile.inc @@ -12,6 +12,15 @@ EXTRA_DIST += modules/arch/x86/tests/gas64/gas-inout.hex EXTRA_DIST += modules/arch/x86/tests/gas64/gas-movsxs.asm EXTRA_DIST += modules/arch/x86/tests/gas64/gas-movsxs.errwarn EXTRA_DIST += modules/arch/x86/tests/gas64/gas-movsxs.hex +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.asm +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.errwarn +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-muldiv.hex +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.asm +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.errwarn +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-retenter.hex +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-shift.asm +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-shift.errwarn +EXTRA_DIST += modules/arch/x86/tests/gas64/gas-shift.hex EXTRA_DIST += modules/arch/x86/tests/gas64/riprel.asm EXTRA_DIST += modules/arch/x86/tests/gas64/riprel.errwarn EXTRA_DIST += modules/arch/x86/tests/gas64/riprel.hex diff --git a/modules/arch/x86/tests/gas64/gas-muldiv.asm b/modules/arch/x86/tests/gas64/gas-muldiv.asm new file mode 100644 index 00000000..e4596363 --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-muldiv.asm @@ -0,0 +1,36 @@ +mulb %bl +mulw %bx +mull %ebx +mulq %rbx +imulw %bx, %cx +imull %ebx, %ecx +imulq %rbx, %rcx +imulw $5, %bx, %cx +imull $5, %ebx, %ecx +imulq $5, %rbx, %rcx +imulw $5000, %bx, %cx +imull $5000, %ebx, %ecx +imulq $5000, %rbx, %rcx +imulw $5, %cx +imull $5, %ecx +imulq $5, %rcx +imulw $5000, %cx +imull $5000, %ecx +imulq $5000, %rcx +divb %cl +divw %cx +divl %ecx +divq %rcx +divb %cl, %al +divw %cx, %ax +divl %ecx, %eax +divq %rcx, %rax +idivb %cl +idivw %cx +idivl %ecx +idivq %rcx +idivb %cl, %al +idivw %cx, %ax +idivl %ecx, %eax +idivq %rcx, %rax + diff --git a/modules/arch/x86/tests/gas64/gas-muldiv.errwarn b/modules/arch/x86/tests/gas64/gas-muldiv.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/arch/x86/tests/gas64/gas-muldiv.hex b/modules/arch/x86/tests/gas64/gas-muldiv.hex new file mode 100644 index 00000000..51900e5f --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-muldiv.hex @@ -0,0 +1,624 @@ +7f +45 +4c +46 +02 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +3e +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +30 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +40 +00 +05 +00 +01 +00 +f6 +e3 +66 +f7 +e3 +f7 +e3 +48 +f7 +e3 +66 +0f +af +cb +0f +af +cb +48 +0f +af +cb +66 +6b +cb +05 +6b +cb +05 +48 +6b +cb +05 +66 +69 +cb +88 +13 +69 +cb +88 +13 +00 +00 +48 +69 +cb +88 +13 +00 +00 +66 +6b +c9 +05 +6b +c9 +05 +48 +6b +c9 +05 +66 +69 +c9 +88 +13 +69 +c9 +88 +13 +00 +00 +48 +69 +c9 +88 +13 +00 +00 +f6 +f1 +66 +f7 +f1 +f7 +f1 +48 +f7 +f1 +f6 +f1 +66 +f7 +f1 +f7 +f1 +48 +f7 +f1 +f6 +f9 +66 +f7 +f9 +f7 +f9 +48 +f7 +f9 +f6 +f9 +66 +f7 +f9 +f7 +f9 +48 +f7 +f9 +00 +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +b8 +00 +00 +00 +00 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +dc +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +e0 +00 +00 +00 +00 +00 +00 +00 +48 +00 +00 +00 +00 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +08 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +77 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/modules/arch/x86/tests/gas64/gas-retenter.asm b/modules/arch/x86/tests/gas64/gas-retenter.asm new file mode 100644 index 00000000..552598a2 --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-retenter.asm @@ -0,0 +1,16 @@ +retw +#retl +retq +retw $5 +#retl $5 +retq $5 +lretw +#lretl +lretq $5 + +enterw $5000, $5 +#enterl +enterq $5000, $5 +leavew +#leavel +leaveq diff --git a/modules/arch/x86/tests/gas64/gas-retenter.errwarn b/modules/arch/x86/tests/gas64/gas-retenter.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/arch/x86/tests/gas64/gas-retenter.hex b/modules/arch/x86/tests/gas64/gas-retenter.hex new file mode 100644 index 00000000..78304292 --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-retenter.hex @@ -0,0 +1,528 @@ +7f +45 +4c +46 +02 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +3e +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +d0 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +40 +00 +05 +00 +01 +00 +66 +c3 +c3 +66 +c2 +05 +00 +c2 +05 +00 +66 +cb +ca +05 +00 +66 +c8 +88 +13 +05 +c8 +88 +13 +05 +66 +c9 +c9 +00 +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +5c +00 +00 +00 +00 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +80 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +84 +00 +00 +00 +00 +00 +00 +00 +48 +00 +00 +00 +00 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +08 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +1b +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/modules/arch/x86/tests/gas64/gas-shift.asm b/modules/arch/x86/tests/gas64/gas-shift.asm new file mode 100644 index 00000000..bfbef976 --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-shift.asm @@ -0,0 +1,26 @@ +shlb $1, %al +shlb $5, %al +shlb %cl, %al +shlb %al +shlw $1, %ax +shlw $5, %ax +shlw %cl, %ax +shlw %ax +shll $1, %eax +shll $5, %eax +shll %cl, %eax +shll %eax +shlq $1, %rax +shlq $5, %rax +shlq %cl, %rax +shlq %rax + +shldw $5, %bx, %dx +shldw %cl, %bx, %dx +shldw %bx, %dx +shldl $5, %ebx, %edx +shldl %cl, %ebx, %edx +shldl %ebx, %edx +shldq $5, %rbx, %rdx +shldq %cl, %rbx, %rdx +shldq %rbx, %rdx diff --git a/modules/arch/x86/tests/gas64/gas-shift.errwarn b/modules/arch/x86/tests/gas64/gas-shift.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/arch/x86/tests/gas64/gas-shift.hex b/modules/arch/x86/tests/gas64/gas-shift.hex new file mode 100644 index 00000000..56e7e240 --- /dev/null +++ b/modules/arch/x86/tests/gas64/gas-shift.hex @@ -0,0 +1,576 @@ +7f +45 +4c +46 +02 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +3e +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +40 +00 +05 +00 +01 +00 +d0 +e0 +c0 +e0 +05 +d2 +e0 +d0 +e0 +66 +d1 +e0 +66 +c1 +e0 +05 +66 +d3 +e0 +66 +d1 +e0 +d1 +e0 +c1 +e0 +05 +d3 +e0 +d1 +e0 +48 +d1 +e0 +48 +c1 +e0 +05 +48 +d3 +e0 +48 +d1 +e0 +66 +0f +a4 +da +05 +66 +0f +a5 +da +66 +0f +a5 +da +0f +a4 +da +05 +0f +a5 +da +0f +a5 +da +48 +0f +a4 +da +05 +48 +0f +a5 +da +48 +0f +a5 +da +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +90 +00 +00 +00 +00 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +b4 +00 +00 +00 +00 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +b8 +00 +00 +00 +00 +00 +00 +00 +48 +00 +00 +00 +00 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +08 +00 +00 +00 +00 +00 +00 +00 +18 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/modules/arch/x86/x86arch.h b/modules/arch/x86/x86arch.h index c3140e29..f2e9580c 100644 --- a/modules/arch/x86/x86arch.h +++ b/modules/arch/x86/x86arch.h @@ -252,10 +252,11 @@ void yasm_x86__ea_init(yasm_effaddr *ea, unsigned int spare, */ int yasm_x86__expr_checkea (yasm_expr **ep, unsigned char *addrsize, unsigned int bits, - unsigned int nosplit, unsigned char *displen, unsigned char *modrm, - unsigned char *v_modrm, unsigned char *n_modrm, unsigned char *sib, - unsigned char *v_sib, unsigned char *n_sib, unsigned char *pcrel, - unsigned char *rex, yasm_calc_bc_dist_func calc_bc_dist); + unsigned int nosplit, int address16_op, unsigned char *displen, + unsigned char *modrm, unsigned char *v_modrm, unsigned char *n_modrm, + unsigned char *sib, unsigned char *v_sib, unsigned char *n_sib, + unsigned char *pcrel, unsigned char *rex, + yasm_calc_bc_dist_func calc_bc_dist); void yasm_x86__parse_cpu(yasm_arch *arch, const char *cpuid, unsigned long line); diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index 1d7114a5..298ae700 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -529,10 +529,10 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save, * displacement. */ switch (yasm_x86__expr_checkea(&temp, &insn->common.addrsize, - insn->common.mode_bits, ea->nosplit, &displen, &eat.modrm, - &eat.valid_modrm, &eat.need_modrm, &eat.sib, - &eat.valid_sib, &eat.need_sib, &eat.pcrel, &insn->rex, - calc_bc_dist)) { + insn->common.mode_bits, ea->nosplit, insn->address16_op, + &displen, &eat.modrm, &eat.valid_modrm, &eat.need_modrm, + &eat.sib, &eat.valid_sib, &eat.need_sib, &eat.pcrel, + &insn->rex, calc_bc_dist)) { case 1: yasm_expr_destroy(temp); /* failed, don't bother checking rest of insn */ @@ -904,7 +904,8 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, */ if (yasm_x86__expr_checkea(&ea->disp, &addrsize, insn->common.mode_bits, ea->nosplit, - &displen, &eat.modrm, &eat.valid_modrm, + insn->address16_op, &displen, + &eat.modrm, &eat.valid_modrm, &eat.need_modrm, &eat.sib, &eat.valid_sib, &eat.need_sib, &eat.pcrel, &insn->rex, diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index 4d1f1a85..80810778 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -558,11 +558,11 @@ x86_expr_checkea_getregsize_callback(yasm_expr__item *ei, void *d) int yasm_x86__expr_checkea(yasm_expr **ep, unsigned char *addrsize, unsigned int bits, unsigned int nosplit, - unsigned char *displen, unsigned char *modrm, - unsigned char *v_modrm, unsigned char *n_modrm, - unsigned char *sib, unsigned char *v_sib, - unsigned char *n_sib, unsigned char *pcrel, - unsigned char *rex, + int address16_op, unsigned char *displen, + unsigned char *modrm, unsigned char *v_modrm, + unsigned char *n_modrm, unsigned char *sib, + unsigned char *v_sib, unsigned char *n_sib, + unsigned char *pcrel, unsigned char *rex, yasm_calc_bc_dist_func calc_bc_dist) { yasm_expr *e, *wrt; @@ -898,7 +898,7 @@ yasm_x86__expr_checkea(yasm_expr **ep, unsigned char *addrsize, } havereg = HAVE_NONE; /* 64-bit mode does not allow 16-bit addresses */ - if (bits == 64) { + if (bits == 64 && !address16_op) { yasm__error(e->line, N_("16-bit addresses not supported in 64-bit mode")); return 1; @@ -976,7 +976,7 @@ yasm_x86__expr_checkea(yasm_expr **ep, unsigned char *addrsize, break; case 16: /* 64-bit mode does not allow 16-bit addresses */ - if (bits == 64) { + if (bits == 64 && !address16_op) { yasm__error(e->line, N_("16-bit addresses not supported in 64-bit mode")); return 1; diff --git a/modules/arch/x86/x86id.re b/modules/arch/x86/x86id.re index 4f3ae6bf..af61b136 100644 --- a/modules/arch/x86/x86id.re +++ b/modules/arch/x86/x86id.re @@ -860,16 +860,39 @@ static const x86_insn_info incdec_insn[] = { {OPT_RM|OPS_64|OPA_EA, 0, 0} }, }; -/* Arithmetic - "F6" opcodes (div/idiv/mul/neg/not) */ +/* Arithmetic - mul/neg/not F6 opcodes */ static const x86_insn_info f6_insn[] = { - { CPU_Any, MOD_SpAdd, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 1, + { CPU_Any, MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 1, {OPT_RM|OPS_8|OPA_EA, 0, 0} }, - { CPU_Any, MOD_SpAdd, 16, 0, 0, 1, {0xF7, 0, 0}, 0, 1, + { CPU_Any, MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0xF7, 0, 0}, 0, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, - { CPU_386, MOD_SpAdd, 32, 0, 0, 1, {0xF7, 0, 0}, 0, 1, + { CPU_386, MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0xF7, 0, 0}, 0, 1, {OPT_RM|OPS_32|OPA_EA, 0, 0} }, - { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 0, 1, {0xF7, 0, 0}, 0, 1, - {OPT_RM|OPS_64|OPA_EA, 0, 0} }, + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1, {0xF7, 0, 0}, 0, + 1, {OPT_RM|OPS_64|OPA_EA, 0, 0} }, +}; + +/* Arithmetic - div/idiv F6 opcodes + * These allow explicit accumulator in GAS mode. + */ +static const x86_insn_info div_insn[] = { + { CPU_Any, MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 1, + {OPT_RM|OPS_8|OPA_EA, 0, 0} }, + { CPU_Any, MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0xF7, 0, 0}, 0, 1, + {OPT_RM|OPS_16|OPA_EA, 0, 0} }, + { CPU_386, MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0xF7, 0, 0}, 0, 1, + {OPT_RM|OPS_32|OPA_EA, 0, 0} }, + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1, {0xF7, 0, 0}, 0, + 1, {OPT_RM|OPS_64|OPA_EA, 0, 0} }, + /* Versions with explicit accumulator */ + { CPU_Any, MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 2, + {OPT_Areg|OPS_8|OPA_None, OPT_RM|OPS_8|OPA_EA, 0} }, + { CPU_Any, MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0xF7, 0, 0}, 0, 2, + {OPT_Areg|OPS_16|OPA_None, OPT_RM|OPS_16|OPA_EA, 0} }, + { CPU_386, MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0xF7, 0, 0}, 0, 2, + {OPT_Areg|OPS_32|OPA_None, OPT_RM|OPS_32|OPA_EA, 0} }, + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1, {0xF7, 0, 0}, 0, + 2, {OPT_Areg|OPS_64|OPA_None, OPT_RM|OPS_64|OPA_EA, 0} }, }; /* Arithmetic - test instruction */ @@ -928,108 +951,127 @@ static const x86_insn_info aadm_insn[] = { /* Arithmetic - imul */ static const x86_insn_info imul_insn[] = { - { CPU_Any, 0, 0, 0, 0, 1, {0xF6, 0, 0}, 5, 1, + { CPU_Any, MOD_GasSufB, 0, 0, 0, 1, {0xF6, 0, 0}, 5, 1, {OPT_RM|OPS_8|OPA_EA, 0, 0} }, - { CPU_Any, 0, 16, 0, 0, 1, {0xF7, 0, 0}, 5, 1, + { CPU_Any, MOD_GasSufW, 16, 0, 0, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, - { CPU_386, 0, 32, 0, 0, 1, {0xF7, 0, 0}, 5, 1, + { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_32|OPA_EA, 0, 0} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0xF7, 0, 0}, 5, 1, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_64|OPA_EA, 0, 0} }, - { CPU_386, 0, 16, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, + { CPU_386, MOD_GasSufW, 16, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, - { CPU_386, 0, 32, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, + { CPU_386, MOD_GasSufL, 32, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 2, {0x0F, 0xAF, 0}, 0, 2, {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }, - { CPU_186, 0, 16, 0, 0, 1, {0x6B, 0, 0}, 0, 3, + { CPU_186, MOD_GasSufW, 16, 0, 0, 1, {0x6B, 0, 0}, 0, 3, {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_SImm} }, - { CPU_386, 0, 32, 0, 0, 1, {0x6B, 0, 0}, 0, 3, + { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x6B, 0, 0}, 0, 3, {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_SImm} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x6B, 0, 0}, 0, 3, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x6B, 0, 0}, 0, 3, {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_SImm} }, - { CPU_186, 0, 16, 0, 0, 1, {0x6B, 0, 0}, 0, 2, + { CPU_186, MOD_GasSufW, 16, 0, 0, 1, {0x6B, 0, 0}, 0, 2, {OPT_Reg|OPS_16|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, - { CPU_386, 0, 32, 0, 0, 1, {0x6B, 0, 0}, 0, 2, + { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x6B, 0, 0}, 0, 2, {OPT_Reg|OPS_32|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x6B, 0, 0}, 0, 2, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x6B, 0, 0}, 0, 2, {OPT_Reg|OPS_64|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, - { CPU_186, 0, 16, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, + { CPU_186, MOD_GasSufW, 16, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, - { CPU_386, 0, 32, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, + { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x69, 0x6B, 0}, 0, 3, {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, - { CPU_186, 0, 16, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, + { CPU_186, MOD_GasSufW, 16, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, {OPT_Reg|OPS_16|OPA_SpareEA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} }, - { CPU_386, 0, 32, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, + { CPU_386, MOD_GasSufL, 32, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, {OPT_Reg|OPS_32|OPA_SpareEA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} }, - { CPU_Hammer|CPU_64, 0, 64, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, + { CPU_Hammer|CPU_64, MOD_GasSufQ, 64, 0, 0, 1, {0x69, 0x6B, 0}, 0, 2, {OPT_Reg|OPS_64|OPA_SpareEA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} } }; /* Shifts - standard */ static const x86_insn_info shift_insn[] = { - { CPU_Any, MOD_SpAdd, 0, 0, 0, 1, {0xD2, 0, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0xD2, 0, 0}, 0, 2, {OPT_RM|OPS_8|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, /* FIXME: imm8 is only avail on 186+, but we use imm8 to get to postponed * ,1 form, so it has to be marked as Any. We need to store the active * CPU flags somewhere to pass that parse-time info down the line. */ - { CPU_Any, MOD_SpAdd, 0, 0, 0, 1, {0xC0, 0xD0, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufB, 0, 0, 0, 1, {0xC0, 0xD0, 0}, 0, 2, {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, 0} }, - { CPU_Any, MOD_SpAdd, 16, 0, 0, 1, {0xD3, 0, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0xD3, 0, 0}, 0, 2, {OPT_RM|OPS_16|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, - { CPU_Any, MOD_SpAdd, 16, 0, 0, 1, {0xC1, 0xD1, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufW, 16, 0, 0, 1, {0xC1, 0xD1, 0}, 0, 2, {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, 0} }, - { CPU_Any, MOD_SpAdd, 32, 0, 0, 1, {0xD3, 0, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0xD3, 0, 0}, 0, 2, {OPT_RM|OPS_32|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, - { CPU_Any, MOD_SpAdd, 32, 0, 0, 1, {0xC1, 0xD1, 0}, 0, 2, + { CPU_Any, MOD_SpAdd|MOD_GasSufL, 32, 0, 0, 1, {0xC1, 0xD1, 0}, 0, 2, {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, 0} }, - { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 0, 1, {0xD3, 0, 0}, 0, 2, - {OPT_RM|OPS_64|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, - { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 0, 1, {0xC1, 0xD1, 0}, 0, 2, - {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, - 0} } + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1, {0xD3, 0, 0}, 0, + 2, {OPT_RM|OPS_64|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasSufQ, 64, 0, 0, 1, {0xC1, 0xD1, 0}, + 0, 2, {OPT_RM|OPS_64|OPA_EA, + OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, 0} }, + /* In GAS mode, single operands are equivalent to shifting by 1 forms */ + { CPU_Any, MOD_SpAdd|MOD_GasOnly|MOD_GasSufB, 0, 0, 0, 1, {0xD0, 0, 0}, + 0, 1, {OPT_RM|OPS_8|OPA_EA, 0, 0} }, + { CPU_Any, MOD_SpAdd|MOD_GasOnly|MOD_GasSufW, 16, 0, 0, 1, {0xD1, 0, 0}, + 0, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, + { CPU_Any, MOD_SpAdd|MOD_GasOnly|MOD_GasSufL, 32, 0, 0, 1, {0xD1, 0, 0}, + 0, 1, {OPT_RM|OPS_32|OPA_EA, 0, 0} }, + { CPU_Hammer|CPU_64, MOD_SpAdd|MOD_GasOnly|MOD_GasSufQ, 64, 0, 0, 1, + {0xD1, 0, 0}, 0, 1, {OPT_RM|OPS_64|OPA_EA, 0, 0} } }; /* Shifts - doubleword */ static const x86_insn_info shlrd_insn[] = { - { CPU_386, MOD_Op1Add, 16, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, + { CPU_386, MOD_Op1Add|MOD_GasSufW, 16, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, - { CPU_386, MOD_Op1Add, 16, 0, 0, 2, {0x0F, 0x01, 0}, 0, 3, + { CPU_386, MOD_Op1Add|MOD_GasSufW, 16, 0, 0, 2, {0x0F, 0x01, 0}, 0, 3, {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, OPT_Creg|OPS_8|OPA_None} }, - { CPU_386, MOD_Op1Add, 32, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, + { CPU_386, MOD_Op1Add|MOD_GasSufL, 32, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, - { CPU_386, MOD_Op1Add, 32, 0, 0, 2, {0x0F, 0x01, 0}, 0, 3, + { CPU_386, MOD_Op1Add|MOD_GasSufL, 32, 0, 0, 2, {0x0F, 0x01, 0}, 0, 3, {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, OPT_Creg|OPS_8|OPA_None} }, - { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, - {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, - OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, - { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 0, 2, {0x0F, 0x01, 0}, 0, 3, - {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, - OPT_Creg|OPS_8|OPA_None} } + { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_GasSufQ, 64, 0, 0, 2, {0x0F, 0x00, 0}, + 0, 3, {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, + OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, + { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_GasSufQ, 64, 0, 0, 2, {0x0F, 0x01, 0}, + 0, 3, {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, + OPT_Creg|OPS_8|OPA_None} }, + /* GAS parser supports two-operand form for shift with CL count */ + { CPU_386, MOD_Op1Add|MOD_GasOnly|MOD_GasSufW, 16, 0, 0, 2, + {0x0F, 0x01, 0}, 0, 2, + {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, + { CPU_386, MOD_Op1Add|MOD_GasOnly|MOD_GasSufL, 32, 0, 0, 2, + {0x0F, 0x01, 0}, 0, 2, + {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, + { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_GasOnly|MOD_GasSufQ, 64, 0, 0, 2, + {0x0F, 0x01, 0}, 0, 2, + {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} } }; /* Control transfer instructions (unconditional) */ @@ -1136,17 +1178,31 @@ static const x86_insn_info jmp_insn[] = { {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} } }; static const x86_insn_info retnf_insn[] = { - { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, {0x01, 0, 0}, 0, 0, {0, 0, 0} }, - { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, {0x00, 0, 0}, 0, 1, - {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} } + { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, + {0x01, 0, 0}, 0, 0, {0, 0, 0} }, + { CPU_Any, MOD_Op0Add, 0, 0, 0, 1, + {0x00, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} }, + /* GAS suffix versions */ + { CPU_Any, MOD_Op0Add|MOD_GasSufW, 16, 0, 0, 1, + {0x01, 0, 0}, 0, 0, {0, 0, 0} }, + { CPU_Any, MOD_Op0Add|MOD_GasSufW, 16, 0, 0, 1, + {0x00, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} }, + { CPU_Any, MOD_Op0Add|MOD_GasSufL|MOD_GasSufQ, 0, 0, 0, 1, + {0x01, 0, 0}, 0, 0, {0, 0, 0} }, + { CPU_Any, MOD_Op0Add|MOD_GasSufL|MOD_GasSufQ, 0, 0, 0, 1, + {0x00, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} } }; static const x86_insn_info enter_insn[] = { - { CPU_186|CPU_Not64, 0, 0, 0, 0, 1, {0xC8, 0, 0}, 0, 2, - {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA|OPAP_A16, - OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, - { CPU_Hammer|CPU_64, 0, 64, 64, 0, 1, {0xC8, 0, 0}, 0, 2, - {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA|OPAP_A16, - OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} } + { CPU_186|CPU_Not64, MOD_GasNoRev|MOD_GasSufL, 0, 0, 0, 1, {0xC8, 0, 0}, 0, + 2, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA|OPAP_A16, + OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, + { CPU_Hammer|CPU_64, MOD_GasNoRev|MOD_GasSufQ, 64, 64, 0, 1, {0xC8, 0, 0}, + 0, 2, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA|OPAP_A16, + OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, + /* GAS suffix version */ + { CPU_186, MOD_GasOnly|MOD_GasNoRev|MOD_GasSufW, 16, 0, 0, 1, + {0xC8, 0, 0}, 0, 2, {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA|OPAP_A16, + OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, }; /* Conditional jumps */ @@ -2034,7 +2090,6 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, for (i = num_operands-1, op = yasm_ops_first(operands); op && i >= 0; op = yasm_operand_next(op), i--) rev_ops[i] = op; - use_ops = rev_ops; } /* If we're running in GAS mode, look at the first insn_info to see @@ -2113,6 +2168,14 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc, break; } + /* Use reversed operands in GAS mode if not otherwise specified */ + if (arch_x86->parser == X86_PARSER_GAS) { + if (info->modifiers & MOD_GasNoRev) + use_ops = ops; + else + use_ops = rev_ops; + } + /* Match each operand type and size */ for (i = 0, op = use_ops[0]; op && inum_operands && !mismatch; op = use_ops[++i]) { @@ -3512,29 +3575,48 @@ yasm_x86__parse_check_insn(yasm_arch *arch, unsigned long data[4], RET_INSN_GAS(4, onebyte, 0x4099, CPU_Hammer|CPU_64); } /* Multiplication and division */ - M U L { RET_INSN(3, f6, 0x04, CPU_Any); } - I M U L { RET_INSN(4, imul, 0, CPU_Any); } - D I V { RET_INSN(3, f6, 0x06, CPU_Any); } - I D I V { RET_INSN(4, f6, 0x07, CPU_Any); } + M U L [bBwWlLqQ]? { RET_INSN(3, f6, 0x04, CPU_Any); } + I M U L [bBwWlLqQ]? { RET_INSN(4, imul, 0, CPU_Any); } + D I V [bBwWlLqQ]? { RET_INSN(3, div, 0x06, CPU_Any); } + I D I V [bBwWlLqQ]? { RET_INSN(4, div, 0x07, CPU_Any); } /* Shifts */ - R O L { RET_INSN(3, shift, 0x00, CPU_Any); } - R O R { RET_INSN(3, shift, 0x01, CPU_Any); } - R C L { RET_INSN(3, shift, 0x02, CPU_Any); } - R C R { RET_INSN(3, shift, 0x03, CPU_Any); } - S A L { RET_INSN(3, shift, 0x04, CPU_Any); } - S H L { RET_INSN(3, shift, 0x04, CPU_Any); } - S H R { RET_INSN(3, shift, 0x05, CPU_Any); } - S A R { RET_INSN(3, shift, 0x07, CPU_Any); } - S H L D { RET_INSN(4, shlrd, 0xA4, CPU_386); } - S H R D { RET_INSN(4, shlrd, 0xAC, CPU_386); } + R O L [bBwWlLqQ]? { RET_INSN(3, shift, 0x00, CPU_Any); } + R O R [bBwWlLqQ]? { RET_INSN(3, shift, 0x01, CPU_Any); } + R C L [bBwWlLqQ]? { RET_INSN(3, shift, 0x02, CPU_Any); } + R C R [bBwWlLqQ]? { RET_INSN(3, shift, 0x03, CPU_Any); } + S A L [bBwWlLqQ]? { RET_INSN(3, shift, 0x04, CPU_Any); } + S H L [bBwWlLqQ]? { RET_INSN(3, shift, 0x04, CPU_Any); } + S H R [bBwWlLqQ]? { RET_INSN(3, shift, 0x05, CPU_Any); } + S A R [bBwWlLqQ]? { RET_INSN(3, shift, 0x07, CPU_Any); } + S H L D [wWlLqQ]? { RET_INSN(4, shlrd, 0xA4, CPU_386); } + S H R D [wWlLqQ]? { RET_INSN(4, shlrd, 0xAC, CPU_386); } /* Control transfer instructions (unconditional) */ C A L L { RET_INSN(4, call, 0, CPU_Any); } J M P { RET_INSN(3, jmp, 0, CPU_Any); } - R E T { RET_INSN(3, retnf, 0xC2, CPU_Any); } - R E T N { RET_INSN(4, retnf, 0xC2, CPU_Any); } - R E T F { RET_INSN(4, retnf, 0xCA, CPU_Any); } - E N T E R { RET_INSN(5, enter, 0, CPU_186); } + R E T W? { RET_INSN(3, retnf, 0xC2, CPU_Any); } + R E T L { + not64 = 1; + RET_INSN_GAS(3, retnf, 0xC2, CPU_Any); + } + R E T Q { + warn64 = 1; + RET_INSN_GAS(3, retnf, 0xC2, CPU_Hammer|CPU_64); + } + R E T N { RET_INSN_NONGAS(4, retnf, 0xC2, CPU_Any); } + R E T F { RET_INSN_NONGAS(4, retnf, 0xCA, CPU_Any); } + L R E T W { RET_INSN_GAS(4, retnf, 0xCA, CPU_Any); } + L R E T L { + not64 = 1; + RET_INSN_GAS(4, retnf, 0xCA, CPU_Any); + } + L R E T Q { + warn64 = 1; + RET_INSN_GAS(4, retnf, 0xCA, CPU_Any); + } + E N T E R [wWlLqQ]? { RET_INSN(5, enter, 0, CPU_186); } L E A V E { RET_INSN(5, onebyte, 0x4000C9, CPU_186); } + L E A V E [wW] { RET_INSN_GAS(6, onebyte, 0x0010C9, CPU_186); } + L E A V E [lLqQ] { RET_INSN_GAS(6, onebyte, 0x4000C9, CPU_186); } /* Conditional jumps */ J O { RET_INSN(2, jcc, 0x00, CPU_Any); } J N O { RET_INSN(3, jcc, 0x01, CPU_Any); } -- 2.40.0