]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Redesign the ARM code generation macros so that they have stronger
authorRhys Weatherley <rweather@southern-storm.com.au>
Wed, 9 Jun 2004 23:40:34 +0000 (23:40 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Wed, 9 Jun 2004 23:40:34 +0000 (23:40 +0000)
protection against buffer overruns.

ChangeLog
jit/jit-apply-arm.c
jit/jit-gen-arm.c
jit/jit-gen-arm.h
jit/jit-rules-arm.c
jit/jit-rules-arm.h
jit/jit-rules-arm.sel
tools/gen-sel-parser.y

index ccc4e399a31502f44f10e1d0e0cf1345c1f1c766..b510fb38576c41c083741be817a5db530cd896e2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * jit/jit-rules-arm.c (_jit_gen_load_value): use ARM register pairs
        properly for "long" and "float64" values.
 
+       * jit/jit-apply-arm.c, jit/jit-gen-arm.c, jit/jit-gen-arm.h,
+       jit/jit-rules-arm.c, jit/jit-rules-arm.h, jit/jit-rules-arm.sel,
+       tools/gen-sel-parser.y: redesign the ARM code generation macros
+       so that they have stronger protection against buffer overruns.
+
 2004-06-08  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/Makefile.am, jit/jit-cpuid-x86.c, jit/jit-cpuid-x86.h:
index dd16e2328b417582f3a57208c13ea62436decc13..cb04df3ac5e57e1eeb796e702a4cd4a4fbe432fd 100644 (file)
 void _jit_create_closure(unsigned char *buf, void *func,
                          void *closure, void *_type)
 {
-       arm_inst_ptr inst = (arm_inst_ptr)buf;
+       arm_inst_buf inst;
+
+       /* Initialize the instruction buffer */
+       arm_inst_buf_init(inst, buf, buf + jit_closure_size);
 
        /* Set up the local stack frame */
        arm_setup_frame(inst, 0);
@@ -56,7 +59,7 @@ void _jit_create_closure(unsigned char *buf, void *func,
 void *_jit_create_redirector(unsigned char *buf, void *func,
                                                         void *user_data, int abi)
 {
-       arm_inst_ptr inst;
+       arm_inst_buf inst;
 
        /* Align "buf" on an appropriate boundary */
        if((((jit_nint)buf) % jit_closure_align) != 0)
@@ -64,8 +67,8 @@ void *_jit_create_redirector(unsigned char *buf, void *func,
                buf += jit_closure_align - (((jit_nint)buf) % jit_closure_align);
        }
 
-       /* Set up the instruction output pointer */
-       inst = (arm_inst_ptr)buf;
+       /* Initialize the instruction buffer */
+       arm_inst_buf_init(inst, buf, buf + jit_redirector_size);
 
        /* Set up the local stack frame, and save R0-R3 */
        arm_setup_frame(inst, 0x000F);
@@ -86,7 +89,7 @@ void *_jit_create_redirector(unsigned char *buf, void *func,
        arm_mov_reg_reg(inst, ARM_PC, ARM_R12);
 
        /* Flush the cache lines that we just wrote */
-       jit_flush_exec(buf, ((unsigned char *)inst) - buf);
+       jit_flush_exec(buf, ((unsigned char *)(inst.current)) - buf);
 
        /* Return the aligned start of the buffer as the entry point */
        return (void *)buf;
index 162d7aeaecda59f0c40e72fbfbba725824fe9431..50b4ba07b376330fd4096c9db5ccda2d7d6a7b20 100644 (file)
@@ -28,8 +28,8 @@
 
 #include "jit-gen-arm.h"
 
-arm_inst_ptr _arm_mov_reg_imm
-       (arm_inst_ptr inst, int reg, int value, int execute_prefix)
+void _arm_mov_reg_imm
+       (arm_inst_buf *inst, int reg, int value, int execute_prefix)
 {
        int bit;
 
@@ -39,8 +39,8 @@ arm_inst_ptr _arm_mov_reg_imm
                if((value & (0xFF << bit)) == value)
                {
                        arm_mov_reg_imm8_rotate
-                               (inst, reg, ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F);
-                       return inst;
+                               (*inst, reg, ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F);
+                       return;
                }
        }
 
@@ -51,9 +51,9 @@ arm_inst_ptr _arm_mov_reg_imm
                if((value & (0xFF << bit)) == value)
                {
                        arm_alu_reg_imm8_rotate
-                               (inst, ARM_MVN, reg, 0,
+                               (*inst, ARM_MVN, reg, 0,
                                 ((value >> bit) & 0xFF), (16 - bit / 2) & 0x0F);
-                       return inst;
+                       return;
                }
        }
 
@@ -61,48 +61,47 @@ arm_inst_ptr _arm_mov_reg_imm
        value = ~value;
        if((value & 0xFF000000) != 0)
        {
-               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 24) & 0xFF), 4);
+               arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 24) & 0xFF), 4);
                if((value & 0x00FF0000) != 0)
                {
                        arm_alu_reg_imm8_rotate
-                               (inst, ARM_ADD, reg, reg, ((value >> 16) & 0xFF), 8);
+                               (*inst, ARM_ADD, reg, reg, ((value >> 16) & 0xFF), 8);
                }
                if((value & 0x0000FF00) != 0)
                {
                        arm_alu_reg_imm8_rotate
-                               (inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12);
+                               (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12);
                }
                if((value & 0x000000FF) != 0)
                {
-                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 0xFF));
+                       arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF));
                }
        }
        else if((value & 0x00FF0000) != 0)
        {
-               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 16) & 0xFF), 8);
+               arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 16) & 0xFF), 8);
                if((value & 0x0000FF00) != 0)
                {
                        arm_alu_reg_imm8_rotate
-                               (inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12);
+                               (*inst, ARM_ADD, reg, reg, ((value >> 8) & 0xFF), 12);
                }
                if((value & 0x000000FF) != 0)
                {
-                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 0xFF));
+                       arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF));
                }
        }
        else if((value & 0x0000FF00) != 0)
        {
-               arm_mov_reg_imm8_rotate(inst, reg, ((value >> 8) & 0xFF), 12);
+               arm_mov_reg_imm8_rotate(*inst, reg, ((value >> 8) & 0xFF), 12);
                if((value & 0x000000FF) != 0)
                {
-                       arm_alu_reg_imm8(inst, ARM_ADD, reg, reg, (value & 0xFF));
+                       arm_alu_reg_imm8(*inst, ARM_ADD, reg, reg, (value & 0xFF));
                }
        }
        else
        {
-               arm_mov_reg_imm8(inst, reg, (value & 0xFF));
+               arm_mov_reg_imm8(*inst, reg, (value & 0xFF));
        }
-       return inst;
 }
 
 int arm_is_complex_imm(int value)
@@ -123,8 +122,8 @@ int arm_is_complex_imm(int value)
        return 1;
 }
 
-arm_inst_ptr _arm_alu_reg_imm
-       (arm_inst_ptr inst, int opc, int dreg,
+void _arm_alu_reg_imm
+       (arm_inst_buf *inst, int opc, int dreg,
         int sreg, int imm, int saveWork, int execute_prefix)
 {
        int bit, tempreg;
@@ -133,9 +132,9 @@ arm_inst_ptr _arm_alu_reg_imm
                if((imm & (0xFF << bit)) == imm)
                {
                        arm_alu_reg_imm8_rotate
-                               (inst, opc, dreg, sreg,
+                               (*inst, opc, dreg, sreg,
                                 ((imm >> bit) & 0xFF), (16 - bit / 2) & 0x0F);
-                       return inst;
+                       return;
                }
        }
        if(saveWork)
@@ -152,19 +151,18 @@ arm_inst_ptr _arm_alu_reg_imm
                {
                        tempreg = ARM_R4;
                }
-               arm_push_reg(inst, tempreg);
+               arm_push_reg(*inst, tempreg);
        }
        else
        {
                tempreg = ARM_WORK;
        }
-       inst = _arm_mov_reg_imm(inst, tempreg, imm, execute_prefix);
-       arm_alu_reg_reg(inst, opc, dreg, sreg, tempreg);
+       _arm_mov_reg_imm(inst, tempreg, imm, execute_prefix);
+       arm_alu_reg_reg(*inst, opc, dreg, sreg, tempreg);
        if(saveWork)
        {
-               arm_pop_reg(inst, tempreg);
+               arm_pop_reg(*inst, tempreg);
        }
-       return inst;
 }
 
 #endif /* arm */
index c2c80ec6de1baa468744f3e37c45bc3edb244f03..16b7e2c6d0bce9f57449e350fbfdef0fe7431122 100644 (file)
@@ -183,9 +183,17 @@ typedef enum
 #define        ARM_NUM_PARAM_REGS      4
 
 /*
- * Type for instruction pointers (word-based, not byte-based).
+ * Type that keeps track of the instruction buffer.
  */
-typedef unsigned int *arm_inst_ptr;
+typedef unsigned int arm_inst_word;
+typedef struct
+{
+       arm_inst_word *current;
+       arm_inst_word *limit;
+
+} arm_inst_buf;
+#define        arm_inst_get_posn(inst)         ((inst).current)
+#define        arm_inst_get_limit(inst)        ((inst).limit)
 
 /*
  * Build an instruction prefix from a condition code and a mask value.
@@ -216,44 +224,64 @@ typedef unsigned int *arm_inst_ptr;
 #define        arm_execute_imm         arm_always_imm
 #endif
 
+/*
+ * Initialize an instruction buffer.
+ */
+#define        arm_inst_buf_init(inst,start,end)       \
+                       do { \
+                               (inst).current = (arm_inst_word *)(start); \
+                               (inst).limit = (arm_inst_word *)(end); \
+                       } while (0)
+
+/*
+ * Add an instruction to an instruction buffer.
+ */
+#define        arm_inst_add(inst,value)        \
+                       do { \
+                               if((inst).current < (inst).limit) \
+                               { \
+                                       *((inst).current)++ = (value); \
+                               } \
+                       } while (0)
+
 /*
  * Arithmetic or logical operation which doesn't set condition codes.
  */
 #define        arm_alu_reg_reg(inst,opc,dreg,sreg1,sreg2)      \
                        do { \
-                               *(inst)++ = arm_execute | \
+                               arm_inst_add((inst), arm_execute | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg1)) << 16) | \
-                                                        ((unsigned int)(sreg2)); \
+                                                        ((unsigned int)(sreg2))); \
                        } while (0)
 #define        arm_alu_reg_imm8(inst,opc,dreg,sreg,imm)        \
                        do { \
-                               *(inst)++ = arm_execute_imm | \
+                               arm_inst_add((inst), arm_execute_imm | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg)) << 16) | \
-                                                        ((unsigned int)((imm) & 0xFF)); \
+                                                        ((unsigned int)((imm) & 0xFF))); \
                        } while (0)
 #define        arm_alu_reg_imm8_cond(inst,opc,dreg,sreg,imm,cond)      \
                        do { \
-                               *(inst)++ = arm_build_prefix((cond), (1 << 25)) | \
+                               arm_inst_add((inst), arm_build_prefix((cond), (1 << 25)) | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg)) << 16) | \
-                                                        ((unsigned int)((imm) & 0xFF)); \
+                                                        ((unsigned int)((imm) & 0xFF))); \
                        } while (0)
 #define        arm_alu_reg_imm8_rotate(inst,opc,dreg,sreg,imm,rotate)  \
                        do { \
-                               *(inst)++ = arm_execute_imm | \
+                               arm_inst_add((inst), arm_execute_imm | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg)) << 16) | \
                                                        (((unsigned int)(rotate)) << 8) | \
-                                                        ((unsigned int)((imm) & 0xFF)); \
+                                                        ((unsigned int)((imm) & 0xFF))); \
                        } while (0)
-extern arm_inst_ptr _arm_alu_reg_imm
-               (arm_inst_ptr inst, int opc, int dreg,
+extern void _arm_alu_reg_imm
+               (arm_inst_buf *inst, int opc, int dreg,
                 int sreg, int imm, int saveWork, int execute_prefix);
 #define        arm_alu_reg_imm(inst,opc,dreg,sreg,imm) \
                        do { \
@@ -265,8 +293,8 @@ extern arm_inst_ptr _arm_alu_reg_imm
                                } \
                                else \
                                { \
-                                       (inst) = _arm_alu_reg_imm \
-                                               ((inst), (opc), (dreg), (sreg), __alu_imm, 0, \
+                                       _arm_alu_reg_imm \
+                                               (&(inst), (opc), (dreg), (sreg), __alu_imm, 0, \
                                                 arm_execute); \
                                } \
                        } while (0)
@@ -280,24 +308,24 @@ extern arm_inst_ptr _arm_alu_reg_imm
                                } \
                                else \
                                { \
-                                       (inst) = _arm_alu_reg_imm \
-                                               ((inst), (opc), (dreg), (sreg), __alu_imm_save, 1, \
+                                       _arm_alu_reg_imm \
+                                               (&(inst), (opc), (dreg), (sreg), __alu_imm_save, 1, \
                                                 arm_execute); \
                                } \
                        } while (0)
 #define arm_alu_reg(inst,opc,dreg,sreg)        \
                        do { \
-                               *(inst)++ = arm_execute | \
+                               arm_inst_add((inst), arm_execute | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 #define arm_alu_reg_cond(inst,opc,dreg,sreg,cond)      \
                        do { \
-                               *(inst)++ = arm_build_prefix((cond), 0) | \
+                               arm_inst_add((inst), arm_build_prefix((cond), 0) | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 
 /*
@@ -305,26 +333,26 @@ extern arm_inst_ptr _arm_alu_reg_imm
  */
 #define        arm_alu_cc_reg_reg(inst,opc,dreg,sreg1,sreg2)   \
                        do { \
-                               *(inst)++ = arm_execute_cc | \
+                               arm_inst_add((inst), arm_execute_cc | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg1)) << 16) | \
-                                                        ((unsigned int)(sreg2)); \
+                                                        ((unsigned int)(sreg2))); \
                        } while (0)
 #define        arm_alu_cc_reg_imm8(inst,opc,dreg,sreg,imm)     \
                        do { \
-                               *(inst)++ = arm_execute_imm | arm_execute_cc | \
+                               arm_inst_add((inst), arm_execute_imm | arm_execute_cc | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg)) << 16) | \
-                                                        ((unsigned int)((imm) & 0xFF)); \
+                                                        ((unsigned int)((imm) & 0xFF))); \
                        } while (0)
 #define arm_alu_cc_reg(inst,opc,dreg,sreg)     \
                        do { \
-                               *(inst)++ = arm_execute_cc | \
+                               arm_inst_add((inst), = arm_execute_cc | \
                                                        (((unsigned int)(opc)) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 
 /*
@@ -374,8 +402,8 @@ extern arm_inst_ptr _arm_alu_reg_imm
                                arm_alu_reg_imm8_rotate((inst), ARM_MOV, (reg), \
                                                                                0, (imm), (rotate)); \
                        } while (0)
-extern arm_inst_ptr _arm_mov_reg_imm
-       (arm_inst_ptr inst, int reg, int value, int execute_prefix);
+extern void _arm_mov_reg_imm
+       (arm_inst_buf *inst, int reg, int value, int execute_prefix);
 extern int arm_is_complex_imm(int value);
 #define        arm_mov_reg_imm(inst,reg,imm)   \
                        do { \
@@ -386,8 +414,8 @@ extern int arm_is_complex_imm(int value);
                                } \
                                else if((reg) == ARM_PC) \
                                { \
-                                       (inst) = _arm_mov_reg_imm \
-                                               ((inst), ARM_WORK, __imm, arm_execute); \
+                                       _arm_mov_reg_imm \
+                                               (&(inst), ARM_WORK, __imm, arm_execute); \
                                        arm_mov_reg_reg((inst), ARM_PC, ARM_WORK); \
                                } \
                                else if(__imm > -256 && __imm < 0) \
@@ -397,8 +425,7 @@ extern int arm_is_complex_imm(int value);
                                } \
                                else \
                                { \
-                                       (inst) = _arm_mov_reg_imm \
-                                               ((inst), (reg), __imm, arm_execute); \
+                                       _arm_mov_reg_imm(&(inst), (reg), __imm, arm_execute); \
                                } \
                        } while (0)
 
@@ -420,22 +447,22 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_shift_reg_reg(inst,opc,dreg,sreg1,sreg2) \
                        do { \
-                               *(inst)++ = arm_execute | \
+                               arm_inst_add((inst), arm_execute | \
                                                        (((unsigned int)ARM_MOV) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg2)) << 8) | \
                                                        (((unsigned int)(opc)) << 5) | \
                                                         ((unsigned int)(1 << 4)) | \
-                                                        ((unsigned int)(sreg1)); \
+                                                        ((unsigned int)(sreg1))); \
                        } while (0)
 #define        arm_shift_reg_imm8(inst,opc,dreg,sreg,imm) \
                        do { \
-                               *(inst)++ = arm_execute | \
+                               arm_inst_add((inst), arm_execute | \
                                                        (((unsigned int)ARM_MOV) << 21) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(opc)) << 5) | \
                                                        (((unsigned int)(imm)) << 7) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 
 /*
@@ -448,17 +475,17 @@ extern int arm_is_complex_imm(int value);
                        do { \
                                if((dreg) != (sreg2)) \
                                { \
-                                       *(inst)++ = arm_prefix(0x00000090) | \
+                                       arm_inst_add((inst), arm_prefix(0x00000090) | \
                                                                (((unsigned int)(dreg)) << 16) | \
                                                                (((unsigned int)(sreg1)) << 8) | \
-                                                                ((unsigned int)(sreg2)); \
+                                                                ((unsigned int)(sreg2))); \
                                } \
                                else \
                                { \
-                                       *(inst)++ = arm_prefix(0x00000090) | \
+                                       arm_inst_add((inst), arm_prefix(0x00000090) | \
                                                                (((unsigned int)(dreg)) << 16) | \
                                                                (((unsigned int)(sreg2)) << 8) | \
-                                                                ((unsigned int)(sreg1)); \
+                                                                ((unsigned int)(sreg1))); \
                                } \
                        } while (0)
 
@@ -467,19 +494,19 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_alu_freg_freg(inst,opc,dreg,sreg1,sreg2)    \
                        do { \
-                               *(inst)++ = arm_prefix(0x0E000180) | \
+                               arm_inst_add((inst), arm_prefix(0x0E000180) | \
                                                        (((unsigned int)(opc)) << 20) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg1)) << 16) | \
-                                                        ((unsigned int)(sreg2)); \
+                                                        ((unsigned int)(sreg2))); \
                        } while (0)
 #define        arm_alu_freg_freg_32(inst,opc,dreg,sreg1,sreg2) \
                        do { \
-                               *(inst)++ = arm_prefix(0x0E000100) | \
+                               arm_inst_add((inst), arm_prefix(0x0E000100) | \
                                                        (((unsigned int)(opc)) << 20) | \
                                                        (((unsigned int)(dreg)) << 12) | \
                                                        (((unsigned int)(sreg1)) << 16) | \
-                                                        ((unsigned int)(sreg2)); \
+                                                        ((unsigned int)(sreg2))); \
                        } while (0)
 
 /*
@@ -487,17 +514,17 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_alu_freg(inst,opc,dreg,sreg)        \
                        do { \
-                               *(inst)++ = arm_prefix(0x0E008180) | \
+                               arm_inst_add((inst), arm_prefix(0x0E008180) | \
                                                        (((unsigned int)(opc)) << 20) | \
                                                        (((unsigned int)(dreg)) << 12) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 #define        arm_alu_freg_32(inst,opc,dreg,sreg)     \
                        do { \
-                               *(inst)++ = arm_prefix(0x0E008100) | \
+                               arm_inst_add((inst), arm_prefix(0x0E008100) | \
                                                        (((unsigned int)(opc)) << 20) | \
                                                        (((unsigned int)(dreg)) << 12) | \
-                                                        ((unsigned int)(sreg)); \
+                                                        ((unsigned int)(sreg))); \
                        } while (0)
 
 /*
@@ -506,9 +533,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_branch_imm(inst,cond,imm)   \
                        do { \
-                               *(inst)++ = arm_build_prefix((cond), 0x0A000000) | \
+                               arm_inst_add((inst), arm_build_prefix((cond), 0x0A000000) | \
                                                        (((unsigned int)(((int)(imm)) >> 2)) & \
-                                                               0x00FFFFFF); \
+                                                               0x00FFFFFF)); \
                        } while (0)
 #define        arm_jump_imm(inst,imm)  arm_branch_imm((inst), ARM_CC_AL, (imm))
 
@@ -519,7 +546,7 @@ extern int arm_is_complex_imm(int value);
 #define        arm_branch(inst,cond,target)    \
                        do { \
                                int __br_offset = (int)(((unsigned char *)(target)) - \
-                                                                  (((unsigned char *)(inst)) + 8)); \
+                                                  (((unsigned char *)((inst).current)) + 8)); \
                                arm_branch_imm((inst), (cond), __br_offset); \
                        } while (0)
 #define        arm_jump(inst,target)   arm_branch((inst), ARM_CC_AL, (target))
@@ -531,7 +558,7 @@ extern int arm_is_complex_imm(int value);
 #define        arm_jump_long(inst,target)      \
                        do { \
                                int __jmp_offset = (int)(((unsigned char *)(target)) - \
-                                                                   (((unsigned char *)(inst)) + 8)); \
+                                                   (((unsigned char *)((inst).current)) + 8)); \
                                if(__jmp_offset >= -0x04000000 && __jmp_offset < 0x04000000) \
                                { \
                                        arm_jump_imm((inst), __jmp_offset); \
@@ -545,13 +572,16 @@ extern int arm_is_complex_imm(int value);
 /*
  * Back-patch a branch instruction.
  */
-#define        arm_patch(inst,target)  \
+#define        arm_patch(inst,posn,target)     \
                        do { \
                                int __p_offset = (int)(((unsigned char *)(target)) - \
-                                                                 (((unsigned char *)(inst)) + 8)); \
+                                                                 (((unsigned char *)(posn)) + 8)); \
                                __p_offset = (__p_offset >> 2) & 0x00FFFFFF; \
-                               *((int *)(inst)) = (*((int *)(inst)) & 0xFF000000) | \
-                                       __p_offset; \
+                               if(((arm_inst_word *)(posn)) < (inst).limit) \
+                               { \
+                                       *((int *)(posn)) = (*((int *)(posn)) & 0xFF000000) | \
+                                               __p_offset; \
+                               } \
                        } while (0)
 
 /*
@@ -559,9 +589,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_call_imm(inst,imm)  \
                        do { \
-                               *(inst)++ = arm_prefix(0x0B000000) | \
+                               arm_inst_add((inst), arm_prefix(0x0B000000) | \
                                                        (((unsigned int)(((int)(imm)) >> 2)) & \
-                                                               0x00FFFFFF); \
+                                                               0x00FFFFFF)); \
                        } while (0)
 
 /*
@@ -570,7 +600,7 @@ extern int arm_is_complex_imm(int value);
 #define        arm_call(inst,target)   \
                        do { \
                                int __call_offset = (int)(((unsigned char *)(target)) - \
-                                                                    (((unsigned char *)(inst)) + 8)); \
+                                                    (((unsigned char *)((inst).current)) + 8)); \
                                if(__call_offset >= -0x04000000 && __call_offset < 0x04000000) \
                                { \
                                        arm_call_imm((inst), __call_offset); \
@@ -580,7 +610,7 @@ extern int arm_is_complex_imm(int value);
                                        arm_load_membase((inst), ARM_WORK, ARM_PC, 4); \
                                        arm_alu_reg_imm8((inst), ARM_ADD, ARM_LINK, ARM_PC, 4); \
                                        arm_mov_reg_reg((inst), ARM_PC, ARM_WORK); \
-                                       *(inst)++ = (int)(target); \
+                                       arm_inst_add((inst), (int)(target)); \
                                } \
                        } while (0)
 
@@ -597,9 +627,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_push_reg(inst,reg)  \
                        do { \
-                               *(inst)++ = arm_prefix(0x05200004) | \
+                               arm_inst_add((inst), arm_prefix(0x05200004) | \
                                                        (((unsigned int)ARM_SP) << 16) | \
-                                                       (((unsigned int)(reg)) << 12); \
+                                                       (((unsigned int)(reg)) << 12)); \
                        } while (0)
 
 /*
@@ -607,9 +637,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_pop_reg(inst,reg)   \
                        do { \
-                               *(inst)++ = arm_prefix(0x04900004) | \
+                               arm_inst_add((inst), arm_prefix(0x04900004) | \
                                                        (((unsigned int)ARM_SP) << 16) | \
-                                                       (((unsigned int)(reg)) << 12); \
+                                                       (((unsigned int)(reg)) << 12)); \
                        } while (0)
 
 /*
@@ -618,9 +648,9 @@ extern int arm_is_complex_imm(int value);
 #define        arm_setup_frame(inst,regset)    \
                        do { \
                                arm_mov_reg_reg((inst), ARM_WORK, ARM_SP); \
-                               *(inst)++ = arm_prefix(0x0920D800) | \
+                               arm_inst_add((inst), arm_prefix(0x0920D800) | \
                                                        (((unsigned int)ARM_SP) << 16) | \
-                                                       (((unsigned int)(regset))); \
+                                                       (((unsigned int)(regset)))); \
                                arm_alu_reg_imm8((inst), ARM_SUB, ARM_FP, ARM_WORK, 4); \
                        } while (0)
 
@@ -630,9 +660,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_pop_frame(inst,regset)      \
                        do { \
-                               *(inst)++ = arm_prefix(0x0910A800) | \
+                               arm_inst_add((inst), arm_prefix(0x0910A800) | \
                                                        (((unsigned int)ARM_FP) << 16) | \
-                                                       (((unsigned int)(regset))); \
+                                                       (((unsigned int)(regset)))); \
                        } while (0)
 
 /*
@@ -641,9 +671,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_pop_frame_tail(inst,regset) \
                        do { \
-                               *(inst)++ = arm_prefix(0x09106800) | \
+                               arm_inst_add((inst), arm_prefix(0x09106800) | \
                                                        (((unsigned int)ARM_FP) << 16) | \
-                                                       (((unsigned int)(regset))); \
+                                                       (((unsigned int)(regset)))); \
                        } while (0)
 
 /*
@@ -651,9 +681,9 @@ extern int arm_is_complex_imm(int value);
  */
 #define        arm_load_advance(inst,dreg,sreg)        \
                        do { \
-                               *(inst)++ = arm_prefix(0x04900004) | \
+                               arm_inst_add((inst), arm_prefix(0x04900004) | \
                                                        (((unsigned int)(sreg)) << 16) | \
-                                                       (((unsigned int)(dreg)) << 12); \
+                                                       (((unsigned int)(dreg)) << 12)); \
                        } while (0)
 
 /*
@@ -664,25 +694,25 @@ extern int arm_is_complex_imm(int value);
                                int __mb_offset = (int)(imm); \
                                if(__mb_offset >= 0 && __mb_offset < (1 << 12)) \
                                { \
-                                       *(inst)++ = arm_prefix(0x05900000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x05900000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)__mb_offset); \
+                                                                ((unsigned int)__mb_offset)); \
                                } \
                                else if(__mb_offset > -(1 << 12) && __mb_offset < 0) \
                                { \
-                                       *(inst)++ = arm_prefix(0x05100000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x05100000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)(-__mb_offset)); \
+                                                                ((unsigned int)(-__mb_offset))); \
                                } \
                                else \
                                { \
                                        arm_mov_reg_imm((inst), ARM_WORK, __mb_offset); \
-                                       *(inst)++ = arm_prefix(0x07900000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x07900000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)ARM_WORK); \
+                                                                ((unsigned int)ARM_WORK)); \
                                } \
                        } while (0)
 #define        arm_load_membase(inst,reg,basereg,imm)  \
@@ -726,27 +756,27 @@ extern int arm_is_complex_imm(int value);
                                if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
                                   (__mb_offset & 3) == 0) \
                                { \
-                                       *(inst)++ = arm_prefix(0x0D900100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D900100 | (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) \
                                { \
-                                       *(inst)++ = arm_prefix(0x0D180100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D180100 | (mask)) | \
                                                        (((unsigned int)(basereg)) << 16) | \
                                                        (((unsigned int)(reg)) << 12) | \
-                                                        ((unsigned int)(((-__mb_offset) / 4) & 0xFF));\
+                                                        ((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(0x0D900100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D900100 | (mask)) | \
                                                        (((unsigned int)ARM_WORK) << 16) | \
-                                                       (((unsigned int)(reg)) << 12); \
+                                                       (((unsigned int)(reg)) << 12)); \
                                } \
                        } while (0)
 #define        arm_load_membase_float32(inst,reg,basereg,imm)  \
@@ -769,25 +799,25 @@ extern int arm_is_complex_imm(int value);
                                int __sm_offset = (int)(imm); \
                                if(__sm_offset >= 0 && __sm_offset < (1 << 12)) \
                                { \
-                                       *(inst)++ = arm_prefix(0x05800000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x05800000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)__sm_offset); \
+                                                                ((unsigned int)__sm_offset)); \
                                } \
                                else if(__sm_offset > -(1 << 12) && __sm_offset < 0) \
                                { \
-                                       *(inst)++ = arm_prefix(0x05000000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x05000000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)(-__sm_offset)); \
+                                                                ((unsigned int)(-__sm_offset))); \
                                } \
                                else \
                                { \
                                        arm_mov_reg_imm((inst), ARM_WORK, __sm_offset); \
-                                       *(inst)++ = arm_prefix(0x07800000 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x07800000 | (mask)) | \
                                                                (((unsigned int)(basereg)) << 16) | \
                                                                (((unsigned int)(reg)) << 12) | \
-                                                                ((unsigned int)ARM_WORK); \
+                                                                ((unsigned int)ARM_WORK)); \
                                } \
                        } while (0)
 #define        arm_store_membase(inst,reg,basereg,imm) \
@@ -825,27 +855,27 @@ extern int arm_is_complex_imm(int value);
                                if(__mb_offset >= 0 && __mb_offset < (1 << 10) && \
                                   (__mb_offset & 3) == 0) \
                                { \
-                                       *(inst)++ = arm_prefix(0x0D800100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D800100 | (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) \
                                { \
-                                       *(inst)++ = arm_prefix(0x0D080100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D080100 | (mask)) | \
                                                        (((unsigned int)(basereg)) << 16) | \
                                                        (((unsigned int)(reg)) << 12) | \
-                                                        ((unsigned int)(((-__mb_offset) / 4) & 0xFF));\
+                                                        ((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(0x0D800100 | (mask)) | \
+                                       arm_inst_add((inst), arm_prefix(0x0D800100 | (mask)) | \
                                                        (((unsigned int)ARM_WORK) << 16) | \
-                                                       (((unsigned int)(reg)) << 12); \
+                                                       (((unsigned int)(reg)) << 12)); \
                                } \
                        } while (0)
 #define        arm_store_membase_float32(inst,reg,basereg,imm) \
@@ -873,11 +903,11 @@ extern int arm_is_complex_imm(int value);
  */
 #define arm_load_memindex_either(inst,reg,basereg,indexreg,shift,mask) \
                        do { \
-                               *(inst)++ = arm_prefix(0x07900000 | (mask)) | \
+                               arm_inst_add((inst), arm_prefix(0x07900000 | (mask)) | \
                                                        (((unsigned int)(basereg)) << 16) | \
                                                        (((unsigned int)(reg)) << 12) | \
                                                        (((unsigned int)(shift)) << 7) | \
-                                                        ((unsigned int)(indexreg)); \
+                                                        ((unsigned int)(indexreg))); \
                        } while (0)
 #define        arm_load_memindex(inst,reg,basereg,indexreg)    \
                        do { \
@@ -928,11 +958,11 @@ extern int arm_is_complex_imm(int value);
  */
 #define arm_store_memindex_either(inst,reg,basereg,indexreg,shift,mask)        \
                        do { \
-                               *(inst)++ = arm_prefix(0x07800000 | (mask)) | \
+                               arm_inst_add((inst), arm_prefix(0x07800000 | (mask)) | \
                                                        (((unsigned int)(basereg)) << 16) | \
                                                        (((unsigned int)(reg)) << 12) | \
                                                        (((unsigned int)(shift)) << 7) | \
-                                                        ((unsigned int)(indexreg)); \
+                                                        ((unsigned int)(indexreg))); \
                        } while (0)
 #define        arm_store_memindex(inst,reg,basereg,indexreg)   \
                        do { \
index 21ea02a12333920a7c871b989be9ca157e19c7a6..da6f3f972f761ba0fe831f6d852325235b986deb 100644 (file)
 #define        ROUND_STACK(size)       \
                (((size) + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
 
+/*
+ * Load the instruction pointer from the generation context.
+ */
+#define        jit_gen_load_inst_ptr(gen,inst) \
+               do { \
+                       arm_inst_buf_init((inst), (gen)->posn.ptr, (gen)->posn.limit); \
+               } while (0)
+
+/*
+ * Save the instruction pointer back to the generation context.
+ */
+#define        jit_gen_save_inst_ptr(gen,inst) \
+               do { \
+                       (gen)->posn.ptr = (unsigned char *)arm_inst_get_posn(inst); \
+               } while (0)
+
 void _jit_init_backend(void)
 {
        /* Nothing to do here */
@@ -50,24 +66,12 @@ void _jit_gen_get_elf_info(jit_elf_info_t *info)
 /*
  * Flush the contents of the constant pool.
  */
-#define        check_for_word()        \
-       do { \
-               if(inst >= limit) \
-               { \
-                       jit_cache_mark_full(&(gen->posn)); \
-                       gen->num_constants = 0; \
-                       gen->align_constants = 0; \
-                       gen->first_constant_use = 0; \
-                       return; \
-               } \
-       } while (0)
 static void flush_constants(jit_gencode_t gen, int after_epilog)
 {
-       arm_inst_ptr inst;
-       arm_inst_ptr limit;
-       arm_inst_ptr patch;
-       arm_inst_ptr current;
-       arm_inst_ptr fixup;
+       arm_inst_buf inst;
+       arm_inst_word *patch;
+       arm_inst_word *current;
+       arm_inst_word *fixup;
        int index, value, offset;
 
        /* Bail out if there are no constants to flush */
@@ -77,14 +81,12 @@ static void flush_constants(jit_gencode_t gen, int after_epilog)
        }
 
        /* Initialize the cache output pointer */
-       inst = (arm_inst_ptr)(gen->posn.ptr);
-       limit = (arm_inst_ptr)(gen->posn.limit);
+       jit_gen_load_inst_ptr(gen, inst);
 
        /* Jump over the constant pool if it is being output inline */
        if(!after_epilog)
        {
-               patch = inst;
-               check_for_word();
+               patch = arm_inst_get_posn(inst);
                arm_jump_imm(inst, 0);
        }
        else
@@ -93,18 +95,16 @@ static void flush_constants(jit_gencode_t gen, int after_epilog)
        }
 
        /* Align the constant pool, if requested */
-       if(gen->align_constants && (((int)inst) & 7) != 0)
+       if(gen->align_constants && (((int)arm_inst_get_posn(inst)) & 7) != 0)
        {
-               check_for_word();
-               *inst++ = 0;
+               arm_inst_add(inst, 0);
        }
 
        /* Output the constant values and apply the necessary fixups */
        for(index = 0; index < gen->num_constants; ++index)
        {
-               current = inst;
-               check_for_word();
-               *inst++ = gen->constants[index];
+               current = arm_inst_get_posn(inst);
+               arm_inst_add(inst, gen->constants[index]);
                fixup = gen->fixup_constants[index];
                while(fixup != 0)
                {
@@ -112,14 +112,14 @@ static void flush_constants(jit_gencode_t gen, int after_epilog)
                        {
                                /* Word constant fixup */
                                value = *fixup & 0x0FFF;
-                               offset = ((inst - 1 - fixup) * 4) - 8;
+                               offset = ((arm_inst_get_posn(inst) - 1 - fixup) * 4) - 8;
                                *fixup = ((*fixup & ~0x0FFF) | offset);
                        }
                        else
                        {
                                /* Floating-point constant fixup */
                                value = (*fixup & 0x00FF) * 4;
-                               offset = ((inst - 1 - fixup) * 4) - 8;
+                               offset = ((arm_inst_get_posn(inst) - 1 - fixup) * 4) - 8;
                                *fixup = ((*fixup & ~0x00FF) | (offset / 4));
                        }
                        if(value)
@@ -136,14 +136,14 @@ static void flush_constants(jit_gencode_t gen, int after_epilog)
        /* Backpatch the jump if necessary */
        if(!after_epilog)
        {
-               arm_patch(patch, inst);
+               arm_patch(inst, patch, arm_inst_get_posn(inst));
        }
 
        /* Flush the pool state and restart */
        gen->num_constants = 0;
        gen->align_constants = 0;
        gen->first_constant_use = 0;
-       gen->posn.ptr = (unsigned char *)inst;
+       jit_gen_save_inst_ptr(gen, inst);
 }
 
 /*
@@ -152,8 +152,8 @@ static void flush_constants(jit_gencode_t gen, int after_epilog)
 static int flush_if_too_far(jit_gencode_t gen)
 {
        if(gen->first_constant_use &&
-          (((arm_inst_ptr)(gen->posn.ptr)) -
-                       ((arm_inst_ptr)(gen->first_constant_use))) >= 100)
+          (((arm_inst_word *)(gen->posn.ptr)) -
+                       ((arm_inst_word *)(gen->first_constant_use))) >= 100)
        {
                flush_constants(gen, 0);
                return 1;
@@ -168,10 +168,15 @@ static int flush_if_too_far(jit_gencode_t gen)
  * Add a fixup for a particular constant pool entry.
  */
 static void add_constant_fixup
-       (jit_gencode_t gen, int index, arm_inst_ptr fixup)
+       (jit_gencode_t gen, int index, arm_inst_word *fixup)
 {
-       arm_inst_ptr prev;
+       arm_inst_word *prev;
        int value;
+       if(((unsigned char *)fixup) >= gen->posn.limit)
+       {
+               /* The instruction buffer is full, so don't record this fixup */
+               return;
+       }
        prev = gen->fixup_constants[index];
        if(prev)
        {
@@ -200,7 +205,7 @@ static void add_constant_fixup
  * Add an immediate value to the constant pool.  The constant
  * is loaded from the instruction at "fixup".
  */
-static void add_constant(jit_gencode_t gen, int value, arm_inst_ptr fixup)
+static void add_constant(jit_gencode_t gen, int value, arm_inst_word *fixup)
 {
        int index;
 
@@ -231,7 +236,7 @@ static void add_constant(jit_gencode_t gen, int value, arm_inst_ptr fixup)
  * Add a double-word immedite value to the constant pool.
  */
 static void add_constant_dword
-       (jit_gencode_t gen, int value1, int value2, arm_inst_ptr fixup, int align)
+       (jit_gencode_t gen, int value1, int value2, arm_inst_word *fixup, int align)
 {
        int index;
 
@@ -282,88 +287,64 @@ static void add_constant_dword
  * Load an immediate value into a word register.  If the value is
  * complicated, then add an entry to the constant pool.
  */
-static arm_inst_ptr mov_reg_imm
-       (jit_gencode_t gen, arm_inst_ptr inst, int reg, int value)
+static void mov_reg_imm
+       (jit_gencode_t gen, arm_inst_buf *inst, int reg, int value)
 {
-       arm_inst_ptr fixup;
-
-       /* Bail out if the buffer is full */
-       if(inst >= (arm_inst_ptr)(gen->posn.limit))
-       {
-               return inst;
-       }
+       arm_inst_word *fixup;
 
        /* Bail out if the value is not complex enough to need a pool entry */
        if(!arm_is_complex_imm(value))
        {
-               arm_mov_reg_imm(inst, reg, value);
-               return inst;
+               arm_mov_reg_imm(*inst, reg, value);
+               return;
        }
 
        /* Output a placeholder to load the value later */
-       fixup = inst;
-       arm_load_membase(inst, reg, ARM_PC, 0);
+       fixup = arm_inst_get_posn(*inst);
+       arm_load_membase(*inst, reg, ARM_PC, 0);
 
        /* Add the constant to the pool, which may cause a flush */
-       gen->posn.ptr = (unsigned char *)inst;
+       jit_gen_save_inst_ptr(gen, *inst);
        add_constant(gen, value, fixup);
-
-       /* Return the new program counter location */
-       return (arm_inst_ptr)(gen->posn.ptr);
+       jit_gen_load_inst_ptr(gen, *inst);
 }
 
 /*
  * Load a float32 immediate value into a float register.  If the value is
  * complicated, then add an entry to the constant pool.
  */
-static arm_inst_ptr mov_freg_imm_32
-       (jit_gencode_t gen, arm_inst_ptr inst, int reg, int value)
+static void mov_freg_imm_32
+       (jit_gencode_t gen, arm_inst_buf *inst, int reg, int value)
 {
-       arm_inst_ptr fixup;
-
-       /* Bail out if the buffer is full */
-       if(inst >= (arm_inst_ptr)(gen->posn.limit))
-       {
-               return inst;
-       }
+       arm_inst_word *fixup;
 
        /* Output a placeholder to load the value later */
-       fixup = inst;
-       arm_load_membase_float32(inst, reg, ARM_PC, 0);
+       fixup = arm_inst_get_posn(*inst);
+       arm_load_membase_float32(*inst, reg, ARM_PC, 0);
 
        /* Add the constant to the pool, which may cause a flush */
-       gen->posn.ptr = (unsigned char *)inst;
+       jit_gen_save_inst_ptr(gen, *inst);
        add_constant(gen, value, fixup);
-
-       /* Return the new program counter location */
-       return (arm_inst_ptr)(gen->posn.ptr);
+       jit_gen_load_inst_ptr(gen, *inst);
 }
 
 /*
  * Load a float64 immediate value into a float register.  If the value is
  * complicated, then add an entry to the constant pool.
  */
-static arm_inst_ptr mov_freg_imm_64
-       (jit_gencode_t gen, arm_inst_ptr inst, int reg, int value1, int value2)
+static void mov_freg_imm_64
+       (jit_gencode_t gen, arm_inst_buf *inst, int reg, int value1, int value2)
 {
-       arm_inst_ptr fixup;
-
-       /* Bail out if the buffer is full */
-       if(inst >= (arm_inst_ptr)(gen->posn.limit))
-       {
-               return inst;
-       }
+       arm_inst_word *fixup;
 
        /* Output a placeholder to load the value later */
-       fixup = inst;
-       arm_load_membase_float64(inst, reg, ARM_PC, 0);
+       fixup = arm_inst_get_posn(*inst);
+       arm_load_membase_float64(*inst, reg, ARM_PC, 0);
 
        /* Add the constant to the pool, which may cause a flush */
-       gen->posn.ptr = (unsigned char *)inst;
+       jit_gen_save_inst_ptr(gen, *inst);
        add_constant_dword(gen, value1, value2, fixup, 1);
-
-       /* Return the new program counter location */
-       return (arm_inst_ptr)(gen->posn.ptr);
+       jit_gen_load_inst_ptr(gen, *inst);
 }
 
 /*
@@ -774,11 +755,14 @@ int _jit_opcode_is_supported(int opcode)
 void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
 {
        unsigned int prolog[JIT_PROLOG_SIZE / sizeof(int)];
-       arm_inst_ptr inst = prolog;
+       arm_inst_buf inst;
        int reg, regset;
        unsigned int saved;
        unsigned int frame_size;
 
+       /* Initialize the instruction buffer */
+       arm_inst_buf_init(inst, prolog, prolog + JIT_PROLOG_SIZE / sizeof(int));
+
        /* Determine which registers need to be preserved */
        regset = 0;
        saved = 0;
@@ -805,7 +789,7 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
        }
 
        /* Copy the prolog into place and return the adjusted entry position */
-       reg = (int)((inst - prolog) * sizeof(unsigned int));
+       reg = (int)((arm_inst_get_posn(inst) - prolog) * sizeof(unsigned int));
        jit_memcpy(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg, prolog, reg);
        return (void *)(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg);
 }
@@ -813,17 +797,13 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
 void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
 {
        int reg, regset;
-       arm_inst_ptr inst;
+       arm_inst_buf inst;
        void **fixup;
        void **next;
        jit_nint offset;
 
-       /* Bail out if there is insufficient space for the epilog */
-       if(!jit_cache_check_for_n(&(gen->posn), 4))
-       {
-               jit_cache_mark_full(&(gen->posn));
-               return;
-       }
+       /* Initialize the instruction buffer */
+       jit_gen_load_inst_ptr(gen, inst);
 
        /* Determine which registers need to be restored when we return */
        regset = 0;
@@ -849,15 +829,14 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
                {
                        next = (void **)(((unsigned char *)fixup) - offset);
                }
-               arm_patch(fixup, gen->posn.ptr);
+               arm_patch(inst, fixup, arm_inst_get_posn(inst));
                fixup = next;
        }
        gen->epilog_fixup = 0;
 
        /* Pop the local stack frame and return */
-       inst = (arm_inst_ptr)(gen->posn.ptr);
        arm_pop_frame(inst, regset);
-       gen->posn.ptr = (unsigned char *)inst;
+       jit_gen_save_inst_ptr(gen, inst);
 
        /* Flush the remainder of the constant pool */
        flush_constants(gen, 1);
@@ -866,19 +845,14 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
 void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
 {
        void *ptr, *entry;
-       arm_inst_ptr inst;
-       if(!jit_cache_check_for_n(&(gen->posn), 12))
-       {
-               jit_cache_mark_full(&(gen->posn));
-               return 0;
-       }
+       arm_inst_buf inst;
+       jit_gen_load_inst_ptr(gen, inst);
        ptr = (void *)&(func->entry_point);
        entry = gen->posn.ptr;
-       inst = (arm_inst_ptr)(gen->posn.ptr);
        arm_load_membase(inst, ARM_WORK, ARM_PC, 0);
        arm_load_membase(inst, ARM_PC, ARM_WORK, 0);
-       *inst++ = (unsigned int)ptr;
-       gen->posn.ptr = (unsigned char *)inst;
+       arm_inst_add(inst, (unsigned int)ptr);
+       jit_gen_save_inst_ptr(gen, inst);
        return entry;
 }
 
@@ -886,14 +860,10 @@ void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
  * Setup or teardown the ARM code output process.
  */
 #define        jit_cache_setup_output(needed)  \
-       arm_inst_ptr inst = (arm_inst_ptr)(gen->posn.ptr); \
-       if(!jit_cache_check_for_n(&(gen->posn), (needed))) \
-       { \
-               jit_cache_mark_full(&(gen->posn)); \
-               return; \
-       }
+       arm_inst_buf inst; \
+       jit_gen_load_inst_ptr(gen, inst)
 #define        jit_cache_end_output()  \
-       gen->posn.ptr = (unsigned char *)inst
+       jit_gen_save_inst_ptr(gen, inst)
 
 void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
                                                int other_reg, jit_value_t value)
@@ -904,7 +874,7 @@ void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
        jit_cache_setup_output(32);
        if(flush_if_too_far(gen))
        {
-               inst = (arm_inst_ptr)(gen->posn.ptr);
+               jit_gen_load_inst_ptr(gen, inst);
        }
 
        /* Output an appropriate instruction to spill the value */
@@ -956,7 +926,7 @@ void _jit_gen_load_value
        jit_cache_setup_output(32);
        if(flush_if_too_far(gen))
        {
-               inst = (arm_inst_ptr)(gen->posn.ptr);
+               jit_gen_load_inst_ptr(gen, inst);
        }
 
        if(value->is_constant)
@@ -971,8 +941,8 @@ void _jit_gen_load_value
                        case JIT_TYPE_INT:
                        case JIT_TYPE_UINT:
                        {
-                               inst = mov_reg_imm(gen, inst, _jit_reg_info[reg].cpu_reg,
-                                                              (jit_nint)(value->address));
+                               mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
+                                                       (jit_nint)(value->address));
                        }
                        break;
 
@@ -981,10 +951,10 @@ void _jit_gen_load_value
                        {
                                jit_long long_value;
                                long_value = jit_value_get_long_constant(value);
-                               inst = mov_reg_imm(gen, inst, _jit_reg_info[reg].cpu_reg,
-                                                                  (jit_int)long_value);
-                               inst = mov_reg_imm(gen, inst, _jit_reg_info[reg].cpu_reg + 1,
-                                                                   (jit_int)(long_value >> 32));
+                               mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
+                                                   (jit_int)long_value);
+                               mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg + 1,
+                                                   (jit_int)(long_value >> 32));
                        }
                        break;
 
@@ -992,20 +962,15 @@ void _jit_gen_load_value
                        {
                                jit_float32 float32_value;
                                float32_value = jit_value_get_float32_constant(value);
-                               if(!jit_cache_check_for_n(&(gen->posn), 32))
-                               {
-                                       jit_cache_mark_full(&(gen->posn));
-                                       return;
-                               }
                                if(reg < 16)
                                {
-                                       inst = mov_reg_imm(gen, inst, _jit_reg_info[reg].cpu_reg,
-                                                                          *((int *)&float32_value));
+                                       mov_reg_imm(gen, &inst, _jit_reg_info[reg].cpu_reg,
+                                                           *((int *)&float32_value));
                                }
                                else
                                {
-                                       inst = mov_freg_imm_32
-                                               (gen, inst, _jit_reg_info[reg].cpu_reg,
+                                       mov_freg_imm_32
+                                               (gen, &inst, _jit_reg_info[reg].cpu_reg,
                                             *((int *)&float32_value));
                                }
                        }
@@ -1016,24 +981,19 @@ void _jit_gen_load_value
                        {
                                jit_float64 float64_value;
                                float64_value = jit_value_get_float64_constant(value);
-                               if(!jit_cache_check_for_n(&(gen->posn), 32))
-                               {
-                                       jit_cache_mark_full(&(gen->posn));
-                                       return;
-                               }
                                if(reg < 16)
                                {
-                                       inst = mov_reg_imm
-                                               (gen, inst, _jit_reg_info[reg].cpu_reg,
+                                       mov_reg_imm
+                                               (gen, &inst, _jit_reg_info[reg].cpu_reg,
                                                 ((int *)&float64_value)[0]);
-                                       inst = mov_reg_imm
-                                               (gen, inst, _jit_reg_info[reg].cpu_reg + 1,
+                                       mov_reg_imm
+                                               (gen, &inst, _jit_reg_info[reg].cpu_reg + 1,
                                                 ((int *)&float64_value)[1]);
                                }
                                else
                                {
-                                       inst = mov_freg_imm_64
-                                               (gen, inst, _jit_reg_info[reg].cpu_reg,
+                                       mov_freg_imm_64
+                                               (gen, &inst, _jit_reg_info[reg].cpu_reg,
                                             ((int *)&float64_value)[0],
                                             ((int *)&float64_value)[1]);
                                }
@@ -1155,78 +1115,81 @@ void _jit_gen_fix_value(jit_value_t value)
 /*
  * Output a branch instruction.
  */
-static arm_inst_ptr output_branch
-       (jit_function_t func, arm_inst_ptr inst, int cond, jit_insn_t insn)
+static void output_branch
+       (jit_function_t func, arm_inst_buf *inst, int cond, jit_insn_t insn)
 {
        jit_block_t block;
        int offset;
        block = jit_block_from_label(func, (jit_label_t)(insn->dest));
        if(!block)
        {
-               return inst;
+               return;
+       }
+       if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
+       {
+               /* The buffer has overflowed, so don't worry about fixups */
+               return;
        }
        if(block->address)
        {
                /* We already know the address of the block */
-               arm_branch(inst, cond, block->address);
+               arm_branch(*inst, cond, block->address);
        }
        else
        {
                /* Output a placeholder and record on the block's fixup list */
                if(block->fixup_list)
                {
-                       offset = (int)(((unsigned char *)inst) -
+                       offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
                                                   ((unsigned char *)(block->fixup_list)));
                }
                else
                {
                        offset = 0;
                }
-               arm_branch_imm(inst, cond, offset);
-               block->fixup_list = (void *)(inst - 1);
+               arm_branch_imm(*inst, cond, offset);
+               block->fixup_list = (void *)(arm_inst_get_posn(*inst) - 1);
        }
-       return inst;
 }
 
 /*
  * Throw a builtin exception.
  */
-static arm_inst_ptr throw_builtin
-               (arm_inst_ptr inst, jit_function_t func, int cond, int type)
+static void throw_builtin
+               (arm_inst_buf *inst, jit_function_t func, int cond, int type)
 {
-       arm_inst_ptr patch;
+       arm_inst_word *patch;
 
        /* Branch past the following code if "cond" is not true */
-       patch = inst;
-       arm_branch_imm(inst, cond ^ 0x01, 0);
+       patch = arm_inst_get_posn(*inst);
+       arm_branch_imm(*inst, cond ^ 0x01, 0);
 
        /* We need to update "catch_pc" if we have a "try" block */
        if(func->builder->setjmp_value != 0)
        {
                _jit_gen_fix_value(func->builder->setjmp_value);
-               arm_mov_reg_reg(inst, ARM_WORK, ARM_PC);
-               arm_store_membase(inst, ARM_WORK, ARM_FP,
+               arm_mov_reg_reg(*inst, ARM_WORK, ARM_PC);
+               arm_store_membase(*inst, ARM_WORK, ARM_FP,
                                                  func->builder->setjmp_value->frame_offset +
                                                  jit_jmp_catch_pc_offset);
        }
 
        /* Push the exception type onto the stack */
-       arm_mov_reg_imm(inst, ARM_WORK, type);
-       arm_push_reg(inst, ARM_WORK);
+       arm_mov_reg_imm(*inst, ARM_WORK, type);
+       arm_push_reg(*inst, ARM_WORK);
 
        /* Call the "jit_exception_builtin" function, which will never return */
-       arm_call(inst, jit_exception_builtin);
+       arm_call(*inst, jit_exception_builtin);
 
        /* Back-patch the previous branch instruction */
-       arm_patch(patch, inst);
-       return inst;
+       arm_patch(*inst, patch, arm_inst_get_posn(*inst));
 }
 
 /*
  * Jump to the current function's epilog.
  */
-static arm_inst_ptr jump_to_epilog
-       (jit_gencode_t gen, arm_inst_ptr inst, jit_block_t block)
+static void jump_to_epilog
+       (jit_gencode_t gen, arm_inst_buf *inst, jit_block_t block)
 {
        int offset;
 
@@ -1239,22 +1202,27 @@ static arm_inst_ptr jump_to_epilog
        }
        if(!block)
        {
-               return inst;
+               return;
+       }
+
+       /* Bail out if the instruction buffer has overflowed */
+       if(arm_inst_get_posn(*inst) >= arm_inst_get_limit(*inst))
+       {
+               return;
        }
 
        /* Output a placeholder for the jump and add it to the fixup list */
        if(gen->epilog_fixup)
        {
-               offset = (int)(((unsigned char *)inst) -
+               offset = (int)(((unsigned char *)arm_inst_get_posn(*inst)) -
                                           ((unsigned char *)(gen->epilog_fixup)));
        }
        else
        {
                offset = 0;
        }
-       arm_branch_imm(inst, ARM_CC_AL, offset);
-       gen->epilog_fixup = (void *)(inst - 1);
-       return inst;
+       arm_branch_imm(*inst, ARM_CC_AL, offset);
+       gen->epilog_fixup = (void *)(arm_inst_get_posn(*inst) - 1);
 }
 
 #define        TODO()          \
@@ -1286,6 +1254,7 @@ void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block)
        void **fixup;
        void **next;
        jit_nint offset;
+       arm_inst_buf inst;
 
        /* Set the address of this block */
        block->address = (void *)(gen->posn.ptr);
@@ -1303,7 +1272,8 @@ void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block)
                {
                        next = (void **)(((unsigned char *)fixup) - offset);
                }
-               arm_patch(fixup, block->address);
+               jit_gen_load_inst_ptr(gen, inst);
+               arm_patch(inst, fixup, block->address);
                fixup = next;
        }
        block->fixup_list = 0;
index 39b8d01bab0ba7d1a9eccc390f288eb7309756fc..94acca01b34e472c11184d9f040ea5aede2dbb6d 100644 (file)
@@ -105,7 +105,7 @@ extern      "C" {
                        int *fixup_constants[JIT_ARM_MAX_CONSTANTS]; \
                        int num_constants; \
                        int align_constants; \
-                       int *first_constant_use
+                       unsigned int *first_constant_use
 #define        jit_extra_gen_init(gen) \
                        do { \
                                (gen)->num_constants = 0; \
index f0c34271f9c081f48d23d086cf6a26ea5b88c35e..7c1b6f513ba81aaf25a4794d0adc2c2f4ea351eb 100644 (file)
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-%inst_type arm_inst_ptr
+%inst_type arm_inst_buf
 
 /*
  * Conversion opcodes.
@@ -267,119 +267,119 @@ JIT_OP_ISHR_UN: binary
 JIT_OP_BR: spill_before
        [] -> {
                /* ARM_CC_AL == "always branch" */
-               inst = output_branch(func, inst, ARM_CC_AL, insn);
+               output_branch(func, &inst, ARM_CC_AL, insn);
        }
 
 JIT_OP_BR_IFALSE: unary_branch
        [reg] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, 0);
-               inst = output_branch(func, inst, ARM_CC_EQ, insn);
+               output_branch(func, &inst, ARM_CC_EQ, insn);
        }
 
 JIT_OP_BR_ITRUE: unary_branch
        [reg] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, 0);
-               inst = output_branch(func, inst, ARM_CC_NE, insn);
+               output_branch(func, &inst, ARM_CC_NE, insn);
        }
 
 JIT_OP_BR_IEQ: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_EQ, insn);
+               output_branch(func, &inst, ARM_CC_EQ, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_EQ, insn);
+               output_branch(func, &inst, ARM_CC_EQ, insn);
        }
 
 JIT_OP_BR_INE: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_NE, insn);
+               output_branch(func, &inst, ARM_CC_NE, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_NE, insn);
+               output_branch(func, &inst, ARM_CC_NE, insn);
        }
 
 JIT_OP_BR_ILT: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LT, insn);
+               output_branch(func, &inst, ARM_CC_LT, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LT, insn);
+               output_branch(func, &inst, ARM_CC_LT, insn);
        }
 
 JIT_OP_BR_ILT_UN: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LT_UN, insn);
+               output_branch(func, &inst, ARM_CC_LT_UN, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LT_UN, insn);
+               output_branch(func, &inst, ARM_CC_LT_UN, insn);
        }
 
 JIT_OP_BR_ILE: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LE, insn);
+               output_branch(func, &inst, ARM_CC_LE, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LE, insn);
+               output_branch(func, &inst, ARM_CC_LE, insn);
        }
 
 JIT_OP_BR_ILE_UN: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LE_UN, insn);
+               output_branch(func, &inst, ARM_CC_LE_UN, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_LE_UN, insn);
+               output_branch(func, &inst, ARM_CC_LE_UN, insn);
        }
 
 JIT_OP_BR_IGT: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GT, insn);
+               output_branch(func, &inst, ARM_CC_GT, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GT, insn);
+               output_branch(func, &inst, ARM_CC_GT, insn);
        }
 
 JIT_OP_BR_IGT_UN: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GT_UN, insn);
+               output_branch(func, &inst, ARM_CC_GT_UN, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GT_UN, insn);
+               output_branch(func, &inst, ARM_CC_GT_UN, insn);
        }
 
 JIT_OP_BR_IGE: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GE, insn);
+               output_branch(func, &inst, ARM_CC_GE, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GE, insn);
+               output_branch(func, &inst, ARM_CC_GE, insn);
        }
 
 JIT_OP_BR_IGE_UN: binary_branch
        [reg, immu8] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GE_UN, insn);
+               output_branch(func, &inst, ARM_CC_GE_UN, insn);
        }
        [reg, reg] -> {
                arm_test_reg_reg(inst, ARM_CMP, $1, $2);
-               inst = output_branch(func, inst, ARM_CC_GE_UN, insn);
+               output_branch(func, &inst, ARM_CC_GE_UN, insn);
        }
 
 /*
@@ -541,7 +541,7 @@ JIT_OP_IGE_UN: binary
 JIT_OP_CHECK_NULL: unary_note
        [reg] -> {
                arm_test_reg_imm8(inst, ARM_CMP, $1, 0);
-               inst = throw_builtin(inst, func, ARM_CC_EQ, JIT_RESULT_NULL_REFERENCE);
+               throw_builtin(&inst, func, ARM_CC_EQ, JIT_RESULT_NULL_REFERENCE);
        }
 
 /*
@@ -579,7 +579,7 @@ JIT_OP_CALL_EXTERNAL:
 
 JIT_OP_RETURN:
        [] -> {
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_RETURN_INT: unary_branch
@@ -589,17 +589,17 @@ JIT_OP_RETURN_INT: unary_branch
                {
                        arm_mov_reg_reg(inst, ARM_R0, cpu_reg);
                }
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_RETURN_LONG: spill_before
        [] -> {
                if(jit_value_is_constant(insn->value1))
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_R0, ((jit_int *)(insn->value1->address))[0]);
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_R1, ((jit_int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_R0, ((jit_int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_R1, ((jit_int *)(insn->value1->address))[1]);
                }
                else
                {
@@ -609,7 +609,7 @@ JIT_OP_RETURN_LONG: spill_before
                        arm_load_membase(inst, ARM_R0, ARM_FP, offset);
                        arm_load_membase(inst, ARM_R1, ARM_FP, offset + 4);
                }
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_RETURN_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_branch
@@ -618,31 +618,26 @@ JIT_OP_RETURN_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_branch
                {
                        arm_alu_freg_32(inst, ARM_MVF, ARM_F0, $1);
                }
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_RETURN_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_spill_all(gen);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_R0, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_R0, ((int *)(insn->value1->address))[0]);
                }
                else
                {
                        arm_load_membase(inst, ARM_R0, ARM_FP, insn->value1->frame_offset);
                }
-               inst = jump_to_epilog(gen, inst, block);
-               gen->posn.ptr = (unsigned char *)inst;
+               jump_to_epilog(gen, &inst, block);
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT
@@ -652,26 +647,21 @@ JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT
                {
                        arm_alu_freg(inst, ARM_MVF, ARM_F0, $1);
                }
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_spill_all(gen);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_R0, ((int *)(insn->value1->address))[0]);
-                       inst= mov_reg_imm
-                               (gen, inst, ARM_R1, ((int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_R0, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_R1, ((int *)(insn->value1->address))[1]);
                }
                else
                {
@@ -679,8 +669,8 @@ JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
                        arm_load_membase(inst, ARM_R1, ARM_FP,
                                                         insn->value1->frame_offset + 4);
                }
-               inst = jump_to_epilog(gen, inst, block);
-               gen->posn.ptr = (unsigned char *)inst;
+               jump_to_epilog(gen, &inst, block);
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_RETURN_SMALL_STRUCT: unary_branch
@@ -751,7 +741,7 @@ JIT_OP_RETURN_SMALL_STRUCT: unary_branch
                        }
                        break;
                }
-               inst = jump_to_epilog(gen, inst, block);
+               jump_to_epilog(gen, &inst, block);
        }
 
 JIT_OP_SETUP_FOR_NESTED: spill_before
@@ -783,12 +773,6 @@ JIT_OP_SETUP_FOR_SIBLING: spill_before
                arm_load_membase(inst, cpu_reg, ARM_FP, JIT_APPLY_PARENT_FRAME_OFFSET);
                while(level > 0)
                {
-                       gen->posn.ptr = (unsigned char *)inst;
-                       if(!jit_cache_check_for_n(&(gen->posn), 16))
-                       {
-                               jit_cache_mark_full(&(gen->posn));
-                               return;
-                       }
                        arm_load_membase(inst, cpu_reg, cpu_reg,
                                                         JIT_APPLY_PARENT_FRAME_OFFSET);
                        --level;
@@ -826,25 +810,20 @@ JIT_OP_COPY_INT: unary
 
 JIT_OP_COPY_LONG: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_regs_force_out(gen, insn->dest, 1);
                _jit_gen_fix_value(insn->value1);
                _jit_gen_fix_value(insn->dest);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset);
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset + 4);
                }
@@ -859,7 +838,7 @@ JIT_OP_COPY_LONG: manual
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset + 4);
                }
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_COPY_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary
@@ -867,21 +846,16 @@ JIT_OP_COPY_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary
 
 JIT_OP_COPY_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_regs_force_out(gen, insn->dest, 1);
                _jit_gen_fix_value(insn->value1);
                _jit_gen_fix_value(insn->dest);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                }
                else
                {
@@ -889,7 +863,7 @@ JIT_OP_COPY_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
                                                         insn->value1->frame_offset);
                }
                arm_store_membase(inst, ARM_WORK, ARM_FP, insn->dest->frame_offset);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary
@@ -897,25 +871,20 @@ JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary
 
 JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_regs_force_out(gen, insn->dest, 1);
                _jit_gen_fix_value(insn->value1);
                _jit_gen_fix_value(insn->dest);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset);
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset + 4);
                }
@@ -930,7 +899,7 @@ JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
                        arm_store_membase(inst, ARM_WORK, ARM_FP,
                                                          insn->dest->frame_offset + 4);
                }
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_COPY_STRUCT: manual
@@ -941,7 +910,7 @@ JIT_OP_COPY_STRUCT: manual
 
 JIT_OP_COPY_STORE_BYTE: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg;
                _jit_regs_force_out(gen, insn->dest, 1);
                _jit_gen_fix_value(insn->dest);
@@ -949,20 +918,15 @@ JIT_OP_COPY_STORE_BYTE: manual
                        (gen, insn->value1, 0,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
                                                         JIT_INSN_VALUE1_LIVE)));
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                arm_store_membase_byte(inst, _jit_reg_info[reg].cpu_reg,
                                                           ARM_FP, insn->dest->frame_offset);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_COPY_STORE_SHORT: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg;
                _jit_regs_force_out(gen, insn->dest, 1);
                _jit_gen_fix_value(insn->dest);
@@ -970,30 +934,20 @@ JIT_OP_COPY_STORE_SHORT: manual
                        (gen, insn->value1, 1,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
                                                         JIT_INSN_VALUE1_LIVE)));
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                arm_store_membase_short(inst, _jit_reg_info[reg].cpu_reg,
                                                            ARM_FP, insn->dest->frame_offset);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
                _jit_regs_free_reg(gen, reg, 1);
        }
 
 JIT_OP_ADDRESS_OF: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg, offset;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                reg = _jit_regs_dest_value(gen, insn->dest);
                reg = _jit_reg_info[reg].cpu_reg;
                offset = insn->value1->frame_offset;
@@ -1009,7 +963,7 @@ JIT_OP_ADDRESS_OF: manual
                {
                        arm_mov_reg_reg(inst, reg, ARM_FP);
                }
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 /*
@@ -1026,22 +980,17 @@ JIT_OP_PUSH_INT: unary_note
 
 JIT_OP_PUSH_LONG: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
                        arm_push_reg(inst, ARM_WORK);
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                        arm_push_reg(inst, ARM_WORK);
                }
                else
@@ -1053,7 +1002,7 @@ JIT_OP_PUSH_LONG: manual
                                                         insn->value1->frame_offset);
                        arm_push_reg(inst, ARM_WORK);
                }
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_PUSH_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_note
@@ -1063,19 +1012,14 @@ JIT_OP_PUSH_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_note
 
 JIT_OP_PUSH_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                }
                else
                {
@@ -1083,7 +1027,7 @@ JIT_OP_PUSH_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
                                                         insn->value1->frame_offset);
                }
                arm_push_reg(inst, ARM_WORK);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary_note
@@ -1093,22 +1037,17 @@ JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary_note
 
 JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                _jit_regs_force_out(gen, insn->value1, 0);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                if(insn->value1->is_constant)
                {
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]);
                        arm_push_reg(inst, ARM_WORK);
-                       inst = mov_reg_imm
-                               (gen, inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
+                       mov_reg_imm
+                               (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]);
                        arm_push_reg(inst, ARM_WORK);
                }
                else
@@ -1120,7 +1059,7 @@ JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
                                                         insn->value1->frame_offset);
                        arm_push_reg(inst, ARM_WORK);
                }
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_PUSH_STRUCT: unary_note
@@ -1234,7 +1173,7 @@ JIT_OP_LOAD_RELATIVE_INT: unary
 
 JIT_OP_LOAD_RELATIVE_LONG: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg = _jit_regs_load_value
                        (gen, insn->value1, 0,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
@@ -1247,18 +1186,13 @@ JIT_OP_LOAD_RELATIVE_LONG: manual
                reg2 = _jit_reg_info[reg2].cpu_reg;
                reg3 = _jit_reg_info[reg3].cpu_reg;
                frame_offset = insn->dest->frame_offset;
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                arm_load_membase(inst, reg2, reg, insn->value2->address);
                arm_load_membase(inst, reg3, reg, insn->value2->address + 4);
                arm_store_membase(inst, reg2, ARM_FP, frame_offset);
                arm_store_membase(inst, reg3, ARM_FP, frame_offset + 4);
                insn->dest->in_frame = 1;
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_LOAD_RELATIVE_FLOAT32: manual
@@ -1281,7 +1215,7 @@ JIT_OP_LOAD_RELATIVE_STRUCT: manual
 
 JIT_OP_STORE_RELATIVE_BYTE: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg = _jit_regs_load_value
                        (gen, insn->dest, 0,
                         (insn->flags & (JIT_INSN_DEST_NEXT_USE |
@@ -1290,21 +1224,16 @@ JIT_OP_STORE_RELATIVE_BYTE: manual
                        (gen, insn->value1, 0,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
                                                         JIT_INSN_VALUE1_LIVE)));
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                reg  = _jit_reg_info[reg].cpu_reg;
                reg2 = _jit_reg_info[reg2].cpu_reg;
                arm_store_membase_byte(inst, reg2, reg, insn->value2->address);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_STORE_RELATIVE_SHORT: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg = _jit_regs_load_value
                        (gen, insn->dest, 0,
                         (insn->flags & (JIT_INSN_DEST_NEXT_USE |
@@ -1313,22 +1242,17 @@ JIT_OP_STORE_RELATIVE_SHORT: manual
                        (gen, insn->value1, 1,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
                                                         JIT_INSN_VALUE1_LIVE)));
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                reg  = _jit_reg_info[reg].cpu_reg;
                reg2 = _jit_reg_info[reg2].cpu_reg;
                arm_store_membase_short(inst, reg2, reg, insn->value2->address);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
                _jit_regs_free_reg(gen, reg2, 1);
        }
 
 JIT_OP_STORE_RELATIVE_INT: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg = _jit_regs_load_value
                        (gen, insn->dest, 0,
                         (insn->flags & (JIT_INSN_DEST_NEXT_USE |
@@ -1337,21 +1261,16 @@ JIT_OP_STORE_RELATIVE_INT: manual
                        (gen, insn->value1, 0,
                         (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
                                                         JIT_INSN_VALUE1_LIVE)));
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                reg  = _jit_reg_info[reg].cpu_reg;
                reg2 = _jit_reg_info[reg2].cpu_reg;
                arm_store_membase(inst, reg2, reg, insn->value2->address);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_STORE_RELATIVE_LONG: manual
        [] -> {
-               arm_inst_ptr inst;
+               arm_inst_buf inst;
                int reg = _jit_regs_load_value
                        (gen, insn->dest, 0,
                         (insn->flags & (JIT_INSN_DEST_NEXT_USE |
@@ -1360,12 +1279,7 @@ JIT_OP_STORE_RELATIVE_LONG: manual
                int frame_offset;
                _jit_regs_get_reg_pair(gen, reg, -1, -1, &reg2, &reg3);
                _jit_gen_fix_value(insn->value1);
-               inst = (arm_inst_ptr)(gen->posn.ptr);
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
+               jit_gen_load_inst_ptr(gen, inst);
                reg  = _jit_reg_info[reg].cpu_reg;
                reg2 = _jit_reg_info[reg2].cpu_reg;
                reg3 = _jit_reg_info[reg3].cpu_reg;
@@ -1374,7 +1288,7 @@ JIT_OP_STORE_RELATIVE_LONG: manual
                arm_load_membase(inst, reg3, ARM_FP, frame_offset + 4);
                arm_store_membase(inst, reg2, reg, insn->value2->address);
                arm_store_membase(inst, reg3, reg, insn->value2->address + 4);
-               gen->posn.ptr = (unsigned char *)inst;
+               jit_gen_save_inst_ptr(gen, inst);
        }
 
 JIT_OP_STORE_RELATIVE_FLOAT32: manual
index dfc2e999088c7bd5e1870e3981adb6ed6343063a..ac76699e5cb9fc44c43ef8f5497e372f1f23440f 100644 (file)
@@ -59,6 +59,7 @@ extern long gensel_linenum;
  * Instruction type for the "inst" variable.
  */
 static char *gensel_inst_type = "unsigned char *";
+static int gensel_new_inst_type = 0;
 
 /*
  * Amount of space to reserve for the primary instruction output.
@@ -277,20 +278,34 @@ static void gensel_output_clause_code(gensel_clause_t clause)
 static void gensel_output_clause(gensel_clause_t clause, int options)
 {
        /* Cache the instruction pointer into "inst" */
-       printf("\t\tinst = (%s)(gen->posn.ptr);\n", gensel_inst_type);
-       printf("\t\tif(!jit_cache_check_for_n(&(gen->posn), %d))\n",
-                  (((options & GENSEL_OPT_MORE_SPACE) == 0)
-                               ? gensel_reserve_space : gensel_reserve_more_space));
-       printf("\t\t{\n");
-       printf("\t\t\tjit_cache_mark_full(&(gen->posn));\n");
-       printf("\t\t\treturn;\n");
-       printf("\t\t}\n");
+       if(gensel_new_inst_type)
+       {
+               printf("\t\tjit_gen_load_inst_ptr(gen, inst);\n");
+       }
+       else
+       {
+               printf("\t\tinst = (%s)(gen->posn.ptr);\n", gensel_inst_type);
+               printf("\t\tif(!jit_cache_check_for_n(&(gen->posn), %d))\n",
+                          (((options & GENSEL_OPT_MORE_SPACE) == 0)
+                                       ? gensel_reserve_space : gensel_reserve_more_space));
+               printf("\t\t{\n");
+               printf("\t\t\tjit_cache_mark_full(&(gen->posn));\n");
+               printf("\t\t\treturn;\n");
+               printf("\t\t}\n");
+       }
 
        /* Output the clause code */
        gensel_output_clause_code(clause);
 
        /* Copy "inst" back into the generation context */
-       printf("\t\tgen->posn.ptr = (unsigned char *)inst;\n");
+       if(gensel_new_inst_type)
+       {
+               printf("\t\tjit_gen_save_inst_ptr(gen, inst);\n");
+       }
+       else
+       {
+               printf("\t\tgen->posn.ptr = (unsigned char *)inst;\n");
+       }
 }
 
 /*
@@ -791,6 +806,7 @@ Rule
                        }
        | K_INST_TYPE IDENTIFIER        {
                                gensel_inst_type = $2;
+                               gensel_new_inst_type = 1;
                        }
        ;