void md_return_alloc(jitdata *jd, stackptr stackslot) { methodinfo *m; registerdata *rd; methoddesc *md; /* get required compiler data */ m = jd->m; rd = jd->rd; md = m->parseddesc; /* In Leafmethods Local Vars holding parameters are precolored to their argument register -> so leafmethods with paramcount > 0 could already use R3 == a00! */ if (!jd->isleafmethod || (md->paramcount == 0)) { /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has not to survive method invokations. */ if (!(stackslot->flags & SAVEDVAR)) { VAR(stackslot->varnum)->flags = PREALLOC; if (IS_INT_LNG_TYPE(md->returntype.type)) { if (!IS_2_WORD_TYPE(md->returntype.type)) { if (rd->argintreguse < 1) rd->argintreguse = 1; VAR(stackslot->varnum)->vv.regoff = REG_RESULT; } else { if (rd->argintreguse < 2) rd->argintreguse = 2; VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED; } } else { if (rd->argfltreguse < 1) rd->argfltreguse = 1; VAR(stackslot->varnum)->vv.regoff = REG_FRESULT; } } } }
void md_return_alloc(jitdata *jd, stackelement_t *stackslot) { methodinfo *m; methoddesc *md; /* get required compiler data */ m = jd->m; md = m->parseddesc; /* Only precolor the stackslot, if it is not a SAVEDVAR <-> has not to survive method invokations. */ if (!(stackslot->flags & SAVEDVAR)) { VAR(stackslot->varnum)->flags = PREALLOC; if (IS_INT_LNG_TYPE(md->returntype.type)) VAR(stackslot->varnum)->vv.regoff = REG_RESULT; else VAR(stackslot->varnum)->vv.regoff = REG_FRESULT; } }
void md_param_alloc(methoddesc *md) { paramdesc *pd; s4 i; s4 iarg; s4 farg; s4 stacksize; /* set default values */ iarg = 0; farg = 0; stacksize = LA_SIZE_IN_POINTERS; /* get params field of methoddesc */ pd = md->params; for (i = 0; i < md->paramcount; i++, pd++) { switch (md->paramtypes[i].type) { case TYPE_INT: case TYPE_ADR: if (iarg < INT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_integer_argument[iarg]; iarg++; } else { pd->inmemory = true; pd->regoff = stacksize; stacksize++; } break; case TYPE_LNG: if (iarg < INT_ARG_CNT - 1) { _ALIGN(iarg); pd->inmemory = false; pd->regoff = PACK_REGS(abi_registers_integer_argument[iarg + 1], abi_registers_integer_argument[iarg]); iarg += 2; } else { _ALIGN(stacksize); pd->inmemory = true; pd->regoff = stacksize; iarg = INT_ARG_CNT; stacksize += 2; } break; case TYPE_FLT: if (farg < FLT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_float_argument[farg]; farg++; } else { pd->inmemory = true; pd->regoff = stacksize; stacksize++; } break; case TYPE_DBL: if (farg < FLT_ARG_CNT) { pd->inmemory = false; pd->regoff = abi_registers_float_argument[farg]; farg++; } else { _ALIGN(stacksize); pd->inmemory = true; pd->regoff = stacksize; stacksize += 2; } break; default: assert(0); } } /* Since R3/R4, F1 (==A0/A1, A0) are used for passing return values, this argument register usage has to be regarded, too. */ if (IS_INT_LNG_TYPE(md->returntype.type)) { if (iarg < (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1)) iarg = IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1; } else { if (IS_FLT_DBL_TYPE(md->returntype.type)) if (farg < 1) farg = 1; } /* fill register and stack usage */ md->argintreguse = iarg; md->argfltreguse = farg; md->memuse = stacksize; }