1 ;; GCC machine description for Blackfin synchronization instructions. 2 ;; Copyright (C) 2005-2022 Free Software Foundation, Inc. 3 ;; Contributed by Analog Devices. 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_code_iterator FETCHOP [plus minus ior and xor]) 22 (define_code_attr fetchop_name 23 [(plus "add") (minus "sub") (ior "ior") (and "and") (xor "xor")]) 24 (define_code_attr fetchop_addr 25 [(plus "1072") (minus "1088") (ior "1104") (and "1120") (xor "1136")]) 26 27 (define_insn "sync_<fetchop_name>si_internal" 28 [(set (mem:SI (match_operand:SI 0 "register_operand" "qA")) 29 (unspec:SI 30 [(FETCHOP:SI (mem:SI (match_dup 0)) 31 (match_operand:SI 1 "register_operand" "q0")) 32 (match_operand:SI 2 "register_no_elim_operand" "a")] 33 UNSPEC_ATOMIC)) 34 (clobber (match_scratch:SI 3 "=q0")) 35 (clobber (match_scratch:SI 4 "=q1")) 36 (clobber (reg:SI REG_RETS))] 37 "TARGET_SUPPORTS_SYNC_CALLS" 38 "call (%2);" 39 [(set_attr "type" "call")]) 40 41 (define_expand "sync_<fetchop_name>si" 42 [(parallel 43 [(set (match_operand:SI 0 "memory_operand" "+m") 44 (unspec:SI 45 [(FETCHOP:SI (match_dup 0) 46 (match_operand:SI 1 "register_operand" "q0")) 47 (match_dup 2)] 48 UNSPEC_ATOMIC)) 49 (clobber (match_scratch:SI 3 "")) 50 (clobber (match_scratch:SI 4 "")) 51 (clobber (reg:SI REG_RETS))])] 52 "TARGET_SUPPORTS_SYNC_CALLS" 53 { 54 if (!REG_P (XEXP (operands[0], 0))) 55 { 56 operands[0] = shallow_copy_rtx (operands[0]); 57 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0)); 58 } 59 operands[2] = force_reg (Pmode, GEN_INT (<fetchop_addr>)); 60 }) 61 62 (define_insn "sync_old_<fetchop_name>si_internal" 63 [(set (match_operand:SI 0 "register_operand" "=q1") 64 (mem:SI (match_operand:SI 1 "register_operand" "qA"))) 65 (set (mem:SI (match_dup 1)) 66 (unspec:SI 67 [(FETCHOP:SI (mem:SI (match_dup 1)) 68 (match_operand:SI 2 "register_operand" "q0")) 69 (match_operand:SI 3 "register_no_elim_operand" "a")] 70 UNSPEC_ATOMIC)) 71 (clobber (match_scratch:SI 4 "=q0")) 72 (clobber (reg:SI REG_RETS))] 73 "TARGET_SUPPORTS_SYNC_CALLS" 74 "call (%3);" 75 [(set_attr "type" "call")]) 76 77 (define_expand "sync_old_<fetchop_name>si" 78 [(parallel 79 [(set (match_operand:SI 0 "register_operand" "") 80 (match_operand:SI 1 "memory_operand" "")) 81 (set (match_dup 1) 82 (unspec:SI 83 [(FETCHOP:SI (match_dup 1) 84 (match_operand:SI 2 "register_operand" "")) 85 (match_dup 3)] 86 UNSPEC_ATOMIC)) 87 (clobber (match_scratch:SI 4 "")) 88 (clobber (reg:SI REG_RETS))])] 89 "TARGET_SUPPORTS_SYNC_CALLS" 90 { 91 if (!REG_P (XEXP (operands[1], 0))) 92 { 93 operands[1] = shallow_copy_rtx (operands[1]); 94 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0)); 95 } 96 operands[3] = force_reg (Pmode, GEN_INT (<fetchop_addr>)); 97 }) 98 99 (define_insn "sync_new_<fetchop_name>si_internal" 100 [(set (match_operand:SI 0 "register_operand" "=q0") 101 (unspec:SI 102 [(FETCHOP:SI 103 (mem:SI (match_operand:SI 1 "register_operand" "qA")) 104 (match_operand:SI 2 "register_operand" "q0")) 105 (match_operand:SI 3 "register_no_elim_operand" "a")] 106 UNSPEC_ATOMIC)) 107 (set (mem:SI (match_dup 1)) 108 (unspec:SI 109 [(FETCHOP:SI (mem:SI (match_dup 1)) (match_dup 2)) 110 (match_dup 3)] 111 UNSPEC_ATOMIC)) 112 (clobber (match_scratch:SI 4 "=q1")) 113 (clobber (reg:SI REG_RETS))] 114 "TARGET_SUPPORTS_SYNC_CALLS" 115 "call (%3);" 116 [(set_attr "type" "call")]) 117 118 (define_expand "sync_new_<fetchop_name>si" 119 [(parallel 120 [(set (match_operand:SI 0 "register_operand" "") 121 (unspec:SI 122 [(FETCHOP:SI (match_operand:SI 1 "memory_operand" "") 123 (match_operand:SI 2 "register_operand" "")) 124 (match_dup 3)] 125 UNSPEC_ATOMIC)) 126 (set (match_dup 1) 127 (unspec:SI 128 [(FETCHOP:SI (match_dup 1) (match_dup 2)) 129 (match_dup 3)] 130 UNSPEC_ATOMIC)) 131 (clobber (match_scratch:SI 4 "")) 132 (clobber (reg:SI REG_RETS))])] 133 "TARGET_SUPPORTS_SYNC_CALLS" 134 { 135 if (!REG_P (XEXP (operands[1], 0))) 136 { 137 operands[1] = shallow_copy_rtx (operands[1]); 138 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0)); 139 } 140 operands[3] = force_reg (Pmode, GEN_INT (<fetchop_addr>)); 141 }) 142 143 (define_insn "sync_compare_and_swapsi_internal" 144 [(set (match_operand:SI 0 "register_operand" "=q0") 145 (mem:SI (match_operand:SI 1 "register_operand" "qA"))) 146 (set (mem:SI (match_dup 1)) 147 (unspec:SI 148 [(mem:SI (match_dup 1)) 149 (match_operand:SI 2 "register_operand" "q1") 150 (match_operand:SI 3 "register_operand" "q2") 151 (match_operand:SI 4 "register_no_elim_operand" "a")] 152 UNSPEC_ATOMIC)) 153 (clobber (reg:SI REG_RETS))] 154 "TARGET_SUPPORTS_SYNC_CALLS" 155 "call (%4);" 156 [(set_attr "type" "call")]) 157 158 (define_expand "sync_compare_and_swapsi" 159 [(parallel 160 [(set (match_operand:SI 0 "register_operand" "") 161 (match_operand:SI 1 "memory_operand" "")) 162 (set (match_dup 1) 163 (unspec:SI 164 [(match_dup 1) 165 (match_operand:SI 2 "register_operand" "") 166 (match_operand:SI 3 "register_operand" "") 167 (match_dup 4)] 168 UNSPEC_ATOMIC)) 169 (clobber (reg:SI REG_RETS))])] 170 "TARGET_SUPPORTS_SYNC_CALLS" 171 { 172 if (!REG_P (XEXP (operands[1], 0))) 173 { 174 operands[1] = shallow_copy_rtx (operands[1]); 175 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0)); 176 } 177 operands[4] = force_reg (Pmode, GEN_INT (0x420)); 178 }) 179