diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-12-30 19:19:05 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-12-30 19:19:05 -0500 |
| commit | 73e535e1125d76bcd4e85123defea8b76412ab09 (patch) | |
| tree | e347bc78a7ea39a2009b490e3be97074d05f9fcb /src/codegen.cpp | |
| parent | cbfd66f68a5a390abcf99e8cc6923d056ee1e4fa (diff) | |
| parent | 2252951066f772ac6b77ab183ad3bc074ae8f09f (diff) | |
| download | zig-73e535e1125d76bcd4e85123defea8b76412ab09.tar.gz zig-73e535e1125d76bcd4e85123defea8b76412ab09.zip | |
Merge pull request #3683 from Vexu/atomic-float
Support floats with some atomic operations
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 01cda22cd4..320d5c75d5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5132,19 +5132,21 @@ static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { zig_unreachable(); } -static LLVMAtomicRMWBinOp to_LLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed) { +static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) { switch (op) { - case AtomicRmwOp_xchg: return LLVMAtomicRMWBinOpXchg; - case AtomicRmwOp_add: return LLVMAtomicRMWBinOpAdd; - case AtomicRmwOp_sub: return LLVMAtomicRMWBinOpSub; - case AtomicRmwOp_and: return LLVMAtomicRMWBinOpAnd; - case AtomicRmwOp_nand: return LLVMAtomicRMWBinOpNand; - case AtomicRmwOp_or: return LLVMAtomicRMWBinOpOr; - case AtomicRmwOp_xor: return LLVMAtomicRMWBinOpXor; + case AtomicRmwOp_xchg: return ZigLLVMAtomicRMWBinOpXchg; + case AtomicRmwOp_add: + return is_float ? ZigLLVMAtomicRMWBinOpFAdd : ZigLLVMAtomicRMWBinOpAdd; + case AtomicRmwOp_sub: + return is_float ? ZigLLVMAtomicRMWBinOpFSub : ZigLLVMAtomicRMWBinOpSub; + case AtomicRmwOp_and: return ZigLLVMAtomicRMWBinOpAnd; + case AtomicRmwOp_nand: return ZigLLVMAtomicRMWBinOpNand; + case AtomicRmwOp_or: return ZigLLVMAtomicRMWBinOpOr; + case AtomicRmwOp_xor: return ZigLLVMAtomicRMWBinOpXor; case AtomicRmwOp_max: - return is_signed ? LLVMAtomicRMWBinOpMax : LLVMAtomicRMWBinOpUMax; + return is_signed ? ZigLLVMAtomicRMWBinOpMax : ZigLLVMAtomicRMWBinOpUMax; case AtomicRmwOp_min: - return is_signed ? LLVMAtomicRMWBinOpMin : LLVMAtomicRMWBinOpUMin; + return is_signed ? ZigLLVMAtomicRMWBinOpMin : ZigLLVMAtomicRMWBinOpUMin; } zig_unreachable(); } @@ -5738,25 +5740,26 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, { bool is_signed; ZigType *operand_type = instruction->operand->value->type; + bool is_float = operand_type->id == ZigTypeIdFloat; if (operand_type->id == ZigTypeIdInt) { is_signed = operand_type->data.integral.is_signed; } else { is_signed = false; } - LLVMAtomicRMWBinOp op = to_LLVMAtomicRMWBinOp(instruction->resolved_op, is_signed); + enum ZigLLVM_AtomicRMWBinOp op = to_ZigLLVMAtomicRMWBinOp(instruction->resolved_op, is_signed, is_float); LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); LLVMValueRef operand = ir_llvm_value(g, instruction->operand); if (get_codegen_ptr_type(operand_type) == nullptr) { - return LLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded); + return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded); } // it's a pointer but we need to treat it as an int LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, LLVMPointerType(g->builtin_types.entry_usize->llvm_type, 0), ""); LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_usize->llvm_type, ""); - LLVMValueRef uncasted_result = LLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, + LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, g->is_single_threaded); return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); } |
