hopefully this is less of a mess now

This commit is contained in:
Jakub Doka 2024-11-15 23:18:40 +01:00
parent b1b6d9eba1
commit 867a750d8f
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 12 additions and 11 deletions

View file

@ -370,7 +370,7 @@ main := fn(): uint {
truncated_uint := @as(u8, @intcast(wide_uint)) truncated_uint := @as(u8, @intcast(wide_uint))
widened_float := @as(f64, @floatcast(1.)) widened_float := @as(f64, @floatcast(1.))
int_from_float := @as(int, @fti(1.)) int_from_float := @as(int, @fti(1.))
float_from_int := @as(f64, @itf(@as(int, 1))) float_from_int := @as(f64, @itf(1))
size_of_Type_in_bytes := @sizeof(foo.Type) size_of_Type_in_bytes := @sizeof(foo.Type)
align_of_Type_in_bytes := @alignof(foo.Type) align_of_Type_in_bytes := @alignof(foo.Type)
hardcoded_pointer := @as(^u8, @bitcast(10)) hardcoded_pointer := @as(^u8, @bitcast(10))

View file

@ -429,7 +429,7 @@ impl Nodes {
&& node.outputs.iter().all(|&n| self[n].uses_direct_offset_of(nid, tys))) && node.outputs.iter().all(|&n| self[n].uses_direct_offset_of(nid, tys)))
} }
Kind::BinOp { op } => { Kind::BinOp { op } => {
op.cond_op(node.ty).is_some() op.cond_op(self[node.inputs[1]].ty).is_some()
&& node.outputs.iter().all(|&n| self[n].kind == Kind::If) && node.outputs.iter().all(|&n| self[n].kind == Kind::If)
} }
Kind::Stck if tys.size_of(node.ty) == 0 => true, Kind::Stck if tys.size_of(node.ty) == 0 => true,
@ -585,7 +585,7 @@ impl HbvmBackend {
self.emit(op(dst, oper)); self.emit(op(dst, oper));
} }
Kind::BinOp { op } => { Kind::BinOp { op } => {
let &[.., lh, rh] = node.inputs.as_slice() else { unreachable!() }; let &[.., rh] = node.inputs.as_slice() else { unreachable!() };
if let Kind::CInt { value } = nodes[rh].kind if let Kind::CInt { value } = nodes[rh].kind
&& nodes[rh].lock_rc != 0 && nodes[rh].lock_rc != 0
@ -593,20 +593,18 @@ impl HbvmBackend {
{ {
let &[dst, lhs] = allocs else { unreachable!() }; let &[dst, lhs] = allocs else { unreachable!() };
self.emit(op(dst, lhs, value as _)); self.emit(op(dst, lhs, value as _));
} else if let Some(op) = op.binop(node.ty).or(op.float_cmp(nodes[lh].ty)) {
let &[dst, lhs, rhs] = allocs else { unreachable!() };
self.emit(op(dst, lhs, rhs));
} else if let Some(against) = op.cmp_against() { } else if let Some(against) = op.cmp_against() {
let op_ty = nodes[rh].ty; let op_ty = nodes[rh].ty;
let &[dst, lhs, rhs] = allocs else { unreachable!() }; let &[dst, lhs, rhs] = allocs else { unreachable!() };
if let Some(op) = op.float_cmp(op_ty) {
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) { self.emit(op(dst, lhs, rhs));
let opop = match op { } else if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
let op = match op {
TokenKind::Le => TokenKind::Gt, TokenKind::Le => TokenKind::Gt,
TokenKind::Ge => TokenKind::Lt, TokenKind::Ge => TokenKind::Lt,
_ => unreachable!(), _ => unreachable!(),
}; };
let op_fn = opop.float_cmp(op_ty).unwrap(); let op_fn = op.float_cmp(op_ty).unwrap();
self.emit(op_fn(dst, lhs, rhs)); self.emit(op_fn(dst, lhs, rhs));
self.emit(instrs::not(dst, dst)); self.emit(instrs::not(dst, dst));
} else { } else {
@ -617,6 +615,9 @@ impl HbvmBackend {
self.emit(instrs::not(dst, dst)); self.emit(instrs::not(dst, dst));
} }
} }
} else if let Some(op) = op.binop(node.ty) {
let &[dst, lhs, rhs] = allocs else { unreachable!() };
self.emit(op(dst, lhs, rhs));
} else { } else {
todo!("unhandled operator: {op}"); todo!("unhandled operator: {op}");
} }
@ -772,7 +773,7 @@ impl TokenKind {
} }
fn binop(self, ty: ty::Id) -> Option<fn(u8, u8, u8) -> EncodedInstr> { fn binop(self, ty: ty::Id) -> Option<fn(u8, u8, u8) -> EncodedInstr> {
let size = ty.simple_size().unwrap(); let size = ty.simple_size().unwrap_or_else(|| panic!("{:?}", ty.expand()));
if ty.is_integer() || ty == ty::Id::BOOL || ty.is_pointer() { if ty.is_integer() || ty == ty::Id::BOOL || ty.is_pointer() {
macro_rules! div { ($($op:ident),*) => {[$(|a, b, c| $op(a, 0, b, c)),*]}; } macro_rules! div { ($($op:ident),*) => {[$(|a, b, c| $op(a, 0, b, c)),*]}; }
macro_rules! rem { ($($op:ident),*) => {[$(|a, b, c| $op(0, a, b, c)),*]}; } macro_rules! rem { ($($op:ident),*) => {[$(|a, b, c| $op(0, a, b, c)),*]}; }