< prev index next >
src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp
Print this page
rev 12409 : 8171244: PPC64: Make interpreter's math entries consistent with C1 and C2 and support FMA
Reviewed-by:
@@ -290,32 +290,32 @@
patching_epilog(patch, lir_patch_normal, reg, info);
}
-void LIR_Assembler::emit_op3(LIR_Op3* op) {
- const bool is_int = op->result_opr()->is_single_cpu();
- Register Rdividend = is_int ? op->in_opr1()->as_register() : op->in_opr1()->as_register_lo();
+void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
+ const bool is_int = result->is_single_cpu();
+ Register Rdividend = is_int ? left->as_register() : left->as_register_lo();
Register Rdivisor = noreg;
- Register Rscratch = op->in_opr3()->as_register();
- Register Rresult = is_int ? op->result_opr()->as_register() : op->result_opr()->as_register_lo();
+ Register Rscratch = temp->as_register();
+ Register Rresult = is_int ? result->as_register() : result->as_register_lo();
long divisor = -1;
- if (op->in_opr2()->is_register()) {
- Rdivisor = is_int ? op->in_opr2()->as_register() : op->in_opr2()->as_register_lo();
+ if (right->is_register()) {
+ Rdivisor = is_int ? right->as_register() : right->as_register_lo();
} else {
- divisor = is_int ? op->in_opr2()->as_constant_ptr()->as_jint()
- : op->in_opr2()->as_constant_ptr()->as_jlong();
+ divisor = is_int ? right->as_constant_ptr()->as_jint()
+ : right->as_constant_ptr()->as_jlong();
}
assert(Rdividend != Rscratch, "");
assert(Rdivisor != Rscratch, "");
- assert(op->code() == lir_idiv || op->code() == lir_irem, "Must be irem or idiv");
+ assert(code == lir_idiv || code == lir_irem, "Must be irem or idiv");
if (Rdivisor == noreg) {
if (divisor == 1) { // stupid, but can happen
- if (op->code() == lir_idiv) {
+ if (code == lir_idiv) {
__ mr_if_needed(Rresult, Rdividend);
} else {
__ li(Rresult, 0);
}
@@ -338,11 +338,11 @@
}
__ clrldi(Rscratch, Rscratch, 64-log2);
}
__ add(Rscratch, Rdividend, Rscratch);
- if (op->code() == lir_idiv) {
+ if (code == lir_idiv) {
if (is_int) {
__ srawi(Rresult, Rscratch, log2);
} else {
__ sradi(Rresult, Rscratch, log2);
}
@@ -350,19 +350,19 @@
__ clrrdi(Rscratch, Rscratch, log2);
__ sub(Rresult, Rdividend, Rscratch);
}
} else if (divisor == -1) {
- if (op->code() == lir_idiv) {
+ if (code == lir_idiv) {
__ neg(Rresult, Rdividend);
} else {
__ li(Rresult, 0);
}
} else {
__ load_const_optimized(Rscratch, divisor);
- if (op->code() == lir_idiv) {
+ if (code == lir_idiv) {
if (is_int) {
__ divw(Rresult, Rdividend, Rscratch); // Can't divide minint/-1.
} else {
__ divd(Rresult, Rdividend, Rscratch); // Can't divide minint/-1.
}
@@ -387,11 +387,11 @@
__ cmpwi(CCR0, Rdivisor, -1);
} else {
__ cmpdi(CCR0, Rdivisor, -1);
}
__ bne(CCR0, regular);
- if (op->code() == lir_idiv) {
+ if (code == lir_idiv) {
__ neg(Rresult, Rdividend);
__ b(done);
__ bind(regular);
if (is_int) {
__ divw(Rresult, Rdividend, Rdivisor); // Can't divide minint/-1.
@@ -413,10 +413,30 @@
}
__ bind(done);
}
+void LIR_Assembler::emit_op3(LIR_Op3* op) {
+ switch (op->code()) {
+ case lir_idiv:
+ case lir_irem:
+ arithmetic_idiv(op->code(), op->in_opr1(), op->in_opr2(), op->in_opr3(),
+ op->result_opr(), op->info());
+ break;
+ case lir_fmad:
+ __ fmadd(op->result_opr()->as_double_reg(), op->in_opr1()->as_double_reg(),
+ op->in_opr2()->as_double_reg(), op->in_opr3()->as_double_reg());
+ break;
+ case lir_fmaf:
+ __ fmadds(op->result_opr()->as_float_reg(), op->in_opr1()->as_float_reg(),
+ op->in_opr2()->as_float_reg(), op->in_opr3()->as_float_reg());
+ break;
+ default: ShouldNotReachHere(); break;
+ }
+}
+
+
void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
#ifdef ASSERT
assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
if (op->block() != NULL) _branch_target_blocks.append(op->block());
if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());
< prev index next >