| author | |
| committer | |
| log | 5e60872060da894c38343f2afc1ddc45bce14fc6 |
| tree | e47e5a5e1578b1a926f2f8c19c4e803bf0c5a7e1 |
| parent | 88496041312023948cfd34f6e96acc5d27ee4cf6 |
3 files changed, 67 insertions(+), 13 deletions(-)
src-self-hosted/Module.zig+10-3| ... | ... | @@ -867,8 +867,10 @@ pub fn update(self: *Module) !void { |
| 867 | 867 | try self.deleteDecl(decl); |
| 868 | 868 | } |
| 869 | 869 | |
| 870 | // This is needed before reading the error flags. | |
| 871 | try self.bin_file.flush(); | |
| 870 | if (self.totalErrorCount() == 0) { | |
| 871 | // This is needed before reading the error flags. | |
| 872 | try self.bin_file.flush(); | |
| 873 | } | |
| 872 | 874 | |
| 873 | 875 | self.link_error_flags = self.bin_file.error_flags; |
| 874 | 876 | 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 |
| 2388 | 2390 | const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int; |
| 2389 | 2391 | return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int); |
| 2390 | 2392 | }, |
| 2393 | .inttype => return self.analyzeInstIntType(scope, old_inst.cast(zir.Inst.IntType).?), | |
| 2391 | 2394 | .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.cast(zir.Inst.PtrToInt).?), |
| 2392 | 2395 | .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.cast(zir.Inst.FieldPtr).?), |
| 2393 | 2396 | .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 |
| 2737 | 2740 | }); |
| 2738 | 2741 | } |
| 2739 | 2742 | |
| 2743 | fn analyzeInstIntType(self: *Module, scope: *Scope, inttype: *zir.Inst.IntType) InnerError!*Inst { | |
| 2744 | return self.fail(scope, inttype.base.src, "TODO implement inttype", .{}); | |
| 2745 | } | |
| 2746 | ||
| 2740 | 2747 | fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst { |
| 2741 | 2748 | const return_type = try self.resolveType(scope, fntype.positionals.return_type); |
| 2742 | 2749 | |
| ... | ... | @@ -3333,7 +3340,7 @@ fn cmpNumeric( |
| 3333 | 3340 | break :blk try self.makeIntType(scope, dest_int_is_signed, casted_bits); |
| 3334 | 3341 | }; |
| 3335 | 3342 | const casted_lhs = try self.coerce(scope, dest_type, lhs); |
| 3336 | const casted_rhs = try self.coerce(scope, dest_type, lhs); | |
| 3343 | const casted_rhs = try self.coerce(scope, dest_type, rhs); | |
| 3337 | 3344 | |
| 3338 | 3345 | return self.addNewInstArgs(b, src, Type.initTag(.bool), Inst.Cmp, .{ |
| 3339 | 3346 | .lhs = casted_lhs, |
src-self-hosted/codegen.zig+23-10| ... | ... | @@ -698,18 +698,34 @@ const Function = struct { |
| 698 | 698 | .lte => 0x8f, |
| 699 | 699 | .eq => 0x85, |
| 700 | 700 | }; |
| 701 | self.code.appendSliceAssumeCapacity(&[_]u8{0x0f, opcode}); | |
| 702 | const reloc = Reloc{ .rel32 = self.code.items.len }; | |
| 703 | self.code.items.len += 4; | |
| 704 | try self.genBody(inst.args.true_body, arch); | |
| 705 | try self.performReloc(inst.base.src, reloc); | |
| 706 | try self.genBody(inst.args.false_body, arch); | |
| 701 | return self.genX86CondBr(inst, opcode, arch); | |
| 702 | }, | |
| 703 | .compare_flags_unsigned => |cmp_op| { | |
| 704 | // Here we map to the opposite opcode because the jump is to the false branch. | |
| 705 | const opcode: u8 = switch (cmp_op) { | |
| 706 | .gte => 0x82, | |
| 707 | .gt => 0x86, | |
| 708 | .neq => 0x84, | |
| 709 | .lt => 0x83, | |
| 710 | .lte => 0x87, | |
| 711 | .eq => 0x85, | |
| 712 | }; | |
| 713 | return self.genX86CondBr(inst, opcode, arch); | |
| 707 | 714 | }, |
| 708 | 715 | else => return self.fail(inst.base.src, "TODO implement condbr {} when condition not already in the compare flags", .{self.target.cpu.arch}), |
| 709 | 716 | } |
| 710 | 717 | }, |
| 711 | 718 | else => return self.fail(inst.base.src, "TODO implement condbr for {}", .{self.target.cpu.arch}), |
| 712 | 719 | } |
| 720 | } | |
| 721 | ||
| 722 | fn genX86CondBr(self: *Function, inst: *ir.Inst.CondBr, opcode: u8, comptime arch: std.Target.Cpu.Arch) !MCValue { | |
| 723 | self.code.appendSliceAssumeCapacity(&[_]u8{0x0f, opcode}); | |
| 724 | const reloc = Reloc{ .rel32 = self.code.items.len }; | |
| 725 | self.code.items.len += 4; | |
| 726 | try self.genBody(inst.args.true_body, arch); | |
| 727 | try self.performReloc(inst.base.src, reloc); | |
| 728 | try self.genBody(inst.args.false_body, arch); | |
| 713 | 729 | return MCValue.unreach; |
| 714 | 730 | } |
| 715 | 731 | |
| ... | ... | @@ -1028,10 +1044,7 @@ const Function = struct { |
| 1028 | 1044 | const branch = &self.branch_stack.items[0]; |
| 1029 | 1045 | const gop = try branch.inst_table.getOrPut(self.gpa, inst); |
| 1030 | 1046 | if (!gop.found_existing) { |
| 1031 | const mcv = try self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val }); | |
| 1032 | try branch.inst_table.putNoClobber(self.gpa, inst, mcv); | |
| 1033 | gop.entry.value = mcv; | |
| 1034 | return mcv; | |
| 1047 | gop.entry.value = try self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val }); | |
| 1035 | 1048 | } |
| 1036 | 1049 | return gop.entry.value; |
| 1037 | 1050 | } |
src-self-hosted/zir.zig+34| ... | ... | @@ -57,6 +57,7 @@ pub const Inst = struct { |
| 57 | 57 | /// String Literal. Makes an anonymous Decl and then takes a pointer to it. |
| 58 | 58 | str, |
| 59 | 59 | int, |
| 60 | inttype, | |
| 60 | 61 | ptrtoint, |
| 61 | 62 | fieldptr, |
| 62 | 63 | deref, |
| ... | ... | @@ -95,6 +96,7 @@ pub const Inst = struct { |
| 95 | 96 | .@"const" => Const, |
| 96 | 97 | .str => Str, |
| 97 | 98 | .int => Int, |
| 99 | .inttype => IntType, | |
| 98 | 100 | .ptrtoint => PtrToInt, |
| 99 | 101 | .fieldptr => FieldPtr, |
| 100 | 102 | .deref => Deref, |
| ... | ... | @@ -369,6 +371,17 @@ pub const Inst = struct { |
| 369 | 371 | }, |
| 370 | 372 | }; |
| 371 | 373 | |
| 374 | pub const IntType = struct { | |
| 375 | pub const base_tag = Tag.inttype; | |
| 376 | base: Inst, | |
| 377 | ||
| 378 | positionals: struct { | |
| 379 | signed: *Inst, | |
| 380 | bits: *Inst, | |
| 381 | }, | |
| 382 | kw_args: struct {}, | |
| 383 | }; | |
| 384 | ||
| 372 | 385 | pub const Export = struct { |
| 373 | 386 | pub const base_tag = Tag.@"export"; |
| 374 | 387 | base: Inst, |
| ... | ... | @@ -675,6 +688,7 @@ pub const Module = struct { |
| 675 | 688 | .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst, inst_table, indent), |
| 676 | 689 | .str => return self.writeInstToStreamGeneric(stream, .str, inst, inst_table, indent), |
| 677 | 690 | .int => return self.writeInstToStreamGeneric(stream, .int, inst, inst_table, indent), |
| 691 | .inttype => return self.writeInstToStreamGeneric(stream, .inttype, inst, inst_table, indent), | |
| 678 | 692 | .ptrtoint => return self.writeInstToStreamGeneric(stream, .ptrtoint, inst, inst_table, indent), |
| 679 | 693 | .fieldptr => return self.writeInstToStreamGeneric(stream, .fieldptr, inst, inst_table, indent), |
| 680 | 694 | .deref => return self.writeInstToStreamGeneric(stream, .deref, inst, inst_table, indent), |
| ... | ... | @@ -1886,6 +1900,26 @@ const EmitZIR = struct { |
| 1886 | 1900 | }; |
| 1887 | 1901 | return self.emitUnnamedDecl(&fntype_inst.base); |
| 1888 | 1902 | }, |
| 1903 | .Int => { | |
| 1904 | const info = ty.intInfo(self.old_module.target()); | |
| 1905 | const signed = try self.emitPrimitive(src, if (info.signed) .@"true" else .@"false"); | |
| 1906 | const bits_payload = try self.arena.allocator.create(Value.Payload.Int_u64); | |
| 1907 | bits_payload.* = .{ .int = info.bits }; | |
| 1908 | const bits = try self.emitComptimeIntVal(src, Value.initPayload(&bits_payload.base)); | |
| 1909 | const inttype_inst = try self.arena.allocator.create(Inst.IntType); | |
| 1910 | inttype_inst.* = .{ | |
| 1911 | .base = .{ | |
| 1912 | .src = src, | |
| 1913 | .tag = Inst.IntType.base_tag, | |
| 1914 | }, | |
| 1915 | .positionals = .{ | |
| 1916 | .signed = signed.inst, | |
| 1917 | .bits = bits.inst, | |
| 1918 | }, | |
| 1919 | .kw_args = .{}, | |
| 1920 | }; | |
| 1921 | return self.emitUnnamedDecl(&inttype_inst.base); | |
| 1922 | }, | |
| 1889 | 1923 | else => std.debug.panic("TODO implement emitType for {}", .{ty}), |
| 1890 | 1924 | }, |
| 1891 | 1925 | } |