From: Rhys Weatherley Date: Mon, 7 Jun 2004 04:21:25 +0000 (+0000) Subject: Expand floating-point instructions for ARM. X-Git-Tag: r.0.0.4~48 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=0715f8f40684326141998be96d76c86617d2c9dc;p=francis%2Flibjit.git Expand floating-point instructions for ARM. --- diff --git a/ChangeLog b/ChangeLog index f19108d..3109f89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,9 @@ * jit-gen-arm.h: add floating-point instruction macros. + * jit/jit-gen-arm.h, jit/jit-rules-arm.c, jit/jit-rules-arm.h, + jit/jit-rules-arm.sel: expand floating-point instructions for ARM. + 2004-06-06 Miroslaw Dobrzanski-Neumann * jit/jit-alloc.c (jit_flush_exec): flush cache lines properly diff --git a/jit/jit-gen-arm.h b/jit/jit-gen-arm.h index a89b7c7..35071e0 100644 --- a/jit/jit-gen-arm.h +++ b/jit/jit-gen-arm.h @@ -718,7 +718,7 @@ extern arm_inst_ptr _arm_mov_reg_imm /* * Load a floating-point value from an address into a register. */ -#define arm_load_membase_float_either(inst,reg,basereg,imm,mask) \ +#define arm_load_membase_float(inst,reg,basereg,imm,mask) \ do { \ int __mb_offset = (int)(imm); \ if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \ @@ -727,7 +727,7 @@ extern arm_inst_ptr _arm_mov_reg_imm *(inst)++ = arm_prefix(0x0D100000 | (mask)) | \ (((unsigned int)(basereg)) << 16) | \ (((unsigned int)(reg)) << 12) | \ - ((unsigned int)((__mb_offset / 4) & 0xFF); \ + ((unsigned int)((__mb_offset / 4) & 0xFF)); \ } \ else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \ (__mb_offset & 3) == 0) \ @@ -817,7 +817,7 @@ extern arm_inst_ptr _arm_mov_reg_imm /* * Store a floating-point value to a memory address. */ -#define arm_store_membase_float_either(inst,reg,basereg,imm,mask) \ +#define arm_store_membase_float(inst,reg,basereg,imm,mask) \ do { \ int __mb_offset = (int)(imm); \ if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \ @@ -826,7 +826,7 @@ extern arm_inst_ptr _arm_mov_reg_imm *(inst)++ = arm_prefix(0x0D800000 | (mask)) | \ (((unsigned int)(basereg)) << 16) | \ (((unsigned int)(reg)) << 12) | \ - ((unsigned int)((__mb_offset / 4) & 0xFF); \ + ((unsigned int)((__mb_offset / 4) & 0xFF)); \ } \ else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \ (__mb_offset & 3) == 0) \ diff --git a/jit/jit-rules-arm.c b/jit/jit-rules-arm.c index 4e6f2b1..2ab1f72 100644 --- a/jit/jit-rules-arm.c +++ b/jit/jit-rules-arm.c @@ -29,13 +29,6 @@ #include "jit-setjmp.h" #include -/* - * Determine if we actually have floating-point registers. - */ -#if JIT_APPLY_NUM_FLOAT_REGS != 0 || JIT_APPLY_RETURN_FLOATS_AFTER != 0 - #define JIT_ARM_HAS_FLOAT_REGS 1 -#endif - /* * Round a size up to a multiple of the stack word size. */ @@ -44,14 +37,7 @@ void _jit_init_backend(void) { -#ifndef JIT_ARM_HAS_FLOAT_REGS - /* Turn off floating-point registers, as this ARM core doesn't have them */ - int reg; - for(reg = 16; reg < JIT_NUM_REGS; ++reg) - { - _jit_reg_info[reg].flags = JIT_REG_FIXED; - } -#endif + /* Nothing to do here */ } void _jit_gen_get_elf_info(jit_elf_info_t *info) @@ -482,9 +468,20 @@ int _jit_create_call_return_insns return 0; } } +#ifdef JIT_ARM_HAS_FLOAT_REGS + else if(return_type->kind == JIT_TYPE_FLOAT32 || + return_type->kind == JIT_TYPE_FLOAT64 || + return_type->kind == JIT_TYPE_NFLOAT) + { + if(!jit_insn_return_reg(func, return_value, 16 /* f0 */)) + { + return 0; + } + } +#endif else if(return_type->kind != JIT_TYPE_VOID) { - if(!jit_insn_return_reg(func, return_value, ARM_R0)) + if(!jit_insn_return_reg(func, return_value, 0 /* r0 */)) { return 0; } @@ -639,12 +636,23 @@ void _jit_gen_spill_reg(jit_gencode_t gen, int reg, /* Output an appropriate instruction to spill the value */ offset = (int)(value->frame_offset); - arm_store_membase(inst, ARM_FP, offset, reg); - if(other_reg != -1) + if(reg < 16) { - /* Spill the other word register in a pair */ - offset += sizeof(void *); - arm_store_membase(inst, ARM_FP, offset, reg); + arm_store_membase(inst, reg, ARM_FP, offset); + if(other_reg != -1) + { + /* Spill the other word register in a pair */ + offset += sizeof(void *); + arm_store_membase(inst, other_reg, ARM_FP, offset); + } + } + else if(jit_type_normalize(value->type)->kind == JIT_TYPE_FLOAT32) + { + arm_store_membase_float32(inst, reg - 16, ARM_FP, offset); + } + else + { + arm_store_membase_float64(inst, reg - 16, ARM_FP, offset); } /* End the code output process */ @@ -660,7 +668,6 @@ void _jit_gen_free_reg(jit_gencode_t gen, int reg, void _jit_gen_load_value (jit_gencode_t gen, int reg, int other_reg, jit_value_t value) { - void *ptr; int offset; /* Make sure that we have sufficient space */ @@ -704,10 +711,18 @@ void _jit_gen_load_value jit_cache_mark_full(&(gen->posn)); return; } - ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float32)); - jit_memcpy(ptr, &float32_value, sizeof(float32_value)); - /* TODO */ - /*x86_fld(inst, ptr, 0);*/ + if(reg < 16) + { + arm_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg, + *((int *)&float32_value)); + } + else + { + arm_load_membase_float32 + (inst, _jit_reg_info[reg].cpu_reg, ARM_PC, 0); + arm_jump_imm(inst, 0); + *(inst)++ = *((int *)&float32_value); + } } break; @@ -721,10 +736,30 @@ void _jit_gen_load_value jit_cache_mark_full(&(gen->posn)); return; } - ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_float64)); - jit_memcpy(ptr, &float64_value, sizeof(float64_value)); - /* TODO */ - /*x86_fld(inst, ptr, 1);*/ + if(reg < 16) + { + arm_mov_reg_imm(inst, _jit_reg_info[reg].cpu_reg, + ((int *)&float64_value)[0]); + arm_mov_reg_imm(inst, _jit_reg_info[other_reg].cpu_reg, + ((int *)&float64_value)[1]); + } + else if((((int)inst) & 7) == 0) + { + arm_load_membase_float64 + (inst, _jit_reg_info[reg].cpu_reg, ARM_PC, 0); + arm_jump_imm(inst, 4); + *(inst)++ = ((int *)&float64_value)[0]; + *(inst)++ = ((int *)&float64_value)[1]; + } + else + { + arm_load_membase_float64 + (inst, _jit_reg_info[reg].cpu_reg, ARM_PC, 4); + arm_jump_imm(inst, 8); + *(inst)++ = 0; + *(inst)++ = ((int *)&float64_value)[0]; + *(inst)++ = ((int *)&float64_value)[1]; + } } break; } @@ -792,16 +827,34 @@ void _jit_gen_load_value case JIT_TYPE_FLOAT32: { - /* TODO */ - /*x86_fld_membase(inst, X86_EBP, offset, 0);*/ + if(reg < 16) + { + arm_load_membase(inst, _jit_reg_info[reg].cpu_reg, + ARM_FP, offset); + } + else + { + arm_load_membase_float32 + (inst, _jit_reg_info[reg].cpu_reg, ARM_FP, offset); + } } break; case JIT_TYPE_FLOAT64: case JIT_TYPE_NFLOAT: { - /* TODO */ - /*x86_fld_membase(inst, X86_EBP, offset, 1);*/ + if(reg < 16) + { + arm_load_membase(inst, _jit_reg_info[reg].cpu_reg, + ARM_FP, offset); + arm_load_membase(inst, _jit_reg_info[other_reg].cpu_reg, + ARM_FP, offset + 4); + } + else + { + arm_load_membase_float64 + (inst, _jit_reg_info[reg].cpu_reg, ARM_FP, offset); + } } break; } diff --git a/jit/jit-rules-arm.h b/jit/jit-rules-arm.h index 20bd76b..e5bc8be 100644 --- a/jit/jit-rules-arm.h +++ b/jit/jit-rules-arm.h @@ -21,10 +21,19 @@ #ifndef _JIT_RULES_ARM_H #define _JIT_RULES_ARM_H +#include "jit-apply-rules.h" + #ifdef __cplusplus extern "C" { #endif +/* + * Determine if this ARM core has floating point registers available. + */ +#if JIT_APPLY_NUM_FLOAT_REGS != 0 || JIT_APPLY_RETURN_FLOATS_AFTER != 0 + #define JIT_ARM_HAS_FLOAT_REGS 1 +#endif + /* * Information about all of the registers, in allocation order. * We use r0-r5 for general-purpose values and r6-r8 for globals. @@ -32,8 +41,12 @@ extern "C" { * Of the floating-point registers, we only use f0-f3 at present, * so that we don't have to worry about saving the values of f4-f7. * The floating-point registers are only present on some ARM cores. - * "_jit_init_backend" will disable the FP registers if they don't exist. */ +#ifdef JIT_ARM_HAS_FLOAT_REGS + #define JIT_REG_ARM_FLOAT JIT_REG_FLOAT | JIT_REG_CALL_USED +#else + #define JIT_REG_ARM_FLOAT JIT_REG_FIXED +#endif #define JIT_REG_INFO \ {"r0", 0, 1, JIT_REG_WORD | JIT_REG_CALL_USED}, \ {"r1", 1, -1, JIT_REG_WORD | JIT_REG_CALL_USED}, \ @@ -51,10 +64,10 @@ extern "C" { {"sp", 13, -1, JIT_REG_FIXED | JIT_REG_STACK_PTR}, \ {"lr", 14, -1, JIT_REG_FIXED}, \ {"pc", 15, -1, JIT_REG_FIXED}, \ - {"f0", 0, -1, JIT_REG_FLOAT | JIT_REG_CALL_USED}, \ - {"f1", 1, -1, JIT_REG_FLOAT | JIT_REG_CALL_USED}, \ - {"f2", 2, -1, JIT_REG_FLOAT | JIT_REG_CALL_USED}, \ - {"f3", 3, -1, JIT_REG_FLOAT | JIT_REG_CALL_USED}, + {"f0", 0, -1, JIT_REG_ARM_FLOAT}, \ + {"f1", 1, -1, JIT_REG_ARM_FLOAT}, \ + {"f2", 2, -1, JIT_REG_ARM_FLOAT}, \ + {"f3", 3, -1, JIT_REG_ARM_FLOAT}, #define JIT_NUM_REGS 20 #define JIT_NUM_GLOBAL_REGS 3 diff --git a/jit/jit-rules-arm.sel b/jit/jit-rules-arm.sel index b70b8e9..046359d 100644 --- a/jit/jit-rules-arm.sel +++ b/jit/jit-rules-arm.sel @@ -149,6 +149,81 @@ JIT_OP_INEG: unary arm_alu_reg_imm8(inst, ARM_RSB, $1, $1, 0); } +JIT_OP_FADD: binary + [freg, freg] -> { + arm_alu_freg_freg_32(inst, ARM_ADF, $1, $1, $2); + } + +JIT_OP_FSUB: binary + [freg, freg] -> { + arm_alu_freg_freg_32(inst, ARM_SUF, $1, $1, $2); + } + +JIT_OP_FMUL: binary + [freg, freg] -> { + arm_alu_freg_freg_32(inst, ARM_MUF, $1, $1, $2); + } + +JIT_OP_FDIV: binary + [freg, freg] -> { + arm_alu_freg_freg_32(inst, ARM_DVF, $1, $1, $2); + } + +JIT_OP_FNEG: unary + [freg] -> { + arm_alu_freg_32(inst, ARM_MNF, $1, $1); + } + +JIT_OP_DADD: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_ADF, $1, $1, $2); + } + +JIT_OP_DSUB: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_SUF, $1, $1, $2); + } + +JIT_OP_DMUL: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_MUF, $1, $1, $2); + } + +JIT_OP_DDIV: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_DVF, $1, $1, $2); + } + +JIT_OP_DNEG: unary + [freg] -> { + arm_alu_freg(inst, ARM_MNF, $1, $1); + } + +JIT_OP_NFADD: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_ADF, $1, $1, $2); + } + +JIT_OP_NFSUB: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_SUF, $1, $1, $2); + } + +JIT_OP_NFMUL: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_MUF, $1, $1, $2); + } + +JIT_OP_NFDIV: binary + [freg, freg] -> { + arm_alu_freg_freg(inst, ARM_DVF, $1, $1, $2); + } + +JIT_OP_NFNEG: unary + [freg] -> { + arm_alu_freg(inst, ARM_MNF, $1, $1); + } + /* * Bitwise opcodes. */ @@ -562,22 +637,28 @@ JIT_OP_RETURN_LONG: spill_before inst = jump_to_epilog(gen, inst, block); } -JIT_OP_RETURN_FLOAT32: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_RETURN_FLOAT32: unary_note + [freg] -> { + if($1 != 0) + { + arm_alu_freg_32(inst, ARM_MVF, ARM_F0, $1); + } } -JIT_OP_RETURN_FLOAT64: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_RETURN_FLOAT64: unary_note + [freg] -> { + if($1 != 0) + { + arm_alu_freg(inst, ARM_MVF, ARM_F0, $1); + } } -JIT_OP_RETURN_NFLOAT: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_RETURN_NFLOAT: unary_note + [freg] -> { + if($1 != 0) + { + arm_alu_freg(inst, ARM_MVF, ARM_F0, $1); + } } JIT_OP_RETURN_SMALL_STRUCT: spill_before @@ -663,23 +744,14 @@ JIT_OP_COPY_LONG: spill_before TODO(); } -JIT_OP_COPY_FLOAT32: manual - [] -> { - /* TODO */ - TODO(); - } +JIT_OP_COPY_FLOAT32: unary + [freg] -> {} -JIT_OP_COPY_FLOAT64: manual - [] -> { - /* TODO */ - TODO(); - } +JIT_OP_COPY_FLOAT64: unary + [freg] -> {} -JIT_OP_COPY_NFLOAT: manual - [] -> { - /* TODO */ - TODO(); - } +JIT_OP_COPY_NFLOAT: unary + [freg] -> {} JIT_OP_COPY_STRUCT: manual [] -> { @@ -778,22 +850,19 @@ JIT_OP_PUSH_LONG: manual TODO(); } -JIT_OP_PUSH_FLOAT32: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_PUSH_FLOAT32: unary_note + [freg] -> { + arm_push_reg_float32(inst, $1); } -JIT_OP_PUSH_FLOAT64: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_PUSH_FLOAT64: unary_note + [freg] -> { + arm_push_reg_float64(inst, $1); } -JIT_OP_PUSH_NFLOAT: manual - [] -> { - /* TODO */ - TODO(); +JIT_OP_PUSH_NFLOAT: unary_note + [freg] -> { + arm_push_reg_float64(inst, $1); } JIT_OP_PUSH_STRUCT: unary_note