summaryrefslogtreecommitdiff
path: root/gen_x86.c
diff options
context:
space:
mode:
authorMike Pavone <pavone@retrodev.com>2013-06-24 21:32:25 -0700
committerMike Pavone <pavone@retrodev.com>2013-06-24 21:32:25 -0700
commitf8296ee1fa057adc180ed4d6a2066a841dbe74c4 (patch)
tree60ea83ccfa73b1c75c99d9705a7a375613f2a43e /gen_x86.c
parentda088cadfb4c361fd91aeb9a5fb0147164978daf (diff)
Fix access to int_enable_cycle in EI
Diffstat (limited to 'gen_x86.c')
-rw-r--r--gen_x86.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/gen_x86.c b/gen_x86.c
index 8ba2136..aa68700 100644
--- a/gen_x86.c
+++ b/gen_x86.c
@@ -517,6 +517,54 @@ uint8_t * x86_irdisp8(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val,
return out;
}
+uint8_t * x86_irdisp32(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int32_t disp, uint8_t size)
+{
+ uint8_t sign_extend = 0;
+ 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 (size == SZ_Q || dst >= R8) {
+ *out = PRE_REX;
+ if (size == SZ_Q) {
+ *out |= REX_QUAD;
+ }
+ if (dst >= R8) {
+ *out |= REX_RM_FIELD;
+ dst -= (R8 - X86_R8);
+ }
+ out++;
+ }
+ if (size != SZ_B) {
+ opcode |= BIT_SIZE;
+ }
+ *(out++) = opcode;
+ *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
+ *(out++) = disp;
+ disp >>= 8;
+ *(out++) = disp;
+ disp >>= 8;
+ *(out++) = disp;
+ disp >>= 8;
+ *(out++) = disp;
+ *(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 * x86_shiftrot_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
{
@@ -781,6 +829,11 @@ uint8_t * add_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp,
return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size);
}
+uint8_t * add_irdisp32(uint8_t * out, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
+{
+ return x86_irdisp32(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size);
+}
+
uint8_t * add_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size)
{
return x86_rrdisp8_sizedir(out, OP_ADD, src, dst_base, disp, size, 0);