x86-asm: Add more SSE2 instructions

In particular those that are extensions of existing mmx (or sse1)
instructions by a simple 0x66 prefix.  There's one caveat for
x86-64: as we don't yet correctly handle the 0xf3 prefix
the movq mem64->xmm is wrong (tested in asmtest.S).  Needs
some refactoring of the instr_type member.
This commit is contained in:
Michael Matz
2016-05-15 06:54:42 +02:00
parent 2b7ee000cd
commit ed35ac841b
4 changed files with 257 additions and 119 deletions

View File

@ -27,7 +27,7 @@
#define TOK_ASM_first TOK_ASM_clc
#define TOK_ASM_last TOK_ASM_emms
#define TOK_ASM_alllast TOK_ASM_pxor
#define TOK_ASM_alllast TOK_ASM_subps
#define OPC_JMP 0x01 /* jmp operand */
#define OPC_B 0x02 /* only used with OPC_WL */
@ -89,6 +89,7 @@ enum {
OPT_REG, /* REG8 | REG16 | REG32 | REG64 */
OPT_REGW, /* REG16 | REG32 | REG64 */
OPT_IMW, /* IM16 | IM32 */
OPT_MMXSSE, /* MMX | SSE */
/* can be ored with any OPT_xxx */
OPT_EA = 0x80
};
@ -512,6 +513,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
int op_type[3]; /* decoded op type */
int alltypes; /* OR of all operand types */
int autosize;
int p66;
/* force synthetic ';' after prefix instruction, so we can handle */
/* one-line things like "rep stosb" instead of only "rep\nstosb" */
@ -630,6 +632,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
case OPT_IMW:
v = OP_IM16 | OP_IM32;
break;
case OPT_MMXSSE:
v = OP_MMX | OP_SSE;
break;
default:
v = 1 << op2;
break;
@ -693,7 +698,19 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
}
#endif
/* generate data16 prefix if needed */
p66 = 0;
if (s == 1 || (pa->instr_type & OPC_D16))
p66 = 1;
else {
/* accepting mmx+sse in all operands --> needs 0x66 to
switch to sse mode. Accepting only sse in an operand --> is
already SSE insn and needs 0x66/f2/f3 handling. */
for (i = 0; i < nb_ops; i++)
if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
&& ops[i].type & OP_SSE)
p66 = 1;
}
if (p66)
g(0x66);
#ifdef TCC_TARGET_X86_64
if (s == 3 || (alltypes & OP_REG64)) {