summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--68kinst.c137
-rw-r--r--68kinst.h4
-rw-r--r--gen_x86.c207
-rw-r--r--gen_x86.h22
-rw-r--r--test_x86.c12
5 files changed, 169 insertions, 213 deletions
diff --git a/68kinst.c b/68kinst.c
index 694b7fa..1171aca 100644
--- a/68kinst.c
+++ b/68kinst.c
@@ -39,12 +39,12 @@ uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t si
case 0:
dst->addr_mode = MODE_ABSOLUTE_SHORT;
ext = *(++cur);
- dst->params.u32 = sign_extend16(ext);
+ dst->params.immed = sign_extend16(ext);
break;
case 1:
dst->addr_mode = MODE_ABSOLUTE;
ext = *(++cur);
- dst->params.u32 = ext << 16 | *(++cur);
+ dst->params.immed = ext << 16 | *(++cur);
break;
case 2:
dst->addr_mode = MODE_PC_DISPLACE;
@@ -57,13 +57,13 @@ uint16_t *m68k_decode_op_ex(uint16_t *cur, uint8_t mode, uint8_t reg, uint8_t si
switch (size)
{
case OPSIZE_BYTE:
- dst->params.u8 = ext;
+ dst->params.immed = ext & 0xFF;
break;
case OPSIZE_WORD:
- dst->params.u16 = ext;
+ dst->params.immed = ext;
break;
case OPSIZE_LONG:
- dst->params.u32 = ext << 16 | *(++cur);
+ dst->params.immed = ext << 16 | *(++cur);
break;
}
break;
@@ -145,7 +145,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
opmode = (*istream >> 3) & 0x7;
reg = *istream & 0x7;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
decoded->extra.size = OPSIZE_BYTE;
istream = m68k_decode_op_ex(istream, opmode, reg, OPSIZE_BYTE, &(decoded->dst));
} else if ((*istream & 0xC0) == 0xC0) {
@@ -160,12 +160,12 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->op = M68K_ORI_CCR;
decoded->extra.size = OPSIZE_BYTE;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
} else if((*istream & 0xFF) == 0x7C) {
decoded->op = M68K_ORI_SR;
decoded->extra.size = OPSIZE_WORD;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
} else {
decoded->op = M68K_OR;
decoded->variant = VAR_IMMEDIATE;
@@ -176,14 +176,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = immed << 16 | *(++istream);
+ decoded->src.params.immed = immed << 16 | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -195,12 +195,12 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->op = M68K_ANDI_CCR;
decoded->extra.size = OPSIZE_BYTE;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
} else if((*istream & 0xFF) == 0x7C) {
decoded->op = M68K_ANDI_SR;
decoded->extra.size = OPSIZE_WORD;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
} else {
decoded->op = M68K_AND;
decoded->variant = VAR_IMMEDIATE;
@@ -211,14 +211,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = immed << 16 | *(++istream);
+ decoded->src.params.immed = immed << 16 | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -234,14 +234,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = immed << 16 | *(++istream);
+ decoded->src.params.immed = immed << 16 | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -256,14 +256,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = immed << 16 | *(++istream);
+ decoded->src.params.immed = immed << 16 | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -286,7 +286,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
break;
}
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
break;
case 5:
@@ -295,12 +295,12 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->op = M68K_EORI_CCR;
decoded->extra.size = OPSIZE_BYTE;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
} else if((*istream & 0xFF) == 0x7C) {
decoded->op = M68K_EORI_SR;
decoded->extra.size = OPSIZE_WORD;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
} else {
decoded->op = M68K_EOR;
decoded->variant = VAR_IMMEDIATE;
@@ -311,14 +311,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = immed << 16 | *(++istream);
+ decoded->src.params.immed = immed << 16 | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -334,14 +334,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
switch (decoded->extra.size)
{
case OPSIZE_BYTE:
- decoded->src.params.u8 = *(++istream);
+ decoded->src.params.immed = *(++istream) & 0xFF;
break;
case OPSIZE_WORD:
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
break;
case OPSIZE_LONG:
immed = *(++istream);
- decoded->src.params.u32 = (immed << 16) | *(++istream);
+ decoded->src.params.immed = (immed << 16) | *(++istream);
break;
}
istream = m68k_decode_op_ex(istream, opmode, reg, size, &(decoded->dst));
@@ -411,11 +411,11 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
immed = *(++istream);
if(*istream & 0x400) {
decoded->dst.addr_mode = MODE_REG;
- decoded->dst.params.u16 = immed;
+ decoded->dst.params.immed = immed;
istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->src));
} else {
decoded->src.addr_mode = MODE_REG;
- decoded->src.params.u16 = immed;
+ decoded->src.params.immed = immed;
istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
}
} else {
@@ -497,7 +497,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->op = M68K_BKPT;
decoded->src.addr_mode = MODE_IMMEDIATE;
decoded->extra.size = OPSIZE_UNSIZED;
- decoded->src.params.u32 = *istream & 0x7;
+ decoded->src.params.immed = *istream & 0x7;
#endif
break;
case 0x10:
@@ -573,7 +573,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->op = M68K_TRAP;
decoded->extra.size = OPSIZE_UNSIZED;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u32 = *istream & 0xF;
+ decoded->src.params.immed = *istream & 0xF;
break;
case 2:
//LINK.w
@@ -582,7 +582,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->src.addr_mode = MODE_AREG;
decoded->src.params.regs.pri = *istream & 0x7;
decoded->dst.addr_mode = MODE_IMMEDIATE;
- decoded->dst.params.u16 = *(++istream);
+ decoded->dst.params.immed = *(++istream);
break;
case 3:
//UNLK
@@ -616,7 +616,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
case 2:
decoded->op = M68K_STOP;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u32 =*(++istream);
+ decoded->src.params.immed =*(++istream);
break;
case 3:
decoded->op = M68K_RTE;
@@ -625,7 +625,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
#ifdef M68010
decoded->op = M68K_RTD;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u32 =*(++istream);
+ decoded->src.params.immed =*(++istream);
#endif
break;
case 5:
@@ -662,7 +662,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
case 1: //DBcc
decoded->op = M68K_DBCC;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u16 = *(++istream);
+ decoded->src.params.immed = *(++istream);
decoded->dst.addr_mode = MODE_REG;
decoded->dst.params.regs.pri = *istream & 0x7;
break;
@@ -688,18 +688,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
if (!immed) {
immed = 8;
}
- switch (size)
- {
- case OPSIZE_BYTE:
- decoded->src.params.u8 = immed;
- break;
- case OPSIZE_WORD:
- decoded->src.params.u16 = immed;
- break;
- case OPSIZE_LONG:
- decoded->src.params.u32 = immed;
- break;
- }
+ decoded->src.params.immed = immed;
if (*istream & 0x100) {
decoded->op = M68K_SUB;
} else {
@@ -724,13 +713,14 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
decoded->variant = VAR_BYTE;
immed = sign_extend8(immed);
}
- decoded->src.params.u32 = immed;
+ decoded->src.params.immed = immed;
break;
case MOVEQ:
decoded->op = M68K_MOVE;
decoded->variant = VAR_QUICK;
+ decoded->extra.size = OPSIZE_LONG;
decoded->src.addr_mode = MODE_IMMEDIATE;
- decoded->src.params.u32 = sign_extend8(*istream & 0xFF);
+ decoded->src.params.immed = sign_extend8(*istream & 0xFF);
decoded->dst.addr_mode = MODE_REG;
decoded->dst.params.regs.pri = m68K_reg_quick_field(*istream);
immed = *istream & 0xFF;
@@ -1012,18 +1002,7 @@ uint16_t * m68K_decode(uint16_t * istream, m68kinst * decoded)
immed = (*istream >> 9) & 0x7;
if (*istream & 0x100) {
decoded->src.addr_mode = MODE_IMMEDIATE;
- switch(decoded->extra.size)
- {
- case OPSIZE_BYTE:
- decoded->src.params.u8 = immed;
- break;
- case OPSIZE_WORD:
- decoded->src.params.u16 = immed;
- break;
- case OPSIZE_LONG:
- decoded->src.params.u32 = immed;
- break;
- }
+ decoded->src.params.immed = immed;
} else {
decoded->src.addr_mode = MODE_REG;
decoded->src.params.regs.pri = immed;
@@ -1136,7 +1115,7 @@ char * cond_mnem[] = {
"le"
};
-int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comma)
+int m68k_disasm_op(m68k_op_info *decoded, char *dst, int need_comma)
{
char * c = need_comma ? "," : "";
switch(decoded->addr_mode)
@@ -1154,11 +1133,11 @@ int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comm
case MODE_AREG_DISPLACE:
return sprintf(dst, "%s (a%d, %d)", c, decoded->params.regs.pri, decoded->params.regs.displacement);
case MODE_IMMEDIATE:
- return sprintf(dst, "%s #%d", c, (size == OPSIZE_LONG || size == OPSIZE_UNSIZED) ? decoded->params.u32 : (size == OPSIZE_WORD ? decoded->params.u16 : decoded->params.u8));
+ return sprintf(dst, "%s #%d", c, decoded->params.immed);
case MODE_ABSOLUTE_SHORT:
- return sprintf(dst, "%s $%X.w", c, decoded->params.u32);
+ return sprintf(dst, "%s $%X.w", c, decoded->params.immed);
case MODE_ABSOLUTE:
- return sprintf(dst, "%s $%X", c, decoded->params.u32);
+ return sprintf(dst, "%s $%X", c, decoded->params.immed);
case MODE_PC_DISPLACE:
return sprintf(dst, "%s (pc, %d)", c, decoded->params.regs.displacement);
default:
@@ -1166,7 +1145,7 @@ int m68k_disasm_op(m68k_op_info *decoded, uint8_t size, char *dst, int need_comm
}
}
-int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t size, char *dst, int need_comma)
+int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, char *dst, int need_comma)
{
int8_t dir, reg, bit, regnum, last=-1, lastreg, first=-1;
char *rtype, *last_rtype;
@@ -1181,7 +1160,7 @@ int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t siz
}
strcat(dst, " ");
for (oplen = 1, reg=0; bit < 16 && bit > -1; bit += dir, reg++) {
- if (decoded->params.u16 & (1 << bit)) {
+ if (decoded->params.immed & (1 << bit)) {
if (reg > 7) {
rtype = "a";
regnum = reg - 8;
@@ -1214,7 +1193,7 @@ int m68k_disasm_movem_op(m68k_op_info *decoded, m68k_op_info *other, uint8_t siz
}
return oplen;
} else {
- return m68k_disasm_op(decoded, size, dst, need_comma);
+ return m68k_disasm_op(decoded, dst, need_comma);
}
}
@@ -1233,16 +1212,14 @@ int m68k_disasm(m68kinst * decoded, char * dst)
dst[ret] = 0;
strcat(dst, cond_mnem[decoded->extra.cond]);
ret = strlen(dst);
- size = decoded->op = M68K_BCC ? OPSIZE_LONG : OPSIZE_WORD;
break;
case M68K_BSR:
- size = OPSIZE_LONG;
ret = sprintf(dst, "bsr%s", decoded->variant == VAR_BYTE ? ".s" : "");
break;
case M68K_MOVE_FROM_SR:
ret = sprintf(dst, "%s", mnemonics[decoded->op]);
ret += sprintf(dst + ret, " SR");
- ret += m68k_disasm_op(&(decoded->dst), decoded->extra.size, dst + ret, 1);
+ ret += m68k_disasm_op(&(decoded->dst), dst + ret, 1);
return ret;
case M68K_ANDI_SR:
case M68K_EORI_SR:
@@ -1254,7 +1231,7 @@ int m68k_disasm(m68kinst * decoded, char * dst)
case M68K_MOVE_CCR:
case M68K_ORI_CCR:
ret = sprintf(dst, "%s", mnemonics[decoded->op]);
- ret += m68k_disasm_op(&(decoded->src), decoded->extra.size, dst + ret, 0);
+ ret += m68k_disasm_op(&(decoded->src), dst + ret, 0);
ret += sprintf(dst + ret, ", %s", special_op);
return ret;
default:
@@ -1265,13 +1242,13 @@ int m68k_disasm(m68kinst * decoded, char * dst)
size == OPSIZE_BYTE ? ".b" : (size == OPSIZE_WORD ? ".w" : (size == OPSIZE_LONG ? ".l" : "")));
}
if (decoded->op == M68K_MOVEM) {
- op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), size, dst + ret, 0);
+ op1len = m68k_disasm_movem_op(&(decoded->src), &(decoded->dst), dst + ret, 0);
ret += op1len;
- ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), size, dst + ret, op1len);
+ ret += m68k_disasm_movem_op(&(decoded->dst), &(decoded->src), dst + ret, op1len);
} else {
- op1len = m68k_disasm_op(&(decoded->src), size, dst + ret, 0);
+ op1len = m68k_disasm_op(&(decoded->src), dst + ret, 0);
ret += op1len;
- ret += m68k_disasm_op(&(decoded->dst), size, dst + ret, op1len);
+ ret += m68k_disasm_op(&(decoded->dst), dst + ret, op1len);
}
return ret;
}
diff --git a/68kinst.h b/68kinst.h
index 8b5a089..842ab12 100644
--- a/68kinst.h
+++ b/68kinst.h
@@ -158,9 +158,7 @@ typedef struct {
uint8_t sec;
int32_t displacement;
} regs;
- uint8_t u8;
- uint16_t u16;
- uint32_t u32;
+ uint32_t immed;
} params;
} m68k_op_info;
diff --git a/gen_x86.c b/gen_x86.c
index 6dcc444..1b0bed9 100644
--- a/gen_x86.c
+++ b/gen_x86.c
@@ -29,6 +29,7 @@
#define OP_MOV_I8R 0xB0
#define OP_MOV_IR 0xB8
#define OP_RETN 0xC3
+#define OP_MOV_IEA 0xC6
#define OP_CALL 0xE8
#define OP_CALL_EA 0xFF
@@ -197,79 +198,77 @@ uint8_t * x86_rrind_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_t
return out;
}
-uint8_t * x86_i8r(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, uint8_t val, uint8_t dst)
-{
- if (dst == RAX) {
- *(out++) = al_opcode | BIT_IMMED_RAX;
- } else {
- if (dst >= AH && dst <= BH) {
- dst -= (AH-X86_AH);
- } else if(dst >= R8) {
- *(out++) = PRE_REX | REX_RM_FIELD;
- }
- *(out++) = opcode;
- *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3);
- }
- *(out++) = val;
- return out;
-}
-
-uint8_t * x86_i32r(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst)
+uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size)
{
uint8_t sign_extend = 0;
- if (val <= 0x7F && val >= -0x80) {
+ if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) {
sign_extend = 1;
opcode |= BIT_DIR;
}
+ if (size == SZ_W) {
+ *(out++) = PRE_SIZE;
+ }
if (dst == RAX && !sign_extend) {
- *(out++) = al_opcode | BIT_IMMED_RAX | BIT_SIZE;
+ if (size != SZ_B) {
+ al_opcode |= BIT_SIZE;
+ if (size == SZ_Q) {
+ *out = PRE_REX | REX_QUAD;
+ }
+ }
+ *(out++) = al_opcode | BIT_IMMED_RAX;
} else {
- if(dst >= R8) {
- *(out++) = PRE_REX | REX_RM_FIELD;
+ if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) {
+ *out = PRE_REX;
+ if (size == SZ_Q) {
+ *out |= REX_QUAD;
+ }
+ if (dst >= R8) {
+ *out |= REX_RM_FIELD;
+ dst -= (R8 - X86_R8);
+ }
+ out++;
}
- *(out++) = opcode | BIT_SIZE;
+ if (dst >= AH && dst <= BH) {
+ dst -= (AH-X86_AH);
+ }
+ if (size != SZ_B) {
+ opcode |= BIT_SIZE;
+ }
+ *(out++) = opcode;
*(out++) = MODE_REG_DIRECT | dst | (op_ex << 3);
}
*(out++) = val;
- if (!sign_extend) {
- val >>= 8;
- *(out++) = val;
- val >>= 8;
- *(out++) = val;
+ if (size != SZ_B && !sign_extend) {
val >>= 8;
*(out++) = val;
+ if (size != SZ_W) {
+ val >>= 8;
+ *(out++) = val;
+ val >>= 8;
+ *(out++) = val;
+ }
}
return out;
}
+
uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
{
return x86_rr_sizedir(out, OP_ADD, src, dst, size);
}
-uint8_t * add_i8r(uint8_t * out, uint8_t val, uint8_t dst)
-{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst);
-}
-
-uint8_t * add_i32r(uint8_t * out, int32_t val, uint8_t dst)
+uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size);
}
uint8_t * or_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
{
return x86_rr_sizedir(out, OP_OR, src, dst, size);
}
-
-uint8_t * or_i8r(uint8_t * out, uint8_t val, uint8_t dst)
-{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst);
-}
-
-uint8_t * or_i32r(uint8_t * out, int32_t val, uint8_t dst)
+uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size);
}
uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
@@ -277,14 +276,9 @@ uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
return x86_rr_sizedir(out, OP_AND, src, dst, size);
}
-uint8_t * and_i8r(uint8_t * out, uint8_t val, uint8_t dst)
+uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst);
-}
-
-uint8_t * and_i32r(uint8_t * out, int32_t val, uint8_t dst)
-{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size);
}
uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
@@ -292,14 +286,9 @@ uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
return x86_rr_sizedir(out, OP_XOR, src, dst, size);
}
-uint8_t * xor_i8r(uint8_t * out, uint8_t val, uint8_t dst)
-{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst);
-}
-
-uint8_t * xor_i32r(uint8_t * out, int32_t val, uint8_t dst)
+uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size);
}
uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
@@ -307,30 +296,19 @@ uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
return x86_rr_sizedir(out, OP_SUB, src, dst, size);
}
-uint8_t * sub_i8r(uint8_t * out, uint8_t val, uint8_t dst)
+uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size);
}
-uint8_t * sub_i32r(uint8_t * out, int32_t val, uint8_t dst)
-{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst);
-}
-
-
uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
{
return x86_rr_sizedir(out, OP_CMP, src, dst, size);
}
-uint8_t * cmp_i8r(uint8_t * out, uint8_t val, uint8_t dst)
-{
- return x86_i8r(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst);
-}
-
-uint8_t * cmp_i32r(uint8_t * out, int32_t val, uint8_t dst)
+uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size)
{
- return x86_i32r(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst);
+ return x86_ir(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size);
}
uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
@@ -358,49 +336,58 @@ uint8_t * mov_rindr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
return x86_rrind_sizedir(out, OP_MOV, dst, src, size, BIT_DIR);
}
-uint8_t * mov_i8r(uint8_t * out, uint8_t val, uint8_t dst)
-{
+uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size)
+{
+ uint8_t sign_extend = 0;
+ if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) {
+ sign_extend = 1;
+ }
+ if (size == SZ_W) {
+ *(out++) = PRE_SIZE;
+ }
+ if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) {
+ *out = PRE_REX;
+ if (size == SZ_Q) {
+ *out |= REX_QUAD;
+ }
+ if (dst >= R8) {
+ *out |= REX_RM_FIELD;
+ dst -= (R8 - X86_R8);
+ }
+ out++;
+ }
if (dst >= AH && dst <= BH) {
- dst -= AH - X86_AH;
- } else if (dst >= RSP && dst <= RDI) {
- *(out++) = PRE_REX;
- } else if (dst >= R8) {
- *(out++) = PRE_REX | REX_RM_FIELD;
- dst -= R8 - X86_R8;
+ dst -= (AH-X86_AH);
}
- *(out++) = OP_MOV_I8R | dst;
- *(out++) = val;
- return out;
-}
-
-uint8_t * mov_i16r(uint8_t * out, uint16_t val, uint8_t dst)
-{
- *(out++) = PRE_SIZE;
- if (dst >= R8) {
- *(out++) = PRE_REX | REX_RM_FIELD;
- dst -= R8 - X86_R8;
+ if (size == SZ_B) {
+ *(out++) = OP_MOV_I8R;
+ } else if (size == SZ_Q && sign_extend) {
+ *(out++) = OP_MOV_IEA | BIT_SIZE;
+ *(out++) = MODE_REG_DIRECT | dst;
+ } else {
+ *(out++) = OP_MOV_IR;
}
- *(out++) = OP_MOV_IR | dst;
*(out++) = val;
- val >>= 8;
- *(out++) = val;
- return out;
-}
-
-uint8_t * mov_i32r(uint8_t * out, uint32_t val, uint8_t dst)
-{
- if (dst >= R8) {
- *(out++) = PRE_REX | REX_RM_FIELD;
- dst -= R8 - X86_R8;
+ if (size != SZ_B) {
+ val >>= 8;
+ *(out++) = val;
+ if (size != SZ_W) {
+ val >>= 8;
+ *(out++) = val;
+ val >>= 8;
+ *(out++) = val;
+ if (size == SZ_Q && !sign_extend) {
+ val >>= 8;
+ *(out++) = val;
+ val >>= 8;
+ *(out++) = val;
+ val >>= 8;
+ *(out++) = val;
+ val >>= 8;
+ *(out++) = val;
+ }
+ }
}
- *(out++) = OP_MOV_IR | dst;
- *(out++) = val;
- val >>= 8;
- *(out++) = val;
- val >>= 8;
- *(out++) = val;
- val >>= 8;
- *(out++) = val;
return out;
}
diff --git a/gen_x86.h b/gen_x86.h
index c240919..b566508 100644
--- a/gen_x86.h
+++ b/gen_x86.h
@@ -58,26 +58,18 @@ uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
-uint8_t * add_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * or_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * xor_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * and_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * sub_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * cmp_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * add_i32r(uint8_t * out, int32_t val, uint8_t dst);
-uint8_t * or_i32r(uint8_t * out, int32_t val, uint8_t dst);
-uint8_t * xor_i32r(uint8_t * out, int32_t val, uint8_t dst);
-uint8_t * and_i32r(uint8_t * out, int32_t val, uint8_t dst);
-uint8_t * sub_i32r(uint8_t * out, int32_t val, uint8_t dst);
-uint8_t * cmp_i32r(uint8_t * out, int32_t val, uint8_t dst);
+uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
+uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
+uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
+uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
+uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
+uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size);
uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
uint8_t * mov_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size);
uint8_t * mov_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size);
uint8_t * mov_rrind(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
uint8_t * mov_rindr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size);
-uint8_t * mov_i8r(uint8_t * out, uint8_t val, uint8_t dst);
-uint8_t * mov_i16r(uint8_t * out, uint16_t val, uint8_t dst);
-uint8_t * mov_i32r(uint8_t * out, uint32_t val, uint8_t dst);
+uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size);
uint8_t * pushf(uint8_t * out);
uint8_t * popf(uint8_t * out);
uint8_t * push_r(uint8_t * out, uint8_t reg);
diff --git a/test_x86.c b/test_x86.c
index 05acd27..bad0e1e 100644
--- a/test_x86.c
+++ b/test_x86.c
@@ -1,4 +1,5 @@
#include "gen_x86.h"
+#include "m68k_to_x86.h"
#include <stdio.h>
#include <stddef.h>
@@ -14,12 +15,13 @@ int main(int argc, char ** argv)
cur = mov_rr(cur, R11, R12, SZ_W);
cur = mov_rr(cur, RAX, RBX, SZ_D);
cur = mov_rr(cur, RAX, RBX, SZ_Q);
- cur = mov_i32r(cur, 5, RAX);
- cur = mov_i32r(cur, 3, R8);
- cur = mov_i8r(cur, 4, RSP);
+ cur = mov_ir(cur, 5, RAX, SZ_D);
+ cur = mov_ir(cur, 3, R8, SZ_D);
+ cur = mov_ir(cur, 4, RSP, SZ_B);
cur = add_rr(cur, RAX, RBX, SZ_D);
- cur = add_i8r(cur, 5, RAX);
- cur = add_i8r(cur, 5, RBX);
+ cur = add_ir(cur, 5, RAX, SZ_B);
+ cur = add_ir(cur, 5, RBX, SZ_B);
+ cur = add_ir(cur, 5, RBP, SZ_B);
cur = pushf(cur);
cur = popf(cur);
cur = setcc_r(cur, CC_S, RBX);