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 dnl
  28 define(`ORL2I', `ifelse($1,I,orL2I)')
  29 dnl
  30 define(`BASE_SHIFT_INSN',
  31 `
  32 instruct $2$1_reg_$4_reg(iReg$1NoSp dst,
  33                          iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2,
  34                          immI src3, rFlagsReg cr) %{
  35   match(Set dst ($2$1 src1 ($4$1 src2 src3)));
  36 
  37   ins_cost(1.9 * INSN_COST);
  38   format %{ "$3  $dst, $src1, $src2, $5 $src3" %}
  39 
  40   ins_encode %{
  41     __ $3(as_Register($dst$$reg),
  42               as_Register($src1$$reg),
  43               as_Register($src2$$reg),
  44               Assembler::$5,
  45               $src3$$constant & ifelse($1,I,0x1f,0x3f));
  46   %}
  47 
  48   ins_pipe(ialu_reg_reg_shift);
  49 %}')dnl
  50 define(`BASE_INVERTED_INSN',
  51 `
  52 instruct $2$1_reg_not_reg(iReg$1NoSp dst,
  53                          iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_M1 m1,
  54                          rFlagsReg cr) %{
  55 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
  56 dnl into this canonical form.
  57   ifelse($2,Xor,
  58     match(Set dst (Xor$1 m1 (Xor$1 src2 src1)));,
  59     match(Set dst ($2$1 src1 (Xor$1 src2 m1)));)
  60   ins_cost(INSN_COST);
  61   format %{ "$3  $dst, $src1, $src2" %}
  62 
  63   ins_encode %{
  64     __ $3(as_Register($dst$$reg),
  65               as_Register($src1$$reg),
  66               as_Register($src2$$reg),
  67               Assembler::LSL, 0);
  68   %}
  69 
  70   ins_pipe(ialu_reg_reg);
  71 %}')dnl
  72 define(`INVERTED_SHIFT_INSN',
  73 `
  74 instruct $2$1_reg_$4_not_reg(iReg$1NoSp dst,
  75                          iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2,
  76                          immI src3, imm$1_M1 src4, rFlagsReg cr) %{
  77 dnl This ifelse is because hotspot reassociates (xor (xor ..)..)
  78 dnl into this canonical form.
  79   ifelse($2,Xor,
  80     match(Set dst ($2$1 src4 (Xor$1($4$1 src2 src3) src1)));,
  81     match(Set dst ($2$1 src1 (Xor$1($4$1 src2 src3) src4)));)
  82   ins_cost(1.9 * INSN_COST);
  83   format %{ "$3  $dst, $src1, $src2, $5 $src3" %}
  84 
  85   ins_encode %{
  86     __ $3(as_Register($dst$$reg),
  87               as_Register($src1$$reg),
  88               as_Register($src2$$reg),
  89               Assembler::$5,
  90               $src3$$constant & ifelse($1,I,0x1f,0x3f));
  91   %}
  92 
  93   ins_pipe(ialu_reg_reg_shift);
  94 %}')dnl
  95 define(`NOT_INSN',
  96 `instruct reg$1_not_reg(iReg$1NoSp dst,
  97                          iReg$1`'ORL2I($1) src1, imm$1_M1 m1,
  98                          rFlagsReg cr) %{
  99   match(Set dst (Xor$1 src1 m1));
 100   ins_cost(INSN_COST);
 101   format %{ "$2  $dst, $src1, zr" %}
 102 
 103   ins_encode %{
 104     __ $2(as_Register($dst$$reg),
 105               as_Register($src1$$reg),
 106               zr,
 107               Assembler::LSL, 0);
 108   %}
 109 
 110   ins_pipe(ialu_reg);
 111 %}')dnl
 112 dnl
 113 define(`BOTH_SHIFT_INSNS',
 114 `BASE_SHIFT_INSN(I, $1, ifelse($2,andr,andw,$2w), $3, $4)
 115 BASE_SHIFT_INSN(L, $1, $2, $3, $4)')dnl
 116 dnl
 117 define(`BOTH_INVERTED_INSNS',
 118 `BASE_INVERTED_INSN(I, $1, $2w, $3, $4)
 119 BASE_INVERTED_INSN(L, $1, $2, $3, $4)')dnl
 120 dnl
 121 define(`BOTH_INVERTED_SHIFT_INSNS',
 122 `INVERTED_SHIFT_INSN(I, $1, $2w, $3, $4, ~0, int)
 123 INVERTED_SHIFT_INSN(L, $1, $2, $3, $4, ~0l, long)')dnl
 124 dnl
 125 define(`ALL_SHIFT_KINDS',
 126 `BOTH_SHIFT_INSNS($1, $2, URShift, LSR)
 127 BOTH_SHIFT_INSNS($1, $2, RShift, ASR)
 128 BOTH_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
 129 dnl
 130 define(`ALL_INVERTED_SHIFT_KINDS',
 131 `BOTH_INVERTED_SHIFT_INSNS($1, $2, URShift, LSR)
 132 BOTH_INVERTED_SHIFT_INSNS($1, $2, RShift, ASR)
 133 BOTH_INVERTED_SHIFT_INSNS($1, $2, LShift, LSL)')dnl
 134 dnl
 135 NOT_INSN(L, eon)
 136 NOT_INSN(I, eonw)
 137 BOTH_INVERTED_INSNS(And, bic)
 138 BOTH_INVERTED_INSNS(Or, orn)
 139 BOTH_INVERTED_INSNS(Xor, eon)
 140 ALL_INVERTED_SHIFT_KINDS(And, bic)
 141 ALL_INVERTED_SHIFT_KINDS(Xor, eon)
 142 ALL_INVERTED_SHIFT_KINDS(Or, orn)
 143 ALL_SHIFT_KINDS(And, andr)
 144 ALL_SHIFT_KINDS(Xor, eor)
 145 ALL_SHIFT_KINDS(Or, orr)
 146 ALL_SHIFT_KINDS(Add, add)
 147 ALL_SHIFT_KINDS(Sub, sub)
 148 dnl
 149 dnl EXTEND mode, rshift_op, src, lshift_count, rshift_count
 150 define(`EXTEND', `($2$1 (LShift$1 $3 $4) $5)')
 151 define(`BFM_INSN',`
 152 // Shift Left followed by Shift Right.
 153 // This idiom is used by the compiler for the i2b bytecode etc.
 154 instruct $4$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift_count, immI rshift_count)
 155 %{
 156   match(Set dst EXTEND($1, $3, src, lshift_count, rshift_count));
 157   // Make sure we are not going to exceed what $4 can do.
 158   predicate((unsigned int)n->in(2)->get_int() <= $2
 159             && (unsigned int)n->in(1)->in(2)->get_int() <= $2);
 160 
 161   ins_cost(INSN_COST * 2);
 162   format %{ "$4  $dst, $src, $rshift_count - $lshift_count, #$2 - $lshift_count" %}
 163   ins_encode %{
 164     int lshift = $lshift_count$$constant, rshift = $rshift_count$$constant;
 165     int s = $2 - lshift;
 166     int r = (rshift - lshift) & $2;
 167     __ $4(as_Register($dst$$reg),
 168             as_Register($src$$reg),
 169             r, s);
 170   %}
 171 
 172   ins_pipe(ialu_reg_shift);
 173 %}')
 174 BFM_INSN(L, 63, RShift, sbfm)
 175 BFM_INSN(I, 31, RShift, sbfmw)
 176 BFM_INSN(L, 63, URShift, ubfm)
 177 BFM_INSN(I, 31, URShift, ubfmw)
 178 dnl
 179 // Bitfield extract with shift & mask
 180 define(`BFX_INSN',
 181 `instruct $3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI rshift, imm$1_bitmask mask)
 182 %{
 183   match(Set dst (And$1 ($2$1 src rshift) mask));
 184 
 185   ins_cost(INSN_COST);
 186   format %{ "$3 $dst, $src, $mask" %}
 187   ins_encode %{
 188     int rshift = $rshift$$constant;
 189     long mask = $mask$$constant;
 190     int width = exact_log2(mask+1);
 191     __ $3(as_Register($dst$$reg),
 192             as_Register($src$$reg), rshift, width);
 193   %}
 194   ins_pipe(ialu_reg_shift);
 195 %}')
 196 BFX_INSN(I,URShift,ubfxw)
 197 BFX_INSN(L,URShift,ubfx)
 198 
 199 // We can use ubfx when extending an And with a mask when we know mask
 200 // is positive.  We know that because immI_bitmask guarantees it.
 201 instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask mask)
 202 %{
 203   match(Set dst (ConvI2L (AndI (URShiftI src rshift) mask)));
 204 
 205   ins_cost(INSN_COST * 2);
 206   format %{ "ubfx $dst, $src, $mask" %}
 207   ins_encode %{
 208     int rshift = $rshift$$constant;
 209     long mask = $mask$$constant;
 210     int width = exact_log2(mask+1);
 211     __ ubfx(as_Register($dst$$reg),
 212             as_Register($src$$reg), rshift, width);
 213   %}
 214   ins_pipe(ialu_reg_shift);
 215 %}
 216 
 217 // Rotations
 218 
 219 define(`EXTRACT_INSN',
 220 `instruct extr$3$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI lshift, immI rshift, rFlagsReg cr)
 221 %{
 222   match(Set dst ($3$1 (LShift$1 src1 lshift) (URShift$1 src2 rshift)));
 223   predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & $2));
 224 
 225   ins_cost(INSN_COST);
 226   format %{ "extr $dst, $src1, $src2, #$rshift" %}
 227 
 228   ins_encode %{
 229     __ $4(as_Register($dst$$reg), as_Register($src1$$reg), as_Register($src2$$reg),
 230             $rshift$$constant & $2);
 231   %}
 232   ins_pipe(ialu_reg_reg_extr);
 233 %}
 234 ')dnl
 235 EXTRACT_INSN(L, 63, Or, extr)
 236 EXTRACT_INSN(I, 31, Or, extrw)
 237 EXTRACT_INSN(L, 63, Add, extr)
 238 EXTRACT_INSN(I, 31, Add, extrw)
 239 define(`ROL_EXPAND', `
 240 // $2 expander
 241 
 242 instruct $2$1_rReg(iReg$1NoSp dst, iReg$1 src, iRegI shift, rFlagsReg cr)
 243 %{
 244   effect(DEF dst, USE src, USE shift);
 245 
 246   format %{ "$2    $dst, $src, $shift" %}
 247   ins_cost(INSN_COST * 3);
 248   ins_encode %{
 249     __ subw(rscratch1, zr, as_Register($shift$$reg));
 250     __ $3(as_Register($dst$$reg), as_Register($src$$reg),
 251             rscratch1);
 252     %}
 253   ins_pipe(ialu_reg_reg_vshift);
 254 %}')dnl
 255 define(`ROR_EXPAND', `
 256 // $2 expander
 257 
 258 instruct $2$1_rReg(iReg$1NoSp dst, iReg$1 src, iRegI shift, rFlagsReg cr)
 259 %{
 260   effect(DEF dst, USE src, USE shift);
 261 
 262   format %{ "$2    $dst, $src, $shift" %}
 263   ins_cost(INSN_COST);
 264   ins_encode %{
 265     __ $3(as_Register($dst$$reg), as_Register($src$$reg),
 266             as_Register($shift$$reg));
 267     %}
 268   ins_pipe(ialu_reg_reg_vshift);
 269 %}')dnl
 270 define(ROL_INSN, `
 271 instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
 272 %{
 273   match(Set dst (Or$1 (LShift$1 src shift) (URShift$1 src (SubI c$2 shift))));
 274 
 275   expand %{
 276     $3$1_rReg(dst, src, shift, cr);
 277   %}
 278 %}')dnl
 279 define(ROR_INSN, `
 280 instruct $3$1_rReg_Var_C$2(iReg$1NoSp dst, iReg$1 src, iRegI shift, immI$2 c$2, rFlagsReg cr)
 281 %{
 282   match(Set dst (Or$1 (URShift$1 src shift) (LShift$1 src (SubI c$2 shift))));
 283 
 284   expand %{
 285     $3$1_rReg(dst, src, shift, cr);
 286   %}
 287 %}')dnl
 288 ROL_EXPAND(L, rol, rorv)
 289 ROL_EXPAND(I, rol, rorvw)
 290 ROL_INSN(L, _64, rol)
 291 ROL_INSN(L, 0, rol)
 292 ROL_INSN(I, _32, rol)
 293 ROL_INSN(I, 0, rol)
 294 ROR_EXPAND(L, ror, rorv)
 295 ROR_EXPAND(I, ror, rorvw)
 296 ROR_INSN(L, _64, ror)
 297 ROR_INSN(L, 0, ror)
 298 ROR_INSN(I, _32, ror)
 299 ROR_INSN(I, 0, ror)
 300 
 301 // Add/subtract (extended)
 302 dnl ADD_SUB_EXTENDED(mode, size, add node, shift node, insn, shift type, wordsize
 303 define(`ADD_SUB_CONV', `
 304 instruct $3Ext$1(iReg$2NoSp dst, iReg$2`'ORL2I($2) src1, iReg$1`'ORL2I($1) src2, rFlagsReg cr)
 305 %{
 306   match(Set dst ($3$2 src1 (ConvI2L src2)));
 307   ins_cost(INSN_COST);
 308   format %{ "$4  $dst, $src1, $5 $src2" %}
 309 
 310    ins_encode %{
 311      __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
 312             as_Register($src2$$reg), ext::$5);
 313    %}
 314   ins_pipe(ialu_reg_reg);
 315 %}')dnl
 316 ADD_SUB_CONV(I,L,Add,add,sxtw);
 317 ADD_SUB_CONV(I,L,Sub,sub,sxtw);
 318 dnl
 319 define(`ADD_SUB_EXTENDED', `
 320 instruct $3Ext$1_$6(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, immI_`'eval($7-$2) lshift, immI_`'eval($7-$2) rshift, rFlagsReg cr)
 321 %{
 322   match(Set dst ($3$1 src1 EXTEND($1, $4, src2, lshift, rshift)));
 323   ins_cost(INSN_COST);
 324   format %{ "$5  $dst, $src1, $6 $src2" %}
 325 
 326    ins_encode %{
 327      __ $5(as_Register($dst$$reg), as_Register($src1$$reg),
 328             as_Register($src2$$reg), ext::$6);
 329    %}
 330   ins_pipe(ialu_reg_reg);
 331 %}')
 332 ADD_SUB_EXTENDED(I,16,Add,RShift,add,sxth,32)
 333 ADD_SUB_EXTENDED(I,8,Add,RShift,add,sxtb,32)
 334 ADD_SUB_EXTENDED(I,8,Add,URShift,add,uxtb,32)
 335 ADD_SUB_EXTENDED(L,16,Add,RShift,add,sxth,64)
 336 ADD_SUB_EXTENDED(L,32,Add,RShift,add,sxtw,64)
 337 ADD_SUB_EXTENDED(L,8,Add,RShift,add,sxtb,64)
 338 ADD_SUB_EXTENDED(L,8,Add,URShift,add,uxtb,64)
 339 dnl
 340 dnl ADD_SUB_ZERO_EXTEND(mode, size, add node, insn, shift type)
 341 define(`ADD_SUB_ZERO_EXTEND', `
 342 instruct $3Ext$1_$5_and(iReg$1NoSp dst, iReg$1`'ORL2I($1) src1, iReg$1`'ORL2I($1) src2, imm$1_$2 mask, rFlagsReg cr)
 343 %{
 344   match(Set dst ($3$1 src1 (And$1 src2 mask)));
 345   ins_cost(INSN_COST);
 346   format %{ "$4  $dst, $src1, $src2, $5" %}
 347 
 348    ins_encode %{
 349      __ $4(as_Register($dst$$reg), as_Register($src1$$reg),
 350             as_Register($src2$$reg), ext::$5);
 351    %}
 352   ins_pipe(ialu_reg_reg);
 353 %}')
 354 dnl
 355 ADD_SUB_ZERO_EXTEND(I,255,Add,addw,uxtb)
 356 ADD_SUB_ZERO_EXTEND(I,65535,Add,addw,uxth)
 357 ADD_SUB_ZERO_EXTEND(L,255,Add,add,uxtb)
 358 ADD_SUB_ZERO_EXTEND(L,65535,Add,add,uxth)
 359 ADD_SUB_ZERO_EXTEND(L,4294967295,Add,add,uxtw)
 360 dnl
 361 ADD_SUB_ZERO_EXTEND(I,255,Sub,subw,uxtb)
 362 ADD_SUB_ZERO_EXTEND(I,65535,Sub,subw,uxth)
 363 ADD_SUB_ZERO_EXTEND(L,255,Sub,sub,uxtb)
 364 ADD_SUB_ZERO_EXTEND(L,65535,Sub,sub,uxth)
 365 ADD_SUB_ZERO_EXTEND(L,4294967295,Sub,sub,uxtw)
 366 
 367 // END This section of the file is automatically generated. Do not edit --------------