authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-21 17:54:00-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-21 17:54:00-04:00
log0746028a2a6caf28e396f042be0b23c8d6fb7a5e
tree088ed6296d5a96c44ca92d76dbc1d82a9386b1fd
parent69878207e7b49efca2cf9d7eaef6a345b741946f

ir: analyze int instruction


2 files changed, 60 insertions(+), 1 deletions(-)

src-self-hosted/ir.zig+51-1
...@@ -5,6 +5,7 @@ const Value = @import("value.zig").Value;...@@ -5,6 +5,7 @@ const Value = @import("value.zig").Value;
5const Type = @import("type.zig").Type;5const Type = @import("type.zig").Type;
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const text = @import("ir/text.zig");7const text = @import("ir/text.zig");
8const BigInt = std.math.big.Int;
89
9/// These are in-memory, analyzed instructions. See `text.Inst` for the representation10/// These are in-memory, analyzed instructions. See `text.Inst` for the representation
10/// of instructions that correspond to the ZIR text format.11/// of instructions that correspond to the ZIR text format.
...@@ -267,6 +268,52 @@ const Analyze = struct {...@@ -267,6 +268,52 @@ const Analyze = struct {
267 });268 });
268 }269 }
269270
271 fn constIntUnsigned(self: *Analyze, src: usize, ty: Type, int: u64) !*Inst {
272 const int_payload = try self.arena.allocator.create(Value.Payload.Int_u64);
273 int_payload.* = .{ .int = int };
274
275 return self.constInst(src, .{
276 .ty = ty,
277 .val = Value.initPayload(&int_payload.base),
278 });
279 }
280
281 fn constIntSigned(self: *Analyze, src: usize, ty: Type, int: i64) !*Inst {
282 const int_payload = try self.arena.allocator.create(Value.Payload.Int_i64);
283 int_payload.* = .{ .int = int };
284
285 return self.constInst(src, .{
286 .ty = ty,
287 .val = Value.initPayload(&int_payload.base),
288 });
289 }
290
291 fn constIntBig(self: *Analyze, src: usize, ty: Type, big_int: BigInt) !*Inst {
292 if (big_int.isPositive()) {
293 if (big_int.to(u64)) |x| {
294 return self.constIntUnsigned(src, ty, x);
295 } else |err| switch (err) {
296 error.NegativeIntoUnsigned => unreachable,
297 error.TargetTooSmall => {}, // handled below
298 }
299 } else {
300 if (big_int.to(i64)) |x| {
301 return self.constIntSigned(src, ty, x);
302 } else |err| switch (err) {
303 error.NegativeIntoUnsigned => unreachable,
304 error.TargetTooSmall => {}, // handled below
305 }
306 }
307
308 const big_int_payload = try self.arena.allocator.create(Value.Payload.IntBig);
309 big_int_payload.* = .{ .big_int = big_int };
310
311 return self.constInst(src, .{
312 .ty = ty,
313 .val = Value.initPayload(&big_int_payload.base),
314 });
315 }
316
270 fn analyzeInst(self: *Analyze, func: ?*Fn, old_inst: *text.Inst) InnerError!*Inst {317 fn analyzeInst(self: *Analyze, func: ?*Fn, old_inst: *text.Inst) InnerError!*Inst {
271 switch (old_inst.tag) {318 switch (old_inst.tag) {
272 .str => {319 .str => {
...@@ -275,7 +322,10 @@ const Analyze = struct {...@@ -275,7 +322,10 @@ const Analyze = struct {
275 const bytes = old_inst.cast(text.Inst.Str).?.positionals.bytes;322 const bytes = old_inst.cast(text.Inst.Str).?.positionals.bytes;
276 return self.constStr(old_inst.src, bytes);323 return self.constStr(old_inst.src, bytes);
277 },324 },
278 .int => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),325 .int => {
326 const big_int = old_inst.cast(text.Inst.Int).?.positionals.int;
327 return self.constIntBig(old_inst.src, Type.initTag(.comptime_int), big_int);
328 },
279 .ptrtoint => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),329 .ptrtoint => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),
280 .fieldptr => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),330 .fieldptr => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),
281 .deref => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),331 .deref => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}),
src-self-hosted/value.zig+9
...@@ -2,6 +2,7 @@ const std = @import("std");...@@ -2,6 +2,7 @@ const std = @import("std");
2const Type = @import("type.zig").Type;2const Type = @import("type.zig").Type;
3const log2 = std.math.log2;3const log2 = std.math.log2;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const BigInt = std.math.big.Int;
56
6/// This is the raw data, with no bookkeeping, no memory awareness,7/// This is the raw data, with no bookkeeping, no memory awareness,
7/// no de-duplication, and no type system awareness.8/// no de-duplication, and no type system awareness.
...@@ -53,6 +54,7 @@ pub const Value = extern union {...@@ -53,6 +54,7 @@ pub const Value = extern union {
53 ty,54 ty,
54 int_u64,55 int_u64,
55 int_i64,56 int_i64,
57 int_big,
56 function,58 function,
57 ref,59 ref,
58 bytes,60 bytes,
...@@ -133,6 +135,7 @@ pub const Value = extern union {...@@ -133,6 +135,7 @@ pub const Value = extern union {
133 .ty => return self.cast(Payload.Ty).?.ty.format("", options, out_stream),135 .ty => return self.cast(Payload.Ty).?.ty.format("", options, out_stream),
134 .int_u64 => return std.fmt.formatIntValue(self.cast(Payload.Int_u64).?.int, "", options, out_stream),136 .int_u64 => return std.fmt.formatIntValue(self.cast(Payload.Int_u64).?.int, "", options, out_stream),
135 .int_i64 => return std.fmt.formatIntValue(self.cast(Payload.Int_i64).?.int, "", options, out_stream),137 .int_i64 => return std.fmt.formatIntValue(self.cast(Payload.Int_i64).?.int, "", options, out_stream),
138 .int_big => return out_stream.print("{}", .{self.cast(Payload.IntBig).?.big_int}),
136 .function => return out_stream.writeAll("(function)"),139 .function => return out_stream.writeAll("(function)"),
137 .ref => return out_stream.writeAll("(ref)"),140 .ref => return out_stream.writeAll("(ref)"),
138 .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream),141 .bytes => return std.zig.renderStringLiteral(self.cast(Payload.Bytes).?.data, out_stream),
...@@ -187,6 +190,7 @@ pub const Value = extern union {...@@ -187,6 +190,7 @@ pub const Value = extern union {
187 .bool_false,190 .bool_false,
188 .int_u64,191 .int_u64,
189 .int_i64,192 .int_i64,
193 .int_big,
190 .function,194 .function,
191 .ref,195 .ref,
192 .bytes,196 .bytes,
...@@ -208,6 +212,11 @@ pub const Value = extern union {...@@ -208,6 +212,11 @@ pub const Value = extern union {
208 int: i64,212 int: i64,
209 };213 };
210214
215 pub const IntBig = struct {
216 base: Payload = Payload{ .tag = .int_big },
217 big_int: BigInt,
218 };
219
211 pub const Function = struct {220 pub const Function = struct {
212 base: Payload = Payload{ .tag = .function },221 base: Payload = Payload{ .tag = .function },
213 /// Index into the `fns` array of the `ir.Module`222 /// Index into the `fns` array of the `ir.Module`