Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 38 additions & 23 deletions lib/compiler-singlepass/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
common_decl::*,
config::Singlepass,
location::{Location, Reg},
machine::{Label, Machine, MachineStackOffset, NATIVE_PAGE_SIZE},
machine::{Label, Machine, MachineStackOffset, UnsignedCondition, NATIVE_PAGE_SIZE},
unwind::UnwindFrame,
};
#[cfg(feature = "unwind")]
Expand Down Expand Up @@ -2818,10 +2818,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
)?;
}

self.machine
.location_cmp(Size::S32, func_index, Location::GPR(table_count))?;
self.machine
.jmp_on_belowequal(self.special_labels.table_access_oob)?;
self.machine.jmp_on_condition(
UnsignedCondition::BelowEqual,
Size::S32,
func_index,
Location::GPR(table_count),
self.special_labels.table_access_oob,
)?;
self.machine
.move_location(Size::S32, func_index, Location::GPR(table_count))?;
self.machine.emit_imul_imm32(
Expand All @@ -2843,13 +2846,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
Location::GPR(table_count),
)?;
// Trap if the FuncRef is null
self.machine.location_cmp(
self.machine.jmp_on_condition(
UnsignedCondition::Equal,
Size::S64,
Location::Imm32(0),
Location::GPR(table_count),
self.special_labels.indirect_call_null,
)?;
self.machine
.jmp_on_equal(self.special_labels.indirect_call_null)?;
self.machine.move_location(
Size::S64,
Location::Memory(
Expand All @@ -2860,17 +2863,16 @@ impl<'a, M: Machine> FuncGen<'a, M> {
)?;

// Trap if signature mismatches.
self.machine.location_cmp(
self.machine.jmp_on_condition(
UnsignedCondition::NotEqual,
Size::S32,
Location::GPR(sigidx),
Location::Memory(
table_count,
(self.vmoffsets.vmcaller_checked_anyfunc_type_index() as usize) as i32,
),
self.special_labels.bad_signature,
)?;
self.machine
.jmp_on_different(self.special_labels.bad_signature)?;

self.machine.release_gpr(sigidx);
self.machine.release_gpr(table_count);
self.machine.release_gpr(table_base);
Expand Down Expand Up @@ -2981,9 +2983,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
state_diff_id: self.get_state_diff(),
};
self.control_stack.push(frame);
self.machine
.emit_relaxed_cmp(Size::S32, Location::Imm32(0), cond)?;
self.machine.jmp_on_equal(label_else)?;
self.machine.jmp_on_condition(
UnsignedCondition::Equal,
Size::S32,
Location::Imm32(0),
cond,
label_else,
)?;
}
Operator::Else => {
let frame = self.control_stack.last_mut().unwrap();
Expand Down Expand Up @@ -3051,9 +3057,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
let end_label = self.machine.get_label();
let zero_label = self.machine.get_label();

self.machine
.emit_relaxed_cmp(Size::S32, Location::Imm32(0), cond)?;
self.machine.jmp_on_equal(zero_label)?;
self.machine.jmp_on_condition(
UnsignedCondition::Equal,
Size::S32,
Location::Imm32(0),
cond,
zero_label,
)?;
match cncl {
Some((Some(fp), _))
if self.machine.arch_supports_canonicalize_nan()
Expand Down Expand Up @@ -4051,9 +4061,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
Operator::BrIf { relative_depth } => {
let after = self.machine.get_label();
let cond = self.pop_value_released()?;
self.machine
.emit_relaxed_cmp(Size::S32, Location::Imm32(0), cond)?;
self.machine.jmp_on_equal(after)?;
self.machine.jmp_on_condition(
UnsignedCondition::Equal,
Size::S32,
Location::Imm32(0),
cond,
after,
)?;

let frame =
&self.control_stack[self.control_stack.len() - 1 - (relative_depth as usize)];
Expand Down Expand Up @@ -4096,12 +4110,13 @@ impl<'a, M: Machine> FuncGen<'a, M> {
let table_label = self.machine.get_label();
let mut table: Vec<Label> = vec![];
let default_br = self.machine.get_label();
self.machine.emit_relaxed_cmp(
self.machine.jmp_on_condition(
UnsignedCondition::AboveEqual,
Size::S32,
Location::Imm32(targets.len() as u32),
cond,
default_br,
)?;
self.machine.jmp_on_aboveequal(default_br)?;

self.machine.emit_jmp_to_jumptable(table_label, cond)?;

Expand Down
38 changes: 20 additions & 18 deletions lib/compiler-singlepass/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ pub const NATIVE_PAGE_SIZE: usize = 4096;

pub struct MachineStackOffset(pub usize);

#[allow(dead_code)]
pub enum UnsignedCondition {
Equal,
NotEqual,
Above,
AboveEqual,
Below,
BelowEqual,
}

#[allow(unused)]
pub trait Machine {
type GPR: Copy + Eq + Debug + Reg;
Expand Down Expand Up @@ -382,24 +392,16 @@ pub trait Machine {

/// jmp without condidtion
fn jmp_unconditionnal(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on equal (src==dst)
/// like Equal set on x86_64
fn jmp_on_equal(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on different (src!=dst)
/// like NotEqual set on x86_64
fn jmp_on_different(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on above (src>dst)
/// like Above set on x86_64
fn jmp_on_above(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on above (src>=dst)
/// like Above or Equal set on x86_64
fn jmp_on_aboveequal(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on above (src<=dst)
/// like Below or Equal set on x86_64
fn jmp_on_belowequal(&mut self, label: Label) -> Result<(), CompileError>;
/// jmp on overflow
/// like Carry set on x86_64
fn jmp_on_overflow(&mut self, label: Label) -> Result<(), CompileError>;

/// jmp to label if the provided condition is true (when comparing source and dest)
fn jmp_on_condition(
&mut self,
cond: UnsignedCondition,
size: Size,
source: Location<Self::GPR, Self::SIMD>,
dest: Location<Self::GPR, Self::SIMD>,
label: Label,
) -> Result<(), CompileError>;

/// jmp using a jump table at lable with cond as the indice
fn emit_jmp_to_jumptable(
Expand Down
36 changes: 19 additions & 17 deletions lib/compiler-singlepass/src/machine_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2604,23 +2604,25 @@ impl Machine for MachineARM64 {
fn jmp_unconditionnal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_b_label(label)
}
fn jmp_on_equal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Eq, label)
}
fn jmp_on_different(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Ne, label)
}
fn jmp_on_above(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Hi, label)
}
fn jmp_on_aboveequal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Cs, label)
}
fn jmp_on_belowequal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Ls, label)
}
fn jmp_on_overflow(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_bcond_label_far(Condition::Cs, label)

fn jmp_on_condition(
&mut self,
cond: UnsignedCondition,
size: Size,
source: AbstractLocation<Self::GPR, Self::SIMD>,
dest: AbstractLocation<Self::GPR, Self::SIMD>,
label: Label,
) -> Result<(), CompileError> {
self.emit_relaxed_binop(Assembler::emit_cmp, size, source, dest, false)?;
let cond = match cond {
UnsignedCondition::Equal => Condition::Eq,
UnsignedCondition::NotEqual => Condition::Ne,
UnsignedCondition::Above => Condition::Hi,
UnsignedCondition::AboveEqual => Condition::Cs,
UnsignedCondition::Below => Condition::Cc,
UnsignedCondition::BelowEqual => Condition::Ls,
};
self.assembler.emit_bcond_label_far(cond, label)
}

// jmp table
Expand Down
42 changes: 22 additions & 20 deletions lib/compiler-singlepass/src/machine_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ impl MachineX86_64 {
},
)?;

self.jmp_on_different(retry)?;
self.assembler.emit_jmp(Condition::NotEqual, retry)?;

self.assembler.emit_pop(Size::S64, Location::GPR(value))?;
self.release_gpr(compare);
Expand Down Expand Up @@ -2751,28 +2751,30 @@ impl Machine for MachineX86_64 {
) -> Result<(), CompileError> {
self.assembler.emit_cmp(size, source, dest)
}
// (un)conditionnal jmp
// (un)conditionnal jmp

// unconditionnal jmp
fn jmp_unconditionnal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::None, label)
}
fn jmp_on_equal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::Equal, label)
}
fn jmp_on_different(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::NotEqual, label)
}
fn jmp_on_above(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::Above, label)
}
fn jmp_on_aboveequal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::AboveEqual, label)
}
fn jmp_on_belowequal(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::BelowEqual, label)
}
fn jmp_on_overflow(&mut self, label: Label) -> Result<(), CompileError> {
self.assembler.emit_jmp(Condition::Carry, label)

fn jmp_on_condition(
&mut self,
cond: UnsignedCondition,
size: Size,
source: AbstractLocation<Self::GPR, Self::SIMD>,
dest: AbstractLocation<Self::GPR, Self::SIMD>,
label: Label,
) -> Result<(), CompileError> {
self.assembler.emit_cmp(size, source, dest)?;
let cond = match cond {
UnsignedCondition::Equal => Condition::Equal,
UnsignedCondition::NotEqual => Condition::NotEqual,
UnsignedCondition::Above => Condition::Above,
UnsignedCondition::AboveEqual => Condition::AboveEqual,
UnsignedCondition::Below => Condition::Below,
UnsignedCondition::BelowEqual => Condition::BelowEqual,
};
self.assembler.emit_jmp(cond, label)
}

// jmp table
Expand Down
Loading