Skip to content

Commit c5693cb

Browse files
committed
Skeleton for multiple arch support
1 parent c4261cf commit c5693cb

File tree

1 file changed

+77
-39
lines changed

1 file changed

+77
-39
lines changed

src/inline_asm.rs

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

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

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

@@ -424,10 +427,10 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
424427
.zip(self.stack_slots_input.iter().copied())
425428
.filter_map(|(r, s)| r.zip(s))
426429
{
427-
restore_register(&mut generated_asm, self.arch, reg, slot);
430+
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
428431
}
429432

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

@@ -459,7 +462,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
459462
.zip(self.stack_slots_output.iter().copied())
460463
.filter_map(|(r, s)| r.zip(s))
461464
{
462-
save_register(&mut generated_asm, self.arch, reg, slot);
465+
Self::save_register(&mut generated_asm, self.arch, reg, slot);
463466
}
464467

465468
// Restore clobbered registers
@@ -469,22 +472,84 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
469472
.zip(self.stack_slots_clobber.iter().copied())
470473
.filter_map(|(r, s)| r.zip(s))
471474
{
472-
restore_register(&mut generated_asm, self.arch, reg, slot);
475+
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
473476
}
474477

475-
generated_asm.push_str(" pop rbp\n");
476-
generated_asm.push_str(" ret\n");
478+
Self::epilogue(&mut generated_asm, self.arch);
477479
} else {
478-
generated_asm.push_str(" ud2\n");
480+
Self::epilogue_noreturn(&mut generated_asm, self.arch);
479481
}
480482

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

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

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

0 commit comments

Comments
 (0)