| ... | @@ -314,7 +314,6 @@ pub fn analyzeBody( | ... | @@ -314,7 +314,6 @@ pub fn analyzeBody( |
| 314 | .select => try sema.zirSelect(block, inst), | 314 | .select => try sema.zirSelect(block, inst), |
| 315 | .atomic_load => try sema.zirAtomicLoad(block, inst), | 315 | .atomic_load => try sema.zirAtomicLoad(block, inst), |
| 316 | .atomic_rmw => try sema.zirAtomicRmw(block, inst), | 316 | .atomic_rmw => try sema.zirAtomicRmw(block, inst), |
| 317 | .atomic_store => try sema.zirAtomicStore(block, inst), | | |
| 318 | .mul_add => try sema.zirMulAdd(block, inst), | 317 | .mul_add => try sema.zirMulAdd(block, inst), |
| 319 | .builtin_call => try sema.zirBuiltinCall(block, inst), | 318 | .builtin_call => try sema.zirBuiltinCall(block, inst), |
| 320 | .field_ptr_type => try sema.zirFieldPtrType(block, inst), | 319 | .field_ptr_type => try sema.zirFieldPtrType(block, inst), |
| ... | @@ -413,6 +412,11 @@ pub fn analyzeBody( | ... | @@ -413,6 +412,11 @@ pub fn analyzeBody( |
| 413 | i += 1; | 412 | i += 1; |
| 414 | continue; | 413 | continue; |
| 415 | }, | 414 | }, |
| | 415 | .atomic_store => { |
| | 416 | try sema.zirAtomicStore(block, inst); |
| | 417 | i += 1; |
| | 418 | continue; |
| | 419 | }, |
| 416 | .store => { | 420 | .store => { |
| 417 | try sema.zirStore(block, inst); | 421 | try sema.zirStore(block, inst); |
| 418 | i += 1; | 422 | i += 1; |
| ... | @@ -7669,6 +7673,8 @@ fn zirCmpxchg( | ... | @@ -7669,6 +7673,8 @@ fn zirCmpxchg( |
| 7669 | if (try sema.resolveMaybeUndefVal(block, expected_src, expected_value)) |expected_val| { | 7673 | if (try sema.resolveMaybeUndefVal(block, expected_src, expected_value)) |expected_val| { |
| 7670 | if (try sema.resolveMaybeUndefVal(block, new_value_src, new_value)) |new_val| { | 7674 | if (try sema.resolveMaybeUndefVal(block, new_value_src, new_value)) |new_val| { |
| 7671 | if (expected_val.isUndef() or new_val.isUndef()) { | 7675 | if (expected_val.isUndef() or new_val.isUndef()) { |
| | 7676 | // TODO: this should probably cause the memory stored at the pointer |
| | 7677 | // to become undef as well |
| 7672 | return sema.addConstUndef(result_ty); | 7678 | return sema.addConstUndef(result_ty); |
| 7673 | } | 7679 | } |
| 7674 | const stored_val = (try ptr_val.pointerDeref(sema.arena)) orelse break :rs ptr_src; | 7680 | const stored_val = (try ptr_val.pointerDeref(sema.arena)) orelse break :rs ptr_src; |
| ... | @@ -7830,10 +7836,38 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -7830,10 +7836,38 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 7830 | }); | 7836 | }); |
| 7831 | } | 7837 | } |
| 7832 | | 7838 | |
| 7833 | fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 7839 | fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| 7834 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 7840 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| | 7841 | const extra = sema.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data; |
| 7835 | const src = inst_data.src(); | 7842 | const src = inst_data.src(); |
| 7836 | return sema.mod.fail(&block.base, src, "TODO: Sema.zirAtomicStore", .{}); | 7843 | // zig fmt: off |
| | 7844 | const operand_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| | 7845 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| | 7846 | const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| | 7847 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; |
| | 7848 | // zig fmt: on |
| | 7849 | const ptr = sema.resolveInst(extra.ptr); |
| | 7850 | const operand_ty = sema.typeOf(ptr).elemType(); |
| | 7851 | try sema.checkAtomicOperandType(block, operand_ty_src, operand_ty); |
| | 7852 | const operand = try sema.coerce(block, operand_ty, sema.resolveInst(extra.operand), operand_src); |
| | 7853 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| | 7854 | |
| | 7855 | const air_tag: Air.Inst.Tag = switch (order) { |
| | 7856 | .Acquire, .AcqRel => { |
| | 7857 | return sema.mod.fail( |
| | 7858 | &block.base, |
| | 7859 | order_src, |
| | 7860 | "@atomicStore atomic ordering must not be Acquire or AcqRel", |
| | 7861 | .{}, |
| | 7862 | ); |
| | 7863 | }, |
| | 7864 | .Unordered => .atomic_store_unordered, |
| | 7865 | .Monotonic => .atomic_store_monotonic, |
| | 7866 | .Release => .atomic_store_release, |
| | 7867 | .SeqCst => .atomic_store_seq_cst, |
| | 7868 | }; |
| | 7869 | |
| | 7870 | return sema.storePtr2(block, src, ptr, ptr_src, operand, operand_src, air_tag); |
| 7837 | } | 7871 | } |
| 7838 | | 7872 | |
| 7839 | fn zirMulAdd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 7873 | fn zirMulAdd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -9310,25 +9344,39 @@ fn coerceVarArgParam( | ... | @@ -9310,25 +9344,39 @@ fn coerceVarArgParam( |
| 9310 | return inst; | 9344 | return inst; |
| 9311 | } | 9345 | } |
| 9312 | | 9346 | |
| | 9347 | // TODO migrate callsites to use storePtr2 instead. |
| 9313 | fn storePtr( | 9348 | fn storePtr( |
| 9314 | sema: *Sema, | 9349 | sema: *Sema, |
| 9315 | block: *Scope.Block, | 9350 | block: *Scope.Block, |
| 9316 | src: LazySrcLoc, | 9351 | src: LazySrcLoc, |
| 9317 | ptr: Air.Inst.Ref, | 9352 | ptr: Air.Inst.Ref, |
| 9318 | uncasted_value: Air.Inst.Ref, | 9353 | uncasted_operand: Air.Inst.Ref, |
| | 9354 | ) !void { |
| | 9355 | return sema.storePtr2(block, src, ptr, src, uncasted_operand, src, .store); |
| | 9356 | } |
| | 9357 | |
| | 9358 | fn storePtr2( |
| | 9359 | sema: *Sema, |
| | 9360 | block: *Scope.Block, |
| | 9361 | src: LazySrcLoc, |
| | 9362 | ptr: Air.Inst.Ref, |
| | 9363 | ptr_src: LazySrcLoc, |
| | 9364 | uncasted_operand: Air.Inst.Ref, |
| | 9365 | operand_src: LazySrcLoc, |
| | 9366 | air_tag: Air.Inst.Tag, |
| 9319 | ) !void { | 9367 | ) !void { |
| 9320 | const ptr_ty = sema.typeOf(ptr); | 9368 | const ptr_ty = sema.typeOf(ptr); |
| 9321 | if (ptr_ty.isConstPtr()) | 9369 | if (ptr_ty.isConstPtr()) |
| 9322 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); | 9370 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); |
| 9323 | | 9371 | |
| 9324 | const elem_ty = ptr_ty.elemType(); | 9372 | const elem_ty = ptr_ty.elemType(); |
| 9325 | const value = try sema.coerce(block, elem_ty, uncasted_value, src); | 9373 | const operand = try sema.coerce(block, elem_ty, uncasted_operand, operand_src); |
| 9326 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) | 9374 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) |
| 9327 | return; | 9375 | return; |
| 9328 | | 9376 | |
| 9329 | if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| { | 9377 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { |
| 9330 | if (ptr_val.castTag(.decl_ref_mut)) |decl_ref_mut| { | 9378 | if (ptr_val.castTag(.decl_ref_mut)) |decl_ref_mut| { |
| 9331 | const const_val = (try sema.resolveMaybeUndefVal(block, src, value)) orelse | 9379 | const const_val = (try sema.resolveMaybeUndefVal(block, operand_src, operand)) orelse |
| 9332 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); | 9380 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); |
| 9333 | | 9381 | |
| 9334 | if (decl_ref_mut.data.runtime_index < block.runtime_index) { | 9382 | if (decl_ref_mut.data.runtime_index < block.runtime_index) { |
| ... | @@ -9365,11 +9413,13 @@ fn storePtr( | ... | @@ -9365,11 +9413,13 @@ fn storePtr( |
| 9365 | old_arena.deinit(); | 9413 | old_arena.deinit(); |
| 9366 | return; | 9414 | return; |
| 9367 | } | 9415 | } |
| 9368 | } | 9416 | break :rs operand_src; |
| | 9417 | } else ptr_src; |
| | 9418 | |
| 9369 | // TODO handle if the element type requires comptime | 9419 | // TODO handle if the element type requires comptime |
| 9370 | | 9420 | |
| 9371 | try sema.requireRuntimeBlock(block, src); | 9421 | try sema.requireRuntimeBlock(block, runtime_src); |
| 9372 | _ = try block.addBinOp(.store, ptr, value); | 9422 | _ = try block.addBinOp(air_tag, ptr, operand); |
| 9373 | } | 9423 | } |
| 9374 | | 9424 | |
| 9375 | fn bitcast( | 9425 | fn bitcast( |