authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-17 00:24:23+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-23 11:55:00+02:00
logab7fc33c8342583a8323c19a2596b7e4cd0c5e90
treed76ac2acf85ea9aea83c5eff701bccc8295ea888
parent8bb1e0444951b7b83254277c52534c7ab58fd135
signature Commit is signed but in an unrecognized format.

add zig llvm wrapper for atomicrmw


4 files changed, 88 insertions(+), 17 deletions(-)

src/codegen.cpp+14-13
......@@ -5129,21 +5129,21 @@ static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) {
51295129 zig_unreachable();
51305130}
51315131
5132static LLVMAtomicRMWBinOp to_LLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) {
5132static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) {
51335133 switch (op) {
5134 case AtomicRmwOp_xchg: return LLVMAtomicRMWBinOpXchg;
5134 case AtomicRmwOp_xchg: return ZigLLVMAtomicRMWBinOpXchg;
51355135 case AtomicRmwOp_add:
5136 return is_float ? LLVMAtomicRMWBinOpFAdd: LLVMAtomicRMWBinOpAdd;
5136 return is_float ? ZigLLVMAtomicRMWBinOpFAdd : ZigLLVMAtomicRMWBinOpAdd;
51375137 case AtomicRmwOp_sub:
5138 return is_float ? LLVMAtomicRMWBinOpFSub: LLVMAtomicRMWBinOpSub;
5139 case AtomicRmwOp_and: return LLVMAtomicRMWBinOpAnd;
5140 case AtomicRmwOp_nand: return LLVMAtomicRMWBinOpNand;
5141 case AtomicRmwOp_or: return LLVMAtomicRMWBinOpOr;
5142 case AtomicRmwOp_xor: return LLVMAtomicRMWBinOpXor;
5138 return is_float ? ZigLLVMAtomicRMWBinOpFSub : ZigLLVMAtomicRMWBinOpSub;
5139 case AtomicRmwOp_and: return ZigLLVMAtomicRMWBinOpAnd;
5140 case AtomicRmwOp_nand: return ZigLLVMAtomicRMWBinOpNand;
5141 case AtomicRmwOp_or: return ZigLLVMAtomicRMWBinOpOr;
5142 case AtomicRmwOp_xor: return ZigLLVMAtomicRMWBinOpXor;
51435143 case AtomicRmwOp_max:
5144 return is_signed ? LLVMAtomicRMWBinOpMax : LLVMAtomicRMWBinOpUMax;
5144 return is_signed ? ZigLLVMAtomicRMWBinOpMax : ZigLLVMAtomicRMWBinOpUMax;
51455145 case AtomicRmwOp_min:
5146 return is_signed ? LLVMAtomicRMWBinOpMin : LLVMAtomicRMWBinOpUMin;
5146 return is_signed ? ZigLLVMAtomicRMWBinOpMin : ZigLLVMAtomicRMWBinOpUMin;
51475147 }
51485148 zig_unreachable();
51495149}
......@@ -5727,6 +5727,7 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst
57275727static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
57285728 IrInstructionAtomicRmw *instruction)
57295729{
5730 bool is_signed;
57305731 ZigType *operand_type = instruction->operand->value->type;
57315732 bool is_float = operand_type->id == ZigTypeIdFloat;
57325733 if (operand_type->id == ZigTypeIdInt) {
......@@ -5734,20 +5735,20 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable,
57345735 } else {
57355736 is_signed = false;
57365737 }
5737 LLVMAtomicRMWBinOp op = to_LLVMAtomicRMWBinOp(instruction->resolved_op, is_signed, is_float);
5738 enum ZigLLVM_AtomicRMWBinOp op = to_ZigLLVMAtomicRMWBinOp(instruction->resolved_op, is_signed, is_float);
57385739 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
57395740 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
57405741 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
57415742
57425743 if (get_codegen_ptr_type(operand_type) == nullptr) {
5743 return LLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded);
5744 return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded);
57445745 }
57455746
57465747 // it's a pointer but we need to treat it as an int
57475748 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,
57485749 LLVMPointerType(g->builtin_types.entry_usize->llvm_type, 0), "");
57495750 LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_usize->llvm_type, "");
5750 LLVMValueRef uncasted_result = LLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,
5751 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,
57515752 g->is_single_threaded);
57525753 return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
57535754}
src/zig_llvm.cpp+50
......@@ -1096,6 +1096,56 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
10961096 abort();
10971097}
10981098
1099static AtomicRMWInst::BinOp toLLVMRMWBinOp(enum ZigLLVM_AtomicRMWBinOp BinOp) {
1100 switch (BinOp) {
1101 default:
1102 case ZigLLVMAtomicRMWBinOpXchg: return AtomicRMWInst::Xchg;
1103 case ZigLLVMAtomicRMWBinOpAdd: return AtomicRMWInst::Add;
1104 case ZigLLVMAtomicRMWBinOpSub: return AtomicRMWInst::Sub;
1105 case ZigLLVMAtomicRMWBinOpAnd: return AtomicRMWInst::And;
1106 case ZigLLVMAtomicRMWBinOpNand: return AtomicRMWInst::Nand;
1107 case ZigLLVMAtomicRMWBinOpOr: return AtomicRMWInst::Or;
1108 case ZigLLVMAtomicRMWBinOpXor: return AtomicRMWInst::Xor;
1109 case ZigLLVMAtomicRMWBinOpMax: return AtomicRMWInst::Max;
1110 case ZigLLVMAtomicRMWBinOpMin: return AtomicRMWInst::Min;
1111 case ZigLLVMAtomicRMWBinOpUMax: return AtomicRMWInst::UMax;
1112 case ZigLLVMAtomicRMWBinOpUMin: return AtomicRMWInst::UMin;
1113 case ZigLLVMAtomicRMWBinOpFAdd: return AtomicRMWInst::FAdd;
1114 case ZigLLVMAtomicRMWBinOpFSub: return AtomicRMWInst::FSub;
1115 }
1116}
1117
1118static AtomicOrdering toLLVMOrdering(LLVMAtomicOrdering Ordering) {
1119 switch (Ordering) {
1120 default:
1121 case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
1122 case LLVMAtomicOrderingUnordered: return AtomicOrdering::Unordered;
1123 case LLVMAtomicOrderingMonotonic: return AtomicOrdering::Monotonic;
1124 case LLVMAtomicOrderingAcquire: return AtomicOrdering::Acquire;
1125 case LLVMAtomicOrderingRelease: return AtomicOrdering::Release;
1126 case LLVMAtomicOrderingAcquireRelease: return AtomicOrdering::AcquireRelease;
1127 case LLVMAtomicOrderingSequentiallyConsistent: return AtomicOrdering::SequentiallyConsistent;
1128 }
1129}
1130
1131inline LLVMAttributeRef wrap(Attribute Attr) {
1132 return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
1133}
1134
1135inline Attribute unwrap(LLVMAttributeRef Attr) {
1136 return Attribute::fromRawPointer(Attr);
1137}
1138
1139LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp op,
1140 LLVMValueRef PTR, LLVMValueRef Val,
1141 LLVMAtomicOrdering ordering, LLVMBool singleThread)
1142{
1143 AtomicRMWInst::BinOp intop = toLLVMRMWBinOp(op);
1144 return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR),
1145 unwrap(Val), toLLVMOrdering(ordering),
1146 singleThread ? SyncScope::SingleThread : SyncScope::System));
1147}
1148
10991149static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, "");
11001150static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, "");
11011151static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, "");
src/zig_llvm.h+20
......@@ -422,6 +422,26 @@ enum ZigLLVM_ObjectFormatType {
422422 ZigLLVM_XCOFF,
423423};
424424
425enum ZigLLVM_AtomicRMWBinOp {
426 ZigLLVMAtomicRMWBinOpXchg,
427 ZigLLVMAtomicRMWBinOpAdd,
428 ZigLLVMAtomicRMWBinOpSub,
429 ZigLLVMAtomicRMWBinOpAnd,
430 ZigLLVMAtomicRMWBinOpNand,
431 ZigLLVMAtomicRMWBinOpOr,
432 ZigLLVMAtomicRMWBinOpXor,
433 ZigLLVMAtomicRMWBinOpMax,
434 ZigLLVMAtomicRMWBinOpMin,
435 ZigLLVMAtomicRMWBinOpUMax,
436 ZigLLVMAtomicRMWBinOpUMin,
437 ZigLLVMAtomicRMWBinOpFAdd,
438 ZigLLVMAtomicRMWBinOpFSub,
439};
440
441LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp op,
442 LLVMValueRef PTR, LLVMValueRef Val,
443 LLVMAtomicOrdering ordering, LLVMBool singleThread);
444
425445#define ZigLLVM_DIFlags_Zero 0U
426446#define ZigLLVM_DIFlags_Private 1U
427447#define ZigLLVM_DIFlags_Protected 2U
test/compile_errors.zig+4-4
......@@ -19,9 +19,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1919 \\ var x: f32 = 0;
2020 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);
2121 \\}
22 ,
22 , &[_][]const u8{
2323 "tmp.zig:3:22: error: expected integer, enum or pointer type, found 'f32'",
24 );
24 });
2525
2626 cases.add(
2727 "atomicrmw with float op not .Xchg, .Add or .Sub",
......@@ -29,9 +29,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2929 \\ var x: f32 = 0;
3030 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
3131 \\}
32 ,
32 , &[_][]const u8{
3333 "tmp.zig:3:29: error: @atomicRmw with float only works with .Xchg, .Add and .Sub",
34 );
34 });
3535
3636 cases.add("intToPtr with misaligned address",
3737 \\pub fn main() void {