sync.md revision 169689
1187938Semax;; Machine description for PowerPC synchronization instructions. 2187938Semax;; Copyright (C) 2005 Free Software Foundation, Inc. 3187938Semax;; Contributed by Geoffrey Keating. 4187938Semax 5187938Semax;; This file is part of GCC. 6187938Semax 7187938Semax;; GCC is free software; you can redistribute it and/or modify it 8187938Semax;; under the terms of the GNU General Public License as published 9187938Semax;; by the Free Software Foundation; either version 2, or (at your 10187938Semax;; option) any later version. 11187938Semax 12187938Semax;; GCC is distributed in the hope that it will be useful, but WITHOUT 13187938Semax;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14187938Semax;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15187938Semax;; License for more details. 16187938Semax 17187938Semax;; You should have received a copy of the GNU General Public License 18187938Semax;; along with GCC; see the file COPYING. If not, write to the 19187938Semax;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 20187938Semax;; MA 02110-1301, USA. 21187938Semax 22187938Semax(define_mode_attr larx [(SI "lwarx") (DI "ldarx")]) 23187938Semax(define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")]) 24187938Semax 25187938Semax(define_code_macro FETCHOP [plus minus ior xor and]) 26187938Semax(define_code_attr fetchop_name 27187938Semax [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")]) 28187938Semax(define_code_attr fetchop_pred 29187938Semax [(plus "add_operand") (minus "gpc_reg_operand") 30187938Semax (ior "logical_operand") (xor "logical_operand") (and "and_operand")]) 31187938Semax(define_code_attr fetchopsi_constr 32187938Semax [(plus "rIL") (minus "r") (ior "rKL") (xor "rKL") (and "rTKL")]) 33187938Semax(define_code_attr fetchopdi_constr 34187938Semax [(plus "rIL") (minus "r") (ior "rKJF") (xor "rKJF") (and "rSTKJ")]) 35187938Semax 36187938Semax(define_expand "memory_barrier" 37187938Semax [(set (mem:BLK (match_dup 0)) 38187938Semax (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_SYNC))] 39187938Semax "" 40187938Semax{ 41187938Semax operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 42187938Semax MEM_VOLATILE_P (operands[0]) = 1; 43187938Semax}) 44187938Semax 45187938Semax(define_insn "*sync_internal" 46187938Semax [(set (match_operand:BLK 0 "" "") 47187938Semax (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_SYNC))] 48187938Semax "" 49187938Semax "{dcs|sync}" 50241699Semax [(set_attr "type" "sync")]) 51187938Semax 52187938Semax(define_insn "load_locked_<mode>" 53187938Semax [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 54187938Semax (unspec_volatile:GPR 55187938Semax [(match_operand:GPR 1 "memory_operand" "Z")] UNSPECV_LL))] 56187938Semax "TARGET_POWERPC" 57187938Semax "<larx> %0,%y1" 58187938Semax [(set_attr "type" "load_l")]) 59187938Semax 60187938Semax(define_insn "store_conditional_<mode>" 61187938Semax [(set (match_operand:CC 0 "cc_reg_operand" "=x") 62187938Semax (unspec_volatile:CC [(const_int 0)] UNSPECV_SC)) 63187938Semax (set (match_operand:GPR 1 "memory_operand" "=Z") 64187938Semax (match_operand:GPR 2 "gpc_reg_operand" "r"))] 65187938Semax "TARGET_POWERPC" 66187938Semax "<stcx> %2,%y1" 67187938Semax [(set_attr "type" "store_c")]) 68187938Semax 69187938Semax(define_insn_and_split "sync_compare_and_swap<mode>" 70187938Semax [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 71187938Semax (match_operand:GPR 1 "memory_operand" "+Z")) 72187938Semax (set (match_dup 1) 73187938Semax (unspec:GPR 74187938Semax [(match_operand:GPR 2 "reg_or_short_operand" "rI") 75187938Semax (match_operand:GPR 3 "gpc_reg_operand" "r")] 76187938Semax UNSPEC_CMPXCHG)) 77187938Semax (clobber (match_scratch:GPR 4 "=&r")) 78187938Semax (clobber (match_scratch:CC 5 "=&x"))] 79187938Semax "TARGET_POWERPC" 80187938Semax "#" 81187938Semax "&& reload_completed" 82187938Semax [(const_int 0)] 83187938Semax{ 84187938Semax rs6000_split_compare_and_swap (operands[0], operands[1], operands[2], 85187938Semax operands[3], operands[4]); 86187938Semax DONE; 87187938Semax}) 88187938Semax 89187938Semax(define_expand "sync_compare_and_swaphi" 90187938Semax [(match_operand:HI 0 "gpc_reg_operand" "") 91187938Semax (match_operand:HI 1 "memory_operand" "") 92187938Semax (match_operand:HI 2 "gpc_reg_operand" "") 93187938Semax (match_operand:HI 3 "gpc_reg_operand" "")] 94187938Semax "TARGET_POWERPC" 95187938Semax{ 96187938Semax rs6000_expand_compare_and_swapqhi (operands[0], operands[1], 97187938Semax operands[2], operands[3]); 98187938Semax DONE; 99187938Semax}) 100241699Semax 101241699Semax(define_expand "sync_compare_and_swapqi" 102241699Semax [(match_operand:QI 0 "gpc_reg_operand" "") 103241699Semax (match_operand:QI 1 "memory_operand" "") 104241699Semax (match_operand:QI 2 "gpc_reg_operand" "") 105241699Semax (match_operand:QI 3 "gpc_reg_operand" "")] 106241699Semax "TARGET_POWERPC" 107241699Semax{ 108241699Semax rs6000_expand_compare_and_swapqhi (operands[0], operands[1], 109241699Semax operands[2], operands[3]); 110241699Semax DONE; 111187938Semax}) 112187938Semax 113187938Semax(define_insn_and_split "sync_compare_and_swapqhi_internal" 114187938Semax [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 115187938Semax (match_operand:SI 4 "memory_operand" "+Z")) 116187938Semax (set (match_dup 4) 117187938Semax (unspec:SI 118187938Semax [(match_operand:SI 1 "gpc_reg_operand" "r") 119187938Semax (match_operand:SI 2 "gpc_reg_operand" "r") 120187938Semax (match_operand:SI 3 "gpc_reg_operand" "r")] 121241699Semax UNSPEC_CMPXCHG)) 122241699Semax (clobber (match_scratch:SI 5 "=&r")) 123241699Semax (clobber (match_scratch:CC 6 "=&x"))] 124241699Semax "TARGET_POWERPC" 125241699Semax "#" 126241699Semax "&& reload_completed" 127241699Semax [(const_int 0)] 128241699Semax{ 129241699Semax rs6000_split_compare_and_swapqhi (operands[0], operands[1], 130241699Semax operands[2], operands[3], operands[4], 131241699Semax operands[5]); 132241699Semax DONE; 133241699Semax}) 134241699Semax 135241699Semax(define_insn_and_split "sync_lock_test_and_set<mode>" 136241699Semax [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 137241699Semax (match_operand:GPR 1 "memory_operand" "+Z")) 138241699Semax (set (match_dup 1) 139241699Semax (unspec:GPR 140241699Semax [(match_operand:GPR 2 "reg_or_short_operand" "rL")] 141241699Semax UNSPEC_XCHG)) 142187938Semax (clobber (match_scratch:GPR 3 "=&r")) 143187938Semax (clobber (match_scratch:CC 4 "=&x"))] 144187938Semax "TARGET_POWERPC" 145187938Semax "#" 146187938Semax "&& reload_completed" 147187938Semax [(const_int 0)] 148187938Semax{ 149187938Semax rs6000_split_lock_test_and_set (operands[0], operands[1], operands[2], 150187938Semax operands[3]); 151187938Semax DONE; 152187938Semax}) 153187938Semax 154187938Semax(define_expand "sync_<fetchop_name><mode>" 155187938Semax [(parallel [(set (match_operand:INT1 0 "memory_operand" "") 156187938Semax (unspec:INT1 157187938Semax [(FETCHOP:INT1 (match_dup 0) 158187938Semax (match_operand:INT1 1 "<fetchop_pred>" ""))] 159187938Semax UNSPEC_ATOMIC)) 160187938Semax (clobber (scratch:INT1)) 161187938Semax (clobber (scratch:CC))])] 162187938Semax "TARGET_POWERPC" 163187938Semax " 164187938Semax{ 165187938Semax if (<MODE>mode != SImode && <MODE>mode != DImode) 166187938Semax { 167187938Semax if (PPC405_ERRATUM77) 168187938Semax FAIL; 169187938Semax rs6000_emit_sync (<CODE>, <MODE>mode, operands[0], operands[1], 170187938Semax NULL_RTX, NULL_RTX, true); 171187938Semax DONE; 172187938Semax } 173187938Semax}") 174187938Semax 175187938Semax(define_insn_and_split "*sync_<fetchop_name>si_internal" 176187938Semax [(set (match_operand:SI 0 "memory_operand" "+Z") 177187938Semax (unspec:SI 178187938Semax [(FETCHOP:SI (match_dup 0) 179187938Semax (match_operand:SI 1 "<fetchop_pred>" "<fetchopsi_constr>"))] 180187938Semax UNSPEC_ATOMIC)) 181187938Semax (clobber (match_scratch:SI 2 "=&b")) 182187938Semax (clobber (match_scratch:CC 3 "=&x"))] 183187938Semax "TARGET_POWERPC" 184187938Semax "#" 185187938Semax "&& reload_completed" 186187938Semax [(const_int 0)] 187187938Semax{ 188187938Semax rs6000_split_atomic_op (<CODE>, operands[0], operands[1], 189187938Semax NULL_RTX, NULL_RTX, operands[2]); 190187938Semax DONE; 191187938Semax}) 192187938Semax 193187938Semax(define_insn_and_split "*sync_<fetchop_name>di_internal" 194187938Semax [(set (match_operand:DI 0 "memory_operand" "+Z") 195187938Semax (unspec:DI 196187938Semax [(FETCHOP:DI (match_dup 0) 197187938Semax (match_operand:DI 1 "<fetchop_pred>" "<fetchopdi_constr>"))] 198187938Semax UNSPEC_ATOMIC)) 199187938Semax (clobber (match_scratch:DI 2 "=&b")) 200187938Semax (clobber (match_scratch:CC 3 "=&x"))] 201187938Semax "TARGET_POWERPC" 202187938Semax "#" 203187938Semax "&& reload_completed" 204187938Semax [(const_int 0)] 205187938Semax{ 206187938Semax rs6000_split_atomic_op (<CODE>, operands[0], operands[1], 207187938Semax NULL_RTX, NULL_RTX, operands[2]); 208187938Semax DONE; 209187938Semax}) 210187938Semax 211187938Semax(define_expand "sync_nand<mode>" 212187938Semax [(parallel [(set (match_operand:INT1 0 "memory_operand" "") 213187938Semax (unspec:INT1 214187938Semax [(and:INT1 (not:INT1 (match_dup 0)) 215187938Semax (match_operand:INT1 1 "gpc_reg_operand" ""))] 216187938Semax UNSPEC_ATOMIC)) 217187938Semax (clobber (scratch:INT1)) 218187938Semax (clobber (scratch:CC))])] 219187938Semax "TARGET_POWERPC" 220187938Semax " 221187938Semax{ 222187938Semax if (<MODE>mode != SImode && <MODE>mode != DImode) 223187938Semax { 224187938Semax 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