]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add floating-point instruction macros.
authorRhys Weatherley <rweather@southern-storm.com.au>
Mon, 7 Jun 2004 03:18:34 +0000 (03:18 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Mon, 7 Jun 2004 03:18:34 +0000 (03:18 +0000)
ChangeLog
jit/jit-gen-arm.h

index 5cfb54d447f633d770e3bbdb9c814d28fcf046e9..f19108df02de05ffc6f63bc6ca99fbd70aacb6b5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,8 @@
        * configure.in, jit/jit-insn.c: use "sigsetjmp" instead of
        "setjmp", because "setjmp" may be a macro on some systems.
 
+       * jit-gen-arm.h: add floating-point instruction macros.
+
 2004-06-06  Miroslaw Dobrzanski-Neumann  <mne@mosaic-ag.com>
 
        * jit/jit-alloc.c (jit_flush_exec): flush cache lines properly
index 69b7e62787e0c0e7a83c39a97da4bbcfaa6f1e36..a89b7c7de2ed339ab1e4a1f6da8c6a9e7cfaed91 100644 (file)
@@ -50,10 +50,26 @@ typedef enum
        ARM_LINK = ARM_R14,                     /* Link register */
        ARM_PC   = ARM_R15,                     /* Program counter */
        ARM_WORK = ARM_R12,                     /* Work register that we can destroy */
-       ARM_SP   = ARM_R13,                     /* Stack pointer */
+       ARM_SP   = ARM_R13                      /* Stack pointer */
 
 } ARM_REG;
 
+/*
+ * Floating-point register numbers.
+ */
+typedef enum
+{
+       ARM_F0  = 0,
+       ARM_F1  = 1,
+       ARM_F2  = 2,
+       ARM_F3  = 3,
+       ARM_F4  = 4,
+       ARM_F5  = 5,
+       ARM_F6  = 6,
+       ARM_F7  = 7
+
+} ARM_FREG;
+
 /*
  * Condition codes.
  */
@@ -78,7 +94,7 @@ typedef enum
        ARM_CC_GE_UN = ARM_CC_CS,       /* Unsigned greater than or equal */
        ARM_CC_LT_UN = ARM_CC_CC,       /* Unsigned less than */
        ARM_CC_GT_UN = ARM_CC_HI,       /* Unsigned greater than */
-       ARM_CC_LE_UN = ARM_CC_LS,       /* Unsigned less than or equal */
+       ARM_CC_LE_UN = ARM_CC_LS        /* Unsigned less than or equal */
 
 } ARM_CC;
 
@@ -102,7 +118,7 @@ typedef enum
        ARM_ORR = 12,                           /* Bitwise OR */
        ARM_MOV = 13,                           /* Move */
        ARM_BIC = 14,                           /* Test with Op1 & ~Op2 */
-       ARM_MVN = 15,                           /* Bitwise NOT */
+       ARM_MVN = 15                            /* Bitwise NOT */
 
 } ARM_OP;
 
@@ -114,10 +130,53 @@ typedef enum
        ARM_SHL = 0,                            /* Logical left */
        ARM_SHR = 1,                            /* Logical right */
        ARM_SAR = 2,                            /* Arithmetic right */
-       ARM_ROR = 3,                            /* Rotate right */
+       ARM_ROR = 3                                     /* Rotate right */
 
 } ARM_SHIFT;
 
+/*
+ * Floating-point unary operators.
+ */
+typedef enum
+{
+       ARM_MVF         = 0,                    /* Move */
+       ARM_MNF         = 1,                    /* Move negative */
+       ARM_ABS         = 2,                    /* Absolute value */
+       ARM_RND         = 3,                    /* Round */
+       ARM_SQT         = 4,                    /* Square root */
+       ARM_LOG         = 5,                    /* log10 */
+       ARM_LGN         = 6,                    /* ln */
+       ARM_EXP         = 7,                    /* exp */
+       ARM_SIN         = 8,                    /* sin */
+       ARM_COS         = 9,                    /* cos */
+       ARM_TAN         = 10,                   /* tan */
+       ARM_ASN         = 11,                   /* asin */
+       ARM_ACS         = 12,                   /* acos */
+       ARM_ATN         = 13                    /* atan */
+
+} ARM_FUNARY;
+
+/*
+ * Floating-point binary operators.
+ */
+typedef enum
+{
+       ARM_ADF         = 0,                    /* Add */
+       ARM_MUF         = 1,                    /* Multiply */
+       ARM_SUF         = 2,                    /* Subtract */
+       ARM_RSF         = 3,                    /* Reverse subtract */
+       ARM_DVF         = 4,                    /* Divide */
+       ARM_RDF         = 5,                    /* Reverse divide */
+       ARM_POW         = 6,                    /* pow */
+       ARM_RPW         = 7,                    /* Reverse pow */
+       ARM_RMF         = 8,                    /* Remainder */
+       ARM_FML         = 9,                    /* Fast multiply (32-bit only) */
+       ARM_FDV         = 10,                   /* Fast divide (32-bit only) */
+       ARM_FRD         = 11,                   /* Fast reverse divide (32-bit only) */
+       ARM_POL         = 12                    /* Polar angle */
+
+} ARM_FBINARY;
+
 /*
  * Number of registers that are used for parameters (r0-r3).
  */
@@ -402,6 +461,44 @@ extern arm_inst_ptr _arm_mov_reg_imm
                                } \
                        } while (0)
 
+/*
+ * Perform a binary operation on floating-point arguments.
+ */
+#define        arm_alu_freg_freg(inst,opc,dreg,sreg1,sreg2)    \
+                       do { \
+                               *(inst)++ = arm_prefix(0x0E000180) | \
+                                                       (((unsigned int)(opc)) << 20) | \
+                                                       (((unsigned int)(dreg)) << 12) | \
+                                                       (((unsigned int)(sreg1)) << 16) | \
+                                                        ((unsigned int)(sreg2)); \
+                       } while (0)
+#define        arm_alu_freg_freg_32(inst,opc,dreg,sreg1,sreg2) \
+                       do { \
+                               *(inst)++ = arm_prefix(0x0E000100) | \
+                                                       (((unsigned int)(opc)) << 20) | \
+                                                       (((unsigned int)(dreg)) << 12) | \
+                                                       (((unsigned int)(sreg1)) << 16) | \
+                                                        ((unsigned int)(sreg2)); \
+                       } while (0)
+
+/*
+ * Perform a unary operation on floating-point arguments.
+ */
+#define        arm_alu_freg(inst,opc,dreg,sreg)        \
+                       do { \
+                               *(inst)++ = arm_prefix(0x0E008180) | \
+                                                       (((unsigned int)(opc)) << 20) | \
+                                                       (((unsigned int)(dreg)) << 12) | \
+                                                        ((unsigned int)(sreg)); \
+                       } while (0)
+#define        arm_alu_freg_32(inst,opc,dreg,sreg)     \
+                       do { \
+                               *(inst)++ = arm_prefix(0x0E008100) | \
+                                                       (((unsigned int)(opc)) << 20) | \
+                                                       (((unsigned int)(dreg)) << 12) | \
+                                                        ((unsigned int)(sreg)); \
+                       } while (0)
+
 /*
  * Branch or jump immediate by a byte offset.  The offset is
  * assumed to be +/- 32 Mbytes.
@@ -618,6 +715,48 @@ extern arm_inst_ptr _arm_mov_reg_imm
                                arm_alu_reg_reg((inst), ARM_ORR, (reg), (reg), ARM_WORK); \
                        } while (0)
 
+/*
+ * Load a floating-point value from an address into a register.
+ */
+#define        arm_load_membase_float_either(inst,reg,basereg,imm,mask)        \
+                       do { \
+                               int __mb_offset = (int)(imm); \
+                               if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
+                                  (__mb_offset & 3) == 0) \
+                               { \
+                                       *(inst)++ = arm_prefix(0x0D100000 | (mask)) | \
+                                                       (((unsigned int)(basereg)) << 16) | \
+                                                       (((unsigned int)(reg)) << 12) | \
+                                                        ((unsigned int)((__mb_offset / 4) & 0xFF); \
+                               } \
+                               else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
+                                       (__mb_offset & 3) == 0) \
+                               { \
+                                       *(inst)++ = arm_prefix(0x0D180000 | (mask)) | \
+                                                       (((unsigned int)(basereg)) << 16) | \
+                                                       (((unsigned int)(reg)) << 12) | \
+                                                        ((unsigned int)(((-__mb_offset) / 4) & 0xFF));\
+                               } \
+                               else \
+                               { \
+                                       arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
+                                       arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, \
+                                                                   (basereg), ARM_WORK); \
+                                       *(inst)++ = arm_prefix(0x0D100000 | (mask)) | \
+                                                       (((unsigned int)ARM_WORK) << 16) | \
+                                                       (((unsigned int)(reg)) << 12); \
+                               } \
+                       } while (0)
+#define        arm_load_membase_float32(inst,reg,basereg,imm)  \
+                       do { \
+                               arm_load_membase_float((inst), (reg), (basereg), (imm), 0); \
+                       } while (0)
+#define        arm_load_membase_float64(inst,reg,basereg,imm)  \
+                       do { \
+                               arm_load_membase_float((inst), (reg), (basereg), \
+                                                                          (imm), 0x00008000); \
+                       } while (0)
+
 /*
  * Store a value from a register into an address.
  *
@@ -675,6 +814,58 @@ extern arm_inst_ptr _arm_mov_reg_imm
                                arm_store_membase_short((inst), (reg), (basereg), (imm)); \
                        } while (0)
 
+/*
+ * Store a floating-point value to a memory address.
+ */
+#define        arm_store_membase_float_either(inst,reg,basereg,imm,mask)       \
+                       do { \
+                               int __mb_offset = (int)(imm); \
+                               if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
+                                  (__mb_offset & 3) == 0) \
+                               { \
+                                       *(inst)++ = arm_prefix(0x0D800000 | (mask)) | \
+                                                       (((unsigned int)(basereg)) << 16) | \
+                                                       (((unsigned int)(reg)) << 12) | \
+                                                        ((unsigned int)((__mb_offset / 4) & 0xFF); \
+                               } \
+                               else if(__mb_offset > -(1 << 10) && __mb_offset < 0 && \
+                                       (__mb_offset & 3) == 0) \
+                               { \
+                                       *(inst)++ = arm_prefix(0x0D880000 | (mask)) | \
+                                                       (((unsigned int)(basereg)) << 16) | \
+                                                       (((unsigned int)(reg)) << 12) | \
+                                                        ((unsigned int)(((-__mb_offset) / 4) & 0xFF));\
+                               } \
+                               else \
+                               { \
+                                       arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
+                                       arm_alu_reg_reg((inst), ARM_ADD, ARM_WORK, \
+                                                                   (basereg), ARM_WORK); \
+                                       *(inst)++ = arm_prefix(0x0D800000 | (mask)) | \
+                                                       (((unsigned int)ARM_WORK) << 16) | \
+                                                       (((unsigned int)(reg)) << 12); \
+                               } \
+                       } while (0)
+#define        arm_store_membase_float32(inst,reg,basereg,imm) \
+                       do { \
+                               arm_store_membase_float((inst), (reg), (basereg), (imm), 0); \
+                       } while (0)
+#define        arm_store_membase_float64(inst,reg,basereg,imm) \
+                       do { \
+                               arm_store_membase_float((inst), (reg), (basereg), \
+                                                                           (imm), 0x00008000); \
+                       } while (0)
+#define        arm_push_reg_float32(inst,reg)  \
+                       do { \
+                               arm_store_membase_float((inst), (reg), ARM_SP, \
+                                                                           -4, 0x00200000); \
+                       } while (0)
+#define        arm_push_reg_float64(inst,reg)  \
+                       do { \
+                               arm_store_membase_float((inst), (reg), ARM_SP, \
+                                                                           -4, 0x00208000); \
+                       } while (0)
+
 /*
  * Load a value from an indexed address into a register.
  */