src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File open Cdiff src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp

src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp

Print this page

        

*** 116,156 **** //--------- loading items into registers -------------------------------- bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const { - #ifdef AARCH64 - if (v->type()->as_IntConstant() != NULL) { - return v->type()->as_IntConstant()->value() == 0; - } else if (v->type()->as_LongConstant() != NULL) { - return v->type()->as_LongConstant()->value() == 0; - } else if (v->type()->as_ObjectConstant() != NULL) { - return v->type()->as_ObjectConstant()->value()->is_null_object(); - } else if (v->type()->as_FloatConstant() != NULL) { - return jint_cast(v->type()->as_FloatConstant()->value()) == 0; - } else if (v->type()->as_DoubleConstant() != NULL) { - return jlong_cast(v->type()->as_DoubleConstant()->value()) == 0; - } - #endif // AARCH64 return false; } bool LIRGenerator::can_inline_as_constant(Value v) const { if (v->type()->as_IntConstant() != NULL) { return Assembler::is_arith_imm_in_range(v->type()->as_IntConstant()->value()); } else if (v->type()->as_ObjectConstant() != NULL) { return v->type()->as_ObjectConstant()->value()->is_null_object(); - #ifdef AARCH64 - } else if (v->type()->as_LongConstant() != NULL) { - return Assembler::is_arith_imm_in_range(v->type()->as_LongConstant()->value()); - #else } else if (v->type()->as_FloatConstant() != NULL) { return v->type()->as_FloatConstant()->value() == 0.0f; } else if (v->type()->as_DoubleConstant() != NULL) { return v->type()->as_DoubleConstant()->value() == 0.0; - #endif // AARCH64 } return false; } --- 116,138 ----
*** 158,200 **** ShouldNotCallThis(); // Not used on ARM return false; } - #ifdef AARCH64 - - static bool can_inline_as_constant_in_cmp(Value v) { - jlong constant; - if (v->type()->as_IntConstant() != NULL) { - constant = v->type()->as_IntConstant()->value(); - } else if (v->type()->as_LongConstant() != NULL) { - constant = v->type()->as_LongConstant()->value(); - } else if (v->type()->as_ObjectConstant() != NULL) { - return v->type()->as_ObjectConstant()->value()->is_null_object(); - } else if (v->type()->as_FloatConstant() != NULL) { - return v->type()->as_FloatConstant()->value() == 0.0f; - } else if (v->type()->as_DoubleConstant() != NULL) { - return v->type()->as_DoubleConstant()->value() == 0.0; - } else { - return false; - } - - return Assembler::is_arith_imm_in_range(constant) || Assembler::is_arith_imm_in_range(-constant); - } - - - static bool can_inline_as_constant_in_logic(Value v) { - if (v->type()->as_IntConstant() != NULL) { - return Assembler::LogicalImmediate(v->type()->as_IntConstant()->value(), true).is_encoded(); - } else if (v->type()->as_LongConstant() != NULL) { - return Assembler::LogicalImmediate(v->type()->as_LongConstant()->value(), false).is_encoded(); - } - return false; - } - - - #endif // AARCH64 LIR_Opr LIRGenerator::safepoint_poll_register() { return LIR_OprFact::illegalOpr; } --- 140,149 ----
*** 209,260 **** default: ShouldNotReachHere(); return LIR_OprFact::intConst(-1); } } - #ifdef AARCH64 - - void LIRGenerator::add_constant(LIR_Opr src, jlong c, LIR_Opr dest) { - if (c == 0) { - __ move(src, dest); - return; - } - - BasicType type = src->type(); - bool is_neg = (c < 0); - c = ABS(c); - - if ((c >> 24) == 0) { - for (int shift = 0; shift <= 12; shift += 12) { - int part = ((int)c) & (right_n_bits(12) << shift); - if (part != 0) { - if (is_neg) { - __ sub(src, make_constant(type, part), dest); - } else { - __ add(src, make_constant(type, part), dest); - } - src = dest; - } - } - } else { - __ move(make_constant(type, c), dest); - if (is_neg) { - __ sub(src, dest, dest); - } else { - __ add(src, dest, dest); - } - } - } - - #endif // AARCH64 void LIRGenerator::add_large_constant(LIR_Opr src, int c, LIR_Opr dest) { assert(c != 0, "must be"); - #ifdef AARCH64 - add_constant(src, c, dest); - #else // Find first non-zero bit int shift = 0; while ((c & (3 << shift)) == 0) { shift += 2; } --- 158,171 ----
*** 270,280 **** __ add(dest, LIR_OprFact::intConst(c & (mask << 16)), dest); } if (c & (mask << 24)) { __ add(dest, LIR_OprFact::intConst(c & (mask << 24)), dest); } - #endif // AARCH64 } static LIR_Address* make_address(LIR_Opr base, LIR_Opr index, LIR_Address::Scale scale, BasicType type) { return new LIR_Address(base, index, scale, 0, type); } --- 181,190 ----
*** 286,296 **** if (index->is_constant()) { disp += index->as_constant_ptr()->as_jint() << shift; index = LIR_OprFact::illegalOpr; } - #ifndef AARCH64 if (base->type() == T_LONG) { LIR_Opr tmp = new_register(T_INT); __ convert(Bytecodes::_l2i, base, tmp); base = tmp; } --- 196,205 ----
*** 300,329 **** index = tmp; } // At this point base and index should be all ints and not constants assert(base->is_single_cpu() && !base->is_constant(), "base should be an non-constant int"); assert(index->is_illegal() || (index->type() == T_INT && !index->is_constant()), "index should be an non-constant int"); - #endif int max_disp; bool disp_is_in_range; bool embedded_shift; - #ifdef AARCH64 - int align = exact_log2(type2aelembytes(type, true)); - assert((disp & right_n_bits(align)) == 0, "displacement is not aligned"); - assert(shift == 0 || shift == align, "shift should be zero or equal to embedded align"); - max_disp = (1 << 12) << align; - - if (disp >= 0) { - disp_is_in_range = Assembler::is_unsigned_imm_in_range(disp, 12, align); - } else { - disp_is_in_range = Assembler::is_imm_in_range(disp, 9, 0); - } - - embedded_shift = true; - #else switch (type) { case T_BYTE: case T_SHORT: case T_CHAR: max_disp = 256; // ldrh, ldrsb encoding has 8-bit offset --- 209,223 ----
*** 342,352 **** max_disp = 4096; // ldr, ldrb allow 12-bit offset embedded_shift = true; } disp_is_in_range = (-max_disp < disp && disp < max_disp); - #endif // !AARCH64 if (index->is_register()) { LIR_Opr tmp = new_pointer_register(); if (!disp_is_in_range) { add_large_constant(base, disp, tmp); --- 236,245 ----
*** 392,406 **** LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { assert(type == T_LONG || type == T_INT, "should be"); LIR_Opr r = make_constant(type, x); - #ifdef AARCH64 - bool imm_in_range = Assembler::LogicalImmediate(x, type == T_INT).is_encoded(); - #else bool imm_in_range = AsmOperand::is_rotated_imm(x); - #endif // AARCH64 if (!imm_in_range) { LIR_Opr tmp = new_register(type); __ move(r, tmp); return tmp; } --- 285,295 ----
*** 437,454 **** bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) { assert(left != result, "should be different registers"); if (is_power_of_2(c + 1)) { - #ifdef AARCH64 - __ shift_left(left, log2_intptr(c + 1), result); - __ sub(result, left, result); - #else LIR_Address::Scale scale = (LIR_Address::Scale) log2_intptr(c + 1); LIR_Address* addr = new LIR_Address(left, left, scale, 0, T_INT); __ sub(LIR_OprFact::address(addr), left, result); // rsb with shifted register - #endif // AARCH64 return true; } else if (is_power_of_2(c - 1)) { LIR_Address::Scale scale = (LIR_Address::Scale) log2_intptr(c - 1); LIR_Address* addr = new LIR_Address(left, left, scale, 0, T_INT); __ add(left, LIR_OprFact::address(addr), result); // add with shifted register --- 326,338 ----
*** 463,517 **** __ store(item, new LIR_Address(FrameMap::SP_opr, in_bytes(offset_from_sp), item->type())); } void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) { assert(CardTable::dirty_card_val() == 0, ! "Cannot use ZR register (aarch64) or the register containing the card table base address directly (aarch32) otherwise"); ! #ifdef AARCH64 ! // AARCH64 has a register that is constant zero. We can use that one to set the ! // value in the card table to dirty. ! __ move(FrameMap::ZR_opr, card_addr); ! #else // AARCH64 if((ci_card_table_address_as<intx>() & 0xff) == 0) { // If the card table base address is aligned to 256 bytes, we can use the register // that contains the card_table_base_address. __ move(value, card_addr); } else { // Otherwise we need to create a register containing that value. LIR_Opr tmp_zero = new_register(T_INT); __ move(LIR_OprFact::intConst(CardTable::dirty_card_val()), tmp_zero); __ move(tmp_zero, card_addr); } - #endif // AARCH64 } void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) { assert(addr->is_register(), "must be a register at this point"); CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set()); CardTable* ct = ctbs->card_table(); LIR_Opr tmp = FrameMap::LR_ptr_opr; ! // TODO-AARCH64: check performance ! bool load_card_table_base_const = AARCH64_ONLY(false) NOT_AARCH64(VM_Version::supports_movw()); if (load_card_table_base_const) { __ move((LIR_Opr)card_table_base, tmp); } else { __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp); } - #ifdef AARCH64 - LIR_Address* shifted_reg_operand = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BYTE); - LIR_Opr tmp2 = tmp; - __ add(tmp, LIR_OprFact::address(shifted_reg_operand), tmp2); // tmp2 = tmp + (addr >> CardTable::card_shift) - LIR_Address* card_addr = new LIR_Address(tmp2, T_BYTE); - #else // Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load // byte instruction does not support the addressing mode we need. LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN); - #endif if (UseCondCardMark) { if (ct->scanned_concurrently()) { __ membar_storeload(); } LIR_Opr cur_value = new_register(T_INT); --- 347,387 ---- __ store(item, new LIR_Address(FrameMap::SP_opr, in_bytes(offset_from_sp), item->type())); } void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) { assert(CardTable::dirty_card_val() == 0, ! "Cannot use the register containing the card table base address directly"); if((ci_card_table_address_as<intx>() & 0xff) == 0) { // If the card table base address is aligned to 256 bytes, we can use the register // that contains the card_table_base_address. __ move(value, card_addr); } else { // Otherwise we need to create a register containing that value. LIR_Opr tmp_zero = new_register(T_INT); __ move(LIR_OprFact::intConst(CardTable::dirty_card_val()), tmp_zero); __ move(tmp_zero, card_addr); } } void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) { assert(addr->is_register(), "must be a register at this point"); CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set()); CardTable* ct = ctbs->card_table(); LIR_Opr tmp = FrameMap::LR_ptr_opr; ! bool load_card_table_base_const = VM_Version::supports_movw(); if (load_card_table_base_const) { __ move((LIR_Opr)card_table_base, tmp); } else { __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp); } // Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load // byte instruction does not support the addressing mode we need. LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN); if (UseCondCardMark) { if (ct->scanned_concurrently()) { __ membar_storeload(); } LIR_Opr cur_value = new_register(T_INT);
*** 677,743 **** CodeEmitInfo* info = NULL; if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) { info = state_for(x); } - #ifdef AARCH64 - LIRItem left(x->x(), this); - LIRItem right(x->y(), this); - LIRItem* left_arg = &left; - LIRItem* right_arg = &right; - - // Test if instr is commutative and if we should swap - if (x->is_commutative() && left.is_constant()) { - left_arg = &right; - right_arg = &left; - } - - left_arg->load_item(); - switch (x->op()) { - case Bytecodes::_ldiv: - right_arg->load_item(); - make_div_by_zero_check(right_arg->result(), T_LONG, info); - __ idiv(left_arg->result(), right_arg->result(), rlock_result(x), LIR_OprFact::illegalOpr, NULL); - break; - - case Bytecodes::_lrem: { - right_arg->load_item(); - make_div_by_zero_check(right_arg->result(), T_LONG, info); - // a % b is implemented with 2 instructions: - // tmp = a/b (sdiv) - // res = a - b*tmp (msub) - LIR_Opr tmp = FrameMap::as_long_opr(Rtemp); - __ irem(left_arg->result(), right_arg->result(), rlock_result(x), tmp, NULL); - break; - } - - case Bytecodes::_lmul: - if (right_arg->is_constant() && is_power_of_2_long(right_arg->get_jlong_constant())) { - right_arg->dont_load_item(); - __ shift_left(left_arg->result(), exact_log2_long(right_arg->get_jlong_constant()), rlock_result(x)); - } else { - right_arg->load_item(); - __ mul(left_arg->result(), right_arg->result(), rlock_result(x)); - } - break; - - case Bytecodes::_ladd: - case Bytecodes::_lsub: - if (right_arg->is_constant()) { - jlong c = right_arg->get_jlong_constant(); - add_constant(left_arg->result(), (x->op() == Bytecodes::_ladd) ? c : -c, rlock_result(x)); - } else { - right_arg->load_item(); - arithmetic_op_long(x->op(), rlock_result(x), left_arg->result(), right_arg->result(), NULL); - } - break; - - default: - ShouldNotReachHere(); - return; - } - #else switch (x->op()) { case Bytecodes::_ldiv: case Bytecodes::_lrem: { LIRItem right(x->y(), this); right.load_item(); --- 547,556 ----
*** 775,785 **** break; } default: ShouldNotReachHere(); } - #endif // AARCH64 } // for: _iadd, _imul, _isub, _idiv, _irem void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) { --- 588,597 ----
*** 802,825 **** right_arg->dont_load_item(); LIR_Opr tmp = LIR_OprFact::illegalOpr; LIR_Opr result = rlock_result(x); __ idiv(left_arg->result(), right_arg->result(), result, tmp, info); } else { - #ifdef AARCH64 - left_arg->load_item(); - right_arg->load_item(); - make_div_by_zero_check(right_arg->result(), T_INT, info); - if (x->op() == Bytecodes::_idiv) { - __ idiv(left_arg->result(), right_arg->result(), rlock_result(x), LIR_OprFact::illegalOpr, NULL); - } else { - // a % b is implemented with 2 instructions: - // tmp = a/b (sdiv) - // res = a - b*tmp (msub) - LIR_Opr tmp = FrameMap::as_opr(Rtemp); - __ irem(left_arg->result(), right_arg->result(), rlock_result(x), tmp, NULL); - } - #else left_arg->load_item_force(FrameMap::R0_opr); right_arg->load_item_force(FrameMap::R2_opr); LIR_Opr tmp = FrameMap::R1_opr; LIR_Opr result = rlock_result(x); LIR_Opr out_reg; --- 614,623 ----
*** 829,848 **** } else { // (x->op() == Bytecodes::_idiv) out_reg = FrameMap::R1_opr; __ idiv(left_arg->result(), right_arg->result(), out_reg, tmp, info); } __ move(out_reg, result); - #endif // AARCH64 } - #ifdef AARCH64 - } else if (((x->op() == Bytecodes::_iadd) || (x->op() == Bytecodes::_isub)) && right_arg->is_constant()) { - left_arg->load_item(); - jint c = right_arg->get_jint_constant(); - right_arg->dont_load_item(); - add_constant(left_arg->result(), (x->op() == Bytecodes::_iadd) ? c : -c, rlock_result(x)); - #endif // AARCH64 } else { left_arg->load_item(); if (x->op() == Bytecodes::_imul && right_arg->is_constant()) { jint c = right_arg->get_jint_constant(); --- 627,638 ----
*** 850,860 **** right_arg->dont_load_item(); } else { right_arg->load_item(); } } else { - AARCH64_ONLY(assert(!right_arg->is_constant(), "constant right_arg is already handled by this moment");) right_arg->load_nonconstant(); } rlock_result(x); assert(right_arg->is_constant() || right_arg->is_register(), "wrong state of right"); arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), NULL); --- 640,649 ----
*** 878,892 **** // _ishl, _lshl, _ishr, _lshr, _iushr, _lushr void LIRGenerator::do_ShiftOp(ShiftOp* x) { LIRItem value(x->x(), this); LIRItem count(x->y(), this); - #ifndef AARCH64 if (value.type()->is_long()) { count.set_destroys_register(); } - #endif // !AARCH64 if (count.is_constant()) { assert(count.type()->as_IntConstant() != NULL, "should be"); count.dont_load_item(); } else { --- 667,679 ----
*** 904,922 **** LIRItem left(x->x(), this); LIRItem right(x->y(), this); left.load_item(); - #ifdef AARCH64 - if (right.is_constant() && can_inline_as_constant_in_logic(right.value())) { - right.dont_load_item(); - } else { - right.load_item(); - } - #else right.load_nonconstant(); - #endif // AARCH64 logic_op(x->op(), rlock_result(x), left.result(), right.result()); } --- 691,701 ----
*** 954,972 **** #else // __SOFTFP__ LIRItem left(x->x(), this); LIRItem right(x->y(), this); left.load_item(); - #ifdef AARCH64 - if (right.is_constant() && can_inline_as_constant_in_cmp(right.value())) { - right.dont_load_item(); - } else { - right.load_item(); - } - #else right.load_nonconstant(); - #endif // AARCH64 LIR_Opr reg = rlock_result(x); if (x->x()->type()->is_float_kind()) { Bytecodes::Code code = x->op(); --- 733,743 ----
*** 985,1007 **** LIR_Opr tmp2 = LIR_OprFact::illegalOpr; new_value.load_item(); cmp_value.load_item(); LIR_Opr result = new_register(T_INT); if (type == T_OBJECT || type == T_ARRAY) { - #ifdef AARCH64 - if (UseCompressedOops) { - tmp1 = new_pointer_register(); - tmp2 = new_pointer_register(); - } - #endif __ cas_obj(addr, cmp_value.result(), new_value.result(), new_register(T_INT), new_register(T_INT), result); } else if (type == T_INT) { __ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), tmp1, tmp1, result); } else if (type == T_LONG) { - #ifndef AARCH64 tmp1 = new_register(T_LONG); - #endif // !AARCH64 __ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), tmp1, tmp2, result); } else { ShouldNotReachHere(); } return result; --- 756,770 ----
*** 1133,1143 **** } void LIRGenerator::do_Convert(Convert* x) { address runtime_func; switch (x->op()) { - #ifndef AARCH64 case Bytecodes::_l2f: runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::l2f); break; case Bytecodes::_l2d: runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::l2d); --- 896,905 ----
*** 1168,1178 **** // This is implemented in hard float in assembler on arm but a call // on other platforms. runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::d2i); break; #endif // __SOFTFP__ - #endif // !AARCH64 default: { LIRItem value(x->value(), this); value.load_item(); LIR_Opr reg = rlock_result(x); __ convert(x->op(), value.result(), reg, NULL); --- 930,939 ----
*** 1486,1527 **** LIRItem yitem(x->y(), this); LIRItem* xin = &xitem; LIRItem* yin = &yitem; If::Condition cond = x->cond(); - #ifndef AARCH64 if (tag == longTag) { if (cond == If::gtr || cond == If::leq) { cond = Instruction::mirror(cond); xin = &yitem; yin = &xitem; } xin->set_destroys_register(); } - #endif // !AARCH64 xin->load_item(); LIR_Opr left = xin->result(); LIR_Opr right; - #ifdef AARCH64 - if (yin->is_constant() && can_inline_as_constant_in_cmp(yin->value())) { - yin->dont_load_item(); - } else { - yin->load_item(); - } - right = yin->result(); - #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 { yin->load_nonconstant(); right = yin->result(); } - #endif // AARCH64 set_no_result(x); // add safepoint before generating condition code so it can be recomputed if (x->is_safepoint()) { --- 1247,1277 ----
*** 1556,1587 **** } void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address, CodeEmitInfo* info) { - #ifndef AARCH64 if (value->is_double_cpu()) { assert(address->index()->is_illegal(), "should have a constant displacement"); LIR_Opr tmp = new_pointer_register(); add_large_constant(address->base(), address->disp(), tmp); __ volatile_store_mem_reg(value, new LIR_Address(tmp, (intx)0, address->type()), info); return; } - #endif // !AARCH64 - // TODO-AARCH64 implement with stlr instruction __ store(value, address, info, lir_patch_none); } void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, CodeEmitInfo* info) { - #ifndef AARCH64 if (result->is_double_cpu()) { assert(address->index()->is_illegal(), "should have a constant displacement"); LIR_Opr tmp = new_pointer_register(); add_large_constant(address->base(), address->disp(), tmp); __ volatile_load_mem_reg(new LIR_Address(tmp, (intx)0, address->type()), result, info); return; } - #endif // !AARCH64 - // TODO-AARCH64 implement with ldar instruction __ load(address, result, info, lir_patch_none); } --- 1306,1331 ----
src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File