src/share/vm/c1/c1_LIR.cpp
Print this page
rev 3227 : 7133857: exp() and pow() should use the x87 ISA on x86
Summary: use x87 instructions to implement exp() and pow() in interpreter/c1/c2.
Reviewed-by:
*** 622,636 ****
case lir_shr:
case lir_ushr:
{
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
if (op2->_info) do_info(op2->_info);
if (op2->_opr1->is_valid()) do_input(op2->_opr1);
if (op2->_opr2->is_valid()) do_input(op2->_opr2);
! if (op2->_tmp->is_valid()) do_temp(op2->_tmp);
if (op2->_result->is_valid()) do_output(op2->_result);
break;
}
--- 622,638 ----
case lir_shr:
case lir_ushr:
{
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
+ assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+ op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
if (op2->_info) do_info(op2->_info);
if (op2->_opr1->is_valid()) do_input(op2->_opr1);
if (op2->_opr2->is_valid()) do_input(op2->_opr2);
! if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1);
if (op2->_result->is_valid()) do_output(op2->_result);
break;
}
*** 639,649 ****
case lir_cmove:
{
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
! assert(op2->_info == NULL && op2->_tmp->is_illegal(), "not used");
assert(op2->_opr1->is_valid() && op2->_opr2->is_valid() && op2->_result->is_valid(), "used");
do_input(op2->_opr1);
do_input(op2->_opr2);
do_temp(op2->_opr2);
--- 641,652 ----
case lir_cmove:
{
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
! assert(op2->_info == NULL && op2->_tmp1->is_illegal() && op2->_tmp2->is_illegal() &&
! op2->_tmp3->is_illegal() && op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
assert(op2->_opr1->is_valid() && op2->_opr2->is_valid() && op2->_result->is_valid(), "used");
do_input(op2->_opr1);
do_input(op2->_opr2);
do_temp(op2->_opr2);
*** 663,676 ****
assert(op2->_info == NULL, "not used");
assert(op2->_opr1->is_valid(), "used");
assert(op2->_opr2->is_valid(), "used");
assert(op2->_result->is_valid(), "used");
do_input(op2->_opr1); do_temp(op2->_opr1);
do_input(op2->_opr2); do_temp(op2->_opr2);
! if (op2->_tmp->is_valid()) do_temp(op2->_tmp);
do_output(op2->_result);
break;
}
--- 666,681 ----
assert(op2->_info == NULL, "not used");
assert(op2->_opr1->is_valid(), "used");
assert(op2->_opr2->is_valid(), "used");
assert(op2->_result->is_valid(), "used");
+ assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+ op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
do_input(op2->_opr1); do_temp(op2->_opr1);
do_input(op2->_opr2); do_temp(op2->_opr2);
! if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1);
do_output(op2->_result);
break;
}
*** 680,689 ****
--- 685,696 ----
if (op2->_info) do_info(op2->_info);
if (op2->_opr1->is_valid()) do_temp(op2->_opr1);
if (op2->_opr2->is_valid()) do_input(op2->_opr2); // exception object is input parameter
assert(op2->_result->is_illegal(), "no result");
+ assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+ op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
break;
}
case lir_unwind: {
*** 700,728 ****
case lir_tan:
case lir_sin:
case lir_cos:
case lir_log:
! case lir_log10: {
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
// On x86 tan/sin/cos need two temporary fpu stack slots and
// log/log10 need one so handle opr2 and tmp as temp inputs.
// Register input operand as temp to guarantee that it doesn't
// overlap with the input.
assert(op2->_info == NULL, "not used");
assert(op2->_opr1->is_valid(), "used");
do_input(op2->_opr1); do_temp(op2->_opr1);
if (op2->_opr2->is_valid()) do_temp(op2->_opr2);
! if (op2->_tmp->is_valid()) do_temp(op2->_tmp);
if (op2->_result->is_valid()) do_output(op2->_result);
break;
}
// LIR_Op3
case lir_idiv:
case lir_irem: {
assert(op->as_Op3() != NULL, "must be");
--- 707,767 ----
case lir_tan:
case lir_sin:
case lir_cos:
case lir_log:
! case lir_log10:
! case lir_exp: {
assert(op->as_Op2() != NULL, "must be");
LIR_Op2* op2 = (LIR_Op2*)op;
// On x86 tan/sin/cos need two temporary fpu stack slots and
// log/log10 need one so handle opr2 and tmp as temp inputs.
// Register input operand as temp to guarantee that it doesn't
// overlap with the input.
assert(op2->_info == NULL, "not used");
+ assert(op2->_tmp5->is_illegal(), "not used");
+ assert(op2->_tmp2->is_valid() == (op->code() == lir_exp), "not used");
+ assert(op2->_tmp3->is_valid() == (op->code() == lir_exp), "not used");
+ assert(op2->_tmp4->is_valid() == (op->code() == lir_exp), "not used");
assert(op2->_opr1->is_valid(), "used");
do_input(op2->_opr1); do_temp(op2->_opr1);
if (op2->_opr2->is_valid()) do_temp(op2->_opr2);
! if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1);
! if (op2->_tmp2->is_valid()) do_temp(op2->_tmp2);
! if (op2->_tmp3->is_valid()) do_temp(op2->_tmp3);
! if (op2->_tmp4->is_valid()) do_temp(op2->_tmp4);
if (op2->_result->is_valid()) do_output(op2->_result);
break;
}
+ case lir_pow: {
+ assert(op->as_Op2() != NULL, "must be");
+ LIR_Op2* op2 = (LIR_Op2*)op;
+
+ // On x86 pow needs two temporary fpu stack slots: tmp1 and
+ // tmp2. Register input operands as temps to guarantee that it
+ // doesn't overlap with the temporary slots.
+ assert(op2->_info == NULL, "not used");
+ assert(op2->_opr1->is_valid() && op2->_opr2->is_valid(), "used");
+ assert(op2->_tmp1->is_valid() && op2->_tmp2->is_valid() && op2->_tmp3->is_valid()
+ && op2->_tmp4->is_valid() && op2->_tmp5->is_valid(), "used");
+ assert(op2->_result->is_valid(), "used");
+
+ do_input(op2->_opr1); do_temp(op2->_opr1);
+ do_input(op2->_opr2); do_temp(op2->_opr2);
+ do_temp(op2->_tmp1);
+ do_temp(op2->_tmp2);
+ do_temp(op2->_tmp3);
+ do_temp(op2->_tmp4);
+ do_temp(op2->_tmp5);
+ do_output(op2->_result);
+
+ break;
+ }
// LIR_Op3
case lir_idiv:
case lir_irem: {
assert(op->as_Op3() != NULL, "must be");
*** 1668,1677 ****
--- 1707,1718 ----
case lir_sin: s = "sin"; break;
case lir_cos: s = "cos"; break;
case lir_tan: s = "tan"; break;
case lir_log: s = "log"; break;
case lir_log10: s = "log10"; break;
+ case lir_exp: s = "exp"; break;
+ case lir_pow: s = "pow"; break;
case lir_logic_and: s = "logic_and"; break;
case lir_logic_or: s = "logic_or"; break;
case lir_logic_xor: s = "logic_xor"; break;
case lir_shl: s = "shift_left"; break;
case lir_shr: s = "shift_right"; break;
*** 1890,1900 ****
if (code() == lir_cmove) {
print_condition(out, condition()); out->print(" ");
}
in_opr1()->print(out); out->print(" ");
in_opr2()->print(out); out->print(" ");
! if (tmp_opr()->is_valid()) { tmp_opr()->print(out); out->print(" "); }
result_opr()->print(out);
}
void LIR_OpAllocArray::print_instr(outputStream* out) const {
klass()->print(out); out->print(" ");
--- 1931,1945 ----
if (code() == lir_cmove) {
print_condition(out, condition()); out->print(" ");
}
in_opr1()->print(out); out->print(" ");
in_opr2()->print(out); out->print(" ");
! if (tmp1_opr()->is_valid()) { tmp1_opr()->print(out); out->print(" "); }
! if (tmp2_opr()->is_valid()) { tmp2_opr()->print(out); out->print(" "); }
! if (tmp3_opr()->is_valid()) { tmp3_opr()->print(out); out->print(" "); }
! if (tmp4_opr()->is_valid()) { tmp4_opr()->print(out); out->print(" "); }
! if (tmp5_opr()->is_valid()) { tmp5_opr()->print(out); out->print(" "); }
result_opr()->print(out);
}
void LIR_OpAllocArray::print_instr(outputStream* out) const {
klass()->print(out); out->print(" ");