aboutsummaryrefslogtreecommitdiff
path: root/src/arch/arm/CodeGen.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/CodeGen.zig')
-rw-r--r--src/arch/arm/CodeGen.zig383
1 files changed, 219 insertions, 164 deletions
diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig
index 3f10513bb2..0dd513d4fe 100644
--- a/src/arch/arm/CodeGen.zig
+++ b/src/arch/arm/CodeGen.zig
@@ -12,11 +12,9 @@ const Type = @import("../../Type.zig");
const Value = @import("../../Value.zig");
const link = @import("../../link.zig");
const Zcu = @import("../../Zcu.zig");
-/// Deprecated.
-const Module = Zcu;
const InternPool = @import("../../InternPool.zig");
const Compilation = @import("../../Compilation.zig");
-const ErrorMsg = Module.ErrorMsg;
+const ErrorMsg = Zcu.ErrorMsg;
const Target = std.Target;
const Allocator = mem.Allocator;
const trace = @import("../../tracy.zig").trace;
@@ -48,6 +46,7 @@ const gp = abi.RegisterClass.gp;
const InnerError = CodeGenError || error{OutOfRegisters};
gpa: Allocator,
+pt: Zcu.PerThread,
air: Air,
liveness: Liveness,
bin_file: *link.File,
@@ -59,7 +58,7 @@ args: []MCValue,
ret_mcv: MCValue,
fn_type: Type,
arg_index: u32,
-src_loc: Module.LazySrcLoc,
+src_loc: Zcu.LazySrcLoc,
stack_align: u32,
/// MIR Instructions
@@ -261,7 +260,6 @@ const DbgInfoReloc = struct {
}
fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
- const mod = function.bin_file.comp.module.?;
switch (function.debug_output) {
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
@@ -282,7 +280,7 @@ const DbgInfoReloc = struct {
else => unreachable, // not a possible argument
};
- try dw.genArgDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), loc);
+ try dw.genArgDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), loc);
},
.plan9 => {},
.none => {},
@@ -290,7 +288,6 @@ const DbgInfoReloc = struct {
}
fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
- const mod = function.bin_file.comp.module.?;
const is_ptr = switch (reloc.tag) {
.dbg_var_ptr => true,
.dbg_var_val => false,
@@ -326,7 +323,7 @@ const DbgInfoReloc = struct {
break :blk .nop;
},
};
- try dw.genVarDbgInfo(reloc.name, reloc.ty, mod.funcOwnerDeclIndex(function.func_index), is_ptr, loc);
+ try dw.genVarDbgInfo(reloc.name, reloc.ty, function.pt.zcu.funcOwnerDeclIndex(function.func_index), is_ptr, loc);
},
.plan9 => {},
.none => {},
@@ -338,15 +335,16 @@ const Self = @This();
pub fn generate(
lf: *link.File,
- src_loc: Module.LazySrcLoc,
+ pt: Zcu.PerThread,
+ src_loc: Zcu.LazySrcLoc,
func_index: InternPool.Index,
air: Air,
liveness: Liveness,
code: *std.ArrayList(u8),
debug_output: DebugInfoOutput,
) CodeGenError!Result {
- const gpa = lf.comp.gpa;
- const zcu = lf.comp.module.?;
+ const zcu = pt.zcu;
+ const gpa = zcu.gpa;
const func = zcu.funcInfo(func_index);
const fn_owner_decl = zcu.declPtr(func.owner_decl);
assert(fn_owner_decl.has_tv);
@@ -364,6 +362,7 @@ pub fn generate(
var function: Self = .{
.gpa = gpa,
+ .pt = pt,
.air = air,
.liveness = liveness,
.target = target,
@@ -482,7 +481,8 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
}
fn gen(self: *Self) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const cc = self.fn_type.fnCallingConvention(mod);
if (cc != .Naked) {
// push {fp, lr}
@@ -526,8 +526,8 @@ fn gen(self: *Self) !void {
const ty = self.typeOfIndex(inst);
- const abi_size: u32 = @intCast(ty.abiSize(mod));
- const abi_align = ty.abiAlignment(mod);
+ const abi_size: u32 = @intCast(ty.abiSize(pt));
+ const abi_align = ty.abiAlignment(pt);
const stack_offset = try self.allocMem(abi_size, abi_align, inst);
try self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
@@ -642,7 +642,8 @@ fn gen(self: *Self) !void {
}
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ip = &mod.intern_pool;
const air_tags = self.air.instructions.items(.tag);
@@ -1004,10 +1005,11 @@ fn allocMem(
/// Use a pointer instruction as the basis for allocating stack memory.
fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const elem_ty = self.typeOfIndex(inst).childType(mod);
- if (!elem_ty.hasRuntimeBits(mod)) {
+ if (!elem_ty.hasRuntimeBits(pt)) {
// As this stack item will never be dereferenced at runtime,
// return the stack offset 0. Stack offset 0 will be where all
// zero-sized stack allocations live as non-zero-sized
@@ -1015,21 +1017,21 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
return 0;
}
- const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
- return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
+ const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
+ return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
};
// TODO swap this for inst.ty.ptrAlign
- const abi_align = elem_ty.abiAlignment(mod);
+ const abi_align = elem_ty.abiAlignment(pt);
return self.allocMem(abi_size, abi_align, inst);
}
fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
- const mod = self.bin_file.comp.module.?;
- const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
- return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
+ const pt = self.pt;
+ const abi_size = math.cast(u32, elem_ty.abiSize(pt)) orelse {
+ return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(pt)});
};
- const abi_align = elem_ty.abiAlignment(mod);
+ const abi_align = elem_ty.abiAlignment(pt);
if (reg_ok) {
// Make sure the type can fit in a register before we try to allocate one.
@@ -1112,14 +1114,15 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
}
fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = switch (self.ret_mcv) {
.none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },
.stack_offset => blk: {
// self.ret_mcv is an address to where this function
// should store its result into
const ret_ty = self.fn_type.fnReturnType(mod);
- const ptr_ty = try mod.singleMutPtrType(ret_ty);
+ const ptr_ty = try pt.singleMutPtrType(ret_ty);
// addr_reg will contain the address of where to store the
// result into
@@ -1145,7 +1148,8 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
if (self.liveness.isUnused(inst))
return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
@@ -1154,8 +1158,8 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const operand_ty = self.typeOf(ty_op.operand);
const dest_ty = self.typeOfIndex(inst);
- const operand_abi_size = operand_ty.abiSize(mod);
- const dest_abi_size = dest_ty.abiSize(mod);
+ const operand_abi_size = operand_ty.abiSize(pt);
+ const dest_abi_size = dest_ty.abiSize(pt);
const info_a = operand_ty.intInfo(mod);
const info_b = dest_ty.intInfo(mod);
@@ -1211,7 +1215,8 @@ fn trunc(
operand_ty: Type,
dest_ty: Type,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const info_a = operand_ty.intInfo(mod);
const info_b = dest_ty.intInfo(mod);
@@ -1275,7 +1280,8 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
const operand_ty = self.typeOf(ty_op.operand);
@@ -1371,7 +1377,8 @@ fn minMax(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM min/max on floats", .{}),
.Vector => return self.fail("TODO ARM min/max on vectors", .{}),
@@ -1580,7 +1587,8 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
@@ -1588,9 +1596,9 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
const rhs_ty = self.typeOf(extra.rhs);
const tuple_ty = self.typeOfIndex(inst);
- const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));
- const tuple_align = tuple_ty.abiAlignment(mod);
- const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));
+ const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
+ const tuple_align = tuple_ty.abiAlignment(pt);
+ const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement add_with_overflow/sub_with_overflow for vectors", .{}),
@@ -1693,7 +1701,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = result: {
const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
@@ -1701,9 +1710,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const rhs_ty = self.typeOf(extra.rhs);
const tuple_ty = self.typeOfIndex(inst);
- const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));
- const tuple_align = tuple_ty.abiAlignment(mod);
- const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));
+ const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
+ const tuple_align = tuple_ty.abiAlignment(pt);
+ const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
@@ -1857,15 +1866,16 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = result: {
const lhs_ty = self.typeOf(extra.lhs);
const rhs_ty = self.typeOf(extra.rhs);
const tuple_ty = self.typeOfIndex(inst);
- const tuple_size: u32 = @intCast(tuple_ty.abiSize(mod));
- const tuple_align = tuple_ty.abiAlignment(mod);
- const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, mod));
+ const tuple_size: u32 = @intCast(tuple_ty.abiSize(pt));
+ const tuple_align = tuple_ty.abiAlignment(pt);
+ const overflow_bit_offset: u32 = @intCast(tuple_ty.structFieldOffset(1, pt));
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO implement shl_with_overflow for vectors", .{}),
@@ -2013,11 +2023,11 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
}
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const optional_ty = self.typeOfIndex(inst);
- const abi_size: u32 = @intCast(optional_ty.abiSize(mod));
+ const abi_size: u32 = @intCast(optional_ty.abiSize(pt));
// Optional with a zero-bit payload type is just a boolean true
if (abi_size == 1) {
@@ -2036,17 +2046,18 @@ fn errUnionErr(
error_union_ty: Type,
maybe_inst: ?Air.Inst.Index,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const err_ty = error_union_ty.errorUnionSet(mod);
const payload_ty = error_union_ty.errorUnionPayload(mod);
if (err_ty.errorSetIsEmpty(mod)) {
return MCValue{ .immediate = 0 };
}
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
return try error_union_bind.resolveToMcv(self);
}
- const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, mod));
+ const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, pt));
switch (try error_union_bind.resolveToMcv(self)) {
.register => {
var operand_reg: Register = undefined;
@@ -2068,7 +2079,7 @@ fn errUnionErr(
);
const err_bit_offset = err_offset * 8;
- const err_bit_size: u32 = @intCast(err_ty.abiSize(mod) * 8);
+ const err_bit_size: u32 = @intCast(err_ty.abiSize(pt) * 8);
_ = try self.addInst(.{
.tag = .ubfx, // errors are unsigned integers
@@ -2113,17 +2124,18 @@ fn errUnionPayload(
error_union_ty: Type,
maybe_inst: ?Air.Inst.Index,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const err_ty = error_union_ty.errorUnionSet(mod);
const payload_ty = error_union_ty.errorUnionPayload(mod);
if (err_ty.errorSetIsEmpty(mod)) {
return try error_union_bind.resolveToMcv(self);
}
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
return MCValue.none;
}
- const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, mod));
+ const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, pt));
switch (try error_union_bind.resolveToMcv(self)) {
.register => {
var operand_reg: Register = undefined;
@@ -2145,7 +2157,7 @@ fn errUnionPayload(
);
const payload_bit_offset = payload_offset * 8;
- const payload_bit_size: u32 = @intCast(payload_ty.abiSize(mod) * 8);
+ const payload_bit_size: u32 = @intCast(payload_ty.abiSize(pt) * 8);
_ = try self.addInst(.{
.tag = if (payload_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
@@ -2223,20 +2235,21 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
/// T to E!T
fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_ty = ty_op.ty.toType();
const error_ty = error_union_ty.errorUnionSet(mod);
const payload_ty = error_union_ty.errorUnionPayload(mod);
const operand = try self.resolveInst(ty_op.operand);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
- const abi_size: u32 = @intCast(error_union_ty.abiSize(mod));
- const abi_align = error_union_ty.abiAlignment(mod);
+ const abi_size: u32 = @intCast(error_union_ty.abiSize(pt));
+ const abi_align = error_union_ty.abiAlignment(pt);
const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));
- const payload_off = errUnionPayloadOffset(payload_ty, mod);
- const err_off = errUnionErrorOffset(payload_ty, mod);
+ const payload_off = errUnionPayloadOffset(payload_ty, pt);
+ const err_off = errUnionErrorOffset(payload_ty, pt);
try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), operand);
try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), .{ .immediate = 0 });
@@ -2247,20 +2260,21 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
/// E to E!T
fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_ty = ty_op.ty.toType();
const error_ty = error_union_ty.errorUnionSet(mod);
const payload_ty = error_union_ty.errorUnionPayload(mod);
const operand = try self.resolveInst(ty_op.operand);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :result operand;
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) break :result operand;
- const abi_size: u32 = @intCast(error_union_ty.abiSize(mod));
- const abi_align = error_union_ty.abiAlignment(mod);
+ const abi_size: u32 = @intCast(error_union_ty.abiSize(pt));
+ const abi_align = error_union_ty.abiAlignment(pt);
const stack_offset: u32 = @intCast(try self.allocMem(abi_size, abi_align, inst));
- const payload_off = errUnionPayloadOffset(payload_ty, mod);
- const err_off = errUnionErrorOffset(payload_ty, mod);
+ const payload_off = errUnionPayloadOffset(payload_ty, pt);
+ const err_off = errUnionErrorOffset(payload_ty, pt);
try self.genSetStack(error_ty, stack_offset - @as(u32, @intCast(err_off)), operand);
try self.genSetStack(payload_ty, stack_offset - @as(u32, @intCast(payload_off)), .undef);
@@ -2364,9 +2378,10 @@ fn ptrElemVal(
ptr_ty: Type,
maybe_inst: ?Air.Inst.Index,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const elem_ty = ptr_ty.childType(mod);
- const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
+ const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
switch (elem_size) {
1, 4 => {
@@ -2423,7 +2438,8 @@ fn ptrElemVal(
}
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
@@ -2466,7 +2482,8 @@ fn arrayElemVal(
array_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const elem_ty = array_ty.childType(mod);
const mcv = try array_bind.resolveToMcv(self);
@@ -2501,7 +2518,7 @@ fn arrayElemVal(
const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv };
- const ptr_ty = try mod.singleMutPtrType(elem_ty);
+ const ptr_ty = try pt.singleMutPtrType(elem_ty);
return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst);
},
@@ -2522,7 +2539,8 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
@@ -2656,9 +2674,10 @@ fn reuseOperand(
}
fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const elem_ty = ptr_ty.childType(mod);
- const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
+ const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
switch (ptr) {
.none => unreachable,
@@ -2733,11 +2752,12 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
}
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const elem_ty = self.typeOfIndex(inst);
const result: MCValue = result: {
- if (!elem_ty.hasRuntimeBits(mod))
+ if (!elem_ty.hasRuntimeBits(pt))
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
@@ -2746,7 +2766,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
break :result MCValue.dead;
const dest_mcv: MCValue = blk: {
- const ptr_fits_dest = elem_ty.abiSize(mod) <= 4;
+ const ptr_fits_dest = elem_ty.abiSize(pt) <= 4;
if (ptr_fits_dest and self.reuseOperand(inst, ty_op.operand, 0, ptr)) {
// The MCValue that holds the pointer can be re-used as the value.
break :blk ptr;
@@ -2762,8 +2782,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
}
fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
- const mod = self.bin_file.comp.module.?;
- const elem_size: u32 = @intCast(value_ty.abiSize(mod));
+ const pt = self.pt;
+ const elem_size: u32 = @intCast(value_ty.abiSize(pt));
switch (ptr) {
.none => unreachable,
@@ -2882,11 +2902,12 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
return if (self.liveness.isUnused(inst)) .dead else result: {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const mcv = try self.resolveInst(operand);
const ptr_ty = self.typeOf(operand);
const struct_ty = ptr_ty.childType(mod);
- const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod));
+ const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt));
switch (mcv) {
.ptr_stack_offset => |off| {
break :result MCValue{ .ptr_stack_offset = off - struct_field_offset };
@@ -2906,11 +2927,12 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
const operand = extra.struct_operand;
const index = extra.field_index;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(operand);
const struct_ty = self.typeOf(operand);
- const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, mod));
+ const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(index, pt));
const struct_field_ty = struct_ty.structFieldType(index, mod);
switch (mcv) {
@@ -2974,7 +2996,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
);
const field_bit_offset = struct_field_offset * 8;
- const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(mod) * 8);
+ const field_bit_size: u32 = @intCast(struct_field_ty.abiSize(pt) * 8);
_ = try self.addInst(.{
.tag = if (struct_field_ty.isSignedInt(mod)) Mir.Inst.Tag.sbfx else .ubfx,
@@ -2996,7 +3018,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
@@ -3007,7 +3030,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
return self.fail("TODO implement @fieldParentPtr codegen for unions", .{});
}
- const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, mod));
+ const struct_field_offset: u32 = @intCast(struct_ty.structFieldOffset(extra.field_index, pt));
switch (field_ptr) {
.ptr_stack_offset => |off| {
break :result MCValue{ .ptr_stack_offset = off + struct_field_offset };
@@ -3390,7 +3413,8 @@ fn addSub(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3446,7 +3470,8 @@ fn mul(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3479,7 +3504,8 @@ fn divFloat(
_ = rhs_ty;
_ = maybe_inst;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3495,7 +3521,8 @@ fn divTrunc(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3538,7 +3565,8 @@ fn divFloor(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3586,7 +3614,8 @@ fn divExact(
_ = rhs_ty;
_ = maybe_inst;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3603,7 +3632,8 @@ fn rem(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3672,7 +3702,8 @@ fn modulo(
_ = rhs_ty;
_ = maybe_inst;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Float => return self.fail("TODO ARM binary operations on floats", .{}),
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
@@ -3690,7 +3721,8 @@ fn wrappingArithmetic(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
.Int => {
@@ -3728,7 +3760,8 @@ fn bitwise(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
.Int => {
@@ -3773,7 +3806,8 @@ fn shiftExact(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
.Int => {
@@ -3812,7 +3846,8 @@ fn shiftNormal(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
.Int => {
@@ -3855,7 +3890,8 @@ fn booleanOp(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Bool => {
const lhs_immediate = try lhs_bind.resolveToImmediate(self);
@@ -3889,7 +3925,8 @@ fn ptrArithmetic(
rhs_ty: Type,
maybe_inst: ?Air.Inst.Index,
) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (lhs_ty.zigTypeTag(mod)) {
.Pointer => {
assert(rhs_ty.eql(Type.usize, mod));
@@ -3899,7 +3936,7 @@ fn ptrArithmetic(
.One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type
else => ptr_ty.childType(mod),
};
- const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
+ const elem_size: u32 = @intCast(elem_ty.abiSize(pt));
const base_tag: Air.Inst.Tag = switch (tag) {
.ptr_add => .add,
@@ -3926,8 +3963,9 @@ fn ptrArithmetic(
}
fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {
- const mod = self.bin_file.comp.module.?;
- const abi_size = ty.abiSize(mod);
+ const pt = self.pt;
+ const mod = pt.zcu;
+ const abi_size = ty.abiSize(pt);
const tag: Mir.Inst.Tag = switch (abi_size) {
1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
@@ -3961,8 +3999,8 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
}
fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {
- const mod = self.bin_file.comp.module.?;
- const abi_size = ty.abiSize(mod);
+ const pt = self.pt;
+ const abi_size = ty.abiSize(pt);
const tag: Mir.Inst.Tag = switch (abi_size) {
1 => .strb,
@@ -4168,7 +4206,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
while (self.args[arg_index] == .none) arg_index += 1;
self.arg_index = arg_index + 1;
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty = self.typeOfIndex(inst);
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
@@ -4223,7 +4262,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
const ty = self.typeOf(callee);
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const fn_ty = switch (ty.zigTypeTag(mod)) {
.Fn => ty,
@@ -4253,11 +4293,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const r0_lock: ?RegisterLock = if (info.return_value == .stack_offset) blk: {
log.debug("airCall: return by reference", .{});
const ret_ty = fn_ty.fnReturnType(mod);
- const ret_abi_size: u32 = @intCast(ret_ty.abiSize(mod));
- const ret_abi_align = ret_ty.abiAlignment(mod);
+ const ret_abi_size: u32 = @intCast(ret_ty.abiSize(pt));
+ const ret_abi_align = ret_ty.abiAlignment(pt);
const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst);
- const ptr_ty = try mod.singleMutPtrType(ret_ty);
+ const ptr_ty = try pt.singleMutPtrType(ret_ty);
try self.register_manager.getReg(.r0, null);
try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset });
@@ -4293,7 +4333,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// Due to incremental compilation, how function calls are generated depends
// on linking.
- if (try self.air.value(callee, mod)) |func_value| {
+ if (try self.air.value(callee, pt)) |func_value| {
if (func_value.getFunction(mod)) |func| {
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
@@ -4374,7 +4414,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}
fn airRet(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const ret_ty = self.fn_type.fnReturnType(mod);
@@ -4393,7 +4434,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
//
// self.ret_mcv is an address to where this function
// should store its result into
- const ptr_ty = try mod.singleMutPtrType(ret_ty);
+ const ptr_ty = try pt.singleMutPtrType(ret_ty);
try self.store(self.ret_mcv, operand, ptr_ty, ret_ty);
},
else => unreachable, // invalid return result
@@ -4406,7 +4447,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
}
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const ptr = try self.resolveInst(un_op);
const ptr_ty = self.typeOf(un_op);
@@ -4430,8 +4472,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
// location.
const op_inst = un_op.toIndex().?;
if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {
- const abi_size: u32 = @intCast(ret_ty.abiSize(mod));
- const abi_align = ret_ty.abiAlignment(mod);
+ const abi_size: u32 = @intCast(ret_ty.abiSize(pt));
+ const abi_align = ret_ty.abiAlignment(pt);
const offset = try self.allocMem(abi_size, abi_align, null);
@@ -4467,11 +4509,12 @@ fn cmp(
lhs_ty: Type,
op: math.CompareOperator,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
.Optional => blk: {
const payload_ty = lhs_ty.optionalChild(mod);
- if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
break :blk Type.u1;
} else if (lhs_ty.isPtrLikeOptional(mod)) {
break :blk Type.usize;
@@ -4573,7 +4616,8 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
const func = mod.funcInfo(extra.data.func);
@@ -4785,9 +4829,10 @@ fn isNull(
operand_bind: ReadArg.Bind,
operand_ty: Type,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
if (operand_ty.isPtrLikeOptional(mod)) {
- assert(operand_ty.abiSize(mod) == 4);
+ assert(operand_ty.abiSize(pt) == 4);
const imm_bind: ReadArg.Bind = .{ .mcv = .{ .immediate = 0 } };
return self.cmp(operand_bind, imm_bind, Type.usize, .eq);
@@ -4819,7 +4864,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
@@ -4846,7 +4892,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
@@ -4866,7 +4913,8 @@ fn isErr(
error_union_bind: ReadArg.Bind,
error_union_ty: Type,
) !MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const error_type = error_union_ty.errorUnionSet(mod);
if (error_type.errorSetIsEmpty(mod)) {
@@ -4908,7 +4956,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
@@ -4935,7 +4984,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand_ptr = try self.resolveInst(un_op);
@@ -5154,10 +5204,10 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
}
fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
const block_data = self.blocks.getPtr(block).?;
- if (self.typeOf(operand).hasRuntimeBits(mod)) {
+ if (self.typeOf(operand).hasRuntimeBits(pt)) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
@@ -5325,8 +5375,9 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
}
fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
- const mod = self.bin_file.comp.module.?;
- const abi_size: u32 = @intCast(ty.abiSize(mod));
+ const pt = self.pt;
+ const mod = pt.zcu;
+ const abi_size: u32 = @intCast(ty.abiSize(pt));
switch (mcv) {
.dead => unreachable,
.unreach, .none => return, // Nothing to do.
@@ -5407,7 +5458,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg });
const overflow_bit_ty = ty.structFieldType(1, mod);
- const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, mod));
+ const overflow_bit_offset: u32 = @intCast(ty.structFieldOffset(1, pt));
const cond_reg = try self.register_manager.allocReg(null, gp);
// C flag: movcs reg, #1
@@ -5445,7 +5496,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
const reg = try self.copyToTmpRegister(ty, mcv);
return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
} else {
- const ptr_ty = try mod.singleMutPtrType(ty);
+ const ptr_ty = try pt.singleMutPtrType(ty);
// TODO call extern memcpy
const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
@@ -5487,7 +5538,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
}
fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
switch (mcv) {
.dead => unreachable,
.unreach, .none => return, // Nothing to do.
@@ -5662,7 +5714,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
},
.stack_offset => |off| {
// TODO: maybe addressing from sp instead of fp
- const abi_size: u32 = @intCast(ty.abiSize(mod));
+ const abi_size: u32 = @intCast(ty.abiSize(pt));
const tag: Mir.Inst.Tag = switch (abi_size) {
1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb else .ldrb,
@@ -5713,7 +5765,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
}
},
.stack_argument_offset => |off| {
- const abi_size = ty.abiSize(mod);
+ const abi_size = ty.abiSize(pt);
const tag: Mir.Inst.Tag = switch (abi_size) {
1 => if (ty.isSignedInt(mod)) Mir.Inst.Tag.ldrsb_stack_argument else .ldrb_stack_argument,
@@ -5734,8 +5786,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
}
fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
- const mod = self.bin_file.comp.module.?;
- const abi_size: u32 = @intCast(ty.abiSize(mod));
+ const pt = self.pt;
+ const abi_size: u32 = @intCast(ty.abiSize(pt));
switch (mcv) {
.dead => unreachable,
.none, .unreach => return,
@@ -5802,7 +5854,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
const reg = try self.copyToTmpRegister(ty, mcv);
return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg });
} else {
- const ptr_ty = try mod.singleMutPtrType(ty);
+ const ptr_ty = try pt.singleMutPtrType(ty);
// TODO call extern memcpy
const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp);
@@ -5890,7 +5942,8 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
}
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr_ty = self.typeOf(ty_op.operand);
@@ -6009,7 +6062,8 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen(mod);
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
@@ -6054,15 +6108,15 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTry(self: *Self, inst: Air.Inst.Index) !void {
+ const pt = self.pt;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const result: MCValue = result: {
const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
const error_union_ty = self.typeOf(pl_op.operand);
- const mod = self.bin_file.comp.module.?;
- const error_union_size: u32 = @intCast(error_union_ty.abiSize(mod));
- const error_union_align = error_union_ty.abiAlignment(mod);
+ const error_union_size: u32 = @intCast(error_union_ty.abiSize(pt));
+ const error_union_align = error_union_ty.abiAlignment(pt);
// The error union will die in the body. However, we need the
// error union after the body in order to extract the payload
@@ -6091,14 +6145,15 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
// If the type has no codegen bits, no need to store it.
const inst_ty = self.typeOf(inst);
- if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
+ if (!inst_ty.hasRuntimeBitsIgnoreComptime(pt) and !inst_ty.isError(mod))
return MCValue{ .none = {} };
- const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, mod)).?);
+ const inst_index = inst.toIndex() orelse return self.genTypedValue((try self.air.value(inst, pt)).?);
return self.getResolvedInstValue(inst_index);
}
@@ -6116,12 +6171,13 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
}
fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
const mcv: MCValue = switch (try codegen.genTypedValue(
self.bin_file,
+ pt,
self.src_loc,
val,
- mod.funcOwnerDeclIndex(self.func_index),
+ pt.zcu.funcOwnerDeclIndex(self.func_index),
)) {
.mcv => |mcv| switch (mcv) {
.none => .none,
@@ -6152,7 +6208,8 @@ const CallMCValues = struct {
/// Caller must call `CallMCValues.deinit`.
fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
- const mod = self.bin_file.comp.module.?;
+ const pt = self.pt;
+ const mod = pt.zcu;
const ip = &mod.intern_pool;
const fn_info = mod.typeToFunc(fn_ty).?;
const cc = fn_info.cc;
@@ -6182,10 +6239,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
if (ret_ty.zigTypeTag(mod) == .NoReturn) {
result.return_value = .{ .unreach = {} };
- } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
+ } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt)) {
result.return_value = .{ .none = {} };
} else {
- const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));
+ const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
// TODO handle cases where multiple registers are used
if (ret_ty_size <= 4) {
result.return_value = .{ .register = c_abi_int_return_regs[0] };
@@ -6200,10 +6257,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
}
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
- if (Type.fromInterned(ty).abiAlignment(mod) == .@"8")
+ if (Type.fromInterned(ty).abiAlignment(pt) == .@"8")
ncrn = std.mem.alignForward(usize, ncrn, 2);
- const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));
+ const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt));
if (std.math.divCeil(u32, param_size, 4) catch unreachable <= 4 - ncrn) {
if (param_size <= 4) {
result_arg.* = .{ .register = c_abi_int_param_regs[ncrn] };
@@ -6215,7 +6272,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
return self.fail("TODO MCValues split between registers and stack", .{});
} else {
ncrn = 4;
- if (Type.fromInterned(ty).abiAlignment(mod) == .@"8")
+ if (Type.fromInterned(ty).abiAlignment(pt) == .@"8")
nsaa = std.mem.alignForward(u32, nsaa, 8);
result_arg.* = .{ .stack_argument_offset = nsaa };
@@ -6229,10 +6286,10 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
.Unspecified => {
if (ret_ty.zigTypeTag(mod) == .NoReturn) {
result.return_value = .{ .unreach = {} };
- } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod) and !ret_ty.isError(mod)) {
+ } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
result.return_value = .{ .none = {} };
} else {
- const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));
+ const ret_ty_size: u32 = @intCast(ret_ty.abiSize(pt));
if (ret_ty_size == 0) {
assert(ret_ty.isError(mod));
result.return_value = .{ .immediate = 0 };
@@ -6250,9 +6307,9 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
var stack_offset: u32 = 0;
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
- if (Type.fromInterned(ty).abiSize(mod) > 0) {
- const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));
- const param_alignment = Type.fromInterned(ty).abiAlignment(mod);
+ if (Type.fromInterned(ty).abiSize(pt) > 0) {
+ const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(pt));
+ const param_alignment = Type.fromInterned(ty).abiAlignment(pt);
stack_offset = @intCast(param_alignment.forward(stack_offset));
result_arg.* = .{ .stack_argument_offset = stack_offset };
@@ -6271,7 +6328,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
return result;
}
-/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.
+/// TODO support scope overrides. Also note this logic is duplicated with `Zcu.wantSafety`.
fn wantSafety(self: *Self) bool {
return switch (self.bin_file.comp.root_mod.optimize_mode) {
.Debug => true,
@@ -6305,11 +6362,9 @@ fn parseRegName(name: []const u8) ?Register {
}
fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
- const mod = self.bin_file.comp.module.?;
- return self.air.typeOf(inst, &mod.intern_pool);
+ return self.air.typeOf(inst, &self.pt.zcu.intern_pool);
}
fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
- const mod = self.bin_file.comp.module.?;
- return self.air.typeOfIndex(inst, &mod.intern_pool);
+ return self.air.typeOfIndex(inst, &self.pt.zcu.intern_pool);
}