Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Singlepass f32_load and f64_load function, and introduce emit_bond_label_far as direct bcond may not work all the time (for #2777) #2778

Merged
merged 1 commit into from Feb 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions lib/compiler-singlepass/src/emitter_arm64.rs
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
}
Expand Down
28 changes: 13 additions & 15 deletions lib/compiler-singlepass/src/machine_arm64.rs
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
},
);
}
Expand Down Expand Up @@ -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));
},
);
}
Expand Down