diff options
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/inline_asm.rs')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/inline_asm.rs | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 6b9cec39d70..7793b1b7092 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -52,7 +52,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( } let operands = operands - .into_iter() + .iter() .map(|operand| match *operand { InlineAsmOperand::In { reg, ref value } => CInlineAsmOperand::In { reg, @@ -506,10 +506,34 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { if self.options.contains(InlineAsmOptions::ATT_SYNTAX) { generated_asm.push('%'); } - self.registers[*operand_idx] - .unwrap() - .emit(&mut generated_asm, self.arch, *modifier) - .unwrap(); + + let reg = self.registers[*operand_idx].unwrap(); + match self.arch { + InlineAsmArch::X86_64 => match reg { + InlineAsmReg::X86(reg) + if reg as u32 >= X86InlineAsmReg::xmm0 as u32 + && reg as u32 <= X86InlineAsmReg::xmm15 as u32 => + { + // rustc emits x0 rather than xmm0 + let class = match *modifier { + None | Some('x') => "xmm", + Some('y') => "ymm", + Some('z') => "zmm", + _ => unreachable!(), + }; + write!( + generated_asm, + "{class}{}", + reg as u32 - X86InlineAsmReg::xmm0 as u32 + ) + .unwrap(); + } + _ => reg + .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier) + .unwrap(), + }, + _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(), + } } CInlineAsmOperand::Const { ref value } => { generated_asm.push_str(value); @@ -739,7 +763,7 @@ fn call_inline_asm<'tcx>( }, ) .unwrap(); - let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func); + let inline_asm_func = fx.module.declare_func_in_func(inline_asm_func, fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(inline_asm_func, asm_name); } |
