mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Add greater than
comparison
This commit is contained in:
parent
3683e9d436
commit
6670a5d205
5 changed files with 128 additions and 2 deletions
|
@ -788,6 +788,26 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
|
||||||
todo!("registers unsigned less than for AArch64");
|
todo!("registers unsigned less than for AArch64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn igt_reg64_reg64_reg64(
|
||||||
|
_buf: &mut Vec<'_, u8>,
|
||||||
|
_dst: AArch64GeneralReg,
|
||||||
|
_src1: AArch64GeneralReg,
|
||||||
|
_src2: AArch64GeneralReg,
|
||||||
|
) {
|
||||||
|
todo!("registers signed greater than for AArch64");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn ugt_reg64_reg64_reg64(
|
||||||
|
_buf: &mut Vec<'_, u8>,
|
||||||
|
_dst: AArch64GeneralReg,
|
||||||
|
_src1: AArch64GeneralReg,
|
||||||
|
_src2: AArch64GeneralReg,
|
||||||
|
) {
|
||||||
|
todo!("registers unsigned greater than for AArch64");
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_float_freg64_reg64(
|
fn to_float_freg64_reg64(
|
||||||
_buf: &mut Vec<'_, u8>,
|
_buf: &mut Vec<'_, u8>,
|
||||||
|
|
|
@ -332,6 +332,20 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait>: Sized + Copy {
|
||||||
src2: GeneralReg,
|
src2: GeneralReg,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn igt_reg64_reg64_reg64(
|
||||||
|
buf: &mut Vec<'_, u8>,
|
||||||
|
dst: GeneralReg,
|
||||||
|
src1: GeneralReg,
|
||||||
|
src2: GeneralReg,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn ugt_reg64_reg64_reg64(
|
||||||
|
buf: &mut Vec<'_, u8>,
|
||||||
|
dst: GeneralReg,
|
||||||
|
src1: GeneralReg,
|
||||||
|
src2: GeneralReg,
|
||||||
|
);
|
||||||
|
|
||||||
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
|
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
|
||||||
|
|
||||||
fn to_float_freg64_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
|
fn to_float_freg64_reg64(buf: &mut Vec<'_, u8>, dst: FloatReg, src: GeneralReg);
|
||||||
|
@ -1100,6 +1114,38 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_num_gt(
|
||||||
|
&mut self,
|
||||||
|
dst: &Symbol,
|
||||||
|
src1: &Symbol,
|
||||||
|
src2: &Symbol,
|
||||||
|
arg_layout: &InLayout<'a>,
|
||||||
|
) {
|
||||||
|
match self.layout_interner.get(*arg_layout) {
|
||||||
|
Layout::Builtin(Builtin::Int(IntWidth::I64)) => {
|
||||||
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
let src1_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src1);
|
||||||
|
let src2_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src2);
|
||||||
|
ASM::igt_reg64_reg64_reg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
|
||||||
|
}
|
||||||
|
Layout::Builtin(Builtin::Int(IntWidth::U64)) => {
|
||||||
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
let src1_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src1);
|
||||||
|
let src2_reg = self
|
||||||
|
.storage_manager
|
||||||
|
.load_to_general_reg(&mut self.buf, src2);
|
||||||
|
ASM::ugt_reg64_reg64_reg64(&mut self.buf, dst_reg, src1_reg, src2_reg);
|
||||||
|
}
|
||||||
|
x => todo!("NumGt: layout, {:?}", x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn build_num_to_frac(
|
fn build_num_to_frac(
|
||||||
&mut self,
|
&mut self,
|
||||||
dst: &Symbol,
|
dst: &Symbol,
|
||||||
|
|
|
@ -1368,6 +1368,28 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
|
||||||
setb_reg64(buf, dst);
|
setb_reg64(buf, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn igt_reg64_reg64_reg64(
|
||||||
|
buf: &mut Vec<'_, u8>,
|
||||||
|
dst: X86_64GeneralReg,
|
||||||
|
src1: X86_64GeneralReg,
|
||||||
|
src2: X86_64GeneralReg,
|
||||||
|
) {
|
||||||
|
cmp_reg64_reg64(buf, src1, src2);
|
||||||
|
setg_reg64(buf, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn ugt_reg64_reg64_reg64(
|
||||||
|
buf: &mut Vec<'_, u8>,
|
||||||
|
dst: X86_64GeneralReg,
|
||||||
|
src1: X86_64GeneralReg,
|
||||||
|
src2: X86_64GeneralReg,
|
||||||
|
) {
|
||||||
|
cmp_reg64_reg64(buf, src1, src2);
|
||||||
|
seta_reg64(buf, dst);
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) {
|
fn to_float_freg32_reg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64GeneralReg) {
|
||||||
cvtsi2ss_freg64_reg64(buf, dst, src);
|
cvtsi2ss_freg64_reg64(buf, dst, src);
|
||||||
|
@ -2173,6 +2195,18 @@ fn setb_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
||||||
set_reg64_help(0x92, buf, reg);
|
set_reg64_help(0x92, buf, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `SETG r/m64` -> Set byte if greater (ZF=0 and SF=OF).
|
||||||
|
#[inline(always)]
|
||||||
|
fn setg_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
||||||
|
set_reg64_help(0x9f, buf, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `SETA r/m64` -> Set byte if above (CF=0 and ZF=0).
|
||||||
|
#[inline(always)]
|
||||||
|
fn seta_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
||||||
|
set_reg64_help(0x97, buf, reg);
|
||||||
|
}
|
||||||
|
|
||||||
/// `SETLE r/m64` -> Set byte if less or equal (ZF=1 or SF≠ OF).
|
/// `SETLE r/m64` -> Set byte if less or equal (ZF=1 or SF≠ OF).
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn setle_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
fn setle_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) {
|
||||||
|
|
|
@ -584,6 +584,23 @@ trait Backend<'a> {
|
||||||
);
|
);
|
||||||
self.build_num_lt(sym, &args[0], &args[1], &arg_layouts[0])
|
self.build_num_lt(sym, &args[0], &args[1], &arg_layouts[0])
|
||||||
}
|
}
|
||||||
|
LowLevel::NumGt => {
|
||||||
|
debug_assert_eq!(
|
||||||
|
2,
|
||||||
|
args.len(),
|
||||||
|
"NumGt: expected to have exactly two argument"
|
||||||
|
);
|
||||||
|
debug_assert_eq!(
|
||||||
|
arg_layouts[0], arg_layouts[1],
|
||||||
|
"NumGt: expected all arguments of to have the same layout"
|
||||||
|
);
|
||||||
|
debug_assert_eq!(
|
||||||
|
Layout::BOOL,
|
||||||
|
*ret_layout,
|
||||||
|
"NumGt: expected to have return layout of type Bool"
|
||||||
|
);
|
||||||
|
self.build_num_gt(sym, &args[0], &args[1], &arg_layouts[0])
|
||||||
|
}
|
||||||
LowLevel::NumToFrac => {
|
LowLevel::NumToFrac => {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
1,
|
1,
|
||||||
|
@ -837,6 +854,15 @@ trait Backend<'a> {
|
||||||
arg_layout: &InLayout<'a>,
|
arg_layout: &InLayout<'a>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// build_num_gt stores the result of `src1 > src2` into dst.
|
||||||
|
fn build_num_gt(
|
||||||
|
&mut self,
|
||||||
|
dst: &Symbol,
|
||||||
|
src1: &Symbol,
|
||||||
|
src2: &Symbol,
|
||||||
|
arg_layout: &InLayout<'a>,
|
||||||
|
);
|
||||||
|
|
||||||
/// build_num_to_frac convert Number to Frac
|
/// build_num_to_frac convert Number to Frac
|
||||||
fn build_num_to_frac(
|
fn build_num_to_frac(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -1402,7 +1402,7 @@ fn lte_u64() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn gt_u64() {
|
fn gt_u64() {
|
||||||
assert_evals_to!("2u64 > 1u64", true, bool);
|
assert_evals_to!("2u64 > 1u64", true, bool);
|
||||||
assert_evals_to!("2u64 > 2u64", false, bool);
|
assert_evals_to!("2u64 > 2u64", false, bool);
|
||||||
|
@ -1440,7 +1440,7 @@ fn lte_i64() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn gt_i64() {
|
fn gt_i64() {
|
||||||
assert_evals_to!("2 > 1", true, bool);
|
assert_evals_to!("2 > 1", true, bool);
|
||||||
assert_evals_to!("2 > 2", false, bool);
|
assert_evals_to!("2 > 2", false, bool);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue