Add the rest of atomic op.

This commit is contained in:
Siu Kwan Lam 2012-08-03 10:14:09 -07:00
commit fb72ab5c8d
6 changed files with 159 additions and 33 deletions

View file

@ -110,6 +110,76 @@ char *do_print(W obj)
p->print(buf);
return strdup(buf.str().c_str());
}
static
llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering)
{
using namespace llvm;
if ( strcmp(ordering, "unordered") == 0 )
return Unordered;
else if ( strcmp(ordering, "monotonic") == 0 )
return Monotonic;
else if ( strcmp(ordering, "acquire") == 0 )
return Acquire;
else if ( strcmp(ordering, "release") == 0 )
return Release;
else if ( strcmp(ordering, "acq_rel") == 0 )
return AcquireRelease;
else if ( strcmp(ordering, "seq_cst") == 0 )
return SequentiallyConsistent;
else
return NotAtomic;
}
static
llvm::SynchronizationScope sync_scope_from_int(int crossthread)
{
if( crossthread )
return llvm::CrossThread;
else
return llvm::SingleThread;
}
LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef builder, const char * opname,
LLVMValueRef ptr, LLVMValueRef val,
const char* ordering, int crossthread)
{
using namespace llvm;
AtomicRMWInst::BinOp op;
if( strcmp(opname, "xchg") == 0 )
op = AtomicRMWInst::Xchg;
else if( strcmp(opname, "add") == 0 )
op = AtomicRMWInst::Add;
else if( strcmp(opname, "sub") == 0 )
op = AtomicRMWInst::Sub;
else if( strcmp(opname, "and") == 0 )
op = AtomicRMWInst::And;
else if( strcmp(opname, "nand") == 0 )
op = AtomicRMWInst::Nand;
else if( strcmp(opname, "or") == 0 )
op = AtomicRMWInst::Or;
else if( strcmp(opname, "xor") == 0 )
op = AtomicRMWInst::Xor;
else if( strcmp(opname, "max") == 0 )
op = AtomicRMWInst::Max;
else if( strcmp(opname, "min") == 0 )
op = AtomicRMWInst::Min;
else if( strcmp(opname, "umax") == 0 )
op = AtomicRMWInst::UMax;
else if( strcmp(opname, "umin") == 0 )
op = AtomicRMWInst::UMin;
else
op = AtomicRMWInst::BAD_BINOP;
AtomicOrdering atomic_order = atomic_ordering_from_string(ordering);
SynchronizationScope sync_scope = sync_scope_from_int(crossthread);
Value * inst = unwrap(builder)->CreateAtomicRMW(op, unwrap(ptr), unwrap(val),
atomic_order, sync_scope);
return wrap(inst);
}
LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr,
LLVMValueRef cmp, LLVMValueRef val,
@ -117,36 +187,12 @@ LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr,
{
using namespace llvm;
AtomicOrdering ordering_enum;
if ( strcmp(ordering, "unordered") == 0 )
ordering_enum = Unordered;
else if ( strcmp(ordering, "monotonic") == 0 )
ordering_enum = Monotonic;
else if ( strcmp(ordering, "acquire") == 0 )
ordering_enum = Acquire;
else if ( strcmp(ordering, "release") == 0 )
ordering_enum = Release;
else if ( strcmp(ordering, "acq_rel") == 0 )
ordering_enum = AcquireRelease;
else if ( strcmp(ordering, "seq_cst") == 0 )
ordering_enum = SequentiallyConsistent;
else
ordering_enum = NotAtomic;
SynchronizationScope crossthread_enum;
switch( crossthread ){
case 0:
crossthread_enum = SingleThread;
break;
default:
crossthread_enum = CrossThread;
}
AtomicOrdering atomic_order = atomic_ordering_from_string(ordering);
SynchronizationScope sync_scope = sync_scope_from_int(crossthread);
Value * inst = unwrap(builder)->CreateAtomicCmpXchg(
unwrap(ptr), unwrap(cmp), unwrap(val),
ordering_enum, crossthread_enum);
atomic_order, sync_scope);
return wrap(inst);
}