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
Unified · Split
| @@ -4984,6 +4984,9 @@ int gv(int rc) · 4983 unmodified lines | |||
| 4984 | #endif | 4984 | #endif |
| 4985 | 4985 | ||
| 4986 | r = vtop->r & VT_VALMASK; | 4986 | r = vtop->r & VT_VALMASK; |
| 4987 | rc2 = RC_INT; | ||
| 4988 | if (rc == RC_IRET) | ||
| 4989 | rc2 = RC_LRET; | ||
| 4987 | /* need to reload if: | 4990 | /* need to reload if: |
| 4988 | - constant | 4991 | - constant |
| 4989 | - lvalue (need to dereference pointer) | 4992 | - lvalue (need to dereference pointer) |
| @@ -4992,7 +4995,7 @@ int gv(int rc) · 2 unmodified lines | |||
| 4992 | (vtop->r & VT_LVAL) || | 4995 | (vtop->r & VT_LVAL) || |
| 4993 | !(reg_classes[r] & rc) || | 4996 | !(reg_classes[r] & rc) || |
| 4994 | ((vtop->type.t & VT_BTYPE) == VT_LLONG && | 4997 | ((vtop->type.t & VT_BTYPE) == VT_LLONG && |
| 4995 | !(reg_classes[vtop->r2] & rc))) { | 4998 | !(reg_classes[vtop->r2] & rc2))) { |
| 4996 | r = get_reg(rc); | 4999 | r = get_reg(rc); |
| 4997 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { | 5000 | if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { |
| 4998 | /* two register type load : expand to two words | 5001 | /* two register type load : expand to two words |
| @@ -5029,9 +5032,6 @@ int gv(int rc) · 30 unmodified lines | |||
| 5029 | vtop->r = vtop[-1].r2; | 5032 | vtop->r = vtop[-1].r2; |
| 5030 | } | 5033 | } |
| 5031 | /* allocate second register */ | 5034 | /* allocate second register */ |
| 5032 | rc2 = RC_INT; | ||
| 5033 | if (rc == RC_IRET) | ||
| 5034 | rc2 = RC_LRET; | ||
| 5035 | r2 = get_reg(rc2); | 5035 | r2 = get_reg(rc2); |
| 5036 | load(r2, vtop); | 5036 | load(r2, vtop); |
| 5037 | vpop(); | 5037 | vpop(); |