simplifing code patterns and sixing argument passing
This commit is contained in:
parent
ad4aed9c98
commit
73c9ccef6a
|
@ -8,7 +8,7 @@ use {
|
||||||
},
|
},
|
||||||
reg,
|
reg,
|
||||||
ty::{self, TyCheck},
|
ty::{self, TyCheck},
|
||||||
Comptime, Field, Func, Global, OffsetIter, ParamAlloc, Reloc, Sig, Struct, SymKey,
|
Comptime, Field, Func, Global, OffsetIter, PLoc, ParamAlloc, Reloc, Sig, Struct, SymKey,
|
||||||
TypeParser, TypedReloc, Types,
|
TypeParser, TypedReloc, Types,
|
||||||
},
|
},
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
|
@ -1037,7 +1037,7 @@ impl Codegen {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parama = self.tys.parama(ty);
|
let (_, mut parama) = self.tys.parama(ty);
|
||||||
let base = self.pool.arg_locs.len();
|
let base = self.pool.arg_locs.len();
|
||||||
for arg in args {
|
for arg in args {
|
||||||
let arg = self.expr(arg)?;
|
let arg = self.expr(arg)?;
|
||||||
|
@ -1402,7 +1402,7 @@ impl Codegen {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parama = self.tys.parama(sig.ret);
|
let (_, mut parama) = self.tys.parama(sig.ret);
|
||||||
let base = self.pool.arg_locs.len();
|
let base = self.pool.arg_locs.len();
|
||||||
let mut sig_args = sig.args.range();
|
let mut sig_args = sig.args.range();
|
||||||
let mut should_momize = !args.is_empty() && sig.ret == ty::Id::from(ty::TYPE);
|
let mut should_momize = !args.is_empty() && sig.ret == ty::Id::from(ty::TYPE);
|
||||||
|
@ -2135,7 +2135,7 @@ impl Codegen {
|
||||||
|
|
||||||
self.ci.emit_prelude();
|
self.ci.emit_prelude();
|
||||||
|
|
||||||
let mut parama = self.tys.parama(sig.ret);
|
let (ret, mut parama) = self.tys.parama(sig.ret);
|
||||||
let mut sig_args = sig.args.range();
|
let mut sig_args = sig.args.range();
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
let ty = self.tys.ins.args[sig_args.next().unwrap()];
|
let ty = self.tys.ins.args[sig_args.next().unwrap()];
|
||||||
|
@ -2147,7 +2147,7 @@ impl Codegen {
|
||||||
self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
|
self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tys.size_of(sig.ret) > 16 {
|
if let PLoc::Ref(..) = ret {
|
||||||
let reg = self.ci.regs.allocate();
|
let reg = self.ci.regs.allocate();
|
||||||
self.ci.emit(instrs::cp(reg.get(), 1));
|
self.ci.emit(instrs::cp(reg.get(), 1));
|
||||||
self.ci.ret_reg = reg;
|
self.ci.ret_reg = reg;
|
||||||
|
@ -2179,20 +2179,21 @@ impl Codegen {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return Loc::default();
|
return Loc::default();
|
||||||
}
|
}
|
||||||
let (src, dst) = match size {
|
let (src, dst) = match parama.next(ty, &self.tys) {
|
||||||
0 => (Loc::default(), Loc::default()),
|
PLoc::None => (Loc::default(), Loc::default()),
|
||||||
..=8 if flags & idfl::REFERENCED == 0 => {
|
PLoc::Reg(r, _) if flags & idfl::REFERENCED == 0 => {
|
||||||
(Loc::reg(parama.next()), Loc::reg(self.ci.regs.allocate()))
|
(Loc::reg(r), Loc::reg(self.ci.regs.allocate()))
|
||||||
}
|
}
|
||||||
1..=8 => (Loc::reg(parama.next()), Loc::stack(self.ci.stack.allocate(size))),
|
PLoc::Reg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
|
||||||
9..=16 => (Loc::reg(parama.next_wide()), Loc::stack(self.ci.stack.allocate(size))),
|
PLoc::WideReg(r, _) => (Loc::reg(r), Loc::stack(self.ci.stack.allocate(size))),
|
||||||
_ if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
|
PLoc::Ref(ptr, _) if flags & (idfl::MUTABLE | idfl::REFERENCED) == 0 => {
|
||||||
let ptr = parama.next();
|
|
||||||
let reg = self.ci.regs.allocate();
|
let reg = self.ci.regs.allocate();
|
||||||
self.ci.emit(instrs::cp(reg.get(), ptr));
|
self.ci.emit(instrs::cp(reg.get(), ptr));
|
||||||
return Loc::reg(reg).into_derefed();
|
return Loc::reg(reg).into_derefed();
|
||||||
}
|
}
|
||||||
_ => (Loc::reg(parama.next()).into_derefed(), Loc::stack(self.ci.stack.allocate(size))),
|
PLoc::Ref(ptr, _) => {
|
||||||
|
(Loc::reg(ptr).into_derefed(), Loc::stack(self.ci.stack.allocate(size)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.store_sized(src, &dst, size);
|
self.store_sized(src, &dst, size);
|
||||||
|
@ -2265,23 +2266,16 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
|
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
|
||||||
self.pass_arg_low(&value.loc, self.tys.size_of(value.ty), parama)
|
match parama.next(value.ty, &self.tys) {
|
||||||
}
|
PLoc::None => {}
|
||||||
|
PLoc::Reg(r, _) | PLoc::WideReg(r, _) => {
|
||||||
fn pass_arg_low(&mut self, loc: &Loc, size: Size, parama: &mut ParamAlloc) {
|
self.store_typed(&value.loc, Loc::reg(r), value.ty)
|
||||||
if size > 16 {
|
}
|
||||||
let Loc::Rt { reg, stack, offset, .. } = loc else { unreachable!() };
|
PLoc::Ref(ptr, _) => {
|
||||||
self.stack_offset(parama.next(), reg.get(), stack.as_ref(), *offset as _);
|
let Loc::Rt { reg, stack, offset, .. } = &value.loc else { unreachable!() };
|
||||||
return;
|
self.stack_offset(ptr, reg.get(), stack.as_ref(), *offset as _);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dst = match size {
|
|
||||||
0 => return,
|
|
||||||
9..=16 => Loc::reg(parama.next_wide()),
|
|
||||||
_ => Loc::reg(parama.next()),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.store_sized(loc, dst, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_typed(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, ty: ty::Id) {
|
fn store_typed(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, ty: ty::Id) {
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
str_from_raw_parts,
|
str_from_raw_parts,
|
||||||
ptr_sub_ptr,
|
ptr_sub_ptr,
|
||||||
slice_from_ptr_range,
|
slice_from_ptr_range,
|
||||||
is_sorted
|
is_sorted,
|
||||||
|
iter_next_chunk
|
||||||
)]
|
)]
|
||||||
#![feature(pointer_is_aligned_to)]
|
#![feature(pointer_is_aligned_to)]
|
||||||
#![warn(clippy::dbg_macro)]
|
#![warn(clippy::dbg_macro)]
|
||||||
|
@ -247,7 +248,7 @@ mod ty {
|
||||||
ident,
|
ident,
|
||||||
lexer::TokenKind,
|
lexer::TokenKind,
|
||||||
parser::{self, Pos},
|
parser::{self, Pos},
|
||||||
Size,
|
Size, Types,
|
||||||
},
|
},
|
||||||
core::{num::NonZeroU32, ops::Range},
|
core::{num::NonZeroU32, ops::Range},
|
||||||
};
|
};
|
||||||
|
@ -405,6 +406,21 @@ mod ty {
|
||||||
Self::UINT
|
Self::UINT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn loc(&self, tys: &Types) -> Loc {
|
||||||
|
match self.expand() {
|
||||||
|
Kind::Ptr(_) | Kind::Builtin(_) => Loc::Reg,
|
||||||
|
Kind::Struct(_) if tys.size_of(*self) == 0 => Loc::Reg,
|
||||||
|
Kind::Struct(_) | Kind::Slice(_) => Loc::Stack,
|
||||||
|
Kind::Func(_) | Kind::Global(_) | Kind::Module(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub enum Loc {
|
||||||
|
Reg,
|
||||||
|
Stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
|
#[derive(PartialEq, Eq, Default, Debug, Clone, Copy)]
|
||||||
|
@ -771,15 +787,23 @@ impl Array {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PLoc {
|
||||||
|
None,
|
||||||
|
Reg(u8, u16),
|
||||||
|
WideReg(u8, u16),
|
||||||
|
Ref(u8, u32),
|
||||||
|
}
|
||||||
|
|
||||||
struct ParamAlloc(Range<u8>);
|
struct ParamAlloc(Range<u8>);
|
||||||
|
|
||||||
impl ParamAlloc {
|
impl ParamAlloc {
|
||||||
pub fn next(&mut self) -> u8 {
|
pub fn next(&mut self, ty: ty::Id, tys: &Types) -> PLoc {
|
||||||
self.0.next().expect("too many paramteters")
|
match tys.size_of(ty) {
|
||||||
}
|
0 => PLoc::None,
|
||||||
|
size @ 1..=8 => PLoc::Reg(self.0.next().unwrap(), size as _),
|
||||||
fn next_wide(&mut self) -> u8 {
|
size @ 9..=16 => PLoc::WideReg(self.0.next_chunk::<2>().unwrap()[0], size as _),
|
||||||
(self.next(), self.next()).0
|
size @ 17.. => PLoc::Ref(self.0.next().unwrap(), size),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,8 +1226,13 @@ impl Types {
|
||||||
instrs::disasm(&mut sluce, &functions, output, eca_handler)
|
instrs::disasm(&mut sluce, &functions, output, eca_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parama(&self, ret: impl Into<ty::Id>) -> ParamAlloc {
|
fn parama(&self, ret: impl Into<ty::Id>) -> (PLoc, ParamAlloc) {
|
||||||
ParamAlloc(2 + (9..=16).contains(&self.size_of(ret.into())) as u8..12)
|
let mut iter = ParamAlloc(1..12);
|
||||||
|
let ret = iter.next(ret.into(), self);
|
||||||
|
if let PLoc::None = ret {
|
||||||
|
iter.0.start += 1;
|
||||||
|
}
|
||||||
|
(ret, iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_ptr(&mut self, base: ty::Id) -> ty::Id {
|
fn make_ptr(&mut self, base: ty::Id) -> ty::Id {
|
||||||
|
|
168
lang/src/son.rs
168
lang/src/son.rs
|
@ -10,10 +10,10 @@ use {
|
||||||
CtorField, Expr, ExprRef, FileId, Pos,
|
CtorField, Expr, ExprRef, FileId, Pos,
|
||||||
},
|
},
|
||||||
reg, task,
|
reg, task,
|
||||||
ty::{self, ArrayLen, Tuple},
|
ty::{self, ArrayLen, Loc, Tuple},
|
||||||
vc::{BitSet, Vc},
|
vc::{BitSet, Vc},
|
||||||
Comptime, Func, Global, HashMap, Offset, OffsetIter, Reloc, Sig, TypeParser, TypedReloc,
|
Comptime, Func, Global, HashMap, Offset, OffsetIter, PLoc, Reloc, Sig, TypeParser,
|
||||||
Types,
|
TypedReloc, Types,
|
||||||
},
|
},
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::{string::String, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
|
@ -1093,20 +1093,16 @@ impl ItemCtx {
|
||||||
*saved_regs.entry(hvenc).or_insert(would_insert)
|
*saved_regs.entry(hvenc).or_insert(would_insert)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parama = tys.parama(sig.ret);
|
let (retl, mut parama) = tys.parama(sig.ret);
|
||||||
|
|
||||||
for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) {
|
for (ti, &arg) in sig.args.range().zip(fuc.nodes[VOID].outputs.iter().skip(2)) {
|
||||||
let ty = tys.ins.args[ti];
|
let ty = tys.ins.args[ti];
|
||||||
if tys.size_of(ty) == 0 {
|
let (rg, size) = match parama.next(ty, tys) {
|
||||||
continue;
|
PLoc::WideReg(rg, size) => (rg, size),
|
||||||
}
|
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
|
||||||
if let size @ 9..=16 = tys.size_of(ty) {
|
PLoc::Reg(..) | PLoc::Ref(..) | PLoc::None => continue,
|
||||||
let rg = parama.next_wide();
|
};
|
||||||
self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size as _));
|
self.emit(instrs::st(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _, size));
|
||||||
self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _));
|
self.emit(instrs::addi64(rg, reg::STACK_PTR, fuc.nodes[arg].offset as _));
|
||||||
} else {
|
|
||||||
parama.next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, block) in fuc.blocks.iter().enumerate() {
|
for (i, block) in fuc.blocks.iter().enumerate() {
|
||||||
|
@ -1177,17 +1173,13 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
match tys.size_of(sig.ret) {
|
match retl {
|
||||||
0..=8 => {}
|
PLoc::None | PLoc::Reg(..) => {}
|
||||||
size @ 9..=16 => {
|
PLoc::WideReg(r, size) => {
|
||||||
self.emit(instrs::ld(reg::RET, atr(allocs[0]), 0, size as _));
|
self.emit(instrs::ld(r, atr(allocs[0]), 0, size))
|
||||||
}
|
}
|
||||||
size @ 17.. => {
|
PLoc::Ref(r, size) => {
|
||||||
self.emit(instrs::bmc(
|
self.emit(instrs::bmc(atr(allocs[0]), r, size.try_into().unwrap()));
|
||||||
atr(allocs[0]),
|
|
||||||
reg::RET,
|
|
||||||
size.try_into().unwrap(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,14 +1235,29 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Call { func } => {
|
Kind::Call { func } => {
|
||||||
|
let (ret, mut parama) = tys.parama(node.ty);
|
||||||
|
let mut allocs = allocs.iter();
|
||||||
|
for ti in tys.ins.funcs[func as usize].sig.unwrap().args.range() {
|
||||||
|
let ty = tys.ins.args[ti];
|
||||||
|
let (rg, size) = match parama.next(ty, tys) {
|
||||||
|
PLoc::Reg(rg, size) if ty.loc(tys) == Loc::Stack => (rg, size),
|
||||||
|
PLoc::WideReg(rg, size) => (rg, size),
|
||||||
|
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.relocs.push(TypedReloc {
|
self.relocs.push(TypedReloc {
|
||||||
target: ty::Kind::Func(func).compress(),
|
target: ty::Kind::Func(func).compress(),
|
||||||
reloc: Reloc::new(self.code.len(), 3, 4),
|
reloc: Reloc::new(self.code.len(), 3, 4),
|
||||||
});
|
});
|
||||||
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
self.emit(instrs::jal(reg::RET_ADDR, reg::ZERO, 0));
|
||||||
if let size @ 9..=16 = tys.size_of(node.ty) {
|
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(reg::RET, reg::STACK_PTR, stck as _, size as _));
|
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Global { global } => {
|
Kind::Global { global } => {
|
||||||
|
@ -1589,6 +1596,7 @@ impl TypeParser for Codegen<'_> {
|
||||||
code: core::mem::take(&mut self.ci.code),
|
code: core::mem::take(&mut self.ci.code),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.pool.pop_ci(&mut self.ci);
|
self.pool.pop_ci(&mut self.ci);
|
||||||
self.complete_call_graph();
|
self.complete_call_graph();
|
||||||
|
|
||||||
|
@ -2043,12 +2051,8 @@ impl<'a> Codegen<'a> {
|
||||||
let mut inps = Vc::from([self.ci.ctrl]);
|
let mut inps = Vc::from([self.ci.ctrl]);
|
||||||
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.ins.args[tyx];
|
let ty = self.tys.ins.args[tyx];
|
||||||
if self.tys.size_of(ty) == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
|
||||||
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||||
debug_assert_ne!(value.id, 0);
|
|
||||||
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
||||||
|
|
||||||
self.ci.nodes.lock(value.id);
|
self.ci.nodes.lock(value.id);
|
||||||
|
@ -2074,9 +2078,9 @@ impl<'a> Codegen<'a> {
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
|
|
||||||
let alt_value = match self.tys.size_of(sig.ret) {
|
let alt_value = match sig.ret.loc(&self.tys) {
|
||||||
0..=8 => None,
|
Loc::Reg => None,
|
||||||
9.. => {
|
Loc::Stack => {
|
||||||
let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]);
|
let stck = self.ci.nodes.new_node_nop(sig.ret, Kind::Stck, [VOID, MEM]);
|
||||||
inps.push(stck);
|
inps.push(stck);
|
||||||
Some(Value::ptr(stck).ty(sig.ret))
|
Some(Value::ptr(stck).ty(sig.ret))
|
||||||
|
@ -2692,7 +2696,7 @@ impl<'a> Codegen<'a> {
|
||||||
for arg in args.iter() {
|
for arg in args.iter() {
|
||||||
let ty = self.tys.ins.args[sig_args.next().unwrap()];
|
let ty = self.tys.ins.args[sig_args.next().unwrap()];
|
||||||
let mut deps = Vc::from([VOID]);
|
let mut deps = Vc::from([VOID]);
|
||||||
if matches!(self.tys.size_of(ty), 9..=16) {
|
if ty.loc(&self.tys) == Loc::Stack {
|
||||||
deps.push(MEM);
|
deps.push(MEM);
|
||||||
}
|
}
|
||||||
let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, [VOID]);
|
let value = self.ci.nodes.new_node_nop(ty, Kind::Arg, [VOID]);
|
||||||
|
@ -2994,18 +2998,15 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Return => {
|
Kind::Return => {
|
||||||
let ops = match self.tys.size_of(self.sig.ret) {
|
let ops = match self.tys.parama(self.sig.ret).0 {
|
||||||
0 => vec![],
|
PLoc::None => vec![],
|
||||||
1..=8 => {
|
PLoc::Reg(r, ..) => {
|
||||||
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(r as _, regalloc2::RegClass::Int),
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
9..=16 => {
|
PLoc::WideReg(..) | PLoc::Ref(..) => {
|
||||||
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
|
|
||||||
}
|
|
||||||
17.. => {
|
|
||||||
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
|
vec![self.urg(self.nodes[node.inputs[1]].inputs[1])]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3035,32 +3036,17 @@ impl<'a> Function<'a> {
|
||||||
Kind::Entry => {
|
Kind::Entry => {
|
||||||
self.nodes[nid].ralloc_backref = self.add_block(nid);
|
self.nodes[nid].ralloc_backref = self.add_block(nid);
|
||||||
|
|
||||||
let mut parama = self.tys.parama(self.sig.ret);
|
let (_, mut parama) = self.tys.parama(self.sig.ret);
|
||||||
for (ti, arg) in
|
for (ti, arg) in
|
||||||
self.sig.args.range().zip(self.nodes[VOID].clone().outputs.into_iter().skip(2))
|
self.sig.args.range().zip(self.nodes[VOID].clone().outputs.into_iter().skip(2))
|
||||||
{
|
{
|
||||||
let ty = self.tys.ins.args[ti];
|
let ty = self.tys.ins.args[ti];
|
||||||
match self.tys.size_of(ty) {
|
match parama.next(ty, self.tys) {
|
||||||
0 => continue,
|
PLoc::None => {}
|
||||||
1..=8 => {
|
PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _) => {
|
||||||
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
|
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
|
||||||
self.rg(arg),
|
self.rg(arg),
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
)]);
|
|
||||||
}
|
|
||||||
9..=16 => {
|
|
||||||
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
|
|
||||||
self.rg(arg),
|
|
||||||
regalloc2::PReg::new(
|
|
||||||
parama.next_wide() as _,
|
|
||||||
regalloc2::RegClass::Int,
|
|
||||||
),
|
|
||||||
)]);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
self.add_instr(NEVER, vec![regalloc2::Operand::reg_fixed_def(
|
|
||||||
self.rg(arg),
|
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
|
||||||
)]);
|
)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3120,20 +3106,18 @@ impl<'a> Function<'a> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut parama = self.tys.parama(fuc.ret);
|
let (ret, mut parama) = self.tys.parama(fuc.ret);
|
||||||
let mut inps = node.inputs[1..].iter();
|
for (ti, &(mut i)) in fuc.args.range().zip(node.inputs[1..].iter()) {
|
||||||
for ti in fuc.args.range() {
|
|
||||||
let ty = self.tys.ins.args[ti];
|
let ty = self.tys.ins.args[ti];
|
||||||
match self.tys.size_of(ty) {
|
match parama.next(ty, self.tys) {
|
||||||
0 => continue,
|
PLoc::None => {}
|
||||||
1..=8 => {
|
PLoc::Reg(r, _) => {
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
self.rg(*inps.next().unwrap()),
|
self.rg(i),
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
9..=16 => {
|
PLoc::WideReg(r, _) => {
|
||||||
let mut i = *inps.next().unwrap();
|
|
||||||
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],
|
||||||
|
@ -3145,15 +3129,14 @@ impl<'a> Function<'a> {
|
||||||
debug_assert!(i != 0);
|
debug_assert!(i != 0);
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
self.rg(i),
|
self.rg(i),
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
self.rg(i),
|
self.rg(i),
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as usize + 1, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
PLoc::Ref(r, _) => {
|
||||||
let mut i = *inps.next().unwrap();
|
|
||||||
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],
|
||||||
|
@ -3165,20 +3148,17 @@ impl<'a> Function<'a> {
|
||||||
debug_assert!(i != 0);
|
debug_assert!(i != 0);
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
self.rg(i),
|
self.rg(i),
|
||||||
regalloc2::PReg::new(parama.next() as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.tys.size_of(fuc.ret) {
|
if let PLoc::Ref(r, _) = ret {
|
||||||
0..=16 => {}
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
17.. => {
|
self.rg(*node.inputs.last().unwrap()),
|
||||||
ops.push(regalloc2::Operand::reg_fixed_use(
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
self.rg(*node.inputs.last().unwrap()),
|
));
|
||||||
regalloc2::PReg::new(1, regalloc2::RegClass::Int),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
|
@ -3203,6 +3183,7 @@ impl<'a> Function<'a> {
|
||||||
// .iter()
|
// .iter()
|
||||||
// .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)))
|
// .all(|&n| matches!(self.nodes[n].kind, Kind::Stre | Kind::Load)))
|
||||||
// }) => {}
|
// }) => {}
|
||||||
|
Kind::Stck if self.tys.size_of(node.ty) == 0 => self.nodes.lock(nid),
|
||||||
Kind::Stck => {
|
Kind::Stck => {
|
||||||
let ops = vec![self.drg(nid)];
|
let ops = vec![self.drg(nid)];
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
|
@ -3212,6 +3193,9 @@ impl<'a> Function<'a> {
|
||||||
self.add_instr(nid, ops);
|
self.add_instr(nid, ops);
|
||||||
}
|
}
|
||||||
Kind::Phi | Kind::Arg | Kind::Mem => {}
|
Kind::Phi | Kind::Arg | Kind::Mem => {}
|
||||||
|
Kind::Load { .. } if matches!(self.tys.size_of(node.ty), 0 | 9..) => {
|
||||||
|
self.nodes.lock(nid)
|
||||||
|
}
|
||||||
Kind::Load { .. } => {
|
Kind::Load { .. } => {
|
||||||
let mut region = node.inputs[1];
|
let mut region = node.inputs[1];
|
||||||
if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
||||||
|
@ -3219,13 +3203,11 @@ impl<'a> Function<'a> {
|
||||||
{
|
{
|
||||||
region = self.nodes[region].inputs[1]
|
region = self.nodes[region].inputs[1]
|
||||||
}
|
}
|
||||||
if self.tys.size_of(node.ty) <= 8 {
|
let ops = match self.nodes[region].kind {
|
||||||
let ops = match self.nodes[region].kind {
|
Kind::Stck => vec![self.drg(nid)],
|
||||||
Kind::Stck => vec![self.drg(nid)],
|
_ => vec![self.drg(nid), self.urg(region)],
|
||||||
_ => vec![self.drg(nid), self.urg(region)],
|
};
|
||||||
};
|
self.add_instr(nid, ops);
|
||||||
self.add_instr(nid, ops);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Kind::Stre if node.inputs[2] == VOID => self.nodes.lock(nid),
|
Kind::Stre if node.inputs[2] == VOID => self.nodes.lock(nid),
|
||||||
Kind::Stre => {
|
Kind::Stre => {
|
||||||
|
|
|
@ -47,6 +47,9 @@ main:
|
||||||
CP r2, r3
|
CP r2, r3
|
||||||
CP r4, r5
|
CP r4, r5
|
||||||
CP r6, r7
|
CP r6, r7
|
||||||
|
LD r2, r2, 0a, 16h
|
||||||
|
LD r4, r4, 0a, 16h
|
||||||
|
LD r6, r6, 0a, 16h
|
||||||
JAL r31, r0, :line
|
JAL r31, r0, :line
|
||||||
ADDI64 r7, r254, 0d
|
ADDI64 r7, r254, 0d
|
||||||
ADDI64 r5, r254, 16d
|
ADDI64 r5, r254, 16d
|
||||||
|
@ -61,6 +64,9 @@ main:
|
||||||
CP r2, r3
|
CP r2, r3
|
||||||
CP r4, r5
|
CP r4, r5
|
||||||
CP r6, r7
|
CP r6, r7
|
||||||
|
LD r2, r2, 0a, 16h
|
||||||
|
LD r4, r4, 0a, 16h
|
||||||
|
LD r6, r6, 0a, 16h
|
||||||
JAL r31, r0, :rect_line
|
JAL r31, r0, :rect_line
|
||||||
JAL r31, r0, :example
|
JAL r31, r0, :example
|
||||||
LD r31, r254, 96a, 16h
|
LD r31, r254, 96a, 16h
|
||||||
|
@ -86,7 +92,6 @@ rect_line:
|
||||||
2: ADDI64 r9, r9, 1d
|
2: ADDI64 r9, r9, 1d
|
||||||
JMP :4
|
JMP :4
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
timed out
|
code size: 875
|
||||||
code size: 797
|
ret: 4
|
||||||
ret: 0
|
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -14,29 +14,30 @@ main:
|
||||||
ADDI64 r254, r254, 56d
|
ADDI64 r254, r254, 56d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
maina:
|
maina:
|
||||||
ADDI64 r254, r254, -88d
|
ADDI64 r254, r254, -100d
|
||||||
ST r31, r254, 24a, 64h
|
ST r31, r254, 28a, 72h
|
||||||
|
ADDI64 r32, r254, 24d
|
||||||
JAL r31, r0, :small_struct
|
JAL r31, r0, :small_struct
|
||||||
LI64 r32, 1d
|
LI64 r33, 1d
|
||||||
LI64 r33, 3d
|
LI64 r34, 3d
|
||||||
LI64 r34, 0d
|
LI64 r35, 0d
|
||||||
ADDI64 r35, r254, 0d
|
ADDI64 r36, r254, 0d
|
||||||
ADDI64 r36, r254, 16d
|
ADDI64 r37, r254, 16d
|
||||||
ST r34, r254, 16a, 1h
|
ST r35, r254, 16a, 1h
|
||||||
ST r34, r254, 17a, 1h
|
ST r35, r254, 17a, 1h
|
||||||
ST r34, r254, 18a, 1h
|
ST r35, r254, 18a, 1h
|
||||||
ST r33, r254, 19a, 1h
|
ST r34, r254, 19a, 1h
|
||||||
ST r32, r254, 20a, 1h
|
ST r33, r254, 20a, 1h
|
||||||
ST r34, r254, 21a, 1h
|
ST r35, r254, 21a, 1h
|
||||||
ST r34, r254, 22a, 1h
|
ST r35, r254, 22a, 1h
|
||||||
ST r34, r254, 23a, 1h
|
ST r35, r254, 23a, 1h
|
||||||
LD r37, r254, 16a, 8h
|
|
||||||
ST r37, r254, 0a, 8h
|
|
||||||
LD r38, r254, 16a, 8h
|
LD r38, r254, 16a, 8h
|
||||||
ST r38, r254, 8a, 8h
|
ST r38, r254, 0a, 8h
|
||||||
LD r1, r35, 0a, 16h
|
LD r39, r254, 16a, 8h
|
||||||
LD r31, r254, 24a, 64h
|
ST r39, r254, 8a, 8h
|
||||||
ADDI64 r254, r254, 88d
|
LD r1, r36, 0a, 16h
|
||||||
|
LD r31, r254, 28a, 72h
|
||||||
|
ADDI64 r254, r254, 100d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
small_struct:
|
small_struct:
|
||||||
ADDI64 r254, r254, -4d
|
ADDI64 r254, r254, -4d
|
||||||
|
@ -47,6 +48,6 @@ small_struct:
|
||||||
LD r1, r254, 0a, 4h
|
LD r1, r254, 0a, 4h
|
||||||
ADDI64 r254, r254, 4d
|
ADDI64 r254, r254, 4d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 532
|
code size: 543
|
||||||
ret: 2
|
ret: 2
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue