Skeleton for multiple arch support
This commit is contained in:
parent
fe3ba31860
commit
eaf88c5b52
@ -402,9 +402,12 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
|||||||
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
|
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
|
||||||
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
||||||
|
|
||||||
generated_asm.push_str(".intel_syntax noprefix\n");
|
let is_x86 = matches!(self.arch, InlineAsmArch::X86 | InlineAsmArch::X86_64);
|
||||||
generated_asm.push_str(" push rbp\n");
|
|
||||||
generated_asm.push_str(" mov rbp,rdi\n");
|
if is_x86 {
|
||||||
|
generated_asm.push_str(".intel_syntax noprefix\n");
|
||||||
|
}
|
||||||
|
Self::prologue(&mut generated_asm, self.arch);
|
||||||
|
|
||||||
// Save clobbered registers
|
// Save clobbered registers
|
||||||
if !self.options.contains(InlineAsmOptions::NORETURN) {
|
if !self.options.contains(InlineAsmOptions::NORETURN) {
|
||||||
@ -414,7 +417,7 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
|||||||
.zip(self.stack_slots_clobber.iter().copied())
|
.zip(self.stack_slots_clobber.iter().copied())
|
||||||
.filter_map(|(r, s)| r.zip(s))
|
.filter_map(|(r, s)| r.zip(s))
|
||||||
{
|
{
|
||||||
save_register(&mut generated_asm, self.arch, reg, slot);
|
Self::save_register(&mut generated_asm, self.arch, reg, slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,10 +428,10 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
|||||||
.zip(self.stack_slots_input.iter().copied())
|
.zip(self.stack_slots_input.iter().copied())
|
||||||
.filter_map(|(r, s)| r.zip(s))
|
.filter_map(|(r, s)| r.zip(s))
|
||||||
{
|
{
|
||||||
restore_register(&mut generated_asm, self.arch, reg, slot);
|
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
|
if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||||
generated_asm.push_str(".att_syntax\n");
|
generated_asm.push_str(".att_syntax\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +463,7 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
|||||||
.zip(self.stack_slots_output.iter().copied())
|
.zip(self.stack_slots_output.iter().copied())
|
||||||
.filter_map(|(r, s)| r.zip(s))
|
.filter_map(|(r, s)| r.zip(s))
|
||||||
{
|
{
|
||||||
save_register(&mut generated_asm, self.arch, reg, slot);
|
Self::save_register(&mut generated_asm, self.arch, reg, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore clobbered registers
|
// Restore clobbered registers
|
||||||
@ -470,22 +473,84 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
|||||||
.zip(self.stack_slots_clobber.iter().copied())
|
.zip(self.stack_slots_clobber.iter().copied())
|
||||||
.filter_map(|(r, s)| r.zip(s))
|
.filter_map(|(r, s)| r.zip(s))
|
||||||
{
|
{
|
||||||
restore_register(&mut generated_asm, self.arch, reg, slot);
|
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
generated_asm.push_str(" pop rbp\n");
|
Self::epilogue(&mut generated_asm, self.arch);
|
||||||
generated_asm.push_str(" ret\n");
|
|
||||||
} else {
|
} else {
|
||||||
generated_asm.push_str(" ud2\n");
|
Self::epilogue_noreturn(&mut generated_asm, self.arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
generated_asm.push_str(".att_syntax\n");
|
if is_x86 {
|
||||||
|
generated_asm.push_str(".att_syntax\n");
|
||||||
|
}
|
||||||
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
|
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
|
||||||
generated_asm.push_str(".text\n");
|
generated_asm.push_str(".text\n");
|
||||||
generated_asm.push_str("\n\n");
|
generated_asm.push_str("\n\n");
|
||||||
|
|
||||||
generated_asm
|
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,rdi\n");
|
||||||
|
}
|
||||||
|
_ => unimplemented!("prologue for {:?}", arch),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {
|
||||||
|
match arch {
|
||||||
|
InlineAsmArch::X86_64 => {
|
||||||
|
generated_asm.push_str(" pop rbp\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");
|
||||||
|
}
|
||||||
|
_ => unimplemented!("epilogue_noreturn for {:?}", arch),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_register(
|
||||||
|
generated_asm: &mut String,
|
||||||
|
arch: InlineAsmArch,
|
||||||
|
reg: InlineAsmReg,
|
||||||
|
offset: Size,
|
||||||
|
) {
|
||||||
|
match arch {
|
||||||
|
InlineAsmArch::X86_64 => {
|
||||||
|
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
|
||||||
|
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||||
|
generated_asm.push('\n');
|
||||||
|
}
|
||||||
|
_ => unimplemented!("save_register for {:?}", arch),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_register(
|
||||||
|
generated_asm: &mut String,
|
||||||
|
arch: InlineAsmArch,
|
||||||
|
reg: InlineAsmReg,
|
||||||
|
offset: Size,
|
||||||
|
) {
|
||||||
|
match arch {
|
||||||
|
InlineAsmArch::X86_64 => {
|
||||||
|
generated_asm.push_str(" mov ");
|
||||||
|
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||||
|
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
|
||||||
|
}
|
||||||
|
_ => unimplemented!("restore_register for {:?}", arch),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_inline_asm<'tcx>(
|
fn call_inline_asm<'tcx>(
|
||||||
@ -533,30 +598,3 @@ fn call_inline_asm<'tcx>(
|
|||||||
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
|
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsmReg, offset: Size) {
|
|
||||||
match arch {
|
|
||||||
InlineAsmArch::X86_64 => {
|
|
||||||
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
|
|
||||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
|
||||||
generated_asm.push('\n');
|
|
||||||
}
|
|
||||||
_ => unimplemented!("save_register for {:?}", arch),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn restore_register(
|
|
||||||
generated_asm: &mut String,
|
|
||||||
arch: InlineAsmArch,
|
|
||||||
reg: InlineAsmReg,
|
|
||||||
offset: Size,
|
|
||||||
) {
|
|
||||||
match arch {
|
|
||||||
InlineAsmArch::X86_64 => {
|
|
||||||
generated_asm.push_str(" mov ");
|
|
||||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
|
||||||
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
|
|
||||||
}
|
|
||||||
_ => unimplemented!("restore_register for {:?}", arch),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user