From fa61b66516165770b7afae378747e2d7c5a9136c Mon Sep 17 00:00:00 2001 From: losfair Date: Tue, 5 Mar 2019 00:23:49 +0800 Subject: [PATCH] Strongly type scratch registers and fixed an unwinding issue. --- lib/dynasm-backend/src/codegen_x64.rs | 10 ++++++---- lib/dynasm-backend/src/stack.rs | 19 ++++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/dynasm-backend/src/codegen_x64.rs b/lib/dynasm-backend/src/codegen_x64.rs index 38833a491..610ac9a2f 100644 --- a/lib/dynasm-backend/src/codegen_x64.rs +++ b/lib/dynasm-backend/src/codegen_x64.rs @@ -1,5 +1,7 @@ use super::codegen::*; -use super::stack::{ControlFrame, ControlStack, IfElseState, ValueInfo, ValueLocation, ValueStack}; +use super::stack::{ + ControlFrame, ControlStack, IfElseState, ScratchRegister, ValueInfo, ValueLocation, ValueStack, +}; use byteorder::{ByteOrder, LittleEndian}; use dynasmrt::{ x64::Assembler, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, ExecutableBuffer, @@ -85,9 +87,9 @@ pub enum Register { } impl Register { - pub fn from_scratch_reg(id: u8) -> Register { + pub fn from_scratch_reg(sr: ScratchRegister) -> Register { use self::Register::*; - match id { + match sr.raw_id() { 0 => RDI, 1 => RSI, 2 => RDX, @@ -804,7 +806,7 @@ impl X64FunctionCode { let reg = Register::from_scratch_reg(x); dynasm!( assembler - ; mov Rq(x as u8), rax + ; mov Rq(reg as u8), rax ); } ValueLocation::Stack => { diff --git a/lib/dynasm-backend/src/stack.rs b/lib/dynasm-backend/src/stack.rs index 8e45c6d38..e78eaa0ed 100644 --- a/lib/dynasm-backend/src/stack.rs +++ b/lib/dynasm-backend/src/stack.rs @@ -56,10 +56,19 @@ pub struct ValueInfo { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum ValueLocation { - Register(u8), + Register(ScratchRegister), Stack, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct ScratchRegister(u8); + +impl ScratchRegister { + pub fn raw_id(&self) -> u8 { + self.0 + } +} + impl ValueLocation { pub fn is_register(&self) -> bool { if let ValueLocation::Register(_) = *self { @@ -69,7 +78,7 @@ impl ValueLocation { } } - pub fn get_register(&self) -> Result { + pub fn get_register(&self) -> Result { if let ValueLocation::Register(id) = *self { Ok(id) } else { @@ -90,11 +99,11 @@ impl ValueStack { fn next_location(&self, loc: &ValueLocation) -> ValueLocation { match *loc { - ValueLocation::Register(x) => { + ValueLocation::Register(ScratchRegister(x)) => { if x >= self.num_regs - 1 { ValueLocation::Stack } else { - ValueLocation::Register(x + 1) + ValueLocation::Register(ScratchRegister(x + 1)) } } ValueLocation::Stack => ValueLocation::Stack, @@ -106,7 +115,7 @@ impl ValueStack { .values .last() .map(|x| self.next_location(&x.location)) - .unwrap_or(ValueLocation::Register(0)); + .unwrap_or(ValueLocation::Register(ScratchRegister(0))); self.values.push(ValueInfo { ty: ty, location: loc,