mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8357551: RISC-V: support CMoveF/D vectorization
Reviewed-by: fyang, luhenry
This commit is contained in:
parent
b83bf0717e
commit
6700baa505
@ -2067,6 +2067,83 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
|
||||
FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask;
|
||||
int op_select = cmpFlag & (~unsigned_branch_mask);
|
||||
|
||||
switch (op_select) {
|
||||
case BoolTest::eq:
|
||||
cmov_fp_eq(op1, op2, dst, src, is_single);
|
||||
break;
|
||||
case BoolTest::ne:
|
||||
cmov_fp_ne(op1, op2, dst, src, is_single);
|
||||
break;
|
||||
case BoolTest::le:
|
||||
if (is_unsigned) {
|
||||
cmov_fp_leu(op1, op2, dst, src, is_single);
|
||||
} else {
|
||||
cmov_fp_le(op1, op2, dst, src, is_single);
|
||||
}
|
||||
break;
|
||||
case BoolTest::ge:
|
||||
if (is_unsigned) {
|
||||
cmov_fp_geu(op1, op2, dst, src, is_single);
|
||||
} else {
|
||||
cmov_fp_ge(op1, op2, dst, src, is_single);
|
||||
}
|
||||
break;
|
||||
case BoolTest::lt:
|
||||
if (is_unsigned) {
|
||||
cmov_fp_ltu(op1, op2, dst, src, is_single);
|
||||
} else {
|
||||
cmov_fp_lt(op1, op2, dst, src, is_single);
|
||||
}
|
||||
break;
|
||||
case BoolTest::gt:
|
||||
if (is_unsigned) {
|
||||
cmov_fp_gtu(op1, op2, dst, src, is_single);
|
||||
} else {
|
||||
cmov_fp_gt(op1, op2, dst, src, is_single);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false, "unsupported compare condition");
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::enc_cmove_fp_cmp_fp(int cmpFlag,
|
||||
FloatRegister op1, FloatRegister op2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
int op_select = cmpFlag & (~unsigned_branch_mask);
|
||||
|
||||
switch (op_select) {
|
||||
case BoolTest::eq:
|
||||
cmov_fp_cmp_fp_eq(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
case BoolTest::ne:
|
||||
cmov_fp_cmp_fp_ne(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
case BoolTest::le:
|
||||
cmov_fp_cmp_fp_le(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
case BoolTest::ge:
|
||||
cmov_fp_cmp_fp_ge(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
case BoolTest::lt:
|
||||
cmov_fp_cmp_fp_lt(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
case BoolTest::gt:
|
||||
cmov_fp_cmp_fp_gt(op1, op2, dst, src, cmp_single, cmov_single);
|
||||
break;
|
||||
default:
|
||||
assert(false, "unsupported compare condition");
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
// Set dst to NaN if any NaN input.
|
||||
void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2,
|
||||
FLOAT_TYPE ft, bool is_min) {
|
||||
|
||||
@ -132,6 +132,13 @@
|
||||
FloatRegister op1, FloatRegister op2,
|
||||
Register dst, Register src, bool is_single);
|
||||
|
||||
void enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
|
||||
FloatRegister dst, FloatRegister src, bool is_single);
|
||||
|
||||
void enc_cmove_fp_cmp_fp(int cmpFlag, FloatRegister op1, FloatRegister op2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single);
|
||||
|
||||
void spill(Register r, bool is64, int offset) {
|
||||
is64 ? sd(r, Address(sp, offset))
|
||||
: sw(r, Address(sp, offset));
|
||||
|
||||
@ -1233,7 +1233,119 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// ----------- cmove, compare float -----------
|
||||
// ----------- cmove float/double -----------
|
||||
|
||||
void MacroAssembler::cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bne(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
beq(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bgt(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bgtu(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
blt(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bltu(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bge(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bgeu(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
ble(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||
Label no_set;
|
||||
bleu(cmp1, cmp2, no_set);
|
||||
if (is_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// ----------- cmove, compare float/double -----------
|
||||
//
|
||||
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
|
||||
// so, just list behaviour of unordered ones as follow.
|
||||
@ -1391,6 +1503,148 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// ----------- cmove float/double, compare float/double -----------
|
||||
|
||||
// Move src to dst only if cmp1 == cmp2,
|
||||
// otherwise leave dst unchanged, including the case where one of them is NaN.
|
||||
// Clarification:
|
||||
// java code : cmp1 != cmp2 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 eq cmp2), dst, src
|
||||
void MacroAssembler::cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 != cmp2, including the case of NaN
|
||||
// not jump (i.e. move src to dst) if cmp1 == cmp2
|
||||
float_bne(cmp1, cmp2, no_set);
|
||||
} else {
|
||||
double_bne(cmp1, cmp2, no_set);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// Keep dst unchanged only if cmp1 == cmp2,
|
||||
// otherwise move src to dst, including the case where one of them is NaN.
|
||||
// Clarification:
|
||||
// java code : cmp1 == cmp2 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 ne cmp2), dst, src
|
||||
void MacroAssembler::cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 == cmp2
|
||||
// not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
|
||||
float_beq(cmp1, cmp2, no_set);
|
||||
} else {
|
||||
double_beq(cmp1, cmp2, no_set);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
|
||||
// Clarification
|
||||
// scenario 1:
|
||||
// java code : cmp2 < cmp1 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
|
||||
// scenario 2:
|
||||
// java code : cmp1 > cmp2 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
|
||||
void MacroAssembler::cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 > cmp2
|
||||
// not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
|
||||
float_bgt(cmp1, cmp2, no_set);
|
||||
} else {
|
||||
double_bgt(cmp1, cmp2, no_set);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 < cmp2 or either is NaN
|
||||
// not jump (i.e. move src to dst) if cmp1 >= cmp2
|
||||
float_blt(cmp1, cmp2, no_set, false, true);
|
||||
} else {
|
||||
double_blt(cmp1, cmp2, no_set, false, true);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
|
||||
// Clarification
|
||||
// scenario 1:
|
||||
// java code : cmp2 <= cmp1 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
|
||||
// scenario 2:
|
||||
// java code : cmp1 >= cmp2 ? dst : src
|
||||
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
|
||||
void MacroAssembler::cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 >= cmp2
|
||||
// not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
|
||||
float_bge(cmp1, cmp2, no_set);
|
||||
} else {
|
||||
double_bge(cmp1, cmp2, no_set);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2,
|
||||
FloatRegister dst, FloatRegister src,
|
||||
bool cmp_single, bool cmov_single) {
|
||||
Label no_set;
|
||||
if (cmp_single) {
|
||||
// jump if cmp1 <= cmp2 or either is NaN
|
||||
// not jump (i.e. move src to dst) if cmp1 > cmp2
|
||||
float_ble(cmp1, cmp2, no_set, false, true);
|
||||
} else {
|
||||
double_ble(cmp1, cmp2, no_set, false, true);
|
||||
}
|
||||
if (cmov_single) {
|
||||
fmv_s(dst, src);
|
||||
} else {
|
||||
fmv_d(dst, src);
|
||||
}
|
||||
bind(no_set);
|
||||
}
|
||||
|
||||
// Float compare branch instructions
|
||||
|
||||
#define INSN(NAME, FLOATCMP, BRANCH) \
|
||||
|
||||
@ -665,6 +665,24 @@ class MacroAssembler: public Assembler {
|
||||
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
||||
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
||||
|
||||
void cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
void cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||
|
||||
void cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
void cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
void cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
void cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
void cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
void cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||
|
||||
public:
|
||||
// We try to follow risc-v asm menomics.
|
||||
// But as we don't layout a reachable GOT,
|
||||
|
||||
@ -1924,8 +1924,6 @@ bool Matcher::match_rule_supported(int opcode) {
|
||||
case Op_SubHF:
|
||||
return UseZfh;
|
||||
|
||||
case Op_CMoveF:
|
||||
case Op_CMoveD:
|
||||
case Op_CMoveP:
|
||||
case Op_CMoveN:
|
||||
return false;
|
||||
@ -10466,6 +10464,286 @@ instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop)
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
// --------- CMoveF ---------
|
||||
|
||||
instruct cmovF_cmpI(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpI op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpI\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpU(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOpU cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpU op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpU\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpL op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpL\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpUL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOpU cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpUL op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpUL\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpF(fRegF dst, fRegF src, fRegF op1, fRegF op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpF\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
|
||||
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
true /* cmp_single */, true /* cmov_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpD(fRegF dst, fRegF src, fRegD op1, fRegD op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpD\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
|
||||
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
false /* cmp_single */, true /* cmov_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpN(fRegF dst, fRegF src, iRegN op1, iRegN op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpN op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpN\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovF_cmpP(fRegF dst, fRegF src, iRegP op1, iRegP op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveF (Binary cop (CmpP op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpP\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
// --------- CMoveD ---------
|
||||
|
||||
instruct cmovD_cmpI(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpI op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpI\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpU(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOpU cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpU op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpU\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpL op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpL\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpUL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOpU cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpUL op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpUL\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpF(fRegD dst, fRegD src, fRegF op1, fRegF op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpF\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
|
||||
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
true /* cmp_single */, false /* cmov_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpD(fRegD dst, fRegD src, fRegD op1, fRegD op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpD\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
|
||||
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
false /* cmp_single */, false /* cmov_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpN(fRegD dst, fRegD src, iRegN op1, iRegN op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpN op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpN\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
instruct cmovD_cmpP(fRegD dst, fRegD src, iRegP op1, iRegP op2, cmpOp cop) %{
|
||||
match(Set dst (CMoveD (Binary cop (CmpP op1 op2)) (Binary dst src)));
|
||||
ins_cost(ALU_COST + BRANCH_COST);
|
||||
|
||||
format %{
|
||||
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpP\n\t"
|
||||
%}
|
||||
|
||||
ins_encode %{
|
||||
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_compare);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// Procedure Call/Return Instructions
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (c) 2025, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package compiler.c2.irTests;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test conditional move + compare object.
|
||||
* @requires vm.simpleArch == "riscv64"
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.c2.irTests.TestScalarConditionalMoveCmpObj
|
||||
*/
|
||||
|
||||
public class TestScalarConditionalMoveCmpObj {
|
||||
final private static int SIZE = 1024;
|
||||
private static final Random RANDOM = Utils.getRandomInstance();
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+UseCompressedOops");
|
||||
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-UseCompressedOops");
|
||||
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+UseCompressedOops");
|
||||
TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:-UseVectorCmov",
|
||||
"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-UseCompressedOops");
|
||||
}
|
||||
|
||||
// Object comparison
|
||||
// O for I
|
||||
private int cmoveOEQforI(Object a, Object b, int c, int d) {
|
||||
return (a == b) ? c : d;
|
||||
}
|
||||
|
||||
private int cmoveONEforI(Object a, Object b, int c, int d) {
|
||||
return (a != b) ? c : d;
|
||||
}
|
||||
|
||||
// O for L
|
||||
private long cmoveOEQforL(Object a, Object b, long c, long d) {
|
||||
return (a == b) ? c : d;
|
||||
}
|
||||
|
||||
private long cmoveONEforL(Object a, Object b, long c, long d) {
|
||||
return (a != b) ? c : d;
|
||||
}
|
||||
|
||||
// O for F
|
||||
private float cmoveOEQforF(Object a, Object b, float c, float d) {
|
||||
return (a == b) ? c : d;
|
||||
}
|
||||
|
||||
private float cmoveONEforF(Object a, Object b, float c, float d) {
|
||||
return (a != b) ? c : d;
|
||||
}
|
||||
|
||||
// O for D
|
||||
private double cmoveOEQforD(Object a, Object b, double c, double d) {
|
||||
return (a == b) ? c : d;
|
||||
}
|
||||
|
||||
private double cmoveONEforD(Object a, Object b, double c, double d) {
|
||||
return (a != b) ? c : d;
|
||||
}
|
||||
|
||||
// Tests shows CMoveI is generated, so let @IR verify CMOVE_I.
|
||||
//
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveOEQforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
int cc = c[i];
|
||||
int dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] == b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_I, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveONEforI(Object[] a, Object[] b, int[] c, int[] d, int[] r, int[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
int cc = c[i];
|
||||
int dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] != b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
// So far, CMoveL is not guaranteed to be generated, so @IR not verify CMOVE_L.
|
||||
// TODO: enable CMOVE_L verification when it's guaranteed to generate CMOVE_L.
|
||||
//
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
|
||||
// applyIf = {"UseCompressedOops", "false"})
|
||||
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
|
||||
// applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveOEQforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
long cc = c[i];
|
||||
long dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] == b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_P, ">0"},
|
||||
// applyIf = {"UseCompressedOops", "false"})
|
||||
// @IR(counts = {IRNode.CMOVE_L, ">0", IRNode.CMP_N, ">0"},
|
||||
// applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveONEforL(Object[] a, Object[] b, long[] c, long[] d, long[] r, long[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
long cc = c[i];
|
||||
long dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] != b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveOEQforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
float cc = c[i];
|
||||
float dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] == b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_F, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveONEforF(Object[] a, Object[] b, float[] c, float[] d, float[] r, float[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
float cc = c[i];
|
||||
float dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] != b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveOEQforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
double cc = c[i];
|
||||
double dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] == b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(failOn = {IRNode.STORE_VECTOR})
|
||||
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_P, ">0"},
|
||||
applyIf = {"UseCompressedOops", "false"})
|
||||
@IR(counts = {IRNode.CMOVE_D, ">0", IRNode.CMP_N, ">0"},
|
||||
applyIf = {"UseCompressedOops", "true"})
|
||||
private static void testCMoveONEforD(Object[] a, Object[] b, double[] c, double[] d, double[] r, double[] r2) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
double cc = c[i];
|
||||
double dd = d[i];
|
||||
r2[i] = cc + dd;
|
||||
r[i] = (a[i] != b[i]) ? cc : dd;
|
||||
}
|
||||
}
|
||||
|
||||
@Warmup(0)
|
||||
@Run(test = {// Object
|
||||
"testCMoveOEQforI",
|
||||
"testCMoveONEforI",
|
||||
"testCMoveOEQforL",
|
||||
"testCMoveONEforL",
|
||||
"testCMoveOEQforF",
|
||||
"testCMoveONEforF",
|
||||
"testCMoveOEQforD",
|
||||
"testCMoveONEforD",
|
||||
})
|
||||
private void testCMove_runner_two() {
|
||||
Object[] aO = new Object[SIZE];
|
||||
Object[] bO = new Object[SIZE];
|
||||
int[] cI = new int[SIZE];
|
||||
int[] dI = new int[SIZE];
|
||||
int[] rI = new int[SIZE];
|
||||
long[] cL = new long[SIZE];
|
||||
long[] dL = new long[SIZE];
|
||||
long[] rL = new long[SIZE];
|
||||
float[] cF = new float[SIZE];
|
||||
float[] dF = new float[SIZE];
|
||||
float[] rF = new float[SIZE];
|
||||
double[] cD = new double[SIZE];
|
||||
double[] dD = new double[SIZE];
|
||||
double[] rD = new double[SIZE];
|
||||
|
||||
init(aO);
|
||||
shuffle(aO, bO);
|
||||
init(cL);
|
||||
init(dL);
|
||||
init(cF);
|
||||
init(dF);
|
||||
init(cD);
|
||||
init(dD);
|
||||
|
||||
testCMoveOEQforI(aO, bO, cI, dI, rI, rI);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rI[i], cmoveOEQforI(aO[i], bO[i], cI[i], dI[i]));
|
||||
}
|
||||
|
||||
testCMoveONEforI(aO, bO, cI, dI, rI, rI);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rI[i], cmoveONEforI(aO[i], bO[i], cI[i], dI[i]));
|
||||
}
|
||||
|
||||
testCMoveOEQforL(aO, bO, cL, dL, rL, rL);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rL[i], cmoveOEQforL(aO[i], bO[i], cL[i], dL[i]));
|
||||
}
|
||||
|
||||
testCMoveONEforL(aO, bO, cL, dL, rL, rL);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rL[i], cmoveONEforL(aO[i], bO[i], cL[i], dL[i]));
|
||||
}
|
||||
|
||||
testCMoveOEQforF(aO, bO, cF, dF, rF, rF);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rF[i], cmoveOEQforF(aO[i], bO[i], cF[i], dF[i]));
|
||||
}
|
||||
|
||||
testCMoveONEforF(aO, bO, cF, dF, rF, rF);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rF[i], cmoveONEforF(aO[i], bO[i], cF[i], dF[i]));
|
||||
}
|
||||
|
||||
testCMoveOEQforD(aO, bO, cD, dD, rD, rD);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rD[i], cmoveOEQforD(aO[i], bO[i], cD[i], dD[i]));
|
||||
}
|
||||
|
||||
testCMoveONEforD(aO, bO, cD, dD, rD, rD);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Asserts.assertEquals(rD[i], cmoveONEforD(aO[i], bO[i], cD[i], dD[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void init(Object[] a) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
a[i] = new Object();
|
||||
}
|
||||
}
|
||||
|
||||
private static void shuffle(Object[] a, Object[] b) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
b[i] = a[i];
|
||||
}
|
||||
Random rand = new Random();
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
if (rand.nextInt(5) == 0) {
|
||||
Object t = b[i];
|
||||
b[i] = b[SIZE-1-i];
|
||||
b[SIZE-1-i] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void init(int[] a) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
a[i] = RANDOM.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
private static void init(long[] a) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
a[i] = RANDOM.nextLong();
|
||||
}
|
||||
}
|
||||
|
||||
private static void init(float[] a) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
a[i] = switch(RANDOM.nextInt() % 20) {
|
||||
case 0 -> Float.NaN;
|
||||
case 1 -> 0;
|
||||
case 2 -> 1;
|
||||
case 3 -> Float.POSITIVE_INFINITY;
|
||||
case 4 -> Float.NEGATIVE_INFINITY;
|
||||
case 5 -> Float.MAX_VALUE;
|
||||
case 6 -> Float.MIN_VALUE;
|
||||
case 7, 8, 9 -> RANDOM.nextFloat();
|
||||
default -> Float.intBitsToFloat(RANDOM.nextInt());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static void init(double[] a) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
a[i] = switch(RANDOM.nextInt() % 20) {
|
||||
case 0 -> Double.NaN;
|
||||
case 1 -> 0;
|
||||
case 2 -> 1;
|
||||
case 3 -> Double.POSITIVE_INFINITY;
|
||||
case 4 -> Double.NEGATIVE_INFINITY;
|
||||
case 5 -> Double.MAX_VALUE;
|
||||
case 6 -> Double.MIN_VALUE;
|
||||
case 7, 8, 9 -> RANDOM.nextDouble();
|
||||
default -> Double.longBitsToDouble(RANDOM.nextLong());
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -545,11 +545,36 @@ public class IRNode {
|
||||
trapNodes(CLASS_CHECK_TRAP, "class_check");
|
||||
}
|
||||
|
||||
public static final String CMOVE_F = PREFIX + "CMOVE_F" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMOVE_F, "CMoveF");
|
||||
}
|
||||
|
||||
public static final String CMOVE_D = PREFIX + "CMOVE_D" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMOVE_D, "CMoveD");
|
||||
}
|
||||
|
||||
public static final String CMOVE_I = PREFIX + "CMOVE_I" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMOVE_I, "CMoveI");
|
||||
}
|
||||
|
||||
public static final String CMOVE_L = PREFIX + "CMOVE_L" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMOVE_L, "CMoveL");
|
||||
}
|
||||
|
||||
public static final String CMP_F = PREFIX + "CMP_F" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMP_F, "CmpF");
|
||||
}
|
||||
|
||||
public static final String CMP_D = PREFIX + "CMP_D" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMP_D, "CmpD");
|
||||
}
|
||||
|
||||
public static final String CMP_I = PREFIX + "CMP_I" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMP_I, "CmpI");
|
||||
@ -585,6 +610,11 @@ public class IRNode {
|
||||
beforeMatchingNameRegex(CMP_P, "CmpP");
|
||||
}
|
||||
|
||||
public static final String CMP_N = PREFIX + "CMP_N" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMP_N, "CmpN");
|
||||
}
|
||||
|
||||
public static final String CMP_LT_MASK = PREFIX + "CMP_LT_MASK" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(CMP_LT_MASK, "CmpLTMask");
|
||||
|
||||
@ -44,12 +44,8 @@ public class ClassComparison {
|
||||
Class[] c2;
|
||||
int[] res;
|
||||
long[] resLong;
|
||||
Object[] resObject;
|
||||
Object ro1;
|
||||
Object ro2;
|
||||
Object[] resClass;
|
||||
Class rc1;
|
||||
Class rc2;
|
||||
float[] resFloat;
|
||||
double[] resDouble;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
@ -58,12 +54,8 @@ public class ClassComparison {
|
||||
c2 = new Class[INVOCATIONS];
|
||||
res = new int[INVOCATIONS];
|
||||
resLong = new long[INVOCATIONS];
|
||||
resObject = new Object[INVOCATIONS];
|
||||
ro1 = new Object();
|
||||
ro2 = new Object();
|
||||
resClass = new Class[INVOCATIONS];
|
||||
rc1 = Float.class;
|
||||
rc2 = Double.class;
|
||||
resFloat = new float[INVOCATIONS];
|
||||
resDouble = new double[INVOCATIONS];
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
c1[i] = random.nextBoolean() ? Float.class : Double.class;
|
||||
}
|
||||
@ -86,6 +78,7 @@ public class ClassComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalClassResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (c1[i] == c2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -98,4 +91,32 @@ public class ClassComparison {
|
||||
resLong[i] = (c1[i] != c2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalClassResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (c1[i] == c2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualClassResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (c1[i] != c2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalClassResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (c1[i] == c2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualClassResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (c1[i] != c2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,34 +37,18 @@ import java.util.random.RandomGenerator;
|
||||
public class FPComparison {
|
||||
static final int INVOCATIONS = 1024;
|
||||
|
||||
float[] f1;
|
||||
double[] d1;
|
||||
float[] f2;
|
||||
double[] d2;
|
||||
int[] res;
|
||||
long[] resLong;
|
||||
Object[] resObject;
|
||||
Object ro1;
|
||||
Object ro2;
|
||||
Class[] resClass;
|
||||
Class rc1;
|
||||
Class rc2;
|
||||
static final float[] f1 = new float[INVOCATIONS];
|
||||
static final double[] d1 = new double[INVOCATIONS];
|
||||
static final float[] f2 = new float[INVOCATIONS];
|
||||
static final double[] d2 = new double[INVOCATIONS];
|
||||
static final int[] res = new int[INVOCATIONS];;
|
||||
static final long[] resLong = new long[INVOCATIONS];
|
||||
static final float[] resFloat = new float[INVOCATIONS];
|
||||
static final double[] resDouble = new double[INVOCATIONS];
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
var random = RandomGenerator.getDefault();
|
||||
f1 = new float[INVOCATIONS];
|
||||
d1 = new double[INVOCATIONS];
|
||||
f2 = new float[INVOCATIONS];
|
||||
d2 = new double[INVOCATIONS];
|
||||
res = new int[INVOCATIONS];
|
||||
resLong = new long[INVOCATIONS];
|
||||
resObject = new Object[INVOCATIONS];
|
||||
ro1 = new Object();
|
||||
ro2 = new Object();
|
||||
resClass = new Class[INVOCATIONS];
|
||||
rc1 = Float.class;
|
||||
rc2 = Double.class;
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
int type = random.nextInt(5);
|
||||
if (type == 1) {
|
||||
@ -274,4 +258,148 @@ public class FPComparison {
|
||||
resLong[i] = (d1[i] >= d2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: float ---------
|
||||
|
||||
@Benchmark
|
||||
public void equalFloatResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (f1[i] == f2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalDoubleResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (d1[i] == d2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessFloatResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (f1[i] < f2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessDoubleResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (d1[i] < d2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualFloatResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (f1[i] <= f2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualDoubleResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (d1[i] <= d2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterFloatResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (f1[i] > f2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterDoubleResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (d1[i] > d2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualFloatResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (f1[i] >= f2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualDoubleResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (d1[i] >= d2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: double ---------
|
||||
|
||||
@Benchmark
|
||||
public void equalFloatResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (f1[i] == f2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalDoubleResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (d1[i] == d2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessFloatResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (f1[i] < f2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessDoubleResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (d1[i] < d2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualFloatResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (f1[i] <= f2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualDoubleResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (d1[i] <= d2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterFloatResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (f1[i] > f2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterDoubleResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (d1[i] > d2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualFloatResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (f1[i] >= f2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualDoubleResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (d1[i] >= d2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,12 +42,8 @@ public class IntegerComparison {
|
||||
int[] i2;
|
||||
int[] res;
|
||||
long[] resLong;
|
||||
Object[] resObject;
|
||||
Object ro1;
|
||||
Object ro2;
|
||||
Object[] resClass;
|
||||
Class rc1;
|
||||
Class rc2;
|
||||
float[] resFloat;
|
||||
double[] resDouble;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
@ -56,18 +52,17 @@ public class IntegerComparison {
|
||||
i2 = new int[INVOCATIONS];
|
||||
res = new int[INVOCATIONS];
|
||||
resLong = new long[INVOCATIONS];
|
||||
resObject = new Object[INVOCATIONS];
|
||||
ro1 = new Object();
|
||||
ro2 = new Object();
|
||||
resClass = new Class[INVOCATIONS];
|
||||
rc1 = Float.class;
|
||||
rc2 = Double.class;
|
||||
resFloat = new float[INVOCATIONS];
|
||||
resDouble = new double[INVOCATIONS];
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
i1[i] = random.nextInt(INVOCATIONS);
|
||||
i2[i] = random.nextInt(INVOCATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: int ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalInteger() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
@ -110,8 +105,55 @@ public class IntegerComparison {
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: long ---------
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------- result: long ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (i1[i] == i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -125,6 +167,7 @@ public class IntegerComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (i1[i] < i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -138,6 +181,7 @@ public class IntegerComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (i1[i] > i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -150,4 +194,226 @@ public class IntegerComparison {
|
||||
resLong[i] = (i1[i] >= i2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: float ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] == i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] != i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] < i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] <= i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] > i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (i1[i] >= i2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: double ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] == i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] != i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] < i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] <= i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] > i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (i1[i] >= i2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) == 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) != 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) < 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) <= 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) > 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualIntegerUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Integer.compareUnsigned(i1[i], i2[i]) >= 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,12 +41,8 @@ public class LongComparison {
|
||||
long[] l2;
|
||||
int[] res;
|
||||
long[] resLong;
|
||||
Object[] resObject;
|
||||
Object ro1;
|
||||
Object ro2;
|
||||
Object[] resClass;
|
||||
Class rc1;
|
||||
Class rc2;
|
||||
float[] resFloat;
|
||||
double[] resDouble;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
@ -55,18 +51,17 @@ public class LongComparison {
|
||||
l2 = new long[INVOCATIONS];
|
||||
res = new int[INVOCATIONS];
|
||||
resLong = new long[INVOCATIONS];
|
||||
resObject = new Object[INVOCATIONS];
|
||||
ro1 = new Object();
|
||||
ro2 = new Object();
|
||||
resClass = new Class[INVOCATIONS];
|
||||
rc1 = Float.class;
|
||||
rc2 = Double.class;
|
||||
resFloat = new float[INVOCATIONS];
|
||||
resDouble = new double[INVOCATIONS];
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
l1[i] = random.nextLong(INVOCATIONS);
|
||||
l2[i] = random.nextLong(INVOCATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: int ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
@ -109,8 +104,54 @@ public class LongComparison {
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: long ---------
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongUnsigned() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
res[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: long ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (l1[i] == l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -124,6 +165,7 @@ public class LongComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (l1[i] < l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -137,6 +179,7 @@ public class LongComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (l1[i] > l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -149,4 +192,226 @@ public class LongComparison {
|
||||
resLong[i] = (l1[i] >= l2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongUnsignedResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: float ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] == l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] != l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] < l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] <= l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] > l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (l1[i] >= l2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongUnsignedResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// --------- result: double ---------
|
||||
// Signed comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] == l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] != l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] < l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] <= l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] > l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (l1[i] >= l2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned comparison
|
||||
|
||||
@Benchmark
|
||||
public void equalLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) == 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) != 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) < 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void lessEqualLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) <= 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) > 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void greaterEqualLongUnsignedResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = Long.compareUnsigned(l1[i], l2[i]) >= 0 ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,12 +44,8 @@ public class PointerComparison {
|
||||
Object[] o2;
|
||||
int[] res;
|
||||
long[] resLong;
|
||||
Object[] resObject;
|
||||
Object ro1;
|
||||
Object ro2;
|
||||
Object[] resClass;
|
||||
Class rc1;
|
||||
Class rc2;
|
||||
float[] resFloat;
|
||||
double[] resDouble;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
@ -58,12 +54,8 @@ public class PointerComparison {
|
||||
o2 = new Object[INVOCATIONS];
|
||||
res = new int[INVOCATIONS];
|
||||
resLong = new long[INVOCATIONS];
|
||||
resObject = new Object[INVOCATIONS];
|
||||
ro1 = new Object();
|
||||
ro2 = new Object();
|
||||
resClass = new Class[INVOCATIONS];
|
||||
rc1 = Float.class;
|
||||
rc2 = Double.class;
|
||||
resFloat = new float[INVOCATIONS];
|
||||
resDouble = new double[INVOCATIONS];
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
o1[i] = new Object();
|
||||
}
|
||||
@ -86,6 +78,7 @@ public class PointerComparison {
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalObjectResLong() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resLong[i] = (o1[i] == o2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
@ -98,4 +91,32 @@ public class PointerComparison {
|
||||
resLong[i] = (o1[i] != o2[i]) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalObjecResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (o1[i] == o2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualObjecResFloat() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resFloat[i] = (o1[i] != o2[i]) ? 0.1f : 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void equalObjecResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (o1[i] == o2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void notEqualObjecResDouble() {
|
||||
for (int i = 0; i < INVOCATIONS; i++) {
|
||||
resDouble[i] = (o1[i] != o2[i]) ? 0.1 : 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user