| author | |
| committer | |
| log | ab7fc33c8342583a8323c19a2596b7e4cd0c5e90 |
| tree | d76ac2acf85ea9aea83c5eff701bccc8295ea888 |
| parent | 8bb1e0444951b7b83254277c52534c7ab58fd135 |
| signature | Commit is signed but in an unrecognized format. |
4 files changed, 88 insertions(+), 17 deletions(-)
src/codegen.cpp+14-13| ... | @@ -5129,21 +5129,21 @@ static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { | ... | @@ -5129,21 +5129,21 @@ static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { |
| 5129 | zig_unreachable(); | 5129 | zig_unreachable(); |
| 5130 | } | 5130 | } |
| 5131 | 5131 | ||
| 5132 | static LLVMAtomicRMWBinOp to_LLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) { | 5132 | static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) { |
| 5133 | switch (op) { | 5133 | switch (op) { |
| 5134 | case AtomicRmwOp_xchg: return LLVMAtomicRMWBinOpXchg; | 5134 | case AtomicRmwOp_xchg: return ZigLLVMAtomicRMWBinOpXchg; |
| 5135 | case AtomicRmwOp_add: | 5135 | case AtomicRmwOp_add: |
| 5136 | return is_float ? LLVMAtomicRMWBinOpFAdd: LLVMAtomicRMWBinOpAdd; | 5136 | return is_float ? ZigLLVMAtomicRMWBinOpFAdd : ZigLLVMAtomicRMWBinOpAdd; |
| 5137 | case AtomicRmwOp_sub: | 5137 | case AtomicRmwOp_sub: |
| 5138 | return is_float ? LLVMAtomicRMWBinOpFSub: LLVMAtomicRMWBinOpSub; | 5138 | return is_float ? ZigLLVMAtomicRMWBinOpFSub : ZigLLVMAtomicRMWBinOpSub; |
| 5139 | case AtomicRmwOp_and: return LLVMAtomicRMWBinOpAnd; | 5139 | case AtomicRmwOp_and: return ZigLLVMAtomicRMWBinOpAnd; |
| 5140 | case AtomicRmwOp_nand: return LLVMAtomicRMWBinOpNand; | 5140 | case AtomicRmwOp_nand: return ZigLLVMAtomicRMWBinOpNand; |
| 5141 | case AtomicRmwOp_or: return LLVMAtomicRMWBinOpOr; | 5141 | case AtomicRmwOp_or: return ZigLLVMAtomicRMWBinOpOr; |
| 5142 | case AtomicRmwOp_xor: return LLVMAtomicRMWBinOpXor; | 5142 | case AtomicRmwOp_xor: return ZigLLVMAtomicRMWBinOpXor; |
| 5143 | case AtomicRmwOp_max: | 5143 | case AtomicRmwOp_max: |
| 5144 | return is_signed ? LLVMAtomicRMWBinOpMax : LLVMAtomicRMWBinOpUMax; | 5144 | return is_signed ? ZigLLVMAtomicRMWBinOpMax : ZigLLVMAtomicRMWBinOpUMax; |
| 5145 | case AtomicRmwOp_min: | 5145 | case AtomicRmwOp_min: |
| 5146 | return is_signed ? LLVMAtomicRMWBinOpMin : LLVMAtomicRMWBinOpUMin; | 5146 | return is_signed ? ZigLLVMAtomicRMWBinOpMin : ZigLLVMAtomicRMWBinOpUMin; |
| 5147 | } | 5147 | } |
| 5148 | zig_unreachable(); | 5148 | zig_unreachable(); |
| 5149 | } | 5149 | } |
| ... | @@ -5727,6 +5727,7 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst | ... | @@ -5727,6 +5727,7 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst |
| 5727 | static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, | 5727 | static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, |
| 5728 | IrInstructionAtomicRmw *instruction) | 5728 | IrInstructionAtomicRmw *instruction) |
| 5729 | { | 5729 | { |
| 5730 | bool is_signed; | ||
| 5730 | ZigType *operand_type = instruction->operand->value->type; | 5731 | ZigType *operand_type = instruction->operand->value->type; |
| 5731 | bool is_float = operand_type->id == ZigTypeIdFloat; | 5732 | bool is_float = operand_type->id == ZigTypeIdFloat; |
| 5732 | if (operand_type->id == ZigTypeIdInt) { | 5733 | if (operand_type->id == ZigTypeIdInt) { |
| ... | @@ -5734,20 +5735,20 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, | ... | @@ -5734,20 +5735,20 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, |
| 5734 | } else { | 5735 | } else { |
| 5735 | is_signed = false; | 5736 | is_signed = false; |
| 5736 | } | 5737 | } |
| 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); |
| 5738 | LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); | 5739 | LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); |
| 5739 | LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); | 5740 | LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); |
| 5740 | LLVMValueRef operand = ir_llvm_value(g, instruction->operand); | 5741 | LLVMValueRef operand = ir_llvm_value(g, instruction->operand); |
| 5741 | 5742 | ||
| 5742 | if (get_codegen_ptr_type(operand_type) == nullptr) { | 5743 | 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); |
| 5744 | } | 5745 | } |
| 5745 | 5746 | ||
| 5746 | // it's a pointer but we need to treat it as an int | 5747 | // it's a pointer but we need to treat it as an int |
| 5747 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, | 5748 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, |
| 5748 | LLVMPointerType(g->builtin_types.entry_usize->llvm_type, 0), ""); | 5749 | LLVMPointerType(g->builtin_types.entry_usize->llvm_type, 0), ""); |
| 5749 | LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_usize->llvm_type, ""); | 5750 | 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, |
| 5751 | g->is_single_threaded); | 5752 | g->is_single_threaded); |
| 5752 | return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); | 5753 | return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); |
| 5753 | } | 5754 | } |
src/zig_llvm.cpp+50| ... | @@ -1096,6 +1096,56 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_ | ... | @@ -1096,6 +1096,56 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_ |
| 1096 | abort(); | 1096 | abort(); |
| 1097 | } | 1097 | } |
| 1098 | 1098 | ||
| 1099 | static 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 | |||
| 1118 | static 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 | |||
| 1131 | inline LLVMAttributeRef wrap(Attribute Attr) { | ||
| 1132 | return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer()); | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | inline Attribute unwrap(LLVMAttributeRef Attr) { | ||
| 1136 | return Attribute::fromRawPointer(Attr); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | LLVMValueRef 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 | |||
| 1099 | static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, ""); | 1149 | static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, ""); |
| 1100 | static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, ""); | 1150 | static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, ""); |
| 1101 | static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, ""); | 1151 | static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, ""); |
src/zig_llvm.h+20| ... | @@ -422,6 +422,26 @@ enum ZigLLVM_ObjectFormatType { | ... | @@ -422,6 +422,26 @@ enum ZigLLVM_ObjectFormatType { |
| 422 | ZigLLVM_XCOFF, | 422 | ZigLLVM_XCOFF, |
| 423 | }; | 423 | }; |
| 424 | 424 | ||
| 425 | enum 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 | |||
| 441 | LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp op, | ||
| 442 | LLVMValueRef PTR, LLVMValueRef Val, | ||
| 443 | LLVMAtomicOrdering ordering, LLVMBool singleThread); | ||
| 444 | |||
| 425 | #define ZigLLVM_DIFlags_Zero 0U | 445 | #define ZigLLVM_DIFlags_Zero 0U |
| 426 | #define ZigLLVM_DIFlags_Private 1U | 446 | #define ZigLLVM_DIFlags_Private 1U |
| 427 | #define ZigLLVM_DIFlags_Protected 2U | 447 | #define ZigLLVM_DIFlags_Protected 2U |
test/compile_errors.zig+4-4| ... | @@ -19,9 +19,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -19,9 +19,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 19 | \\ var x: f32 = 0; | 19 | \\ var x: f32 = 0; |
| 20 | \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst); | 20 | \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst); |
| 21 | \\} | 21 | \\} |
| 22 | , | 22 | , &[_][]const u8{ |
| 23 | "tmp.zig:3:22: error: expected integer, enum or pointer type, found 'f32'", | 23 | "tmp.zig:3:22: error: expected integer, enum or pointer type, found 'f32'", |
| 24 | ); | 24 | }); |
| 25 | 25 | ||
| 26 | cases.add( | 26 | cases.add( |
| 27 | "atomicrmw with float op not .Xchg, .Add or .Sub", | 27 | "atomicrmw with float op not .Xchg, .Add or .Sub", |
| ... | @@ -29,9 +29,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -29,9 +29,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 29 | \\ var x: f32 = 0; | 29 | \\ var x: f32 = 0; |
| 30 | \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst); | 30 | \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst); |
| 31 | \\} | 31 | \\} |
| 32 | , | 32 | , &[_][]const u8{ |
| 33 | "tmp.zig:3:29: error: @atomicRmw with float only works with .Xchg, .Add and .Sub", | 33 | "tmp.zig:3:29: error: @atomicRmw with float only works with .Xchg, .Add and .Sub", |
| 34 | ); | 34 | }); |
| 35 | 35 | ||
| 36 | cases.add("intToPtr with misaligned address", | 36 | cases.add("intToPtr with misaligned address", |
| 37 | \\pub fn main() void { | 37 | \\pub fn main() void { |