aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/config/tc-i386-intel.c9
-rw-r--r--gas/config/tc-i386.c102
-rw-r--r--gas/testsuite/gas/i386/insn-32.d13
-rw-r--r--gas/testsuite/gas/i386/insn-32.s24
-rw-r--r--gas/testsuite/gas/i386/insn-64.d13
-rw-r--r--gas/testsuite/gas/i386/insn-64.s25
6 files changed, 182 insertions, 4 deletions
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c
index 98262bd..5a2bf6d 100644
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -965,7 +965,8 @@ i386_intel_operand (char *operand_string, int got_a_float)
i386_operand_type temp;
/* Register operand. */
- if (intel_state.base || intel_state.index || intel_state.seg)
+ if (intel_state.base || intel_state.index || intel_state.seg
+ || i.imm_bits[this_operand])
{
as_bad (_("invalid operand"));
return 0;
@@ -998,6 +999,12 @@ i386_intel_operand (char *operand_string, int got_a_float)
|| intel_state.is_mem)
{
/* Memory operand. */
+ if (i.imm_bits[this_operand])
+ {
+ as_bad (_("invalid operand"));
+ return 0;
+ }
+
if (i.mem_operands)
{
/* Handle
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index c8e68d5..ea2ed0d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -288,6 +288,7 @@ struct _i386_insn
unsigned int flags[MAX_OPERANDS];
#define Operand_PCrel 1
#define Operand_Mem 2
+#define Operand_Signed 4 /* .insn only */
/* Relocation type for operand */
enum bfd_reloc_code_real reloc[MAX_OPERANDS];
@@ -310,6 +311,9 @@ struct _i386_insn
/* .insn allows for reserved opcode spaces. */
unsigned char insn_opcode_space;
+ /* .insn also allows (requires) specifying immediate size. */
+ unsigned char imm_bits[MAX_OPERANDS];
+
/* Register is in low 3 bits of opcode. */
bool short_form;
@@ -5923,6 +5927,10 @@ swap_2_operands (unsigned int xchg1, unsigned int xchg2)
i.reloc[xchg2] = i.reloc[xchg1];
i.reloc[xchg1] = temp_reloc;
+ temp_flags = i.imm_bits[xchg2];
+ i.imm_bits[xchg2] = i.imm_bits[xchg1];
+ i.imm_bits[xchg1] = temp_flags;
+
if (i.mask.reg)
{
if (i.mask.operand == xchg1)
@@ -10188,7 +10196,8 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off)
if (i.types[n].bitfield.imm32s
&& (i.suffix == QWORD_MNEM_SUFFIX
- || (!i.suffix && i.tm.opcode_modifier.no_lsuf)))
+ || (!i.suffix && i.tm.opcode_modifier.no_lsuf)
+ || dot_insn ()))
sign = 1;
else
sign = 0;
@@ -11216,6 +11225,57 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
if (i.disp_operands && !optimize_disp (&i.tm))
goto done;
+ /* Establish size for immediate operands. */
+ for (j = 0; j < i.imm_operands; ++j)
+ {
+ expressionS *expP = i.op[j].imms;
+
+ gas_assert (operand_type_check (i.types[j], imm));
+ operand_type_set (&i.types[j], 0);
+
+ if (i.imm_bits[j] > 32)
+ i.types[j].bitfield.imm64 = 1;
+ else if (i.imm_bits[j] > 16)
+ {
+ if (flag_code == CODE_64BIT && (i.flags[j] & Operand_Signed))
+ i.types[j].bitfield.imm32s = 1;
+ else
+ i.types[j].bitfield.imm32 = 1;
+ }
+ else if (i.imm_bits[j] > 8)
+ i.types[j].bitfield.imm16 = 1;
+ else if (i.imm_bits[j] > 0)
+ {
+ if (i.flags[j] & Operand_Signed)
+ i.types[j].bitfield.imm8s = 1;
+ else
+ i.types[j].bitfield.imm8 = 1;
+ }
+ else if (expP->X_op == O_constant)
+ {
+ i.types[j] = smallest_imm_type (expP->X_add_number);
+ i.types[j].bitfield.imm1 = 0;
+ /* Oddly enough imm_size() checks imm64 first, so the bit needs
+ zapping since smallest_imm_type() sets it unconditionally. */
+ if (flag_code != CODE_64BIT)
+ {
+ i.types[j].bitfield.imm64 = 0;
+ i.types[j].bitfield.imm32s = 0;
+ i.types[j].bitfield.imm32 = 1;
+ }
+ else if (i.types[j].bitfield.imm32 || i.types[j].bitfield.imm32s)
+ i.types[j].bitfield.imm64 = 0;
+ }
+ else
+ /* Non-constant expressions are sized heuristically. */
+ switch (flag_code)
+ {
+ case CODE_64BIT: i.types[j].bitfield.imm32s = 1; break;
+ case CODE_32BIT: i.types[j].bitfield.imm32 = 1; break;
+ case CODE_16BIT: i.types[j].bitfield.imm16 = 1; break;
+ }
+ }
+
for (j = 0; j < i.operands; ++j)
i.tm.operand_types[j] = i.types[j];
@@ -11396,10 +11456,11 @@ check_VecOperations (char *op_string)
else if (dot_insn () && *op_string == ':')
{
dot_insn_modifier:
- if (op_string[1] == 'd')
+ switch (op_string[1])
{
unsigned long n;
+ case 'd':
if (i.memshift < 32)
goto duplicated_vec_op;
@@ -11409,6 +11470,27 @@ check_VecOperations (char *op_string)
++i.memshift;
if (i.memshift < 32 && n == 1)
op_string = end_op;
+ break;
+
+ case 's': case 'u':
+ /* This isn't really a "vector" operation, but a sign/size
+ specifier for immediate operands of .insn. Note that AT&T
+ syntax handles the same in i386_immediate(). */
+ if (!intel_syntax)
+ break;
+
+ if (i.imm_bits[this_operand])
+ goto duplicated_vec_op;
+
+ n = strtoul (op_string + 2, &end_op, 0);
+ if (n && n <= (flag_code == CODE_64BIT ? 64 : 32))
+ {
+ i.imm_bits[this_operand] = n;
+ if (op_string[1] == 's')
+ i.flags[this_operand] |= Operand_Signed;
+ op_string = end_op;
+ }
+ break;
}
}
/* Check masking operation. */
@@ -11547,6 +11629,22 @@ i386_immediate (char *imm_start)
exp_seg = expression (exp);
+ /* For .insn immediates there may be a size specifier. */
+ if (dot_insn () && *input_line_pointer == '{' && input_line_pointer[1] == ':'
+ && (input_line_pointer[2] == 's' || input_line_pointer[2] == 'u'))
+ {
+ char *e;
+ unsigned long n = strtoul (input_line_pointer + 3, &e, 0);
+
+ if (*e == '}' && n && n <= (flag_code == CODE_64BIT ? 64 : 32))
+ {
+ i.imm_bits[this_operand] = n;
+ if (input_line_pointer[2] == 's')
+ i.flags[this_operand] |= Operand_Signed;
+ input_line_pointer = e + 1;
+ }
+ }
+
SKIP_WHITESPACE ();
if (*input_line_pointer)
as_bad (_("junk `%s' after expression"), input_line_pointer);
diff --git a/gas/testsuite/gas/i386/insn-32.d b/gas/testsuite/gas/i386/insn-32.d
index d898a71..c2d8202 100644
--- a/gas/testsuite/gas/i386/insn-32.d
+++ b/gas/testsuite/gas/i386/insn-32.d
@@ -1,5 +1,7 @@
+#as: --divide
#objdump: -dw
#name: .insn (32-bit code)
+#xfail: *-*-darwin*
.*: +file format .*
@@ -10,6 +12,7 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: f3 90[ ]+pause
[ ]*[a-f0-9]+: f3 90[ ]+pause
[ ]*[a-f0-9]+: d9 ee[ ]+fldz
+[ ]*[a-f0-9]+: d9 ee[ ]+fldz
[ ]*[a-f0-9]+: f3 0f 01 e8[ ]+setssbsy
[ ]*[a-f0-9]+: 8b c1[ ]+mov %ecx,%eax
[ ]*[a-f0-9]+: 66 8b c8[ ]+mov %ax,%cx
@@ -17,7 +20,10 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: 8b 0c 05 44 44 00 00[ ]+mov 0x4444\(,%eax,1\),%ecx
[ ]*[a-f0-9]+: 66 0f b6 cc[ ]+movzbw %ah,%cx
[ ]*[a-f0-9]+: 0f b7 c8[ ]+movzwl %ax,%ecx
+[ ]*[a-f0-9]+: 64 f0 80 30 01[ ]+lock xorb \$(0x)?1,%fs:\(%eax\)
[ ]*[a-f0-9]+: 0f ca[ ]+bswap %edx
+[ ]*[a-f0-9]+: c7 f8 02 00 00 00[ ]+xbegin [0-9a-f]+ <insn\+.*>
+[ ]*[a-f0-9]+: e2 f8[ ]+loop [0-9a-f]+ <insn\+.*>
[ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall
[ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall
[ ]*[a-f0-9]+: c5 f1 58 d0[ ]+vaddpd %xmm0,%xmm1,%xmm2
@@ -27,6 +33,9 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: c4 e3 69 68 19 00[ ]+vfmaddps %xmm0,\(%ecx\),%xmm2,%xmm3
[ ]*[a-f0-9]+: c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
[ ]*[a-f0-9]+: c4 e3 e9 68 18 10[ ]+vfmaddps \(%eax\),%xmm1,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 69 48 19 00[ ]+vpermil2ps \$(0x)?0,%xmm0,\(%ecx\),%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 e9 48 19 02[ ]+vpermil2ps \$(0x)?2,\(%ecx\),%xmm0,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 e9 48 18 13[ ]+vpermil2ps \$(0x)?3,\(%eax\),%xmm1,%xmm2,%xmm3
[ ]*[a-f0-9]+: c5 f8 92 c8[ ]+kmovw %eax,%k1
[ ]*[a-f0-9]+: c5 f8 93 c1[ ]+kmovw %k1,%eax
[ ]*[a-f0-9]+: 62 f1 74 18 58 d0[ ]+vaddps \{rn-sae\},%zmm0,%zmm1,%zmm2
@@ -41,4 +50,8 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: 62 f5 fd 58 5a 40 01[ ]+vcvtpd2ph (0x)?8\(%eax\)\{1to8\},%xmm0
[ ]*[a-f0-9]+: 62 f5 7c 48 5a 40 01[ ]+vcvtph2pd 0x10\(%eax\),%zmm0
[ ]*[a-f0-9]+: 62 f5 7c 58 5a 40 01[ ]+vcvtph2pd (0x)?2\(%eax\)\{1to8\},%zmm0
+[ ]*[a-f0-9]+: 62 f3 7d 28 66 40 01 ff[ ]+vfpclasspsy \$0xff,0x20\(%eax\),%k0
+[ ]*[a-f0-9]+: 62 f3 7d 28 66 40 01 ff[ ]+vfpclasspsy \$0xff,0x20\(%eax\),%k0
+[ ]*[a-f0-9]+: 62 f3 7d 38 66 40 01 ff[ ]+vfpclassps \$0xff,(0x)?4\(%eax\)\{1to8\},%k0
+[ ]*[a-f0-9]+: 62 f3 7d 38 66 40 01 ff[ ]+vfpclassps \$0xff,(0x)?4\(%eax\)\{1to8\},%k0
#pass
diff --git a/gas/testsuite/gas/i386/insn-32.s b/gas/testsuite/gas/i386/insn-32.s
index d54ad3b..20bae32 100644
--- a/gas/testsuite/gas/i386/insn-32.s
+++ b/gas/testsuite/gas/i386/insn-32.s
@@ -9,6 +9,7 @@ insn:
# fldz
.insn 0xd9ee
+ .insn 0xd9, $0xee
# setssbsy
.insn 0xf30f01e8
@@ -23,9 +24,20 @@ insn:
.insn 0x0fb6, %ah, %cx
.insn 0x0fb7, %eax, %ecx
+ # xorb
+ .insn lock 0x80/6, $1, %fs:(%eax)
+
# bswap
.insn 0x0fc8+r, %edx
+1:
+ # xbegin 3f
+ .insn 0xc7f8, $3f-2f{:s32}
+2:
+ # loop 1b
+ .insn 0xe2, $1b-3f{:s8}
+3:
+
# vzeroall
.insn VEX.256.0F.WIG 0x77
.insn {vex3} VEX.L1 0x0f77
@@ -43,6 +55,11 @@ insn:
.insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
.insn VEX.66.0F3A.W1 0x68, (%eax), %xmm1, %xmm2, %xmm3
+ # vpermil2ps
+ .insn VEX.66.0F3A.W0 0x48, $0, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x48, $2, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x48, $3, (%eax), %xmm1, %xmm2, %xmm3
+
# kmovw
.insn VEX.L0.0F.W0 0x92, %eax, %k1
.insn VEX.L0.0F.W0 0x93, %k1, %eax
@@ -68,3 +85,10 @@ insn:
# vcvtph2pd
.insn EVEX.M5.W0 0x5a, 16(%eax){:d16}, %zmm0
.insn EVEX.M5.W0 0x5a, 2(%eax){1to8:d2}, %zmm0
+
+ .intel_syntax noprefix
+ # vfpclassps
+ .insn EVEX.256.66.0f3a.W0 0x66, k0, [eax+32], 0xff
+ .insn EVEX.66.0f3a.W0 0x66, k0, ymmword ptr [eax+32], 0xff
+ .insn EVEX.256.66.0f3a.W0 0x66, k0, [eax+4]{1to8}, 0xff
+ .insn EVEX.66.0f3a.W0 0x66, k0, dword ptr [eax+4]{1to8}, 0xff
diff --git a/gas/testsuite/gas/i386/insn-64.d b/gas/testsuite/gas/i386/insn-64.d
index 0f1ec88..0c1f0c5 100644
--- a/gas/testsuite/gas/i386/insn-64.d
+++ b/gas/testsuite/gas/i386/insn-64.d
@@ -1,5 +1,7 @@
-#objdump: -dw
+#as: --divide
+#objdump: -dwr
#name: .insn (64-bit code)
+#xfail: *-*-darwin*
.*: +file format .*
@@ -18,8 +20,14 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: 66 0f be cc[ ]+movsbw %ah,%cx
[ ]*[a-f0-9]+: 0f bf c8[ ]+movswl %ax,%ecx
[ ]*[a-f0-9]+: 48 63 c8[ ]+movslq %eax,%rcx
+[ ]*[a-f0-9]+: f0 80 35 ((00|ff) ){4}01[ ]+lock xorb \$(0x)?1,[-x01]+\(%rip\) *# .*: (R_X86_64_PC32 lock-(0x)?5|IMAGE_REL_AMD64_REL32 lock)
[ ]*[a-f0-9]+: 48 0f ca[ ]+bswap %rdx
[ ]*[a-f0-9]+: 41 0f c8[ ]+bswap %r8d
+[ ]*[a-f0-9]+: c7 f8 02 00 00 00[ ]+xbegin [0-9a-f]+ <insn\+.*>
+[ ]*[a-f0-9]+: e2 f8[ ]+loop [0-9a-f]+ <insn\+.*>
+[ ]*[a-f0-9]+: 05 00 00 00 00[ ]+add \$(0x)?0,%eax .*: (R_X86_64_32|IMAGE_REL_AMD64_ADDR32) var
+[ ]*[a-f0-9]+: 48 05 00 00 00 00[ ]+add \$(0x)?0,%rax .*: R_X86_64_32S var
+[ ]*[a-f0-9]+: 81 3d (00|fc) ((00|ff) ){3}13 12 23 21[ ]+cmpl \$0x21231213,[-x04]+\(%rip\) *# .*: (R_X86_64_PC32 var-(0x)?8|IMAGE_REL_AMD64_REL32 var)
[ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall
[ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall
[ ]*[a-f0-9]+: c4 c1 71 58 d0[ ]+vaddpd %xmm8,%xmm1,%xmm2
@@ -29,6 +37,9 @@ Disassembly of section .text:
[ ]*[a-f0-9]+: c4 e3 69 68 19 80[ ]+vfmaddps %xmm8,\(%rcx\),%xmm2,%xmm3
[ ]*[a-f0-9]+: 67 c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3
[ ]*[a-f0-9]+: c4 c3 e9 68 18 10[ ]+vfmaddps \(%r8\),%xmm1,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 e3 69 48 19 80[ ]+vpermil2ps \$(0x)0,%xmm8,\(%rcx\),%xmm2,%xmm3
+[ ]*[a-f0-9]+: 67 c4 e3 e9 48 19 02[ ]+vpermil2ps \$(0x)2,\(%ecx\),%xmm0,%xmm2,%xmm3
+[ ]*[a-f0-9]+: c4 c3 e9 48 18 13[ ]+vpermil2ps \$(0x)3,\(%r8\),%xmm1,%xmm2,%xmm3
[ ]*[a-f0-9]+: c4 c1 78 92 c8[ ]+kmovw %r8d,%k1
[ ]*[a-f0-9]+: c5 78 93 c1[ ]+kmovw %k1,%r8d
[ ]*[a-f0-9]+: 62 b1 74 38 58 d0[ ]+vaddps \{rd-sae\},%zmm16,%zmm1,%zmm2
diff --git a/gas/testsuite/gas/i386/insn-64.s b/gas/testsuite/gas/i386/insn-64.s
index 9dfdd3a..3152ec9 100644
--- a/gas/testsuite/gas/i386/insn-64.s
+++ b/gas/testsuite/gas/i386/insn-64.s
@@ -24,10 +24,30 @@ insn:
.insn 0x0fbf, %eax, %ecx
.insn 0x63, %rax, %rcx
+ # xorb
+ .insn lock 0x80/6, $1, lock(%rip)
+
# bswap
.insn 0x0fc8+r, %rdx
.insn 0x0fc8+r, %r8d
+1:
+ # xbegin 3f
+ .insn 0xc7f8, $3f-2f{:s32}
+2:
+ # loop 1b
+ .insn 0xe2, $1b-3f{:s8}
+3:
+
+ # add $var, %eax
+ .insn 0x05, $var{:u32}
+
+ # add $var, %rax
+ .insn rex.w 0x05, $var{:s32}
+
+ # cmpl (32-bit immediate split into two 16-bit halves)
+ .insn 0x81/7, $0x1213, $0x2123, var(%rip)
+
# vzeroall
.insn VEX.256.0F.WIG 0x77
.insn {vex3} VEX.L1 0x0f77
@@ -45,6 +65,11 @@ insn:
.insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3
.insn VEX.66.0F3A.W1 0x68, (%r8), %xmm1, %xmm2, %xmm3
+ # vpermil2ps
+ .insn VEX.66.0F3A.W0 0x48, $0, %xmm8, (%rcx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x48, $2, %xmm0, (%ecx), %xmm2, %xmm3
+ .insn VEX.66.0F3A.W1 0x48, $3, (%r8), %xmm1, %xmm2, %xmm3
+
# kmovw
.insn VEX.L0.0F.W0 0x92, %r8d, %k1
.insn VEX.L0.0F.W0 0x93, %k1, %r8d