| ... | ... | @@ -314,7 +314,6 @@ pub fn analyzeBody( |
| 314 | 314 | .select => try sema.zirSelect(block, inst), |
| 315 | 315 | .atomic_load => try sema.zirAtomicLoad(block, inst), |
| 316 | 316 | .atomic_rmw => try sema.zirAtomicRmw(block, inst), |
| 317 | | .atomic_store => try sema.zirAtomicStore(block, inst), |
| 318 | 317 | .mul_add => try sema.zirMulAdd(block, inst), |
| 319 | 318 | .builtin_call => try sema.zirBuiltinCall(block, inst), |
| 320 | 319 | .field_ptr_type => try sema.zirFieldPtrType(block, inst), |
| ... | ... | @@ -413,6 +412,11 @@ pub fn analyzeBody( |
| 413 | 412 | i += 1; |
| 414 | 413 | continue; |
| 415 | 414 | }, |
| 415 | .atomic_store => { |
| 416 | try sema.zirAtomicStore(block, inst); |
| 417 | i += 1; |
| 418 | continue; |
| 419 | }, |
| 416 | 420 | .store => { |
| 417 | 421 | try sema.zirStore(block, inst); |
| 418 | 422 | i += 1; |
| ... | ... | @@ -7669,6 +7673,8 @@ fn zirCmpxchg( |
| 7669 | 7673 | if (try sema.resolveMaybeUndefVal(block, expected_src, expected_value)) |expected_val| { |
| 7670 | 7674 | if (try sema.resolveMaybeUndefVal(block, new_value_src, new_value)) |new_val| { |
| 7671 | 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 | 7678 | return sema.addConstUndef(result_ty); |
| 7673 | 7679 | } |
| 7674 | 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 | 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 | 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 | 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 | 7873 | fn zirMulAdd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -9310,25 +9344,39 @@ fn coerceVarArgParam( |
| 9310 | 9344 | return inst; |
| 9311 | 9345 | } |
| 9312 | 9346 | |
| 9347 | // TODO migrate callsites to use storePtr2 instead. |
| 9313 | 9348 | fn storePtr( |
| 9314 | 9349 | sema: *Sema, |
| 9315 | 9350 | block: *Scope.Block, |
| 9316 | 9351 | src: LazySrcLoc, |
| 9317 | 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 | 9367 | ) !void { |
| 9320 | 9368 | const ptr_ty = sema.typeOf(ptr); |
| 9321 | 9369 | if (ptr_ty.isConstPtr()) |
| 9322 | 9370 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); |
| 9323 | 9371 | |
| 9324 | 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 | 9374 | if ((try sema.typeHasOnePossibleValue(block, src, elem_ty)) != null) |
| 9327 | 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 | 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 | 9380 | return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); |
| 9333 | 9381 | |
| 9334 | 9382 | if (decl_ref_mut.data.runtime_index < block.runtime_index) { |
| ... | ... | @@ -9365,11 +9413,13 @@ fn storePtr( |
| 9365 | 9413 | old_arena.deinit(); |
| 9366 | 9414 | return; |
| 9367 | 9415 | } |
| 9368 | | } |
| 9416 | break :rs operand_src; |
| 9417 | } else ptr_src; |
| 9418 | |
| 9369 | 9419 | // TODO handle if the element type requires comptime |
| 9370 | 9420 | |
| 9371 | | try sema.requireRuntimeBlock(block, src); |
| 9372 | | _ = try block.addBinOp(.store, ptr, value); |
| 9421 | try sema.requireRuntimeBlock(block, runtime_src); |
| 9422 | _ = try block.addBinOp(air_tag, ptr, operand); |
| 9373 | 9423 | } |
| 9374 | 9424 | |
| 9375 | 9425 | fn bitcast( |