< prev index next >
src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp
Print this page
@@ -384,10 +384,46 @@
LIR_Opr tmp = LIR_OprFact::illegalOpr;
if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) {
tmp = new_register(T_DOUBLE);
}
+#ifdef _LP64
+ if (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem) {
+ // frem and drem are implemented as a direct call into the runtime.
+ LIRItem left(x->x(), this);
+ LIRItem right(x->y(), this);
+
+ BasicType bt = as_BasicType(x->type());
+ BasicTypeList signature(2);
+ signature.append(bt);
+ signature.append(bt);
+ CallingConvention* cc = frame_map()->c_calling_convention(&signature);
+
+ const LIR_Opr result_reg = result_register_for(x->type());
+ left.load_item_force(cc->at(0));
+ right.load_item_force(cc->at(1));
+
+ address entry = NULL;
+ switch (x->op()) {
+ case Bytecodes::_frem:
+ entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);
+ break;
+ case Bytecodes::_drem:
+ entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+
+ LIR_Opr result = rlock_result(x);
+ __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());
+ __ move(result_reg, result);
+ } else {
+ arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
+ set_result(x, round_item(reg));
+ }
+#else
if ((UseSSE >= 1 && x->op() == Bytecodes::_frem) || (UseSSE >= 2 && x->op() == Bytecodes::_drem)) {
// special handling for frem and drem: no SSE instruction, so must use FPU with temporary fpu stack slots
LIR_Opr fpu0, fpu1;
if (x->op() == Bytecodes::_frem) {
fpu0 = LIR_OprFact::single_fpu(0);
@@ -402,12 +438,12 @@
__ move(fpu0, reg);
} else {
arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
}
-
set_result(x, round_item(reg));
+#endif // _LP64
}
// for _ladd, _lmul, _lsub, _ldiv, _lrem
void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
@@ -442,13 +478,10 @@
entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
break; // check if dividend is 0 is done elsewhere
case Bytecodes::_ldiv:
entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
break; // check if dividend is 0 is done elsewhere
- case Bytecodes::_lmul:
- entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);
- break;
default:
ShouldNotReachHere();
}
LIR_Opr result = rlock_result(x);
@@ -1143,10 +1176,19 @@
default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
}
}
void LIRGenerator::do_Convert(Convert* x) {
+#ifdef _LP64
+ LIRItem value(x->value(), this);
+ value.load_item();
+ LIR_Opr input = value.result();
+ LIR_Opr result = rlock(x);
+ __ convert(x->op(), input, result);
+ assert(result->is_virtual(), "result must be virtual register");
+ set_result(x, result);
+#else
// flags that vary for the different operations and different SSE-settings
bool fixed_input = false, fixed_result = false, round_result = false, needs_stub = false;
switch (x->op()) {
case Bytecodes::_i2l: // fall through
@@ -1201,10 +1243,11 @@
__ move(conv_result, result);
}
assert(result->is_virtual(), "result must be virtual register");
set_result(x, result);
+#endif // _LP64
}
void LIRGenerator::do_NewInstance(NewInstance* x) {
print_if_not_loaded(x);
< prev index next >