diff --git a/lib/compiler-singlepass/src/emitter_arm64.rs b/lib/compiler-singlepass/src/emitter_arm64.rs index 51722a051a1..08505560d94 100644 --- a/lib/compiler-singlepass/src/emitter_arm64.rs +++ b/lib/compiler-singlepass/src/emitter_arm64.rs @@ -165,6 +165,7 @@ pub trait EmitterARM64 { fn emit_tbz_label(&mut self, sz: Size, reg: Location, n: u32, label: Label); fn emit_tbnz_label(&mut self, sz: Size, reg: Location, n: u32, label: Label); fn emit_bcond_label(&mut self, condition: Condition, label: Label); + fn emit_bcond_label_far(&mut self, condition: Condition, label: Label); fn emit_b_register(&mut self, reg: GPR); fn emit_call_label(&mut self, label: Label); fn emit_call_register(&mut self, reg: GPR); @@ -1934,6 +1935,29 @@ impl EmitterARM64 for Assembler { Condition::Al => dynasm!(self ; b => label), } } + fn emit_bcond_label_far(&mut self, condition: Condition, label: Label) { + let cont: Label = self.get_label(); + match condition { + // if not condition than continue + Condition::Eq => dynasm!(self ; b.ne => cont), + Condition::Ne => dynasm!(self ; b.eq => cont), + Condition::Cs => dynasm!(self ; b.cc => cont), + Condition::Cc => dynasm!(self ; b.cs => cont), + Condition::Mi => dynasm!(self ; b.pl => cont), + Condition::Pl => dynasm!(self ; b.mi => cont), + Condition::Vs => dynasm!(self ; b.vc => cont), + Condition::Vc => dynasm!(self ; b.vs => cont), + Condition::Hi => dynasm!(self ; b.ls => cont), + Condition::Ls => dynasm!(self ; b.hi => cont), + Condition::Ge => dynasm!(self ; b.lt => cont), + Condition::Lt => dynasm!(self ; b.ge => cont), + Condition::Gt => dynasm!(self ; b.le => cont), + Condition::Le => dynasm!(self ; b.gt => cont), + Condition::Al => { /*nothing*/ } + } + dynasm!(self ; b => label); + self.emit_label(cont); + } fn emit_b_register(&mut self, reg: GPR) { dynasm!(self ; br X(reg.into_index() as u32)); } diff --git a/lib/compiler-singlepass/src/machine_arm64.rs b/lib/compiler-singlepass/src/machine_arm64.rs index eca8e1f5777..9b678b7e453 100644 --- a/lib/compiler-singlepass/src/machine_arm64.rs +++ b/lib/compiler-singlepass/src/machine_arm64.rs @@ -832,7 +832,7 @@ impl MachineARM64 { // Trap if offset calculation overflowed. self.assembler - .emit_bcond_label(Condition::Cs, heap_access_oob); + .emit_bcond_label_far(Condition::Cs, heap_access_oob); } // Wasm linear memory -> real memory @@ -850,7 +850,7 @@ impl MachineARM64 { // `tmp_bound` is inclusive. So trap only if `tmp_addr > tmp_bound`. self.assembler - .emit_bcond_label(Condition::Hi, heap_access_oob); + .emit_bcond_label_far(Condition::Hi, heap_access_oob); } self.release_gpr(tmp_bound); @@ -864,7 +864,7 @@ impl MachineARM64 { Location::GPR(tmp_addr), ); self.assembler - .emit_bcond_label(Condition::Ne, heap_access_oob); + .emit_bcond_label_far(Condition::Ne, heap_access_oob); } let begin = self.assembler.get_offset().0; cb(self, tmp_addr); @@ -2093,22 +2093,22 @@ impl Machine for MachineARM64 { self.assembler.emit_b_label(label); } fn jmp_on_equal(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Eq, label); + self.assembler.emit_bcond_label_far(Condition::Eq, label); } fn jmp_on_different(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Ne, label); + self.assembler.emit_bcond_label_far(Condition::Ne, label); } fn jmp_on_above(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Hi, label); + self.assembler.emit_bcond_label_far(Condition::Hi, label); } fn jmp_on_aboveequal(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Cs, label); + self.assembler.emit_bcond_label_far(Condition::Cs, label); } fn jmp_on_belowequal(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Ls, label); + self.assembler.emit_bcond_label_far(Condition::Ls, label); } fn jmp_on_overflow(&mut self, label: Label) { - self.assembler.emit_bcond_label(Condition::Cs, label); + self.assembler.emit_bcond_label_far(Condition::Cs, label); } // jmp table @@ -2310,7 +2310,7 @@ impl Machine for MachineARM64 { self.assembler.emit_movn(Size::S32, tmp, 0); self.assembler.emit_cmp(Size::S32, tmp, src2); self.assembler - .emit_bcond_label(Condition::Eq, integer_overflow); + .emit_bcond_label_far(Condition::Eq, integer_overflow); let offset = self.mark_instruction_with_trap_code(TrapCode::IntegerOverflow); self.assembler.emit_label(label_nooverflow); self.assembler.emit_sdiv(Size::S32, src1, src2, dest); @@ -3265,7 +3265,7 @@ impl Machine for MachineARM64 { self.assembler.emit_movn(Size::S64, tmp, 0); self.assembler.emit_cmp(Size::S64, tmp, src2); self.assembler - .emit_bcond_label(Condition::Eq, integer_overflow); + .emit_bcond_label_far(Condition::Eq, integer_overflow); let offset = self.mark_instruction_with_trap_code(TrapCode::IntegerOverflow); self.assembler.emit_label(label_nooverflow); self.assembler.emit_sdiv(Size::S64, src1, src2, dest); @@ -4310,8 +4310,7 @@ impl Machine for MachineARM64 { offset, heap_access_oob, |this, addr| { - this.assembler - .emit_ldr(Size::S32, ret, Location::Memory(addr, 0)); + this.emit_relaxed_ldr32(Size::S32, ret, Location::Memory(addr, 0)); }, ); } @@ -4365,8 +4364,7 @@ impl Machine for MachineARM64 { offset, heap_access_oob, |this, addr| { - this.assembler - .emit_ldr(Size::S64, ret, Location::Memory(addr, 0)); + this.emit_relaxed_ldr64(Size::S64, ret, Location::Memory(addr, 0)); }, ); }