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