< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page
rev 9428 : 8144028: Use AArch64 bit-test instructions in C2
Reviewed-by: kvn


4289   %}
4290 
4291 
4292   // auxiliary used for CompareAndSwapX to set result register
4293   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
4294     MacroAssembler _masm(&cbuf);
4295     Register res_reg = as_Register($res$$reg);
4296     __ cset(res_reg, Assembler::EQ);
4297   %}
4298 
4299   // prefetch encodings
4300 
4301   enc_class aarch64_enc_prefetchw(memory mem) %{
4302     MacroAssembler _masm(&cbuf);
4303     Register base = as_Register($mem$$base);
4304     int index = $mem$$index;
4305     int scale = $mem$$scale;
4306     int disp = $mem$$disp;
4307     if (index == -1) {
4308       __ prfm(Address(base, disp), PSTL1KEEP);
4309       __ nop();
4310     } else {
4311       Register index_reg = as_Register(index);
4312       if (disp == 0) {
4313         __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
4314       } else {
4315         __ lea(rscratch1, Address(base, disp));
4316         __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
4317       }
4318     }
4319   %}
4320 
4321   enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{
4322     MacroAssembler _masm(&cbuf);
4323     Register cnt_reg = as_Register($cnt$$reg);
4324     Register base_reg = as_Register($base$$reg);
4325     // base is word aligned
4326     // cnt is count of words
4327 
4328     Label loop;
4329     Label entry;


13826 %}
13827 
13828 instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
13829   match(If cmp (CmpP (DecodeN oop) zero));
13830   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13831             || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13832   effect(USE labl);
13833 
13834   ins_cost(BRANCH_COST);
13835   format %{ "cb$cmp   $oop, $labl" %}
13836   ins_encode %{
13837     Label* L = $labl$$label;
13838     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13839     if (cond == Assembler::EQ)
13840       __ cbzw($oop$$Register, *L);
13841     else
13842       __ cbnzw($oop$$Register, *L);
13843   %}
13844   ins_pipe(pipe_cmp_branch);
13845 %}





































































































































13846 
13847 // Conditional Far Branch
13848 // Conditional Far Branch Unsigned
13849 // TODO: fixme
13850 
13851 // counted loop end branch near
13852 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
13853 %{
13854   match(CountedLoopEnd cmp cr);
13855 
13856   effect(USE lbl);
13857 
13858   ins_cost(BRANCH_COST);
13859   // short variant.
13860   // ins_short_branch(1);
13861   format %{ "b$cmp $lbl \t// counted loop end" %}
13862 
13863   ins_encode(aarch64_enc_br_con(cmp, lbl));
13864 
13865   ins_pipe(pipe_branch);




4289   %}
4290 
4291 
4292   // auxiliary used for CompareAndSwapX to set result register
4293   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
4294     MacroAssembler _masm(&cbuf);
4295     Register res_reg = as_Register($res$$reg);
4296     __ cset(res_reg, Assembler::EQ);
4297   %}
4298 
4299   // prefetch encodings
4300 
4301   enc_class aarch64_enc_prefetchw(memory mem) %{
4302     MacroAssembler _masm(&cbuf);
4303     Register base = as_Register($mem$$base);
4304     int index = $mem$$index;
4305     int scale = $mem$$scale;
4306     int disp = $mem$$disp;
4307     if (index == -1) {
4308       __ prfm(Address(base, disp), PSTL1KEEP);

4309     } else {
4310       Register index_reg = as_Register(index);
4311       if (disp == 0) {
4312         __ prfm(Address(base, index_reg, Address::lsl(scale)), PSTL1KEEP);
4313       } else {
4314         __ lea(rscratch1, Address(base, disp));
4315         __ prfm(Address(rscratch1, index_reg, Address::lsl(scale)), PSTL1KEEP);
4316       }
4317     }
4318   %}
4319 
4320   enc_class aarch64_enc_clear_array_reg_reg(iRegL_R11 cnt, iRegP_R10 base) %{
4321     MacroAssembler _masm(&cbuf);
4322     Register cnt_reg = as_Register($cnt$$reg);
4323     Register base_reg = as_Register($base$$reg);
4324     // base is word aligned
4325     // cnt is count of words
4326 
4327     Label loop;
4328     Label entry;


13825 %}
13826 
13827 instruct cmpP_narrowOop_imm0_branch(cmpOp cmp, iRegN oop, immP0 zero, label labl, rFlagsReg cr) %{
13828   match(If cmp (CmpP (DecodeN oop) zero));
13829   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::ne
13830             || n->in(1)->as_Bool()->_test._test == BoolTest::eq);
13831   effect(USE labl);
13832 
13833   ins_cost(BRANCH_COST);
13834   format %{ "cb$cmp   $oop, $labl" %}
13835   ins_encode %{
13836     Label* L = $labl$$label;
13837     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13838     if (cond == Assembler::EQ)
13839       __ cbzw($oop$$Register, *L);
13840     else
13841       __ cbnzw($oop$$Register, *L);
13842   %}
13843   ins_pipe(pipe_cmp_branch);
13844 %}
13845 
13846 // Test bit and Branch
13847 
13848 instruct cmpL_branch_sign(cmpOp cmp, iRegL op1, immL0 op2, label labl, rFlagsReg cr) %{
13849   match(If cmp (CmpL op1 op2));
13850   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13851             || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13852   effect(USE labl);
13853 
13854   ins_cost(BRANCH_COST);
13855   format %{ "cb$cmp   $op1, $labl # long" %}
13856   ins_encode %{
13857     Label* L = $labl$$label;
13858     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13859     if (cond == Assembler::LT)
13860       __ tbnz($op1$$Register, 63, *L);
13861     else
13862       __ tbz($op1$$Register, 63, *L);
13863   %}
13864   ins_pipe(pipe_cmp_branch);
13865 %}
13866 
13867 instruct cmpI_branch_sign(cmpOp cmp, iRegIorL2I op1, immI0 op2, label labl, rFlagsReg cr) %{
13868   match(If cmp (CmpI op1 op2));
13869   predicate(n->in(1)->as_Bool()->_test._test == BoolTest::lt
13870             || n->in(1)->as_Bool()->_test._test == BoolTest::ge);
13871   effect(USE labl);
13872 
13873   ins_cost(BRANCH_COST);
13874   format %{ "cb$cmp   $op1, $labl # int" %}
13875   ins_encode %{
13876     Label* L = $labl$$label;
13877     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13878     if (cond == Assembler::LT)
13879       __ tbnz($op1$$Register, 31, *L);
13880     else
13881       __ tbz($op1$$Register, 31, *L);
13882   %}
13883   ins_pipe(pipe_cmp_branch);
13884 %}
13885 
13886 instruct cmpL_branch_bit(cmpOp cmp, iRegL op1, immL op2, immL0 op3, label labl, rFlagsReg cr) %{
13887   match(If cmp (CmpL (AndL op1 op2) op3));
13888   predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13889             || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13890             && is_power_of_2(n->in(2)->in(1)->in(2)->get_long()));
13891   effect(USE labl);
13892 
13893   ins_cost(BRANCH_COST);
13894   format %{ "tb$cmp   $op1, $op2, $labl" %}
13895   ins_encode %{
13896     Label* L = $labl$$label;
13897     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13898     int bit = exact_log2($op2$$constant);
13899     if (cond == Assembler::EQ)
13900       __ tbz($op1$$Register, bit, *L);
13901     else
13902       __ tbnz($op1$$Register, bit, *L);
13903   %}
13904   ins_pipe(pipe_cmp_branch);
13905 %}
13906 
13907 instruct cmpI_branch_bit(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, label labl, rFlagsReg cr) %{
13908   match(If cmp (CmpI (AndI op1 op2) op3));
13909   predicate((n->in(1)->as_Bool()->_test._test == BoolTest::ne
13910             || n->in(1)->as_Bool()->_test._test == BoolTest::eq)
13911             && is_power_of_2(n->in(2)->in(1)->in(2)->get_int()));
13912   effect(USE labl);
13913 
13914   ins_cost(BRANCH_COST);
13915   format %{ "tb$cmp   $op1, $op2, $labl" %}
13916   ins_encode %{
13917     Label* L = $labl$$label;
13918     Assembler::Condition cond = (Assembler::Condition)$cmp$$cmpcode;
13919     int bit = exact_log2($op2$$constant);
13920     if (cond == Assembler::EQ)
13921       __ tbz($op1$$Register, bit, *L);
13922     else
13923       __ tbnz($op1$$Register, bit, *L);
13924   %}
13925   ins_pipe(pipe_cmp_branch);
13926 %}
13927 
13928 // Test bits
13929 
13930 instruct cmpL_and(cmpOp cmp, iRegL op1, immL op2, immL0 op3, rFlagsReg cr) %{
13931   match(Set cr (CmpL (AndL op1 op2) op3));
13932   predicate(Assembler::operand_valid_for_logical_immediate
13933             (/*is_32*/false, n->in(1)->in(2)->get_long()));
13934 
13935   ins_cost(INSN_COST);
13936   format %{ "tst $op1, $op2 # long" %}
13937   ins_encode %{
13938     __ tst($op1$$Register, $op2$$constant);
13939   %}
13940   ins_pipe(ialu_reg_reg);
13941 %}
13942 
13943 instruct cmpI_and(cmpOp cmp, iRegIorL2I op1, immI op2, immI0 op3, rFlagsReg cr) %{
13944   match(Set cr (CmpI (AndI op1 op2) op3));
13945   predicate(Assembler::operand_valid_for_logical_immediate
13946             (/*is_32*/true, n->in(1)->in(2)->get_int()));
13947 
13948   ins_cost(INSN_COST);
13949   format %{ "tst $op1, $op2 # int" %}
13950   ins_encode %{
13951     __ tstw($op1$$Register, $op2$$constant);
13952   %}
13953   ins_pipe(ialu_reg_reg);
13954 %}
13955 
13956 instruct cmpL_and_reg(cmpOp cmp, iRegL op1, iRegL op2, immL0 op3, rFlagsReg cr) %{
13957   match(Set cr (CmpL (AndL op1 op2) op3));
13958 
13959   ins_cost(INSN_COST);
13960   format %{ "tst $op1, $op2 # long" %}
13961   ins_encode %{
13962     __ tst($op1$$Register, $op2$$Register);
13963   %}
13964   ins_pipe(ialu_reg_reg);
13965 %}
13966 
13967 instruct cmpI_and_reg(cmpOp cmp, iRegIorL2I op1, iRegIorL2I op2, immI0 op3, rFlagsReg cr) %{
13968   match(Set cr (CmpI (AndI op1 op2) op3));
13969 
13970   ins_cost(INSN_COST);
13971   format %{ "tstw $op1, $op2 # int" %}
13972   ins_encode %{
13973     __ tstw($op1$$Register, $op2$$Register);
13974   %}
13975   ins_pipe(ialu_reg_reg);
13976 %}
13977 
13978 
13979 // Conditional Far Branch
13980 // Conditional Far Branch Unsigned
13981 // TODO: fixme
13982 
13983 // counted loop end branch near
13984 instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
13985 %{
13986   match(CountedLoopEnd cmp cr);
13987 
13988   effect(USE lbl);
13989 
13990   ins_cost(BRANCH_COST);
13991   // short variant.
13992   // ins_short_branch(1);
13993   format %{ "b$cmp $lbl \t// counted loop end" %}
13994 
13995   ins_encode(aarch64_enc_br_con(cmp, lbl));
13996 
13997   ins_pipe(pipe_branch);


< prev index next >