This commit is contained in:
Jakub Doka 2024-10-17 19:32:10 +02:00
parent da58a5926d
commit 11f6537a09
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
4 changed files with 375 additions and 416 deletions

View file

@ -1825,7 +1825,10 @@ impl Codegen {
self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } }); self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } });
} }
let args = self.pack_args(pos, arg_base); let args = self
.tys
.pack_args(arg_base)
.unwrap_or_else(|| self.report(pos, "function instance has too many arguments"));
let ret = self.ty(ret); let ret = self.ty(ret);
let sym = SymKey::FuncInst(*func, args); let sym = SymKey::FuncInst(*func, args);
@ -2373,7 +2376,7 @@ impl Codegen {
let tmp = self.ci.regs.allocate(); let tmp = self.ci.regs.allocate();
let off = self.opt_stack_reloc(ssta.as_ref(), soff, 3); let off = self.opt_stack_reloc(ssta.as_ref(), soff, 3);
self.ci.emit(ld(tmp.get(), src.get(), off, size as _)); self.ci.emit(ld(tmp.get(), src.get(), off, size as _));
let off = self.opt_stack_reloc(dsta.as_ref(), soff, 3); let off = self.opt_stack_reloc(dsta.as_ref(), doff, 3);
self.ci.emit(st(tmp.get(), dst.get(), off, size as _)); self.ci.emit(st(tmp.get(), dst.get(), off, size as _));
self.ci.regs.free(tmp); self.ci.regs.free(tmp);
break 'a; break 'a;
@ -2583,7 +2586,10 @@ impl Codegen {
self.tys.tmp.args.push(ty); self.tys.tmp.args.push(ty);
} }
let args = self.pack_args(pos, arg_base); let args = self
.tys
.pack_args(arg_base)
.unwrap_or_else(|| self.report(pos, "function has too many argumnets"));
let ret = self.ty(ret); let ret = self.ty(ret);
Some(Sig { args, ret }) Some(Sig { args, ret })
@ -2809,22 +2815,6 @@ impl Codegen {
&self.files[self.ci.file as usize] &self.files[self.ci.file as usize]
} }
fn pack_args(&mut self, pos: Pos, arg_base: usize) -> ty::Tuple {
let base = self.tys.ins.args.len();
self.tys.ins.args.extend(self.tys.tmp.args.drain(arg_base..));
let needle = &self.tys.ins.args[base..];
if needle.is_empty() {
return ty::Tuple::empty();
}
let len = needle.len();
// FIXME: maybe later when this becomes a bottleneck we use more
// efficient search (SIMD?, indexing?)
let sp = self.tys.ins.args.windows(needle.len()).position(|val| val == needle).unwrap();
self.tys.ins.args.truncate((sp + needle.len()).max(base));
ty::Tuple::new(sp, len)
.unwrap_or_else(|| self.report(pos, "amount of arguments not supported"))
}
fn cow_reg(&mut self, rhs: reg::Id) -> reg::Id { fn cow_reg(&mut self, rhs: reg::Id) -> reg::Id {
if rhs.is_ref() { if rhs.is_ref() {
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();

View file

@ -845,6 +845,21 @@ impl Types {
start..end start..end
} }
fn pack_args(&mut self, arg_base: usize) -> Option<ty::Tuple> {
let base = self.ins.args.len();
self.ins.args.extend(self.tmp.args.drain(arg_base..));
let needle = &self.ins.args[base..];
if needle.is_empty() {
return Some(ty::Tuple::empty());
}
let len = needle.len();
// FIXME: maybe later when this becomes a bottleneck we use more
// efficient search (SIMD?, indexing?)
let sp = self.ins.args.windows(needle.len()).position(|val| val == needle).unwrap();
self.ins.args.truncate((sp + needle.len()).max(base));
ty::Tuple::new(sp, len)
}
fn struct_fields(&self, strct: ty::Struct) -> &[Field] { fn struct_fields(&self, strct: ty::Struct) -> &[Field] {
&self.ins.fields[self.struct_field_range(strct)] &self.ins.fields[self.struct_field_range(strct)]
} }
@ -1199,6 +1214,7 @@ impl Types {
} }
#[cfg_attr(not(feature = "opts"), expect(dead_code))] #[cfg_attr(not(feature = "opts"), expect(dead_code))]
#[expect(dead_code)]
fn find_struct_field(&self, s: ty::Struct, name: &str) -> Option<usize> { fn find_struct_field(&self, s: ty::Struct, name: &str) -> Option<usize> {
let name = self.names.project(name)?; let name = self.names.project(name)?;
self.struct_fields(s).iter().position(|f| f.name == name) self.struct_fields(s).iter().position(|f| f.name == name)

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@ main:
LD r34, r254, 0a, 8h LD r34, r254, 0a, 8h
ST r34, r254, 8a, 8h ST r34, r254, 8a, 8h
LD r34, r254, 0a, 8h LD r34, r254, 0a, 8h
ST r34, r254, 8a, 8h ST r34, r254, 16a, 8h
LD r1, r254, 8a, 16h LD r1, r254, 8a, 16h
LD r31, r254, 24a, 32h LD r31, r254, 24a, 32h
ADDI64 r254, r254, 56d ADDI64 r254, r254, 56d