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(" ");