diff options
| author | Gary Guo <gary@garyguo.net> | 2021-11-22 02:38:50 +0000 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2021-11-22 13:45:17 +0000 |
| commit | 14aa039d3087b76152018e3ca8c5df34fe1540b3 (patch) | |
| tree | e6b8f3cceef12d382c5acdd2e21dfa9b7a0c609a /src | |
| parent | 703027f0fc5dbd47d1655f1af013e67ae7d5f974 (diff) | |
| download | rust-14aa039d3087b76152018e3ca8c5df34fe1540b3.tar.gz rust-14aa039d3087b76152018e3ca8c5df34fe1540b3.zip | |
Skip registers saved by calling convention
Diffstat (limited to 'src')
| -rw-r--r-- | src/inline_asm.rs | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 8b999f3c55a..8f9deeec718 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -320,21 +320,44 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { offset }; + // Allocate stack slots for saving clobbered registers + let abi_clobber = + InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, Symbol::intern("C")) + .unwrap() + .clobbered_regs(); + for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) { + let mut need_save = true; + // If the register overlaps with a register clobbered by function call, then + // we don't need to save it. + for r in abi_clobber { + r.overlapping_regs(|r| { + if r == reg { + need_save = false; + } + }); + + if !need_save { + break; + } + } + + if need_save { + slots_clobber[i] = Some(new_slot(reg.reg_class())); + } + } + // FIXME overlap input and output slots to save stack space for (i, operand) in self.operands.iter().enumerate() { match *operand { InlineAsmOperand::In { reg, .. } => { - slots_clobber[i] = Some(new_slot(reg.reg_class())); slots_input[i] = Some(new_slot(reg.reg_class())); } InlineAsmOperand::Out { reg, place, .. } => { - slots_clobber[i] = Some(new_slot(reg.reg_class())); if place.is_some() { slots_output[i] = Some(new_slot(reg.reg_class())); } } InlineAsmOperand::InOut { reg, out_place, .. } => { - slots_clobber[i] = Some(new_slot(reg.reg_class())); let slot = new_slot(reg.reg_class()); slots_input[i] = Some(slot); if out_place.is_some() { @@ -366,7 +389,6 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Save clobbered registers if !self.options.contains(InlineAsmOptions::NORETURN) { - // FIXME skip registers saved by the calling convention for (reg, slot) in self .registers .iter() |
