Merge pull request #22876 from jacobly0/x86_64-rewrite

x86_64: implement error set and enum safety
This commit is contained in:
Andrew Kelley authored and GitHub committed 2025-02-15 12:33:09 -08:00
commit e5174c7441
172 files changed
+11211 -5445

No files matched your search

+1
View File
@@ -230,6 +230,7 @@ comptime {
_ = @import("compiler_rt/trunc.zig"); _ = @import("compiler_rt/trunc.zig");
// BigInt. Alphabetically sorted. // BigInt. Alphabetically sorted.
_ = @import("compiler_rt/divmodei4.zig");
_ = @import("compiler_rt/udivmodei4.zig"); _ = @import("compiler_rt/udivmodei4.zig");
_ = @import("compiler_rt/udivmodti4.zig"); _ = @import("compiler_rt/udivmodti4.zig");
+50
View File
@@ -0,0 +1,50 @@
const std = @import("std");
const builtin = @import("builtin");
const common = @import("common.zig");
const udivmod = @import("udivmodei4.zig").divmod;
comptime {
@export(&__divei4, .{ .name = "__divei4", .linkage = common.linkage, .visibility = common.visibility });
@export(&__modei4, .{ .name = "__modei4", .linkage = common.linkage, .visibility = common.visibility });
}
const endian = builtin.cpu.arch.endian();
inline fn limb(x: []u32, i: usize) *u32 {
return if (endian == .little) &x[i] else &x[x.len - 1 - i];
}
inline fn neg(x: []u32) void {
var ov: u1 = 1;
for (0..x.len) |limb_index| {
const l = limb(x, limb_index);
l.*, ov = @addWithOverflow(~l.*, ov);
}
}
/// Mutates the arguments!
fn divmod(q: ?[]u32, r: ?[]u32, u: []u32, v: []u32) !void {
const u_sign: i32 = @bitCast(u[u.len - 1]);
const v_sign: i32 = @bitCast(v[v.len - 1]);
if (u_sign < 0) neg(u);
if (v_sign < 0) neg(v);
try @call(.always_inline, udivmod, .{ q, r, u, v });
if (q) |x| if (u_sign ^ v_sign < 0) neg(x);
if (r) |x| if (u_sign < 0) neg(x);
}
pub fn __divei4(r_q: [*]u32, u_p: [*]u32, v_p: [*]u32, bits: usize) callconv(.C) void {
@setRuntimeSafety(builtin.is_test);
const u = u_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
const v = v_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
const q = r_q[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
@call(.always_inline, divmod, .{ q, null, u, v }) catch unreachable;
}
pub fn __modei4(r_p: [*]u32, u_p: [*]u32, v_p: [*]u32, bits: usize) callconv(.C) void {
@setRuntimeSafety(builtin.is_test);
const u = u_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
const v = v_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
const r = r_p[0 .. std.math.divCeil(usize, bits, 32) catch unreachable];
@call(.always_inline, divmod, .{ null, r, u, v }) catch unreachable;
}
+2 -2
View File
@@ -27,8 +27,8 @@ inline fn limb_set(x: []u32, i: usize, v: u32) void {
} }
} }
// Uses Knuth's Algorithm D, 4.3.1, p. 272. /// Uses Knuth's Algorithm D, 4.3.1, p. 272.
fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void { pub fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void {
if (q) |q_| @memset(q_[0..], 0); if (q) |q_| @memset(q_[0..], 0);
if (r) |r_| @memset(r_[0..], 0); if (r) |r_| @memset(r_[0..], 0);
+1 -1
View File
@@ -8850,7 +8850,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
// Use `intCast`, since it'll set up the Sema-emitted safety checks for us! // Use `intCast`, since it'll set up the Sema-emitted safety checks for us!
const int_val = try sema.intCast(block, src, int_tag_ty, src, operand, src, true, true); const int_val = try sema.intCast(block, src, int_tag_ty, src, operand, src, true, true);
const result = try block.addBitCast(dest_ty, int_val); const result = try block.addBitCast(dest_ty, int_val);
if (zcu.backendSupportsFeature(.is_named_enum_value)) { if (!dest_ty.isNonexhaustiveEnum(zcu) and zcu.backendSupportsFeature(.is_named_enum_value)) {
const ok = try block.addUnOp(.is_named_enum_value, result); const ok = try block.addUnOp(.is_named_enum_value, result);
try sema.addSafetyCheck(block, src, ok, .invalid_enum_value); try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
} }
+4 -4
View File
@@ -4190,11 +4190,11 @@ pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type };
pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type }; pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type };
pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type }; pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type };
pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type }; pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type };
pub const single_const_pointer_to_comptime_int: Type = .{ pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };
.ip_index = .single_const_pointer_to_comptime_int_type, pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type };
}; pub const single_const_pointer_to_comptime_int: Type = .{ .ip_index = .single_const_pointer_to_comptime_int_type };
pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type }; pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };
pub const vector_16_i8: Type = .{ .ip_index = .vector_16_i8_type }; pub const vector_16_i8: Type = .{ .ip_index = .vector_16_i8_type };
+10511 -5061
View File
File diff suppressed because it is too large. Load diff
+46 -22
View File
@@ -88,13 +88,32 @@ pub fn emitMir(emit: *Emit) Error!void {
lowered_relocs[0].lowered_inst_index == lowered_index) : ({ lowered_relocs[0].lowered_inst_index == lowered_index) : ({
lowered_relocs = lowered_relocs[1..]; lowered_relocs = lowered_relocs[1..];
}) switch (lowered_relocs[0].target) { }) switch (lowered_relocs[0].target) {
.inst => |target| try relocs.append(emit.lower.allocator, .{ .inst => |target| {
.source = start_offset, const inst_length: u4 = @intCast(end_offset - start_offset);
.source_offset = end_offset - 4, const reloc_offset, const reloc_length = reloc_offset_length: {
.target = target, var reloc_offset = inst_length;
.target_offset = lowered_relocs[0].off, var op_index: usize = lowered_inst.ops.len;
.length = @intCast(end_offset - start_offset), while (true) {
}), op_index -= 1;
const op = lowered_inst.encoding.data.ops[op_index];
if (op == .none) continue;
const enc_length: u4 = @intCast(
std.math.divCeil(u7, @intCast(op.immBitSize()), 8) catch unreachable,
);
reloc_offset -= enc_length;
if (op_index == lowered_relocs[0].op_index)
break :reloc_offset_length .{ reloc_offset, enc_length };
}
};
try relocs.append(emit.lower.allocator, .{
.inst_offset = start_offset,
.inst_length = inst_length,
.source_offset = reloc_offset,
.source_length = reloc_length,
.target = target,
.target_offset = lowered_relocs[0].off,
});
},
.table => try table_relocs.append(emit.lower.allocator, .{ .table => try table_relocs.append(emit.lower.allocator, .{
.source_offset = end_offset - 4, .source_offset = end_offset - 4,
.target_offset = lowered_relocs[0].off, .target_offset = lowered_relocs[0].off,
@@ -409,7 +428,7 @@ pub fn emitMir(emit: *Emit) Error!void {
} } }; } } };
}, },
.pseudo_dbg_local_am => loc: { .pseudo_dbg_local_am => loc: {
const mem = emit.lower.mem(mir_inst.data.ax.payload); const mem = emit.lower.mem(undefined, mir_inst.data.ax.payload);
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{ break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
base: { base: {
loc_buf[0] = switch (mem.base()) { loc_buf[0] = switch (mem.base()) {
@@ -466,15 +485,18 @@ pub fn emitMir(emit: *Emit) Error!void {
} }
} }
} }
{ for (relocs.items) |reloc| {
// TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size. const target = code_offset_mapping[reloc.target];
// This should be reversed like it is done in aarch64 MIR emit code: start with the smallest const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.inst_offset + reloc.inst_length)) + reloc.target_offset;
// possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution const inst_bytes = emit.code.items[reloc.inst_offset..][0..reloc.inst_length];
// until the entire decl is correctly emitted with all JMP/CALL instructions within range. switch (reloc.source_length) {
for (relocs.items) |reloc| { else => unreachable,
const target = code_offset_mapping[reloc.target]; inline 1, 4 => |source_length| std.mem.writeInt(
const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)) + reloc.target_offset; @Type(.{ .int = .{ .signedness = .signed, .bits = @as(u16, 8) * source_length } }),
std.mem.writeInt(i32, emit.code.items[reloc.source_offset..][0..4], @intCast(disp), .little); inst_bytes[reloc.source_offset..][0..source_length],
@intCast(disp),
.little,
),
} }
} }
if (emit.lower.mir.table.len > 0) { if (emit.lower.mir.table.len > 0) {
@@ -511,15 +533,17 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error {
const Reloc = struct { const Reloc = struct {
/// Offset of the instruction. /// Offset of the instruction.
source: u32, inst_offset: u32,
/// Length of the instruction.
inst_length: u4,
/// Offset of the relocation within the instruction. /// Offset of the relocation within the instruction.
source_offset: u32, source_offset: u4,
/// Length of the relocation.
source_length: u4,
/// Target of the relocation. /// Target of the relocation.
target: Mir.Inst.Index, target: Mir.Inst.Index,
/// Offset from the target instruction. /// Offset from the target.
target_offset: i32, target_offset: i32,
/// Length of the instruction.
length: u5,
}; };
const TableReloc = struct { const TableReloc = struct {
+11 -6
View File
@@ -304,20 +304,20 @@ pub const Mnemonic = enum {
jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, jrcxz, js, jz, jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, jrcxz, js, jz,
lahf, lar, lea, leave, lfence, lgdt, lidt, lldt, lmsw, loop, loope, loopne, lahf, lar, lea, leave, lfence, lgdt, lidt, lldt, lmsw, loop, loope, loopne,
lods, lodsb, lodsd, lodsq, lodsw, lods, lodsb, lodsd, lodsq, lodsw,
lsl, ltr, lzcnt, lsl, ltr,
mfence, mov, movbe, mfence, mov, movbe,
movs, movsb, movsd, movsq, movsw, movs, movsb, movsd, movsq, movsw,
movsx, movsxd, movzx, mul, movsx, movsxd, movzx, mul,
neg, nop, not, neg, nop, not,
@"or", out, outs, outsb, outsd, outsw, @"or", out, outs, outsb, outsd, outsw,
pause, pop, popcnt, popf, popfd, popfq, push, pushfq, pause, pop, popf, popfd, popfq, push, pushfq,
rcl, rcr, rcl, rcr,
rdfsbase, rdgsbase, rdmsr, rdpid, rdpkru, rdpmc, rdrand, rdseed, rdssd, rdssq, rdtsc, rdtscp, rdfsbase, rdgsbase, rdmsr, rdpid, rdpkru, rdpmc, rdrand, rdseed, rdssd, rdssq, rdtsc, rdtscp,
ret, rol, ror, rorx, rsm, ret, rol, ror, rsm,
sahf, sal, sar, sarx, sbb, sahf, sal, sar, sbb,
scas, scasb, scasd, scasq, scasw, scas, scasb, scasd, scasq, scasw,
senduipi, serialize, senduipi, serialize,
shl, shld, shlx, shr, shrd, shrx, shl, shld, shr, shrd,
stac, stc, std, sti, str, stui, stac, stc, std, sti, str, stui,
sub, swapgs, syscall, sysenter, sysexit, sysret, sub, swapgs, syscall, sysenter, sysexit, sysret,
seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae,
@@ -433,6 +433,8 @@ pub const Mnemonic = enum {
roundpd, roundps, roundsd, roundss, roundpd, roundps, roundsd, roundss,
// SSE4.2 // SSE4.2
crc32, pcmpgtq, crc32, pcmpgtq,
// ABM
lzcnt, popcnt,
// PCLMUL // PCLMUL
pclmulqdq, pclmulqdq,
// AES // AES
@@ -440,7 +442,6 @@ pub const Mnemonic = enum {
// SHA // SHA
sha1rnds4, sha1nexte, sha1msg1, sha1msg2, sha256msg1, sha256msg2, sha256rnds2, sha1rnds4, sha1nexte, sha1msg1, sha1msg2, sha256msg1, sha256msg2, sha256rnds2,
// AVX // AVX
andn, bextr, blsi, blsmsk, blsr, bzhi, tzcnt,
vaddpd, vaddps, vaddsd, vaddss, vaddsubpd, vaddsubps, vaddpd, vaddps, vaddsd, vaddss, vaddsubpd, vaddsubps,
vaesdec, vaesdeclast, vaesenc, vaesenclast, vaesimc, vaeskeygenassist, vaesdec, vaesdeclast, vaesenc, vaesenclast, vaesimc, vaeskeygenassist,
vandnpd, vandnps, vandpd, vandps, vandnpd, vandnps, vandpd, vandps,
@@ -506,6 +507,10 @@ pub const Mnemonic = enum {
vtestpd, vtestps, vtestpd, vtestps,
vucomisd, vucomiss, vunpckhpd, vunpckhps, vunpcklpd, vunpcklps, vucomisd, vucomiss, vunpckhpd, vunpckhps, vunpcklpd, vunpcklps,
vxorpd, vxorps, vxorpd, vxorps,
// BMI
andn, bextr, blsi, blsmsk, blsr, tzcnt,
// BMI2
bzhi, mulx, pdep, pext, rorx, sarx, shlx, shrx,
// F16C // F16C
vcvtph2ps, vcvtps2ph, vcvtph2ps, vcvtps2ph,
// FMA // FMA
+92 -76
View File
@@ -10,32 +10,38 @@ mir: Mir,
cc: std.builtin.CallingConvention, cc: std.builtin.CallingConvention,
err_msg: ?*Zcu.ErrorMsg = null, err_msg: ?*Zcu.ErrorMsg = null,
src_loc: Zcu.LazySrcLoc, src_loc: Zcu.LazySrcLoc,
result_insts_len: u8 = undefined, result_insts_len: ResultInstIndex = undefined,
result_relocs_len: u8 = undefined, result_insts: [max_result_insts]Instruction = undefined,
result_insts: [ result_relocs_len: ResultRelocIndex = undefined,
@max( result_relocs: [max_result_relocs]Reloc = undefined,
1, // non-pseudo instructions
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode const max_result_insts = @max(
2, // cmovcc: cmovcc \ cmovcc 1, // non-pseudo instructions
3, // setcc: setcc \ setcc \ logicop 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
2, // jcc: jcc \ jcc 2, // cmovcc: cmovcc \ cmovcc
pseudo_probe_align_insts, 3, // setcc: setcc \ setcc \ logicop
pseudo_probe_adjust_unrolled_max_insts, 2, // jcc: jcc \ jcc
pseudo_probe_adjust_setup_insts, pseudo_probe_align_insts,
pseudo_probe_adjust_loop_insts, pseudo_probe_adjust_unrolled_max_insts,
abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs pseudo_probe_adjust_setup_insts,
abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs pseudo_probe_adjust_loop_insts,
) abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs
]Instruction = undefined, abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs
result_relocs: [ );
@max( const max_result_relocs = @max(
1, // jmp/jcc/call/mov/lea: jmp/jcc/call/mov/lea 1, // jmp/jcc/call/mov/lea: jmp/jcc/call/mov/lea
2, // jcc: jcc \ jcc 2, // jcc: jcc \ jcc
2, // test \ jcc \ probe \ sub \ jmp 2, // test \ jcc \ probe \ sub \ jmp
1, // probe \ sub \ jcc 1, // probe \ sub \ jcc
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
) );
]Reloc = undefined,
const ResultInstIndex = std.math.IntFittingRange(0, max_result_insts - 1);
const ResultRelocIndex = std.math.IntFittingRange(0, max_result_relocs - 1);
const InstOpIndex = std.math.IntFittingRange(
0,
@typeInfo(@FieldType(Instruction, "ops")).array.len - 1,
);
pub const pseudo_probe_align_insts = 5; // test \ jcc \ probe \ sub \ jmp pub const pseudo_probe_align_insts = 5; // test \ jcc \ probe \ sub \ jmp
pub const pseudo_probe_adjust_unrolled_max_insts = pub const pseudo_probe_adjust_unrolled_max_insts =
@@ -51,7 +57,8 @@ pub const Error = error{
}; };
pub const Reloc = struct { pub const Reloc = struct {
lowered_inst_index: u8, lowered_inst_index: ResultInstIndex,
op_index: InstOpIndex,
target: Target, target: Target,
off: i32, off: i32,
@@ -114,11 +121,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
assert(inst.data.rx.fixes == ._); assert(inst.data.rx.fixes == ._);
try lower.emit(.none, .cmovnz, &.{ try lower.emit(.none, .cmovnz, &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(1, inst.data.rx.payload) },
}); });
try lower.emit(.none, .cmovp, &.{ try lower.emit(.none, .cmovp, &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(1, inst.data.rx.payload) },
}); });
}, },
.pseudo_set_z_and_np_r => { .pseudo_set_z_and_np_r => {
@@ -137,13 +144,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.pseudo_set_z_and_np_m => { .pseudo_set_z_and_np_m => {
assert(inst.data.rx.fixes == ._); assert(inst.data.rx.fixes == ._);
try lower.emit(.none, .setz, &.{ try lower.emit(.none, .setz, &.{
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(0, inst.data.rx.payload) },
}); });
try lower.emit(.none, .setnp, &.{ try lower.emit(.none, .setnp, &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
}); });
try lower.emit(.none, .@"and", &.{ try lower.emit(.none, .@"and", &.{
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(0, inst.data.rx.payload) },
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
}); });
}, },
@@ -163,32 +170,32 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.pseudo_set_nz_or_p_m => { .pseudo_set_nz_or_p_m => {
assert(inst.data.rx.fixes == ._); assert(inst.data.rx.fixes == ._);
try lower.emit(.none, .setnz, &.{ try lower.emit(.none, .setnz, &.{
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(0, inst.data.rx.payload) },
}); });
try lower.emit(.none, .setp, &.{ try lower.emit(.none, .setp, &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
}); });
try lower.emit(.none, .@"or", &.{ try lower.emit(.none, .@"or", &.{
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(0, inst.data.rx.payload) },
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
}); });
}, },
.pseudo_j_z_and_np_inst => { .pseudo_j_z_and_np_inst => {
assert(inst.data.inst.fixes == ._); assert(inst.data.inst.fixes == ._);
try lower.emit(.none, .jnz, &.{ try lower.emit(.none, .jnz, &.{
.{ .imm = lower.reloc(.{ .inst = index + 1 }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },
}); });
try lower.emit(.none, .jnp, &.{ try lower.emit(.none, .jnp, &.{
.{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
}); });
}, },
.pseudo_j_nz_or_p_inst => { .pseudo_j_nz_or_p_inst => {
assert(inst.data.inst.fixes == ._); assert(inst.data.inst.fixes == ._);
try lower.emit(.none, .jnz, &.{ try lower.emit(.none, .jnz, &.{
.{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
}); });
try lower.emit(.none, .jp, &.{ try lower.emit(.none, .jp, &.{
.{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
}); });
}, },
@@ -198,7 +205,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.{ .imm = .s(@bitCast(inst.data.ri.i)) }, .{ .imm = .s(@bitCast(inst.data.ri.i)) },
}); });
try lower.emit(.none, .jz, &.{ try lower.emit(.none, .jz, &.{
.{ .imm = lower.reloc(.{ .inst = index + 1 }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = index + 1 }, 0) },
}); });
try lower.emit(.none, .lea, &.{ try lower.emit(.none, .lea, &.{
.{ .reg = inst.data.ri.r1 }, .{ .reg = inst.data.ri.r1 },
@@ -214,7 +221,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.{ .reg = inst.data.ri.r1.to32() }, .{ .reg = inst.data.ri.r1.to32() },
}); });
try lower.emit(.none, .jmp, &.{ try lower.emit(.none, .jmp, &.{
.{ .imm = lower.reloc(.{ .inst = index }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },
}); });
assert(lower.result_insts_len == pseudo_probe_align_insts); assert(lower.result_insts_len == pseudo_probe_align_insts);
}, },
@@ -260,7 +267,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.{ .imm = .s(page_size) }, .{ .imm = .s(page_size) },
}); });
try lower.emit(.none, .jae, &.{ try lower.emit(.none, .jae, &.{
.{ .imm = lower.reloc(.{ .inst = index }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = index }, 0) },
}); });
assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts); assert(lower.result_insts_len == pseudo_probe_adjust_loop_insts);
}, },
@@ -382,21 +389,22 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
}; };
} }
pub fn mem(lower: *Lower, payload: u32) Memory { pub fn mem(lower: *Lower, op_index: InstOpIndex, payload: u32) Memory {
var m = lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode(); var m = lower.mir.resolveFrameLoc(lower.mir.extraData(Mir.Memory, payload).data).decode();
switch (m) { switch (m) {
.sib => |*sib| switch (sib.base) { .sib => |*sib| switch (sib.base) {
else => {}, else => {},
.table => sib.disp = lower.reloc(.table, sib.disp).signed, .table => sib.disp = lower.reloc(op_index, .table, sib.disp).signed,
}, },
else => {}, else => {},
} }
return m; return m;
} }
fn reloc(lower: *Lower, target: Reloc.Target, off: i32) Immediate { fn reloc(lower: *Lower, op_index: InstOpIndex, target: Reloc.Target, off: i32) Immediate {
lower.result_relocs[lower.result_relocs_len] = .{ lower.result_relocs[lower.result_relocs_len] = .{
.lowered_inst_index = lower.result_insts_len, .lowered_inst_index = lower.result_insts_len,
.op_index = op_index,
.target = target, .target = target,
.off = off, .off = off,
}; };
@@ -409,7 +417,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
var emit_mnemonic = mnemonic; var emit_mnemonic = mnemonic;
var emit_ops_storage: [4]Operand = undefined; var emit_ops_storage: [4]Operand = undefined;
const emit_ops = emit_ops_storage[0..ops.len]; const emit_ops = emit_ops_storage[0..ops.len];
for (emit_ops, ops) |*emit_op, op| { for (emit_ops, ops, 0..) |*emit_op, op, op_index| {
emit_op.* = switch (op) { emit_op.* = switch (op) {
else => op, else => op,
.mem => |mem_op| switch (mem_op.base()) { .mem => |mem_op| switch (mem_op.base()) {
@@ -428,22 +436,22 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
if (lower.pic) { if (lower.pic) {
// Here, we currently assume local dynamic TLS vars, and so // Here, we currently assume local dynamic TLS vars, and so
// we emit LD model. // we emit LD model.
_ = lower.reloc(.{ .linker_tlsld = sym_index }, 0); _ = lower.reloc(1, .{ .linker_tlsld = sym_index }, 0);
lower.result_insts[lower.result_insts_len] = try .new(.none, .lea, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .lea, &.{
.{ .reg = .rdi }, .{ .reg = .rdi },
.{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }, .{ .mem = Memory.initRip(.none, 0) },
}, lower.target); }, lower.target);
lower.result_insts_len += 1; lower.result_insts_len += 1;
_ = lower.reloc(.{ _ = lower.reloc(0, .{
.linker_extern_fn = try elf_file.getGlobalSymbol("__tls_get_addr", null), .linker_extern_fn = try elf_file.getGlobalSymbol("__tls_get_addr", null),
}, 0); }, 0);
lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{
.{ .imm = .s(0) }, .{ .imm = .s(0) },
}, lower.target); }, lower.target);
lower.result_insts_len += 1; lower.result_insts_len += 1;
_ = lower.reloc(.{ .linker_dtpoff = sym_index }, 0); _ = lower.reloc(@intCast(op_index), .{ .linker_dtpoff = sym_index }, 0);
emit_mnemonic = .lea; emit_mnemonic = .lea;
break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{ break :op .{ .mem = Memory.initSib(.none, .{
.base = .{ .reg = .rax }, .base = .{ .reg = .rax },
.disp = std.math.minInt(i32), .disp = std.math.minInt(i32),
}) }; }) };
@@ -454,24 +462,26 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
.{ .mem = Memory.initSib(.qword, .{ .base = .{ .reg = .fs } }) }, .{ .mem = Memory.initSib(.qword, .{ .base = .{ .reg = .fs } }) },
}, lower.target); }, lower.target);
lower.result_insts_len += 1; lower.result_insts_len += 1;
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0); _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
emit_mnemonic = .lea; emit_mnemonic = .lea;
break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{ break :op .{ .mem = Memory.initSib(.none, .{
.base = .{ .reg = .rax }, .base = .{ .reg = .rax },
.disp = std.math.minInt(i32), .disp = std.math.minInt(i32),
}) }; }) };
} }
} }
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0);
if (lower.pic) switch (mnemonic) { if (lower.pic) switch (mnemonic) {
.lea => { .lea => {
if (elf_sym.flags.is_extern_ptr) emit_mnemonic = .mov; _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }; if (!elf_sym.flags.is_extern_ptr) break :op .{ .mem = Memory.initRip(.none, 0) };
emit_mnemonic = .mov;
break :op .{ .mem = Memory.initRip(.ptr, 0) };
}, },
.mov => { .mov => {
if (elf_sym.flags.is_extern_ptr) { if (elf_sym.flags.is_extern_ptr) {
const reg = ops[0].reg; const reg = ops[0].reg;
_ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
.{ .reg = reg.to64() }, .{ .reg = reg.to64() },
.{ .mem = Memory.initRip(.qword, 0) }, .{ .mem = Memory.initRip(.qword, 0) },
@@ -481,10 +491,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
.reg = reg.to64(), .reg = reg.to64(),
} }) }; } }) };
} }
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }; break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
}, },
else => unreachable, else => unreachable,
} else switch (mnemonic) { };
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
switch (mnemonic) {
.call => break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{ .call => break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{
.base = .{ .reg = .ds }, .base = .{ .reg = .ds },
}) }, }) },
@@ -502,10 +515,10 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
const macho_sym = zo.symbols.items[sym_index]; const macho_sym = zo.symbols.items[sym_index];
if (macho_sym.flags.tlv) { if (macho_sym.flags.tlv) {
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0); _ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
.{ .reg = .rdi }, .{ .reg = .rdi },
.{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }, .{ .mem = Memory.initRip(.ptr, 0) },
}, lower.target); }, lower.target);
lower.result_insts_len += 1; lower.result_insts_len += 1;
lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{
@@ -516,15 +529,17 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
break :op .{ .reg = .rax }; break :op .{ .reg = .rax };
} }
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0);
break :op switch (mnemonic) { break :op switch (mnemonic) {
.lea => { .lea => {
if (macho_sym.flags.is_extern_ptr) emit_mnemonic = .mov; _ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }; if (!macho_sym.flags.is_extern_ptr) break :op .{ .mem = Memory.initRip(.none, 0) };
emit_mnemonic = .mov;
break :op .{ .mem = Memory.initRip(.ptr, 0) };
}, },
.mov => { .mov => {
if (macho_sym.flags.is_extern_ptr) { if (macho_sym.flags.is_extern_ptr) {
const reg = ops[0].reg; const reg = ops[0].reg;
_ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{ lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
.{ .reg = reg.to64() }, .{ .reg = reg.to64() },
.{ .mem = Memory.initRip(.qword, 0) }, .{ .mem = Memory.initRip(.qword, 0) },
@@ -534,6 +549,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
.reg = reg.to64(), .reg = reg.to64(),
} }) }; } }) };
} }
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) }; break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
}, },
else => unreachable, else => unreachable,
@@ -550,7 +566,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
} }
fn generic(lower: *Lower, inst: Mir.Inst) Error!void { fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
@setEvalBranchQuota(2_400); @setEvalBranchQuota(2_500);
const fixes = switch (inst.ops) { const fixes = switch (inst.ops) {
.none => inst.data.none.fixes, .none => inst.data.none.fixes,
.inst => inst.data.inst.fixes, .inst => inst.data.inst.fixes,
@@ -595,7 +611,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
}, switch (inst.ops) { }, switch (inst.ops) {
.none => &.{}, .none => &.{},
.inst => &.{ .inst => &.{
.{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) }, .{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
}, },
.i_s, .i_u => &.{ .i_s, .i_u => &.{
.{ .imm = lower.imm(inst.ops, inst.data.i.i) }, .{ .imm = lower.imm(inst.ops, inst.data.i.i) },
@@ -642,10 +658,10 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
.{ .imm = lower.imm(inst.ops, inst.data.rri.i) }, .{ .imm = lower.imm(inst.ops, inst.data.rri.i) },
}, },
.m => &.{ .m => &.{
.{ .mem = lower.mem(inst.data.x.payload) }, .{ .mem = lower.mem(0, inst.data.x.payload) },
}, },
.mi_s, .mi_u => &.{ .mi_s, .mi_u => &.{
.{ .mem = lower.mem(inst.data.x.payload + 1) }, .{ .mem = lower.mem(0, inst.data.x.payload + 1) },
.{ .imm = lower.imm( .{ .imm = lower.imm(
inst.ops, inst.ops,
lower.mir.extraData(Mir.Imm32, inst.data.x.payload).data.imm, lower.mir.extraData(Mir.Imm32, inst.data.x.payload).data.imm,
@@ -653,64 +669,64 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
}, },
.rm => &.{ .rm => &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(1, inst.data.rx.payload) },
}, },
.rmr => &.{ .rmr => &.{
.{ .reg = inst.data.rrx.r1 }, .{ .reg = inst.data.rrx.r1 },
.{ .mem = lower.mem(inst.data.rrx.payload) }, .{ .mem = lower.mem(1, inst.data.rrx.payload) },
.{ .reg = inst.data.rrx.r2 }, .{ .reg = inst.data.rrx.r2 },
}, },
.rmi => &.{ .rmi => &.{
.{ .reg = inst.data.rix.r1 }, .{ .reg = inst.data.rix.r1 },
.{ .mem = lower.mem(inst.data.rix.payload) }, .{ .mem = lower.mem(1, inst.data.rix.payload) },
.{ .imm = lower.imm(inst.ops, inst.data.rix.i) }, .{ .imm = lower.imm(inst.ops, inst.data.rix.i) },
}, },
.rmi_s, .rmi_u => &.{ .rmi_s, .rmi_u => &.{
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
.{ .mem = lower.mem(inst.data.rx.payload + 1) }, .{ .mem = lower.mem(1, inst.data.rx.payload + 1) },
.{ .imm = lower.imm( .{ .imm = lower.imm(
inst.ops, inst.ops,
lower.mir.extraData(Mir.Imm32, inst.data.rx.payload).data.imm, lower.mir.extraData(Mir.Imm32, inst.data.rx.payload).data.imm,
) }, ) },
}, },
.mr => &.{ .mr => &.{
.{ .mem = lower.mem(inst.data.rx.payload) }, .{ .mem = lower.mem(0, inst.data.rx.payload) },
.{ .reg = inst.data.rx.r1 }, .{ .reg = inst.data.rx.r1 },
}, },
.mrr => &.{ .mrr => &.{
.{ .mem = lower.mem(inst.data.rrx.payload) }, .{ .mem = lower.mem(0, inst.data.rrx.payload) },
.{ .reg = inst.data.rrx.r1 }, .{ .reg = inst.data.rrx.r1 },
.{ .reg = inst.data.rrx.r2 }, .{ .reg = inst.data.rrx.r2 },
}, },
.mri => &.{ .mri => &.{
.{ .mem = lower.mem(inst.data.rix.payload) }, .{ .mem = lower.mem(0, inst.data.rix.payload) },
.{ .reg = inst.data.rix.r1 }, .{ .reg = inst.data.rix.r1 },
.{ .imm = lower.imm(inst.ops, inst.data.rix.i) }, .{ .imm = lower.imm(inst.ops, inst.data.rix.i) },
}, },
.rrm => &.{ .rrm => &.{
.{ .reg = inst.data.rrx.r1 }, .{ .reg = inst.data.rrx.r1 },
.{ .reg = inst.data.rrx.r2 }, .{ .reg = inst.data.rrx.r2 },
.{ .mem = lower.mem(inst.data.rrx.payload) }, .{ .mem = lower.mem(2, inst.data.rrx.payload) },
}, },
.rrmr => &.{ .rrmr => &.{
.{ .reg = inst.data.rrrx.r1 }, .{ .reg = inst.data.rrrx.r1 },
.{ .reg = inst.data.rrrx.r2 }, .{ .reg = inst.data.rrrx.r2 },
.{ .mem = lower.mem(inst.data.rrrx.payload) }, .{ .mem = lower.mem(2, inst.data.rrrx.payload) },
.{ .reg = inst.data.rrrx.r3 }, .{ .reg = inst.data.rrrx.r3 },
}, },
.rrmi => &.{ .rrmi => &.{
.{ .reg = inst.data.rrix.r1 }, .{ .reg = inst.data.rrix.r1 },
.{ .reg = inst.data.rrix.r2 }, .{ .reg = inst.data.rrix.r2 },
.{ .mem = lower.mem(inst.data.rrix.payload) }, .{ .mem = lower.mem(2, inst.data.rrix.payload) },
.{ .imm = lower.imm(inst.ops, inst.data.rrix.i) }, .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) },
}, },
.extern_fn_reloc, .rel => &.{ .extern_fn_reloc, .rel => &.{
.{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc.sym_index }, inst.data.reloc.off) }, .{ .imm = lower.reloc(0, .{ .linker_extern_fn = inst.data.reloc.sym_index }, inst.data.reloc.off) },
}, },
.got_reloc, .direct_reloc, .import_reloc => ops: { .got_reloc, .direct_reloc, .import_reloc => ops: {
const reg = inst.data.rx.r1; const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(bits.SymbolOffset, inst.data.rx.payload).data; const extra = lower.mir.extraData(bits.SymbolOffset, inst.data.rx.payload).data;
_ = lower.reloc(switch (inst.ops) { _ = lower.reloc(1, switch (inst.ops) {
.got_reloc => .{ .linker_got = extra.sym_index }, .got_reloc => .{ .linker_got = extra.sym_index },
.direct_reloc => .{ .linker_direct = extra.sym_index }, .direct_reloc => .{ .linker_direct = extra.sym_index },
.import_reloc => .{ .linker_import = extra.sym_index }, .import_reloc => .{ .linker_import = extra.sym_index },
+4 -3
View File
@@ -100,6 +100,8 @@ pub const Inst = struct {
/// ___ Division /// ___ Division
_d, _d,
/// ___ Without Affecting Flags
_x,
/// ___ Left /// ___ Left
_l, _l,
/// ___ Left Double /// ___ Left Double
@@ -483,6 +485,7 @@ pub const Inst = struct {
/// ASCII adjust al after subtraction /// ASCII adjust al after subtraction
aa, aa,
/// Add with carry /// Add with carry
/// Unsigned integer addition of two operands with carry flag
adc, adc,
/// Add /// Add
/// Add packed integers /// Add packed integers
@@ -1162,10 +1165,8 @@ pub const Inst = struct {
fmadd231, fmadd231,
// ADX // ADX
/// Unsigned integer addition of two operands with carry flag
adcx,
/// Unsigned integer addition of two operands with overflow flag /// Unsigned integer addition of two operands with overflow flag
adox, ado,
// AESKLE // AESKLE
/// Encode 128-bit key with key locker /// Encode 128-bit key with key locker
+55 -43
View File
@@ -405,9 +405,9 @@ pub const table = [_]Entry{
.{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none }, .{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
.{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none }, .{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
.{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none }, .{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
.{ .jcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .short, .@"32bit" }, .{ .jcxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .short, .@"32bit" },
.{ .jecxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"32bit" }, .{ .jecxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .none, .@"32bit" },
.{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"64bit" }, .{ .jrcxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .none, .@"64bit" },
.{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none }, .{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
.{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none }, .{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none },
.{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none }, .{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none },
@@ -477,10 +477,6 @@ pub const table = [_]Entry{
.{ .ltr, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 3, .none, .none }, .{ .ltr, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 3, .none, .none },
.{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt },
.{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt },
.{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .lzcnt },
.{ .mfence, .z, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none }, .{ .mfence, .z, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none, .none },
.{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none, .none }, .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none, .none },
@@ -630,10 +626,6 @@ pub const table = [_]Entry{
.{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .short, .none }, .{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .short, .none },
.{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none, .none }, .{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none, .none },
.{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .short, .popcnt },
.{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt },
.{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt },
.{ .popf, .z, &.{}, &.{ 0x9d }, 0, .short, .none }, .{ .popf, .z, &.{}, &.{ 0x9d }, 0, .short, .none },
.{ .popfd, .z, &.{}, &.{ 0x9d }, 0, .none, .@"32bit" }, .{ .popfd, .z, &.{}, &.{ 0x9d }, 0, .none, .@"32bit" },
.{ .popfq, .z, &.{}, &.{ 0x9d }, 0, .none, .@"64bit" }, .{ .popfq, .z, &.{}, &.{ 0x9d }, 0, .none, .@"64bit" },
@@ -1738,6 +1730,15 @@ pub const table = [_]Entry{
.{ .pcmpgtq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x37 }, 0, .none, .sse4_2 }, .{ .pcmpgtq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x37 }, 0, .none, .sse4_2 },
// ABM
.{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt },
.{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt },
.{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long, .lzcnt },
.{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .short, .popcnt },
.{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt },
.{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt },
// PCLMUL // PCLMUL
.{ .pclmulqdq, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x44 }, 0, .none, .pclmul }, .{ .pclmulqdq, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x44 }, 0, .none, .pclmul },
@@ -1771,38 +1772,6 @@ pub const table = [_]Entry{
.{ .sha256msg2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcd }, 0, .none, .sha }, .{ .sha256msg2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcd }, 0, .none, .sha },
// AVX // AVX
.{ .andn, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w0, .bmi },
.{ .andn, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w1, .bmi },
.{ .bextr, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi },
.{ .bextr, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi },
.{ .blsi, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w0, .bmi },
.{ .blsi, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w1, .bmi },
.{ .blsmsk, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w0, .bmi },
.{ .blsmsk, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w1, .bmi },
.{ .blsr, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w0, .bmi },
.{ .blsr, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w1, .bmi },
.{ .bzhi, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w0, .bmi2 },
.{ .bzhi, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w1, .bmi2 },
.{ .rorx, .rmi, &.{ .r32, .rm32, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w0, .bmi2 },
.{ .rorx, .rmi, &.{ .r64, .rm64, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w1, .bmi2 },
.{ .sarx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0xf3, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .shlx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .shrx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .sarx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf3, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
.{ .shlx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
.{ .shrx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
.{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .bmi },
.{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi },
.{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi },
.{ .vaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_128_wig, .avx }, .{ .vaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_128_wig, .avx },
.{ .vaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_256_wig, .avx }, .{ .vaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_256_wig, .avx },
@@ -2307,6 +2276,49 @@ pub const table = [_]Entry{
.{ .vxorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .vex_128_wig, .avx }, .{ .vxorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .vex_128_wig, .avx },
.{ .vxorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x57 }, 0, .vex_256_wig, .avx }, .{ .vxorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x57 }, 0, .vex_256_wig, .avx },
// BMI
.{ .andn, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w0, .bmi },
.{ .andn, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w1, .bmi },
.{ .bextr, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi },
.{ .bextr, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi },
.{ .blsi, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w0, .bmi },
.{ .blsi, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w1, .bmi },
.{ .blsmsk, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w0, .bmi },
.{ .blsmsk, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w1, .bmi },
.{ .blsr, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w0, .bmi },
.{ .blsr, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w1, .bmi },
.{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .bmi },
.{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi },
.{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi },
// BMI2
.{ .bzhi, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w0, .bmi2 },
.{ .bzhi, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w1, .bmi2 },
.{ .mulx, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0xf2, 0x0f, 0x38, 0xf6 }, 0, .vex_lz_w0, .bmi2 },
.{ .mulx, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0xf2, 0x0f, 0x38, 0xf6 }, 0, .vex_lz_w1, .bmi2 },
.{ .pdep, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0xf2, 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w0, .bmi2 },
.{ .pdep, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0xf2, 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w1, .bmi2 },
.{ .pext, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0xf3, 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w0, .bmi2 },
.{ .pext, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0xf3, 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w1, .bmi2 },
.{ .rorx, .rmi, &.{ .r32, .rm32, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w0, .bmi2 },
.{ .rorx, .rmi, &.{ .r64, .rm64, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w1, .bmi2 },
.{ .sarx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0xf3, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .shlx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .shrx, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi2 },
.{ .sarx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf3, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
.{ .shlx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
.{ .shrx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
// F16C // F16C
.{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c }, .{ .vcvtph2ps, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_128_w0, .f16c },
.{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c }, .{ .vcvtph2ps, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x13 }, 0, .vex_256_w0, .f16c },
+4 -2
View File
@@ -83,8 +83,10 @@ pub fn generateLazyFunction(
debug_output: link.File.DebugInfoOutput, debug_output: link.File.DebugInfoOutput,
) CodeGenError!void { ) CodeGenError!void {
const zcu = pt.zcu; const zcu = pt.zcu;
const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool); const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
const target = zcu.fileByIndex(file).mod.resolved_target.result; zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.resolved_target.result
else
zcu.getTarget();
switch (target_util.zigBackend(target, false)) { switch (target_util.zigBackend(target, false)) {
else => unreachable, else => unreachable,
inline .stage2_x86_64, .stage2_riscv64 => |backend| { inline .stage2_x86_64, .stage2_riscv64 => |backend| {
+1 -4
View File
@@ -39,10 +39,7 @@ test {
_ = Package; _ = Package;
} }
const thread_stack_size = switch (builtin.zig_backend) { const thread_stack_size = 32 << 20;
else => std.Thread.SpawnConfig.default_stack_size,
.stage2_x86_64 => 32 << 20,
};
pub const std_options: std.Options = .{ pub const std_options: std.Options = .{
.wasiCwd = wasi_cwd, .wasiCwd = wasi_cwd,
+2 -2
View File
@@ -726,11 +726,11 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
else => false, else => false,
}, },
.is_named_enum_value => switch (backend) { .is_named_enum_value => switch (backend) {
.stage2_llvm => true, .stage2_llvm, .stage2_x86_64 => true,
else => false, else => false,
}, },
.error_set_has_value => switch (backend) { .error_set_has_value => switch (backend) {
.stage2_llvm, .stage2_wasm => true, .stage2_llvm, .stage2_wasm, .stage2_x86_64 => true,
else => false, else => false,
}, },
.field_reordering => switch (backend) { .field_reordering => switch (backend) {
+1 -1
View File
@@ -527,7 +527,7 @@ fn testIntDivision() !void {
try expect(mod(i64, -14, 12) == 10); try expect(mod(i64, -14, 12) == 10);
try expect(mod(i16, -2, 12) == 10); try expect(mod(i16, -2, 12) == 10);
try expect(mod(i16, -118, 12) == 2); try expect(mod(i16, -118, 12) == 2);
try expect(mod(i8, -2, 12) == 10); // TODO: fails in x86_64 try expect(mod(i8, -2, 12) == 10);
try expect(rem(i64, -118, 12) == -10); try expect(rem(i64, -118, 12) == -10);
try expect(rem(i32, 10, 12) == 10); try expect(rem(i32, 10, 12) == 10);
+5
View File
@@ -93,6 +93,11 @@ pub fn build(b: *std.Build) void {
.cpu_arch = .x86_64, .cpu_arch = .x86_64,
.cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v3 }, .cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v3 },
}, },
.{
.cpu_arch = .x86_64,
.cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v3 },
.cpu_features_add = std.Target.x86.featureSet(&.{.adx}),
},
.{ .{
.cpu_arch = .x86_64, .cpu_arch = .x86_64,
.cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v4 }, .cpu_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v4 },
+122 -58
View File
@@ -33,6 +33,28 @@ fn Scalar(comptime Type: type) type {
.vector => |info| info.child, .vector => |info| info.child,
}; };
} }
fn AddOneBit(comptime Type: type) type {
const ResultScalar = switch (@typeInfo(Scalar(Type))) {
.int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = 1 + int.bits } }),
.float => Scalar(Type),
else => @compileError(@typeName(Type)),
};
return switch (@typeInfo(Type)) {
else => ResultScalar,
.vector => |vector| @Vector(vector.len, ResultScalar),
};
}
fn DoubleBits(comptime Type: type) type {
const ResultScalar = switch (@typeInfo(Scalar(Type))) {
.int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = int.bits * 2 } }),
.float => Scalar(Type),
else => @compileError(@typeName(Type)),
};
return switch (@typeInfo(Type)) {
else => ResultScalar,
.vector => |vector| @Vector(vector.len, ResultScalar),
};
}
// inline to avoid a runtime `@splat` // inline to avoid a runtime `@splat`
inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type { inline fn splat(comptime Type: type, scalar: Scalar(Type)) Type {
return switch (@typeInfo(Type)) { return switch (@typeInfo(Type)) {
@@ -16205,6 +16227,8 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
); );
} }
fn testInts() !void { fn testInts() !void {
try testArgs(i4, 0x3, 0x2);
try testArgs(u4, 0xe, 0x6);
try testArgs(i8, 0x48, 0x6c); try testArgs(i8, 0x48, 0x6c);
try testArgs(u8, 0xbb, 0x43); try testArgs(u8, 0xbb, 0x43);
try testArgs(i16, -0x0fdf, 0x302e); try testArgs(i16, -0x0fdf, 0x302e);
@@ -17967,8 +17991,8 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
-0x12, -0x1e, 0x18, 0x6e, 0x31, 0x53, -0x6a, -0x34, 0x13, 0x4d, 0x30, -0x7d, -0x31, 0x1e, -0x24, 0x32, -0x12, -0x1e, 0x18, 0x6e, 0x31, 0x53, -0x6a, -0x34, 0x13, 0x4d, 0x30, -0x7d, -0x31, 0x1e, -0x24, 0x32,
-0x1e, -0x01, 0x55, 0x33, -0x75, -0x44, -0x57, 0x2b, -0x66, 0x19, 0x7f, -0x28, -0x3f, -0x7e, -0x5d, -0x06, -0x1e, -0x01, 0x55, 0x33, -0x75, -0x44, -0x57, 0x2b, -0x66, 0x19, 0x7f, -0x28, -0x3f, -0x7e, -0x5d, -0x06,
}, .{ }, .{
0x05, -0x23, 0x43, -0x54, -0x41, 0x7f, -0x6a, -0x31, 0x04, 0x15, -0x7a, -0x37, 0x6d, 0x16, 0x00, 0x4a, 0x05, -0x23, 0x43, -0x54, -0x41, 0x7f, -0x6a, -0x31, 0x04, 0x15, -0x7a, -0x37, 0x6d, 0x16, 0x01, 0x4a,
0x15, 0x55, -0x4a, 0x16, -0x73, -0x0c, 0x1c, -0x26, -0x14, 0x00, 0x55, 0x7b, 0x16, -0x2e, -0x5f, -0x67, 0x15, 0x55, -0x4a, 0x16, -0x73, -0x0c, 0x1c, -0x26, -0x14, -0x01, 0x55, 0x7b, 0x16, -0x2e, -0x5f, -0x67,
}); });
try testArgs(@Vector(64, i8), .{ try testArgs(@Vector(64, i8), .{
-0x05, 0x76, 0x4e, -0x5c, 0x7b, -0x1a, -0x38, -0x2e, 0x3d, 0x36, 0x01, 0x30, -0x02, -0x71, -0x24, 0x24, -0x05, 0x76, 0x4e, -0x5c, 0x7b, -0x1a, -0x38, -0x2e, 0x3d, 0x36, 0x01, 0x30, -0x02, -0x71, -0x24, 0x24,
@@ -17997,7 +18021,7 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
0x23, 0x3b, 0x0a, 0x7a, 0x19, 0x14, 0x65, -0x1d, 0x2b, 0x65, 0x33, 0x2a, 0x52, -0x63, 0x57, 0x10, 0x23, 0x3b, 0x0a, 0x7a, 0x19, 0x14, 0x65, -0x1d, 0x2b, 0x65, 0x33, 0x2a, 0x52, -0x63, 0x57, 0x10,
-0x1b, 0x26, -0x46, -0x7e, -0x25, 0x79, -0x01, -0x0d, -0x49, -0x4d, 0x74, 0x03, 0x77, 0x16, 0x03, -0x3d, -0x1b, 0x26, -0x46, -0x7e, -0x25, 0x79, -0x01, -0x0d, -0x49, -0x4d, 0x74, 0x03, 0x77, 0x16, 0x03, -0x3d,
0x1c, 0x25, 0x5a, -0x2f, -0x16, -0x5f, -0x36, -0x55, -0x44, -0x0c, -0x0f, 0x7b, -0x15, -0x1d, 0x32, 0x31, 0x1c, 0x25, 0x5a, -0x2f, -0x16, -0x5f, -0x36, -0x55, -0x44, -0x0c, -0x0f, 0x7b, -0x15, -0x1d, 0x32, 0x31,
0x6e, -0x44, -0x4a, -0x64, 0x67, 0x04, 0x47, 0x00, 0x3c, -0x0a, -0x79, 0x3d, 0x48, 0x5a, 0x61, -0x2c, 0x6e, -0x44, -0x4a, -0x64, 0x67, 0x04, 0x47, -0x02, 0x3c, -0x0a, -0x79, 0x3d, 0x48, 0x5a, 0x61, -0x2c,
0x6d, -0x68, -0x71, -0x6b, -0x11, 0x44, -0x75, -0x55, -0x67, -0x52, 0x64, -0x3d, -0x05, -0x76, -0x6d, -0x44, 0x6d, -0x68, -0x71, -0x6b, -0x11, 0x44, -0x75, -0x55, -0x67, -0x52, 0x64, -0x3d, -0x05, -0x76, -0x6d, -0x44,
}); });
@@ -18024,7 +18048,7 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
try testArgs(@Vector(16, u8), .{ try testArgs(@Vector(16, u8), .{
0xea, 0x80, 0xbb, 0xe8, 0x74, 0x81, 0xc8, 0x66, 0x7b, 0x41, 0x90, 0xcb, 0x30, 0x70, 0x4b, 0x0f, 0xea, 0x80, 0xbb, 0xe8, 0x74, 0x81, 0xc8, 0x66, 0x7b, 0x41, 0x90, 0xcb, 0x30, 0x70, 0x4b, 0x0f,
}, .{ }, .{
0x61, 0x26, 0xbe, 0x47, 0x00, 0x9c, 0x55, 0xa5, 0x59, 0xf0, 0xb2, 0x20, 0x30, 0xaf, 0x82, 0x3e, 0x61, 0x26, 0xbe, 0x47, 0x02, 0x9c, 0x55, 0xa5, 0x59, 0xf0, 0xb2, 0x20, 0x30, 0xaf, 0x82, 0x3e,
}); });
try testArgs(@Vector(32, u8), .{ try testArgs(@Vector(32, u8), .{
0xa1, 0x88, 0xc4, 0xf4, 0x77, 0x0b, 0xf5, 0xbb, 0x09, 0x03, 0xbf, 0xf5, 0xcc, 0x7f, 0x6b, 0x2a, 0xa1, 0x88, 0xc4, 0xf4, 0x77, 0x0b, 0xf5, 0xbb, 0x09, 0x03, 0xbf, 0xf5, 0xcc, 0x7f, 0x6b, 0x2a,
@@ -18950,22 +18974,45 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
}; };
} }
inline fn add(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs + rhs) { inline fn addUnsafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
return lhs + rhs; @setRuntimeSafety(false);
return @as(AddOneBit(Type), lhs) + rhs;
} }
test add { test addUnsafe {
const test_add = binary(add, .{}); const test_add_unsafe = binary(addUnsafe, .{});
try test_add.testFloats(); try test_add_unsafe.testInts();
try test_add.testFloatVectors(); try test_add_unsafe.testIntVectors();
try test_add_unsafe.testFloats();
try test_add_unsafe.testFloatVectors();
} }
inline fn subtract(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs - rhs) { inline fn subUnsafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
return lhs - rhs; @setRuntimeSafety(false);
switch (@typeInfo(Scalar(Type))) {
else => @compileError(@typeName(Type)),
.int => |int| switch (int.signedness) {
.signed => {},
.unsigned => return @as(AddOneBit(Type), @max(lhs, rhs)) - @min(lhs, rhs),
},
.float => {},
}
return @as(AddOneBit(Type), lhs) - rhs;
} }
test subtract { test subUnsafe {
const test_subtract = binary(subtract, .{}); const test_sub_unsafe = binary(subUnsafe, .{});
try test_subtract.testFloats(); try test_sub_unsafe.testInts();
try test_subtract.testFloatVectors(); try test_sub_unsafe.testIntVectors();
try test_sub_unsafe.testFloats();
try test_sub_unsafe.testFloatVectors();
}
inline fn mulUnsafe(comptime Type: type, lhs: Type, rhs: Type) DoubleBits(Type) {
@setRuntimeSafety(false);
return @as(DoubleBits(Type), lhs) * rhs;
}
test mulUnsafe {
const test_mul_unsafe = binary(mulUnsafe, .{});
try test_mul_unsafe.testInts();
} }
inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) { inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs * rhs) {
@@ -18999,42 +19046,51 @@ test divide {
try test_divide.testFloatVectors(); try test_divide.testFloatVectors();
} }
// workaround https://github.com/ziglang/zig/issues/22748 inline fn divTrunc(comptime Type: type, lhs: Type, rhs: Type) Type {
// TODO: @TypeOf(@divTrunc(lhs, rhs)) switch (@typeInfo(Scalar(Type))) {
inline fn divTrunc(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) { else => @compileError(@typeName(Type)),
if (@inComptime()) { .int => return @divTrunc(lhs, rhs),
// workaround https://github.com/ziglang/zig/issues/22748 .float => {
return @trunc(lhs / rhs); if (@inComptime()) {
// workaround https://github.com/ziglang/zig/issues/22748
return @trunc(lhs / rhs);
}
// workaround https://github.com/ziglang/zig/issues/22748
// workaround https://github.com/ziglang/zig/issues/22749
// TODO: return @divTrunc(lhs, rhs);
var rt_lhs = lhs;
var rt_rhs = rhs;
_ = .{ &rt_lhs, &rt_rhs };
return @divTrunc(rt_lhs, rt_rhs);
},
} }
// workaround https://github.com/ziglang/zig/issues/22748
// workaround https://github.com/ziglang/zig/issues/22749
// TODO: return @divTrunc(lhs, rhs);
var rt_lhs = lhs;
var rt_rhs = rhs;
_ = .{ &rt_lhs, &rt_rhs };
return @divTrunc(rt_lhs, rt_rhs);
} }
test divTrunc { test divTrunc {
const test_div_trunc = binary(divTrunc, .{ .compare = .approx_int }); const test_div_trunc = binary(divTrunc, .{ .compare = .approx_int });
try test_div_trunc.testInts();
try test_div_trunc.testIntVectors();
try test_div_trunc.testFloats(); try test_div_trunc.testFloats();
try test_div_trunc.testFloatVectors(); try test_div_trunc.testFloatVectors();
} }
// workaround https://github.com/ziglang/zig/issues/22748 inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) Type {
// TODO: @TypeOf(@divFloor(lhs, rhs)) switch (@typeInfo(Scalar(Type))) {
inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) { else => @compileError(@typeName(Type)),
if (@inComptime()) { .int => return @divFloor(lhs, rhs),
// workaround https://github.com/ziglang/zig/issues/22748 .float => {
return @floor(lhs / rhs); if (@inComptime()) {
// workaround https://github.com/ziglang/zig/issues/22748
return @floor(lhs / rhs);
}
// workaround https://github.com/ziglang/zig/issues/22748
// workaround https://github.com/ziglang/zig/issues/22749
// TODO: return @divFloor(lhs, rhs);
var rt_lhs = lhs;
var rt_rhs = rhs;
_ = .{ &rt_lhs, &rt_rhs };
return @divFloor(rt_lhs, rt_rhs);
},
} }
// workaround https://github.com/ziglang/zig/issues/22748
// workaround https://github.com/ziglang/zig/issues/22749
// TODO: return @divFloor(lhs, rhs);
var rt_lhs = lhs;
var rt_rhs = rhs;
_ = &rt_lhs;
_ = &rt_rhs;
return @divFloor(rt_lhs, rt_rhs);
} }
test divFloor { test divFloor {
const test_div_floor = binary(divFloor, .{ .compare = .approx_int }); const test_div_floor = binary(divFloor, .{ .compare = .approx_int });
@@ -19045,25 +19101,33 @@ test divFloor {
// workaround https://github.com/ziglang/zig/issues/22748 // workaround https://github.com/ziglang/zig/issues/22748
// TODO: @TypeOf(@rem(lhs, rhs)) // TODO: @TypeOf(@rem(lhs, rhs))
inline fn rem(comptime Type: type, lhs: Type, rhs: Type) Type { inline fn rem(comptime Type: type, lhs: Type, rhs: Type) Type {
if (@inComptime()) { switch (@typeInfo(Scalar(Type))) {
// workaround https://github.com/ziglang/zig/issues/22748 else => @compileError(@typeName(Type)),
switch (@typeInfo(Type)) { .int => return @rem(lhs, rhs),
else => return if (rhs != 0) @rem(lhs, rhs) else nan(Type), .float => {
.vector => |info| { if (@inComptime()) {
var res: Type = undefined; // workaround https://github.com/ziglang/zig/issues/22748
inline for (0..info.len) |i| res[i] = if (rhs[i] != 0) @rem(lhs[i], rhs[i]) else nan(Scalar(Type)); switch (@typeInfo(Type)) {
return res; else => return if (rhs != 0) @rem(lhs, rhs) else nan(Type),
}, .vector => |info| {
} var res: Type = undefined;
inline for (0..info.len) |i| res[i] = if (rhs[i] != 0) @rem(lhs[i], rhs[i]) else nan(Scalar(Type));
return res;
},
}
}
// workaround https://github.com/ziglang/zig/issues/22748
// TODO: return @rem(lhs, rhs);
var rt_rhs = rhs;
_ = &rt_rhs;
return @rem(lhs, rt_rhs);
},
} }
// workaround https://github.com/ziglang/zig/issues/22748
// TODO: return @rem(lhs, rhs);
var rt_rhs = rhs;
_ = &rt_rhs;
return @rem(lhs, rt_rhs);
} }
test rem { test rem {
const test_rem = binary(rem, .{}); const test_rem = binary(rem, .{});
try test_rem.testInts();
try test_rem.testIntVectors();
try test_rem.testFloats(); try test_rem.testFloats();
try test_rem.testFloatVectors(); try test_rem.testFloatVectors();
} }
+142 -7
View File
@@ -1,4 +1,4 @@
fn access(comptime array: anytype) !void { fn accessSlice(comptime array: anytype) !void {
var slice: []const @typeInfo(@TypeOf(array)).array.child = undefined; var slice: []const @typeInfo(@TypeOf(array)).array.child = undefined;
slice = &array; slice = &array;
inline for (0.., &array) |ct_index, *elem| { inline for (0.., &array) |ct_index, *elem| {
@@ -20,18 +20,153 @@ fn access(comptime array: anytype) !void {
if (slice[rt_index] != elem.*) return error.Unexpected; if (slice[rt_index] != elem.*) return error.Unexpected;
} }
} }
test access { test accessSlice {
try access([3]u8{ 0xdb, 0xef, 0xbd }); try accessSlice([3]u8{ 0xdb, 0xef, 0xbd });
try access([3]u16{ 0x340e, 0x3654, 0x88d7 }); try accessSlice([3]u16{ 0x340e, 0x3654, 0x88d7 });
try access([3]u32{ 0xd424c2c0, 0x2d6ac466, 0x5a0cfaba }); try accessSlice([3]u32{ 0xd424c2c0, 0x2d6ac466, 0x5a0cfaba });
try access([3]u64{ try accessSlice([3]u64{
0x9327a4f5221666a6, 0x9327a4f5221666a6,
0x5c34d3ddd84a8b12, 0x5c34d3ddd84a8b12,
0xbae087f39f649260, 0xbae087f39f649260,
}); });
try access([3]u128{ try accessSlice([3]u128{
0x601cf010065444d4d42d5536dd9b95db, 0x601cf010065444d4d42d5536dd9b95db,
0xa03f592fcaa22d40af23a0c735531e3c, 0xa03f592fcaa22d40af23a0c735531e3c,
0x5da44907b31602b95c2d93f0b582ceab, 0x5da44907b31602b95c2d93f0b582ceab,
}); });
} }
fn accessVector(comptime init: anytype) !void {
const Vector = @TypeOf(init);
var vector: Vector = undefined;
vector = init;
inline for (0..@typeInfo(Vector).vector.len) |ct_index| {
var rt_index: usize = undefined;
rt_index = ct_index;
if (&vector[rt_index] != &vector[ct_index]) return error.Unexpected;
if (vector[rt_index] != vector[ct_index]) return error.Unexpected;
}
}
test accessVector {
try accessVector(@Vector(1, bool){
false,
});
try accessVector(@Vector(2, bool){
false, true,
});
try accessVector(@Vector(3, bool){
true, true, false,
});
try accessVector(@Vector(5, bool){
true, false, true, false, true,
});
try accessVector(@Vector(7, bool){
true, false, true, true, true, false, true,
});
try accessVector(@Vector(8, bool){
false, true, false, true, false, false, false, true,
});
try accessVector(@Vector(9, bool){
true, true, false, true, false, false, false, false,
true,
});
try accessVector(@Vector(15, bool){
false, true, true, true, false, true, false, false,
true, true, false, false, true, false, false,
});
try accessVector(@Vector(16, bool){
true, true, false, true, false, false, false, false,
false, true, true, false, false, false, true, true,
});
try accessVector(@Vector(17, bool){
true, false, true, true, false, true, false, true,
true, true, true, false, false, false, true, true,
false,
});
try accessVector(@Vector(31, bool){
true, false, true, true, false, true, true, true,
false, true, false, true, false, true, true, true,
false, false, true, false, false, false, false, true,
true, true, true, false, false, false, false,
});
try accessVector(@Vector(32, bool){
true, true, false, false, false, true, true, true,
false, true, true, true, false, true, false, true,
false, true, false, true, false, true, true, false,
false, false, false, false, false, true, true, true,
});
try accessVector(@Vector(33, bool){
true, false, false, false, false, true, true, true,
false, false, true, false, true, true, false, true,
true, true, false, true, true, false, false, false,
false, true, false, false, false, true, true, false,
false,
});
try accessVector(@Vector(63, bool){
false, false, true, true, true, false, true, true,
true, false, true, true, true, false, true, false,
true, true, false, true, false, true, true, true,
false, false, true, false, false, false, false, true,
true, true, true, true, false, true, false, true,
true, true, false, false, true, false, false, true,
false, true, false, false, false, false, true, true,
false, true, false, false, true, true, true,
});
try accessVector(@Vector(64, bool){
false, false, true, true, true, false, true, true,
true, false, true, true, false, true, true, false,
false, false, false, false, true, true, false, true,
true, true, true, true, false, false, false, true,
true, false, true, true, false, false, true, false,
false, true, true, false, true, true, false, false,
true, true, false, true, false, true, true, true,
false, true, true, false, false, false, false, false,
});
try accessVector(@Vector(65, bool){
false, false, true, true, true, true, true, true,
true, false, false, false, false, true, true, false,
true, false, true, true, true, false, false, false,
true, false, true, true, false, true, true, true,
true, true, false, true, true, false, true, false,
false, true, false, true, false, false, true, false,
true, false, true, true, true, false, true, true,
false, false, true, true, true, true, false, false,
true,
});
try accessVector(@Vector(8, u8){
0x60, 0xf7, 0xf4, 0xb0, 0x05, 0xd3, 0x06, 0x78,
});
try accessVector(@Vector(8, u16){
0x9c91, 0xfb8b, 0x7f80, 0x8304, 0x6e52, 0xd8ef, 0x37fc, 0x7851,
});
try accessVector(@Vector(8, u32){
0x688b88e2, 0x68e2b7a2, 0x87574680, 0xab4f0769,
0x75472bb5, 0xa791f2ae, 0xeb2ed416, 0x5f05ce82,
});
try accessVector(@Vector(8, u64){
0xdefd1ddffaedf818, 0x91c78a29d3d59890,
0x842aaf8fd3c7b785, 0x970a07b8f9f4a6b3,
0x21b2425d1a428246, 0xea50e41174a7977b,
0x08d0f1c4f5978b74, 0x8dc88a7fd85e0e67,
});
try accessVector(@Vector(8, u128){
0x6f2cbde1fb219b1e73d7f774d10f0d94,
0x7c1412616cda20436d7106691d8ba4cc,
0x4ee940b50e97675b3b35d7872a35b5ad,
0x6d994fb8caa1b2fac48acbb68fa2d2f1,
0xdee698c7ec8de9b5940903e3fc665b63,
0x0751491a509e4a1ce8cfa6d62fe9e74c,
0x3d880f0a927ce3bfc2682b72070fcd50,
0x82f0eec62881598699eeb93fbb456e95,
});
try accessVector(@Vector(8, u256){
0x6ee4f35fe624d365952f73960791238ac781bfba782abc7866a691063e43ce48,
0xb006491f54a9c9292458a5835b7d5f4cfa18136f175eef0a13bb8adf5c3dc061,
0xd6e25ca1bc5685fc52609e261b9065bc05a8662e9291660033dd7f6d98e562b3,
0x992c5e54e0e6331dac258996be7dae9b2a2eff323a39043ba8d2721420dc5f5c,
0x257313f45fb3556d0fc323d5f38c953e9a093fe2278655312b6a5b64aab9d901,
0x6c8ad2182b9a3b2b19c2c9b152956b383d0fee2e3fbd5b02ed72227446a7b221,
0xd80cafc2252b289793799675e43f97ba4a5448c7b57e1544a464687b435efc7b,
0xfcb480f2d70afd53c4689dd3f5db7638c24302f2a6a15f738167db090d91fb28,
});
}
+1 -1
View File
@@ -18,5 +18,5 @@ pub fn main() !void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -8,7 +8,7 @@ export fn entry() usize {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :4:29: error: invalid operands to binary expression: 'struct' and 'struct' // :4:29: error: invalid operands to binary expression: 'struct' and 'struct'
@@ -11,7 +11,7 @@ fn doSomeAsm() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :6:5: error: unable to evaluate comptime expression // :6:5: error: unable to evaluate comptime expression
@@ -8,7 +8,7 @@ export fn foo() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :4:5: error: asm cannot output to const local 'f' // :4:5: error: asm cannot output to const local 'f'
@@ -17,7 +17,7 @@ export fn comptimeBuiltinCall() callconv(.Naked) void {
fn f() void {} fn f() void {}
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:6: error: runtime call not allowed in naked function // :2:6: error: runtime call not allowed in naked function
@@ -4,7 +4,7 @@ export fn entry() void {
fn foo() callconv(.naked) void {} fn foo() callconv(.naked) void {}
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:5: error: unable to call function with calling convention 'naked' // :2:5: error: unable to call function with calling convention 'naked'
@@ -10,7 +10,7 @@ export fn entry1() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:36: error: type 'u32' cannot represent integer value '-1' // :3:36: error: type 'u32' cannot represent integer value '-1'
@@ -5,7 +5,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :4:12: error: operator == not allowed for type '?[3]i32' // :4:12: error: operator == not allowed for type '?[3]i32'
+1 -1
View File
@@ -13,7 +13,7 @@ export fn baz() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :6:5: error: found compile log statement // :6:5: error: found compile log statement
@@ -10,7 +10,7 @@ fn inner(comptime n: usize) void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :8:9: error: found compile log statement // :8:9: error: found compile log statement
@@ -8,7 +8,7 @@ export fn entry() usize {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:16: error: division by zero here causes undefined behavior // :3:16: error: division by zero here causes undefined behavior
@@ -5,7 +5,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:32: error: null pointer casted to type '*i32' // :3:32: error: null pointer casted to type '*i32'
@@ -6,7 +6,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:32: error: use of undefined value here causes undefined behavior // :3:32: error: use of undefined value here causes undefined behavior
@@ -6,7 +6,7 @@ export fn foo() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:9: error: expected type 'u16', found '*const [5:0]u8' // :3:9: error: expected type 'u16', found '*const [5:0]u8'
@@ -15,7 +15,7 @@ fn foo(x: i32) !void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :5:9: error: duplicate switch value // :5:9: error: duplicate switch value
@@ -15,7 +15,7 @@ pub export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :9:48: error: caught unexpected error 'InvalidVersion' // :9:48: error: caught unexpected error 'InvalidVersion'
@@ -13,7 +13,7 @@ fn foo(x: i32) !void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:26: error: switch must handle all possibilities // :2:26: error: switch must handle all possibilities
@@ -24,7 +24,7 @@ pub fn main() Error!void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :23:29: error: expected type 'error{InvalidCharacter}', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set' // :23:29: error: expected type 'error{InvalidCharacter}', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set'
@@ -4,7 +4,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: exact division produced remainder // :2:15: error: exact division produced remainder
@@ -8,7 +8,7 @@ export fn entry2() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: primitive integer type 'u65536' exceeds maximum bit width of 65535 // :2:15: error: primitive integer type 'u65536' exceeds maximum bit width of 65535
@@ -4,7 +4,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:25: error: exported symbol name cannot be empty // :3:25: error: exported symbol name cannot be empty
@@ -4,7 +4,7 @@ export fn foo(a: *i32) Foo {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:12: error: expected pointer type, found 'i32' // :3:12: error: expected pointer type, found 'i32'
@@ -4,7 +4,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: exact division produced remainder // :2:15: error: exact division produced remainder
@@ -7,7 +7,7 @@ fn concat() [16]f32 {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:17: error: expected type '[4]f32', found '[16]f32' // :3:17: error: expected type '[4]f32', found '[16]f32'
@@ -4,7 +4,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :1:1: error: non-extern function has no body // :1:1: error: non-extern function has no body
@@ -19,7 +19,7 @@ pub export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :18:43: error: value of type 'type' ignored // :18:43: error: value of type 'type' ignored
@@ -36,7 +36,7 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :8:48: error: expected type 'type', found 'bool' // :8:48: error: expected type 'type', found 'bool'
@@ -7,7 +7,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :6:9: error: array literal requires address-of operator (&) to coerce to slice type '[]i32' // :6:9: error: array literal requires address-of operator (&) to coerce to slice type '[]i32'
@@ -11,7 +11,7 @@ export fn entry2() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:14: error: expected type 'f32', found 'f64' // :2:14: error: expected type 'f32', found 'f64'
@@ -13,7 +13,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :11:21: error: 'error.B' not a member of error set 'error{A,C}' // :11:21: error: 'error.B' not a member of error set 'error{A,C}'
@@ -24,7 +24,7 @@ export fn incompatiblePointers4() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :5:9: error: incompatible types: '?@Vector(10, i32)' and '@Vector(11, i32)' // :5:9: error: incompatible types: '?@Vector(10, i32)' and '@Vector(11, i32)'
@@ -4,7 +4,7 @@ fn main() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:23: error: trailing digit separator // :2:23: error: trailing digit separator
@@ -16,7 +16,7 @@ export fn entry4() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: primitive integer type 'u000123' has leading zero // :2:15: error: primitive integer type 'u000123' has leading zero
@@ -11,7 +11,7 @@ fn loadv(ptr: anytype) i31 {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :10:15: error: unable to determine vector element index of type '*align(16:0:4:?) i31' // :10:15: error: unable to determine vector element index of type '*align(16:0:4:?) i31'
@@ -24,7 +24,7 @@ export fn foo() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :23:6: error: no field or member function named 'init' in 'tmp.List' // :23:6: error: no field or member function named 'init' in 'tmp.List'
@@ -12,7 +12,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :4:26: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32' // :4:26: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'
@@ -1,5 +1,5 @@
// error // error
// backend=llvm // backend=stage2
// target=x86_64-linux // target=x86_64-linux
// output_mode=Exe // output_mode=Exe
// //
@@ -11,7 +11,7 @@ fn foo() ?OtherError!i32 {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :5:34: error: expected type '?error{NextError}!i32', found '?error{OutOfMemory}!i32' // :5:34: error: expected type '?error{NextError}!i32', found '?error{OutOfMemory}!i32'
@@ -16,7 +16,7 @@ pub export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :15:28: error: expected type '*const fn (type, u8, u8) u32', found '*const fn (void, u8, u8) u32' // :15:28: error: expected type '*const fn (type, u8, u8) u32', found '*const fn (void, u8, u8) u32'
@@ -43,7 +43,7 @@ export fn entry7() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:31: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 29 // :2:31: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 29
@@ -78,7 +78,7 @@ export fn entry14() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :3:12: error: packed structs cannot contain fields of type 'anyerror' // :3:12: error: packed structs cannot contain fields of type 'anyerror'
@@ -1,7 +1,7 @@
fn main() void {} fn main() void {}
// error // error
// backend=llvm // backend=stage2
// target=x86_64-linux // target=x86_64-linux
// output_mode=Exe // output_mode=Exe
// //
@@ -3,7 +3,7 @@ export fn entry(a: *i32) usize {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:12: error: expected pointer type, found 'usize' // :2:12: error: expected pointer type, found 'usize'
@@ -13,7 +13,7 @@ fn foo(x: i32) !void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:34: error: ranges not allowed when switching on type '@typeInfo(@typeInfo(@TypeOf(tmp.foo)).@"fn".return_type.?).error_union.error_set' // :2:34: error: ranges not allowed when switching on type '@typeInfo(@typeInfo(@TypeOf(tmp.foo)).@"fn".return_type.?).error_union.error_set'
@@ -6,7 +6,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:5: error: cannot assign to constant // :2:5: error: cannot assign to constant
@@ -6,7 +6,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:5: error: cannot assign to constant // :2:5: error: cannot assign to constant
@@ -7,7 +7,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:5: error: cannot return from naked function // :2:5: error: cannot return from naked function
@@ -4,7 +4,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: operation caused overflow // :2:15: error: operation caused overflow
@@ -4,7 +4,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:15: error: exact shift shifted out 1 bits // :2:15: error: exact shift shifted out 1 bits
@@ -3,7 +3,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}' // :?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
@@ -11,7 +11,7 @@ fn storev(ptr: anytype, val: i31) void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :10:8: error: unable to determine vector element index of type '*align(16:0:4:?) i31' // :10:8: error: unable to determine vector element index of type '*align(16:0:4:?) i31'
@@ -8,7 +8,7 @@ fn foo() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :6:9: error: cannot suspend inside suspend block // :6:9: error: cannot suspend inside suspend block
@@ -20,7 +20,7 @@ export fn entry() usize {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :14:14: error: unreachable else prong; all cases already handled // :14:14: error: unreachable else prong; all cases already handled
@@ -7,7 +7,7 @@ export fn entry() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:11: error: unable to evaluate comptime expression // :2:11: error: unable to evaluate comptime expression
@@ -21,7 +21,7 @@ pub export fn simple() void {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :7:14: error: unreachable else prong; all cases already handled // :7:14: error: unreachable else prong; all cases already handled
@@ -19,7 +19,7 @@ comptime {
} }
// error // error
// backend=llvm // backend=stage2
// target=native // target=native
// //
// :2:5: error: runtime safety check not allowed in naked function // :2:5: error: runtime safety check not allowed in naked function
+1 -1
View File
@@ -23,7 +23,7 @@ pub export fn entry2() void {
} }
// error // error
// backend=llvm // backend=stage2,llvm
// target=native // target=native
// //
// :6:20: error: cannot @bitCast to '[]i32' // :6:20: error: cannot @bitCast to '[]i32'
+1 -1
View File
@@ -7,7 +7,7 @@ pub fn main() void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux-gnu // target=x86_64-linux-gnu
// link_libc=true // link_libc=true
// //
@@ -14,5 +14,5 @@ fn foo(comptime info: std.builtin.Type) !void {
// run // run
// is_test=true // is_test=true
// backend=llvm // backend=stage2,llvm
// //
+1 -1
View File
@@ -36,5 +36,5 @@ fn assert(ok: bool) void {
// TODO: enable this for native backend // TODO: enable this for native backend
// run // run
// backend=llvm // backend=stage2,llvm
// target=aarch64-linux,aarch64-macos // target=aarch64-linux,aarch64-macos
@@ -7,6 +7,6 @@ pub fn main() void {
// compile // compile
// output_mode=Exe // output_mode=Exe
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //
@@ -8,6 +8,6 @@ pub fn main() void {
// compile // compile
// output_mode=Exe // output_mode=Exe
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //
+1 -1
View File
@@ -11,6 +11,6 @@ pub fn main() void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //
+1 -1
View File
@@ -5,7 +5,7 @@ pub fn main() void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// link_libc=true // link_libc=true
// //
+1 -1
View File
@@ -4,6 +4,6 @@ pub fn main() void {
} }
// compile // compile
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //
+1 -1
View File
@@ -44,6 +44,6 @@ pub fn main() void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //
+1 -1
View File
@@ -18,5 +18,5 @@ pub fn main() !void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -7,5 +7,5 @@ pub fn main() void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
+1 -1
View File
@@ -21,5 +21,5 @@ fn foo(bytes: []u8) u32 {
return int_slice[0]; return int_slice[0];
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -22,5 +22,5 @@ fn bar(a: u2) Foo {
fn baz(_: Foo) void {} fn baz(_: Foo) void {}
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -19,5 +19,5 @@ pub fn main() u8 {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -19,5 +19,5 @@ pub fn main() u8 {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -17,5 +17,5 @@ fn foo(set1: Set1) Set2 {
return @errorCast(set1); return @errorCast(set1);
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -16,5 +16,5 @@ fn foo() anyerror!i32 {
return error.Bar; return error.Bar;
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
+1 -1
View File
@@ -18,5 +18,5 @@ fn bar(one: u1, not_zero: i32) void {
_ = x; _ = x;
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -16,5 +16,5 @@ fn bar(a: f32) i8 {
} }
fn baz(_: i8) void {} fn baz(_: i8) void {}
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -16,5 +16,5 @@ fn bar(a: f32) u8 {
} }
fn baz(_: u8) void {} fn baz(_: u8) void {}
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -16,5 +16,5 @@ fn bar(a: f32) u8 {
} }
fn baz(_: u8) void {} fn baz(_: u8) void {}
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -15,5 +15,5 @@ pub fn main() !void {
return error.TestFailed; return error.TestFailed;
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -15,5 +15,5 @@ pub fn main() !void {
return error.TestFailed; return error.TestFailed;
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -15,5 +15,5 @@ pub fn main() !void {
return error.TestFailed; return error.TestFailed;
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
@@ -22,5 +22,5 @@ pub fn main() !void {
} }
// run // run
// backend=llvm // backend=stage2,llvm
// target=native // target=native
Loaded 100 of 172 files, more files were not shown because too many files have changed in this diff. Show more