diff --git a/BRANCH_TODO b/BRANCH_TODO index 3d91b80d8e..fcd3ecbec6 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -1,7 +1,5 @@ * get stage2 tests passing - spu-ii test is saying "unimplemented" for some reason - - compile log test has wrong source loc - - extern variable has no type: TODO implement generateSymbol for int type 'i32' * modify stage2 tests so that only 1 uses _start and the rest use pub fn main * modify stage2 CBE tests so that only 1 uses pub export main and the diff --git a/src/codegen.zig b/src/codegen.zig index 9d533db39a..6e37692093 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -212,20 +212,50 @@ pub fn generateSymbol( }, .Int => { // TODO populate .debug_info for the integer + const endian = bin_file.options.target.cpu.arch.endian(); const info = typed_value.ty.intInfo(bin_file.options.target); - if (info.bits == 8 and info.signedness == .unsigned) { - const x = typed_value.val.toUnsignedInt(); - try code.append(@intCast(u8, x)); + if (info.bits <= 8) { + const x = @intCast(u8, typed_value.val.toUnsignedInt()); + try code.append(x); return Result{ .appended = {} }; } - return Result{ - .fail = try ErrorMsg.create( - bin_file.allocator, - src_loc, - "TODO implement generateSymbol for int type '{}'", - .{typed_value.ty}, - ), - }; + if (info.bits > 64) { + return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for big ints ('{}')", + .{typed_value.ty}, + ), + }; + } + switch (info.signedness) { + .unsigned => { + if (info.bits <= 16) { + const x = @intCast(u16, typed_value.val.toUnsignedInt()); + mem.writeInt(u16, try code.addManyAsArray(2), x, endian); + } else if (info.bits <= 32) { + const x = @intCast(u32, typed_value.val.toUnsignedInt()); + mem.writeInt(u32, try code.addManyAsArray(4), x, endian); + } else { + const x = typed_value.val.toUnsignedInt(); + mem.writeInt(u64, try code.addManyAsArray(8), x, endian); + } + }, + .signed => { + if (info.bits <= 16) { + const x = @intCast(i16, typed_value.val.toSignedInt()); + mem.writeInt(i16, try code.addManyAsArray(2), x, endian); + } else if (info.bits <= 32) { + const x = @intCast(i32, typed_value.val.toSignedInt()); + mem.writeInt(i32, try code.addManyAsArray(4), x, endian); + } else { + const x = typed_value.val.toSignedInt(); + mem.writeInt(i64, try code.addManyAsArray(8), x, endian); + } + }, + } + return Result{ .appended = {} }; }, else => |t| { return Result{ diff --git a/src/codegen/x86_64.zig b/src/codegen/x86_64.zig index 5a09f48e17..0e1ffefe75 100644 --- a/src/codegen/x86_64.zig +++ b/src/codegen/x86_64.zig @@ -171,7 +171,7 @@ pub const Encoder = struct { /// This is because the helper functions will assume capacity /// in order to avoid bounds checking. pub fn init(code: *ArrayList(u8), maximum_inst_size: u8) !Self { - try code.ensureCapacity(code.items.len + maximum_inst_size); + try code.ensureUnusedCapacity(maximum_inst_size); return Self{ .code = code }; } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 83b35cf12c..e88bb036f2 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2196,6 +2196,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { if (decl.val.tag() == .extern_fn) { return; // TODO Should we do more when front-end analyzed extern decl? } + if (decl.val.castTag(.variable)) |payload| { + const variable = payload.data; + if (variable.is_extern) { + return; // TODO Should we do more when front-end analyzed extern decl? + } + } var code_buffer = std.ArrayList(u8).init(self.base.allocator); defer code_buffer.deinit(); @@ -2287,9 +2293,10 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { } else { // TODO implement .debug_info for global variables } + const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ .ty = decl.ty, - .val = decl.val, + .val = decl_val, }, &code_buffer, .{ .dwarf = .{ .dbg_line = &dbg_line_buffer, diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 213b8d0ced..56fe2b026f 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -1293,9 +1293,10 @@ pub fn addCases(ctx: *TestContext) !void { \\ _ = foo; \\} \\extern var foo: i32; + \\pub export fn _start() void {} , &[_][]const u8{":2:9: error: unable to resolve comptime value"}); case.addError( - \\export fn entry() void { + \\pub export fn _start() void { \\ _ = foo; \\} \\extern var foo;