* jit/codegen-common.h: Enabled dseg_adddata for s390.
authorpm <none@none>
Sun, 4 Feb 2007 19:41:14 +0000 (19:41 +0000)
committerpm <none@none>
Sun, 4 Feb 2007 19:41:14 +0000 (19:41 +0000)
* jit/dseg.c: Likewise.
* jit/s390/md-abi.h: Continued work on s390 port.
* jit/s390/emit.c: Likewise.
* jit/s390/md.c: Likewise.
* jit/s390/codegen.c: Likewise.
* jit/s390/codegen.h: Likewise.
* jit/s390/md-asm.h: Likewise.
* jit/s390/asmpart.S: Likewise.
* jit/s390/md-abi.c: Likewise.

src/vm/jit/codegen-common.h
src/vm/jit/dseg.c
src/vm/jit/s390/asmpart.S
src/vm/jit/s390/codegen.c
src/vm/jit/s390/codegen.h
src/vm/jit/s390/emit.c
src/vm/jit/s390/md-abi.c
src/vm/jit/s390/md-abi.h
src/vm/jit/s390/md-asm.h
src/vm/jit/s390/md.c

index 6776b122ecfe7ea29d822ae886b0839934ca64c9..c23ceef8b2fc7889d4dea9ab2173707ffa9bf43a 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: codegen-common.h 7246 2007-01-29 18:49:05Z twisti $
+   $Id: codegen-common.h 7283 2007-02-04 19:41:14Z pm $
 
 */
 
@@ -125,7 +125,7 @@ struct codegendata {
 
        jumpref        *jumpreferences; /* list of jumptable target addresses     */
 
-#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
+#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP) || defined(__S390__)
        dataref        *datareferences; /* list of data segment references        */
 #endif
 
index abacc37377311bdef804eec82d636bcbebf66643..9a2d3b2e6a5a9ae5ee8f4eca5e25760412ef768b 100644 (file)
@@ -30,7 +30,7 @@
             Joseph Wenninger
             Edwin Steiner
 
-   $Id: dseg.c 7246 2007-01-29 18:49:05Z twisti $
+   $Id: dseg.c 7283 2007-02-04 19:41:14Z pm $
 
 */
 
@@ -854,7 +854,7 @@ s4 dseg_get_linenumber_from_pc(methodinfo **pm, u1 *pv, u1 *pc)
 
 *******************************************************************************/
 
-#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
+#if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
 void dseg_adddata(codegendata *cd)
 {
        dataref *dr;
index 05585a378c753685ab20bde22ad5d53b4a387ec5..4884bbe6db67ffb45d28b901baa04d676fb6b543 100644 (file)
@@ -30,7 +30,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: asmpart.S 7219 2007-01-16 22:18:57Z pm $
+   $Id: asmpart.S 7283 2007-02-04 19:41:14Z pm $
 
 */
 
@@ -392,7 +392,7 @@ L_basr:
 
        /* call L_asm_call_jit_compiler like JIT code would do */
 
-       l     itmp3, 12(s3)                   /* load address of target from memory */
+       l     itmp3, 0(mptr)                  /* load address of target from memory */
        basr  %r14, itmp3                     /* jump to target */
 
        /* todo will s4 survive the call? */
@@ -454,269 +454,6 @@ L_handle_d1:
        j     L_register_copy
 
 
-/* .... */
-
-#if 0
-
-       .align  8
-
-       .quad   0                           /* catch type all                     */
-       .quad   0                           /* handler pc                         */
-       .quad   0                           /* end pc                             */
-       .quad   0                           /* start pc                           */
-       .long   1                           /* extable size                       */
-       .long   0                           /* ALIGNMENT PADDING                  */
-       .quad   0                           /* line number table  start           */
-       .quad   0                           /* line number table  size            */
-       .long   0                           /* ALIGNMENT PADDING                  */
-       .long   0                           /* fltsave                            */
-       .long   0                           /* intsave                            */
-       .long   0                           /* isleaf                             */
-       .long   0                           /* IsSync                             */
-       .long   0                           /* frame size                         */
-       .quad   0                           /* codeinfo pointer                   */
-
-asm_vm_call_method:
-asm_vm_call_method_int:
-asm_vm_call_method_long:
-asm_vm_call_method_float:
-asm_vm_call_method_double:
-
-       stm %r6,%r15,24(sp)                /* save callers regiters */
-
-       ahi sp, -12  /* allocate space on stack for local variables */
-
-       st a0, 0(sp) /* store method info */
-       st a1, 4(sp) /* store arg count */
-       st a2, 8(sp) /* store args */
-
-
-#      define r_methodinfo  itmp1
-#      define r_vmargscount itmp2
-#      define r_vmargs      s0
-
-#      define r_arg_ctr     s1
-#      define r_arg_ptr     s2
-
-#      define r_int_ctr     s3
-#      define r_float_ctr   s4
-#   define r_int_extra_ctr    itmp3
-
-       /* save arguments */
-
-       lr      r_methodinfo,a0                    /* move method pointer for compiler   */
-       lr      r_vmargscount,a1
-       lr      r_vmargs,a2                    
-
-       ltr     a1,a1                       /* maybe we have no args...           */
-       je      L_copy_done
-
-       lr      r_arg_ctr,r_vmargscount         /* arg count                          */
-       lr      r_arg_ptr,r_vmargs              /* pointer to arg block               */
-
-       ahi     r_arg_ptr,-sizevmarg            /* initialize pointer (smaller code)  */
-       ahi     r_arg_ctr,1                     /* initialize argument count          */
-
-       lhi     r_int_ctr,0                      /* initialize integer argument counter*/
-       lhi     r_float_ctr,0                      /* initialize float argument counter  */
-       lhi     r_int_extra_ctr,0
-
-L_register_copy:
-       ahi     r_arg_ptr,sizevmarg             /* goto next argument block           */
-       ahi     r_arg_ctr,-1                    /* argument count - 1                 */
-       je      L_register_copy_done
-
-       tm      offvmargtype(r_arg_ptr),0x02    /* is this a float/double type?       */
-       jne     L_register_handle_float     /* yes, handle it                     */
-
-       cli     offvmargtype(r_arg_ptr),0x01
-       je      L_register_handle_long
-
-L_register_handle_int:
-
-       chi     r_int_ctr,INT_ARG_CNT            /* are we out of integer argument     */
-       je      L_register_copy             /* register? yes, next loop           */
-
-       ahi     r_int_ctr,1
-
-       chi     r_int_ctr,1
-       je      L_handle_a0
-       chi     r_int_ctr,2
-       je      L_handle_a1
-       chi     r_int_ctr,3
-       je      L_handle_a2
-       chi     r_int_ctr,4
-       je      L_handle_a3
-       chi     r_int_ctr,5
-       je      L_handle_a4
-
-L_register_handle_long:
-
-       chi     r_int_ctr,INT_ARG_CNT-1 /* only one integer register left ? */
-       je      L_register_handle_long_last_reg
-
-       chi     r_int_ctr,INT_ARG_CNT /* no registers left */
-       je     L_register_copy
-
-       ahi     r_int_ctr,2
-       ahi     r_int_extra_ctr,1
-
-       chi     r_int_ctr,2
-       je      L_handle_al0
-       chi     r_int_ctr,3
-       je      L_handle_al1
-       chi     r_int_ctr,4
-       je      L_handle_al2
-       chi     r_int_ctr,5
-       je      L_handle_al3
-
-L_register_handle_long_last_reg:
-       ahi     r_int_ctr,1 /* skip the integer register */
-       ahi     r_int_extra_ctr,1
-       j       L_register_copy
-
-L_register_handle_float:
-       chi     r_float_ctr,FLT_ARG_CNT         /* are we out of float argument         */
-       je      L_register_copy           /* register? yes, next loop             */
-
-       ahi     r_float_ctr,1
-
-       chi     r_int_ctr,1
-       je      L_handle_af0
-       chi     r_int_ctr,2
-       je      L_handle_af1
-
-L_register_copy_done:
-
-       lr      r_arg_ctr, r_vmargscount
-       sr      r_arg_ctr, r_int_ctr
-       ar      r_arg_ctr, r_int_extra_ctr
-       sr      r_arg_ctr, r_float_ctr
-       jle     L_copy_done 
-
-       /* now allocate the parameter area on the stack
-        * the register save area will be allocated later
-        */
-
-#      define r_arg_stack_ptr r_arg_ptr
-
-       sll     r_arg_ctr, 3 /* 8 bytes per parameter on stack */
-       sr      sp,r_arg_ctr /* allocate stack space for parameters */
-       lr      r_arg_stack_ptr,sp /* points now to arguments on stack */
-
-       ahi     r_vmargs,-sizevmarg            /* initialize pointer (smaller code)  */
-       ahi     r_vmargscount,1                     /* initialize argument count          */
-               
-L_stack_copy_loop:
-       ahi     r_vmargs,sizevmarg             /* goto next argument block           */
-       ahi     r_vmargscount,-1                    /* argument count - 1                 */
-       jz      L_copy_done               /* no test needed after dec             */
-
-       tm      offvmargtype(r_vmargs),0x02    /* is this a float/double type?       */
-       jne     L_stack_handle_float     /* yes, handle it                     */
-
-       cli     offvmargtype(r_vmargs),0x01
-       je      L_stack_handle_long
-
-L_stack_handle_int:
-
-       ahi     r_int_ctr,-1                        /* arguments assigned to registers    */
-       jhe     L_stack_copy_loop
-       j       L_stack_copy
-
-L_stack_handle_long:
-
-       ahi     r_int_ctr,-2
-       jhe     L_stack_copy_loop
-       j       L_stack_copy
-
-L_stack_handle_float:
-       ahi     r_float_ctr,-1                        /* arguments assigned to registers    */
-       jhe     L_stack_copy_loop
-
-L_stack_copy:
-       mvc     0(8,r_arg_stack_ptr),offvmargdata(r_vmargs) /* copy s8 argument onto stack        */
-
-       ahi     r_arg_stack_ptr,8                     /* increase sp to next argument       */
-       j       L_stack_copy_loop
-
-L_copy_done:
-#if 0
-                                           /* itmp1 still contains method pointer*/
-       lea     L_asm_call_jit_compiler(%rip),mptr
-       mov     sp,itmp3                    /* calculate the old stack pointer    */
-       add     bp,itmp3
-       mov     mptr,6*8(itmp3) /* store mptr on stack */
-       lea     (6*8-256)(itmp3),mptr       /* We subtract 256 to force the next  */
-                                           /* move instruction to have a 32-bit  */
-                                           /* offset.                            */
-
-       mov     (0*8+256)(mptr),itmp3       /* method call as in Java             */
-       call    *itmp3                      /* call JIT compiler                  */
-
-       add     bp,sp                       /* remove argument stack frame if any */
-#endif
-
-                                           /* itmp1 still contains method pointer*/
-       
-       bras %r14, L_asm_call_jit_compiler
-       ar      sp,r_arg_ctr                /* r_arg_ctr in callee saved regiter */
-
-L_asm_vm_call_method_return:
-
-       ahi sp, 12                        /* free stack space */
-       lm %r6,%r15,24(sp)                /* restore registers */
-       br %r14                           /* branch to return address */
-               
-#if 0
-asm_vm_call_method_exception_handler:
-       mov     xptr,a0                     /* pass exception pointer             */
-       call    builtin_throw_exception@PLT
-       jmp     L_asm_vm_call_method_return
-#endif
-
-L_handle_a0:
-       l       a0,offvmargdata(r_arg_ptr)
-       j       L_register_copy
-L_handle_a1:
-       l       a1,offvmargdata(r_arg_ptr)
-       j       L_register_copy
-L_handle_a2:
-       l       a2,offvmargdata(r_arg_ptr)
-       j       L_register_copy
-L_handle_a3:
-       l       a3,offvmargdata(r_arg_ptr)
-       j       L_register_copy
-L_handle_a4:
-       l       a4,offvmargdata(r_arg_ptr)
-       j       L_register_copy
-
-L_handle_al0:
-       l       a0,offvmargdata(r_arg_ptr)
-       l       a1,offvmargdata+4(r_arg_ptr)
-       j       L_register_copy
-L_handle_al1:
-       l       a1,offvmargdata(r_arg_ptr)
-       l       a2,offvmargdata+4(r_arg_ptr)
-       j       L_register_copy
-L_handle_al2:
-       l       a2,offvmargdata(r_arg_ptr)
-       l       a3,offvmargdata+4(r_arg_ptr)
-       j       L_register_copy
-L_handle_al3:
-       l       a3,offvmargdata(r_arg_ptr)
-       l       a4,offvmargdata+4(r_arg_ptr)
-       j       L_register_copy
-
-L_handle_af0:
-       ld    fa0,offvmargdata(r_arg_ptr)
-       j     L_register_copy
-L_handle_af1:
-       ld    fa1,offvmargdata(r_arg_ptr)
-       j     L_register_copy
-
-#endif
-
 /****************** function asm_call_jit_compiler *****************************
 *                                                                              *
 *   invokes the compiler for untranslated JavaVM methods.                      *
@@ -771,17 +508,19 @@ L_bras_jac:
        l       itmp3, 0(itmp3)
        basr    %r14, itmp3
 
-       lm     %r2,%r5,96(sp)             /* restore volatile int arg regs */
-       ld     %f0,96+16(sp)              /* store volatile float arg regs */
-       ld     %f2,96+24(sp)              /* store volatile float arg regs */
-       ld     %r14,96+32(sp)             /* restore return address */
+       lr      pv, v0                     /* save return value */
+
+       lm      %r2,%r5,96(sp)             /* restore volatile int arg regs */
+       ld      %f0,96+16(sp)              /* restore volatile float arg regs */
+       ld      %f2,96+24(sp)              /* restore volatile float arg regs */
+       ld      %r14,96+32(sp)             /* restore return address */
 
 #if 0
        ltr     v0,v0
        je      L_asm_call_jit_compiler_exception
 #endif
 
-       b       0(v0)                      /* call the method, it will return to the caller */
+       br      pv                         /* call the method, it will return to the caller */
 
 
 L_asm_call_jit_compiler_exception:
index ff8e83c33a418065ebaca6f995928fdc60731c89..595c48e58e32e6c9fad0836892c36c6493fab1a2 100644 (file)
@@ -29,7 +29,7 @@
             Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 7219 2007-01-16 22:18:57Z pm $
+   $Id: codegen.c 7283 2007-02-04 19:41:14Z pm $
 
 */
 
@@ -127,7 +127,9 @@ bool codegen(jitdata *jd)
        fieldinfo          *fi;
        unresolved_field   *uf;
        s4                  fieldtype;
+#if 0
        rplpoint           *replacementpoint;
+#endif
        s4                 varindex;
 
        /* get required compiler data */
@@ -148,20 +150,26 @@ bool codegen(jitdata *jd)
        s4 i, p, t, l;
        s4 savedregs_num;
 
-       savedregs_num = 0;
+       savedregs_num = 1; /* space to save RA */
 
        /* space to save used callee saved registers */
 
        savedregs_num += (INT_SAV_CNT - rd->savintreguse);
-       savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
+       savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
 
        cd->stackframesize = rd->memuse + savedregs_num;
 
+       /* CAUTION:
+        * As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
+        */
+
 #if defined(ENABLE_THREADS)
        /* space to save argument of monitor_enter */
-
+       OOPS(); /* see powerpc  */
+#if 0
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
                cd->stackframesize++;
+#endif
 #endif
 
        /* Keep stack of non-leaf functions 16-byte aligned for calls into
@@ -169,12 +177,13 @@ bool codegen(jitdata *jd)
           movaps). */
 
        if (!jd->isleafmethod || opt_verbosecall)
-               cd->stackframesize |= 0x1;
+               /* TODO really 16 bytes ? */
+               cd->stackframesize = (cd->stackframesize + 3) & ~3;
 
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
 
 #if defined(ENABLE_THREADS)
        /* IsSync contains the offset relative to the stack pointer for the
@@ -184,7 +193,7 @@ bool codegen(jitdata *jd)
        */
 
        if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync        */
+               (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync        */
        else
 #endif
                (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
@@ -211,25 +220,28 @@ bool codegen(jitdata *jd)
        if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
                /* count frequency */
 
-               M_MOV_IMM(code, REG_ITMP3);
-               M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
+               M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
+               M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
+               M_IADD_IMM(1, REG_ITMP2);
+               M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
 
-               PROFILE_CYCLE_START;
+/*             PROFILE_CYCLE_START; */
        }
 
        /* create stack frame (if necessary) */
 
        if (cd->stackframesize)
-               M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
+               M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
 
-       /* save used callee saved registers */
+       /* save used callee saved registers and return address */
 
        p = cd->stackframesize;
+       p--; M_AST(REG_RA, REG_SP, p * 4);
        for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
-               p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
+               p--; M_LST(rd->savintregs[i], REG_SP, p * 4);
        }
        for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
-               p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
+               p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
        }
 
        /* take arguments out of register or stack frame */
@@ -238,8 +250,7 @@ bool codegen(jitdata *jd)
 
        for (p = 0, l = 0; p < md->paramcount; p++) {
                t = md->paramtypes[p].type;
-
-               varindex = jd->local_map[l * 5 + t];
+               varindex = jd->local_map[l * 5 + t];
 
                l++;
                if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
@@ -248,27 +259,43 @@ bool codegen(jitdata *jd)
                if (varindex == UNUSED)
                        continue;
 
-               var = VAR(varindex);
-               
-               s1 = md->params[p].regoff;
+               var = VAR(varindex);
 
+               s1 = md->params[p].regoff;
                if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
-                       s2 = rd->argintregs[s1];
+                       if (IS_2_WORD_TYPE(t))
+                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                          rd->argintregs[GET_HIGH_REG(s1)]);
+                       else
+                               s2 = rd->argintregs[s1];
                        if (!md->params[p].inmemory) {           /* register arguments    */
                                if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
-                                       M_INTMOVE(s2, var->vv.regoff);
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_LNGMOVE(s2, var->vv.regoff);
+                                       else
+                                               M_INTMOVE(s2, var->vv.regoff);
 
                                } else {                             /* reg arg -> spilled    */
-                                   M_LST(s2, REG_SP, var->vv.regoff * 8);
-                               }
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_LST(s2, REG_SP, var->vv.regoff * 4);
+                                       else
+                                               M_IST(s2, REG_SP, var->vv.regoff * 4);
+                               }
 
                        } else {                                 /* stack arguments       */
                                if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
-                                       /* + 8 for return address */
-                                       M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+                                       else
+                                               M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
 
                                } else {                             /* stack arg -> spilled  */
-                                       var->vv.regoff = cd->stackframesize + s1 + 1;
+                                       M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
+                                       M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
+                                               M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
+                                       }
                                }
                        }
 
@@ -276,22 +303,37 @@ bool codegen(jitdata *jd)
                        if (!md->params[p].inmemory) {           /* register arguments    */
                                s2 = rd->argfltregs[s1];
                                if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
-                                       M_FLTMOVE(s2, var->vv.regoff);
+                                       M_FLTMOVE(s2, var->vv.regoff);
 
                                } else {                                         /* reg arg -> spilled    */
-                                       M_DST(s2, REG_SP, var->vv.regoff * 8);
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_DST(s2, REG_SP, var->vv.regoff * 4);
+                                       else
+                                               M_FST(s2, REG_SP, var->vv.regoff * 4);
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
-                                       M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
 
-                               } else {
-                                       var->vv.regoff = cd->stackframesize + s1 + 1;
+                                       else
+                                               M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+
+                               } else {                             /* stack-arg -> spilled  */
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
+                                               var->vv.regoff = cd->stackframesize + s1;
+
+                                       } else {
+                                               M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
+                                               M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
+                                       }
                                }
                        }
                }
-       }  /* end for */
+       } /* end for */
 
        /* save monitorenter argument */
 
@@ -348,8 +390,9 @@ bool codegen(jitdata *jd)
        }
 
        /* end of header generation */
-
+#if 0
        replacementpoint = jd->code->rplpoints;
+#endif
 
        /* walk through all basic blocks */
 
@@ -505,29 +548,28 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_ACONST:     /* ...  ==> ..., constant                       */
-                       OOPS();
-#if 0
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                cr = iptr->sx.val.c.ref;
+                               disp = dseg_add_unique_address(cd, NULL);
 
 /*                             PROFILE_CYCLE_STOP; */
 
-                               codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
+                               codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
 
 /*                             PROFILE_CYCLE_START; */
 
-                               M_MOV_IMM(NULL, d);
-
+                               M_ALD(d, REG_PV, disp);
                        } else {
-                               if (iptr->sx.val.anyptr == 0)
+                               if (iptr->sx.val.anyptr == 0) {
                                        M_CLR(d);
-                               else
-                                       M_MOV_IMM(iptr->sx.val.anyptr, d);
+                               } else {
+                                       disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
+                                       M_ALD(d, REG_PV, disp);
+                               }
                        }
                        emit_store_dst(jd, iptr, d);
-#endif
                        break;
 
 
@@ -544,18 +586,12 @@ bool codegen(jitdata *jd)
                case ICMD_DSTORE: 
                case ICMD_COPY:
                case ICMD_MOVE:
-                       OOPS();
-#if 0          
                        emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-#endif
                        break;
 
                case ICMD_ASTORE:
-                       OOPS();
-#if 0
                        if (!(iptr->flags.bits & INS_FLAG_RETADDR))
                                emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-#endif
                        break;
 
                /* integer operations *************************************************/
@@ -2478,23 +2514,18 @@ bool codegen(jitdata *jd)
                        break;
                        
                case ICMD_IFNULL:       /* ..., value ==> ...                         */
-                       OOPS();
-#if 0
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        M_TEST(s1);
                        M_BEQ(0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
                        break;
 
                case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
                        OOPS();
-#if 0
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        M_TEST(s1);
                        M_BNE(0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
                        break;
 
                case ICMD_IFEQ:         /* ..., value ==> ...                         */
@@ -2653,28 +2684,30 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
-                       OOPS();
-#if 0
+               case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_ICMP(s2, s1);
+                       M_CMP(s1, s2);
                        M_BEQ(0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
                        break;
 
                case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
-               case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
-                       OOPS();
-#if 0
 
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_LCMP(s2, s1);
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s1, s2);
+                       /* load low-bits before the branch, so we know the distance */
+                       /* TODO do the loads modify the condition code?
+                        * lr, l, la, lhi dont
+                        */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
+                       M_CMP(s1, s2);
                        M_BEQ(0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
                        break;
 
                case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
@@ -2764,14 +2797,19 @@ bool codegen(jitdata *jd)
 
                case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
 
-                       OOPS();
-#if 0
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_LCMP(s2, s1);
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s1, s2);
+                       M_BLT(0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       /* load low-bits before the branch, so we know the distance */
+                       /* TODO: the loads should not touch the condition code. */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
+                       M_CMP(s1, s2);
                        M_BLE(0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
                        break;
 
                case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
@@ -2799,120 +2837,126 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
-               case ICMD_LRETURN:
 
-                       OOPS();
-#if 0
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT);
                        M_INTMOVE(s1, REG_RESULT);
-#endif
                        goto nowperformreturn;
 
                case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
 
-                       OOPS();
-#if 0
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT);
                        M_INTMOVE(s1, REG_RESULT);
 
 #ifdef ENABLE_VERIFIER
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uc = iptr->sx.s23.s2.uc;
+                               unresolved_class *uc = iptr->sx.s23.s2.uc;
 
-                               PROFILE_CYCLE_STOP;
-
-                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
-
-                               PROFILE_CYCLE_START;
+                               codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
                        }
 #endif /* ENABLE_VERIFIER */
-#endif
+                       goto nowperformreturn;
+
+               case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
+
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
+                       s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(s1, REG_RESULT_PACKED);
                        goto nowperformreturn;
 
                case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
                case ICMD_DRETURN:
 
-                       OOPS();
-#if 0
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FRESULT);
                        M_FLTMOVE(s1, REG_FRESULT);
-#endif
                        goto nowperformreturn;
 
                case ICMD_RETURN:      /* ...  ==> ...                                */
 
+                       REPLACEMENT_POINT_RETURN(cd, iptr);
+
 nowperformreturn:
-                       OOPS();
-#if 0
                        {
                        s4 i, p;
+                       
+                       p = cd->stackframesize;
 
-                       p = cd->stackframesize;
+                       /* call trace function */
 
-#if !defined(NDEBUG)
-                       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
-                               emit_verbosecall_exit(jd);
-#endif /* !defined(NDEBUG) */
+                       emit_verbosecall_exit(jd);
 
 #if defined(ENABLE_THREADS)
                        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-                               M_ALD(REG_A0, REG_SP, rd->memuse * 8);
-       
+                               disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
+                               M_ALD(REG_ITMP3, REG_PV, disp);
+                               M_CALL(REG_ITMP3);
+
                                /* we need to save the proper return value */
+
                                switch (iptr->opc) {
+                               case ICMD_LRETURN:
+                                       M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
+                                       /* fall through */
                                case ICMD_IRETURN:
                                case ICMD_ARETURN:
-                               case ICMD_LRETURN:
-                                       M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
+                                       M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
                                        break;
                                case ICMD_FRETURN:
+                                       M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+                                       break;
                                case ICMD_DRETURN:
-                                       M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
+                                       M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
                                        break;
                                }
 
-                               M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
-                               M_CALL(REG_ITMP1);
+                               M_ALD(REG_A0, REG_SP, rd->memuse * 4);
+                               M_JSR;
 
                                /* and now restore the proper return value */
+
                                switch (iptr->opc) {
+                               case ICMD_LRETURN:
+                                       M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
+                                       /* fall through */
                                case ICMD_IRETURN:
                                case ICMD_ARETURN:
-                               case ICMD_LRETURN:
-                                       M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
+                                       M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
                                        break;
                                case ICMD_FRETURN:
+                                       M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+                                       break;
                                case ICMD_DRETURN:
-                                       M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
+                                       M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
                                        break;
                                }
                        }
 #endif
 
-                       /* restore saved registers */
+                       /* restore return address                                         */
+
+                       M_ALD(REG_RA, REG_SP, p * 4);
+
+                       /* restore saved registers                                        */
 
                        for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
-                               p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
+                               p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
                        }
                        for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
-                               p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
+                               p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
                        }
 
-                       /* deallocate stack */
+                       /* deallocate stack                                               */
 
                        if (cd->stackframesize)
-                               M_AADD_IMM(cd->stackframesize * 8, REG_SP);
-
-                       /* generate method profiling code */
-
-                       PROFILE_CYCLE_STOP;
+                               M_AADD_IMM(cd->stackframesize * 4, REG_SP);
 
                        M_RET;
+                       ALIGNCODENOP;
                        }
-#endif
                        break;
 
-
                case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
                        OOPS();
 #if 0
@@ -2991,20 +3035,17 @@ nowperformreturn:
 
 
                case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
-                       OOPS();
-#if 0
 
                        bte = iptr->sx.s23.s3.bte;
                        md  = bte->md;
-#endif
                        goto gen_method;
 
                case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
                case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
                case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
                case ICMD_INVOKEINTERFACE:
-                       OOPS();
-#if 0
+
+                       REPLACEMENT_POINT_INVOKE(cd, iptr);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                lm = NULL;
@@ -3016,31 +3057,46 @@ nowperformreturn:
                                um = NULL;
                                md = lm->parseddesc;
                        }
-#endif
+
 gen_method:
-#if 0
                        s3 = md->paramcount;
 
-                       MCODECHECK((20 * s3) + 128);
+                       MCODECHECK((s3 << 1) + 64);
 
                        /* copy arguments to registers or stack location */
 
                        for (s3 = s3 - 1; s3 >= 0; s3--) {
                                var = VAR(iptr->sx.s23.s2.args[s3]);
 
-                               /* Already Preallocated (ARGVAR) ? */
+                               /* Already Preallocated? */
                                if (var->flags & PREALLOC)
                                        continue;
 
                                if (IS_INT_LNG_TYPE(var->type)) {
                                        if (!md->params[s3].inmemory) {
-                                               s1 = rd->argintregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
-                                               M_INTMOVE(d, s1);
+                                               if (IS_2_WORD_TYPE(var->type)) {
+                                                       s1 = PACK_REGS(
+                                                               rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
+                                                               rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
+                                                       );
+                                                       d = emit_load(jd, iptr, var, s1);
+                                                       M_LNGMOVE(d, s1);
+                                               }
+                                               else {
+                                                       s1 = rd->argintregs[md->params[s3].regoff];
+                                                       d = emit_load(jd, iptr, var, s1);
+                                                       M_INTMOVE(d, s1);
+                                               }
                                        }
                                        else {
-                                               d = emit_load(jd, iptr, var, REG_ITMP1);
-                                               M_LST(d, REG_SP, md->params[s3].regoff * 8);
+                                               if (IS_2_WORD_TYPE(var->type)) {
+                                                       d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
+                                                       M_LST(d, REG_SP, md->params[s3].regoff * 4);
+                                               }
+                                               else {
+                                                       d = emit_load(jd, iptr, var, REG_ITMP1);
+                                                       M_IST(d, REG_SP, md->params[s3].regoff * 4);
+                                               }
                                        }
                                }
                                else {
@@ -3051,110 +3107,95 @@ gen_method:
                                        }
                                        else {
                                                d = emit_load(jd, iptr, var, REG_FTMP1);
-
                                                if (IS_2_WORD_TYPE(var->type))
-                                                       M_DST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_DST(d, REG_SP, md->params[s3].regoff * 4);
                                                else
-                                                       M_FST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_FST(d, REG_SP, md->params[s3].regoff * 4);
                                        }
                                }
                        }
 
-                       /* generate method profiling code */
-
-                       PROFILE_CYCLE_STOP;
-
                        switch (iptr->opc) {
                        case ICMD_BUILTIN:
-                               M_MOV_IMM(bte->fp, REG_ITMP1);
-                               M_CALL(REG_ITMP1);
+                               disp = dseg_add_functionptr(cd, bte->fp);
 
-                               if (INSTRUCTION_MUST_CHECK(iptr)) {
-                                       M_TEST(REG_RESULT);
-                                       M_BEQ(0);
-                                       codegen_add_fillinstacktrace_ref(cd);
-                               }
+                               N_LHI(REG_ITMP1, disp);
+                               N_L(REG_PV, 0, REG_ITMP1, REG_PV);
                                break;
 
                        case ICMD_INVOKESPECIAL:
-                               M_TEST(REG_A0);
-                               M_BEQ(0);
-                               codegen_add_nullpointerexception_ref(cd);
-
+                               emit_nullpointer_check(cd, iptr, REG_A0);
+                               M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr   */
                                /* fall through */
 
                        case ICMD_INVOKESTATIC:
                                if (lm == NULL) {
-                                       disp = dseg_add_unique_address(cd, NULL);
-                                       disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
-
-                                       /* must be calculated before codegen_add_patch_ref */
-
-                                       if (opt_shownops)
-                                               disp -= PATCHER_CALL_SIZE;
-
-                                       codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
-                                                                                 um, disp);
-
-/*                                     a = 0; */
-                               }
-                               else {
-                                       disp = dseg_add_functionptr(cd, lm->stubroutine);
-                                       disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+                                       disp = dseg_add_unique_address(cd, um);
 
-/*                                     a = (ptrint) lm->stubroutine; */
+                                       codegen_addpatchref(cd, PATCHER_invokestatic_special,
+                                                                               um, disp);
                                }
+                               else
+                                       disp = dseg_add_address(cd, lm->stubroutine);
 
-/*                             M_MOV_IMM(a, REG_ITMP2); */
-                               M_ALD(REG_ITMP2, RIP, disp);
-                               M_CALL(REG_ITMP2);
+                               N_LHI(REG_ITMP1, disp);
+                               N_L(REG_PV, 0, REG_ITMP1, REG_PV);
                                break;
 
                        case ICMD_INVOKEVIRTUAL:
-                               gen_nullptr_check(REG_A0);
+                               emit_nullpointer_check(cd, iptr, REG_A0);
 
                                if (lm == NULL) {
-                                       codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
+                                       codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
 
                                        s1 = 0;
                                }
-                               else
+                               else {
                                        s1 = OFFSET(vftbl_t, table[0]) +
                                                sizeof(methodptr) * lm->vftblindex;
+                               }
 
-                               M_ALD(REG_METHODPTR, REG_A0,
-                                         OFFSET(java_objectheader, vftbl));
-                               M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
-                               M_CALL(REG_ITMP3);
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_PV, REG_METHODPTR, s1);
                                break;
 
                        case ICMD_INVOKEINTERFACE:
-                               gen_nullptr_check(REG_A0);
+                               emit_nullpointer_check(cd, iptr, REG_A0);
 
                                if (lm == NULL) {
-                                       codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
+                                       codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
 
                                        s1 = 0;
                                        s2 = 0;
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr) * lm->class->index;
+                                               sizeof(methodptr*) * lm->class->index;
 
                                        s2 = sizeof(methodptr) * (lm - lm->class->methods);
                                }
 
-                               M_ALD(REG_METHODPTR, REG_A0,
-                                         OFFSET(java_objectheader, vftbl));
-                               M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
-                               M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
-                               M_CALL(REG_ITMP3);
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
+                               M_ALD(REG_PV, REG_METHODPTR, s2);
                                break;
                        }
 
-                       /* generate method profiling code */
+                       /* generate the actual call */
 
-                       PROFILE_CYCLE_START;
+                       M_CALL(REG_PV);
+                       REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+                       N_BASR(REG_ITMP1, RN);
+                       disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                       M_LDA(REG_PV, REG_ITMP1, -disp);
+                       
+                       /* actually only used for ICMD_BUILTIN */
+
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               M_TEST(REG_RESULT);
+                               M_BEQ(0);
+                               codegen_add_fillinstacktrace_ref(cd);
+                       }
 
                        /* store return value */
 
@@ -3162,8 +3203,14 @@ gen_method:
 
                        if (d != TYPE_VOID) {
                                if (IS_INT_LNG_TYPE(d)) {
-                                       s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
-                                       M_INTMOVE(REG_RESULT, s1);
+                                       if (IS_2_WORD_TYPE(d)) {
+                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                                               M_LNGMOVE(REG_RESULT_PACKED, s1);
+                                       }
+                                       else {
+                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                                               M_INTMOVE(REG_RESULT, s1);
+                                       }
                                }
                                else {
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
@@ -3171,7 +3218,7 @@ gen_method:
                                }
                                emit_store_dst(jd, iptr, s1);
                        }
-#endif
+
                        break;
 
 
@@ -3615,7 +3662,7 @@ gen_method:
                        break;
 
                default:
-                       *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+                       exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
                        return false;
        } /* switch */
 
@@ -3702,9 +3749,9 @@ u1 *createcompilerstub(methodinfo *m)
 
        /* don't touch ITMP3 as it cointains the return address */
 
-       N_L2(REG_ITMP1, -2 * 4, REG_PV); /* methodinfo  */
+       M_ILD(REG_ITMP1, REG_PV, -2 * 4); /* methodinfo  */
        /* TODO where is methodpointer loaded into itmp2? is it already inside? */
-       N_L2(REG_PV, -3 * 4, REG_PV); /* compiler pointer */
+       M_ILD(REG_PV, REG_PV, -3 * 4); /* compiler pointer */
        N_BR(REG_PV);
 
 #if defined(ENABLE_STATISTICS)
@@ -3820,7 +3867,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* save return address */
 
-       N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, 0, REG_SP)
+       N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
 
 #if 0
 #if !defined(NDEBUG)
@@ -3837,7 +3884,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 #endif
 
        disp = dseg_add_functionptr(cd, f);
-       N_L2(REG_ITMP3, disp, REG_PV);
+       M_ILD(REG_ITMP1, REG_PV, disp);
 
        j = 96 + (nmd->memuse * 4);
 
@@ -3852,16 +3899,16 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                        if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
                                if (IS_2_WORD_TYPE(t)) {
                                        /* todo store multiple */
-                                       N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, 0, REG_SP);
-                                       N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, 0, REG_SP);
+                                       N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
+                                       N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
                                } else {
-                                       N_ST(rd->argintregs[s1], j, 0, REG_SP);
+                                       N_ST(rd->argintregs[s1], j, RN, REG_SP);
                                }
                        } else {
                                if (IS_2_WORD_TYPE(t)) {
-                                       N_STD(rd->argfltregs[s1], j, 0, REG_SP);
+                                       N_STD(rd->argfltregs[s1], j, RN, REG_SP);
                                } else {
-                                       N_STE(rd->argfltregs[s1], j, 0, REG_SP);
+                                       N_STE(rd->argfltregs[s1], j, RN, REG_SP);
                                }
                        }
 
@@ -3869,17 +3916,17 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                }
        }
 
-       N_ST(REG_ITMP3, j, 0, REG_SP);
+       N_ST(REG_ITMP1, j, RN, REG_SP);
 
        /* create dynamic stack info */
 
-       N_LAE(REG_A0, (cd->stackframesize - 1) * 4, 0, REG_SP); /* datasp */
-       N_LR(REG_A1, REG_PV) /* pv */
-       N_LAE(REG_A2, cd->stackframesize * 4, 0, REG_SP); /* old SP */
-       N_L(REG_A3, (cd->stackframesize - 1) * 4, 0, REG_SP); /* return address */
+       N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
+       N_LR(REG_A1, REG_PV); /* pv */
+       N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
+       N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
 
        disp = dseg_add_functionptr(cd, codegen_start_native_call);
-       N_L2(REG_ITMP1, disp, REG_PV);
+       M_ILD(REG_ITMP1, REG_PV, disp);
 
        M_CALL(REG_ITMP1); /* call */
 
@@ -3894,16 +3941,16 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                        if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
                                if (IS_2_WORD_TYPE(t)) {
                                        /* todo load multiple ! */
-                                       N_L(rd->argintregs[GET_HIGH_REG(s1)], j, 0, REG_SP);
-                                       N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, 0, REG_SP);
+                                       N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
+                                       N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
                                } else {
-                                       N_L(rd->argintregs[s1], j, 0, REG_SP);
+                                       N_L(rd->argintregs[s1], j, RN, REG_SP);
                                }
                        } else {
                                if (IS_2_WORD_TYPE(t)) {
-                                       N_LD(rd->argfltregs[s1], j, 0, REG_SP);
+                                       N_LD(rd->argfltregs[s1], j, RN, REG_SP);
                                } else {
-                                       N_LE(rd->argfltregs[s1], j, 0, REG_SP);
+                                       N_LE(rd->argfltregs[s1], j, RN, REG_SP);
                                }
                        }
 
@@ -3911,7 +3958,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                }
        }
 
-       N_L(REG_ITMP3, j, 0, REG_SP);
+       N_L(REG_ITMP1, j, RN, REG_SP);
 
        /* copy or spill arguments to new locations */
 
@@ -3937,7 +3984,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                        if (IS_2_WORD_TYPE(t)) {
                                                N_LM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
                                        } else {
-                                               N_L(s1, 96 + (s2 * 4), 0, REG_SP);
+                                               N_L(s1, 96 + (s2 * 4), RN, REG_SP);
                                        }
                                }
 
@@ -3973,17 +4020,17 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        if (m->flags & ACC_STATIC) {
                disp = dseg_add_address(cd, m->class);
-               N_L2(REG_A1, disp, REG_PV);
+               M_ILD(REG_A1, REG_PV, disp);
        }
 
        /* put env into first argument register */
 
        disp = dseg_add_address(cd, _Jv_env);
-       N_L2(REG_A0, disp, REG_PV);
+       M_ILD(REG_A0, REG_PV, disp);
 
        /* do the native function call */
 
-       M_CALL(REG_ITMP3); /* call */
+       M_CALL(REG_ITMP1); /* call */
 
        /* save return value */
 
@@ -3994,13 +4041,13 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                        if (IS_2_WORD_TYPE(t)) {
                                N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
                        } else {
-                               N_ST(REG_RESULT, 96, 0, REG_SP);
+                               N_ST(REG_RESULT, 96, RN, REG_SP);
                        }
                } else {
                        if (IS_2_WORD_TYPE(t)) {
-                               N_STD(REG_FRESULT, 96, 0, REG_SP);
+                               N_STD(REG_FRESULT, 96, RN, REG_SP);
                        } else {
-                               N_STE(REG_FRESULT, 96, 0, REG_SP);
+                               N_STE(REG_FRESULT, 96, RN, REG_SP);
                        }
                }
        }
@@ -4014,9 +4061,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* remove native stackframe info */
 
-       N_LAE(REG_A0, cd->stackframesize * 4, 0, REG_SP);
+       N_LAE(REG_A0, cd->stackframesize * 4, RN, REG_SP);
        disp = dseg_add_functionptr(cd, codegen_finish_native_call);
-       N_L2(REG_ITMP1, disp, REG_PV);
+       M_ILD(REG_ITMP1, REG_PV, disp);
        M_CALL(REG_ITMP1);
        N_LR(REG_ITMP3, REG_RESULT);
 
@@ -4027,13 +4074,13 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                        if (IS_2_WORD_TYPE(t)) {
                                N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
                        } else {
-                               N_L(REG_RESULT, 96, 0, REG_SP);
+                               N_L(REG_RESULT, 96, RN, REG_SP);
                        }
                } else {
                        if (IS_2_WORD_TYPE(t)) {
-                               N_LD(REG_FRESULT, 96, 0, REG_SP);
+                               N_LD(REG_FRESULT, 96, RN, REG_SP);
                        } else {
-                               N_LE(REG_FRESULT, 96, 0, REG_SP);
+                               N_LE(REG_FRESULT, 96, RN, REG_SP);
                        }
                }
        }
@@ -4046,7 +4093,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        N_LTR(REG_ITMP3, REG_ITMP3);
        N_BRC(DD_NE, SZ_BRC + SZ_BC);
-       N_BC(DD_ANY, 0, 0, REG_SP); /* return */
+       N_BC(DD_ANY, 0, RN, REG_SP); /* return */
 
        /* handle exception */
 
index a34fa8fb7f208bdb4c0796b5c8f9a64b41e8c61c..130f4d0a0afaa8b7c6bf5e8e41cdf2c8a0e72850 100644 (file)
@@ -27,7 +27,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.h 7219 2007-01-16 22:18:57Z pm $
+   $Id: codegen.h 7283 2007-02-04 19:41:14Z pm $
 
 */
 
     }
 
 
-/* M_INTMOVE:
-    generates an integer-move from register a to b.
-    if a and b are the same int-register, no code will be generated.
-*/ 
-
-#define M_INTMOVE(reg,dreg) \
-    do { \
-        if ((reg) != (dreg)) { \
-            M_MOV(reg, dreg); \
-        } \
-    } while (0)
-
-
-/* M_FLTMOVE:
-    generates a floating-point-move from register a to b.
-    if a and b are the same float-register, no code will be generated
-*/ 
-
-#define M_FLTMOVE(reg,dreg) \
-    do { \
-        if ((reg) != (dreg)) { \
-            M_FMOV(reg, dreg); \
-        } \
-    } while (0)
-
 
 #define ICONST(r,c) \
     do { \
             M_MOV_IMM((c), (d)); \
     } while (0)
 
+/* branch defines *************************************************************/
+
+#define BRANCH_NOPS \
+    do { \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+        M_NOP; \
+    } while (0)
+
 
 /* some patcher defines *******************************************************/
 
 
 /* S390 specific code */
 
+/* Argument checks for debug mode */
+
+/* Some instructions with register arguments treat %r0 as "value not given".
+ * To prevent bugs, in debug mode we use a special value RN (reg none) with 
+ * the meaning "value not given".
+ * In debug mode, the instructions assert that %r0 was not given as argument.
+ */
+
+#if 1
+#      include <stdlib.h>
+       /* register none */
+#      define RN 16
+       /* Optional register.
+        * Check that value given is %r1 - %r15 or RN
+        */
+#      define _WITH_LINE(f, ...) f(__FILE__, __LINE__, __VA_ARGS__)
+       static inline int _OR_IMPL(const char *file, int line, int r) {
+               if(!(
+                       ((0 < r) && (r < 16)) ||
+                       (r == RN)
+               )) {
+                       fprintf(stdout, "%d is not a valid register at %s:%d.\n", r, file, line);
+                       abort();
+               }
+               return ((r == RN) ? 0 : r);
+       }
+#      define _OR(r) _WITH_LINE(_OR_IMPL, r)
+
+#      define _SMIN(b) (-(1 << (bits - 1)))
+#      define _SMAX(b) ((1 << (b - 1)) - 1)
+#      define _UMIN(b) 0
+#      define _UMAX(b) ((1 << b) - 1)
+
+       static inline int _UBITS_IMPL(const char *file, int line, int i, int bits) {
+               if (!((_UMIN(bits) <= i) && (i <= _UMAX(bits)))) {
+                       fprintf(stdout, "%d (0x%X) is not an unsigned %d bit integer at %s:%d.\n", i, i, bits, file, line);
+                       abort();
+               }
+               return i;
+       }
+#      define _UBITS(i, bits) _WITH_LINE(_UBITS_IMPL, i, bits)
+       static inline int _SBITS_IMPL(const char *file, int line, int i, int bits) {
+               if(!((_SMIN(bits) <= i) && (i <= _SMAX(bits)))) {
+                       fprintf(stdout, "%d (0x%X) is not an signed %d bit integer at %s:%d.\n", i, i, bits, file, line);
+                       abort();
+               }
+               return i;
+       }
+#      define _SBITS(i, bits) _WITH_LINE(_SBITS_IMPL, i, bits)
+       static inline int _BITS_IMPL(const char *file, int line, int i, int bits) {
+               if (!(
+                       ((_UMIN(bits) <= i) && (i <= _UMAX(bits))) ||
+                       ((_SMIN(bits) <= i) && (i <= _SMAX(bits)))
+               )) {
+                       fprintf(stdout, "%d (0x%X) is not an %d bit integer at %s:%d.\n", i, i, bits, file, line);
+                       abort();
+               }
+               return i;
+       }
+#      define _BITS(i, bits) _WITH_LINE(_BITS_IMPL, i, bits)
+#else
+#      define RN 0
+#      define _OR(x) (x)
+#      define _BITS(x, b) (x)
+#      define _UBITS(x, b) (x)
+#      define _SBITS(x, b) (x)
+#endif
+
+/* Register */
+#define _R(x) _UBITS((x), 4)
+/* Displacement */
+#define _D(x) _UBITS((x), 12)
+/* 4 bit Immediate */
+#define _I4(x) _BITS((x), 4)
+#define _UI4(x) _UBITS((x), 4)
+#define _SI4(x) _SBITS((x), 4)
+/* 8 bit Immediate */
+#define _I8(x) _BITS((x), 8)
+#define _UI8(x) _UBITS((x), 8)
+#define _SI8(x) _SBITS((x), 8)
+/* 12 bit Immediate */
+#define _I12(x) _BITS((x), 12)
+#define _UI12(x) _UBITS((x), 12)
+#define _SI12(x) _SBITS((x), 12)
+/* 16 bit Immediate */
+#define _I16(x) _BITS((x), 16)
+#define _UI16(x) _UBITS((x), 16)
+#define _SI16(x) _SBITS((x), 16)
+/* Opcode */
+#define _OP(x) _UBITS((x), 8)
+/* Second part of opcode */
+#define _OP4(x) _UBITS((x), 4)
+/* Extended opcode */
+#define _OP16(x) _UBITS((x), 16)
+
 /* Instruction formats */
 
 #define _CODE(t, code) \
        do { \
                *((t *) cd->mcodeptr) = (code); \
                cd->mcodeptr += sizeof(t); \
-       } while (0);
+       } while (0)
 
 #define _CODE2(code) _CODE(u2, code)
 #define _CODE4(code) _CODE(u4, code)
        do { if ((val) < 0) { neg ; } else { pos ; } } while (0)
 
 #define N_RR(op, r1, r2) \
-       _CODE2( (op << 8) | (r1 << 4) | (r2) )
+       _CODE2( (_OP(op) << 8) | (_R(r1) << 4) | _R(r2) )
 
 #define SZ_RR 2
 
 #define N_RR2(op, i) \
-       _CODE2( (op << 8) | (i) )
+       _CODE2( (_OP(op) << 8) | _I8(i) )
 
 #define N_RX(op, r1, d2, x2, b2) \
-       _CODE4( ((op) << 24) | ((r1) << 20) | ((x2) << 16) | ((b2) << 12) | ((d2) << 0) )
+       _CODE4( (_OP(op) << 24) | (_R(r1) << 20) | (_OR(x2) << 16) | (_OR(b2) << 12) | (_D(d2) << 0) )
 
 #define SZ_RX 4
 
 #define N_RI(op1, op2, r1, i2) \
-       _CODE4( ((op1) << 24) | ((r1) << 20) | ((op2) << 16) | ((u2) i2) )
+       _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_I16(i2) )
 
 #define SZ_RI 4
 
 #define N_SI(op, d1, b1, i2) \
-       _CODE4( ((op) << 24) | ((i2) << 16) | ((b1) << 12) | (d1) )
+       _CODE4( (_OP(op) << 24) | (_OR(i2) << 16) | (_OR(b1) << 12) | _D(d1) )
 
 #define SZ_SI 4
 
 #define N_SS(op, d1, l, b1, d2, b2) \
-       _CODE4( ((op) << 24) | ((l) << 16) | ((b1) << 12) | (d1) ) \
-       _CODE2( ((b2) << 12) | (d2) )
+       do { \
+               _CODE4( (_OP(op) << 24) | (_I8(l) << 16) | (_OR(b1) << 12) | _D(d1) ); \
+               _CODE2( (_OR(b2) << 12) | _D(d2) ); \
+       } while (0)
 
 #define SZ_SS 6
 
 #define N_SS2(op, d1, l1, b1, d2, l2, b2) \
-       N_SS(op, d1, ((l1) << 4) | (l2), b1, d2, l2)
+       N_SS(op, d1, (_I4(l1) << 4) | _I4(l2), b1, d2, l2)
 
 #define N_RS(op, r1, r3, d2, b2) \
-       _CODE4( ((op) << 24) | ((r1) << 20) | ((r3) << 16) | ((b2) << 12) | (d2) )
+       _CODE4( (_OP(op) << 24) | (_R(r1) << 20) | (_R(r3) << 16) | (_OR(b2) << 12) | _D(d2) )
 
 #define SZ_RS 4
 
 #define N_RSI(op, r1, r2, i2) \
-       _CODE4( ((op) << 24) | ((r1) << 20) | ((r3) << 16) | ((u2)i2) )
+       _CODE4( ((op) << 24) | (_R(r1) << 20) | (_R(r3) << 16) | (u2)_16(i2) )
 
 #define SZ_RSI 4
 
 #define N_RRE(op, r1, r2) \
-       _CODE4( ((op) << 16) | ((r1) << 4) | (r2) )
+       _CODE4( (_OP16(op) << 16) | (_R(r1) << 4) | _R(r2) )
 
 #define SZ_RRE 4
 
 #define N_S2(d2, b2) \
-       _CODE4( ((op) << 16) | ((b2) << 12) | (d2)  )
+       _CODE4( (_OP16(op) << 16) | (_OR(b2) << 12) | _D(d2)  )
 
 #define SZ_S2 4
 
 #define N_E(op) \
-       _CODE2( (op) )
+       _CODE2( _OP16(op) )
 
 #define SZ_E 2
 
 #define N_N(r1, d2, x2, b2) N_RX(0x54, r1, d2, x2, b2)
 #define N_NI(d1, b1, i2) N_SI(0x94, d1, b1, i2)
 #define N_NC(d1, l, b1, d2, b2) N_NC(0xD4, l, b1, d1, b2, d2)
-#define N_BALR(r1, r2) N_RR(0x05, r1, r2)
+#define N_BALR(r1, r2) N_RR(0x05, r1, _OR(r2))
 #define N_BAL(r1, d2, x2, b2) N_RX(0x45, r1, d2, x2, b2)
-#define N_BASR(r1, r2) N_RR(0x0D, r1, r2)
+#define N_BASR(r1, r2) N_RR(0x0D, r1, _OR(r2))
 #define N_BAS(r1, d2, x2, b2) N_RX(0x4D, r1, d2, x2, b2)
-#define N_BASSM(r1, r2) N_RR(0x0C, r1, r2)
-#define N_BSM(r1, r2) N_RR(0x0B, r1, r2)
-#define N_BCR(m1, r2) N_RR(0x07, m1, r2)
+#define N_BASSM(r1, r2) N_RR(0x0C, r1, _OR(r2))
+#define N_BSM(r1, r2) N_RR(0x0B, r1, _OR(r2))
+#define N_BCR(m1, r2) N_RR(0x07, m1, _OR(r2))
 #      define SZ_BCR SZ_RR
 #      define N_BR(r2) N_BCR(DD_ANY, r2)
 #      define SZ_BR SZ_BCR
 #define N_BC(m1, d2, x2, b2) N_RS(0x47, m1, d2, x2, b2)
 #      define SZ_BC SZ_RS
-#define N_BCTR(r1, r2) N_RR(0x06, r1, r2)
+#define N_BCTR(r1, r2) N_RR(0x06, r1, _OR(r2))
 #define N_BCT(r1, d2, x2, b2) N_RX(0x46, r1, d2, x2, b2)
 #define N_BHX(r1, r2, d2, b2) N_RS(0xB6, r1, r3, d2, b2)
 #define N_BXLE(r1, r3, d2, b2) N_RS(0xB7, r1, r3, d2, b2)
 #define N_BRXH(r1, r3, i2) N_RSI(0x84, r1, r3, (i2) / 2)
 #define N_BRXLE(r1, r3, i2) N_RSI(0x85, r1, r2, (i2) / 2)
 #define N_CKSM(r1, r2) N_RRE(0xB241, r1, r2)
-#define N_CR(r1, r2), N_RR(0x19, r1, r2)
+#define N_CR(r1, r2) N_RR(0x19, r1, r2)
+#      define SZ_CR SZ_RR
 #define N_C(r1, d2, x2, b2) N_RX(0x59, r1, d2, x2, b2)
 #define N_CFC(d2, b2) N_S2(0xB21A, d2, b2)
 #define N_CS(r1, r3, d2, b2) N_RS(0xBA, r1, r3, d2, b2)
 #define N_LR(r1, r2) N_RR(0x18, r1, r2)
 #define N_L(r1, d2, x2, b2) N_RX(0x58, r1, d2, x2, b2)
 #      define SZ_L SZ_RX
-#      define N_L2(r1, d2, b2) \
-               do { N_LHI(r1, d2); N_L(r1, 0, r1, b2); } while (0)
 #define N_LAM(r1, r3, d2, b2) N_RS(0x9A, r1, r3, d2, b2)
 #define N_LA(r1, d2, x2, b2) N_RX(0x41, r1, d2, x2, b2)
-#      define N_LA2(r1, d2, b2) \
-               do { N_LHI(r1, d2); N_LA(r1, 0, r1, b2); } while (0)
 #define N_LAE(r1, d2, x2, b2) N_RX(0x51, r1, d2, x2, b2)
 #define N_LTR(r1, r2) N_RR(0x12, r1, r2)
 #define N_LCR(r1, r2) N_RR(0x13, r1, r2)
 
 #define M_CALL(r2) N_BASR(R14, r2)
 
-#define M_ALD(r, b, d) _IFNEG(d, N_L2(r, d, b), N_L(r, d, 0, b))
-#define M_ILD(r, b, d) _IFNEG(d, N_LA2(r, d, b), N_LA(r, d, 0, b))
-#define M_FLD(r, b, d) _IFNEG(d, assert(0), N_LE(r, d, 0, b))
-#define M_DLD(r, b, d) _IFNEG(d, assert(0), N_LD(r, d, 0, b))
-/* TODO 3 instead of 4 instrs for d < 0 ! */
-#define M_LLD(r, b, d) \
-       do { M_ILD(GET_HIGH_REG(r), b, d); M_ILD(GET_LOW_REG(r), b, d + 4); } while(0)
+#define M_ILD(r, b, d) _IFNEG( \
+       d, \
+       N_LHI(r, d); N_L(r, 0, r, b), \
+       N_L(r, d, RN, b) \
+)
+
+#define M_ALD(r, b, d) M_ILD(r, b, d)
+
+#define M_LDA(r, b, d) _IFNEG( \
+       d, \
+       N_LHI(r, d); N_LA(r, 0, r, b), \
+       N_LA(r, d, RN, b) \
+)
+
+#define M_FLD(r, b, d) _IFNEG(d, assert(0), N_LE(r, d, RN, b))
+#define M_DLD(r, b, d) _IFNEG(d, assert(0), N_LD(r, d, RN, b))
+
+#define M_LLD(r, b, d) _IFNEG( \
+       d, \
+       N_LHI(GET_LOW_REG(r), d); \
+               N_L(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
+               N_L(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+       N_L(GET_HIGH_REG(r), 0, RN, b); N_L(GET_LOW_REG(r), 4, RN, b) \
+)
+
+#define M_MOV(a, b) N_LR(a, b)
+#define M_FMOV(a, b) N_LDR(a, b)
+#define M_DST(r, b, d) _IFNEG(d, assert(0), N_STD(r, d, RN, b))
+#define M_FST(r, b, d) _IFNEG(d, assert(0), N_STE(r, d, RN, b))
+#define M_IST(r, b, d) _IFNEG( \
+       d, \
+       N_LHI(r, d); N_S(r, 0, r, b), \
+       N_S(r, d, RN, b) \
+)
+#define M_AST(r, b, d) M_IST(r, b, d)
+#define M_LST(r, b, d) _IFNEG( \
+       d, \
+       N_LHI(GET_LOW_REG(r), d); \
+               N_S(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
+               N_S(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+       N_S(GET_HIGH_REG(r), 0, RN, b); N_S(GET_LOW_REG(r), 4, RN, b) \
+)
+#define M_TEST(r) N_LTR(r, r)
+#define M_BEQ(off) N_BRC(DD_E, off)
+#define M_BNE(off) N_BRC(DD_NE, off)
+#define M_BLE(off) N_BRC(DD_LE, off)
+#define M_BGT(off) N_BRC(DD_H, off)
+#define M_BLT(off) N_BRC(DD_L, off)
+
+#define M_CMP(r1, r2) N_CR(r1, r2)
+#define M_CLR(r) N_LHI(r, 0)
+#define M_AADD_IMM(val, reg) N_LA(reg, val, RN, reg)
+#define M_IADD_IMM(val, reg) N_AHI(reg, val)
+#define M_ASUB_IMM(val, reg) N_AHI(reg, -(val))
+#define M_RET N_BCR(DD_ANY, R14)
+
+/* M_INTMOVE:
+    generates an integer-move from register a to b.
+    if a and b are the same int-register, no code will be generated.
+*/ 
+
+#define M_INTMOVE(reg,dreg) \
+    do { \
+        if ((reg) != (dreg)) { \
+            M_MOV(reg, dreg); \
+        } \
+    } while (0)
+
+#define M_LNGMOVE(a, b) \
+    do { \
+        if (GET_HIGH_REG(a) == GET_LOW_REG(b)) { \
+            assert((GET_LOW_REG(a) != GET_HIGH_REG(b))); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+        } else { \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+        } \
+    } while (0)
+
+/* M_FLTMOVE:
+    generates a floating-point-move from register a to b.
+    if a and b are the same float-register, no code will be generated
+*/ 
+
+#define M_FLTMOVE(reg,dreg) \
+    do { \
+        if ((reg) != (dreg)) { \
+            M_FMOV(reg, dreg); \
+        } \
+    } while (0)
+
+
 
 /* ----------------------------------------------- */
 
-#define M_MOV(a,b)              emit_mov_reg_reg(cd, (a), (b))
-#define M_MOV_IMM(a,b)          emit_mov_imm_reg(cd, (u8) (a), (b))
+#define _DEPR(x) \
+       do { \
+               fprintf(stdout, \
+                       "Using old x86_64 instruction %s at %s (%s:%d), fix this.\n", \
+                       #x, __FUNCTION__, __FILE__, __LINE__); \
+       } while (0)
+
+#define M_MOV_IMM(a,b) _DEPR( M_MOV_IMM(a,b) )
+
+#define M_IMOV(a,b) _DEPR( M_IMOV(a,b) )
+#define M_IMOV_IMM(a,b) _DEPR( M_IMOV_IMM(a,b) )
 
-#define M_IMOV(a,b)             emit_movl_reg_reg(cd, (a), (b))
-#define M_IMOV_IMM(a,b)         emit_movl_imm_reg(cd, (u4) (a), (b))
 
-#define M_FMOV(a,b)             emit_movq_reg_reg(cd, (a), (b))
+#define M_ILD32(a,b,disp) _DEPR( M_ILD32(a,b,disp) )
+#define M_LLD32(a,b,disp) _DEPR( M_LLD32(a,b,disp) )
 
-#define M__ILD(a,b,disp)         emit_movl_membase_reg(cd, (b), (disp), (a))
-#define M__LLD(a,b,disp)         emit_mov_membase_reg(cd, (b), (disp), (a))
 
-#define M_ILD32(a,b,disp)       emit_movl_membase32_reg(cd, (b), (disp), (a))
-#define M_LLD32(a,b,disp)       emit_mov_membase32_reg(cd, (b), (disp), (a))
+#define M_IST_IMM(a,b,disp) _DEPR( M_IST_IMM(a,b,disp) )
+#define M_LST_IMM32(a,b,disp) _DEPR( M_LST_IMM32(a,b,disp) )
 
-#define M_IST(a,b,disp)         emit_movl_reg_membase(cd, (a), (b), (disp))
-#define M_LST(a,b,disp)         emit_mov_reg_membase(cd, (a), (b), (disp))
+#define M_IST32(a,b,disp) _DEPR( M_IST32(a,b,disp) )
+#define M_LST32(a,b,disp) _DEPR( M_LST32(a,b,disp) )
 
-#define M_IST_IMM(a,b,disp)     emit_movl_imm_membase(cd, (a), (b), (disp))
-#define M_LST_IMM32(a,b,disp)   emit_mov_imm_membase(cd, (a), (b), (disp))
+#define M_IST32_IMM(a,b,disp) _DEPR( M_IST32_IMM(a,b,disp) )
+#define M_LST32_IMM32(a,b,disp) _DEPR( M_LST32_IMM32(a,b,disp) )
 
-#define M_IST32(a,b,disp)       emit_movl_reg_membase32(cd, (a), (b), (disp))
-#define M_LST32(a,b,disp)       emit_mov_reg_membase32(cd, (a), (b), (disp))
+#define M_IADD(a,b) _DEPR( M_IADD(a,b) )
+#define M_ISUB(a,b) _DEPR( M_ISUB(a,b) )
+#define M_IMUL(a,b) _DEPR( M_IMUL(a,b) )
 
-#define M_IST32_IMM(a,b,disp)   emit_movl_imm_membase32(cd, (a), (b), (disp))
-#define M_LST32_IMM32(a,b,disp) emit_mov_imm_membase32(cd, (a), (b), (disp))
+#define M_ISUB_IMM(a,b) _DEPR( M_ISUB_IMM(a,b) )
+#define M_IMUL_IMM(a,b,c) _DEPR( M_IMUL_IMM(a,b,c) )
 
-#define M_IADD(a,b)             emit_alul_reg_reg(cd, ALU_ADD, (a), (b))
-#define M_ISUB(a,b)             emit_alul_reg_reg(cd, ALU_SUB, (a), (b))
-#define M_IMUL(a,b)             emit_imull_reg_reg(cd, (a), (b))
+#define M_LADD(a,b) _DEPR( M_LADD(a,b) )
+#define M_LSUB(a,b) _DEPR( M_LSUB(a,b) )
+#define M_LMUL(a,b) _DEPR( M_LMUL(a,b) )
 
-#define M_IADD_IMM(a,b)         emit_alul_imm_reg(cd, ALU_ADD, (a), (b))
-#define M_ISUB_IMM(a,b)         emit_alul_imm_reg(cd, ALU_SUB, (a), (b))
-#define M_IMUL_IMM(a,b,c)       emit_imull_imm_reg_reg(cd, (b), (a), (c))
+#define M_LADD_IMM(a,b) _DEPR( M_LADD_IMM(a,b) )
+#define M_LSUB_IMM(a,b) _DEPR( M_LSUB_IMM(a,b) )
+#define M_LMUL_IMM(a,b,c) _DEPR( M_LMUL_IMM(a,b,c) )
 
-#define M_LADD(a,b)             emit_alu_reg_reg(cd, ALU_ADD, (a), (b))
-#define M_LSUB(a,b)             emit_alu_reg_reg(cd, ALU_SUB, (a), (b))
-#define M_LMUL(a,b)             emit_imul_reg_reg(cd, (a), (b))
+#define M_IINC(a) _DEPR( M_IINC(a) )
+#define M_IDEC(a) _DEPR( M_IDEC(a) )
 
-#define M_LADD_IMM(a,b)         emit_alu_imm_reg(cd, ALU_ADD, (a), (b))
-#define M_LSUB_IMM(a,b)         emit_alu_imm_reg(cd, ALU_SUB, (a), (b))
-#define M_LMUL_IMM(a,b,c)       emit_imul_imm_reg_reg(cd, (b), (a), (c))
+#define M_ALD32(a,b,disp) _DEPR( M_ALD32(a,b,disp) )
 
-#define M_IINC(a)               emit_incl_reg(cd, (a))
-#define M_IDEC(a)               emit_decl_reg(cd, (a))
+#define M_AST_IMM32(a,b,c) _DEPR( M_AST_IMM32(a,b,c) )
 
-#define M__ALD(a,b,disp)         M_LLD(a,b,disp)
-#define M_ALD32(a,b,disp)       M_LLD32(a,b,disp)
+#define M_AADD(a,b) _DEPR( M_AADD(a,b) )
 
-#define M_AST(a,b,c)            M_LST(a,b,c)
-#define M_AST_IMM32(a,b,c)      M_LST_IMM32(a,b,c)
+#define M_LADD_IMM32(a,b) _DEPR( M_LADD_IMM32(a,b) )
+#define M_AADD_IMM32(a,b) _DEPR( M_AADD_IMM32(a,b) )
+#define M_LSUB_IMM32(a,b) _DEPR( M_LSUB_IMM32(a,b) )
 
-#define M_AADD(a,b)             M_LADD(a,b)
-#define M_AADD_IMM(a,b)         M_LADD_IMM(a,b)
-#define M_ASUB_IMM(a,b)         M_LSUB_IMM(a,b)
+#define M_ILEA(a,b,c) _DEPR( M_ILEA(a,b,c) )
+#define M_LLEA(a,b,c) _DEPR( M_LLEA(a,b,c) )
+#define M_ALEA(a,b,c) _DEPR( M_ALEA(a,b,c) )
 
-#define M_LADD_IMM32(a,b)       emit_alu_imm32_reg(cd, ALU_ADD, (a), (b))
-#define M_AADD_IMM32(a,b)       M_LADD_IMM32(a,b)
-#define M_LSUB_IMM32(a,b)       emit_alu_imm32_reg(cd, ALU_SUB, (a), (b))
+#define M_INEG(a) _DEPR( M_INEG(a) )
+#define M_LNEG(a) _DEPR( M_LNEG(a) )
 
-#define M_ILEA(a,b,c)           emit_leal_membase_reg(cd, (a), (b), (c))
-#define M_LLEA(a,b,c)           emit_lea_membase_reg(cd, (a), (b), (c))
-#define M_ALEA(a,b,c)           M_LLEA(a,b,c)
+#define M_IAND(a,b) _DEPR( M_IAND(a,b) )
+#define M_IOR(a,b) _DEPR( M_IOR(a,b) )
+#define M_IXOR(a,b) _DEPR( M_IXOR(a,b) )
 
-#define M_INEG(a)               emit_negl_reg(cd, (a))
-#define M_LNEG(a)               emit_neg_reg(cd, (a))
+#define M_IAND_IMM(a,b) _DEPR( M_IAND_IMM(a,b) )
+#define M_IOR_IMM(a,b) _DEPR( M_IOR_IMM(a,b) )
+#define M_IXOR_IMM(a,b) _DEPR( M_IXOR_IMM(a,b) )
 
-#define M_IAND(a,b)             emit_alul_reg_reg(cd, ALU_AND, (a), (b))
-#define M_IOR(a,b)              emit_alul_reg_reg(cd, ALU_OR, (a), (b))
-#define M_IXOR(a,b)             emit_alul_reg_reg(cd, ALU_XOR, (a), (b))
+#define M_LAND(a,b) _DEPR( M_LAND(a,b) )
+#define M_LOR(a,b) _DEPR( M_LOR(a,b) )
+#define M_LXOR(a,b) _DEPR( M_LXOR(a,b) )
 
-#define M_IAND_IMM(a,b)         emit_alul_imm_reg(cd, ALU_AND, (a), (b))
-#define M_IOR_IMM(a,b)          emit_alul_imm_reg(cd, ALU_OR, (a), (b))
-#define M_IXOR_IMM(a,b)         emit_alul_imm_reg(cd, ALU_XOR, (a), (b))
+#define M_LAND_IMM(a,b) _DEPR( M_LAND_IMM(a,b) )
+#define M_LOR_IMM(a,b) _DEPR( M_LOR_IMM(a,b) )
+#define M_LXOR_IMM(a,b) _DEPR( M_LXOR_IMM(a,b) )
 
-#define M_LAND(a,b)             emit_alu_reg_reg(cd, ALU_AND, (a), (b))
-#define M_LOR(a,b)              emit_alu_reg_reg(cd, ALU_OR, (a), (b))
-#define M_LXOR(a,b)             emit_alu_reg_reg(cd, ALU_XOR, (a), (b))
+#define M_SSEXT(a,b) _DEPR( M_SSEXT(a,b) )
+#define M_ISEXT(a,b) _DEPR( M_ISEXT(a,b) )
 
-#define M_LAND_IMM(a,b)         emit_alu_imm_reg(cd, ALU_AND, (a), (b))
-#define M_LOR_IMM(a,b)          emit_alu_imm_reg(cd, ALU_OR, (a), (b))
-#define M_LXOR_IMM(a,b)         emit_alu_imm_reg(cd, ALU_XOR, (a), (b))
+#define M_CZEXT(a,b) _DEPR( M_CZEXT(a,b) )
 
-#define M_BSEXT(a,b)            emit_movsbq_reg_reg(cd, (a), (b))
-#define M_SSEXT(a,b)            emit_movswq_reg_reg(cd, (a), (b))
-#define M_ISEXT(a,b)            emit_movslq_reg_reg(cd, (a), (b))
+#define M_ISLL_IMM(a,b) _DEPR( M_ISLL_IMM(a,b) )
+#define M_ISRA_IMM(a,b) _DEPR( M_ISRA_IMM(a,b) )
+#define M_ISRL_IMM(a,b) _DEPR( M_ISRL_IMM(a,b) )
 
-#define M_CZEXT(a,b)            emit_movzwq_reg_reg(cd, (a), (b))
+#define M_LSLL_IMM(a,b) _DEPR( M_LSLL_IMM(a,b) )
+#define M_LSRA_IMM(a,b) _DEPR( M_LSRA_IMM(a,b) )
+#define M_LSRL_IMM(a,b) _DEPR( M_LSRL_IMM(a,b) )
 
-#define M_ISLL_IMM(a,b)         emit_shiftl_imm_reg(cd, SHIFT_SHL, (a), (b))
-#define M_ISRA_IMM(a,b)         emit_shiftl_imm_reg(cd, SHIFT_SAR, (a), (b))
-#define M_ISRL_IMM(a,b)         emit_shiftl_imm_reg(cd, SHIFT_SHR, (a), (b))
+#define M_LCMP(a,b) _DEPR( M_LCMP(a,b) )
+#define M_LCMP_IMM(a,b) _DEPR( M_LCMP_IMM(a,b) )
+#define M_LCMP_IMM_MEMBASE(a,b,c) _DEPR( M_LCMP_IMM_MEMBASE(a,b,c) )
+#define M_LCMP_MEMBASE(a,b,c) _DEPR( M_LCMP_MEMBASE(a,b,c) )
 
-#define M_LSLL_IMM(a,b)         emit_shift_imm_reg(cd, SHIFT_SHL, (a), (b))
-#define M_LSRA_IMM(a,b)         emit_shift_imm_reg(cd, SHIFT_SAR, (a), (b))
-#define M_LSRL_IMM(a,b)         emit_shift_imm_reg(cd, SHIFT_SHR, (a), (b))
+#define M_ICMP(a,b) _DEPR( M_ICMP(a,b) )
+#define M_ICMP_IMM(a,b) _DEPR( M_ICMP_IMM(a,b) )
+#define M_ICMP_IMM_MEMBASE(a,b,c) _DEPR( M_ICMP_IMM_MEMBASE(a,b,c) )
+#define M_ICMP_MEMBASE(a,b,c) _DEPR( M_ICMP_MEMBASE(a,b,c) )
 
-#define M_TEST(a)               emit_test_reg_reg(cd, (a), (a))
-#define M_ITEST(a)              emit_testl_reg_reg(cd, (a), (a))
+#define M_BGE(disp) _DEPR( M_BGE(disp) )
+#define M_BAE(disp) _DEPR( M_BAE(disp) )
+#define M_BA(disp) _DEPR( M_BA(disp) )
 
-#define M_LCMP(a,b)             emit_alu_reg_reg(cd, ALU_CMP, (a), (b))
-#define M_LCMP_IMM(a,b)         emit_alu_imm_reg(cd, ALU_CMP, (a), (b))
-#define M_LCMP_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_CMP, (a), (b), (c))
-#define M_LCMP_MEMBASE(a,b,c)   emit_alu_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_CMOVEQ(a,b) _DEPR( M_CMOVEQ(a,b) )
+#define M_CMOVNE(a,b) _DEPR( M_CMOVNE(a,b) )
+#define M_CMOVLT(a,b) _DEPR( M_CMOVLT(a,b) )
+#define M_CMOVLE(a,b) _DEPR( M_CMOVLE(a,b) )
+#define M_CMOVGE(a,b) _DEPR( M_CMOVGE(a,b) )
+#define M_CMOVGT(a,b) _DEPR( M_CMOVGT(a,b) )
 
-#define M_ICMP(a,b)             emit_alul_reg_reg(cd, ALU_CMP, (a), (b))
-#define M_ICMP_IMM(a,b)         emit_alul_imm_reg(cd, ALU_CMP, (a), (b))
-#define M_ICMP_IMM_MEMBASE(a,b,c) emit_alul_imm_membase(cd, ALU_CMP, (a), (b), (c))
-#define M_ICMP_MEMBASE(a,b,c)   emit_alul_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_CMOVEQ_MEMBASE(a,b,c) _DEPR( M_CMOVEQ_MEMBASE(a,b,c) )
+#define M_CMOVNE_MEMBASE(a,b,c) _DEPR( M_CMOVNE_MEMBASE(a,b,c) )
+#define M_CMOVLT_MEMBASE(a,b,c) _DEPR( M_CMOVLT_MEMBASE(a,b,c) )
+#define M_CMOVLE_MEMBASE(a,b,c) _DEPR( M_CMOVLE_MEMBASE(a,b,c) )
+#define M_CMOVGE_MEMBASE(a,b,c) _DEPR( M_CMOVGE_MEMBASE(a,b,c) )
+#define M_CMOVGT_MEMBASE(a,b,c) _DEPR( M_CMOVGT_MEMBASE(a,b,c) )
 
-#define M_BEQ(disp)             emit_jcc(cd, CC_E, (disp))
-#define M_BNE(disp)             emit_jcc(cd, CC_NE, (disp))
-#define M_BLT(disp)             emit_jcc(cd, CC_L, (disp))
-#define M_BLE(disp)             emit_jcc(cd, CC_LE, (disp))
-#define M_BGE(disp)             emit_jcc(cd, CC_GE, (disp))
-#define M_BGT(disp)             emit_jcc(cd, CC_G, (disp))
-#define M_BAE(disp)             emit_jcc(cd, CC_AE, (disp))
-#define M_BA(disp)              emit_jcc(cd, CC_A, (disp))
+#define M_CMOVB(a,b) _DEPR( M_CMOVB(a,b) )
+#define M_CMOVA(a,b) _DEPR( M_CMOVA(a,b) )
+#define M_CMOVP(a,b) _DEPR( M_CMOVP(a,b) )
 
-#define M_CMOVEQ(a,b)           emit_cmovcc_reg_reg(cd, CC_E, (a), (b))
-#define M_CMOVNE(a,b)           emit_cmovcc_reg_reg(cd, CC_NE, (a), (b))
-#define M_CMOVLT(a,b)           emit_cmovcc_reg_reg(cd, CC_L, (a), (b))
-#define M_CMOVLE(a,b)           emit_cmovcc_reg_reg(cd, CC_LE, (a), (b))
-#define M_CMOVGE(a,b)           emit_cmovcc_reg_reg(cd, CC_GE, (a), (b))
-#define M_CMOVGT(a,b)           emit_cmovcc_reg_reg(cd, CC_G, (a), (b))
+#define M_PUSH(a) _DEPR( M_PUSH(a) )
+#define M_PUSH_IMM(a) _DEPR( M_PUSH_IMM(a) )
+#define M_POP(a) _DEPR( M_POP(a) )
 
-#define M_CMOVEQ_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_E, (a), (b))
-#define M_CMOVNE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_NE, (a), (b))
-#define M_CMOVLT_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_L, (a), (b))
-#define M_CMOVLE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_LE, (a), (b))
-#define M_CMOVGE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_GE, (a), (b))
-#define M_CMOVGT_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_G, (a), (b))
+#define M_JMP(a) _DEPR( M_JMP(a) )
+#define M_JMP_IMM(a) _DEPR( M_JMP_IMM(a) )
+#define M_CALL_IMM(a) _DEPR( M_CALL_IMM(a) )
 
-#define M_CMOVB(a,b)            emit_cmovcc_reg_reg(cd, CC_B, (a), (b))
-#define M_CMOVA(a,b)            emit_cmovcc_reg_reg(cd, CC_A, (a), (b))
-#define M_CMOVP(a,b)            emit_cmovcc_reg_reg(cd, CC_P, (a), (b))
+#define M_NOP _DEPR( M_NOP )
 
-#define M_PUSH(a)               emit_push_reg(cd, (a))
-#define M_PUSH_IMM(a)           emit_push_imm(cd, (a))
-#define M_POP(a)                emit_pop_reg(cd, (a))
 
-#define M_JMP(a)                emit_jmp_reg(cd, (a))
-#define M_JMP_IMM(a)            emit_jmp_imm(cd, (a))
-#define M__CALL(a)               emit_call_reg(cd, (a))
-#define M_CALL_IMM(a)           emit_call_imm(cd, (a))
-#define M_RET                   emit_ret(cd)
-
-#define M_NOP                   emit_nop(cd)
-
-#define M_CLR(a)                M_LXOR(a,a)
 
 
-#define M__FLD(a,b,disp)         emit_movss_membase_reg(cd, (b), (disp), (a))
-#define M__DLD(a,b,disp)         emit_movsd_membase_reg(cd, (b), (disp), (a))
-
-#define M_FLD32(a,b,disp)       emit_movss_membase32_reg(cd, (b), (disp), (a))
-#define M_DLD32(a,b,disp)       emit_movsd_membase32_reg(cd, (b), (disp), (a))
-
-#define M_FST(a,b,disp)         emit_movss_reg_membase(cd, (a), (b), (disp))
-#define M_DST(a,b,disp)         emit_movsd_reg_membase(cd, (a), (b), (disp))
-
-#define M_FST32(a,b,disp)       emit_movss_reg_membase32(cd, (a), (b), (disp))
-#define M_DST32(a,b,disp)       emit_movsd_reg_membase32(cd, (a), (b), (disp))
+#define M_FLD32(a,b,disp) _DEPR( M_FLD32(a,b,disp) )
+#define M_DLD32(a,b,disp) _DEPR( M_DLD32(a,b,disp) )
 
-#define M_FADD(a,b)             emit_addss_reg_reg(cd, (a), (b))
-#define M_DADD(a,b)             emit_addsd_reg_reg(cd, (a), (b))
-#define M_FSUB(a,b)             emit_subss_reg_reg(cd, (a), (b))
-#define M_DSUB(a,b)             emit_subsd_reg_reg(cd, (a), (b))
-#define M_FMUL(a,b)             emit_mulss_reg_reg(cd, (a), (b))
-#define M_DMUL(a,b)             emit_mulsd_reg_reg(cd, (a), (b))
-#define M_FDIV(a,b)             emit_divss_reg_reg(cd, (a), (b))
-#define M_DDIV(a,b)             emit_divsd_reg_reg(cd, (a), (b))
-
-#define M_CVTIF(a,b)            emit_cvtsi2ss_reg_reg(cd, (a), (b))
-#define M_CVTID(a,b)            emit_cvtsi2sd_reg_reg(cd, (a), (b))
-#define M_CVTLF(a,b)            emit_cvtsi2ssq_reg_reg(cd, (a), (b))
-#define M_CVTLD(a,b)            emit_cvtsi2sdq_reg_reg(cd, (a), (b))
-#define M_CVTFI(a,b)            emit_cvttss2si_reg_reg(cd, (a), (b))
-#define M_CVTDI(a,b)            emit_cvttsd2si_reg_reg(cd, (a), (b))
-#define M_CVTFL(a,b)            emit_cvttss2siq_reg_reg(cd, (a), (b))
-#define M_CVTDL(a,b)            emit_cvttsd2siq_reg_reg(cd, (a), (b))
-
-#define M_CVTFD(a,b)            emit_cvtss2sd_reg_reg(cd, (a), (b))
-#define M_CVTDF(a,b)            emit_cvtsd2ss_reg_reg(cd, (a), (b))
+
+#define M_FST32(a,b,disp) _DEPR( M_FST32(a,b,disp) )
+#define M_DST32(a,b,disp) _DEPR( M_DST32(a,b,disp) )
+
+#define M_FADD(a,b) _DEPR( M_FADD(a,b) )
+#define M_DADD(a,b) _DEPR( M_DADD(a,b) )
+#define M_FSUB(a,b) _DEPR( M_FSUB(a,b) )
+#define M_DSUB(a,b) _DEPR( M_DSUB(a,b) )
+#define M_FMUL(a,b) _DEPR( M_FMUL(a,b) )
+#define M_DMUL(a,b) _DEPR( M_DMUL(a,b) )
+#define M_FDIV(a,b) _DEPR( M_FDIV(a,b) )
+#define M_DDIV(a,b) _DEPR( M_DDIV(a,b) )
+
+#define M_CVTIF(a,b) _DEPR( M_CVTIF(a,b) )
+#define M_CVTID(a,b) _DEPR( M_CVTID(a,b) )
+#define M_CVTLF(a,b) _DEPR( M_CVTLF(a,b) )
+#define M_CVTLD(a,b) _DEPR( M_CVTLD(a,b) )
+#define M_CVTFI(a,b) _DEPR( M_CVTFI(a,b) )
+#define M_CVTDI(a,b) _DEPR( M_CVTDI(a,b) )
+#define M_CVTFL(a,b) _DEPR( M_CVTFL(a,b) )
+#define M_CVTDL(a,b) _DEPR( M_CVTDL(a,b) )
+
+#define M_CVTFD(a,b) _DEPR( M_CVTFD(a,b) )
+#define M_CVTDF(a,b) _DEPR( M_CVTDF(a,b) )
 
 
 /* system instructions ********************************************************/
 
-#define M_RDTSC                 emit_rdtsc(cd)
+#define M_RDTSC _DEPR( M_RDTSC )
 
-#define M_IINC_MEMBASE(a,b)     emit_incl_membase(cd, (a), (b))
+#define M_IINC_MEMBASE(a,b) _DEPR( M_IINC_MEMBASE(a,b) )
 
-#define M_IADD_MEMBASE(a,b,c)   emit_alul_reg_membase(cd, ALU_ADD, (a), (b), (c))
-#define M_IADC_MEMBASE(a,b,c)   emit_alul_reg_membase(cd, ALU_ADC, (a), (b), (c))
-#define M_ISUB_MEMBASE(a,b,c)   emit_alul_reg_membase(cd, ALU_SUB, (a), (b), (c))
-#define M_ISBB_MEMBASE(a,b,c)   emit_alul_reg_membase(cd, ALU_SBB, (a), (b), (c))
+#define M_IADD_MEMBASE(a,b,c) _DEPR( M_IADD_MEMBASE(a,b,c) )
+#define M_IADC_MEMBASE(a,b,c) _DEPR( M_IADC_MEMBASE(a,b,c) )
+#define M_ISUB_MEMBASE(a,b,c) _DEPR( M_ISUB_MEMBASE(a,b,c) )
+#define M_ISBB_MEMBASE(a,b,c) _DEPR( M_ISBB_MEMBASE(a,b,c) )
 
-#define PROFILE_CYCLE_START
-#define __PROFILE_CYCLE_START \
-    do { \
-        if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \
-            M_PUSH(RAX); \
-            M_PUSH(RDX); \
-            \
-            M_MOV_IMM(code, REG_ITMP3); \
-            M_RDTSC; \
-            M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \
-            M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \
-            \
-            M_POP(RDX); \
-            M_POP(RAX); \
-        } \
-    } while (0)
+#define PROFILE_CYCLE_START _DEPR( PROFILE_CYCLE_START )
+#define __PROFILE_CYCLE_START _DEPR( __PROFILE_CYCLE_START )
 
-#define PROFILE_CYCLE_STOP 
-#define __PROFILE_CYCLE_STOP \
-    do { \
-        if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \
-            M_PUSH(RAX); \
-            M_PUSH(RDX); \
-            \
-            M_MOV_IMM(code, REG_ITMP3); \
-            M_RDTSC; \
-            M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \
-            M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \
-            \
-            M_POP(RDX); \
-            M_POP(RAX); \
-        } \
-    } while (0)
+#define PROFILE_CYCLE_STOP _DEPR( PROFILE_CYCLE_STOP )
+#define __PROFILE_CYCLE_STOP _DEPR( __PROFILE_CYCLE_STOP )
 
 
 /* function gen_resolvebranch **************************************************
index d9a3c1f3b3ee2a0ba25eb5b0a49504aaf568525f..40444916b1c1cf05e7dbdf7d7ea4e171c92d64c3 100644 (file)
 
    Authors: Christian Thalinger
 
-   $Id: emit.c 7219 2007-01-16 22:18:57Z pm $
+   $Id: emit.c 7283 2007-02-04 19:41:14Z pm $
 
 */
 
+#include <assert.h>
+
 #include "config.h"
 
 #include "vm/types.h"
@@ -105,55 +107,29 @@ __PORTED__ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg
     
 *******************************************************************************/
 
-inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
+__PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
-       codegendata  *cd;
-       s4            disp;
-#if 0
-       s4            s;
-       u2            opcode;
-#endif
+       codegendata *cd;
 
        /* get required compiler data */
 
        cd = jd->cd;
 
-#if 0
-       /* do we have to generate a conditional move? */
-
-       if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
-               /* the passed register d is actually the source register */
-
-               s = d;
-
-               /* Only pass the opcode to codegen_reg_of_var to get the real
-                  destination register. */
-
-               opcode = iptr->opc & ICMD_OPCODE_MASK;
-
-               /* get the real destination register */
-
-               d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
-
-               /* and emit the conditional move */
-
-               emit_cmovxx(cd, iptr, s, d);
-       }
-#endif
-
        if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
 
-               disp = dst->vv.regoff * 8;
-
                if (IS_FLT_DBL_TYPE(dst->type)) {
                        if (IS_2_WORD_TYPE(dst->type))
-                               M_DST(d, REG_SP, disp);
+                               M_DST(d, REG_SP, dst->vv.regoff * 4);
                        else
-                               M_FST(d, REG_SP, disp);
+                               M_FST(d, REG_SP, dst->vv.regoff * 4);
+               }
+               else {
+                       if (IS_2_WORD_TYPE(dst->type))
+                               M_LST(d, REG_SP, dst->vv.regoff * 4);
+                       else
+                               M_IST(d, REG_SP, dst->vv.regoff * 4);
                }
-               else
-                       M_LST(d, REG_SP, disp);
        }
 }
 
@@ -164,7 +140,7 @@ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 
 *******************************************************************************/
 
-void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
+__PORTED__ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 {
        codegendata  *cd;
        s4            s1, d;
@@ -400,6 +376,7 @@ void emit_patcher_stubs(jitdata *jd)
 
 void emit_replacement_stubs(jitdata *jd)
 {
+#if 0
        codegendata *cd;
        codeinfo    *code;
        rplpoint    *rplp;
@@ -438,6 +415,7 @@ void emit_replacement_stubs(jitdata *jd)
                M_MOV_IMM(asm_replacement_out, REG_ITMP3);
                M_JMP(REG_ITMP3);
        }
+#endif
 }
        
 
@@ -2222,6 +2200,105 @@ void emit_rdtsc(codegendata *cd)
        *(cd->mcodeptr++) = 0x31;
 }
 
+/* emit_load_high **************************************************************
+
+   Emits a possible load of the high 32-bits of an operand.
+
+*******************************************************************************/
+
+s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+       codegendata  *cd;
+       s4            disp;
+       s4            reg;
+
+       assert(src->type == TYPE_LNG);
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       if (IS_INMEMORY(src->flags)) {
+               COUNT_SPILLS;
+
+               disp = src->vv.regoff * 4;
+
+               M_ILD(tempreg, REG_SP, disp);
+
+               reg = tempreg;
+       }
+       else
+               reg = GET_HIGH_REG(src->vv.regoff);
+
+       return reg;
+}
+
+/* emit_load_low ***************************************************************
+
+   Emits a possible load of the low 32-bits of an operand.
+
+*******************************************************************************/
+
+s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+       codegendata  *cd;
+       s4            disp;
+       s4            reg;
+
+       assert(src->type == TYPE_LNG);
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       if (IS_INMEMORY(src->flags)) {
+               COUNT_SPILLS;
+
+               disp = src->vv.regoff * 4;
+
+               M_ILD(tempreg, REG_SP, disp + 4);
+
+               reg = tempreg;
+       }
+       else
+               reg = GET_LOW_REG(src->vv.regoff);
+
+       return reg;
+}
+
+/* emit_nullpointer_check ******************************************************
+
+   Emit a NullPointerException check.
+
+*******************************************************************************/
+
+__PORTED__ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(reg);
+               M_BEQ(0);
+               codegen_add_nullpointerexception_ref(cd);
+       }
+}
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+   Emit a ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
+{
+#if 0
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+        M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+        M_ICMP(REG_ITMP3, s2);
+        M_BAE(0);
+        codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+       }
+#endif
+}
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
index b2702665a61dfbb80cd10cca6c71b54dee3ea71e..752b65916423625a6eaba8f88ed8aed31eb383bf 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-abi.c 7219 2007-01-16 22:18:57Z pm $
+   $Id: md-abi.c 7283 2007-02-04 19:41:14Z pm $
 
 */
 
 /* register descripton array **************************************************/
 
 s4 nregdescint[] = {
-#if 0
-    REG_RET, REG_ARG, REG_ARG, REG_TMP, REG_RES, REG_SAV, REG_ARG, REG_ARG,
-    REG_ARG, REG_ARG, REG_RES, REG_RES, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
-#endif
-       REG_TMP, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV,
-       REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_TMP, REG_RES,
+       /*   r0,   itmp1,      a0,      a1,      a2,      a3,      a4,      s0, */
+       REG_TMP, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV,
+       /*   s1,      s2,      s3,      s4,   itmp2,    pv,  ra/itmp3,      sp */
+       REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_RES, REG_RES, REG_RES,
     REG_END
 };
 
 
 s4 nregdescfloat[] = {
-#if 0
-    REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
-    REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
-#endif
        REG_ARG, REG_TMP, REG_ARG, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP,
        REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
     REG_END
index 466cb68ce25e35e93eb56cb520777333b2135914..4067d1b0e77ed2a784c14ccceca940cb60da2514 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-abi.h 7219 2007-01-16 22:18:57Z pm $
+   $Id: md-abi.h 7283 2007-02-04 19:41:14Z pm $
 
 */
 
 #define REG_RESULT      R2       /* to deliver method results                 */
 #define REG_RESULT2     R3
 
-#define REG_ITMP1       R      /* temporary register                        */
-#define REG_ITMP2       R1       /* temporary register and method pointer     */
-#define REG_ITMP3       R14      /* temporary register                        */
+#define REG_ITMP1       R1      /* temporary register                        */
+#define REG_ITMP2       R12     /* temporary register and method pointer     */
+#define REG_ITMP3       R14     /* temporary register                        */
 
 #define REG_ITMP12_PACKED    PACK_REGS(REG_ITMP2, REG_ITMP1)
 #define REG_ITMP23_PACKED    PACK_REGS(REG_ITMP3, REG_ITMP2)
 #define REG_ITMP2_XPC   REG_ITMP2/* exception pc = temporary register 2       */
 
 #define REG_SP          R15      /* stack pointer                             */
+#define REG_RA          R14      /* same as itmp3 */
 
 #define REG_PV  R13
 
 
 
 #define INT_REG_CNT     16       /* number of integer registers               */
-#define INT_SAV_CNT     6        /* number of integer callee saved registers  */
+#define INT_SAV_CNT     5        /* number of integer callee saved registers  */
 #define INT_ARG_CNT     5        /* number of integer argument registers      */
-#define INT_TMP_CNT     3        /* number of integer temporary registers     */
-#define INT_RES_CNT     2        /* number of integer reserved registers      */
+#define INT_TMP_CNT     1        /* number of integer temporary registers     */
+#define INT_RES_CNT     5        /* number of integer reserved registers      */
 
 #define FLT_REG_CNT     16       /* number of float registers                 */
 #define FLT_SAV_CNT     2        /* number of float callee saved registers    */
index 0d673a2a24eb63b67ef45ffc8326fd625380ca82..a4e5adc360783816f00e26844f76542c20603c78 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-asm.h 7219 2007-01-16 22:18:57Z pm $
+   $Id: md-asm.h 7283 2007-02-04 19:41:14Z pm $
 
 */
 
 #define a4       %r6
 
 #define sp       %r15
-#define itmp1    %r0
-#define itmp2    %r1
+#define itmp1    %r1
+#define itmp2    %r12
 #define itmp3    %r14
 #define v0       %r2
 #define pv       %r13
 #define s2 %r9
 #define s3 %r10
 #define s4 %r11
-#define s5 %r12
 
 #define fa0 %f0
 #define fa1 %f2
index 949b1339172990a795b3dbd6bee5f9e895c995ab..2f23342d280445c873376d42fb6f3e4284cdaeb2 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: md.c 7219 2007-01-16 22:18:57Z pm $
+   $Id: md.c 7283 2007-02-04 19:41:14Z pm $
 
 */
 
@@ -71,6 +71,8 @@
 #include "vm/jit/disass.h" /* XXX debug */
 #endif
 
+#include <assert.h>
+#define OOPS() assert(0);
 
 /* md_init *********************************************************************
 
@@ -209,6 +211,7 @@ void thread_restartcriticalsection(ucontext_t *_uc)
 
 void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
 {
+
        s4 *mcodeptr;
        s4  disp;                           /* branch displacement                */
 
@@ -219,13 +222,14 @@ void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
        /* Calculate the branch displacement. */
 
        disp = targetmpc - branchmpc;
+       disp += 4; /* size of branch */
+       disp /= 2; /* specified in halfwords */
 
-       /* I don't think we have to check for branch-displacement
-          overflow.  +/-2GB should be enough. */
+       /* TODO check for overflow */
 
        /* patch the branch instruction before the mcodeptr */
 
-       mcodeptr[-1] = disp;
+       mcodeptr[-1] |= (disp & 0xFFFF);
 }
 
 
@@ -240,9 +244,10 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 {
        u1 *ra;
 
-       /* on x86_64 the return address is above the current stack frame */
+       /* on S390 the return address is located on the top of the stackframe */
+       /* TODO is this true? hope so, copyed from alpha */
 
-       ra = *((u1 **) (sp + framesize));
+       ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P));
 
        return ra;
 }
@@ -256,68 +261,68 @@ u1 *md_stacktrace_get_returnaddress(u1 *sp, u4 framesize)
 
    INVOKESTATIC/SPECIAL:
 
-   4d 8b 15 e2 fe ff ff             mov    -286(%rip),%r10
-   49 ff d2                         rex64Z callq  *%r10
+0x7748d7b2:   a7 18 ff d4                      lhi      %r1,-44  
+(load dseg offset)
+0x7748d7b6:   58 d1 d0 00                      l        %r13,0(%r1,%r13)
+(load pv)
+0x7748d7ba:   0d ed                            basr     %r14,%r13
+(jump to pv)
 
    INVOKEVIRTUAL:
 
-   4c 8b 17                         mov    (%rdi),%r10
-   49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
-   48 ff d3                         rex64 callq  *%rax
+0x7748d82a:   58 c0 20 00                      l        %r12,0(%r2)
+(load mptr)
+0x7748d82e:   58 d0 c0 00                      l        %r13,0(%r12)
+(load pv from mptr)
+0x7748d832:   0d ed                            basr     %r14,%r13
+(jump to pv)
+
 
    INVOKEINTERFACE:
 
-   4c 8b 17                         mov    (%rdi),%r10
-   4d 8b 92 00 00 00 00             mov    0x0(%r10),%r10
-   49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
-   48 ff d3                         rex64 callq  *%r11
+last 2 instructions the same as in invokevirtual
 
 *******************************************************************************/
 
 u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
 {
-       u1  mcode;
+       u1  base;
        s4  offset;
        u1 *pa;                             /* patch address                      */
 
-       /* go back to the actual call instruction (3-bytes) */
+       /* go back to the load before the call instruction */
 
-       ra = ra - 3;
+       ra = ra - 2 /* sizeof bcr */ - 4 /* sizeof l */;
 
-       /* get the last byte of the call */
+       /* get the base register of the load */
 
-       mcode = ra[2];
+       base = ra[2] >> 4;
 
        /* check for the different calls */
 
-       if (mcode == 0xd2) {
+       if (base == 0xd) { /* pv relative */
                /* INVOKESTATIC/SPECIAL */
 
-               /* Get the offset from the instruction (the offset address is
-                  4-bytes before the call instruction). */
+               /* the offset is in the load before the load */
 
-               offset = *((s4 *) (ra - 4));
+               offset = *((s2 *) (ra - 2));
 
-               /* add the offset to the return address (IP-relative addressing) */
+               /* add the offset to the procedure vector */
 
-               pa = ra + offset;
+               pa = sfi->pv + offset;
        }
-       else if (mcode == 0xd3) {
+       else if (base == 0xc) { /* mptr relative */
                /* INVOKEVIRTUAL/INTERFACE */
 
-               /* Get the offset from the instruction (the offset address is
-                  4-bytes before the call instruction). */
-
-               offset = *((s4 *) (ra - 4));
-
-               /* add the offset to the method pointer */
+               offset = *((u2 *)(ra + 2)) & 0xFFF;
 
+               /* add offset to method pointer */
+               
                pa = mptr + offset;
        }
        else {
                /* catch any problems */
-
-               assert(0);
+               assert(0); 
        }
 
        return pa;
@@ -386,7 +391,7 @@ void md_dcacheflush(u1 *addr, s4 nbytes)
    Patch the given replacement point.
 
 *******************************************************************************/
-
+#if 0
 void md_patch_replacement_point(rplpoint *rp)
 {
     u8 mcode;
@@ -418,7 +423,7 @@ void md_patch_replacement_point(rplpoint *rp)
                        
     /* XXX if required asm_cacheflush(rp->pc,8); */
 }
-
+#endif
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where