diff --git a/hblang/src/codegen.rs b/hblang/src/codegen.rs index 64e4fad..db42087 100644 --- a/hblang/src/codegen.rs +++ b/hblang/src/codegen.rs @@ -594,32 +594,6 @@ impl Value { } } -enum LocCow<'a> { - Ref(&'a Loc), - Owned(Loc), -} - -impl<'a> LocCow<'a> { - fn as_ref(&self) -> &Loc { - match self { - Self::Ref(value) => value, - Self::Owned(value) => value, - } - } -} - -impl<'a> From<&'a Loc> for LocCow<'a> { - fn from(value: &'a Loc) -> Self { - Self::Ref(value) - } -} - -impl<'a> From for LocCow<'a> { - fn from(value: Loc) -> Self { - Self::Owned(value) - } -} - #[repr(packed)] #[derive(Debug, PartialEq, Eq, Clone, Copy)] struct CtValue(u64); @@ -816,8 +790,8 @@ impl ItemCtx { output.emit(addi64(STACK_PTR, STACK_PTR, (pushed + stack) as _)); } - fn free_loc(&mut self, src: impl Into) { - if let LocCow::Owned(Loc::Rt { reg, stack, .. }) = src.into() { + fn free_loc(&mut self, src: Loc) { + if let Loc::Rt { reg, stack, .. } = src { self.regs.free(reg); if let Some(stack) = stack { self.stack.free(stack); @@ -1391,10 +1365,10 @@ impl Codegen { let stack = self.ci.stack.allocate(values_size); let mut ptr = Loc::stack(stack.as_ref()); for value in values { - self.store_sized(Loc::ty(value.ty), &ptr, 4); + self.store_sized(Loc::ty(value.ty), ptr.as_ref(), 4); ptr = ptr.offset(4); let size = self.tys.size_of(value.ty); - self.store_sized(value.loc, &ptr, size); + self.store_sized(value.loc, ptr.as_ref(), size); ptr = ptr.offset(size); } @@ -1493,7 +1467,7 @@ impl Codegen { self.output.emit(eca()); - self.load_ret(ty, &loc); + self.load_ret(ty, loc.as_ref()); return Some(Value { ty, loc }); } @@ -1898,7 +1872,7 @@ impl Codegen { self.output.emit(tx()); } - self.load_ret(sig.ret, &loc); + self.load_ret(sig.ret, loc.as_ref()); return Some(Value { ty: sig.ret, loc }); } E::Ident { id, .. } if ident::is_null(id) => Some(Value::ty(id.into())), @@ -1958,7 +1932,7 @@ impl Codegen { E::If { cond, then, else_, .. } => { log::dbg!("if-cond"); let cond = self.expr_ctx(cond, Ctx::default().with_ty(ty::BOOL))?; - let reg = self.loc_to_reg(&cond.loc, 1); + let reg = self.loc_to_reg(cond.loc.as_ref(), 1); let jump_offset = self.local_offset(); self.output.emit(jeq(reg.get(), 0, 0)); self.ci.free_loc(cond.loc); @@ -2467,7 +2441,7 @@ impl Codegen { fn spill(&mut self, loc: Loc, size: Size) -> Loc { let stack = Loc::stack(self.ci.stack.allocate(size)); - self.store_sized(loc, &stack, size); + self.store_sized(loc, stack.as_ref(), size); stack } @@ -2478,7 +2452,7 @@ impl Codegen { 1..=8 => Loc::reg(self.loc_to_reg(loc, size)), _ if loc.is_ref() => { let new_loc = Loc::stack(self.ci.stack.allocate(size)); - self.store_sized(loc, &new_loc, size); + self.store_sized(loc, new_loc.as_ref(), size); new_loc } _ => loc, @@ -2611,7 +2585,7 @@ impl Codegen { _ => (Loc::reg(parama.next()).into_derefed(), Loc::stack(self.ci.stack.allocate(size))), }; - self.store_sized(src, &dst, size); + self.store_sized(src, dst.as_ref(), size); dst } @@ -2637,9 +2611,9 @@ impl Codegen { } } - fn loc_to_reg(&mut self, loc: impl Into, size: Size) -> reg::Id { - match loc.into() { - LocCow::Owned(Loc::Rt { derefed: false, mut reg, offset, stack }) => { + fn loc_to_reg(&mut self, loc: Loc, size: Size) -> reg::Id { + match loc { + Loc::Rt { derefed: false, mut reg, offset, stack } => { debug_assert!(stack.is_none(), "TODO"); assert_eq!(offset, 0, "TODO"); if reg.is_ref() { @@ -2649,11 +2623,6 @@ impl Codegen { } reg } - LocCow::Ref(&Loc::Rt { derefed: false, ref reg, offset, ref stack }) => { - debug_assert!(stack.is_none(), "TODO"); - assert_eq!(offset, 0, "TODO"); - reg.as_ref() - } loc => { let reg = self.ci.regs.allocate(); self.store_sized(loc, Loc::reg(reg.as_ref()), size); @@ -2662,7 +2631,7 @@ impl Codegen { } } - fn load_ret(&mut self, ty: ty::Id, loc: &Loc) { + fn load_ret(&mut self, ty: ty::Id, loc: Loc) { let size = self.tys.size_of(ty); if let 1..=16 = size { self.store_sized(Loc::reg(1), loc, size); @@ -2670,13 +2639,13 @@ impl Codegen { } fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) { - self.pass_arg_low(&value.loc, self.tys.size_of(value.ty), parama) + self.pass_arg_low(value.loc.as_ref(), self.tys.size_of(value.ty), parama) } - fn pass_arg_low(&mut self, loc: &Loc, size: Size, parama: &mut ParamAlloc) { + fn pass_arg_low(&mut self, loc: Loc, size: Size, parama: &mut ParamAlloc) { if size > 16 { let Loc::Rt { reg, stack, offset, .. } = loc else { unreachable!() }; - self.stack_offset(parama.next(), reg.get(), stack.as_ref(), *offset as _); + self.stack_offset(parama.next(), reg.get(), stack.as_ref(), offset as _); return; } @@ -2689,15 +2658,11 @@ impl Codegen { self.store_sized(loc, dst, size); } - fn store_typed(&mut self, src: impl Into, dst: impl Into, ty: ty::Id) { + fn store_typed(&mut self, src: Loc, dst: Loc, ty: ty::Id) { self.store_sized(src, dst, self.tys.size_of(ty) as _) } - fn store_sized(&mut self, src: impl Into, dst: impl Into, size: Size) { - self.store_sized_low(src.into(), dst.into(), size); - } - - fn store_sized_low(&mut self, src: LocCow, dst: LocCow, size: Size) { + fn store_sized(&mut self, src: Loc, dst: Loc, size: Size) { macro_rules! lpat { ($der:literal, $reg:ident, $off:pat, $sta:pat) => { &Loc::Rt { derefed: $der, reg: ref $reg, offset: $off, stack: $sta } @@ -2708,10 +2673,10 @@ impl Codegen { return; } - src.as_ref().assert_valid(); - dst.as_ref().assert_valid(); + src.assert_valid(); + dst.assert_valid(); - match (src.as_ref(), dst.as_ref()) { + match (&src, &dst) { (&Loc::Ct { value, derefed }, lpat!(true, reg, off, ref sta)) => { let ct = self.ci.regs.allocate(); self.output.emit(li64(ct.get(), ensure_loaded(value, derefed, size)));