| ... | @@ -1431,6 +1431,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1431,6 +1431,8 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1431 | if (!is_volatile and f.liveness.isUnused(inst)) | 1431 | if (!is_volatile and f.liveness.isUnused(inst)) |
| 1432 | return CValue.none; | 1432 | return CValue.none; |
| 1433 | const inst_ty = f.air.typeOfIndex(inst); | 1433 | const inst_ty = f.air.typeOfIndex(inst); |
| | 1434 | if (inst_ty.zigTypeTag() == .Array) |
| | 1435 | return f.fail("TODO: C backend: implement airLoad for arrays", .{}); |
| 1434 | const operand = try f.resolveInst(ty_op.operand); | 1436 | const operand = try f.resolveInst(ty_op.operand); |
| 1435 | const writer = f.object.writer(); | 1437 | const writer = f.object.writer(); |
| 1436 | const local = try f.allocLocal(inst_ty, .Const); | 1438 | const local = try f.allocLocal(inst_ty, .Const); |
| ... | @@ -1557,7 +1559,7 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1557,7 +1559,7 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1557 | return local; | 1559 | return local; |
| 1558 | } | 1560 | } |
| 1559 | | 1561 | |
| 1560 | fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue { | 1562 | fn airStoreUndefined(f: *Function, dest_ptr: CValue, dest_type: Type) !CValue { |
| 1561 | const is_debug_build = f.object.dg.module.optimizeMode() == .Debug; | 1563 | const is_debug_build = f.object.dg.module.optimizeMode() == .Debug; |
| 1562 | if (!is_debug_build) | 1564 | if (!is_debug_build) |
| 1563 | return CValue.none; | 1565 | return CValue.none; |
| ... | @@ -1581,9 +1583,11 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue { | ... | @@ -1581,9 +1583,11 @@ fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue { |
| 1581 | try writer.writeAll("));\n"); | 1583 | try writer.writeAll("));\n"); |
| 1582 | }, | 1584 | }, |
| 1583 | else => { | 1585 | else => { |
| | 1586 | const indirection = if (dest_type.zigTypeTag() == .Array) "" else "*"; |
| | 1587 | |
| 1584 | try writer.writeAll("memset("); | 1588 | try writer.writeAll("memset("); |
| 1585 | try f.writeCValue(writer, dest_ptr); | 1589 | try f.writeCValue(writer, dest_ptr); |
| 1586 | try writer.writeAll(", 0xaa, sizeof(*"); | 1590 | try writer.print(", 0xaa, sizeof({s}", .{indirection}); |
| 1587 | try f.writeCValue(writer, dest_ptr); | 1591 | try f.writeCValue(writer, dest_ptr); |
| 1588 | try writer.writeAll("));\n"); | 1592 | try writer.writeAll("));\n"); |
| 1589 | }, | 1593 | }, |
| ... | @@ -1596,11 +1600,16 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -1596,11 +1600,16 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 1596 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 1600 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 1597 | const dest_ptr = try f.resolveInst(bin_op.lhs); | 1601 | const dest_ptr = try f.resolveInst(bin_op.lhs); |
| 1598 | const src_val = try f.resolveInst(bin_op.rhs); | 1602 | const src_val = try f.resolveInst(bin_op.rhs); |
| | 1603 | const lhs_type = f.air.typeOf(bin_op.lhs); |
| 1599 | | 1604 | |
| 1600 | const src_val_is_undefined = | 1605 | const src_val_is_undefined = |
| 1601 | if (f.air.value(bin_op.rhs)) |v| v.isUndef() else false; | 1606 | if (f.air.value(bin_op.rhs)) |v| v.isUndef() else false; |
| 1602 | if (src_val_is_undefined) | 1607 | if (src_val_is_undefined) |
| 1603 | return try airStoreUndefined(f, dest_ptr); | 1608 | return try airStoreUndefined(f, dest_ptr, lhs_type); |
| | 1609 | |
| | 1610 | // Don't check this for airStoreUndefined as that will work for arrays already |
| | 1611 | if (lhs_type.zigTypeTag() == .Array) |
| | 1612 | return f.fail("TODO: C backend: implement airStore for arrays", .{}); |
| 1604 | | 1613 | |
| 1605 | const writer = f.object.writer(); | 1614 | const writer = f.object.writer(); |
| 1606 | switch (dest_ptr) { | 1615 | switch (dest_ptr) { |
| ... | @@ -2420,15 +2429,17 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc | ... | @@ -2420,15 +2429,17 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc |
| 2420 | const writer = f.object.writer(); | 2429 | const writer = f.object.writer(); |
| 2421 | const struct_obj = struct_ptr_ty.elemType().castTag(.@"struct").?.data; | 2430 | const struct_obj = struct_ptr_ty.elemType().castTag(.@"struct").?.data; |
| 2422 | const field_name = struct_obj.fields.keys()[index]; | 2431 | const field_name = struct_obj.fields.keys()[index]; |
| | 2432 | const field_val = struct_obj.fields.values()[index]; |
| | 2433 | const addrof = if (field_val.ty.zigTypeTag() == .Array) "" else "&"; |
| 2423 | | 2434 | |
| 2424 | const inst_ty = f.air.typeOfIndex(inst); | 2435 | const inst_ty = f.air.typeOfIndex(inst); |
| 2425 | const local = try f.allocLocal(inst_ty, .Const); | 2436 | const local = try f.allocLocal(inst_ty, .Const); |
| 2426 | switch (struct_ptr) { | 2437 | switch (struct_ptr) { |
| 2427 | .local_ref => |i| { | 2438 | .local_ref => |i| { |
| 2428 | try writer.print(" = &t{d}.{};\n", .{ i, fmtIdent(field_name) }); | 2439 | try writer.print(" = {s}t{d}.{};\n", .{ addrof, i, fmtIdent(field_name) }); |
| 2429 | }, | 2440 | }, |
| 2430 | else => { | 2441 | else => { |
| 2431 | try writer.writeAll(" = &"); | 2442 | try writer.print(" = {s}", .{addrof}); |
| 2432 | try f.writeCValue(writer, struct_ptr); | 2443 | try f.writeCValue(writer, struct_ptr); |
| 2433 | try writer.print("->{};\n", .{fmtIdent(field_name)}); | 2444 | try writer.print("->{};\n", .{fmtIdent(field_name)}); |
| 2434 | }, | 2445 | }, |