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);
|