implementing directives
This commit is contained in:
parent
0298b32e38
commit
bc817c4ea2
|
@ -273,7 +273,7 @@ main := fn(): int {
|
||||||
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))
|
||||||
ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6))
|
ecall_that_returns_int := @as(int, @eca(1, foo.Type.(10, 20), 5, 6))
|
||||||
embedded_array := @as([u8; 15], @embed("text.txt"))
|
embedded_array := @as(^[u8; 15], @embed("text.txt"))
|
||||||
return @inline(foo.foo)
|
return @inline(foo.foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ fib_iter := fn(n: int): int {
|
||||||
```hb
|
```hb
|
||||||
main := fn(): int {
|
main := fn(): int {
|
||||||
addr := @as(u16, 0x1FF)
|
addr := @as(u16, 0x1FF)
|
||||||
msg := [u8].(0, 0, @trunc(addr), @trunc(addr >> 8))
|
msg := [u8].(0, 0, @intcast(addr), @intcast(addr >> 8))
|
||||||
_force_stack := &msg
|
_force_stack := &msg
|
||||||
|
|
||||||
arr := [int].(1, 2, 4)
|
arr := [int].(1, 2, 4)
|
||||||
|
|
|
@ -107,6 +107,7 @@ mod ctx_map {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Key<T> {
|
pub struct Key<T> {
|
||||||
pub value: T,
|
pub value: T,
|
||||||
pub hash: Hash,
|
pub hash: Hash,
|
||||||
|
@ -125,6 +126,7 @@ mod ctx_map {
|
||||||
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a>;
|
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CtxMap<T> {
|
pub struct CtxMap<T> {
|
||||||
inner: hashbrown::HashMap<Key<T>, (), HashBuilder>,
|
inner: hashbrown::HashMap<Key<T>, (), HashBuilder>,
|
||||||
}
|
}
|
||||||
|
@ -263,6 +265,8 @@ mod ty {
|
||||||
pub type Module = u32;
|
pub type Module = u32;
|
||||||
pub type Slice = u32;
|
pub type Slice = u32;
|
||||||
|
|
||||||
|
pub const ECA: Func = Func::MAX;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Tuple(pub u32);
|
pub struct Tuple(pub u32);
|
||||||
|
|
||||||
|
@ -702,6 +706,7 @@ impl Default for Func {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct TypedReloc {
|
struct TypedReloc {
|
||||||
target: ty::Id,
|
target: ty::Id,
|
||||||
reloc: Reloc,
|
reloc: Reloc,
|
||||||
|
|
204
lang/src/son.rs
204
lang/src/son.rs
|
@ -22,6 +22,7 @@ use {
|
||||||
fmt::{self, Debug, Display, Write},
|
fmt::{self, Debug, Display, Write},
|
||||||
format_args as fa, mem,
|
format_args as fa, mem,
|
||||||
ops::{self},
|
ops::{self},
|
||||||
|
usize,
|
||||||
},
|
},
|
||||||
hashbrown::hash_map,
|
hashbrown::hash_map,
|
||||||
regalloc2::VReg,
|
regalloc2::VReg,
|
||||||
|
@ -55,6 +56,7 @@ impl crate::ctx_map::CtxEntry for Nid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct Nodes {
|
struct Nodes {
|
||||||
values: Vec<Result<Node, Nid>>,
|
values: Vec<Result<Node, Nid>>,
|
||||||
visited: BitSet,
|
visited: BitSet,
|
||||||
|
@ -500,7 +502,7 @@ impl Nodes {
|
||||||
Kind::BinOp { op } | Kind::UnOp { op } => {
|
Kind::BinOp { op } | Kind::UnOp { op } => {
|
||||||
write!(out, "{:>4}: ", op.name())
|
write!(out, "{:>4}: ", op.name())
|
||||||
}
|
}
|
||||||
Kind::Call { func } => {
|
Kind::Call { func, argc: _ } => {
|
||||||
write!(out, "call: {func} {} ", self[node].depth)
|
write!(out, "call: {func} {} ", self[node].depth)
|
||||||
}
|
}
|
||||||
Kind::Global { global } => write!(out, "glob: {global:<5}"),
|
Kind::Global { global } => write!(out, "glob: {global:<5}"),
|
||||||
|
@ -886,6 +888,7 @@ pub enum Kind {
|
||||||
// [ctrl, ...args]
|
// [ctrl, ...args]
|
||||||
Call {
|
Call {
|
||||||
func: ty::Func,
|
func: ty::Func,
|
||||||
|
argc: u32,
|
||||||
},
|
},
|
||||||
// [ctrl]
|
// [ctrl]
|
||||||
Idk,
|
Idk,
|
||||||
|
@ -975,6 +978,7 @@ type LoopDepth = u16;
|
||||||
type LockRc = u16;
|
type LockRc = u16;
|
||||||
type IDomDepth = u16;
|
type IDomDepth = u16;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
struct Loop {
|
struct Loop {
|
||||||
node: Nid,
|
node: Nid,
|
||||||
ctrl: [Nid; 2],
|
ctrl: [Nid; 2],
|
||||||
|
@ -1007,7 +1011,7 @@ impl Scope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
struct ItemCtx {
|
struct ItemCtx {
|
||||||
file: FileId,
|
file: FileId,
|
||||||
ret: Option<ty::Id>,
|
ret: Option<ty::Id>,
|
||||||
|
@ -1247,27 +1251,36 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Call { func } => {
|
Kind::Call { argc, func } => {
|
||||||
|
std::dbg!(node.ty.simple_size());
|
||||||
let (ret, mut parama) = tys.parama(node.ty);
|
let (ret, mut parama) = tys.parama(node.ty);
|
||||||
let mut allocs = allocs.iter();
|
debug_assert_eq!(
|
||||||
for ti in tys.ins.funcs[func as usize].sig.unwrap().args.range() {
|
allocs.len(),
|
||||||
let ty = tys.ins.args[ti];
|
argc as usize
|
||||||
|
+ !matches!(ret, PLoc::Reg(..) | PLoc::None) as usize
|
||||||
|
+ !matches!(ret, PLoc::None) as usize
|
||||||
|
);
|
||||||
|
for (&i, &arg) in node.inputs[1..][..argc as usize].iter().zip(&allocs[1..])
|
||||||
|
{
|
||||||
|
let ty = fuc.nodes[i].ty;
|
||||||
let (rg, size) = match parama.next(ty, tys) {
|
let (rg, size) = match parama.next(ty, tys) {
|
||||||
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
|
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
|
||||||
PLoc::WideReg(rg, size) => (rg, size),
|
PLoc::WideReg(rg, size) => (rg, size),
|
||||||
PLoc::None | PLoc::Ref(..) | PLoc::Reg(..) => continue,
|
PLoc::None | PLoc::Ref(..) | PLoc::Reg(..) => continue,
|
||||||
};
|
};
|
||||||
let &arg = allocs.next().unwrap();
|
|
||||||
if size > 8 {
|
|
||||||
allocs.next().unwrap();
|
|
||||||
}
|
|
||||||
self.emit(instrs::ld(rg, atr(arg), 0, size));
|
self.emit(instrs::ld(rg, atr(arg), 0, size));
|
||||||
}
|
}
|
||||||
self.relocs.push(TypedReloc {
|
|
||||||
target: ty::Kind::Func(func).compress(),
|
if func == ty::ECA {
|
||||||
reloc: Reloc::new(self.code.len(), 3, 4),
|
self.emit(instrs::eca());
|
||||||
});
|
} else {
|
||||||
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
self.relocs.push(TypedReloc {
|
||||||
|
target: ty::Kind::Func(func).compress(),
|
||||||
|
reloc: Reloc::new(self.code.len(), 3, 4),
|
||||||
|
});
|
||||||
|
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
||||||
|
}
|
||||||
|
|
||||||
if let PLoc::WideReg(r, size) = ret {
|
if let PLoc::WideReg(r, size) = ret {
|
||||||
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
||||||
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
||||||
|
@ -1482,6 +1495,20 @@ impl Pool {
|
||||||
self.used_cis -= 1;
|
self.used_cis -= 1;
|
||||||
core::mem::swap(&mut self.cis[self.used_cis], target);
|
core::mem::swap(&mut self.cis[self.used_cis], target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn save_ci(&mut self, ci: &ItemCtx) {
|
||||||
|
if let Some(slot) = self.cis.get_mut(self.used_cis) {
|
||||||
|
slot.clone_from(ci);
|
||||||
|
} else {
|
||||||
|
self.cis.push(ci.clone());
|
||||||
|
}
|
||||||
|
self.used_cis += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_ci(&mut self, dst: &mut ItemCtx) {
|
||||||
|
self.used_cis -= 1;
|
||||||
|
*dst = core::mem::take(&mut self.cis[self.used_cis]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Regalloc {
|
struct Regalloc {
|
||||||
|
@ -1566,9 +1593,11 @@ impl TypeParser for Codegen<'_> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(unused)]
|
|
||||||
fn infer_type(&mut self, expr: &Expr) -> ty::Id {
|
fn infer_type(&mut self, expr: &Expr) -> ty::Id {
|
||||||
todo!()
|
self.pool.save_ci(&self.ci);
|
||||||
|
let ty = self.expr(expr).map_or(ty::Id::NEVER, |v| v.ty);
|
||||||
|
self.pool.restore_ci(&mut self.ci);
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_reuse(&mut self, existing: ty::Id) {
|
fn on_reuse(&mut self, existing: ty::Id) {
|
||||||
|
@ -1672,6 +1701,17 @@ impl TypeParser for Codegen<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Codegen<'a> {
|
impl<'a> Codegen<'a> {
|
||||||
|
pub fn push_embeds(&mut self, embeds: Vec<Vec<u8>>) {
|
||||||
|
self.tys.ins.globals = embeds
|
||||||
|
.into_iter()
|
||||||
|
.map(|data| Global {
|
||||||
|
ty: self.tys.make_array(ty::Id::U8, data.len() as _),
|
||||||
|
data,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
|
||||||
fn store_mem(&mut self, region: Nid, value: Nid) -> Nid {
|
fn store_mem(&mut self, region: Nid, value: Nid) -> Nid {
|
||||||
if value == NEVER {
|
if value == NEVER {
|
||||||
return NEVER;
|
return NEVER;
|
||||||
|
@ -1980,6 +2020,11 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
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::Embed { id, .. } => {
|
||||||
|
let glob = &self.tys.ins.globals[id as usize];
|
||||||
|
let ty = self.tys.make_ptr(glob.ty);
|
||||||
|
Some(self.ci.nodes.new_node_lit(ty, Kind::Global { global: id }, [VOID]))
|
||||||
|
}
|
||||||
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
||||||
let ty = self.ty(ty);
|
let ty = self.ty(ty);
|
||||||
Some(self.ci.nodes.new_node_lit(
|
Some(self.ci.nodes.new_node_lit(
|
||||||
|
@ -1988,7 +2033,44 @@ impl<'a> Codegen<'a> {
|
||||||
[VOID],
|
[VOID],
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "trunc", args: [expr], pos } => {
|
Expr::Directive { name: "alignof", args: [ty], .. } => {
|
||||||
|
let ty = self.ty(ty);
|
||||||
|
Some(self.ci.nodes.new_node_lit(
|
||||||
|
ty::Id::INT,
|
||||||
|
Kind::CInt { value: self.tys.align_of(ty) as _ },
|
||||||
|
[VOID],
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Expr::Directive { name: "bitcast", args: [val], pos } => {
|
||||||
|
let mut val = self.raw_expr(val)?;
|
||||||
|
self.strip_var(&mut val);
|
||||||
|
|
||||||
|
let Some(ty) = ctx.ty else {
|
||||||
|
self.report(
|
||||||
|
pos,
|
||||||
|
"resulting type cannot be inferred from context, \
|
||||||
|
consider using `@as(<ty>, @bitcast(<expr>))` to hint the type",
|
||||||
|
);
|
||||||
|
return Value::NEVER;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (got, expected) = (self.tys.size_of(val.ty), self.tys.size_of(ty));
|
||||||
|
if got != expected {
|
||||||
|
self.report(
|
||||||
|
pos,
|
||||||
|
fa!(
|
||||||
|
"cast from '{}' to '{}' is not supported, \
|
||||||
|
sizes dont match ({got} != {expected})",
|
||||||
|
self.ty_display(val.ty),
|
||||||
|
self.ty_display(ty)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
val.ty = ty;
|
||||||
|
Some(val)
|
||||||
|
}
|
||||||
|
Expr::Directive { name: "intcast", args: [expr], pos } => {
|
||||||
let val = self.expr(expr)?;
|
let val = self.expr(expr)?;
|
||||||
|
|
||||||
if !val.ty.is_integer() {
|
if !val.ty.is_integer() {
|
||||||
|
@ -2006,7 +2088,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.report(
|
self.report(
|
||||||
pos,
|
pos,
|
||||||
"resulting integer cannot be inferred from context, \
|
"resulting integer cannot be inferred from context, \
|
||||||
consider using `@as(<int_ty>, @trunc(<expr>))` to hint the type",
|
consider using `@as(<int_ty>, @intcast(<expr>))` to hint the type",
|
||||||
);
|
);
|
||||||
return Value::NEVER;
|
return Value::NEVER;
|
||||||
};
|
};
|
||||||
|
@ -2031,6 +2113,59 @@ impl<'a> Codegen<'a> {
|
||||||
let ctx = Ctx::default().with_ty(self.ty(ty));
|
let ctx = Ctx::default().with_ty(self.ty(ty));
|
||||||
self.raw_expr_ctx(expr, ctx)
|
self.raw_expr_ctx(expr, ctx)
|
||||||
}
|
}
|
||||||
|
Expr::Directive { pos, name: "eca", args } => {
|
||||||
|
let Some(ty) = ctx.ty else {
|
||||||
|
self.report(
|
||||||
|
pos,
|
||||||
|
"return type cannot be inferred from context, \
|
||||||
|
consider using `@as(<return_ty>, @eca(<expr>...))` to hint the type",
|
||||||
|
);
|
||||||
|
return Value::NEVER;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut inps = Vc::from([self.ci.ctrl]);
|
||||||
|
for arg in args {
|
||||||
|
let value = self.expr(arg)?;
|
||||||
|
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||||
|
self.ci.nodes.lock(value.id);
|
||||||
|
inps.push(value.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for &n in inps.iter().skip(1) {
|
||||||
|
self.ci.nodes.unlock(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(str) = self.ci.scope.store.to_store() {
|
||||||
|
inps.push(str);
|
||||||
|
}
|
||||||
|
self.ci.scope.loads.retain(|&load| {
|
||||||
|
if inps.contains(&load) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.ci.nodes.unlock_remove(load) {
|
||||||
|
inps.push(load);
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
});
|
||||||
|
|
||||||
|
let alt_value = match ty.loc(&self.tys) {
|
||||||
|
Loc::Reg => None,
|
||||||
|
Loc::Stack => {
|
||||||
|
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
|
||||||
|
inps.push(stck);
|
||||||
|
Some(Value::ptr(stck).ty(ty))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let argc = args.len() as u32;
|
||||||
|
self.ci.ctrl = self.ci.nodes.new_node(ty, Kind::Call { func: ty::ECA, argc }, inps);
|
||||||
|
|
||||||
|
self.store_mem(VOID, VOID);
|
||||||
|
|
||||||
|
alt_value.or(Some(Value::new(self.ci.ctrl).ty(ty)))
|
||||||
|
}
|
||||||
Expr::Call { func, args, .. } => {
|
Expr::Call { func, args, .. } => {
|
||||||
self.ci.call_count += 1;
|
self.ci.call_count += 1;
|
||||||
let ty = self.ty(func);
|
let ty = self.ty(func);
|
||||||
|
@ -2100,7 +2235,8 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu }, inps);
|
let argc = args.len() as u32;
|
||||||
|
self.ci.ctrl = self.ci.nodes.new_node(sig.ret, Kind::Call { func: fu, argc }, inps);
|
||||||
|
|
||||||
self.store_mem(VOID, VOID);
|
self.store_mem(VOID, VOID);
|
||||||
|
|
||||||
|
@ -3107,21 +3243,19 @@ impl<'a> Function<'a> {
|
||||||
let ops = vec![self.drg(nid), self.urg(node.inputs[1])];
|
let ops = vec![self.drg(nid), self.urg(node.inputs[1])];
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
}
|
}
|
||||||
Kind::Call { func } => {
|
Kind::Call { argc, .. } => {
|
||||||
self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref;
|
self.nodes[nid].ralloc_backref = self.nodes[prev].ralloc_backref;
|
||||||
let mut ops = vec![];
|
let mut ops = vec![];
|
||||||
|
|
||||||
let fuc = self.tys.ins.funcs[func as usize].sig.unwrap();
|
let (ret, mut parama) = self.tys.parama(node.ty);
|
||||||
if self.tys.size_of(fuc.ret) != 0 {
|
if !matches!(ret, PLoc::None) {
|
||||||
ops.push(regalloc2::Operand::reg_fixed_def(
|
ops.push(regalloc2::Operand::reg_fixed_def(
|
||||||
self.rg(nid),
|
self.rg(nid),
|
||||||
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
for &(mut i) in node.inputs[1..][..argc as usize].iter() {
|
||||||
let (ret, mut parama) = self.tys.parama(fuc.ret);
|
let ty = self.nodes[i].ty;
|
||||||
for (ti, &(mut i)) in fuc.args.range().zip(node.inputs[1..].iter()) {
|
|
||||||
let ty = self.tys.ins.args[ti];
|
|
||||||
match parama.next(ty, self.tys) {
|
match parama.next(ty, self.tys) {
|
||||||
PLoc::None => {}
|
PLoc::None => {}
|
||||||
PLoc::Reg(r, _) => {
|
PLoc::Reg(r, _) => {
|
||||||
|
@ -3130,7 +3264,7 @@ impl<'a> Function<'a> {
|
||||||
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
PLoc::WideReg(r, _) => {
|
PLoc::WideReg(..) => {
|
||||||
loop {
|
loop {
|
||||||
match self.nodes[i].kind {
|
match self.nodes[i].kind {
|
||||||
Kind::Stre { .. } => i = self.nodes[i].inputs[2],
|
Kind::Stre { .. } => i = self.nodes[i].inputs[2],
|
||||||
|
@ -3140,14 +3274,7 @@ impl<'a> Function<'a> {
|
||||||
debug_assert_ne!(i, 0);
|
debug_assert_ne!(i, 0);
|
||||||
}
|
}
|
||||||
debug_assert!(i != 0);
|
debug_assert!(i != 0);
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
ops.push(self.urg(i));
|
||||||
self.rg(i),
|
|
||||||
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
|
||||||
));
|
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
|
||||||
self.rg(i),
|
|
||||||
regalloc2::PReg::new(r as usize + 1, regalloc2::RegClass::Int),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
PLoc::Ref(r, _) => {
|
PLoc::Ref(r, _) => {
|
||||||
loop {
|
loop {
|
||||||
|
@ -3594,8 +3721,9 @@ mod tests {
|
||||||
_ = log::set_logger(&crate::fs::Logger);
|
_ = log::set_logger(&crate::fs::Logger);
|
||||||
log::set_max_level(log::LevelFilter::Info);
|
log::set_max_level(log::LevelFilter::Info);
|
||||||
|
|
||||||
let (ref files, _embeds) = crate::test_parse_files(ident, input);
|
let (ref files, embeds) = crate::test_parse_files(ident, input);
|
||||||
let mut codegen = super::Codegen { files, ..Default::default() };
|
let mut codegen = super::Codegen { files, ..Default::default() };
|
||||||
|
codegen.push_embeds(embeds);
|
||||||
|
|
||||||
codegen.generate();
|
codegen.generate();
|
||||||
|
|
||||||
|
@ -3633,7 +3761,7 @@ mod tests {
|
||||||
hex_octal_binary_literals;
|
hex_octal_binary_literals;
|
||||||
//struct_operators;
|
//struct_operators;
|
||||||
global_variables;
|
global_variables;
|
||||||
//directives;
|
directives;
|
||||||
c_strings;
|
c_strings;
|
||||||
struct_patterns;
|
struct_patterns;
|
||||||
arrays;
|
arrays;
|
||||||
|
|
|
@ -266,7 +266,7 @@ struct AllocedVc {
|
||||||
base: Unique<Nid>,
|
base: Unique<Nid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub struct BitSet {
|
pub struct BitSet {
|
||||||
data: Vec<usize>,
|
data: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,40 +15,38 @@ main:
|
||||||
ST r3, r254, 12a, 4h
|
ST r3, r254, 12a, 4h
|
||||||
ST r8, r254, 0a, 4h
|
ST r8, r254, 0a, 4h
|
||||||
ST r9, r254, 4a, 4h
|
ST r9, r254, 4a, 4h
|
||||||
LD r1, r254, 0a, 8h
|
LD r12, r254, 0a, 8h
|
||||||
ST r1, r254, 16a, 8h
|
ST r12, r254, 16a, 8h
|
||||||
LD r3, r254, 20a, 4h
|
LD r3, r254, 20a, 4h
|
||||||
ANDI r3, r3, 4294967295d
|
ANDI r3, r3, 4294967295d
|
||||||
ANDI r9, r9, 4294967295d
|
ANDI r9, r9, 4294967295d
|
||||||
JEQ r3, r9, :0
|
JEQ r3, r9, :0
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r10, r12, 8d
|
0: LD r9, r254, 16a, 4h
|
||||||
ADDI64 r10, r10, -4d
|
ANDI r9, r9, 4294967295d
|
||||||
LD r1, r10, 0a, 4h
|
|
||||||
ANDI r1, r1, 4294967295d
|
|
||||||
ANDI r8, r8, 4294967295d
|
ANDI r8, r8, 4294967295d
|
||||||
JEQ r1, r8, :2
|
JEQ r9, r8, :2
|
||||||
LI64 r1, 64d
|
LI64 r1, 64d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LD r7, r254, 15a, 1h
|
2: LD r3, r254, 15a, 1h
|
||||||
ANDI r9, r7, 255d
|
ANDI r5, r3, 255d
|
||||||
LD r6, r254, 14a, 1h
|
LD r2, r254, 14a, 1h
|
||||||
ANDI r8, r6, 255d
|
ANDI r4, r2, 255d
|
||||||
LD r5, r254, 13a, 1h
|
LD r1, r254, 13a, 1h
|
||||||
ANDI r7, r5, 255d
|
ANDI r3, r1, 255d
|
||||||
LD r3, r254, 12a, 1h
|
LD r11, r254, 12a, 1h
|
||||||
ANDI r6, r3, 255d
|
ANDI r2, r11, 255d
|
||||||
LD r4, r254, 20a, 4h
|
LD r12, r254, 20a, 4h
|
||||||
LD r5, r254, 16a, 4h
|
LD r1, r254, 16a, 4h
|
||||||
ADD32 r10, r4, r5
|
ADD32 r6, r12, r1
|
||||||
ADD32 r11, r10, r6
|
ADD32 r7, r6, r2
|
||||||
ADD32 r3, r11, r7
|
ADD32 r11, r7, r3
|
||||||
ADD32 r7, r3, r8
|
ADD32 r3, r11, r4
|
||||||
ADD32 r11, r7, r9
|
ADD32 r7, r3, r5
|
||||||
ANDI r1, r11, 4294967295d
|
ANDI r1, r7, 4294967295d
|
||||||
1: ADDI64 r254, r254, 24d
|
1: ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 529
|
code size: 507
|
||||||
ret: 512
|
ret: 512
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
0
lang/tests/son_tests_directives.txt
Normal file
0
lang/tests/son_tests_directives.txt
Normal file
|
@ -1,26 +1,23 @@
|
||||||
drop:
|
drop:
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -48d
|
ADDI64 r254, r254, -32d
|
||||||
ST r31, r254, 8a, 40h
|
ST r31, r254, 8a, 24h
|
||||||
LI64 r32, 1d
|
LI64 r32, 1d
|
||||||
ADDI64 r33, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
ADDI64 r34, r33, 8000d
|
|
||||||
ADDI64 r34, r34, -8000d
|
|
||||||
ST r32, r254, 0a, 8h
|
ST r32, r254, 0a, 8h
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :modify
|
JAL r31, r0, :modify
|
||||||
CP r2, r32
|
CP r2, r32
|
||||||
JAL r31, r0, :drop
|
JAL r31, r0, :drop
|
||||||
LD r35, r34, 0a, 8h
|
LD r33, r254, 0a, 8h
|
||||||
ADDI64 r1, r35, -2d
|
ADDI64 r1, r33, -2d
|
||||||
LD r31, r254, 8a, 40h
|
LD r31, r254, 8a, 24h
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 32d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
modify:
|
modify:
|
||||||
LI64 r3, 2d
|
LI64 r3, 2d
|
||||||
ST r3, r2, 0a, 8h
|
ST r3, r2, 0a, 8h
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 212
|
code size: 187
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue