strinc operatos seem to work now

This commit is contained in:
Jakub Doka 2024-10-22 12:40:41 +02:00
parent 5aa6150c70
commit 4d699fcbf1
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 245 additions and 12 deletions

View file

@ -22,6 +22,7 @@ use {
fmt::{self, Debug, Display, Write},
format_args as fa, mem,
ops::{self},
usize,
},
hashbrown::hash_map,
regalloc2::VReg,
@ -1778,6 +1779,11 @@ impl<'a> Codegen<'a> {
return NEVER;
}
debug_assert!(
self.ci.nodes[region].kind != Kind::Load || self.ci.nodes[region].ty.is_pointer()
);
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
let mut vc = Vc::from([VOID, value, region]);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
self.ci.nodes.unlock(self.ci.scope.store);
@ -1801,6 +1807,10 @@ impl<'a> Codegen<'a> {
fn load_mem(&mut self, region: Nid, ty: ty::Id) -> Nid {
debug_assert_ne!(region, VOID);
debug_assert!(
self.ci.nodes[region].kind != Kind::Load || self.ci.nodes[region].ty.is_pointer()
);
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
let mut vc = Vc::from([VOID, region]);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
if let Some(str) = self.ci.scope.store.to_store() {
@ -2013,6 +2023,7 @@ impl<'a> Codegen<'a> {
Some(self.ci.nodes.new_node_lit(val.ty, Kind::UnOp { op }, [VOID, val.id]))
}
Expr::BinOp { left, op: TokenKind::Decl, right } => {
std::println!("{}", self.ast_display(right));
let mut right = self.expr(right)?;
if right.ty.loc(&self.tys) == Loc::Stack {
let stck = self.ci.nodes.new_node_nop(right.ty, Kind::Stck, [VOID, MEM]);
@ -2030,10 +2041,16 @@ impl<'a> Codegen<'a> {
self.assert_ty(left.pos(), &mut value, dest.ty, "assignment source");
if dest.var {
self.ci.nodes.lock(value.id);
let var = &mut self.ci.scope.vars[(u16::MAX - dest.id) as usize];
let prev = core::mem::replace(&mut var.value, value.id);
self.ci.nodes.unlock_remove(prev);
if var.ptr {
let val = var.value;
self.store_mem(val, value.id);
} else {
self.ci.nodes.lock(value.id);
let prev = core::mem::replace(&mut var.value, value.id);
self.ci.nodes.unlock_remove(prev);
}
} else if dest.ptr {
self.store_mem(dest.id, value.id);
} else {
@ -2045,14 +2062,46 @@ impl<'a> Codegen<'a> {
Expr::BinOp { left, op, right }
if !matches!(op, TokenKind::Assign | TokenKind::Decl) =>
{
let mut lhs = self.expr_ctx(left, ctx)?;
self.ci.nodes.lock(lhs.id);
let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?;
let ty = self.binop_ty(left.pos(), &mut rhs, &mut lhs, op);
let inps = [VOID, lhs.id, rhs.id];
Some(self.ci.nodes.new_node_lit(ty::bin_ret(ty, op), Kind::BinOp { op }, inps))
let mut lhs = self.raw_expr_ctx(left, ctx)?;
self.strip_var(&mut lhs);
match lhs.ty.expand() {
_ if lhs.ty.is_pointer() || lhs.ty.is_integer() || lhs.ty == ty::Id::BOOL => {
if core::mem::take(&mut lhs.ptr) {
lhs.id = self.load_mem(lhs.id, lhs.ty);
}
self.ci.nodes.lock(lhs.id);
let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?;
self.strip_var(&mut rhs);
let ty = self.binop_ty(left.pos(), &mut rhs, &mut lhs, op);
let inps = [VOID, lhs.id, rhs.id];
Some(self.ci.nodes.new_node_lit(
ty::bin_ret(ty, op),
Kind::BinOp { op },
inps,
))
}
ty::Kind::Struct(s) if op.is_homogenous() => {
self.ci.nodes.lock(lhs.id);
let rhs = self.raw_expr_ctx(right, Ctx::default().with_ty(lhs.ty));
self.ci.nodes.unlock(lhs.id);
let mut rhs = rhs?;
self.strip_var(&mut rhs);
let dst = self.ci.nodes.new_node(lhs.ty, Kind::Stck, [VOID, MEM]);
self.struct_op(left.pos(), op, s, dst, lhs.id, rhs.id);
Some(Value::ptr(dst).ty(lhs.ty))
}
_ => {
self.ci.nodes.unlock(lhs.id);
self.report(
left.pos(),
fa!("'{0} {op} {0}' is not supported", self.ty_display(lhs.ty),),
);
Value::NEVER
}
}
}
Expr::Index { base, index } => {
let mut bs = self.raw_expr(base)?;
@ -2773,6 +2822,45 @@ impl<'a> Codegen<'a> {
}
}
fn struct_op(
&mut self,
pos: Pos,
op: TokenKind,
s: ty::Struct,
dst: Nid,
lhs: Nid,
rhs: Nid,
) -> bool {
let mut offs = OffsetIter::new(s, &self.tys);
while let Some((ty, off)) = offs.next_ty(&self.tys) {
let lhs = self.offset(lhs, off);
let rhs = self.offset(rhs, off);
let dst = self.offset(dst, off);
match ty.expand() {
_ if ty.is_pointer() || ty.is_integer() || ty == ty::Id::BOOL => {
let lhs = self.load_mem(lhs, ty);
let rhs = self.load_mem(rhs, ty);
let res = self.ci.nodes.new_node(ty, Kind::BinOp { op }, [VOID, lhs, rhs]);
self.store_mem(dst, res);
}
ty::Kind::Struct(is) => {
if !self.struct_op(pos, op, is, dst, lhs, rhs) {
self.report(
pos,
fa!(
"... when appliing '{0} {op} {0}'",
self.ty_display(ty::Kind::Struct(s).compress())
),
);
}
}
_ => self.report(pos, fa!("'{0} {op} {0}' is not supported", self.ty_display(ty))),
}
}
true
}
fn compute_signature(&mut self, func: &mut ty::Func, pos: Pos, args: &[Expr]) -> Option<Sig> {
let fuc = &self.tys.ins.funcs[*func as usize];
let fast = self.files[fuc.file as usize].clone();
@ -3952,7 +4040,7 @@ mod tests {
pointers;
structs;
hex_octal_binary_literals;
//struct_operators;
struct_operators;
global_variables;
directives;
c_strings;

View file

@ -0,0 +1,145 @@
main:
ADDI64 r254, r254, -440d
ST r31, r254, 352a, 88h
LI64 r4, 4d
LI64 r9, 1d
LI64 r7, 3d
LI64 r11, 2d
LI64 r12, 1d
LI64 r8, 0d
ADDI64 r3, r254, 336d
ADDI64 r2, r254, 340d
ADDI64 r2, r254, 344d
ADDI64 r10, r254, 348d
ST r8, r254, 348a, 1h
ST r8, r254, 349a, 1h
ST r8, r254, 350a, 1h
ST r8, r254, 351a, 1h
BMC r10, r2, 4h
ST r9, r254, 340a, 1h
ST r9, r254, 341a, 1h
ST r9, r254, 342a, 1h
ST r9, r254, 343a, 1h
LD r6, r254, 340a, 1h
LD r8, r254, 344a, 1h
ADD8 r9, r6, r8
ST r9, r254, 336a, 1h
LD r1, r254, 341a, 1h
LD r5, r254, 345a, 1h
ADD8 r5, r5, r1
ST r5, r254, 337a, 1h
LD r8, r254, 342a, 1h
LD r9, r254, 346a, 1h
ADD8 r1, r9, r8
ST r1, r254, 338a, 1h
LD r5, r254, 343a, 1h
LD r6, r254, 347a, 1h
ADD8 r6, r6, r5
ST r6, r254, 339a, 1h
BMC r3, r2, 4h
LD r2, r254, 347a, 1h
LD r3, r254, 344a, 1h
LD r1, r254, 345a, 1h
LD r5, r254, 346a, 1h
ADD8 r5, r5, r1
ADD8 r8, r3, r5
ADD8 r1, r2, r8
ANDI r1, r1, 255d
ANDI r4, r4, 255d
JEQ r1, r4, :0
LI64 r1, 1008d
JMP :1
0: LI64 r5, 0d
LI64 r32, 4d
ADDI64 r2, r254, 0d
ADDI64 r8, r254, 16d
ADDI64 r9, r254, 32d
ADDI64 r10, r254, 64d
ADDI64 r3, r254, 96d
ADDI64 r1, r254, 112d
ADDI64 r4, r1, 16d
ADDI64 r33, r254, 144d
ADDI64 r34, r254, 160d
ADDI64 r35, r254, 176d
ADDI64 r36, r254, 208d
ADDI64 r37, r254, 224d
ADDI64 r38, r254, 240d
ADDI64 r39, r38, 16d
ADDI64 r40, r254, 272d
ADDI64 r41, r254, 288d
ADDI64 r6, r254, 304d
ADDI64 r42, r254, 320d
ST r12, r254, 320a, 8h
ST r11, r254, 328a, 8h
BMC r42, r6, 16h
ST r7, r254, 288a, 8h
ST r32, r254, 296a, 8h
BMC r41, r40, 16h
LD r7, r254, 272a, 8h
LD r11, r254, 304a, 8h
ADD64 r7, r7, r11
ST r7, r254, 224a, 8h
LD r11, r254, 280a, 8h
LD r12, r254, 312a, 8h
ADD64 r7, r11, r12
ST r7, r254, 232a, 8h
BMC r37, r38, 16h
LD r7, r254, 304a, 8h
LD r11, r254, 272a, 8h
SUB64 r11, r11, r7
ST r11, r254, 208a, 8h
LD r7, r254, 312a, 8h
LD r11, r254, 280a, 8h
SUB64 r7, r11, r7
ST r7, r254, 216a, 8h
BMC r36, r39, 16h
BMC r38, r35, 32h
ST r5, r254, 160a, 8h
ST r5, r254, 168a, 8h
BMC r34, r33, 16h
LD r11, r254, 272a, 8h
LD r12, r254, 144a, 8h
SUB64 r12, r12, r11
ST r12, r254, 96a, 8h
LD r5, r254, 280a, 8h
LD r7, r254, 152a, 8h
SUB64 r7, r7, r5
ST r7, r254, 104a, 8h
BMC r3, r1, 16h
BMC r6, r4, 16h
BMC r1, r10, 32h
LD r5, r254, 176a, 8h
LD r6, r254, 64a, 8h
ADD64 r11, r6, r5
ST r11, r254, 32a, 8h
LD r12, r254, 184a, 8h
LD r1, r254, 72a, 8h
ADD64 r3, r12, r1
ST r3, r254, 40a, 8h
LD r7, r254, 192a, 8h
LD r11, r254, 80a, 8h
ADD64 r11, r7, r11
ST r11, r254, 48a, 8h
LD r3, r254, 200a, 8h
LD r4, r254, 88a, 8h
ADD64 r5, r3, r4
ST r5, r254, 56a, 8h
BMC r9, r10, 32h
LD r11, r254, 80a, 8h
LD r12, r254, 64a, 8h
ADD64 r3, r11, r12
ST r3, r254, 16a, 8h
LD r6, r254, 88a, 8h
LD r7, r254, 72a, 8h
ADD64 r9, r6, r7
ST r9, r254, 24a, 8h
BMC r8, r2, 16h
LD r3, r254, 8a, 8h
LD r4, r254, 0a, 8h
ADD64 r1, r3, r4
1: LD r31, r254, 352a, 88h
ADDI64 r254, r254, 440d
JALA r0, r31, 0a
code size: 1460
ret: 10
status: Ok(())