1  /* { dg-do compile { target x86_64-*-* } } */
       2  /* { dg-require-effective-target lp64 } */
       3  
       4  #include "analyzer-decls.h"
       5  
       6  #include <stdint.h>
       7  
       8  int test_1 (int src)
       9  {
      10    int dst;
      11    asm ("mov %1, %0\n\t"
      12         "add $1, %0"
      13         : "=r" (dst)
      14         : "r" (src));
      15    return dst;
      16  }
      17  
      18  uint32_t test_2 (uint32_t Mask)
      19  {
      20    uint32_t Index;
      21    asm ("bsfl %[aMask], %[aIndex]"
      22         : [aIndex] "=r" (Index)
      23         : [aMask] "r" (Mask)
      24         : "cc");
      25    return Index;
      26  }
      27  
      28  int test_3a (int p1, int p2)
      29  {
      30    asm goto ("btl %1, %0\n\t"
      31  	    "jc %l2"
      32  	    : // No outputs
      33  	    : "r" (p1), "r" (p2)
      34  	    : "cc"
      35  	    : carry);
      36  
      37    return 0;
      38  
      39   carry:
      40    return 1;
      41  }
      42  
      43  int test_3b (int p1, int p2)
      44  {
      45    asm goto ("btl %1, %0\n\t"
      46  	    "jc %l[carry]"
      47  	    : // No outputs
      48  	    : "r" (p1), "r" (p2)
      49  	    : "cc"
      50  	    : carry);
      51  
      52    return 0;
      53  
      54   carry:
      55    return 1;
      56  }
      57  
      58  uint64_t test_4 (void)
      59  {
      60    uint64_t start_time, end_time;
      61  
      62    // Get start time
      63    asm volatile ("rdtsc\n\t"    // Returns the time in EDX:EAX.
      64  		"shl $32, %%rdx\n\t"  // Shift the upper bits left.
      65  		"or %%rdx, %0"        // 'Or' in the lower bits.
      66  		: "=a" (start_time)
      67  		:
      68  		: "rdx");
      69  
      70    // could do other work here
      71  
      72    // Get end time
      73    asm volatile ("rdtsc\n\t"    // Returns the time in EDX:EAX.
      74  		"shl $32, %%rdx\n\t"  // Shift the upper bits left.
      75  		"or %%rdx, %0"        // 'Or' in the lower bits.
      76  		: "=a" (end_time)
      77  		:
      78  		: "rdx");
      79  
      80    __analyzer_eval (start_time == end_time); /* { dg-warning "UNKNOWN" } */
      81  
      82    // Get elapsed time
      83    return end_time - start_time;
      84  }
      85  
      86  static uint64_t get_time (void)
      87  {
      88    uint64_t result;
      89    asm volatile ("rdtsc\n\t"    // Returns the time in EDX:EAX.
      90  		"shl $32, %%rdx\n\t"  // Shift the upper bits left.
      91  		"or %%rdx, %0"        // 'Or' in the lower bits.
      92  		: "=a" (result)
      93  		:
      94  		: "rdx");
      95    return result;
      96  }
      97  
      98  uint64_t test_4a (void)
      99  {
     100    uint64_t start_time, end_time;
     101  
     102    start_time = get_time ();
     103    // could do other work here
     104    end_time = get_time ();
     105  
     106    __analyzer_eval (start_time == end_time); /* { dg-warning "UNKNOWN" } */
     107  
     108    // Get elapsed time
     109    return end_time - start_time;
     110  }
     111  
     112  asm ("\t.pushsection .text\n"
     113       "\t.globl add_asm\n"
     114       "\t.type add_asm, @function\n"
     115       "add_asm:\n"
     116       "\tmovq %rdi, %rax\n"
     117       "\tadd %rsi, %rax\n"
     118       "\tret\n"
     119       "\t.popsection\n");
     120  
     121  int test_5 (int count)
     122  {
     123    asm goto ("dec %0; jb %l[stop]"
     124  	    : "+r" (count)
     125  	    :
     126  	    :
     127  	    : stop);
     128    return count;
     129  stop:
     130    return 0;
     131  }