1;; GCC machine description for IA-64 synchronization instructions. 2;; Copyright (C) 2005, 2007, 2008, 2009, 2010 3;; Free Software Foundation, Inc. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, 13;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; GNU General Public License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21(define_mode_iterator IMODE [QI HI SI DI]) 22(define_mode_iterator I124MODE [QI HI SI]) 23(define_mode_iterator I48MODE [SI DI]) 24(define_mode_attr modesuffix [(QI "1") (HI "2") (SI "4") (DI "8")]) 25 26(define_code_iterator FETCHOP [plus minus ior xor and]) 27(define_code_attr fetchop_name 28 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")]) 29 30(define_expand "memory_barrier" 31 [(set (match_dup 0) 32 (unspec:BLK [(match_dup 0)] UNSPEC_MF))] 33 "" 34{ 35 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 36 MEM_VOLATILE_P (operands[0]) = 1; 37}) 38 39(define_insn "*memory_barrier" 40 [(set (match_operand:BLK 0 "" "") 41 (unspec:BLK [(match_dup 0)] UNSPEC_MF))] 42 "" 43 "mf" 44 [(set_attr "itanium_class" "syst_m")]) 45 46(define_insn "fetchadd_acq_<mode>" 47 [(set (match_operand:I48MODE 0 "gr_register_operand" "=r") 48 (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S")) 49 (set (match_dup 1) 50 (unspec:I48MODE [(match_dup 1) 51 (match_operand:I48MODE 2 "fetchadd_operand" "n")] 52 UNSPEC_FETCHADD_ACQ))] 53 "" 54 "fetchadd<modesuffix>.acq %0 = %1, %2" 55 [(set_attr "itanium_class" "sem")]) 56 57(define_expand "sync_<fetchop_name><mode>" 58 [(set (match_operand:IMODE 0 "memory_operand" "") 59 (FETCHOP:IMODE (match_dup 0) 60 (match_operand:IMODE 1 "general_operand" "")))] 61 "" 62{ 63 ia64_expand_atomic_op (<CODE>, operands[0], operands[1], NULL, NULL); 64 DONE; 65}) 66 67(define_expand "sync_nand<mode>" 68 [(set (match_operand:IMODE 0 "memory_operand" "") 69 (not:IMODE 70 (and:IMODE (match_dup 0) 71 (match_operand:IMODE 1 "general_operand" ""))))] 72 "" 73{ 74 ia64_expand_atomic_op (NOT, operands[0], operands[1], NULL, NULL); 75 DONE; 76}) 77 78(define_expand "sync_old_<fetchop_name><mode>" 79 [(set (match_operand:IMODE 0 "gr_register_operand" "") 80 (FETCHOP:IMODE 81 (match_operand:IMODE 1 "memory_operand" "") 82 (match_operand:IMODE 2 "general_operand" "")))] 83 "" 84{ 85 ia64_expand_atomic_op (<CODE>, operands[1], operands[2], operands[0], NULL); 86 DONE; 87}) 88 89(define_expand "sync_old_nand<mode>" 90 [(set (match_operand:IMODE 0 "gr_register_operand" "") 91 (not:IMODE 92 (and:IMODE (match_operand:IMODE 1 "memory_operand" "") 93 (match_operand:IMODE 2 "general_operand" ""))))] 94 "" 95{ 96 ia64_expand_atomic_op (NOT, operands[1], operands[2], operands[0], NULL); 97 DONE; 98}) 99 100(define_expand "sync_new_<fetchop_name><mode>" 101 [(set (match_operand:IMODE 0 "gr_register_operand" "") 102 (FETCHOP:IMODE 103 (match_operand:IMODE 1 "memory_operand" "") 104 (match_operand:IMODE 2 "general_operand" "")))] 105 "" 106{ 107 ia64_expand_atomic_op (<CODE>, operands[1], operands[2], NULL, operands[0]); 108 DONE; 109}) 110 111(define_expand "sync_new_nand<mode>" 112 [(set (match_operand:IMODE 0 "gr_register_operand" "") 113 (not:IMODE 114 (and:IMODE (match_operand:IMODE 1 "memory_operand" "") 115 (match_operand:IMODE 2 "general_operand" ""))))] 116 "" 117{ 118 ia64_expand_atomic_op (NOT, operands[1], operands[2], NULL, operands[0]); 119 DONE; 120}) 121 122(define_expand "sync_compare_and_swap<mode>" 123 [(match_operand:IMODE 0 "gr_register_operand" "") 124 (match_operand:IMODE 1 "memory_operand" "") 125 (match_operand:IMODE 2 "gr_register_operand" "") 126 (match_operand:IMODE 3 "gr_register_operand" "")] 127 "" 128{ 129 rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM); 130 rtx dst; 131 132 convert_move (ccv, operands[2], 1); 133 134 dst = operands[0]; 135 if (GET_MODE (dst) != DImode) 136 dst = gen_reg_rtx (DImode); 137 138 emit_insn (gen_cmpxchg_rel_<mode> (dst, operands[1], ccv, operands[3])); 139 emit_insn (gen_memory_barrier ()); 140 141 if (dst != operands[0]) 142 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, dst)); 143 DONE; 144}) 145 146(define_insn "cmpxchg_rel_<mode>" 147 [(set (match_operand:DI 0 "gr_register_operand" "=r") 148 (zero_extend:DI 149 (match_operand:I124MODE 1 "not_postinc_memory_operand" "+S"))) 150 (set (match_dup 1) 151 (unspec:I124MODE 152 [(match_dup 1) 153 (match_operand:DI 2 "ar_ccv_reg_operand" "") 154 (match_operand:I124MODE 3 "gr_reg_or_0_operand" "rO")] 155 UNSPEC_CMPXCHG_ACQ))] 156 "" 157 "cmpxchg<modesuffix>.rel %0 = %1, %r3, %2" 158 [(set_attr "itanium_class" "sem")]) 159 160(define_insn "cmpxchg_rel_di" 161 [(set (match_operand:DI 0 "gr_register_operand" "=r") 162 (match_operand:DI 1 "not_postinc_memory_operand" "+S")) 163 (set (match_dup 1) 164 (unspec:DI [(match_dup 1) 165 (match_operand:DI 2 "ar_ccv_reg_operand" "") 166 (match_operand:DI 3 "gr_reg_or_0_operand" "rO")] 167 UNSPEC_CMPXCHG_ACQ))] 168 "" 169 "cmpxchg8.rel %0 = %1, %r3, %2" 170 [(set_attr "itanium_class" "sem")]) 171 172(define_insn "sync_lock_test_and_set<mode>" 173 [(set (match_operand:IMODE 0 "gr_register_operand" "=r") 174 (match_operand:IMODE 1 "not_postinc_memory_operand" "+S")) 175 (set (match_dup 1) 176 (match_operand:IMODE 2 "gr_reg_or_0_operand" "rO"))] 177 "" 178 "xchg<modesuffix> %0 = %1, %r2" 179 [(set_attr "itanium_class" "sem")]) 180 181(define_expand "sync_lock_release<mode>" 182 [(set (match_operand:IMODE 0 "memory_operand" "") 183 (match_operand:IMODE 1 "gr_reg_or_0_operand" ""))] 184 "" 185{ 186 gcc_assert (MEM_VOLATILE_P (operands[0])); 187}) 188