mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-03 04:30:06 +00:00
8266950: Remove vestigial support for non-strict floating-point execution
Co-authored-by: Vladimir Ivanov <vlivanov@openjdk.org> Reviewed-by: vlivanov, kvn
This commit is contained in:
parent
8624cb53cd
commit
cb7128b58e
@ -1801,9 +1801,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ fadds (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
|
||||
case lir_sub: __ fsubs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ fmuls (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ fdivs (dest->as_float_reg(), left->as_float_reg(), right->as_float_reg()); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -1814,9 +1812,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ faddd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
|
||||
case lir_sub: __ fsubd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ fmuld (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ fdivd (dest->as_double_reg(), left->as_double_reg(), right->as_double_reg()); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
|
||||
@ -422,12 +422,8 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
left.load_item();
|
||||
|
||||
LIR_Opr reg = rlock(x);
|
||||
LIR_Opr tmp = LIR_OprFact::illegalOpr;
|
||||
if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) {
|
||||
tmp = new_register(T_DOUBLE);
|
||||
}
|
||||
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp());
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result());
|
||||
|
||||
set_result(x, round_item(reg));
|
||||
}
|
||||
|
||||
@ -1628,9 +1628,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ add_float(res, lreg, rreg); break;
|
||||
case lir_sub: __ sub_float(res, lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mul_float(res, lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ div_float(res, lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -1643,9 +1641,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ add_double(res, lreg, rreg); break;
|
||||
case lir_sub: __ sub_double(res, lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mul_double(res, lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ div_double(res, lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2021, 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
|
||||
@ -516,7 +516,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
left.load_item();
|
||||
right.load_item();
|
||||
rlock_result(x);
|
||||
arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result(), x->is_strictfp());
|
||||
arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result());
|
||||
return;
|
||||
}
|
||||
#endif // __SOFTFP__
|
||||
|
||||
@ -1627,10 +1627,8 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ fadds(res, lreg, rreg); break;
|
||||
case lir_sub: __ fsubs(res, lreg, rreg); break;
|
||||
case lir_mul: // fall through
|
||||
case lir_mul_strictfp: __ fmuls(res, lreg, rreg); break;
|
||||
case lir_div: // fall through
|
||||
case lir_div_strictfp: __ fdivs(res, lreg, rreg); break;
|
||||
case lir_mul: __ fmuls(res, lreg, rreg); break;
|
||||
case lir_div: __ fdivs(res, lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
@ -1640,10 +1638,8 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ fadd(res, lreg, rreg); break;
|
||||
case lir_sub: __ fsub(res, lreg, rreg); break;
|
||||
case lir_mul: // fall through
|
||||
case lir_mul_strictfp: __ fmul(res, lreg, rreg); break;
|
||||
case lir_div: // fall through
|
||||
case lir_div_strictfp: __ fdiv(res, lreg, rreg); break;
|
||||
case lir_mul: __ fmul(res, lreg, rreg); break;
|
||||
case lir_div: __ fdiv(res, lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +394,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
left.load_item();
|
||||
right.load_item();
|
||||
rlock_result(x);
|
||||
arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result(), x->is_strictfp());
|
||||
arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result());
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -1610,9 +1610,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ z_aebr(lreg, rreg); break;
|
||||
case lir_sub: __ z_sebr(lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ z_meebr(lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ z_debr(lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -1620,9 +1618,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ z_aeb(lreg, raddr); break;
|
||||
case lir_sub: __ z_seb(lreg, raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ z_meeb(lreg, raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ z_deb(lreg, raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -1645,9 +1641,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ z_adbr(lreg, rreg); break;
|
||||
case lir_sub: __ z_sdbr(lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ z_mdbr(lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ z_ddbr(lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -1655,9 +1649,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ z_adb(lreg, raddr); break;
|
||||
case lir_sub: __ z_sdb(lreg, raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ z_mdb(lreg, raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ z_ddb(lreg, raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -331,7 +331,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
} else {
|
||||
LIR_Opr reg = rlock(x);
|
||||
LIR_Opr tmp = LIR_OprFact::illegalOpr;
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), tmp);
|
||||
set_result(x, reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2204,9 +2204,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ addss(lreg, rreg); break;
|
||||
case lir_sub: __ subss(lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mulss(lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ divss(lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -2223,9 +2221,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ addss(lreg, raddr); break;
|
||||
case lir_sub: __ subss(lreg, raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mulss(lreg, raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ divss(lreg, raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -2240,9 +2236,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ addsd(lreg, rreg); break;
|
||||
case lir_sub: __ subsd(lreg, rreg); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mulsd(lreg, rreg); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ divsd(lreg, rreg); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -2259,9 +2253,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ addsd(lreg, raddr); break;
|
||||
case lir_sub: __ subsd(lreg, raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ mulsd(lreg, raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ divsd(lreg, raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -2293,9 +2285,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ fadd_s(raddr); break;
|
||||
case lir_sub: __ fsub_s(raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ fmul_s(raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ fdiv_s(raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
@ -2304,9 +2294,9 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
} else if (left->is_double_fpu()) {
|
||||
assert(dest->is_double_fpu(), "fpu stack allocation required");
|
||||
|
||||
if (code == lir_mul_strictfp || code == lir_div_strictfp) {
|
||||
if (code == lir_mul || code == lir_div) {
|
||||
// Double values require special handling for strictfp mul/div on x86
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias1()));
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias1()));
|
||||
__ fmulp(left->fpu_regnrLo() + 1);
|
||||
}
|
||||
|
||||
@ -2330,17 +2320,15 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
|
||||
switch (code) {
|
||||
case lir_add: __ fadd_d(raddr); break;
|
||||
case lir_sub: __ fsub_d(raddr); break;
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul: __ fmul_d(raddr); break;
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div: __ fdiv_d(raddr); break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
if (code == lir_mul_strictfp || code == lir_div_strictfp) {
|
||||
if (code == lir_mul || code == lir_div) {
|
||||
// Double values require special handling for strictfp mul/div on x86
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias2()));
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias2()));
|
||||
__ fmulp(dest->fpu_regnrLo() + 1);
|
||||
}
|
||||
#endif // !_LP64
|
||||
@ -2415,14 +2403,12 @@ void LIR_Assembler::arith_fpu_implementation(LIR_Code code, int left_index, int
|
||||
}
|
||||
break;
|
||||
|
||||
case lir_mul_strictfp: // fall through
|
||||
case lir_mul:
|
||||
if (pop_fpu_stack) __ fmulp(non_tos_index);
|
||||
else if (dest_is_tos) __ fmul (non_tos_index);
|
||||
else __ fmula(non_tos_index);
|
||||
break;
|
||||
|
||||
case lir_div_strictfp: // fall through
|
||||
case lir_div:
|
||||
if (left_is_tos) {
|
||||
if (pop_fpu_stack) __ fdivrp(non_tos_index);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2021, 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
|
||||
@ -393,7 +393,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
}
|
||||
LIR_Opr reg = rlock(x);
|
||||
LIR_Opr tmp = LIR_OprFact::illegalOpr;
|
||||
if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) {
|
||||
if (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv) {
|
||||
tmp = new_register(T_DOUBLE);
|
||||
}
|
||||
|
||||
@ -429,7 +429,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
__ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());
|
||||
__ move(result_reg, result);
|
||||
} else {
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), tmp);
|
||||
set_result(x, round_item(reg));
|
||||
}
|
||||
#else
|
||||
@ -449,7 +449,7 @@ void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
|
||||
__ move(fpu0, reg);
|
||||
|
||||
} else {
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
|
||||
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), tmp);
|
||||
}
|
||||
set_result(x, round_item(reg));
|
||||
#endif // _LP64
|
||||
|
||||
@ -678,17 +678,17 @@ void FpuStackAllocator::handle_op2(LIR_Op2* op2) {
|
||||
break;
|
||||
}
|
||||
|
||||
case lir_mul_strictfp:
|
||||
case lir_div_strictfp: {
|
||||
assert(op2->tmp1_opr()->is_fpu_register(), "strict operations need temporary fpu stack slot");
|
||||
insert_free_if_dead(op2->tmp1_opr());
|
||||
assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
|
||||
case lir_mul:
|
||||
case lir_div: {
|
||||
if (res->is_double_fpu()) {
|
||||
assert(op2->tmp1_opr()->is_fpu_register(), "strict operations need temporary fpu stack slot");
|
||||
insert_free_if_dead(op2->tmp1_opr());
|
||||
assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
|
||||
}
|
||||
// fall-through: continue with the normal handling of lir_mul and lir_div
|
||||
}
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
case lir_mul:
|
||||
case lir_div: {
|
||||
case lir_sub: {
|
||||
assert(left->is_fpu_register(), "must be");
|
||||
assert(res->is_fpu_register(), "must be");
|
||||
assert(left->is_equal(res), "must be");
|
||||
|
||||
@ -3867,13 +3867,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// Note: the following two constants are 80-bit values
|
||||
// layout is critical for correct loading by FPU.
|
||||
// Bias for strict fp multiply/divide
|
||||
StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
|
||||
StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
|
||||
StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
|
||||
StubRoutines::x86::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
|
||||
StubRoutines::x86::_fpu_subnormal_bias1[1]= 0x80000000;
|
||||
StubRoutines::x86::_fpu_subnormal_bias1[2]= 0x03ff;
|
||||
// Un-Bias for strict fp multiply/divide
|
||||
StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
|
||||
StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
|
||||
StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
|
||||
StubRoutines::x86::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
|
||||
StubRoutines::x86::_fpu_subnormal_bias2[1]= 0x80000000;
|
||||
StubRoutines::x86::_fpu_subnormal_bias2[2]= 0x7bff;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@ -6721,16 +6721,6 @@ address generate_avx_ghash_processBlocks() {
|
||||
StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
|
||||
// Round to nearest, 64-bit mode, exceptions masked
|
||||
StubRoutines::_mxcsr_std = 0x1F80;
|
||||
// Note: the following two constants are 80-bit values
|
||||
// layout is critical for correct loading by FPU.
|
||||
// Bias for strict fp multiply/divide
|
||||
StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
|
||||
StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
|
||||
StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
|
||||
// Un-Bias for strict fp multiply/divide
|
||||
StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
|
||||
StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
|
||||
StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
|
||||
}
|
||||
|
||||
// Initialization
|
||||
|
||||
@ -97,9 +97,15 @@ class x86 {
|
||||
private:
|
||||
static address _verify_fpu_cntrl_wrd_entry;
|
||||
|
||||
static jint _fpu_subnormal_bias1[3];
|
||||
static jint _fpu_subnormal_bias2[3];
|
||||
|
||||
public:
|
||||
static address verify_fpu_cntrl_wrd_entry() { return _verify_fpu_cntrl_wrd_entry; }
|
||||
|
||||
static address addr_fpu_subnormal_bias1() { return (address)&_fpu_subnormal_bias1; }
|
||||
static address addr_fpu_subnormal_bias2() { return (address)&_fpu_subnormal_bias2; }
|
||||
|
||||
#endif // !LP64
|
||||
|
||||
private:
|
||||
|
||||
@ -34,3 +34,6 @@
|
||||
address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = NULL;
|
||||
address StubRoutines::x86::_method_entry_barrier = NULL;
|
||||
|
||||
jint StubRoutines::x86::_fpu_subnormal_bias1[3] = { 0, 0, 0 };
|
||||
jint StubRoutines::x86::_fpu_subnormal_bias2[3] = { 0, 0, 0 };
|
||||
|
||||
|
||||
@ -1633,41 +1633,21 @@ void TemplateTable::dop2(Operation op) {
|
||||
case add: __ fadd_d (at_rsp()); break;
|
||||
case sub: __ fsubr_d(at_rsp()); break;
|
||||
case mul: {
|
||||
Label L_strict;
|
||||
Label L_join;
|
||||
const Address access_flags (rcx, Method::access_flags_offset());
|
||||
__ get_method(rcx);
|
||||
__ movl(rcx, access_flags);
|
||||
__ testl(rcx, JVM_ACC_STRICT);
|
||||
__ jccb(Assembler::notZero, L_strict);
|
||||
__ fmul_d (at_rsp());
|
||||
__ jmpb(L_join);
|
||||
__ bind(L_strict);
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias1()));
|
||||
// strict semantics
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias1()));
|
||||
__ fmulp();
|
||||
__ fmul_d (at_rsp());
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias2()));
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias2()));
|
||||
__ fmulp();
|
||||
__ bind(L_join);
|
||||
break;
|
||||
}
|
||||
case div: {
|
||||
Label L_strict;
|
||||
Label L_join;
|
||||
const Address access_flags (rcx, Method::access_flags_offset());
|
||||
__ get_method(rcx);
|
||||
__ movl(rcx, access_flags);
|
||||
__ testl(rcx, JVM_ACC_STRICT);
|
||||
__ jccb(Assembler::notZero, L_strict);
|
||||
__ fdivr_d(at_rsp());
|
||||
__ jmp(L_join);
|
||||
__ bind(L_strict);
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias1()));
|
||||
// strict semantics
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias1()));
|
||||
__ fmul_d (at_rsp());
|
||||
__ fdivrp();
|
||||
__ fld_x(ExternalAddress(StubRoutines::addr_fpu_subnormal_bias2()));
|
||||
__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias2()));
|
||||
__ fmulp();
|
||||
__ bind(L_join);
|
||||
break;
|
||||
}
|
||||
case rem: __ fld_d (at_rsp()); __ fremr(rax); break;
|
||||
|
||||
@ -2335,7 +2335,7 @@ encode %{
|
||||
enc_class strictfp_bias1( regDPR dst ) %{
|
||||
emit_opcode( cbuf, 0xDB ); // FLD m80real
|
||||
emit_opcode( cbuf, 0x2D );
|
||||
emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() );
|
||||
emit_d32( cbuf, (int)StubRoutines::x86::addr_fpu_subnormal_bias1() );
|
||||
emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
|
||||
emit_opcode( cbuf, 0xC8+$dst$$reg );
|
||||
%}
|
||||
@ -2343,7 +2343,7 @@ encode %{
|
||||
enc_class strictfp_bias2( regDPR dst ) %{
|
||||
emit_opcode( cbuf, 0xDB ); // FLD m80real
|
||||
emit_opcode( cbuf, 0x2D );
|
||||
emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() );
|
||||
emit_d32( cbuf, (int)StubRoutines::x86::addr_fpu_subnormal_bias2() );
|
||||
emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
|
||||
emit_opcode( cbuf, 0xC8+$dst$$reg );
|
||||
%}
|
||||
@ -9793,15 +9793,15 @@ instruct mulDPR_reg(regDPR dst, regDPR src) %{
|
||||
// rescale product by 2^(15360)
|
||||
//
|
||||
instruct strictfp_mulDPR_reg(regDPR1 dst, regnotDPR1 src) %{
|
||||
predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
|
||||
predicate( UseSSE<=1 && Compile::current()->has_method() );
|
||||
match(Set dst (MulD dst src));
|
||||
ins_cost(1); // Select this instruction for all strict FP double multiplies
|
||||
ins_cost(1); // Select this instruction for all FP double multiplies
|
||||
|
||||
format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t"
|
||||
format %{ "FLD StubRoutines::x86::_fpu_subnormal_bias1\n\t"
|
||||
"DMULp $dst,ST\n\t"
|
||||
"FLD $src\n\t"
|
||||
"DMULp $dst,ST\n\t"
|
||||
"FLD StubRoutines::_fpu_subnormal_bias2\n\t"
|
||||
"FLD StubRoutines::x86::_fpu_subnormal_bias2\n\t"
|
||||
"DMULp $dst,ST\n\t" %}
|
||||
opcode(0xDE, 0x1); /* DE C8+i or DE /1*/
|
||||
ins_encode( strictfp_bias1(dst),
|
||||
@ -9912,14 +9912,14 @@ instruct divDPR_reg(regDPR dst, regDPR src) %{
|
||||
instruct strictfp_divDPR_reg(regDPR1 dst, regnotDPR1 src) %{
|
||||
predicate (UseSSE<=1);
|
||||
match(Set dst (DivD dst src));
|
||||
predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() );
|
||||
predicate( UseSSE<=1 && Compile::current()->has_method() );
|
||||
ins_cost(01);
|
||||
|
||||
format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t"
|
||||
format %{ "FLD StubRoutines::x86::_fpu_subnormal_bias1\n\t"
|
||||
"DMULp $dst,ST\n\t"
|
||||
"FLD $src\n\t"
|
||||
"FDIVp $dst,ST\n\t"
|
||||
"FLD StubRoutines::_fpu_subnormal_bias2\n\t"
|
||||
"FLD StubRoutines::x86::_fpu_subnormal_bias2\n\t"
|
||||
"DMULp $dst,ST\n\t" %}
|
||||
opcode(0xDE, 0x7); /* DE F8+i or DE /7*/
|
||||
ins_encode( strictfp_bias1(dst),
|
||||
@ -9929,20 +9929,6 @@ instruct strictfp_divDPR_reg(regDPR1 dst, regnotDPR1 src) %{
|
||||
ins_pipe( fpu_reg_reg );
|
||||
%}
|
||||
|
||||
instruct divDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{
|
||||
predicate( UseSSE<=1 && !(Compile::current()->has_method() && Compile::current()->method()->is_strict()) );
|
||||
match(Set dst (RoundDouble (DivD src1 src2)));
|
||||
|
||||
format %{ "FLD $src1\n\t"
|
||||
"FDIV ST,$src2\n\t"
|
||||
"FSTP_D $dst\t# D-round" %}
|
||||
opcode(0xD8, 0x6); /* D8 F0+i or D8 /6 */
|
||||
ins_encode( Push_Reg_DPR(src1),
|
||||
OpcP, RegOpc(src2), Pop_Mem_DPR(dst) );
|
||||
ins_pipe( fpu_mem_reg_reg );
|
||||
%}
|
||||
|
||||
|
||||
instruct modDPR_reg(regDPR dst, regDPR src, eAXRegI rax, eFlagsReg cr) %{
|
||||
predicate(UseSSE<=1);
|
||||
match(Set dst (ModD dst src));
|
||||
|
||||
@ -1123,14 +1123,10 @@ void GraphBuilder::stack_op(Bytecodes::Code code) {
|
||||
void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueStack* state_before) {
|
||||
Value y = pop(type);
|
||||
Value x = pop(type);
|
||||
// NOTE: strictfp can be queried from current method since we don't
|
||||
// inline methods with differing strictfp bits
|
||||
Value res = new ArithmeticOp(code, x, y, method()->is_strict(), state_before);
|
||||
Value res = new ArithmeticOp(code, x, y, state_before);
|
||||
// Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level
|
||||
res = append(res);
|
||||
if (method()->is_strict()) {
|
||||
res = round_fp(res);
|
||||
}
|
||||
res = round_fp(res);
|
||||
push(type, res);
|
||||
}
|
||||
|
||||
@ -2125,11 +2121,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
append_split(result);
|
||||
|
||||
if (result_type != voidType) {
|
||||
if (method()->is_strict()) {
|
||||
push(result_type, round_fp(result));
|
||||
} else {
|
||||
push(result_type, result);
|
||||
}
|
||||
push(result_type, round_fp(result));
|
||||
}
|
||||
if (profile_return() && result_type->is_object_kind()) {
|
||||
profile_return_type(result, target);
|
||||
@ -3764,19 +3756,6 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ign
|
||||
// Proper inlining of methods with jsrs requires a little more work.
|
||||
if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
|
||||
|
||||
if (strict_fp_requires_explicit_rounding &&
|
||||
method()->is_strict() != callee->is_strict()) {
|
||||
#ifdef IA32
|
||||
// If explicit rounding is required, do not inline strict code into non-strict code (or the reverse).
|
||||
// When SSE2 is present, no special handling is needed.
|
||||
if (UseSSE < 2) {
|
||||
INLINE_BAILOUT("caller and callee have different strict fp requirements");
|
||||
}
|
||||
#else
|
||||
Unimplemented();
|
||||
#endif // IA32
|
||||
}
|
||||
|
||||
if (is_profiling() && !callee->ensure_method_data()) {
|
||||
INLINE_BAILOUT("mdo allocation failed");
|
||||
}
|
||||
|
||||
@ -332,7 +332,6 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values*
|
||||
{
|
||||
set_flag(TargetIsLoadedFlag, target->is_loaded());
|
||||
set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method());
|
||||
set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict());
|
||||
|
||||
assert(args != NULL, "args must exist");
|
||||
#ifdef ASSERT
|
||||
|
||||
@ -358,13 +358,11 @@ class Instruction: public CompilationResourceObj {
|
||||
IsEliminatedFlag,
|
||||
IsSafepointFlag,
|
||||
IsStaticFlag,
|
||||
IsStrictfpFlag,
|
||||
NeedsStoreCheckFlag,
|
||||
NeedsWriteBarrierFlag,
|
||||
PreservesStateFlag,
|
||||
TargetIsFinalFlag,
|
||||
TargetIsLoadedFlag,
|
||||
TargetIsStrictfpFlag,
|
||||
UnorderedIsTrueFlag,
|
||||
NeedsPatchingFlag,
|
||||
ThrowIncompatibleClassChangeErrorFlag,
|
||||
@ -1059,16 +1057,12 @@ BASE(Op2, Instruction)
|
||||
LEAF(ArithmeticOp, Op2)
|
||||
public:
|
||||
// creation
|
||||
ArithmeticOp(Bytecodes::Code op, Value x, Value y, bool is_strictfp, ValueStack* state_before)
|
||||
ArithmeticOp(Bytecodes::Code op, Value x, Value y, ValueStack* state_before)
|
||||
: Op2(x->type()->meet(y->type()), op, x, y, state_before)
|
||||
{
|
||||
set_flag(IsStrictfpFlag, is_strictfp);
|
||||
if (can_trap()) pin();
|
||||
}
|
||||
|
||||
// accessors
|
||||
bool is_strictfp() const { return check_flag(IsStrictfpFlag); }
|
||||
|
||||
// generic
|
||||
virtual bool is_commutative() const;
|
||||
virtual bool can_trap() const;
|
||||
@ -1266,8 +1260,6 @@ LEAF(Invoke, StateSplit)
|
||||
// Returns false if target is not loaded
|
||||
bool target_is_final() const { return check_flag(TargetIsFinalFlag); }
|
||||
bool target_is_loaded() const { return check_flag(TargetIsLoadedFlag); }
|
||||
// Returns false if target is not loaded
|
||||
bool target_is_strictfp() const { return check_flag(TargetIsStrictfpFlag); }
|
||||
|
||||
// JSR 292 support
|
||||
bool is_invokedynamic() const { return code() == Bytecodes::_invokedynamic; }
|
||||
|
||||
@ -212,9 +212,7 @@ void LIR_Op2::verify() const {
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
case lir_mul:
|
||||
case lir_mul_strictfp:
|
||||
case lir_div:
|
||||
case lir_div_strictfp:
|
||||
case lir_rem:
|
||||
case lir_logic_and:
|
||||
case lir_logic_or:
|
||||
@ -564,8 +562,6 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
case lir_cmp_fd2i:
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
case lir_mul:
|
||||
case lir_div:
|
||||
case lir_rem:
|
||||
case lir_sqrt:
|
||||
case lir_abs:
|
||||
@ -623,8 +619,8 @@ void LIR_OpVisitState::visit(LIR_Op* op) {
|
||||
// vspecial handling for strict operations: register input operands
|
||||
// as temp to guarantee that they do not overlap with other
|
||||
// registers
|
||||
case lir_mul_strictfp:
|
||||
case lir_div_strictfp:
|
||||
case lir_mul:
|
||||
case lir_div:
|
||||
{
|
||||
assert(op->as_Op2() != NULL, "must be");
|
||||
LIR_Op2* op2 = (LIR_Op2*)op;
|
||||
@ -1675,9 +1671,7 @@ const char * LIR_Op::name() const {
|
||||
case lir_add: s = "add"; break;
|
||||
case lir_sub: s = "sub"; break;
|
||||
case lir_mul: s = "mul"; break;
|
||||
case lir_mul_strictfp: s = "mul_strictfp"; break;
|
||||
case lir_div: s = "div"; break;
|
||||
case lir_div_strictfp: s = "div_strictfp"; break;
|
||||
case lir_rem: s = "rem"; break;
|
||||
case lir_abs: s = "abs"; break;
|
||||
case lir_neg: s = "neg"; break;
|
||||
|
||||
@ -931,9 +931,7 @@ enum LIR_Code {
|
||||
, lir_add
|
||||
, lir_sub
|
||||
, lir_mul
|
||||
, lir_mul_strictfp
|
||||
, lir_div
|
||||
, lir_div_strictfp
|
||||
, lir_rem
|
||||
, lir_sqrt
|
||||
, lir_abs
|
||||
@ -2156,9 +2154,9 @@ class LIR_List: public CompilationResourceObj {
|
||||
void add (LIR_Opr left, LIR_Opr right, LIR_Opr res) { append(new LIR_Op2(lir_add, left, right, res)); }
|
||||
void sub (LIR_Opr left, LIR_Opr right, LIR_Opr res, CodeEmitInfo* info = NULL) { append(new LIR_Op2(lir_sub, left, right, res, info)); }
|
||||
void mul (LIR_Opr left, LIR_Opr right, LIR_Opr res) { append(new LIR_Op2(lir_mul, left, right, res)); }
|
||||
void mul_strictfp (LIR_Opr left, LIR_Opr right, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_mul_strictfp, left, right, res, tmp)); }
|
||||
void mul (LIR_Opr left, LIR_Opr right, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_mul, left, right, res, tmp)); }
|
||||
void div (LIR_Opr left, LIR_Opr right, LIR_Opr res, CodeEmitInfo* info = NULL) { append(new LIR_Op2(lir_div, left, right, res, info)); }
|
||||
void div_strictfp (LIR_Opr left, LIR_Opr right, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_div_strictfp, left, right, res, tmp)); }
|
||||
void div (LIR_Opr left, LIR_Opr right, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_div, left, right, res, tmp)); }
|
||||
void rem (LIR_Opr left, LIR_Opr right, LIR_Opr res, CodeEmitInfo* info = NULL) { append(new LIR_Op2(lir_rem, left, right, res, info)); }
|
||||
|
||||
void volatile_load_mem_reg(LIR_Address* address, LIR_Opr dst, CodeEmitInfo* info, LIR_PatchCode patch_code = lir_patch_none);
|
||||
|
||||
@ -707,9 +707,7 @@ void LIR_Assembler::emit_op2(LIR_Op2* op) {
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
case lir_mul:
|
||||
case lir_mul_strictfp:
|
||||
case lir_div:
|
||||
case lir_div_strictfp:
|
||||
case lir_rem:
|
||||
assert(op->fpu_pop_count() < 2, "");
|
||||
arith_op(
|
||||
|
||||
@ -501,7 +501,7 @@ void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result
|
||||
|
||||
|
||||
|
||||
void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp_op, CodeEmitInfo* info) {
|
||||
void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp_op, CodeEmitInfo* info) {
|
||||
LIR_Opr result_op = result;
|
||||
LIR_Opr left_op = left;
|
||||
LIR_Opr right_op = right;
|
||||
@ -520,15 +520,7 @@ void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr l
|
||||
case Bytecodes::_fmul:
|
||||
case Bytecodes::_lmul: __ mul(left_op, right_op, result_op); break;
|
||||
|
||||
case Bytecodes::_dmul:
|
||||
{
|
||||
if (is_strictfp) {
|
||||
__ mul_strictfp(left_op, right_op, result_op, tmp_op); break;
|
||||
} else {
|
||||
__ mul(left_op, right_op, result_op); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Bytecodes::_dmul: __ mul(left_op, right_op, result_op, tmp_op); break;
|
||||
|
||||
case Bytecodes::_imul:
|
||||
{
|
||||
@ -559,15 +551,7 @@ void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr l
|
||||
case Bytecodes::_fdiv: __ div (left_op, right_op, result_op); break;
|
||||
// ldiv and lrem are implemented with a direct runtime call
|
||||
|
||||
case Bytecodes::_ddiv:
|
||||
{
|
||||
if (is_strictfp) {
|
||||
__ div_strictfp (left_op, right_op, result_op, tmp_op); break;
|
||||
} else {
|
||||
__ div (left_op, right_op, result_op); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Bytecodes::_ddiv: __ div(left_op, right_op, result_op, tmp_op); break;
|
||||
|
||||
case Bytecodes::_drem:
|
||||
case Bytecodes::_frem: __ rem (left_op, right_op, result_op); break;
|
||||
@ -578,17 +562,17 @@ void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr l
|
||||
|
||||
|
||||
void LIRGenerator::arithmetic_op_int(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp) {
|
||||
arithmetic_op(code, result, left, right, false, tmp);
|
||||
arithmetic_op(code, result, left, right, tmp);
|
||||
}
|
||||
|
||||
|
||||
void LIRGenerator::arithmetic_op_long(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
|
||||
arithmetic_op(code, result, left, right, false, LIR_OprFact::illegalOpr, info);
|
||||
arithmetic_op(code, result, left, right, LIR_OprFact::illegalOpr, info);
|
||||
}
|
||||
|
||||
|
||||
void LIRGenerator::arithmetic_op_fpu(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp) {
|
||||
arithmetic_op(code, result, left, right, is_strictfp, tmp);
|
||||
void LIRGenerator::arithmetic_op_fpu(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp) {
|
||||
arithmetic_op(code, result, left, right, tmp);
|
||||
}
|
||||
|
||||
|
||||
@ -2994,17 +2978,6 @@ void LIRGenerator::do_Invoke(Invoke* x) {
|
||||
__ move(FrameMap::method_handle_invoke_SP_save_opr(), FrameMap::stack_pointer());
|
||||
}
|
||||
|
||||
if (x->type()->is_float() || x->type()->is_double()) {
|
||||
// Force rounding of results from non-strictfp when in strictfp
|
||||
// scope (or when we don't know the strictness of the callee, to
|
||||
// be safe.)
|
||||
if (method()->is_strict()) {
|
||||
if (!x->target_is_loaded() || !x->target_is_strictfp()) {
|
||||
result_register = round_item(result_register);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result_register->is_valid()) {
|
||||
LIR_Opr result = rlock_result(x);
|
||||
__ move(result_register, result);
|
||||
|
||||
@ -338,8 +338,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||
void increment_counter(address counter, BasicType type, int step = 1);
|
||||
void increment_counter(LIR_Address* addr, int step = 1);
|
||||
|
||||
// is_strictfp is only needed for mul and div (and only generates different code on i486)
|
||||
void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp, CodeEmitInfo* info = NULL);
|
||||
void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp, CodeEmitInfo* info = NULL);
|
||||
// machine dependent. returns true if it emitted code for the multiply
|
||||
bool strength_reduce_multiply(LIR_Opr left, jint constant, LIR_Opr result, LIR_Opr tmp);
|
||||
|
||||
@ -354,7 +353,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
|
||||
|
||||
void arithmetic_op_int (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp);
|
||||
void arithmetic_op_long (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info = NULL);
|
||||
void arithmetic_op_fpu (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp = LIR_OprFact::illegalOpr);
|
||||
void arithmetic_op_fpu (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp = LIR_OprFact::illegalOpr);
|
||||
|
||||
void shift_op (Bytecodes::Code code, LIR_Opr dst_reg, LIR_Opr value, LIR_Opr count, LIR_Opr tmp);
|
||||
|
||||
|
||||
@ -6714,9 +6714,7 @@ void LinearScanStatistic::collect(LinearScan* allocator) {
|
||||
case lir_add:
|
||||
case lir_sub:
|
||||
case lir_mul:
|
||||
case lir_mul_strictfp:
|
||||
case lir_div:
|
||||
case lir_div_strictfp:
|
||||
case lir_rem:
|
||||
case lir_sqrt:
|
||||
case lir_abs:
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, 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
|
||||
@ -530,7 +530,7 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
// Calculate lower bound
|
||||
Instruction *lower_compare = index_instruction;
|
||||
if (min_constant) {
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, false, NULL);
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, min_constant, lower_compare, NULL);
|
||||
insert_position = insert_position->insert_after_same_bci(ao);
|
||||
lower_compare = ao;
|
||||
}
|
||||
@ -538,7 +538,7 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
// Calculate upper bound
|
||||
Instruction *upper_compare = index_instruction;
|
||||
if (max_constant) {
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, false, NULL);
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, max_constant, upper_compare, NULL);
|
||||
insert_position = insert_position->insert_after_same_bci(ao);
|
||||
upper_compare = ao;
|
||||
}
|
||||
@ -660,7 +660,7 @@ Instruction* RangeCheckEliminator::predicate_cmp_with_const(Instruction* instr,
|
||||
Instruction* RangeCheckEliminator::predicate_add(Instruction* left, int left_const, Instruction::Condition cond, Instruction* right, ValueStack* state, Instruction *insert_position, int bci) {
|
||||
Constant *constant = new Constant(new IntConstant(left_const));
|
||||
insert_position = insert_after(insert_position, constant, bci);
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, false, NULL);
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, left, NULL);
|
||||
insert_position = insert_position->insert_after_same_bci(ao);
|
||||
return predicate(ao, cond, right, state, insert_position);
|
||||
}
|
||||
@ -1549,7 +1549,7 @@ void RangeCheckEliminator::Bound::add_assertion(Instruction *instruction, Instru
|
||||
}
|
||||
// Add operation only if necessary
|
||||
if (constant) {
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, false, NULL);
|
||||
ArithmeticOp *ao = new ArithmeticOp(Bytecodes::_iadd, constant, op, NULL);
|
||||
NOT_PRODUCT(ao->set_printable_bci(position->printable_bci()));
|
||||
result = result->insert_after(ao);
|
||||
compare_with = ao;
|
||||
@ -1587,4 +1587,3 @@ void RangeCheckEliminator::add_assertions(Bound *bound, Instruction *instruction
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, 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
|
||||
@ -86,9 +86,6 @@ void ciFlags::print_member_flags(outputStream* st) {
|
||||
if (is_abstract()) {
|
||||
st->print(",abstract");
|
||||
}
|
||||
if (is_strict()) {
|
||||
st->print(",strict");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -58,7 +58,6 @@ public:
|
||||
bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; }
|
||||
bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; }
|
||||
bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; }
|
||||
bool is_strict () const { return (_flags & JVM_ACC_STRICT ) != 0; }
|
||||
bool is_stable () const { return (_flags & JVM_ACC_FIELD_STABLE ) != 0; }
|
||||
// In case the current object represents a field, return true if
|
||||
// the field is modified outside of instance initializer methods
|
||||
|
||||
@ -342,7 +342,6 @@ class ciMethod : public ciMetadata {
|
||||
bool is_native () const { return flags().is_native(); }
|
||||
bool is_interface () const { return flags().is_interface(); }
|
||||
bool is_abstract () const { return flags().is_abstract(); }
|
||||
bool is_strict () const { return flags().is_strict(); }
|
||||
|
||||
// Other flags
|
||||
bool is_final_method() const { return is_final() || holder()->is_final(); }
|
||||
|
||||
@ -581,7 +581,6 @@ public:
|
||||
bool is_synchronized() const { return access_flags().is_synchronized();}
|
||||
bool is_native() const { return access_flags().is_native(); }
|
||||
bool is_abstract() const { return access_flags().is_abstract(); }
|
||||
bool is_strict() const { return access_flags().is_strict(); }
|
||||
bool is_synthetic() const { return access_flags().is_synthetic(); }
|
||||
|
||||
// returns true if contains only return operation
|
||||
|
||||
@ -559,10 +559,6 @@ const Type *AddFNode::add_ring( const Type *t0, const Type *t1 ) const {
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
Node *AddFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
|
||||
return AddNode::Ideal(phase, can_reshape); // commutative and associative transforms
|
||||
}
|
||||
|
||||
// Floating point additions are not associative because of boundary conditions (infinity)
|
||||
return commute(phase, this) ? this : NULL;
|
||||
}
|
||||
@ -594,10 +590,6 @@ const Type *AddDNode::add_ring( const Type *t0, const Type *t1 ) const {
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
Node *AddDNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
if( IdealizedNumerics && !phase->C->method()->is_strict() ) {
|
||||
return AddNode::Ideal(phase, can_reshape); // commutative and associative transforms
|
||||
}
|
||||
|
||||
// Floating point additions are not associative because of boundary conditions (infinity)
|
||||
return commute(phase, this) ? this : NULL;
|
||||
}
|
||||
|
||||
@ -127,10 +127,6 @@
|
||||
notproduct(bool, PrintIdealNodeCount, false, \
|
||||
"Print liveness counts of ideal nodes") \
|
||||
\
|
||||
develop(bool, IdealizedNumerics, false, \
|
||||
"Check performance difference allowing FP " \
|
||||
"associativity and commutativity...") \
|
||||
\
|
||||
product_pd(bool, IdealizeClearArrayNode, DIAGNOSTIC, \
|
||||
"Replace ClearArrayNode by subgraph of basic operations.") \
|
||||
\
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
@ -777,18 +777,15 @@ const Type* DivDNode::Value(PhaseGVN* phase) const {
|
||||
if( t2 == TypeD::ONE )
|
||||
return t1;
|
||||
|
||||
#if defined(IA32)
|
||||
if (!phase->C->method()->is_strict())
|
||||
// Can't trust native compilers to properly fold strict double
|
||||
// division with round-to-zero on this platform.
|
||||
// IA32 would only execute this for non-strict FP, which is never the
|
||||
// case now.
|
||||
#if ! defined(IA32)
|
||||
// If divisor is a constant and not zero, divide them numbers
|
||||
if( t1->base() == Type::DoubleCon &&
|
||||
t2->base() == Type::DoubleCon &&
|
||||
t2->getd() != 0.0 ) // could be negative zero
|
||||
return TypeD::make( t1->getd()/t2->getd() );
|
||||
#endif
|
||||
{
|
||||
// If divisor is a constant and not zero, divide them numbers
|
||||
if( t1->base() == Type::DoubleCon &&
|
||||
t2->base() == Type::DoubleCon &&
|
||||
t2->getd() != 0.0 ) // could be negative zero
|
||||
return TypeD::make( t1->getd()/t2->getd() );
|
||||
}
|
||||
|
||||
// If the dividend is a constant zero
|
||||
// Note: if t1 and t2 are zero then result is NaN (JVMS page 213)
|
||||
|
||||
@ -114,8 +114,6 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
|
||||
// Special case the handling of certain common, profitable library
|
||||
// methods. If these methods are replaced with specialized code,
|
||||
// then we return it as the inlined version of the call.
|
||||
// We do this before the strict f.p. check below because the
|
||||
// intrinsics handle strict f.p. correctly.
|
||||
CallGenerator* cg_intrinsic = NULL;
|
||||
if (allow_inline && allow_intrinsics) {
|
||||
CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
|
||||
@ -152,12 +150,6 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
|
||||
return cg;
|
||||
}
|
||||
|
||||
// If explicit rounding is required, do not inline strict into non-strict code (or the reverse).
|
||||
if (Matcher::strict_fp_requires_explicit_rounding &&
|
||||
caller->is_strict() != callee->is_strict()) {
|
||||
allow_inline = false;
|
||||
}
|
||||
|
||||
// Attempt to inline...
|
||||
if (allow_inline) {
|
||||
// The profile data is only partly attributable to this caller,
|
||||
@ -680,9 +672,6 @@ void Parse::do_call() {
|
||||
// %%% assert(receiver == cast, "should already have cast the receiver");
|
||||
}
|
||||
|
||||
// Round double result after a call from strict to non-strict code
|
||||
round_double_result(cg->method());
|
||||
|
||||
ciType* rtype = cg->method()->return_type();
|
||||
ciType* ctype = declared_signature->return_type();
|
||||
|
||||
|
||||
@ -2319,23 +2319,6 @@ void GraphKit::record_profiled_return_for_speculation() {
|
||||
}
|
||||
}
|
||||
|
||||
void GraphKit::round_double_result(ciMethod* dest_method) {
|
||||
if (Matcher::strict_fp_requires_explicit_rounding) {
|
||||
// If a strict caller invokes a non-strict callee, round a double result.
|
||||
// A non-strict method may return a double value which has an extended exponent,
|
||||
// but this must not be visible in a caller which is strict.
|
||||
BasicType result_type = dest_method->return_type()->basic_type();
|
||||
assert(method() != NULL, "must have caller context");
|
||||
if( result_type == T_DOUBLE && method()->is_strict() && !dest_method->is_strict() ) {
|
||||
// Destination method's return value is on top of stack
|
||||
// dstore_rounding() does gvn.transform
|
||||
Node *result = pop_pair();
|
||||
result = dstore_rounding(result);
|
||||
push_pair(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphKit::round_double_arguments(ciMethod* dest_method) {
|
||||
if (Matcher::strict_fp_requires_explicit_rounding) {
|
||||
// (Note: TypeFunc::make has a cache that makes this fast.)
|
||||
@ -2358,7 +2341,7 @@ void GraphKit::round_double_arguments(ciMethod* dest_method) {
|
||||
Node* GraphKit::precision_rounding(Node* n) {
|
||||
if (Matcher::strict_fp_requires_explicit_rounding) {
|
||||
#ifdef IA32
|
||||
if (_method->flags().is_strict() && UseSSE == 0) {
|
||||
if (UseSSE == 0) {
|
||||
return _gvn.transform(new RoundFloatNode(0, n));
|
||||
}
|
||||
#else
|
||||
@ -2372,7 +2355,7 @@ Node* GraphKit::precision_rounding(Node* n) {
|
||||
Node* GraphKit::dprecision_rounding(Node *n) {
|
||||
if (Matcher::strict_fp_requires_explicit_rounding) {
|
||||
#ifdef IA32
|
||||
if (_method->flags().is_strict() && UseSSE < 2) {
|
||||
if (UseSSE < 2) {
|
||||
return _gvn.transform(new RoundDoubleNode(0, n));
|
||||
}
|
||||
#else
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2021, 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
|
||||
@ -777,7 +777,6 @@ class GraphKit : public Phase {
|
||||
public:
|
||||
// Helper function to round double arguments before a call
|
||||
void round_double_arguments(ciMethod* dest_method);
|
||||
void round_double_result(ciMethod* dest_method);
|
||||
|
||||
// rounding for strict float precision conformance
|
||||
Node* precision_rounding(Node* n);
|
||||
|
||||
@ -189,7 +189,7 @@ const Type* MulNode::Value(PhaseGVN* phase) const {
|
||||
#if defined(IA32)
|
||||
// Can't trust native compilers to properly fold strict double
|
||||
// multiplication with round-to-zero on this platform.
|
||||
if (op == Op_MulD && phase->C->method()->is_strict()) {
|
||||
if (op == Op_MulD) {
|
||||
return TypeD::DOUBLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -464,13 +464,6 @@ Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// return new (phase->C, 3) AddFNode(in(1), phase->makecon( TypeF::make(-t2->getf()) ) );
|
||||
}
|
||||
|
||||
// Not associative because of boundary conditions (infinity)
|
||||
if (IdealizedNumerics && !phase->C->method()->is_strict() &&
|
||||
in(2)->is_Add() && in(1) == in(2)->in(1)) {
|
||||
// Convert "x - (x+y)" into "-y"
|
||||
return new SubFNode(phase->makecon(TypeF::ZERO), in(2)->in(2));
|
||||
}
|
||||
|
||||
// Cannot replace 0.0-X with -X because a 'fsub' bytecode computes
|
||||
// 0.0-0.0 as +0.0, while a 'fneg' bytecode computes -0.0.
|
||||
//if( phase->type(in(1)) == TypeF::ZERO )
|
||||
@ -506,13 +499,6 @@ Node *SubDNode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
// return new (phase->C, 3) AddDNode(in(1), phase->makecon( TypeD::make(-t2->getd()) ) );
|
||||
}
|
||||
|
||||
// Not associative because of boundary conditions (infinity)
|
||||
if (IdealizedNumerics && !phase->C->method()->is_strict() &&
|
||||
in(2)->is_Add() && in(1) == in(2)->in(1)) {
|
||||
// Convert "x - (x+y)" into "-y"
|
||||
return new SubDNode(phase->makecon(TypeD::ZERO), in(2)->in(2));
|
||||
}
|
||||
|
||||
// Cannot replace 0.0-X with -X because a 'dsub' bytecode computes
|
||||
// 0.0-0.0 as +0.0, while a 'dneg' bytecode computes -0.0.
|
||||
//if( phase->type(in(1)) == TypeD::ZERO )
|
||||
|
||||
@ -79,8 +79,6 @@ jint StubRoutines::_fpu_cntrl_wrd_std = 0;
|
||||
jint StubRoutines::_fpu_cntrl_wrd_24 = 0;
|
||||
jint StubRoutines::_fpu_cntrl_wrd_trunc = 0;
|
||||
jint StubRoutines::_mxcsr_std = 0;
|
||||
jint StubRoutines::_fpu_subnormal_bias1[3] = { 0, 0, 0 };
|
||||
jint StubRoutines::_fpu_subnormal_bias2[3] = { 0, 0, 0 };
|
||||
|
||||
// Compiled code entry points default values
|
||||
// The default functions don't have separate disjoint versions.
|
||||
|
||||
@ -157,8 +157,6 @@ class StubRoutines: AllStatic {
|
||||
static jint _fpu_cntrl_wrd_24;
|
||||
static jint _fpu_cntrl_wrd_trunc;
|
||||
static jint _mxcsr_std;
|
||||
static jint _fpu_subnormal_bias1[3];
|
||||
static jint _fpu_subnormal_bias2[3];
|
||||
|
||||
static BufferBlob* _code1; // code buffer for initial routines
|
||||
static BufferBlob* _code2; // code buffer for all other routines
|
||||
@ -329,8 +327,6 @@ class StubRoutines: AllStatic {
|
||||
static address addr_fpu_cntrl_wrd_24() { return (address)&_fpu_cntrl_wrd_24; }
|
||||
static address addr_fpu_cntrl_wrd_trunc() { return (address)&_fpu_cntrl_wrd_trunc; }
|
||||
static address addr_mxcsr_std() { return (address)&_mxcsr_std; }
|
||||
static address addr_fpu_subnormal_bias1() { return (address)&_fpu_subnormal_bias1; }
|
||||
static address addr_fpu_subnormal_bias2() { return (address)&_fpu_subnormal_bias2; }
|
||||
|
||||
|
||||
static address select_arraycopy_function(BasicType t, bool aligned, bool disjoint, const char* &name, bool dest_uninitialized);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, 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
|
||||
@ -62,7 +62,6 @@ void AccessFlags::print_on(outputStream* st) const {
|
||||
if (is_native ()) st->print("native " );
|
||||
if (is_interface ()) st->print("interface " );
|
||||
if (is_abstract ()) st->print("abstract " );
|
||||
if (is_strict ()) st->print("strict " );
|
||||
if (is_synthetic ()) st->print("synthetic " );
|
||||
if (is_old ()) st->print("{old} " );
|
||||
if (is_obsolete ()) st->print("{obsolete} " );
|
||||
|
||||
@ -123,7 +123,6 @@ class AccessFlags {
|
||||
bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; }
|
||||
bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; }
|
||||
bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; }
|
||||
bool is_strict () const { return (_flags & JVM_ACC_STRICT ) != 0; }
|
||||
|
||||
// Attribute flags
|
||||
bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user