From 41af8ff9693f9bbcf62b25d1092fb8d3453b78a0 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 22 Jun 2023 21:14:22 +0200 Subject: [PATCH] fix invalid register write --- crates/compiler/gen_dev/src/generic64/mod.rs | 54 ++++++++++++-------- examples/platform-switching/rocLovesZig.roc | 17 +++++- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/crates/compiler/gen_dev/src/generic64/mod.rs b/crates/compiler/gen_dev/src/generic64/mod.rs index b933ca70dc..76aa3e3f9b 100644 --- a/crates/compiler/gen_dev/src/generic64/mod.rs +++ b/crates/compiler/gen_dev/src/generic64/mod.rs @@ -2798,7 +2798,7 @@ impl< ASM::mov_reg64_imm64(&mut self.buf, mask_reg, (!0b111) as _); // mask out the tag id bits - ASM::and_reg64_reg64_reg64(&mut self.buf, ptr_reg, ptr_reg, mask_reg); + ASM::and_reg64_reg64_reg64(&mut self.buf, mask_reg, ptr_reg, mask_reg); let mut offset = 0; for field in &other_fields[..index as usize] { @@ -2809,7 +2809,7 @@ impl< &mut self.buf, &mut self.storage_manager, self.layout_interner, - ptr_reg, + mask_reg, offset as i32, element_layout, *sym, @@ -2824,15 +2824,22 @@ impl< .load_to_general_reg(&mut self.buf, structure); // mask out the tag id bits - if !union_layout.stores_tag_id_as_data(self.storage_manager.target_info) { - let mask_symbol = self.debug_symbol("tag_id_mask"); - let mask_reg = self + let unmasked_reg = if union_layout + .stores_tag_id_as_data(self.storage_manager.target_info) + { + ptr_reg + } else { + let umasked_symbol = self.debug_symbol("unmasked"); + let unmasked_reg = self .storage_manager - .claim_general_reg(&mut self.buf, &mask_symbol); - ASM::mov_reg64_imm64(&mut self.buf, mask_reg, (!0b111) as _); + .claim_general_reg(&mut self.buf, &umasked_symbol); - ASM::and_reg64_reg64_reg64(&mut self.buf, ptr_reg, ptr_reg, mask_reg); - } + ASM::mov_reg64_imm64(&mut self.buf, unmasked_reg, (!0b111) as _); + + ASM::and_reg64_reg64_reg64(&mut self.buf, unmasked_reg, ptr_reg, unmasked_reg); + + unmasked_reg + }; let mut offset = 0; for field in &other_fields[..index as usize] { @@ -2843,7 +2850,7 @@ impl< &mut self.buf, &mut self.storage_manager, self.layout_interner, - ptr_reg, + unmasked_reg, offset as i32, element_layout, *sym, @@ -2911,14 +2918,14 @@ impl< ASM::mov_reg64_imm64(&mut self.buf, mask_reg, (!0b111) as _); // mask out the tag id bits - ASM::and_reg64_reg64_reg64(&mut self.buf, ptr_reg, ptr_reg, mask_reg); + ASM::and_reg64_reg64_reg64(&mut self.buf, mask_reg, ptr_reg, mask_reg); let mut offset = 0; for field in &other_fields[..index as usize] { offset += self.layout_interner.stack_size(*field); } - ASM::add_reg64_reg64_imm32(&mut self.buf, sym_reg, ptr_reg, offset as i32); + ASM::add_reg64_reg64_imm32(&mut self.buf, sym_reg, mask_reg, offset as i32); } UnionLayout::Recursive(tag_layouts) => { let other_fields = tag_layouts[tag_id as usize]; @@ -2928,22 +2935,29 @@ impl< .load_to_general_reg(&mut self.buf, structure); // mask out the tag id bits - if !union_layout.stores_tag_id_as_data(self.storage_manager.target_info) { - let mask_symbol = self.debug_symbol("tag_id_mask"); - let mask_reg = self + let unmasked_reg = if union_layout + .stores_tag_id_as_data(self.storage_manager.target_info) + { + ptr_reg + } else { + let umasked_symbol = self.debug_symbol("unmasked"); + let unmasked_reg = self .storage_manager - .claim_general_reg(&mut self.buf, &mask_symbol); - ASM::mov_reg64_imm64(&mut self.buf, mask_reg, (!0b111) as _); + .claim_general_reg(&mut self.buf, &umasked_symbol); - ASM::and_reg64_reg64_reg64(&mut self.buf, ptr_reg, ptr_reg, mask_reg); - } + ASM::mov_reg64_imm64(&mut self.buf, unmasked_reg, (!0b111) as _); + + ASM::and_reg64_reg64_reg64(&mut self.buf, unmasked_reg, ptr_reg, unmasked_reg); + + unmasked_reg + }; let mut offset = 0; for field in &other_fields[..index as usize] { offset += self.layout_interner.stack_size(*field); } - ASM::add_reg64_reg64_imm32(&mut self.buf, sym_reg, ptr_reg, offset as i32); + ASM::add_reg64_reg64_imm32(&mut self.buf, sym_reg, unmasked_reg, offset as i32); } } } diff --git a/examples/platform-switching/rocLovesZig.roc b/examples/platform-switching/rocLovesZig.roc index fe838c5396..df8b079d18 100644 --- a/examples/platform-switching/rocLovesZig.roc +++ b/examples/platform-switching/rocLovesZig.roc @@ -3,4 +3,19 @@ app "rocLovesZig" imports [] provides [main] to pf -main = "Roc <3 Zig!\n" +Expr : [Var, Val I64, Add Expr Expr, Mul Expr Expr] + +mkExpr : I64 -> Expr +mkExpr = \n -> + when n is + 0 -> Var + _ -> Add (mkExpr (n-1)) Var + +main : Str +main = + when mkExpr 1 is + Var -> "var" + Add _ _ -> "add" + _ -> "other" + +