Discussion:
[PATCH 0/2] x86: further folding
Jan Beulich
2018-09-13 09:38:21 UTC
Permalink
1: fold CRC32 templates
2: fold Size{16,32,64} template attributes

Jan
Jan Beulich
2018-09-13 09:43:59 UTC
Permalink
Just like other insns having byte and word forms, these can also make
use of the W modifier, which at the same time allows simplifying some
other code a little bit.

gas/
2018-09-13 Jan Beulich <***@suse.com>

* config/tc-i386.c (process_suffix): Simplify CRC32 special
casing code.

opcodes/
2018-09-13 Jan Beulich <***@suse.com>

* i386-opc.tbl (crc32): Fold byte and word forms.
* i386-tbl.h: Re-generate.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -6055,27 +6055,23 @@ process_suffix (void)
Destination register type is more significant than source
register type. crc32 in SSE4.2 prefers source register
type. */
- if (i.tm.base_opcode == 0xf20f38f1)
+ if (i.tm.base_opcode == 0xf20f38f0 && i.types[0].bitfield.reg)
{
- if (i.types[0].bitfield.reg && i.types[0].bitfield.word)
+ if (i.types[0].bitfield.byte)
+ i.suffix = BYTE_MNEM_SUFFIX;
+ else if (i.types[0].bitfield.word)
i.suffix = WORD_MNEM_SUFFIX;
- else if (i.types[0].bitfield.reg && i.types[0].bitfield.dword)
+ else if (i.types[0].bitfield.dword)
i.suffix = LONG_MNEM_SUFFIX;
- else if (i.types[0].bitfield.reg && i.types[0].bitfield.qword)
+ else if (i.types[0].bitfield.qword)
i.suffix = QWORD_MNEM_SUFFIX;
}
- else if (i.tm.base_opcode == 0xf20f38f0)
- {
- if (i.types[0].bitfield.reg && i.types[0].bitfield.byte)
- i.suffix = BYTE_MNEM_SUFFIX;
- }

if (!i.suffix)
{
int op;

- if (i.tm.base_opcode == 0xf20f38f1
- || i.tm.base_opcode == 0xf20f38f0)
+ if (i.tm.base_opcode == 0xf20f38f0)
{
/* We have to know the operand size for crc32. */
as_bad (_("ambiguous memory operand size for `%s`"),
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -1730,12 +1730,8 @@ pcmpistri, 3, 0x6663, None, 1, CpuAVX, M
pcmpistri, 3, 0x660f3a63, None, 3, CpuSSE4_2, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM }
pcmpistrm, 3, 0x6662, None, 1, CpuAVX, Modrm|Vex|VexOpcode=2|VexW=1|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|SSE2AVX, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM }
pcmpistrm, 3, 0x660f3a62, None, 3, CpuSSE4_2, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8, RegXMM|Unspecified|BaseIndex, RegXMM }
-// We put non-8bit version before 8bit so that crc32 with memory operand
-// defaults to non-8bit.
-crc32, 2, 0xf20f38f1, None, 3, CpuSSE4_2, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|NoAVX, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex, Reg32 }
-crc32, 2, 0xf20f38f1, None, 3, CpuSSE4_2|Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoAVX, { Reg64|Qword|Unspecified|BaseIndex, Reg64 }
-crc32, 2, 0xf20f38f0, None, 3, CpuSSE4_2, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|NoAVX, { Reg8|Byte|Unspecified|BaseIndex, Reg32 }
-crc32, 2, 0xf20f38f0, None, 3, CpuSSE4_2|Cpu64, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|NoAVX, { Reg8|Byte|Unspecified|BaseIndex, Reg64 }
+crc32, 2, 0xf20f38f0, None, 3, CpuSSE4_2, W|Modrm|No_sSuf|No_qSuf|No_ldSuf|NoAVX, { Reg8|Reg16|Reg32|Unspecified|BaseIndex, Reg32 }
+crc32, 2, 0xf20f38f0, None, 3, CpuSSE4_2|Cpu64, W|Modrm|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|Rex64|NoAVX, { Reg8|Reg64|Unspecified|BaseIndex, Reg64 }

// xsave/xrstor New Instructions.
Jan Beulich
2018-09-13 09:44:29 UTC
Permalink
Only one of them can be set at a time, which means they can be expressed
by a single 2-bit field instead of three 1-bit ones.

gas/
2018-09-13 Jan Beulich <***@suse.com>

* config/tc-i386.c (parse_insn, process_suffix): Replace
opcode_modifier.size<N> uses.

opcodes/
2018-09-13 Jan Beulich <***@suse.com>

* i386-gen.c (opcode_modifiers): Drop Size16, Size32, and
Size64. Add Size.
* i386-opc.h (Size16, Size32, Size64): Delete.
(Size): New.
(SIZE16, SIZE32, SIZE64): Define.
(struct i386_opcode_modifier): Drop size16, size32, and size64.
Add size.
* i386-opc.tbl (Size16, Size32, Size64): Define.
* i386-tbl.h: Re-generate.

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -4444,10 +4444,10 @@ parse_insn (char *line, char *mnemonic)
}
/* If we are in 16-bit mode, do not allow addr16 or data16.
Similarly, in 32-bit mode, do not allow addr32 or data32. */
- if ((current_templates->start->opcode_modifier.size16
- || current_templates->start->opcode_modifier.size32)
+ if ((current_templates->start->opcode_modifier.size == SIZE16
+ || current_templates->start->opcode_modifier.size == SIZE32)
&& flag_code != CODE_64BIT
- && (current_templates->start->opcode_modifier.size32
+ && ((current_templates->start->opcode_modifier.size == SIZE32)
^ (flag_code == CODE_16BIT)))
{
as_bad (_("redundant %s prefix"),
@@ -6039,11 +6039,11 @@ process_suffix (void)
{
/* If matched instruction specifies an explicit instruction mnemonic
suffix, use it. */
- if (i.tm.opcode_modifier.size16)
+ if (i.tm.opcode_modifier.size == SIZE16)
i.suffix = WORD_MNEM_SUFFIX;
- else if (i.tm.opcode_modifier.size32)
+ else if (i.tm.opcode_modifier.size == SIZE32)
i.suffix = LONG_MNEM_SUFFIX;
- else if (i.tm.opcode_modifier.size64)
+ else if (i.tm.opcode_modifier.size == SIZE64)
i.suffix = QWORD_MNEM_SUFFIX;
else if (i.reg_operands)
{
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -612,9 +612,7 @@ static bitfield opcode_modifiers[] =
BITFIELD (JumpInterSegment),
BITFIELD (FloatMF),
BITFIELD (FloatR),
- BITFIELD (Size16),
- BITFIELD (Size32),
- BITFIELD (Size64),
+ BITFIELD (Size),
BITFIELD (CheckRegSize),
BITFIELD (IgnoreSize),
BITFIELD (DefaultSize),
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -399,11 +399,12 @@ enum
/* src/dest swap for floats. */
FloatR,
/* needs size prefix if in 32-bit mode */
- Size16,
+#define SIZE16 1
/* needs size prefix if in 16-bit mode */
- Size32,
+#define SIZE32 2
/* needs size prefix if in 64-bit mode */
- Size64,
+#define SIZE64 3
+ Size,
/* check register size. */
CheckRegSize,
/* instruction ignores operand size prefix and in Intel mode ignores
@@ -625,9 +626,7 @@ typedef struct i386_opcode_modifier
unsigned int jumpintersegment:1;
unsigned int floatmf:1;
unsigned int floatr:1;
- unsigned int size16:1;
- unsigned int size32:1;
- unsigned int size64:1;
+ unsigned int size:2;
unsigned int checkregsize:1;
unsigned int ignoresize:1;
unsigned int defaultsize:1;
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -22,6 +22,10 @@
#include "i386-opc.h"
#undef None

+#define Size16 Size=SIZE16
+#define Size32 Size=SIZE32
+#define Size64 Size=SIZE64
+
### MARKER ###

// Move instructions.
H.J. Lu
2018-09-13 13:27:36 UTC
Permalink
Post by Jan Beulich
1: fold CRC32 templates
2: fold Size{16,32,64} template attributes
OK. Thanks.
--
H.J.
Loading...