]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Expand floating-point instructions for ARM.
authorRhys Weatherley <rweather@southern-storm.com.au>
Mon, 7 Jun 2004 04:21:25 +0000 (04:21 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Mon, 7 Jun 2004 04:21:25 +0000 (04:21 +0000)
ChangeLog
jit/jit-gen-arm.h
jit/jit-rules-arm.c
jit/jit-rules-arm.h
jit/jit-rules-arm.sel

index f19108df02de05ffc6f63bc6ca99fbd70aacb6b5..3109f89a5d99dccc04bf1c8963411c62c86ae288 100644 (file)
--- 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  <mne@mosaic-ag.com>
 
        * jit/jit-alloc.c (jit_flush_exec): flush cache lines properly
index a89b7c7de2ed339ab1e4a1f6da8c6a9e7cfaed91..35071e0b46e2eb223d51daebf4c4b049f40746d1 100644 (file)
@@ -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) \
index 4e6f2b12629d747a8e8b727e29ffc4131348d0d7..2ab1f7295ee6a1767d66a0568111f5cbbf013fd6 100644 (file)
 #include "jit-setjmp.h"
 #include <stdio.h>
 
-/*
- * 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.
  */
 
 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;
                }
index 20bd76b567cb428a197e7c17446e0e070c5f02ba..e5bc8becad94ed0124c948940f5295b6b725e8d2 100644 (file)
 #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
 
index b70b8e98be975e103f1b970967f42a0ce38894c8..046359d980a2b9e312b75509bd68a5b2bfcf772f 100644 (file)
@@ -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