@@ -35,6 +35,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3535
3636#define SEMANTICS_POST_OP_NEEDS_FENCE ( Acquire | AcquireRelease | SequentiallyConsistent)
3737
38+
3839 __local uint * __builtin_IB_get_local_lock ();
3940 void __builtin_IB_eu_thread_pause (uint value );
4041
@@ -403,6 +404,79 @@ ulong __builtin_spirv_OpAtomicExchange_p1i64_i32_i32_i64( volatile __global ulon
403404 atomic_operation_1op ( __builtin_IB_atomic_xchg_global_i64 , ulong , (global long* )Pointer , Scope , Semantics , Value , true );
404405}
405406
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+ }
406480
407481ulong __builtin_spirv_OpAtomicExchange_p3i64_i32_i32_i64 ( volatile __local ulong * Pointer , uint Scope , uint Semantics , ulong Value )
408482{
0 commit comments