Qing Zhao <qing.z...@oracle.com> writes:
>> On Sep 25, 2020, at 10:28 AM, Richard Sandiford <richard.sandif...@arm.com> 
>> wrote:
>> 
>> Qing Zhao <qing.z...@oracle.com <mailto:qing.z...@oracle.com>> writes:
>>>> On Sep 25, 2020, at 7:53 AM, Richard Sandiford <richard.sandif...@arm.com> 
>>>> wrote:
>>>> 
>>>> Qing Zhao <qing.z...@oracle.com> writes:
>>>>> Hi, Richard,
>>>>> 
>>>>> As you suggested, I added a default implementation of the target hook 
>>>>> “zero_cal_used_regs (HARD_REG_SET)” as following in my latest patch
>>>>> 
>>>>> 
>>>>> /* The default hook for TARGET_ZERO_CALL_USED_REGS.  */
>>>>> 
>>>>> void
>>>>> default_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
>>>> 
>>>> FWIW, I was suggesting to return the set of registers that are actually
>>>> cleared too.  Here you have the hook emit the asm statement, but IMO the
>>>> way we generate the asm for a given set of registers should be entirely
>>>> target-independent, and happen outside the hook.
>>>> 
>>>> So the hook returning the set of cleared registers does two things:
>>>> 
>>>> (1) It indicates which registers should be clobbered by the asm
>>>>   (which would be generated after calling the hook, but emitted
>>>>   before the sequence of instructions generated by the hook).
>>> 
>>> For this purpose, this hook should return a Set of RTX that hold the 
>>> cleared registers, a HARD_REG_SET is not enough.
>>> 
>>> Since in the ASM_OPERANDS, we will need the RTX for the register (not the 
>>> REGNO).
>>> 
>>> Which data structure in GCC should be used here to hold this returned value 
>>> as Set of RTX ?
>> 
>> A HARD_REG_SET is enough.  All the caller needs to know is: which registers
>> were clobbered?  It can then represent a clobber of R with a clobber of
>> reg_regno_rtx[R].
>
> I did not find reg_regno_rtx in the current gcc source, not sure how to use 
> it?

Sorry, I misremembered the name, it's regno_reg_rtx (which makes
more sense than what I wrote).

>> 
>> The mode isn't important for single-register clobbers: clobbering a single
>> register in one mode is equivalent to clobbering it in another mode.
>> None of the register contents survive the clobber.
>
> Okay, I see.
>
> Then is the following good enough:
>
> /* Generate asm volatile("" : : : "memory") as a memory blockage, at the 
>    same time clobbering the register set  specified by ZEROED_REGS.  */
>
> void
> expand_asm_memory_blockage_clobber_regs (HARD_REG_SET zeroed_regs)
> {
>   rtx asm_op, clob_mem, clob_reg;
>
>   /* first get the number of registers that have been zeroed from ZEROED_REGS 
> set.  */
>   unsigned int  num_of_regs = ….;
>
>   asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
>                                  rtvec_alloc (0), rtvec_alloc (0),
>                                  rtvec_alloc (0), UNKNOWN_LOCATION);
>   MEM_VOLATILE_P (asm_op) = 1;
>
>   rtvec v = rtvec_alloc (num_of_regs + 2);
>
>   clob_mem = gen_rtx_SCRATCH (VOIDmode);
>   clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
>   clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);
>
>   RTVEC_ELT (v,0) = asm_op;
>   RTVEC_ELT (v,1) = clob_mem;
>
>   for (unsigned int I = 0; i < FIRST_PSEUDO_REGISTER; i++)
>     If (TEST_HARD_REG_BIT (zeroed_regs, i))
>       {
>         clob_reg  = gen_rtx_CLOBBER (VOIDmode, reg_regno_rtx[i]);
>         RTVEC_ELT (v,i+2) = clob_reg;
>       }
>   
>   emit_insn (gen_rtx_PARALLEL (VOIDmode, v));                              
> }

Yeah, looks like it should work.

Thanks,
Richard

Reply via email to