From ec4e19d01ff401aad04dc1fcdb08781db83c4786 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Sun, 15 Nov 2020 21:05:53 -0800 Subject: [PATCH] Extract remain assembly to asm.rs --- compiler/gen_dev/src/x86_64/asm.rs | 27 ++++++++++++++++++++++++++- compiler/gen_dev/src/x86_64/mod.rs | 12 ++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/compiler/gen_dev/src/x86_64/asm.rs b/compiler/gen_dev/src/x86_64/asm.rs index 8ec5689947..8962c4e4af 100644 --- a/compiler/gen_dev/src/x86_64/asm.rs +++ b/compiler/gen_dev/src/x86_64/asm.rs @@ -22,7 +22,8 @@ pub enum Register { R15, } -const REX_W: u8 = 0x48; +const REX: u8 = 0x40; +const REX_W: u8 = REX + 0x8; fn add_rm_extension(reg: Register, byte: u8) -> u8 { if reg as u8 > 7 { @@ -68,3 +69,27 @@ pub fn mov_register64bit_register64bit<'a>(buf: &mut Vec<'a, u8>, dst: Register, let src_mod = (src as u8 % 8) << 3; buf.extend(&[rex, 0x89, 0xC0 + dst_mod + src_mod]); } + +pub fn ret_near<'a>(buf: &mut Vec<'a, u8>) { + buf.push(0xC3); +} + +pub fn pop_register64bit<'a>(buf: &mut Vec<'a, u8>, reg: Register) { + if reg as u8 > 7 { + let rex = add_reg_extension(reg, REX); + let reg_mod = reg as u8 % 8; + buf.extend(&[rex, 0x58 + reg_mod]); + } else { + buf.push(0x50 + reg as u8); + } +} + +pub fn push_register64bit<'a>(buf: &mut Vec<'a, u8>, reg: Register) { + if reg as u8 > 7 { + let rex = add_reg_extension(reg, REX); + let reg_mod = reg as u8 % 8; + buf.extend(&[rex, 0x50 + reg_mod]); + } else { + buf.push(0x50 + reg as u8); + } +} diff --git a/compiler/gen_dev/src/x86_64/mod.rs b/compiler/gen_dev/src/x86_64/mod.rs index 1ebc6d6fe7..03dd7d3ee5 100644 --- a/compiler/gen_dev/src/x86_64/mod.rs +++ b/compiler/gen_dev/src/x86_64/mod.rs @@ -57,19 +57,15 @@ impl<'a> Backend<'a> for X86_64Backend<'a> { // TODO: handle allocating and cleaning up data on the stack. let mut out = bumpalo::vec![in self.env.arena]; if !self.leaf_proc { - // push rbp (0x55) - // mov rbp, rsp (0x48, 0x89, 0xE5) - out.extend(&[0x55]); - asm::mov_register64bit_register64bit(&mut out, Register::RBP, Register::RSP) + asm::push_register64bit(&mut out, Register::RBP); + asm::mov_register64bit_register64bit(&mut out, Register::RBP, Register::RSP); } out.extend(&self.buf); if !self.leaf_proc { - // pop rbp - out.push(0x5D); + asm::pop_register64bit(&mut out, Register::RBP); } - // ret - out.push(0xC3); + asm::ret_near(&mut out); out.into_bump_slice() }