fixing typechecking issues, pointers now properly typecheck and generic types are properly cached
This commit is contained in:
parent
aeb3a37f7d
commit
60b203daee
|
@ -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<Loc> 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<LocCow>) {
|
||||
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<LocCow>, 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<LocCow>, dst: impl Into<LocCow>, 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<LocCow>, dst: impl Into<LocCow>, 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)));
|
||||
|
|
Loading…
Reference in a new issue