Grishka and Daniel, please see below. Here is the patch (see attached file).
So the thing is during gv() on a long long on i386 at some point the vstack contains at the top 2 values like this: vtop register r contains the address of the value to load register r2 can contain anything (can be a valid register) vtop-1 register r contains the most significant bits of the value register r2 can contain anything (same value as in vtop) get_reg tries first to free r before r2 so if r2 is a valid register, get_reg will try to free a register and the first one it will find to free is the register r of vtop-1 which leads to the bug. It's possible in gv to ignore how get_reg works but that requires a for loop to retry until get_reg returns 2 differents registers. The other solution is to ensure that get_reg tries r2 first, which is what the patch does. Grishka and Daniel, do you know any place in the code which could rely on the previous behavior of get_reg()? If yes please revert the commit d1694f7d7e6d96f64d1330c9b43491b613272b1e. Best regards, Thomas Preud'homme
diff --git a/tccgen.c b/tccgen.c index d27bdba..e27590c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -589,11 +589,11 @@ ST_FUNC int get_reg(int rc) IMPORTANT to start from the bottom to ensure that we don't spill registers used in gen_opi()) */ for(p=vstack;p<=vtop;p++) { - r = p->r & VT_VALMASK; + /* look at second register (if long long) */ + r = p->r2 & VT_VALMASK; if (r < VT_CONST && (reg_classes[r] & rc)) goto save_found; - /* also look at second register (if long long) */ - r = p->r2 & VT_VALMASK; + r = p->r & VT_VALMASK; if (r < VT_CONST && (reg_classes[r] & rc)) { save_found: save_reg(r);
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel