diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-04-23 15:10:18 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-04-25 11:23:41 -0700 |
| commit | 482a0f648c90e8a61dac3a95313e0519bc5f4b5f (patch) | |
| tree | 967a2952ea15e6d543224f64ad7b61a9828a6787 /src/Sema.zig | |
| parent | 83a7303bbf92fcada2e61f2906f84ccf53e50ff0 (diff) | |
| download | zig-482a0f648c90e8a61dac3a95313e0519bc5f4b5f.tar.gz zig-482a0f648c90e8a61dac3a95313e0519bc5f4b5f.zip | |
Sema: implement comptime `@memcpy`
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 9b54d649a0..1ed517ba8c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21828,6 +21828,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const src_ptr = try sema.resolveInst(extra.rhs); const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr); const src_len = try indexablePtrLenOrNone(sema, block, src_src, src_ptr); + const target = sema.mod.getTarget(); if (dest_len == .none and src_len == .none) { const msg = msg: { @@ -21879,9 +21880,41 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: { if (!dest_ptr_val.isComptimeMutablePtr()) break :rs dest_src; - if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |src_ptr_val| { - _ = src_ptr_val; - return sema.fail(block, src, "TODO: @memcpy at comptime", .{}); + if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| { + const len_u64 = (try len_val.?.getUnsignedIntAdvanced(target, sema)).?; + const len = try sema.usizeCast(block, dest_src, len_u64); + for (0..len) |i| { + const elem_index = try sema.addIntUnsigned(Type.usize, i); + const dest_elem_ptr = try sema.elemPtr( + block, + src, + dest_ptr, + elem_index, + src, + true, // init + false, // oob_safety + ); + const src_elem_ptr = try sema.elemPtr( + block, + src, + src_ptr, + elem_index, + src, + false, // init + false, // oob_safety + ); + const uncoerced_elem = try sema.analyzeLoad(block, src, src_elem_ptr, src_src); + try sema.storePtr2( + block, + src, + dest_elem_ptr, + dest_src, + uncoerced_elem, + src_src, + .store, + ); + } + return; } else break :rs src_src; } else dest_src; @@ -21902,7 +21935,6 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const dest_elem_ty = dest_ty.elemType2(); const src_elem_ty = src_ty.elemType2(); - const target = sema.mod.getTarget(); if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) { return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{}); } |
