Air: use typesafe Air.Inst.Index

I need some indices for a thing...
This commit is contained in:
Jacob Young 2023-12-02 21:08:00 -05:00 committed by Andrew Kelley
parent bf5ab54510
commit daf91ed8d1
15 changed files with 1669 additions and 1642 deletions

View File

@ -875,7 +875,19 @@ pub const Inst = struct {
};
/// The position of an AIR instruction within the `Air` instructions array.
pub const Index = u32;
pub const Index = enum(u32) {
_,
pub fn toRef(i: Index) Inst.Ref {
assert(@intFromEnum(i) >> 31 == 0);
return @enumFromInt((1 << 31) | @intFromEnum(i));
}
pub fn toTargetIndex(i: Index) u31 {
assert(@intFromEnum(i) >> 31 == 1);
return @truncate(@intFromEnum(i));
}
};
/// Either a reference to a value stored in the InternPool, or a reference to an AIR instruction.
/// The most-significant bit of the value is a tag bit. This bit is 1 if the value represents an
@ -976,6 +988,41 @@ pub const Inst = struct {
/// value and may instead be used as a sentinel to indicate null.
none = @intFromEnum(InternPool.Index.none),
_,
pub fn toInterned(ref: Ref) ?InternPool.Index {
assert(ref != .none);
return ref.toInternedAllowNone();
}
pub fn toInternedAllowNone(ref: Ref) ?InternPool.Index {
return switch (ref) {
.var_args_param_type => .var_args_param_type,
.none => .none,
else => if (@intFromEnum(ref) >> 31 == 0)
@enumFromInt(@as(u31, @truncate(@intFromEnum(ref))))
else
null,
};
}
pub fn toIndex(ref: Ref) ?Index {
assert(ref != .none);
return ref.toIndexAllowNone();
}
pub fn toIndexAllowNone(ref: Ref) ?Index {
return switch (ref) {
.var_args_param_type, .none => null,
else => if (@intFromEnum(ref) >> 31 != 0)
@enumFromInt(@as(u31, @truncate(@intFromEnum(ref))))
else
null,
};
}
pub fn toType(ref: Ref) Type {
return Type.fromInterned(ref.toInterned().?);
}
};
/// All instructions have an 8-byte payload, which is contained within
@ -1216,20 +1263,20 @@ pub const UnionInit = struct {
pub fn getMainBody(air: Air) []const Air.Inst.Index {
const body_index = air.extra[@intFromEnum(ExtraIndex.main_block)];
const extra = air.extraData(Block, body_index);
return air.extra[extra.end..][0..extra.data.body_len];
return @ptrCast(air.extra[extra.end..][0..extra.data.body_len]);
}
pub fn typeOf(air: *const Air, inst: Air.Inst.Ref, ip: *const InternPool) Type {
if (refToInterned(inst)) |ip_index| {
if (inst.toInterned()) |ip_index| {
return Type.fromInterned(ip.typeOf(ip_index));
} else {
return air.typeOfIndex(refToIndex(inst).?, ip);
return air.typeOfIndex(inst.toIndex().?, ip);
}
}
pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) Type {
const datas = air.instructions.items(.data);
switch (air.instructions.items(.tag)[inst]) {
switch (air.instructions.items(.tag)[@intFromEnum(inst)]) {
.add,
.add_safe,
.add_wrap,
@ -1269,7 +1316,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.div_exact_optimized,
.rem_optimized,
.mod_optimized,
=> return air.typeOf(datas[inst].bin_op.lhs, ip),
=> return air.typeOf(datas[@intFromEnum(inst)].bin_op.lhs, ip),
.sqrt,
.sin,
@ -1286,7 +1333,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.trunc_float,
.neg,
.neg_optimized,
=> return air.typeOf(datas[inst].un_op, ip),
=> return air.typeOf(datas[@intFromEnum(inst)].un_op, ip),
.cmp_lt,
.cmp_lte,
@ -1317,9 +1364,9 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.ret_ptr,
.err_return_trace,
.c_va_start,
=> return datas[inst].ty,
=> return datas[@intFromEnum(inst)].ty,
.arg => return air.getRefType(datas[inst].arg.ty),
.arg => return datas[@intFromEnum(inst)].arg.ty.toType(),
.assembly,
.block,
@ -1343,7 +1390,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.ptr_add,
.ptr_sub,
.try_ptr,
=> return air.getRefType(datas[inst].ty_pl.ty),
=> return datas[@intFromEnum(inst)].ty_pl.ty.toType(),
.not,
.bitcast,
@ -1385,7 +1432,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.c_va_arg,
.c_va_copy,
.abs,
=> return air.getRefType(datas[inst].ty_op.ty),
=> return datas[@intFromEnum(inst)].ty_op.ty.toType(),
.loop,
.br,
@ -1437,36 +1484,36 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.tag_name, .error_name => return Type.slice_const_u8_sentinel_0,
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip);
const callee_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip);
return Type.fromInterned(ip.funcTypeReturnType(callee_ty.toIntern()));
},
.slice_elem_val, .ptr_elem_val, .array_elem_val => {
const ptr_ty = air.typeOf(datas[inst].bin_op.lhs, ip);
const ptr_ty = air.typeOf(datas[@intFromEnum(inst)].bin_op.lhs, ip);
return ptr_ty.childTypeIp(ip);
},
.atomic_load => {
const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr, ip);
const ptr_ty = air.typeOf(datas[@intFromEnum(inst)].atomic_load.ptr, ip);
return ptr_ty.childTypeIp(ip);
},
.atomic_rmw => {
const ptr_ty = air.typeOf(datas[inst].pl_op.operand, ip);
const ptr_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip);
return ptr_ty.childTypeIp(ip);
},
.reduce, .reduce_optimized => {
const operand_ty = air.typeOf(datas[inst].reduce.operand, ip);
const operand_ty = air.typeOf(datas[@intFromEnum(inst)].reduce.operand, ip);
return Type.fromInterned(ip.indexToKey(operand_ty.ip_index).vector_type.child);
},
.mul_add => return air.typeOf(datas[inst].pl_op.operand, ip),
.mul_add => return air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip),
.select => {
const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;
const extra = air.extraData(Air.Bin, datas[@intFromEnum(inst)].pl_op.payload).data;
return air.typeOf(extra.lhs, ip);
},
.@"try" => {
const err_union_ty = air.typeOf(datas[inst].pl_op.operand, ip);
const err_union_ty = air.typeOf(datas[@intFromEnum(inst)].pl_op.operand, ip);
return Type.fromInterned(ip.indexToKey(err_union_ty.ip_index).error_union_type.payload_type);
},
@ -1480,11 +1527,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
}
}
pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type {
_ = air; // TODO: remove this parameter
return Type.fromInterned(refToInterned(ref).?);
}
/// Returns the requested data, as well as the new index which is at the start of the
/// trailers for the object.
pub fn extraData(air: Air, comptime T: type, index: usize) struct { data: T, end: usize } {
@ -1513,21 +1555,6 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {
air.* = undefined;
}
pub fn refToInternedAllowNone(ref: Inst.Ref) ?InternPool.Index {
return switch (ref) {
.var_args_param_type => .var_args_param_type,
.none => .none,
else => if (@intFromEnum(ref) >> 31 == 0) {
return @as(InternPool.Index, @enumFromInt(@intFromEnum(ref)));
} else null,
};
}
pub fn refToInterned(ref: Inst.Ref) ?InternPool.Index {
assert(ref != .none);
return refToInternedAllowNone(ref);
}
pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {
return switch (ip_index) {
.var_args_param_type => .var_args_param_type,
@ -1539,31 +1566,12 @@ pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {
};
}
pub fn refToIndexAllowNone(ref: Inst.Ref) ?Inst.Index {
return switch (ref) {
.var_args_param_type, .none => null,
else => if (@intFromEnum(ref) >> 31 != 0) {
return @as(u31, @truncate(@intFromEnum(ref)));
} else null,
};
}
pub fn refToIndex(ref: Inst.Ref) ?Inst.Index {
assert(ref != .none);
return refToIndexAllowNone(ref);
}
pub fn indexToRef(inst: Inst.Index) Inst.Ref {
assert(inst >> 31 == 0);
return @enumFromInt((1 << 31) | inst);
}
/// Returns `null` if runtime-known.
pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value {
if (refToInterned(inst)) |ip_index| {
if (inst.toInterned()) |ip_index| {
return Value.fromInterned(ip_index);
}
const index = refToIndex(inst).?;
const index = inst.toIndex().?;
return air.typeOfIndex(index, &mod.intern_pool).onePossibleValue(mod);
}
@ -1581,8 +1589,8 @@ pub fn nullTerminatedString(air: Air, index: usize) [:0]const u8 {
/// lowered, and Liveness determines its result is unused, backends should
/// avoid lowering it.
pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
const data = air.instructions.items(.data)[inst];
return switch (air.instructions.items(.tag)[inst]) {
const data = air.instructions.items(.data)[@intFromEnum(inst)];
return switch (air.instructions.items(.tag)[@intFromEnum(inst)]) {
.arg,
.block,
.loop,

View File

@ -177,31 +177,31 @@ pub fn analyze(gpa: Allocator, air: Air, intern_pool: *const InternPool) Allocat
}
pub fn getTombBits(l: Liveness, inst: Air.Inst.Index) Bpi {
const usize_index = (inst * bpi) / @bitSizeOf(usize);
const usize_index = (@intFromEnum(inst) * bpi) / @bitSizeOf(usize);
return @as(Bpi, @truncate(l.tomb_bits[usize_index] >>
@as(Log2Int(usize), @intCast((inst % (@bitSizeOf(usize) / bpi)) * bpi))));
@as(Log2Int(usize), @intCast((@intFromEnum(inst) % (@bitSizeOf(usize) / bpi)) * bpi))));
}
pub fn isUnused(l: Liveness, inst: Air.Inst.Index) bool {
const usize_index = (inst * bpi) / @bitSizeOf(usize);
const usize_index = (@intFromEnum(inst) * bpi) / @bitSizeOf(usize);
const mask = @as(usize, 1) <<
@as(Log2Int(usize), @intCast((inst % (@bitSizeOf(usize) / bpi)) * bpi + (bpi - 1)));
@as(Log2Int(usize), @intCast((@intFromEnum(inst) % (@bitSizeOf(usize) / bpi)) * bpi + (bpi - 1)));
return (l.tomb_bits[usize_index] & mask) != 0;
}
pub fn operandDies(l: Liveness, inst: Air.Inst.Index, operand: OperandInt) bool {
assert(operand < bpi - 1);
const usize_index = (inst * bpi) / @bitSizeOf(usize);
const usize_index = (@intFromEnum(inst) * bpi) / @bitSizeOf(usize);
const mask = @as(usize, 1) <<
@as(Log2Int(usize), @intCast((inst % (@bitSizeOf(usize) / bpi)) * bpi + operand));
@as(Log2Int(usize), @intCast((@intFromEnum(inst) % (@bitSizeOf(usize) / bpi)) * bpi + operand));
return (l.tomb_bits[usize_index] & mask) != 0;
}
pub fn clearOperandDeath(l: Liveness, inst: Air.Inst.Index, operand: OperandInt) void {
assert(operand < bpi - 1);
const usize_index = (inst * bpi) / @bitSizeOf(usize);
const usize_index = (@intFromEnum(inst) * bpi) / @bitSizeOf(usize);
const mask = @as(usize, 1) <<
@as(Log2Int(usize), @intCast((inst % (@bitSizeOf(usize) / bpi)) * bpi + operand));
@as(Log2Int(usize), @intCast((@intFromEnum(inst) % (@bitSizeOf(usize) / bpi)) * bpi + operand));
l.tomb_bits[usize_index] &= ~mask;
}
@ -229,8 +229,8 @@ pub fn categorizeOperand(
) OperandCategory {
const air_tags = air.instructions.items(.tag);
const air_datas = air.instructions.items(.data);
const operand_ref = Air.indexToRef(operand);
switch (air_tags[inst]) {
const operand_ref = operand.toRef();
switch (air_tags[@intFromEnum(inst)]) {
.add,
.add_safe,
.add_wrap,
@ -287,7 +287,7 @@ pub fn categorizeOperand(
.cmp_gt_optimized,
.cmp_neq_optimized,
=> {
const o = air_datas[inst].bin_op;
const o = air_datas[@intFromEnum(inst)].bin_op;
if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (o.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
return .none;
@ -304,14 +304,14 @@ pub fn categorizeOperand(
.memset_safe,
.memcpy,
=> {
const o = air_datas[inst].bin_op;
const o = air_datas[@intFromEnum(inst)].bin_op;
if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
if (o.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write);
return .write;
},
.vector_store_elem => {
const o = air_datas[inst].vector_store_elem;
const o = air_datas[@intFromEnum(inst)].vector_store_elem;
const extra = air.extraData(Air.Bin, o.payload).data;
if (o.vector_ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
@ -386,7 +386,7 @@ pub fn categorizeOperand(
.c_va_copy,
.abs,
=> {
const o = air_datas[inst].ty_op;
const o = air_datas[@intFromEnum(inst)].ty_op;
if (o.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
@ -394,7 +394,7 @@ pub fn categorizeOperand(
.optional_payload_ptr_set,
.errunion_payload_ptr_set,
=> {
const o = air_datas[inst].ty_op;
const o = air_datas[@intFromEnum(inst)].ty_op;
if (o.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
return .write;
},
@ -429,7 +429,7 @@ pub fn categorizeOperand(
.cmp_lt_errors_len,
.c_va_end,
=> {
const o = air_datas[inst].un_op;
const o = air_datas[@intFromEnum(inst)].un_op;
if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
@ -437,13 +437,13 @@ pub fn categorizeOperand(
.ret,
.ret_load,
=> {
const o = air_datas[inst].un_op;
const o = air_datas[@intFromEnum(inst)].un_op;
if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .noret);
return .noret;
},
.set_err_return_trace => {
const o = air_datas[inst].un_op;
const o = air_datas[@intFromEnum(inst)].un_op;
if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
return .write;
},
@ -458,7 +458,7 @@ pub fn categorizeOperand(
.slice_elem_ptr,
.slice,
=> {
const ty_pl = air_datas[inst].ty_pl;
const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
const extra = air.extraData(Air.Bin, ty_pl.payload).data;
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
@ -468,19 +468,19 @@ pub fn categorizeOperand(
.dbg_var_ptr,
.dbg_var_val,
=> {
const o = air_datas[inst].pl_op.operand;
const o = air_datas[@intFromEnum(inst)].pl_op.operand;
if (o == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.prefetch => {
const prefetch = air_datas[inst].prefetch;
const prefetch = air_datas[@intFromEnum(inst)].prefetch;
if (prefetch.ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
const inst_data = air_datas[inst].pl_op;
const inst_data = air_datas[@intFromEnum(inst)].pl_op;
const callee = inst_data.operand;
const extra = air.extraData(Air.Call, inst_data.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(air.extra[extra.end..][0..extra.data.args_len]));
@ -507,7 +507,7 @@ pub fn categorizeOperand(
return .write;
},
.select => {
const pl_op = air_datas[inst].pl_op;
const pl_op = air_datas[@intFromEnum(inst)].pl_op;
const extra = air.extraData(Air.Bin, pl_op.payload).data;
if (pl_op.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
@ -515,25 +515,25 @@ pub fn categorizeOperand(
return .none;
},
.shuffle => {
const extra = air.extraData(Air.Shuffle, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.Shuffle, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.a == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (extra.b == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
return .none;
},
.reduce, .reduce_optimized => {
const reduce = air_datas[inst].reduce;
const reduce = air_datas[@intFromEnum(inst)].reduce;
if (reduce.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.cmp_vector, .cmp_vector_optimized => {
const extra = air.extraData(Air.VectorCmp, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.VectorCmp, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
return .none;
},
.aggregate_init => {
const ty_pl = air_datas[inst].ty_pl;
const aggregate_ty = air.getRefType(ty_pl.ty);
const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
const aggregate_ty = ty_pl.ty.toType();
const len = @as(usize, @intCast(aggregate_ty.arrayLenIp(ip)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(air.extra[ty_pl.payload..][0..len]));
@ -555,29 +555,29 @@ pub fn categorizeOperand(
return .write;
},
.union_init => {
const extra = air.extraData(Air.UnionInit, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.UnionInit, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.init == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.struct_field_ptr, .struct_field_val => {
const extra = air.extraData(Air.StructField, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.StructField, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.struct_operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.field_parent_ptr => {
const extra = air.extraData(Air.FieldParentPtr, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.FieldParentPtr, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.field_ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.cmpxchg_strong, .cmpxchg_weak => {
const extra = air.extraData(Air.Cmpxchg, air_datas[inst].ty_pl.payload).data;
const extra = air.extraData(Air.Cmpxchg, air_datas[@intFromEnum(inst)].ty_pl.payload).data;
if (extra.ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
if (extra.expected_value == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write);
if (extra.new_value == operand_ref) return matchOperandSmallIndex(l, inst, 2, .write);
return .write;
},
.mul_add => {
const pl_op = air_datas[inst].pl_op;
const pl_op = air_datas[@intFromEnum(inst)].pl_op;
const extra = air.extraData(Air.Bin, pl_op.payload).data;
if (extra.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
if (extra.rhs == operand_ref) return matchOperandSmallIndex(l, inst, 1, .none);
@ -585,12 +585,12 @@ pub fn categorizeOperand(
return .none;
},
.atomic_load => {
const ptr = air_datas[inst].atomic_load.ptr;
const ptr = air_datas[@intFromEnum(inst)].atomic_load.ptr;
if (ptr == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
.atomic_rmw => {
const pl_op = air_datas[inst].pl_op;
const pl_op = air_datas[@intFromEnum(inst)].pl_op;
const extra = air.extraData(Air.AtomicRmw, pl_op.payload).data;
if (pl_op.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .write);
if (extra.operand == operand_ref) return matchOperandSmallIndex(l, inst, 1, .write);
@ -598,7 +598,7 @@ pub fn categorizeOperand(
},
.br => {
const br = air_datas[inst].br;
const br = air_datas[@intFromEnum(inst)].br;
if (br.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .noret);
return .noret;
},
@ -606,16 +606,16 @@ pub fn categorizeOperand(
return .complex;
},
.block => {
const extra = air.extraData(Air.Block, air_datas[inst].ty_pl.payload);
const body = air.extra[extra.end..][0..extra.data.body_len];
const extra = air.extraData(Air.Block, air_datas[@intFromEnum(inst)].ty_pl.payload);
const body: []const Air.Inst.Index = @ptrCast(air.extra[extra.end..][0..extra.data.body_len]);
if (body.len == 1 and air_tags[body[0]] == .cond_br) {
if (body.len == 1 and air_tags[@intFromEnum(body[0])] == .cond_br) {
// Peephole optimization for "panic-like" conditionals, which have
// one empty branch and another which calls a `noreturn` function.
// This allows us to infer that safety checks do not modify memory,
// as far as control flow successors are concerned.
const inst_data = air_datas[body[0]].pl_op;
const inst_data = air_datas[@intFromEnum(body[0])].pl_op;
const cond_extra = air.extraData(Air.CondBr, inst_data.payload);
if (inst_data.operand == operand_ref and operandDies(l, body[0], 0))
return .tomb;
@ -623,21 +623,21 @@ pub fn categorizeOperand(
if (cond_extra.data.then_body_len > 2 or cond_extra.data.else_body_len > 2)
return .complex;
const then_body = air.extra[cond_extra.end..][0..cond_extra.data.then_body_len];
const else_body = air.extra[cond_extra.end + cond_extra.data.then_body_len ..][0..cond_extra.data.else_body_len];
if (then_body.len > 1 and air_tags[then_body[1]] != .unreach)
const then_body: []const Air.Inst.Index = @ptrCast(air.extra[cond_extra.end..][0..cond_extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(air.extra[cond_extra.end + cond_extra.data.then_body_len ..][0..cond_extra.data.else_body_len]);
if (then_body.len > 1 and air_tags[@intFromEnum(then_body[1])] != .unreach)
return .complex;
if (else_body.len > 1 and air_tags[else_body[1]] != .unreach)
if (else_body.len > 1 and air_tags[@intFromEnum(else_body[1])] != .unreach)
return .complex;
var operand_live: bool = true;
for (&[_]u32{ then_body[0], else_body[0] }) |cond_inst| {
for (&[_]Air.Inst.Index{ then_body[0], else_body[0] }) |cond_inst| {
if (l.categorizeOperand(air, cond_inst, operand, ip) == .tomb)
operand_live = false;
switch (air_tags[cond_inst]) {
switch (air_tags[@intFromEnum(cond_inst)]) {
.br => { // Breaks immediately back to block
const br = air_datas[cond_inst].br;
const br = air_datas[@intFromEnum(cond_inst)].br;
if (br.block_inst != inst)
return .complex;
},
@ -666,7 +666,7 @@ pub fn categorizeOperand(
return .complex;
},
.wasm_memory_grow => {
const pl_op = air_datas[inst].pl_op;
const pl_op = air_datas[@intFromEnum(inst)].pl_op;
if (pl_op.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
return .none;
},
@ -701,11 +701,11 @@ pub fn getCondBr(l: Liveness, inst: Air.Inst.Index) CondBrSlices {
index += 1;
const else_death_count = l.extra[index];
index += 1;
const then_deaths = l.extra[index..][0..then_death_count];
const then_deaths: []const Air.Inst.Index = @ptrCast(l.extra[index..][0..then_death_count]);
index += then_death_count;
return .{
.then_deaths = then_deaths,
.else_deaths = l.extra[index..][0..else_death_count],
.else_deaths = @ptrCast(l.extra[index..][0..else_death_count]),
};
}
@ -731,13 +731,13 @@ pub fn getSwitchBr(l: Liveness, gpa: Allocator, inst: Air.Inst.Index, cases_len:
while (case_i < cases_len - 1) : (case_i += 1) {
const case_death_count: u32 = l.extra[index];
index += 1;
const case_deaths = l.extra[index..][0..case_death_count];
const case_deaths: []const Air.Inst.Index = @ptrCast(l.extra[index..][0..case_death_count]);
index += case_death_count;
deaths.appendAssumeCapacity(case_deaths);
}
{
// Else
const else_deaths = l.extra[index..][0..else_death_count];
const else_deaths: []const Air.Inst.Index = @ptrCast(l.extra[index..][0..else_death_count]);
deaths.appendAssumeCapacity(else_deaths);
}
return SwitchBrTable{
@ -756,7 +756,7 @@ pub fn getBlock(l: Liveness, inst: Air.Inst.Index) BlockSlices {
.deaths = &.{},
};
const death_count = l.extra[index];
const deaths = l.extra[index + 1 ..][0..death_count];
const deaths: []const Air.Inst.Index = @ptrCast(l.extra[index + 1 ..][0..death_count]);
return .{
.deaths = deaths,
};
@ -883,7 +883,7 @@ fn analyzeInst(
const inst_tags = a.air.instructions.items(.tag);
const inst_datas = a.air.instructions.items(.data);
switch (inst_tags[inst]) {
switch (inst_tags[@intFromEnum(inst)]) {
.add,
.add_safe,
.add_optimized,
@ -949,12 +949,12 @@ fn analyzeInst(
.memset_safe,
.memcpy,
=> {
const o = inst_datas[inst].bin_op;
const o = inst_datas[@intFromEnum(inst)].bin_op;
return analyzeOperands(a, pass, data, inst, .{ o.lhs, o.rhs, .none });
},
.vector_store_elem => {
const o = inst_datas[inst].vector_store_elem;
const o = inst_datas[@intFromEnum(inst)].vector_store_elem;
const extra = a.air.extraData(Air.Bin, o.payload).data;
return analyzeOperands(a, pass, data, inst, .{ o.vector_ptr, extra.lhs, extra.rhs });
},
@ -1029,7 +1029,7 @@ fn analyzeInst(
.c_va_copy,
.abs,
=> {
const o = inst_datas[inst].ty_op;
const o = inst_datas[@intFromEnum(inst)].ty_op;
return analyzeOperands(a, pass, data, inst, .{ o.operand, .none, .none });
},
@ -1065,14 +1065,14 @@ fn analyzeInst(
.set_err_return_trace,
.c_va_end,
=> {
const operand = inst_datas[inst].un_op;
const operand = inst_datas[@intFromEnum(inst)].un_op;
return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none });
},
.ret,
.ret_load,
=> {
const operand = inst_datas[inst].un_op;
const operand = inst_datas[@intFromEnum(inst)].un_op;
return analyzeFuncEnd(a, pass, data, inst, .{ operand, .none, .none });
},
@ -1086,7 +1086,7 @@ fn analyzeInst(
.slice_elem_ptr,
.slice,
=> {
const ty_pl = inst_datas[inst].ty_pl;
const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl;
const extra = a.air.extraData(Air.Bin, ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.lhs, extra.rhs, .none });
},
@ -1094,17 +1094,17 @@ fn analyzeInst(
.dbg_var_ptr,
.dbg_var_val,
=> {
const operand = inst_datas[inst].pl_op.operand;
const operand = inst_datas[@intFromEnum(inst)].pl_op.operand;
return analyzeOperands(a, pass, data, inst, .{ operand, .none, .none });
},
.prefetch => {
const prefetch = inst_datas[inst].prefetch;
const prefetch = inst_datas[@intFromEnum(inst)].prefetch;
return analyzeOperands(a, pass, data, inst, .{ prefetch.ptr, .none, .none });
},
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
const inst_data = inst_datas[inst].pl_op;
const inst_data = inst_datas[@intFromEnum(inst)].pl_op;
const callee = inst_data.operand;
const extra = a.air.extraData(Air.Call, inst_data.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(a.air.extra[extra.end..][0..extra.data.args_len]));
@ -1126,25 +1126,25 @@ fn analyzeInst(
return big.finish();
},
.select => {
const pl_op = inst_datas[inst].pl_op;
const pl_op = inst_datas[@intFromEnum(inst)].pl_op;
const extra = a.air.extraData(Air.Bin, pl_op.payload).data;
return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.lhs, extra.rhs });
},
.shuffle => {
const extra = a.air.extraData(Air.Shuffle, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.Shuffle, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.a, extra.b, .none });
},
.reduce, .reduce_optimized => {
const reduce = inst_datas[inst].reduce;
const reduce = inst_datas[@intFromEnum(inst)].reduce;
return analyzeOperands(a, pass, data, inst, .{ reduce.operand, .none, .none });
},
.cmp_vector, .cmp_vector_optimized => {
const extra = a.air.extraData(Air.VectorCmp, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.VectorCmp, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.lhs, extra.rhs, .none });
},
.aggregate_init => {
const ty_pl = inst_datas[inst].ty_pl;
const aggregate_ty = a.air.getRefType(ty_pl.ty);
const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl;
const aggregate_ty = ty_pl.ty.toType();
const len = @as(usize, @intCast(aggregate_ty.arrayLenIp(ip)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(a.air.extra[ty_pl.payload..][0..len]));
@ -1164,32 +1164,32 @@ fn analyzeInst(
return big.finish();
},
.union_init => {
const extra = a.air.extraData(Air.UnionInit, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.UnionInit, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.init, .none, .none });
},
.struct_field_ptr, .struct_field_val => {
const extra = a.air.extraData(Air.StructField, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.StructField, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.struct_operand, .none, .none });
},
.field_parent_ptr => {
const extra = a.air.extraData(Air.FieldParentPtr, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.FieldParentPtr, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.field_ptr, .none, .none });
},
.cmpxchg_strong, .cmpxchg_weak => {
const extra = a.air.extraData(Air.Cmpxchg, inst_datas[inst].ty_pl.payload).data;
const extra = a.air.extraData(Air.Cmpxchg, inst_datas[@intFromEnum(inst)].ty_pl.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.ptr, extra.expected_value, extra.new_value });
},
.mul_add => {
const pl_op = inst_datas[inst].pl_op;
const pl_op = inst_datas[@intFromEnum(inst)].pl_op;
const extra = a.air.extraData(Air.Bin, pl_op.payload).data;
return analyzeOperands(a, pass, data, inst, .{ extra.lhs, extra.rhs, pl_op.operand });
},
.atomic_load => {
const ptr = inst_datas[inst].atomic_load.ptr;
const ptr = inst_datas[@intFromEnum(inst)].atomic_load.ptr;
return analyzeOperands(a, pass, data, inst, .{ ptr, .none, .none });
},
.atomic_rmw => {
const pl_op = inst_datas[inst].pl_op;
const pl_op = inst_datas[@intFromEnum(inst)].pl_op;
const extra = a.air.extraData(Air.AtomicRmw, pl_op.payload).data;
return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, extra.operand, .none });
},
@ -1197,7 +1197,7 @@ fn analyzeInst(
.br => return analyzeInstBr(a, pass, data, inst),
.assembly => {
const extra = a.air.extraData(Air.Asm, inst_datas[inst].ty_pl.payload);
const extra = a.air.extraData(Air.Asm, inst_datas[@intFromEnum(inst)].ty_pl.payload);
var extra_i: usize = extra.end;
const outputs = @as([]const Air.Inst.Ref, @ptrCast(a.air.extra[extra_i..][0..extra.data.outputs_len]));
extra_i += outputs.len;
@ -1246,7 +1246,7 @@ fn analyzeInst(
.switch_br => return analyzeInstSwitchBr(a, pass, data, inst),
.wasm_memory_grow => {
const pl_op = inst_datas[inst].pl_op;
const pl_op = inst_datas[@intFromEnum(inst)].pl_op;
return analyzeOperands(a, pass, data, inst, .{ pl_op.operand, .none, .none });
},
}
@ -1270,20 +1270,20 @@ fn analyzeOperands(
_ = data.live_set.remove(inst);
for (operands) |op_ref| {
const operand = Air.refToIndexAllowNone(op_ref) orelse continue;
const operand = op_ref.toIndexAllowNone() orelse continue;
_ = try data.live_set.put(gpa, operand, {});
}
},
.main_analysis => {
const usize_index = (inst * bpi) / @bitSizeOf(usize);
const usize_index = (@intFromEnum(inst) * bpi) / @bitSizeOf(usize);
// This logic must synchronize with `will_die_immediately` in `AnalyzeBigOperands.init`.
const immediate_death = if (data.live_set.remove(inst)) blk: {
log.debug("[{}] %{}: removed from live set", .{ pass, inst });
log.debug("[{}] %{}: removed from live set", .{ pass, @intFromEnum(inst) });
break :blk false;
} else blk: {
log.debug("[{}] %{}: immediate death", .{ pass, inst });
log.debug("[{}] %{}: immediate death", .{ pass, @intFromEnum(inst) });
break :blk true;
};
@ -1299,19 +1299,19 @@ fn analyzeOperands(
while (i > 0) {
i -= 1;
const op_ref = operands[i];
const operand = Air.refToIndexAllowNone(op_ref) orelse continue;
const operand = op_ref.toIndexAllowNone() orelse continue;
const mask = @as(Bpi, 1) << @as(OperandInt, @intCast(i));
if ((try data.live_set.fetchPut(gpa, operand, {})) == null) {
log.debug("[{}] %{}: added %{} to live set (operand dies here)", .{ pass, inst, operand });
log.debug("[{}] %{}: added %{} to live set (operand dies here)", .{ pass, @intFromEnum(inst), operand });
tomb_bits |= mask;
}
}
}
a.tomb_bits[usize_index] |= @as(usize, tomb_bits) <<
@as(Log2Int(usize), @intCast((inst % (@bitSizeOf(usize) / bpi)) * bpi));
@as(Log2Int(usize), @intCast((@intFromEnum(inst) % (@bitSizeOf(usize) / bpi)) * bpi));
},
}
}
@ -1346,7 +1346,7 @@ fn analyzeInstBr(
inst: Air.Inst.Index,
) !void {
const inst_datas = a.air.instructions.items(.data);
const br = inst_datas[inst].br;
const br = inst_datas[@intFromEnum(inst)].br;
const gpa = a.gpa;
switch (pass) {
@ -1373,9 +1373,9 @@ fn analyzeInstBlock(
inst: Air.Inst.Index,
) !void {
const inst_datas = a.air.instructions.items(.data);
const ty_pl = inst_datas[inst].ty_pl;
const ty_pl = inst_datas[@intFromEnum(inst)].ty_pl;
const extra = a.air.extraData(Air.Block, ty_pl.payload);
const body = a.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len]);
const gpa = a.gpa;
@ -1405,7 +1405,7 @@ fn analyzeInstBlock(
// If the block is noreturn, block deaths not only aren't useful, they're impossible to
// find: there could be more stuff alive after the block than before it!
if (!a.intern_pool.isNoReturn(a.air.getRefType(ty_pl.ty).ip_index)) {
if (!a.intern_pool.isNoReturn(ty_pl.ty.toType().ip_index)) {
// The block kills the difference in the live sets
const block_scope = data.block_scopes.get(inst).?;
const num_deaths = data.live_set.count() - block_scope.live_set.count();
@ -1421,7 +1421,7 @@ fn analyzeInstBlock(
const alive = key.*;
if (!block_scope.live_set.contains(alive)) {
// Dies in block
a.extra.appendAssumeCapacity(alive);
a.extra.appendAssumeCapacity(@intFromEnum(alive));
measured_num += 1;
}
}
@ -1430,7 +1430,7 @@ fn analyzeInstBlock(
log.debug("[{}] %{}: block deaths are {}", .{
pass,
inst,
fmtInstList(a.extra.items[extra_index + 1 ..][0..num_deaths]),
fmtInstList(@ptrCast(a.extra.items[extra_index + 1 ..][0..num_deaths])),
});
}
},
@ -1444,8 +1444,8 @@ fn analyzeInstLoop(
inst: Air.Inst.Index,
) !void {
const inst_datas = a.air.instructions.items(.data);
const extra = a.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);
const body = a.air.extra[extra.end..][0..extra.data.body_len];
const extra = a.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
const body: []const Air.Inst.Index = @ptrCast(a.air.extra[extra.end..][0..extra.data.body_len]);
const gpa = a.gpa;
try analyzeOperands(a, pass, data, inst, .{ .none, .none, .none });
@ -1469,7 +1469,7 @@ fn analyzeInstLoop(
var it = data.breaks.keyIterator();
while (it.next()) |key| {
const block_inst = key.*;
a.extra.appendAssumeCapacity(block_inst);
a.extra.appendAssumeCapacity(@intFromEnum(block_inst));
}
log.debug("[{}] %{}: includes breaks to {}", .{ pass, inst, fmtInstSet(&data.breaks) });
@ -1481,7 +1481,7 @@ fn analyzeInstLoop(
it = data.live_set.keyIterator();
while (it.next()) |key| {
const alive = key.*;
a.extra.appendAssumeCapacity(alive);
a.extra.appendAssumeCapacity(@intFromEnum(alive));
}
log.debug("[{}] %{}: maintain liveness of {}", .{ pass, inst, fmtInstSet(&data.live_set) });
@ -1506,15 +1506,15 @@ fn analyzeInstLoop(
const extra_idx = a.special.fetchRemove(inst).?.value; // remove because this data does not exist after analysis
const num_breaks = data.old_extra.items[extra_idx];
const breaks = data.old_extra.items[extra_idx + 1 ..][0..num_breaks];
const breaks: []const Air.Inst.Index = @ptrCast(data.old_extra.items[extra_idx + 1 ..][0..num_breaks]);
const num_loop_live = data.old_extra.items[extra_idx + num_breaks + 1];
const loop_live = data.old_extra.items[extra_idx + num_breaks + 2 ..][0..num_loop_live];
const loop_live: []const Air.Inst.Index = @ptrCast(data.old_extra.items[extra_idx + num_breaks + 2 ..][0..num_loop_live]);
// This is necessarily not in the same control flow branch, because loops are noreturn
data.live_set.clearRetainingCapacity();
try data.live_set.ensureUnusedCapacity(gpa, @as(u32, @intCast(loop_live.len)));
try data.live_set.ensureUnusedCapacity(gpa, @intCast(loop_live.len));
for (loop_live) |alive| {
data.live_set.putAssumeCapacity(alive, {});
}
@ -1551,25 +1551,25 @@ fn analyzeInstCondBr(
const gpa = a.gpa;
const extra = switch (inst_type) {
.cond_br => a.air.extraData(Air.CondBr, inst_datas[inst].pl_op.payload),
.@"try" => a.air.extraData(Air.Try, inst_datas[inst].pl_op.payload),
.try_ptr => a.air.extraData(Air.TryPtr, inst_datas[inst].ty_pl.payload),
.cond_br => a.air.extraData(Air.CondBr, inst_datas[@intFromEnum(inst)].pl_op.payload),
.@"try" => a.air.extraData(Air.Try, inst_datas[@intFromEnum(inst)].pl_op.payload),
.try_ptr => a.air.extraData(Air.TryPtr, inst_datas[@intFromEnum(inst)].ty_pl.payload),
};
const condition = switch (inst_type) {
.cond_br, .@"try" => inst_datas[inst].pl_op.operand,
.cond_br, .@"try" => inst_datas[@intFromEnum(inst)].pl_op.operand,
.try_ptr => extra.data.ptr,
};
const then_body = switch (inst_type) {
.cond_br => a.air.extra[extra.end..][0..extra.data.then_body_len],
else => {}, // we won't use this
const then_body: []const Air.Inst.Index = switch (inst_type) {
.cond_br => @ptrCast(a.air.extra[extra.end..][0..extra.data.then_body_len]),
else => &.{}, // we won't use this
};
const else_body = switch (inst_type) {
const else_body: []const Air.Inst.Index = @ptrCast(switch (inst_type) {
.cond_br => a.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len],
.@"try", .try_ptr => a.air.extra[extra.end..][0..extra.data.body_len],
};
});
switch (pass) {
.loop_analysis => {
@ -1645,8 +1645,8 @@ fn analyzeInstCondBr(
.then_death_count = then_death_count,
.else_death_count = else_death_count,
});
a.extra.appendSliceAssumeCapacity(then_mirrored_deaths.items);
a.extra.appendSliceAssumeCapacity(else_mirrored_deaths.items);
a.extra.appendSliceAssumeCapacity(@ptrCast(then_mirrored_deaths.items));
a.extra.appendSliceAssumeCapacity(@ptrCast(else_mirrored_deaths.items));
try a.special.put(gpa, inst, extra_index);
},
}
@ -1661,7 +1661,7 @@ fn analyzeInstSwitchBr(
inst: Air.Inst.Index,
) !void {
const inst_datas = a.air.instructions.items(.data);
const pl_op = inst_datas[inst].pl_op;
const pl_op = inst_datas[@intFromEnum(inst)].pl_op;
const condition = pl_op.operand;
const switch_br = a.air.extraData(Air.SwitchBr, pl_op.payload);
const gpa = a.gpa;
@ -1672,12 +1672,12 @@ fn analyzeInstSwitchBr(
var air_extra_index: usize = switch_br.end;
for (0..ncases) |_| {
const case = a.air.extraData(Air.SwitchBr.Case, air_extra_index);
const case_body = a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len]);
air_extra_index = case.end + case.data.items_len + case_body.len;
try analyzeBody(a, pass, data, case_body);
}
{ // else
const else_body = a.air.extra[air_extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(a.air.extra[air_extra_index..][0..switch_br.data.else_body_len]);
try analyzeBody(a, pass, data, else_body);
}
},
@ -1698,13 +1698,13 @@ fn analyzeInstSwitchBr(
var air_extra_index: usize = switch_br.end;
for (case_live_sets[0..ncases]) |*live_set| {
const case = a.air.extraData(Air.SwitchBr.Case, air_extra_index);
const case_body = a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(a.air.extra[case.end + case.data.items_len ..][0..case.data.body_len]);
air_extra_index = case.end + case.data.items_len + case_body.len;
try analyzeBody(a, pass, data, case_body);
live_set.* = data.live_set.move();
}
{ // else
const else_body = a.air.extra[air_extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(a.air.extra[air_extra_index..][0..switch_br.data.else_body_len]);
try analyzeBody(a, pass, data, else_body);
case_live_sets[ncases] = data.live_set.move();
}
@ -1757,10 +1757,10 @@ fn analyzeInstSwitchBr(
const num = @as(u32, @intCast(mirrored.items.len));
try a.extra.ensureUnusedCapacity(gpa, num + 1);
a.extra.appendAssumeCapacity(num);
a.extra.appendSliceAssumeCapacity(mirrored.items);
a.extra.appendSliceAssumeCapacity(@ptrCast(mirrored.items));
}
try a.extra.ensureUnusedCapacity(gpa, else_death_count);
a.extra.appendSliceAssumeCapacity(mirrored_deaths[ncases].items);
a.extra.appendSliceAssumeCapacity(@ptrCast(mirrored_deaths[ncases].items));
try a.special.put(gpa, inst, extra_index);
},
}
@ -1826,7 +1826,7 @@ fn AnalyzeBigOperands(comptime pass: LivenessPass) type {
return;
}
const operand = Air.refToIndex(op_ref) orelse return;
const operand = op_ref.toIndex() orelse return;
// If our result is unused and the instruction doesn't need to be lowered, backends will
// skip the lowering of this instruction, so we don't want to record uses of operands.

View File

@ -37,7 +37,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
continue;
}
switch (tag[inst]) {
switch (tag[@intFromEnum(inst)]) {
// no operands
.arg,
.alloc,
@ -112,7 +112,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.c_va_copy,
.abs,
=> {
const ty_op = data[inst].ty_op;
const ty_op = data[@intFromEnum(inst)].ty_op;
try self.verifyInstOperands(inst, .{ ty_op.operand, .none, .none });
},
.is_null,
@ -147,13 +147,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.set_err_return_trace,
.c_va_end,
=> {
const un_op = data[inst].un_op;
const un_op = data[@intFromEnum(inst)].un_op;
try self.verifyInstOperands(inst, .{ un_op, .none, .none });
},
.ret,
.ret_load,
=> {
const un_op = data[inst].un_op;
const un_op = data[@intFromEnum(inst)].un_op;
try self.verifyInstOperands(inst, .{ un_op, .none, .none });
// This instruction terminates the function, so everything should be dead
if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
@ -162,36 +162,36 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.dbg_var_val,
.wasm_memory_grow,
=> {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
try self.verifyInstOperands(inst, .{ pl_op.operand, .none, .none });
},
.prefetch => {
const prefetch = data[inst].prefetch;
const prefetch = data[@intFromEnum(inst)].prefetch;
try self.verifyInstOperands(inst, .{ prefetch.ptr, .none, .none });
},
.reduce,
.reduce_optimized,
=> {
const reduce = data[inst].reduce;
const reduce = data[@intFromEnum(inst)].reduce;
try self.verifyInstOperands(inst, .{ reduce.operand, .none, .none });
},
.union_init => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.init, .none, .none });
},
.struct_field_ptr, .struct_field_val => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.struct_operand, .none, .none });
},
.field_parent_ptr => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.field_ptr, .none, .none });
},
.atomic_load => {
const atomic_load = data[inst].atomic_load;
const atomic_load = data[@intFromEnum(inst)].atomic_load;
try self.verifyInstOperands(inst, .{ atomic_load.ptr, .none, .none });
},
@ -261,7 +261,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.memset_safe,
.memcpy,
=> {
const bin_op = data[inst].bin_op;
const bin_op = data[@intFromEnum(inst)].bin_op;
try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none });
},
.add_with_overflow,
@ -274,56 +274,56 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.slice_elem_ptr,
.slice,
=> {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
},
.shuffle => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none });
},
.cmp_vector,
.cmp_vector_optimized,
=> {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
},
.atomic_rmw => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
try self.verifyInstOperands(inst, .{ pl_op.operand, extra.operand, .none });
},
// ternary
.select => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
try self.verifyInstOperands(inst, .{ pl_op.operand, extra.lhs, extra.rhs });
},
.mul_add => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, pl_op.operand });
},
.vector_store_elem => {
const vector_store_elem = data[inst].vector_store_elem;
const vector_store_elem = data[@intFromEnum(inst)].vector_store_elem;
const extra = self.air.extraData(Air.Bin, vector_store_elem.payload).data;
try self.verifyInstOperands(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs });
},
.cmpxchg_strong,
.cmpxchg_weak,
=> {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
try self.verifyInstOperands(inst, .{ extra.ptr, extra.expected_value, extra.new_value });
},
// big tombs
.aggregate_init => {
const ty_pl = data[inst].ty_pl;
const aggregate_ty = self.air.getRefType(ty_pl.ty);
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const aggregate_ty = ty_pl.ty.toType();
const len = @as(usize, @intCast(aggregate_ty.arrayLenIp(ip)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
@ -334,7 +334,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.call, .call_always_tail, .call_never_tail, .call_never_inline => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @as(
[]const Air.Inst.Ref,
@ -349,7 +349,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.assembly => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
var extra_i = extra.end;
const outputs = @as(
@ -377,9 +377,9 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
// control flow
.@"try" => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Try, pl_op.payload);
const try_body = self.air.extra[extra.end..][0..extra.data.body_len];
const try_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const cond_br_liveness = self.liveness.getCondBr(inst);
@ -399,9 +399,9 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.try_ptr => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
const try_body = self.air.extra[extra.end..][0..extra.data.body_len];
const try_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const cond_br_liveness = self.liveness.getCondBr(inst);
@ -421,7 +421,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.br => {
const br = data[inst].br;
const br = data[@intFromEnum(inst)].br;
const gop = try self.blocks.getOrPut(self.gpa, br.block_inst);
try self.verifyOperand(inst, br.operand, self.liveness.operandDies(inst, 0));
@ -433,10 +433,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.block => {
const ty_pl = data[inst].ty_pl;
const block_ty = self.air.getRefType(ty_pl.ty);
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const block_ty = ty_pl.ty.toType();
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const block_body = self.air.extra[extra.end..][0..extra.data.body_len];
const block_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const block_liveness = self.liveness.getBlock(inst);
var orig_live = try self.live.clone(self.gpa);
@ -464,9 +464,9 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInstOperands(inst, .{ .none, .none, .none });
},
.loop => {
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const loop_body = self.air.extra[extra.end..][0..extra.data.body_len];
const loop_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
var live = try self.live.clone(self.gpa);
defer live.deinit(self.gpa);
@ -479,10 +479,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInstOperands(inst, .{ .none, .none, .none });
},
.cond_br => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.CondBr, pl_op.payload);
const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const cond_br_liveness = self.liveness.getCondBr(inst);
try self.verifyOperand(inst, pl_op.operand, self.liveness.operandDies(inst, 0));
@ -502,7 +502,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyInst(inst);
},
.switch_br => {
const pl_op = data[inst].pl_op;
const pl_op = data[@intFromEnum(inst)].pl_op;
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
var extra_index = switch_br.end;
var case_i: u32 = 0;
@ -524,7 +524,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
[]const Air.Inst.Ref,
@ptrCast(self.air.extra[case.end..][0..case.data.items_len]),
);
const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(self.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + items.len + case_body.len;
self.live.deinit(self.gpa);
@ -534,7 +534,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
try self.verifyBody(case_body);
}
const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);
if (else_body.len > 0) {
self.live.deinit(self.gpa);
self.live = try live.clone(self.gpa);
@ -550,11 +550,11 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
}
fn verifyDeath(self: *Verify, inst: Air.Inst.Index, operand: Air.Inst.Index) Error!void {
try self.verifyOperand(inst, Air.indexToRef(operand), true);
try self.verifyOperand(inst, operand.toRef(), true);
}
fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies: bool) Error!void {
const operand = Air.refToIndexAllowNone(op_ref) orelse {
const operand = op_ref.toIndexAllowNone() orelse {
assert(!dies);
return;
};

View File

@ -4591,8 +4591,8 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
gop.value_ptr.* = Air.internedToRef(opv.toIntern());
continue;
}
const arg_index: u32 = @intCast(sema.air_instructions.len);
gop.value_ptr.* = Air.indexToRef(arg_index);
const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
gop.value_ptr.* = arg_index.toRef();
inner_block.instructions.appendAssumeCapacity(arg_index);
sema.air_instructions.appendAssumeCapacity(.{
.tag = .arg,
@ -4626,7 +4626,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
while (it.next()) |ptr_inst| {
// The lack of a resolve_inferred_alloc means that this instruction
// is unused so it just has to be a no-op.
sema.air_instructions.set(ptr_inst.*, .{
sema.air_instructions.set(@intFromEnum(ptr_inst.*), .{
.tag = .alloc,
.data = .{ .ty = Type.single_const_pointer_to_comptime_int },
});
@ -4659,7 +4659,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
const main_block_index = sema.addExtraAssumeCapacity(Air.Block{
.body_len = @intCast(inner_block.instructions.items.len),
});
sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items);
sema.air_extra.appendSliceAssumeCapacity(@ptrCast(inner_block.instructions.items));
sema.air_extra.items[@intFromEnum(Air.ExtraIndex.main_block)] = main_block_index;
// Resolving inferred error sets is done *before* setting the function

File diff suppressed because it is too large Load Diff

View File

@ -287,7 +287,7 @@ const BigTomb = struct {
fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void {
const dies = bt.lbt.feed();
const op_index = Air.refToIndex(op_ref) orelse return;
const op_index = op_ref.toIndex() orelse return;
if (!dies) return;
bt.function.processDeath(op_index);
}
@ -444,7 +444,7 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
const result_index = @as(Air.Inst.Index, @intCast(self.mir_instructions.len));
const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
self.mir_instructions.appendAssumeCapacity(inst);
return result_index;
}
@ -522,7 +522,7 @@ fn gen(self: *Self) !void {
// The first AIR instructions of the main body are guaranteed
// to be the functions arguments
const inst = self.air.getMainBody()[arg_index];
assert(self.air.instructions.items(.tag)[inst] == .arg);
assert(self.air.instructions.items(.tag)[@intFromEnum(inst)] == .arg);
const ty = self.typeOfIndex(inst);
@ -668,7 +668,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
switch (air_tags[inst]) {
switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
.add => try self.airBinOp(inst, .add),
.add_wrap => try self.airBinOp(inst, .add_wrap),
@ -914,7 +914,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
if (std.debug.runtime_safety) {
if (self.air_bookkeeping < old_air_bookkeeping + 1) {
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[inst] });
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[@intFromEnum(inst)] });
}
}
}
@ -954,7 +954,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
const op_index = Air.refToIndex(op) orelse continue;
const op_index = op.toIndex() orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@ -1160,19 +1160,19 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFptrunc for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFpext for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 });
@ -1277,7 +1277,7 @@ fn trunc(
defer if (lock) |reg| self.register_manager.unlockReg(reg);
const dest_reg = if (maybe_inst) |inst| blk: {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
break :blk self.registerAlias(operand_reg, dest_ty);
@ -1299,7 +1299,7 @@ fn trunc(
}
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try self.resolveInst(ty_op.operand);
const operand_ty = self.typeOf(ty_op.operand);
const dest_ty = self.typeOfIndex(inst);
@ -1312,14 +1312,14 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else operand;
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
@ -1488,8 +1488,8 @@ fn minMax(
}
fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_ty = self.typeOf(bin_op.lhs);
const rhs_ty = self.typeOf(bin_op.rhs);
@ -1506,7 +1506,7 @@ fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr = try self.resolveInst(bin_op.lhs);
@ -1662,7 +1662,7 @@ fn allocRegs(
arg.reg.* = self.registerAlias(raw_reg, arg.ty);
} else {
const track_inst: ?Air.Inst.Index = switch (arg.bind) {
.inst => |inst| Air.refToIndex(inst).?,
.inst => |inst| inst.toIndex().?,
else => null,
};
const raw_reg = try self.register_manager.allocReg(track_inst, gp);
@ -1725,7 +1725,7 @@ fn allocRegs(
if (mcv != .register) {
if (arg.bind == .inst) {
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
const inst = Air.refToIndex(arg.bind.inst).?;
const inst = arg.bind.inst.toIndex().?;
// Overwrite the MCValue associated with this inst
branch.inst_table.putAssumeCapacity(inst, .{ .register = arg.reg.* });
@ -2430,7 +2430,7 @@ fn ptrArithmetic(
}
fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_ty = self.typeOf(bin_op.lhs);
const rhs_ty = self.typeOf(bin_op.rhs);
@ -2480,7 +2480,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
}
fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs_ty = self.typeOf(bin_op.lhs);
const rhs_ty = self.typeOf(bin_op.rhs);
@ -2495,26 +2495,26 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
}
fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
@ -2641,7 +2641,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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.options.module.?;
@ -2865,7 +2865,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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.options.module.?;
@ -3000,13 +3000,13 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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.typeOf(ty_op.operand);
const mcv = try self.resolveInst(ty_op.operand);
@ -3042,13 +3042,13 @@ fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty:
}
fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -3123,7 +3123,7 @@ fn errUnionErr(
}
fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
const error_union_ty = self.typeOf(ty_op.operand);
@ -3203,7 +3203,7 @@ fn errUnionPayload(
}
fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
const error_union_ty = self.typeOf(ty_op.operand);
@ -3215,20 +3215,20 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
// *(E!T) -> E
fn airUnwrapErrErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
// *(E!T) -> *T
fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -3253,7 +3253,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 });
@ -3298,9 +3298,9 @@ fn airWrapOptional(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.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 = self.air.getRefType(ty_op.ty);
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);
@ -3321,10 +3321,10 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
/// E to E!T
fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const error_union_ty = self.air.getRefType(ty_op.ty);
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);
@ -3361,7 +3361,7 @@ fn slicePtr(mcv: MCValue) MCValue {
}
fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(ty_op.operand);
break :result slicePtr(mcv);
@ -3370,7 +3370,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bits = 64;
const ptr_bytes = @divExact(ptr_bits, 8);
@ -3394,7 +3394,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bits = 64;
const ptr_bytes = @divExact(ptr_bits, 8);
@ -3411,7 +3411,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(ty_op.operand);
switch (mcv) {
@ -3427,7 +3427,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
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: {
const ptr_ty = slice_ty.slicePtrFieldType(mod);
@ -3467,7 +3467,7 @@ fn ptrElemVal(
}
fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const slice_mcv = try self.resolveInst(extra.lhs);
@ -3486,14 +3486,14 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
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: {
const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
@ -3505,7 +3505,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr_bind: ReadArg.Bind = .{ .inst = extra.lhs };
@ -3521,55 +3521,55 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
_ = bin_op;
return self.fail("TODO implement airSetUnionTag for {}", .{self.target.cpu.arch});
}
fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airClz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCtz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airAbs for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airByteSwap for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
else
@ -3609,7 +3609,7 @@ fn reuseOperand(
// That makes us responsible for doing the rest of the stuff that processDeath would have done.
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
branch.inst_table.putAssumeCapacity(Air.refToIndex(operand).?, .dead);
branch.inst_table.putAssumeCapacity(operand.toIndex().?, .dead);
return true;
}
@ -3864,7 +3864,7 @@ fn genInlineMemsetCode(
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const elem_ty = self.typeOfIndex(inst);
const elem_size = elem_ty.abiSize(mod);
const result: MCValue = result: {
@ -4066,7 +4066,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
} else {
// TODO if the value is undef, don't lower this instruction
}
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
const ptr_ty = self.typeOf(bin_op.lhs);
@ -4078,14 +4078,14 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
}
fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index);
return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });
}
fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = try self.structFieldPtr(inst, ty_op.operand, index);
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -4112,7 +4112,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
}
fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
const operand = extra.struct_operand;
const index = extra.field_index;
@ -4168,11 +4168,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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: {
const field_ptr = try self.resolveInst(extra.field_ptr);
const struct_ty = self.air.getRefType(ty_pl.ty).childType(mod);
const struct_ty = ty_pl.ty.toType().childType(mod);
const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(extra.field_index, mod)));
switch (field_ptr) {
.ptr_stack_offset => |off| {
@ -4197,8 +4197,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty = self.typeOfIndex(inst);
const tag = self.air.instructions.items(.tag)[inst];
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
const name = mod.getParamName(self.func_index, src_index);
try self.dbg_info_relocs.append(self.gpa, .{
@ -4245,7 +4245,7 @@ fn airFence(self: *Self) !void {
fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
if (modifier == .always_tail) return self.fail("TODO implement tail calls for aarch64", .{});
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
@ -4423,7 +4423,7 @@ 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.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
@ -4455,7 +4455,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const ret_ty = self.fn_type.fnReturnType(mod);
@ -4476,8 +4476,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
// here. Else we need to load the result from the location
// pointed to by the operand and store it to the result
// location.
const op_inst = Air.refToIndex(un_op).?;
if (self.air.instructions.items(.tag)[op_inst] != .ret_ptr) {
const op_inst = un_op.toIndex().?;
if (self.air.instructions.items(.tag)[@intFromEnum(op_inst)] != .ret_ptr) {
const abi_size = @as(u32, @intCast(ret_ty.abiSize(mod)));
const abi_align = ret_ty.abiAlignment(mod);
@ -4497,7 +4497,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
@ -4599,7 +4599,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
_ = operand;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch});
@ -4607,7 +4607,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
_ = try self.addInst(.{
.tag = .dbg_line,
@ -4621,7 +4621,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const mod = self.bin_file.options.module.?;
const func = mod.funcInfo(ty_fn.func);
// TODO emit debug info for function change
@ -4635,9 +4635,9 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const operand = pl_op.operand;
const tag = self.air.instructions.items(.tag)[inst];
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const ty = self.typeOf(operand);
const mcv = try self.resolveInst(operand);
const name = self.air.nullTerminatedString(pl_op.payload);
@ -4686,11 +4686,11 @@ fn condBr(self: *Self, condition: MCValue) !Mir.Inst.Index {
}
fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const cond = try self.resolveInst(pl_op.operand);
const extra = self.air.extraData(Air.CondBr, pl_op.payload);
const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const liveness_condbr = self.liveness.getCondBr(inst);
const reloc = try self.condBr(cond);
@ -4699,7 +4699,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
// that death now instead of later as this has an effect on
// whether it needs to be spilled in the branches
if (self.liveness.operandDies(inst, 0)) {
if (Air.refToIndex(pl_op.operand)) |op_index| {
if (pl_op.operand.toIndex()) |op_index| {
self.processDeath(op_index);
}
}
@ -4917,7 +4917,7 @@ fn isNonErr(
}
fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
const operand_ty = self.typeOf(un_op);
@ -4929,7 +4929,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const ptr_ty = self.typeOf(un_op);
@ -4944,7 +4944,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
const operand_ty = self.typeOf(un_op);
@ -4956,7 +4956,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const ptr_ty = self.typeOf(un_op);
@ -4971,7 +4971,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
const error_union_ty = self.typeOf(un_op);
@ -4983,7 +4983,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const ptr_ty = self.typeOf(un_op);
@ -4998,7 +4998,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
const error_union_ty = self.typeOf(un_op);
@ -5010,7 +5010,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const ptr_ty = self.typeOf(un_op);
@ -5026,9 +5026,9 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
// A loop is a setup to be able to jump back to the beginning.
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
const start_index = @as(u32, @intCast(self.mir_instructions.len));
try self.genBody(body);
@ -5058,9 +5058,9 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
});
defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
try self.genBody(body);
// relocations for `br` instructions
@ -5080,7 +5080,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition_ty = self.typeOf(pl_op.operand);
const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload);
const liveness = try self.liveness.getSwitchBr(
@ -5096,7 +5096,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
const items = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[case.end..][0..case.data.items_len]));
assert(items.len > 0);
const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(self.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + items.len + case_body.len;
// For every item, we compare it to condition and branch into
@ -5167,7 +5167,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
}
if (switch_br.data.else_body_len > 0) {
const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);
// Capture the state of register and stack allocation state so that we can revert to it.
const parent_next_stack_offset = self.next_stack_offset;
@ -5212,15 +5212,15 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
fn performReloc(self: *Self, inst: Mir.Inst.Index) !void {
const tag = self.mir_instructions.items(.tag)[inst];
switch (tag) {
.cbz => self.mir_instructions.items(.data)[inst].r_inst.inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len)),
.b_cond => self.mir_instructions.items(.data)[inst].inst_cond.inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len)),
.b => self.mir_instructions.items(.data)[inst].inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len)),
.cbz => self.mir_instructions.items(.data)[inst].r_inst.inst = @intCast(self.mir_instructions.len),
.b_cond => self.mir_instructions.items(.data)[inst].inst_cond.inst = @intCast(self.mir_instructions.len),
.b => self.mir_instructions.items(.data)[inst].inst = @intCast(self.mir_instructions.len),
else => unreachable,
}
}
fn airBr(self: *Self, inst: Air.Inst.Index) !void {
const branch = self.air.instructions.items(.data)[inst].br;
const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
try self.br(branch.block_inst, branch.operand);
return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
}
@ -5263,7 +5263,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void {
}
fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
const clobbers_len = @as(u31, @truncate(extra.data.flags));
@ -5907,13 +5907,13 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
}
fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result = try self.resolveInst(un_op);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
@ -5935,7 +5935,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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);
const ptr = try self.resolveInst(ty_op.operand);
@ -5951,7 +5951,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFloatFromInt for {}", .{
self.target.cpu.arch,
});
@ -5959,7 +5959,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airIntFromFloat for {}", .{
self.target.cpu.arch,
});
@ -5967,7 +5967,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
_ = extra;
@ -6008,7 +6008,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -6018,7 +6018,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -6028,27 +6028,27 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSplat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSelect for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
}
fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ extra.a, extra.b, .none });
}
fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
const reduce = self.air.instructions.items(.data)[inst].reduce;
const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airReduce for aarch64", .{});
return self.finishAir(inst, result, .{ reduce.operand, .none, .none });
}
@ -6057,7 +6057,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen(mod);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
const result: MCValue = res: {
if (self.liveness.isUnused(inst)) break :res MCValue.dead;
@ -6077,19 +6077,19 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
}
fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
_ = extra;
return self.fail("TODO implement airUnionInit for aarch64", .{});
}
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
}
fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
return self.fail("TODO implement airMulAdd for aarch64", .{});
@ -6099,9 +6099,9 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
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);
@ -6126,7 +6126,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
_ = body;
@ -6142,7 +6142,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod) and !inst_ty.isError(mod))
return MCValue{ .none = {} };
const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
const inst_index = inst.toIndex() orelse return self.genTypedValue(.{
.ty = inst_ty,
.val = (try self.air.value(inst, mod)).?,
});

File diff suppressed because it is too large Load Diff

View File

@ -198,7 +198,7 @@ const BigTomb = struct {
fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void {
const dies = bt.lbt.feed();
const op_index = Air.refToIndex(op_ref) orelse return;
const op_index = op_ref.toIndex() orelse return;
if (!dies) return;
bt.function.processDeath(op_index);
}
@ -325,7 +325,7 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
const result_index = @as(Air.Inst.Index, @intCast(self.mir_instructions.len));
const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
self.mir_instructions.appendAssumeCapacity(inst);
return result_index;
}
@ -338,11 +338,11 @@ pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 {
pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
const fields = std.meta.fields(@TypeOf(extra));
const result = @as(u32, @intCast(self.mir_extra.items.len));
const result: u32 = @intCast(self.mir_extra.items.len);
inline for (fields) |field| {
self.mir_extra.appendAssumeCapacity(switch (field.type) {
u32 => @field(extra, field.name),
i32 => @as(u32, @bitCast(@field(extra, field.name))),
i32 => @bitCast(@field(extra, field.name)),
else => @compileError("bad field type"),
});
}
@ -486,7 +486,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
switch (air_tags[inst]) {
switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
.ptr_add => try self.airPtrArithmetic(inst, .ptr_add),
.ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub),
@ -725,7 +725,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
}
if (std.debug.runtime_safety) {
if (self.air_bookkeeping < old_air_bookkeeping + 1) {
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[inst] });
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[@intFromEnum(inst)] });
}
}
}
@ -758,7 +758,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
const op_index = Air.refToIndex(op) orelse continue;
const op_index = op.toIndex() orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@ -877,19 +877,19 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFptrunc for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFpext for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 });
@ -909,7 +909,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 });
@ -920,32 +920,32 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else operand;
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement NOT for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airMin(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement min for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMax(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement max for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
@ -981,8 +981,8 @@ fn binOpRegister(
const lhs_reg = if (lhs_is_register) lhs.register else blk: {
const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
break :inst Air.refToIndex(bin_op.lhs).?;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
break :inst bin_op.lhs.toIndex().?;
} else null;
const reg = try self.register_manager.allocReg(track_inst, gp);
@ -996,8 +996,8 @@ fn binOpRegister(
const rhs_reg = if (rhs_is_register) rhs.register else blk: {
const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
break :inst Air.refToIndex(bin_op.rhs).?;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
break :inst bin_op.rhs.toIndex().?;
} else null;
const reg = try self.register_manager.allocReg(track_inst, gp);
@ -1010,7 +1010,7 @@ fn binOpRegister(
defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg);
const dest_reg = if (maybe_inst) |inst| blk: {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
if (lhs_is_register and self.reuseOperand(inst, bin_op.lhs, 0, lhs)) {
break :blk lhs_reg;
@ -1123,7 +1123,7 @@ fn binOp(
}
fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.typeOf(bin_op.lhs);
@ -1134,7 +1134,7 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
}
fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
@ -1146,43 +1146,43 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
}
fn airAddWrap(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement addwrap for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airSubWrap(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement subwrap for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMul(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMulWrap(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mulwrap for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
@ -1208,105 +1208,105 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement div for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airRem(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement rem for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMod(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mod for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise and for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airBitOr(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise or for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airXor(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement xor for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airShl(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airShr(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union error for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union payload for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
// *(E!T) -> E
fn airUnwrapErrErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union error ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
// *(E!T) -> *T
fn airUnwrapErrPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement unwrap error union payload ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -1330,7 +1330,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
}
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mod = self.bin_file.options.module.?;
const optional_ty = self.typeOfIndex(inst);
@ -1346,127 +1346,127 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
/// T to E!T
fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
/// E to E!T
fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion error for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_len for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_len_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_slice_ptr_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const is_volatile = false; // TODO
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_elem_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
}
fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const is_volatile = false; // TODO
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
}
fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
_ = bin_op;
return self.fail("TODO implement airSetUnionTag for {}", .{self.target.cpu.arch});
// return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airClz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCtz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airAbs for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airByteSwap for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
else
@ -1500,7 +1500,7 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind
// That makes us responsible for doing the rest of the stuff that processDeath would have done.
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
branch.inst_table.putAssumeCapacity(Air.refToIndex(operand).?, .dead);
branch.inst_table.putAssumeCapacity(operand.toIndex().?, .dead);
return true;
}
@ -1533,7 +1533,7 @@ 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.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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))
@ -1590,7 +1590,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
} else {
// TODO if the value is undef, don't lower this instruction
}
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
const ptr_ty = self.typeOf(bin_op.lhs);
@ -1602,13 +1602,13 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
}
fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
return self.structFieldPtr(extra.struct_operand, ty_pl.ty, extra.field_index);
}
fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
return self.structFieldPtr(ty_op.operand, ty_op.ty, index);
}
fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u32) !void {
@ -1620,7 +1620,7 @@ fn structFieldPtr(self: *Self, operand: Air.Inst.Ref, ty: Air.Inst.Ref, index: u
}
fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
_ = extra;
return self.fail("TODO implement codegen struct_field_val", .{});
@ -1634,8 +1634,8 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
const mod = self.bin_file.options.module.?;
const arg = self.air.instructions.items(.data)[inst].arg;
const ty = self.air.getRefType(arg.ty);
const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
const ty = arg.ty.toType();
const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
const name = mod.getParamName(self.func_index, arg.src_index);
@ -1712,11 +1712,11 @@ fn airFence(self: *Self) !void {
fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
const mod = self.bin_file.options.module.?;
if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const fn_ty = self.typeOf(pl_op.operand);
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
var info = try self.resolveCallingConventionValues(fn_ty);
defer info.deinit(self);
@ -1755,7 +1755,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
const sym = elf_file.symbol(sym_index);
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
try self.genSetReg(Type.usize, .ra, .{ .memory = got_addr });
_ = try self.addInst(.{
.tag = .jalr,
@ -1824,14 +1824,14 @@ fn ret(self: *Self, mcv: MCValue) !void {
}
fn airRet(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
try self.ret(operand);
return self.finishAir(inst, .dead, .{ un_op, .none, .none });
}
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const ptr = try self.resolveInst(un_op);
_ = ptr;
return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch});
@ -1839,7 +1839,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
if (self.liveness.isUnused(inst))
return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
const ty = self.typeOf(bin_op.lhs);
@ -1864,7 +1864,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
_ = operand;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch});
@ -1872,7 +1872,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
_ = try self.addInst(.{
.tag = .dbg_line,
@ -1886,7 +1886,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const mod = self.bin_file.options.module.?;
const func = mod.funcInfo(ty_fn.func);
// TODO emit debug info for function change
@ -1900,7 +1900,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const name = self.air.nullTerminatedString(pl_op.payload);
const operand = pl_op.operand;
// TODO emit debug info for this variable
@ -1944,7 +1944,7 @@ fn isNonErr(self: *Self, operand: MCValue) !MCValue {
}
fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isNull(operand);
@ -1953,7 +1953,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const operand: MCValue = blk: {
@ -1971,7 +1971,7 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isNonNull(operand);
@ -1980,7 +1980,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const operand: MCValue = blk: {
@ -1998,7 +1998,7 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isErr(operand);
@ -2007,7 +2007,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const operand: MCValue = blk: {
@ -2025,7 +2025,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isNonErr(operand);
@ -2034,7 +2034,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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);
const operand: MCValue = blk: {
@ -2053,9 +2053,9 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
// A loop is a setup to be able to jump back to the beginning.
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
const start_index = self.code.items.len;
try self.genBody(body);
try self.jump(start_index);
@ -2081,9 +2081,9 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
});
defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
try self.genBody(body);
for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc);
@ -2093,7 +2093,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition = pl_op.operand;
_ = condition;
return self.fail("TODO airSwitch for {}", .{self.target.cpu.arch});
@ -2109,13 +2109,13 @@ fn performReloc(self: *Self, reloc: Reloc) !void {
}
fn airBr(self: *Self, inst: Air.Inst.Index) !void {
const branch = self.air.instructions.items(.data)[inst].br;
const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
try self.br(branch.block_inst, branch.operand);
return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
}
fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const air_tags = self.air.instructions.items(.tag);
_ = air_tags;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement boolean operations for {}", .{self.target.cpu.arch});
@ -2148,14 +2148,14 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void {
}
fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
const clobbers_len = @as(u31, @truncate(extra.data.flags));
const clobbers_len: u31 = @truncate(extra.data.flags);
var extra_i: usize = extra.end;
const outputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]));
const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
extra_i += outputs.len;
const inputs = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]));
const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]);
extra_i += inputs.len;
const dead = !is_volatile and self.liveness.isUnused(inst);
@ -2300,20 +2300,20 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa });
},
.immediate => |unsigned_x| {
const x = @as(i64, @bitCast(unsigned_x));
const x: i64 = @bitCast(unsigned_x);
if (math.minInt(i12) <= x and x <= math.maxInt(i12)) {
_ = try self.addInst(.{
.tag = .addi,
.data = .{ .i_type = .{
.rd = reg,
.rs1 = .zero,
.imm12 = @as(i12, @intCast(x)),
.imm12 = @intCast(x),
} },
});
} else if (math.minInt(i32) <= x and x <= math.maxInt(i32)) {
const lo12 = @as(i12, @truncate(x));
const lo12: i12 = @truncate(x);
const carry: i32 = if (lo12 < 0) 1 else 0;
const hi20 = @as(i20, @truncate((x >> 12) +% carry));
const hi20: i20 = @truncate((x >> 12) +% carry);
// TODO: add test case for 32-bit immediate
_ = try self.addInst(.{
@ -2373,13 +2373,13 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
}
fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result = try self.resolveInst(un_op);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
@ -2398,7 +2398,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
}
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airArrayToSlice for {}", .{
self.target.cpu.arch,
});
@ -2406,7 +2406,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFloatFromInt for {}", .{
self.target.cpu.arch,
});
@ -2414,7 +2414,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airIntFromFloat for {}", .{
self.target.cpu.arch,
});
@ -2422,7 +2422,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
_ = extra;
return self.fail("TODO implement airCmpxchg for {}", .{
@ -2463,7 +2463,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -2473,7 +2473,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -2483,26 +2483,26 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSplat for riscv64", .{});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airSelect(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSelect for riscv64", .{});
return self.finishAir(inst, result, .{ pl_op.operand, extra.lhs, extra.rhs });
}
fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airShuffle for riscv64", .{});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
const reduce = self.air.instructions.items(.data)[inst].reduce;
const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airReduce for riscv64", .{});
return self.finishAir(inst, result, .{ reduce.operand, .none, .none });
}
@ -2511,8 +2511,8 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen(mod);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
const result: MCValue = res: {
if (self.liveness.isUnused(inst)) break :res MCValue.dead;
return self.fail("TODO implement airAggregateInit for riscv64", .{});
@ -2531,7 +2531,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
}
fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
_ = extra;
return self.fail("TODO implement airUnionInit for riscv64", .{});
@ -2539,12 +2539,12 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
}
fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
return self.fail("TODO implement airMulAdd for riscv64", .{});
@ -2560,7 +2560,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
if (!inst_ty.hasRuntimeBits(mod))
return MCValue{ .none = {} };
const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{
const inst_index = inst.toIndex() orelse return self.genTypedValue(.{
.ty = inst_ty,
.val = (try self.air.value(inst, mod)).?,
});
@ -2656,7 +2656,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
const argument_registers = [_]Register{ .a0, .a1, .a2, .a3, .a4, .a5, .a6, .a7 };
for (fn_info.param_types.get(ip), result.args) |ty, *result_arg| {
const param_size = @as(u32, @intCast(Type.fromInterned(ty).abiSize(mod)));
const param_size: u32 = @intCast(Type.fromInterned(ty).abiSize(mod));
if (param_size <= 8) {
if (next_register < argument_registers.len) {
result_arg.* = .{ .register = argument_registers[next_register] };
@ -2693,7 +2693,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
} else switch (cc) {
.Naked => unreachable,
.Unspecified, .C => {
const ret_ty_size = @as(u32, @intCast(ret_ty.abiSize(mod)));
const ret_ty_size: u32 = @intCast(ret_ty.abiSize(mod));
if (ret_ty_size <= 8) {
result.return_value = .{ .register = .a0 };
} else if (ret_ty_size <= 16) {

View File

@ -243,7 +243,7 @@ const BigTomb = struct {
fn feed(bt: *BigTomb, op_ref: Air.Inst.Ref) void {
const dies = bt.lbt.feed();
const op_index = Air.refToIndex(op_ref) orelse return;
const op_index = op_ref.toIndex() orelse return;
if (!dies) return;
bt.function.processDeath(op_index);
}
@ -504,7 +504,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
const old_air_bookkeeping = self.air_bookkeeping;
try self.ensureProcessDeathCapacity(Liveness.bpi);
switch (air_tags[inst]) {
switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
.ptr_add => try self.airPtrArithmetic(inst, .ptr_add),
.ptr_sub => try self.airPtrArithmetic(inst, .ptr_sub),
@ -746,21 +746,21 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
if (std.debug.runtime_safety) {
if (self.air_bookkeeping < old_air_bookkeeping + 1) {
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[inst] });
std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[@intFromEnum(inst)] });
}
}
}
}
fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement add_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
@ -843,7 +843,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const vector_ty = self.typeOfIndex(inst);
const len = vector_ty.vectorLen(mod);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
const result: MCValue = res: {
if (self.liveness.isUnused(inst)) break :res MCValue.dead;
@ -868,14 +868,14 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
}
fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement array_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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);
const ptr = try self.resolveInst(ty_op.operand);
@ -891,7 +891,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = (extra.data.flags & 0x80000000) != 0;
const clobbers_len = @as(u31, @truncate(extra.data.flags));
@ -1047,7 +1047,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
_ = self.air.instructions.items(.data)[inst].atomic_load;
_ = self.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
return self.fail("TODO implement airAtomicLoad for {}", .{
self.target.cpu.arch,
@ -1055,7 +1055,7 @@ fn airAtomicLoad(self: *Self, inst: Air.Inst.Index) !void {
}
fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
_ = self.air.instructions.items(.data)[inst].pl_op;
_ = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
return self.fail("TODO implement airAtomicRmw for {}", .{
self.target.cpu.arch,
@ -1063,7 +1063,7 @@ fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
}
fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.typeOf(bin_op.lhs);
@ -1080,14 +1080,14 @@ fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
}
fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else operand;
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
@ -1105,7 +1105,7 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
}
fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
if (self.reuseOperand(inst, ty_op.operand, 0, operand)) break :result operand;
@ -1125,7 +1125,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
}
fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airBitReverse for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -1143,9 +1143,9 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
});
defer self.blocks.getPtr(inst).?.relocs.deinit(self.gpa);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
try self.genBody(body);
// relocations for `bpcc` instructions
@ -1170,7 +1170,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airBr(self: *Self, inst: Air.Inst.Index) !void {
const branch = self.air.instructions.items(.data)[inst].br;
const branch = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
try self.br(branch.block_inst, branch.operand);
return self.finishAir(inst, .dead, .{ branch.operand, .none, .none });
}
@ -1207,7 +1207,7 @@ fn airBreakpoint(self: *Self) !void {
fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
// We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.
// That being said, the strategy to lower this is:
@ -1293,7 +1293,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
if (modifier == .always_tail) return self.fail("TODO implement tail calls for {}", .{self.target.cpu.arch});
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const callee = pl_op.operand;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len]));
@ -1423,13 +1423,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}
fn airClz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airClz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const lhs = try self.resolveInst(bin_op.lhs);
@ -1486,7 +1486,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
}
fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
_ = operand;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCmpLtErrorsLen for {}", .{self.target.cpu.arch});
@ -1494,7 +1494,7 @@ fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Block, ty_pl.payload);
_ = extra;
@ -1504,11 +1504,11 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition = try self.resolveInst(pl_op.operand);
const extra = self.air.extraData(Air.CondBr, pl_op.payload);
const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const liveness_condbr = self.liveness.getCondBr(inst);
// Here we emit a branch to the false section.
@ -1518,7 +1518,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
// that death now instead of later as this has an effect on
// whether it needs to be spilled in the branches
if (self.liveness.operandDies(inst, 0)) {
if (Air.refToIndex(pl_op.operand)) |op_index| {
if (pl_op.operand.toIndex()) |op_index| {
self.processDeath(op_index);
}
}
@ -1650,7 +1650,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airCtz for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -1661,7 +1661,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const mod = self.bin_file.options.module.?;
const func = mod.funcInfo(ty_fn.func);
// TODO emit debug info for function change
@ -1670,7 +1670,7 @@ fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
_ = try self.addInst(.{
.tag = .dbg_line,
@ -1686,7 +1686,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const name = self.air.nullTerminatedString(pl_op.payload);
const operand = pl_op.operand;
// TODO emit debug info for this variable
@ -1695,13 +1695,13 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
}
fn airDiv(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement div for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -1711,14 +1711,14 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .errunion_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airFence(self: *Self, inst: Air.Inst.Index) !void {
// TODO weaken this as needed, currently this implements the strongest membar form
const fence = self.air.instructions.items(.data)[inst].fence;
const fence = self.air.instructions.items(.data)[@intFromEnum(inst)].fence;
_ = fence;
// membar #StoreStore | #LoadStore | #StoreLoad | #LoadLoad
@ -1740,7 +1740,7 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airIntFromFloat for {}", .{
self.target.cpu.arch,
});
@ -1748,13 +1748,13 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
}
fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 });
@ -1773,7 +1773,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
}
fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFloatFromInt for {}", .{
self.target.cpu.arch,
});
@ -1781,7 +1781,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
const ty = self.typeOf(un_op);
@ -1791,7 +1791,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
const ty = self.typeOf(un_op);
@ -1801,7 +1801,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isNull(operand);
@ -1810,7 +1810,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
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 = try self.resolveInst(un_op);
break :result try self.isNonNull(operand);
@ -1820,7 +1820,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const elem_ty = self.typeOfIndex(inst);
const elem_size = elem_ty.abiSize(mod);
const result: MCValue = result: {
@ -1851,9 +1851,9 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
// A loop is a setup to be able to jump back to the beginning.
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end .. loop.end + loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end .. loop.end + loop.data.body_len]);
const start = @as(u32, @intCast(self.mir_instructions.len));
try self.genBody(body);
@ -1868,7 +1868,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
} else {
// TODO if the value is undef, don't lower this instruction
}
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Bin, pl_op.payload);
const operand = pl_op.operand;
@ -1882,8 +1882,8 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
}
fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
const tag = self.air.instructions.items(.tag)[inst];
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.typeOf(bin_op.lhs);
@ -1898,7 +1898,7 @@ fn airMinMax(self: *Self, inst: Air.Inst.Index) !void {
}
fn airMod(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.typeOf(bin_op.lhs);
@ -2036,14 +2036,14 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
}
fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement mul_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
//const tag = self.air.instructions.items(.tag)[inst];
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
//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.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
@ -2108,7 +2108,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airNot(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const mod = self.bin_file.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const operand = try self.resolveInst(ty_op.operand);
@ -2204,51 +2204,51 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
}
fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement .optional_payload_ptr_set for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPopcount(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airPopcount for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
const prefetch = self.air.instructions.items(.data)[inst].prefetch;
const prefetch = self.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
// TODO Emit a PREFETCH/IPREFETCH as necessary, see A.7 and A.42
return self.finishAir(inst, MCValue.dead, .{ prefetch.ptr, .none, .none });
}
fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
const is_volatile = false; // TODO
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_ptr for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
}
fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bits = self.target.ptrBitWidth();
const ptr_bytes = @divExact(ptr_bits, 8);
@ -2265,7 +2265,7 @@ fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(ty_op.operand);
switch (mcv) {
@ -2280,13 +2280,13 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result = try self.resolveInst(un_op);
return self.finishAir(inst, result, .{ un_op, .none, .none });
}
fn airRem(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try self.resolveInst(bin_op.lhs);
const rhs = try self.resolveInst(bin_op.rhs);
const lhs_ty = self.typeOf(bin_op.lhs);
@ -2307,14 +2307,14 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void {
}
fn airRet(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
try self.ret(operand);
return self.finishAir(inst, .dead, .{ un_op, .none, .none });
}
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const ptr = try self.resolveInst(un_op);
_ = ptr;
return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch});
@ -2327,19 +2327,19 @@ fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
_ = bin_op;
return self.fail("TODO implement airSetUnionTag for {}", .{self.target.cpu.arch});
}
fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
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.options.module.?;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
@ -2429,7 +2429,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const ptr = try self.resolveInst(bin_op.lhs);
@ -2448,7 +2448,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const is_volatile = false; // TODO
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
if (!is_volatile and self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
const result: MCValue = result: {
@ -2490,7 +2490,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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_bits = self.target.ptrBitWidth();
const ptr_bytes = @divExact(ptr_bits, 8);
@ -2511,7 +2511,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const mcv = try self.resolveInst(ty_op.operand);
switch (mcv) {
@ -2530,7 +2530,7 @@ fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airSplat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@ -2541,7 +2541,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
} else {
// TODO if the value is undef, don't lower this instruction
}
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr = try self.resolveInst(bin_op.lhs);
const value = try self.resolveInst(bin_op.rhs);
const ptr_ty = self.typeOf(bin_op.lhs);
@ -2553,20 +2553,20 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
}
fn airStructFieldPtr(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
const result = try self.structFieldPtr(inst, extra.struct_operand, extra.field_index);
return self.finishAir(inst, result, .{ extra.struct_operand, .none, .none });
}
fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = try self.structFieldPtr(inst, ty_op.operand, index);
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
const operand = extra.struct_operand;
const index = extra.field_index;
@ -2636,7 +2636,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
}
fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement sub_sat for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
}
@ -2647,7 +2647,7 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try self.resolveInst(un_op);
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else {
_ = operand;
@ -2657,7 +2657,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try self.resolveInst(ty_op.operand);
const operand_ty = self.typeOf(ty_op.operand);
const dest_ty = self.typeOfIndex(inst);
@ -2670,9 +2670,9 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
}
fn airTry(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const result: MCValue = result: {
const error_union_ty = self.typeOf(pl_op.operand);
const error_union = try self.resolveInst(pl_op.operand);
@ -2688,7 +2688,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
}
fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const result: MCValue = if (self.liveness.isUnused(inst))
.dead
else
@ -2697,7 +2697,7 @@ fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void {
}
fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
_ = extra;
return self.fail("TODO implement airUnionInit for {}", .{self.target.cpu.arch});
@ -2705,7 +2705,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 = self.typeOf(ty_op.operand);
const payload_ty = error_union_ty.errorUnionPayload(mod);
@ -2719,7 +2719,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 = self.typeOf(ty_op.operand);
const payload_ty = error_union_ty.errorUnionPayload(mod);
@ -2733,9 +2733,9 @@ fn airUnwrapErrPayload(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.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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 = self.air.getRefType(ty_op.ty);
const error_union_ty = ty_op.ty.toType();
const payload_ty = error_union_ty.errorUnionPayload(mod);
const mcv = try self.resolveInst(ty_op.operand);
if (!payload_ty.hasRuntimeBits(mod)) break :result mcv;
@ -2747,14 +2747,14 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
/// T to E!T
fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch});
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
const mod = self.bin_file.options.module.?;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
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);
@ -2772,7 +2772,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
const gpa = self.gpa;
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
const result_index = @as(Air.Inst.Index, @intCast(self.mir_instructions.len));
const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
self.mir_instructions.appendAssumeCapacity(inst);
return result_index;
}
@ -3143,9 +3143,7 @@ fn binOpImmediate(
const lhs_reg = if (lhs_is_register) lhs.register else blk: {
const track_inst: ?Air.Inst.Index = if (metadata) |md| inst: {
break :inst Air.refToIndex(
if (lhs_and_rhs_swapped) md.rhs else md.lhs,
).?;
break :inst (if (lhs_and_rhs_swapped) md.rhs else md.lhs).toIndex().?;
} else null;
const reg = try self.register_manager.allocReg(track_inst, gp);
@ -3284,7 +3282,7 @@ fn binOpRegister(
const lhs_reg = if (lhs_is_register) lhs.register else blk: {
const track_inst: ?Air.Inst.Index = if (metadata) |md| inst: {
break :inst Air.refToIndex(md.lhs).?;
break :inst md.lhs.toIndex().?;
} else null;
const reg = try self.register_manager.allocReg(track_inst, gp);
@ -3308,7 +3306,7 @@ fn binOpRegister(
const rhs_reg = if (rhs_is_register) rhs.register else blk: {
const track_inst: ?Air.Inst.Index = if (metadata) |md| inst: {
break :inst Air.refToIndex(md.rhs).?;
break :inst md.rhs.toIndex().?;
} else null;
const reg = try self.register_manager.allocReg(track_inst, gp);
@ -3566,7 +3564,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
const dies = @as(u1, @truncate(tomb_bits)) != 0;
tomb_bits >>= 1;
if (!dies) continue;
const op_index = Air.refToIndex(op) orelse continue;
const op_index = op.toIndex() orelse continue;
self.processDeath(op_index);
}
const is_used = @as(u1, @truncate(tomb_bits)) == 0;
@ -3594,8 +3592,8 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
const mod = self.bin_file.options.module.?;
const arg = self.air.instructions.items(.data)[inst].arg;
const ty = self.air.getRefType(arg.ty);
const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
const ty = arg.ty.toType();
const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
const name = mod.getParamName(self.func_index, arg.src_index);
@ -4411,8 +4409,8 @@ fn parseRegName(name: []const u8) ?Register {
fn performReloc(self: *Self, inst: Mir.Inst.Index) !void {
const tag = self.mir_instructions.items(.tag)[inst];
switch (tag) {
.bpcc => self.mir_instructions.items(.data)[inst].branch_predict_int.inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len)),
.bpr => self.mir_instructions.items(.data)[inst].branch_predict_reg.inst = @as(Mir.Inst.Index, @intCast(self.mir_instructions.len)),
.bpcc => self.mir_instructions.items(.data)[inst].branch_predict_int.inst = @intCast(self.mir_instructions.len),
.bpr => self.mir_instructions.items(.data)[inst].branch_predict_reg.inst = @intCast(self.mir_instructions.len),
else => unreachable,
}
}
@ -4550,7 +4548,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
// If the type has no codegen bits, no need to store it.
if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return .none;
if (Air.refToIndex(ref)) |inst| {
if (ref.toIndex()) |inst| {
return self.getResolvedInstValue(inst);
}
@ -4606,7 +4604,7 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind
// That makes us responsible for doing the rest of the stuff that processDeath would have done.
const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
branch.inst_table.putAssumeCapacity(Air.refToIndex(operand).?, .dead);
branch.inst_table.putAssumeCapacity(operand.toIndex().?, .dead);
return true;
}
@ -4767,7 +4765,7 @@ fn trunc(
defer if (lock) |reg| self.register_manager.unlockReg(reg);
const dest_reg = if (maybe_inst) |inst| blk: {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
break :blk operand_reg;

View File

@ -828,7 +828,7 @@ fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []c
if (result != .none) {
assert(result != .stack); // it's illegal to store a stack value as we cannot track its position
const branch = func.currentBranch();
branch.values.putAssumeCapacityNoClobber(Air.indexToRef(inst), result);
branch.values.putAssumeCapacityNoClobber(inst.toRef(), result);
}
if (builtin.mode == .Debug) {
@ -864,7 +864,7 @@ const BigTomb = struct {
fn finishAir(bt: *BigTomb, result: WValue) void {
assert(result != .stack);
if (result != .none) {
bt.gen.currentBranch().values.putAssumeCapacityNoClobber(Air.indexToRef(bt.inst), result);
bt.gen.currentBranch().values.putAssumeCapacityNoClobber(bt.inst.toRef(), result);
}
if (builtin.mode == .Debug) {
@ -883,7 +883,7 @@ fn iterateBigTomb(func: *CodeGen, inst: Air.Inst.Index, operand_count: usize) !B
}
fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {
if (Air.refToIndex(ref) == null) return;
if (ref.toIndex() == null) return;
// Branches are currently only allowed to free locals allocated
// within their own branch.
// TODO: Upon branch consolidation free any locals if needed.
@ -893,7 +893,7 @@ fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void {
if (value.local.value < reserved_indexes) {
return; // function arguments can never be re-used
}
log.debug("Decreasing reference for ref: %{?d}, using local '{d}'", .{ Air.refToIndex(ref), value.local.value });
log.debug("Decreasing reference for ref: %{d}, using local '{d}'", .{ @intFromEnum(ref.toIndex().?), value.local.value });
value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer
if (value.local.references == 0) {
value.free(func);
@ -1265,7 +1265,7 @@ fn genFunc(func: *CodeGen) InnerError!void {
// In case we have a return value, but the last instruction is a noreturn (such as a while loop)
// we emit an unreachable instruction to tell the stack validator that part will never be reached.
if (func_type.returns.len != 0 and func.air.instructions.len > 0) {
const inst = @as(u32, @intCast(func.air.instructions.len - 1));
const inst: Air.Inst.Index = @enumFromInt(func.air.instructions.len - 1);
const last_inst_ty = func.typeOfIndex(inst);
if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(mod) or last_inst_ty.isNoReturn(mod)) {
try func.addTag(.@"unreachable");
@ -1828,7 +1828,7 @@ fn buildPointerOffset(func: *CodeGen, ptr_value: WValue, offset: u64, action: en
fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const air_tags = func.air.instructions.items(.tag);
return switch (air_tags[inst]) {
return switch (air_tags[@intFromEnum(inst)]) {
.inferred_alloc, .inferred_alloc_comptime => unreachable,
.add => func.airBinOp(inst, .add),
@ -2086,7 +2086,7 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
if (builtin.mode == .Debug and func.air_bookkeeping < old_bookkeeping_value + 1) {
std.debug.panic("Missing call to `finishAir` in AIR instruction %{d} ('{}')", .{
inst,
func.air.instructions.items(.tag)[inst],
func.air.instructions.items(.tag)[@intFromEnum(inst)],
});
}
}
@ -2094,7 +2094,7 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const fn_info = mod.typeToFunc(func.decl.ty).?;
const ret_ty = Type.fromInterned(fn_info.return_type);
@ -2157,7 +2157,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const ret_ty = func.typeOf(un_op).childType(mod);
@ -2178,7 +2178,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) InnerError!void {
if (modifier == .always_tail) return func.fail("TODO implement tail calls for wasm", .{});
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = func.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len]));
const ty = func.typeOf(pl_op.operand);
@ -2301,7 +2301,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
} else {
// TODO if the value is undef, don't lower this instruction
}
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@ -2457,9 +2457,9 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const ty = func.air.getRefType(ty_op.ty);
const ty = ty_op.ty.toType();
const ptr_ty = func.typeOf(ty_op.operand);
const ptr_info = ptr_ty.ptrInfo(mod);
@ -2569,7 +2569,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
switch (func.debug_output) {
.dwarf => |dwarf| {
const src_index = func.air.instructions.items(.data)[inst].arg.src_index;
const src_index = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
const name = mod.getParamName(func.func_index, src_index);
try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
.wasm_local = arg.local.value,
@ -2583,7 +2583,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
const lhs_ty = func.typeOf(bin_op.lhs);
@ -2789,7 +2789,7 @@ const FloatOp = enum {
fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const ty = func.typeOf(ty_op.operand);
const scalar_ty = ty.scalarType(mod);
@ -2864,7 +2864,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const ty = func.typeOf(un_op);
@ -2980,7 +2980,7 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {
fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@ -3473,11 +3473,11 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 {
fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const block_ty = func.air.getRefType(ty_pl.ty);
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const block_ty = ty_pl.ty.toType();
const wasm_block_ty = genBlockType(block_ty, mod);
const extra = func.air.extraData(Air.Block, ty_pl.payload);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
// if wasm_block_ty is non-empty, we create a register to store the temporary value
const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
@ -3518,9 +3518,9 @@ fn endBlock(func: *CodeGen) !void {
}
fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = func.air.extraData(Air.Block, ty_pl.payload);
const body = func.air.extra[loop.end..][0..loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(func.air.extra[loop.end..][0..loop.data.body_len]);
// result type of loop is always 'noreturn', meaning we can always
// emit the wasm type 'block_empty'.
@ -3535,11 +3535,11 @@ fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition = try func.resolveInst(pl_op.operand);
const extra = func.air.extraData(Air.CondBr, pl_op.payload);
const then_body = func.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = func.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const liveness_condbr = func.liveness.getCondBr(inst);
// result type is always noreturn, so use `block_empty` as type.
@ -3579,7 +3579,7 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try func.resolveInst(bin_op.lhs);
const rhs = try func.resolveInst(bin_op.rhs);
@ -3705,7 +3705,7 @@ fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
const errors_len = WValue{ .memory = sym_index };
@ -3721,7 +3721,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const br = func.air.instructions.items(.data)[inst].br;
const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
const block = func.blocks.get(br.block_inst).?;
// if operand has codegen bits we should break with a value
@ -3743,7 +3743,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const operand_ty = func.typeOf(ty_op.operand);
@ -3809,7 +3809,7 @@ fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const result = result: {
const operand = try func.resolveInst(ty_op.operand);
const wanted_ty = func.typeOfIndex(inst);
@ -3853,7 +3853,7 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.StructField, ty_pl.payload);
const struct_ptr = try func.resolveInst(extra.data.struct_operand);
@ -3865,7 +3865,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const struct_ptr = try func.resolveInst(ty_op.operand);
const struct_ptr_ty = func.typeOf(ty_op.operand);
const struct_ty = struct_ptr_ty.childType(mod);
@ -3916,7 +3916,7 @@ fn structFieldPtr(
fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ip = &mod.intern_pool;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
const struct_ty = func.typeOf(struct_field.struct_operand);
@ -4016,7 +4016,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
// result type is always 'noreturn'
const blocktype = wasm.block_empty;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const target = try func.resolveInst(pl_op.operand);
const target_ty = func.typeOf(pl_op.operand);
const switch_br = func.air.extraData(Air.SwitchBr, pl_op.payload);
@ -4040,8 +4040,8 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
var highest_maybe: ?i32 = null;
while (case_i < switch_br.data.cases_len) : (case_i += 1) {
const case = func.air.extraData(Air.SwitchBr.Case, extra_index);
const items = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[case.end..][0..case.data.items_len]));
const case_body = func.air.extra[case.end + items.len ..][0..case.data.body_len];
const items: []const Air.Inst.Ref = @ptrCast(func.air.extra[case.end..][0..case.data.items_len]);
const case_body: []const Air.Inst.Index = @ptrCast(func.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + items.len + case_body.len;
const values = try func.gpa.alloc(CaseValue, items.len);
errdefer func.gpa.free(values);
@ -4072,7 +4072,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
// TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.
const is_sparse = highest - lowest > 50 or target_ty.bitSize(mod) > 32;
const else_body = func.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]);
const has_else_body = else_body.len != 0;
if (has_else_body) {
try func.startBlock(.block, blocktype);
@ -4194,7 +4194,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const err_union_ty = func.typeOf(un_op);
const pl_ty = err_union_ty.errorUnionPayload(mod);
@ -4229,7 +4229,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const op_ty = func.typeOf(ty_op.operand);
@ -4257,7 +4257,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const op_ty = func.typeOf(ty_op.operand);
@ -4281,7 +4281,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const err_ty = func.typeOfIndex(inst);
@ -4311,10 +4311,10 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const err_ty = func.air.getRefType(ty_op.ty);
const err_ty = ty_op.ty.toType();
const pl_ty = err_ty.errorUnionPayload(mod);
const result = result: {
@ -4337,9 +4337,9 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ty = func.air.getRefType(ty_op.ty);
const ty = ty_op.ty.toType();
const operand = try func.resolveInst(ty_op.operand);
const operand_ty = func.typeOf(ty_op.operand);
const mod = func.bin_file.base.options.module.?;
@ -4434,7 +4434,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const op_ty = func.typeOf(un_op);
@ -4476,7 +4476,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const opt_ty = func.typeOf(ty_op.operand);
const payload_ty = func.typeOfIndex(inst);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@ -4499,7 +4499,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const opt_ty = func.typeOf(ty_op.operand).childType(mod);
@ -4516,7 +4516,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const opt_ty = func.typeOf(ty_op.operand).childType(mod);
const payload_ty = opt_ty.optionalChild(mod);
@ -4541,7 +4541,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
}
fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const payload_ty = func.typeOf(ty_op.operand);
const mod = func.bin_file.base.options.module.?;
@ -4578,7 +4578,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try func.resolveInst(bin_op.lhs);
@ -4593,7 +4593,7 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
@ -4601,7 +4601,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const slice_ty = func.typeOf(bin_op.lhs);
const slice = try func.resolveInst(bin_op.lhs);
@ -4631,10 +4631,10 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
const elem_ty = func.air.getRefType(ty_pl.ty).childType(mod);
const elem_ty = ty_pl.ty.toType().childType(mod);
const elem_size = elem_ty.abiSize(mod);
const slice = try func.resolveInst(bin_op.lhs);
@ -4654,7 +4654,7 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
}
@ -4670,10 +4670,10 @@ fn sliceLen(func: *CodeGen, operand: WValue) InnerError!WValue {
}
fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const wanted_ty = func.air.getRefType(ty_op.ty);
const wanted_ty = ty_op.ty.toType();
const op_ty = func.typeOf(ty_op.operand);
const result = try func.trunc(operand, wanted_ty, op_ty);
@ -4699,7 +4699,7 @@ fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) Inner
}
fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const result = func.reuseOperand(un_op, operand);
@ -4708,11 +4708,11 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const array_ty = func.typeOf(ty_op.operand).childType(mod);
const slice_ty = func.air.getRefType(ty_op.ty);
const slice_ty = ty_op.ty.toType();
// create a slice on the stack
const slice_local = try func.allocStack(slice_ty);
@ -4731,7 +4731,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const ptr_ty = func.typeOf(un_op);
const result = if (ptr_ty.isSlice(mod))
@ -4746,7 +4746,7 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = func.typeOf(bin_op.lhs);
const ptr = try func.resolveInst(bin_op.lhs);
@ -4783,11 +4783,11 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_ty = func.typeOf(bin_op.lhs);
const elem_ty = func.air.getRefType(ty_pl.ty).childType(mod);
const elem_ty = ty_pl.ty.toType().childType(mod);
const elem_size = elem_ty.abiSize(mod);
const ptr = try func.resolveInst(bin_op.lhs);
@ -4813,7 +4813,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr = try func.resolveInst(bin_op.lhs);
@ -4846,7 +4846,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
} else {
// TODO if the value is undef, don't lower this instruction
}
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr = try func.resolveInst(bin_op.lhs);
const ptr_ty = func.typeOf(bin_op.lhs);
@ -4963,7 +4963,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const array_ty = func.typeOf(bin_op.lhs);
const array = try func.resolveInst(bin_op.lhs);
@ -5032,7 +5032,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const op_ty = func.typeOf(ty_op.operand);
@ -5077,7 +5077,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const op_ty = func.typeOf(ty_op.operand);
@ -5123,7 +5123,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const ty = func.typeOfIndex(inst);
const elem_ty = ty.childType(mod);
@ -5193,7 +5193,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const operand = try func.resolveInst(pl_op.operand);
_ = operand;
@ -5203,7 +5203,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const inst_ty = func.typeOfIndex(inst);
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
const a = try func.resolveInst(extra.a);
@ -5262,7 +5262,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const reduce = func.air.instructions.items(.data)[inst].reduce;
const reduce = func.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
const operand = try func.resolveInst(reduce.operand);
_ = operand;
@ -5272,7 +5272,7 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ip = &mod.intern_pool;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const result_ty = func.typeOfIndex(inst);
const len = @as(usize, @intCast(result_ty.arrayLen(mod)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[ty_pl.payload..][0..len]));
@ -5402,7 +5402,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ip = &mod.intern_pool;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
const result = result: {
@ -5474,12 +5474,12 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const prefetch = func.air.instructions.items(.data)[inst].prefetch;
const prefetch = func.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
func.finishAir(inst, .none, &.{prefetch.ptr});
}
fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const result = try func.allocLocal(func.typeOfIndex(inst));
try func.addLabel(.memory_size, pl_op.payload);
@ -5488,7 +5488,7 @@ fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const operand = try func.resolveInst(pl_op.operand);
const result = try func.allocLocal(func.typeOfIndex(inst));
@ -5578,7 +5578,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const un_ty = func.typeOf(bin_op.lhs).childType(mod);
const tag_ty = func.typeOf(bin_op.rhs);
const layout = un_ty.unionGetLayout(mod);
@ -5602,7 +5602,7 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const un_ty = func.typeOf(ty_op.operand);
const tag_ty = func.typeOfIndex(inst);
@ -5621,7 +5621,7 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const dest_ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
@ -5666,7 +5666,7 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
}
fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const dest_ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
@ -5707,7 +5707,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const err_set_ty = func.typeOf(ty_op.operand).childType(mod);
const payload_ty = err_set_ty.errorUnionPayload(mod);
@ -5733,11 +5733,11 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
const field_ptr = try func.resolveInst(extra.field_ptr);
const parent_ty = func.air.getRefType(ty_pl.ty).childType(mod);
const parent_ty = ty_pl.ty.toType().childType(mod);
const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
const result = if (field_offset != 0) result: {
@ -5763,7 +5763,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue
fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dst = try func.resolveInst(bin_op.lhs);
const dst_ty = func.typeOf(bin_op.lhs);
const ptr_elem_ty = dst_ty.childType(mod);
@ -5803,7 +5803,7 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const op_ty = func.typeOf(ty_op.operand);
@ -5847,7 +5847,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
// First retrieve the symbol index to the error name table
@ -5889,7 +5889,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airPtrSliceFieldPtr(func: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerError!void {
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const slice_ptr = try func.resolveInst(ty_op.operand);
const result = try func.buildPointerOffset(slice_ptr, offset, .new);
func.finishAir(inst, result, &.{ty_op.operand});
@ -5897,7 +5897,7 @@ fn airPtrSliceFieldPtr(func: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerE
fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
assert(op == .add or op == .sub);
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs_op = try func.resolveInst(extra.lhs);
@ -6041,7 +6041,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try func.resolveInst(extra.lhs);
@ -6097,7 +6097,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try func.resolveInst(extra.lhs);
@ -6275,7 +6275,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
assert(op == .max or op == .min);
const mod = func.bin_file.base.options.module.?;
const target = mod.getTarget();
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ty = func.typeOfIndex(inst);
if (ty.zigTypeTag(mod) == .Vector) {
@ -6318,7 +6318,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
const ty = func.typeOfIndex(inst);
@ -6352,7 +6352,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ty = func.typeOf(ty_op.operand);
const result_ty = func.typeOfIndex(inst);
@ -6405,7 +6405,7 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ty = func.typeOf(ty_op.operand);
const result_ty = func.typeOfIndex(inst);
@ -6472,7 +6472,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
const mod = func.bin_file.base.options.module.?;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const ty = func.typeOf(pl_op.operand);
const operand = try func.resolveInst(pl_op.operand);
@ -6496,7 +6496,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) !void {
if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
const dbg_stmt = func.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = func.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
try func.addInst(.{ .tag = .dbg_line, .data = .{
.payload = try func.addExtra(Mir.DbgLineColumn{
.line = dbg_stmt.line,
@ -6507,10 +6507,10 @@ fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) !void {
}
fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const err_union = try func.resolveInst(pl_op.operand);
const extra = func.air.extraData(Air.Try, pl_op.payload);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
const err_union_ty = func.typeOf(pl_op.operand);
const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
func.finishAir(inst, result, &.{pl_op.operand});
@ -6518,10 +6518,10 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);
const err_union_ptr = try func.resolveInst(extra.data.ptr);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
const err_union_ty = func.typeOf(extra.data.ptr).childType(mod);
const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
func.finishAir(inst, result, &.{extra.data.ptr});
@ -6585,7 +6585,7 @@ fn lowerTry(
fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ty = func.typeOfIndex(inst);
const operand = try func.resolveInst(ty_op.operand);
@ -6656,7 +6656,7 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
@ -6671,7 +6671,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ty = func.typeOfIndex(inst);
const lhs = try func.resolveInst(bin_op.lhs);
@ -6691,7 +6691,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const mod = func.bin_file.base.options.module.?;
const ty = func.typeOfIndex(inst);
@ -6834,7 +6834,7 @@ fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WVal
/// Remainder after floor division, defined by:
/// @divFloor(a, b) * b + @mod(a, b) = a
fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const mod = func.bin_file.base.options.module.?;
const ty = func.typeOfIndex(inst);
@ -6917,7 +6917,7 @@ fn signExtendInt(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
assert(op == .add or op == .sub);
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const mod = func.bin_file.base.options.module.?;
const ty = func.typeOfIndex(inst);
@ -7032,7 +7032,7 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type,
}
fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const mod = func.bin_file.base.options.module.?;
const ty = func.typeOfIndex(inst);
@ -7193,7 +7193,7 @@ fn callIntrinsic(
}
fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const un_op = func.air.instructions.items(.data)[inst].un_op;
const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try func.resolveInst(un_op);
const enum_ty = func.typeOf(un_op);
@ -7365,10 +7365,10 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_op = func.air.instructions.items(.data)[inst].ty_op;
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try func.resolveInst(ty_op.operand);
const error_set_ty = func.air.getRefType(ty_op.ty);
const error_set_ty = ty_op.ty.toType();
const result = try func.allocLocal(Type.bool);
const names = error_set_ty.errorSetNames(mod);
@ -7450,7 +7450,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {
fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
const ptr_ty = func.typeOf(extra.ptr);
@ -7523,7 +7523,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const atomic_load = func.air.instructions.items(.data)[inst].atomic_load;
const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
const ptr = try func.resolveInst(atomic_load.ptr);
const ty = func.typeOfIndex(inst);
@ -7550,7 +7550,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;
const ptr = try func.resolveInst(pl_op.operand);
@ -7736,7 +7736,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const mod = func.bin_file.base.options.module.?;
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr = try func.resolveInst(bin_op.lhs);
const operand = try func.resolveInst(bin_op.rhs);

File diff suppressed because it is too large Load Diff

View File

@ -329,9 +329,13 @@ pub const Function = struct {
return .{ .new_local = @intCast(f.locals.items.len - 1) };
}
fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue {
fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
const result = try f.allocAlignedLocal(ty, .{}, .none);
log.debug("%{d}: allocating t{d}", .{ inst, result.new_local });
if (inst) |i| {
log.debug("%{d}: allocating t{d}", .{ i, result.new_local });
} else {
log.debug("allocating t{d}", .{result.new_local});
}
return result;
}
@ -2951,7 +2955,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
const pre_locals_len = @as(LocalIndex, @intCast(f.locals.items.len));
for (leading_deaths) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
if (inner) {
@ -2969,11 +2973,11 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
// them, unless they were used to store allocs.
for (pre_locals_len..f.locals.items.len) |local_i| {
const local_index = @as(LocalIndex, @intCast(local_i));
const local_index: LocalIndex = @intCast(local_i);
if (f.allocs.contains(local_index)) {
continue;
}
try freeLocal(f, inst, local_index, 0);
try freeLocal(f, inst, local_index, null);
}
}
@ -2986,7 +2990,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip))
continue;
const result_value = switch (air_tags[inst]) {
const result_value = switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
.inferred_alloc, .inferred_alloc_comptime => unreachable,
@ -3013,7 +3017,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
.div_trunc, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .none),
.rem => blk: {
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_scalar_ty = f.typeOf(bin_op.lhs).scalarType(mod);
// For binary operations @TypeOf(lhs)==@TypeOf(rhs),
// so we only check one.
@ -3061,16 +3065,16 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
.slice => try airSlice(f, inst),
.cmp_gt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gt),
.cmp_gte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .gte),
.cmp_lt => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lt),
.cmp_lte => try airCmpOp(f, inst, f.air.instructions.items(.data)[inst].bin_op, .lte),
.cmp_gt => try airCmpOp(f, inst, f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op, .gt),
.cmp_gte => try airCmpOp(f, inst, f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op, .gte),
.cmp_lt => try airCmpOp(f, inst, f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op, .lt),
.cmp_lte => try airCmpOp(f, inst, f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op, .lte),
.cmp_eq => try airEquality(f, inst, .eq),
.cmp_neq => try airEquality(f, inst, .neq),
.cmp_vector => blk: {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.VectorCmp, ty_pl.payload).data;
break :blk try airCmpOp(f, inst, extra, extra.compareOperator());
},
@ -3256,7 +3260,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
if (result_value == .new_local) {
log.debug("map %{d} to t{d}", .{ inst, result_value.new_local });
}
try f.value_map.putNoClobber(Air.indexToRef(inst), switch (result_value) {
try f.value_map.putNoClobber(inst.toRef(), switch (result_value) {
.none => continue,
.new_local => |i| .{ .local = i },
else => result_value,
@ -3265,7 +3269,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
}
fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
@ -3287,7 +3291,7 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
@ -3312,7 +3316,7 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
@ -3349,7 +3353,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const inst_ty = f.typeOfIndex(inst);
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
return .none;
@ -3374,7 +3378,7 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
@ -3404,7 +3408,7 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const inst_ty = f.typeOfIndex(inst);
if (!inst_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
@ -3486,7 +3490,7 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ptr_ty = f.typeOf(ty_op.operand);
const ptr_scalar_ty = ptr_ty.scalarType(mod);
@ -3573,14 +3577,14 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
const op_inst = Air.refToIndex(un_op);
const op_inst = un_op.toIndex();
const op_ty = f.typeOf(un_op);
const ret_ty = if (is_ptr) op_ty.childType(mod) else op_ty;
const lowered_ret_ty = try lowerFnRetTy(ret_ty, mod);
if (op_inst != null and f.air.instructions.items(.tag)[op_inst.?] == .call_always_tail) {
if (op_inst != null and f.air.instructions.items(.tag)[@intFromEnum(op_inst.?)] == .call_always_tail) {
try reap(f, inst, &.{un_op});
_ = try airCall(f, op_inst.?, .always_tail);
} else if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@ -3611,7 +3615,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
try f.writeCValue(writer, ret_val, .Other);
try writer.writeAll(";\n");
if (is_array) {
try freeLocal(f, inst, ret_val.new_local, 0);
try freeLocal(f, inst, ret_val.new_local, null);
}
} else {
try reap(f, inst, &.{un_op});
@ -3623,7 +3627,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -3649,7 +3653,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -3732,7 +3736,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
const writer = f.object.writer();
@ -3749,7 +3753,7 @@ fn airIntFromBool(f: *Function, inst: Air.Inst.Index) !CValue {
fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
const mod = f.object.dg.module;
// *a = b;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = f.typeOf(bin_op.lhs);
const ptr_scalar_ty = ptr_ty.scalarType(mod);
@ -3815,7 +3819,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try f.renderType(writer, src_ty);
try writer.writeAll("))");
if (src_val == .constant) {
try freeLocal(f, inst, array_src.new_local, 0);
try freeLocal(f, inst, array_src.new_local, null);
}
} else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
const host_bits = ptr_info.packed_offset.host_size * 8;
@ -3887,7 +3891,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try f.resolveInst(bin_op.lhs);
@ -3925,7 +3929,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_ty = f.typeOf(ty_op.operand);
const scalar_ty = operand_ty.scalarType(mod);
if (scalar_ty.ip_index != .bool_type) return try airUnBuiltinCall(f, inst, "not", .bits);
@ -3958,7 +3962,7 @@ fn airBinOp(
info: BuiltinInfo,
) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
const scalar_ty = operand_ty.scalarType(mod);
if ((scalar_ty.isInt(mod) and scalar_ty.bitSize(mod) > 64) or scalar_ty.isRuntimeFloat())
@ -4046,7 +4050,7 @@ fn airEquality(
operator: std.math.CompareOperator,
) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
const operand_bits = operand_ty.bitSize(mod);
@ -4109,7 +4113,7 @@ fn airEquality(
}
fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(un_op);
@ -4126,7 +4130,7 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try f.resolveInst(bin_op.lhs);
@ -4174,7 +4178,7 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const inst_ty = f.typeOfIndex(inst);
const inst_scalar_ty = inst_ty.scalarType(mod);
@ -4216,7 +4220,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr = try f.resolveInst(bin_op.lhs);
@ -4260,7 +4264,7 @@ fn airCall(
const gpa = f.object.dg.gpa;
const writer = f.object.writer();
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = f.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[extra.end..][0..extra.data.args_len]));
@ -4366,7 +4370,7 @@ fn airCall(
if (resolved_arg == .none) continue;
if (args_written != 0) try writer.writeAll(", ");
try f.writeCValue(writer, resolved_arg, .FunctionArgument);
if (resolved_arg == .new_local) try freeLocal(f, inst, resolved_arg.new_local, 0);
if (resolved_arg == .new_local) try freeLocal(f, inst, resolved_arg.new_local, null);
args_written += 1;
}
try writer.writeAll(");\n");
@ -4383,7 +4387,7 @@ fn airCall(
try writer.writeAll(", sizeof(");
try f.renderType(writer, ret_ty);
try writer.writeAll("));\n");
try freeLocal(f, inst, result_local.new_local, 0);
try freeLocal(f, inst, result_local.new_local, null);
break :result array_local;
};
@ -4391,7 +4395,7 @@ fn airCall(
}
fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
const dbg_stmt = f.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
const writer = f.object.writer();
// TODO re-evaluate whether to emit these or not. If we naively emit
// these directives, the output file will report bogus line numbers because
@ -4406,7 +4410,7 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_fn = f.air.instructions.items(.data)[inst].ty_fn;
const ty_fn = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const mod = f.object.dg.module;
const writer = f.object.writer();
const owner_decl = mod.funcOwnerDeclPtr(ty_fn.func);
@ -4418,7 +4422,7 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const name = f.air.nullTerminatedString(pl_op.payload);
const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep(mod) else false;
if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
@ -4431,9 +4435,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Block, ty_pl.payload);
const body = f.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);
const liveness_block = f.liveness.getBlock(inst);
const block_id: usize = f.next_block_index;
@ -4457,7 +4461,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
// The body might result in some values we had beforehand being killed
for (liveness_block.deaths) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
try f.object.indent_writer.insertNewline();
@ -4472,18 +4476,18 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = f.air.extraData(Air.Try, pl_op.payload);
const body = f.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);
const err_union_ty = f.typeOf(pl_op.operand);
return lowerTry(f, inst, pl_op.operand, body, err_union_ty, false);
}
fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.TryPtr, ty_pl.payload);
const body = f.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]);
const err_union_ty = f.typeOf(extra.data.ptr).childType(mod);
return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true);
}
@ -4529,7 +4533,7 @@ fn lowerTry(
// Now we have the "then branch" (in terms of the liveness data); process any deaths.
for (liveness_condbr.then_deaths) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
if (!payload_has_bits) {
@ -4559,7 +4563,7 @@ fn lowerTry(
}
fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
const branch = f.air.instructions.items(.data)[inst].br;
const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
const block = f.blocks.get(branch.block_inst).?;
const result = block.result;
const writer = f.object.writer();
@ -4582,7 +4586,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const dest_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
@ -4624,7 +4628,7 @@ const LocalResult = struct {
fn free(lr: LocalResult, f: *Function) !void {
if (lr.need_free) {
try freeLocal(f, 0, lr.c_value.new_local, 0);
try freeLocal(f, null, lr.c_value.new_local, null);
}
}
};
@ -4648,7 +4652,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
}
if (dest_ty.isPtrAtRuntime(mod) and operand_ty.isPtrAtRuntime(mod)) {
const local = try f.allocLocal(0, dest_ty);
const local = try f.allocLocal(null, dest_ty);
try f.writeCValue(writer, local, .Other);
try writer.writeAll(" = (");
try f.renderType(writer, dest_ty);
@ -4662,7 +4666,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
}
const operand_lval = if (operand == .constant) blk: {
const operand_local = try f.allocLocal(0, operand_ty);
const operand_local = try f.allocLocal(null, operand_ty);
try f.writeCValue(writer, operand_local, .Other);
if (operand_ty.isAbiInt(mod)) {
try writer.writeAll(" = ");
@ -4676,7 +4680,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
break :blk operand_local;
} else operand;
const local = try f.allocLocal(0, dest_ty);
const local = try f.allocLocal(null, dest_ty);
try writer.writeAll("memcpy(&");
try f.writeCValue(writer, local, .Other);
try writer.writeAll(", &");
@ -4741,7 +4745,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !Loca
}
if (operand == .constant) {
try freeLocal(f, 0, operand_lval.new_local, 0);
try freeLocal(f, null, operand_lval.new_local, null);
}
return .{
@ -4784,7 +4788,7 @@ fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
const atomic_order = f.air.instructions.items(.data)[inst].fence;
const atomic_order = f.air.instructions.items(.data)[@intFromEnum(inst)].fence;
const writer = f.object.writer();
try writer.writeAll("zig_fence(");
@ -4803,9 +4807,9 @@ fn airUnreach(f: *Function) !CValue {
}
fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = f.air.extraData(Air.Block, ty_pl.payload);
const body = f.air.extra[loop.end..][0..loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(f.air.extra[loop.end..][0..loop.data.body_len]);
const writer = f.object.writer();
try writer.writeAll("for (;;) ");
@ -4816,12 +4820,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const cond = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
const extra = f.air.extraData(Air.CondBr, pl_op.payload);
const then_body = f.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const liveness_condbr = f.liveness.getCondBr(inst);
const writer = f.object.writer();
@ -4837,7 +4841,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
// `free_locals_map` well defined (our parent is responsible for doing that).
for (liveness_condbr.else_deaths) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
// We never actually need an else block, because our branches are noreturn so must (for
@ -4850,7 +4854,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const condition = try f.resolveInst(pl_op.operand);
try reap(f, inst, &.{pl_op.operand});
const condition_ty = f.typeOf(pl_op.operand);
@ -4883,7 +4887,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
for (0..switch_br.data.cases_len) |case_i| {
const case = f.air.extraData(Air.SwitchBr.Case, extra_index);
const items = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[case.end..][0..case.data.items_len]));
const case_body = f.air.extra[case.end + items.len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(f.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + case.data.items_len + case_body.len;
for (items) |item| {
@ -4903,7 +4907,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
try genBodyResolveState(f, inst, liveness.deaths[case_i], case_body, false);
} else {
for (liveness.deaths[case_i]) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
try genBody(f, case_body);
}
@ -4911,12 +4915,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
// The case body must be noreturn so we don't need to insert a break.
}
const else_body = f.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra[extra_index..][0..switch_br.data.else_body_len]);
try f.object.indent_writer.insertNewline();
if (else_body.len > 0) {
// Note that this must be the last case (i.e. the `last_case_i` case was not hit above)
for (liveness.deaths[liveness.deaths.len - 1]) |death| {
try die(f, inst, Air.indexToRef(death));
try die(f, inst, death.toRef());
}
try writer.writeAll("default: ");
try genBody(f, else_body);
@ -4951,7 +4955,7 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
const clobbers_len = @as(u31, @truncate(extra.data.flags));
@ -5213,7 +5217,7 @@ fn airIsNull(
is_ptr: bool,
) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
const operand = try f.resolveInst(un_op);
@ -5259,7 +5263,7 @@ fn airIsNull(
fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -5293,7 +5297,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
@ -5324,7 +5328,7 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const writer = f.object.writer();
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -5433,7 +5437,7 @@ fn fieldLocation(
}
fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
const container_ptr_val = try f.resolveInst(extra.struct_operand);
@ -5443,7 +5447,7 @@ fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const container_ptr_val = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -5453,7 +5457,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
const container_ptr_ty = f.typeOfIndex(inst);
@ -5558,7 +5562,7 @@ fn fieldPtr(
fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
@ -5634,7 +5638,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(", sizeof(");
try f.renderType(writer, inst_ty);
try writer.writeAll("));\n");
try freeLocal(f, inst, temp_local.new_local, 0);
try freeLocal(f, inst, temp_local.new_local, null);
return local;
},
},
@ -5666,7 +5670,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll("));\n");
if (struct_byval == .constant) {
try freeLocal(f, inst, operand_lval.new_local, 0);
try freeLocal(f, inst, operand_lval.new_local, null);
}
return local;
@ -5695,7 +5699,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
/// Note that the result is never a pointer.
fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
@ -5736,7 +5740,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
@ -5772,7 +5776,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const repr_is_payload = inst_ty.optionalReprIsPayload(mod);
@ -5804,7 +5808,7 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const payload_ty = inst_ty.errorUnionPayload(mod);
@ -5844,7 +5848,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const writer = f.object.writer();
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
@ -5894,7 +5898,7 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const payload_ty = inst_ty.errorUnionPayload(mod);
@ -5928,7 +5932,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
const operand = try f.resolveInst(un_op);
@ -5963,7 +5967,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -5994,7 +5998,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(ty_op.operand);
@ -6037,7 +6041,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
fn airIntFromPtr(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
const operand_ty = f.typeOf(un_op);
@ -6066,7 +6070,7 @@ fn airUnBuiltinCall(
info: BuiltinInfo,
) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -6110,7 +6114,7 @@ fn airBinBuiltinCall(
info: BuiltinInfo,
) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const operand_ty = f.typeOf(bin_op.lhs);
const operand_cty = try f.typeToCType(operand_ty, .complete);
@ -6215,7 +6219,7 @@ fn airCmpBuiltinCall(
fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
const inst_ty = f.typeOfIndex(inst);
const ptr = try f.resolveInst(extra.ptr);
@ -6311,7 +6315,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
try new_value_mat.end(f, inst);
if (f.liveness.isUnused(inst)) {
try freeLocal(f, inst, local.new_local, 0);
try freeLocal(f, inst, local.new_local, null);
return .none;
}
@ -6320,7 +6324,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
const inst_ty = f.typeOfIndex(inst);
const ptr_ty = f.typeOf(pl_op.operand);
@ -6366,7 +6370,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
try operand_mat.end(f, inst);
if (f.liveness.isUnused(inst)) {
try freeLocal(f, inst, local.new_local, 0);
try freeLocal(f, inst, local.new_local, null);
return .none;
}
@ -6375,7 +6379,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const atomic_load = f.air.instructions.items(.data)[inst].atomic_load;
const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
const ptr = try f.resolveInst(atomic_load.ptr);
try reap(f, inst, &.{atomic_load.ptr});
const ptr_ty = f.typeOf(atomic_load.ptr);
@ -6411,7 +6415,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = f.typeOf(bin_op.lhs);
const ty = ptr_ty.childType(mod);
const ptr = try f.resolveInst(bin_op.lhs);
@ -6455,7 +6459,7 @@ fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !vo
fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dest_ty = f.typeOf(bin_op.lhs);
const dest_slice = try f.resolveInst(bin_op.lhs);
const value = try f.resolveInst(bin_op.rhs);
@ -6542,7 +6546,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
try a.end(f, writer);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
try freeLocal(f, inst, index.new_local, 0);
try freeLocal(f, inst, index.new_local, null);
return .none;
}
@ -6577,7 +6581,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dest_ptr = try f.resolveInst(bin_op.lhs);
const src_ptr = try f.resolveInst(bin_op.rhs);
const dest_ty = f.typeOf(bin_op.lhs);
@ -6616,7 +6620,7 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const union_ptr = try f.resolveInst(bin_op.lhs);
const new_tag = try f.resolveInst(bin_op.rhs);
try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
@ -6637,7 +6641,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -6659,7 +6663,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const inst_ty = f.typeOfIndex(inst);
const enum_ty = f.typeOf(un_op);
@ -6679,7 +6683,7 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
@ -6696,7 +6700,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
try reap(f, inst, &.{ty_op.operand});
@ -6719,7 +6723,7 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = f.air.extraData(Air.Bin, pl_op.payload).data;
const pred = try f.resolveInst(pl_op.operand);
@ -6751,7 +6755,7 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data;
const mask = Value.fromInterned(extra.mask);
@ -6783,7 +6787,7 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const reduce = f.air.instructions.items(.data)[inst].reduce;
const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
const scalar_ty = f.typeOfIndex(inst);
const operand = try f.resolveInst(reduce.operand);
@ -6939,7 +6943,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const inst_ty = f.typeOfIndex(inst);
const len = @as(usize, @intCast(inst_ty.arrayLen(mod)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(f.air.extra[ty_pl.payload..][0..len]));
@ -7069,7 +7073,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ip = &mod.intern_pool;
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
const union_ty = f.typeOfIndex(inst);
@ -7117,7 +7121,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const prefetch = f.air.instructions.items(.data)[inst].prefetch;
const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
const ptr_ty = f.typeOf(prefetch.ptr);
const ptr = try f.resolveInst(prefetch.ptr);
@ -7142,7 +7146,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
@ -7156,7 +7160,7 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
@ -7174,7 +7178,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
@ -7200,7 +7204,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue {
fn airAbs(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand = try f.resolveInst(ty_op.operand);
const ty = f.typeOf(ty_op.operand);
const scalar_ty = ty.scalarType(mod);
@ -7239,7 +7243,7 @@ fn unFloatOp(f: *Function, inst: Air.Inst.Index, operand: CValue, ty: Type, oper
}
fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
@ -7250,7 +7254,7 @@ fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVal
fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue {
const mod = f.object.dg.module;
const bin_op = f.air.instructions.items(.data)[inst].bin_op;
const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs = try f.resolveInst(bin_op.lhs);
const rhs = try f.resolveInst(bin_op.rhs);
@ -7282,7 +7286,7 @@ fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CVa
fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
const mod = f.object.dg.module;
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;
const mulend1 = try f.resolveInst(bin_op.lhs);
@ -7336,7 +7340,7 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const va_list = try f.resolveInst(ty_op.operand);
@ -7348,13 +7352,13 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
try writer.writeAll(" = va_arg(*(va_list *)");
try f.writeCValue(writer, va_list, .Other);
try writer.writeAll(", ");
try f.renderType(writer, f.air.getRefType(ty_op.ty));
try f.renderType(writer, ty_op.ty.toType());
try writer.writeAll(");\n");
return local;
}
fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
const un_op = f.air.instructions.items(.data)[inst].un_op;
const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const va_list = try f.resolveInst(un_op);
try reap(f, inst, &.{un_op});
@ -7367,7 +7371,7 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
}
fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
const ty_op = f.air.instructions.items(.data)[inst].ty_op;
const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const inst_ty = f.typeOfIndex(inst);
const va_list = try f.resolveInst(ty_op.operand);
@ -7836,7 +7840,7 @@ const Materialize = struct {
pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
switch (self.local) {
.new_local => |local| try freeLocal(f, inst, local, 0),
.new_local => |local| try freeLocal(f, inst, local, null),
else => {},
}
}
@ -7926,7 +7930,7 @@ const Vectorize = struct {
if (self.index != .none) {
f.object.indent_writer.popIndent();
try writer.writeAll("}\n");
try freeLocal(f, inst, self.index.new_local, 0);
try freeLocal(f, inst, self.index.new_local, null);
}
}
};
@ -7972,7 +7976,7 @@ fn reap(f: *Function, inst: Air.Inst.Index, operands: []const Air.Inst.Ref) !voi
}
fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {
const ref_inst = Air.refToIndex(ref) orelse return;
const ref_inst = ref.toIndex() orelse return;
const c_value = (f.value_map.fetchRemove(ref) orelse return).value;
const local_index = switch (c_value) {
.local, .new_local => |l| l,
@ -7981,10 +7985,22 @@ fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {
try freeLocal(f, inst, local_index, ref_inst);
}
fn freeLocal(f: *Function, inst: Air.Inst.Index, local_index: LocalIndex, ref_inst: Air.Inst.Index) !void {
fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_inst: ?Air.Inst.Index) !void {
const gpa = f.object.dg.gpa;
const local = &f.locals.items[local_index];
log.debug("%{d}: freeing t{d} (operand %{d})", .{ inst, local_index, ref_inst });
if (inst) |i| {
if (ref_inst) |operand| {
log.debug("%{d}: freeing t{d} (operand %{d})", .{ @intFromEnum(i), local_index, operand });
} else {
log.debug("%{d}: freeing t{d}", .{ @intFromEnum(i), local_index });
}
} else {
if (ref_inst) |operand| {
log.debug("freeing t{d} (operand %{d})", .{ local_index, operand });
} else {
log.debug("freeing t{d}", .{local_index});
}
}
const gop = try f.free_locals_map.getOrPut(gpa, local.getType());
if (!gop.found_existing) gop.value_ptr.* = .{};
if (std.debug.runtime_safety) {

File diff suppressed because it is too large Load Diff

View File

@ -445,7 +445,7 @@ const DeclGen = struct {
return try self.constant(ty, val, .direct);
}
const index = Air.refToIndex(inst).?;
const index = inst.toIndex().?;
return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage.
}
@ -2089,7 +2089,7 @@ const DeclGen = struct {
return;
const air_tags = self.air.instructions.items(.tag);
const maybe_result_id: ?IdRef = switch (air_tags[inst]) {
const maybe_result_id: ?IdRef = switch (air_tags[@intFromEnum(inst)]) {
// zig fmt: off
.add, .add_wrap => try self.airArithOp(inst, .OpFAdd, .OpIAdd, .OpIAdd, true),
.sub, .sub_wrap => try self.airArithOp(inst, .OpFSub, .OpISub, .OpISub, true),
@ -2255,7 +2255,7 @@ const DeclGen = struct {
fn airBinOpSimple(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const ty = self.typeOf(bin_op.lhs);
@ -2265,7 +2265,7 @@ const DeclGen = struct {
fn airShift(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const result_type_id = try self.resolveTypeId(self.typeOfIndex(inst));
@ -2291,7 +2291,7 @@ const DeclGen = struct {
fn airMinMax(self: *DeclGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const result_ty = self.typeOfIndex(inst);
@ -2395,7 +2395,7 @@ const DeclGen = struct {
// LHS and RHS are guaranteed to have the same type, and AIR guarantees
// the result to be the same as the LHS and RHS, which matches SPIR-V.
const ty = self.typeOfIndex(inst);
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
@ -2492,7 +2492,7 @@ const DeclGen = struct {
) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
const lhs = try self.resolve(extra.lhs);
const rhs = try self.resolve(extra.rhs);
@ -2601,7 +2601,7 @@ const DeclGen = struct {
const mod = self.module;
if (self.liveness.isUnused(inst)) return null;
const ty = self.typeOfIndex(inst);
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
const a = try self.resolve(extra.a);
const b = try self.resolve(extra.b);
@ -2719,7 +2719,7 @@ const DeclGen = struct {
fn airPtrAdd(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_id = try self.resolve(bin_op.lhs);
const offset_id = try self.resolve(bin_op.rhs);
@ -2731,7 +2731,7 @@ const DeclGen = struct {
fn airPtrSub(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_id = try self.resolve(bin_op.lhs);
const ptr_ty = self.typeOf(bin_op.lhs);
@ -2919,7 +2919,7 @@ const DeclGen = struct {
comptime op: std.math.CompareOperator,
) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const lhs_id = try self.resolve(bin_op.lhs);
const rhs_id = try self.resolve(bin_op.rhs);
const ty = self.typeOf(bin_op.lhs);
@ -2931,7 +2931,7 @@ const DeclGen = struct {
fn airVectorCmp(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const vec_cmp = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
const lhs_id = try self.resolve(vec_cmp.lhs);
const rhs_id = try self.resolve(vec_cmp.rhs);
@ -2999,7 +2999,7 @@ const DeclGen = struct {
fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const operand_ty = self.typeOf(ty_op.operand);
const result_ty = self.typeOfIndex(inst);
@ -3009,7 +3009,7 @@ const DeclGen = struct {
fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const src_ty = self.typeOf(ty_op.operand);
const dst_ty = self.typeOfIndex(inst);
@ -3057,7 +3057,7 @@ const DeclGen = struct {
fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand_id = try self.resolve(un_op);
return try self.intFromPtr(operand_id);
}
@ -3065,7 +3065,7 @@ const DeclGen = struct {
fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_ty = self.typeOf(ty_op.operand);
const operand_id = try self.resolve(ty_op.operand);
const operand_info = try self.arithmeticTypeInfo(operand_ty);
@ -3091,7 +3091,7 @@ const DeclGen = struct {
fn airIntFromFloat(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const dest_ty = self.typeOfIndex(inst);
const dest_info = try self.arithmeticTypeInfo(dest_ty);
@ -3116,7 +3116,7 @@ const DeclGen = struct {
fn airFloatCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const dest_ty = self.typeOfIndex(inst);
const dest_ty_id = try self.resolveTypeId(dest_ty);
@ -3132,7 +3132,7 @@ const DeclGen = struct {
fn airNot(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const result_ty = self.typeOfIndex(inst);
const result_ty_id = try self.resolveTypeId(result_ty);
@ -3166,7 +3166,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const array_ptr_ty = self.typeOf(ty_op.operand);
const array_ty = array_ptr_ty.childType(mod);
const slice_ty = self.typeOfIndex(inst);
@ -3195,7 +3195,7 @@ const DeclGen = struct {
fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const ptr_id = try self.resolve(bin_op.lhs);
const len_id = try self.resolve(bin_op.rhs);
@ -3216,7 +3216,7 @@ const DeclGen = struct {
const mod = self.module;
const ip = &mod.intern_pool;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const result_ty = self.typeOfIndex(inst);
const len: usize = @intCast(result_ty.arrayLen(mod));
const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
@ -3316,7 +3316,7 @@ const DeclGen = struct {
}
fn airMemcpy(self: *DeclGen, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const dest_slice = try self.resolve(bin_op.lhs);
const src_slice = try self.resolve(bin_op.rhs);
const dest_ty = self.typeOf(bin_op.lhs);
@ -3333,7 +3333,7 @@ const DeclGen = struct {
fn airSliceField(self: *DeclGen, inst: Air.Inst.Index, field: u32) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const field_ty = self.typeOfIndex(inst);
const operand_id = try self.resolve(ty_op.operand);
return try self.extractField(field_ty, operand_id, field);
@ -3341,7 +3341,7 @@ const DeclGen = struct {
fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const slice_ty = self.typeOf(bin_op.lhs);
if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
@ -3358,7 +3358,7 @@ const DeclGen = struct {
fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const slice_ty = self.typeOf(bin_op.lhs);
if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null;
@ -3392,7 +3392,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
const src_ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = src_ptr_ty.childType(mod);
@ -3411,7 +3411,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const array_ty = self.typeOf(bin_op.lhs);
const elem_ty = array_ty.childType(mod);
const array_id = try self.resolve(bin_op.lhs);
@ -3433,7 +3433,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = self.typeOfIndex(inst);
const ptr_id = try self.resolve(bin_op.lhs);
@ -3444,7 +3444,7 @@ const DeclGen = struct {
fn airSetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const un_ptr_ty = self.typeOf(bin_op.lhs);
const un_ty = un_ptr_ty.childType(mod);
const layout = self.unionLayout(un_ty);
@ -3468,7 +3468,7 @@ const DeclGen = struct {
fn airGetUnionTag(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const un_ty = self.typeOf(ty_op.operand);
const mod = self.module;
@ -3555,7 +3555,7 @@ const DeclGen = struct {
const mod = self.module;
const ip = &mod.intern_pool;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
const ty = self.typeOfIndex(inst);
@ -3572,7 +3572,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
const object_ty = self.typeOf(struct_field.struct_operand);
@ -3616,11 +3616,11 @@ const DeclGen = struct {
fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
const res_ty = try self.resolveType(self.air.getRefType(ty_pl.ty), .indirect);
const parent_ty = ty_pl.ty.toType().childType(mod);
const res_ty = try self.resolveType(ty_pl.ty.toType(), .indirect);
const usize_ty = Type.usize;
const usize_ty_ref = try self.resolveType(usize_ty, .direct);
@ -3692,7 +3692,7 @@ const DeclGen = struct {
fn airStructFieldPtrIndex(self: *DeclGen, inst: Air.Inst.Index, field_index: u32) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const struct_ptr = try self.resolve(ty_op.operand);
const struct_ptr_ty = self.typeOf(ty_op.operand);
const result_ptr_ty = self.typeOfIndex(inst);
@ -3918,8 +3918,9 @@ const DeclGen = struct {
const mod = self.module;
const ty = self.typeOfIndex(inst);
const inst_datas = self.air.instructions.items(.data);
const extra = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const extra = self.air.extraData(Air.Block, inst_datas[@intFromEnum(inst)].ty_pl.payload);
const body: []const Air.Inst.Index =
@ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(mod);
const cf = switch (self.control_flow) {
@ -3983,7 +3984,7 @@ const DeclGen = struct {
// Check if the target of the branch was this current block.
const block_id_ty_ref = try self.intType(.unsigned, 32);
const this_block = try self.constInt(block_id_ty_ref, inst);
const this_block = try self.constInt(block_id_ty_ref, @intFromEnum(inst));
const jump_to_this_block_id = self.spv.allocId();
const bool_ty_ref = try self.resolveType(Type.bool, .direct);
try self.func.body.emit(self.spv.gpa, .OpIEqual, .{
@ -4052,7 +4053,7 @@ const DeclGen = struct {
fn airBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const br = self.air.instructions.items(.data)[inst].br;
const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
const operand_ty = self.typeOf(br.operand);
switch (self.control_flow) {
@ -4064,7 +4065,7 @@ const DeclGen = struct {
}
const block_id_ty_ref = try self.intType(.unsigned, 32);
const next_block = try self.constInt(block_id_ty_ref, br.block_inst);
const next_block = try self.constInt(block_id_ty_ref, @intFromEnum(br.block_inst));
try self.structuredBreak(next_block);
},
.unstructured => |cf| {
@ -4089,10 +4090,10 @@ const DeclGen = struct {
}
fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const cond_br = self.air.extraData(Air.CondBr, pl_op.payload);
const then_body = self.air.extra[cond_br.end..][0..cond_br.data.then_body_len];
const else_body = self.air.extra[cond_br.end + then_body.len ..][0..cond_br.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[cond_br.end..][0..cond_br.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[cond_br.end + then_body.len ..][0..cond_br.data.else_body_len]);
const condition_id = try self.resolve(pl_op.operand);
const then_label = self.spv.allocId();
@ -4149,9 +4150,9 @@ const DeclGen = struct {
}
fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload);
const body = self.air.extra[loop.end..][0..loop.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
const body_label = self.spv.allocId();
@ -4197,7 +4198,7 @@ const DeclGen = struct {
fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const ptr_ty = self.typeOf(ty_op.operand);
const elem_ty = self.typeOfIndex(inst);
const operand = try self.resolve(ty_op.operand);
@ -4207,7 +4208,7 @@ const DeclGen = struct {
}
fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
const ptr_ty = self.typeOf(bin_op.lhs);
const elem_ty = ptr_ty.childType(self.module);
const ptr = try self.resolve(bin_op.lhs);
@ -4217,7 +4218,7 @@ const DeclGen = struct {
}
fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
const operand = self.air.instructions.items(.data)[inst].un_op;
const operand = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const ret_ty = self.typeOf(operand);
const mod = self.module;
if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@ -4241,7 +4242,7 @@ const DeclGen = struct {
fn airRetLoad(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const ptr_ty = self.typeOf(un_op);
const ret_ty = ptr_ty.childType(mod);
@ -4269,10 +4270,10 @@ const DeclGen = struct {
fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const err_union_id = try self.resolve(pl_op.operand);
const extra = self.air.extraData(Air.Try, pl_op.payload);
const body = self.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
const err_union_ty = self.typeOf(pl_op.operand);
const payload_ty = self.typeOfIndex(inst);
@ -4344,7 +4345,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const err_union_ty = self.typeOf(ty_op.operand);
const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
@ -4368,7 +4369,7 @@ const DeclGen = struct {
fn airErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const payload_ty = self.typeOfIndex(inst);
const eu_layout = self.errorUnionLayout(payload_ty);
@ -4384,7 +4385,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const err_union_ty = self.typeOfIndex(inst);
const payload_ty = err_union_ty.errorUnionPayload(mod);
const operand_id = try self.resolve(ty_op.operand);
@ -4410,7 +4411,7 @@ const DeclGen = struct {
fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
if (self.liveness.isUnused(inst)) return null;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const err_union_ty = self.typeOfIndex(inst);
const operand_id = try self.resolve(ty_op.operand);
const payload_ty = self.typeOf(ty_op.operand);
@ -4436,7 +4437,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand_id = try self.resolve(un_op);
const optional_ty = self.typeOf(un_op);
@ -4493,7 +4494,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const un_op = self.air.instructions.items(.data)[inst].un_op;
const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
const operand_id = try self.resolve(un_op);
const err_union_ty = self.typeOf(un_op);
@ -4529,7 +4530,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const operand_id = try self.resolve(ty_op.operand);
const optional_ty = self.typeOf(ty_op.operand);
const payload_ty = self.typeOfIndex(inst);
@ -4547,7 +4548,7 @@ const DeclGen = struct {
if (self.liveness.isUnused(inst)) return null;
const mod = self.module;
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
const payload_ty = self.typeOf(ty_op.operand);
if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@ -4569,7 +4570,7 @@ const DeclGen = struct {
fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const cond_ty = self.typeOf(pl_op.operand);
const cond = try self.resolve(pl_op.operand);
const cond_indirect = try self.convertToIndirect(cond_ty, cond);
@ -4679,8 +4680,8 @@ const DeclGen = struct {
var extra_index: usize = switch_br.end;
for (0..num_cases) |case_i| {
const case = self.air.extraData(Air.SwitchBr.Case, extra_index);
const items = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[case.end..][0..case.data.items_len]));
const case_body = self.air.extra[case.end + items.len ..][0..case.data.body_len];
const items: []const Air.Inst.Ref = @ptrCast(self.air.extra[case.end..][0..case.data.items_len]);
const case_body: []const Air.Inst.Index = @ptrCast(self.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + case.data.items_len + case_body.len;
const label = IdResult{ .id = @intCast(first_case_label.id + case_i) };
@ -4702,7 +4703,7 @@ const DeclGen = struct {
}
}
const else_body = self.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);
try self.beginSpvBlock(default);
if (else_body.len != 0) {
switch (self.control_flow) {
@ -4734,7 +4735,7 @@ const DeclGen = struct {
}
fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
const mod = self.module;
const decl = mod.declPtr(self.decl_index);
const path = decl.getFileScope(mod).sub_file_path;
@ -4749,7 +4750,7 @@ const DeclGen = struct {
fn airDbgInlineBegin(self: *DeclGen, inst: Air.Inst.Index) !void {
const mod = self.module;
const fn_ty = self.air.instructions.items(.data)[inst].ty_fn;
const fn_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const decl_index = mod.funcInfo(fn_ty.func).owner_decl;
const decl = mod.declPtr(decl_index);
try self.base_line_stack.append(self.gpa, decl.src_line);
@ -4761,7 +4762,7 @@ const DeclGen = struct {
}
fn airDbgVar(self: *DeclGen, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const target_id = try self.resolve(pl_op.operand);
const name = self.air.nullTerminatedString(pl_op.payload);
try self.spv.debugName(target_id, name);
@ -4769,7 +4770,7 @@ const DeclGen = struct {
fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const mod = self.module;
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
@ -4901,7 +4902,7 @@ const DeclGen = struct {
_ = modifier;
const mod = self.module;
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = self.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
const callee_ty = self.typeOf(pl_op.operand);

View File

@ -94,7 +94,7 @@ const Writer = struct {
}
fn writeInst(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const tag = w.air.instructions.items(.tag)[inst];
const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)];
try s.writeByteNTimes(' ', w.indent);
try s.print("%{d}{c}= {s}(", .{
inst,
@ -329,14 +329,14 @@ const Writer = struct {
}
fn writeBinOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const bin_op = w.air.instructions.items(.data)[inst].bin_op;
const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
try w.writeOperand(s, inst, 0, bin_op.lhs);
try s.writeAll(", ");
try w.writeOperand(s, inst, 1, bin_op.rhs);
}
fn writeUnOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const un_op = w.air.instructions.items(.data)[inst].un_op;
const un_op = w.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
try w.writeOperand(s, inst, 0, un_op);
}
@ -351,33 +351,33 @@ const Writer = struct {
}
fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty = w.air.instructions.items(.data)[inst].ty;
const ty = w.air.instructions.items(.data)[@intFromEnum(inst)].ty;
try w.writeType(s, ty);
}
fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const arg = w.air.instructions.items(.data)[inst].arg;
try w.writeType(s, w.air.getRefType(arg.ty));
const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
try w.writeType(s, arg.ty.toType());
try s.print(", {d}", .{arg.src_index});
}
fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_op = w.air.instructions.items(.data)[inst].ty_op;
try w.writeType(s, w.air.getRefType(ty_op.ty));
const ty_op = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
try w.writeType(s, ty_op.ty.toType());
try s.writeAll(", ");
try w.writeOperand(s, inst, 0, ty_op.operand);
}
fn writeBlock(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Block, ty_pl.payload);
const body = w.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]);
const liveness_block = if (w.liveness) |liveness|
liveness.getBlock(inst)
else
Liveness.BlockSlices{ .deaths = &.{} };
try w.writeType(s, w.air.getRefType(ty_pl.ty));
try w.writeType(s, ty_pl.ty.toType());
if (w.skip_body) return s.writeAll(", ...");
try s.writeAll(", {\n");
const old_indent = w.indent;
@ -393,11 +393,11 @@ const Writer = struct {
}
fn writeLoop(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Block, ty_pl.payload);
const body = w.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]);
try w.writeType(s, w.air.getRefType(ty_pl.ty));
try w.writeType(s, ty_pl.ty.toType());
if (w.skip_body) return s.writeAll(", ...");
try s.writeAll(", {\n");
const old_indent = w.indent;
@ -410,8 +410,8 @@ const Writer = struct {
fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const mod = w.module;
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const vector_ty = w.air.getRefType(ty_pl.ty);
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const vector_ty = ty_pl.ty.toType();
const len = @as(usize, @intCast(vector_ty.arrayLen(mod)));
const elements = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra[ty_pl.payload..][0..len]));
@ -425,7 +425,7 @@ const Writer = struct {
}
fn writeUnionInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.UnionInit, ty_pl.payload).data;
try s.print("{d}, ", .{extra.field_index});
@ -433,7 +433,7 @@ const Writer = struct {
}
fn writeStructField(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.StructField, ty_pl.payload).data;
try w.writeOperand(s, inst, 0, extra.struct_operand);
@ -442,10 +442,10 @@ const Writer = struct {
fn writeTyPlBin(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const data = w.air.instructions.items(.data);
const ty_pl = data[inst].ty_pl;
const ty_pl = data[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Bin, ty_pl.payload).data;
const inst_ty = w.air.getRefType(data[inst].ty_pl.ty);
const inst_ty = data[@intFromEnum(inst)].ty_pl.ty.toType();
try w.writeType(s, inst_ty);
try s.writeAll(", ");
try w.writeOperand(s, inst, 0, extra.lhs);
@ -454,7 +454,7 @@ const Writer = struct {
}
fn writeCmpxchg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
try w.writeOperand(s, inst, 0, extra.ptr);
@ -468,7 +468,7 @@ const Writer = struct {
}
fn writeMulAdd(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
try w.writeOperand(s, inst, 0, extra.lhs);
@ -479,7 +479,7 @@ const Writer = struct {
}
fn writeShuffle(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Shuffle, ty_pl.payload).data;
try w.writeOperand(s, inst, 0, extra.a);
@ -490,7 +490,7 @@ const Writer = struct {
fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const mod = w.module;
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.Bin, pl_op.payload).data;
const elem_ty = w.typeOfIndex(inst).childType(mod);
@ -504,14 +504,14 @@ const Writer = struct {
}
fn writeReduce(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const reduce = w.air.instructions.items(.data)[inst].reduce;
const reduce = w.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
try w.writeOperand(s, inst, 0, reduce.operand);
try s.print(", {s}", .{@tagName(reduce.operation)});
}
fn writeCmpVector(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data;
try s.print("{s}, ", .{@tagName(extra.compareOperator())});
@ -521,7 +521,7 @@ const Writer = struct {
}
fn writeVectorStoreElem(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const data = w.air.instructions.items(.data)[inst].vector_store_elem;
const data = w.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem;
const extra = w.air.extraData(Air.VectorCmp, data.payload).data;
try w.writeOperand(s, inst, 0, data.vector_ptr);
@ -532,20 +532,20 @@ const Writer = struct {
}
fn writeFence(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const atomic_order = w.air.instructions.items(.data)[inst].fence;
const atomic_order = w.air.instructions.items(.data)[@intFromEnum(inst)].fence;
try s.print("{s}", .{@tagName(atomic_order)});
}
fn writeAtomicLoad(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const atomic_load = w.air.instructions.items(.data)[inst].atomic_load;
const atomic_load = w.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
try w.writeOperand(s, inst, 0, atomic_load.ptr);
try s.print(", {s}", .{@tagName(atomic_load.order)});
}
fn writePrefetch(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const prefetch = w.air.instructions.items(.data)[inst].prefetch;
const prefetch = w.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
try w.writeOperand(s, inst, 0, prefetch.ptr);
try s.print(", {s}, {d}, {s}", .{
@ -559,7 +559,7 @@ const Writer = struct {
inst: Air.Inst.Index,
order: std.builtin.AtomicOrder,
) @TypeOf(s).Error!void {
const bin_op = w.air.instructions.items(.data)[inst].bin_op;
const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
try w.writeOperand(s, inst, 0, bin_op.lhs);
try s.writeAll(", ");
try w.writeOperand(s, inst, 1, bin_op.rhs);
@ -567,7 +567,7 @@ const Writer = struct {
}
fn writeAtomicRmw(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.AtomicRmw, pl_op.payload).data;
try w.writeOperand(s, inst, 0, pl_op.operand);
@ -577,7 +577,7 @@ const Writer = struct {
}
fn writeFieldParentPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
try w.writeOperand(s, inst, 0, extra.field_ptr);
@ -585,7 +585,7 @@ const Writer = struct {
}
fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.Asm, ty_pl.payload);
const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0;
const clobbers_len = @as(u31, @truncate(extra.data.flags));
@ -658,26 +658,26 @@ const Writer = struct {
}
fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const dbg_stmt = w.air.instructions.items(.data)[inst].dbg_stmt;
const dbg_stmt = w.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
}
fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;
const ty_fn = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
const func_index = ty_fn.func;
const owner_decl = w.module.funcOwnerDeclPtr(func_index);
try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)});
}
fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
try w.writeOperand(s, inst, 0, pl_op.operand);
const name = w.air.nullTerminatedString(pl_op.payload);
try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
}
fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.Call, pl_op.payload);
const args = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra[extra.end..][0..extra.data.args_len]));
try w.writeOperand(s, inst, 0, pl_op.operand);
@ -690,16 +690,16 @@ const Writer = struct {
}
fn writeBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const br = w.air.instructions.items(.data)[inst].br;
const br = w.air.instructions.items(.data)[@intFromEnum(inst)].br;
try w.writeInstIndex(s, br.block_inst, false);
try s.writeAll(", ");
try w.writeOperand(s, inst, 0, br.operand);
}
fn writeTry(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.Try, pl_op.payload);
const body = w.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]);
const liveness_condbr = if (w.liveness) |liveness|
liveness.getCondBr(inst)
else
@ -731,9 +731,9 @@ const Writer = struct {
}
fn writeTryPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const ty_pl = w.air.instructions.items(.data)[inst].ty_pl;
const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = w.air.extraData(Air.TryPtr, ty_pl.payload);
const body = w.air.extra[extra.end..][0..extra.data.body_len];
const body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.body_len]);
const liveness_condbr = if (w.liveness) |liveness|
liveness.getCondBr(inst)
else
@ -742,7 +742,7 @@ const Writer = struct {
try w.writeOperand(s, inst, 0, extra.data.ptr);
try s.writeAll(", ");
try w.writeType(s, w.air.getRefType(ty_pl.ty));
try w.writeType(s, ty_pl.ty.toType());
if (w.skip_body) return s.writeAll(", ...");
try s.writeAll(", {\n");
const old_indent = w.indent;
@ -768,10 +768,10 @@ const Writer = struct {
}
fn writeCondBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const extra = w.air.extraData(Air.CondBr, pl_op.payload);
const then_body = w.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = w.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
const then_body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end..][0..extra.data.then_body_len]);
const else_body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
const liveness_condbr = if (w.liveness) |liveness|
liveness.getCondBr(inst)
else
@ -813,7 +813,7 @@ const Writer = struct {
}
fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
const switch_br = w.air.extraData(Air.SwitchBr, pl_op.payload);
const liveness = if (w.liveness) |liveness|
liveness.getSwitchBr(w.gpa, inst, switch_br.data.cases_len + 1) catch
@ -836,7 +836,7 @@ const Writer = struct {
while (case_i < switch_br.data.cases_len) : (case_i += 1) {
const case = w.air.extraData(Air.SwitchBr.Case, extra_index);
const items = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra[case.end..][0..case.data.items_len]));
const case_body = w.air.extra[case.end + items.len ..][0..case.data.body_len];
const case_body: []const Air.Inst.Index = @ptrCast(w.air.extra[case.end + items.len ..][0..case.data.body_len]);
extra_index = case.end + case.data.items_len + case_body.len;
try s.writeAll(", [");
@ -863,7 +863,7 @@ const Writer = struct {
try s.writeAll("}");
}
const else_body = w.air.extra[extra_index..][0..switch_br.data.else_body_len];
const else_body: []const Air.Inst.Index = @ptrCast(w.air.extra[extra_index..][0..switch_br.data.else_body_len]);
if (else_body.len != 0) {
try s.writeAll(", else => {\n");
w.indent += 2;
@ -889,18 +889,18 @@ const Writer = struct {
}
fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
try s.print("{d}", .{pl_op.payload});
}
fn writeWasmMemoryGrow(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
try s.print("{d}, ", .{pl_op.payload});
try w.writeOperand(s, inst, 0, pl_op.operand);
}
fn writeWorkDimension(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
const pl_op = w.air.instructions.items(.data)[inst].pl_op;
const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
try s.print("{d}", .{pl_op.payload});
}
@ -938,7 +938,7 @@ const Writer = struct {
) @TypeOf(s).Error!void {
if (@intFromEnum(operand) < InternPool.static_len) {
return s.print("@{}", .{operand});
} else if (Air.refToInterned(operand)) |ip_index| {
} else if (operand.toInterned()) |ip_index| {
const mod = w.module;
const ty = Type.fromInterned(mod.intern_pool.indexToKey(ip_index).typeOf());
try s.print("<{}, {}>", .{
@ -946,7 +946,7 @@ const Writer = struct {
Value.fromInterned(ip_index).fmtValue(ty, mod),
});
} else {
return w.writeInstIndex(s, Air.refToIndex(operand).?, dies);
return w.writeInstIndex(s, operand.toIndex().?, dies);
}
}