memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 5233 2006-08-14 10:59:39Z twisti $
+ $Id: codegen-common.c 5703 2006-10-05 20:21:04Z edwin $
*/
#include "vm/jit/stacktrace.h"
#include "vm/jit/replace.h"
+#if defined(ENABLE_INTRP)
+#include "vm/jit/intrp/intrp.h"
+#endif
+
/* in this tree we store all method addresses *********************************/
*******************************************************************************/
-s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
+inline s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
{
- varinfo *var;
#if 0
/* Do we have to generate a conditional move? Yes, then always
return tempregnum;
#endif
- switch (v->varkind) {
- case TEMPVAR:
- if (!(v->flags & INMEMORY))
- return(v->regoff);
- break;
-
- case STACKVAR:
- var = &(rd->interfaces[v->varnum][v->type]);
- v->regoff = var->regoff;
- if (!(var->flags & INMEMORY))
- return(var->regoff);
- break;
-
- case LOCALVAR:
- var = &(rd->locals[v->varnum][v->type]);
- v->regoff = var->regoff;
- if (!(var->flags & INMEMORY)) {
+ if (!(v->flags & INMEMORY)) {
#if defined(__ARM__) && defined(__ARMEL__)
- if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(var->regoff) == REG_SPLIT))
- return(PACK_REGS(GET_LOW_REG(var->regoff), GET_HIGH_REG(tempregnum)));
+ if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->vv.regoff) == REG_SPLIT))
+ return PACK_REGS(GET_LOW_REG(v->vv.regoff),
+ GET_HIGH_REG(tempregnum));
#endif
#if defined(__ARM__) && defined(__ARMEB__)
- if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(var->regoff) == REG_SPLIT))
- return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(var->regoff)));
-#endif
- return(var->regoff);
- }
- break;
-
- case ARGVAR:
- if (!(v->flags & INMEMORY)) {
-#if defined(__ARM__) && defined(__ARMEL__)
- if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->regoff) == REG_SPLIT))
- return(PACK_REGS(GET_LOW_REG(v->regoff), GET_HIGH_REG(tempregnum)));
+ if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->vv.regoff) == REG_SPLIT))
+ return PACK_REGS(GET_LOW_REG(tempregnum),
+ GET_HIGH_REG(v->vv.regoff));
#endif
-#if defined(__ARM__) && defined(__ARMEB__)
- if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->regoff) == REG_SPLIT))
- return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(v->regoff)));
-#endif
- return(v->regoff);
- }
- break;
+ return v->vv.regoff;
}
#if defined(ENABLE_STATISTICS)
count_spills_read++;
#endif
- v->flags |= INMEMORY;
-
return tempregnum;
}
+/* codegen_reg_of_dst **********************************************************
+
+ This function determines a register, to which the result of an
+ operation should go, when it is ultimatively intended to store the
+ result in iptr->dst.var. If dst.var is assigned to an actual
+ register, this register will be returned. Otherwise (when it is
+ spilled) this function returns tempregnum. If not already done,
+ regoff and flags are set in the stack location.
+
+ On ARM we have to check if a long/double variable is splitted
+ across reg/stack (HIGH_REG == REG_SPLIT). We return the actual
+ register of dst.var for LOW_REG and the tempregnum for HIGH_REG in such
+ cases. (michi 2005/07/24)
+
+*******************************************************************************/
+
+s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
+{
+ return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
+}
+
#if defined(ENABLE_THREADS)
void codegen_threadcritrestart(codegendata *cd, int offset)