diff --git a/lang/README.md b/lang/README.md index fb5edf3..2fe1e99 100644 --- a/lang/README.md +++ b/lang/README.md @@ -540,6 +540,19 @@ main := fn(): int { } ``` +#### small_struct_bitcast +```hb + +Color := struct {r: u8, g: u8, b: u8, a: u8} +white := Color.(255, 255, 255, 255) +u32_to_color := fn(v: u32): Color { + return @bitcast(v) +} +main := fn(): int { + return u32_to_color(@bitcast(white)).r +} +``` + #### wide_ret ```hb OemIdent := struct { diff --git a/lang/src/son.rs b/lang/src/son.rs index aa7e0ea..0aa3c44 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -24,7 +24,6 @@ use { fmt::{self, Debug, Display, Write}, format_args as fa, mem, ops::{self}, - u16, }, hashbrown::hash_map, hbbytecode::DisasmError, @@ -2491,6 +2490,17 @@ impl<'a> Codegen<'a> { ); } + match ty.loc(&self.tys) { + Loc::Reg if core::mem::take(&mut val.ptr) => val.id = self.load_mem(val.id, ty), + Loc::Stack if !val.ptr => { + let stack = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]); + self.store_mem(stack, val.ty, val.id); + val.id = stack; + val.ptr = true; + } + _ => {} + } + val.ty = ty; Some(val) } @@ -4450,6 +4460,7 @@ mod tests { // Purely Testing Examples; returning_global_struct; + small_struct_bitcast; wide_ret; comptime_min_reg_leak; different_types; diff --git a/lang/tests/son_tests_small_struct_bitcast.txt b/lang/tests/son_tests_small_struct_bitcast.txt new file mode 100644 index 0000000..9d7251d --- /dev/null +++ b/lang/tests/son_tests_small_struct_bitcast.txt @@ -0,0 +1,23 @@ +main: + ADDI64 r254, r254, -12d + ST r31, r254, 4a, 8h + LRA r1, r0, :white + LD r2, r1, 0a, 4h + ADDI64 r5, r254, 0d + JAL r31, r0, :u32_to_color + ST r1, r254, 0a, 4h + LD r9, r254, 0a, 1h + ANDI r1, r9, 255d + LD r31, r254, 4a, 8h + ADDI64 r254, r254, 12d + JALA r0, r31, 0a +u32_to_color: + ADDI64 r254, r254, -4d + ADDI64 r3, r254, 0d + ST r2, r254, 0a, 4h + LD r1, r3, 0a, 4h + ADDI64 r254, r254, 4d + JALA r0, r31, 0a +code size: 216 +ret: 255 +status: Ok(())