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 {...@@ -3257,32 +3257,23 @@ pub const DeclGen = struct {
3257 },3257 },
3258 // TODO this duplicates code with Pointer but they should share the handling3258 // TODO this duplicates code with Pointer but they should share the handling
3259 // of the tv.val.tag() and then Int should do extra constPtrToInt on top3259 // of the tv.val.tag() and then Int should do extra constPtrToInt on top
3260 .Int => switch (tv.val.tag()) {3260 .Int => switch (tv.val.ip_index) {
3261 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),3261 .none => switch (tv.val.tag()) {
3262 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),3262 .decl_ref_mut => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref_mut).?.data.decl_index),
3263 else => {3263 .decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
3264 var bigint_space: Value.BigIntSpace = undefined;3264 else => {
3265 const bigint = tv.val.toBigInt(&bigint_space, mod);3265 var bigint_space: Value.BigIntSpace = undefined;
3266 const int_info = tv.ty.intInfo(mod);3266 const bigint = tv.val.toBigInt(&bigint_space, mod);
3267 assert(int_info.bits != 0);3267 return lowerBigInt(dg, tv.ty, bigint);
3268 const llvm_type = dg.context.intType(int_info.bits);3268 },
32693269 },
3270 const unsigned_val = v: {3270 else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
3271 if (bigint.limbs.len == 1) {3271 .int => |int| {
3272 break :v llvm_type.constInt(bigint.limbs[0], .False);3272 var bigint_space: Value.BigIntSpace = undefined;
3273 }3273 const bigint = int.storage.toBigInt(&bigint_space);
3274 if (@sizeOf(usize) == @sizeOf(u64)) {3274 return lowerBigInt(dg, tv.ty, bigint);
3275 break :v llvm_type.constIntOfArbitraryPrecision(3275 },
3276 @intCast(c_uint, bigint.limbs.len),3276 else => unreachable,
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;
3286 },3277 },
3287 },3278 },
3288 .Enum => {3279 .Enum => {
...@@ -3983,6 +3974,30 @@ pub const DeclGen = struct {...@@ -3983,6 +3974,30 @@ pub const DeclGen = struct {
3983 }3974 }
3984 }3975 }
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
3986 const ParentPtr = struct {4001 const ParentPtr = struct {
3987 ty: Type,4002 ty: Type,
3988 llvm_ptr: *llvm.Value,4003 llvm_ptr: *llvm.Value,