1  // Test sequences that can use RISBG with a normal first operand.
       2  
       3  /* Tests ported from the Llvm testsuite. */
       4  
       5  /* { dg-do compile { target s390x-*-* } } */
       6  /* { dg-options "-O3 -march=z10 -mzarch -fno-asynchronous-unwind-tables" }  */
       7  
       8  #define i64 signed long long
       9  #define ui64 unsigned long long
      10  #define i32 signed int
      11  #define ui32 unsigned int
      12  
      13  // Test a case with two ANDs.
      14  i32 f1 (i32 v_a, i32 v_b)
      15  {
      16    /* { dg-final { scan-assembler "f1:\n\trisbg\t%r2,%r3,60,62,0" } } */
      17    i32 v_anda = v_a & -15;
      18    i32 v_andb = v_b & 14;
      19    i32 v_or = v_anda | v_andb;
      20    return v_or;
      21  }
      22  
      23  // ...and again with i64.
      24  i64 f2 (i64 v_a, i64 v_b)
      25  {
      26    /* { dg-final { scan-assembler "f2:\n\trisbg\t%r2,%r3,60,62,0" { target { lp64 } } } } */
      27    /* { dg-final { scan-assembler "f2:\n\trisbg\t%r3,%r2,0,0\\\+32-1,64-0-32\n\(\t.*\n\)*\trisbg\t%r\[23\],%r5,60,62,0" { target { ! lp64 } } } } */
      28    i64 v_anda = v_a & -15;
      29    i64 v_andb = v_b & 14;
      30    i64 v_or = v_anda | v_andb;
      31    return v_or;
      32  }
      33  
      34  // Test a case with two ANDs and a shift.
      35  i32 f3 (i32 v_a, i32 v_b)
      36  {
      37    /* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,\\(64-32\\)\\+4\\+20\n\tlgfr\t%r2,%r2" } } */
      38    i32 v_anda = v_a & -16;
      39    i32 v_shr = ((ui32)v_b) >> 8;
      40    i32 v_andb = v_shr & 15;
      41    i32 v_or = v_anda | v_andb;
      42    return v_or;
      43  }
      44  
      45  // ...and again with i64.
      46  i64 f4 (i64 v_a, i64 v_b)
      47  {
      48    /* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,64-4,63,\\(64-64\\)\\+4\\+52" { target { lp64 } } } } */
      49    /* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trisbg\t%r5,%r5,64-4,128\\+63,\\(64-64\\)\\+52\\+4" { target { ! lp64 } } } } */
      50    i64 v_anda = v_a & -16;
      51    i64 v_shr = ((ui64)v_b) >> 8;
      52    i64 v_andb = v_shr & 15;
      53    i64 v_or = v_anda | v_andb;
      54    return v_or;
      55  }
      56  
      57  // Test a case with a single AND and a left shift.
      58  i32 f5 (i32 v_a, i32 v_b)
      59  {
      60    /* { dg-final { scan-assembler "f5:\n\trisbg\t%r2,%r3,32,64-10-1,10" } } */
      61    i32 v_anda = v_a & 1023;
      62    i32 v_shlb = v_b << 10;
      63    i32 v_or = v_anda | v_shlb;
      64    return v_or;
      65  }
      66  
      67  // ...and again with i64.
      68  i64 f6 (i64 v_a, i64 v_b)
      69  {
      70    /* { dg-final { scan-assembler "f6:\n\trisbg\t%r2,%r3,0,64-10-1,10" { target { lp64 } } } } */
      71    /* { dg-final { scan-assembler "f6:\n\trisbg\t%r5,%r4,0,0\\\+32-1,64-0-32\n\(\t.*\n\)*\trisbg\t%r\[23\],%r5,0,64-10-1,10" { target { ! lp64 } } } } */
      72    i64 v_anda = v_a & 1023;
      73    i64 v_shlb = v_b << 10;
      74    i64 v_or = v_anda | v_shlb;
      75    return v_or;
      76  }
      77  
      78  // Test a case with a single AND and a right shift.
      79  i32 f7 (i32 v_a, i32 v_b)
      80  {
      81    /* { dg-final { scan-assembler "f7:\n\trisbg\t%r2,%r3,32\\\+8,63,64-8" } } */
      82    i32 v_anda = v_a & -16777216;
      83    i32 v_shrb = ((ui32)v_b) >> 8;
      84    i32 v_or = v_anda | v_shrb;
      85    return v_or;
      86  }
      87  
      88  // ...and again with i64.
      89  i64 f8 (i64 v_a, i64 v_b)
      90  {
      91    /* { dg-final { scan-assembler "f8:\n\trisbg\t%r2,%r3,8,63,64-8" { target { lp64 } } } } */
      92    /* With -m31 risbg is not really useful here, so do not test for it.  */
      93    i64 v_anda = v_a & -72057594037927936;
      94    i64 v_shrb = ((ui64)v_b) >> 8;
      95    i64 v_or = v_anda | v_shrb;
      96    return v_or;
      97  }
      98  
      99  // Check that we can get the case where a 64-bit shift feeds a 32-bit or of
     100  // ands with complement masks.
     101  i32 f9 (i64 v_x, i32 v_y)
     102  {
     103    /* { dg-final { scan-assembler "f9:\n\trisbg\t%r3,%r2,48,63,64-48" { target { lp64 } }} } */
     104    /* { dg-final { scan-assembler "f9:\n\trisbg\t%r4,%r2,32\\+16,63,64-16" { target { ! lp64 } }} } */
     105    i64 v_shr6 = ((ui64)v_x) >> 48;
     106    i32 v_conv = (ui32)v_shr6;
     107    i32 v_and1 = v_y & -65536;
     108    i32 v_or = v_conv | v_and1;
     109    return v_or;
     110  }
     111  
     112  // Check that we don't get the case where a 64-bit shift feeds a 32-bit or of
     113  // ands with incompatible masks.
     114  i32 f10 (i64 v_x, i32 v_y)
     115  {
     116    /* { dg-final { scan-assembler "f10:\n\tsrlg\t%r2,%r2,48\n\trosbg\t%r2,%r3,32,39,0" { target { lp64 } } } } */
     117    /* { dg-final { scan-assembler "f10:\n\tnilf\t%r4,4278190080\n\trosbg\t%r4,%r2,48,63,48" { target { ! lp64 } } } } */
     118    i64 v_shr6 = ((ui64)v_x) >> 48;
     119    i32 v_conv = (ui32)v_shr6;
     120    i32 v_and1 = v_y & -16777216;
     121    i32 v_or = v_conv | v_and1;
     122    return v_or;
     123  }