fixing wide register returns

This commit is contained in:
mlokr 2024-07-18 17:55:55 +02:00
parent 4f9d4f2e71
commit 3c01a40ef2
No known key found for this signature in database
GPG key ID: DEA147DDEE644993
4 changed files with 35 additions and 1 deletions

View file

@ -1,3 +1,10 @@
[workspace]
resolver = "2"
members = ["hbbytecode", "hbvm", "hbxrt", "xtask", "hblang", "hbjit"]
[profile.small]
inherits = "release"
opt-level = "z"
strip = true
lto = true
codegen-units = 1

View file

@ -448,7 +448,6 @@ main := fn(): int {
#### different_types
```hb
Color := struct {
r: u8,
g: u8,
@ -494,3 +493,17 @@ main := fn(): int {
}
```
#### struct_return_from_module_function
```hb
bar := @use("bar.hb");
main := fn(): int {
return 7 - bar.foo().x - bar.foo().y - bar.foo().z;
}
// in module: bar.hb
foo := fn(): struct { x: int, y: u32, z: u32 } {
return .{ x: 3, y: 2, z: 2 };
}
```

View file

@ -2592,6 +2592,16 @@ impl Codegen {
(&Loc::Ct { value }, lpat!(false, reg, 0, None)) => {
self.output.emit(li64(reg.get(), u64::from_ne_bytes(value)))
}
(&Loc::Ct { value }, lpat!(false, reg, 8, None)) if reg.get() == 1 && size == 8 => {
self.output.emit(li64(reg.get() + 1, u64::from_ne_bytes(value)));
}
(&Loc::Ct { value }, lpat!(false, reg, off, None)) if reg.get() == 1 => {
let freg = reg.get() + (off / 8) as u8;
let mask = !(((1u64 << (8 * size)) - 1) << (8 * (off % 8)));
self.output.emit(andi(freg, freg, mask));
let value = u64::from_ne_bytes(value) << (8 * (off % 8));
self.output.emit(ori(freg, freg, value));
}
(lpat!(true, src, soff, ref ssta), lpat!(true, dst, doff, ref dsta)) => {
// TODO: some oportuinies to ellit more optimal code
let src_off = self.ci.regs.allocate();
@ -3131,5 +3141,6 @@ mod tests {
c_strings => README;
struct_patterns => README;
arrays => README;
struct_return_from_module_function => README;
}
}

View file

@ -0,0 +1,3 @@
code size: 330
ret: 0
status: Ok(())