| author | |
| committer | |
| log | fdedd62365b5e3f3fa908ae063df86d11a3c02bb |
| tree | 46f6b65879ff774baec072d6ad745106f7ff3032 |
| parent | af4361f57af388238a075b0c8ef5b34e75b73787 |
8 files changed, 22 insertions(+), 29 deletions(-)
src/codegen/c.zig+22-15| ... | ... | @@ -2999,30 +2999,31 @@ fn airArg(f: *Function) CValue { |
| 2999 | 2999 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3000 | 3000 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3001 | 3001 | const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data; |
| 3002 | const src_ty = ptr_info.pointee_type; | |
| 3002 | 3003 | |
| 3003 | const inst_ty = f.air.typeOfIndex(inst); | |
| 3004 | if (!inst_ty.hasRuntimeBitsIgnoreComptime() or | |
| 3004 | if (!src_ty.hasRuntimeBitsIgnoreComptime() or | |
| 3005 | 3005 | !ptr_info.@"volatile" and f.liveness.isUnused(inst)) |
| 3006 | 3006 | return CValue.none; |
| 3007 | 3007 | |
| 3008 | 3008 | const target = f.object.dg.module.getTarget(); |
| 3009 | const is_array = lowersToArray(inst_ty, target); | |
| 3009 | const is_aligned = ptr_info.@"align" == 0 or ptr_info.@"align" >= src_ty.abiAlignment(target); | |
| 3010 | const is_array = lowersToArray(src_ty, target); | |
| 3011 | const need_memcpy = !is_aligned or is_array; | |
| 3010 | 3012 | const operand = try f.resolveInst(ty_op.operand); |
| 3011 | 3013 | const writer = f.object.writer(); |
| 3012 | 3014 | |
| 3013 | // We need to separately initialize arrays with a memcpy so they must be mutable. | |
| 3014 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); | |
| 3015 | // We need to initialize arrays and unaligned loads with a memcpy so they must be mutable. | |
| 3016 | const local = try f.allocLocal(src_ty, if (need_memcpy) .Mut else .Const); | |
| 3015 | 3017 | |
| 3016 | if (is_array) { | |
| 3017 | // Insert a memcpy to initialize this array. The source operand is always a pointer | |
| 3018 | // and thus we only need to know size/type information from the local type/dest. | |
| 3018 | if (need_memcpy) { | |
| 3019 | 3019 | try writer.writeAll(";\n"); |
| 3020 | 3020 | try writer.writeAll("memcpy("); |
| 3021 | if (!is_array) try writer.writeByte('&'); | |
| 3021 | 3022 | try f.writeCValue(writer, local, .FunctionArgument); |
| 3022 | try writer.writeAll(", "); | |
| 3023 | try f.writeCValue(writer, operand, .FunctionArgument); | |
| 3023 | try writer.writeAll(", (const char *)"); | |
| 3024 | try f.writeCValue(writer, operand, .Other); | |
| 3024 | 3025 | try writer.writeAll(", sizeof("); |
| 3025 | try f.renderTypecast(writer, inst_ty); | |
| 3026 | try f.renderTypecast(writer, src_ty); | |
| 3026 | 3027 | try writer.writeAll("))"); |
| 3027 | 3028 | } else if (ptr_info.host_size != 0) { |
| 3028 | 3029 | var host_pl = Type.Payload.Bits{ |
| ... | ... | @@ -3045,12 +3046,12 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3045 | 3046 | |
| 3046 | 3047 | var field_pl = Type.Payload.Bits{ |
| 3047 | 3048 | .base = .{ .tag = .int_unsigned }, |
| 3048 | .data = @intCast(u16, inst_ty.bitSize(target)), | |
| 3049 | .data = @intCast(u16, src_ty.bitSize(target)), | |
| 3049 | 3050 | }; |
| 3050 | 3051 | const field_ty = Type.initPayload(&field_pl.base); |
| 3051 | 3052 | |
| 3052 | 3053 | try writer.writeAll(" = ("); |
| 3053 | try f.renderTypecast(writer, inst_ty); | |
| 3054 | try f.renderTypecast(writer, src_ty); | |
| 3054 | 3055 | try writer.writeAll(")zig_wrap_"); |
| 3055 | 3056 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty); |
| 3056 | 3057 | try writer.writeAll("(("); |
| ... | ... | @@ -3226,8 +3227,13 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3226 | 3227 | return try airStoreUndefined(f, ptr_info.pointee_type, ptr_val); |
| 3227 | 3228 | |
| 3228 | 3229 | const target = f.object.dg.module.getTarget(); |
| 3230 | const is_aligned = ptr_info.@"align" == 0 or | |
| 3231 | ptr_info.@"align" >= ptr_info.pointee_type.abiAlignment(target); | |
| 3232 | const is_array = lowersToArray(ptr_info.pointee_type, target); | |
| 3233 | const need_memcpy = !is_aligned or is_array; | |
| 3229 | 3234 | const writer = f.object.writer(); |
| 3230 | if (lowersToArray(ptr_info.pointee_type, target)) { | |
| 3235 | ||
| 3236 | if (need_memcpy) { | |
| 3231 | 3237 | // For this memcpy to safely work we need the rhs to have the same |
| 3232 | 3238 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). |
| 3233 | 3239 | assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module)); |
| ... | ... | @@ -3244,9 +3250,10 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3244 | 3250 | break :blk new_local; |
| 3245 | 3251 | } else src_val; |
| 3246 | 3252 | |
| 3247 | try writer.writeAll("memcpy("); | |
| 3253 | try writer.writeAll("memcpy((char *)"); | |
| 3248 | 3254 | try f.writeCValue(writer, ptr_val, .FunctionArgument); |
| 3249 | 3255 | try writer.writeAll(", "); |
| 3256 | if (!is_array) try writer.writeByte('&'); | |
| 3250 | 3257 | try f.writeCValue(writer, array_src, .FunctionArgument); |
| 3251 | 3258 | try writer.writeAll(", sizeof("); |
| 3252 | 3259 | try f.renderTypecast(writer, src_ty); |
test/behavior/basic.zig-2| ... | ... | @@ -754,7 +754,6 @@ fn maybe(x: bool) anyerror!?u32 { |
| 754 | 754 | } |
| 755 | 755 | |
| 756 | 756 | test "pointer to thread local array" { |
| 757 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 758 | 757 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 759 | 758 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 760 | 759 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | ... | @@ -770,7 +769,6 @@ threadlocal var buffer: [11]u8 = undefined; |
| 770 | 769 | |
| 771 | 770 | test "auto created variables have correct alignment" { |
| 772 | 771 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 773 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 774 | 772 | |
| 775 | 773 | const S = struct { |
| 776 | 774 | fn foo(str: [*]const u8) u32 { |
test/behavior/bitreverse.zig-1| ... | ... | @@ -155,7 +155,6 @@ fn vector0() !void { |
| 155 | 155 | test "bitReverse vectors u0" { |
| 156 | 156 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 157 | 157 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 158 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 159 | 158 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 160 | 159 | |
| 161 | 160 | comptime try vector0(); |
test/behavior/byteswap.zig-1| ... | ... | @@ -121,7 +121,6 @@ fn vector0() !void { |
| 121 | 121 | test "@byteSwap vectors u0" { |
| 122 | 122 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 123 | 123 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 124 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 125 | 124 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 126 | 125 | |
| 127 | 126 | comptime try vector0(); |
test/behavior/math.zig-1| ... | ... | @@ -1518,7 +1518,6 @@ fn testRound(comptime T: type, x: T) !void { |
| 1518 | 1518 | } |
| 1519 | 1519 | |
| 1520 | 1520 | test "vector integer addition" { |
| 1521 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1522 | 1521 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1523 | 1522 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1524 | 1523 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/ptrcast.zig-1| ... | ... | @@ -78,7 +78,6 @@ fn testReinterpretBytesAsExternStruct() !void { |
| 78 | 78 | |
| 79 | 79 | test "reinterpret bytes of an extern struct (with under-aligned fields) into another" { |
| 80 | 80 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 81 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO: Under-aligned fields are not yet supported in the CBE | |
| 82 | 81 | |
| 83 | 82 | try testReinterpretExternStructAsExternStruct(); |
| 84 | 83 | comptime try testReinterpretExternStructAsExternStruct(); |
test/behavior/struct.zig-1| ... | ... | @@ -641,7 +641,6 @@ test "default struct initialization fields" { |
| 641 | 641 | |
| 642 | 642 | test "packed array 24bits" { |
| 643 | 643 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 644 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 645 | 644 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 646 | 645 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 647 | 646 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/vector.zig-7| ... | ... | @@ -75,7 +75,6 @@ test "vector bin compares with mem.eql" { |
| 75 | 75 | |
| 76 | 76 | test "vector int operators" { |
| 77 | 77 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 78 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 79 | 78 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 80 | 79 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 81 | 80 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -139,7 +138,6 @@ test "vector bit operators" { |
| 139 | 138 | |
| 140 | 139 | test "implicit cast vector to array" { |
| 141 | 140 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 142 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 143 | 141 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 144 | 142 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 145 | 143 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -158,7 +156,6 @@ test "implicit cast vector to array" { |
| 158 | 156 | |
| 159 | 157 | test "array to vector" { |
| 160 | 158 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 161 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 162 | 159 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 163 | 160 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 164 | 161 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -177,7 +174,6 @@ test "array to vector" { |
| 177 | 174 | |
| 178 | 175 | test "tuple to vector" { |
| 179 | 176 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 180 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 181 | 177 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 182 | 178 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 183 | 179 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -210,7 +206,6 @@ test "tuple to vector" { |
| 210 | 206 | |
| 211 | 207 | test "vector casts of sizes not divisible by 8" { |
| 212 | 208 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 213 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 214 | 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 215 | 210 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 216 | 211 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -945,7 +940,6 @@ test "multiplication-assignment operator with an array operand" { |
| 945 | 940 | return error.SkipZigTest; |
| 946 | 941 | } |
| 947 | 942 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 948 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 949 | 943 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 950 | 944 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 951 | 945 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | ... | @@ -1194,7 +1188,6 @@ test "zero divisor" { |
| 1194 | 1188 | |
| 1195 | 1189 | test "zero multiplicand" { |
| 1196 | 1190 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1197 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1198 | 1191 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1199 | 1192 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1200 | 1193 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |