Exemple #1
0
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;
			}
		}
	}
}
Exemple #2
0
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;
	}
}
Exemple #3
0
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;
}