forked from AbleOS/holey-bytes
some cleanump and ironing out bugs in new regalloc
This commit is contained in:
parent
81cf39b602
commit
bb625a9e19
|
@ -1106,7 +1106,7 @@ trait TypeParser {
|
||||||
files: &[parser::Ast],
|
files: &[parser::Ast],
|
||||||
) -> ty::Id {
|
) -> ty::Id {
|
||||||
match *expr {
|
match *expr {
|
||||||
Expr::Mod { id, .. } => ty::Kind::Module(id).compress(),
|
Expr::Mod { id, .. } => id.into(),
|
||||||
Expr::UnOp { op: TokenKind::Xor, val, .. } => {
|
Expr::UnOp { op: TokenKind::Xor, val, .. } => {
|
||||||
let base = self.parse_ty(file, val, None, files);
|
let base = self.parse_ty(file, val, None, files);
|
||||||
self.tys().make_ptr(base)
|
self.tys().make_ptr(base)
|
||||||
|
|
|
@ -4064,10 +4064,7 @@ impl<'a> Codegen<'a> {
|
||||||
if !self.struct_op(pos, op, is, dst, lhs, rhs) {
|
if !self.struct_op(pos, op, is, dst, lhs, rhs) {
|
||||||
self.report(
|
self.report(
|
||||||
pos,
|
pos,
|
||||||
fa!(
|
fa!("... when appliing '{0} {op} {0}'", self.ty_display(s.into())),
|
||||||
"... when appliing '{0} {op} {0}'",
|
|
||||||
self.ty_display(ty::Kind::Struct(s).compress())
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl Backend for HbvmBackend {
|
||||||
|
|
||||||
self.globals.shadow(types.ins.globals.len());
|
self.globals.shadow(types.ins.globals.len());
|
||||||
|
|
||||||
self.asm.frontier.push(ty::Kind::Func(from).compress());
|
self.asm.frontier.push(from.into());
|
||||||
while let Some(itm) = self.asm.frontier.pop() {
|
while let Some(itm) = self.asm.frontier.pop() {
|
||||||
match itm.expand() {
|
match itm.expand() {
|
||||||
ty::Kind::Func(func) => {
|
ty::Kind::Func(func) => {
|
||||||
|
@ -341,6 +341,14 @@ impl Backend for HbvmBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Nodes {
|
impl Nodes {
|
||||||
|
fn cond_op(&self, cnd: Nid) -> CondRet {
|
||||||
|
let Kind::BinOp { op } = self[cnd].kind else { return None };
|
||||||
|
if self[cnd].lock_rc == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
op.cond_op(self[self[cnd].inputs[1]].ty)
|
||||||
|
}
|
||||||
|
|
||||||
fn strip_offset(&self, region: Nid, ty: ty::Id, tys: &Types) -> (Nid, Offset) {
|
fn strip_offset(&self, region: Nid, ty: ty::Id, tys: &Types) -> (Nid, Offset) {
|
||||||
if matches!(self[region].kind, Kind::BinOp { op: TokenKind::Add | TokenKind::Sub })
|
if matches!(self[region].kind, Kind::BinOp { op: TokenKind::Add | TokenKind::Sub })
|
||||||
&& self[region].lock_rc != 0
|
&& self[region].lock_rc != 0
|
||||||
|
@ -493,9 +501,7 @@ impl HbvmBackend {
|
||||||
match node.kind {
|
match node.kind {
|
||||||
Kind::If => {
|
Kind::If => {
|
||||||
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
||||||
if let Kind::BinOp { op } = nodes[cnd].kind
|
if let Some((op, swapped)) = nodes.cond_op(cnd) {
|
||||||
&& let Some((op, swapped)) = op.cond_op(nodes[nodes[cnd].inputs[1]].ty)
|
|
||||||
{
|
|
||||||
let &[lhs, rhs] = allocs else { unreachable!() };
|
let &[lhs, rhs] = allocs else { unreachable!() };
|
||||||
let &[_, lh, rh] = nodes[cnd].inputs.as_slice() else { unreachable!() };
|
let &[_, lh, rh] = nodes[cnd].inputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
|
@ -584,7 +590,6 @@ impl HbvmBackend {
|
||||||
let &[dst, oper] = allocs else { unreachable!() };
|
let &[dst, oper] = allocs else { unreachable!() };
|
||||||
self.emit(op(dst, oper));
|
self.emit(op(dst, oper));
|
||||||
}
|
}
|
||||||
Kind::BinOp { .. } if node.lock_rc != 0 => {}
|
|
||||||
Kind::BinOp { op } => {
|
Kind::BinOp { op } => {
|
||||||
let &[.., lh, rh] = node.inputs.as_slice() else { unreachable!() };
|
let &[.., lh, rh] = node.inputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
|
@ -649,7 +654,7 @@ impl HbvmBackend {
|
||||||
self.emit(instrs::eca());
|
self.emit(instrs::eca());
|
||||||
} else {
|
} else {
|
||||||
self.relocs.push(TypedReloc {
|
self.relocs.push(TypedReloc {
|
||||||
target: ty::Kind::Func(func).compress(),
|
target: func.into(),
|
||||||
reloc: Reloc::new(self.code.len(), 3, 4),
|
reloc: Reloc::new(self.code.len(), 3, 4),
|
||||||
});
|
});
|
||||||
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
||||||
|
@ -663,7 +668,7 @@ impl HbvmBackend {
|
||||||
}
|
}
|
||||||
Kind::Global { global } => {
|
Kind::Global { global } => {
|
||||||
let reloc = Reloc::new(self.code.len(), 3, 4);
|
let reloc = Reloc::new(self.code.len(), 3, 4);
|
||||||
self.relocs.push(TypedReloc { target: ty::Kind::Global(global).compress(), reloc });
|
self.relocs.push(TypedReloc { target: global.into(), reloc });
|
||||||
self.emit(instrs::lra(allocs[0], 0, 0));
|
self.emit(instrs::lra(allocs[0], 0, 0));
|
||||||
}
|
}
|
||||||
Kind::Stck => {
|
Kind::Stck => {
|
||||||
|
@ -724,12 +729,14 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CondRet = Option<(fn(u8, u8, i16) -> EncodedInstr, bool)>;
|
||||||
|
|
||||||
impl TokenKind {
|
impl TokenKind {
|
||||||
fn cmp_against(self) -> Option<u64> {
|
fn cmp_against(self) -> Option<u64> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
TokenKind::Le | TokenKind::Gt => 1,
|
Self::Le | Self::Gt => 1,
|
||||||
TokenKind::Ne | TokenKind::Eq => 0,
|
Self::Ne | Self::Eq => 0,
|
||||||
TokenKind::Ge | TokenKind::Lt => (-1i64) as _,
|
Self::Ge | Self::Lt => (-1i64) as _,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -741,22 +748,21 @@ impl TokenKind {
|
||||||
let size = ty.simple_size().unwrap();
|
let size = ty.simple_size().unwrap();
|
||||||
|
|
||||||
let ops = match self {
|
let ops = match self {
|
||||||
TokenKind::Gt => [instrs::fcmpgt32, instrs::fcmpgt64],
|
Self::Gt => [instrs::fcmpgt32, instrs::fcmpgt64],
|
||||||
TokenKind::Lt => [instrs::fcmplt32, instrs::fcmplt64],
|
Self::Lt => [instrs::fcmplt32, instrs::fcmplt64],
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(ops[size.ilog2() as usize - 2])
|
Some(ops[size.ilog2() as usize - 2])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::type_complexity)]
|
fn cond_op(self, ty: ty::Id) -> CondRet {
|
||||||
fn cond_op(self, ty: ty::Id) -> Option<(fn(u8, u8, i16) -> EncodedInstr, bool)> {
|
|
||||||
if ty.is_float() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let signed = ty.is_signed();
|
let signed = ty.is_signed();
|
||||||
Some((
|
Some((
|
||||||
match self {
|
match self {
|
||||||
|
Self::Eq => instrs::jne,
|
||||||
|
Self::Ne => instrs::jeq,
|
||||||
|
_ if ty.is_float() => return None,
|
||||||
Self::Le if signed => instrs::jgts,
|
Self::Le if signed => instrs::jgts,
|
||||||
Self::Le => instrs::jgtu,
|
Self::Le => instrs::jgtu,
|
||||||
Self::Lt if signed => instrs::jlts,
|
Self::Lt if signed => instrs::jlts,
|
||||||
|
@ -765,11 +771,9 @@ impl TokenKind {
|
||||||
Self::Ge => instrs::jltu,
|
Self::Ge => instrs::jltu,
|
||||||
Self::Gt if signed => instrs::jgts,
|
Self::Gt if signed => instrs::jgts,
|
||||||
Self::Gt => instrs::jgtu,
|
Self::Gt => instrs::jgtu,
|
||||||
Self::Eq => instrs::jne,
|
|
||||||
Self::Ne => instrs::jeq,
|
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
matches!(self, Self::Lt | TokenKind::Gt),
|
matches!(self, Self::Lt | Self::Gt),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,7 @@ impl HbvmBackend {
|
||||||
match node.kind {
|
match node.kind {
|
||||||
Kind::If => {
|
Kind::If => {
|
||||||
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
||||||
if let Kind::BinOp { op } = fuc.nodes[cnd].kind
|
if fuc.nodes.cond_op(cnd).is_some() {
|
||||||
&& op.cond_op(fuc.nodes[fuc.nodes[cnd].inputs[1]].ty).is_some()
|
|
||||||
{
|
|
||||||
let &[_, lh, rh] = fuc.nodes[cnd].inputs.as_slice() else {
|
let &[_, lh, rh] = fuc.nodes[cnd].inputs.as_slice() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
@ -475,12 +473,10 @@ impl<'a> Function<'a> {
|
||||||
self.emit_node(node.outputs[0])
|
self.emit_node(node.outputs[0])
|
||||||
}
|
}
|
||||||
Kind::If => {
|
Kind::If => {
|
||||||
let &[_, cond] = node.inputs.as_slice() else { unreachable!() };
|
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
||||||
let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() };
|
let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
if let Kind::BinOp { op } = self.nodes[cond].kind
|
if let Some((_, swapped)) = self.nodes.cond_op(cnd) {
|
||||||
&& let Some((_, swapped)) = op.cond_op(node.ty)
|
|
||||||
{
|
|
||||||
if swapped {
|
if swapped {
|
||||||
mem::swap(&mut then, &mut else_);
|
mem::swap(&mut then, &mut else_);
|
||||||
}
|
}
|
||||||
|
@ -506,6 +502,11 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
Kind::Entry => {
|
Kind::Entry => {
|
||||||
let (ret, mut parama) = self.tys.parama(self.sig.ret);
|
let (ret, mut parama) = self.tys.parama(self.sig.ret);
|
||||||
|
|
||||||
|
if let Some(PLoc::Ref(..)) = ret {
|
||||||
|
self.add_instr(MEM);
|
||||||
|
}
|
||||||
|
|
||||||
let mut typs = self.sig.args.args();
|
let mut typs = self.sig.args.args();
|
||||||
#[expect(clippy::unnecessary_to_owned)]
|
#[expect(clippy::unnecessary_to_owned)]
|
||||||
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
||||||
|
@ -518,10 +519,6 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(PLoc::Ref(..)) = ret {
|
|
||||||
self.add_instr(MEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.nodes.reschedule_block(nid, &mut node.outputs);
|
self.nodes.reschedule_block(nid, &mut node.outputs);
|
||||||
for o in node.outputs.into_iter().rev() {
|
for o in node.outputs.into_iter().rev() {
|
||||||
self.emit_node(o);
|
self.emit_node(o);
|
||||||
|
@ -649,7 +646,7 @@ impl<'a> Env<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
range.end = new;
|
range.end = new;
|
||||||
debug_assert!(range.start < range.end, "{:?}", range);
|
debug_assert!(range.start < range.end, "{:?} {inst} {uinst}", range);
|
||||||
|
|
||||||
bundle.add(range);
|
bundle.add(range);
|
||||||
});
|
});
|
||||||
|
|
|
@ -332,21 +332,19 @@ impl<'a> Function<'a> {
|
||||||
Kind::If => {
|
Kind::If => {
|
||||||
self.backrefs[nid as usize] = self.backrefs[prev as usize];
|
self.backrefs[nid as usize] = self.backrefs[prev as usize];
|
||||||
|
|
||||||
let &[_, cond] = node.inputs.as_slice() else { unreachable!() };
|
let &[_, cnd] = node.inputs.as_slice() else { unreachable!() };
|
||||||
let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() };
|
let &[mut then, mut else_] = node.outputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
if let Kind::BinOp { op } = self.nodes[cond].kind
|
if let Some((_, swapped)) = self.nodes.cond_op(cnd) {
|
||||||
&& let Some((_, swapped)) = op.cond_op(node.ty)
|
|
||||||
{
|
|
||||||
if swapped {
|
if swapped {
|
||||||
mem::swap(&mut then, &mut else_);
|
mem::swap(&mut then, &mut else_);
|
||||||
}
|
}
|
||||||
let &[_, lhs, rhs] = self.nodes[cond].inputs.as_slice() else { unreachable!() };
|
let &[_, lhs, rhs] = self.nodes[cnd].inputs.as_slice() else { unreachable!() };
|
||||||
let ops = vec![self.urg(lhs), self.urg(rhs)];
|
let ops = vec![self.urg(lhs), self.urg(rhs)];
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
} else {
|
} else {
|
||||||
mem::swap(&mut then, &mut else_);
|
mem::swap(&mut then, &mut else_);
|
||||||
let ops = vec![self.urg(cond)];
|
let ops = vec![self.urg(cnd)];
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue