Commit dc036f5b6f
Changed files (5)
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 };
}
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,
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{
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;
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