implementing optimizations up to is statements
This commit is contained in:
parent
955e4a5c7a
commit
1a3b0c2eec
|
@ -8,7 +8,7 @@ use {
|
||||||
parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos},
|
parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos},
|
||||||
HashMap,
|
HashMap,
|
||||||
},
|
},
|
||||||
std::{fmt::Display, ops::Range, rc::Rc},
|
std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Offset = u32;
|
type Offset = u32;
|
||||||
|
@ -3294,7 +3294,7 @@ impl Codegen {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
crate::disasm(&mut sluce, &functions, output, |bin| {
|
crate::disasm(&mut sluce, &functions, output, |bin| {
|
||||||
if self.ct.active()
|
if self.ct.active()
|
||||||
&& let Some(trap) = Self::read_trap(bin.as_ptr() as u64)
|
&& let Some(trap) = Self::read_trap(bin.as_ptr() as u64)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
use {
|
use {
|
||||||
parser::Ast,
|
parser::Ast,
|
||||||
std::{
|
std::{
|
||||||
collections::{hash_map, VecDeque},
|
collections::{hash_map, BTreeMap, VecDeque},
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
|
@ -146,7 +146,7 @@ enum DisasmItem {
|
||||||
|
|
||||||
fn disasm(
|
fn disasm(
|
||||||
binary: &mut &[u8],
|
binary: &mut &[u8],
|
||||||
functions: &HashMap<u32, (&str, u32, DisasmItem)>,
|
functions: &BTreeMap<u32, (&str, u32, DisasmItem)>,
|
||||||
out: &mut impl std::io::Write,
|
out: &mut impl std::io::Write,
|
||||||
mut eca_handler: impl FnMut(&mut &[u8]),
|
mut eca_handler: impl FnMut(&mut &[u8]),
|
||||||
) -> std::io::Result<()> {
|
) -> std::io::Result<()> {
|
||||||
|
|
|
@ -14,9 +14,11 @@ use {
|
||||||
},
|
},
|
||||||
core::fmt,
|
core::fmt,
|
||||||
std::{
|
std::{
|
||||||
|
collections::BTreeMap,
|
||||||
mem,
|
mem,
|
||||||
ops::{self, Range},
|
ops::{self, Range},
|
||||||
rc::Rc,
|
rc::{self, Rc},
|
||||||
|
u32,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,6 +26,8 @@ type Nid = u32;
|
||||||
const NILL: u32 = u32::MAX;
|
const NILL: u32 = u32::MAX;
|
||||||
|
|
||||||
mod reg {
|
mod reg {
|
||||||
|
use crate::log;
|
||||||
|
|
||||||
pub const STACK_PTR: Reg = 254;
|
pub const STACK_PTR: Reg = 254;
|
||||||
pub const ZERO: Reg = 0;
|
pub const ZERO: Reg = 0;
|
||||||
pub const RET: Reg = 1;
|
pub const RET: Reg = 1;
|
||||||
|
@ -59,7 +63,7 @@ mod reg {
|
||||||
impl Drop for Id {
|
impl Drop for Id {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !std::thread::panicking() && self.1 {
|
if !std::thread::panicking() && self.1 {
|
||||||
panic!("reg id leaked: {:?}", self.0);
|
log::err!("reg id leaked: {:?}", self.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,6 +283,8 @@ mod ty {
|
||||||
I16;
|
I16;
|
||||||
I32;
|
I32;
|
||||||
INT;
|
INT;
|
||||||
|
LEFT_UNREACHABLE;
|
||||||
|
RIGHT_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! type_kind {
|
macro_rules! type_kind {
|
||||||
|
@ -526,6 +532,9 @@ impl Nodes {
|
||||||
Kind::Tuple { .. } => {}
|
Kind::Tuple { .. } => {}
|
||||||
Kind::ConstInt { .. } => {}
|
Kind::ConstInt { .. } => {}
|
||||||
Kind::Call { .. } => {}
|
Kind::Call { .. } => {}
|
||||||
|
Kind::If => {}
|
||||||
|
Kind::Region => {}
|
||||||
|
Kind::Phi => {}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -692,9 +701,11 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
write!(f, "{}: return [{:?}] ", node, self[node].inputs[0])?;
|
write!(f, "{}: return [{:?}] ", node, self[node].inputs[0])?;
|
||||||
self.fmt(f, self[node].inputs[1], rcs)?;
|
if self[node].inputs[2] != NILL {
|
||||||
|
self.fmt(f, self[node].inputs[2], rcs)?;
|
||||||
|
}
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
self.fmt(f, self[node].inputs[2], rcs)?;
|
self.fmt(f, self[node].inputs[1], rcs)?;
|
||||||
}
|
}
|
||||||
Kind::ConstInt { value } => write!(f, "{}", value)?,
|
Kind::ConstInt { value } => write!(f, "{}", value)?,
|
||||||
Kind::End => {
|
Kind::End => {
|
||||||
|
@ -744,6 +755,9 @@ impl Nodes {
|
||||||
write!(f, "call{node}")?;
|
write!(f, "call{node}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Kind::If => todo!(),
|
||||||
|
Kind::Region => todo!(),
|
||||||
|
Kind::Phi => todo!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -799,8 +813,11 @@ enum PoolSlot {
|
||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
Start,
|
Start,
|
||||||
End,
|
End,
|
||||||
|
If,
|
||||||
|
Region,
|
||||||
Return,
|
Return,
|
||||||
ConstInt { value: i64 },
|
ConstInt { value: i64 },
|
||||||
|
Phi,
|
||||||
Tuple { index: u32 },
|
Tuple { index: u32 },
|
||||||
BinOp { op: lexer::TokenKind },
|
BinOp { op: lexer::TokenKind },
|
||||||
Call { func: ty::Func, args: Vec<Nid> },
|
Call { func: ty::Func, args: Vec<Nid> },
|
||||||
|
@ -871,6 +888,7 @@ struct Loop {
|
||||||
break_relocs: Vec<Reloc>,
|
break_relocs: Vec<Reloc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct Variable {
|
struct Variable {
|
||||||
id: Ident,
|
id: Ident,
|
||||||
value: Nid,
|
value: Nid,
|
||||||
|
@ -887,7 +905,9 @@ struct ItemCtx {
|
||||||
nodes: Nodes,
|
nodes: Nodes,
|
||||||
start: Nid,
|
start: Nid,
|
||||||
end: Nid,
|
end: Nid,
|
||||||
cfg: Nid,
|
ctrl: Nid,
|
||||||
|
|
||||||
|
call_count: usize,
|
||||||
|
|
||||||
loops: Vec<Loop>,
|
loops: Vec<Loop>,
|
||||||
vars: Vec<Variable>,
|
vars: Vec<Variable>,
|
||||||
|
@ -1313,7 +1333,7 @@ impl Codegen {
|
||||||
|
|
||||||
(g.offset, (file.ident_str(g.name), self.tys.size_of(g.ty), DisasmItem::Global))
|
(g.offset, (file.ident_str(g.name), self.tys.size_of(g.ty), DisasmItem::Global))
|
||||||
}))
|
}))
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
crate::disasm(&mut sluce, &functions, output, |_| {})
|
crate::disasm(&mut sluce, &functions, output, |_| {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,7 +1400,74 @@ impl Codegen {
|
||||||
self.ci.nodes.new_node(ty::bin_ret(ty, op), Kind::BinOp { op }, [lhs, rhs]);
|
self.ci.nodes.new_node(ty::bin_ret(ty, op), Kind::BinOp { op }, [lhs, rhs]);
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
|
Expr::If { pos, cond, then, else_ } => {
|
||||||
|
let cond = self.expr_ctx(cond, Ctx::default().with_ty(ty::BOOL))?;
|
||||||
|
|
||||||
|
let if_node = self.ci.nodes.new_node(ty::VOID, Kind::If, [self.ci.ctrl, cond]);
|
||||||
|
|
||||||
|
'b: {
|
||||||
|
let branch = match self.tof(if_node).expand().inner() {
|
||||||
|
ty::LEFT_UNREACHABLE => else_,
|
||||||
|
ty::RIGHT_UNREACHABLE => Some(then),
|
||||||
|
_ => break 'b,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.ci.nodes.lock(self.ci.ctrl);
|
||||||
|
self.ci.nodes.remove(if_node);
|
||||||
|
self.ci.nodes.unlock(self.ci.ctrl);
|
||||||
|
|
||||||
|
if let Some(branch) = branch {
|
||||||
|
return self.expr(branch);
|
||||||
|
} else {
|
||||||
|
return Some(NILL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let else_scope = self.ci.vars.clone();
|
||||||
|
|
||||||
|
self.ci.ctrl =
|
||||||
|
self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 0 }, [if_node]);
|
||||||
|
let lcntrl = self.expr(then).map_or(NILL, |_| self.ci.ctrl);
|
||||||
|
|
||||||
|
let then_scope = std::mem::replace(&mut self.ci.vars, else_scope);
|
||||||
|
self.ci.ctrl =
|
||||||
|
self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 1 }, [if_node]);
|
||||||
|
let rcntrl = if let Some(else_) = else_ {
|
||||||
|
self.expr(else_).map_or(NILL, |_| self.ci.ctrl)
|
||||||
|
} else {
|
||||||
|
self.ci.ctrl
|
||||||
|
};
|
||||||
|
|
||||||
|
if lcntrl == NILL && rcntrl == NILL {
|
||||||
|
return None;
|
||||||
|
} else if lcntrl == NILL {
|
||||||
|
return Some(NILL);
|
||||||
|
} else if rcntrl == NILL {
|
||||||
|
self.ci.vars = then_scope;
|
||||||
|
return Some(NILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
let region = self.ci.nodes.new_node(ty::VOID, Kind::Region, [lcntrl, rcntrl]);
|
||||||
|
|
||||||
|
for (else_var, then_var) in self.ci.vars.iter_mut().zip(then_scope) {
|
||||||
|
if else_var.value == then_var.value {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ty = self.ci.nodes[else_var.value].ty;
|
||||||
|
debug_assert_eq!(
|
||||||
|
ty, self.ci.nodes[then_var.value].ty,
|
||||||
|
"TODO: typecheck properly"
|
||||||
|
);
|
||||||
|
|
||||||
|
let inps = [region, then_var.value, else_var.value];
|
||||||
|
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(NILL)
|
||||||
|
}
|
||||||
Expr::Call { func: &Expr::Ident { pos, id, name, .. }, args, .. } => {
|
Expr::Call { func: &Expr::Ident { pos, id, name, .. }, args, .. } => {
|
||||||
|
self.ci.call_count += 1;
|
||||||
let func = self.find_or_declare(pos, self.ci.file, Some(id), name);
|
let func = self.find_or_declare(pos, self.ci.file, Some(id), name);
|
||||||
let ty::Kind::Func(func) = func else {
|
let ty::Kind::Func(func) = func else {
|
||||||
self.report(
|
self.report(
|
||||||
|
@ -1416,28 +1503,38 @@ impl Codegen {
|
||||||
let mut inps = vec![];
|
let mut inps = vec![];
|
||||||
for ((arg, _carg), tyx) in args.iter().zip(cargs).zip(sig.args.range()) {
|
for ((arg, _carg), tyx) in args.iter().zip(cargs).zip(sig.args.range()) {
|
||||||
let ty = self.tys.args[tyx];
|
let ty = self.tys.args[tyx];
|
||||||
|
if self.tys.size_of(ty) == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
let value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||||
_ = self.assert_ty(arg.pos(), self.tof(value), ty, true);
|
_ = self.assert_ty(arg.pos(), self.tof(value), ty, true);
|
||||||
inps.push(value);
|
inps.push(value);
|
||||||
}
|
}
|
||||||
self.ci.cfg =
|
self.ci.ctrl =
|
||||||
self.ci
|
self.ci
|
||||||
.nodes
|
.nodes
|
||||||
.new_node(sig.ret, Kind::Call { func, args: inps.clone() }, [self.ci.cfg]);
|
.new_node(sig.ret, Kind::Call { func, args: inps.clone() }, [self.ci.ctrl]);
|
||||||
self.ci.nodes.add_deps(self.ci.cfg, &inps);
|
self.ci.nodes.add_deps(self.ci.ctrl, &inps);
|
||||||
|
|
||||||
Some(self.ci.cfg)
|
Some(self.ci.ctrl)
|
||||||
}
|
}
|
||||||
Expr::Return { pos, val } => {
|
Expr::Return { pos, val } => {
|
||||||
let ty = if let Some(val) = val {
|
let (ty, value) = if let Some(val) = val {
|
||||||
let value = self.expr_ctx(val, Ctx { ty: self.ci.ret })?;
|
let value = self.expr_ctx(val, Ctx { ty: self.ci.ret })?;
|
||||||
let inps = [self.ci.cfg, value, self.ci.end];
|
|
||||||
self.ci.cfg = self.ci.nodes.new_node(ty::VOID, Kind::Return, inps);
|
(self.tof(value), value)
|
||||||
self.tof(value)
|
|
||||||
} else {
|
} else {
|
||||||
ty::VOID.into()
|
(ty::VOID.into(), NILL)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if value == NILL {
|
||||||
|
let inps = [self.ci.ctrl, self.ci.end];
|
||||||
|
self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Return, inps);
|
||||||
|
} else {
|
||||||
|
let inps = [self.ci.ctrl, self.ci.end, value];
|
||||||
|
self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Return, inps);
|
||||||
|
}
|
||||||
|
|
||||||
let expected = *self.ci.ret.get_or_insert(ty);
|
let expected = *self.ci.ret.get_or_insert(ty);
|
||||||
_ = self.assert_ty(pos, ty, expected, true);
|
_ = self.assert_ty(pos, ty, expected, true);
|
||||||
|
|
||||||
|
@ -1494,7 +1591,8 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_task(&mut self, FTask { file, id }: FTask) {
|
fn handle_task(&mut self, FTask { file, id }: FTask) {
|
||||||
let func = &self.tys.funcs[id as usize];
|
let func = &mut self.tys.funcs[id as usize];
|
||||||
|
func.offset = u32::MAX - 1;
|
||||||
debug_assert!(func.file == file);
|
debug_assert!(func.file == file);
|
||||||
let sig = func.sig.unwrap();
|
let sig = func.sig.unwrap();
|
||||||
let ast = self.files[file as usize].clone();
|
let ast = self.files[file as usize].clone();
|
||||||
|
@ -1510,7 +1608,7 @@ impl Codegen {
|
||||||
|
|
||||||
self.ci.start = self.ci.nodes.new_node(ty::VOID, Kind::Start, []);
|
self.ci.start = self.ci.nodes.new_node(ty::VOID, Kind::Start, []);
|
||||||
self.ci.end = self.ci.nodes.new_node(ty::VOID, Kind::End, []);
|
self.ci.end = self.ci.nodes.new_node(ty::VOID, Kind::End, []);
|
||||||
self.ci.cfg = self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 0 }, [self.ci.start]);
|
self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Tuple { index: 0 }, [self.ci.start]);
|
||||||
|
|
||||||
let Expr::BinOp {
|
let Expr::BinOp {
|
||||||
left: Expr::Ident { .. },
|
left: Expr::Ident { .. },
|
||||||
|
@ -1574,6 +1672,18 @@ impl Codegen {
|
||||||
|
|
||||||
self.emit_control(self.ci.nodes[self.ci.start].outputs[0]);
|
self.emit_control(self.ci.nodes[self.ci.start].outputs[0]);
|
||||||
|
|
||||||
|
if let Some(last_ret) = self.ci.ret_relocs.last()
|
||||||
|
&& last_ret.offset as usize == self.ci.code.len() - 5
|
||||||
|
{
|
||||||
|
self.ci.code.truncate(self.ci.code.len() - 5);
|
||||||
|
self.ci.ret_relocs.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
let end = self.ci.code.len();
|
||||||
|
for ret_rel in self.ci.ret_relocs.drain(..) {
|
||||||
|
ret_rel.apply_jump(&mut self.ci.code, end as _, 0);
|
||||||
|
}
|
||||||
|
|
||||||
'_close_function: {
|
'_close_function: {
|
||||||
let pushed = self.ci.regs.pushed_size() as i64;
|
let pushed = self.ci.regs.pushed_size() as i64;
|
||||||
let stack = 0;
|
let stack = 0;
|
||||||
|
@ -1593,29 +1703,27 @@ impl Codegen {
|
||||||
self.pool.cis.push(std::mem::replace(&mut self.ci, prev_ci));
|
self.pool.cis.push(std::mem::replace(&mut self.ci, prev_ci));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_control(&mut self, mut ctrl: Nid) {
|
fn emit_control(&mut self, mut ctrl: Nid) -> Option<Nid> {
|
||||||
loop {
|
loop {
|
||||||
match self.ci.nodes[ctrl].kind.clone() {
|
match self.ci.nodes[ctrl].kind.clone() {
|
||||||
Kind::Start => unreachable!(),
|
Kind::Start => unreachable!(),
|
||||||
Kind::End => unreachable!(),
|
Kind::End => unreachable!(),
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
let ret_loc = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
if let Some(&ret) = self.ci.nodes[ctrl].inputs().get(2) {
|
||||||
0 => Loc::default(),
|
let ret_loc = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
||||||
1..=8 => Loc { reg: 1u8.into() },
|
0 => Loc::default(),
|
||||||
s => todo!("{s}"),
|
1..=8 => Loc { reg: 1u8.into() },
|
||||||
};
|
s => todo!("{s}"),
|
||||||
|
};
|
||||||
let dst = self.emit_expr(
|
let dst = self.emit_expr(ret, GenCtx::default().with_loc(ret_loc));
|
||||||
self.ci.nodes[ctrl].inputs[1],
|
self.ci.free_loc(dst);
|
||||||
GenCtx::default().with_loc(ret_loc),
|
}
|
||||||
);
|
self.ci.ret_relocs.push(Reloc::new(self.ci.code.len(), 1, 4));
|
||||||
self.ci.free_loc(dst);
|
self.ci.emit(instrs::jmp(0));
|
||||||
|
break None;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Kind::ConstInt { .. } => unreachable!(),
|
Kind::ConstInt { .. } => unreachable!(),
|
||||||
Kind::Tuple { index } => {
|
Kind::Tuple { .. } => {
|
||||||
debug_assert!(index == 0);
|
|
||||||
ctrl = self.ci.nodes[ctrl].outputs[0];
|
ctrl = self.ci.nodes[ctrl].outputs[0];
|
||||||
}
|
}
|
||||||
Kind::BinOp { .. } => unreachable!(),
|
Kind::BinOp { .. } => unreachable!(),
|
||||||
|
@ -1633,12 +1741,6 @@ impl Codegen {
|
||||||
self.ci.free_loc(dst);
|
self.ci.free_loc(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_loc = match self.tys.size_of(ret) {
|
|
||||||
0 => Loc::default(),
|
|
||||||
1..=8 => Loc { reg: 1u8.into() },
|
|
||||||
s => todo!("{s}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let reloc = Reloc::new(self.ci.code.len(), 3, 4);
|
let reloc = Reloc::new(self.ci.code.len(), 3, 4);
|
||||||
self.ci
|
self.ci
|
||||||
.relocs
|
.relocs
|
||||||
|
@ -1646,12 +1748,30 @@ impl Codegen {
|
||||||
self.ci.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
self.ci.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
||||||
self.make_func_reachable(func);
|
self.make_func_reachable(func);
|
||||||
|
|
||||||
// TODO: allocate return register
|
self.ci.call_count -= 1;
|
||||||
let loc = Loc { reg: self.ci.regs.allocate() };
|
|
||||||
self.ci.emit(instrs::cp(loc.reg.get(), ret_loc.reg.get()));
|
|
||||||
|
|
||||||
self.ci.nodes[ctrl].loc = loc;
|
'b: {
|
||||||
self.ci.nodes[ctrl].lock_rc += 1;
|
let ret_loc = match self.tys.size_of(ret) {
|
||||||
|
0 => break 'b,
|
||||||
|
1..=8 => Loc { reg: 1u8.into() },
|
||||||
|
s => todo!("{s}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.ci.nodes[ctrl].outputs.len() == 1 {
|
||||||
|
break 'b;
|
||||||
|
}
|
||||||
|
|
||||||
|
let loc;
|
||||||
|
if self.ci.call_count != 0 {
|
||||||
|
loc = Loc { reg: self.ci.regs.allocate() };
|
||||||
|
self.ci.emit(instrs::cp(loc.reg.get(), ret_loc.reg.get()));
|
||||||
|
} else {
|
||||||
|
loc = ret_loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ci.nodes[ctrl].loc = loc;
|
||||||
|
self.ci.nodes[ctrl].lock_rc += 1;
|
||||||
|
}
|
||||||
|
|
||||||
ctrl = *self.ci.nodes[ctrl]
|
ctrl = *self.ci.nodes[ctrl]
|
||||||
.outputs
|
.outputs
|
||||||
|
@ -1659,6 +1779,106 @@ impl Codegen {
|
||||||
.find(|&&o| self.ci.nodes.is_cfg(o))
|
.find(|&&o| self.ci.nodes.is_cfg(o))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
Kind::If => {
|
||||||
|
let cond = self.ci.nodes[ctrl].inputs[1];
|
||||||
|
|
||||||
|
let jump_offset: i64;
|
||||||
|
match self.ci.nodes[cond].kind {
|
||||||
|
Kind::BinOp { op: TokenKind::Le } => {
|
||||||
|
let [left, right, ..] = self.ci.nodes[cond].inputs;
|
||||||
|
let ldst = self.emit_expr(left, GenCtx::default());
|
||||||
|
let rdst = self.emit_expr(right, GenCtx::default());
|
||||||
|
jump_offset = self.ci.code.len() as _;
|
||||||
|
let op = if self.ci.nodes[left].ty.is_signed() {
|
||||||
|
instrs::jgts
|
||||||
|
} else {
|
||||||
|
instrs::jgtu
|
||||||
|
};
|
||||||
|
self.ci.emit(op(
|
||||||
|
self.ci.nodes[left].loc.reg.get(),
|
||||||
|
self.ci.nodes[right].loc.reg.get(),
|
||||||
|
0,
|
||||||
|
));
|
||||||
|
self.ci.free_loc(ldst);
|
||||||
|
self.ci.free_loc(rdst);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let cdst = self.emit_expr(cond, GenCtx::default());
|
||||||
|
let cond = self.ci.nodes[cond].loc.reg.get();
|
||||||
|
jump_offset = self.ci.code.len() as _;
|
||||||
|
self.ci.emit(instrs::jeq(cond, reg::ZERO, 0));
|
||||||
|
self.ci.free_loc(cdst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let left_unreachable = self.emit_control(self.ci.nodes[ctrl].outputs[0]);
|
||||||
|
let mut skip_then_offset = self.ci.code.len() as i64;
|
||||||
|
if let Some(region) = left_unreachable {
|
||||||
|
for i in 0..self.ci.nodes[region].outputs.len() {
|
||||||
|
let o = self.ci.nodes[region].outputs[i];
|
||||||
|
if self.ci.nodes[o].kind != Kind::Phi {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let out = self.ci.nodes[o].inputs[1];
|
||||||
|
let dst = self.emit_expr(out, GenCtx::default());
|
||||||
|
self.ci.nodes[o].loc = dst.unwrap_or_else(|| {
|
||||||
|
let reg = self.ci.regs.allocate();
|
||||||
|
self.ci
|
||||||
|
.emit(instrs::cp(reg.get(), self.ci.nodes[out].loc.reg.get()));
|
||||||
|
Loc { reg }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ci.emit(instrs::jmp(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let right_base = self.ci.code.len();
|
||||||
|
let right_unreachable = self.emit_control(self.ci.nodes[ctrl].outputs[1]);
|
||||||
|
if let Some(region) = left_unreachable {
|
||||||
|
for i in 0..self.ci.nodes[region].outputs.len() {
|
||||||
|
let o = self.ci.nodes[region].outputs[i];
|
||||||
|
if self.ci.nodes[o].kind != Kind::Phi {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let out = self.ci.nodes[o].inputs[2];
|
||||||
|
// TODO: this can be improved if we juggle ownership of the Phi inputs
|
||||||
|
let dst = self.emit_expr(out, GenCtx::default());
|
||||||
|
self.ci.free_loc(dst);
|
||||||
|
self.ci.emit(instrs::cp(
|
||||||
|
self.ci.nodes[o].loc.reg.get(),
|
||||||
|
self.ci.nodes[out].loc.reg.get(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let right_end = self.ci.code.len();
|
||||||
|
if right_base == right_end {
|
||||||
|
self.ci.code.truncate(skip_then_offset as _);
|
||||||
|
} else {
|
||||||
|
write_reloc(
|
||||||
|
&mut self.ci.code,
|
||||||
|
skip_then_offset as usize + 1,
|
||||||
|
right_end as i64 - skip_then_offset,
|
||||||
|
4,
|
||||||
|
);
|
||||||
|
skip_then_offset += instrs::jmp(69).0 as i64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_reloc(
|
||||||
|
&mut self.ci.code,
|
||||||
|
jump_offset as usize + 3,
|
||||||
|
skip_then_offset - jump_offset,
|
||||||
|
2,
|
||||||
|
);
|
||||||
|
|
||||||
|
if left_unreachable.is_none() && right_unreachable.is_none() {
|
||||||
|
break None;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(left_unreachable, right_unreachable);
|
||||||
|
}
|
||||||
|
Kind::Region => break Some(ctrl),
|
||||||
|
Kind::Phi => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1685,28 +1905,46 @@ impl Codegen {
|
||||||
let ty = self.tof(expr);
|
let ty = self.tof(expr);
|
||||||
let [left, right, ..] = self.ci.nodes[expr].inputs;
|
let [left, right, ..] = self.ci.nodes[expr].inputs;
|
||||||
let mut ldst = self.emit_expr(left, GenCtx::default());
|
let mut ldst = self.emit_expr(left, GenCtx::default());
|
||||||
let mut rdst = self.emit_expr(right, GenCtx::default());
|
|
||||||
|
|
||||||
let op = Self::math_op(op, ty.is_signed(), self.tys.size_of(ty))
|
if let Kind::ConstInt { value } = self.ci.nodes[right].kind
|
||||||
.expect("TODO: what now?");
|
&& let Some(op) = Self::imm_math_op(op, ty.is_signed(), self.tys.size_of(ty))
|
||||||
|
{
|
||||||
|
let loc = ctx
|
||||||
|
.loc
|
||||||
|
.or_else(|| ldst.take())
|
||||||
|
.unwrap_or_else(|| Loc { reg: self.ci.regs.allocate() });
|
||||||
|
|
||||||
let loc = ctx
|
self.ci.free_loc(ldst);
|
||||||
.loc
|
|
||||||
.or_else(|| ldst.take())
|
|
||||||
.or_else(|| rdst.take())
|
|
||||||
.unwrap_or_else(|| Loc { reg: self.ci.regs.allocate() });
|
|
||||||
|
|
||||||
self.ci.free_loc(ldst);
|
self.ci.emit(op(loc.reg.get(), self.ci.nodes[left].loc.reg.get(), value as _));
|
||||||
self.ci.free_loc(rdst);
|
self.ci.nodes[expr].loc = loc;
|
||||||
|
} else {
|
||||||
|
let mut rdst = self.emit_expr(right, GenCtx::default());
|
||||||
|
|
||||||
self.ci.emit(op(
|
let op = Self::math_op(op, ty.is_signed(), self.tys.size_of(ty))
|
||||||
loc.reg.get(),
|
.expect("TODO: what now?");
|
||||||
self.ci.nodes[left].loc.reg.get(),
|
|
||||||
self.ci.nodes[right].loc.reg.get(),
|
let loc = ctx
|
||||||
));
|
.loc
|
||||||
self.ci.nodes[expr].loc = loc;
|
.or_else(|| ldst.take())
|
||||||
|
.or_else(|| rdst.take())
|
||||||
|
.unwrap_or_else(|| Loc { reg: self.ci.regs.allocate() });
|
||||||
|
|
||||||
|
self.ci.free_loc(ldst);
|
||||||
|
self.ci.free_loc(rdst);
|
||||||
|
|
||||||
|
self.ci.emit(op(
|
||||||
|
loc.reg.get(),
|
||||||
|
self.ci.nodes[left].loc.reg.get(),
|
||||||
|
self.ci.nodes[right].loc.reg.get(),
|
||||||
|
));
|
||||||
|
self.ci.nodes[expr].loc = loc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Kind::Call { .. } => {}
|
Kind::Call { .. } => {}
|
||||||
|
Kind::If => todo!(),
|
||||||
|
Kind::Region => todo!(),
|
||||||
|
Kind::Phi => todo!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.nodes[expr].lock_rc += 1;
|
self.ci.nodes[expr].lock_rc += 1;
|
||||||
|
@ -1718,6 +1956,45 @@ impl Codegen {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn imm_math_op(
|
||||||
|
op: TokenKind,
|
||||||
|
signed: bool,
|
||||||
|
size: u32,
|
||||||
|
) -> Option<fn(u8, u8, u64) -> (usize, [u8; instrs::MAX_SIZE])> {
|
||||||
|
use {instrs::*, TokenKind as T};
|
||||||
|
|
||||||
|
macro_rules! def_op {
|
||||||
|
($name:ident |$a:ident, $b:ident, $c:ident| $($tt:tt)*) => {
|
||||||
|
macro_rules! $name {
|
||||||
|
($$($$op:ident),*) => {
|
||||||
|
[$$(
|
||||||
|
|$a, $b, $c: u64| $$op($($tt)*),
|
||||||
|
)*]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
def_op!(basic_op | a, b, c | a, b, c as _);
|
||||||
|
def_op!(sub_op | a, b, c | a, b, c.wrapping_neg() as _);
|
||||||
|
|
||||||
|
let ops = match op {
|
||||||
|
T::Add => basic_op!(addi8, addi16, addi32, addi64),
|
||||||
|
T::Sub => sub_op!(addi8, addi16, addi32, addi64),
|
||||||
|
T::Mul => basic_op!(muli8, muli16, muli32, muli64),
|
||||||
|
T::Band => return Some(andi),
|
||||||
|
T::Bor => return Some(ori),
|
||||||
|
T::Xor => return Some(xori),
|
||||||
|
T::Shr if signed => basic_op!(srui8, srui16, srui32, srui64),
|
||||||
|
T::Shr => basic_op!(srui8, srui16, srui32, srui64),
|
||||||
|
T::Shl => basic_op!(slui8, slui16, slui32, slui64),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(ops[size.ilog2() as usize])
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn math_op(
|
fn math_op(
|
||||||
op: TokenKind,
|
op: TokenKind,
|
||||||
|
@ -1788,8 +2065,8 @@ impl Codegen {
|
||||||
if let Some(existing) = self.tys.syms.get(&SymKey { file, ident }) {
|
if let Some(existing) = self.tys.syms.get(&SymKey { file, ident }) {
|
||||||
if let ty::Kind::Func(id) = existing.expand()
|
if let ty::Kind::Func(id) = existing.expand()
|
||||||
&& let func = &mut self.tys.funcs[id as usize]
|
&& let func = &mut self.tys.funcs[id as usize]
|
||||||
&& func.offset != u32::MAX
|
|
||||||
&& let Err(idx) = task::unpack(func.offset)
|
&& let Err(idx) = task::unpack(func.offset)
|
||||||
|
&& idx < self.tasks.len()
|
||||||
{
|
{
|
||||||
func.offset = task::id(self.tasks.len());
|
func.offset = task::id(self.tasks.len());
|
||||||
let task = self.tasks[idx].take();
|
let task = self.tasks[idx].take();
|
||||||
|
@ -2104,8 +2381,8 @@ mod tests {
|
||||||
const_folding_with_arg => README;
|
const_folding_with_arg => README;
|
||||||
variables => README;
|
variables => README;
|
||||||
functions => README;
|
functions => README;
|
||||||
//comments => README;
|
comments => README;
|
||||||
//if_statements => README;
|
if_statements => README;
|
||||||
//loops => README;
|
//loops => README;
|
||||||
//fb_driver => README;
|
//fb_driver => README;
|
||||||
//pointers => README;
|
//pointers => README;
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
check_platform:
|
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
JAL r31, r0, :x86_fb_ptr
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -64d
|
ADDI64 r254, r254, -64d
|
||||||
ST r31, r254, 0a, 64h
|
ST r31, r254, 0a, 64h
|
||||||
|
@ -60,6 +53,13 @@ set_pixel:
|
||||||
LD r31, r254, 0a, 32h
|
LD r31, r254, 0a, 32h
|
||||||
ADDI64 r254, r254, 32d
|
ADDI64 r254, r254, 32d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
check_platform:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
JAL r31, r0, :x86_fb_ptr
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
x86_fb_ptr:
|
x86_fb_ptr:
|
||||||
ADDI64 r254, r254, -8d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 0a, 8h
|
ST r31, r254, 0a, 8h
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
add_two:
|
|
||||||
ADDI64 r254, r254, -16d
|
|
||||||
ST r31, r254, 0a, 16h
|
|
||||||
CP r32, r2
|
|
||||||
ADDI64 r32, r32, 2d
|
|
||||||
CP r1, r32
|
|
||||||
LD r31, r254, 0a, 16h
|
|
||||||
ADDI64 r254, r254, 16d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 0a, 24h
|
ST r31, r254, 0a, 24h
|
||||||
|
@ -21,6 +12,15 @@ main:
|
||||||
LD r31, r254, 0a, 24h
|
LD r31, r254, 0a, 24h
|
||||||
ADDI64 r254, r254, 24d
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
add_two:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
ST r31, r254, 0a, 16h
|
||||||
|
CP r32, r2
|
||||||
|
ADDI64 r32, r32, 2d
|
||||||
|
CP r1, r32
|
||||||
|
LD r31, r254, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
add_one:
|
add_one:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
ST r31, r254, 0a, 16h
|
ST r31, r254, 0a, 16h
|
||||||
|
|
|
@ -1,13 +1,3 @@
|
||||||
add:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
ADD32 r32, r32, r33
|
|
||||||
CP r1, r32
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 0a, 24h
|
ST r31, r254, 0a, 24h
|
||||||
|
@ -35,6 +25,16 @@ add:
|
||||||
LD r31, r254, 0a, 24h
|
LD r31, r254, 0a, 24h
|
||||||
ADDI64 r254, r254, 24d
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
add:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ST r31, r254, 0a, 24h
|
||||||
|
CP r32, r2
|
||||||
|
CP r33, r3
|
||||||
|
ADD32 r32, r32, r33
|
||||||
|
CP r1, r32
|
||||||
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
code size: 281
|
code size: 281
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,3 +1,39 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -72d
|
||||||
|
ST r31, r254, 48a, 24h
|
||||||
|
ADDI64 r1, r254, 0d
|
||||||
|
JAL r31, r0, :new
|
||||||
|
ADDI64 r32, r254, 0d
|
||||||
|
ADDI64 r33, r254, 24d
|
||||||
|
BMC r32, r33, 24h
|
||||||
|
ADDI64 r33, r254, 24d
|
||||||
|
CP r2, r33
|
||||||
|
LI64 r3, 69d
|
||||||
|
JAL r31, r0, :push
|
||||||
|
LD r33, r254, 24a, 8h
|
||||||
|
LD r32, r33, 0a, 8h
|
||||||
|
ADDI64 r33, r254, 24d
|
||||||
|
CP r2, r33
|
||||||
|
JAL r31, r0, :deinit
|
||||||
|
CP r1, r32
|
||||||
|
LD r31, r254, 48a, 24h
|
||||||
|
ADDI64 r254, r254, 72d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
deinit:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ST r31, r254, 0a, 24h
|
||||||
|
CP r32, r2
|
||||||
|
LD r2, r32, 0a, 8h
|
||||||
|
LD r33, r32, 16a, 8h
|
||||||
|
MULI64 r33, r33, 8d
|
||||||
|
CP r3, r33
|
||||||
|
LI64 r4, 8d
|
||||||
|
JAL r31, r0, :free
|
||||||
|
CP r1, r32
|
||||||
|
JAL r31, r0, :new
|
||||||
|
LD r31, r254, 0a, 24h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
free:
|
free:
|
||||||
ADDI64 r254, r254, -40d
|
ADDI64 r254, r254, -40d
|
||||||
ST r31, r254, 0a, 40h
|
ST r31, r254, 0a, 40h
|
||||||
|
@ -100,34 +136,6 @@ push:
|
||||||
4: LD r31, r254, 0a, 88h
|
4: LD r31, r254, 0a, 88h
|
||||||
ADDI64 r254, r254, 88d
|
ADDI64 r254, r254, 88d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
new:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r1
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 0a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 8a, 8h
|
|
||||||
LI64 r33, 0d
|
|
||||||
ST r33, r32, 16a, 8h
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
deinit:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r2
|
|
||||||
LD r2, r32, 0a, 8h
|
|
||||||
LD r33, r32, 16a, 8h
|
|
||||||
MULI64 r33, r33, 8d
|
|
||||||
CP r3, r33
|
|
||||||
LI64 r4, 8d
|
|
||||||
JAL r31, r0, :free
|
|
||||||
CP r1, r32
|
|
||||||
JAL r31, r0, :new
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
malloc:
|
malloc:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -32d
|
||||||
ST r31, r254, 0a, 32h
|
ST r31, r254, 0a, 32h
|
||||||
|
@ -141,26 +149,18 @@ malloc:
|
||||||
LD r31, r254, 0a, 32h
|
LD r31, r254, 0a, 32h
|
||||||
ADDI64 r254, r254, 32d
|
ADDI64 r254, r254, 32d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
new:
|
||||||
ADDI64 r254, r254, -72d
|
ADDI64 r254, r254, -24d
|
||||||
ST r31, r254, 48a, 24h
|
ST r31, r254, 0a, 24h
|
||||||
ADDI64 r1, r254, 0d
|
CP r32, r1
|
||||||
JAL r31, r0, :new
|
LI64 r33, 0d
|
||||||
ADDI64 r32, r254, 0d
|
ST r33, r32, 0a, 8h
|
||||||
ADDI64 r33, r254, 24d
|
LI64 r33, 0d
|
||||||
BMC r32, r33, 24h
|
ST r33, r32, 8a, 8h
|
||||||
ADDI64 r33, r254, 24d
|
LI64 r33, 0d
|
||||||
CP r2, r33
|
ST r33, r32, 16a, 8h
|
||||||
LI64 r3, 69d
|
LD r31, r254, 0a, 24h
|
||||||
JAL r31, r0, :push
|
ADDI64 r254, r254, 24d
|
||||||
LD r33, r254, 24a, 8h
|
|
||||||
LD r32, r33, 0a, 8h
|
|
||||||
ADDI64 r33, r254, 24d
|
|
||||||
CP r2, r33
|
|
||||||
JAL r31, r0, :deinit
|
|
||||||
CP r1, r32
|
|
||||||
LD r31, r254, 48a, 24h
|
|
||||||
ADDI64 r254, r254, 72d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 1470
|
code size: 1470
|
||||||
ret: 69
|
ret: 69
|
||||||
|
|
|
@ -1,96 +1,3 @@
|
||||||
integer:
|
|
||||||
ADDI64 r254, r254, -56d
|
|
||||||
ST r31, r254, 0a, 56h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r3
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 4d
|
|
||||||
ECA
|
|
||||||
CP r34, r1
|
|
||||||
CP r35, r32
|
|
||||||
LI64 r36, 0d
|
|
||||||
CMPS r35, r35, r36
|
|
||||||
CMPUI r35, r35, 0d
|
|
||||||
CP r36, r33
|
|
||||||
LI64 r37, 0d
|
|
||||||
CMPS r36, r36, r37
|
|
||||||
CMPUI r36, r36, 0d
|
|
||||||
OR r35, r35, r36
|
|
||||||
JEQ r35, r0, :0
|
|
||||||
CP r35, r34
|
|
||||||
CP r36, r32
|
|
||||||
SUB64 r33, r33, r36
|
|
||||||
ADDI64 r33, r33, 1d
|
|
||||||
DIRS64 r0, r35, r35, r33
|
|
||||||
ADD64 r35, r35, r32
|
|
||||||
CP r1, r35
|
|
||||||
JMP :1
|
|
||||||
0: CP r1, r34
|
|
||||||
1: LD r31, r254, 0a, 56h
|
|
||||||
ADDI64 r254, r254, 56d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
line:
|
|
||||||
ADDI64 r254, r254, -80d
|
|
||||||
ST r31, r254, 48a, 32h
|
|
||||||
ST r2, r254, 0a, 16h
|
|
||||||
ST r4, r254, 16a, 16h
|
|
||||||
ST r6, r254, 32a, 16h
|
|
||||||
CP r32, r8
|
|
||||||
LI64 r33, 1d
|
|
||||||
JEQ r33, r0, :0
|
|
||||||
LD r33, r254, 0a, 8h
|
|
||||||
LD r34, r254, 16a, 8h
|
|
||||||
CMPS r33, r33, r34
|
|
||||||
CMPUI r33, r33, 1d
|
|
||||||
NOT r33, r33
|
|
||||||
JEQ r33, r0, :1
|
|
||||||
JMP :1
|
|
||||||
1: JMP :2
|
|
||||||
0: LD r33, r254, 8a, 8h
|
|
||||||
LD r34, r254, 24a, 8h
|
|
||||||
CMPS r33, r33, r34
|
|
||||||
CMPUI r33, r33, 1d
|
|
||||||
NOT r33, r33
|
|
||||||
JEQ r33, r0, :2
|
|
||||||
JMP :2
|
|
||||||
2: LD r31, r254, 48a, 32h
|
|
||||||
ADDI64 r254, r254, 80d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
example:
|
|
||||||
ADDI64 r254, r254, -48d
|
|
||||||
ST r31, r254, 0a, 48h
|
|
||||||
LI64 r2, 3d
|
|
||||||
LI64 r3, 4d
|
|
||||||
ECA
|
|
||||||
CP r33, r1
|
|
||||||
LI64 r34, 0d
|
|
||||||
LI64 r35, 0d
|
|
||||||
CMPS r34, r34, r35
|
|
||||||
CMPUI r34, r34, 0d
|
|
||||||
LI64 r35, 1024d
|
|
||||||
LI64 r36, 0d
|
|
||||||
CMPS r35, r35, r36
|
|
||||||
CMPUI r35, r35, 0d
|
|
||||||
OR r34, r34, r35
|
|
||||||
JEQ r34, r0, :0
|
|
||||||
CP r34, r33
|
|
||||||
LI64 r35, 1024d
|
|
||||||
ADDI64 r35, r35, 0d
|
|
||||||
ADDI64 r35, r35, 1d
|
|
||||||
DIRS64 r0, r34, r34, r35
|
|
||||||
ADDI64 r34, r34, 0d
|
|
||||||
CP r32, r34
|
|
||||||
JMP :1
|
|
||||||
0: CP r32, r33
|
|
||||||
1: LI64 r2, 0d
|
|
||||||
LI64 r3, 768d
|
|
||||||
JAL r31, r0, :integer
|
|
||||||
CP r33, r1
|
|
||||||
CP r34, r32
|
|
||||||
JMP :2
|
|
||||||
2: LD r31, r254, 0a, 48h
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -64d
|
ADDI64 r254, r254, -64d
|
||||||
ST r31, r254, 48a, 16h
|
ST r31, r254, 48a, 16h
|
||||||
|
@ -133,6 +40,72 @@ main:
|
||||||
LD r31, r254, 48a, 16h
|
LD r31, r254, 48a, 16h
|
||||||
ADDI64 r254, r254, 64d
|
ADDI64 r254, r254, 64d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
example:
|
||||||
|
ADDI64 r254, r254, -48d
|
||||||
|
ST r31, r254, 0a, 48h
|
||||||
|
LI64 r2, 3d
|
||||||
|
LI64 r3, 4d
|
||||||
|
ECA
|
||||||
|
CP r33, r1
|
||||||
|
LI64 r34, 0d
|
||||||
|
LI64 r35, 0d
|
||||||
|
CMPS r34, r34, r35
|
||||||
|
CMPUI r34, r34, 0d
|
||||||
|
LI64 r35, 1024d
|
||||||
|
LI64 r36, 0d
|
||||||
|
CMPS r35, r35, r36
|
||||||
|
CMPUI r35, r35, 0d
|
||||||
|
OR r34, r34, r35
|
||||||
|
JEQ r34, r0, :0
|
||||||
|
CP r34, r33
|
||||||
|
LI64 r35, 1024d
|
||||||
|
ADDI64 r35, r35, 0d
|
||||||
|
ADDI64 r35, r35, 1d
|
||||||
|
DIRS64 r0, r34, r34, r35
|
||||||
|
ADDI64 r34, r34, 0d
|
||||||
|
CP r32, r34
|
||||||
|
JMP :1
|
||||||
|
0: CP r32, r33
|
||||||
|
1: LI64 r2, 0d
|
||||||
|
LI64 r3, 768d
|
||||||
|
JAL r31, r0, :integer
|
||||||
|
CP r33, r1
|
||||||
|
CP r34, r32
|
||||||
|
JMP :2
|
||||||
|
2: LD r31, r254, 0a, 48h
|
||||||
|
ADDI64 r254, r254, 48d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
integer:
|
||||||
|
ADDI64 r254, r254, -56d
|
||||||
|
ST r31, r254, 0a, 56h
|
||||||
|
CP r32, r2
|
||||||
|
CP r33, r3
|
||||||
|
LI64 r2, 3d
|
||||||
|
LI64 r3, 4d
|
||||||
|
ECA
|
||||||
|
CP r34, r1
|
||||||
|
CP r35, r32
|
||||||
|
LI64 r36, 0d
|
||||||
|
CMPS r35, r35, r36
|
||||||
|
CMPUI r35, r35, 0d
|
||||||
|
CP r36, r33
|
||||||
|
LI64 r37, 0d
|
||||||
|
CMPS r36, r36, r37
|
||||||
|
CMPUI r36, r36, 0d
|
||||||
|
OR r35, r35, r36
|
||||||
|
JEQ r35, r0, :0
|
||||||
|
CP r35, r34
|
||||||
|
CP r36, r32
|
||||||
|
SUB64 r33, r33, r36
|
||||||
|
ADDI64 r33, r33, 1d
|
||||||
|
DIRS64 r0, r35, r35, r33
|
||||||
|
ADD64 r35, r35, r32
|
||||||
|
CP r1, r35
|
||||||
|
JMP :1
|
||||||
|
0: CP r1, r34
|
||||||
|
1: LD r31, r254, 0a, 56h
|
||||||
|
ADDI64 r254, r254, 56d
|
||||||
|
JALA r0, r31, 0a
|
||||||
rect_line:
|
rect_line:
|
||||||
ADDI64 r254, r254, -112d
|
ADDI64 r254, r254, -112d
|
||||||
ST r31, r254, 48a, 64h
|
ST r31, r254, 48a, 64h
|
||||||
|
@ -179,6 +152,33 @@ rect_line:
|
||||||
1: LD r31, r254, 48a, 64h
|
1: LD r31, r254, 48a, 64h
|
||||||
ADDI64 r254, r254, 112d
|
ADDI64 r254, r254, 112d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
line:
|
||||||
|
ADDI64 r254, r254, -80d
|
||||||
|
ST r31, r254, 48a, 32h
|
||||||
|
ST r2, r254, 0a, 16h
|
||||||
|
ST r4, r254, 16a, 16h
|
||||||
|
ST r6, r254, 32a, 16h
|
||||||
|
CP r32, r8
|
||||||
|
LI64 r33, 1d
|
||||||
|
JEQ r33, r0, :0
|
||||||
|
LD r33, r254, 0a, 8h
|
||||||
|
LD r34, r254, 16a, 8h
|
||||||
|
CMPS r33, r33, r34
|
||||||
|
CMPUI r33, r33, 1d
|
||||||
|
NOT r33, r33
|
||||||
|
JEQ r33, r0, :1
|
||||||
|
JMP :1
|
||||||
|
1: JMP :2
|
||||||
|
0: LD r33, r254, 8a, 8h
|
||||||
|
LD r34, r254, 24a, 8h
|
||||||
|
CMPS r33, r33, r34
|
||||||
|
CMPUI r33, r33, 1d
|
||||||
|
NOT r33, r33
|
||||||
|
JEQ r33, r0, :2
|
||||||
|
JMP :2
|
||||||
|
2: LD r31, r254, 48a, 32h
|
||||||
|
ADDI64 r254, r254, 80d
|
||||||
|
JALA r0, r31, 0a
|
||||||
code size: 1521
|
code size: 1521
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,29 +1,3 @@
|
||||||
fib:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
CP r33, r32
|
|
||||||
LI64 r34, 2d
|
|
||||||
CMPS r33, r33, r34
|
|
||||||
CMPUI r33, r33, -1d
|
|
||||||
NOT r33, r33
|
|
||||||
JEQ r33, r0, :0
|
|
||||||
CP r1, r32
|
|
||||||
JMP :1
|
|
||||||
0: CP r33, r32
|
|
||||||
ADDI64 r33, r33, -1d
|
|
||||||
CP r2, r33
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r33, r1
|
|
||||||
ADDI64 r32, r32, -2d
|
|
||||||
CP r2, r32
|
|
||||||
JAL r31, r0, :fib
|
|
||||||
CP r32, r1
|
|
||||||
ADD64 r33, r33, r32
|
|
||||||
CP r1, r33
|
|
||||||
1: LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -26d
|
ADDI64 r254, r254, -26d
|
||||||
ST r31, r254, 2a, 24h
|
ST r31, r254, 2a, 24h
|
||||||
|
@ -72,6 +46,32 @@ fib_iter:
|
||||||
LD r31, r254, 0a, 48h
|
LD r31, r254, 0a, 48h
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 48d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
fib:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
CP r32, r2
|
||||||
|
CP r33, r32
|
||||||
|
LI64 r34, 2d
|
||||||
|
CMPS r33, r33, r34
|
||||||
|
CMPUI r33, r33, -1d
|
||||||
|
NOT r33, r33
|
||||||
|
JEQ r33, r0, :0
|
||||||
|
CP r1, r32
|
||||||
|
JMP :1
|
||||||
|
0: CP r33, r32
|
||||||
|
ADDI64 r33, r33, -1d
|
||||||
|
CP r2, r33
|
||||||
|
JAL r31, r0, :fib
|
||||||
|
CP r33, r1
|
||||||
|
ADDI64 r32, r32, -2d
|
||||||
|
CP r2, r32
|
||||||
|
JAL r31, r0, :fib
|
||||||
|
CP r32, r1
|
||||||
|
ADD64 r33, r33, r32
|
||||||
|
CP r1, r33
|
||||||
|
1: LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
code size: 518
|
code size: 518
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
foo:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
LI64 r1, 3d
|
||||||
|
ANDI r2, r2, -4294967296d
|
||||||
|
ORI r2, r2, 2d
|
||||||
|
ANDI r2, r2, 4294967295d
|
||||||
|
ORI r2, r2, 8589934592d
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -40d
|
ADDI64 r254, r254, -40d
|
||||||
ST r31, r254, 16a, 24h
|
ST r31, r254, 16a, 24h
|
||||||
|
@ -22,17 +33,6 @@ main:
|
||||||
LD r31, r254, 16a, 24h
|
LD r31, r254, 16a, 24h
|
||||||
ADDI64 r254, r254, 40d
|
ADDI64 r254, r254, 40d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
foo:
|
|
||||||
ADDI64 r254, r254, -8d
|
|
||||||
ST r31, r254, 0a, 8h
|
|
||||||
LI64 r1, 3d
|
|
||||||
ANDI r2, r2, -4294967296d
|
|
||||||
ORI r2, r2, 2d
|
|
||||||
ANDI r2, r2, 4294967295d
|
|
||||||
ORI r2, r2, 8589934592d
|
|
||||||
LD r31, r254, 0a, 8h
|
|
||||||
ADDI64 r254, r254, 8d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
code size: 320
|
code size: 320
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,14 +1,3 @@
|
||||||
pass:
|
|
||||||
ADDI64 r254, r254, -32d
|
|
||||||
ST r31, r254, 0a, 32h
|
|
||||||
CP r32, r2
|
|
||||||
LD r33, r32, 0a, 8h
|
|
||||||
LD r34, r32, 8a, 8h
|
|
||||||
SUB64 r33, r33, r34
|
|
||||||
CP r1, r33
|
|
||||||
LD r31, r254, 0a, 32h
|
|
||||||
ADDI64 r254, r254, 32d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -72d
|
ADDI64 r254, r254, -72d
|
||||||
ST r31, r254, 48a, 24h
|
ST r31, r254, 48a, 24h
|
||||||
|
@ -38,6 +27,17 @@ main:
|
||||||
1: LD r31, r254, 48a, 24h
|
1: LD r31, r254, 48a, 24h
|
||||||
ADDI64 r254, r254, 72d
|
ADDI64 r254, r254, 72d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
pass:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
CP r32, r2
|
||||||
|
LD r33, r32, 0a, 8h
|
||||||
|
LD r34, r32, 8a, 8h
|
||||||
|
SUB64 r33, r33, r34
|
||||||
|
CP r1, r33
|
||||||
|
LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
odher_pass:
|
odher_pass:
|
||||||
ADDI64 r254, r254, -40d
|
ADDI64 r254, r254, -40d
|
||||||
ST r31, r254, 0a, 40h
|
ST r31, r254, 0a, 40h
|
||||||
|
|
17
hblang/tests/son_tests_comments.txt
Normal file
17
hblang/tests/son_tests_comments.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
JAL r31, r0, :foo
|
||||||
|
LI64 r1, 0d
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
foo:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 143
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -1,34 +1,31 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -16d
|
||||||
ST r31, r254, 0a, 24h
|
ST r31, r254, 0a, 16h
|
||||||
LI64 r2, 10d
|
LI64 r2, 10d
|
||||||
JAL r31, r0, :add_one
|
JAL r31, r0, :add_one
|
||||||
CP r32, r1
|
CP r32, r1
|
||||||
LI64 r2, 20d
|
LI64 r2, 20d
|
||||||
JAL r31, r0, :add_two
|
JAL r31, r0, :add_two
|
||||||
CP r33, r1
|
ADD64 r1, r1, r32
|
||||||
ADD64 r1, r33, r32
|
LD r31, r254, 0a, 16h
|
||||||
LD r31, r254, 0a, 24h
|
ADDI64 r254, r254, 16d
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
|
||||||
add_one:
|
|
||||||
ADDI64 r254, r254, -24d
|
|
||||||
ST r31, r254, 0a, 24h
|
|
||||||
CP r32, r2
|
|
||||||
LI64 r33, 1d
|
|
||||||
ADD64 r1, r32, r33
|
|
||||||
LD r31, r254, 0a, 24h
|
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
add_two:
|
add_two:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -16d
|
||||||
ST r31, r254, 0a, 24h
|
ST r31, r254, 0a, 16h
|
||||||
CP r32, r2
|
CP r32, r2
|
||||||
LI64 r33, 2d
|
ADDI64 r1, r32, 2d
|
||||||
ADD64 r1, r32, r33
|
LD r31, r254, 0a, 16h
|
||||||
LD r31, r254, 0a, 24h
|
ADDI64 r254, r254, 16d
|
||||||
ADDI64 r254, r254, 24d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 263
|
add_one:
|
||||||
|
ADDI64 r254, r254, -16d
|
||||||
|
ST r31, r254, 0a, 16h
|
||||||
|
CP r32, r2
|
||||||
|
ADDI64 r1, r32, 1d
|
||||||
|
LD r31, r254, 0a, 16h
|
||||||
|
ADDI64 r254, r254, 16d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 254
|
||||||
ret: 33
|
ret: 33
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
28
hblang/tests/son_tests_if_statements.txt
Normal file
28
hblang/tests/son_tests_if_statements.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -8d
|
||||||
|
ST r31, r254, 0a, 8h
|
||||||
|
LI64 r2, 10d
|
||||||
|
JAL r31, r0, :fib
|
||||||
|
LD r31, r254, 0a, 8h
|
||||||
|
ADDI64 r254, r254, 8d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
fib:
|
||||||
|
ADDI64 r254, r254, -32d
|
||||||
|
ST r31, r254, 0a, 32h
|
||||||
|
CP r32, r2
|
||||||
|
LI64 r33, 2d
|
||||||
|
JGTS r32, r33, :0
|
||||||
|
LI64 r1, 1d
|
||||||
|
JMP :1
|
||||||
|
0: ADDI64 r2, r32, -1d
|
||||||
|
JAL r31, r0, :fib
|
||||||
|
CP r34, r1
|
||||||
|
ADDI64 r2, r32, -2d
|
||||||
|
JAL r31, r0, :fib
|
||||||
|
ADD64 r1, r1, r34
|
||||||
|
1: LD r31, r254, 0a, 32h
|
||||||
|
ADDI64 r254, r254, 32d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 219
|
||||||
|
ret: 55
|
||||||
|
status: Ok(())
|
Loading…
Reference in a new issue