From 356f406b229fd1386fb6d1d4586bfc3c4e8a5df4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 18:41:53 +0000 Subject: [PATCH] Fix codegen pointer register reads. --- src/codegen_backend_arm64_uops.c | 14 ++++++++ src/codegen_backend_arm_ops.h | 2 ++ src/codegen_backend_arm_uops.c | 8 +++++ src/codegen_backend_x86-64_ops.c | 57 ++++++++++++++++++++++++++++++- src/codegen_backend_x86-64_ops.h | 1 + src/codegen_backend_x86-64_uops.c | 16 +++++++++ src/codegen_backend_x86_uops.c | 8 +++++ src/codegen_ir_defs.h | 4 +++ src/codegen_reg.c | 9 +++++ 9 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 0ee74dc..c7729af 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -2687,6 +2687,13 @@ void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_double - not in range\n"); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_pointer - not in range\n"); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) @@ -2801,6 +2808,13 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32_stack - not in range\n"); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (in_range12_q(stack_offset)) + host_arm64_LDR_IMM_X(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_read_pointer_stack - not in range\n"); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 542dc2a..b7877df 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -215,6 +215,8 @@ void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shif void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a9ce03e..8ceebbc 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -2829,6 +2829,10 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + codegen_direct_read_32(block, host_reg, p); +} void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); @@ -2941,6 +2945,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + codegen_direct_read_32_stack(block, host_reg, stack_offset); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 4ec3fd4..04d0080 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -777,6 +777,25 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addlong(block, (uint32_t)(uintptr_t)p); } } +void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOV64_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } + else + fatal("host_x86_MOV64_REG_ABS - out of range\n"); +} void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { @@ -845,11 +864,29 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re else fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } +void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); if (offset >= -128 && offset < 127) { @@ -863,6 +900,24 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset else fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); } +void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + else + fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); +} void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 10fe26a..a86e3ed 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -92,6 +92,7 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index dc87d53..4955609 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -2430,6 +2430,10 @@ void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV64_REG_ABS(block, host_reg, p); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); @@ -2478,6 +2482,10 @@ void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } +void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV64_ABS_REG(block, p, host_reg); +} void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); @@ -2527,6 +2535,10 @@ void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); @@ -2540,6 +2552,10 @@ void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int hos { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } +void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 20f39a7..67f28d4 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2440,6 +2440,10 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + codegen_direct_read_32(block, host_reg, p); +} void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); @@ -2537,6 +2541,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + codegen_direct_read_32_stack(block, host_reg, stack_offset); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 15b3014..2a2733e 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -688,6 +688,7 @@ void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx); @@ -697,6 +698,7 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg); @@ -706,10 +708,12 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset); +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg); +void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_set_jump_dest(codeblock_t *block, void *p); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 1e2fbb6..7d993fd 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -253,6 +253,15 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; + case REG_POINTER: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_pointer(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; + case REG_DOUBLE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n");