| ... | ... | @@ -5,6 +5,7 @@ const Value = @import("value.zig").Value; |
| 5 | 5 | const Type = @import("type.zig").Type; |
| 6 | 6 | const assert = std.debug.assert; |
| 7 | 7 | const text = @import("ir/text.zig"); |
| 8 | const BigInt = std.math.big.Int; |
| 8 | 9 | |
| 9 | 10 | /// These are in-memory, analyzed instructions. See `text.Inst` for the representation |
| 10 | 11 | /// of instructions that correspond to the ZIR text format. |
| ... | ... | @@ -267,6 +268,52 @@ const Analyze = struct { |
| 267 | 268 | }); |
| 268 | 269 | } |
| 269 | 270 | |
| 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 | 317 | fn analyzeInst(self: *Analyze, func: ?*Fn, old_inst: *text.Inst) InnerError!*Inst { |
| 271 | 318 | switch (old_inst.tag) { |
| 272 | 319 | .str => { |
| ... | ... | @@ -275,7 +322,10 @@ const Analyze = struct { |
| 275 | 322 | const bytes = old_inst.cast(text.Inst.Str).?.positionals.bytes; |
| 276 | 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 | 329 | .ptrtoint => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), |
| 280 | 330 | .fieldptr => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), |
| 281 | 331 | .deref => return self.fail(old_inst.src, "TODO implement analyzing {}", .{@tagName(old_inst.tag)}), |