mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Merge pull request #22876 from jacobly0/x86_64-rewrite
x86_64: implement error set and enum safety
This commit is contained in:
commit
e5174c7441
@ -230,6 +230,7 @@ comptime {
|
||||
_ = @import("compiler_rt/trunc.zig");
|
||||
|
||||
// BigInt. Alphabetically sorted.
|
||||
_ = @import("compiler_rt/divmodei4.zig");
|
||||
_ = @import("compiler_rt/udivmodei4.zig");
|
||||
_ = @import("compiler_rt/udivmodti4.zig");
|
||||
|
||||
|
||||
50
lib/compiler_rt/divmodei4.zig
Normal file
50
lib/compiler_rt/divmodei4.zig
Normal 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;
|
||||
}
|
||||
@ -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.
|
||||
fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void {
|
||||
/// Uses Knuth's Algorithm D, 4.3.1, p. 272.
|
||||
pub fn divmod(q: ?[]u32, r: ?[]u32, u: []const u32, v: []const u32) !void {
|
||||
if (q) |q_| @memset(q_[0..], 0);
|
||||
if (r) |r_| @memset(r_[0..], 0);
|
||||
|
||||
|
||||
@ -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!
|
||||
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);
|
||||
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);
|
||||
try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
|
||||
}
|
||||
|
||||
@ -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_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 single_const_pointer_to_comptime_int: Type = .{
|
||||
.ip_index = .single_const_pointer_to_comptime_int_type,
|
||||
};
|
||||
pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_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 vector_16_i8: Type = .{ .ip_index = .vector_16_i8_type };
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -88,13 +88,32 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
lowered_relocs[0].lowered_inst_index == lowered_index) : ({
|
||||
lowered_relocs = lowered_relocs[1..];
|
||||
}) switch (lowered_relocs[0].target) {
|
||||
.inst => |target| try relocs.append(emit.lower.allocator, .{
|
||||
.source = start_offset,
|
||||
.source_offset = end_offset - 4,
|
||||
.target = target,
|
||||
.target_offset = lowered_relocs[0].off,
|
||||
.length = @intCast(end_offset - start_offset),
|
||||
}),
|
||||
.inst => |target| {
|
||||
const inst_length: u4 = @intCast(end_offset - start_offset);
|
||||
const reloc_offset, const reloc_length = reloc_offset_length: {
|
||||
var reloc_offset = inst_length;
|
||||
var op_index: usize = lowered_inst.ops.len;
|
||||
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, .{
|
||||
.source_offset = end_offset - 4,
|
||||
.target_offset = lowered_relocs[0].off,
|
||||
@ -409,7 +428,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
} } };
|
||||
},
|
||||
.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 = .{
|
||||
base: {
|
||||
loc_buf[0] = switch (mem.base()) {
|
||||
@ -466,15 +485,18 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
// TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size.
|
||||
// This should be reversed like it is done in aarch64 MIR emit code: start with the smallest
|
||||
// possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution
|
||||
// until the entire decl is correctly emitted with all JMP/CALL instructions within range.
|
||||
for (relocs.items) |reloc| {
|
||||
const target = code_offset_mapping[reloc.target];
|
||||
const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length)) + reloc.target_offset;
|
||||
std.mem.writeInt(i32, emit.code.items[reloc.source_offset..][0..4], @intCast(disp), .little);
|
||||
for (relocs.items) |reloc| {
|
||||
const target = code_offset_mapping[reloc.target];
|
||||
const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.inst_offset + reloc.inst_length)) + reloc.target_offset;
|
||||
const inst_bytes = emit.code.items[reloc.inst_offset..][0..reloc.inst_length];
|
||||
switch (reloc.source_length) {
|
||||
else => unreachable,
|
||||
inline 1, 4 => |source_length| std.mem.writeInt(
|
||||
@Type(.{ .int = .{ .signedness = .signed, .bits = @as(u16, 8) * source_length } }),
|
||||
inst_bytes[reloc.source_offset..][0..source_length],
|
||||
@intCast(disp),
|
||||
.little,
|
||||
),
|
||||
}
|
||||
}
|
||||
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 {
|
||||
/// Offset of the instruction.
|
||||
source: u32,
|
||||
inst_offset: u32,
|
||||
/// Length of the instruction.
|
||||
inst_length: u4,
|
||||
/// 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: Mir.Inst.Index,
|
||||
/// Offset from the target instruction.
|
||||
/// Offset from the target.
|
||||
target_offset: i32,
|
||||
/// Length of the instruction.
|
||||
length: u5,
|
||||
};
|
||||
|
||||
const TableReloc = struct {
|
||||
|
||||
@ -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,
|
||||
lahf, lar, lea, leave, lfence, lgdt, lidt, lldt, lmsw, loop, loope, loopne,
|
||||
lods, lodsb, lodsd, lodsq, lodsw,
|
||||
lsl, ltr, lzcnt,
|
||||
lsl, ltr,
|
||||
mfence, mov, movbe,
|
||||
movs, movsb, movsd, movsq, movsw,
|
||||
movsx, movsxd, movzx, mul,
|
||||
neg, nop, not,
|
||||
@"or", out, outs, outsb, outsd, outsw,
|
||||
pause, pop, popcnt, popf, popfd, popfq, push, pushfq,
|
||||
pause, pop, popf, popfd, popfq, push, pushfq,
|
||||
rcl, rcr,
|
||||
rdfsbase, rdgsbase, rdmsr, rdpid, rdpkru, rdpmc, rdrand, rdseed, rdssd, rdssq, rdtsc, rdtscp,
|
||||
ret, rol, ror, rorx, rsm,
|
||||
sahf, sal, sar, sarx, sbb,
|
||||
ret, rol, ror, rsm,
|
||||
sahf, sal, sar, sbb,
|
||||
scas, scasb, scasd, scasq, scasw,
|
||||
senduipi, serialize,
|
||||
shl, shld, shlx, shr, shrd, shrx,
|
||||
shl, shld, shr, shrd,
|
||||
stac, stc, std, sti, str, stui,
|
||||
sub, swapgs, syscall, sysenter, sysexit, sysret,
|
||||
seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae,
|
||||
@ -433,6 +433,8 @@ pub const Mnemonic = enum {
|
||||
roundpd, roundps, roundsd, roundss,
|
||||
// SSE4.2
|
||||
crc32, pcmpgtq,
|
||||
// ABM
|
||||
lzcnt, popcnt,
|
||||
// PCLMUL
|
||||
pclmulqdq,
|
||||
// AES
|
||||
@ -440,7 +442,6 @@ pub const Mnemonic = enum {
|
||||
// SHA
|
||||
sha1rnds4, sha1nexte, sha1msg1, sha1msg2, sha256msg1, sha256msg2, sha256rnds2,
|
||||
// AVX
|
||||
andn, bextr, blsi, blsmsk, blsr, bzhi, tzcnt,
|
||||
vaddpd, vaddps, vaddsd, vaddss, vaddsubpd, vaddsubps,
|
||||
vaesdec, vaesdeclast, vaesenc, vaesenclast, vaesimc, vaeskeygenassist,
|
||||
vandnpd, vandnps, vandpd, vandps,
|
||||
@ -506,6 +507,10 @@ pub const Mnemonic = enum {
|
||||
vtestpd, vtestps,
|
||||
vucomisd, vucomiss, vunpckhpd, vunpckhps, vunpcklpd, vunpcklps,
|
||||
vxorpd, vxorps,
|
||||
// BMI
|
||||
andn, bextr, blsi, blsmsk, blsr, tzcnt,
|
||||
// BMI2
|
||||
bzhi, mulx, pdep, pext, rorx, sarx, shlx, shrx,
|
||||
// F16C
|
||||
vcvtph2ps, vcvtps2ph,
|
||||
// FMA
|
||||
|
||||
@ -10,32 +10,38 @@ mir: Mir,
|
||||
cc: std.builtin.CallingConvention,
|
||||
err_msg: ?*Zcu.ErrorMsg = null,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
result_insts_len: u8 = undefined,
|
||||
result_relocs_len: u8 = undefined,
|
||||
result_insts: [
|
||||
@max(
|
||||
1, // non-pseudo instructions
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
2, // cmovcc: cmovcc \ cmovcc
|
||||
3, // setcc: setcc \ setcc \ logicop
|
||||
2, // jcc: jcc \ jcc
|
||||
pseudo_probe_align_insts,
|
||||
pseudo_probe_adjust_unrolled_max_insts,
|
||||
pseudo_probe_adjust_setup_insts,
|
||||
pseudo_probe_adjust_loop_insts,
|
||||
abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs
|
||||
abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs
|
||||
)
|
||||
]Instruction = undefined,
|
||||
result_relocs: [
|
||||
@max(
|
||||
1, // jmp/jcc/call/mov/lea: jmp/jcc/call/mov/lea
|
||||
2, // jcc: jcc \ jcc
|
||||
2, // test \ jcc \ probe \ sub \ jmp
|
||||
1, // probe \ sub \ jcc
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
)
|
||||
]Reloc = undefined,
|
||||
result_insts_len: ResultInstIndex = undefined,
|
||||
result_insts: [max_result_insts]Instruction = undefined,
|
||||
result_relocs_len: ResultRelocIndex = undefined,
|
||||
result_relocs: [max_result_relocs]Reloc = undefined,
|
||||
|
||||
const max_result_insts = @max(
|
||||
1, // non-pseudo instructions
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
2, // cmovcc: cmovcc \ cmovcc
|
||||
3, // setcc: setcc \ setcc \ logicop
|
||||
2, // jcc: jcc \ jcc
|
||||
pseudo_probe_align_insts,
|
||||
pseudo_probe_adjust_unrolled_max_insts,
|
||||
pseudo_probe_adjust_setup_insts,
|
||||
pseudo_probe_adjust_loop_insts,
|
||||
abi.Win64.callee_preserved_regs.len * 2, // push_regs/pop_regs
|
||||
abi.SysV.callee_preserved_regs.len * 2, // push_regs/pop_regs
|
||||
);
|
||||
const max_result_relocs = @max(
|
||||
1, // jmp/jcc/call/mov/lea: jmp/jcc/call/mov/lea
|
||||
2, // jcc: jcc \ jcc
|
||||
2, // test \ jcc \ probe \ sub \ jmp
|
||||
1, // probe \ sub \ jcc
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
);
|
||||
|
||||
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_adjust_unrolled_max_insts =
|
||||
@ -51,7 +57,8 @@ pub const Error = error{
|
||||
};
|
||||
|
||||
pub const Reloc = struct {
|
||||
lowered_inst_index: u8,
|
||||
lowered_inst_index: ResultInstIndex,
|
||||
op_index: InstOpIndex,
|
||||
target: Target,
|
||||
off: i32,
|
||||
|
||||
@ -114,11 +121,11 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
||||
assert(inst.data.rx.fixes == ._);
|
||||
try lower.emit(.none, .cmovnz, &.{
|
||||
.{ .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, &.{
|
||||
.{ .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 => {
|
||||
@ -137,13 +144,13 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
||||
.pseudo_set_z_and_np_m => {
|
||||
assert(inst.data.rx.fixes == ._);
|
||||
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, &.{
|
||||
.{ .reg = inst.data.rx.r1 },
|
||||
});
|
||||
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 },
|
||||
});
|
||||
},
|
||||
@ -163,32 +170,32 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
||||
.pseudo_set_nz_or_p_m => {
|
||||
assert(inst.data.rx.fixes == ._);
|
||||
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, &.{
|
||||
.{ .reg = inst.data.rx.r1 },
|
||||
});
|
||||
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 },
|
||||
});
|
||||
},
|
||||
.pseudo_j_z_and_np_inst => {
|
||||
assert(inst.data.inst.fixes == ._);
|
||||
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, &.{
|
||||
.{ .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 => {
|
||||
assert(inst.data.inst.fixes == ._);
|
||||
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, &.{
|
||||
.{ .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)) },
|
||||
});
|
||||
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, &.{
|
||||
.{ .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() },
|
||||
});
|
||||
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);
|
||||
},
|
||||
@ -260,7 +267,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
||||
.{ .imm = .s(page_size) },
|
||||
});
|
||||
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);
|
||||
},
|
||||
@ -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();
|
||||
switch (m) {
|
||||
.sib => |*sib| switch (sib.base) {
|
||||
else => {},
|
||||
.table => sib.disp = lower.reloc(.table, sib.disp).signed,
|
||||
.table => sib.disp = lower.reloc(op_index, .table, sib.disp).signed,
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
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] = .{
|
||||
.lowered_inst_index = lower.result_insts_len,
|
||||
.op_index = op_index,
|
||||
.target = target,
|
||||
.off = off,
|
||||
};
|
||||
@ -409,7 +417,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
var emit_mnemonic = mnemonic;
|
||||
var emit_ops_storage: [4]Operand = undefined;
|
||||
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) {
|
||||
else => op,
|
||||
.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) {
|
||||
// Here, we currently assume local dynamic TLS vars, and so
|
||||
// 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, &.{
|
||||
.{ .reg = .rdi },
|
||||
.{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) },
|
||||
.{ .mem = Memory.initRip(.none, 0) },
|
||||
}, lower.target);
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{
|
||||
_ = lower.reloc(0, .{
|
||||
.linker_extern_fn = try elf_file.getGlobalSymbol("__tls_get_addr", null),
|
||||
}, 0);
|
||||
lower.result_insts[lower.result_insts_len] = try .new(.none, .call, &.{
|
||||
.{ .imm = .s(0) },
|
||||
}, lower.target);
|
||||
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;
|
||||
break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{
|
||||
break :op .{ .mem = Memory.initSib(.none, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.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 } }) },
|
||||
}, lower.target);
|
||||
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;
|
||||
break :op .{ .mem = Memory.initSib(mem_op.sib.ptr_size, .{
|
||||
break :op .{ .mem = Memory.initSib(.none, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.disp = std.math.minInt(i32),
|
||||
}) };
|
||||
}
|
||||
}
|
||||
|
||||
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0);
|
||||
if (lower.pic) switch (mnemonic) {
|
||||
.lea => {
|
||||
if (elf_sym.flags.is_extern_ptr) emit_mnemonic = .mov;
|
||||
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
|
||||
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 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 => {
|
||||
if (elf_sym.flags.is_extern_ptr) {
|
||||
const reg = ops[0].reg;
|
||||
_ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
|
||||
lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
|
||||
.{ .reg = reg.to64() },
|
||||
.{ .mem = Memory.initRip(.qword, 0) },
|
||||
@ -481,10 +491,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
.reg = reg.to64(),
|
||||
} }) };
|
||||
}
|
||||
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
|
||||
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
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, .{
|
||||
.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];
|
||||
|
||||
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, &.{
|
||||
.{ .reg = .rdi },
|
||||
.{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) },
|
||||
.{ .mem = Memory.initRip(.ptr, 0) },
|
||||
}, lower.target);
|
||||
lower.result_insts_len += 1;
|
||||
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 };
|
||||
}
|
||||
|
||||
_ = lower.reloc(.{ .linker_reloc = sym_index }, 0);
|
||||
break :op switch (mnemonic) {
|
||||
.lea => {
|
||||
if (macho_sym.flags.is_extern_ptr) emit_mnemonic = .mov;
|
||||
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
|
||||
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 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 => {
|
||||
if (macho_sym.flags.is_extern_ptr) {
|
||||
const reg = ops[0].reg;
|
||||
_ = lower.reloc(1, .{ .linker_reloc = sym_index }, 0);
|
||||
lower.result_insts[lower.result_insts_len] = try .new(.none, .mov, &.{
|
||||
.{ .reg = reg.to64() },
|
||||
.{ .mem = Memory.initRip(.qword, 0) },
|
||||
@ -534,6 +549,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
.reg = reg.to64(),
|
||||
} }) };
|
||||
}
|
||||
_ = lower.reloc(@intCast(op_index), .{ .linker_reloc = sym_index }, 0);
|
||||
break :op .{ .mem = Memory.initRip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
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 {
|
||||
@setEvalBranchQuota(2_400);
|
||||
@setEvalBranchQuota(2_500);
|
||||
const fixes = switch (inst.ops) {
|
||||
.none => inst.data.none.fixes,
|
||||
.inst => inst.data.inst.fixes,
|
||||
@ -595,7 +611,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
||||
}, switch (inst.ops) {
|
||||
.none => &.{},
|
||||
.inst => &.{
|
||||
.{ .imm = lower.reloc(.{ .inst = inst.data.inst.inst }, 0) },
|
||||
.{ .imm = lower.reloc(0, .{ .inst = inst.data.inst.inst }, 0) },
|
||||
},
|
||||
.i_s, .i_u => &.{
|
||||
.{ .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) },
|
||||
},
|
||||
.m => &.{
|
||||
.{ .mem = lower.mem(inst.data.x.payload) },
|
||||
.{ .mem = lower.mem(0, inst.data.x.payload) },
|
||||
},
|
||||
.mi_s, .mi_u => &.{
|
||||
.{ .mem = lower.mem(inst.data.x.payload + 1) },
|
||||
.{ .mem = lower.mem(0, inst.data.x.payload + 1) },
|
||||
.{ .imm = lower.imm(
|
||||
inst.ops,
|
||||
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 => &.{
|
||||
.{ .reg = inst.data.rx.r1 },
|
||||
.{ .mem = lower.mem(inst.data.rx.payload) },
|
||||
.{ .mem = lower.mem(1, inst.data.rx.payload) },
|
||||
},
|
||||
.rmr => &.{
|
||||
.{ .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 },
|
||||
},
|
||||
.rmi => &.{
|
||||
.{ .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) },
|
||||
},
|
||||
.rmi_s, .rmi_u => &.{
|
||||
.{ .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(
|
||||
inst.ops,
|
||||
lower.mir.extraData(Mir.Imm32, inst.data.rx.payload).data.imm,
|
||||
) },
|
||||
},
|
||||
.mr => &.{
|
||||
.{ .mem = lower.mem(inst.data.rx.payload) },
|
||||
.{ .mem = lower.mem(0, inst.data.rx.payload) },
|
||||
.{ .reg = inst.data.rx.r1 },
|
||||
},
|
||||
.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.r2 },
|
||||
},
|
||||
.mri => &.{
|
||||
.{ .mem = lower.mem(inst.data.rix.payload) },
|
||||
.{ .mem = lower.mem(0, inst.data.rix.payload) },
|
||||
.{ .reg = inst.data.rix.r1 },
|
||||
.{ .imm = lower.imm(inst.ops, inst.data.rix.i) },
|
||||
},
|
||||
.rrm => &.{
|
||||
.{ .reg = inst.data.rrx.r1 },
|
||||
.{ .reg = inst.data.rrx.r2 },
|
||||
.{ .mem = lower.mem(inst.data.rrx.payload) },
|
||||
.{ .mem = lower.mem(2, inst.data.rrx.payload) },
|
||||
},
|
||||
.rrmr => &.{
|
||||
.{ .reg = inst.data.rrrx.r1 },
|
||||
.{ .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 },
|
||||
},
|
||||
.rrmi => &.{
|
||||
.{ .reg = inst.data.rrix.r1 },
|
||||
.{ .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) },
|
||||
},
|
||||
.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: {
|
||||
const reg = inst.data.rx.r1;
|
||||
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 },
|
||||
.direct_reloc => .{ .linker_direct = extra.sym_index },
|
||||
.import_reloc => .{ .linker_import = extra.sym_index },
|
||||
|
||||
@ -100,6 +100,8 @@ pub const Inst = struct {
|
||||
/// ___ Division
|
||||
_d,
|
||||
|
||||
/// ___ Without Affecting Flags
|
||||
_x,
|
||||
/// ___ Left
|
||||
_l,
|
||||
/// ___ Left Double
|
||||
@ -483,6 +485,7 @@ pub const Inst = struct {
|
||||
/// ASCII adjust al after subtraction
|
||||
aa,
|
||||
/// Add with carry
|
||||
/// Unsigned integer addition of two operands with carry flag
|
||||
adc,
|
||||
/// Add
|
||||
/// Add packed integers
|
||||
@ -1162,10 +1165,8 @@ pub const Inst = struct {
|
||||
fmadd231,
|
||||
|
||||
// ADX
|
||||
/// Unsigned integer addition of two operands with carry flag
|
||||
adcx,
|
||||
/// Unsigned integer addition of two operands with overflow flag
|
||||
adox,
|
||||
ado,
|
||||
|
||||
// AESKLE
|
||||
/// Encode 128-bit key with key locker
|
||||
|
||||
@ -405,9 +405,9 @@ pub const table = [_]Entry{
|
||||
.{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
|
||||
.{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
|
||||
.{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
|
||||
.{ .jcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .short, .@"32bit" },
|
||||
.{ .jecxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"32bit" },
|
||||
.{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"64bit" },
|
||||
.{ .jcxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .short, .@"32bit" },
|
||||
.{ .jecxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .none, .@"32bit" },
|
||||
.{ .jrcxz, .d, &.{ .rel8 }, &.{ 0xe3 }, 0, .none, .@"64bit" },
|
||||
.{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
|
||||
.{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 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 },
|
||||
|
||||
.{ .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 },
|
||||
|
||||
.{ .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, &.{ .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 },
|
||||
.{ .popfd, .z, &.{}, &.{ 0x9d }, 0, .none, .@"32bit" },
|
||||
.{ .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 },
|
||||
|
||||
// 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
|
||||
.{ .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 },
|
||||
|
||||
// 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, &.{ .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, &.{ .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
|
||||
.{ .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 },
|
||||
|
||||
@ -83,8 +83,10 @@ pub fn generateLazyFunction(
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
) CodeGenError!void {
|
||||
const zcu = pt.zcu;
|
||||
const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool);
|
||||
const target = zcu.fileByIndex(file).mod.resolved_target.result;
|
||||
const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
|
||||
zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.resolved_target.result
|
||||
else
|
||||
zcu.getTarget();
|
||||
switch (target_util.zigBackend(target, false)) {
|
||||
else => unreachable,
|
||||
inline .stage2_x86_64, .stage2_riscv64 => |backend| {
|
||||
|
||||
@ -39,10 +39,7 @@ test {
|
||||
_ = Package;
|
||||
}
|
||||
|
||||
const thread_stack_size = switch (builtin.zig_backend) {
|
||||
else => std.Thread.SpawnConfig.default_stack_size,
|
||||
.stage2_x86_64 => 32 << 20,
|
||||
};
|
||||
const thread_stack_size = 32 << 20;
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.wasiCwd = wasi_cwd,
|
||||
|
||||
@ -726,11 +726,11 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
|
||||
else => false,
|
||||
},
|
||||
.is_named_enum_value => switch (backend) {
|
||||
.stage2_llvm => true,
|
||||
.stage2_llvm, .stage2_x86_64 => true,
|
||||
else => false,
|
||||
},
|
||||
.error_set_has_value => switch (backend) {
|
||||
.stage2_llvm, .stage2_wasm => true,
|
||||
.stage2_llvm, .stage2_wasm, .stage2_x86_64 => true,
|
||||
else => false,
|
||||
},
|
||||
.field_reordering => switch (backend) {
|
||||
|
||||
@ -527,7 +527,7 @@ fn testIntDivision() !void {
|
||||
try expect(mod(i64, -14, 12) == 10);
|
||||
try expect(mod(i16, -2, 12) == 10);
|
||||
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(i32, 10, 12) == 10);
|
||||
|
||||
@ -93,6 +93,11 @@ pub fn build(b: *std.Build) void {
|
||||
.cpu_arch = .x86_64,
|
||||
.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_model = .{ .explicit = &std.Target.x86.cpu.x86_64_v4 },
|
||||
|
||||
@ -33,6 +33,28 @@ fn Scalar(comptime Type: type) type {
|
||||
.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 fn splat(comptime Type: type, scalar: Scalar(Type)) Type {
|
||||
return switch (@typeInfo(Type)) {
|
||||
@ -16205,6 +16227,8 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
|
||||
);
|
||||
}
|
||||
fn testInts() !void {
|
||||
try testArgs(i4, 0x3, 0x2);
|
||||
try testArgs(u4, 0xe, 0x6);
|
||||
try testArgs(i8, 0x48, 0x6c);
|
||||
try testArgs(u8, 0xbb, 0x43);
|
||||
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,
|
||||
-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,
|
||||
0x15, 0x55, -0x4a, 0x16, -0x73, -0x0c, 0x1c, -0x26, -0x14, 0x00, 0x55, 0x7b, 0x16, -0x2e, -0x5f, -0x67,
|
||||
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, -0x01, 0x55, 0x7b, 0x16, -0x2e, -0x5f, -0x67,
|
||||
});
|
||||
try testArgs(@Vector(64, i8), .{
|
||||
-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,
|
||||
-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,
|
||||
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,
|
||||
});
|
||||
|
||||
@ -18024,7 +18048,7 @@ fn binary(comptime op: anytype, comptime opts: struct { compare: Compare = .rela
|
||||
try testArgs(@Vector(16, u8), .{
|
||||
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), .{
|
||||
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) {
|
||||
return lhs + rhs;
|
||||
inline fn addUnsafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
|
||||
@setRuntimeSafety(false);
|
||||
return @as(AddOneBit(Type), lhs) + rhs;
|
||||
}
|
||||
test add {
|
||||
const test_add = binary(add, .{});
|
||||
try test_add.testFloats();
|
||||
try test_add.testFloatVectors();
|
||||
test addUnsafe {
|
||||
const test_add_unsafe = binary(addUnsafe, .{});
|
||||
try test_add_unsafe.testInts();
|
||||
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) {
|
||||
return lhs - rhs;
|
||||
inline fn subUnsafe(comptime Type: type, lhs: Type, rhs: Type) AddOneBit(Type) {
|
||||
@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 {
|
||||
const test_subtract = binary(subtract, .{});
|
||||
try test_subtract.testFloats();
|
||||
try test_subtract.testFloatVectors();
|
||||
test subUnsafe {
|
||||
const test_sub_unsafe = binary(subUnsafe, .{});
|
||||
try test_sub_unsafe.testInts();
|
||||
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) {
|
||||
@ -18999,42 +19046,51 @@ test divide {
|
||||
try test_divide.testFloatVectors();
|
||||
}
|
||||
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
// TODO: @TypeOf(@divTrunc(lhs, rhs))
|
||||
inline fn divTrunc(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) {
|
||||
if (@inComptime()) {
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
return @trunc(lhs / rhs);
|
||||
inline fn divTrunc(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||
switch (@typeInfo(Scalar(Type))) {
|
||||
else => @compileError(@typeName(Type)),
|
||||
.int => return @divTrunc(lhs, rhs),
|
||||
.float => {
|
||||
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 {
|
||||
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.testFloatVectors();
|
||||
}
|
||||
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
// TODO: @TypeOf(@divFloor(lhs, rhs))
|
||||
inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(lhs / rhs) {
|
||||
if (@inComptime()) {
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
return @floor(lhs / rhs);
|
||||
inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||
switch (@typeInfo(Scalar(Type))) {
|
||||
else => @compileError(@typeName(Type)),
|
||||
.int => return @divFloor(lhs, rhs),
|
||||
.float => {
|
||||
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 {
|
||||
const test_div_floor = binary(divFloor, .{ .compare = .approx_int });
|
||||
@ -19045,25 +19101,33 @@ test divFloor {
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
// TODO: @TypeOf(@rem(lhs, rhs))
|
||||
inline fn rem(comptime Type: type, lhs: Type, rhs: Type) Type {
|
||||
if (@inComptime()) {
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
switch (@typeInfo(Type)) {
|
||||
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;
|
||||
},
|
||||
}
|
||||
switch (@typeInfo(Scalar(Type))) {
|
||||
else => @compileError(@typeName(Type)),
|
||||
.int => return @rem(lhs, rhs),
|
||||
.float => {
|
||||
if (@inComptime()) {
|
||||
// workaround https://github.com/ziglang/zig/issues/22748
|
||||
switch (@typeInfo(Type)) {
|
||||
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 {
|
||||
const test_rem = binary(rem, .{});
|
||||
try test_rem.testInts();
|
||||
try test_rem.testIntVectors();
|
||||
try test_rem.testFloats();
|
||||
try test_rem.testFloatVectors();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
slice = &array;
|
||||
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;
|
||||
}
|
||||
}
|
||||
test access {
|
||||
try access([3]u8{ 0xdb, 0xef, 0xbd });
|
||||
try access([3]u16{ 0x340e, 0x3654, 0x88d7 });
|
||||
try access([3]u32{ 0xd424c2c0, 0x2d6ac466, 0x5a0cfaba });
|
||||
try access([3]u64{
|
||||
test accessSlice {
|
||||
try accessSlice([3]u8{ 0xdb, 0xef, 0xbd });
|
||||
try accessSlice([3]u16{ 0x340e, 0x3654, 0x88d7 });
|
||||
try accessSlice([3]u32{ 0xd424c2c0, 0x2d6ac466, 0x5a0cfaba });
|
||||
try accessSlice([3]u64{
|
||||
0x9327a4f5221666a6,
|
||||
0x5c34d3ddd84a8b12,
|
||||
0xbae087f39f649260,
|
||||
});
|
||||
try access([3]u128{
|
||||
try accessSlice([3]u128{
|
||||
0x601cf010065444d4d42d5536dd9b95db,
|
||||
0xa03f592fcaa22d40af23a0c735531e3c,
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
@ -18,5 +18,5 @@ pub fn main() !void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -8,7 +8,7 @@ export fn entry() usize {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :4:29: error: invalid operands to binary expression: 'struct' and 'struct'
|
||||
|
||||
@ -11,7 +11,7 @@ fn doSomeAsm() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:5: error: unable to evaluate comptime expression
|
||||
|
||||
@ -8,7 +8,7 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :4:5: error: asm cannot output to const local 'f'
|
||||
|
||||
@ -17,7 +17,7 @@ export fn comptimeBuiltinCall() callconv(.Naked) void {
|
||||
fn f() void {}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:6: error: runtime call not allowed in naked function
|
||||
|
||||
@ -4,7 +4,7 @@ export fn entry() void {
|
||||
fn foo() callconv(.naked) void {}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: unable to call function with calling convention 'naked'
|
||||
|
||||
@ -10,7 +10,7 @@ export fn entry1() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:36: error: type 'u32' cannot represent integer value '-1'
|
||||
|
||||
@ -5,7 +5,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :4:12: error: operator == not allowed for type '?[3]i32'
|
||||
|
||||
@ -13,7 +13,7 @@ export fn baz() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:5: error: found compile log statement
|
||||
|
||||
@ -10,7 +10,7 @@ fn inner(comptime n: usize) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :8:9: error: found compile log statement
|
||||
|
||||
@ -8,7 +8,7 @@ export fn entry() usize {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:16: error: division by zero here causes undefined behavior
|
||||
|
||||
@ -5,7 +5,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:32: error: null pointer casted to type '*i32'
|
||||
|
||||
@ -6,7 +6,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:32: error: use of undefined value here causes undefined behavior
|
||||
|
||||
@ -6,7 +6,7 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:9: error: expected type 'u16', found '*const [5:0]u8'
|
||||
|
||||
@ -15,7 +15,7 @@ fn foo(x: i32) !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:9: error: duplicate switch value
|
||||
|
||||
@ -15,7 +15,7 @@ pub export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :9:48: error: caught unexpected error 'InvalidVersion'
|
||||
|
||||
@ -13,7 +13,7 @@ fn foo(x: i32) !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:26: error: switch must handle all possibilities
|
||||
|
||||
@ -24,7 +24,7 @@ pub fn main() Error!void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :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
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: exact division produced remainder
|
||||
|
||||
@ -8,7 +8,7 @@ export fn entry2() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: primitive integer type 'u65536' exceeds maximum bit width of 65535
|
||||
|
||||
@ -4,7 +4,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:25: error: exported symbol name cannot be empty
|
||||
|
||||
@ -4,7 +4,7 @@ export fn foo(a: *i32) Foo {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:12: error: expected pointer type, found 'i32'
|
||||
|
||||
@ -4,7 +4,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: exact division produced remainder
|
||||
|
||||
@ -7,7 +7,7 @@ fn concat() [16]f32 {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:17: error: expected type '[4]f32', found '[16]f32'
|
||||
|
||||
@ -4,7 +4,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :1:1: error: non-extern function has no body
|
||||
|
||||
@ -19,7 +19,7 @@ pub export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :18:43: error: value of type 'type' ignored
|
||||
|
||||
@ -36,7 +36,7 @@ pub fn is(comptime id: std.builtin.TypeId) TraitFn {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :8:48: error: expected type 'type', found 'bool'
|
||||
|
||||
@ -7,7 +7,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:9: error: array literal requires address-of operator (&) to coerce to slice type '[]i32'
|
||||
|
||||
@ -11,7 +11,7 @@ export fn entry2() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:14: error: expected type 'f32', found 'f64'
|
||||
|
||||
@ -13,7 +13,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :11:21: error: 'error.B' not a member of error set 'error{A,C}'
|
||||
|
||||
@ -24,7 +24,7 @@ export fn incompatiblePointers4() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:9: error: incompatible types: '?@Vector(10, i32)' and '@Vector(11, i32)'
|
||||
|
||||
@ -4,7 +4,7 @@ fn main() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:23: error: trailing digit separator
|
||||
|
||||
@ -16,7 +16,7 @@ export fn entry4() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: primitive integer type 'u000123' has leading zero
|
||||
|
||||
@ -11,7 +11,7 @@ fn loadv(ptr: anytype) i31 {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :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
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :23:6: error: no field or member function named 'init' in 'tmp.List'
|
||||
|
||||
@ -12,7 +12,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :4:26: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=x86_64-linux
|
||||
// output_mode=Exe
|
||||
//
|
||||
|
||||
@ -11,7 +11,7 @@ fn foo() ?OtherError!i32 {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:34: error: expected type '?error{NextError}!i32', found '?error{OutOfMemory}!i32'
|
||||
|
||||
@ -16,7 +16,7 @@ pub export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :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
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :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
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:12: error: packed structs cannot contain fields of type 'anyerror'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
fn main() void {}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=x86_64-linux
|
||||
// output_mode=Exe
|
||||
//
|
||||
|
||||
@ -3,7 +3,7 @@ export fn entry(a: *i32) usize {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:12: error: expected pointer type, found 'usize'
|
||||
|
||||
@ -13,7 +13,7 @@ fn foo(x: i32) !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :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
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: cannot assign to constant
|
||||
|
||||
@ -6,7 +6,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: cannot assign to constant
|
||||
|
||||
@ -7,7 +7,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: cannot return from naked function
|
||||
|
||||
@ -4,7 +4,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: operation caused overflow
|
||||
|
||||
@ -4,7 +4,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: exact shift shifted out 1 bits
|
||||
|
||||
@ -3,7 +3,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
|
||||
|
||||
@ -11,7 +11,7 @@ fn storev(ptr: anytype, val: i31) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :10:8: error: unable to determine vector element index of type '*align(16:0:4:?) i31'
|
||||
|
||||
@ -8,7 +8,7 @@ fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :6:9: error: cannot suspend inside suspend block
|
||||
|
||||
@ -20,7 +20,7 @@ export fn entry() usize {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :14:14: error: unreachable else prong; all cases already handled
|
||||
|
||||
@ -7,7 +7,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:11: error: unable to evaluate comptime expression
|
||||
|
||||
@ -21,7 +21,7 @@ pub export fn simple() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :7:14: error: unreachable else prong; all cases already handled
|
||||
|
||||
@ -19,7 +19,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:5: error: runtime safety check not allowed in naked function
|
||||
|
||||
@ -23,7 +23,7 @@ pub export fn entry2() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
//
|
||||
// :6:20: error: cannot @bitCast to '[]i32'
|
||||
|
||||
@ -7,7 +7,7 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux-gnu
|
||||
// link_libc=true
|
||||
//
|
||||
|
||||
@ -14,5 +14,5 @@ fn foo(comptime info: std.builtin.Type) !void {
|
||||
|
||||
// run
|
||||
// is_test=true
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
//
|
||||
|
||||
@ -36,5 +36,5 @@ fn assert(ok: bool) void {
|
||||
// TODO: enable this for native backend
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=aarch64-linux,aarch64-macos
|
||||
|
||||
@ -7,6 +7,6 @@ pub fn main() void {
|
||||
|
||||
// compile
|
||||
// output_mode=Exe
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
//
|
||||
|
||||
@ -8,6 +8,6 @@ pub fn main() void {
|
||||
|
||||
// compile
|
||||
// output_mode=Exe
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
//
|
||||
|
||||
@ -11,6 +11,6 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
//
|
||||
|
||||
@ -5,7 +5,7 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
// link_libc=true
|
||||
//
|
||||
|
||||
@ -4,6 +4,6 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// compile
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
//
|
||||
|
||||
@ -44,6 +44,6 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux,x86_64-macos
|
||||
//
|
||||
|
||||
@ -18,5 +18,5 @@ pub fn main() !void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -7,5 +7,5 @@ pub fn main() void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -21,5 +21,5 @@ fn foo(bytes: []u8) u32 {
|
||||
return int_slice[0];
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -22,5 +22,5 @@ fn bar(a: u2) Foo {
|
||||
fn baz(_: Foo) void {}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -19,5 +19,5 @@ pub fn main() u8 {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -19,5 +19,5 @@ pub fn main() u8 {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -17,5 +17,5 @@ fn foo(set1: Set1) Set2 {
|
||||
return @errorCast(set1);
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -16,5 +16,5 @@ fn foo() anyerror!i32 {
|
||||
return error.Bar;
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -18,5 +18,5 @@ fn bar(one: u1, not_zero: i32) void {
|
||||
_ = x;
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -16,5 +16,5 @@ fn bar(a: f32) i8 {
|
||||
}
|
||||
fn baz(_: i8) void {}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -16,5 +16,5 @@ fn bar(a: f32) u8 {
|
||||
}
|
||||
fn baz(_: u8) void {}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -16,5 +16,5 @@ fn bar(a: f32) u8 {
|
||||
}
|
||||
fn baz(_: u8) void {}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -15,5 +15,5 @@ pub fn main() !void {
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -15,5 +15,5 @@ pub fn main() !void {
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -15,5 +15,5 @@ pub fn main() !void {
|
||||
return error.TestFailed;
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
@ -22,5 +22,5 @@ pub fn main() !void {
|
||||
}
|
||||
|
||||
// run
|
||||
// backend=llvm
|
||||
// backend=stage2,llvm
|
||||
// target=native
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user