//! Codegen of `asm!` invocations.

use std::fmt::Write;

use cranelift_codegen::isa::CallConv;
use rustc_abi::CanonAbi;
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::attrs::lang_items::LangItem;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_span::sym;
use rustc_target::asm::*;
use rustc_target::spec::Arch;
use target_lexicon::BinaryFormat;

use crate::prelude::*;

pub(crate) enum CInlineAsmOperand<'tcx> {
    In {
        reg: InlineAsmRegOrRegClass,
        value: Value,
    },
    Out {
        reg: InlineAsmRegOrRegClass,
        late: bool,
        place: Option<CPlace<'tcx>>,
    },
    InOut {
        reg: InlineAsmRegOrRegClass,
        _late: bool,
        in_value: Value,
        out_place: Option<CPlace<'tcx>>,
    },
    Const {
        value: String,
    },
    Symbol {
        symbol: String,
    },
}

pub(crate) fn codegen_inline_asm_terminator<'tcx>(
    fx: &mut FunctionCx<'_, '_, 'tcx>,
    span: Span,
    template: &[InlineAsmTemplatePiece],
    operands: &[InlineAsmOperand<'tcx>],
    options: InlineAsmOptions,
    destination: Option<mir::BasicBlock>,
) {
    // Used by panic_abort on Windows, but uses a syntax which only happens to work with
    // asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
    // the LLVM backend.
    if template.len() == 1 && template[0] == InlineAsmTemplatePiece::String("int $$0x29".into()) {
        fx.bcx.ins().trap(TrapCode::user(2).unwrap());
        return;
    }

    if fx.tcx.sess.target.arch == Arch::S390x
        && template.len() == 3
        && template[0] == InlineAsmTemplatePiece::String("stfle 0(".into())
        && let InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ } =
            template[1]
        && template[2] == InlineAsmTemplatePiece::String(")".into())
    {
        // FIXME no inline asm support for s390x yet, but stdarch needs it for feature detection
        match destination {
            Some(destination) => {
                let destination_block = fx.get_block(destination);
                fx.bcx.ins().jump(destination_block, &[]);
            }
            None => {
                fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
            }
        }
        return;
    }

    let operands = operands
        .iter()
        .map(|operand| match *operand {
            InlineAsmOperand::In { reg, ref value } => CInlineAsmOperand::In {
                reg,
                value: crate::base::codegen_operand(fx, value).load_scalar(fx),
            },
            InlineAsmOperand::Out { reg, late, ref place } => CInlineAsmOperand::Out {
                reg,
                late,
                place: place.map(|place| crate::base::codegen_place(fx, place)),
            },
            InlineAsmOperand::InOut { reg, late, ref in_value, ref out_place } => {
                CInlineAsmOperand::InOut {
                    reg,
                    _late: late,
                    in_value: crate::base::codegen_operand(fx, in_value).load_scalar(fx),
                    out_place: out_place.map(|place| crate::base::codegen_place(fx, place)),
                }
            }
            InlineAsmOperand::Const { ref value } => {
                let (const_value, ty) = crate::constant::eval_mir_constant(fx, value);
                let mir::ConstValue::Scalar(scalar) = const_value else {
                    span_bug!(
                        span,
                        "expected Scalar for promoted asm const, but got {:#?}",
                        const_value
                    )
                };

                let value = rustc_codegen_ssa::common::asm_const_to_str(
                    fx.tcx,
                    span,
                    scalar.assert_scalar_int(),
                    fx.layout_of(ty),
                );
                CInlineAsmOperand::Const { value }
            }
            InlineAsmOperand::SymFn { ref value } => {
                if cfg!(not(feature = "inline_asm_sym")) {
                    fx.tcx
                        .dcx()
                        .span_err(span, "asm! and global_asm! sym operands are not yet supported");
                }

                let const_ = fx.monomorphize(value.const_);
                if let ty::FnDef(def_id, args) = *const_.ty().kind() {
                    let instance = ty::Instance::resolve_for_fn_ptr(
                        fx.tcx,
                        ty::TypingEnv::fully_monomorphized(),
                        def_id,
                        args.no_bound_vars().unwrap(),
                    )
                    .unwrap();
                    let symbol = fx.tcx.symbol_name(instance);

                    if FullyMonomorphizedLayoutCx(fx.tcx)
                        .fn_abi_of_instance(instance, ty::List::empty())
                        .conv
                        == CanonAbi::Custom
                    {
                        // We can't create a wrapper for custom ABI functions.
                        CInlineAsmOperand::Symbol { symbol: symbol.name.to_owned() }
                    } else {
                        // Pass a wrapper rather than the function itself as the function itself may not
                        // be exported from the main codegen unit and may thus be unreachable from the
                        // object file created by an external assembler.
                        let wrapper_name = format!(
                            "{}__inline_asm_{}_wrapper_n{}",
                            fx.symbol_name,
                            fx.cgu_name.as_str().replace('.', "__").replace('-', "_"),
                            fx.inline_asm_index,
                        );
                        fx.inline_asm_index += 1;
                        let sig =
                            get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance);
                        create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name);

                        CInlineAsmOperand::Symbol { symbol: wrapper_name }
                    }
                } else {
                    span_bug!(span, "invalid type for asm sym (fn)");
                }
            }
            InlineAsmOperand::SymStatic { def_id } => {
                assert!(fx.tcx.is_static(def_id));
                let instance = Instance::mono(fx.tcx, def_id);
                CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() }
            }
            InlineAsmOperand::Label { .. } => {
                span_bug!(span, "asm! label operands are not yet supported");
            }
        })
        .collect::<Vec<_>>();

    codegen_inline_asm_inner(fx, template, &operands, options);

    match destination {
        Some(destination) => {
            let destination_block = fx.get_block(destination);
            fx.bcx.ins().jump(destination_block, &[]);
        }
        None => {
            fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
        }
    }
}

pub(crate) fn codegen_inline_asm_inner<'tcx>(
    fx: &mut FunctionCx<'_, '_, 'tcx>,
    template: &[InlineAsmTemplatePiece],
    operands: &[CInlineAsmOperand<'tcx>],
    options: InlineAsmOptions,
) {
    // FIXME add .eh_frame unwind info directives

    let mut asm_gen = InlineAssemblyGenerator {
        tcx: fx.tcx,
        arch: fx.tcx.sess.asm_arch.unwrap(),
        enclosing_def_id: fx.instance.def_id(),
        template,
        operands,
        options,
        registers: Vec::new(),
        stack_slots_clobber: Vec::new(),
        stack_slots_input: Vec::new(),
        stack_slots_output: Vec::new(),
        stack_slot_size: Size::from_bytes(0),
    };
    asm_gen.allocate_registers();
    asm_gen.allocate_stack_slots();

    let asm_name = format!(
        "{}__inline_asm_{}_n{}",
        fx.symbol_name,
        fx.cgu_name.as_str().replace('.', "__").replace('-', "_"),
        fx.inline_asm_index,
    );
    fx.inline_asm_index += 1;

    let generated_asm = asm_gen.generate_asm_wrapper(&asm_name);
    fx.inline_asm.push_str(&generated_asm);

    let mut inputs = Vec::new();
    let mut outputs = Vec::new();
    for (i, operand) in operands.iter().enumerate() {
        match operand {
            CInlineAsmOperand::In { reg: _, value } => {
                inputs.push((asm_gen.stack_slots_input[i].unwrap(), *value));
            }
            CInlineAsmOperand::Out { reg: _, late: _, place } => {
                if let Some(place) = place {
                    outputs.push((asm_gen.stack_slots_output[i].unwrap(), *place));
                }
            }
            CInlineAsmOperand::InOut { reg: _, _late: _, in_value, out_place } => {
                inputs.push((asm_gen.stack_slots_input[i].unwrap(), *in_value));
                if let Some(out_place) = out_place {
                    outputs.push((asm_gen.stack_slots_output[i].unwrap(), *out_place));
                }
            }
            CInlineAsmOperand::Const { value: _ } | CInlineAsmOperand::Symbol { symbol: _ } => {}
        }
    }

    call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
}

struct InlineAssemblyGenerator<'a, 'tcx> {
    tcx: TyCtxt<'tcx>,
    arch: InlineAsmArch,
    enclosing_def_id: DefId,
    template: &'a [InlineAsmTemplatePiece],
    operands: &'a [CInlineAsmOperand<'tcx>],
    options: InlineAsmOptions,
    registers: Vec<Option<InlineAsmReg>>,
    stack_slots_clobber: Vec<Option<Size>>,
    stack_slots_input: Vec<Option<Size>>,
    stack_slots_output: Vec<Option<Size>>,
    stack_slot_size: Size,
}

impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
    fn allocate_registers(&mut self) {
        let sess = self.tcx.sess;
        let map = allocatable_registers(
            self.arch,
            sess.relocation_model(),
            self.tcx.asm_target_features(self.enclosing_def_id),
            &sess.target,
        );
        let mut allocated = FxHashMap::<_, (bool, bool)>::default();
        let mut regs = vec![None; self.operands.len()];

        // Add explicit registers to the allocated set.
        for (i, operand) in self.operands.iter().enumerate() {
            match *operand {
                CInlineAsmOperand::In { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => {
                    regs[i] = Some(reg);
                    allocated.entry(reg).or_default().0 = true;
                }
                CInlineAsmOperand::Out {
                    reg: InlineAsmRegOrRegClass::Reg(reg),
                    late: true,
                    ..
                } => {
                    regs[i] = Some(reg);
                    allocated.entry(reg).or_default().1 = true;
                }
                CInlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(reg), .. }
                | CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => {
                    regs[i] = Some(reg);
                    allocated.insert(reg, (true, true));
                }
                _ => (),
            }
        }

        // Allocate out/inout/inlateout registers first because they are more constrained.
        for (i, operand) in self.operands.iter().enumerate() {
            match *operand {
                CInlineAsmOperand::Out {
                    reg: InlineAsmRegOrRegClass::RegClass(class),
                    late: false,
                    ..
                }
                | CInlineAsmOperand::InOut {
                    reg: InlineAsmRegOrRegClass::RegClass(class), ..
                } => {
                    let mut alloc_reg = None;
                    for &reg in &map[&class] {
                        let mut used = false;
                        reg.overlapping_regs(|r| {
                            if allocated.contains_key(&r) {
                                used = true;
                            }
                        });

                        if !used {
                            alloc_reg = Some(reg);
                            break;
                        }
                    }

                    let reg = alloc_reg.expect("cannot allocate registers");
                    regs[i] = Some(reg);
                    allocated.insert(reg, (true, true));
                }
                _ => (),
            }
        }

        // Allocate in/lateout.
        for (i, operand) in self.operands.iter().enumerate() {
            match *operand {
                CInlineAsmOperand::In { reg: InlineAsmRegOrRegClass::RegClass(class), .. } => {
                    let mut alloc_reg = None;
                    for &reg in &map[&class] {
                        let mut used = false;
                        reg.overlapping_regs(|r| {
                            if allocated.get(&r).copied().unwrap_or_default().0 {
                                used = true;
                            }
                        });

                        if !used {
                            alloc_reg = Some(reg);
                            break;
                        }
                    }

                    let reg = alloc_reg.expect("cannot allocate registers");
                    regs[i] = Some(reg);
                    allocated.entry(reg).or_default().0 = true;
                }
                CInlineAsmOperand::Out {
                    reg: InlineAsmRegOrRegClass::RegClass(class),
                    late: true,
                    ..
                } => {
                    let mut alloc_reg = None;
                    for &reg in &map[&class] {
                        let mut used = false;
                        reg.overlapping_regs(|r| {
                            if allocated.get(&r).copied().unwrap_or_default().1 {
                                used = true;
                            }
                        });

                        if !used {
                            alloc_reg = Some(reg);
                            break;
                        }
                    }

                    let reg = alloc_reg.expect("cannot allocate registers");
                    regs[i] = Some(reg);
                    allocated.entry(reg).or_default().1 = true;
                }
                _ => (),
            }
        }

        self.registers = regs;
    }

    fn allocate_stack_slots(&mut self) {
        let mut slot_size = Size::from_bytes(0);
        let mut slots_clobber = vec![None; self.operands.len()];
        let mut slots_input = vec![None; self.operands.len()];
        let mut slots_output = vec![None; self.operands.len()];

        let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| {
            let reg_size = reg_class
                .supported_types(self.arch, true)
                .iter()
                .map(|(ty, _)| ty.size())
                .max()
                .unwrap();
            let align = rustc_abi::Align::from_bytes(reg_size.bytes()).unwrap();
            let offset = slot_size.align_to(align);
            *slot_size = offset + reg_size;
            offset
        };
        let mut new_slot = |x| new_slot_fn(&mut slot_size, x);

        // Allocate stack slots for saving clobbered registers
        let abi_clobber = InlineAsmClobberAbi::parse(
            self.arch,
            &self.tcx.sess.target,
            &self.tcx.sess.internal_target_features,
            sym::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()));
            }
        }

        // Allocate stack slots for inout
        for (i, operand) in self.operands.iter().enumerate() {
            if let CInlineAsmOperand::InOut { reg, out_place: Some(_), .. } = *operand {
                let slot = new_slot(reg.reg_class());
                slots_input[i] = Some(slot);
                slots_output[i] = Some(slot);
            }
        }

        let slot_size_before_input = slot_size;
        let mut new_slot = |x| new_slot_fn(&mut slot_size, x);

        // Allocate stack slots for input
        for (i, operand) in self.operands.iter().enumerate() {
            match *operand {
                CInlineAsmOperand::In { reg, .. }
                | CInlineAsmOperand::InOut { reg, out_place: None, .. } => {
                    slots_input[i] = Some(new_slot(reg.reg_class()));
                }
                _ => (),
            }
        }

        // Reset slot size to before input so that input and output operands can overlap
        // and save some memory.
        let slot_size_after_input = slot_size;
        slot_size = slot_size_before_input;
        let mut new_slot = |x| new_slot_fn(&mut slot_size, x);

        // Allocate stack slots for output
        for (i, operand) in self.operands.iter().enumerate() {
            if let CInlineAsmOperand::Out { reg, place: Some(_), .. } = *operand {
                slots_output[i] = Some(new_slot(reg.reg_class()));
            }
        }

        slot_size = slot_size.max(slot_size_after_input);

        self.stack_slots_clobber = slots_clobber;
        self.stack_slots_input = slots_input;
        self.stack_slots_output = slots_output;
        self.stack_slot_size = slot_size;
    }

    fn generate_asm_wrapper(&self, asm_name: &str) -> String {
        let binary_format = crate::target_triple(self.tcx.sess).binary_format;

        let mut generated_asm = String::new();
        match binary_format {
            BinaryFormat::Elf => {
                writeln!(generated_asm, ".globl {}", asm_name).unwrap();
                writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
                writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
                writeln!(generated_asm, "{}:", asm_name).unwrap();
            }
            BinaryFormat::Macho => {
                writeln!(generated_asm, ".globl _{}", asm_name).unwrap();
                writeln!(generated_asm, "_{}:", asm_name).unwrap();
            }
            BinaryFormat::Coff => {
                writeln!(generated_asm, ".globl {}", asm_name).unwrap();
                writeln!(generated_asm, "{}:", asm_name).unwrap();
            }
            _ => self
                .tcx
                .dcx()
                .fatal(format!("Unsupported binary format for inline asm: {binary_format:?}")),
        }

        let is_x86 = matches!(self.arch, InlineAsmArch::X86 | InlineAsmArch::X86_64);

        if is_x86 {
            generated_asm.push_str(".intel_syntax noprefix\n");
        }

        Self::prologue(&mut generated_asm, self.arch);

        // Save clobbered registers
        if !self.options.contains(InlineAsmOptions::NORETURN) {
            for (reg, slot) in self
                .registers
                .iter()
                .zip(self.stack_slots_clobber.iter().copied())
                .filter_map(|(r, s)| r.zip(s))
            {
                Self::save_register(&mut generated_asm, self.arch, reg, slot);
            }
        }

        // Write input registers
        for (reg, slot) in self
            .registers
            .iter()
            .zip(self.stack_slots_input.iter().copied())
            .filter_map(|(r, s)| r.zip(s))
        {
            Self::restore_register(&mut generated_asm, self.arch, reg, slot);
        }

        if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
            generated_asm.push_str(".att_syntax\n");
        }

        if self.arch == InlineAsmArch::AArch64 {
            for feature in &self.tcx.codegen_fn_attrs(self.enclosing_def_id).target_features {
                if feature.name == sym::neon {
                    continue;
                }
                writeln!(generated_asm, ".arch_extension {}", feature.name).unwrap();
            }
        }

        // The actual inline asm
        for piece in self.template {
            match piece {
                InlineAsmTemplatePiece::String(s) => {
                    generated_asm.push_str(s);
                }
                InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span: _ } => {
                    match self.operands[*operand_idx] {
                        CInlineAsmOperand::In { .. }
                        | CInlineAsmOperand::Out { .. }
                        | CInlineAsmOperand::InOut { .. } => {
                            if self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
                                generated_asm.push('%');
                            }

                            let reg = self.registers[*operand_idx].unwrap();
                            match self.arch {
                                InlineAsmArch::X86_64 => match reg {
                                    InlineAsmReg::X86(reg)
                                        if matches!(
                                            reg.reg_class(),
                                            X86InlineAsmRegClass::xmm_reg
                                                | X86InlineAsmRegClass::ymm_reg
                                                | X86InlineAsmRegClass::zmm_reg
                                        ) =>
                                    {
                                        // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0
                                        let name = reg.name();
                                        if let Some(prefix) = modifier {
                                            let index = &name[3..];
                                            write!(generated_asm, "{prefix}mm{index}").unwrap();
                                        } else {
                                            write!(generated_asm, "{name}").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);
                        }
                        CInlineAsmOperand::Symbol { ref symbol } => {
                            if binary_format == BinaryFormat::Macho {
                                generated_asm.push('_');
                            }

                            generated_asm.push_str(symbol);
                        }
                    }
                }
            }
        }
        generated_asm.push('\n');

        if self.arch == InlineAsmArch::AArch64 {
            for feature in &self.tcx.codegen_fn_attrs(self.enclosing_def_id).target_features {
                if feature.name == sym::neon {
                    continue;
                }
                writeln!(generated_asm, ".arch_extension no{}", feature.name).unwrap();
            }
        }

        if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
            generated_asm.push_str(".intel_syntax noprefix\n");
        }

        if !self.options.contains(InlineAsmOptions::NORETURN) {
            // Read output registers
            for (reg, slot) in self
                .registers
                .iter()
                .zip(self.stack_slots_output.iter().copied())
                .filter_map(|(r, s)| r.zip(s))
            {
                Self::save_register(&mut generated_asm, self.arch, reg, slot);
            }

            // Restore clobbered registers
            for (reg, slot) in self
                .registers
                .iter()
                .zip(self.stack_slots_clobber.iter().copied())
                .filter_map(|(r, s)| r.zip(s))
            {
                Self::restore_register(&mut generated_asm, self.arch, reg, slot);
            }

            Self::epilogue(&mut generated_asm, self.arch);
        } else {
            Self::epilogue_noreturn(&mut generated_asm, self.arch);
        }

        if is_x86 {
            generated_asm.push_str(".att_syntax\n");
        }

        match binary_format {
            BinaryFormat::Elf => {
                writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
                generated_asm.push_str(".text\n");
            }
            BinaryFormat::Macho | BinaryFormat::Coff => {}
            _ => self
                .tcx
                .dcx()
                .fatal(format!("Unsupported binary format for inline asm: {binary_format:?}")),
        }

        generated_asm.push_str("\n\n");

        generated_asm
    }

    fn prologue(generated_asm: &mut String, arch: InlineAsmArch) {
        match arch {
            InlineAsmArch::X86_64 => {
                generated_asm.push_str("    push rbp\n");
                generated_asm.push_str("    mov rbp,rsp\n");
                generated_asm.push_str("    push rbx\n"); // rbx is callee saved
                // rbx is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
                generated_asm.push_str("    mov rbx,rdi\n");
            }
            InlineAsmArch::AArch64 => {
                generated_asm.push_str("    stp fp, lr, [sp, #-32]!\n");
                generated_asm.push_str("    mov fp, sp\n");
                generated_asm.push_str("    str x19, [sp, #24]\n"); // x19 is callee saved
                // x19 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
                generated_asm.push_str("    mov x19, x0\n");
            }
            InlineAsmArch::RiscV64 => {
                generated_asm.push_str("    addi sp, sp, -16\n");
                generated_asm.push_str("    sd ra, 8(sp)\n");
                generated_asm.push_str("    sd s1, 0(sp)\n"); // s1 is callee saved
                // s1/x9 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
                generated_asm.push_str("    mv s1, a0\n");
            }
            _ => unimplemented!("prologue for {:?}", arch),
        }
    }

    fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {
        match arch {
            InlineAsmArch::X86_64 => {
                generated_asm.push_str("    pop rbx\n");
                generated_asm.push_str("    pop rbp\n");
                generated_asm.push_str("    ret\n");
            }
            InlineAsmArch::AArch64 => {
                generated_asm.push_str("    ldr x19, [sp, #24]\n");
                generated_asm.push_str("    ldp fp, lr, [sp], #32\n");
                generated_asm.push_str("    ret\n");
            }
            InlineAsmArch::RiscV64 => {
                generated_asm.push_str("    ld s1, 0(sp)\n");
                generated_asm.push_str("    ld ra, 8(sp)\n");
                generated_asm.push_str("    addi sp, sp, 16\n");
                generated_asm.push_str("    ret\n");
            }
            _ => unimplemented!("epilogue for {:?}", arch),
        }
    }

    fn epilogue_noreturn(generated_asm: &mut String, arch: InlineAsmArch) {
        match arch {
            InlineAsmArch::X86_64 => {
                generated_asm.push_str("    ud2\n");
            }
            InlineAsmArch::AArch64 => {
                generated_asm.push_str("    brk     #0x1\n");
            }
            InlineAsmArch::RiscV64 => {
                generated_asm.push_str("    ebreak\n");
            }
            _ => unimplemented!("epilogue_noreturn for {:?}", arch),
        }
    }

    fn save_register(
        generated_asm: &mut String,
        arch: InlineAsmArch,
        reg: InlineAsmReg,
        offset: Size,
    ) {
        match arch {
            InlineAsmArch::X86_64 => {
                match reg {
                    InlineAsmReg::X86(reg)
                        if matches!(
                            reg.reg_class(),
                            X86InlineAsmRegClass::xmm_reg
                                | X86InlineAsmRegClass::ymm_reg
                                | X86InlineAsmRegClass::zmm_reg
                        ) =>
                    {
                        // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0
                        let name = reg.name();
                        let mov = if name.starts_with("xmm") { "movups" } else { "vmovups" };
                        write!(generated_asm, "    {mov} [rbx+0x{:x}], {name}", offset.bytes())
                            .unwrap();
                    }
                    _ => {
                        write!(generated_asm, "    mov [rbx+0x{:x}], ", offset.bytes()).unwrap();
                        reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
                    }
                }
                generated_asm.push('\n');
            }
            InlineAsmArch::AArch64 => {
                generated_asm.push_str("    str ");
                match reg {
                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {
                        // rustc emits v0 rather than q0
                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()
                    }
                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),
                }
                writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
            }
            InlineAsmArch::RiscV64 => {
                generated_asm.push_str("    sd ");
                reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
                writeln!(generated_asm, ", 0x{:x}(s1)", offset.bytes()).unwrap();
            }
            _ => unimplemented!("save_register for {:?}", arch),
        }
    }

    fn restore_register(
        generated_asm: &mut String,
        arch: InlineAsmArch,
        reg: InlineAsmReg,
        offset: Size,
    ) {
        match arch {
            InlineAsmArch::X86_64 => {
                match reg {
                    InlineAsmReg::X86(reg)
                        if matches!(
                            reg.reg_class(),
                            X86InlineAsmRegClass::xmm_reg
                                | X86InlineAsmRegClass::ymm_reg
                                | X86InlineAsmRegClass::zmm_reg
                        ) =>
                    {
                        // rustc emits x0/y0/z0 rather than xmm0/ymm0/zmm0
                        let name = reg.name();
                        let mov = if name.starts_with("xmm") { "movups" } else { "vmovups" };
                        write!(generated_asm, "    {mov} {name}").unwrap();
                    }
                    _ => {
                        generated_asm.push_str("    mov ");
                        reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap()
                    }
                }
                writeln!(generated_asm, ", [rbx+0x{:x}]", offset.bytes()).unwrap();
            }
            InlineAsmArch::AArch64 => {
                generated_asm.push_str("    ldr ");
                match reg {
                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {
                        // rustc emits v0 rather than q0
                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()
                    }
                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),
                }
                writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
            }
            InlineAsmArch::RiscV64 => {
                generated_asm.push_str("    ld ");
                reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
                writeln!(generated_asm, ", 0x{:x}(s1)", offset.bytes()).unwrap();
            }
            _ => unimplemented!("restore_register for {:?}", arch),
        }
    }
}

fn call_inline_asm<'tcx>(
    fx: &mut FunctionCx<'_, '_, 'tcx>,
    asm_name: &str,
    slot_size: Size,
    inputs: Vec<(Size, Value)>,
    outputs: Vec<(Size, CPlace<'tcx>)>,
) {
    let stack_slot =
        fx.create_stack_slot(u32::try_from(slot_size.bytes().next_multiple_of(16)).unwrap(), 16);

    let inline_asm_func = fx
        .module
        .declare_function(
            asm_name,
            Linkage::Import,
            &Signature {
                call_conv: CallConv::SystemV,
                params: vec![AbiParam::new(fx.pointer_type)],
                returns: vec![],
            },
        )
        .unwrap();
    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);
    }

    for (offset, value) in inputs {
        stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).store(
            fx,
            value,
            MemFlagsData::trusted(),
        );
    }

    let stack_slot_addr = stack_slot.get_addr(fx);
    // FIXME use try_call once unwinding inline assembly is supported
    fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]);

    for (offset, place) in outputs {
        let ty = if place.layout().ty.is_simd() {
            let (lane_count, lane_type) = place.layout().ty.simd_size_and_type(fx.tcx);
            asm_clif_type(fx, lane_type).unwrap().by(lane_count.try_into().unwrap()).unwrap()
        } else {
            asm_clif_type(fx, place.layout().ty).unwrap()
        };
        let value = stack_slot.offset(fx, i32::try_from(offset.bytes()).unwrap().into()).load(
            fx,
            ty,
            MemFlagsData::trusted(),
        );
        place.write_cvalue(fx, CValue::by_val(value, place.layout()));
    }
}

fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
    match ty.kind() {
        // Adapted from https://github.com/rust-lang/rust/blob/df44a57fd29fca899ce473f85ed64efd0708dd7c/compiler/rustc_hir_typeck/src/inline_asm.rs#L180-L183
        ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
            let ty = args.type_at(0);
            fx.clif_type(ty)
        }
        _ => fx.clif_type(ty),
    }
}
