Unified variables changes for common/i386.
[cacao.git] / src / vm / jit / i386 / emit.c
index 3051bb41cc94e1886543b009b86e52af62967cdb..fbc38dcb7de51c62cb7410e05a5080293560eb85 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: emit.c 5320 2006-09-05 16:10:21Z twisti $
+   $Id: emit.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
 #include "vm/jit/replace.h"
 
 
-/* emit_load_s1 ****************************************************************
+/* emit_load ******************************************************************
 
-   Emits a possible load of the first source operand.
+   Emits a possible load of an operand.
 
 *******************************************************************************/
 
-s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -72,7 +72,7 @@ s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
        cd = jd->cd;
 
-       if (src->flags & INMEMORY) {
+       if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
                disp = src->regoff * 4;
@@ -99,56 +99,48 @@ s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 }
 
 
-/* emit_load_s2 ****************************************************************
+/* emit_load_low ************************************************************
 
-   Emits a possible load of the second source operand.
+   Emits a possible load of the low 32-bits of an operand.
 
 *******************************************************************************/
 
-s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline 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 (src->flags & INMEMORY) {
+
+       if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
                disp = src->regoff * 4;
 
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-               }
-               else {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_LLD(tempreg, REG_SP, disp);
-                       else
-                               M_ILD(tempreg, REG_SP, disp);
-               }
+               M_ILD(tempreg, REG_SP, disp);
 
                reg = tempreg;
        }
        else
-               reg = src->regoff;
+               reg = GET_LOW_REG(src->regoff);
 
        return reg;
 }
 
 
-/* emit_load_s3 ****************************************************************
+/* emit_load_high ***********************************************************
 
-   Emits a possible load of the third source operand.
+   Emits a possible load of the high 32-bits of an operand.
 
 *******************************************************************************/
 
-s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline s4 emit_load_high(jitdata *jd, instruction *iptr,varinfo *src,s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -156,100 +148,131 @@ s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
        /* get required compiler data */
 
+       assert(src->type == TYPE_LNG);
+
        cd = jd->cd;
 
-       if (src->flags & INMEMORY) {
+       if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
                disp = src->regoff * 4;
 
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-               }
-               else {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_LLD(tempreg, REG_SP, disp);
-                       else
-                               M_ILD(tempreg, REG_SP, disp);
-               }
+               M_ILD(tempreg, REG_SP, disp + 4);
 
                reg = tempreg;
        }
        else
-               reg = src->regoff;
+               reg = GET_HIGH_REG(src->regoff);
 
        return reg;
 }
 
 
-/* emit_load_s1_low ************************************************************
+/* emit_load_s1 ****************************************************************
 
-   Emits a possible load of the low 32-bits of the first long source
-   operand.
+   Emits a possible load of the first source operand.
 
 *******************************************************************************/
 
-s4 emit_load_s1_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       codegendata  *cd;
-       s4            disp;
+       varinfo       *src;
        s4            reg;
 
-       assert(src->type == TYPE_LNG);
+       /* get required compiler data */
+
+       src = &(jd->var[iptr->s1.varindex]);
+
+       reg = emit_load(jd, iptr, src, tempreg);
+   
+       return reg;
+}
+
+
+/* emit_load_s2 ****************************************************************
+
+   Emits a possible load of the second source operand.
+
+*******************************************************************************/
+
+s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
+{
+       varinfo       *src;
+       s4            reg;
 
        /* get required compiler data */
 
-       cd = jd->cd;
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
 
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
+       reg = emit_load(jd, iptr, src, tempreg);
+       
+       return reg;
+}
 
-               disp = src->regoff * 4;
 
-               M_ILD(tempreg, REG_SP, disp);
+/* emit_load_s3 ****************************************************************
 
-               reg = tempreg;
-       }
-       else
-               reg = GET_LOW_REG(src->regoff);
+   Emits a possible load of the third source operand.
+
+*******************************************************************************/
+
+s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
+{
+       varinfo       *src;
+       s4            reg;
+
+       /* get required compiler data */
+
+       src = &(jd->var[iptr->sx.s23.s3.varindex]);
+
+       reg = emit_load(jd, iptr, src, tempreg);
 
        return reg;
 }
 
 
-/* emit_load_s2_low ************************************************************
+/* emit_load_s1_low ************************************************************
 
-   Emits a possible load of the low 32-bits of the second long source
+   Emits a possible load of the low 32-bits of the first long source
    operand.
 
 *******************************************************************************/
 
-s4 emit_load_s2_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       codegendata  *cd;
-       s4            disp;
+       varinfo       *src;
        s4            reg;
 
-       assert(src->type == TYPE_LNG);
 
        /* get required compiler data */
 
-       cd = jd->cd;
+       src = &(jd->var[iptr->s1.varindex]);
 
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
+       reg = emit_load_low(jd, iptr, src, tempreg);
 
-               disp = src->regoff * 4;
+       return reg;
+}
 
-               M_ILD(tempreg, REG_SP, disp);
 
-               reg = tempreg;
-       }
-       else
-               reg = GET_LOW_REG(src->regoff);
+
+
+/* emit_load_s2_low ************************************************************
+
+   Emits a possible load of the low 32-bits of the second long source
+   operand.
+
+*******************************************************************************/
+
+s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
+{
+       varinfo       *src;
+       s4            reg;
+
+       /* get required compiler data */
+
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
+
+       reg = emit_load_low(jd, iptr, src, tempreg);
 
        return reg;
 }
@@ -262,29 +285,16 @@ s4 emit_load_s2_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
 *******************************************************************************/
 
-s4 emit_load_s1_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       codegendata  *cd;
-       s4            disp;
+       varinfo       *src;
        s4            reg;
 
-       assert(src->type == TYPE_LNG);
-
        /* get required compiler data */
 
-       cd = jd->cd;
-
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
-
-               disp = src->regoff * 4;
+       src = &(jd->var[iptr->s1.varindex]);
 
-               M_ILD(tempreg, REG_SP, disp + 4);
-
-               reg = tempreg;
-       }
-       else
-               reg = GET_HIGH_REG(src->regoff);
+       reg = emit_load_high(jd, iptr, src, tempreg);
 
        return reg;
 }
@@ -297,28 +307,16 @@ s4 emit_load_s1_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
 *******************************************************************************/
 
-s4 emit_load_s2_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       codegendata  *cd;
-       s4            disp;
+       varinfo       *src;
        s4            reg;
 
-       assert(src->type == TYPE_LNG);
-
        /* get required compiler data */
 
-       cd = jd->cd;
-
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
 
-               disp = src->regoff * 4;
-
-               M_ILD(tempreg, REG_SP, disp + 4);
-
-               reg = tempreg;
-       } else
-               reg = GET_HIGH_REG(src->regoff);
+       reg = emit_load_high(jd, iptr, src, tempreg);
 
        return reg;
 }
@@ -330,7 +328,7 @@ s4 emit_load_s2_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
 *******************************************************************************/
 
-void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -338,7 +336,7 @@ void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
        cd = jd->cd;
 
-       if (dst->flags & INMEMORY) {
+       if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
 
                if (IS_FLT_DBL_TYPE(dst->type)) {
@@ -364,7 +362,7 @@ void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
 *******************************************************************************/
 
-void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -374,7 +372,7 @@ void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
        cd = jd->cd;
 
-       if (dst->flags & INMEMORY) {
+       if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
                M_IST(GET_LOW_REG(d), REG_SP, dst->regoff * 4);
        }
@@ -388,7 +386,7 @@ void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
 *******************************************************************************/
 
-void emit_store_high(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -398,38 +396,69 @@ void emit_store_high(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
        cd = jd->cd;
 
-       if (dst->flags & INMEMORY) {
+       if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
                M_IST(GET_HIGH_REG(d), REG_SP, dst->regoff * 4 + 4);
        }
 }
 
+/* emit_store_dst **************************************************************
+
+   This function generates the code to store the result of an
+   operation back into a spilled pseudo-variable.  If the
+   pseudo-variable has not been spilled in the first place, this
+   function will generate nothing.
+    
+*******************************************************************************/
+
+void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
+{
+       varinfo *dst;
+       
+       dst = &(jd->var[iptr->dst.varindex]);
+
+       emit_store(jd, iptr, dst, d);
+}
+
 
 /* emit_copy *******************************************************************
 
-   XXX
+   Generates a register/memory to register/memory copy.
 
 *******************************************************************************/
 
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
+void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 {
        codegendata  *cd;
-       registerdata *rd;
        s4            s1, d;
 
        /* get required compiler data */
 
        cd = jd->cd;
-       rd = jd->rd;
 
        if ((src->regoff != dst->regoff) ||
                ((src->flags ^ dst->flags) & INMEMORY)) {
-               if (IS_LNG_TYPE(src->type))
-                       d = codegen_reg_of_var(rd, iptr->opc, dst, REG_ITMP12_PACKED);
-               else
-                       d = codegen_reg_of_var(rd, iptr->opc, dst, REG_ITMP1);
 
-               s1 = emit_load_s1(jd, iptr, src, d);
+               /* If one of the variables resides in memory, we can eliminate
+                  the register move from/to the temporary register with the
+                  order of getting the destination register and the load. */
+
+               if (IS_INMEMORY(src->flags)) {
+                       if (IS_LNG_TYPE(src->type))
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
+                       else
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP1);
+
+                       s1 = emit_load(jd, iptr, src, d);
+               }
+               else {
+                       if (IS_LNG_TYPE(src->type))
+                               s1 = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
+                       else
+                               s1 = emit_load(jd, iptr, src, REG_ITMP1);
+
+                       d = codegen_reg_of_var(iptr->opc, dst, s1);
+               }
 
                if (s1 != d) {
                        if (IS_FLT_DBL_TYPE(src->type)) {