Fix type/r/r2 confusion differently

on i386 111_conversion.c breaks when save_reg_upstack isn't careful
about r2 and type mismatches.  The bcheck patches fixed this by
enlarging the stack slot beyond the natural type, this variant simply
avoids saving the second register is the type indicates that it isn't
needed.

Adds also a comment how this should ideally work, namely that type
and r/r2 entries in the vstack are consistent.  In the 111_conversion
testcase it's specifically gen_cast via gen_cvt_ftoi that breaks
this, but there more general code broken as well, so that would deserve
a careful fixup based on some additional asserts.
This commit is contained in:
Michael Matz 2019-12-10 17:49:04 +01:00
parent ac2a61d1b3
commit fb22e0c12d

View File

@ -1193,10 +1193,6 @@ ST_FUNC void save_reg_upstack(int r, int n)
type = &int_type;
#endif
size = type_size(type, &align);
if ((p->r2 & VT_VALMASK) < VT_CONST) {
size *= 2;
align *= 2;
}
l=get_temp_local_var(size,align);
sv.type.t = type->t;
sv.r = VT_LOCAL | VT_LVAL;
@ -1208,8 +1204,11 @@ ST_FUNC void save_reg_upstack(int r, int n)
o(0xd8dd); /* fstp %st(0) */
}
#endif
/* special long long case */
if ((p->r2 & VT_VALMASK) < VT_CONST) {
/* special long long case. Ideally r2 would always
be VT_CONST is the type is smaller than a double-word
type. Not all routines (e.g. gen_cast with _ftoi) are
careful to clear r2, though. */
if ((p->r2 & VT_VALMASK) < VT_CONST && size > PTR_SIZE) {
sv.c.i += PTR_SIZE;
store(p->r2, &sv);
}