| author | |
| committer | |
| log | dc036f5b6fde67c4a74701c75c5947a956abaec1 |
| tree | 149d62133f77763a194685b5793f764619707df7 |
| parent | 5769ed2d4428305e4478cf4e425f5df2469a7ffd |
5 files changed, 52 insertions(+), 16 deletions(-)
BRANCH_TODO-2| ... | ... | @@ -1,7 +1,5 @@ |
| 1 | 1 | * get stage2 tests passing |
| 2 | 2 | - spu-ii test is saying "unimplemented" for some reason |
| 3 | - compile log test has wrong source loc | |
| 4 | - extern variable has no type: TODO implement generateSymbol for int type 'i32' | |
| 5 | 3 | * modify stage2 tests so that only 1 uses _start and the rest use |
| 6 | 4 | pub fn main |
| 7 | 5 | * modify stage2 CBE tests so that only 1 uses pub export main and the |
src/codegen.zig+41-11| ... | ... | @@ -212,20 +212,50 @@ pub fn generateSymbol( |
| 212 | 212 | }, |
| 213 | 213 | .Int => { |
| 214 | 214 | // TODO populate .debug_info for the integer |
| 215 | const endian = bin_file.options.target.cpu.arch.endian(); | |
| 215 | 216 | const info = typed_value.ty.intInfo(bin_file.options.target); |
| 216 | if (info.bits == 8 and info.signedness == .unsigned) { | |
| 217 | const x = typed_value.val.toUnsignedInt(); | |
| 218 | try code.append(@intCast(u8, x)); | |
| 217 | if (info.bits <= 8) { | |
| 218 | const x = @intCast(u8, typed_value.val.toUnsignedInt()); | |
| 219 | try code.append(x); | |
| 219 | 220 | return Result{ .appended = {} }; |
| 220 | 221 | } |
| 221 | return Result{ | |
| 222 | .fail = try ErrorMsg.create( | |
| 223 | bin_file.allocator, | |
| 224 | src_loc, | |
| 225 | "TODO implement generateSymbol for int type '{}'", | |
| 226 | .{typed_value.ty}, | |
| 227 | ), | |
| 228 | }; | |
| 222 | if (info.bits > 64) { | |
| 223 | return Result{ | |
| 224 | .fail = try ErrorMsg.create( | |
| 225 | bin_file.allocator, | |
| 226 | src_loc, | |
| 227 | "TODO implement generateSymbol for big ints ('{}')", | |
| 228 | .{typed_value.ty}, | |
| 229 | ), | |
| 230 | }; | |
| 231 | } | |
| 232 | switch (info.signedness) { | |
| 233 | .unsigned => { | |
| 234 | if (info.bits <= 16) { | |
| 235 | const x = @intCast(u16, typed_value.val.toUnsignedInt()); | |
| 236 | mem.writeInt(u16, try code.addManyAsArray(2), x, endian); | |
| 237 | } else if (info.bits <= 32) { | |
| 238 | const x = @intCast(u32, typed_value.val.toUnsignedInt()); | |
| 239 | mem.writeInt(u32, try code.addManyAsArray(4), x, endian); | |
| 240 | } else { | |
| 241 | const x = typed_value.val.toUnsignedInt(); | |
| 242 | mem.writeInt(u64, try code.addManyAsArray(8), x, endian); | |
| 243 | } | |
| 244 | }, | |
| 245 | .signed => { | |
| 246 | if (info.bits <= 16) { | |
| 247 | const x = @intCast(i16, typed_value.val.toSignedInt()); | |
| 248 | mem.writeInt(i16, try code.addManyAsArray(2), x, endian); | |
| 249 | } else if (info.bits <= 32) { | |
| 250 | const x = @intCast(i32, typed_value.val.toSignedInt()); | |
| 251 | mem.writeInt(i32, try code.addManyAsArray(4), x, endian); | |
| 252 | } else { | |
| 253 | const x = typed_value.val.toSignedInt(); | |
| 254 | mem.writeInt(i64, try code.addManyAsArray(8), x, endian); | |
| 255 | } | |
| 256 | }, | |
| 257 | } | |
| 258 | return Result{ .appended = {} }; | |
| 229 | 259 | }, |
| 230 | 260 | else => |t| { |
| 231 | 261 | return Result{ |
src/codegen/x86_64.zig+1-1| ... | ... | @@ -171,7 +171,7 @@ pub const Encoder = struct { |
| 171 | 171 | /// This is because the helper functions will assume capacity |
| 172 | 172 | /// in order to avoid bounds checking. |
| 173 | 173 | pub fn init(code: *ArrayList(u8), maximum_inst_size: u8) !Self { |
| 174 | try code.ensureCapacity(code.items.len + maximum_inst_size); | |
| 174 | try code.ensureUnusedCapacity(maximum_inst_size); | |
| 175 | 175 | return Self{ .code = code }; |
| 176 | 176 | } |
| 177 | 177 |
src/link/Elf.zig+8-1| ... | ... | @@ -2196,6 +2196,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2196 | 2196 | if (decl.val.tag() == .extern_fn) { |
| 2197 | 2197 | return; // TODO Should we do more when front-end analyzed extern decl? |
| 2198 | 2198 | } |
| 2199 | if (decl.val.castTag(.variable)) |payload| { | |
| 2200 | const variable = payload.data; | |
| 2201 | if (variable.is_extern) { | |
| 2202 | return; // TODO Should we do more when front-end analyzed extern decl? | |
| 2203 | } | |
| 2204 | } | |
| 2199 | 2205 | |
| 2200 | 2206 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 2201 | 2207 | defer code_buffer.deinit(); |
| ... | ... | @@ -2287,9 +2293,10 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2287 | 2293 | } else { |
| 2288 | 2294 | // TODO implement .debug_info for global variables |
| 2289 | 2295 | } |
| 2296 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; | |
| 2290 | 2297 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ |
| 2291 | 2298 | .ty = decl.ty, |
| 2292 | .val = decl.val, | |
| 2299 | .val = decl_val, | |
| 2293 | 2300 | }, &code_buffer, .{ |
| 2294 | 2301 | .dwarf = .{ |
| 2295 | 2302 | .dbg_line = &dbg_line_buffer, |
test/stage2/test.zig+2-1| ... | ... | @@ -1293,9 +1293,10 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1293 | 1293 | \\ _ = foo; |
| 1294 | 1294 | \\} |
| 1295 | 1295 | \\extern var foo: i32; |
| 1296 | \\pub export fn _start() void {} | |
| 1296 | 1297 | , &[_][]const u8{":2:9: error: unable to resolve comptime value"}); |
| 1297 | 1298 | case.addError( |
| 1298 | \\export fn entry() void { | |
| 1299 | \\pub export fn _start() void { | |
| 1299 | 1300 | \\ _ = foo; |
| 1300 | 1301 | \\} |
| 1301 | 1302 | \\extern var foo; |