Skip to content

Commit b5193c5

Browse files
committed
impl i{32,64} comparison translation
1 parent a7dc6a0 commit b5193c5

File tree

2 files changed

+151
-16
lines changed

2 files changed

+151
-16
lines changed

crates/wasmi/src/engine/translator/func2/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,61 @@ impl FuncTranslator {
899899
}
900900
}
901901

902+
/// Translates binary non-commutative Wasm operators to Wasmi bytecode.
903+
fn translate_binary<T, R>(
904+
&mut self,
905+
make_instr: fn(result: Reg, lhs: Reg, rhs: Reg) -> Instruction,
906+
make_instr_imm16_rhs: fn(result: Reg, lhs: Reg, rhs: Const16<T>) -> Instruction,
907+
make_instr_imm16_lhs: fn(result: Reg, lhs: Const16<T>, rhs: Reg) -> Instruction,
908+
consteval: fn(T, T) -> R,
909+
) -> Result<(), Error>
910+
where
911+
T: WasmInteger,
912+
R: Into<TypedVal>,
913+
{
914+
bail_unreachable!(self);
915+
match self.stack.pop2() {
916+
(Operand::Immediate(lhs), Operand::Immediate(rhs)) => {
917+
self.translate_binary_consteval::<T, R>(lhs, rhs, consteval)
918+
}
919+
(lhs, Operand::Immediate(rhs)) => {
920+
let lhs = self.layout.operand_to_reg(lhs)?;
921+
let rhs = T::from(rhs.val());
922+
let rhs16 = self.make_imm16(rhs)?;
923+
self.push_instr_with_result(
924+
<T as Typed>::TY,
925+
|result| match rhs16 {
926+
Operand16::Immediate(rhs) => make_instr_imm16_rhs(result, lhs, rhs),
927+
Operand16::Reg(rhs) => make_instr(result, lhs, rhs),
928+
},
929+
FuelCostsProvider::base,
930+
)
931+
}
932+
(Operand::Immediate(lhs), rhs) => {
933+
let lhs = T::from(lhs.val());
934+
let lhs16 = self.make_imm16(lhs)?;
935+
let rhs = self.layout.operand_to_reg(rhs)?;
936+
self.push_instr_with_result(
937+
<T as Typed>::TY,
938+
|result| match lhs16 {
939+
Operand16::Immediate(lhs) => make_instr_imm16_lhs(result, lhs, rhs),
940+
Operand16::Reg(lhs) => make_instr(result, lhs, rhs),
941+
},
942+
FuelCostsProvider::base,
943+
)
944+
}
945+
(lhs, rhs) => {
946+
let lhs = self.layout.operand_to_reg(lhs)?;
947+
let rhs = self.layout.operand_to_reg(rhs)?;
948+
self.push_instr_with_result(
949+
<T as Typed>::TY,
950+
|result| make_instr(result, lhs, rhs),
951+
FuelCostsProvider::base,
952+
)
953+
}
954+
}
955+
}
956+
902957
/// Translates a generic trap instruction.
903958
fn translate_trap(&mut self, trap: TrapCode) -> Result<(), Error> {
904959
self.push_instr(Instruction::trap(trap), FuelCostsProvider::base)?;

crates/wasmi/src/engine/translator/func2/visit.rs

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -457,35 +457,75 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
457457
}
458458

459459
fn visit_i32_lt_s(&mut self) -> Self::Output {
460-
todo!()
460+
self.translate_binary::<i32, bool>(
461+
Instruction::i32_lt_s,
462+
Instruction::i32_lt_s_imm16_rhs,
463+
Instruction::i32_lt_s_imm16_lhs,
464+
wasm::i32_lt_s,
465+
)
461466
}
462467

463468
fn visit_i32_lt_u(&mut self) -> Self::Output {
464-
todo!()
469+
self.translate_binary::<u32, bool>(
470+
Instruction::i32_lt_u,
471+
Instruction::i32_lt_u_imm16_rhs,
472+
Instruction::i32_lt_u_imm16_lhs,
473+
wasm::i32_lt_u,
474+
)
465475
}
466476

467477
fn visit_i32_gt_s(&mut self) -> Self::Output {
468-
todo!()
478+
self.translate_binary::<i32, bool>(
479+
swap_ops!(Instruction::i32_lt_s),
480+
swap_ops!(Instruction::i32_lt_s_imm16_lhs),
481+
swap_ops!(Instruction::i32_lt_s_imm16_rhs),
482+
wasm::i32_gt_s,
483+
)
469484
}
470485

471486
fn visit_i32_gt_u(&mut self) -> Self::Output {
472-
todo!()
487+
self.translate_binary::<u32, bool>(
488+
swap_ops!(Instruction::i32_lt_u),
489+
swap_ops!(Instruction::i32_lt_u_imm16_lhs),
490+
swap_ops!(Instruction::i32_lt_u_imm16_rhs),
491+
wasm::i32_gt_u,
492+
)
473493
}
474494

475495
fn visit_i32_le_s(&mut self) -> Self::Output {
476-
todo!()
496+
self.translate_binary::<i32, bool>(
497+
Instruction::i32_le_s,
498+
Instruction::i32_le_s_imm16_rhs,
499+
Instruction::i32_le_s_imm16_lhs,
500+
wasm::i32_le_s,
501+
)
477502
}
478503

479504
fn visit_i32_le_u(&mut self) -> Self::Output {
480-
todo!()
505+
self.translate_binary::<u32, bool>(
506+
Instruction::i32_le_u,
507+
Instruction::i32_le_u_imm16_rhs,
508+
Instruction::i32_le_u_imm16_lhs,
509+
wasm::i32_le_u,
510+
)
481511
}
482512

483513
fn visit_i32_ge_s(&mut self) -> Self::Output {
484-
todo!()
514+
self.translate_binary::<i32, bool>(
515+
swap_ops!(Instruction::i32_le_s),
516+
swap_ops!(Instruction::i32_le_s_imm16_lhs),
517+
swap_ops!(Instruction::i32_le_s_imm16_rhs),
518+
wasm::i32_ge_s,
519+
)
485520
}
486521

487522
fn visit_i32_ge_u(&mut self) -> Self::Output {
488-
todo!()
523+
self.translate_binary::<u32, bool>(
524+
swap_ops!(Instruction::i32_le_u),
525+
swap_ops!(Instruction::i32_le_u_imm16_lhs),
526+
swap_ops!(Instruction::i32_le_u_imm16_rhs),
527+
wasm::i32_ge_u,
528+
)
489529
}
490530

491531
fn visit_i64_eqz(&mut self) -> Self::Output {
@@ -511,35 +551,75 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
511551
}
512552

513553
fn visit_i64_lt_s(&mut self) -> Self::Output {
514-
todo!()
554+
self.translate_binary::<i64, bool>(
555+
Instruction::i64_lt_s,
556+
Instruction::i64_lt_s_imm16_rhs,
557+
Instruction::i64_lt_s_imm16_lhs,
558+
wasm::i64_lt_s,
559+
)
515560
}
516561

517562
fn visit_i64_lt_u(&mut self) -> Self::Output {
518-
todo!()
563+
self.translate_binary::<u64, bool>(
564+
Instruction::i64_lt_u,
565+
Instruction::i64_lt_u_imm16_rhs,
566+
Instruction::i64_lt_u_imm16_lhs,
567+
wasm::i64_lt_u,
568+
)
519569
}
520570

521571
fn visit_i64_gt_s(&mut self) -> Self::Output {
522-
todo!()
572+
self.translate_binary::<i64, bool>(
573+
swap_ops!(Instruction::i64_lt_s),
574+
swap_ops!(Instruction::i64_lt_s_imm16_lhs),
575+
swap_ops!(Instruction::i64_lt_s_imm16_rhs),
576+
wasm::i64_gt_s,
577+
)
523578
}
524579

525580
fn visit_i64_gt_u(&mut self) -> Self::Output {
526-
todo!()
581+
self.translate_binary::<u64, bool>(
582+
swap_ops!(Instruction::i64_lt_u),
583+
swap_ops!(Instruction::i64_lt_u_imm16_lhs),
584+
swap_ops!(Instruction::i64_lt_u_imm16_rhs),
585+
wasm::i64_gt_u,
586+
)
527587
}
528588

529589
fn visit_i64_le_s(&mut self) -> Self::Output {
530-
todo!()
590+
self.translate_binary::<i64, bool>(
591+
Instruction::i64_le_s,
592+
Instruction::i64_le_s_imm16_rhs,
593+
Instruction::i64_le_s_imm16_lhs,
594+
wasm::i64_le_s,
595+
)
531596
}
532597

533598
fn visit_i64_le_u(&mut self) -> Self::Output {
534-
todo!()
599+
self.translate_binary::<u64, bool>(
600+
Instruction::i64_le_u,
601+
Instruction::i64_le_u_imm16_rhs,
602+
Instruction::i64_le_u_imm16_lhs,
603+
wasm::i64_le_u,
604+
)
535605
}
536606

537607
fn visit_i64_ge_s(&mut self) -> Self::Output {
538-
todo!()
608+
self.translate_binary::<i64, bool>(
609+
swap_ops!(Instruction::i64_le_s),
610+
swap_ops!(Instruction::i64_le_s_imm16_lhs),
611+
swap_ops!(Instruction::i64_le_s_imm16_rhs),
612+
wasm::i64_ge_s,
613+
)
539614
}
540615

541616
fn visit_i64_ge_u(&mut self) -> Self::Output {
542-
todo!()
617+
self.translate_binary::<u64, bool>(
618+
swap_ops!(Instruction::i64_le_u),
619+
swap_ops!(Instruction::i64_le_u_imm16_lhs),
620+
swap_ops!(Instruction::i64_le_u_imm16_rhs),
621+
wasm::i64_ge_u,
622+
)
543623
}
544624

545625
fn visit_f32_eq(&mut self) -> Self::Output {

0 commit comments

Comments
 (0)