hotspot/src/cpu/aarch64/vm/aarch64_ad.m4
changeset 29184 e234025cafb6
child 29190 9917b8aed927
equal deleted inserted replaced
29183:0cc8699f7372 29184:e234025cafb6
       
     1 dnl Copyright (c) 2014, Red Hat Inc. All rights reserved.
       
     2 dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3 dnl
       
     4 dnl This code is free software; you can redistribute it and/or modify it
       
     5 dnl under the terms of the GNU General Public License version 2 only, as
       
     6 dnl published by the Free Software Foundation.
       
     7 dnl
       
     8 dnl This code is distributed in the hope that it will be useful, but WITHOUT
       
     9 dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    10 dnl FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    11 dnl version 2 for more details (a copy is included in the LICENSE file that
       
    12 dnl accompanied this code).
       
    13 dnl
       
    14 dnl You should have received a copy of the GNU General Public License version
       
    15 dnl 2 along with this work; if not, write to the Free Software Foundation,
       
    16 dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    17 dnl
       
    18 dnl Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    19 dnl or visit www.oracle.com if you need additional information or have any
       
    20 dnl questions.
       
    21 dnl
       
    22 dnl 
       
    23 dnl Process this file with m4 aarch64_ad.m4 to generate the arithmetic
       
    24 dnl and shift patterns patterns used in aarch64.ad.
       
    25 dnl
       
    26 // BEGIN This section of the file is automatically generated. Do not edit --------------
       
    27 
       
    28 define(`BASE_SHIFT_INSN',
       
    29 `
       
    30 instruct $2$1_reg_$4_reg(iReg$1NoSp dst,
       
    31                          iReg$1 src1, iReg$1 src2,
       
    32                          immI src3, rFlagsReg cr) %{
       
    33   match(Set dst ($2$1 src1 ($4$1 src2 src3)));
       
    34 
       
    35   ins_cost(1.9 * INSN_COST);
       
    36   format %{ "$3  $dst, $src1, $src2, $5 $src3" %}
       
    37 
       
    38   ins_encode %{
       
    39     __ $3(as_Register($dst$$reg),
       
    40               as_Register($src1$$reg),
       
    41               as_Register($src2$$reg),
       
    42               Assembler::$5,
       
    43               $src3$$constant & 0x3f);
       
    44   %}
       
    45 
       
    46   ins_pipe(ialu_reg_reg_shift);
       
    47 %}')dnl
       
    48 define(`BASE_INVERTED_INSN',
       
    49 `
       
    50 instruct $2$1_reg_not_reg(iReg$1NoSp dst,
       
    51                          iReg$1 src1, iReg$1 src2, imm$1_M1 m1,
       
    52                          rFlagsReg cr) %{
       
    53 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
       
    54 dnl into this canonical form.
       
    55   ifelse($2,Xor,
       
    56     match(Set dst (Xor$1 m1 (Xor$1 src2 src1)));,
       
    57     match(Set dst ($2$1 src1 (Xor$1 src2 m1)));)
       
    58   ins_cost(INSN_COST);
       
    59   format %{ "$3  $dst, $src1, $src2" %}
       
    60 
       
    61   ins_encode %{
       
    62     __ $3(as_Register($dst$$reg),
       
    63               as_Register($src1$$reg),
       
    64               as_Register($src2$$reg),
       
    65               Assembler::LSL, 0);
       
    66   %}
       
    67 
       
    68   ins_pipe(ialu_reg_reg);
       
    69 %}')dnl
       
    70 define(`INVERTED_SHIFT_INSN',
       
    71 `
       
    72 instruct $2$1_reg_$4_not_reg(iReg$1NoSp dst,
       
    73                          iReg$1 src1, iReg$1 src2,
       
    74                          immI src3, imm$1_M1 src4, rFlagsReg cr) %{
       
    75 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
       
    76 dnl into this canonical form.
       
    77   ifelse($2,Xor,
       
    78     match(Set dst ($2$1 src4 (Xor$1($4$1 src2 src3) src1)));,
       
    79     match(Set dst ($2$1 src1 (Xor$1($4$1 src2 src3) src4)));)
       
    80   ins_cost(1.9 * INSN_COST);
       
    81   format %{ "$3  $dst, $src1, $src2, $5 $src3" %}
       
    82 
       
    83   ins_encode %{
       
    84     __ $3(as_Register($dst$$reg),
       
    85               as_Register($src1$$reg),
       
    86               as_Register($src2$$reg),
       
    87               Assembler::$5,
       
    88               $src3$$constant & 0x3f);
       
    89   %}
       
    90 
       
    91   ins_pipe(ialu_reg_reg_shift);
       
    92 %}')dnl
       
    93 define(`NOT_INSN',
       
    94 `instruct reg$1_not_reg(iReg$1NoSp dst,
       
    95                          iReg$1 src1, imm$1_M1 m1,
       
    96                          rFlagsReg cr) %{
       
    97   match(Set dst (Xor$1 src1 m1));
       
    98   ins_cost(INSN_COST);
       
    99   format %{ "$2  $dst, $src1, zr" %}
       
   100 
       
   101   ins_encode %{
       
   102     __ $2(as_Register($dst$$reg),
       
   103               as_Register($src1$$reg),
       
   104               zr,
       
   105               Assembler::LSL, 0);
       
   106   %}
       
   107 
       
   108   ins_pipe(ialu_reg);
       
   109 %}')dnl
       
   110 dnl
       
   111 define(`BOTH_SHIFT_INSNS',
       
   112 `BASE_SHIFT_INSN(I, $1, ifelse($2,andr,andw,$2w), $3, $4)
       
   113 BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl
       
   114 dnl
       
   115 define(`BOTH_INVERTED_INSNS',
       
   116 `BASE_INVERTED_INSN(I, $1, $2, $3, $4)
       
   117 BASE_INVERTED_INSN(L, $1, $2, $3, $4)')dnl
       
   118 dnl
       
   119 define(`BOTH_INVERTED_SHIFT_INSNS',
       
   120 `INVERTED_SHIFT_INSN(I, $1, $2w, $3, $4, ~0, int)
       
   121 INVERTED_SHIFT_INSN(L, $1, $2, $3, $4, ~0l, long)')dnl
       
   122 dnl
       
   123 define(`ALL_SHIFT_KINDS',
       
   124 `BOTH_SHIFT_INSNS($1, $2, URShift, LSR)
       
   125 BOTH_SHIFT_INSNS($1, $2, RShift, ASR)
       
   126 BOTH_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
       
   127 dnl
       
   128 define(`ALL_INVERTED_SHIFT_KINDS',
       
   129 `BOTH_INVERTED_SHIFT_INSNS($1, $2, URShift, LSR)
       
   130 BOTH_INVERTED_SHIFT_INSNS($1, $2, RShift, ASR)
       
   131 BOTH_INVERTED_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
       
   132 dnl
       
   133 NOT_INSN(L, eon)
       
   134 NOT_INSN(I, eonw)
       
   135 BOTH_INVERTED_INSNS(And, bic)
       
   136 BOTH_INVERTED_INSNS(Or, orn)
       
   137 BOTH_INVERTED_INSNS(Xor, eon)
       
   138 ALL_INVERTED_SHIFT_KINDS(And, bic)
       
   139 ALL_INVERTED_SHIFT_KINDS(Xor, eon)
       
   140 ALL_INVERTED_SHIFT_KINDS(Or, orn)
       
   141 ALL_SHIFT_KINDS(And, andr)
       
   142 ALL_SHIFT_KINDS(Xor, eor)
       
   143 ALL_SHIFT_KINDS(Or, orr)
       
   144 ALL_SHIFT_KINDS(Add, add)
       
   145 ALL_SHIFT_KINDS(Sub, sub)
       
   146 dnl
       
   147 dnl EXTEND mode, rshift_op, src, lshift_count, rshift_count
       
   148 define(`EXTEND', `($2$1 (LShift$1 $3 $4) $5)')
       
   149 define(`BFM_INSN',`
       
   150 // Shift Left followed by Shift Right.
       
   151 // This idiom is used by the compiler for the i2b bytecode etc.
       
   152 instruct $4$1(iReg$1NoSp dst, iReg$1 src, immI lshift_count, immI rshift_count)
       
   153 %{
       
   154   match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count));
       
   155   // Make sure we are not going to exceed what $4 can do.
       
   156   predicate((unsigned int)n->in(2)->get_int() <= $2
       
   157             && (unsigned int)n->in(1)->in(2)->get_int() <= $2);
       
   158 
       
   159   ins_cost(INSN_COST * 2);
       
   160   format %{ "$4  $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %}
       
   161   ins_encode %{
       
   162     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
       
   163     int s = $2 - lshift;
       
   164     int r = (rshift - lshift) & $2;
       
   165     __ $4(as_Register($dst$$reg),
       
   166 	    as_Register($src$$reg),
       
   167 	    r, s);
       
   168   %}
       
   169 
       
   170   ins_pipe(ialu_reg_shift);
       
   171 %}')
       
   172 BFM_INSN(L, 63, RShift, sbfm)
       
   173 BFM_INSN(I, 31, RShift, sbfmw)
       
   174 BFM_INSN(L, 63, URShift, ubfm)
       
   175 BFM_INSN(I, 31, URShift, ubfmw)
       
   176 dnl
       
   177 // Bitfield extract with shift & mask
       
   178 define(`BFX_INSN',
       
   179 `instruct $3$1(iReg$1NoSp dst, iReg$1 src, immI rshift, imm$1_bitmask mask)
       
   180 %{
       
   181   match(Set dst (And$1 ($2$1 src rshift) mask));
       
   182 
       
   183   ins_cost(INSN_COST);
       
   184   format %{ "$3 $dst, $src, $mask" %}
       
   185   ins_encode %{
       
   186     int rshift = $rshift$$constant;
       
   187     long mask = $mask$$constant;
       
   188     int width = exact_log2(mask+1);
       
   189     __ $3(as_Register($dst$$reg),
       
   190 	    as_Register($src$$reg), rshift, width);
       
   191   %}
       
   192   ins_pipe(ialu_reg_shift);
       
   193 %}')
       
   194 BFX_INSN(I,URShift,ubfxw)
       
   195 BFX_INSN(L,URShift,ubfx)
       
   196 
       
   197 // We can use ubfx when extending an And with a mask when we know mask
       
   198 // is positive.  We know that because immI_bitmask guarantees it.
       
   199 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
       
   200 %{
       
   201   match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
       
   202 
       
   203   ins_cost(INSN_COST * 2);
       
   204   format %{ "ubfx $dst, $src, $mask" %}
       
   205   ins_encode %{
       
   206     int rshift = $rshift$$constant;
       
   207     long mask = $mask$$constant;
       
   208     int width = exact_log2(mask+1);
       
   209     __ ubfx(as_Register($dst$$reg),
       
   210 	    as_Register($src$$reg), rshift, width);
       
   211   %}
       
   212   ins_pipe(ialu_reg_shift);
       
   213 %}
       
   214 
       
   215 // Rotations
       
   216 
       
   217 define(`EXTRACT_INSN',
       
   218 `instruct extr$3$1(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI lshift, immI rshift, rFlagsReg cr)
       
   219 %{
       
   220   match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift)));
       
   221   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2));
       
   222 
       
   223   ins_cost(INSN_COST);
       
   224   format %{ "extr $dst, $src1, $src2, #$rshift" %}
       
   225 
       
   226   ins_encode %{
       
   227     __ $4(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
       
   228             $rshift$$constant & $2);
       
   229   %}
       
   230   ins_pipe(ialu_reg_reg_extr);
       
   231 %}
       
   232 ')dnl
       
   233 EXTRACT_INSN(L, 63, Or, extr)
       
   234 EXTRACT_INSN(I, 31, Or, extrw)
       
   235 EXTRACT_INSN(L, 63, Add, extr)
       
   236 EXTRACT_INSN(I, 31, Add, extrw)
       
   237 define(`ROL_EXPAND', `
       
   238 // $2 expander
       
   239 
       
   240 instruct $2$1_rReg(iReg$1 dst, iReg$1 src, iRegI shift, rFlagsReg cr)
       
   241 %{
       
   242   effect(DEF dst, USE src, USE shift);
       
   243 
       
   244   format %{ "$2    $dst, $src, $shift" %}
       
   245   ins_cost(INSN_COST * 3);
       
   246   ins_encode %{
       
   247     __ subw(rscratch1, zr, as_Register($shift$$reg));
       
   248     __ $3(as_Register($dst$$reg), as_Register($src$$reg),
       
   249 	    rscratch1);
       
   250     %}
       
   251   ins_pipe(ialu_reg_reg_vshift);
       
   252 %}')dnl
       
   253 define(`ROR_EXPAND', `
       
   254 // $2 expander
       
   255 
       
   256 instruct $2$1_rReg(iReg$1 dst, iReg$1 src, iRegI shift, rFlagsReg cr)
       
   257 %{
       
   258   effect(DEF dst, USE src, USE shift);
       
   259 
       
   260   format %{ "$2    $dst, $src, $shift" %}
       
   261   ins_cost(INSN_COST);
       
   262   ins_encode %{
       
   263     __ $3(as_Register($dst$$reg), as_Register($src$$reg),
       
   264 	    as_Register($shift$$reg));
       
   265     %}
       
   266   ins_pipe(ialu_reg_reg_vshift);
       
   267 %}')dnl
       
   268 define(ROL_INSN, `
       
   269 instruct $3$1_rReg_Var_C$2(iRegL dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
       
   270 %{
       
   271   match(Set dst (Or$1 (LShift$1 src shift) (URShift$1 src (SubI c$2 shift))));
       
   272 
       
   273   expand %{
       
   274     $3L_rReg(dst, src, shift, cr);
       
   275   %}
       
   276 %}')dnl
       
   277 define(ROR_INSN, `
       
   278 instruct $3$1_rReg_Var_C$2(iRegL dst, iRegL src, iRegI shift, immI$2 c$2, rFlagsReg cr)
       
   279 %{
       
   280   match(Set dst (Or$1 (URShift$1 src shift) (LShift$1 src (SubI c$2 shift))));
       
   281 
       
   282   expand %{
       
   283     $3L_rReg(dst, src, shift, cr);
       
   284   %}
       
   285 %}')dnl
       
   286 ROL_EXPAND(L, rol, rorv)
       
   287 ROL_EXPAND(I, rol, rorvw)
       
   288 ROL_INSN(L, _64, rol)
       
   289 ROL_INSN(L, 0, rol)
       
   290 ROL_INSN(I, _32, rol)
       
   291 ROL_INSN(I, 0, rol)
       
   292 ROR_EXPAND(L, ror, rorv)
       
   293 ROR_EXPAND(I, ror, rorvw)
       
   294 ROR_INSN(L, _64, ror)
       
   295 ROR_INSN(L, 0, ror)
       
   296 ROR_INSN(I, _32, ror)
       
   297 ROR_INSN(I, 0, ror)
       
   298 
       
   299 // Add/subtract (extended)
       
   300 dnl ADD_SUB_EXTENDED(mode, size, add node, shift node, insn, shift type, wordsize
       
   301 define(`ADD_SUB_CONV', `
       
   302 instruct $3Ext$1(iReg$2NoSp dst, iReg$2 src1, iReg$1orL2I src2, rFlagsReg cr)
       
   303 %{
       
   304   match(Set dst ($3$2 src1 (ConvI2L src2)));
       
   305   ins_cost(INSN_COST);
       
   306   format %{ "$4  $dst, $src1, $5 $src2" %}
       
   307 
       
   308    ins_encode %{
       
   309      __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
       
   310             as_Register($src2$$reg), ext::$5);
       
   311    %}
       
   312   ins_pipe(ialu_reg_reg);
       
   313 %}')dnl
       
   314 ADD_SUB_CONV(I,L,Add,add,sxtw);
       
   315 ADD_SUB_CONV(I,L,Sub,sub,sxtw);
       
   316 dnl
       
   317 define(`ADD_SUB_EXTENDED', `
       
   318 instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, immI_`'eval($7-$2) lshift, immI_`'eval($7-$2) rshift, rFlagsReg cr)
       
   319 %{
       
   320   match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
       
   321   ins_cost(INSN_COST);
       
   322   format %{ "$5  $dst, $src1, $6 $src2" %}
       
   323 
       
   324    ins_encode %{
       
   325      __ $5(as_Register($dst$$reg), as_Register($src1$$reg),
       
   326             as_Register($src2$$reg), ext::$6);
       
   327    %}
       
   328   ins_pipe(ialu_reg_reg);
       
   329 %}')
       
   330 ADD_SUB_EXTENDED(I,16,Add,RShift,add,sxth,32)
       
   331 ADD_SUB_EXTENDED(I,8,Add,RShift,add,sxtb,32)
       
   332 ADD_SUB_EXTENDED(I,8,Add,URShift,add,uxtb,32)
       
   333 ADD_SUB_EXTENDED(L,16,Add,RShift,add,sxth,64)
       
   334 ADD_SUB_EXTENDED(L,32,Add,RShift,add,sxtw,64)
       
   335 ADD_SUB_EXTENDED(L,8,Add,RShift,add,sxtb,64)
       
   336 ADD_SUB_EXTENDED(L,8,Add,URShift,add,uxtb,64)
       
   337 dnl
       
   338 dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, shift type)
       
   339 define(`ADD_SUB_ZERO_EXTEND', `
       
   340 instruct $3Ext$1_$5_and(iReg$1NoSp dst, iReg$1 src1, iReg$1 src2, imm$1_$2 mask, rFlagsReg cr)
       
   341 %{
       
   342   match(Set dst ($3$1 src1 (And$1 src2 mask)));
       
   343   ins_cost(INSN_COST);
       
   344   format %{ "$4  $dst, $src1, $src2, $5" %}
       
   345 
       
   346    ins_encode %{
       
   347      __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
       
   348             as_Register($src2$$reg), ext::$5);
       
   349    %}
       
   350   ins_pipe(ialu_reg_reg);
       
   351 %}')
       
   352 dnl
       
   353 ADD_SUB_ZERO_EXTEND(I,255,Add,addw,uxtb)
       
   354 ADD_SUB_ZERO_EXTEND(I,65535,Add,addw,uxth)
       
   355 ADD_SUB_ZERO_EXTEND(L,255,Add,add,uxtb)
       
   356 ADD_SUB_ZERO_EXTEND(L,65535,Add,add,uxth)
       
   357 ADD_SUB_ZERO_EXTEND(L,4294967295,Add,add,uxtw)
       
   358 dnl
       
   359 ADD_SUB_ZERO_EXTEND(I,255,Sub,subw,uxtb)
       
   360 ADD_SUB_ZERO_EXTEND(I,65535,Sub,subw,uxth)
       
   361 ADD_SUB_ZERO_EXTEND(L,255,Sub,sub,uxtb)
       
   362 ADD_SUB_ZERO_EXTEND(L,65535,Sub,sub,uxth)
       
   363 ADD_SUB_ZERO_EXTEND(L,4294967295,Sub,sub,uxtw)
       
   364 
       
   365 // END This section of the file is automatically generated. Do not edit --------------