From 5e60872060da894c38343f2afc1ddc45bce14fc6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 8 Jul 2020 06:56:20 +0000 Subject: [PATCH] stage2 misc fixes --- src-self-hosted/Module.zig | 13 ++++++++++--- src-self-hosted/codegen.zig | 33 +++++++++++++++++++++++---------- src-self-hosted/zir.zig | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index d40afebb64..0bd917b2b1 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -867,8 +867,10 @@ pub fn update(self: *Module) !void { try self.deleteDecl(decl); } - // This is needed before reading the error flags. - try self.bin_file.flush(); + if (self.totalErrorCount() == 0) { + // This is needed before reading the error flags. + try self.bin_file.flush(); + } self.link_error_flags = self.bin_file.error_flags; std.log.debug(.module, "link_error_flags: {}\n", .{self.link_error_flags}); @@ -2388,6 +2390,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int; return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int); }, + .inttype => return self.analyzeInstIntType(scope, old_inst.cast(zir.Inst.IntType).?), .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.cast(zir.Inst.PtrToInt).?), .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.cast(zir.Inst.FieldPtr).?), .deref => return self.analyzeInstDeref(scope, old_inst.cast(zir.Inst.Deref).?), @@ -2737,6 +2740,10 @@ fn analyzeInstFn(self: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError }); } +fn analyzeInstIntType(self: *Module, scope: *Scope, inttype: *zir.Inst.IntType) InnerError!*Inst { + return self.fail(scope, inttype.base.src, "TODO implement inttype", .{}); +} + fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst { const return_type = try self.resolveType(scope, fntype.positionals.return_type); @@ -3333,7 +3340,7 @@ fn cmpNumeric( break :blk try self.makeIntType(scope, dest_int_is_signed, casted_bits); }; const casted_lhs = try self.coerce(scope, dest_type, lhs); - const casted_rhs = try self.coerce(scope, dest_type, lhs); + const casted_rhs = try self.coerce(scope, dest_type, rhs); return self.addNewInstArgs(b, src, Type.initTag(.bool), Inst.Cmp, .{ .lhs = casted_lhs, diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index b3fa94f088..232703b697 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -698,18 +698,34 @@ const Function = struct { .lte => 0x8f, .eq => 0x85, }; - self.code.appendSliceAssumeCapacity(&[_]u8{0x0f, opcode}); - const reloc = Reloc{ .rel32 = self.code.items.len }; - self.code.items.len += 4; - try self.genBody(inst.args.true_body, arch); - try self.performReloc(inst.base.src, reloc); - try self.genBody(inst.args.false_body, arch); + return self.genX86CondBr(inst, opcode, arch); + }, + .compare_flags_unsigned => |cmp_op| { + // Here we map to the opposite opcode because the jump is to the false branch. + const opcode: u8 = switch (cmp_op) { + .gte => 0x82, + .gt => 0x86, + .neq => 0x84, + .lt => 0x83, + .lte => 0x87, + .eq => 0x85, + }; + return self.genX86CondBr(inst, opcode, arch); }, else => return self.fail(inst.base.src, "TODO implement condbr {} when condition not already in the compare flags", .{self.target.cpu.arch}), } }, else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.target.cpu.arch}), } + } + + fn genX86CondBr(self: *Function, inst: *ir.Inst.CondBr, opcode: u8, comptime arch: std.Target.Cpu.Arch) !MCValue { + self.code.appendSliceAssumeCapacity(&[_]u8{0x0f, opcode}); + const reloc = Reloc{ .rel32 = self.code.items.len }; + self.code.items.len += 4; + try self.genBody(inst.args.true_body, arch); + try self.performReloc(inst.base.src, reloc); + try self.genBody(inst.args.false_body, arch); return MCValue.unreach; } @@ -1028,10 +1044,7 @@ const Function = struct { const branch = &self.branch_stack.items[0]; const gop = try branch.inst_table.getOrPut(self.gpa, inst); if (!gop.found_existing) { - const mcv = try self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val }); - try branch.inst_table.putNoClobber(self.gpa, inst, mcv); - gop.entry.value = mcv; - return mcv; + gop.entry.value = try self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val }); } return gop.entry.value; } diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 697c7673ac..ab48bf535f 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -57,6 +57,7 @@ pub const Inst = struct { /// String Literal. Makes an anonymous Decl and then takes a pointer to it. str, int, + inttype, ptrtoint, fieldptr, deref, @@ -95,6 +96,7 @@ pub const Inst = struct { .@"const" => Const, .str => Str, .int => Int, + .inttype => IntType, .ptrtoint => PtrToInt, .fieldptr => FieldPtr, .deref => Deref, @@ -369,6 +371,17 @@ pub const Inst = struct { }, }; + pub const IntType = struct { + pub const base_tag = Tag.inttype; + base: Inst, + + positionals: struct { + signed: *Inst, + bits: *Inst, + }, + kw_args: struct {}, + }; + pub const Export = struct { pub const base_tag = Tag.@"export"; base: Inst, @@ -675,6 +688,7 @@ pub const Module = struct { .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst, inst_table, indent), .str => return self.writeInstToStreamGeneric(stream, .str, inst, inst_table, indent), .int => return self.writeInstToStreamGeneric(stream, .int, inst, inst_table, indent), + .inttype => return self.writeInstToStreamGeneric(stream, .inttype, inst, inst_table, indent), .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, inst, inst_table, indent), .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, inst, inst_table, indent), .deref => return self.writeInstToStreamGeneric(stream, .deref, inst, inst_table, indent), @@ -1886,6 +1900,26 @@ const EmitZIR = struct { }; return self.emitUnnamedDecl(&fntype_inst.base); }, + .Int => { + const info = ty.intInfo(self.old_module.target()); + const signed = try self.emitPrimitive(src, if (info.signed) .@"true" else .@"false"); + const bits_payload = try self.arena.allocator.create(Value.Payload.Int_u64); + bits_payload.* = .{ .int = info.bits }; + const bits = try self.emitComptimeIntVal(src, Value.initPayload(&bits_payload.base)); + const inttype_inst = try self.arena.allocator.create(Inst.IntType); + inttype_inst.* = .{ + .base = .{ + .src = src, + .tag = Inst.IntType.base_tag, + }, + .positionals = .{ + .signed = signed.inst, + .bits = bits.inst, + }, + .kw_args = .{}, + }; + return self.emitUnnamedDecl(&inttype_inst.base); + }, else => std.debug.panic("TODO implement emitType for {}", .{ty}), }, }