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