From a09873431d7f22e5e2f97d0e5d9257183a3d4ff0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 9 Jun 2004 23:40:34 +0000 Subject: [PATCH] Redesign the ARM code generation macros so that they have stronger protection against buffer overruns. --- ChangeLog | 5 + jit/jit-apply-arm.c | 13 +- jit/jit-gen-arm.c | 50 ++++--- jit/jit-gen-arm.h | 230 +++++++++++++++++------------- jit/jit-rules-arm.c | 304 ++++++++++++++++++---------------------- jit/jit-rules-arm.h | 2 +- jit/jit-rules-arm.sel | 308 +++++++++++++++-------------------------- tools/gen-sel-parser.y | 34 +++-- 8 files changed, 441 insertions(+), 505 deletions(-) diff --git a/ChangeLog b/ChangeLog index ccc4e39..b510fb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,11 @@ * 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 * jit/Makefile.am, jit/jit-cpuid-x86.c, jit/jit-cpuid-x86.h: diff --git a/jit/jit-apply-arm.c b/jit/jit-apply-arm.c index dd16e23..cb04df3 100644 --- a/jit/jit-apply-arm.c +++ b/jit/jit-apply-arm.c @@ -27,7 +27,10 @@ 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; diff --git a/jit/jit-gen-arm.c b/jit/jit-gen-arm.c index 162d7ae..50b4ba0 100644 --- a/jit/jit-gen-arm.c +++ b/jit/jit-gen-arm.c @@ -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 */ diff --git a/jit/jit-gen-arm.h b/jit/jit-gen-arm.h index c2c80ec..16b7e2c 100644 --- a/jit/jit-gen-arm.h +++ b/jit/jit-gen-arm.h @@ -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 { \ diff --git a/jit/jit-rules-arm.c b/jit/jit-rules-arm.c index 21ea02a..da6f3f9 100644 --- a/jit/jit-rules-arm.c +++ b/jit/jit-rules-arm.c @@ -35,6 +35,22 @@ #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; diff --git a/jit/jit-rules-arm.h b/jit/jit-rules-arm.h index 39b8d01..94acca0 100644 --- a/jit/jit-rules-arm.h +++ b/jit/jit-rules-arm.h @@ -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; \ diff --git a/jit/jit-rules-arm.sel b/jit/jit-rules-arm.sel index f0c3427..7c1b6f5 100644 --- a/jit/jit-rules-arm.sel +++ b/jit/jit-rules-arm.sel @@ -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, ®2, ®3); _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 diff --git a/tools/gen-sel-parser.y b/tools/gen-sel-parser.y index dfc2e99..ac76699 100644 --- a/tools/gen-sel-parser.y +++ b/tools/gen-sel-parser.y @@ -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; } ; -- 2.47.3