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

Reply via email to