authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-27 17:08:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-27 17:08:37-07:00
logdc88864c9742029c2980fc16cd2c9e6f04ff3568
tree2569f14d189ef238ca7a281774e09ba49374113b
parent66e5920dc3411daa4f0c84a8f4c733c1263e8523

stage2: implement `@boolToInt`

This is the first commit in which some behavior tests are passing for both stage1 and stage2.

15 files changed, 92 insertions(+), 16 deletions(-)

doc/langref.html.in+2-2
...@@ -7165,8 +7165,8 @@ fn func(y: *i32) void {...@@ -7165,8 +7165,8 @@ fn func(y: *i32) void {
7165 {#header_open|@boolToInt#}7165 {#header_open|@boolToInt#}
7166 <pre>{#syntax#}@boolToInt(value: bool) u1{#endsyntax#}</pre>7166 <pre>{#syntax#}@boolToInt(value: bool) u1{#endsyntax#}</pre>
7167 <p>7167 <p>
7168 Converts {#syntax#}true{#endsyntax#} to {#syntax#}u1(1){#endsyntax#} and {#syntax#}false{#endsyntax#} to7168 Converts {#syntax#}true{#endsyntax#} to {#syntax#}@as(u1, 1){#endsyntax#} and {#syntax#}false{#endsyntax#} to
7169 {#syntax#}u1(0){#endsyntax#}.7169 {#syntax#}@as(u1, 0){#endsyntax#}.
7170 </p>7170 </p>
7171 <p>7171 <p>
7172 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#}7172 If the value is known at compile-time, the return type is {#syntax#}comptime_int{#endsyntax#}
src/Air.zig+6
...@@ -189,6 +189,10 @@ pub const Inst = struct {...@@ -189,6 +189,10 @@ pub const Inst = struct {
189 /// Converts a pointer to its address. Result type is always `usize`.189 /// Converts a pointer to its address. Result type is always `usize`.
190 /// Uses the `un_op` field.190 /// Uses the `un_op` field.
191 ptrtoint,191 ptrtoint,
192 /// Given a boolean, returns 0 or 1.
193 /// Result type is always `u1`.
194 /// Uses the `un_op` field.
195 bool_to_int,
192 /// Stores a value onto the stack and returns a pointer to it.196 /// Stores a value onto the stack and returns a pointer to it.
193 /// TODO audit where this AIR instruction is emitted, maybe it should instead be emitting197 /// TODO audit where this AIR instruction is emitted, maybe it should instead be emitting
194 /// alloca instruction and storing to the alloca.198 /// alloca instruction and storing to the alloca.
...@@ -490,6 +494,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -490,6 +494,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
490 .slice_len,494 .slice_len,
491 => return Type.initTag(.usize),495 => return Type.initTag(.usize),
492496
497 .bool_to_int => return Type.initTag(.u1),
498
493 .call => {499 .call => {
494 const callee_ty = air.typeOf(datas[inst].pl_op.operand);500 const callee_ty = air.typeOf(datas[inst].pl_op.operand);
495 return callee_ty.fnReturnType();501 return callee_ty.fnReturnType();
src/AstGen.zig+2
...@@ -7754,6 +7754,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{...@@ -7754,6 +7754,7 @@ pub const simple_types = std.ComptimeStringMap(Zir.Inst.Ref, .{
7754 .{ "u32", .u32_type },7754 .{ "u32", .u32_type },
7755 .{ "u64", .u64_type },7755 .{ "u64", .u64_type },
7756 .{ "u128", .u128_type },7756 .{ "u128", .u128_type },
7757 .{ "u1", .u1_type },
7757 .{ "u8", .u8_type },7758 .{ "u8", .u8_type },
7758 .{ "undefined", .undef },7759 .{ "undefined", .undef },
7759 .{ "usize", .usize_type },7760 .{ "usize", .usize_type },
...@@ -8400,6 +8401,7 @@ fn rvalue(...@@ -8400,6 +8401,7 @@ fn rvalue(
8400 const as_usize = @as(u64, @enumToInt(Zir.Inst.Ref.usize_type)) << 32;8401 const as_usize = @as(u64, @enumToInt(Zir.Inst.Ref.usize_type)) << 32;
8401 const as_void = @as(u64, @enumToInt(Zir.Inst.Ref.void_type)) << 32;8402 const as_void = @as(u64, @enumToInt(Zir.Inst.Ref.void_type)) << 32;
8402 switch ((@as(u64, @enumToInt(ty_inst)) << 32) | @as(u64, @enumToInt(result))) {8403 switch ((@as(u64, @enumToInt(ty_inst)) << 32) | @as(u64, @enumToInt(result))) {
8404 as_ty | @enumToInt(Zir.Inst.Ref.u1_type),
8403 as_ty | @enumToInt(Zir.Inst.Ref.u8_type),8405 as_ty | @enumToInt(Zir.Inst.Ref.u8_type),
8404 as_ty | @enumToInt(Zir.Inst.Ref.i8_type),8406 as_ty | @enumToInt(Zir.Inst.Ref.i8_type),
8405 as_ty | @enumToInt(Zir.Inst.Ref.u16_type),8407 as_ty | @enumToInt(Zir.Inst.Ref.u16_type),
src/Liveness.zig+1
...@@ -291,6 +291,7 @@ fn analyzeInst(...@@ -291,6 +291,7 @@ fn analyzeInst(
291 .is_err_ptr,291 .is_err_ptr,
292 .is_non_err_ptr,292 .is_non_err_ptr,
293 .ptrtoint,293 .ptrtoint,
294 .bool_to_int,
294 .ret,295 .ret,
295 => {296 => {
296 const operand = inst_datas[inst].un_op;297 const operand = inst_datas[inst].un_op;
src/Sema.zig+9-2
...@@ -5848,8 +5848,14 @@ fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -5848,8 +5848,14 @@ fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
58485848
5849fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5849fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
5850 const inst_data = sema.code.instructions.items(.data)[inst].un_node;5850 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
5851 const src = inst_data.src();5851 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5852 return sema.mod.fail(&block.base, src, "TODO: Sema.zirBoolToInt", .{});5852 const operand = sema.resolveInst(inst_data.operand);
5853 if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
5854 if (val.isUndef()) return sema.addConstUndef(Type.initTag(.u1));
5855 const bool_ints = [2]Air.Inst.Ref{ .zero, .one };
5856 return bool_ints[@boolToInt(val.toBool())];
5857 }
5858 return block.addUnOp(.bool_to_int, operand);
5853}5859}
58545860
5855fn zirEmbedFile(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5861fn zirEmbedFile(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -8252,6 +8258,7 @@ fn typeHasOnePossibleValue(...@@ -8252,6 +8258,7 @@ fn typeHasOnePossibleValue(
8252 .c_longdouble,8258 .c_longdouble,
8253 .comptime_int,8259 .comptime_int,
8254 .comptime_float,8260 .comptime_float,
8261 .u1,
8255 .u8,8262 .u8,
8256 .i8,8263 .i8,
8257 .u16,8264 .u16,
src/Zir.zig+5
...@@ -1633,6 +1633,7 @@ pub const Inst = struct {...@@ -1633,6 +1633,7 @@ pub const Inst = struct {
1633 /// value and may instead be used as a sentinel to indicate null.1633 /// value and may instead be used as a sentinel to indicate null.
1634 none,1634 none,
16351635
1636 u1_type,
1636 u8_type,1637 u8_type,
1637 i8_type,1638 i8_type,
1638 u16_type,1639 u16_type,
...@@ -1719,6 +1720,10 @@ pub const Inst = struct {...@@ -1719,6 +1720,10 @@ pub const Inst = struct {
1719 pub const typed_value_map = std.enums.directEnumArray(Ref, TypedValue, 0, .{1720 pub const typed_value_map = std.enums.directEnumArray(Ref, TypedValue, 0, .{
1720 .none = undefined,1721 .none = undefined,
17211722
1723 .u1_type = .{
1724 .ty = Type.initTag(.type),
1725 .val = Value.initTag(.u1_type),
1726 },
1722 .u8_type = .{1727 .u8_type = .{
1723 .ty = Type.initTag(.type),1728 .ty = Type.initTag(.type),
1724 .val = Value.initTag(.u8_type),1729 .val = Value.initTag(.u8_type),
src/codegen.zig+8
...@@ -835,6 +835,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -835,6 +835,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
835 .dbg_stmt => try self.airDbgStmt(inst),835 .dbg_stmt => try self.airDbgStmt(inst),
836 .floatcast => try self.airFloatCast(inst),836 .floatcast => try self.airFloatCast(inst),
837 .intcast => try self.airIntCast(inst),837 .intcast => try self.airIntCast(inst),
838 .bool_to_int => try self.airBoolToInt(inst),
838 .is_non_null => try self.airIsNonNull(inst),839 .is_non_null => try self.airIsNonNull(inst),
839 .is_non_null_ptr => try self.airIsNonNullPtr(inst),840 .is_non_null_ptr => try self.airIsNonNullPtr(inst),
840 .is_null => try self.airIsNull(inst),841 .is_null => try self.airIsNull(inst),
...@@ -1110,6 +1111,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1110,6 +1111,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1110 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1111 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1111 }1112 }
11121113
1114 fn airBoolToInt(self: *Self, inst: Air.Inst.Index) !void {
1115 const un_op = self.air.instructions.items(.data)[inst].un_op;
1116 const operand = try self.resolveInst(un_op);
1117 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else operand;
1118 return self.finishAir(inst, result, .{ un_op, .none, .none });
1119 }
1120
1113 fn airNot(self: *Self, inst: Air.Inst.Index) !void {1121 fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1114 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1122 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1115 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1123 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
src/codegen/c.zig+15
...@@ -925,6 +925,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM...@@ -925,6 +925,7 @@ fn genBody(o: *Object, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfM
925 .call => try airCall(o, inst),925 .call => try airCall(o, inst),
926 .dbg_stmt => try airDbgStmt(o, inst),926 .dbg_stmt => try airDbgStmt(o, inst),
927 .intcast => try airIntCast(o, inst),927 .intcast => try airIntCast(o, inst),
928 .bool_to_int => try airBoolToInt(o, inst),
928 .load => try airLoad(o, inst),929 .load => try airLoad(o, inst),
929 .ret => try airRet(o, inst),930 .ret => try airRet(o, inst),
930 .store => try airStore(o, inst),931 .store => try airStore(o, inst),
...@@ -1083,6 +1084,20 @@ fn airIntCast(o: *Object, inst: Air.Inst.Index) !CValue {...@@ -1083,6 +1084,20 @@ fn airIntCast(o: *Object, inst: Air.Inst.Index) !CValue {
1083 return local;1084 return local;
1084}1085}
10851086
1087fn airBoolToInt(o: *Object, inst: Air.Inst.Index) !CValue {
1088 if (o.liveness.isUnused(inst))
1089 return CValue.none;
1090 const un_op = o.air.instructions.items(.data)[inst].un_op;
1091 const writer = o.writer();
1092 const inst_ty = o.air.typeOfIndex(inst);
1093 const operand = try o.resolveInst(un_op);
1094 const local = try o.allocLocal(inst_ty, .Const);
1095 try writer.writeAll(" = ");
1096 try o.writeCValue(writer, operand);
1097 try writer.writeAll(";\n");
1098 return local;
1099}
1100
1086fn airStore(o: *Object, inst: Air.Inst.Index) !CValue {1101fn airStore(o: *Object, inst: Air.Inst.Index) !CValue {
1087 // *a = b;1102 // *a = b;
1088 const bin_op = o.air.instructions.items(.data)[inst].bin_op;1103 const bin_op = o.air.instructions.items(.data)[inst].bin_op;
src/codegen/llvm.zig+10
...@@ -961,6 +961,7 @@ pub const FuncGen = struct {...@@ -961,6 +961,7 @@ pub const FuncGen = struct {
961 .alloc => try self.airAlloc(inst),961 .alloc => try self.airAlloc(inst),
962 .arg => try self.airArg(inst),962 .arg => try self.airArg(inst),
963 .bitcast => try self.airBitCast(inst),963 .bitcast => try self.airBitCast(inst),
964 .bool_to_int=> try self.airBoolToInt(inst),
964 .block => try self.airBlock(inst),965 .block => try self.airBlock(inst),
965 .br => try self.airBr(inst),966 .br => try self.airBr(inst),
966 .switch_br => try self.airSwitchBr(inst),967 .switch_br => try self.airSwitchBr(inst),
...@@ -1656,6 +1657,15 @@ pub const FuncGen = struct {...@@ -1656,6 +1657,15 @@ pub const FuncGen = struct {
1656 return self.builder.buildBitCast(operand, dest_type, "");1657 return self.builder.buildBitCast(operand, dest_type, "");
1657 }1658 }
16581659
1660 fn airBoolToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
1661 if (self.liveness.isUnused(inst))
1662 return null;
1663
1664 const un_op = self.air.instructions.items(.data)[inst].un_op;
1665 const operand = try self.resolveInst(un_op);
1666 return operand;
1667 }
1668
1659 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {1669 fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
1660 const arg_val = self.args[self.arg_index];1670 const arg_val = self.args[self.arg_index];
1661 self.arg_index += 1;1671 self.arg_index += 1;
src/link/Coff.zig+5-2
...@@ -885,7 +885,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -885,7 +885,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
885 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.885 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.
886 if (self.base.options.use_llvm) {886 if (self.base.options.use_llvm) {
887 // Stage2 has to call flushModule since that outputs the LLVM object file.887 // Stage2 has to call flushModule since that outputs the LLVM object file.
888 if (!build_options.is_stage1) try self.flushModule(comp);888 if (!build_options.is_stage1 or !self.base.options.use_stage1) try self.flushModule(comp);
889889
890 const obj_basename = try std.zig.binNameAlloc(arena, .{890 const obj_basename = try std.zig.binNameAlloc(arena, .{
891 .root_name = self.base.options.root_name,891 .root_name = self.base.options.root_name,
...@@ -1269,7 +1269,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {...@@ -1269,7 +1269,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void {
12691269
1270 // TODO: remove when stage2 can build compiler_rt.zig, c.zig and ssp.zig1270 // TODO: remove when stage2 can build compiler_rt.zig, c.zig and ssp.zig
1271 // compiler-rt, libc and libssp1271 // compiler-rt, libc and libssp
1272 if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies and build_options.is_stage1) {1272 if (is_exe_or_dyn_lib and
1273 !self.base.options.skip_linker_dependencies and
1274 build_options.is_stage1 and self.base.options.use_stage1)
1275 {
1273 if (!self.base.options.link_libc) {1276 if (!self.base.options.link_libc) {
1274 try argv.append(comp.libc_static_lib.?.full_object_path);1277 try argv.append(comp.libc_static_lib.?.full_object_path);
1275 }1278 }
src/link/Elf.zig+4-3
...@@ -1257,7 +1257,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1257,7 +1257,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1257 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.1257 // Both stage1 and stage2 LLVM backend put the object file in the cache directory.
1258 if (self.base.options.use_llvm) {1258 if (self.base.options.use_llvm) {
1259 // Stage2 has to call flushModule since that outputs the LLVM object file.1259 // Stage2 has to call flushModule since that outputs the LLVM object file.
1260 if (!build_options.is_stage1) try self.flushModule(comp);1260 if (!build_options.is_stage1 or !self.base.options.use_stage1) try self.flushModule(comp);
12611261
1262 const obj_basename = try std.zig.binNameAlloc(arena, .{1262 const obj_basename = try std.zig.binNameAlloc(arena, .{
1263 .root_name = self.base.options.root_name,1263 .root_name = self.base.options.root_name,
...@@ -1287,7 +1287,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1287,7 +1287,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1287 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;1287 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
1288 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {1288 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
1289 // TODO: remove when stage2 can build compiler_rt.zig1289 // TODO: remove when stage2 can build compiler_rt.zig
1290 if (!build_options.is_stage1) break :blk null;1290 if (!build_options.is_stage1 or !self.base.options.use_stage1) break :blk null;
12911291
1292 // In the case of build-obj we include the compiler-rt symbols directly alongside1292 // In the case of build-obj we include the compiler-rt symbols directly alongside
1293 // the symbols of the root source file, in the same compilation unit.1293 // the symbols of the root source file, in the same compilation unit.
...@@ -1605,7 +1605,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1605,7 +1605,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1605 if (is_exe_or_dyn_lib and1605 if (is_exe_or_dyn_lib and
1606 !self.base.options.skip_linker_dependencies and1606 !self.base.options.skip_linker_dependencies and
1607 !self.base.options.link_libc and1607 !self.base.options.link_libc and
1608 build_options.is_stage1)1608 build_options.is_stage1 and
1609 self.base.options.use_stage1)
1609 {1610 {
1610 try argv.append(comp.libc_static_lib.?.full_object_path);1611 try argv.append(comp.libc_static_lib.?.full_object_path);
1611 }1612 }
src/print_air.zig+1
...@@ -137,6 +137,7 @@ const Writer = struct {...@@ -137,6 +137,7 @@ const Writer = struct {
137 .is_err_ptr,137 .is_err_ptr,
138 .is_non_err_ptr,138 .is_non_err_ptr,
139 .ptrtoint,139 .ptrtoint,
140 .bool_to_int,
140 .ret,141 .ret,
141 => try w.writeUnOp(s, inst),142 => try w.writeUnOp(s, inst),
142143
src/type.zig+15-2
...@@ -23,6 +23,7 @@ pub const Type = extern union {...@@ -23,6 +23,7 @@ pub const Type = extern union {
2323
24 pub fn zigTypeTag(self: Type) std.builtin.TypeId {24 pub fn zigTypeTag(self: Type) std.builtin.TypeId {
25 switch (self.tag()) {25 switch (self.tag()) {
26 .u1,
26 .u8,27 .u8,
27 .i8,28 .i8,
28 .u16,29 .u16,
...@@ -638,6 +639,7 @@ pub const Type = extern union {...@@ -638,6 +639,7 @@ pub const Type = extern union {
638 if (self.tag_if_small_enough < Tag.no_payload_count) {639 if (self.tag_if_small_enough < Tag.no_payload_count) {
639 return Type{ .tag_if_small_enough = self.tag_if_small_enough };640 return Type{ .tag_if_small_enough = self.tag_if_small_enough };
640 } else switch (self.ptr_otherwise.tag) {641 } else switch (self.ptr_otherwise.tag) {
642 .u1,
641 .u8,643 .u8,
642 .i8,644 .i8,
643 .u16,645 .u16,
...@@ -819,6 +821,7 @@ pub const Type = extern union {...@@ -819,6 +821,7 @@ pub const Type = extern union {
819 while (true) {821 while (true) {
820 const t = ty.tag();822 const t = ty.tag();
821 switch (t) {823 switch (t) {
824 .u1,
822 .u8,825 .u8,
823 .i8,826 .i8,
824 .u16,827 .u16,
...@@ -1082,6 +1085,7 @@ pub const Type = extern union {...@@ -1082,6 +1085,7 @@ pub const Type = extern union {
10821085
1083 pub fn toValue(self: Type, allocator: *Allocator) Allocator.Error!Value {1086 pub fn toValue(self: Type, allocator: *Allocator) Allocator.Error!Value {
1084 switch (self.tag()) {1087 switch (self.tag()) {
1088 .u1 => return Value.initTag(.u1_type),
1085 .u8 => return Value.initTag(.u8_type),1089 .u8 => return Value.initTag(.u8_type),
1086 .i8 => return Value.initTag(.i8_type),1090 .i8 => return Value.initTag(.i8_type),
1087 .u16 => return Value.initTag(.u16_type),1091 .u16 => return Value.initTag(.u16_type),
...@@ -1141,6 +1145,7 @@ pub const Type = extern union {...@@ -1141,6 +1145,7 @@ pub const Type = extern union {
11411145
1142 pub fn hasCodeGenBits(self: Type) bool {1146 pub fn hasCodeGenBits(self: Type) bool {
1143 return switch (self.tag()) {1147 return switch (self.tag()) {
1148 .u1,
1144 .u8,1149 .u8,
1145 .i8,1150 .i8,
1146 .u16,1151 .u16,
...@@ -1321,6 +1326,7 @@ pub const Type = extern union {...@@ -1321,6 +1326,7 @@ pub const Type = extern union {
1321 /// Asserts that hasCodeGenBits() is true.1326 /// Asserts that hasCodeGenBits() is true.
1322 pub fn abiAlignment(self: Type, target: Target) u32 {1327 pub fn abiAlignment(self: Type, target: Target) u32 {
1323 return switch (self.tag()) {1328 return switch (self.tag()) {
1329 .u1,
1324 .u8,1330 .u8,
1325 .i8,1331 .i8,
1326 .bool,1332 .bool,
...@@ -1539,6 +1545,7 @@ pub const Type = extern union {...@@ -1539,6 +1545,7 @@ pub const Type = extern union {
1539 @panic("TODO abiSize unions");1545 @panic("TODO abiSize unions");
1540 },1546 },
15411547
1548 .u1,
1542 .u8,1549 .u8,
1543 .i8,1550 .i8,
1544 .bool,1551 .bool,
...@@ -1704,7 +1711,7 @@ pub const Type = extern union {...@@ -1704,7 +1711,7 @@ pub const Type = extern union {
17041711
1705 .u8, .i8 => 8,1712 .u8, .i8 => 8,
17061713
1707 .bool => 1,1714 .bool, .u1 => 1,
17081715
1709 .vector => {1716 .vector => {
1710 const payload = self.castTag(.vector).?.data;1717 const payload = self.castTag(.vector).?.data;
...@@ -2217,12 +2224,13 @@ pub const Type = extern union {...@@ -2217,12 +2224,13 @@ pub const Type = extern union {
2217 pub fn isUnsignedInt(self: Type) bool {2224 pub fn isUnsignedInt(self: Type) bool {
2218 return switch (self.tag()) {2225 return switch (self.tag()) {
2219 .int_unsigned,2226 .int_unsigned,
2220 .u8,
2221 .usize,2227 .usize,
2222 .c_ushort,2228 .c_ushort,
2223 .c_uint,2229 .c_uint,
2224 .c_ulong,2230 .c_ulong,
2225 .c_ulonglong,2231 .c_ulonglong,
2232 .u1,
2233 .u8,
2226 .u16,2234 .u16,
2227 .u32,2235 .u32,
2228 .u64,2236 .u64,
...@@ -2244,6 +2252,7 @@ pub const Type = extern union {...@@ -2244,6 +2252,7 @@ pub const Type = extern union {
2244 .signedness = .signed,2252 .signedness = .signed,
2245 .bits = self.castTag(.int_signed).?.data,2253 .bits = self.castTag(.int_signed).?.data,
2246 },2254 },
2255 .u1 => .{ .signedness = .unsigned, .bits = 1 },
2247 .u8 => .{ .signedness = .unsigned, .bits = 8 },2256 .u8 => .{ .signedness = .unsigned, .bits = 8 },
2248 .i8 => .{ .signedness = .signed, .bits = 8 },2257 .i8 => .{ .signedness = .signed, .bits = 8 },
2249 .u16 => .{ .signedness = .unsigned, .bits = 16 },2258 .u16 => .{ .signedness = .unsigned, .bits = 16 },
...@@ -2406,6 +2415,7 @@ pub const Type = extern union {...@@ -2406,6 +2415,7 @@ pub const Type = extern union {
2406 .c_longdouble,2415 .c_longdouble,
2407 .comptime_int,2416 .comptime_int,
2408 .comptime_float,2417 .comptime_float,
2418 .u1,
2409 .u8,2419 .u8,
2410 .i8,2420 .i8,
2411 .u16,2421 .u16,
...@@ -2446,6 +2456,7 @@ pub const Type = extern union {...@@ -2446,6 +2456,7 @@ pub const Type = extern union {
2446 .c_longdouble,2456 .c_longdouble,
2447 .comptime_int,2457 .comptime_int,
2448 .comptime_float,2458 .comptime_float,
2459 .u1,
2449 .u8,2460 .u8,
2450 .i8,2461 .i8,
2451 .u16,2462 .u16,
...@@ -2911,6 +2922,7 @@ pub const Type = extern union {...@@ -2911,6 +2922,7 @@ pub const Type = extern union {
2911 /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`.2922 /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`.
2912 pub const Tag = enum {2923 pub const Tag = enum {
2913 // The first section of this enum are tags that require no payload.2924 // The first section of this enum are tags that require no payload.
2925 u1,
2914 u8,2926 u8,
2915 i8,2927 i8,
2916 u16,2928 u16,
...@@ -3018,6 +3030,7 @@ pub const Type = extern union {...@@ -3018,6 +3030,7 @@ pub const Type = extern union {
30183030
3019 pub fn Type(comptime t: Tag) type {3031 pub fn Type(comptime t: Tag) type {
3020 return switch (t) {3032 return switch (t) {
3033 .u1,
3021 .u8,3034 .u8,
3022 .i8,3035 .i8,
3023 .u16,3036 .u16,
src/value.zig+7
...@@ -22,6 +22,7 @@ pub const Value = extern union {...@@ -22,6 +22,7 @@ pub const Value = extern union {
2222
23 pub const Tag = enum {23 pub const Tag = enum {
24 // The first section of this enum are tags that require no payload.24 // The first section of this enum are tags that require no payload.
25 u1_type,
25 u8_type,26 u8_type,
26 i8_type,27 i8_type,
27 u16_type,28 u16_type,
...@@ -138,6 +139,7 @@ pub const Value = extern union {...@@ -138,6 +139,7 @@ pub const Value = extern union {
138139
139 pub fn Type(comptime t: Tag) type {140 pub fn Type(comptime t: Tag) type {
140 return switch (t) {141 return switch (t) {
142 .u1_type,
141 .u8_type,143 .u8_type,
142 .i8_type,144 .i8_type,
143 .u16_type,145 .u16_type,
...@@ -314,6 +316,7 @@ pub const Value = extern union {...@@ -314,6 +316,7 @@ pub const Value = extern union {
314 if (self.tag_if_small_enough < Tag.no_payload_count) {316 if (self.tag_if_small_enough < Tag.no_payload_count) {
315 return Value{ .tag_if_small_enough = self.tag_if_small_enough };317 return Value{ .tag_if_small_enough = self.tag_if_small_enough };
316 } else switch (self.ptr_otherwise.tag) {318 } else switch (self.ptr_otherwise.tag) {
319 .u1_type,
317 .u8_type,320 .u8_type,
318 .i8_type,321 .i8_type,
319 .u16_type,322 .u16_type,
...@@ -520,6 +523,7 @@ pub const Value = extern union {...@@ -520,6 +523,7 @@ pub const Value = extern union {
520 comptime assert(fmt.len == 0);523 comptime assert(fmt.len == 0);
521 var val = start_val;524 var val = start_val;
522 while (true) switch (val.tag()) {525 while (true) switch (val.tag()) {
526 .u1_type => return out_stream.writeAll("u1"),
523 .u8_type => return out_stream.writeAll("u8"),527 .u8_type => return out_stream.writeAll("u8"),
524 .i8_type => return out_stream.writeAll("i8"),528 .i8_type => return out_stream.writeAll("i8"),
525 .u16_type => return out_stream.writeAll("u16"),529 .u16_type => return out_stream.writeAll("u16"),
...@@ -671,6 +675,7 @@ pub const Value = extern union {...@@ -671,6 +675,7 @@ pub const Value = extern union {
671 pub fn toType(self: Value, allocator: *Allocator) !Type {675 pub fn toType(self: Value, allocator: *Allocator) !Type {
672 return switch (self.tag()) {676 return switch (self.tag()) {
673 .ty => self.castTag(.ty).?.data,677 .ty => self.castTag(.ty).?.data,
678 .u1_type => Type.initTag(.u1),
674 .u8_type => Type.initTag(.u8),679 .u8_type => Type.initTag(.u8),
675 .i8_type => Type.initTag(.i8),680 .i8_type => Type.initTag(.i8),
676 .u16_type => Type.initTag(.u16),681 .u16_type => Type.initTag(.u16),
...@@ -1150,6 +1155,7 @@ pub const Value = extern union {...@@ -1150,6 +1155,7 @@ pub const Value = extern union {
1150 var hasher = std.hash.Wyhash.init(0);1155 var hasher = std.hash.Wyhash.init(0);
11511156
1152 switch (self.tag()) {1157 switch (self.tag()) {
1158 .u1_type,
1153 .u8_type,1159 .u8_type,
1154 .i8_type,1160 .i8_type,
1155 .u16_type,1161 .u16_type,
...@@ -1502,6 +1508,7 @@ pub const Value = extern union {...@@ -1502,6 +1508,7 @@ pub const Value = extern union {
1502 return switch (self.tag()) {1508 return switch (self.tag()) {
1503 .ty,1509 .ty,
1504 .int_type,1510 .int_type,
1511 .u1_type,
1505 .u8_type,1512 .u8_type,
1506 .i8_type,1513 .i8_type,
1507 .u16_type,1514 .u16_type,
test/behavior.zig+2-5
...@@ -2,11 +2,9 @@ const builtin = @import("builtin");...@@ -2,11 +2,9 @@ const builtin = @import("builtin");
22
3test {3test {
4 // Tests that pass for both.4 // Tests that pass for both.
5 {}5 _ = @import("behavior/bool.zig");
66
7 if (builtin.zig_is_stage2) {7 if (!builtin.zig_is_stage2) {
8 // Tests that only pass for stage2.
9 } else {
10 // Tests that only pass for stage1.8 // Tests that only pass for stage1.
11 _ = @import("behavior/align.zig");9 _ = @import("behavior/align.zig");
12 _ = @import("behavior/alignof.zig");10 _ = @import("behavior/alignof.zig");
...@@ -20,7 +18,6 @@ test {...@@ -20,7 +18,6 @@ test {
20 _ = @import("behavior/bit_shifting.zig");18 _ = @import("behavior/bit_shifting.zig");
21 _ = @import("behavior/bitcast.zig");19 _ = @import("behavior/bitcast.zig");
22 _ = @import("behavior/bitreverse.zig");20 _ = @import("behavior/bitreverse.zig");
23 _ = @import("behavior/bool.zig");
24 _ = @import("behavior/bugs/1025.zig");21 _ = @import("behavior/bugs/1025.zig");
25 _ = @import("behavior/bugs/1076.zig");22 _ = @import("behavior/bugs/1076.zig");
26 _ = @import("behavior/bugs/1111.zig");23 _ = @import("behavior/bugs/1111.zig");