forked from AbleOS/holey-bytes
fixing struct return and copy miscompilation
This commit is contained in:
parent
3aff6fc006
commit
1da900461c
|
@ -634,7 +634,7 @@ Foo := struct {x: int, y: u32, z: u32}
|
||||||
#### sort_something_viredly
|
#### sort_something_viredly
|
||||||
```hb
|
```hb
|
||||||
main := fn(): int {
|
main := fn(): int {
|
||||||
return sqrt(1)
|
return sqrt(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
sqrt := fn(x: int): int {
|
sqrt := fn(x: int): int {
|
||||||
|
|
|
@ -1159,10 +1159,6 @@ impl Codegen {
|
||||||
E::String { pos, literal } => {
|
E::String { pos, literal } => {
|
||||||
let literal = &literal[1..literal.len() - 1];
|
let literal = &literal[1..literal.len() - 1];
|
||||||
|
|
||||||
if !literal.ends_with("\\0") {
|
|
||||||
self.report(pos, "string literal must end with null byte (for now)");
|
|
||||||
}
|
|
||||||
|
|
||||||
let report = |bytes: &core::str::Bytes, message: &str| {
|
let report = |bytes: &core::str::Bytes, message: &str| {
|
||||||
self.report(pos + (literal.len() - bytes.len()) as u32 - 1, message)
|
self.report(pos + (literal.len() - bytes.len()) as u32 - 1, message)
|
||||||
};
|
};
|
||||||
|
|
|
@ -1762,6 +1762,10 @@ fn endoce_string(
|
||||||
str.push(b);
|
str.push(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if str.last() != Some(&0) {
|
||||||
|
report(&bytes, "string literal must end with null byte (for now)");
|
||||||
|
}
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
140
lang/src/son.rs
140
lang/src/son.rs
|
@ -140,7 +140,7 @@ impl Nodes {
|
||||||
Node { ralloc_backref: u16::MAX, inputs: inps.into(), kind, ty, ..Default::default() };
|
Node { ralloc_backref: u16::MAX, inputs: inps.into(), kind, ty, ..Default::default() };
|
||||||
|
|
||||||
let mut lookup_meta = None;
|
let mut lookup_meta = None;
|
||||||
if !node.is_gvnd() {
|
if !node.is_not_gvnd() {
|
||||||
let (raw_entry, hash) = self.lookup.entry(node.key(), &self.values);
|
let (raw_entry, hash) = self.lookup.entry(node.key(), &self.values);
|
||||||
|
|
||||||
let entry = match raw_entry {
|
let entry = match raw_entry {
|
||||||
|
@ -170,7 +170,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_node_lookup(&mut self, target: Nid) {
|
fn remove_node_lookup(&mut self, target: Nid) {
|
||||||
if !self[target].is_gvnd() {
|
if !self[target].is_not_gvnd() {
|
||||||
self.lookup.remove(&target, &self.values).unwrap();
|
self.lookup.remove(&target, &self.values).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,6 +482,7 @@ impl Nodes {
|
||||||
Kind::Load => write!(out, "load: "),
|
Kind::Load => write!(out, "load: "),
|
||||||
Kind::Stre => write!(out, "stre: "),
|
Kind::Stre => write!(out, "stre: "),
|
||||||
Kind::Mem => write!(out, " mem: "),
|
Kind::Mem => write!(out, " mem: "),
|
||||||
|
Kind::Idk => write!(out, " idk: "),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
||||||
|
@ -774,9 +775,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lock_scope(&mut self, scope: &Scope) {
|
fn lock_scope(&mut self, scope: &Scope) {
|
||||||
if let Some(str) = scope.store.to_store() {
|
self.lock(scope.store);
|
||||||
self.lock(str);
|
|
||||||
}
|
|
||||||
for &load in &scope.loads {
|
for &load in &scope.loads {
|
||||||
self.lock(load);
|
self.lock(load);
|
||||||
}
|
}
|
||||||
|
@ -786,9 +785,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock_remove_scope(&mut self, scope: &Scope) {
|
fn unlock_remove_scope(&mut self, scope: &Scope) {
|
||||||
if let Some(str) = scope.store.to_store() {
|
self.unlock_remove(scope.store);
|
||||||
self.unlock_remove(str);
|
|
||||||
}
|
|
||||||
for &load in &scope.loads {
|
for &load in &scope.loads {
|
||||||
self.unlock_remove(load);
|
self.unlock_remove(load);
|
||||||
}
|
}
|
||||||
|
@ -856,6 +853,8 @@ pub enum Kind {
|
||||||
func: ty::Func,
|
func: ty::Func,
|
||||||
},
|
},
|
||||||
// [ctrl]
|
// [ctrl]
|
||||||
|
Idk,
|
||||||
|
// [ctrl]
|
||||||
Stck,
|
Stck,
|
||||||
// [ctrl, memory]
|
// [ctrl, memory]
|
||||||
Load,
|
Load,
|
||||||
|
@ -930,8 +929,8 @@ impl Node {
|
||||||
self.kind == Kind::Phi && self.inputs[2] == 0
|
self.kind == Kind::Phi && self.inputs[2] == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_gvnd(&self) -> bool {
|
fn is_not_gvnd(&self) -> bool {
|
||||||
self.is_lazy_phi() || matches!(self.kind, Kind::Arg)
|
self.is_lazy_phi() || matches!(self.kind, Kind::Arg | Kind::Stck)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,7 +1018,6 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(&mut self) {
|
fn finalize(&mut self) {
|
||||||
self.nodes.unlock(ENTRY);
|
|
||||||
self.nodes.unlock(NEVER);
|
self.nodes.unlock(NEVER);
|
||||||
self.nodes.unlock_remove_scope(&core::mem::take(&mut self.scope));
|
self.nodes.unlock_remove_scope(&core::mem::take(&mut self.scope));
|
||||||
self.nodes.unlock(MEM);
|
self.nodes.unlock(MEM);
|
||||||
|
@ -1109,6 +1107,14 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
|
match tys.size_of(sig.ret) {
|
||||||
|
0..=8 => {}
|
||||||
|
9..=16 => todo!(),
|
||||||
|
size @ 17.. => {
|
||||||
|
self.emit(instrs::bmc(atr(allocs[0]), 1, size.try_into().unwrap()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if i != func.blocks.len() - 1 {
|
if i != func.blocks.len() - 1 {
|
||||||
let rel = Reloc::new(self.code.len(), 1, 4);
|
let rel = Reloc::new(self.code.len(), 1, 4);
|
||||||
self.ret_relocs.push(rel);
|
self.ret_relocs.push(rel);
|
||||||
|
@ -1163,6 +1169,7 @@ impl ItemCtx {
|
||||||
let offset = func.nodes[nid].offset;
|
let offset = func.nodes[nid].offset;
|
||||||
self.emit(instrs::addi64(atr(allocs[0]), base, offset as _));
|
self.emit(instrs::addi64(atr(allocs[0]), base, offset as _));
|
||||||
}
|
}
|
||||||
|
Kind::Idk => {}
|
||||||
Kind::Load => {
|
Kind::Load => {
|
||||||
let mut region = node.inputs[1];
|
let mut region = node.inputs[1];
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
@ -1186,21 +1193,24 @@ impl ItemCtx {
|
||||||
Kind::Stre => {
|
Kind::Stre => {
|
||||||
let mut region = node.inputs[2];
|
let mut region = node.inputs[2];
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
let size = u16::try_from(tys.size_of(node.ty)).expect("TODO");
|
||||||
if func.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
if func.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
||||||
&& let Kind::CInt { value } =
|
&& let Kind::CInt { value } =
|
||||||
func.nodes[func.nodes[region].inputs[2]].kind
|
func.nodes[func.nodes[region].inputs[2]].kind
|
||||||
|
&& size <= 8
|
||||||
{
|
{
|
||||||
region = func.nodes[region].inputs[1];
|
region = func.nodes[region].inputs[1];
|
||||||
offset = value as Offset;
|
offset = value as Offset;
|
||||||
}
|
}
|
||||||
let size = u16::try_from(tys.size_of(node.ty)).expect("TODO");
|
|
||||||
let nd = &func.nodes[region];
|
let nd = &func.nodes[region];
|
||||||
let (base, offset, src) = match nd.kind {
|
let (base, offset, src) = match nd.kind {
|
||||||
Kind::Stck => (reg::STACK_PTR, nd.offset + offset, allocs[0]),
|
Kind::Stck if size <= 8 => {
|
||||||
|
(reg::STACK_PTR, nd.offset + offset, allocs[0])
|
||||||
|
}
|
||||||
_ => (atr(allocs[0]), offset, allocs[1]),
|
_ => (atr(allocs[0]), offset, allocs[1]),
|
||||||
};
|
};
|
||||||
if size > 8 {
|
if size > 8 {
|
||||||
self.emit(instrs::bmc(base, atr(src), size));
|
self.emit(instrs::bmc(atr(src), base, size));
|
||||||
} else {
|
} else {
|
||||||
self.emit(instrs::st(atr(src), base, offset as _, size));
|
self.emit(instrs::st(atr(src), base, offset as _, size));
|
||||||
}
|
}
|
||||||
|
@ -1539,8 +1549,8 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let mut vc = Vc::from([VOID, value, region]);
|
let mut vc = Vc::from([VOID, value, region]);
|
||||||
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
|
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
|
||||||
|
self.ci.nodes.unlock(self.ci.scope.store);
|
||||||
if let Some(str) = self.ci.scope.store.to_store() {
|
if let Some(str) = self.ci.scope.store.to_store() {
|
||||||
self.ci.nodes.unlock(str);
|
|
||||||
vc.push(str);
|
vc.push(str);
|
||||||
}
|
}
|
||||||
for load in self.ci.scope.loads.drain(..) {
|
for load in self.ci.scope.loads.drain(..) {
|
||||||
|
@ -1592,6 +1602,23 @@ impl<'a> Codegen<'a> {
|
||||||
fn raw_expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
|
fn raw_expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option<Value> {
|
||||||
// ordered by complexity of the expression
|
// ordered by complexity of the expression
|
||||||
match *expr {
|
match *expr {
|
||||||
|
Expr::Idk { pos } => {
|
||||||
|
let Some(ty) = ctx.ty else {
|
||||||
|
self.report(
|
||||||
|
pos,
|
||||||
|
"resulting value cannot be inferred from context, \
|
||||||
|
consider using `@as(<ty>, idk)` to hint the type",
|
||||||
|
);
|
||||||
|
return Value::NEVER;
|
||||||
|
};
|
||||||
|
|
||||||
|
if matches!(ty.expand(), ty::Kind::Struct(_) | ty::Kind::Slice(_)) {
|
||||||
|
let stck = self.ci.nodes.new_node(ty, Kind::Stck, [VOID, MEM]);
|
||||||
|
Some(Value::ptr(stck).ty(ty))
|
||||||
|
} else {
|
||||||
|
Some(self.ci.nodes.new_node_lit(ty, Kind::Idk, [VOID]))
|
||||||
|
}
|
||||||
|
}
|
||||||
Expr::Number { value, .. } => Some(self.ci.nodes.new_node_lit(
|
Expr::Number { value, .. } => Some(self.ci.nodes.new_node_lit(
|
||||||
ctx.ty.filter(|ty| ty.is_integer() || ty.is_pointer()).unwrap_or(ty::Id::INT),
|
ctx.ty.filter(|ty| ty.is_integer() || ty.is_pointer()).unwrap_or(ty::Id::INT),
|
||||||
Kind::CInt { value },
|
Kind::CInt { value },
|
||||||
|
@ -1620,10 +1647,6 @@ impl<'a> Codegen<'a> {
|
||||||
Expr::String { pos, literal } => {
|
Expr::String { pos, literal } => {
|
||||||
let literal = &literal[1..literal.len() - 1];
|
let literal = &literal[1..literal.len() - 1];
|
||||||
|
|
||||||
if !literal.ends_with("\\0") {
|
|
||||||
self.report(pos, "string literal must end with null byte (for now)");
|
|
||||||
}
|
|
||||||
|
|
||||||
let report = |bytes: &core::str::Bytes, message: &str| {
|
let report = |bytes: &core::str::Bytes, message: &str| {
|
||||||
self.report(pos + (literal.len() - bytes.len()) as u32 - 1, message)
|
self.report(pos + (literal.len() - bytes.len()) as u32 - 1, message)
|
||||||
};
|
};
|
||||||
|
@ -1696,7 +1719,7 @@ impl<'a> Codegen<'a> {
|
||||||
return Value::NEVER;
|
return Value::NEVER;
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Value::ptr(self.offset(vtarget.id, ty, offset)).ty(ty))
|
Some(Value::ptr(self.offset(vtarget.id, offset)).ty(ty))
|
||||||
}
|
}
|
||||||
Expr::UnOp { op: TokenKind::Band, val, .. } => {
|
Expr::UnOp { op: TokenKind::Band, val, .. } => {
|
||||||
let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) };
|
let ctx = Ctx { ty: ctx.ty.and_then(|ty| self.tys.base_of(ty)) };
|
||||||
|
@ -1751,9 +1774,9 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
Expr::BinOp { left, op: TokenKind::Assign, right } => {
|
Expr::BinOp { left, op: TokenKind::Assign, right } => {
|
||||||
let dest = self.raw_expr(left)?;
|
let dest = self.raw_expr(left)?;
|
||||||
let value = self.expr(right)?;
|
let value = self.expr_ctx(right, Ctx::default().with_ty(dest.ty))?;
|
||||||
|
|
||||||
self.assert_ty(left.pos(), value.ty, dest.ty, "assignment dest");
|
self.assert_ty(left.pos(), value.ty, dest.ty, "assignment source");
|
||||||
|
|
||||||
if dest.var {
|
if dest.var {
|
||||||
self.ci.nodes.lock(value.id);
|
self.ci.nodes.lock(value.id);
|
||||||
|
@ -1805,7 +1828,8 @@ impl<'a> Codegen<'a> {
|
||||||
let offset =
|
let offset =
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
||||||
let inps = [VOID, bs.id, offset];
|
let inps = [VOID, bs.id, offset];
|
||||||
let ptr = self.ci.nodes.new_node(elem, Kind::BinOp { op: TokenKind::Add }, inps);
|
let ptr =
|
||||||
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
||||||
Some(Value::ptr(ptr).ty(elem))
|
Some(Value::ptr(ptr).ty(elem))
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
||||||
|
@ -1857,7 +1881,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "as", args: [ty, expr], .. } => {
|
Expr::Directive { name: "as", args: [ty, expr], .. } => {
|
||||||
let ctx = Ctx::default().with_ty(self.ty(ty));
|
let ctx = Ctx::default().with_ty(self.ty(ty));
|
||||||
self.expr_ctx(expr, ctx)
|
self.raw_expr_ctx(expr, ctx)
|
||||||
}
|
}
|
||||||
Expr::Call { func, args, .. } => {
|
Expr::Call { func, args, .. } => {
|
||||||
self.ci.call_count += 1;
|
self.ci.call_count += 1;
|
||||||
|
@ -1918,11 +1942,22 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let alt_value = match self.tys.size_of(sig.ret) {
|
||||||
|
0..=8 => None,
|
||||||
|
9..=16 => todo!(),
|
||||||
|
17.. => {
|
||||||
|
let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]);
|
||||||
|
inps.push(stck);
|
||||||
|
Some(Value::ptr(stck).ty(sig.ret))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fnc }, inps);
|
self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fnc }, inps);
|
||||||
|
|
||||||
self.store_mem(VOID, VOID);
|
self.store_mem(VOID, VOID);
|
||||||
|
|
||||||
Some(Value::new(self.ci.ctrl).ty(sig.ret))
|
alt_value.or(Some(Value::new(self.ci.ctrl).ty(sig.ret)))
|
||||||
}
|
}
|
||||||
Expr::Tupl { pos, ty, fields, .. } => {
|
Expr::Tupl { pos, ty, fields, .. } => {
|
||||||
let Some(sty) = ty.map(|ty| self.ty(ty)).or(ctx.ty) else {
|
let Some(sty) = ty.map(|ty| self.ty(ty)).or(ctx.ty) else {
|
||||||
|
@ -1948,7 +1983,7 @@ impl<'a> Codegen<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = self.expr_ctx(field, Ctx::default().with_ty(ty))?;
|
let value = self.expr_ctx(field, Ctx::default().with_ty(ty))?;
|
||||||
let mem = self.offset(mem, ty, offset);
|
let mem = self.offset(mem, offset);
|
||||||
self.store_mem(mem, value.id);
|
self.store_mem(mem, value.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1995,7 +2030,7 @@ impl<'a> Codegen<'a> {
|
||||||
{
|
{
|
||||||
let value = self.expr_ctx(field, Ctx::default().with_ty(elem))?;
|
let value = self.expr_ctx(field, Ctx::default().with_ty(elem))?;
|
||||||
_ = self.assert_ty(field.pos(), value.ty, elem, "array value");
|
_ = self.assert_ty(field.pos(), value.ty, elem, "array value");
|
||||||
let mem = self.offset(mem, elem, offset);
|
let mem = self.offset(mem, offset);
|
||||||
self.store_mem(mem, value.id);
|
self.store_mem(mem, value.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2063,7 +2098,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?;
|
let value = self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?;
|
||||||
let mem = self.offset(mem, ty, offset);
|
let mem = self.offset(mem, offset);
|
||||||
self.store_mem(mem, value.id);
|
self.store_mem(mem, value.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2238,9 +2273,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
|
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
|
||||||
let orig_store = self.ci.scope.store;
|
let orig_store = self.ci.scope.store;
|
||||||
if let Some(str) = orig_store.to_store() {
|
self.ci.nodes.lock(orig_store);
|
||||||
self.ci.nodes.lock(str);
|
|
||||||
}
|
|
||||||
let else_scope = self.ci.scope.clone();
|
let else_scope = self.ci.scope.clone();
|
||||||
self.ci.nodes.lock_scope(&else_scope);
|
self.ci.nodes.lock_scope(&else_scope);
|
||||||
|
|
||||||
|
@ -2255,9 +2288,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.ctrl
|
self.ci.ctrl
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(str) = orig_store.to_store() {
|
self.ci.nodes.unlock_remove(orig_store);
|
||||||
self.ci.nodes.unlock_remove(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if lcntrl == Nid::MAX && rcntrl == Nid::MAX {
|
if lcntrl == Nid::MAX && rcntrl == Nid::MAX {
|
||||||
self.ci.nodes.unlock_remove_scope(&then_scope);
|
self.ci.nodes.unlock_remove_scope(&then_scope);
|
||||||
|
@ -2298,14 +2329,14 @@ impl<'a> Codegen<'a> {
|
||||||
Some(n)
|
Some(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset(&mut self, val: Nid, ty: ty::Id, off: Offset) -> Nid {
|
fn offset(&mut self, val: Nid, off: Offset) -> Nid {
|
||||||
if off == 0 {
|
if off == 0 {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]);
|
let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]);
|
||||||
let inps = [VOID, val, off];
|
let inps = [VOID, val, off];
|
||||||
self.ci.nodes.new_node(ty, Kind::BinOp { op: TokenKind::Add }, inps)
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn strip_var(&mut self, n: &mut Value) {
|
fn strip_var(&mut self, n: &mut Value) {
|
||||||
|
@ -2688,14 +2719,20 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
let ops = if node.inputs[1] != VOID {
|
let ops = match self.tys.size_of(self.sig.ret) {
|
||||||
|
0 => vec![],
|
||||||
|
1..=8 => {
|
||||||
vec![regalloc2::Operand::reg_fixed_use(
|
vec![regalloc2::Operand::reg_fixed_use(
|
||||||
self.rg(node.inputs[1]),
|
self.rg(node.inputs[1]),
|
||||||
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
||||||
)]
|
)]
|
||||||
} else {
|
}
|
||||||
vec![]
|
9..=16 => todo!(),
|
||||||
|
17.. => {
|
||||||
|
vec![self.urg(node.inputs[1])]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
self.emit_node(node.outputs[0], nid);
|
self.emit_node(node.outputs[0], nid);
|
||||||
}
|
}
|
||||||
|
@ -2755,10 +2792,10 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
Kind::BinOp { op: TokenKind::Add }
|
Kind::BinOp { op: TokenKind::Add }
|
||||||
if self.nodes.is_const(node.inputs[2])
|
if self.nodes.is_const(node.inputs[2])
|
||||||
&& node
|
&& node.outputs.iter().all(|&n| {
|
||||||
.outputs
|
matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)
|
||||||
.iter()
|
&& self.tys.size_of(self.nodes[n].ty) <= 8
|
||||||
.all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)) =>
|
}) =>
|
||||||
{
|
{
|
||||||
self.nodes.lock(nid)
|
self.nodes.lock(nid)
|
||||||
}
|
}
|
||||||
|
@ -2825,6 +2862,17 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match self.tys.size_of(fuc.ret) {
|
||||||
|
0..=8 => {}
|
||||||
|
9..=16 => todo!(),
|
||||||
|
17.. => {
|
||||||
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
|
self.rg(*node.inputs.last().unwrap()),
|
||||||
|
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
|
|
||||||
for o in node.outputs.into_iter().rev() {
|
for o in node.outputs.into_iter().rev() {
|
||||||
|
@ -2851,6 +2899,10 @@ impl<'a> Function<'a> {
|
||||||
let ops = vec![self.drg(nid)];
|
let ops = vec![self.drg(nid)];
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
}
|
}
|
||||||
|
Kind::Idk => {
|
||||||
|
let ops = vec![self.drg(nid)];
|
||||||
|
self.add_instr(nid, ops);
|
||||||
|
}
|
||||||
Kind::Phi | Kind::Arg | Kind::Mem => {}
|
Kind::Phi | Kind::Arg | Kind::Mem => {}
|
||||||
Kind::Load { .. } => {
|
Kind::Load { .. } => {
|
||||||
let mut region = node.inputs[1];
|
let mut region = node.inputs[1];
|
||||||
|
@ -3283,7 +3335,7 @@ mod tests {
|
||||||
//struct_patterns;
|
//struct_patterns;
|
||||||
arrays;
|
arrays;
|
||||||
//inline;
|
//inline;
|
||||||
//idk;
|
idk;
|
||||||
//wide_ret;
|
//wide_ret;
|
||||||
|
|
||||||
// Incomplete Examples;
|
// Incomplete Examples;
|
||||||
|
|
|
@ -1,11 +1,36 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 0a, 16h
|
ST r31, r254, 0a, 8h
|
||||||
LI64 r32, 1610612737d
|
LI64 r2, 1d
|
||||||
LI64 r1, 0d
|
JAL r31, r0, :sqrt
|
||||||
LD r31, r254, 0a, 16h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 87
|
sqrt:
|
||||||
ret: 0
|
ADDI64 r254, r254, -56d
|
||||||
|
ST r31, r254, 0a, 56h
|
||||||
|
CP r32, r2
|
||||||
|
LI64 r33, 0d
|
||||||
|
LI64 r34, 0d
|
||||||
|
LI64 r35, 32768d
|
||||||
|
LI64 r36, 15d
|
||||||
|
3: LI64 r37, 0d
|
||||||
|
JNE r35, r37, :0
|
||||||
|
JMP :1
|
||||||
|
0: ADDI64 r36, r36, -1d
|
||||||
|
CP r37, r34
|
||||||
|
SLUI64 r37, r37, 1b
|
||||||
|
ADD64 r33, r35, r37
|
||||||
|
SLU64 r33, r33, r36
|
||||||
|
JLTS r32, r33, :2
|
||||||
|
ADD64 r34, r34, r35
|
||||||
|
SUB64 r32, r32, r33
|
||||||
|
2: SRUI64 r35, r35, 1b
|
||||||
|
JMP :3
|
||||||
|
1: CP r1, r34
|
||||||
|
LD r31, r254, 0a, 56h
|
||||||
|
ADDI64 r254, r254, 56d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 257
|
||||||
|
ret: 1
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -14,12 +14,13 @@ main:
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
outl:
|
outl:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 0a, 16h
|
ST r31, r254, 0a, 24h
|
||||||
LRA r32, r0, :"whahaha\0"
|
LRA r32, r0, :"whahaha\0"
|
||||||
LD r31, r254, 0a, 16h
|
LI64 r33, 0d
|
||||||
ADDI64 r254, r254, 16d
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 229
|
code size: 239
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
19
lang/tests/son_tests_idk.txt
Normal file
19
lang/tests/son_tests_idk.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -128d
|
||||||
|
LI64 r6, 69d
|
||||||
|
LI64 r5, 128d
|
||||||
|
LI64 r7, 0d
|
||||||
|
ADDI64 r4, r254, 0d
|
||||||
|
2: JLTU r7, r5, :0
|
||||||
|
LD r1, r254, 42a, 1h
|
||||||
|
JMP :1
|
||||||
|
0: ADDI64 r3, r7, 1d
|
||||||
|
ADD64 r2, r7, r4
|
||||||
|
ST r6, r2, 0a, 1h
|
||||||
|
CP r7, r3
|
||||||
|
JMP :2
|
||||||
|
1: ADDI64 r254, r254, 128d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 141
|
||||||
|
ret: 69
|
||||||
|
status: Ok(())
|
|
@ -1,7 +1,7 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -8d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 0a, 8h
|
ST r31, r254, 0a, 8h
|
||||||
LI64 r2, 1d
|
LI64 r2, 100d
|
||||||
JAL r31, r0, :sqrt
|
JAL r31, r0, :sqrt
|
||||||
LD r31, r254, 0a, 8h
|
LD r31, r254, 0a, 8h
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
|
@ -25,5 +25,5 @@ sqrt:
|
||||||
JMP :3
|
JMP :3
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
code size: 188
|
code size: 188
|
||||||
ret: 0
|
ret: 14
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue