"H.J. Lu" <[email protected]> writes: > On Wed, May 13, 2026 at 7:11 PM Richard Sandiford > <[email protected]> wrote: >> >> "H.J. Lu" <[email protected]> writes: >> > Implement TARGET_FNTYPE_ABI to avoid spills of callee-saved registers >> > when calling functions with no_caller_saved_registers attribute. >> > >> > 1. For functions with no_callee_saved_registers attribute, frame register >> > is preserved to mitigate PR target/114116. MMX and x87 registers aren't >> > clobbered if MMX and x87 aren't enabled. >> > 2. For functions with no_caller_saved_registers attribute, MMX and x87 >> > registers are clobbered since saving and restoring registers doesn't >> > include MMX nor x87 registers. >> > 3. Don't mark disabled registers as call used to avoid reg_to_stack >> > crashes when x87 registers are still accessed even with -mno-mmx >> > -mno-80387. >> > 4. Add ABI_ORIGINAL which is the function ABI without attributes on >> > the current function. >> > 5. Add ABI_ALTERNATE which is the alternate function ABI from ABI_DEFAULT. >> > If ix86_abi is SYSV_ABI, ABI_ALTERNATE is the function ABI for MS_ABI. >> > Otherwise, ABI_ALTERNATE is the function ABI for SYSV_ABI. >> > >> > Tested on Linux/x86-64 and with CPython 3.14.4. >> >> Like I mentioned in the PR trail for 125266, I don't think >> the ix86_original_abi stuff, and the use of cfun in >> ix86_conditional_register_usage, is correct. Maybe the simplest >> thing would be for me to come up with a counterproposal, based on >> this patch. It might be a few days before I can give it a go though. > > Hi Richard, > > I found a typo in the v2 patch. Here is the v3 patch. I also changed > ix86_original_abi and ix86_alternate_abi implementation: > > /* Return the descriptor of the standard function ABI type. If > ABI_TYPE == ABI_ALTERNATE, return the function alternate ABI type. */ > > static const predefined_function_abi & > ix86_standard_abi (int abi_type) > { > static const char ix86_call_used_regs[] = CALL_USED_REGISTERS; > auto &standard_abi = function_abis[abi_type]; > if (!standard_abi.initialized_p ()) > { > HARD_REG_SET full_reg_clobbers = {}; > > /* Add all registers that are clobbered by the call. NB: If the > current ABI is SYSV_ABI, the alternate ABI is MS_ABI. */ > bool is_64bit_ms_abi = (TARGET_64BIT > && ix86_abi == (abi_type == ABI_ALTERNATE > ? SYSV_ABI : MS_ABI)); > char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi); > for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++) > if (global_regs[i] > || (!fixed_regs[i] > && (ix86_call_used_regs[i] == 1 > || (ix86_call_used_regs[i] & c_mask)))) > SET_HARD_REG_BIT (full_reg_clobbers, i); > > SET_HARD_REG_BIT (full_reg_clobbers, FLAGS_REG); > SET_HARD_REG_BIT (full_reg_clobbers, FPSR_REG); > > standard_abi.initialize (abi_type, full_reg_clobbers); > } > return standard_abi; > } > > /* Return the descriptor of the function ABI type without attributes > on the current function. */ > > static const predefined_function_abi & > ix86_original_abi (void) > { > return ix86_standard_abi (ABI_ORIGINAL); > } > > /* Return the descriptor of the function alternate ABI type. */ > > static const predefined_function_abi & > ix86_alternate_abi (void) > { > return ix86_standard_abi (ABI_ALTERNATE); > }
Thanks. I made a start on what I wanted to try today, but realised that I needed a target-independent patch first. I'll send that in a sec. Richard
