< prev index next >
src/cpu/ppc/vm/ppc.ad
Print this page
*** 3077,3086 ****
--- 3077,3097 ----
__ ld($dst$$Register, Idisp, $mem$$base$$Register);
// TODO PPC port __ endgroup_if_needed(_size == 12);
__ bind(done);
%}
+ enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
+ // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
+
+ MacroAssembler _masm(&cbuf);
+ Label done;
+ __ bso($crx$$CondRegister, done);
+ __ mffprd($dst$$Register, $src$$FloatRegister);
+ // TODO PPC port __ endgroup_if_needed(_size == 12);
+ __ bind(done);
+ %}
+
enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
// TODO: PPC port $archOpcode(ppc64Opcode_bc);
MacroAssembler _masm(&cbuf);
Label d; // dummy
*** 10076,10088 ****
// of java.lang.Float etc., e.g.
// int floatToIntBits(float value)
// float intBitsToFloat(int bits)
//
// Notes on the implementation on ppc64:
! // We only provide rules which move between a register and a stack-location,
! // because we always have to go through memory when moving between a float
! // register and an integer register.
//---------- Chain stack slots between similar types --------
// These are needed so that the rules below can match.
--- 10087,10127 ----
// of java.lang.Float etc., e.g.
// int floatToIntBits(float value)
// float intBitsToFloat(int bits)
//
// Notes on the implementation on ppc64:
! // For Power7 and earlier, the rules are limited to those which move between a
! // register and a stack-location, because we always have to go through memory
! // when moving between a float register and an integer register.
! // This restriction is removed in Power8 with the introduction of the mtfprd
! // and mffprd instructions.
!
! instruct moveL2D_reg(regD dst, iRegLsrc src) %{
! match(Set dst (MoveL2D src));
! effect(DEF dst, USE src);
! predicate(VM_Version::has_mtfprd());
!
! format %{ "MTFPRD $dst, $src" %}
! size(4);
! ins_encode %{
! __ mtfprd($dst$$FloatRegister, $src$$Register);
! %}
! ins_pipe(pipe_class_default);
! %}
!
! instruct moveI2D_reg(regD dst, iRegIsrc src) %{
! // no match-rule, false predicate
! effect(DEF dst, USE src);
! predicate(false);
!
! format %{ "MTFPRWA $dst, $src" %}
! size(4);
! ins_encode %{
! __ mtfprwa($dst$$FloatRegister, $src$$Register);
! %}
! ins_pipe(pipe_class_default);
! %}
//---------- Chain stack slots between similar types --------
// These are needed so that the rules below can match.
*** 10581,10590 ****
--- 10620,10643 ----
size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
ins_pipe(pipe_class_default);
%}
+ instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
+ // no match-rule, false predicate
+ effect(DEF dst, USE crx, USE src);
+ predicate(false);
+
+ ins_variable_size_depending_on_alignment(true);
+
+ format %{ "cmovI $crx, $dst, $src" %}
+ // Worst case is branch + move + stop, no stop without scheduler.
+ size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8);
+ ins_encode( enc_cmove_bso_reg(dst, crx, src) );
+ ins_pipe(pipe_class_default);
+ %}
+
instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE mem);
predicate(false);
*** 10635,10647 ****
--- 10688,10755 ----
nodes->push(m1);
nodes->push(m2);
%}
%}
+ instruct cmovI_bso_reg_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, regD src) %{
+ // no match-rule, false predicate
+ effect(DEF dst, USE crx, USE src);
+ predicate(false);
+
+ format %{ "CmovI $dst, $crx, $src \t// postalloc expanded" %}
+ postalloc_expand %{
+ //
+ // replaces
+ //
+ // region dst crx src
+ // \ | | /
+ // dst=cmovI_bso_reg_conLvalue0
+ //
+ // with
+ //
+ // region dst
+ // \ /
+ // dst=loadConI16(0)
+ // |
+ // ^ region dst crx src
+ // | \ | | /
+ // dst=cmovI_bso_reg
+ //
+
+ // Create new nodes.
+ MachNode *m1 = new loadConI16Node();
+ MachNode *m2 = new cmovI_bso_regNode();
+
+ // inputs for new nodes
+ m1->add_req(n_region);
+ m2->add_req(n_region, n_crx, n_src);
+
+ // precedences for new nodes
+ m2->add_prec(m1);
+
+ // operands for new nodes
+ m1->_opnds[0] = op_dst;
+ m1->_opnds[1] = new immI16Oper(0);
+
+ m2->_opnds[0] = op_dst;
+ m2->_opnds[1] = op_crx;
+ m2->_opnds[2] = op_src;
+
+ // registers for new nodes
+ ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
+ ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
+
+ // Insert new nodes.
+ nodes->push(m1);
+ nodes->push(m2);
+ %}
+ %}
+
// Double to Int conversion, NaN is mapped to 0.
instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{
match(Set dst (ConvD2I src));
+ predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
stackSlotL tmpS;
*** 10651,10660 ****
--- 10759,10783 ----
moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
%}
%}
+ // Double to Int conversion, NaN is mapped to 0. Special version for Power8.
+ instruct convD2I_reg_mffprd_ExEx(iRegIdst dst, regD src) %{
+ match(Set dst (ConvD2I src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ flagsReg crx;
+ cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
+ convD2IRaw_regD(tmpD, src); // Convert float to int (speculated).
+ cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
+ %}
+ %}
+
instruct convF2IRaw_regF(regF dst, regF src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
predicate(false);
*** 10668,10677 ****
--- 10791,10801 ----
%}
// Float to Int conversion, NaN is mapped to 0.
instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{
match(Set dst (ConvF2I src));
+ predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regF tmpF;
stackSlotL tmpS;
*** 10681,10690 ****
--- 10805,10829 ----
moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
%}
%}
+ // Float to Int conversion, NaN is mapped to 0. Special version for Power8.
+ instruct convF2I_regF_mffprd_ExEx(iRegIdst dst, regF src) %{
+ match(Set dst (ConvF2I src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regF tmpF;
+ flagsReg crx;
+ cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
+ convF2IRaw_regF(tmpF, src); // Convert float to int (speculated).
+ cmovI_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
+ %}
+ %}
+
// Convert to Long
instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
match(Set dst (ConvI2L src));
format %{ "EXTSW $dst, $src \t// int->long" %}
*** 10750,10759 ****
--- 10889,10912 ----
size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
ins_pipe(pipe_class_default);
%}
+ instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
+ // no match-rule, false predicate
+ effect(DEF dst, USE crx, USE src);
+ predicate(false);
+
+ ins_variable_size_depending_on_alignment(true);
+
+ format %{ "cmovL $crx, $dst, $src" %}
+ // Worst case is branch + move + stop, no stop without scheduler.
+ size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8);
+ ins_encode( enc_cmove_bso_reg(dst, crx, src) );
+ ins_pipe(pipe_class_default);
+ %}
+
instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{
// no match-rule, false predicate
effect(DEF dst, USE crx, USE mem);
predicate(false);
*** 10801,10813 ****
--- 10954,11018 ----
nodes->push(m1);
nodes->push(m2);
%}
%}
+ instruct cmovL_bso_reg_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, regD src) %{
+ // no match-rule, false predicate
+ effect(DEF dst, USE crx, USE src);
+ predicate(false);
+
+ format %{ "CmovL $dst, $crx, $src \t// postalloc expanded" %}
+ postalloc_expand %{
+ //
+ // replaces
+ //
+ // region dst crx src
+ // \ | | /
+ // dst=cmovL_bso_reg_conLvalue0
+ //
+ // with
+ //
+ // region dst
+ // \ /
+ // dst=loadConL16(0)
+ // |
+ // ^ region dst crx src
+ // | \ | | /
+ // dst=cmovL_bso_reg
+ //
+
+ // Create new nodes.
+ MachNode *m1 = new loadConL16Node();
+ MachNode *m2 = new cmovL_bso_regNode();
+
+ // inputs for new nodes
+ m1->add_req(n_region);
+ m2->add_req(n_region, n_crx, n_src);
+ m2->add_prec(m1);
+
+ // operands for new nodes
+ m1->_opnds[0] = op_dst;
+ m1->_opnds[1] = new immL16Oper(0);
+ m2->_opnds[0] = op_dst;
+ m2->_opnds[1] = op_crx;
+ m2->_opnds[2] = op_src;
+
+ // registers for new nodes
+ ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
+ ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst
+
+ // Insert new nodes.
+ nodes->push(m1);
+ nodes->push(m2);
+ %}
+ %}
+
// Float to Long conversion, NaN is mapped to 0.
instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{
match(Set dst (ConvF2L src));
+ predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regF tmpF;
stackSlotL tmpS;
*** 10817,10826 ****
--- 11022,11046 ----
moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated).
cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
%}
%}
+ // Float to Long conversion, NaN is mapped to 0. Special version for Power8.
+ instruct convF2L_reg_mffprd_ExEx(iRegLdst dst, regF src) %{
+ match(Set dst (ConvF2L src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regF tmpF;
+ flagsReg crx;
+ cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
+ convF2LRaw_regF(tmpF, src); // Convert float to long (speculated).
+ cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpF); // Cmove based on NaN check.
+ %}
+ %}
+
instruct convD2LRaw_regD(regD dst, regD src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
predicate(false);
*** 10834,10843 ****
--- 11054,11064 ----
%}
// Double to Long conversion, NaN is mapped to 0.
instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{
match(Set dst (ConvD2L src));
+ predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
regD tmpD;
stackSlotL tmpS;
*** 10847,10856 ****
--- 11068,11092 ----
moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated).
cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check.
%}
%}
+ // Double to Long conversion, NaN is mapped to 0. Special version for Power8.
+ instruct convD2L_reg_mffprd_ExEx(iRegLdst dst, regD src) %{
+ match(Set dst (ConvD2L src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ flagsReg crx;
+ cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN.
+ convD2LRaw_regD(tmpD, src); // Convert float to long (speculated).
+ cmovL_bso_reg_conLvalue0_Ex(dst, crx, tmpD); // Cmove based on NaN check.
+ %}
+ %}
+
// Convert to Float
// Placed here as needed in expand.
instruct convL2DRaw_regD(regD dst, regD src) %{
// no match-rule, false predicate
*** 10912,10922 ****
%}
// Integer to Float conversion. Special version for Power7.
instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
match(Set dst (ConvI2F src));
! predicate(VM_Version::has_fcfids());
ins_cost(DEFAULT_COST);
expand %{
iRegLdst tmpL;
stackSlotL tmpS;
--- 11148,11158 ----
%}
// Integer to Float conversion. Special version for Power7.
instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{
match(Set dst (ConvI2F src));
! predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
iRegLdst tmpL;
stackSlotL tmpS;
*** 10926,10939 ****
moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
convL2FRaw_regF(dst, tmpD); // Convert to float.
%}
%}
// L2F to avoid runtime call.
instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
match(Set dst (ConvL2F src));
! predicate(VM_Version::has_fcfids());
ins_cost(DEFAULT_COST);
expand %{
stackSlotL tmpS;
regD tmpD;
--- 11162,11188 ----
moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
convL2FRaw_regF(dst, tmpD); // Convert to float.
%}
%}
+ // Integer to Float conversion. Special version for Power8.
+ instruct convI2F_ireg_mtfprd_Ex(regF dst, iRegIsrc src) %{
+ match(Set dst (ConvI2F src));
+ predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ moveI2D_reg(tmpD, src);
+ convL2FRaw_regF(dst, tmpD); // Convert to float.
+ %}
+ %}
+
// L2F to avoid runtime call.
instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{
match(Set dst (ConvL2F src));
! predicate(VM_Version::has_fcfids() && !VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
stackSlotL tmpS;
regD tmpD;
*** 10941,10958 ****
--- 11190,11221 ----
moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
convL2FRaw_regF(dst, tmpD); // Convert to float.
%}
%}
+ // L2F to avoid runtime call. Special version for Power8.
+ instruct convL2F_ireg_mtfprd_Ex(regF dst, iRegLsrc src) %{
+ match(Set dst (ConvL2F src));
+ predicate(VM_Version::has_fcfids() && VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ moveL2D_reg(tmpD, src);
+ convL2FRaw_regF(dst, tmpD); // Convert to float.
+ %}
+ %}
+
// Moved up as used in expand.
//instruct convD2F_reg(regF dst, regD src) %{%}
// Convert to Double
// Integer to Double conversion.
instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{
match(Set dst (ConvI2D src));
+ predicate(!VM_Version::has_mtfprd());
ins_cost(DEFAULT_COST);
expand %{
iRegLdst tmpL;
stackSlotL tmpS;
*** 10962,10971 ****
--- 11225,11247 ----
moveL2D_stack_reg(tmpD, tmpS); // Load long into double register.
convL2DRaw_regD(dst, tmpD); // Convert to double.
%}
%}
+ // Integer to Double conversion. Special version for Power8.
+ instruct convI2D_reg_mtfprd_Ex(regD dst, iRegIsrc src) %{
+ match(Set dst (ConvI2D src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ moveI2D_reg(tmpD, src);
+ convL2DRaw_regD(dst, tmpD); // Convert to double.
+ %}
+ %}
+
// Long to Double conversion
instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{
match(Set dst (ConvL2D src));
ins_cost(DEFAULT_COST + MEMORY_REF_COST);
*** 10974,10983 ****
--- 11250,11272 ----
moveL2D_stack_reg(tmpD, src);
convL2DRaw_regD(dst, tmpD);
%}
%}
+ // Long to Double conversion. Special version for Power8.
+ instruct convL2D_reg_mtfprd_Ex(regD dst, iRegLsrc src) %{
+ match(Set dst (ConvL2D src));
+ predicate(VM_Version::has_mtfprd());
+ ins_cost(DEFAULT_COST);
+
+ expand %{
+ regD tmpD;
+ moveL2D_reg(tmpD, src);
+ convL2DRaw_regD(dst, tmpD); // Convert to double.
+ %}
+ %}
+
instruct convF2D_reg(regD dst, regF src) %{
match(Set dst (ConvF2D src));
format %{ "FMR $dst, $src \t// float->double" %}
// variable size, 0 or 4
ins_encode %{
< prev index next >