Fix gv for long longs

long long a();
long long b() {
  return a();
}

At the end of b there will be some useless register shuffling.
This is because return wants to have the result of a in REG_IRET.
gv checks if this is the case for BOTH registers of the long long.
After this test it uses REG_LRET for the second register if the
first is supposed to be REG_IRET. In other cases it uses RC_INT.

The patch compares the second register against the class it will
have in the end instead of the register class the first register
will have.

At this point I would like to remind those who pick up the patches
that there are two other mails by me with uncommitted fixes:
http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html
http://lists.gnu.org/archive/html/tinycc-devel/2008-08/msg00007.html

  Daniel
This commit is contained in:
Daniel Glöckner 2008-09-05 21:08:48 +02:00 committed by grischka
parent 15e0dc08a6
commit e263ee3cbf

8
tcc.c
View File

@ -4984,6 +4984,9 @@ int gv(int rc)
#endif
r = vtop->r & VT_VALMASK;
rc2 = RC_INT;
if (rc == RC_IRET)
rc2 = RC_LRET;
/* need to reload if:
- constant
- lvalue (need to dereference pointer)
@ -4992,7 +4995,7 @@ int gv(int rc)
(vtop->r & VT_LVAL) ||
!(reg_classes[r] & rc) ||
((vtop->type.t & VT_BTYPE) == VT_LLONG &&
!(reg_classes[vtop->r2] & rc))) {
!(reg_classes[vtop->r2] & rc2))) {
r = get_reg(rc);
if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
/* two register type load : expand to two words
@ -5029,9 +5032,6 @@ int gv(int rc)
vtop->r = vtop[-1].r2;
}
/* allocate second register */
rc2 = RC_INT;
if (rc == RC_IRET)
rc2 = RC_LRET;
r2 = get_reg(rc2);
load(r2, vtop);
vpop();