aboutsummaryrefslogtreecommitdiff
path: root/i386-asm.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2017-02-23 00:16:25 +0100
committerMichael Matz <matz@suse.de>2017-02-23 00:16:25 +0100
commit3e4c296ebab341bbe95974e39b589ea821f02789 (patch)
treeec59975e207493bcaa76ff47dc8d151553db8bc4 /i386-asm.c
parente209b7dac463e228525499153103ec28173ca365 (diff)
downloadtinycc-3e4c296ebab341bbe95974e39b589ea821f02789.tar.gz
tinycc-3e4c296ebab341bbe95974e39b589ea821f02789.tar.bz2
x86-64-asm: Fix mov im64,rax encoding
the avoidance of mov im32->reg64 wasn't working when reg64 was rax. While fixing this also fix instructions which had the REX prefix hardcoded in opcode and so didn't support extended registers which would have added another REX prefix.
Diffstat (limited to 'i386-asm.c')
-rw-r--r--i386-asm.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/i386-asm.c b/i386-asm.c
index 5011af5..0c0985e 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -42,6 +42,7 @@
#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
#define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */
+#define OPC_48 0x200 /* Always has REX prefix */
#ifdef TCC_TARGET_X86_64
# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */
# define OPC_BWLQ (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
@@ -785,7 +786,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
should only be done if we really have an >32bit imm64, and that
is hardcoded. Ignore it here. */
if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
- && ops[1].type == OP_REG64
+ && (ops[1].type & OP_REG) == OP_REG64
&& !(pa->instr_type & OPC_0F))
continue;
#endif
@@ -901,14 +902,16 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
g(0x66);
#ifdef TCC_TARGET_X86_64
rex64 = 0;
- if (s == 3 || (alltypes & OP_REG64)) {
+ if (pa->instr_type & OPC_48)
+ rex64 = 1;
+ else if (s == 3 || (alltypes & OP_REG64)) {
/* generate REX prefix */
int default64 = 0;
for(i = 0; i < nb_ops; i++) {
- if (op_type[i] == OP_REG64) {
+ if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
/* If only 64bit regs are accepted in one operand
this is a default64 instruction without need for
- REX prefixes. */
+ REX prefixes, except for movabs(0xb8). */
default64 = 1;
break;
}