]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Added trap barrier macro alpha_trapb. Implemented _jit_gen_prolog and
authorThomas Cort <linuxgeek@gmail.com>
Thu, 13 Jul 2006 03:11:57 +0000 (03:11 +0000)
committerThomas Cort <linuxgeek@gmail.com>
Thu, 13 Jul 2006 03:11:57 +0000 (03:11 +0000)
_jit_gen_epilog for alpha.

jit/jit-gen-alpha.h
jit/jit-rules-alpha.c
jit/jit-rules-alpha.h

index 857f831f2ffd78b64916f0577704bed44793e195..96dbd04b517052eb79e1870b78f74ba422ba7425 100644 (file)
@@ -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)
index 3c5cca2c41ea7968ba2a27b966206b52eb330eee..63f94d1666da26ab54d4ad2d818574cb06fba135 100644 (file)
@@ -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);
 }
 
index e2f116f6d583a6fa3b2010a71a2820108d150d7e..c6f79c0ea94538b175e079aacdec5d04788feccc 100644 (file)
@@ -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.