stage2: implement inttype ZIR

also add i128 and u128 to const inst list
This commit is contained in:
Andrew Kelley 2021-03-23 16:12:26 -07:00
parent aa46a705ad
commit be673e6793
5 changed files with 94 additions and 9 deletions

View File

@ -3599,11 +3599,14 @@ pub fn lookupDeclName(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Dec
return mod.decl_table.get(name_hash);
}
pub fn makeIntType(arena: *Allocator, signed: bool, bits: u16) !Type {
pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
const int_payload = try arena.create(Type.Payload.Bits);
int_payload.* = .{
.base = .{
.tag = if (signed) .int_signed else .int_unsigned,
.tag = switch (signedness) {
.signed => .int_signed,
.unsigned => .int_unsigned,
},
},
.data = bits,
};

View File

@ -1226,7 +1226,11 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
const tracy = trace(@src());
defer tracy.end();
return sema.mod.fail(&block.base, sema.src, "TODO implement inttype", .{});
const int_type = sema.code.instructions.items(.data)[inst].int_type;
const src = int_type.src();
const ty = try Module.makeIntType(sema.arena, int_type.signedness, int_type.bit_count);
return sema.mod.constType(sema.arena, src, ty);
}
fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
@ -3967,7 +3971,8 @@ fn cmpNumeric(
const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) {
error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}),
};
break :blk try Module.makeIntType(sema.arena, dest_int_is_signed, casted_bits);
const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned;
break :blk try Module.makeIntType(sema.arena, signedness, casted_bits);
};
const casted_lhs = try sema.coerce(block, dest_type, lhs, lhs.src);
const casted_rhs = try sema.coerce(block, dest_type, rhs, rhs.src);

View File

@ -2888,7 +2888,10 @@ fn identifier(
if (ident_name.len >= 2) integer: {
const first_c = ident_name[0];
if (first_c == 'i' or first_c == 'u') {
const is_signed = first_c == 'i';
const signedness: std.builtin.Signedness = switch (first_c == 'i') {
true => .signed,
false => .unsigned,
};
const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {
error.Overflow => return mod.failNode(
scope,
@ -2898,7 +2901,15 @@ fn identifier(
),
error.InvalidCharacter => break :integer,
};
return rvalue(mod, scope, rl, try gz.addBin(.int_type, @boolToInt(is_signed), bit_count), ident);
const result = try gz.add(.{
.tag = .int_type,
.data = .{ .int_type = .{
.src_node = gz.zir_code.decl.nodeIndexToRelative(ident),
.signedness = signedness,
.bit_count = bit_count,
} },
});
return rvalue(mod, scope, rl, result, ident);
}
}

View File

@ -30,6 +30,8 @@ pub const Value = extern union {
i32_type,
u64_type,
i64_type,
u128_type,
i128_type,
usize_type,
isize_type,
c_short_type,
@ -120,6 +122,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -274,6 +278,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -427,6 +433,8 @@ pub const Value = extern union {
.i32_type => return out_stream.writeAll("i32"),
.u64_type => return out_stream.writeAll("u64"),
.i64_type => return out_stream.writeAll("i64"),
.u128_type => return out_stream.writeAll("u128"),
.i128_type => return out_stream.writeAll("i128"),
.isize_type => return out_stream.writeAll("isize"),
.usize_type => return out_stream.writeAll("usize"),
.c_short_type => return out_stream.writeAll("c_short"),
@ -554,6 +562,8 @@ pub const Value = extern union {
.i32_type => Type.initTag(.i32),
.u64_type => Type.initTag(.u64),
.i64_type => Type.initTag(.i64),
.u128_type => Type.initTag(.u128),
.i128_type => Type.initTag(.i128),
.usize_type => Type.initTag(.usize),
.isize_type => Type.initTag(.isize),
.c_short_type => Type.initTag(.c_short),
@ -650,6 +660,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -736,6 +748,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -822,6 +836,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -935,6 +951,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1026,6 +1044,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1182,6 +1202,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1265,6 +1287,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1416,6 +1440,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1573,6 +1599,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1659,6 +1687,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1762,6 +1792,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1843,6 +1875,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,
@ -1944,6 +1978,8 @@ pub const Value = extern union {
.i32_type,
.u64_type,
.i64_type,
.u128_type,
.i128_type,
.usize_type,
.isize_type,
.c_short_type,

View File

@ -125,6 +125,8 @@ pub const Const = enum {
i32_type,
u64_type,
i64_type,
u128_type,
i128_type,
usize_type,
isize_type,
c_short_type,
@ -210,6 +212,14 @@ pub const const_inst_list = std.enums.directEnumArray(Const, TypedValue, 0, .{
.ty = Type.initTag(.type),
.val = Value.initTag(.i64_type),
},
.u128_type = .{
.ty = Type.initTag(.type),
.val = Value.initTag(.u128_type),
},
.i128_type = .{
.ty = Type.initTag(.type),
.val = Value.initTag(.i128_type),
},
.usize_type = .{
.ty = Type.initTag(.type),
.val = Value.initTag(.usize_type),
@ -619,8 +629,7 @@ pub const Inst = struct {
/// Payload is `Bin` with lhs as the dest type, rhs the operand.
intcast,
/// Make an integer type out of signedness and bit count.
/// lhs is signedness, rhs is bit count.
/// Payload is `Bin`
/// Payload is `int_type`
int_type,
/// Return a boolean false if an optional is null. `x != null`
/// Uses the `un_tok` field.
@ -1135,6 +1144,17 @@ pub const Inst = struct {
/// For `fn_type_cc` this points to `FnTypeCc` in `extra`.
payload_index: u32,
},
int_type: struct {
/// Offset from Decl AST node index.
/// `Tag` determines which kind of AST node this points to.
src_node: i32,
signedness: std.builtin.Signedness,
bit_count: u16,
pub fn src(self: @This()) LazySrcLoc {
return .{ .node_offset = self.src_node };
}
},
bool_br: struct {
lhs: Ref,
/// Points to a `Block`.
@ -1340,7 +1360,6 @@ const Writer = struct {
.elem_ptr,
.elem_val,
.intcast,
.int_type,
.merge_error_sets,
=> try self.writeBin(stream, inst),
@ -1405,6 +1424,7 @@ const Writer = struct {
.str => try self.writeStr(stream, inst),
.elided => try stream.writeAll(")"),
.break_void_node => try self.writeBreakVoidNode(stream, inst),
.int_type => try self.writeIntType(stream, inst),
.@"asm",
.asm_volatile,
@ -1742,6 +1762,16 @@ const Writer = struct {
try self.writeSrc(stream, inst_data.src());
}
fn writeIntType(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const int_type = self.code.instructions.items(.data)[inst].int_type;
const prefix: u8 = switch (int_type.signedness) {
.signed => 'i',
.unsigned => 'u',
};
try stream.print("{c}{d}) ", .{ prefix, int_type.bit_count });
try self.writeSrc(stream, int_type.src());
}
fn writeUnreachable(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].@"unreachable";
const safety_str = if (inst_data.safety) "safe" else "unsafe";