@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
35
36
36
#define SEMANTICS_POST_OP_NEEDS_FENCE ( Acquire | AcquireRelease | SequentiallyConsistent)
37
37
38
+
38
39
__local uint * __builtin_IB_get_local_lock ();
39
40
void __builtin_IB_eu_thread_pause (uint value );
40
41
@@ -403,6 +404,79 @@ ulong __builtin_spirv_OpAtomicExchange_p1i64_i32_i32_i64( volatile __global ulon
403
404
atomic_operation_1op ( __builtin_IB_atomic_xchg_global_i64 , ulong , (global long* )Pointer , Scope , Semantics , Value , true );
404
405
}
405
406
407
+ enum IntAtomicOp
408
+ {
409
+ ATOMIC_IADD64 ,
410
+ ATOMIC_SUB64 ,
411
+ ATOMIC_XCHG64 ,
412
+ ATOMIC_AND64 ,
413
+ ATOMIC_OR64 ,
414
+ ATOMIC_XOR64 ,
415
+ ATOMIC_IMIN64 ,
416
+ ATOMIC_IMAX64 ,
417
+ ATOMIC_UMAX64 ,
418
+ ATOMIC_UMIN64
419
+ };
420
+
421
+ // handle int64 SLM atomic add/sub/xchg/and/or/xor/umax/umin
422
+ ulong __builtin_spirv_OpAtomicUlongBinary_p3 ( enum IntAtomicOp atomicOp , volatile __local ulong * Pointer ,
423
+ uint Scope , uint Semantics , ulong Value )
424
+ {
425
+
426
+ ulong orig ;
427
+ FENCE_PRE_OP (Scope , Semantics , false)
428
+ SPINLOCK_START
429
+ orig = * Pointer ;
430
+ switch (atomicOp )
431
+ {
432
+ case ATOMIC_IADD64 : * Pointer += Value ; break ;
433
+ case ATOMIC_SUB64 : * Pointer -= Value ; break ;
434
+ case ATOMIC_AND64 : * Pointer &= Value ; break ;
435
+ case ATOMIC_OR64 : * Pointer |= Value ; break ;
436
+ case ATOMIC_XOR64 : * Pointer ^= Value ; break ;
437
+ case ATOMIC_XCHG64 : * Pointer = Value ; break ;
438
+ case ATOMIC_UMIN64 : * Pointer = ( orig < Value ) ? orig : Value ; break ;
439
+ case ATOMIC_UMAX64 : * Pointer = ( orig > Value ) ? orig : Value ; break ;
440
+ default : break ; // What should we do here? OCL doesn't have assert
441
+ }
442
+ SPINLOCK_END
443
+ FENCE_POST_OP (Scope , Semantics , false )
444
+ return orig ;
445
+ }
446
+
447
+ // handle int64 SLM atomic IMin and IMax
448
+ long __builtin_spirv_OpAtomicSlongBinary_p3 ( enum IntAtomicOp atomicOp , volatile __local long * Pointer ,
449
+ uint Scope , uint Semantics , long Value )
450
+ {
451
+
452
+ ulong orig ;
453
+ FENCE_PRE_OP (Scope , Semantics , false)
454
+ SPINLOCK_START
455
+ orig = * Pointer ;
456
+ switch (atomicOp )
457
+ {
458
+ case ATOMIC_IMIN64 : * Pointer = ( orig < Value ) ? orig : Value ; break ;
459
+ case ATOMIC_IMAX64 : * Pointer = ( orig > Value ) ? orig : Value ; break ;
460
+ default : break ; // What should we do here? OCL doesn't have assert
461
+ }
462
+ SPINLOCK_END
463
+ FENCE_POST_OP (Scope , Semantics , false )
464
+ return orig ;
465
+ }
466
+
467
+ // handle uint64 SLM atomic inc/dec
468
+ ulong __builtin_spirv_OpAtomicUlongUnary_p3 ( bool isInc , volatile __local long * Pointer , uint Scope , uint Semantics )
469
+ {
470
+
471
+ ulong orig ;
472
+ FENCE_PRE_OP (Scope , Semantics , false)
473
+ SPINLOCK_START
474
+ orig = * Pointer ;
475
+ * Pointer = isInc ? orig + 1 : orig - 1 ;
476
+ SPINLOCK_END
477
+ FENCE_POST_OP (Scope , Semantics , false )
478
+ return orig ;
479
+ }
406
480
407
481
ulong __builtin_spirv_OpAtomicExchange_p3i64_i32_i32_i64 ( volatile __local ulong * Pointer , uint Scope , uint Semantics , ulong Value )
408
482
{
0 commit comments