mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
cbe: implement aggregate_init of struct
This commit is contained in:
parent
feb8f81cd9
commit
87d432328e
@ -62,7 +62,6 @@ const FormatTypeAsCIdentContext = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ValueRenderLocation = enum {
|
const ValueRenderLocation = enum {
|
||||||
Identifier,
|
|
||||||
FunctionArgument,
|
FunctionArgument,
|
||||||
Other,
|
Other,
|
||||||
};
|
};
|
||||||
@ -340,7 +339,7 @@ pub const Function = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
|
fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) {
|
||||||
return f.object.dg.fmtIntLiteral(ty, val, .Other);
|
return f.object.dg.fmtIntLiteral(ty, val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -533,16 +532,13 @@ pub const DeclGen = struct {
|
|||||||
// Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
|
// Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang)
|
||||||
// with 'error: expected expression' (including when built with 'zig cc')
|
// with 'error: expected expression' (including when built with 'zig cc')
|
||||||
.Bool => return writer.writeAll("false"),
|
.Bool => return writer.writeAll("false"),
|
||||||
.Int,
|
.Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val)}),
|
||||||
.Enum,
|
|
||||||
.ErrorSet,
|
|
||||||
=> return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val, location)}),
|
|
||||||
.Float => switch (ty.tag()) {
|
.Float => switch (ty.tag()) {
|
||||||
.f32 => return writer.print("zig_bitcast_f32_u32({x})", .{
|
.f32 => return writer.print("zig_bitcast_f32_u32({x})", .{
|
||||||
try dg.fmtIntLiteral(Type.u32, val, location),
|
try dg.fmtIntLiteral(Type.u32, val),
|
||||||
}),
|
}),
|
||||||
.f64 => return writer.print("zig_bitcast_f64_u64({x})", .{
|
.f64 => return writer.print("zig_bitcast_f64_u64({x})", .{
|
||||||
try dg.fmtIntLiteral(Type.u64, val, location),
|
try dg.fmtIntLiteral(Type.u64, val),
|
||||||
}),
|
}),
|
||||||
else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
|
else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
|
||||||
},
|
},
|
||||||
@ -554,14 +550,12 @@ pub const DeclGen = struct {
|
|||||||
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
|
||||||
const ptr_ty = ty.slicePtrFieldType(&buf);
|
const ptr_ty = ty.slicePtrFieldType(&buf);
|
||||||
try dg.renderTypecast(writer, ptr_ty);
|
try dg.renderTypecast(writer, ptr_ty);
|
||||||
return writer.print("){x}, {0x}}}", .{
|
return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)});
|
||||||
try dg.fmtIntLiteral(Type.usize, val, location),
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
.Many, .C, .One => {
|
.Many, .C, .One => {
|
||||||
try writer.writeAll("((");
|
try writer.writeAll("((");
|
||||||
try dg.renderTypecast(writer, ty);
|
try dg.renderTypecast(writer, ty);
|
||||||
return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, location)});
|
return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.Optional => {
|
.Optional => {
|
||||||
@ -598,9 +592,7 @@ pub const DeclGen = struct {
|
|||||||
|
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
if (empty) try writer.print("{x}", .{
|
if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
|
||||||
try dg.fmtIntLiteral(Type.u8, Value.undef, location),
|
|
||||||
});
|
|
||||||
|
|
||||||
return writer.writeByte('}');
|
return writer.writeByte('}');
|
||||||
},
|
},
|
||||||
@ -613,9 +605,7 @@ pub const DeclGen = struct {
|
|||||||
if (!field.ty.hasRuntimeBits()) continue;
|
if (!field.ty.hasRuntimeBits()) continue;
|
||||||
try dg.renderValue(writer, field.ty, val, location);
|
try dg.renderValue(writer, field.ty, val, location);
|
||||||
break;
|
break;
|
||||||
} else try writer.print("{x}", .{
|
} else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)});
|
||||||
try dg.fmtIntLiteral(Type.u8, Value.undef, location),
|
|
||||||
});
|
|
||||||
|
|
||||||
return writer.writeByte('}');
|
return writer.writeByte('}');
|
||||||
},
|
},
|
||||||
@ -625,7 +615,7 @@ pub const DeclGen = struct {
|
|||||||
try writer.writeAll("){ .payload = ");
|
try writer.writeAll("){ .payload = ");
|
||||||
try dg.renderValue(writer, ty.errorUnionPayload(), val, location);
|
try dg.renderValue(writer, ty.errorUnionPayload(), val, location);
|
||||||
return writer.print(", .error = {x} }}", .{
|
return writer.print(", .error = {x} }}", .{
|
||||||
try dg.fmtIntLiteral(ty.errorUnionSet(), Value.undef, location),
|
try dg.fmtIntLiteral(ty.errorUnionSet(), Value.undef),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
.Array => {
|
.Array => {
|
||||||
@ -670,7 +660,7 @@ pub const DeclGen = struct {
|
|||||||
.decl_ref_mut,
|
.decl_ref_mut,
|
||||||
.decl_ref,
|
.decl_ref,
|
||||||
=> try dg.renderParentPtr(writer, val, ty),
|
=> try dg.renderParentPtr(writer, val, ty),
|
||||||
else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val, location)}),
|
else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val)}),
|
||||||
},
|
},
|
||||||
.Float => {
|
.Float => {
|
||||||
if (ty.floatBits(target) <= 64) {
|
if (ty.floatBits(target) <= 64) {
|
||||||
@ -682,22 +672,20 @@ pub const DeclGen = struct {
|
|||||||
.base = .{ .tag = .int_u64 },
|
.base = .{ .tag = .int_u64 },
|
||||||
.data = @bitCast(u32, val.toFloat(f32)),
|
.data = @bitCast(u32, val.toFloat(f32)),
|
||||||
};
|
};
|
||||||
return writer.print("zig_bitcast_f32_u32({x})", .{try dg.fmtIntLiteral(
|
const bitcast_val = Value.initPayload(&bitcast_val_pl.base);
|
||||||
Type.u32,
|
return writer.print("zig_bitcast_f32_u32({x})", .{
|
||||||
Value.initPayload(&bitcast_val_pl.base),
|
try dg.fmtIntLiteral(Type.u32, bitcast_val),
|
||||||
location,
|
});
|
||||||
)});
|
|
||||||
},
|
},
|
||||||
.f64 => {
|
.f64 => {
|
||||||
var bitcast_val_pl = Value.Payload.U64{
|
var bitcast_val_pl = Value.Payload.U64{
|
||||||
.base = .{ .tag = .int_u64 },
|
.base = .{ .tag = .int_u64 },
|
||||||
.data = @bitCast(u64, val.toFloat(f64)),
|
.data = @bitCast(u64, val.toFloat(f64)),
|
||||||
};
|
};
|
||||||
return writer.print("zig_bitcast_f32_u32({x})", .{try dg.fmtIntLiteral(
|
const bitcast_val = Value.initPayload(&bitcast_val_pl.base);
|
||||||
Type.u64,
|
return writer.print("zig_bitcast_f64_u64({x})", .{
|
||||||
Value.initPayload(&bitcast_val_pl.base),
|
try dg.fmtIntLiteral(Type.u64, bitcast_val),
|
||||||
location,
|
});
|
||||||
)});
|
|
||||||
},
|
},
|
||||||
else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
|
else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}),
|
||||||
}
|
}
|
||||||
@ -740,7 +728,7 @@ pub const DeclGen = struct {
|
|||||||
.int_u64, .one => {
|
.int_u64, .one => {
|
||||||
try writer.writeAll("((");
|
try writer.writeAll("((");
|
||||||
try dg.renderTypecast(writer, ty);
|
try dg.renderTypecast(writer, ty);
|
||||||
return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, location)});
|
return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)});
|
||||||
},
|
},
|
||||||
.field_ptr,
|
.field_ptr,
|
||||||
.elem_ptr,
|
.elem_ptr,
|
||||||
@ -918,7 +906,7 @@ pub const DeclGen = struct {
|
|||||||
|
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
if (empty) try writer.writeByte('0');
|
if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)});
|
||||||
|
|
||||||
try writer.writeByte('}');
|
try writer.writeByte('}');
|
||||||
},
|
},
|
||||||
@ -1730,7 +1718,7 @@ pub const DeclGen = struct {
|
|||||||
var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
|
var len_val_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len };
|
||||||
const len_val = Value.initPayload(&len_val_pl.base);
|
const len_val = Value.initPayload(&len_val_pl.base);
|
||||||
|
|
||||||
try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val, .Other)});
|
try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)});
|
||||||
try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);
|
try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0);
|
||||||
try buffer.appendSlice(" = ");
|
try buffer.appendSlice(" = ");
|
||||||
try dg.renderValue(bw, name_ty, name_val, .Other);
|
try dg.renderValue(bw, name_ty, name_val, .Other);
|
||||||
@ -1738,7 +1726,7 @@ pub const DeclGen = struct {
|
|||||||
try dg.renderTypecast(bw, name_slice_ty);
|
try dg.renderTypecast(bw, name_slice_ty);
|
||||||
try bw.print("){{{}, {}}};\n", .{
|
try bw.print("){{{}, {}}};\n", .{
|
||||||
fmtIdent("name"),
|
fmtIdent("name"),
|
||||||
try dg.fmtIntLiteral(Type.usize, len_val, .Other),
|
try dg.fmtIntLiteral(Type.usize, len_val),
|
||||||
});
|
});
|
||||||
|
|
||||||
try buffer.appendSlice(" }\n");
|
try buffer.appendSlice(" }\n");
|
||||||
@ -1793,7 +1781,7 @@ pub const DeclGen = struct {
|
|||||||
.undefined_ptr => |ty| {
|
.undefined_ptr => |ty| {
|
||||||
try w.writeAll("((");
|
try w.writeAll("((");
|
||||||
try dg.renderTypecast(w, ty);
|
try dg.renderTypecast(w, ty);
|
||||||
return w.print("){x})", .{try dg.fmtIntLiteral(Type.usize, Value.undef, .Other)});
|
return w.print("){x})", .{try dg.fmtIntLiteral(Type.usize, Value.undef)});
|
||||||
},
|
},
|
||||||
.identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
|
.identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}),
|
||||||
.bytes => |bytes| return w.writeAll(bytes),
|
.bytes => |bytes| return w.writeAll(bytes),
|
||||||
@ -1843,7 +1831,6 @@ pub const DeclGen = struct {
|
|||||||
dg: *DeclGen,
|
dg: *DeclGen,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
val: Value,
|
val: Value,
|
||||||
location: ValueRenderLocation,
|
|
||||||
) !std.fmt.Formatter(formatIntLiteral) {
|
) !std.fmt.Formatter(formatIntLiteral) {
|
||||||
const int_info = ty.intInfo(dg.module.getTarget());
|
const int_info = ty.intInfo(dg.module.getTarget());
|
||||||
const c_bits = toCIntBits(int_info.bits);
|
const c_bits = toCIntBits(int_info.bits);
|
||||||
@ -1853,7 +1840,6 @@ pub const DeclGen = struct {
|
|||||||
.ty = ty,
|
.ty = ty,
|
||||||
.val = val,
|
.val = val,
|
||||||
.mod = dg.module,
|
.mod = dg.module,
|
||||||
.location = location,
|
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1916,7 +1902,7 @@ pub fn genErrDecls(o: *Object) !void {
|
|||||||
|
|
||||||
try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{
|
try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{
|
||||||
fmtIdent(name),
|
fmtIdent(name),
|
||||||
try o.dg.fmtIntLiteral(Type.usize, len_val, .Other),
|
try o.dg.fmtIntLiteral(Type.usize, len_val),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
try writer.writeAll("};\n");
|
try writer.writeAll("};\n");
|
||||||
@ -4415,27 +4401,44 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||||||
|
|
||||||
const inst_ty = f.air.typeOfIndex(inst);
|
const inst_ty = f.air.typeOfIndex(inst);
|
||||||
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
|
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
|
||||||
const vector_ty = f.air.getRefType(ty_pl.ty);
|
const len = @intCast(usize, inst_ty.arrayLen());
|
||||||
const len = vector_ty.vectorLen();
|
|
||||||
const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
|
const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]);
|
||||||
|
|
||||||
const writer = f.object.writer();
|
const writer = f.object.writer();
|
||||||
const local = try f.allocLocal(inst_ty, .Const);
|
const local = try f.allocLocal(inst_ty, .Const);
|
||||||
try writer.writeAll(" = {");
|
try writer.writeAll(" = {");
|
||||||
switch (vector_ty.zigTypeTag()) {
|
switch (inst_ty.zigTypeTag()) {
|
||||||
.Struct => {
|
.Array => {
|
||||||
const tuple = vector_ty.tupleFields();
|
const elem_ty = inst_ty.childType();
|
||||||
var i: usize = 0;
|
var empty = true;
|
||||||
for (elements) |elem, elem_index| {
|
for (elements) |element| {
|
||||||
if (tuple.values[elem_index].tag() != .unreachable_value) continue;
|
if (empty) try writer.writeAll(", ");
|
||||||
|
try f.writeCValue(writer, try f.resolveInst(element));
|
||||||
const value = try f.resolveInst(elem);
|
empty = false;
|
||||||
if (i != 0) try writer.writeAll(", ");
|
|
||||||
try f.writeCValue(writer, value);
|
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
|
if (inst_ty.sentinel()) |sentinel| {
|
||||||
|
if (empty) try writer.writeAll(", ");
|
||||||
|
try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
|
||||||
},
|
},
|
||||||
else => |tag| return f.fail("TODO: C backend: implement airAggregateInit for type {s}", .{@tagName(tag)}),
|
.Struct => {
|
||||||
|
var empty = true;
|
||||||
|
for (elements) |element, index| {
|
||||||
|
if (inst_ty.structFieldValueComptime(index)) |_| continue;
|
||||||
|
|
||||||
|
if (!empty) try writer.writeAll(", ");
|
||||||
|
if (!inst_ty.isTupleOrAnonStruct()) {
|
||||||
|
try writer.print(".{ } = ", .{fmtIdent(inst_ty.structFieldName(index))});
|
||||||
|
}
|
||||||
|
try f.writeCValue(writer, try f.resolveInst(element));
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)});
|
||||||
|
},
|
||||||
|
.Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),
|
||||||
|
else => unreachable,
|
||||||
}
|
}
|
||||||
try writer.writeAll("};\n");
|
try writer.writeAll("};\n");
|
||||||
|
|
||||||
@ -4706,7 +4709,6 @@ const FormatIntLiteralContext = struct {
|
|||||||
ty: Type,
|
ty: Type,
|
||||||
val: Value,
|
val: Value,
|
||||||
mod: *Module,
|
mod: *Module,
|
||||||
location: ValueRenderLocation,
|
|
||||||
};
|
};
|
||||||
fn formatIntLiteral(
|
fn formatIntLiteral(
|
||||||
data: FormatIntLiteralContext,
|
data: FormatIntLiteralContext,
|
||||||
@ -4755,13 +4757,6 @@ fn formatIntLiteral(
|
|||||||
} else data.val.toBigInt(&int_buf, target);
|
} else data.val.toBigInt(&int_buf, target);
|
||||||
assert(int.fitsInTwosComp(int_info.signedness, int_info.bits));
|
assert(int.fitsInTwosComp(int_info.signedness, int_info.bits));
|
||||||
|
|
||||||
if (data.location == .Identifier) {
|
|
||||||
const str = try int.toStringAlloc(allocator, 10, undefined);
|
|
||||||
defer allocator.free(str);
|
|
||||||
|
|
||||||
return writer.writeAll(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
const limbs_count_64 = @divExact(64, @bitSizeOf(Limb));
|
const limbs_count_64 = @divExact(64, @bitSizeOf(Limb));
|
||||||
const c_bits = toCIntBits(int_info.bits) orelse unreachable;
|
const c_bits = toCIntBits(int_info.bits) orelse unreachable;
|
||||||
if (c_bits == 128) {
|
if (c_bits == 128) {
|
||||||
@ -4788,7 +4783,6 @@ fn formatIntLiteral(
|
|||||||
.ty = Type.u64,
|
.ty = Type.u64,
|
||||||
.val = upper_val,
|
.val = upper_val,
|
||||||
.mod = data.mod,
|
.mod = data.mod,
|
||||||
.location = data.location,
|
|
||||||
}, fmt, options, writer);
|
}, fmt, options, writer);
|
||||||
try writer.writeAll("<<64|");
|
try writer.writeAll("<<64|");
|
||||||
}
|
}
|
||||||
@ -4802,7 +4796,6 @@ fn formatIntLiteral(
|
|||||||
.ty = Type.u64,
|
.ty = Type.u64,
|
||||||
.val = lower_val,
|
.val = lower_val,
|
||||||
.mod = data.mod,
|
.mod = data.mod,
|
||||||
.location = data.location,
|
|
||||||
}, fmt, options, writer);
|
}, fmt, options, writer);
|
||||||
|
|
||||||
if (have_upper) try writer.writeByte(')');
|
if (have_upper) try writer.writeByte(')');
|
||||||
|
|||||||
@ -86,7 +86,6 @@ test "tuple parameters" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "result location of function call argument through runtime condition and struct init" {
|
test "result location of function call argument through runtime condition and struct init" {
|
||||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
|||||||
@ -1017,7 +1017,6 @@ test "struct with union field" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "type coercion of anon struct literal to struct" {
|
test "type coercion of anon struct literal to struct" {
|
||||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
@ -1056,7 +1055,6 @@ test "type coercion of anon struct literal to struct" {
|
|||||||
|
|
||||||
test "type coercion of pointer to anon struct literal to pointer to struct" {
|
test "type coercion of pointer to anon struct literal to pointer to struct" {
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user