Skip to content

Commit c0f2e47

Browse files
committed
Skeleton for multiple arch support
1 parent cf5e07c commit c0f2e47

File tree

1 file changed

+77
-39
lines changed

1 file changed

+77
-39
lines changed

src/inline_asm.rs

+77-39
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
402402
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
403403
writeln!(generated_asm, "{}:", asm_name).unwrap();
404404

405-
generated_asm.push_str(".intel_syntax noprefix\n");
406-
generated_asm.push_str(" push rbp\n");
407-
generated_asm.push_str(" mov rbp,rdi\n");
405+
let is_x86 = matches!(self.arch, InlineAsmArch::X86 | InlineAsmArch::X86_64);
406+
407+
if is_x86 {
408+
generated_asm.push_str(".intel_syntax noprefix\n");
409+
}
410+
Self::prologue(&mut generated_asm, self.arch);
408411

409412
// Save clobbered registers
410413
if !self.options.contains(InlineAsmOptions::NORETURN) {
@@ -414,7 +417,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
414417
.zip(self.stack_slots_clobber.iter().copied())
415418
.filter_map(|(r, s)| r.zip(s))
416419
{
417-
save_register(&mut generated_asm, self.arch, reg, slot);
420+
Self::save_register(&mut generated_asm, self.arch, reg, slot);
418421
}
419422
}
420423

@@ -425,10 +428,10 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
425428
.zip(self.stack_slots_input.iter().copied())
426429
.filter_map(|(r, s)| r.zip(s))
427430
{
428-
restore_register(&mut generated_asm, self.arch, reg, slot);
431+
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
429432
}
430433

431-
if self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
434+
if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
432435
generated_asm.push_str(".att_syntax\n");
433436
}
434437

@@ -460,7 +463,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
460463
.zip(self.stack_slots_output.iter().copied())
461464
.filter_map(|(r, s)| r.zip(s))
462465
{
463-
save_register(&mut generated_asm, self.arch, reg, slot);
466+
Self::save_register(&mut generated_asm, self.arch, reg, slot);
464467
}
465468

466469
// Restore clobbered registers
@@ -470,22 +473,84 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
470473
.zip(self.stack_slots_clobber.iter().copied())
471474
.filter_map(|(r, s)| r.zip(s))
472475
{
473-
restore_register(&mut generated_asm, self.arch, reg, slot);
476+
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
474477
}
475478

476-
generated_asm.push_str(" pop rbp\n");
477-
generated_asm.push_str(" ret\n");
479+
Self::epilogue(&mut generated_asm, self.arch);
478480
} else {
479-
generated_asm.push_str(" ud2\n");
481+
Self::epilogue_noreturn(&mut generated_asm, self.arch);
480482
}
481483

482-
generated_asm.push_str(".att_syntax\n");
484+
if is_x86 {
485+
generated_asm.push_str(".att_syntax\n");
486+
}
483487
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
484488
generated_asm.push_str(".text\n");
485489
generated_asm.push_str("\n\n");
486490

487491
generated_asm
488492
}
493+
494+
fn prologue(generated_asm: &mut String, arch: InlineAsmArch) {
495+
match arch {
496+
InlineAsmArch::X86_64 => {
497+
generated_asm.push_str(" push rbp\n");
498+
generated_asm.push_str(" mov rbp,rdi\n");
499+
}
500+
_ => unimplemented!("prologue for {:?}", arch),
501+
}
502+
}
503+
504+
fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {
505+
match arch {
506+
InlineAsmArch::X86_64 => {
507+
generated_asm.push_str(" pop rbp\n");
508+
generated_asm.push_str(" ret\n");
509+
}
510+
_ => unimplemented!("epilogue for {:?}", arch),
511+
}
512+
}
513+
514+
fn epilogue_noreturn(generated_asm: &mut String, arch: InlineAsmArch) {
515+
match arch {
516+
InlineAsmArch::X86_64 => {
517+
generated_asm.push_str(" ud2\n");
518+
}
519+
_ => unimplemented!("epilogue_noreturn for {:?}", arch),
520+
}
521+
}
522+
523+
fn save_register(
524+
generated_asm: &mut String,
525+
arch: InlineAsmArch,
526+
reg: InlineAsmReg,
527+
offset: Size,
528+
) {
529+
match arch {
530+
InlineAsmArch::X86_64 => {
531+
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
532+
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
533+
generated_asm.push('\n');
534+
}
535+
_ => unimplemented!("save_register for {:?}", arch),
536+
}
537+
}
538+
539+
fn restore_register(
540+
generated_asm: &mut String,
541+
arch: InlineAsmArch,
542+
reg: InlineAsmReg,
543+
offset: Size,
544+
) {
545+
match arch {
546+
InlineAsmArch::X86_64 => {
547+
generated_asm.push_str(" mov ");
548+
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
549+
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
550+
}
551+
_ => unimplemented!("restore_register for {:?}", arch),
552+
}
553+
}
489554
}
490555

491556
fn call_inline_asm<'tcx>(
@@ -533,30 +598,3 @@ fn call_inline_asm<'tcx>(
533598
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
534599
}
535600
}
536-
537-
fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsmReg, offset: Size) {
538-
match arch {
539-
InlineAsmArch::X86_64 => {
540-
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
541-
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
542-
generated_asm.push('\n');
543-
}
544-
_ => unimplemented!("save_register for {:?}", arch),
545-
}
546-
}
547-
548-
fn restore_register(
549-
generated_asm: &mut String,
550-
arch: InlineAsmArch,
551-
reg: InlineAsmReg,
552-
offset: Size,
553-
) {
554-
match arch {
555-
InlineAsmArch::X86_64 => {
556-
generated_asm.push_str(" mov ");
557-
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
558-
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
559-
}
560-
_ => unimplemented!("restore_register for {:?}", arch),
561-
}
562-
}

0 commit comments

Comments
 (0)