src/cpu/x86/vm/c1_LinearScan_x86.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:

*** 688,699 **** break; } case lir_mul_strictfp: case lir_div_strictfp: { ! assert(op2->tmp_opr()->is_fpu_register(), "strict operations need temporary fpu stack slot"); ! insert_free_if_dead(op2->tmp_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: --- 688,699 ---- 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"); // fall-through: continue with the normal handling of lir_mul and lir_div } case lir_add: case lir_sub:
*** 785,804 **** break; } case lir_log: case lir_log10: { ! // log and log10 needs one temporary fpu stack slot, so there is ontemporary ! // registers stored in temp of the operation. ! // the stack allocator must guarantee that the stack slots are really free, ! // otherwise there might be a stack overflow. assert(right->is_illegal(), "must be"); assert(left->is_fpu_register(), "must be"); assert(res->is_fpu_register(), "must be"); ! assert(op2->tmp_opr()->is_fpu_register(), "must be"); ! insert_free_if_dead(op2->tmp_opr()); insert_free_if_dead(res, left); insert_exchange(left); do_rename(left, res); new_left = to_fpu_stack_top(res); --- 785,805 ---- break; } case lir_log: case lir_log10: { ! // log and log10 need one temporary fpu stack slot, so ! // there is one temporary registers stored in temp of the ! // operation. the stack allocator must guarantee that the stack ! // slots are really free, otherwise there might be a stack ! // overflow. assert(right->is_illegal(), "must be"); assert(left->is_fpu_register(), "must be"); assert(res->is_fpu_register(), "must be"); ! assert(op2->tmp1_opr()->is_fpu_register(), "must be"); ! insert_free_if_dead(op2->tmp1_opr()); insert_free_if_dead(res, left); insert_exchange(left); do_rename(left, res); new_left = to_fpu_stack_top(res);
*** 810,833 **** } case lir_tan: case lir_sin: ! case lir_cos: { ! // sin and cos need two temporary fpu stack slots, so there are two temporary // registers (stored in right and temp of the operation). // the stack allocator must guarantee that the stack slots are really free, // otherwise there might be a stack overflow. assert(left->is_fpu_register(), "must be"); assert(res->is_fpu_register(), "must be"); // assert(left->is_last_use(), "old value gets destroyed"); assert(right->is_fpu_register(), "right is used as the first temporary register"); ! assert(op2->tmp_opr()->is_fpu_register(), "temp is used as the second temporary register"); ! assert(fpu_num(left) != fpu_num(right) && fpu_num(right) != fpu_num(op2->tmp_opr()) && fpu_num(op2->tmp_opr()) != fpu_num(res), "need distinct temp registers"); insert_free_if_dead(right); ! insert_free_if_dead(op2->tmp_opr()); insert_free_if_dead(res, left); insert_exchange(left); do_rename(left, res); --- 811,835 ---- } case lir_tan: case lir_sin: ! case lir_cos: ! case lir_exp: { ! // sin, cos and exp need two temporary fpu stack slots, so there are two temporary // registers (stored in right and temp of the operation). // the stack allocator must guarantee that the stack slots are really free, // otherwise there might be a stack overflow. assert(left->is_fpu_register(), "must be"); assert(res->is_fpu_register(), "must be"); // assert(left->is_last_use(), "old value gets destroyed"); assert(right->is_fpu_register(), "right is used as the first temporary register"); ! assert(op2->tmp1_opr()->is_fpu_register(), "temp is used as the second temporary register"); ! assert(fpu_num(left) != fpu_num(right) && fpu_num(right) != fpu_num(op2->tmp1_opr()) && fpu_num(op2->tmp1_opr()) != fpu_num(res), "need distinct temp registers"); insert_free_if_dead(right); ! insert_free_if_dead(op2->tmp1_opr()); insert_free_if_dead(res, left); insert_exchange(left); do_rename(left, res);
*** 837,846 **** --- 839,895 ---- op2->set_fpu_stack_size(sim()->stack_size()); assert(sim()->stack_size() <= 6, "at least two stack slots must be free"); break; } + case lir_pow: { + // pow needs two temporary fpu stack slots, so there are two temporary + // registers (stored in tmp1 and tmp2 of the operation). + // the stack allocator must guarantee that the stack slots are really free, + // otherwise there might be a stack overflow. + assert(left->is_fpu_register(), "must be"); + assert(right->is_fpu_register(), "must be"); + assert(res->is_fpu_register(), "must be"); + + assert(op2->tmp1_opr()->is_fpu_register(), "tmp1 is the first temporary register"); + assert(op2->tmp2_opr()->is_fpu_register(), "tmp2 is the second temporary register"); + assert(fpu_num(left) != fpu_num(right) && fpu_num(left) != fpu_num(op2->tmp1_opr()) && fpu_num(left) != fpu_num(op2->tmp2_opr()) && fpu_num(left) != fpu_num(res), "need distinct temp registers"); + assert(fpu_num(right) != fpu_num(op2->tmp1_opr()) && fpu_num(right) != fpu_num(op2->tmp2_opr()) && fpu_num(right) != fpu_num(res), "need distinct temp registers"); + assert(fpu_num(op2->tmp1_opr()) != fpu_num(op2->tmp2_opr()) && fpu_num(op2->tmp1_opr()) != fpu_num(res), "need distinct temp registers"); + assert(fpu_num(op2->tmp2_opr()) != fpu_num(res), "need distinct temp registers"); + + insert_free_if_dead(op2->tmp1_opr()); + insert_free_if_dead(op2->tmp2_opr()); + + // Must bring both operands to top of stack with following operand ordering: + // * fpu stack before pow: ... right left + // * fpu stack after pow: ... left + + insert_free_if_dead(res, right); + + if (tos_offset(right) != 1) { + insert_exchange(right); + insert_exchange(1); + } + insert_exchange(left); + assert(tos_offset(right) == 1, "check"); + assert(tos_offset(left) == 0, "check"); + + new_left = to_fpu_stack_top(left); + new_right = to_fpu_stack(right); + + op2->set_fpu_stack_size(sim()->stack_size()); + assert(sim()->stack_size() <= 6, "at least two stack slots must be free"); + + sim()->pop(); + + do_rename(right, res); + + new_res = to_fpu_stack_top(res); + break; + } + default: { assert(false, "missed a fpu-operation"); } }