Skip to content

Commit b91e84c

Browse files
committed
Skip registers saved by calling convention
1 parent 703027f commit b91e84c

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

src/inline_asm.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -320,21 +320,44 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
320320
offset
321321
};
322322

323+
// Allocate stack slots for saving clobbered registers
324+
let abi_clobber =
325+
InlineAsmClobberAbi::parse(self.arch, &self.tcx.sess.target, Symbol::intern("C"))
326+
.unwrap()
327+
.clobbered_regs();
328+
for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| Some(i).zip(*r)) {
329+
let mut need_save = true;
330+
// If the register overlaps with a register clobbered by function call, then
331+
// we don't need to save it.
332+
for r in abi_clobber {
333+
r.overlapping_regs(|r| {
334+
if r == reg {
335+
need_save = false;
336+
}
337+
});
338+
339+
if !need_save {
340+
break;
341+
}
342+
}
343+
344+
if need_save {
345+
slots_clobber[i] = Some(new_slot(reg.reg_class()));
346+
}
347+
}
348+
323349
// FIXME overlap input and output slots to save stack space
324350
for (i, operand) in self.operands.iter().enumerate() {
325351
match *operand {
326352
InlineAsmOperand::In { reg, .. } => {
327-
slots_clobber[i] = Some(new_slot(reg.reg_class()));
328353
slots_input[i] = Some(new_slot(reg.reg_class()));
329354
}
330355
InlineAsmOperand::Out { reg, place, .. } => {
331-
slots_clobber[i] = Some(new_slot(reg.reg_class()));
332356
if place.is_some() {
333357
slots_output[i] = Some(new_slot(reg.reg_class()));
334358
}
335359
}
336360
InlineAsmOperand::InOut { reg, out_place, .. } => {
337-
slots_clobber[i] = Some(new_slot(reg.reg_class()));
338361
let slot = new_slot(reg.reg_class());
339362
slots_input[i] = Some(slot);
340363
if out_place.is_some() {
@@ -366,7 +389,6 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
366389

367390
// Save clobbered registers
368391
if !self.options.contains(InlineAsmOptions::NORETURN) {
369-
// FIXME skip registers saved by the calling convention
370392
for (reg, slot) in self
371393
.registers
372394
.iter()

0 commit comments

Comments
 (0)