From 7bd246b7d11e1d2a7f005889a1b42e77bf2f97b7 Mon Sep 17 00:00:00 2001 From: Thomas Cort Date: Thu, 13 Jul 2006 03:11:57 +0000 Subject: [PATCH] Added trap barrier macro alpha_trapb. Implemented _jit_gen_prolog and _jit_gen_epilog for alpha. --- jit/jit-gen-alpha.h | 9 ++++- jit/jit-rules-alpha.c | 88 ++++++++++++++++++++++++------------------- jit/jit-rules-alpha.h | 4 +- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/jit/jit-gen-alpha.h b/jit/jit-gen-alpha.h index 857f831..96dbd04 100644 --- a/jit/jit-gen-alpha.h +++ b/jit/jit-gen-alpha.h @@ -67,7 +67,7 @@ typedef enum { ALPHA_R26 = 26, ALPHA_RA = ALPHA_R26, /* Return address */ ALPHA_R27 = 27, ALPHA_T12 = ALPHA_R27, /* ALPHA_R27 can hold either a temp value */ - ALPHA_PV = ALPHA_R27, + ALPHA_PV = ALPHA_R27, /* or the procedure value */ ALPHA_R28 = 28, ALPHA_AT = ALPHA_R28, /* Reeserved for the assembler */ @@ -247,6 +247,7 @@ typedef unsigned int * alpha_inst; #define ALPHA_OP_UMULH 0x13 #define ALPHA_OP_MULLV 0x13 #define ALPHA_OP_MULLQV 0x13 +#define ALPHA_OP_TRAPB 0x18 #define ALPHA_OP_JMP 0x1a #define ALPHA_OP_JSR 0x1a #define ALPHA_OP_RET 0x1a @@ -371,6 +372,9 @@ typedef unsigned int * alpha_inst; #define ALPHA_FUNC_MULLV 0x40 #define ALPHA_FUNC_MULQV 0x60 +/* trap barrier -- use with ALPHA_OP_* == 0x18 */ +#define ALPHA_FUNC_TRAPB 0x0 + /* branching operations -- use with ALPHA_OP_* == 0x1a */ #define ALPHA_FUNC_JMP 0x0 #define ALPHA_FUNC_JSR 0x1 @@ -559,6 +563,9 @@ typedef unsigned int * alpha_inst; #define alpha_ret(inst,sreg,hint) alpha_encode_mem_branch(inst,ALPHA_OP_RET,ALPHA_FUNC_RET,ALPHA_ZERO,sreg,hint) #define alpha_jsrco(inst,dreg,sreg,hint) alpha_encode_mem_branch(inst,ALPHA_OP_JSRCO,ALPHA_FUNC_JSRCO,dreg,sreg,hint) +/* trap barrier */ +#define alpha_trapb(inst) alpha_encode_mem_branch(inst,ALPHA_OP_TRAPB,ALPHA_FUNC_TRAPB,0,0,0) + /* memory operations */ #define alpha_ldf(inst,dreg,sreg,offset) alpha_encode_mem(inst,ALPHA_OP_LDF,dreg,sreg,offset) #define alpha_ldg(inst,dreg,sreg,offset) alpha_encode_mem(inst,ALPHA_OP_LDG,dreg,sreg,offset) diff --git a/jit/jit-rules-alpha.c b/jit/jit-rules-alpha.c index 3c5cca2..63f94d1 100644 --- a/jit/jit-rules-alpha.c +++ b/jit/jit-rules-alpha.c @@ -114,31 +114,37 @@ void _jit_gen_get_elf_info(jit_elf_info_t *info) { */ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf) { unsigned int prolog[JIT_PROLOG_SIZE]; + unsigned int offset = 0; alpha_inst inst = prolog; - short int savereg_space = 0; - unsigned char reg; - /* NOT IMPLEMENTED YET */ + /* Allocate space for a new stack frame. (1 instruction) */ + alpha_lda(inst,ALPHA_SP,ALPHA_SP,-(64)); - /* Determine which registers need to be preserved and push them onto the stack */ - for (reg = 0; reg < 32; reg++) { - if(jit_reg_is_used(gen->touched, reg) && (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) { - /* store the register value on the stack */ - alpha_stq(inst,ALPHA_SP,reg,savereg_space); - savereg_space -= 8; - } - } + /* Save the return address. (1 instruction) */ + alpha_stq(inst,ALPHA_RA,ALPHA_SP,offset); offset += 8; + + /* Save the frame pointer. (1 instruction) */ + alpha_stq(inst,ALPHA_FP,ALPHA_SP,offset); offset += 8; + + /* Save the integer save registers (6 instructions) */ + alpha_stq(inst,ALPHA_S0,ALPHA_SP,offset); offset += 8; + alpha_stq(inst,ALPHA_S1,ALPHA_SP,offset); offset += 8; + alpha_stq(inst,ALPHA_S2,ALPHA_SP,offset); offset += 8; + alpha_stq(inst,ALPHA_S3,ALPHA_SP,offset); offset += 8; + alpha_stq(inst,ALPHA_S4,ALPHA_SP,offset); offset += 8; + alpha_stq(inst,ALPHA_S5,ALPHA_SP,offset); offset += 8; - /* adjust the stack pointer to point to the 'top' of the stack */ - alpha_li(inst,ALPHA_AT,savereg_space); - alpha_addq(inst,ALPHA_SP,ALPHA_AT,ALPHA_SP); + /* Set the frame pointer (1 instruction) */ + alpha_mov(inst,ALPHA_SP,ALPHA_FP); - /* TODO see if ALPHA_RA needs to be saved or was saved above -----^ */ + /* TODO: Save the floating point save registers ; requires fp support */ - /* Copy the prolog into place and return the adjusted entry position */ - reg = (int)(inst - prolog); - jit_memcpy(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg, prolog, reg); - return (void *)(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg); + /* Force any pending hardware exceptions to be raised. (1 instruction) */ + alpha_trapb(inst); + + /* Copy the prolog into place and return the entry position */ + jit_memcpy(buf, prolog, JIT_PROLOG_SIZE); + return (void *) buf; } /* @@ -151,29 +157,13 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf) { * epilog until the full function has been processed. */ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) { - short int savereg_space = 0; - unsigned char reg; - alpha_inst inst; void **fixup, **next; - - /* NOT IMPLEMENTED YET */; + unsigned int offset = 0; inst = (alpha_inst) gen->posn.ptr; - /* Determine which registers need to be restored when we return and restore them */ - for (reg = 0; reg < 32; reg++) { - if (jit_reg_is_used(gen->touched, reg) && (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0) { - /* store the register value on the stack */ - alpha_ldq(inst,reg,ALPHA_SP,savereg_space); - savereg_space += 8; - } - } - - /* adjust the stack pointer to point to the 'top' of the stack */ - alpha_li(inst,ALPHA_AT,savereg_space); - alpha_addq(inst,ALPHA_SP,ALPHA_AT,ALPHA_SP); - + /* Perform fixups on any blocks that jump to the epilog */ fixup = (void **)(gen->epilog_fixup); while (fixup) { next = (void **)(fixup[0]); @@ -181,7 +171,29 @@ void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func) { fixup = next; } - /* Return from the current function */ + /* Set the stack pointer */ + alpha_mov(inst,ALPHA_FP,ALPHA_SP); + + /* Restore the return address. (1 instruction) */ + alpha_ldq(inst,ALPHA_RA,ALPHA_SP,offset); offset += 8; + + /* Restore the frame pointer. (1 instruction) */ + alpha_ldq(inst,ALPHA_FP,ALPHA_SP,offset); offset += 8; + + /* Restore the integer save registers (6 instructions) */ + alpha_ldq(inst,ALPHA_S0,ALPHA_SP,offset); offset += 8; + alpha_ldq(inst,ALPHA_S1,ALPHA_SP,offset); offset += 8; + alpha_ldq(inst,ALPHA_S2,ALPHA_SP,offset); offset += 8; + alpha_ldq(inst,ALPHA_S3,ALPHA_SP,offset); offset += 8; + alpha_ldq(inst,ALPHA_S4,ALPHA_SP,offset); offset += 8; + alpha_ldq(inst,ALPHA_S5,ALPHA_SP,offset); offset += 8; + + /* TODO: Restore the floating point save registers ; requires fp support */ + + /* Force any pending hardware exceptions to be raised. (1 instruction) */ + alpha_trapb(inst); + + /* Return from the current function (1 instruction) */ alpha_ret(inst,ALPHA_RA,1); } diff --git a/jit/jit-rules-alpha.h b/jit/jit-rules-alpha.h index e2f116f..c6f79c0 100644 --- a/jit/jit-rules-alpha.h +++ b/jit/jit-rules-alpha.h @@ -152,10 +152,8 @@ extern "C" { /* * The maximum number of bytes to allocate for the prolog. * This may be shortened once we know the true prolog size. - * - * Use the prolog size mono uses. See mono/arch/alpha/tramp.c */ -#define JIT_PROLOG_SIZE 24 +#define JIT_PROLOG_SIZE (13 /* instructions */ * 4 /* bytes per instruction */) /* * Preferred alignment for the start of functions. -- 2.47.3