authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-15 21:00:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-15 21:00:15-07:00
logdc036f5b6fde67c4a74701c75c5947a956abaec1
tree149d62133f77763a194685b5793f764619707df7
parent5769ed2d4428305e4478cf4e425f5df2469a7ffd

codegen: implement const value rendering for ints <= 64 bits


5 files changed, 52 insertions(+), 16 deletions(-)

BRANCH_TODO-2
...@@ -1,7 +1,5 @@...@@ -1,7 +1,5 @@
1 * get stage2 tests passing1 * get stage2 tests passing
2 - spu-ii test is saying "unimplemented" for some reason2 - 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 * modify stage2 tests so that only 1 uses _start and the rest use3 * modify stage2 tests so that only 1 uses _start and the rest use
6 pub fn main4 pub fn main
7 * modify stage2 CBE tests so that only 1 uses pub export main and the5 * 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,20 +212,50 @@ pub fn generateSymbol(
212 },212 },
213 .Int => {213 .Int => {
214 // TODO populate .debug_info for the integer214 // TODO populate .debug_info for the integer
215 const endian = bin_file.options.target.cpu.arch.endian();
215 const info = typed_value.ty.intInfo(bin_file.options.target);216 const info = typed_value.ty.intInfo(bin_file.options.target);
216 if (info.bits == 8 and info.signedness == .unsigned) {217 if (info.bits <= 8) {
217 const x = typed_value.val.toUnsignedInt();218 const x = @intCast(u8, typed_value.val.toUnsignedInt());
218 try code.append(@intCast(u8, x));219 try code.append(x);
219 return Result{ .appended = {} };220 return Result{ .appended = {} };
220 }221 }
221 return Result{222 if (info.bits > 64) {
222 .fail = try ErrorMsg.create(223 return Result{
223 bin_file.allocator,224 .fail = try ErrorMsg.create(
224 src_loc,225 bin_file.allocator,
225 "TODO implement generateSymbol for int type '{}'",226 src_loc,
226 .{typed_value.ty},227 "TODO implement generateSymbol for big ints ('{}')",
227 ),228 .{typed_value.ty},
228 };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 else => |t| {260 else => |t| {
231 return Result{261 return Result{
src/codegen/x86_64.zig+1-1
...@@ -171,7 +171,7 @@ pub const Encoder = struct {...@@ -171,7 +171,7 @@ pub const Encoder = struct {
171 /// This is because the helper functions will assume capacity171 /// This is because the helper functions will assume capacity
172 /// in order to avoid bounds checking.172 /// in order to avoid bounds checking.
173 pub fn init(code: *ArrayList(u8), maximum_inst_size: u8) !Self {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 return Self{ .code = code };175 return Self{ .code = code };
176 }176 }
177177
src/link/Elf.zig+8-1
...@@ -2196,6 +2196,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2196,6 +2196,12 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2196 if (decl.val.tag() == .extern_fn) {2196 if (decl.val.tag() == .extern_fn) {
2197 return; // TODO Should we do more when front-end analyzed extern decl?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 }
21992205
2200 var code_buffer = std.ArrayList(u8).init(self.base.allocator);2206 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2201 defer code_buffer.deinit();2207 defer code_buffer.deinit();
...@@ -2287,9 +2293,10 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2287,9 +2293,10 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2287 } else {2293 } else {
2288 // TODO implement .debug_info for global variables2294 // 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 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{2297 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
2291 .ty = decl.ty,2298 .ty = decl.ty,
2292 .val = decl.val,2299 .val = decl_val,
2293 }, &code_buffer, .{2300 }, &code_buffer, .{
2294 .dwarf = .{2301 .dwarf = .{
2295 .dbg_line = &dbg_line_buffer,2302 .dbg_line = &dbg_line_buffer,
test/stage2/test.zig+2-1
...@@ -1293,9 +1293,10 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1293,9 +1293,10 @@ pub fn addCases(ctx: *TestContext) !void {
1293 \\ _ = foo;1293 \\ _ = foo;
1294 \\}1294 \\}
1295 \\extern var foo: i32;1295 \\extern var foo: i32;
1296 \\pub export fn _start() void {}
1296 , &[_][]const u8{":2:9: error: unable to resolve comptime value"});1297 , &[_][]const u8{":2:9: error: unable to resolve comptime value"});
1297 case.addError(1298 case.addError(
1298 \\export fn entry() void {1299 \\pub export fn _start() void {
1299 \\ _ = foo;1300 \\ _ = foo;
1300 \\}1301 \\}
1301 \\extern var foo;1302 \\extern var foo;