On Fri, 2022-03-11 at 16:08 +0000, Qing Zhao wrote: > Why there is “mthi $0” instruction, but there is NO emit_move_insn(HI, > CONST_0)? > Is such mismatch a bug? If not, why? > > > In theory it's possible > > to emit the mthi instruction explicitly here though, but we'll need to > > clear something NOT in need_zeroed_hardregs for MIPS anyway (see below). > > One question here, is there situation when only HI is cleared but LO is not > cleared?
No, if I interpret the document of -fzero_call_used_regs and attribute((zero_call_used_regs(...))) correctly. A 2-reg multiplication (or division) always set the value of both HI and LO. Richard has added a comment for this in mips.cc: > 12868 /* After a multiplication or division, clobbering HI makes > 1 the value of LO unpredictable, and vice versa. This means > 2 that, for all interesting cases, HI and LO are effectively > 3 a single register. > 4 > 5 We model this by requiring that any value that uses HI > 6 also uses LO. */ This is also why the handling of emit_move_insn(HI, CONST_0) was removed, I guess (the removal happened in the same commit adding this comment). > > > > Okay, I see. So, each ST_REGi register is a 1-bit pseudo register? > But physically each of them is 1-bit in a physical register? Yes. > > > > Because there is no elegant way to clear one specific FCC bit in MIPS. > > A "ctc1 $0, $25" instruction will zero them altogether. If we really > > need to clear only one of them (let's say ST_REG3), we'll have to emit > > something like > > > > mtc1 $0, $0 # zero FPR0 to ensure it won't contain sNaN > > c.f.s $3, $0, $0 > > > > Then we'll still need to clobber FPR0 with zero. So anyway we'll have > > to clear some registers not specified in need_zeroed_hardregs. > > So, “c.f.s” instruction can be used to clear ONLY one specific FCC bit? > But you have to clear one FPR (floating pointer register?) first to avoid > raising exception? > My question here is: is there a case when only FCC need to be cleared but no > FPR need to be cleared? Yes, for example: double a, b; struct x { double a, b; }; struct x f(void) { struct x x = { .a = a, .b = b }; if (a < b) x.a = x.b; return x; } It does not need to zero the two FPRs, as they contain the return value. But a FCC bit needs to be cleared. > If NOT, then we can always pick one FPRi before c.f.s to avoid the > issue you mentioned (We’ll have to clear some registers not specified > in need_zeroed_hardregs). I'm now thinking: is there always at least one *GPR* which need to be cleared? If it's true, let's say GPR $12, and fcc0 & fcc2 needs to be cleared, we can use something like: cfc1 $12, $25 andi $25, 5 ctc1 $12, $25 move $12, $0 > > And the question is: is it really allowed to return something other than > > a subset of need_zeroed_hardregs for a TARGET_ZERO_CALL_USED_REGS hook? > > Although currently there is no assertion added to force this > requirement, I still think that we should keep it. > > The “need_zeroed_hardregs” is computed based on > > 1. User’s request from command line option; > 2. Data flow info of the routine; > 3. Abi info of the target; > > If zero_call_used_regs target hook return registers out of > “need_zeroed_hardregs” set, then it might out of the user’s exception, > it should be considered as a bug, I think. I have the same concern. But now I'm too sleepy... Will try to improve this tomorrow. -- Xi Ruoyao <xry...@mengyan1223.wang> School of Aerospace Science and Technology, Xidian University