tccasm: Accept suffixed cmovCC

The length suffix for cmovCC isn't necessary as the required register
operands always allow length deduction.  But let's be nice to users
and accept them anyway.  Do that without blowing up tables, which means
we don't detect invalid suffixes for the given operands, but so be it.
master
Michael Matz 2017-12-03 04:53:50 +01:00
parent 9e0d23cc47
commit 529b44c0d5
2 changed files with 17 additions and 4 deletions

View File

@ -727,6 +727,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
s = 0; /* avoid warning */ s = 0; /* avoid warning */
again:
/* optimize matching by using a lookup table (no hashing is needed /* optimize matching by using a lookup table (no hashing is needed
!) */ !) */
for(pa = asm_instrs; pa->sym != 0; pa++) { for(pa = asm_instrs; pa->sym != 0; pa++) {
@ -757,8 +758,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
continue; continue;
/* cmovxx is a test opcode but accepts multiple sizes. /* cmovxx is a test opcode but accepts multiple sizes.
TCC doesn't accept the suffixed mnemonic, instead we The suffixes aren't encoded in the table, instead we
simply force size autodetection always. */ simply force size autodetection always and deal with suffixed
variants below when we don't find e.g. "cmovzl". */
if (pa->instr_type & OPC_WLX) if (pa->instr_type & OPC_WLX)
s = NBWLX - 1; s = NBWLX - 1;
} else if (pa->instr_type & OPC_B) { } else if (pa->instr_type & OPC_B) {
@ -844,8 +846,16 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
tcc_error("bad operand with opcode '%s'", tcc_error("bad operand with opcode '%s'",
get_tok_str(opcode, NULL)); get_tok_str(opcode, NULL));
} else { } else {
tcc_error("unknown opcode '%s'", /* Special case for cmovcc, we accept size suffixes but ignore
get_tok_str(opcode, NULL)); them, but we don't want them to blow up our tables. */
TokenSym *ts = table_ident[opcode - TOK_IDENT];
if (ts->len >= 6
&& strchr("wlq", ts->str[ts->len-1])
&& !memcmp(ts->str, "cmov", 4)) {
opcode = tok_alloc(ts->str, ts->len-1)->tok;
goto again;
}
tcc_error("unknown opcode '%s'", ts->str);
} }
} }
/* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */

View File

@ -577,10 +577,13 @@ fucomip %st(5), %st
cmovs 0x1000, %eax cmovs 0x1000, %eax
cmovns %edx, %edi cmovns %edx, %edi
cmovne %ax, %si cmovne %ax, %si
cmovbw %ax, %di
cmovnbel %edx, %ecx
#ifdef __x86_64__ #ifdef __x86_64__
bswapq %rsi bswapq %rsi
bswapq %r10 bswapq %r10
cmovz %rdi,%rbx cmovz %rdi,%rbx
cmovpeq %rsi, %rdx
#endif #endif
int $3 int $3