aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2007-04-18 16:13:15 +0000
committerH.J. Lu <hjl.tools@gmail.com>2007-04-18 16:13:15 +0000
commit42903f7f5903fc4a27294aab1e23708c59a86b17 (patch)
tree5e5e5c86c160605d02c3bd5d9663b0faf1776893 /gas/config
parent026d3abbb22d4ac067a57d0a9aa2b2482266c9e7 (diff)
downloadgdb-42903f7f5903fc4a27294aab1e23708c59a86b17.zip
gdb-42903f7f5903fc4a27294aab1e23708c59a86b17.tar.gz
gdb-42903f7f5903fc4a27294aab1e23708c59a86b17.tar.bz2
gas/
2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * config/tc-i386.c (cpu_arch): Add .sse4.1. (process_operands): Adjust implicit operand for blendvpd, blendvps and pblendvb in SSE4.1. (output_insn): Support SSE4.1. gas/testsuite/ 2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * gas/i386/i386.exp: Add sse4.1 and x86-64-sse4.1. * gas/i386/sse4_1.d: New file. * gas/i386/sse4_1.s: Likewise. * gas/i386/x86-64-sse4_1.d: Likewise. * gas/i386/x86-64-sse4_1.s: Likewise. opcodes/ 2007-04-18 H.J. Lu <hongjiu.lu@intel.com> * i386-dis.c (XMM_Fixup): New. (Edqb): New. (Edqd): New. (XMM0): New. (dqb_mode): New. (dqd_mode): New. (PREGRP39 ... PREGRP85): New. (threebyte_0x38_uses_DATA_prefix): Updated for SSE4. (threebyte_0x3a_uses_DATA_prefix): Likewise. (prefix_user_table): Add PREGRP39 ... PREGRP85. (three_byte_table): Likewise. (putop): Handle 'K'. (intel_operand_size): Handle dqb_mode, dqd_mode): (OP_E): Likewise. (OP_G): Likewise. * i386-opc.c (i386_optab): Add SSE4.1 opcodes. * i386-opc.h (CpuSSE4_1): New. (CpuUnknownFlags): Add CpuSSE4_1. (regKludge): Update comment.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-i386.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index b70396d..6ee4010 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -498,6 +498,8 @@ static const arch_entry cpu_arch[] =
CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3},
{".ssse3", PROCESSOR_UNKNOWN,
CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3},
+ {".sse4.1", PROCESSOR_UNKNOWN,
+ CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuSSSE3|CpuSSE4_1},
{".3dnow", PROCESSOR_UNKNOWN,
CpuMMX|Cpu3dnow},
{".3dnowa", PROCESSOR_UNKNOWN,
@@ -3277,14 +3279,47 @@ process_operands (void)
is converted into xor %reg, %reg. */
if (i.tm.opcode_modifier & regKludge)
{
- unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
- /* Pretend we saw the extra register operand. */
- assert (i.reg_operands == 1
- && i.op[first_reg_op + 1].regs == 0);
- i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
- i.types[first_reg_op + 1] = i.types[first_reg_op];
- i.operands++;
- i.reg_operands++;
+ if ((i.tm.cpu_flags & CpuSSE4_1))
+ {
+ /* The first operand in instruction blendvpd, blendvps and
+ pblendvb in SSE4.1 is implicit and must be xmm0. */
+ assert (i.operands == 3
+ && i.reg_operands >= 2
+ && i.types[0] == RegXMM);
+ if (i.op[0].regs->reg_num != 0)
+ {
+ if (intel_syntax)
+ as_bad (_("the last operand of `%s' must be `%sxmm0'"),
+ i.tm.name, register_prefix);
+ else
+ as_bad (_("the first operand of `%s' must be `%sxmm0'"),
+ i.tm.name, register_prefix);
+ return 0;
+ }
+ i.op[0] = i.op[1];
+ i.op[1] = i.op[2];
+ i.types[0] = i.types[1];
+ i.types[1] = i.types[2];
+ i.operands--;
+ i.reg_operands--;
+
+ /* We need to adjust fields in i.tm since they are used by
+ build_modrm_byte. */
+ i.tm.operand_types [0] = i.tm.operand_types [1];
+ i.tm.operand_types [1] = i.tm.operand_types [2];
+ i.tm.operands--;
+ }
+ else
+ {
+ unsigned int first_reg_op = (i.types[0] & Reg) ? 0 : 1;
+ /* Pretend we saw the extra register operand. */
+ assert (i.reg_operands == 1
+ && i.op[first_reg_op + 1].regs == 0);
+ i.op[first_reg_op + 1].regs = i.op[first_reg_op].regs;
+ i.types[first_reg_op + 1] = i.types[first_reg_op];
+ i.operands++;
+ i.reg_operands++;
+ }
}
if (i.tm.opcode_modifier & ShortForm)
@@ -3893,11 +3928,10 @@ output_insn (void)
unsigned char *q;
unsigned int prefix;
- /* All opcodes on i386 have either 1 or 2 bytes. Supplemental
- Streaming SIMD extensions 3 Instructions have 3 bytes. We may
- use one more higher byte to specify a prefix the instruction
- requires. */
- if ((i.tm.cpu_flags & CpuSSSE3) != 0)
+ /* All opcodes on i386 have either 1 or 2 bytes. SSSE3 and
+ SSE4.1 instructions have 3 bytes. We may use one more higher
+ byte to specify a prefix the instruction requires. */
+ if ((i.tm.cpu_flags & (CpuSSSE3 | CpuSSE4_1)) != 0)
{
if (i.tm.base_opcode & 0xff000000)
{
@@ -3938,7 +3972,7 @@ output_insn (void)
}
else
{
- if ((i.tm.cpu_flags & CpuSSSE3) != 0)
+ if ((i.tm.cpu_flags & (CpuSSSE3 | CpuSSE4_1)) != 0)
{
p = frag_more (3);
*p++ = (i.tm.base_opcode >> 16) & 0xff;