1;; Machine description for PowerPC synchronization instructions. 2;; Copyright (C) 2005 Free Software Foundation, Inc. 3;; Contributed by Geoffrey Keating. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 2, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; 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 COPYING. If not, write to the 19;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 20;; MA 02110-1301, USA. 21 22(define_mode_attr larx [(SI "lwarx") (DI "ldarx")]) 23(define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")]) 24 25(define_code_macro FETCHOP [plus minus ior xor and]) 26(define_code_attr fetchop_name 27 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")]) 28(define_code_attr fetchop_pred 29 [(plus "add_operand") (minus "gpc_reg_operand") 30 (ior "logical_operand") (xor "logical_operand") (and "and_operand")]) 31(define_code_attr fetchopsi_constr 32 [(plus "rIL") (minus "r") (ior "rKL") (xor "rKL") (and "rTKL")]) 33(define_code_attr fetchopdi_constr 34 [(plus "rIL") (minus "r") (ior "rKJF") (xor "rKJF") (and "rSTKJ")]) 35 36(define_expand "memory_barrier" 37 [(set (mem:BLK (match_dup 0)) 38 (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_SYNC))] 39 "" 40{ 41 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 42 MEM_VOLATILE_P (operands[0]) = 1; 43}) 44 45(define_insn "*sync_internal" 46 [(set (match_operand:BLK 0 "" "") 47 (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_SYNC))] 48 "" 49 "{dcs|sync}" 50 [(set_attr "type" "sync")]) 51 52(define_insn "load_locked_<mode>" 53 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 54 (unspec_volatile:GPR 55 [(match_operand:GPR 1 "memory_operand" "Z")] UNSPECV_LL))] 56 "TARGET_POWERPC" 57 "<larx> %0,%y1" 58 [(set_attr "type" "load_l")]) 59 60(define_insn "store_conditional_<mode>" 61 [(set (match_operand:CC 0 "cc_reg_operand" "=x") 62 (unspec_volatile:CC [(const_int 0)] UNSPECV_SC)) 63 (set (match_operand:GPR 1 "memory_operand" "=Z") 64 (match_operand:GPR 2 "gpc_reg_operand" "r"))] 65 "TARGET_POWERPC" 66 "<stcx> %2,%y1" 67 [(set_attr "type" "store_c")]) 68 69(define_insn_and_split "sync_compare_and_swap<mode>" 70 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 71 (match_operand:GPR 1 "memory_operand" "+Z")) 72 (set (match_dup 1) 73 (unspec:GPR 74 [(match_operand:GPR 2 "reg_or_short_operand" "rI") 75 (match_operand:GPR 3 "gpc_reg_operand" "r")] 76 UNSPEC_CMPXCHG)) 77 (clobber (match_scratch:GPR 4 "=&r")) 78 (clobber (match_scratch:CC 5 "=&x"))] 79 "TARGET_POWERPC" 80 "#" 81 "&& reload_completed" 82 [(const_int 0)] 83{ 84 rs6000_split_compare_and_swap (operands[0], operands[1], operands[2], 85 operands[3], operands[4]); 86 DONE; 87}) 88 89(define_expand "sync_compare_and_swaphi" 90 [(match_operand:HI 0 "gpc_reg_operand" "") 91 (match_operand:HI 1 "memory_operand" "") 92 (match_operand:HI 2 "gpc_reg_operand" "") 93 (match_operand:HI 3 "gpc_reg_operand" "")] 94 "TARGET_POWERPC" 95{ 96 rs6000_expand_compare_and_swapqhi (operands[0], operands[1], 97 operands[2], operands[3]); 98 DONE; 99}) 100 101(define_expand "sync_compare_and_swapqi" 102 [(match_operand:QI 0 "gpc_reg_operand" "") 103 (match_operand:QI 1 "memory_operand" "") 104 (match_operand:QI 2 "gpc_reg_operand" "") 105 (match_operand:QI 3 "gpc_reg_operand" "")] 106 "TARGET_POWERPC" 107{ 108 rs6000_expand_compare_and_swapqhi (operands[0], operands[1], 109 operands[2], operands[3]); 110 DONE; 111}) 112 113(define_insn_and_split "sync_compare_and_swapqhi_internal" 114 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 115 (match_operand:SI 4 "memory_operand" "+Z")) 116 (set (match_dup 4) 117 (unspec:SI 118 [(match_operand:SI 1 "gpc_reg_operand" "r") 119 (match_operand:SI 2 "gpc_reg_operand" "r") 120 (match_operand:SI 3 "gpc_reg_operand" "r")] 121 UNSPEC_CMPXCHG)) 122 (clobber (match_scratch:SI 5 "=&r")) 123 (clobber (match_scratch:CC 6 "=&x"))] 124 "TARGET_POWERPC" 125 "#" 126 "&& reload_completed" 127 [(const_int 0)] 128{ 129 rs6000_split_compare_and_swapqhi (operands[0], operands[1], 130 operands[2], operands[3], operands[4], 131 operands[5]); 132 DONE; 133}) 134 135(define_insn_and_split "sync_lock_test_and_set<mode>" 136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 137 (match_operand:GPR 1 "memory_operand" "+Z")) 138 (set (match_dup 1) 139 (unspec:GPR 140 [(match_operand:GPR 2 "reg_or_short_operand" "rL")] 141 UNSPEC_XCHG)) 142 (clobber (match_scratch:GPR 3 "=&r")) 143 (clobber (match_scratch:CC 4 "=&x"))] 144 "TARGET_POWERPC" 145 "#" 146 "&& reload_completed" 147 [(const_int 0)] 148{ 149 rs6000_split_lock_test_and_set (operands[0], operands[1], operands[2], 150 operands[3]); 151 DONE; 152}) 153 154(define_expand "sync_<fetchop_name><mode>" 155 [(parallel [(set (match_operand:INT1 0 "memory_operand" "") 156 (unspec:INT1 157 [(FETCHOP:INT1 (match_dup 0) 158 (match_operand:INT1 1 "<fetchop_pred>" ""))] 159 UNSPEC_ATOMIC)) 160 (clobber (scratch:INT1)) 161 (clobber (scratch:CC))])] 162 "TARGET_POWERPC" 163 " 164{ 165 if (<MODE>mode != SImode && <MODE>mode != DImode) 166 { 167 if (PPC405_ERRATUM77) 168 FAIL; 169 rs6000_emit_sync (<CODE>, <MODE>mode, operands[0], operands[1], 170 NULL_RTX, NULL_RTX, true); 171 DONE; 172 } 173}") 174 175(define_insn_and_split "*sync_<fetchop_name>si_internal" 176 [(set (match_operand:SI 0 "memory_operand" "+Z") 177 (unspec:SI 178 [(FETCHOP:SI (match_dup 0) 179 (match_operand:SI 1 "<fetchop_pred>" "<fetchopsi_constr>"))] 180 UNSPEC_ATOMIC)) 181 (clobber (match_scratch:SI 2 "=&b")) 182 (clobber (match_scratch:CC 3 "=&x"))] 183 "TARGET_POWERPC" 184 "#" 185 "&& reload_completed" 186 [(const_int 0)] 187{ 188 rs6000_split_atomic_op (<CODE>, operands[0], operands[1], 189 NULL_RTX, NULL_RTX, operands[2]); 190 DONE; 191}) 192 193(define_insn_and_split "*sync_<fetchop_name>di_internal" 194 [(set (match_operand:DI 0 "memory_operand" "+Z") 195 (unspec:DI 196 [(FETCHOP:DI (match_dup 0) 197 (match_operand:DI 1 "<fetchop_pred>" "<fetchopdi_constr>"))] 198 UNSPEC_ATOMIC)) 199 (clobber (match_scratch:DI 2 "=&b")) 200 (clobber (match_scratch:CC 3 "=&x"))] 201 "TARGET_POWERPC" 202 "#" 203 "&& reload_completed" 204 [(const_int 0)] 205{ 206 rs6000_split_atomic_op (<CODE>, operands[0], operands[1], 207 NULL_RTX, NULL_RTX, operands[2]); 208 DONE; 209}) 210 211(define_expand "sync_nand<mode>" 212 [(parallel [(set (match_operand:INT1 0 "memory_operand" "") 213 (unspec:INT1 214 [(and:INT1 (not:INT1 (match_dup 0)) 215 (match_operand:INT1 1 "gpc_reg_operand" ""))] 216 UNSPEC_ATOMIC)) 217 (clobber (scratch:INT1)) 218 (clobber (scratch:CC))])] 219 "TARGET_POWERPC" 220 " 221{ 222 if (<MODE>mode != SImode && <MODE>mode != DImode) 223 { 224 if (PPC405_ERRATUM77) 225 FAIL; 226 rs6000_emit_sync (AND, <MODE>mode, 227 gen_rtx_NOT (<MODE>mode, operands[0]), 228 operands[1], 229 NULL_RTX, NULL_RTX, true); 230 DONE; 231 } 232}") 233 234(define_insn_and_split "*sync_nand<mode>_internal" 235 [(set (match_operand:GPR 0 "memory_operand" "+Z") 236 (unspec:GPR 237 [(and:GPR (not:GPR (match_dup 0)) 238 (match_operand:GPR 1 "gpc_reg_operand" "r"))] 239 UNSPEC_ATOMIC)) 240 (clobber (match_scratch:GPR 2 "=&r")) 241 (clobber (match_scratch:CC 3 "=&x"))] 242 "TARGET_POWERPC" 243 "#" 244 "&& reload_completed" 245 [(const_int 0)] 246{ 247 rs6000_split_atomic_op (NOT, operands[0], operands[1], 248 NULL_RTX, NULL_RTX, operands[2]); 249 DONE; 250}) 251 252(define_expand "sync_old_<fetchop_name><mode>" 253 [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "") 254 (match_operand:INT1 1 "memory_operand" "")) 255 (set (match_dup 1) 256 (unspec:INT1 257 [(FETCHOP:INT1 (match_dup 1) 258 (match_operand:INT1 2 "<fetchop_pred>" ""))] 259 UNSPEC_ATOMIC)) 260 (clobber (scratch:INT1)) 261 (clobber (scratch:CC))])] 262 "TARGET_POWERPC" 263 " 264{ 265 if (<MODE>mode != SImode && <MODE>mode != DImode) 266 { 267 if (PPC405_ERRATUM77) 268 FAIL; 269 rs6000_emit_sync (<CODE>, <MODE>mode, operands[1], operands[2], 270 operands[0], NULL_RTX, true); 271 DONE; 272 } 273}") 274 275(define_insn_and_split "*sync_old_<fetchop_name>si_internal" 276 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 277 (match_operand:SI 1 "memory_operand" "+Z")) 278 (set (match_dup 1) 279 (unspec:SI 280 [(FETCHOP:SI (match_dup 1) 281 (match_operand:SI 2 "<fetchop_pred>" "<fetchopsi_constr>"))] 282 UNSPEC_ATOMIC)) 283 (clobber (match_scratch:SI 3 "=&b")) 284 (clobber (match_scratch:CC 4 "=&x"))] 285 "TARGET_POWERPC" 286 "#" 287 "&& reload_completed" 288 [(const_int 0)] 289{ 290 rs6000_split_atomic_op (<CODE>, operands[1], operands[2], 291 operands[0], NULL_RTX, operands[3]); 292 DONE; 293}) 294 295(define_insn_and_split "*sync_old_<fetchop_name>di_internal" 296 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 297 (match_operand:DI 1 "memory_operand" "+Z")) 298 (set (match_dup 1) 299 (unspec:DI 300 [(FETCHOP:DI (match_dup 1) 301 (match_operand:DI 2 "<fetchop_pred>" "<fetchopdi_constr>"))] 302 UNSPEC_ATOMIC)) 303 (clobber (match_scratch:DI 3 "=&b")) 304 (clobber (match_scratch:CC 4 "=&x"))] 305 "TARGET_POWERPC" 306 "#" 307 "&& reload_completed" 308 [(const_int 0)] 309{ 310 rs6000_split_atomic_op (<CODE>, operands[1], operands[2], 311 operands[0], NULL_RTX, operands[3]); 312 DONE; 313}) 314 315(define_expand "sync_old_nand<mode>" 316 [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "") 317 (match_operand:INT1 1 "memory_operand" "")) 318 (set (match_dup 1) 319 (unspec:INT1 320 [(and:INT1 (not:INT1 (match_dup 1)) 321 (match_operand:INT1 2 "gpc_reg_operand" ""))] 322 UNSPEC_ATOMIC)) 323 (clobber (scratch:INT1)) 324 (clobber (scratch:CC))])] 325 "TARGET_POWERPC" 326 " 327{ 328 if (<MODE>mode != SImode && <MODE>mode != DImode) 329 { 330 if (PPC405_ERRATUM77) 331 FAIL; 332 rs6000_emit_sync (AND, <MODE>mode, 333 gen_rtx_NOT (<MODE>mode, operands[1]), 334 operands[2], 335 operands[0], NULL_RTX, true); 336 DONE; 337 } 338}") 339 340(define_insn_and_split "*sync_old_nand<mode>_internal" 341 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 342 (match_operand:GPR 1 "memory_operand" "+Z")) 343 (set (match_dup 1) 344 (unspec:GPR 345 [(and:GPR (not:GPR (match_dup 1)) 346 (match_operand:GPR 2 "gpc_reg_operand" "r"))] 347 UNSPEC_ATOMIC)) 348 (clobber (match_scratch:GPR 3 "=&r")) 349 (clobber (match_scratch:CC 4 "=&x"))] 350 "TARGET_POWERPC" 351 "#" 352 "&& reload_completed" 353 [(const_int 0)] 354{ 355 rs6000_split_atomic_op (NOT, operands[1], operands[2], 356 operands[0], NULL_RTX, operands[3]); 357 DONE; 358}) 359 360(define_expand "sync_new_<fetchop_name><mode>" 361 [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "") 362 (FETCHOP:INT1 363 (match_operand:INT1 1 "memory_operand" "") 364 (match_operand:INT1 2 "<fetchop_pred>" ""))) 365 (set (match_dup 1) 366 (unspec:INT1 367 [(FETCHOP:INT1 (match_dup 1) (match_dup 2))] 368 UNSPEC_ATOMIC)) 369 (clobber (scratch:INT1)) 370 (clobber (scratch:CC))])] 371 "TARGET_POWERPC" 372 " 373{ 374 if (<MODE>mode != SImode && <MODE>mode != DImode) 375 { 376 if (PPC405_ERRATUM77) 377 FAIL; 378 rs6000_emit_sync (<CODE>, <MODE>mode, operands[1], operands[2], 379 NULL_RTX, operands[0], true); 380 DONE; 381 } 382}") 383 384(define_insn_and_split "*sync_new_<fetchop_name>si_internal" 385 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 386 (FETCHOP:SI 387 (match_operand:SI 1 "memory_operand" "+Z") 388 (match_operand:SI 2 "<fetchop_pred>" "<fetchopsi_constr>"))) 389 (set (match_dup 1) 390 (unspec:SI 391 [(FETCHOP:SI (match_dup 1) (match_dup 2))] 392 UNSPEC_ATOMIC)) 393 (clobber (match_scratch:SI 3 "=&b")) 394 (clobber (match_scratch:CC 4 "=&x"))] 395 "TARGET_POWERPC" 396 "#" 397 "&& reload_completed" 398 [(const_int 0)] 399{ 400 rs6000_split_atomic_op (<CODE>, operands[1], operands[2], 401 NULL_RTX, operands[0], operands[3]); 402 DONE; 403}) 404 405(define_insn_and_split "*sync_new_<fetchop_name>di_internal" 406 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 407 (FETCHOP:DI 408 (match_operand:DI 1 "memory_operand" "+Z") 409 (match_operand:DI 2 "<fetchop_pred>" "<fetchopdi_constr>"))) 410 (set (match_dup 1) 411 (unspec:DI 412 [(FETCHOP:DI (match_dup 1) (match_dup 2))] 413 UNSPEC_ATOMIC)) 414 (clobber (match_scratch:DI 3 "=&b")) 415 (clobber (match_scratch:CC 4 "=&x"))] 416 "TARGET_POWERPC" 417 "#" 418 "&& reload_completed" 419 [(const_int 0)] 420{ 421 rs6000_split_atomic_op (<CODE>, operands[1], operands[2], 422 NULL_RTX, operands[0], operands[3]); 423 DONE; 424}) 425 426(define_expand "sync_new_nand<mode>" 427 [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "") 428 (and:INT1 429 (not:INT1 (match_operand:INT1 1 "memory_operand" "")) 430 (match_operand:INT1 2 "gpc_reg_operand" ""))) 431 (set (match_dup 1) 432 (unspec:INT1 433 [(and:INT1 (not:INT1 (match_dup 1)) (match_dup 2))] 434 UNSPEC_ATOMIC)) 435 (clobber (scratch:INT1)) 436 (clobber (scratch:CC))])] 437 "TARGET_POWERPC" 438 " 439{ 440 if (<MODE>mode != SImode && <MODE>mode != DImode) 441 { 442 if (PPC405_ERRATUM77) 443 FAIL; 444 rs6000_emit_sync (AND, <MODE>mode, 445 gen_rtx_NOT (<MODE>mode, operands[1]), 446 operands[2], 447 NULL_RTX, operands[0], true); 448 DONE; 449 } 450}") 451 452(define_insn_and_split "*sync_new_nand<mode>_internal" 453 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 454 (and:GPR 455 (not:GPR (match_operand:GPR 1 "memory_operand" "+Z")) 456 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 457 (set (match_dup 1) 458 (unspec:GPR 459 [(and:GPR (not:GPR (match_dup 1)) (match_dup 2))] 460 UNSPEC_ATOMIC)) 461 (clobber (match_scratch:GPR 3 "=&r")) 462 (clobber (match_scratch:CC 4 "=&x"))] 463 "TARGET_POWERPC" 464 "#" 465 "&& reload_completed" 466 [(const_int 0)] 467{ 468 rs6000_split_atomic_op (NOT, operands[1], operands[2], 469 NULL_RTX, operands[0], operands[3]); 470 DONE; 471}) 472 473; and<mode> without cr0 clobber to avoid generation of additional clobber 474; in atomic splitters causing internal consistency failure. 475; cr0 already clobbered by larx/stcx. 476(define_insn "*atomic_andsi" 477 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") 478 (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") 479 (match_operand:SI 2 "and_operand" "?r,T,K,L")] 480 UNSPEC_AND))] 481 "" 482 "@ 483 and %0,%1,%2 484 {rlinm|rlwinm} %0,%1,0,%m2,%M2 485 {andil.|andi.} %0,%1,%b2 486 {andiu.|andis.} %0,%1,%u2" 487 [(set_attr "type" "*,*,compare,compare")]) 488 489(define_insn "*atomic_anddi" 490 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r") 491 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r") 492 (match_operand:DI 2 "and_operand" "?r,S,T,K,J")] 493 UNSPEC_AND))] 494 "TARGET_POWERPC64" 495 "@ 496 and %0,%1,%2 497 rldic%B2 %0,%1,0,%S2 498 rlwinm %0,%1,0,%m2,%M2 499 andi. %0,%1,%b2 500 andis. %0,%1,%u2" 501 [(set_attr "type" "*,*,*,compare,compare") 502 (set_attr "length" "4,4,4,4,4")]) 503 504; the sync_*_internal patterns all have these operands: 505; 0 - memory location 506; 1 - operand 507; 2 - value in memory after operation 508; 3 - value in memory immediately before operation 509 510(define_insn "*sync_addshort_internal" 511 [(set (match_operand:SI 2 "gpc_reg_operand" "=&r") 512 (ior:SI (and:SI (plus:SI (match_operand:SI 0 "memory_operand" "+Z") 513 (match_operand:SI 1 "add_operand" "rI")) 514 (match_operand:SI 4 "gpc_reg_operand" "r")) 515 (and:SI (not:SI (match_dup 4)) (match_dup 0)))) 516 (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0)) 517 (set (match_dup 0) 518 (unspec:SI [(ior:SI (and:SI (plus:SI (match_dup 0) (match_dup 1)) 519 (match_dup 4)) 520 (and:SI (not:SI (match_dup 4)) (match_dup 0)))] 521 UNSPEC_SYNC_OP)) 522 (clobber (match_scratch:CC 5 "=&x")) 523 (clobber (match_scratch:SI 6 "=&r"))] 524 "TARGET_POWERPC && !PPC405_ERRATUM77" 525 "lwarx %3,%y0\n\tadd%I1 %2,%3,%1\n\tandc %6,%3,%4\n\tand %2,%2,%4\n\tor %2,%2,%6\n\tstwcx. %2,%y0\n\tbne- $-24" 526 [(set_attr "length" "28")]) 527 528(define_insn "*sync_subshort_internal" 529 [(set (match_operand:SI 2 "gpc_reg_operand" "=&r") 530 (ior:SI (and:SI (minus:SI (match_operand:SI 0 "memory_operand" "+Z") 531 (match_operand:SI 1 "add_operand" "rI")) 532 (match_operand:SI 4 "gpc_reg_operand" "r")) 533 (and:SI (not:SI (match_dup 4)) (match_dup 0)))) 534 (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0)) 535 (set (match_dup 0) 536 (unspec:SI [(ior:SI (and:SI (minus:SI (match_dup 0) (match_dup 1)) 537 (match_dup 4)) 538 (and:SI (not:SI (match_dup 4)) (match_dup 0)))] 539 UNSPEC_SYNC_OP)) 540 (clobber (match_scratch:CC 5 "=&x")) 541 (clobber (match_scratch:SI 6 "=&r"))] 542 "TARGET_POWERPC && !PPC405_ERRATUM77" 543 "lwarx %3,%y0\n\tsubf %2,%1,%3\n\tandc %6,%3,%4\n\tand %2,%2,%4\n\tor %2,%2,%6\n\tstwcx. %2,%y0\n\tbne- $-24" 544 [(set_attr "length" "28")]) 545 546(define_insn "*sync_andsi_internal" 547 [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r,&r") 548 (and:SI (match_operand:SI 0 "memory_operand" "+Z,Z,Z,Z") 549 (match_operand:SI 1 "and_operand" "r,T,K,L"))) 550 (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b,&b") (match_dup 0)) 551 (set (match_dup 0) 552 (unspec:SI [(and:SI (match_dup 0) (match_dup 1))] 553 UNSPEC_SYNC_OP)) 554 (clobber (match_scratch:CC 4 "=&x,&x,&x,&x"))] 555 "TARGET_POWERPC && !PPC405_ERRATUM77" 556 "@ 557 lwarx %3,%y0\n\tand %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12 558 lwarx %3,%y0\n\trlwinm %2,%3,0,%m1,%M1\n\tstwcx. %2,%y0\n\tbne- $-12 559 lwarx %3,%y0\n\tandi. %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12 560 lwarx %3,%y0\n\tandis. %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12" 561 [(set_attr "length" "16,16,16,16")]) 562 563(define_insn "*sync_boolsi_internal" 564 [(set (match_operand:SI 2 "gpc_reg_operand" "=&r,&r,&r") 565 (match_operator:SI 4 "boolean_or_operator" 566 [(match_operand:SI 0 "memory_operand" "+Z,Z,Z") 567 (match_operand:SI 1 "logical_operand" "r,K,L")])) 568 (set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0)) 569 (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP)) 570 (clobber (match_scratch:CC 5 "=&x,&x,&x"))] 571 "TARGET_POWERPC && !PPC405_ERRATUM77" 572 "@ 573 lwarx %3,%y0\n\t%q4 %2,%3,%1\n\tstwcx. %2,%y0\n\tbne- $-12 574 lwarx %3,%y0\n\t%q4i %2,%3,%b1\n\tstwcx. %2,%y0\n\tbne- $-12 575 lwarx %3,%y0\n\t%q4is %2,%3,%u1\n\tstwcx. %2,%y0\n\tbne- $-12" 576 [(set_attr "length" "16,16,16")]) 577 578; This pattern could also take immediate values of operand 1, 579; since the non-NOT version of the operator is used; but this is not 580; very useful, since in practice operand 1 is a full 32-bit value. 581; Likewise, operand 5 is in practice either <= 2^16 or it is a register. 582(define_insn "*sync_boolcshort_internal" 583 [(set (match_operand:SI 2 "gpc_reg_operand" "=&r") 584 (match_operator:SI 4 "boolean_operator" 585 [(xor:SI (match_operand:SI 0 "memory_operand" "+Z") 586 (match_operand:SI 5 "logical_operand" "rK")) 587 (match_operand:SI 1 "gpc_reg_operand" "r")])) 588 (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0)) 589 (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP)) 590 (clobber (match_scratch:CC 6 "=&x"))] 591 "TARGET_POWERPC && !PPC405_ERRATUM77" 592 "lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16" 593 [(set_attr "length" "20")]) 594 595(define_insn "isync" 596 [(set (mem:BLK (match_scratch 0 "X")) 597 (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_ISYNC))] 598 "" 599 "{ics|isync}" 600 [(set_attr "type" "isync")]) 601 602(define_expand "sync_lock_release<mode>" 603 [(set (match_operand:INT 0 "memory_operand") 604 (match_operand:INT 1 "any_operand"))] 605 "" 606 " 607{ 608 emit_insn (gen_lwsync ()); 609 emit_move_insn (operands[0], operands[1]); 610 DONE; 611}") 612 613; Some AIX assemblers don't accept lwsync, so we use a .long. 614(define_insn "lwsync" 615 [(set (mem:BLK (match_scratch 0 "X")) 616 (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_LWSYNC))] 617 "" 618{ 619 if (TARGET_NO_LWSYNC) 620 return "sync"; 621 else 622 return ".long 0x7c2004ac"; 623} 624 [(set_attr "type" "sync")]) 625 626