authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-05 20:49:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
logf7bd42785bf763e66557f886188ec53824cc45e0
tree2f02725a48ad1931582d2e38ccf4741a22a999f7
parent27d641eb35820a012e64e99df18c3577100f9dba

LLVM backend: update integer constant lowering for InternPool


1 files changed, 41 insertions(+), 26 deletions(-)

src/codegen/llvm.zig+41-26
......@@ -3257,32 +3257,23 @@ pub const DeclGen = struct {
32573257 },
32583258 // TODO this duplicates code with Pointer but they should share the handling
32593259 // of the tv.val.tag() and then Int should do extra constPtrToInt on top
3260 .Int => switch (tv.val.tag()) {
3261 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
3262 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
3263 else => {
3264 var bigint_space: Value.BigIntSpace = undefined;
3265 const bigint = tv.val.toBigInt(&bigint_space, mod);
3266 const int_info = tv.ty.intInfo(mod);
3267 assert(int_info.bits != 0);
3268 const llvm_type = dg.context.intType(int_info.bits);
3269
3270 const unsigned_val = v: {
3271 if (bigint.limbs.len == 1) {
3272 break :v llvm_type.constInt(bigint.limbs[0], .False);
3273 }
3274 if (@sizeOf(usize) == @sizeOf(u64)) {
3275 break :v llvm_type.constIntOfArbitraryPrecision(
3276 @intCast(c_uint, bigint.limbs.len),
3277 bigint.limbs.ptr,
3278 );
3279 }
3280 @panic("TODO implement bigint to llvm int for 32-bit compiler builds");
3281 };
3282 if (!bigint.positive) {
3283 return llvm.constNeg(unsigned_val);
3284 }
3285 return unsigned_val;
3260 .Int => switch (tv.val.ip_index) {
3261 .none => switch (tv.val.tag()) {
3262 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
3263 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
3264 else => {
3265 var bigint_space: Value.BigIntSpace = undefined;
3266 const bigint = tv.val.toBigInt(&bigint_space, mod);
3267 return lowerBigInt(dg, tv.ty, bigint);
3268 },
3269 },
3270 else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
3271 .int => |int| {
3272 var bigint_space: Value.BigIntSpace = undefined;
3273 const bigint = int.storage.toBigInt(&bigint_space);
3274 return lowerBigInt(dg, tv.ty, bigint);
3275 },
3276 else => unreachable,
32863277 },
32873278 },
32883279 .Enum => {
......@@ -3983,6 +3974,30 @@ pub const DeclGen = struct {
39833974 }
39843975 }
39853976
3977 fn lowerBigInt(dg: *DeclGen, ty: Type, bigint: std.math.big.int.Const) *llvm.Value {
3978 const mod = dg.module;
3979 const int_info = ty.intInfo(mod);
3980 assert(int_info.bits != 0);
3981 const llvm_type = dg.context.intType(int_info.bits);
3982
3983 const unsigned_val = v: {
3984 if (bigint.limbs.len == 1) {
3985 break :v llvm_type.constInt(bigint.limbs[0], .False);
3986 }
3987 if (@sizeOf(usize) == @sizeOf(u64)) {
3988 break :v llvm_type.constIntOfArbitraryPrecision(
3989 @intCast(c_uint, bigint.limbs.len),
3990 bigint.limbs.ptr,
3991 );
3992 }
3993 @panic("TODO implement bigint to llvm int for 32-bit compiler builds");
3994 };
3995 if (!bigint.positive) {
3996 return llvm.constNeg(unsigned_val);
3997 }
3998 return unsigned_val;
3999 }
4000
39864001 const ParentPtr = struct {
39874002 ty: Type,
39884003 llvm_ptr: *llvm.Value,