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;
cd = jd->cd;
- if (src->flags & INMEMORY) {
+ if (IS_INMEMORY(src->flags)) {
COUNT_SPILLS;
disp = src->regoff * 4;
}
-/* 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;
/* 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;
}
*******************************************************************************/
-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;
}
*******************************************************************************/
-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;
}
*******************************************************************************/
-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;
cd = jd->cd;
- if (dst->flags & INMEMORY) {
+ if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
if (IS_FLT_DBL_TYPE(dst->type)) {
*******************************************************************************/
-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;
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);
}
*******************************************************************************/
-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;
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)) {