{"id":"c257c86d76ac6b56","repo":"rust-lang/rust","slug":"save-register-for","errorCode":null,"errorMessage":"save_register for {:?}","messagePattern":"save_register for (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_cranelift/src/inline_asm.rs","lineNumber":773,"sourceCode":"                generated_asm.push('\\n');\n            }\n            InlineAsmArch::AArch64 => {\n                generated_asm.push_str(\"    str \");\n                match reg {\n                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {\n                        // rustc emits v0 rather than q0\n                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()\n                    }\n                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),\n                }\n                writeln!(generated_asm, \", [x19, 0x{:x}]\", offset.bytes()).unwrap();\n            }\n            InlineAsmArch::RiscV64 => {\n                generated_asm.push_str(\"    sd \");\n                reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();\n                writeln!(generated_asm, \", 0x{:x}(s1)\", offset.bytes()).unwrap();\n            }\n            _ => unimplemented!(\"save_register for {:?}\", arch),\n        }\n    }\n\n    fn restore_register(\n        generated_asm: &mut String,\n        arch: InlineAsmArch,\n        reg: InlineAsmReg,\n        offset: Size,\n    ) {\n        match arch {\n            InlineAsmArch::X86_64 => {\n                match reg {\n                    InlineAsmReg::X86(reg)\n                        if matches!(\n                            reg.reg_class(),\n                            X86InlineAsmRegClass::xmm_reg\n                                | X86InlineAsmRegClass::ymm_reg\n                                | X86InlineAsmRegClass::zmm_reg","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_cranelift/src/inline_asm.rs#L755-L791","documentation":"Thrown by rustc_codegen_cranelift when saving a clobbered register to a stack slot before a user asm! block. save_register() emits the architecture-specific store instruction for the base-pointer-relative slot (e.g. mov [rbx+off], reg). Only X86_64, AArch64, and RiscV64 are implemented; other arches hit `_ => unimplemented!(\"save_register for {:?}\", arch)`.","triggerScenarios":"Compiling asm! with out(\"reg\") / inout(\"reg\") operands that clobber registers, on a target other than X86_64/AArch64/RiscV64 using the Cranelift backend. The backend must spill each clobbered register to a stack slot before the asm and reload it after.","commonSituations":"Inline asm with multiple register operands (e.g. SIMD/DSP intrinsics) targeting a tier-3 arch under cg_clif; porting a crate that relies on per-register asm operands to a new architecture before the cranelift backend has the save/restore sequences.","solutions":["Switch to the LLVM backend for that target.","Reduce the asm to arches Cranelift supports (x86_64/aarch64/riscv64) via cfg.","Avoid explicit register clobbers in asm operands where a plain Rust intrinsic or builtin is available.","Implement save_register for the arch (emit the store to the base-pointer-relative offset, mirroring the existing arms) upstream."],"exampleFix":"// before\nlet r: u64;\nasm!(\"mov {}, 1\", out(\"rax\") r, options(nostack));\n\n// after - avoid register-clobber asm, use a plain expression\nlet r: u64 = 1;","handlingStrategy":"validation","validationCode":"// Detect asm! blocks that explicitly list registers in `out(\"reg\")` /\n// `inout(\"reg\")` — save_register path triggers on named-register operands.\nlet re = regex::Regex::new(r#\"asm!\\([^)]*\\b(out|inout|lateout)\\(\"(?:rax|rbx|rcx|rdx|rsi|rdi|rbp|r[0-9]+)\"\"#).unwrap();\nif re.is_match(&src) {\n    eprintln!(\"cg_clif cannot save_named_register for asm; use LLVM.\");\n}","typeGuard":null,"tryCatchPattern":"// Compiler-process panic; not catchable. Use LLVM backend for any crate\n// that performs explicit register save/restore via asm!.","preventionTips":["Avoid named-register operands in asm! under cg_clif; prefer `in(\"reg\")` class operands.","If you must save/restore a specific register, wrap the asm in a Rust function compiled by LLVM.","Audit clobbers: every explicit register clobber can hit the unimplemented save_register path."],"tags":["rustc","cranelift","inline-asm","codegen","unimplemented","registers","target-arch"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}