mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8026844: Various Math functions needs intrinsification
Reviewed-by: kvn, twisti
This commit is contained in:
parent
073409c543
commit
615376fb9b
52 changed files with 2970 additions and 270 deletions
|
@ -2022,6 +2022,10 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
return G1_REGI_mask();
|
return G1_REGI_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||||
|
return G1_REGL_mask();
|
||||||
|
}
|
||||||
|
|
||||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
return INT_FLAGS_mask();
|
return INT_FLAGS_mask();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1405,6 +1405,15 @@ void Assembler::imull(Register dst, Register src, int value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::imull(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefix(src, dst);
|
||||||
|
emit_int8(0x0F);
|
||||||
|
emit_int8((unsigned char) 0xAF);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Assembler::incl(Address dst) {
|
void Assembler::incl(Address dst) {
|
||||||
// Don't use it directly. Use MacroAssembler::increment() instead.
|
// Don't use it directly. Use MacroAssembler::increment() instead.
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
|
@ -5024,6 +5033,14 @@ void Assembler::imulq(Register dst, Register src, int value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Assembler::imulq(Register dst, Address src) {
|
||||||
|
InstructionMark im(this);
|
||||||
|
prefixq(src, dst);
|
||||||
|
emit_int8(0x0F);
|
||||||
|
emit_int8((unsigned char) 0xAF);
|
||||||
|
emit_operand(dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
void Assembler::incl(Register dst) {
|
void Assembler::incl(Register dst) {
|
||||||
// Don't use it directly. Use MacroAssembler::incrementl() instead.
|
// Don't use it directly. Use MacroAssembler::incrementl() instead.
|
||||||
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
|
// Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
|
||||||
|
|
|
@ -1162,9 +1162,13 @@ private:
|
||||||
|
|
||||||
void imull(Register dst, Register src);
|
void imull(Register dst, Register src);
|
||||||
void imull(Register dst, Register src, int value);
|
void imull(Register dst, Register src, int value);
|
||||||
|
void imull(Register dst, Address src);
|
||||||
|
|
||||||
void imulq(Register dst, Register src);
|
void imulq(Register dst, Register src);
|
||||||
void imulq(Register dst, Register src, int value);
|
void imulq(Register dst, Register src, int value);
|
||||||
|
#ifdef _LP64
|
||||||
|
void imulq(Register dst, Address src);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// jcc is the generic conditional branch generator to run-
|
// jcc is the generic conditional branch generator to run-
|
||||||
|
|
|
@ -1538,6 +1538,11 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
return EAX_REG_mask();
|
return EAX_REG_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||||
|
ShouldNotReachHere();
|
||||||
|
return RegMask();
|
||||||
|
}
|
||||||
|
|
||||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
return INT_FLAGS_mask();
|
return INT_FLAGS_mask();
|
||||||
}
|
}
|
||||||
|
@ -7519,7 +7524,7 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
|
||||||
//----------Arithmetic Instructions--------------------------------------------
|
//----------Arithmetic Instructions--------------------------------------------
|
||||||
//----------Addition Instructions----------------------------------------------
|
//----------Addition Instructions----------------------------------------------
|
||||||
|
|
||||||
instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
instruct addExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(AddExactI dst src);
|
match(AddExactI dst src);
|
||||||
effect(DEF cr);
|
effect(DEF cr);
|
||||||
|
@ -7531,7 +7536,7 @@ instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||||
ins_pipe(ialu_reg_reg);
|
ins_pipe(ialu_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
instruct addExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(AddExactI dst src);
|
match(AddExactI dst src);
|
||||||
effect(DEF cr);
|
effect(DEF cr);
|
||||||
|
@ -7543,6 +7548,20 @@ instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||||
ins_pipe(ialu_reg_reg);
|
ins_pipe(ialu_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct addExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "ADD $dst,$src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe( ialu_reg_mem );
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Integer Addition Instructions
|
// Integer Addition Instructions
|
||||||
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||||
match(Set dst (AddI dst src));
|
match(Set dst (AddI dst src));
|
||||||
|
@ -7851,6 +7870,44 @@ instruct xchgP( memory mem, pRegP newval) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
//----------Subtraction Instructions-------------------------------------------
|
//----------Subtraction Instructions-------------------------------------------
|
||||||
|
|
||||||
|
instruct subExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "SUB $dst, $src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactI_eReg_imm(eAXRegI dst, immI src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "SUB $dst, $src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "SUB $dst,$src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe( ialu_reg_mem );
|
||||||
|
%}
|
||||||
|
|
||||||
// Integer Subtraction Instructions
|
// Integer Subtraction Instructions
|
||||||
instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||||
match(Set dst (SubI dst src));
|
match(Set dst (SubI dst src));
|
||||||
|
@ -7919,6 +7976,16 @@ instruct negI_eReg(rRegI dst, immI0 zero, eFlagsReg cr) %{
|
||||||
ins_pipe( ialu_reg );
|
ins_pipe( ialu_reg );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct negExactI_eReg(eAXRegI dst, eFlagsReg cr) %{
|
||||||
|
match(NegExactI dst);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "NEG $dst\t# negExact int"%}
|
||||||
|
ins_encode %{
|
||||||
|
__ negl($dst$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
//----------Multiplication/Division Instructions-------------------------------
|
//----------Multiplication/Division Instructions-------------------------------
|
||||||
// Integer Multiplication Instructions
|
// Integer Multiplication Instructions
|
||||||
|
@ -8131,6 +8198,46 @@ instruct mulL_eReg_con(eADXRegL dst, immL_127 src, rRegI tmp, eFlagsReg cr) %{
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct mulExactI_eReg(eAXRegI dst, rRegI src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "IMUL $dst, $src\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactI_eReg_imm(eAXRegI dst, rRegI src, immI imm, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI src imm);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "IMUL $dst, $src, $imm\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Register, $imm$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactI_eReg_mem(eAXRegI dst, memory src, eFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(350);
|
||||||
|
format %{ "IMUL $dst, $src\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_mem_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Integer DIV with Register
|
// Integer DIV with Register
|
||||||
instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
|
instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
|
||||||
match(Set rax (DivI rax div));
|
match(Set rax (DivI rax div));
|
||||||
|
|
|
@ -1653,6 +1653,10 @@ const RegMask Matcher::mathExactI_result_proj_mask() {
|
||||||
return INT_RAX_REG_mask();
|
return INT_RAX_REG_mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RegMask Matcher::mathExactL_result_proj_mask() {
|
||||||
|
return LONG_RAX_REG_mask();
|
||||||
|
}
|
||||||
|
|
||||||
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
const RegMask Matcher::mathExactI_flags_proj_mask() {
|
||||||
return INT_FLAGS_mask();
|
return INT_FLAGS_mask();
|
||||||
}
|
}
|
||||||
|
@ -6962,6 +6966,58 @@ instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
|
||||||
ins_pipe(ialu_reg_reg);
|
ins_pipe(ialu_reg_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125); // XXX
|
||||||
|
format %{ "addl $dst, $src\t# addExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addl($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactL dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "addq $dst, $src\t# addExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addq($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactL dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "addq $dst, $src\t# addExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addq($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(AddExactL dst (LoadL src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125); // XXX
|
||||||
|
format %{ "addq $dst, $src\t# addExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ addq($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(Set dst (AddI dst src));
|
match(Set dst (AddI dst src));
|
||||||
|
@ -7574,6 +7630,80 @@ instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
|
||||||
ins_pipe(ialu_mem_imm);
|
ins_pipe(ialu_mem_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "subl $dst, $src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "subl $dst, $src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "subl $dst, $src\t# subExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subl($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactL dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "subq $dst, $src\t# subExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subq($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactL dst (LoadL src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
format %{ "subq $dst, $src\t# subExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subq($dst$$Register, $src$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(SubExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(125);
|
||||||
|
format %{ "subq $dst, $src\t# subExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ subq($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_mem);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
match(Set dst (SubL dst src));
|
match(Set dst (SubL dst src));
|
||||||
|
@ -7690,6 +7820,30 @@ instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
|
||||||
ins_pipe(ialu_reg);
|
ins_pipe(ialu_reg);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(NegExactI dst);
|
||||||
|
effect(KILL cr);
|
||||||
|
|
||||||
|
format %{ "negl $dst\t# negExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ negl($dst$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(NegExactL dst);
|
||||||
|
effect(KILL cr);
|
||||||
|
|
||||||
|
format %{ "negq $dst\t# negExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ negq($dst$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
//----------Multiplication/Division Instructions-------------------------------
|
//----------Multiplication/Division Instructions-------------------------------
|
||||||
// Integer Multiplication Instructions
|
// Integer Multiplication Instructions
|
||||||
|
@ -7807,6 +7961,86 @@ instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
|
||||||
ins_pipe(ialu_reg_reg_alu0);
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "imull $dst, $src\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI src imm);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "imull $dst, $src, $imm\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Register, $imm$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactI dst (LoadI src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(350);
|
||||||
|
format %{ "imull $dst, $src\t# mulExact int" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imull($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_mem_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactL dst src);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "imulq $dst, $src\t# mulExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imulq($dst$$Register, $src$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactL src imm);
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(300);
|
||||||
|
format %{ "imulq $dst, $src, $imm\t# mulExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imulq($dst$$Register, $src$$Register, $imm$$constant);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_reg_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
|
||||||
|
%{
|
||||||
|
match(MulExactL dst (LoadL src));
|
||||||
|
effect(DEF cr);
|
||||||
|
|
||||||
|
ins_cost(350);
|
||||||
|
format %{ "imulq $dst, $src\t# mulExact long" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ imulq($dst$$Register, $src$$Address);
|
||||||
|
%}
|
||||||
|
ins_pipe(ialu_reg_mem_alu0);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
|
instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
|
||||||
rFlagsReg cr)
|
rFlagsReg cr)
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -1193,6 +1193,13 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
|
||||||
|| strcmp(idealName,"FastLock") == 0
|
|| strcmp(idealName,"FastLock") == 0
|
||||||
|| strcmp(idealName,"FastUnlock") == 0
|
|| strcmp(idealName,"FastUnlock") == 0
|
||||||
|| strcmp(idealName,"AddExactI") == 0
|
|| strcmp(idealName,"AddExactI") == 0
|
||||||
|
|| strcmp(idealName,"AddExactL") == 0
|
||||||
|
|| strcmp(idealName,"SubExactI") == 0
|
||||||
|
|| strcmp(idealName,"SubExactL") == 0
|
||||||
|
|| strcmp(idealName,"MulExactI") == 0
|
||||||
|
|| strcmp(idealName,"MulExactL") == 0
|
||||||
|
|| strcmp(idealName,"NegExactI") == 0
|
||||||
|
|| strcmp(idealName,"NegExactL") == 0
|
||||||
|| strcmp(idealName,"FlagsProj") == 0
|
|| strcmp(idealName,"FlagsProj") == 0
|
||||||
|| strcmp(idealName,"Bool") == 0
|
|| strcmp(idealName,"Bool") == 0
|
||||||
|| strcmp(idealName,"Binary") == 0 ) {
|
|| strcmp(idealName,"Binary") == 0 ) {
|
||||||
|
|
|
@ -624,6 +624,7 @@
|
||||||
do_class(java_lang_StrictMath, "java/lang/StrictMath") \
|
do_class(java_lang_StrictMath, "java/lang/StrictMath") \
|
||||||
do_signature(double2_double_signature, "(DD)D") \
|
do_signature(double2_double_signature, "(DD)D") \
|
||||||
do_signature(int2_int_signature, "(II)I") \
|
do_signature(int2_int_signature, "(II)I") \
|
||||||
|
do_signature(long2_long_signature, "(JJ)J") \
|
||||||
\
|
\
|
||||||
/* here are the math names, all together: */ \
|
/* here are the math names, all together: */ \
|
||||||
do_name(abs_name,"abs") do_name(sin_name,"sin") do_name(cos_name,"cos") \
|
do_name(abs_name,"abs") do_name(sin_name,"sin") do_name(cos_name,"cos") \
|
||||||
|
@ -632,8 +633,11 @@
|
||||||
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
|
do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \
|
||||||
\
|
\
|
||||||
do_name(addExact_name,"addExact") \
|
do_name(addExact_name,"addExact") \
|
||||||
do_name(subtractExact_name,"subtractExact") \
|
do_name(decrementExact_name,"decrementExact") \
|
||||||
|
do_name(incrementExact_name,"incrementExact") \
|
||||||
do_name(multiplyExact_name,"multiplyExact") \
|
do_name(multiplyExact_name,"multiplyExact") \
|
||||||
|
do_name(negateExact_name,"negateExact") \
|
||||||
|
do_name(subtractExact_name,"subtractExact") \
|
||||||
\
|
\
|
||||||
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
|
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
|
||||||
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
|
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
|
||||||
|
@ -647,7 +651,18 @@
|
||||||
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
|
do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \
|
||||||
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
|
do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \
|
||||||
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
|
do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \
|
||||||
do_intrinsic(_addExact, java_lang_Math, addExact_name, int2_int_signature, F_S) \
|
do_intrinsic(_addExactI, java_lang_Math, addExact_name, int2_int_signature, F_S) \
|
||||||
|
do_intrinsic(_addExactL, java_lang_Math, addExact_name, long2_long_signature, F_S) \
|
||||||
|
do_intrinsic(_decrementExactI, java_lang_Math, decrementExact_name, int_int_signature, F_S) \
|
||||||
|
do_intrinsic(_decrementExactL, java_lang_Math, decrementExact_name, long2_long_signature, F_S) \
|
||||||
|
do_intrinsic(_incrementExactI, java_lang_Math, incrementExact_name, int_int_signature, F_S) \
|
||||||
|
do_intrinsic(_incrementExactL, java_lang_Math, incrementExact_name, long2_long_signature, F_S) \
|
||||||
|
do_intrinsic(_multiplyExactI, java_lang_Math, multiplyExact_name, int2_int_signature, F_S) \
|
||||||
|
do_intrinsic(_multiplyExactL, java_lang_Math, multiplyExact_name, long2_long_signature, F_S) \
|
||||||
|
do_intrinsic(_negateExactI, java_lang_Math, negateExact_name, int_int_signature, F_S) \
|
||||||
|
do_intrinsic(_negateExactL, java_lang_Math, negateExact_name, long_long_signature, F_S) \
|
||||||
|
do_intrinsic(_subtractExactI, java_lang_Math, subtractExact_name, int2_int_signature, F_S) \
|
||||||
|
do_intrinsic(_subtractExactL, java_lang_Math, subtractExact_name, long2_long_signature, F_S) \
|
||||||
\
|
\
|
||||||
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
|
do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \
|
||||||
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
|
do_name( floatToRawIntBits_name, "floatToRawIntBits") \
|
||||||
|
|
|
@ -30,6 +30,7 @@ macro(AbsF)
|
||||||
macro(AbsI)
|
macro(AbsI)
|
||||||
macro(AddD)
|
macro(AddD)
|
||||||
macro(AddExactI)
|
macro(AddExactI)
|
||||||
|
macro(AddExactL)
|
||||||
macro(AddF)
|
macro(AddF)
|
||||||
macro(AddI)
|
macro(AddI)
|
||||||
macro(AddL)
|
macro(AddL)
|
||||||
|
@ -170,6 +171,8 @@ macro(LoopLimit)
|
||||||
macro(Mach)
|
macro(Mach)
|
||||||
macro(MachProj)
|
macro(MachProj)
|
||||||
macro(MathExact)
|
macro(MathExact)
|
||||||
|
macro(MathExactI)
|
||||||
|
macro(MathExactL)
|
||||||
macro(MaxI)
|
macro(MaxI)
|
||||||
macro(MemBarAcquire)
|
macro(MemBarAcquire)
|
||||||
macro(MemBarAcquireLock)
|
macro(MemBarAcquireLock)
|
||||||
|
@ -189,12 +192,16 @@ macro(MoveF2I)
|
||||||
macro(MoveL2D)
|
macro(MoveL2D)
|
||||||
macro(MoveD2L)
|
macro(MoveD2L)
|
||||||
macro(MulD)
|
macro(MulD)
|
||||||
|
macro(MulExactI)
|
||||||
|
macro(MulExactL)
|
||||||
macro(MulF)
|
macro(MulF)
|
||||||
macro(MulHiL)
|
macro(MulHiL)
|
||||||
macro(MulI)
|
macro(MulI)
|
||||||
macro(MulL)
|
macro(MulL)
|
||||||
macro(Multi)
|
macro(Multi)
|
||||||
macro(NegD)
|
macro(NegD)
|
||||||
|
macro(NegExactI)
|
||||||
|
macro(NegExactL)
|
||||||
macro(NegF)
|
macro(NegF)
|
||||||
macro(NeverBranch)
|
macro(NeverBranch)
|
||||||
macro(Opaque1)
|
macro(Opaque1)
|
||||||
|
@ -244,6 +251,8 @@ macro(StrComp)
|
||||||
macro(StrEquals)
|
macro(StrEquals)
|
||||||
macro(StrIndexOf)
|
macro(StrIndexOf)
|
||||||
macro(SubD)
|
macro(SubD)
|
||||||
|
macro(SubExactI)
|
||||||
|
macro(SubExactL)
|
||||||
macro(SubF)
|
macro(SubF)
|
||||||
macro(SubI)
|
macro(SubI)
|
||||||
macro(SubL)
|
macro(SubL)
|
||||||
|
|
|
@ -203,8 +203,15 @@ class LibraryCallKit : public GraphKit {
|
||||||
bool inline_math_native(vmIntrinsics::ID id);
|
bool inline_math_native(vmIntrinsics::ID id);
|
||||||
bool inline_trig(vmIntrinsics::ID id);
|
bool inline_trig(vmIntrinsics::ID id);
|
||||||
bool inline_math(vmIntrinsics::ID id);
|
bool inline_math(vmIntrinsics::ID id);
|
||||||
bool inline_math_mathExact(Node* math);
|
void inline_math_mathExact(Node* math);
|
||||||
bool inline_math_addExact();
|
bool inline_math_addExactI(bool is_increment);
|
||||||
|
bool inline_math_addExactL(bool is_increment);
|
||||||
|
bool inline_math_multiplyExactI();
|
||||||
|
bool inline_math_multiplyExactL();
|
||||||
|
bool inline_math_negateExactI();
|
||||||
|
bool inline_math_negateExactL();
|
||||||
|
bool inline_math_subtractExactI(bool is_decrement);
|
||||||
|
bool inline_math_subtractExactL(bool is_decrement);
|
||||||
bool inline_exp();
|
bool inline_exp();
|
||||||
bool inline_pow();
|
bool inline_pow();
|
||||||
void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
|
void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
|
||||||
|
@ -507,13 +514,33 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
|
||||||
if (!UseCRC32Intrinsics) return NULL;
|
if (!UseCRC32Intrinsics) return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case vmIntrinsics::_addExact:
|
case vmIntrinsics::_incrementExactI:
|
||||||
if (!Matcher::match_rule_supported(Op_AddExactI)) {
|
case vmIntrinsics::_addExactI:
|
||||||
return NULL;
|
if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
|
||||||
}
|
break;
|
||||||
if (!UseMathExactIntrinsics) {
|
case vmIntrinsics::_incrementExactL:
|
||||||
return NULL;
|
case vmIntrinsics::_addExactL:
|
||||||
}
|
if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_decrementExactI:
|
||||||
|
case vmIntrinsics::_subtractExactI:
|
||||||
|
if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_decrementExactL:
|
||||||
|
case vmIntrinsics::_subtractExactL:
|
||||||
|
if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_negateExactI:
|
||||||
|
if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_negateExactL:
|
||||||
|
if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_multiplyExactI:
|
||||||
|
if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
|
||||||
|
break;
|
||||||
|
case vmIntrinsics::_multiplyExactL:
|
||||||
|
if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -686,7 +713,18 @@ bool LibraryCallKit::try_to_inline() {
|
||||||
case vmIntrinsics::_min:
|
case vmIntrinsics::_min:
|
||||||
case vmIntrinsics::_max: return inline_min_max(intrinsic_id());
|
case vmIntrinsics::_max: return inline_min_max(intrinsic_id());
|
||||||
|
|
||||||
case vmIntrinsics::_addExact: return inline_math_addExact();
|
case vmIntrinsics::_addExactI: return inline_math_addExactI(false /* add */);
|
||||||
|
case vmIntrinsics::_addExactL: return inline_math_addExactL(false /* add */);
|
||||||
|
case vmIntrinsics::_decrementExactI: return inline_math_subtractExactI(true /* decrement */);
|
||||||
|
case vmIntrinsics::_decrementExactL: return inline_math_subtractExactL(true /* decrement */);
|
||||||
|
case vmIntrinsics::_incrementExactI: return inline_math_addExactI(true /* increment */);
|
||||||
|
case vmIntrinsics::_incrementExactL: return inline_math_addExactL(true /* increment */);
|
||||||
|
case vmIntrinsics::_multiplyExactI: return inline_math_multiplyExactI();
|
||||||
|
case vmIntrinsics::_multiplyExactL: return inline_math_multiplyExactL();
|
||||||
|
case vmIntrinsics::_negateExactI: return inline_math_negateExactI();
|
||||||
|
case vmIntrinsics::_negateExactL: return inline_math_negateExactL();
|
||||||
|
case vmIntrinsics::_subtractExactI: return inline_math_subtractExactI(false /* subtract */);
|
||||||
|
case vmIntrinsics::_subtractExactL: return inline_math_subtractExactL(false /* subtract */);
|
||||||
|
|
||||||
case vmIntrinsics::_arraycopy: return inline_arraycopy();
|
case vmIntrinsics::_arraycopy: return inline_arraycopy();
|
||||||
|
|
||||||
|
@ -1931,7 +1969,14 @@ bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibraryCallKit::inline_math_mathExact(Node* math) {
|
void LibraryCallKit::inline_math_mathExact(Node* math) {
|
||||||
|
// If we didn't get the expected opcode it means we have optimized
|
||||||
|
// the node to something else and don't need the exception edge.
|
||||||
|
if (!math->is_MathExact()) {
|
||||||
|
set_result(math);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
|
Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
|
||||||
Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
|
Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
|
||||||
|
|
||||||
|
@ -1954,19 +1999,106 @@ bool LibraryCallKit::inline_math_mathExact(Node* math) {
|
||||||
|
|
||||||
set_control(fast_path);
|
set_control(fast_path);
|
||||||
set_result(result);
|
set_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
|
||||||
|
Node* arg1 = argument(0);
|
||||||
|
Node* arg2 = NULL;
|
||||||
|
|
||||||
|
if (is_increment) {
|
||||||
|
arg2 = intcon(1);
|
||||||
|
} else {
|
||||||
|
arg2 = argument(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
|
||||||
|
inline_math_mathExact(add);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibraryCallKit::inline_math_addExact() {
|
bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
|
||||||
|
Node* arg1 = argument(0); // type long
|
||||||
|
// argument(1) == TOP
|
||||||
|
Node* arg2 = NULL;
|
||||||
|
|
||||||
|
if (is_increment) {
|
||||||
|
arg2 = longcon(1);
|
||||||
|
} else {
|
||||||
|
arg2 = argument(2); // type long
|
||||||
|
// argument(3) == TOP
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
|
||||||
|
inline_math_mathExact(add);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
|
||||||
|
Node* arg1 = argument(0);
|
||||||
|
Node* arg2 = NULL;
|
||||||
|
|
||||||
|
if (is_decrement) {
|
||||||
|
arg2 = intcon(1);
|
||||||
|
} else {
|
||||||
|
arg2 = argument(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
|
||||||
|
inline_math_mathExact(sub);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
|
||||||
|
Node* arg1 = argument(0); // type long
|
||||||
|
// argument(1) == TOP
|
||||||
|
Node* arg2 = NULL;
|
||||||
|
|
||||||
|
if (is_decrement) {
|
||||||
|
arg2 = longcon(1);
|
||||||
|
} else {
|
||||||
|
Node* arg2 = argument(2); // type long
|
||||||
|
// argument(3) == TOP
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
|
||||||
|
inline_math_mathExact(sub);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_negateExactI() {
|
||||||
|
Node* arg1 = argument(0);
|
||||||
|
|
||||||
|
Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
|
||||||
|
inline_math_mathExact(neg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_negateExactL() {
|
||||||
|
Node* arg1 = argument(0);
|
||||||
|
// argument(1) == TOP
|
||||||
|
|
||||||
|
Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
|
||||||
|
inline_math_mathExact(neg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_multiplyExactI() {
|
||||||
Node* arg1 = argument(0);
|
Node* arg1 = argument(0);
|
||||||
Node* arg2 = argument(1);
|
Node* arg2 = argument(1);
|
||||||
|
|
||||||
Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
|
Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
|
||||||
if (add->Opcode() == Op_AddExactI) {
|
inline_math_mathExact(mul);
|
||||||
return inline_math_mathExact(add);
|
return true;
|
||||||
} else {
|
|
||||||
set_result(add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LibraryCallKit::inline_math_multiplyExactL() {
|
||||||
|
Node* arg1 = argument(0);
|
||||||
|
// argument(1) == TOP
|
||||||
|
Node* arg2 = argument(2);
|
||||||
|
// argument(3) == TOP
|
||||||
|
|
||||||
|
Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
|
||||||
|
inline_math_mathExact(mul);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,6 +338,7 @@ public:
|
||||||
static RegMask modL_proj_mask();
|
static RegMask modL_proj_mask();
|
||||||
|
|
||||||
static const RegMask mathExactI_result_proj_mask();
|
static const RegMask mathExactI_result_proj_mask();
|
||||||
|
static const RegMask mathExactL_result_proj_mask();
|
||||||
static const RegMask mathExactI_flags_proj_mask();
|
static const RegMask mathExactI_flags_proj_mask();
|
||||||
|
|
||||||
// Use hardware DIV instruction when it is faster than
|
// Use hardware DIV instruction when it is faster than
|
||||||
|
|
|
@ -31,10 +31,17 @@
|
||||||
#include "opto/mathexactnode.hpp"
|
#include "opto/mathexactnode.hpp"
|
||||||
#include "opto/subnode.hpp"
|
#include "opto/subnode.hpp"
|
||||||
|
|
||||||
MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) {
|
MathExactNode::MathExactNode(Node* ctrl, Node* in1) : MultiNode(2) {
|
||||||
|
init_class_id(Class_MathExact);
|
||||||
init_req(0, ctrl);
|
init_req(0, ctrl);
|
||||||
init_req(1, n1);
|
init_req(1, in1);
|
||||||
init_req(2, n2);
|
}
|
||||||
|
|
||||||
|
MathExactNode::MathExactNode(Node* ctrl, Node* in1, Node* in2) : MultiNode(3) {
|
||||||
|
init_class_id(Class_MathExact);
|
||||||
|
init_req(0, ctrl);
|
||||||
|
init_req(1, in1);
|
||||||
|
init_req(2, in2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BoolNode* MathExactNode::bool_node() const {
|
BoolNode* MathExactNode::bool_node() const {
|
||||||
|
@ -64,19 +71,6 @@ Node* MathExactNode::non_throwing_branch() const {
|
||||||
return ifnode->proj_out(1);
|
return ifnode->proj_out(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
|
|
||||||
uint ideal_reg = proj->ideal_reg();
|
|
||||||
RegMask rm;
|
|
||||||
if (proj->_con == result_proj_node) {
|
|
||||||
rm = m->mathExactI_result_proj_mask();
|
|
||||||
} else {
|
|
||||||
assert(proj->_con == flags_proj_node, "must be result or flags");
|
|
||||||
assert(ideal_reg == Op_RegFlags, "sanity");
|
|
||||||
rm = m->mathExactI_flags_proj_mask();
|
|
||||||
}
|
|
||||||
return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the MathExactNode won't overflow we have to replace the
|
// If the MathExactNode won't overflow we have to replace the
|
||||||
// FlagsProjNode and ProjNode that is generated by the MathExactNode
|
// FlagsProjNode and ProjNode that is generated by the MathExactNode
|
||||||
Node* MathExactNode::no_overflow(PhaseGVN* phase, Node* new_result) {
|
Node* MathExactNode::no_overflow(PhaseGVN* phase, Node* new_result) {
|
||||||
|
@ -110,6 +104,32 @@ Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
|
||||||
return new_result;
|
return new_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node* MathExactINode::match(const ProjNode* proj, const Matcher* m) {
|
||||||
|
uint ideal_reg = proj->ideal_reg();
|
||||||
|
RegMask rm;
|
||||||
|
if (proj->_con == result_proj_node) {
|
||||||
|
rm = m->mathExactI_result_proj_mask();
|
||||||
|
} else {
|
||||||
|
assert(proj->_con == flags_proj_node, "must be result or flags");
|
||||||
|
assert(ideal_reg == Op_RegFlags, "sanity");
|
||||||
|
rm = m->mathExactI_flags_proj_mask();
|
||||||
|
}
|
||||||
|
return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MathExactLNode::match(const ProjNode* proj, const Matcher* m) {
|
||||||
|
uint ideal_reg = proj->ideal_reg();
|
||||||
|
RegMask rm;
|
||||||
|
if (proj->_con == result_proj_node) {
|
||||||
|
rm = m->mathExactL_result_proj_mask();
|
||||||
|
} else {
|
||||||
|
assert(proj->_con == flags_proj_node, "must be result or flags");
|
||||||
|
assert(ideal_reg == Op_RegFlags, "sanity");
|
||||||
|
rm = m->mathExactI_flags_proj_mask();
|
||||||
|
}
|
||||||
|
return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
|
||||||
|
}
|
||||||
|
|
||||||
Node* AddExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
Node* AddExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
Node* arg1 = in(1);
|
Node* arg1 = in(1);
|
||||||
Node* arg2 = in(2);
|
Node* arg2 = in(2);
|
||||||
|
@ -130,12 +150,7 @@ Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
|
if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) { // (Add 0 x) == x
|
||||||
Node* add_result = new (phase->C) AddINode(arg1, arg2);
|
|
||||||
return no_overflow(phase, add_result);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type2 == TypeInt::ZERO) { // (Add x 0) == x
|
|
||||||
Node* add_result = new (phase->C) AddINode(arg1, arg2);
|
Node* add_result = new (phase->C) AddINode(arg1, arg2);
|
||||||
return no_overflow(phase, add_result);
|
return no_overflow(phase, add_result);
|
||||||
}
|
}
|
||||||
|
@ -169,3 +184,247 @@ Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node* AddExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* arg1 = in(1);
|
||||||
|
Node* arg2 = in(2);
|
||||||
|
|
||||||
|
const Type* type1 = phase->type(arg1);
|
||||||
|
const Type* type2 = phase->type(arg2);
|
||||||
|
|
||||||
|
if (type1 != Type::TOP && type1->singleton() &&
|
||||||
|
type2 != Type::TOP && type2->singleton()) {
|
||||||
|
jlong val1 = arg1->get_long();
|
||||||
|
jlong val2 = arg2->get_long();
|
||||||
|
jlong result = val1 + val2;
|
||||||
|
// Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
|
||||||
|
if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
|
||||||
|
Node* con_result = ConLNode::make(phase->C, result);
|
||||||
|
return no_overflow(phase, con_result);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) { // (Add 0 x) == x
|
||||||
|
Node* add_result = new (phase->C) AddLNode(arg1, arg2);
|
||||||
|
return no_overflow(phase, add_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type2->singleton()) {
|
||||||
|
return NULL; // no change - keep constant on the right
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1->singleton()) {
|
||||||
|
// Make it x + Constant - move constant to the right
|
||||||
|
swap_edges(1, 2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg2->is_Load()) {
|
||||||
|
return NULL; // no change - keep load on the right
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg1->is_Load()) {
|
||||||
|
// Make it x + Load - move load to the right
|
||||||
|
swap_edges(1, 2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg1->_idx > arg2->_idx) {
|
||||||
|
// Sort the edges
|
||||||
|
swap_edges(1, 2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* SubExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* arg1 = in(1);
|
||||||
|
Node* arg2 = in(2);
|
||||||
|
|
||||||
|
const Type* type1 = phase->type(arg1);
|
||||||
|
const Type* type2 = phase->type(arg2);
|
||||||
|
|
||||||
|
if (type1 != Type::TOP && type1->singleton() &&
|
||||||
|
type2 != Type::TOP && type2->singleton()) {
|
||||||
|
jint val1 = arg1->get_int();
|
||||||
|
jint val2 = arg2->get_int();
|
||||||
|
jint result = val1 - val2;
|
||||||
|
|
||||||
|
// Hacker's Delight 2-12 Overflow iff the arguments have different signs and
|
||||||
|
// the sign of the result is different than the sign of arg1
|
||||||
|
if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
|
||||||
|
Node* con_result = ConINode::make(phase->C, result);
|
||||||
|
return no_overflow(phase, con_result);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
|
||||||
|
// Sub with zero is the same as add with zero
|
||||||
|
Node* add_result = new (phase->C) AddINode(arg1, arg2);
|
||||||
|
return no_overflow(phase, add_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* SubExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* arg1 = in(1);
|
||||||
|
Node* arg2 = in(2);
|
||||||
|
|
||||||
|
const Type* type1 = phase->type(arg1);
|
||||||
|
const Type* type2 = phase->type(arg2);
|
||||||
|
|
||||||
|
if (type1 != Type::TOP && type1->singleton() &&
|
||||||
|
type2 != Type::TOP && type2->singleton()) {
|
||||||
|
jlong val1 = arg1->get_long();
|
||||||
|
jlong val2 = arg2->get_long();
|
||||||
|
jlong result = val1 - val2;
|
||||||
|
|
||||||
|
// Hacker's Delight 2-12 Overflow iff the arguments have different signs and
|
||||||
|
// the sign of the result is different than the sign of arg1
|
||||||
|
if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
|
||||||
|
Node* con_result = ConLNode::make(phase->C, result);
|
||||||
|
return no_overflow(phase, con_result);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
|
||||||
|
// Sub with zero is the same as add with zero
|
||||||
|
Node* add_result = new (phase->C) AddLNode(arg1, arg2);
|
||||||
|
return no_overflow(phase, add_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* NegExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node *arg = in(1);
|
||||||
|
|
||||||
|
const Type* type = phase->type(arg);
|
||||||
|
if (type != Type::TOP && type->singleton()) {
|
||||||
|
jint value = arg->get_int();
|
||||||
|
if (value != min_jint) {
|
||||||
|
Node* neg_result = ConINode::make(phase->C, -value);
|
||||||
|
return no_overflow(phase, neg_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* NegExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node *arg = in(1);
|
||||||
|
|
||||||
|
const Type* type = phase->type(arg);
|
||||||
|
if (type != Type::TOP && type->singleton()) {
|
||||||
|
jlong value = arg->get_long();
|
||||||
|
if (value != min_jlong) {
|
||||||
|
Node* neg_result = ConLNode::make(phase->C, -value);
|
||||||
|
return no_overflow(phase, neg_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MulExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* arg1 = in(1);
|
||||||
|
Node* arg2 = in(2);
|
||||||
|
|
||||||
|
const Type* type1 = phase->type(arg1);
|
||||||
|
const Type* type2 = phase->type(arg2);
|
||||||
|
|
||||||
|
if (type1 != Type::TOP && type1->singleton() &&
|
||||||
|
type2 != Type::TOP && type2->singleton()) {
|
||||||
|
jint val1 = arg1->get_int();
|
||||||
|
jint val2 = arg2->get_int();
|
||||||
|
jlong result = (jlong) val1 * (jlong) val2;
|
||||||
|
if ((jint) result == result) {
|
||||||
|
// no overflow
|
||||||
|
Node* mul_result = ConINode::make(phase->C, result);
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
|
||||||
|
return no_overflow(phase, ConINode::make(phase->C, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeInt::ONE) {
|
||||||
|
Node* mul_result = new (phase->C) AddINode(arg2, phase->intcon(0));
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
if (type2 == TypeInt::ONE) {
|
||||||
|
Node* mul_result = new (phase->C) AddINode(arg1, phase->intcon(0));
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeInt::MINUS_1) {
|
||||||
|
return new (phase->C) NegExactINode(NULL, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type2 == TypeInt::MINUS_1) {
|
||||||
|
return new (phase->C) NegExactINode(NULL, arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* MulExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||||
|
Node* arg1 = in(1);
|
||||||
|
Node* arg2 = in(2);
|
||||||
|
|
||||||
|
const Type* type1 = phase->type(arg1);
|
||||||
|
const Type* type2 = phase->type(arg2);
|
||||||
|
|
||||||
|
if (type1 != Type::TOP && type1->singleton() &&
|
||||||
|
type2 != Type::TOP && type2->singleton()) {
|
||||||
|
jlong val1 = arg1->get_long();
|
||||||
|
jlong val2 = arg2->get_long();
|
||||||
|
|
||||||
|
jlong result = val1 * val2;
|
||||||
|
jlong ax = (val1 < 0 ? -val1 : val1);
|
||||||
|
jlong ay = (val2 < 0 ? -val2 : val2);
|
||||||
|
|
||||||
|
bool overflow = false;
|
||||||
|
if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
|
||||||
|
// potential overflow if any bit in upper 32 bits are set
|
||||||
|
if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
|
||||||
|
// -1 * Long.MIN_VALUE will overflow
|
||||||
|
overflow = true;
|
||||||
|
} else if (val2 != 0 && (result / val2 != val1)) {
|
||||||
|
overflow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overflow) {
|
||||||
|
Node* mul_result = ConLNode::make(phase->C, result);
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
|
||||||
|
return no_overflow(phase, ConLNode::make(phase->C, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeLong::ONE) {
|
||||||
|
Node* mul_result = new (phase->C) AddLNode(arg2, phase->longcon(0));
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
if (type2 == TypeLong::ONE) {
|
||||||
|
Node* mul_result = new (phase->C) AddLNode(arg1, phase->longcon(0));
|
||||||
|
return no_overflow(phase, mul_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type1 == TypeLong::MINUS_1) {
|
||||||
|
return new (phase->C) NegExactLNode(NULL, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type2 == TypeLong::MINUS_1) {
|
||||||
|
return new (phase->C) NegExactLNode(NULL, arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ class PhaseTransform;
|
||||||
|
|
||||||
class MathExactNode : public MultiNode {
|
class MathExactNode : public MultiNode {
|
||||||
public:
|
public:
|
||||||
|
MathExactNode(Node* ctrl, Node* in1);
|
||||||
MathExactNode(Node* ctrl, Node* in1, Node* in2);
|
MathExactNode(Node* ctrl, Node* in1, Node* in2);
|
||||||
enum {
|
enum {
|
||||||
result_proj_node = 0,
|
result_proj_node = 0,
|
||||||
|
@ -62,12 +63,77 @@ protected:
|
||||||
Node* no_overflow(PhaseGVN *phase, Node* new_result);
|
Node* no_overflow(PhaseGVN *phase, Node* new_result);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddExactINode : public MathExactNode {
|
class MathExactINode : public MathExactNode {
|
||||||
public:
|
public:
|
||||||
AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
|
MathExactINode(Node* ctrl, Node* in1) : MathExactNode(ctrl, in1) {}
|
||||||
|
MathExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
|
|
||||||
virtual Node* match(const ProjNode* proj, const Matcher* m);
|
virtual Node* match(const ProjNode* proj, const Matcher* m);
|
||||||
|
virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class MathExactLNode : public MathExactNode {
|
||||||
|
public:
|
||||||
|
MathExactLNode(Node* ctrl, Node* in1) : MathExactNode(ctrl, in1) {}
|
||||||
|
MathExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* match(const ProjNode* proj, const Matcher* m);
|
||||||
|
virtual const Type* bottom_type() const { return TypeTuple::LONG_CC_PAIR; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddExactINode : public MathExactINode {
|
||||||
|
public:
|
||||||
|
AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddExactLNode : public MathExactLNode {
|
||||||
|
public:
|
||||||
|
AddExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubExactINode : public MathExactINode {
|
||||||
|
public:
|
||||||
|
SubExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubExactLNode : public MathExactLNode {
|
||||||
|
public:
|
||||||
|
SubExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NegExactINode : public MathExactINode {
|
||||||
|
public:
|
||||||
|
NegExactINode(Node* ctrl, Node* in1) : MathExactINode(ctrl, in1) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NegExactLNode : public MathExactLNode {
|
||||||
|
public:
|
||||||
|
NegExactLNode(Node* ctrl, Node* in1) : MathExactLNode(ctrl, in1) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MulExactINode : public MathExactINode {
|
||||||
|
public:
|
||||||
|
MulExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactINode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MulExactLNode : public MathExactLNode {
|
||||||
|
public:
|
||||||
|
MulExactLNode(Node* ctrl, Node* in1, Node* in2) : MathExactLNode(ctrl, in1, in2) {}
|
||||||
|
virtual int Opcode() const;
|
||||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ class MachSafePointNode;
|
||||||
class MachSpillCopyNode;
|
class MachSpillCopyNode;
|
||||||
class MachTempNode;
|
class MachTempNode;
|
||||||
class Matcher;
|
class Matcher;
|
||||||
|
class MathExactNode;
|
||||||
class MemBarNode;
|
class MemBarNode;
|
||||||
class MemBarStoreStoreNode;
|
class MemBarStoreStoreNode;
|
||||||
class MemNode;
|
class MemNode;
|
||||||
|
@ -568,6 +569,7 @@ public:
|
||||||
DEFINE_CLASS_ID(MemBar, Multi, 3)
|
DEFINE_CLASS_ID(MemBar, Multi, 3)
|
||||||
DEFINE_CLASS_ID(Initialize, MemBar, 0)
|
DEFINE_CLASS_ID(Initialize, MemBar, 0)
|
||||||
DEFINE_CLASS_ID(MemBarStoreStore, MemBar, 1)
|
DEFINE_CLASS_ID(MemBarStoreStore, MemBar, 1)
|
||||||
|
DEFINE_CLASS_ID(MathExact, Multi, 4)
|
||||||
|
|
||||||
DEFINE_CLASS_ID(Mach, Node, 1)
|
DEFINE_CLASS_ID(Mach, Node, 1)
|
||||||
DEFINE_CLASS_ID(MachReturn, Mach, 0)
|
DEFINE_CLASS_ID(MachReturn, Mach, 0)
|
||||||
|
@ -757,6 +759,7 @@ public:
|
||||||
DEFINE_CLASS_QUERY(MachSafePoint)
|
DEFINE_CLASS_QUERY(MachSafePoint)
|
||||||
DEFINE_CLASS_QUERY(MachSpillCopy)
|
DEFINE_CLASS_QUERY(MachSpillCopy)
|
||||||
DEFINE_CLASS_QUERY(MachTemp)
|
DEFINE_CLASS_QUERY(MachTemp)
|
||||||
|
DEFINE_CLASS_QUERY(MathExact)
|
||||||
DEFINE_CLASS_QUERY(Mem)
|
DEFINE_CLASS_QUERY(Mem)
|
||||||
DEFINE_CLASS_QUERY(MemBar)
|
DEFINE_CLASS_QUERY(MemBar)
|
||||||
DEFINE_CLASS_QUERY(MemBarStoreStore)
|
DEFINE_CLASS_QUERY(MemBarStoreStore)
|
||||||
|
|
|
@ -435,6 +435,11 @@ void Type::Initialize_shared(Compile* current) {
|
||||||
intccpair[1] = TypeInt::CC;
|
intccpair[1] = TypeInt::CC;
|
||||||
TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair);
|
TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair);
|
||||||
|
|
||||||
|
const Type **longccpair = TypeTuple::fields(2);
|
||||||
|
longccpair[0] = TypeLong::LONG;
|
||||||
|
longccpair[1] = TypeInt::CC;
|
||||||
|
TypeTuple::LONG_CC_PAIR = TypeTuple::make(2, longccpair);
|
||||||
|
|
||||||
_const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
|
_const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
|
||||||
_const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
|
_const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
|
||||||
_const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
|
_const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
|
||||||
|
@ -1675,6 +1680,7 @@ const TypeTuple *TypeTuple::START_I2C;
|
||||||
const TypeTuple *TypeTuple::INT_PAIR;
|
const TypeTuple *TypeTuple::INT_PAIR;
|
||||||
const TypeTuple *TypeTuple::LONG_PAIR;
|
const TypeTuple *TypeTuple::LONG_PAIR;
|
||||||
const TypeTuple *TypeTuple::INT_CC_PAIR;
|
const TypeTuple *TypeTuple::INT_CC_PAIR;
|
||||||
|
const TypeTuple *TypeTuple::LONG_CC_PAIR;
|
||||||
|
|
||||||
|
|
||||||
//------------------------------make-------------------------------------------
|
//------------------------------make-------------------------------------------
|
||||||
|
|
|
@ -593,6 +593,7 @@ public:
|
||||||
static const TypeTuple *INT_PAIR;
|
static const TypeTuple *INT_PAIR;
|
||||||
static const TypeTuple *LONG_PAIR;
|
static const TypeTuple *LONG_PAIR;
|
||||||
static const TypeTuple *INT_CC_PAIR;
|
static const TypeTuple *INT_CC_PAIR;
|
||||||
|
static const TypeTuple *LONG_CC_PAIR;
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping
|
virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1938,7 +1938,13 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
declare_c2_type(CmpDNode, CmpNode) \
|
declare_c2_type(CmpDNode, CmpNode) \
|
||||||
declare_c2_type(CmpD3Node, CmpDNode) \
|
declare_c2_type(CmpD3Node, CmpDNode) \
|
||||||
declare_c2_type(MathExactNode, MultiNode) \
|
declare_c2_type(MathExactNode, MultiNode) \
|
||||||
declare_c2_type(AddExactINode, MathExactNode) \
|
declare_c2_type(MathExactINode, MathExactNode) \
|
||||||
|
declare_c2_type(AddExactINode, MathExactINode) \
|
||||||
|
declare_c2_type(AddExactLNode, MathExactLNode) \
|
||||||
|
declare_c2_type(SubExactINode, MathExactINode) \
|
||||||
|
declare_c2_type(SubExactLNode, MathExactLNode) \
|
||||||
|
declare_c2_type(NegExactINode, MathExactINode) \
|
||||||
|
declare_c2_type(MulExactINode, MathExactINode) \
|
||||||
declare_c2_type(FlagsProjNode, ProjNode) \
|
declare_c2_type(FlagsProjNode, ProjNode) \
|
||||||
declare_c2_type(BoolNode, Node) \
|
declare_c2_type(BoolNode, Node) \
|
||||||
declare_c2_type(AbsNode, Node) \
|
declare_c2_type(AbsNode, Node) \
|
||||||
|
|
|
@ -25,14 +25,12 @@
|
||||||
* @test
|
* @test
|
||||||
* @bug 8024924
|
* @bug 8024924
|
||||||
* @summary Test non constant addExact
|
* @summary Test non constant addExact
|
||||||
* @compile CondTest.java Verify.java
|
* @compile AddExactICondTest.java
|
||||||
* @run main CondTest
|
* @run main AddExactICondTest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
public class AddExactICondTest {
|
||||||
|
|
||||||
public class CondTest {
|
|
||||||
public static int result = 0;
|
public static int result = 0;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
|
@ -25,23 +25,13 @@
|
||||||
* @test
|
* @test
|
||||||
* @bug 8024924
|
* @bug 8024924
|
||||||
* @summary Test constant addExact
|
* @summary Test constant addExact
|
||||||
* @compile ConstantTest.java Verify.java
|
* @compile AddExactIConstantTest.java Verify.java
|
||||||
* @run main ConstantTest
|
* @run main AddExactIConstantTest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
public class AddExactIConstantTest {
|
||||||
|
|
||||||
public class ConstantTest {
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for (int i = 0; i < 50000; ++i) {
|
Verify.ConstantTest.verify(new Verify.AddExactI());
|
||||||
Verify.verify(5, 7);
|
|
||||||
Verify.verify(Integer.MAX_VALUE, 1);
|
|
||||||
Verify.verify(Integer.MIN_VALUE, -1);
|
|
||||||
Verify.verify(Integer.MAX_VALUE, -1);
|
|
||||||
Verify.verify(Integer.MIN_VALUE, 1);
|
|
||||||
Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2);
|
|
||||||
Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,24 +25,14 @@
|
||||||
* @test
|
* @test
|
||||||
* @bug 8024924
|
* @bug 8024924
|
||||||
* @summary Test non constant addExact
|
* @summary Test non constant addExact
|
||||||
* @compile NonConstantTest.java Verify.java
|
* @compile AddExactILoadTest.java Verify.java
|
||||||
* @run main NonConstantTest
|
* @run main AddExactILoadTest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
public class AddExactILoadTest {
|
||||||
|
|
||||||
public class NonConstantTest {
|
|
||||||
public static java.util.Random rnd = new java.util.Random();
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for (int i = 0; i < 50000; ++i) {
|
Verify.LoadTest.init();
|
||||||
int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
|
Verify.LoadTest.verify(new Verify.AddExactI());
|
||||||
Verify.verify(rnd1, rnd2);
|
|
||||||
Verify.verify(rnd1, rnd2 + 1);
|
|
||||||
Verify.verify(rnd1 + 1, rnd2);
|
|
||||||
Verify.verify(rnd1 - 1, rnd2);
|
|
||||||
Verify.verify(rnd1, rnd2 - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,24 +25,13 @@
|
||||||
* @test
|
* @test
|
||||||
* @bug 8024924
|
* @bug 8024924
|
||||||
* @summary Test non constant addExact
|
* @summary Test non constant addExact
|
||||||
* @compile LoopDependentTest.java Verify.java
|
* @compile AddExactILoopDependentTest.java Verify.java
|
||||||
* @run main LoopDependentTest
|
* @run main AddExactILoopDependentTest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
public class AddExactILoopDependentTest {
|
||||||
|
|
||||||
public class LoopDependentTest {
|
|
||||||
public static java.util.Random rnd = new java.util.Random();
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
|
Verify.LoopDependentTest.verify(new Verify.AddExactI());
|
||||||
for (int i = 0; i < 50000; ++i) {
|
|
||||||
Verify.verify(rnd1 + i, rnd2 + i);
|
|
||||||
Verify.verify(rnd1 + i, rnd2 + (i & 0xff));
|
|
||||||
Verify.verify(rnd1 - i, rnd2 - (i & 0xff));
|
|
||||||
Verify.verify(rnd1 + i + 1, rnd2 + i + 2);
|
|
||||||
Verify.verify(rnd1 + i * 2, rnd2 + i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8024924
|
||||||
|
* @summary Test non constant addExact
|
||||||
|
* @compile AddExactINonConstantTest.java Verify.java
|
||||||
|
* @run main AddExactINonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AddExactINonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantTest.verify(new Verify.AddExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8025657
|
||||||
|
* @summary Test repeating addExact
|
||||||
|
* @compile AddExactIRepeatTest.java Verify.java
|
||||||
|
* @run main AddExactIRepeatTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AddExactIRepeatTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.AddExactI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int nonExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.BinaryMethod method) {
|
||||||
|
java.util.Random rnd = new java.util.Random();
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
int x = Integer.MAX_VALUE - 10;
|
||||||
|
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
|
||||||
|
|
||||||
|
int c = rnd.nextInt() / 2;
|
||||||
|
int d = rnd.nextInt() / 2;
|
||||||
|
|
||||||
|
int a = catchingExact(x, y, method);
|
||||||
|
|
||||||
|
if (a != 36) {
|
||||||
|
throw new RuntimeException("a != 36 : " + a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int b = nonExact(c, d, method);
|
||||||
|
int n = exact(c, d, method);
|
||||||
|
|
||||||
|
|
||||||
|
if (n != b) {
|
||||||
|
throw new RuntimeException("n != b : " + n + " != " + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int exact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
result += 5;
|
||||||
|
result = method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 6;
|
||||||
|
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 2;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 7;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 3;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 8;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 4;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant addExact
|
||||||
|
* @compile AddExactLConstantTest.java Verify.java
|
||||||
|
* @run main AddExactLConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AddExactLConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantLongTest.verify(new Verify.AddExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant addExact
|
||||||
|
* @compile AddExactLNonConstantTest.java Verify.java
|
||||||
|
* @run main AddExactLNonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AddExactLNonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantLongTest.verify(new Verify.AddExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test decrementExact
|
||||||
|
* @compile DecExactITest.java Verify.java
|
||||||
|
* @run main DecExactITest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DecExactITest {
|
||||||
|
public static int[] values = {1, 1, 1, 1};
|
||||||
|
public static int[] minvalues = {Integer.MIN_VALUE, Integer.MIN_VALUE};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.DecExactI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.UnaryMethod method) {
|
||||||
|
for (int i = 0; i < 20000; ++i) {
|
||||||
|
Verify.verifyUnary(Integer.MIN_VALUE, method);
|
||||||
|
Verify.verifyUnary(minvalues[0], method);
|
||||||
|
Verify.verifyUnary(Integer.MIN_VALUE - values[2], method);
|
||||||
|
Verify.verifyUnary(0, method);
|
||||||
|
Verify.verifyUnary(values[2], method);
|
||||||
|
Verify.verifyUnary(Integer.MAX_VALUE, method);
|
||||||
|
Verify.verifyUnary(Integer.MIN_VALUE - values[0] + values[3], method);
|
||||||
|
Verify.verifyUnary(Integer.MIN_VALUE + 1 - values[0], method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test decrementExact
|
||||||
|
* @compile DecExactITest.java Verify.java
|
||||||
|
* @run main DecExactITest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DecExactLTest {
|
||||||
|
public static long[] values = {1, 1, 1, 1};
|
||||||
|
public static long[] minvalues = {Long.MIN_VALUE, Long.MIN_VALUE};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.DecExactL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.UnaryLongMethod method) {
|
||||||
|
for (int i = 0; i < 20000; ++i) {
|
||||||
|
Verify.verifyUnary(Long.MIN_VALUE, method);
|
||||||
|
Verify.verifyUnary(minvalues[0], method);
|
||||||
|
Verify.verifyUnary(Long.MIN_VALUE - values[2], method);
|
||||||
|
Verify.verifyUnary(0, method);
|
||||||
|
Verify.verifyUnary(values[2], method);
|
||||||
|
Verify.verifyUnary(Long.MAX_VALUE, method);
|
||||||
|
Verify.verifyUnary(Long.MIN_VALUE - values[0] + values[3], method);
|
||||||
|
Verify.verifyUnary(Long.MIN_VALUE + 1 - values[0], method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test incrementExact
|
||||||
|
* @compile IncExactITest.java Verify.java
|
||||||
|
* @run main IncExactITest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class IncExactITest {
|
||||||
|
public static int[] values = {1, 1, 1, 1};
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.IncExactI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.UnaryMethod method) {
|
||||||
|
for (int i = 0; i < 20000; ++i) {
|
||||||
|
Verify.verifyUnary(Integer.MIN_VALUE, method);
|
||||||
|
Verify.verifyUnary(Integer.MAX_VALUE - 1, method);
|
||||||
|
Verify.verifyUnary(0, method);
|
||||||
|
Verify.verifyUnary(values[1], method);
|
||||||
|
Verify.verifyUnary(Integer.MAX_VALUE, method);
|
||||||
|
Verify.verifyUnary(Integer.MAX_VALUE - values[0] + values[3], method);
|
||||||
|
Verify.verifyUnary(Integer.MAX_VALUE - 1 + values[0], method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,33 +23,28 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8024924
|
* @bug 8026844
|
||||||
* @summary Test non constant addExact
|
* @summary Test incrementExact
|
||||||
* @compile LoadTest.java Verify.java
|
* @compile IncExactLTest.java Verify.java
|
||||||
* @run main LoadTest
|
* @run main IncExactLTest
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
public class IncExactLTest {
|
||||||
|
public static long[] values = {1, 1, 1, 1};
|
||||||
public class LoadTest {
|
|
||||||
public static java.util.Random rnd = new java.util.Random();
|
|
||||||
public static int[] values = new int[256];
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for (int i = 0; i < values.length; ++i) {
|
runTest(new Verify.IncExactL());
|
||||||
values[i] = rnd.nextInt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 50000; ++i) {
|
public static void runTest(Verify.UnaryLongMethod method) {
|
||||||
Verify.verify(values[i & 255], values[i & 255] - i);
|
for (int i = 0; i < 20000; ++i) {
|
||||||
Verify.verify(values[i & 255] + i, values[i & 255] - i);
|
Verify.verifyUnary(Long.MIN_VALUE, method);
|
||||||
Verify.verify(values[i & 255], values[i & 255]);
|
Verify.verifyUnary(Long.MAX_VALUE - 1, method);
|
||||||
if ((i & 1) == 1 && i > 5) {
|
Verify.verifyUnary(0, method);
|
||||||
Verify.verify(values[i & 255] + i, values[i & 255] - i);
|
Verify.verifyUnary(values[1], method);
|
||||||
} else {
|
Verify.verifyUnary(Long.MAX_VALUE, method);
|
||||||
Verify.verify(values[i & 255] - i, values[i & 255] + i);
|
Verify.verifyUnary(Long.MAX_VALUE - values[0] + values[3], method);
|
||||||
}
|
Verify.verifyUnary(Long.MAX_VALUE - 1 + values[0], method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test multiplyExact as condition
|
||||||
|
* @compile MulExactICondTest.java
|
||||||
|
* @run main MulExactICondTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactICondTest {
|
||||||
|
public static int result = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest() {
|
||||||
|
int i = 7;
|
||||||
|
while (java.lang.Math.multiplyExact(i, result) < 89361) {
|
||||||
|
if ((java.lang.Math.multiplyExact(i, i) & 1) == 1) {
|
||||||
|
i += 3;
|
||||||
|
} else if ((i & 5) == 4) {
|
||||||
|
i += 7;
|
||||||
|
} else if ((i & 0xf) == 6) {
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
result += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant multiplyExact
|
||||||
|
* @compile MulExactIConstantTest.java Verify.java
|
||||||
|
* @run main MulExactIConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactIConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantTest.verify(new Verify.MulExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test multiplyExact
|
||||||
|
* @compile MulExactILoadTest.java Verify.java
|
||||||
|
* @run main MulExactILoadTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactILoadTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoadTest.init();
|
||||||
|
Verify.LoadTest.verify(new Verify.MulExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test loop dependent multiplyExact
|
||||||
|
* @compile MulExactILoopDependentTest.java Verify.java
|
||||||
|
* @run main MulExactILoopDependentTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MulExactILoopDependentTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoopDependentTest.verify(new Verify.MulExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant multiplyExact
|
||||||
|
* @compile MulExactINonConstantTest.java Verify.java
|
||||||
|
* @run main MulExactINonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactINonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantTest.verify(new Verify.MulExactI());
|
||||||
|
Verify.LoadTest.verify(new Verify.MulExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test repeating multiplyExact
|
||||||
|
* @compile MulExactIRepeatTest.java Verify.java
|
||||||
|
* @run main MulExactIRepeatTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactIRepeatTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.MulExactI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int nonExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.BinaryMethod method) {
|
||||||
|
java.util.Random rnd = new java.util.Random();
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
int x = Integer.MAX_VALUE - 10;
|
||||||
|
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
|
||||||
|
|
||||||
|
int c = rnd.nextInt() / 10;
|
||||||
|
int d = rnd.nextInt(9);
|
||||||
|
|
||||||
|
int a = catchingExact(x, y, method);
|
||||||
|
|
||||||
|
if (a != 36) {
|
||||||
|
throw new RuntimeException("a != 36 : " + a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int b = nonExact(c, d, method);
|
||||||
|
int n = exact(c, d, method);
|
||||||
|
|
||||||
|
|
||||||
|
if (n != b) {
|
||||||
|
throw new RuntimeException("n != b : " + n + " != " + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int exact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
result += 5;
|
||||||
|
result = method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 6;
|
||||||
|
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 2;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 7;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 3;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 8;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 4;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant mulExact
|
||||||
|
* @compile MulExactLConstantTest.java Verify.java
|
||||||
|
* @run main MulExactLConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactLConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantLongTest.verify(new Verify.MulExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant mulExact
|
||||||
|
* @compile MulExactLNonConstantTest.java Verify.java
|
||||||
|
* @run main MulExactLNonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MulExactLNonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantLongTest.verify(new Verify.MulExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant negExact
|
||||||
|
* @compile NegExactIConstantTest.java Verify.java
|
||||||
|
* @run main NegExactIConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NegExactIConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test negExact
|
||||||
|
* @compile NegExactILoadTest.java Verify.java
|
||||||
|
* @run main NegExactILoadTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NegExactILoadTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoadTest.init();
|
||||||
|
Verify.LoadTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test negExact loop dependent
|
||||||
|
* @compile NegExactILoopDependentTest.java Verify.java
|
||||||
|
* @run main NegExactILoopDependentTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class NegExactILoopDependentTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoopDependentTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant negExact
|
||||||
|
* @compile NegExactINonConstantTest.java Verify.java
|
||||||
|
* @run main NegExactINonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NegExactINonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantTest.verify(new Verify.UnaryToBinary(new Verify.NegExactI()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant negExact
|
||||||
|
* @compile NegExactLConstantTest.java Verify.java
|
||||||
|
* @run main NegExactLConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NegExactLConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantLongTest.verify(new Verify.UnaryToBinaryLong(new Verify.NegExactL()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant negExact
|
||||||
|
* @compile NegExactLNonConstantTest.java Verify.java
|
||||||
|
* @run main NegExactLNonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NegExactLNonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantLongTest.verify(new Verify.UnaryToBinaryLong(new Verify.NegExactL()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @test
|
|
||||||
* @bug 8025657
|
|
||||||
* @summary Test repeating addExact
|
|
||||||
* @compile RepeatTest.java
|
|
||||||
* @run main RepeatTest
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.lang.ArithmeticException;
|
|
||||||
|
|
||||||
public class RepeatTest {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
java.util.Random rnd = new java.util.Random();
|
|
||||||
for (int i = 0; i < 50000; ++i) {
|
|
||||||
int x = Integer.MAX_VALUE - 10;
|
|
||||||
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5); //rnd.nextInt() / 2;
|
|
||||||
|
|
||||||
int c = rnd.nextInt() / 2;
|
|
||||||
int d = rnd.nextInt() / 2;
|
|
||||||
|
|
||||||
int a = addExact(x, y);
|
|
||||||
|
|
||||||
if (a != 36) {
|
|
||||||
throw new RuntimeException("a != 0 : " + a);
|
|
||||||
}
|
|
||||||
|
|
||||||
int b = nonExact(c, d);
|
|
||||||
int n = addExact2(c, d);
|
|
||||||
|
|
||||||
|
|
||||||
if (n != b) {
|
|
||||||
throw new RuntimeException("n != b : " + n + " != " + b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int addExact2(int x, int y) {
|
|
||||||
int result = 0;
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int addExact(int x, int y) {
|
|
||||||
int result = 0;
|
|
||||||
try {
|
|
||||||
result += 5;
|
|
||||||
result = java.lang.Math.addExact(x, y);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
result += 1;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
result += 6;
|
|
||||||
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
result += 2;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
result += 7;
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
result += 3;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
result += 8;
|
|
||||||
result += java.lang.Math.addExact(x, y);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
result += 4;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int nonExact(int x, int y) {
|
|
||||||
int result = x + y;
|
|
||||||
result += x + y;
|
|
||||||
result += x + y;
|
|
||||||
result += x + y;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test subtractExact as condition
|
||||||
|
* @compile SubExactICondTest.java Verify.java
|
||||||
|
* @run main SubExactICondTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactICondTest {
|
||||||
|
public static int result = 0;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
runTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest() {
|
||||||
|
int i = 7;
|
||||||
|
while (java.lang.Math.subtractExact(i, result) > -31361) {
|
||||||
|
if ((java.lang.Math.subtractExact(i, i) & 1) == 1) {
|
||||||
|
i -= 3;
|
||||||
|
} else if ((i & 5) == 4) {
|
||||||
|
i -= 7;
|
||||||
|
} else if ((i & 0xf) == 6) {
|
||||||
|
i -= 2;
|
||||||
|
} else {
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
result += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant subtractExact
|
||||||
|
* @compile SubExactIConstantTest.java Verify.java
|
||||||
|
* @run main SubExactIConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactIConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantTest.verify(new Verify.SubExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant subtractExact
|
||||||
|
* @compile SubExactILoadTest.java Verify.java
|
||||||
|
* @run main SubExactILoadTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactILoadTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoadTest.init();
|
||||||
|
Verify.LoadTest.verify(new Verify.SubExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant subtractExact
|
||||||
|
* @compile SubExactILoopDependentTest.java Verify.java
|
||||||
|
* @run main SubExactILoopDependentTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactILoopDependentTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.LoopDependentTest.verify(new Verify.SubExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant subtractExact
|
||||||
|
* @compile SubExactINonConstantTest.java Verify.java
|
||||||
|
* @run main SubExactINonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactINonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantTest.verify(new Verify.SubExactI());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test repeating subtractExact
|
||||||
|
* @compile SubExactIRepeatTest.java Verify.java
|
||||||
|
* @run main SubExactIRepeatTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.ArithmeticException;
|
||||||
|
|
||||||
|
public class SubExactIRepeatTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
runTest(new Verify.SubExactI());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int nonExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
result += method.unchecked(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runTest(Verify.BinaryMethod method) {
|
||||||
|
java.util.Random rnd = new java.util.Random();
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
int x = Integer.MIN_VALUE + 10;
|
||||||
|
int y = Integer.MAX_VALUE - 10 + rnd.nextInt(5);
|
||||||
|
|
||||||
|
int c = rnd.nextInt() / 2;
|
||||||
|
int d = rnd.nextInt() / 2;
|
||||||
|
|
||||||
|
int a = catchingExact(x, y, method);
|
||||||
|
|
||||||
|
if (a != 36) {
|
||||||
|
throw new RuntimeException("a != 36 : " + a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int b = nonExact(c, d, method);
|
||||||
|
int n = exact(c, d, method);
|
||||||
|
|
||||||
|
|
||||||
|
if (n != b) {
|
||||||
|
throw new RuntimeException("n != b : " + n + " != " + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int exact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int catchingExact(int x, int y, Verify.BinaryMethod method) {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
result += 5;
|
||||||
|
result = method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 6;
|
||||||
|
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 2;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 7;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 3;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result += 8;
|
||||||
|
result += method.checkMethod(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
result += 4;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test constant subtractExact
|
||||||
|
* @compile SubExactLConstantTest.java Verify.java
|
||||||
|
* @run main SubExactLConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactLConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.ConstantLongTest.verify(new Verify.SubExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8026844
|
||||||
|
* @summary Test non constant subtractExact
|
||||||
|
* @compile SubExactLNonConstantTest.java Verify.java
|
||||||
|
* @run main SubExactLNonConstantTest
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubExactLNonConstantTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Verify.NonConstantLongTest.verify(new Verify.SubExactL());
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,43 +26,637 @@ public class Verify {
|
||||||
return (threw ? "threw" : "didn't throw");
|
return (threw ? "threw" : "didn't throw");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void verify(int a, int b) {
|
public static void verifyResult(UnaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int value) {
|
||||||
|
if (exception1 != exception2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
|
||||||
|
}
|
||||||
|
if (result1 != result2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void verifyResult(UnaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long value) {
|
||||||
|
if (exception1 != exception2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
|
||||||
|
}
|
||||||
|
if (result1 != result2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyResult(BinaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int a, int b) {
|
||||||
|
if (exception1 != exception2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
|
||||||
|
}
|
||||||
|
if (result1 != result2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyResult(BinaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long a, long b) {
|
||||||
|
if (exception1 != exception2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
|
||||||
|
}
|
||||||
|
if (result1 != result2) {
|
||||||
|
throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void verifyUnary(int a, UnaryMethod method) {
|
||||||
boolean exception1 = false, exception2 = false;
|
boolean exception1 = false, exception2 = false;
|
||||||
int result1 = 0, result2 = 0;
|
int result1 = 0, result2 = 0;
|
||||||
try {
|
try {
|
||||||
result1 = testIntrinsic(a, b);
|
result1 = method.checkMethod(a);
|
||||||
} catch (ArithmeticException e) {
|
} catch (ArithmeticException e) {
|
||||||
exception1 = true;
|
exception1 = true;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
result2 = testNonIntrinsic(a, b);
|
result2 = method.safeMethod(a);
|
||||||
} catch (ArithmeticException e) {
|
} catch (ArithmeticException e) {
|
||||||
exception2 = true;
|
exception2 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exception1 != exception2) {
|
verifyResult(method, result1, result2, exception1, exception2, a);
|
||||||
throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
|
|
||||||
}
|
}
|
||||||
if (result1 != result2) {
|
|
||||||
throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);
|
public static void verifyUnary(long a, UnaryLongMethod method) {
|
||||||
|
boolean exception1 = false, exception2 = false;
|
||||||
|
long result1 = 0, result2 = 0;
|
||||||
|
try {
|
||||||
|
result1 = method.checkMethod(a);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception1 = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result2 = method.safeMethod(a);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyResult(method, result1, result2, exception1, exception2, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void verifyBinary(int a, int b, BinaryMethod method) {
|
||||||
|
boolean exception1 = false, exception2 = false;
|
||||||
|
int result1 = 0, result2 = 0;
|
||||||
|
try {
|
||||||
|
result1 = method.checkMethod(a, b);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception1 = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result2 = method.safeMethod(a, b);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyResult(method, result1, result2, exception1, exception2, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void verifyBinary(long a, long b, BinaryLongMethod method) {
|
||||||
|
boolean exception1 = false, exception2 = false;
|
||||||
|
long result1 = 0, result2 = 0;
|
||||||
|
try {
|
||||||
|
result1 = method.checkMethod(a, b);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception1 = true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
result2 = method.safeMethod(a, b);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exception2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyResult(method, result1, result2, exception1, exception2, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class LoadTest {
|
||||||
|
public static java.util.Random rnd = new java.util.Random();
|
||||||
|
public static int[] values = new int[256];
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
for (int i = 0; i < values.length; ++i) {
|
||||||
|
values[i] = rnd.nextInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int testIntrinsic(int a, int b) {
|
public static void verify(BinaryMethod method) {
|
||||||
return java.lang.Math.addExact(a, b);
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
Verify.verifyBinary(values[i & 255], values[i & 255] - i, method);
|
||||||
|
Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
|
||||||
|
Verify.verifyBinary(values[i & 255], values[i & 255], method);
|
||||||
|
if ((i & 1) == 1 && i > 5) {
|
||||||
|
Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
|
||||||
|
} else {
|
||||||
|
Verify.verifyBinary(values[i & 255] - i, values[i & 255] + i, method);
|
||||||
|
}
|
||||||
|
Verify.verifyBinary(values[i & 255], values[(i + 1) & 255], method);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int testNonIntrinsic(int a, int b) {
|
public static class NonConstantTest {
|
||||||
return safeAddExact(a, b);
|
public static java.util.Random rnd = new java.util.Random();
|
||||||
|
|
||||||
|
public static void verify(BinaryMethod method) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
|
||||||
|
Verify.verifyBinary(rnd1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1, rnd2 + 1, method);
|
||||||
|
Verify.verifyBinary(rnd1 + 1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1 - 1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1, rnd2 - 1, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied java.lang.Math.addExact to avoid intrinsification
|
public static class NonConstantLongTest {
|
||||||
public static int safeAddExact(int x, int y) {
|
public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 };
|
||||||
|
public static java.util.Random rnd = new java.util.Random();
|
||||||
|
|
||||||
|
public static void verify(BinaryLongMethod method) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
long rnd1 = rnd.nextLong(), rnd2 = rnd.nextLong();
|
||||||
|
Verify.verifyBinary(rnd1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1, rnd2 + 1, method);
|
||||||
|
Verify.verifyBinary(rnd1 + 1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1 - 1, rnd2, method);
|
||||||
|
Verify.verifyBinary(rnd1, rnd2 - 1, method);
|
||||||
|
Verify.verifyBinary(rnd1 + Long.MAX_VALUE - rnd2, rnd2 + 1, method);
|
||||||
|
Verify.verifyBinary(values[0], values[2], method);
|
||||||
|
Verify.verifyBinary(values[1], values[2], method);
|
||||||
|
Verify.verifyBinary(values[3], 74L, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LoopDependentTest {
|
||||||
|
public static java.util.Random rnd = new java.util.Random();
|
||||||
|
|
||||||
|
public static void verify(BinaryMethod method) {
|
||||||
|
int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
|
||||||
|
runTest(rnd1, rnd2, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runTest(int rnd1, int rnd2, BinaryMethod method) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
Verify.verifyBinary(rnd1 + i, rnd2 + i, method);
|
||||||
|
Verify.verifyBinary(rnd1 + i, rnd2 + (i & 0xff), method);
|
||||||
|
Verify.verifyBinary(rnd1 - i, rnd2 - (i & 0xff), method);
|
||||||
|
Verify.verifyBinary(rnd1 + i + 1, rnd2 + i + 2, method);
|
||||||
|
Verify.verifyBinary(rnd1 + i * 2, rnd2 + i, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConstantTest {
|
||||||
|
public static void verify(BinaryMethod method) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
Verify.verifyBinary(5, 7, method);
|
||||||
|
Verify.verifyBinary(Integer.MAX_VALUE, 1, method);
|
||||||
|
Verify.verifyBinary(Integer.MIN_VALUE, -1, method);
|
||||||
|
Verify.verifyBinary(Integer.MAX_VALUE, -1, method);
|
||||||
|
Verify.verifyBinary(Integer.MIN_VALUE, 1, method);
|
||||||
|
Verify.verifyBinary(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2, method);
|
||||||
|
Verify.verifyBinary(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3, method);
|
||||||
|
Verify.verifyBinary(Integer.MAX_VALUE, Integer.MIN_VALUE, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ConstantLongTest {
|
||||||
|
public static void verify(BinaryLongMethod method) {
|
||||||
|
for (int i = 0; i < 50000; ++i) {
|
||||||
|
Verify.verifyBinary(5, 7, method);
|
||||||
|
Verify.verifyBinary(Long.MAX_VALUE, 1, method);
|
||||||
|
Verify.verifyBinary(Long.MIN_VALUE, -1, method);
|
||||||
|
Verify.verifyBinary(Long.MAX_VALUE, -1, method);
|
||||||
|
Verify.verifyBinary(Long.MIN_VALUE, 1, method);
|
||||||
|
Verify.verifyBinary(Long.MAX_VALUE / 2, Long.MAX_VALUE / 2, method);
|
||||||
|
Verify.verifyBinary(Long.MAX_VALUE / 2, (Long.MAX_VALUE / 2) + 3, method);
|
||||||
|
Verify.verifyBinary(Long.MAX_VALUE, Long.MIN_VALUE, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface BinaryMethod {
|
||||||
|
int safeMethod(int a, int b);
|
||||||
|
int checkMethod(int a, int b);
|
||||||
|
int unchecked(int a, int b);
|
||||||
|
String name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface UnaryMethod {
|
||||||
|
int safeMethod(int value);
|
||||||
|
int checkMethod(int value);
|
||||||
|
int unchecked(int value);
|
||||||
|
String name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface BinaryLongMethod {
|
||||||
|
long safeMethod(long a, long b);
|
||||||
|
long checkMethod(long a, long b);
|
||||||
|
long unchecked(long a, long b);
|
||||||
|
String name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface UnaryLongMethod {
|
||||||
|
long safeMethod(long value);
|
||||||
|
long checkMethod(long value);
|
||||||
|
long unchecked(long value);
|
||||||
|
String name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UnaryToBinary implements BinaryMethod {
|
||||||
|
private final UnaryMethod method;
|
||||||
|
public UnaryToBinary(UnaryMethod method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int a, int b) {
|
||||||
|
return method.safeMethod(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int a, int b) {
|
||||||
|
return method.checkMethod(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int a, int b) {
|
||||||
|
return method.unchecked(a);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return method.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UnaryToBinaryLong implements BinaryLongMethod {
|
||||||
|
private final UnaryLongMethod method;
|
||||||
|
public UnaryToBinaryLong(UnaryLongMethod method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long a, long b) {
|
||||||
|
return method.safeMethod(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long a, long b) {
|
||||||
|
return method.checkMethod(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long a, long b) {
|
||||||
|
return method.unchecked(a);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return method.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class AddExactI implements BinaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int x, int y) {
|
||||||
int r = x + y;
|
int r = x + y;
|
||||||
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
|
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
|
||||||
if (((x ^ r) & (y ^ r)) < 0) {
|
if (((x ^ r) & (y ^ r)) < 0) {
|
||||||
throw new ArithmeticException("integer overflow");
|
throw new ArithmeticException("integer overflow");
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int a, int b) {
|
||||||
|
return Math.addExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "addExact";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int a, int b) {
|
||||||
|
return a + b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AddExactL implements BinaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long x, long y) {
|
||||||
|
long r = x + y;
|
||||||
|
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
|
||||||
|
if (((x ^ r) & (y ^ r)) < 0) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long a, long b) {
|
||||||
|
return Math.addExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "addExactLong";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long a, long b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MulExactI implements BinaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int x, int y) {
|
||||||
|
long r = (long)x * (long)y;
|
||||||
|
if ((int)r != r) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
return (int)r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int a, int b) {
|
||||||
|
return Math.multiplyExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int a, int b) {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "multiplyExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MulExactL implements BinaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long x, long y) {
|
||||||
|
long r = x * y;
|
||||||
|
long ax = Math.abs(x);
|
||||||
|
long ay = Math.abs(y);
|
||||||
|
if (((ax | ay) >>> 31 != 0)) {
|
||||||
|
// Some bits greater than 2^31 that might cause overflow
|
||||||
|
// Check the result using the divide operator
|
||||||
|
// and check for the special case of Long.MIN_VALUE * -1
|
||||||
|
if (((y != 0) && (r / y != x)) ||
|
||||||
|
(x == Long.MIN_VALUE && y == -1)) {
|
||||||
|
throw new ArithmeticException("long overflow");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long a, long b) {
|
||||||
|
return Math.multiplyExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long a, long b) {
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "multiplyExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NegExactL implements UnaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long a) {
|
||||||
|
if (a == Long.MIN_VALUE) {
|
||||||
|
throw new ArithmeticException("long overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return -a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long value) {
|
||||||
|
return Math.negateExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long value) {
|
||||||
|
return -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "negateExactLong";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NegExactI implements UnaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int a) {
|
||||||
|
if (a == Integer.MIN_VALUE) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return -a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int value) {
|
||||||
|
return Math.negateExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int value) {
|
||||||
|
return -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "negateExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SubExactI implements BinaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int x, int y) {
|
||||||
|
int r = x - y;
|
||||||
|
// HD 2-12 Overflow iff the arguments have different signs and
|
||||||
|
// the sign of the result is different than the sign of x
|
||||||
|
if (((x ^ y) & (x ^ r)) < 0) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int a, int b) {
|
||||||
|
return Math.subtractExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int a, int b) {
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "subtractExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SubExactL implements BinaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long x, long y) {
|
||||||
|
long r = x - y;
|
||||||
|
// HD 2-12 Overflow iff the arguments have different signs and
|
||||||
|
// the sign of the result is different than the sign of x
|
||||||
|
if (((x ^ y) & (x ^ r)) < 0) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long a, long b) {
|
||||||
|
return Math.subtractExact(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long a, long b) {
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "subtractExactLong";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class IncExactL implements UnaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long a) {
|
||||||
|
if (a == Long.MAX_VALUE) {
|
||||||
|
throw new ArithmeticException("long overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return a + 1L;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long value) {
|
||||||
|
return Math.incrementExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long value) {
|
||||||
|
return value + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "incrementExactLong";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class IncExactI implements UnaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int a) {
|
||||||
|
if (a == Integer.MAX_VALUE) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return a + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int value) {
|
||||||
|
return Math.incrementExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int value) {
|
||||||
|
return value + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "incrementExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DecExactL implements UnaryLongMethod {
|
||||||
|
@Override
|
||||||
|
public long safeMethod(long a) {
|
||||||
|
if (a == Long.MIN_VALUE) {
|
||||||
|
throw new ArithmeticException("long overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return a - 1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long checkMethod(long value) {
|
||||||
|
return Math.decrementExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long unchecked(long value) {
|
||||||
|
return value - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "decExactLong";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DecExactI implements UnaryMethod {
|
||||||
|
@Override
|
||||||
|
public int safeMethod(int a) {
|
||||||
|
if (a == Integer.MIN_VALUE) {
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
return a - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int checkMethod(int value) {
|
||||||
|
return Math.decrementExact(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int unchecked(int value) {
|
||||||
|
return value - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "decrementExact";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue