LCOV - code coverage report
Current view: top level - gcc/config/i386 - sync.md (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1991 2288 87.0 %
Date: 2020-03-28 11:57:23 Functions: 112 127 88.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : ;; GCC machine description for i386 synchronization instructions.
       2                 :            : ;; Copyright (C) 2005-2020 Free Software Foundation, Inc.
       3                 :            : ;;
       4                 :            : ;; This file is part of GCC.
       5                 :            : ;;
       6                 :            : ;; GCC is free software; you can redistribute it and/or modify
       7                 :            : ;; it under the terms of the GNU General Public License as published by
       8                 :            : ;; the Free Software Foundation; either version 3, or (at your option)
       9                 :            : ;; any later version.
      10                 :            : ;;
      11                 :            : ;; GCC is distributed in the hope that it will be useful,
      12                 :            : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            : ;; GNU General Public License for more details.
      15                 :            : ;;
      16                 :            : ;; You should have received a copy of the GNU General Public License
      17                 :            : ;; along with GCC; see the file COPYING3.  If not see
      18                 :            : ;; <http://www.gnu.org/licenses/>.
      19                 :            : 
      20                 :            : (define_c_enum "unspec" [
      21                 :            :   UNSPEC_LFENCE
      22                 :            :   UNSPEC_SFENCE
      23                 :            :   UNSPEC_MFENCE
      24                 :            : 
      25                 :            :   UNSPEC_FILD_ATOMIC
      26                 :            :   UNSPEC_FIST_ATOMIC
      27                 :            : 
      28                 :            :   UNSPEC_LDX_ATOMIC
      29                 :            :   UNSPEC_STX_ATOMIC
      30                 :            : 
      31                 :            :   ;; __atomic support
      32                 :            :   UNSPEC_LDA
      33                 :            :   UNSPEC_STA
      34                 :            : ])
      35                 :            : 
      36                 :            : (define_c_enum "unspecv" [
      37                 :            :   UNSPECV_CMPXCHG
      38                 :            :   UNSPECV_XCHG
      39                 :            :   UNSPECV_LOCK
      40                 :            : ])
      41                 :            : 
      42                 :            : (define_expand "sse2_lfence"
      43                 :            :   [(set (match_dup 0)
      44                 :            :         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
      45                 :            :   "TARGET_SSE2"
      46                 :         14 : {
      47                 :         16 :   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
      48                 :         14 :   MEM_VOLATILE_P (operands[0]) = 1;
      49                 :            : })
      50                 :            : 
      51                 :            : (define_insn "*sse2_lfence"
      52                 :         14 :   [(set (match_operand:BLK 0)
      53                 :         14 :         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
      54                 :         14 :   "TARGET_SSE2"
      55                 :         14 :   "lfence"
      56                 :            :   [(set_attr "type" "sse")
      57                 :            :    (set_attr "length_address" "0")
      58                 :         10 :    (set_attr "atom_sse_attr" "lfence")
      59                 :         10 :    (set_attr "memory" "unknown")])
      60                 :         14 : 
      61                 :         24 : (define_expand "sse_sfence"
      62                 :         24 :   [(set (match_dup 0)
      63                 :         10 :         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
      64                 :            :   "TARGET_SSE || TARGET_3DNOW_A"
      65                 :         10 : {
      66                 :         10 :   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
      67                 :         10 :   MEM_VOLATILE_P (operands[0]) = 1;
      68                 :            : })
      69                 :         10 : 
      70                 :         10 : (define_insn "*sse_sfence"
      71                 :         10 :   [(set (match_operand:BLK 0)
      72                 :         20 :         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
      73                 :         10 :   "TARGET_SSE || TARGET_3DNOW_A"
      74                 :         10 :   "sfence"
      75                 :            :   [(set_attr "type" "sse")
      76                 :            :    (set_attr "length_address" "0")
      77                 :        336 :    (set_attr "atom_sse_attr" "fence")
      78                 :        336 :    (set_attr "memory" "unknown")])
      79                 :         10 : 
      80                 :        346 : (define_expand "sse2_mfence"
      81                 :        346 :   [(set (match_dup 0)
      82                 :            :         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
      83                 :        336 :   "TARGET_SSE2"
      84                 :         16 : {
      85                 :         16 :   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
      86                 :         16 :   MEM_VOLATILE_P (operands[0]) = 1;
      87                 :            : })
      88                 :         16 : 
      89                 :         16 : (define_insn "mfence_sse2"
      90                 :         16 :   [(set (match_operand:BLK 0)
      91                 :         32 :         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
      92                 :        352 :   "TARGET_64BIT || TARGET_SSE2"
      93                 :         16 :   "mfence"
      94                 :          0 :   [(set_attr "type" "sse")
      95                 :            :    (set_attr "length_address" "0")
      96                 :            :    (set_attr "atom_sse_attr" "fence")
      97                 :            :    (set_attr "memory" "unknown")])
      98                 :         16 : 
      99                 :         16 : (define_insn "mfence_nosse"
     100                 :         16 :   [(set (match_operand:BLK 0)
     101                 :            :         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))
     102                 :            :    (clobber (reg:CC FLAGS_REG))]
     103                 :            :   "!(TARGET_64BIT || TARGET_SSE2)"
     104                 :          0 :   "lock{%;} or{l}\t{$0, (%%esp)|DWORD PTR [esp], 0}"
     105                 :        835 :   [(set_attr "memory" "unknown")])
     106                 :          0 : 
     107                 :        835 : (define_expand "mem_thread_fence"
     108                 :        835 :   [(match_operand:SI 0 "const_int_operand")]          ;; model
     109                 :        835 :   ""
     110                 :        835 : {
     111                 :        835 :   enum memmodel model = memmodel_from_int (INTVAL (operands[0]));
     112                 :          0 : 
     113                 :          0 :   /* Unless this is a SEQ_CST fence, the i386 memory model is strong
     114                 :          0 :      enough not to require barriers of any kind.  */
     115                 :        835 :   if (is_mm_seq_cst (model))
     116                 :          0 :     {
     117                 :        426 :       rtx (*mfence_insn)(rtx);
     118                 :        426 :       rtx mem;
     119                 :          0 : 
     120                 :        426 :       if (TARGET_64BIT || TARGET_SSE2)
     121                 :            :         mfence_insn = gen_mfence_sse2;
     122                 :          0 :       else
     123                 :        106 :         mfence_insn = gen_mfence_nosse;
     124                 :          0 : 
     125                 :        540 :       mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
     126                 :        426 :       MEM_VOLATILE_P (mem) = 1;
     127                 :            : 
     128                 :        426 :       emit_insn (mfence_insn (mem));
     129                 :            :     }
     130                 :        835 :   DONE;
     131                 :            : })
     132                 :            : 
     133                 :            : ;; ??? From volume 3 section 8.1.1 Guaranteed Atomic Operations,
     134                 :            : ;; Only beginning at Pentium family processors do we get any guarantee of
     135                 :            : ;; atomicity in aligned 64-bit quantities.  Beginning at P6, we get a
     136                 :            : ;; guarantee for 64-bit accesses that do not cross a cacheline boundary.
     137                 :            : ;;
     138                 :            : ;; Note that the TARGET_CMPXCHG8B test below is a stand-in for "Pentium".
     139                 :            : ;;
     140                 :            : ;; Importantly, *no* processor makes atomicity guarantees for larger
     141                 :            : ;; accesses.  In particular, there's no way to perform an atomic TImode
     142                 :            : ;; move, despite the apparent applicability of MOVDQA et al.
     143                 :            : 
     144                 :            : (define_mode_iterator ATOMIC
     145                 :      17318 :    [QI HI SI
     146                 :            :     (DI "TARGET_64BIT || (TARGET_CMPXCHG8B && (TARGET_80387 || TARGET_SSE))")
     147                 :            :    ])
     148                 :            : 
     149                 :      17318 : (define_expand "atomic_load<mode>"
     150                 :      17318 :   [(set (match_operand:ATOMIC 0 "nonimmediate_operand")
     151                 :      17318 :         (unspec:ATOMIC [(match_operand:ATOMIC 1 "memory_operand")
     152                 :      17318 :                         (match_operand:SI 2 "const_int_operand")]
     153                 :      17318 :                        UNSPEC_LDA))]
     154                 :      17318 :   ""
     155                 :      48203 : {
     156                 :            :   /* For DImode on 32-bit, we can use the FPU to perform the load.  */
     157                 :      48203 :   if (<MODE>mode == DImode && !TARGET_64BIT)
     158                 :          9 :     emit_insn (gen_atomic_loaddi_fpu
     159                 :            :                (operands[0], operands[1],
     160                 :            :                 assign_386_stack_local (DImode, SLOT_TEMP)));
     161                 :            :   else
     162                 :            :     {
     163                 :      48194 :       rtx dst = operands[0];
     164                 :            : 
     165                 :      31218 :       if (MEM_P (dst))
     166                 :          0 :         dst = gen_reg_rtx (<MODE>mode);
     167                 :            : 
     168                 :      48194 :       emit_move_insn (dst, operands[1]);
     169                 :            : 
     170                 :            :       /* Fix up the destination if needed.  */
     171                 :      48194 :       if (dst != operands[0])
     172                 :          0 :         emit_move_insn (operands[0], dst);
     173                 :            :     }
     174                 :      48203 :   DONE;
     175                 :            : })
     176                 :            : 
     177                 :            : (define_insn_and_split "atomic_loaddi_fpu"
     178                 :            :   [(set (match_operand:DI 0 "nonimmediate_operand" "=x,m,?r")
     179                 :            :         (unspec:DI [(match_operand:DI 1 "memory_operand" "m,m,m")]
     180                 :            :                    UNSPEC_LDA))
     181                 :            :    (clobber (match_operand:DI 2 "memory_operand" "=X,X,m"))
     182                 :            :    (clobber (match_scratch:DF 3 "=X,xf,xf"))]
     183                 :         45 :   "!TARGET_64BIT && (TARGET_80387 || TARGET_SSE)"
     184                 :          0 :   "#"
     185                 :         18 :   "&& reload_completed"
     186                 :          9 :   [(const_int 0)]
     187                 :         18 : {
     188                 :         27 :   rtx dst = operands[0], src = operands[1];
     189                 :          9 :   rtx mem = operands[2], tmp = operands[3];
     190                 :         12 : 
     191                 :         39 :   if (SSE_REG_P (dst))
     192                 :         13 :     emit_move_insn (dst, src);
     193                 :          0 :   else
     194                 :         18 :     {
     195                 :          8 :       if (MEM_P (dst))
     196                 :         18 :         mem = dst;
     197                 :          0 : 
     198                 :      30911 :       if (STACK_REG_P (tmp))
     199                 :          9 :         {
     200                 :         18 :           emit_insn (gen_loaddi_via_fpu (tmp, src));
     201                 :          0 :           emit_insn (gen_storedi_via_fpu (mem, tmp));
     202                 :         27 :         }
     203                 :      30885 :       else
     204                 :         27 :         {
     205                 :          8 :           emit_insn (gen_loaddi_via_sse (tmp, src));
     206                 :         26 :           emit_insn (gen_storedi_via_sse (mem, tmp));
     207                 :      30885 :         }
     208                 :      30903 : 
     209                 :         26 :       if (mem != dst)
     210                 :         26 :         emit_move_insn (dst, mem);
     211                 :         18 :     }
     212                 :          9 :   DONE;
     213                 :            : })
     214                 :            : 
     215                 :            : (define_peephole2
     216                 :            :   [(set (match_operand:DF 0 "fp_register_operand")
     217                 :            :         (unspec:DF [(match_operand:DI 1 "memory_operand")]
     218                 :            :                    UNSPEC_FILD_ATOMIC))
     219                 :            :    (set (match_operand:DI 2 "memory_operand")
     220                 :            :         (unspec:DI [(match_dup 0)]
     221                 :            :                    UNSPEC_FIST_ATOMIC))
     222                 :            :    (set (match_operand:DF 3 "any_fp_register_operand")
     223                 :            :         (match_operand:DF 4 "memory_operand"))]
     224                 :          0 :   "!TARGET_64BIT
     225                 :          0 :    && peep2_reg_dead_p (2, operands[0])
     226                 :          0 :    && rtx_equal_p (XEXP (operands[4], 0), XEXP (operands[2], 0))"
     227                 :          0 :   [(set (match_dup 3) (match_dup 5))]
     228                 :          0 :   "operands[5] = gen_lowpart (DFmode, operands[1]);")
     229                 :          0 : 
     230                 :          0 : (define_peephole2
     231                 :          0 :   [(set (match_operand:DF 0 "fp_register_operand")
     232                 :          0 :         (unspec:DF [(match_operand:DI 1 "memory_operand")]
     233                 :          0 :                    UNSPEC_FILD_ATOMIC))
     234                 :          0 :    (set (match_operand:DI 2 "memory_operand")
     235                 :          0 :         (unspec:DI [(match_dup 0)]
     236                 :          0 :                    UNSPEC_FIST_ATOMIC))
     237                 :          0 :    (set (mem:BLK (scratch:SI))
     238                 :          0 :         (unspec:BLK [(mem:BLK (scratch:SI))] UNSPEC_MEMORY_BLOCKAGE))
     239                 :          0 :    (set (match_operand:DF 3 "any_fp_register_operand")
     240                 :          0 :         (match_operand:DF 4 "memory_operand"))]
     241                 :          0 :   "!TARGET_64BIT
     242                 :          0 :    && peep2_reg_dead_p (2, operands[0])
     243                 :          0 :    && rtx_equal_p (XEXP (operands[4], 0), XEXP (operands[2], 0))"
     244                 :          0 :   [(const_int 0)]
     245                 :          0 : {
     246                 :          0 :   emit_move_insn (operands[3], gen_lowpart (DFmode, operands[1]));
     247                 :          0 :   emit_insn (gen_memory_blockage ());
     248                 :          0 :   DONE;
     249                 :            : })
     250                 :            : 
     251                 :            : (define_peephole2
     252                 :         14 :   [(set (match_operand:DF 0 "sse_reg_operand")
     253                 :         14 :         (unspec:DF [(match_operand:DI 1 "memory_operand")]
     254                 :            :                    UNSPEC_LDX_ATOMIC))
     255                 :         14 :    (set (match_operand:DI 2 "memory_operand")
     256                 :          0 :         (unspec:DI [(match_dup 0)]
     257                 :          0 :                    UNSPEC_STX_ATOMIC))
     258                 :          0 :    (set (match_operand:DF 3 "any_fp_register_operand")
     259                 :            :         (match_operand:DF 4 "memory_operand"))]
     260                 :          0 :   "!TARGET_64BIT
     261                 :          0 :    && peep2_reg_dead_p (2, operands[0])
     262                 :          0 :    && rtx_equal_p (XEXP (operands[4], 0), XEXP (operands[2], 0))"
     263                 :          0 :   [(set (match_dup 3) (match_dup 5))]
     264                 :          0 :   "operands[5] = gen_lowpart (DFmode, operands[1]);")
     265                 :          0 : 
     266                 :          0 : (define_peephole2
     267                 :          0 :   [(set (match_operand:DF 0 "sse_reg_operand")
     268                 :          0 :         (unspec:DF [(match_operand:DI 1 "memory_operand")]
     269                 :          0 :                    UNSPEC_LDX_ATOMIC))
     270                 :          0 :    (set (match_operand:DI 2 "memory_operand")
     271                 :          0 :         (unspec:DI [(match_dup 0)]
     272                 :          0 :                    UNSPEC_STX_ATOMIC))
     273                 :          0 :    (set (mem:BLK (scratch:SI))
     274                 :          0 :         (unspec:BLK [(mem:BLK (scratch:SI))] UNSPEC_MEMORY_BLOCKAGE))
     275                 :          0 :    (set (match_operand:DF 3 "any_fp_register_operand")
     276                 :          0 :         (match_operand:DF 4 "memory_operand"))]
     277                 :          0 :   "!TARGET_64BIT
     278                 :          0 :    && peep2_reg_dead_p (2, operands[0])
     279                 :          0 :    && rtx_equal_p (XEXP (operands[4], 0), XEXP (operands[2], 0))"
     280                 :          0 :   [(const_int 0)]
     281                 :          0 : {
     282                 :          0 :   emit_move_insn (operands[3], gen_lowpart (DFmode, operands[1]));
     283                 :          0 :   emit_insn (gen_memory_blockage ());
     284                 :          0 :   DONE;
     285                 :            : })
     286                 :            : 
     287                 :            : (define_expand "atomic_store<mode>"
     288                 :            :   [(set (match_operand:ATOMIC 0 "memory_operand")
     289                 :          0 :         (unspec:ATOMIC [(match_operand:ATOMIC 1 "nonimmediate_operand")
     290                 :            :                         (match_operand:SI 2 "const_int_operand")]
     291                 :          0 :                        UNSPEC_STA))]
     292                 :          0 :   ""
     293                 :          0 : {
     294                 :          0 :   enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
     295                 :            : 
     296                 :       3071 :   if (<MODE>mode == DImode && !TARGET_64BIT)
     297                 :            :     {
     298                 :     173670 :       /* For DImode on 32-bit, we can use the FPU to perform the store.  */
     299                 :            :       /* Note that while we could perform a cmpxchg8b loop, that turns
     300                 :       5553 :          out to be significantly larger than this plus a barrier.  */
     301                 :       5559 :       emit_insn (gen_atomic_storedi_fpu
     302                 :     179223 :                  (operands[0], operands[1],
     303                 :     179223 :                   assign_386_stack_local (DImode, SLOT_TEMP)));
     304                 :     179223 :     }
     305                 :     179223 :   else
     306                 :     179223 :     {
     307                 :     186385 :       operands[1] = force_reg (<MODE>mode, operands[1]);
     308                 :     173670 : 
     309                 :     173670 :       /* For seq-cst stores, use XCHG when we lack MFENCE
     310                 :            :          or when target prefers XCHG.  */
     311                 :     186385 :       if (is_mm_seq_cst (model)
     312                 :     186385 :           && (!(TARGET_64BIT || TARGET_SSE2)
     313                 :      10883 :               || TARGET_USE_XCHG_FOR_ATOMIC_STORE))
     314                 :     116698 :         {
     315                 :     127599 :           emit_insn (gen_atomic_exchange<mode> (gen_reg_rtx (<MODE>mode),
     316                 :     116698 :                                                 operands[0], operands[1],
     317                 :            :                                                 operands[2]));
     318                 :      19060 :           DONE;
     319                 :       8159 :         }
     320                 :       8159 : 
     321                 :       8159 :       /* Otherwise use a store.  */
     322                 :       9924 :       emit_insn (gen_atomic_store<mode>_1 (operands[0], operands[1],
     323                 :       8023 :                                            operands[2]));
     324                 :            :     }
     325                 :       8023 :   /* ... followed by an MFENCE, if required.  */
     326                 :       9843 :   if (is_mm_seq_cst (model))
     327                 :       8029 :     emit_insn (gen_mem_thread_fence (operands[2]));
     328                 :       9843 :   DONE;
     329                 :            : })
     330                 :       8023 : 
     331                 :       8023 : (define_insn "atomic_store<mode>_1"
     332                 :            :   [(set (match_operand:SWI 0 "memory_operand" "=m")
     333                 :       8023 :         (unspec:SWI [(match_operand:SWI 1 "<nonmemory_operand>" "<r><i>")
     334                 :       8023 :                      (match_operand:SI 2 "const_int_operand")]
     335                 :            :                     UNSPEC_STA))]
     336                 :       8023 :   ""
     337                 :            :   "%K2mov{<imodesuffix>}\t{%1, %0|%0, %1}")
     338                 :        153 : 
     339                 :        153 : (define_insn_and_split "atomic_storedi_fpu"
     340                 :        153 :   [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
     341                 :        153 :         (unspec:DI [(match_operand:DI 1 "nonimmediate_operand" "x,m,?r")]
     342                 :        306 :                    UNSPEC_STA))
     343                 :            :    (clobber (match_operand:DI 2 "memory_operand" "=X,X,m"))
     344                 :            :    (clobber (match_scratch:DF 3 "=X,xf,xf"))]
     345                 :         30 :   "!TARGET_64BIT && (TARGET_80387 || TARGET_SSE)"
     346                 :          0 :   "#"
     347                 :         12 :   "&& reload_completed"
     348                 :          6 :   [(const_int 0)]
     349                 :         12 : {
     350                 :          6 :   rtx dst = operands[0], src = operands[1];
     351                 :          6 :   rtx mem = operands[2], tmp = operands[3];
     352                 :       7168 : 
     353                 :       1209 :   if (SSE_REG_P (src))
     354                 :      12498 :     emit_move_insn (dst, src);
     355                 :      12504 :   else
     356                 :          6 :     {
     357                 :       8359 :       if (REG_P (src))
     358                 :       1191 :         {
     359                 :       7594 :           emit_move_insn (mem, src);
     360                 :        414 :           src = mem;
     361                 :       7346 :         }
     362                 :       7220 : 
     363                 :         58 :       if (STACK_REG_P (tmp))
     364                 :        178 :         {
     365                 :     169784 :           emit_insn (gen_loaddi_via_fpu (tmp, src));
     366                 :         52 :           emit_insn (gen_storedi_via_fpu (dst, tmp));
     367                 :         32 :         }
     368                 :        210 :       else
     369                 :     170104 :         {
     370                 :          6 :           emit_insn (gen_loaddi_via_sse (tmp, src));
     371                 :     169738 :           emit_insn (gen_storedi_via_sse (dst, tmp));
     372                 :        194 :         }
     373                 :         16 :     }
     374                 :     133844 :   DONE;
     375                 :        178 : })
     376                 :      11214 : 
     377                 :      11198 : (define_peephole2
     378                 :         16 :   [(set (match_operand:DF 0 "memory_operand")
     379                 :        194 :         (match_operand:DF 1 "any_fp_register_operand"))
     380                 :         43 :    (set (match_operand:DF 2 "fp_register_operand")
     381                 :          0 :         (unspec:DF [(match_operand:DI 3 "memory_operand")]
     382                 :        194 :                    UNSPEC_FILD_ATOMIC))
     383                 :        194 :    (set (match_operand:DI 4 "memory_operand")
     384                 :            :         (unspec:DI [(match_dup 2)]
     385                 :        194 :                    UNSPEC_FIST_ATOMIC))]
     386                 :         16 :   "!TARGET_64BIT
     387                 :        178 :    && peep2_reg_dead_p (3, operands[2])
     388                 :         16 :    && rtx_equal_p (XEXP (operands[0], 0), XEXP (operands[3], 0))"
     389                 :          0 :   [(set (match_dup 5) (match_dup 1))]
     390                 :        194 :   "operands[5] = gen_lowpart (DFmode, operands[4]);")
     391                 :        194 : 
     392                 :         16 : (define_peephole2
     393                 :        178 :   [(set (match_operand:DF 0 "memory_operand")
     394                 :        178 :         (match_operand:DF 1 "any_fp_register_operand"))
     395                 :          0 :    (set (mem:BLK (scratch:SI))
     396                 :        178 :         (unspec:BLK [(mem:BLK (scratch:SI))] UNSPEC_MEMORY_BLOCKAGE))
     397                 :        178 :    (set (match_operand:DF 2 "fp_register_operand")
     398                 :          0 :         (unspec:DF [(match_operand:DI 3 "memory_operand")]
     399                 :          0 :                    UNSPEC_FILD_ATOMIC))
     400                 :        178 :    (set (match_operand:DI 4 "memory_operand")
     401                 :          0 :         (unspec:DI [(match_dup 2)]
     402                 :        178 :                    UNSPEC_FIST_ATOMIC))]
     403                 :        178 :   "!TARGET_64BIT
     404                 :          0 :    && peep2_reg_dead_p (4, operands[2])
     405                 :          0 :    && rtx_equal_p (XEXP (operands[0], 0), XEXP (operands[3], 0))"
     406                 :        178 :   [(const_int 0)]
     407                 :          0 : {
     408                 :        178 :   emit_insn (gen_memory_blockage ());
     409                 :          0 :   emit_move_insn (gen_lowpart (DFmode, operands[4]), operands[1]);
     410                 :         89 :   DONE;
     411                 :         89 : })
     412                 :          0 : 
     413                 :          0 : (define_peephole2
     414                 :          0 :   [(set (match_operand:DF 0 "memory_operand")
     415                 :          0 :         (match_operand:DF 1 "any_fp_register_operand"))
     416                 :            :    (set (match_operand:DF 2 "sse_reg_operand")
     417                 :          0 :         (unspec:DF [(match_operand:DI 3 "memory_operand")]
     418                 :          0 :                    UNSPEC_LDX_ATOMIC))
     419                 :          0 :    (set (match_operand:DI 4 "memory_operand")
     420                 :          0 :         (unspec:DI [(match_dup 2)]
     421                 :          0 :                    UNSPEC_STX_ATOMIC))]
     422                 :          0 :   "!TARGET_64BIT
     423                 :          0 :    && peep2_reg_dead_p (3, operands[2])
     424                 :          0 :    && rtx_equal_p (XEXP (operands[0], 0), XEXP (operands[3], 0))"
     425                 :          0 :   [(set (match_dup 5) (match_dup 1))]
     426                 :          0 :   "operands[5] = gen_lowpart (DFmode, operands[4]);")
     427                 :          0 : 
     428                 :          0 : (define_peephole2
     429                 :          0 :   [(set (match_operand:DF 0 "memory_operand")
     430                 :          0 :         (match_operand:DF 1 "any_fp_register_operand"))
     431                 :          0 :    (set (mem:BLK (scratch:SI))
     432                 :          0 :         (unspec:BLK [(mem:BLK (scratch:SI))] UNSPEC_MEMORY_BLOCKAGE))
     433                 :          0 :    (set (match_operand:DF 2 "sse_reg_operand")
     434                 :          0 :         (unspec:DF [(match_operand:DI 3 "memory_operand")]
     435                 :          0 :                    UNSPEC_LDX_ATOMIC))
     436                 :          0 :    (set (match_operand:DI 4 "memory_operand")
     437                 :          0 :         (unspec:DI [(match_dup 2)]
     438                 :          0 :                    UNSPEC_STX_ATOMIC))]
     439                 :          0 :   "!TARGET_64BIT
     440                 :          0 :    && peep2_reg_dead_p (4, operands[2])
     441                 :          0 :    && rtx_equal_p (XEXP (operands[0], 0), XEXP (operands[3], 0))"
     442                 :          0 :   [(const_int 0)]
     443                 :    5666040 : {
     444                 :          0 :   emit_insn (gen_memory_blockage ());
     445                 :          0 :   emit_move_insn (gen_lowpart (DFmode, operands[4]), operands[1]);
     446                 :          0 :   DONE;
     447                 :    5666040 : })
     448                 :    5666040 : 
     449                 :    5666040 : ;; ??? You'd think that we'd be able to perform this via FLOAT + FIX_TRUNC
     450                 :    5666040 : ;; operations.  But the fix_trunc patterns want way more setup than we want
     451                 :          0 : ;; to provide.  Note that the scratch is DFmode instead of XFmode in order
     452                 :    5666040 : ;; to make it easy to allocate a scratch in either SSE or FP_REGs above.
     453                 :        538 : 
     454                 :    5666570 : (define_insn "loaddi_via_fpu"
     455                 :          0 :   [(set (match_operand:DF 0 "register_operand" "=f")
     456                 :        531 :         (unspec:DF [(match_operand:DI 1 "memory_operand" "m")]
     457                 :        531 :                    UNSPEC_FILD_ATOMIC))]
     458                 :       5020 :   "TARGET_80387"
     459                 :          0 :   "fild%Z1\t%1"
     460                 :        531 :   [(set_attr "type" "fmov")
     461                 :        531 :    (set_attr "mode" "DF")
     462                 :         14 :    (set_attr "fp_int_src" "true")])
     463                 :         14 : 
     464                 :        531 : (define_insn "storedi_via_fpu"
     465                 :         14 :   [(set (match_operand:DI 0 "memory_operand" "=m")
     466                 :        545 :         (unspec:DI [(match_operand:DF 1 "register_operand" "f")]
     467                 :       4503 :                    UNSPEC_FIST_ATOMIC))]
     468                 :       5020 :   "TARGET_80387"
     469                 :       4489 : {
     470                 :       4692 :   gcc_assert (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != NULL_RTX);
     471                 :       4503 : 
     472                 :       4692 :   return "fistp%Z0\t%0";
     473                 :       4503 : }
     474                 :       4692 :   [(set_attr "type" "fmov")
     475                 :       4678 :    (set_attr "mode" "DI")])
     476                 :       4503 : 
     477                 :       4700 : (define_insn "loaddi_via_sse"
     478                 :       4503 :   [(set (match_operand:DF 0 "register_operand" "=x")
     479                 :        197 :         (unspec:DF [(match_operand:DI 1 "memory_operand" "m")]
     480                 :            :                    UNSPEC_LDX_ATOMIC))]
     481                 :         14 :   "TARGET_SSE"
     482                 :        119 : {
     483                 :        223 :   if (TARGET_SSE2)
     484                 :         14 :     return "%vmovq\t{%1, %0|%0, %1}";
     485                 :            :   return "movlps\t{%1, %0|%0, %1}";
     486                 :            : }
     487                 :            :   [(set_attr "type" "ssemov")
     488                 :            :    (set_attr "mode" "DI")])
     489                 :            : 
     490                 :         14 : (define_insn "storedi_via_sse"
     491                 :    1896400 :   [(set (match_operand:DI 0 "memory_operand" "=m")
     492                 :            :         (unspec:DI [(match_operand:DF 1 "register_operand" "x")]
     493                 :            :                    UNSPEC_STX_ATOMIC))]
     494                 :         14 :   "TARGET_SSE"
     495                 :         14 : {
     496                 :    1896414 :   if (TARGET_SSE2)
     497                 :    1896414 :     return "%vmovq\t{%1, %0|%0, %1}";
     498                 :    1896400 :   return "movlps\t{%1, %0|%0, %1}";
     499                 :    1896400 : }
     500                 :    1896400 :   [(set_attr "type" "ssemov")
     501                 :            :    (set_attr "mode" "DI")])
     502                 :    1450400 : 
     503                 :    1450526 : (define_expand "atomic_compare_and_swap<mode>"
     504                 :    1077920 :   [(match_operand:QI 0 "register_operand")    ;; bool success output
     505                 :     270961 :    (match_operand:SWI124 1 "register_operand")        ;; oldval output
     506                 :     270961 :    (match_operand:SWI124 2 "memory_operand")  ;; memory
     507                 :            :    (match_operand:SWI124 3 "register_operand")        ;; expected input
     508                 :    1096200 :    (match_operand:SWI124 4 "register_operand")        ;; newval input
     509                 :      18287 :    (match_operand:SI 5 "const_int_operand")   ;; is_weak
     510                 :      18287 :    (match_operand:SI 6 "const_int_operand")   ;; success model
     511                 :    1077920 :    (match_operand:SI 7 "const_int_operand")]  ;; failure model
     512                 :    1096200 :   "TARGET_CMPXCHG"
     513                 :      32215 : {
     514                 :    1091848 :   emit_insn
     515                 :    1091848 :    (gen_atomic_compare_and_swap<mode>_1
     516                 :      15024 :     (operands[1], operands[2], operands[3], operands[4], operands[6]));
     517                 :      27758 :   ix86_expand_setcc (operands[0], EQ, gen_rtx_REG (CCZmode, FLAGS_REG),
     518                 :     810179 :                      const0_rtx);
     519                 :      13928 :   DONE;
     520                 :     169402 : })
     521                 :      10737 : 
     522                 :     158665 : (define_mode_iterator CASMODE
     523                 :     158665 :   [(DI "TARGET_64BIT || TARGET_CMPXCHG8B")
     524                 :      10737 :    (TI "TARGET_64BIT && TARGET_CMPXCHG16B")])
     525                 :      10737 : (define_mode_attr CASHMODE [(DI "SI") (TI "DI")])
     526                 :      20353 : 
     527                 :            : (define_expand "atomic_compare_and_swap<mode>"
     528                 :       9616 :   [(match_operand:QI 0 "register_operand")    ;; bool success output
     529                 :       9616 :    (match_operand:CASMODE 1 "register_operand")       ;; oldval output
     530                 :        106 :    (match_operand:CASMODE 2 "memory_operand") ;; memory
     531                 :       9510 :    (match_operand:CASMODE 3 "register_operand")       ;; expected input
     532                 :       9510 :    (match_operand:CASMODE 4 "register_operand")       ;; newval input
     533                 :         56 :    (match_operand:SI 5 "const_int_operand")   ;; is_weak
     534                 :         56 :    (match_operand:SI 6 "const_int_operand")   ;; success model
     535                 :        217 :    (match_operand:SI 7 "const_int_operand")]  ;; failure model
     536                 :         73 :   "TARGET_CMPXCHG"
     537                 :       6816 : {
     538                 :       7033 :   if (<MODE>mode == DImode && TARGET_64BIT)
     539                 :            :     {
     540                 :       6707 :       emit_insn
     541                 :       6707 :        (gen_atomic_compare_and_swapdi_1
     542                 :            :         (operands[1], operands[2], operands[3], operands[4], operands[6]));
     543                 :            :     }
     544                 :            :   else
     545                 :            :     {
     546                 :        106 :       machine_mode hmode = <CASHMODE>mode;
     547                 :            : 
     548                 :        106 :       emit_insn
     549                 :        177 :        (gen_atomic_compare_and_swap<mode>_doubleword
     550                 :            :         (operands[1], operands[2], operands[3],
     551                 :        106 :          gen_lowpart (hmode, operands[4]), gen_highpart (hmode, operands[4]),
     552                 :            :          operands[6]));
     553                 :            :     }
     554                 :            : 
     555                 :      16252 :   ix86_expand_setcc (operands[0], EQ, gen_rtx_REG (CCZmode, FLAGS_REG),
     556                 :            :                      const0_rtx);
     557                 :       6813 :   DONE;
     558                 :            : })
     559                 :            : 
     560                 :            : ;; For double-word compare and swap, we are obliged to play tricks with
     561                 :            : ;; the input newval (op3:op4) because the Intel register numbering does
     562                 :            : ;; not match the gcc register numbering, so the pair must be CX:BX.
     563                 :            : 
     564                 :      16217 : (define_mode_attr doublemodesuffix [(SI "8") (DI "16")])
     565                 :      16217 : 
     566                 :      16217 : (define_insn "atomic_compare_and_swap<dwi>_doubleword"
     567                 :      16217 :   [(set (match_operand:<DWI> 0 "register_operand" "=A")
     568                 :      16217 :         (unspec_volatile:<DWI>
     569                 :      16217 :           [(match_operand:<DWI> 1 "memory_operand" "+m")
     570                 :      16217 :            (match_operand:<DWI> 2 "register_operand" "0")
     571                 :      16217 :            (match_operand:DWIH 3 "register_operand" "b")
     572                 :      16217 :            (match_operand:DWIH 4 "register_operand" "c")
     573                 :      16217 :            (match_operand:SI 5 "const_int_operand")]
     574                 :      16217 :           UNSPECV_CMPXCHG))
     575                 :      16217 :    (set (match_dup 1)
     576                 :            :         (unspec_volatile:<DWI> [(const_int 0)] UNSPECV_CMPXCHG))
     577                 :            :    (set (reg:CCZ FLAGS_REG)
     578                 :            :         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_CMPXCHG))]
     579                 :        229 :   "TARGET_CMPXCHG<doublemodesuffix>B"
     580                 :            :   "lock{%;} %K5cmpxchg<doublemodesuffix>b\t%1")
     581                 :            : 
     582                 :            : (define_insn "atomic_compare_and_swap<mode>_1"
     583                 :            :   [(set (match_operand:SWI 0 "register_operand" "=a")
     584                 :            :         (unspec_volatile:SWI
     585                 :            :           [(match_operand:SWI 1 "memory_operand" "+m")
     586                 :            :            (match_operand:SWI 2 "register_operand" "0")
     587                 :            :            (match_operand:SWI 3 "register_operand" "<r>")
     588                 :            :            (match_operand:SI 4 "const_int_operand")]
     589                 :            :           UNSPECV_CMPXCHG))
     590                 :            :    (set (match_dup 1)
     591                 :            :         (unspec_volatile:SWI [(const_int 0)] UNSPECV_CMPXCHG))
     592                 :            :    (set (reg:CCZ FLAGS_REG)
     593                 :         35 :         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_CMPXCHG))]
     594                 :       8312 :   "TARGET_CMPXCHG"
     595                 :      34350 :   "lock{%;} %K4cmpxchg{<imodesuffix>}\t{%3, %1|%1, %3}")
     596                 :        126 : 
     597                 :        126 : ;; For operand 2 nonmemory_operand predicate is used instead of
     598                 :      65535 : ;; register_operand to allow combiner to better optimize atomic
     599                 :      65535 : ;; additions of constants.
     600                 :      65535 : (define_insn "atomic_fetch_add<mode>"
     601                 :        126 :   [(set (match_operand:SWI 0 "register_operand" "=<r>")
     602                 :        126 :         (unspec_volatile:SWI
     603                 :         35 :           [(match_operand:SWI 1 "memory_operand" "+m")
     604                 :        126 :            (match_operand:SI 3 "const_int_operand")]          ;; model
     605                 :        161 :           UNSPECV_XCHG))
     606                 :        161 :    (set (match_dup 1)
     607                 :        161 :         (plus:SWI (match_dup 1)
     608                 :        161 :                   (match_operand:SWI 2 "nonmemory_operand" "0")))
     609                 :        161 :    (clobber (reg:CC FLAGS_REG))]
     610                 :       2959 :   "TARGET_XADD"
     611                 :       5896 :   "lock{%;} %K3xadd{<imodesuffix>}\t{%0, %1|%1, %0}")
     612                 :        161 : 
     613                 :         35 : ;; This peephole2 and following insn optimize
     614                 :      21903 : ;; __sync_fetch_and_add (x, -N) == N into just lock {add,sub,inc,dec}
     615                 :      21903 : ;; followed by testing of flags instead of lock xadd and comparisons.
     616                 :      27578 : (define_peephole2
     617                 :       5801 :   [(set (match_operand:SWI 0 "register_operand")
     618                 :            :         (match_operand:SWI 2 "const_int_operand"))
     619                 :            :    (parallel [(set (match_dup 0)
     620                 :            :                    (unspec_volatile:SWI
     621                 :            :                      [(match_operand:SWI 1 "memory_operand")
     622                 :            :                       (match_operand:SI 4 "const_int_operand")]
     623                 :            :                      UNSPECV_XCHG))
     624                 :            :               (set (match_dup 1)
     625                 :            :                    (plus:SWI (match_dup 1)
     626                 :            :                              (match_dup 0)))
     627                 :            :               (clobber (reg:CC FLAGS_REG))])
     628                 :            :    (set (reg:CCZ FLAGS_REG)
     629                 :            :         (compare:CCZ (match_dup 0)
     630                 :        126 :                      (match_operand:SWI 3 "const_int_operand")))]
     631                 :       3256 :   "peep2_reg_dead_p (3, operands[0])
     632                 :       3251 :    && (unsigned HOST_WIDE_INT) INTVAL (operands[2])
     633                 :       3125 :       == -(unsigned HOST_WIDE_INT) INTVAL (operands[3])
     634                 :        927 :    && !reg_overlap_mentioned_p (operands[0], operands[1])"
     635                 :     330255 :   [(parallel [(set (reg:CCZ FLAGS_REG)
     636                 :        773 :                    (compare:CCZ
     637                 :        773 :                      (unspec_volatile:SWI [(match_dup 1) (match_dup 4)]
     638                 :        202 :                                           UNSPECV_XCHG)
     639                 :    3129620 :                      (match_dup 3)))
     640                 :       1036 :               (set (match_dup 1)
     641                 :    3130706 :                    (plus:SWI (match_dup 1)
     642                 :         76 :                              (match_dup 2)))])])
     643                 :   31071476 : 
     644                 :    3128736 : ;; Likewise, but for the -Os special case of *mov<mode>_or.
     645                 :    3128736 : (define_peephole2
     646                 :    1083376 :   [(parallel [(set (match_operand:SWI 0 "register_operand")
     647                 :       1476 :                    (match_operand:SWI 2 "constm1_operand"))
     648                 :    2046916 :               (clobber (reg:CC FLAGS_REG))])
     649                 :         77 :    (parallel [(set (match_dup 0)
     650                 :         77 :                    (unspec_volatile:SWI
     651                 :         77 :                      [(match_operand:SWI 1 "memory_operand")
     652                 :    1971886 :                       (match_operand:SI 4 "const_int_operand")]
     653                 :    1971886 :                      UNSPECV_XCHG))
     654                 :    1971886 :               (set (match_dup 1)
     655                 :     322776 :                    (plus:SWI (match_dup 1)
     656                 :    2215316 :                              (match_dup 0)))
     657                 :         76 :               (clobber (reg:CC FLAGS_REG))])
     658                 :         76 :    (set (reg:CCZ FLAGS_REG)
     659                 :         76 :         (compare:CCZ (match_dup 0)
     660                 :            :                      (match_operand:SWI 3 "const_int_operand")))]
     661                 :        101 :   "peep2_reg_dead_p (3, operands[0])
     662                 :        101 :    && (unsigned HOST_WIDE_INT) INTVAL (operands[2])
     663                 :        101 :       == -(unsigned HOST_WIDE_INT) INTVAL (operands[3])
     664                 :         68 :    && !reg_overlap_mentioned_p (operands[0], operands[1])"
     665                 :         15 :   [(parallel [(set (reg:CCZ FLAGS_REG)
     666                 :         52 :                    (compare:CCZ
     667                 :         52 :                      (unspec_volatile:SWI [(match_dup 1) (match_dup 4)]
     668                 :            :                                           UNSPECV_XCHG)
     669                 :        103 :                      (match_dup 3)))
     670                 :        103 :               (set (match_dup 1)
     671                 :        272 :                    (plus:SWI (match_dup 1)
     672                 :            :                              (match_dup 2)))])])
     673                 :            : 
     674                 :         76 : (define_insn "*atomic_fetch_add_cmp<mode>"
     675                 :         76 :   [(set (reg:CCZ FLAGS_REG)
     676                 :         76 :         (compare:CCZ
     677                 :            :           (unspec_volatile:SWI
     678                 :            :             [(match_operand:SWI 0 "memory_operand" "+m")
     679                 :            :              (match_operand:SI 3 "const_int_operand")]                ;; model
     680                 :            :             UNSPECV_XCHG)
     681                 :            :           (match_operand:SWI 2 "const_int_operand" "i")))
     682                 :        571 :    (set (match_dup 0)
     683                 :            :         (plus:SWI (match_dup 0)
     684                 :        571 :                   (match_operand:SWI 1 "const_int_operand" "i")))]
     685                 :       1580 :   "(unsigned HOST_WIDE_INT) INTVAL (operands[1])
     686                 :        697 :    == -(unsigned HOST_WIDE_INT) INTVAL (operands[2])"
     687                 :       1566 : {
     688                 :       1566 :   if (incdec_operand (operands[1], <MODE>mode))
     689                 :        571 :     {
     690                 :       1513 :       if (operands[1] == const1_rtx)
     691                 :        883 :         return "lock{%;} %K3inc{<imodesuffix>}\t%0";
     692                 :       1454 :       else
     693                 :        571 :         {
     694                 :        608 :           gcc_assert (operands[1] == constm1_rtx);
     695                 :        571 :           return "lock{%;} %K3dec{<imodesuffix>}\t%0";
     696                 :        571 :         }
     697                 :        571 :     }
     698                 :        571 : 
     699                 :       1507 :   if (x86_maybe_negate_const_int (&operands[1], <MODE>mode))
     700                 :       1375 :     return "lock{%;} %K3sub{<imodesuffix>}\t{%1, %0|%0, %1}";
     701                 :        571 : 
     702                 :        571 :   return "lock{%;} %K3add{<imodesuffix>}\t{%1, %0|%0, %1}";
     703                 :        571 : })
     704                 :            : 
     705                 :            : ;; Recall that xchg implicitly sets LOCK#, so adding it again wastes space.
     706                 :            : ;; In addition, it is always a full barrier, so we can ignore the memory model.
     707                 :       1159 : (define_insn "atomic_exchange<mode>"
     708                 :            :   [(set (match_operand:SWI 0 "register_operand" "=<r>")               ;; output
     709                 :            :         (unspec_volatile:SWI
     710                 :            :           [(match_operand:SWI 1 "memory_operand" "+m")              ;; memory
     711                 :            :            (match_operand:SI 3 "const_int_operand")]          ;; model
     712                 :            :           UNSPECV_XCHG))
     713                 :            :    (set (match_dup 1)
     714                 :            :         (match_operand:SWI 2 "register_operand" "0"))]              ;; input
     715                 :            :   ""
     716                 :            :   "%K3xchg{<imodesuffix>}\t{%1, %0|%0, %1}")
     717                 :            : 
     718                 :        571 : (define_insn "atomic_add<mode>"
     719                 :        571 :   [(set (match_operand:SWI 0 "memory_operand" "+m")
     720                 :        571 :         (unspec_volatile:SWI
     721                 :            :           [(plus:SWI (match_dup 0)
     722                 :            :                      (match_operand:SWI 1 "nonmemory_operand" "<r><i>"))
     723                 :            :            (match_operand:SI 2 "const_int_operand")]          ;; model
     724                 :            :           UNSPECV_LOCK))
     725                 :            :    (clobber (reg:CC FLAGS_REG))]
     726                 :        154 :   ""
     727                 :       8196 : {
     728                 :       8350 :   if (incdec_operand (operands[1], <MODE>mode))
     729                 :        154 :     {
     730                 :        276 :       if (operands[1] == const1_rtx)
     731                 :        154 :         return "lock{%;} %K2inc{<imodesuffix>}\t%0";
     732                 :        154 :       else
     733                 :        154 :         {
     734                 :        176 :           gcc_assert (operands[1] == constm1_rtx);
     735                 :          0 :           return "lock{%;} %K2dec{<imodesuffix>}\t%0";
     736                 :        154 :         }
     737                 :        154 :     }
     738                 :        154 : 
     739                 :       8228 :   if (x86_maybe_negate_const_int (&operands[1], <MODE>mode))
     740                 :        826 :     return "lock{%;} %K2sub{<imodesuffix>}\t{%1, %0|%0, %1}";
     741                 :        154 : 
     742                 :        154 :   return "lock{%;} %K2add{<imodesuffix>}\t{%1, %0|%0, %1}";
     743                 :        154 : })
     744                 :        154 : 
     745                 :        154 : (define_insn "atomic_sub<mode>"
     746                 :        154 :   [(set (match_operand:SWI 0 "memory_operand" "+m")
     747                 :       8280 :         (unspec_volatile:SWI
     748                 :            :           [(minus:SWI (match_dup 0)
     749                 :            :                       (match_operand:SWI 1 "nonmemory_operand" "<r><i>"))
     750                 :            :            (match_operand:SI 2 "const_int_operand")]          ;; model
     751                 :            :           UNSPECV_LOCK))
     752                 :            :    (clobber (reg:CC FLAGS_REG))]
     753                 :            :   ""
     754                 :       1757 : {
     755                 :       1757 :   if (incdec_operand (operands[1], <MODE>mode))
     756                 :            :     {
     757                 :         76 :       if (operands[1] == const1_rtx)
     758                 :            :         return "lock{%;} %K2dec{<imodesuffix>}\t%0";
     759                 :            :       else
     760                 :            :         {
     761                 :         20 :           gcc_assert (operands[1] == constm1_rtx);
     762                 :        154 :           return "lock{%;} %K2inc{<imodesuffix>}\t%0";
     763                 :        154 :         }
     764                 :        154 :     }
     765                 :            : 
     766                 :       1681 :   if (x86_maybe_negate_const_int (&operands[1], <MODE>mode))
     767                 :        122 :     return "lock{%;} %K2add{<imodesuffix>}\t{%1, %0|%0, %1}";
     768                 :            : 
     769                 :            :   return "lock{%;} %K2sub{<imodesuffix>}\t{%1, %0|%0, %1}";
     770                 :          0 : })
     771                 :            : 
     772                 :          0 : (define_insn "atomic_<logic><mode>"
     773                 :          0 :   [(set (match_operand:SWI 0 "memory_operand" "+m")
     774                 :       1537 :         (unspec_volatile:SWI
     775                 :          0 :           [(any_logic:SWI (match_dup 0)
     776                 :          0 :                           (match_operand:SWI 1 "nonmemory_operand" "<r><i>"))
     777                 :          0 :            (match_operand:SI 2 "const_int_operand")]          ;; model
     778                 :          0 :           UNSPECV_LOCK))
     779                 :          0 :    (clobber (reg:CC FLAGS_REG))]
     780                 :          0 :   ""
     781                 :          0 :   "lock{%;} %K2<logic>{<imodesuffix>}\t{%1, %0|%0, %1}")
     782                 :          0 : 
     783                 :          0 : (define_expand "atomic_bit_test_and_set<mode>"
     784                 :          0 :   [(match_operand:SWI248 0 "register_operand")
     785                 :          0 :    (match_operand:SWI248 1 "memory_operand")
     786                 :          0 :    (match_operand:SWI248 2 "nonmemory_operand")
     787                 :          0 :    (match_operand:SI 3 "const_int_operand") ;; model
     788                 :          0 :    (match_operand:SI 4 "const_int_operand")]
     789                 :          0 :   ""
     790                 :         55 : {
     791                 :         55 :   emit_insn (gen_atomic_bit_test_and_set<mode>_1 (operands[1], operands[2],
     792                 :            :                                                   operands[3]));
     793                 :         55 :   rtx tem = gen_reg_rtx (QImode);
     794                 :         55 :   ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
     795                 :         55 :   rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
     796                 :         55 :   if (operands[4] == const0_rtx)
     797                 :         12 :     result = expand_simple_binop (<MODE>mode, ASHIFT, result,
     798                 :            :                                   operands[2], operands[0], 0, OPTAB_DIRECT);
     799                 :         55 :   if (result != operands[0])
     800                 :         43 :     emit_move_insn (operands[0], result);
     801                 :         55 :   DONE;
     802                 :            : })
     803                 :            : 
     804                 :            : (define_insn "atomic_bit_test_and_set<mode>_1"
     805                 :            :   [(set (reg:CCC FLAGS_REG)
     806                 :          0 :         (compare:CCC
     807                 :          0 :           (unspec_volatile:SWI248
     808                 :          0 :             [(match_operand:SWI248 0 "memory_operand" "+m")
     809                 :            :              (match_operand:SI 2 "const_int_operand")]                ;; model
     810                 :            :             UNSPECV_XCHG)
     811                 :            :           (const_int 0)))
     812                 :            :    (set (zero_extract:SWI248 (match_dup 0)
     813                 :            :                              (const_int 1)
     814                 :          0 :                              (match_operand:SWI248 1 "nonmemory_operand" "rN"))
     815                 :            :         (const_int 1))]
     816                 :          0 :   ""
     817                 :          0 :   "lock{%;} %K2bts{<imodesuffix>}\t{%1, %0|%0, %1}")
     818                 :          0 : 
     819                 :          0 : (define_expand "atomic_bit_test_and_complement<mode>"
     820                 :          0 :   [(match_operand:SWI248 0 "register_operand")
     821                 :          0 :    (match_operand:SWI248 1 "memory_operand")
     822                 :          0 :    (match_operand:SWI248 2 "nonmemory_operand")
     823                 :          0 :    (match_operand:SI 3 "const_int_operand") ;; model
     824                 :          0 :    (match_operand:SI 4 "const_int_operand")]
     825                 :          0 :   ""
     826                 :         60 : {
     827                 :         60 :   emit_insn (gen_atomic_bit_test_and_complement<mode>_1 (operands[1],
     828                 :         43 :                                                          operands[2],
     829                 :          0 :                                                          operands[3]));
     830                 :         60 :   rtx tem = gen_reg_rtx (QImode);
     831                 :         60 :   ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
     832                 :         60 :   rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
     833                 :         60 :   if (operands[4] == const0_rtx)
     834                 :         18 :     result = expand_simple_binop (<MODE>mode, ASHIFT, result,
     835                 :         43 :                                   operands[2], operands[0], 0, OPTAB_DIRECT);
     836                 :         60 :   if (result != operands[0])
     837                 :         42 :     emit_move_insn (operands[0], result);
     838                 :         60 :   DONE;
     839                 :         43 : })
     840                 :         43 : 
     841                 :         43 : (define_insn "atomic_bit_test_and_complement<mode>_1"
     842                 :         43 :   [(set (reg:CCC FLAGS_REG)
     843                 :            :         (compare:CCC
     844                 :            :           (unspec_volatile:SWI248
     845                 :            :             [(match_operand:SWI248 0 "memory_operand" "+m")
     846                 :            :              (match_operand:SI 2 "const_int_operand")]                ;; model
     847                 :            :             UNSPECV_XCHG)
     848                 :            :           (const_int 0)))
     849                 :            :    (set (zero_extract:SWI248 (match_dup 0)
     850                 :          0 :                              (const_int 1)
     851                 :          0 :                              (match_operand:SWI248 1 "nonmemory_operand" "rN"))
     852                 :          0 :         (not:SWI248 (zero_extract:SWI248 (match_dup 0)
     853                 :            :                                          (const_int 1)
     854                 :            :                                          (match_dup 1))))]
     855                 :            :   ""
     856                 :            :   "lock{%;} %K2btc{<imodesuffix>}\t{%1, %0|%0, %1}")
     857                 :            : 
     858                 :         52 : (define_expand "atomic_bit_test_and_reset<mode>"
     859                 :            :   [(match_operand:SWI248 0 "register_operand")
     860                 :         52 :    (match_operand:SWI248 1 "memory_operand")
     861                 :         52 :    (match_operand:SWI248 2 "nonmemory_operand")
     862                 :         52 :    (match_operand:SI 3 "const_int_operand") ;; model
     863                 :         52 :    (match_operand:SI 4 "const_int_operand")]
     864                 :         52 :   ""
     865                 :        148 : {
     866                 :         88 :   emit_insn (gen_atomic_bit_test_and_reset<mode>_1 (operands[1], operands[2],
     867                 :          0 :                                                     operands[3]));
     868                 :         88 :   rtx tem = gen_reg_rtx (QImode);
     869                 :         36 :   ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
     870                 :         36 :   rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
     871                 :         36 :   if (operands[4] == const0_rtx)
     872                 :         66 :     result = expand_simple_binop (<MODE>mode, ASHIFT, result,
     873                 :        112 :                                   operands[2], operands[0], 0, OPTAB_DIRECT);
     874                 :         36 :   if (result != operands[0])
     875                 :         30 :     emit_move_insn (operands[0], result);
     876                 :         36 :   DONE;
     877                 :        112 : })
     878                 :        112 : 
     879                 :        112 : (define_insn "atomic_bit_test_and_reset<mode>_1"
     880                 :            :   [(set (reg:CCC FLAGS_REG)
     881                 :            :         (compare:CCC
     882                 :            :           (unspec_volatile:SWI248
     883                 :            :             [(match_operand:SWI248 0 "memory_operand" "+m")
     884                 :            :              (match_operand:SI 2 "const_int_operand")]                ;; model
     885                 :            :             UNSPECV_XCHG)
     886                 :            :           (const_int 0)))
     887                 :            :    (set (zero_extract:SWI248 (match_dup 0)
     888                 :            :                              (const_int 1)
     889                 :            :                              (match_operand:SWI248 1 "nonmemory_operand" "rN"))
     890                 :            :         (const_int 0))]
     891                 :            :   ""
     892                 :            :   "lock{%;} %K2btr{<imodesuffix>}\t{%1, %0|%0, %1}")

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.