protection against buffer overruns.
* 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:
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);
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)
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);
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;
#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;
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;
}
}
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;
}
}
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)
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;
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)
{
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 */
#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.
#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 { \
} \
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)
} \
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)
/*
*/
#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)
/*
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 { \
} \
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) \
} \
else \
{ \
- (inst) = _arm_mov_reg_imm \
- ((inst), (reg), __imm, arm_execute); \
+ _arm_mov_reg_imm(&(inst), (reg), __imm, arm_execute); \
} \
} while (0)
*/
#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)
/*
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)
*/
#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)
/*
*/
#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)
/*
*/
#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))
#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))
#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); \
/*
* 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)
/*
*/
#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)
/*
#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); \
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)
*/
#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)
/*
*/
#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)
/*
#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)
*/
#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)
/*
*/
#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)
/*
*/
#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)
/*
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) \
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) \
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) \
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) \
*/
#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 { \
*/
#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 { \
#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 */
/*
* 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 */
}
/* 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
}
/* 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)
{
{
/* 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)
/* 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);
}
/*
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;
* 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)
{
* 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;
* 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;
* 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);
}
/*
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;
}
/* 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);
}
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;
{
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);
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;
}
* 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)
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 */
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)
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;
{
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;
{
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));
}
}
{
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]);
}
/*
* 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;
}
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() \
void **fixup;
void **next;
jit_nint offset;
+ arm_inst_buf inst;
/* Set the address of this block */
block->address = (void *)(gen->posn.ptr);
{
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;
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; \
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-%inst_type arm_inst_ptr
+%inst_type arm_inst_buf
/*
* Conversion opcodes.
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);
}
/*
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);
}
/*
JIT_OP_RETURN:
[] -> {
- inst = jump_to_epilog(gen, inst, block);
+ jump_to_epilog(gen, &inst, block);
}
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
{
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
{
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
{
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
{
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
}
break;
}
- inst = jump_to_epilog(gen, inst, block);
+ jump_to_epilog(gen, &inst, block);
}
JIT_OP_SETUP_FOR_NESTED: 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;
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);
}
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
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
{
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
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);
}
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
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);
(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);
(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;
{
arm_mov_reg_reg(inst, reg, ARM_FP);
}
- gen->posn.ptr = (unsigned char *)inst;
+ jit_gen_save_inst_ptr(gen, inst);
}
/*
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
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
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
{
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
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
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
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 |
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
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 |
(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 |
(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 |
(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 |
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;
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
* 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.
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");
+ }
}
/*
}
| K_INST_TYPE IDENTIFIER {
gensel_inst_type = $2;
+ gensel_new_inst_type = 1;
}
;