< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page
rev 12410 : 8171410: aarch64: long multiplyExact shifts by 31 instead of 63
Reviewed-by: aph


14069             "cmp   rscratch1, rscratch1, sxtw\n\t"
14070             "b$cmp   $labl" %}
14071   ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
14072   ins_encode %{
14073     Label* L = $labl$$label;
14074     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14075     __ smull(rscratch1, $op1$$Register, $op2$$Register);
14076     __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
14077     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
14078   %}
14079 
14080   ins_pipe(pipe_serial);
14081 %}
14082 
14083 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
14084 %{
14085   match(Set cr (OverflowMulL op1 op2));
14086 
14087   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
14088             "smulh rscratch2, $op1, $op2\n\t"
14089             "cmp   rscratch2, rscratch1, ASR #31\n\t"
14090             "movw  rscratch1, #0x80000000\n\t"
14091             "cselw rscratch1, rscratch1, zr, NE\n\t"
14092             "cmpw  rscratch1, #1" %}
14093   ins_cost(6 * INSN_COST);
14094   ins_encode %{
14095     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
14096     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
14097     __ cmp(rscratch2, rscratch1, Assembler::ASR, 31);    // Top is pure sign ext
14098     __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
14099     __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
14100     __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
14101   %}
14102 
14103   ins_pipe(pipe_slow);
14104 %}
14105 
14106 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
14107 %{
14108   match(If cmp (OverflowMulL op1 op2));
14109   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
14110             || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
14111   effect(USE labl, KILL cr);
14112 
14113   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
14114             "smulh rscratch2, $op1, $op2\n\t"
14115             "cmp   rscratch2, rscratch1, ASR #31\n\t"
14116             "b$cmp $labl" %}
14117   ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
14118   ins_encode %{
14119     Label* L = $labl$$label;
14120     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14121     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
14122     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
14123     __ cmp(rscratch2, rscratch1, Assembler::ASR, 31);    // Top is pure sign ext
14124     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
14125   %}
14126 
14127   ins_pipe(pipe_serial);
14128 %}
14129 
14130 // ============================================================================
14131 // Compare Instructions
14132 
14133 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
14134 %{
14135   match(Set cr (CmpI op1 op2));
14136 
14137   effect(DEF cr, USE op1, USE op2);
14138 
14139   ins_cost(INSN_COST);
14140   format %{ "cmpw  $op1, $op2" %}
14141 
14142   ins_encode(aarch64_enc_cmpw(op1, op2));
14143 




14069             "cmp   rscratch1, rscratch1, sxtw\n\t"
14070             "b$cmp   $labl" %}
14071   ins_cost(3 * INSN_COST); // Branch is rare so treat as INSN_COST
14072   ins_encode %{
14073     Label* L = $labl$$label;
14074     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14075     __ smull(rscratch1, $op1$$Register, $op2$$Register);
14076     __ subs(zr, rscratch1, rscratch1, ext::sxtw);      // NE => overflow
14077     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
14078   %}
14079 
14080   ins_pipe(pipe_serial);
14081 %}
14082 
14083 instruct overflowMulL_reg(rFlagsReg cr, iRegL op1, iRegL op2)
14084 %{
14085   match(Set cr (OverflowMulL op1 op2));
14086 
14087   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
14088             "smulh rscratch2, $op1, $op2\n\t"
14089             "cmp   rscratch2, rscratch1, ASR #63\n\t"
14090             "movw  rscratch1, #0x80000000\n\t"
14091             "cselw rscratch1, rscratch1, zr, NE\n\t"
14092             "cmpw  rscratch1, #1" %}
14093   ins_cost(6 * INSN_COST);
14094   ins_encode %{
14095     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
14096     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
14097     __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
14098     __ movw(rscratch1, 0x80000000);                    // Develop 0 (EQ),
14099     __ cselw(rscratch1, rscratch1, zr, Assembler::NE); // or 0x80000000 (NE)
14100     __ cmpw(rscratch1, 1);                             // 0x80000000 - 1 => VS
14101   %}
14102 
14103   ins_pipe(pipe_slow);
14104 %}
14105 
14106 instruct overflowMulL_reg_branch(cmpOp cmp, iRegL op1, iRegL op2, label labl, rFlagsReg cr)
14107 %{
14108   match(If cmp (OverflowMulL op1 op2));
14109   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::overflow
14110             || n->in(1)->as_Bool()->_test._test == BoolTest::no_overflow);
14111   effect(USE labl, KILL cr);
14112 
14113   format %{ "mul   rscratch1, $op1, $op2\t#overflow check long\n\t"
14114             "smulh rscratch2, $op1, $op2\n\t"
14115             "cmp   rscratch2, rscratch1, ASR #63\n\t"
14116             "b$cmp $labl" %}
14117   ins_cost(4 * INSN_COST); // Branch is rare so treat as INSN_COST
14118   ins_encode %{
14119     Label* L = $labl$$label;
14120     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
14121     __ mul(rscratch1, $op1$$Register, $op2$$Register);   // Result bits 0..63
14122     __ smulh(rscratch2, $op1$$Register, $op2$$Register); // Result bits 64..127
14123     __ cmp(rscratch2, rscratch1, Assembler::ASR, 63);    // Top is pure sign ext
14124     __ br(cond == Assembler::VS ? Assembler::NE : Assembler::EQ, *L);
14125   %}
14126 
14127   ins_pipe(pipe_serial);
14128 %}
14129 
14130 // ============================================================================
14131 // Compare Instructions
14132 
14133 instruct compI_reg_reg(rFlagsReg cr, iRegI op1, iRegI op2)
14134 %{
14135   match(Set cr (CmpI op1 op2));
14136 
14137   effect(DEF cr, USE op1, USE op2);
14138 
14139   ins_cost(INSN_COST);
14140   format %{ "cmpw  $op1, $op2" %}
14141 
14142   ins_encode(aarch64_enc_cmpw(op1, op2));
14143 


< prev index next >