From 49981965fa8d99165160a184e5a5952528f87030 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 24 Jan 2022 15:54:17 +0200 Subject: [PATCH] x64: fix assert when calling a function --- lib/compiler-singlepass/src/machine_x64.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/compiler-singlepass/src/machine_x64.rs b/lib/compiler-singlepass/src/machine_x64.rs index 3f428fe19fe..e2e13a4c7d3 100644 --- a/lib/compiler-singlepass/src/machine_x64.rs +++ b/lib/compiler-singlepass/src/machine_x64.rs @@ -1807,16 +1807,22 @@ impl Machine for MachineX86_64 { fn push_location_for_native(&mut self, loc: Location) { match loc { Location::Imm64(_) => { - // Push R9 value slot to be exchange with `mov`. + // x86_64 does not support `mov imm64, mem`. We must first place the immdiate value + // into a register and then write the register to the memory. Now the problem is + // that there might not be any registers available to clobber. In order to make + // this work out we spill a register thus retaining both the original value of the + // register and producing the required data at the top of the stack. + // + // FIXME(#2723): figure out how to not require spilling a register here. It should + // definitely be possible to `pick_gpr`/`pick_temp_gpr` to grab an otherwise unused + // register and just clobber its value here. self.assembler.emit_push(Size::S64, Location::GPR(GPR::R9)); - self.reserve_unused_temp_gpr(GPR::R9); self.move_location(Size::S64, loc, Location::GPR(GPR::R9)); self.assembler.emit_xchg( Size::S64, Location::GPR(GPR::R9), Location::Memory(GPR::RSP, 0), ); - self.release_gpr(GPR::R9); } Location::SIMD(_) => { // Dummy value slot to be filled with `mov`.