diff -r 65ba11df4ffe src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Wed Oct 02 12:45:18 2013 +0200 +++ b/src/cpu/sparc/vm/sparc.ad Wed Oct 02 13:52:53 2013 +0200 @@ -1886,7 +1886,7 @@ } // Does the CPU require late expand (see block.cpp for description of late expand)? -const bool Matcher::require_late_expand = false; +const bool Matcher::require_late_expand = true; // Should the Matcher clone shifts on addressing modes, expecting them to // be subsumed into complex addressing expressions or compute them into @@ -7444,6 +7444,7 @@ // Register Division instruct divI_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ match(Set dst (DivI src1 src2)); + predicate(!UseNewCode); ins_cost((2+71)*DEFAULT_COST); format %{ "SRA $src2,0,$src2\n\t" @@ -7453,6 +7454,68 @@ ins_pipe(sdiv_reg_reg); %} +//------------------------------------------------------------------------------------ + +encode %{ + + enc_class lateExpandIdiv_reg_reg(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ + MachNode *m1 = new (C) divI_reg_reg_SRANode(); + MachNode *m2 = new (C) divI_reg_reg_SRANode(); + MachNode *m3 = new (C) divI_reg_reg_SDIVXNode(); + + m1->add_req(n_region, n_src1); + m2->add_req(n_region, n_src2); + m3->add_req(n_region, m1, m2); + + m1->_opnds[0] = _opnds[1]->clone(C); + m1->_opnds[1] = _opnds[1]->clone(C); + + m2->_opnds[0] = _opnds[2]->clone(C); + m2->_opnds[1] = _opnds[2]->clone(C); + + m3->_opnds[0] = _opnds[0]->clone(C); + m3->_opnds[1] = _opnds[1]->clone(C); + m3->_opnds[2] = _opnds[2]->clone(C); + + ra_->set1(m1->_idx, ra_->get_reg_first(n_src1)); + ra_->set1(m2->_idx, ra_->get_reg_first(n_src2)); + ra_->set1(m3->_idx, ra_->get_reg_first(this)); + + nodes->push(m1); + nodes->push(m2); + nodes->push(m3); + %} +%} + +instruct divI_reg_reg_SRA(iRegIsafe dst) %{ + effect(USE_DEF dst); + size(4); + format %{ "SRA $dst,0,$dst\n\t" %} + ins_encode %{ __ sra($dst$$Register, 0, $dst$$Register); %} + ins_pipe(ialu_reg_reg); +%} + +instruct divI_reg_reg_SDIVX(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ + effect(DEF dst, USE src1, USE src2); + size(4); + format %{ "SDIVX $src1,$src2,$dst\n\t" %} + ins_encode %{ __ sdivx($dst$$Register, 0, $dst$$Register); %} + ins_pipe(sdiv_reg_reg); +%} + +instruct divI_reg_reg_Ex(iRegI dst, iRegIsafe src1, iRegIsafe src2) %{ + match(Set dst (DivI src1 src2)); + predicate(UseNewCode); + ins_cost((2+71)*DEFAULT_COST); + + format %{ "SRA $src2,0,$src2\n\t" + "SRA $src1,0,$src1\n\t" + "SDIVX $src1,$src2,$dst" %} + lateExpand( lateExpandIdiv_reg_reg(src1, src2, dst) ); +%} + +//------------------------------------------------------------------------------------ + // Immediate Division instruct divI_reg_imm13(iRegI dst, iRegIsafe src1, immI13 src2) %{ match(Set dst (DivI src1 src2));