void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); ValueTag tag = x->x()->type()->tag(); bool is_safepoint = x->is_safepoint(); If::Condition cond = x->cond(); LIRItem xitem(x->x(), this); LIRItem yitem(x->y(), this); LIRItem* xin = &xitem; LIRItem* yin = &yitem; if (tag == longTag) { // for longs, only conditions "eql", "neq", "lss", "geq" are valid; // mirror for other conditions if (cond == If::gtr || cond == If::leq) { cond = Instruction::mirror(cond); xin = &yitem; yin = &xitem; } xin->set_destroys_register(); } if (tag == floatTag || tag == doubleTag) { xin->set_destroys_register(); yin->set_destroys_register(); } xin->load_item(); if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { // inline long zero yin->dont_load_item(); } else if (tag == longTag || tag == floatTag || tag == doubleTag) { // longs cannot handle constants at right side yin->load_item(); } else { yin->dont_load_item(); } // note that the condition test must happen before the // moves into Phi area happen, and that the control flow // jump must happen after the moves into the phi area set_no_result(x); if (x->is_safepoint()) { CodeEmitInfo* info_before = state_for(x, x->state_before()); emit()->safepoint_nop(info_before); } emit()->if_op(1, cond, xin->result(), yin->result(), x->tsux(), x->fsux(), x->usux()); move_to_phi(x->state()); emit()->if_op(2, cond, xin->result(), yin->result(), x->tsux(), x->fsux(), x->usux()); goto_default_successor(x); }
void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); ValueTag tag = x->x()->type()->tag(); bool is_safepoint = x->is_safepoint(); If::Condition cond = x->cond(); LIRItem xitem(x->x(), this); LIRItem yitem(x->y(), this); LIRItem* xin = &xitem; LIRItem* yin = &yitem; if (tag == longTag) { // for longs, only conditions "eql", "neq", "lss", "geq" are valid; // mirror for other conditions if (cond == If::gtr || cond == If::leq) { cond = Instruction::mirror(cond); xin = &yitem; yin = &xitem; } xin->set_destroys_register(); } xin->load_item(); if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { // inline long zero yin->dont_load_item(); } else if (tag == longTag || tag == floatTag || tag == doubleTag) { // longs cannot handle constants at right side yin->load_item(); } else { yin->dont_load_item(); } // add safepoint before generating condition code so it can be recomputed if (x->is_safepoint()) { // increment backedge counter if needed increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci()); __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before())); } set_no_result(x); LIR_Opr left = xin->result(); LIR_Opr right = yin->result(); __ cmp(lir_cond(cond), left, right); // Generate branch profiling. Profiling code doesn't kill flags. profile_branch(x, cond); move_to_phi(x->state()); if (x->x()->type()->is_float_kind()) { __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux()); } else { __ branch(lir_cond(cond), right->type(), x->tsux()); } assert(x->default_sux() == x->fsux(), "wrong destination above"); __ jump(x->default_sux()); }
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f // _i2b, _i2c, _i2s void LIRGenerator::do_Convert(Convert* x) { switch (x->op()) { case Bytecodes::_f2l: case Bytecodes::_d2l: case Bytecodes::_d2i: case Bytecodes::_l2f: case Bytecodes::_l2d: { address entry; switch (x->op()) { case Bytecodes::_l2f: entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f); break; case Bytecodes::_l2d: entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2d); break; case Bytecodes::_f2l: entry = CAST_FROM_FN_PTR(address, SharedRuntime::f2l); break; case Bytecodes::_d2l: entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2l); break; case Bytecodes::_d2i: entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2i); break; default: ShouldNotReachHere(); } LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL); set_result(x, result); break; } case Bytecodes::_i2f: case Bytecodes::_i2d: { LIRItem value(x->value(), this); LIR_Opr reg = rlock_result(x); // To convert an int to double, we need to load the 32-bit int // from memory into a single precision floating point register // (even numbered). Then the sparc fitod instruction takes care // of the conversion. This is a bit ugly, but is the best way to // get the int value in a single precision floating point register value.load_item(); LIR_Opr tmp = force_to_spill(value.result(), T_FLOAT); __ convert(x->op(), tmp, reg); break; } break; case Bytecodes::_i2l: case Bytecodes::_i2b: case Bytecodes::_i2c: case Bytecodes::_i2s: case Bytecodes::_l2i: case Bytecodes::_f2d: case Bytecodes::_d2f: { // inline code LIRItem value(x->value(), this); value.load_item(); LIR_Opr reg = rlock_result(x); __ convert(x->op(), value.result(), reg, false); } break; case Bytecodes::_f2i: { LIRItem value (x->value(), this); value.set_destroys_register(); value.load_item(); LIR_Opr reg = rlock_result(x); set_vreg_flag(reg, must_start_in_memory); __ convert(x->op(), value.result(), reg, false); } break; default: ShouldNotReachHere(); } }
void LIRGenerator::do_If(If* x) { assert(x->number_of_sux() == 2, "inconsistency"); ValueTag tag = x->x()->type()->tag(); LIRItem xitem(x->x(), this); LIRItem yitem(x->y(), this); LIRItem* xin = &xitem; LIRItem* yin = &yitem; If::Condition cond = x->cond(); if (tag == longTag) { // for longs, only conditions "eql", "neq", "lss", "geq" are valid; // mirror for other conditions if (cond == If::gtr || cond == If::leq) { // swap inputs cond = Instruction::mirror(cond); xin = &yitem; yin = &xitem; } xin->set_destroys_register(); } LIR_Opr left = LIR_OprFact::illegalOpr; LIR_Opr right = LIR_OprFact::illegalOpr; xin->load_item(); left = xin->result(); if (is_simm13(yin->result())) { // inline int constants which are small enough to be immediate operands right = LIR_OprFact::value_type(yin->value()->type()); } else if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) { // inline long zero right = LIR_OprFact::value_type(yin->value()->type()); } else if (tag == objectTag && yin->is_constant() && (yin->get_jobject_constant()->is_null_object())) { right = LIR_OprFact::value_type(yin->value()->type()); } else { yin->load_item(); right = yin->result(); } set_no_result(x); // add safepoint before generating condition code so it can be recomputed if (x->is_safepoint()) { // increment backedge counter if needed increment_backedge_counter(state_for(x, x->state_before())); __ safepoint(new_register(T_INT), state_for(x, x->state_before())); } __ cmp(lir_cond(cond), left, right); profile_branch(x, cond); move_to_phi(x->state()); if (x->x()->type()->is_float_kind()) { __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux()); } else { __ branch(lir_cond(cond), right->type(), x->tsux()); } assert(x->default_sux() == x->fsux(), "wrong destination above"); __ jump(x->default_sux()); }