Merge pull request #2975 from afonso360/aarch64-icmp
aarch64: Implement lowering i128 icmp instructions
This commit is contained in:
@@ -599,10 +599,14 @@ impl MachInstEmit for Inst {
|
||||
ALUOp::Add64 => 0b10001011_000,
|
||||
ALUOp::Adc32 => 0b00011010_000,
|
||||
ALUOp::Adc64 => 0b10011010_000,
|
||||
ALUOp::AdcS32 => 0b00111010_000,
|
||||
ALUOp::AdcS64 => 0b10111010_000,
|
||||
ALUOp::Sub32 => 0b01001011_000,
|
||||
ALUOp::Sub64 => 0b11001011_000,
|
||||
ALUOp::Sbc32 => 0b01011010_000,
|
||||
ALUOp::Sbc64 => 0b11011010_000,
|
||||
ALUOp::SbcS32 => 0b01111010_000,
|
||||
ALUOp::SbcS64 => 0b11111010_000,
|
||||
ALUOp::Orr32 => 0b00101010_000,
|
||||
ALUOp::Orr64 => 0b10101010_000,
|
||||
ALUOp::And32 => 0b00001010_000,
|
||||
|
||||
@@ -70,6 +70,26 @@ fn test_aarch64_binemit() {
|
||||
"A400069A",
|
||||
"adc x4, x5, x6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AdcS32,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
},
|
||||
"4100033A",
|
||||
"adcs w1, w2, w3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::AdcS64,
|
||||
rd: writable_xreg(4),
|
||||
rn: xreg(5),
|
||||
rm: xreg(6),
|
||||
},
|
||||
"A40006BA",
|
||||
"adcs x4, x5, x6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::Sub32,
|
||||
@@ -110,6 +130,26 @@ fn test_aarch64_binemit() {
|
||||
"A40006DA",
|
||||
"sbc x4, x5, x6",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SbcS32,
|
||||
rd: writable_xreg(1),
|
||||
rn: xreg(2),
|
||||
rm: xreg(3),
|
||||
},
|
||||
"4100037A",
|
||||
"sbcs w1, w2, w3",
|
||||
));
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
alu_op: ALUOp::SbcS64,
|
||||
rd: writable_xreg(4),
|
||||
rn: xreg(5),
|
||||
rm: xreg(6),
|
||||
},
|
||||
"A40006FA",
|
||||
"sbcs x4, x5, x6",
|
||||
));
|
||||
|
||||
insns.push((
|
||||
Inst::AluRRR {
|
||||
|
||||
@@ -89,9 +89,15 @@ pub enum ALUOp {
|
||||
/// Add with carry
|
||||
Adc32,
|
||||
Adc64,
|
||||
/// Add with carry, settings flags
|
||||
AdcS32,
|
||||
AdcS64,
|
||||
/// Subtract with carry
|
||||
Sbc32,
|
||||
Sbc64,
|
||||
/// Subtract with carry, settings flags
|
||||
SbcS32,
|
||||
SbcS64,
|
||||
}
|
||||
|
||||
/// An ALU operation with three arguments.
|
||||
@@ -3216,8 +3222,12 @@ impl Inst {
|
||||
ALUOp::Lsl64 => ("lsl", OperandSize::Size64),
|
||||
ALUOp::Adc32 => ("adc", OperandSize::Size32),
|
||||
ALUOp::Adc64 => ("adc", OperandSize::Size64),
|
||||
ALUOp::AdcS32 => ("adcs", OperandSize::Size32),
|
||||
ALUOp::AdcS64 => ("adcs", OperandSize::Size64),
|
||||
ALUOp::Sbc32 => ("sbc", OperandSize::Size32),
|
||||
ALUOp::Sbc64 => ("sbc", OperandSize::Size64),
|
||||
ALUOp::SbcS32 => ("sbcs", OperandSize::Size32),
|
||||
ALUOp::SbcS64 => ("sbcs", OperandSize::Size64),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Lower a single Cranelift instruction into vcode.
|
||||
|
||||
use crate::binemit::CodeOffset;
|
||||
use crate::ir::condcodes::FloatCC;
|
||||
use crate::ir::condcodes::{FloatCC, IntCC};
|
||||
use crate::ir::types::*;
|
||||
use crate::ir::Inst as IRInst;
|
||||
use crate::ir::{InstructionData, Opcode, TrapCode};
|
||||
@@ -1735,14 +1735,112 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
(false, true) => NarrowValueMode::SignExtend64,
|
||||
(false, false) => NarrowValueMode::ZeroExtend64,
|
||||
};
|
||||
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||
|
||||
if !ty.is_vector() {
|
||||
if ty == I128 {
|
||||
let lhs = put_input_in_regs(ctx, inputs[0]);
|
||||
let rhs = put_input_in_regs(ctx, inputs[1]);
|
||||
|
||||
let tmp1 = ctx.alloc_tmp(I64).only_reg().unwrap();
|
||||
let tmp2 = ctx.alloc_tmp(I64).only_reg().unwrap();
|
||||
|
||||
match condcode {
|
||||
IntCC::Equal | IntCC::NotEqual => {
|
||||
// eor tmp1, lhs_lo, rhs_lo
|
||||
// eor tmp2, lhs_hi, rhs_hi
|
||||
// adds xzr, tmp1, tmp2
|
||||
// cset dst, {eq, ne}
|
||||
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::Eor64,
|
||||
rd: tmp1,
|
||||
rn: lhs.regs()[0],
|
||||
rm: rhs.regs()[0],
|
||||
});
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::Eor64,
|
||||
rd: tmp2,
|
||||
rn: lhs.regs()[1],
|
||||
rm: rhs.regs()[1],
|
||||
});
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::AddS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: tmp1.to_reg(),
|
||||
rm: tmp2.to_reg(),
|
||||
});
|
||||
materialize_bool_result(ctx, insn, rd, cond);
|
||||
}
|
||||
IntCC::Overflow | IntCC::NotOverflow => {
|
||||
// We can do an 128bit add while throwing away the results
|
||||
// and check the overflow flags at the end.
|
||||
//
|
||||
// adds xzr, lhs_lo, rhs_lo
|
||||
// adcs xzr, lhs_hi, rhs_hi
|
||||
// cset dst, {vs, vc}
|
||||
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::AddS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: lhs.regs()[0],
|
||||
rm: rhs.regs()[0],
|
||||
});
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::AdcS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: lhs.regs()[1],
|
||||
rm: rhs.regs()[1],
|
||||
});
|
||||
materialize_bool_result(ctx, insn, rd, cond);
|
||||
}
|
||||
_ => {
|
||||
// cmp lhs_lo, rhs_lo
|
||||
// cset tmp1, low_cc
|
||||
// cmp lhs_hi, rhs_hi
|
||||
// cset tmp2, cond
|
||||
// csel dst, tmp1, tmp2, eq
|
||||
|
||||
let low_cc = match condcode {
|
||||
IntCC::SignedGreaterThanOrEqual | IntCC::UnsignedGreaterThanOrEqual => {
|
||||
Cond::Hs
|
||||
}
|
||||
IntCC::SignedGreaterThan | IntCC::UnsignedGreaterThan => Cond::Hi,
|
||||
IntCC::SignedLessThanOrEqual | IntCC::UnsignedLessThanOrEqual => {
|
||||
Cond::Ls
|
||||
}
|
||||
IntCC::SignedLessThan | IntCC::UnsignedLessThan => Cond::Lo,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::SubS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: lhs.regs()[0],
|
||||
rm: rhs.regs()[0],
|
||||
});
|
||||
materialize_bool_result(ctx, insn, tmp1, low_cc);
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::SubS64,
|
||||
rd: writable_zero_reg(),
|
||||
rn: lhs.regs()[1],
|
||||
rm: rhs.regs()[1],
|
||||
});
|
||||
materialize_bool_result(ctx, insn, tmp2, cond);
|
||||
ctx.emit(Inst::CSel {
|
||||
cond: Cond::Eq,
|
||||
rd,
|
||||
rn: tmp1.to_reg(),
|
||||
rm: tmp2.to_reg(),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if !ty.is_vector() {
|
||||
let alu_op = choose_32_64(ty, ALUOp::SubS32, ALUOp::SubS64);
|
||||
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||
let rm = put_input_in_rse_imm12(ctx, inputs[1], narrow_mode);
|
||||
ctx.emit(alu_inst_imm12(alu_op, writable_zero_reg(), rn, rm));
|
||||
materialize_bool_result(ctx, insn, rd, cond);
|
||||
} else {
|
||||
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||
let rm = put_input_in_reg(ctx, inputs[1], narrow_mode);
|
||||
lower_vector_compare(ctx, rd, rn, rm, ty, cond)?;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,197 @@ block0(v0: i64, v1: i64):
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_eq_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp eq v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: eor x0, x0, x2
|
||||
; nextln: eor x1, x1, x3
|
||||
; nextln: adds xzr, x0, x1
|
||||
; nextln: cset x0, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %icmp_ne_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp ne v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: eor x0, x0, x2
|
||||
; nextln: eor x1, x1, x3
|
||||
; nextln: adds xzr, x0, x1
|
||||
; nextln: cset x0, ne
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %icmp_slt_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp slt v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, lo
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, lt
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %icmp_ult_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp ult v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, lo
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, lo
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_sle_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp sle v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, ls
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, le
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_ule_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp ule v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, ls
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, ls
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_sgt_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp sgt v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, hi
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, gt
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_ugt_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp ugt v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, hi
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, hi
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %icmp_sge_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp sge v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, hs
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, ge
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_uge_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp uge v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: subs xzr, x0, x2
|
||||
; nextln: cset x0, hs
|
||||
; nextln: subs xzr, x1, x3
|
||||
; nextln: cset x1, hs
|
||||
; nextln: csel x0, x0, x1, eq
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_of_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp of v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: adds xzr, x0, x2
|
||||
; nextln: adcs xzr, x1, x3
|
||||
; nextln: cset x0, vs
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
function %icmp_nof_i128(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = icmp nof v0, v1
|
||||
return v2
|
||||
}
|
||||
|
||||
; check: stp fp, lr, [sp, #-16]!
|
||||
; nextln: mov fp, sp
|
||||
; nextln: adds xzr, x0, x2
|
||||
; nextln: adcs xzr, x1, x3
|
||||
; nextln: cset x0, vc
|
||||
; nextln: ldp fp, lr, [sp], #16
|
||||
; nextln: ret
|
||||
|
||||
|
||||
function %f(i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
test run
|
||||
target aarch64
|
||||
; target x86_64 machinst TODO: X86_64 does not implement i128 icmp overflow
|
||||
|
||||
; TODO: Cleanup these tests when we have native support for i128 immediates in CLIF's parser
|
||||
function %icmp_of_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 of v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_of_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_of_i128(0, 0, 1, 0) == false
|
||||
; run: %icmp_of_i128(0, 0, -1, -1) == false
|
||||
; run: %icmp_of_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_of_i128(0x00000000_00000000, 0x80000000_00000000, 0, 0) == false
|
||||
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0, 0) == false
|
||||
; run: %icmp_of_i128(1, 0, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 1, 0) == true
|
||||
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x80000000_00000000) == false
|
||||
; run: %icmp_of_i128(0x00000000_00000000, 0x80000000_00000000, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x30000000_00000000) == false
|
||||
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x30000000_00000000) == true
|
||||
|
||||
function %icmp_nof_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 nof v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_nof_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_nof_i128(0, 0, 1, 0) == true
|
||||
; run: %icmp_nof_i128(0, 0, -1, -1) == true
|
||||
; run: %icmp_nof_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_nof_i128(0x00000000_00000000, 0x80000000_00000000, 0, 0) == true
|
||||
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0, 0) == true
|
||||
; run: %icmp_nof_i128(1, 0, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 1, 0) == false
|
||||
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x80000000_00000000) == true
|
||||
; run: %icmp_nof_i128(0x00000000_00000000, 0x80000000_00000000, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x30000000_00000000) == true
|
||||
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x30000000_00000000) == false
|
||||
@@ -1,20 +1,191 @@
|
||||
test run
|
||||
target aarch64
|
||||
target x86_64 machinst
|
||||
|
||||
function %test_icmp_eq_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x0
|
||||
v12 = iconst.i64 0x0
|
||||
v1 = iconcat v11, v12
|
||||
v21 = iconst.i64 0x0
|
||||
v22 = iconst.i64 0x0
|
||||
v2 = iconcat v21, v22
|
||||
v10 = icmp.i128 eq v1, v2
|
||||
return v10
|
||||
; TODO: Cleanup these tests when we have native support for i128 immediates in CLIF's parser
|
||||
function %icmp_eq_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 eq v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_eq_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_eq_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_eq_i128(-1, -1, 0, 0) == false
|
||||
; run: %icmp_eq_i128(-1, -1, 0, -1) == false
|
||||
; run: %icmp_eq_i128(-1, 0, -1, -1) == false
|
||||
; run: %icmp_eq_i128(0, -1, -1, -1) == false
|
||||
; run: %icmp_eq_i128(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE, 0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == true
|
||||
; run: %icmp_eq_i128(0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001) == false
|
||||
; run: %icmp_eq_i128(0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001, 0x00000000_00000001) == false
|
||||
|
||||
; run
|
||||
function %icmp_ne_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 ne v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_ne_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_ne_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_ne_i128(-1, -1, 0, 0) == true
|
||||
; run: %icmp_ne_i128(-1, -1, 0, -1) == true
|
||||
; run: %icmp_ne_i128(-1, 0, -1, -1) == true
|
||||
; run: %icmp_ne_i128(0, -1, -1, -1) == true
|
||||
; run: %icmp_ne_i128(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE, 0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == false
|
||||
; run: %icmp_ne_i128(0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001) == true
|
||||
; run: %icmp_ne_i128(0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001, 0x00000000_00000001) == true
|
||||
|
||||
|
||||
function %icmp_slt_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 slt v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_slt_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_slt_i128(1, 0, 1, 0) == false
|
||||
; run: %icmp_slt_i128(0, 0, 1, 0) == true
|
||||
; run: %icmp_slt_i128(-1, -1, 0, 0) == true
|
||||
; run: %icmp_slt_i128(0, 0, -1, -1) == false
|
||||
; run: %icmp_slt_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_slt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_slt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||
; run: %icmp_slt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||
|
||||
function %icmp_ult_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 ult v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_ult_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_ult_i128(1, 0, 1, 0) == false
|
||||
; run: %icmp_ult_i128(0, 0, 1, 0) == true
|
||||
; run: %icmp_ult_i128(-1, -1, 0, 0) == false
|
||||
; run: %icmp_ult_i128(0, 0, -1, -1) == true
|
||||
; run: %icmp_ult_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_ult_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_ult_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||
; run: %icmp_ult_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||
|
||||
function %icmp_sle_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 sle v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_sle_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_sle_i128(1, 0, 1, 0) == true
|
||||
; run: %icmp_sle_i128(0, 0, 1, 0) == true
|
||||
; run: %icmp_sle_i128(-1, -1, 0, 0) == true
|
||||
; run: %icmp_sle_i128(0, 0, -1, -1) == false
|
||||
; run: %icmp_sle_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_sle_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_sle_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||
; run: %icmp_sle_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||
|
||||
function %icmp_ule_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 ule v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_ule_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_ule_i128(1, 0, 1, 0) == true
|
||||
; run: %icmp_ule_i128(0, 0, 1, 0) == true
|
||||
; run: %icmp_ule_i128(-1, -1, 0, 0) == false
|
||||
; run: %icmp_ule_i128(0, 0, -1, -1) == true
|
||||
; run: %icmp_ule_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_ule_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||
; run: %icmp_ule_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||
; run: %icmp_ule_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||
|
||||
function %icmp_sgt_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 sgt v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_sgt_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_sgt_i128(1, 0, 1, 0) == false
|
||||
; run: %icmp_sgt_i128(0, 0, 1, 0) == false
|
||||
; run: %icmp_sgt_i128(-1, -1, 0, 0) == false
|
||||
; run: %icmp_sgt_i128(0, 0, -1, -1) == true
|
||||
; run: %icmp_sgt_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_sgt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_sgt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||
; run: %icmp_sgt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||
|
||||
function %icmp_ugt_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 ugt v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_ugt_i128(0, 0, 0, 0) == false
|
||||
; run: %icmp_ugt_i128(1, 0, 1, 0) == false
|
||||
; run: %icmp_ugt_i128(0, 0, 1, 0) == false
|
||||
; run: %icmp_ugt_i128(-1, -1, 0, 0) == true
|
||||
; run: %icmp_ugt_i128(0, 0, -1, -1) == false
|
||||
; run: %icmp_ugt_i128(-1, -1, -1, -1) == false
|
||||
; run: %icmp_ugt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_ugt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||
; run: %icmp_ugt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||
|
||||
function %icmp_sge_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 sge v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_sge_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_sge_i128(1, 0, 1, 0) == true
|
||||
; run: %icmp_sge_i128(0, 0, 1, 0) == false
|
||||
; run: %icmp_sge_i128(-1, -1, 0, 0) == false
|
||||
; run: %icmp_sge_i128(0, 0, -1, -1) == true
|
||||
; run: %icmp_sge_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_sge_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_sge_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||
; run: %icmp_sge_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||
|
||||
function %icmp_uge_i128(i64, i64, i64, i64) -> b1 {
|
||||
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||
v4 = iconcat v0, v1
|
||||
v5 = iconcat v2, v3
|
||||
|
||||
v6 = icmp.i128 uge v4, v5
|
||||
return v6
|
||||
}
|
||||
; run: %icmp_uge_i128(0, 0, 0, 0) == true
|
||||
; run: %icmp_uge_i128(1, 0, 1, 0) == true
|
||||
; run: %icmp_uge_i128(0, 0, 1, 0) == false
|
||||
; run: %icmp_uge_i128(-1, -1, 0, 0) == true
|
||||
; run: %icmp_uge_i128(0, 0, -1, -1) == false
|
||||
; run: %icmp_uge_i128(-1, -1, -1, -1) == true
|
||||
; run: %icmp_uge_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||
; run: %icmp_uge_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||
; run: %icmp_uge_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||
|
||||
|
||||
; Icmp Imm Tests
|
||||
function %test_icmp_imm_eq_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x0
|
||||
@@ -26,20 +197,6 @@ block0:
|
||||
|
||||
; run
|
||||
|
||||
function %test_icmp_ne_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x0
|
||||
v12 = iconst.i64 0x0
|
||||
v1 = iconcat v11, v12
|
||||
v21 = iconst.i64 0x0
|
||||
v22 = iconst.i64 0x1
|
||||
v2 = iconcat v21, v22
|
||||
v10 = icmp.i128 ne v1, v2
|
||||
return v10
|
||||
}
|
||||
|
||||
; run
|
||||
|
||||
function %test_icmp_imm_ne_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x0
|
||||
@@ -50,45 +207,3 @@ block0:
|
||||
}
|
||||
|
||||
; run
|
||||
|
||||
function %test_icmp_nz_eq_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x1
|
||||
v12 = iconst.i64 0x1
|
||||
v1 = iconcat v11, v12
|
||||
v21 = iconst.i64 0x1
|
||||
v22 = iconst.i64 0x1
|
||||
v2 = iconcat v21, v22
|
||||
v10 = icmp.i128 eq v1, v2
|
||||
return v10
|
||||
}
|
||||
|
||||
; run
|
||||
|
||||
function %test_icmp_nz_gt_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x1
|
||||
v12 = iconst.i64 0x1
|
||||
v1 = iconcat v11, v12
|
||||
v21 = iconst.i64 0x1
|
||||
v22 = iconst.i64 0x2
|
||||
v2 = iconcat v21, v22
|
||||
v10 = icmp.i128 ugt v2, v1
|
||||
return v10
|
||||
}
|
||||
|
||||
; run
|
||||
|
||||
function %test_icmp_nz_ge_i128() -> b1 {
|
||||
block0:
|
||||
v11 = iconst.i64 0x1
|
||||
v12 = iconst.i64 0x1
|
||||
v1 = iconcat v11, v12
|
||||
v21 = iconst.i64 0x1
|
||||
v22 = iconst.i64 0x1
|
||||
v2 = iconcat v21, v22
|
||||
v10 = icmp.i128 uge v1, v2
|
||||
return v10
|
||||
}
|
||||
|
||||
; run
|
||||
|
||||
Reference in New Issue
Block a user