mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #15727 from jacobly0/x86_64-behavior
x86_64: behavior
This commit is contained in:
commit
b873ce1e0e
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,7 @@ pub fn format(
|
||||
try writer.print("+{s} ", .{tag});
|
||||
},
|
||||
.m, .mi, .m1, .mc, .vmi => try writer.print("/{d} ", .{encoding.modRmExt()}),
|
||||
.mr, .rm, .rmi, .mri, .mrc, .rvm, .rvmi, .mvr => try writer.writeAll("/r "),
|
||||
.mr, .rm, .rmi, .mri, .mrc, .rm0, .rvm, .rvmr, .rvmi, .mvr => try writer.writeAll("/r "),
|
||||
}
|
||||
|
||||
switch (encoding.data.op_en) {
|
||||
@ -202,7 +202,8 @@ pub fn format(
|
||||
};
|
||||
try writer.print("{s} ", .{tag});
|
||||
},
|
||||
.np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm, .mrc, .rvm, .mvr => {},
|
||||
.rvmr => try writer.writeAll("/is4 "),
|
||||
.np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .rvm, .mvr => {},
|
||||
}
|
||||
|
||||
try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
|
||||
@ -262,6 +263,7 @@ pub const Mnemonic = enum {
|
||||
fisttp, fld,
|
||||
// MMX
|
||||
movd, movq,
|
||||
packssdw, packsswb, packuswb,
|
||||
paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw,
|
||||
pand, pandn, por, pxor,
|
||||
pmulhw, pmullw,
|
||||
@ -270,7 +272,7 @@ pub const Mnemonic = enum {
|
||||
addps, addss,
|
||||
andps,
|
||||
andnps,
|
||||
cmpss,
|
||||
cmpps, cmpss,
|
||||
cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si,
|
||||
divps, divss,
|
||||
maxps, maxss,
|
||||
@ -290,7 +292,7 @@ pub const Mnemonic = enum {
|
||||
addpd, addsd,
|
||||
andpd,
|
||||
andnpd,
|
||||
//cmpsd,
|
||||
cmppd, //cmpsd,
|
||||
cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd,
|
||||
cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd,
|
||||
cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si,
|
||||
@ -315,8 +317,10 @@ pub const Mnemonic = enum {
|
||||
// SSE3
|
||||
movddup, movshdup, movsldup,
|
||||
// SSE4.1
|
||||
blendpd, blendps, blendvpd, blendvps,
|
||||
extractps,
|
||||
insertps,
|
||||
packusdw,
|
||||
pextrb, pextrd, pextrq,
|
||||
pinsrb, pinsrd, pinsrq,
|
||||
pmaxsb, pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw,
|
||||
@ -325,7 +329,9 @@ pub const Mnemonic = enum {
|
||||
// AVX
|
||||
vaddpd, vaddps, vaddsd, vaddss,
|
||||
vandnpd, vandnps, vandpd, vandps,
|
||||
vblendpd, vblendps, vblendvpd, vblendvps,
|
||||
vbroadcastf128, vbroadcastsd, vbroadcastss,
|
||||
vcmppd, vcmpps, vcmpsd, vcmpss,
|
||||
vcvtdq2pd, vcvtdq2ps, vcvtpd2dq, vcvtpd2ps,
|
||||
vcvtps2dq, vcvtps2pd, vcvtsd2si, vcvtsd2ss,
|
||||
vcvtsi2sd, vcvtsi2ss, vcvtss2sd, vcvtss2si,
|
||||
@ -347,6 +353,7 @@ pub const Mnemonic = enum {
|
||||
vmovupd, vmovups,
|
||||
vmulpd, vmulps, vmulsd, vmulss,
|
||||
vorpd, vorps,
|
||||
vpackssdw, vpacksswb, vpackusdw, vpackuswb,
|
||||
vpaddb, vpaddd, vpaddq, vpaddsb, vpaddsw, vpaddusb, vpaddusw, vpaddw,
|
||||
vpand, vpandn,
|
||||
vpextrb, vpextrd, vpextrq, vpextrw,
|
||||
@ -385,7 +392,7 @@ pub const OpEn = enum {
|
||||
fd, td,
|
||||
m1, mc, mi, mr, rm,
|
||||
rmi, mri, mrc,
|
||||
vmi, rvm, rvmi, mvr,
|
||||
rm0, vmi, rvm, rvmr, rvmi, mvr,
|
||||
// zig fmt: on
|
||||
};
|
||||
|
||||
@ -407,7 +414,7 @@ pub const Op = enum {
|
||||
moffs,
|
||||
sreg,
|
||||
st, mm, mm_m64,
|
||||
xmm, xmm_m32, xmm_m64, xmm_m128,
|
||||
xmm0, xmm, xmm_m32, xmm_m64, xmm_m128,
|
||||
ymm, ymm_m256,
|
||||
// zig fmt: on
|
||||
|
||||
@ -436,7 +443,9 @@ pub const Op = enum {
|
||||
.segment => .sreg,
|
||||
.x87 => .st,
|
||||
.mmx => .mm,
|
||||
.sse => switch (reg.bitSize()) {
|
||||
.sse => if (reg == .xmm0)
|
||||
.xmm0
|
||||
else switch (reg.bitSize()) {
|
||||
128 => .xmm,
|
||||
256 => .ymm,
|
||||
else => unreachable,
|
||||
@ -494,7 +503,7 @@ pub const Op = enum {
|
||||
.eax, .r32, .rm32, .r32_m16 => unreachable,
|
||||
.rax, .r64, .rm64, .r64_m16 => unreachable,
|
||||
.st, .mm, .mm_m64 => unreachable,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable,
|
||||
.xmm0, .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable,
|
||||
.ymm, .ymm_m256 => unreachable,
|
||||
.m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable,
|
||||
.unity => 1,
|
||||
@ -516,7 +525,7 @@ pub const Op = enum {
|
||||
.eax, .r32, .rm32, .r32_m8, .r32_m16 => 32,
|
||||
.rax, .r64, .rm64, .r64_m16, .mm, .mm_m64 => 64,
|
||||
.st => 80,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128,
|
||||
.xmm0, .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => 128,
|
||||
.ymm, .ymm_m256 => 256,
|
||||
};
|
||||
}
|
||||
@ -526,7 +535,8 @@ pub const Op = enum {
|
||||
.none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
|
||||
.unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable,
|
||||
.rel8, .rel16, .rel32 => unreachable,
|
||||
.al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64, .st, .mm, .xmm, .ymm => unreachable,
|
||||
.al, .cl, .r8, .ax, .r16, .eax, .r32, .rax, .r64 => unreachable,
|
||||
.st, .mm, .xmm0, .xmm, .ymm => unreachable,
|
||||
.m8, .rm8, .r32_m8 => 8,
|
||||
.m16, .rm16, .r32_m16, .r64_m16 => 16,
|
||||
.m32, .rm32, .xmm_m32 => 32,
|
||||
@ -558,7 +568,7 @@ pub const Op = enum {
|
||||
.rm8, .rm16, .rm32, .rm64,
|
||||
.r32_m8, .r32_m16, .r64_m16,
|
||||
.st, .mm, .mm_m64,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128,
|
||||
.xmm0, .xmm, .xmm_m32, .xmm_m64, .xmm_m128,
|
||||
.ymm, .ymm_m256,
|
||||
=> true,
|
||||
else => false,
|
||||
@ -612,7 +622,7 @@ pub const Op = enum {
|
||||
.sreg => .segment,
|
||||
.st => .x87,
|
||||
.mm, .mm_m64 => .mmx,
|
||||
.xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .sse,
|
||||
.xmm0, .xmm, .xmm_m32, .xmm_m64, .xmm_m128 => .sse,
|
||||
.ymm, .ymm_m256 => .sse,
|
||||
};
|
||||
}
|
||||
@ -629,7 +639,7 @@ pub const Op = enum {
|
||||
else => {
|
||||
if (op.isRegister() and target.isRegister()) {
|
||||
return switch (target) {
|
||||
.cl, .al, .ax, .eax, .rax => op == target,
|
||||
.cl, .al, .ax, .eax, .rax, .xmm0 => op == target,
|
||||
else => op.class() == target.class() and op.regBitSize() == target.regBitSize(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -377,6 +377,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
||||
.r => inst.data.r.fixes,
|
||||
.rr => inst.data.rr.fixes,
|
||||
.rrr => inst.data.rrr.fixes,
|
||||
.rrrr => inst.data.rrrr.fixes,
|
||||
.rrri => inst.data.rrri.fixes,
|
||||
.rri_s, .rri_u => inst.data.rri.fixes,
|
||||
.ri_s, .ri_u => inst.data.ri.fixes,
|
||||
@ -430,6 +431,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
||||
.{ .reg = inst.data.rrr.r2 },
|
||||
.{ .reg = inst.data.rrr.r3 },
|
||||
},
|
||||
.rrrr => &.{
|
||||
.{ .reg = inst.data.rrrr.r1 },
|
||||
.{ .reg = inst.data.rrrr.r2 },
|
||||
.{ .reg = inst.data.rrrr.r3 },
|
||||
.{ .reg = inst.data.rrrr.r4 },
|
||||
},
|
||||
.rrri => &.{
|
||||
.{ .reg = inst.data.rrri.r1 },
|
||||
.{ .reg = inst.data.rrri.r2 },
|
||||
|
||||
@ -446,6 +446,12 @@ pub const Inst = struct {
|
||||
/// Bitwise logical xor of packed double-precision floating-point values
|
||||
xor,
|
||||
|
||||
/// Pack with signed saturation
|
||||
ackssw,
|
||||
/// Pack with signed saturation
|
||||
ackssd,
|
||||
/// Pack with unsigned saturation
|
||||
ackusw,
|
||||
/// Add packed signed integers with signed saturation
|
||||
adds,
|
||||
/// Add packed unsigned integers with unsigned saturation
|
||||
@ -596,6 +602,18 @@ pub const Inst = struct {
|
||||
/// Replicate single floating-point values
|
||||
movsldup,
|
||||
|
||||
/// Pack with unsigned saturation
|
||||
ackusd,
|
||||
/// Blend packed single-precision floating-point values
|
||||
/// Blend scalar single-precision floating-point values
|
||||
/// Blend packed double-precision floating-point values
|
||||
/// Blend scalar double-precision floating-point values
|
||||
blend,
|
||||
/// Variable blend packed single-precision floating-point values
|
||||
/// Variable blend scalar single-precision floating-point values
|
||||
/// Variable blend packed double-precision floating-point values
|
||||
/// Variable blend scalar double-precision floating-point values
|
||||
blendv,
|
||||
/// Extract packed floating-point values
|
||||
extract,
|
||||
/// Insert scalar single-precision floating-point value
|
||||
@ -651,6 +669,9 @@ pub const Inst = struct {
|
||||
/// Register, register, register operands.
|
||||
/// Uses `rrr` payload.
|
||||
rrr,
|
||||
/// Register, register, register, register operands.
|
||||
/// Uses `rrrr` payload.
|
||||
rrrr,
|
||||
/// Register, register, register, immediate (byte) operands.
|
||||
/// Uses `rrri` payload.
|
||||
rrri,
|
||||
@ -870,6 +891,13 @@ pub const Inst = struct {
|
||||
r2: Register,
|
||||
r3: Register,
|
||||
},
|
||||
rrrr: struct {
|
||||
fixes: Fixes = ._,
|
||||
r1: Register,
|
||||
r2: Register,
|
||||
r3: Register,
|
||||
r4: Register,
|
||||
},
|
||||
rrri: struct {
|
||||
fixes: Fixes = ._,
|
||||
r1: Register,
|
||||
|
||||
@ -226,8 +226,8 @@ pub const Instruction = struct {
|
||||
else => {
|
||||
const mem_op = switch (data.op_en) {
|
||||
.m, .mi, .m1, .mc, .mr, .mri, .mrc, .mvr => inst.ops[0],
|
||||
.rm, .rmi, .vmi => inst.ops[1],
|
||||
.rvm, .rvmi => inst.ops[2],
|
||||
.rm, .rmi, .rm0, .vmi => inst.ops[1],
|
||||
.rvm, .rvmr, .rvmi => inst.ops[2],
|
||||
else => unreachable,
|
||||
};
|
||||
switch (mem_op) {
|
||||
@ -235,7 +235,7 @@ pub const Instruction = struct {
|
||||
const rm = switch (data.op_en) {
|
||||
.m, .mi, .m1, .mc, .vmi => enc.modRmExt(),
|
||||
.mr, .mri, .mrc => inst.ops[1].reg.lowEnc(),
|
||||
.rm, .rmi, .rvm, .rvmi => inst.ops[0].reg.lowEnc(),
|
||||
.rm, .rmi, .rm0, .rvm, .rvmr, .rvmi => inst.ops[0].reg.lowEnc(),
|
||||
.mvr => inst.ops[2].reg.lowEnc(),
|
||||
else => unreachable,
|
||||
};
|
||||
@ -245,7 +245,7 @@ pub const Instruction = struct {
|
||||
const op = switch (data.op_en) {
|
||||
.m, .mi, .m1, .mc, .vmi => .none,
|
||||
.mr, .mri, .mrc => inst.ops[1],
|
||||
.rm, .rmi, .rvm, .rvmi => inst.ops[0],
|
||||
.rm, .rmi, .rm0, .rvm, .rvmr, .rvmi => inst.ops[0],
|
||||
.mvr => inst.ops[2],
|
||||
else => unreachable,
|
||||
};
|
||||
@ -257,6 +257,7 @@ pub const Instruction = struct {
|
||||
switch (data.op_en) {
|
||||
.mi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder),
|
||||
.rmi, .mri, .vmi => try encodeImm(inst.ops[2].imm, data.ops[2], encoder),
|
||||
.rvmr => try encoder.imm8(@as(u8, inst.ops[3].reg.enc()) << 4),
|
||||
.rvmi => try encodeImm(inst.ops[3].imm, data.ops[3], encoder),
|
||||
else => {},
|
||||
}
|
||||
@ -298,7 +299,7 @@ pub const Instruction = struct {
|
||||
.i, .zi, .o, .oi, .d, .np => null,
|
||||
.fd => inst.ops[1].mem.base().reg,
|
||||
.td => inst.ops[0].mem.base().reg,
|
||||
.rm, .rmi => if (inst.ops[1].isSegmentRegister())
|
||||
.rm, .rmi, .rm0 => if (inst.ops[1].isSegmentRegister())
|
||||
switch (inst.ops[1]) {
|
||||
.reg => |reg| reg,
|
||||
.mem => |mem| mem.base().reg,
|
||||
@ -314,7 +315,7 @@ pub const Instruction = struct {
|
||||
}
|
||||
else
|
||||
null,
|
||||
.vmi, .rvm, .rvmi, .mvr => unreachable,
|
||||
.vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable,
|
||||
};
|
||||
if (segment_override) |seg| {
|
||||
legacy.setSegmentOverride(seg);
|
||||
@ -333,23 +334,23 @@ pub const Instruction = struct {
|
||||
switch (op_en) {
|
||||
.np, .i, .zi, .fd, .td, .d => {},
|
||||
.o, .oi => rex.b = inst.ops[0].reg.isExtended(),
|
||||
.m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc => {
|
||||
.m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0 => {
|
||||
const r_op = switch (op_en) {
|
||||
.rm, .rmi => inst.ops[0],
|
||||
.rm, .rmi, .rm0 => inst.ops[0],
|
||||
.mr, .mri, .mrc => inst.ops[1],
|
||||
else => .none,
|
||||
};
|
||||
rex.r = r_op.isBaseExtended();
|
||||
|
||||
const b_x_op = switch (op_en) {
|
||||
.rm, .rmi => inst.ops[1],
|
||||
.rm, .rmi, .rm0 => inst.ops[1],
|
||||
.m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.ops[0],
|
||||
else => unreachable,
|
||||
};
|
||||
rex.b = b_x_op.isBaseExtended();
|
||||
rex.x = b_x_op.isIndexExtended();
|
||||
},
|
||||
.vmi, .rvm, .rvmi, .mvr => unreachable,
|
||||
.vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable,
|
||||
}
|
||||
|
||||
try encoder.rex(rex);
|
||||
@ -367,9 +368,9 @@ pub const Instruction = struct {
|
||||
switch (op_en) {
|
||||
.np, .i, .zi, .fd, .td, .d => {},
|
||||
.o, .oi => vex.b = inst.ops[0].reg.isExtended(),
|
||||
.m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .vmi, .rvm, .rvmi, .mvr => {
|
||||
.m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr => {
|
||||
const r_op = switch (op_en) {
|
||||
.rm, .rmi, .rvm, .rvmi => inst.ops[0],
|
||||
.rm, .rmi, .rm0, .rvm, .rvmr, .rvmi => inst.ops[0],
|
||||
.mr, .mri, .mrc => inst.ops[1],
|
||||
.mvr => inst.ops[2],
|
||||
.m, .mi, .m1, .mc, .vmi => .none,
|
||||
@ -378,9 +379,9 @@ pub const Instruction = struct {
|
||||
vex.r = r_op.isBaseExtended();
|
||||
|
||||
const b_x_op = switch (op_en) {
|
||||
.rm, .rmi, .vmi => inst.ops[1],
|
||||
.rm, .rmi, .rm0, .vmi => inst.ops[1],
|
||||
.m, .mi, .m1, .mc, .mr, .mri, .mrc, .mvr => inst.ops[0],
|
||||
.rvm, .rvmi => inst.ops[2],
|
||||
.rvm, .rvmr, .rvmi => inst.ops[2],
|
||||
else => unreachable,
|
||||
};
|
||||
vex.b = b_x_op.isBaseExtended();
|
||||
@ -408,7 +409,7 @@ pub const Instruction = struct {
|
||||
switch (op_en) {
|
||||
else => {},
|
||||
.vmi => vex.v = inst.ops[0].reg,
|
||||
.rvm, .rvmi => vex.v = inst.ops[1].reg,
|
||||
.rvm, .rvmr, .rvmi => vex.v = inst.ops[1].reg,
|
||||
}
|
||||
|
||||
try encoder.vex(vex);
|
||||
|
||||
@ -846,6 +846,8 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .andps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x54 }, 0, .none, .sse },
|
||||
|
||||
.{ .cmpps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc2 }, 0, .none, .sse },
|
||||
|
||||
.{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .none, .sse },
|
||||
|
||||
.{ .cvtpi2ps, .rm, &.{ .xmm, .mm_m64 }, &.{ 0x0f, 0x2a }, 0, .none, .sse },
|
||||
@ -917,6 +919,8 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .andpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x54 }, 0, .none, .sse2 },
|
||||
|
||||
.{ .cmppd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc2 }, 0, .none, .sse2 },
|
||||
|
||||
.{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .none, .sse2 },
|
||||
|
||||
.{ .cvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .none, .sse2 },
|
||||
@ -992,6 +996,11 @@ pub const table = [_]Entry{
|
||||
|
||||
.{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .none, .sse2 },
|
||||
|
||||
.{ .packsswb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x63 }, 0, .none, .sse2 },
|
||||
.{ .packssdw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6b }, 0, .none, .sse2 },
|
||||
|
||||
.{ .packuswb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x67 }, 0, .none, .sse2 },
|
||||
|
||||
.{ .paddb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .none, .sse2 },
|
||||
.{ .paddw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .none, .sse2 },
|
||||
.{ .paddd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .none, .sse2 },
|
||||
@ -1085,10 +1094,20 @@ pub const table = [_]Entry{
|
||||
.{ .movsldup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x12 }, 0, .none, .sse3 },
|
||||
|
||||
// SSE4.1
|
||||
.{ .blendpd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0d }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .blendps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0c }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .blendvpd, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x15 }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .blendvps, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x14 }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .extractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .insertps, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .packusdw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x2b }, 0, .none, .sse4_1 },
|
||||
|
||||
.{ .pextrb, .mri, &.{ .r32_m8, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x14 }, 0, .none, .sse4_1 },
|
||||
.{ .pextrd, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .none, .sse4_1 },
|
||||
.{ .pextrq, .mri, &.{ .rm64, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x16 }, 0, .long, .sse4_1 },
|
||||
@ -1146,11 +1165,33 @@ pub const table = [_]Entry{
|
||||
.{ .vandps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x54 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vandps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x54 }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vblendpd, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0d }, 0, .vex_128_wig, .avx },
|
||||
.{ .vblendpd, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0d }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vblendps, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0c }, 0, .vex_128_wig, .avx },
|
||||
.{ .vblendps, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0c }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vblendvpd, .rvmr, &.{ .xmm, .xmm, .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x3a, 0x4b }, 0, .vex_128_w0, .avx },
|
||||
.{ .vblendvpd, .rvmr, &.{ .ymm, .ymm, .ymm_m256, .ymm }, &.{ 0x66, 0x0f, 0x3a, 0x4b }, 0, .vex_256_w0, .avx },
|
||||
|
||||
.{ .vblendvps, .rvmr, &.{ .xmm, .xmm, .xmm_m128, .xmm }, &.{ 0x66, 0x0f, 0x3a, 0x4a }, 0, .vex_128_w0, .avx },
|
||||
.{ .vblendvps, .rvmr, &.{ .ymm, .ymm, .ymm_m256, .ymm }, &.{ 0x66, 0x0f, 0x3a, 0x4a }, 0, .vex_256_w0, .avx },
|
||||
|
||||
.{ .vbroadcastss, .rm, &.{ .xmm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx },
|
||||
.{ .vbroadcastss, .rm, &.{ .ymm, .m32 }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx },
|
||||
.{ .vbroadcastsd, .rm, &.{ .ymm, .m64 }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx },
|
||||
.{ .vbroadcastf128, .rm, &.{ .ymm, .m128 }, &.{ 0x66, 0x0f, 0x38, 0x1a }, 0, .vex_256_w0, .avx },
|
||||
|
||||
.{ .vcmppd, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0xc2 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vcmppd, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0xc2 }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vcmpps, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0xc2 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vcmpps, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x0f, 0xc2 }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vcmpsd, .rvmi, &.{ .xmm, .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .vex_lig_wig, .avx },
|
||||
|
||||
.{ .vcmpss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .vex_lig_wig, .avx },
|
||||
|
||||
.{ .vcvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vcvtdq2pd, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx },
|
||||
|
||||
@ -1312,6 +1353,13 @@ pub const table = [_]Entry{
|
||||
.{ .vorps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x0f, 0x56 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vorps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x0f, 0x56 }, 0, .vex_256_wig, .avx },
|
||||
|
||||
.{ .vpacksswb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x63 }, 0, .vex_128_wig, .avx },
|
||||
.{ .vpackssdw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x6b }, 0, .vex_128_wig, .avx },
|
||||
|
||||
.{ .vpackusdw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x2b }, 0, .vex_128_wig, .avx },
|
||||
|
||||
.{ .vpackuswb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x67 }, 0, .vex_128_wig, .avx },
|
||||
|
||||
.{ .vpaddb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_128_wig, .avx },
|
||||
.{ .vpaddw, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_128_wig, .avx },
|
||||
.{ .vpaddd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_128_wig, .avx },
|
||||
@ -1474,6 +1522,13 @@ pub const table = [_]Entry{
|
||||
.{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 },
|
||||
.{ .vbroadcastsd, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x19 }, 0, .vex_256_w0, .avx2 },
|
||||
|
||||
.{ .vpacksswb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x63 }, 0, .vex_256_wig, .avx2 },
|
||||
.{ .vpackssdw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6b }, 0, .vex_256_wig, .avx2 },
|
||||
|
||||
.{ .vpackusdw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0x2b }, 0, .vex_256_wig, .avx2 },
|
||||
|
||||
.{ .vpackuswb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x67 }, 0, .vex_256_wig, .avx2 },
|
||||
|
||||
.{ .vpaddb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfc }, 0, .vex_256_wig, .avx2 },
|
||||
.{ .vpaddw, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfd }, 0, .vex_256_wig, .avx2 },
|
||||
.{ .vpaddd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xfe }, 0, .vex_256_wig, .avx2 },
|
||||
|
||||
@ -747,15 +747,23 @@ pub fn generateSymbol(
|
||||
.Vector => switch (typed_value.val.tag()) {
|
||||
.bytes => {
|
||||
const bytes = typed_value.val.castTag(.bytes).?.data;
|
||||
const len = @intCast(usize, typed_value.ty.arrayLen());
|
||||
try code.ensureUnusedCapacity(len);
|
||||
const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;
|
||||
const padding = math.cast(usize, typed_value.ty.abiSize(target) - len) orelse
|
||||
return error.Overflow;
|
||||
try code.ensureUnusedCapacity(len + padding);
|
||||
code.appendSliceAssumeCapacity(bytes[0..len]);
|
||||
if (padding > 0) try code.writer().writeByteNTimes(0, padding);
|
||||
return Result.ok;
|
||||
},
|
||||
.aggregate => {
|
||||
const elem_vals = typed_value.val.castTag(.aggregate).?.data;
|
||||
const elem_ty = typed_value.ty.elemType();
|
||||
const len = @intCast(usize, typed_value.ty.arrayLen());
|
||||
const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow;
|
||||
const padding = math.cast(usize, typed_value.ty.abiSize(target) -
|
||||
(math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {
|
||||
error.DivisionByZero => unreachable,
|
||||
else => |e| return e,
|
||||
})) orelse return error.Overflow;
|
||||
for (elem_vals[0..len]) |elem_val| {
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
.ty = elem_ty,
|
||||
@ -765,13 +773,18 @@ pub fn generateSymbol(
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
}
|
||||
if (padding > 0) try code.writer().writeByteNTimes(0, padding);
|
||||
return Result.ok;
|
||||
},
|
||||
.repeated => {
|
||||
const array = typed_value.val.castTag(.repeated).?.data;
|
||||
const elem_ty = typed_value.ty.childType();
|
||||
const len = typed_value.ty.arrayLen();
|
||||
|
||||
const padding = math.cast(usize, typed_value.ty.abiSize(target) -
|
||||
(math.divCeil(u64, elem_ty.bitSize(target) * len, 8) catch |err| switch (err) {
|
||||
error.DivisionByZero => unreachable,
|
||||
else => |e| return e,
|
||||
})) orelse return error.Overflow;
|
||||
var index: u64 = 0;
|
||||
while (index < len) : (index += 1) {
|
||||
switch (try generateSymbol(bin_file, src_loc, .{
|
||||
@ -782,13 +795,17 @@ pub fn generateSymbol(
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
}
|
||||
if (padding > 0) try code.writer().writeByteNTimes(0, padding);
|
||||
return Result.ok;
|
||||
},
|
||||
.str_lit => {
|
||||
const str_lit = typed_value.val.castTag(.str_lit).?.data;
|
||||
const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
|
||||
try code.ensureUnusedCapacity(str_lit.len);
|
||||
const padding = math.cast(usize, typed_value.ty.abiSize(target) - str_lit.len) orelse
|
||||
return error.Overflow;
|
||||
try code.ensureUnusedCapacity(str_lit.len + padding);
|
||||
code.appendSliceAssumeCapacity(bytes);
|
||||
if (padding > 0) try code.writer().writeByteNTimes(0, padding);
|
||||
return Result.ok;
|
||||
},
|
||||
else => unreachable,
|
||||
|
||||
@ -35,7 +35,6 @@ test "@bitCast iX -> uX (8, 16, 128)" {
|
||||
|
||||
test "@bitCast iX -> uX exotic integers" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -82,7 +81,6 @@ fn conv_uN(comptime N: usize, x: std.meta.Int(.unsigned, N)) std.meta.Int(.signe
|
||||
|
||||
test "bitcast uX to bytes" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -14,7 +14,6 @@ fn foo(val: U) !void {
|
||||
test "runtime union init, most-aligned field != largest" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
@ -816,7 +816,6 @@ test "array concatenation peer resolves element types - pointer" {
|
||||
|
||||
test "array concatenation sets the sentinel - value" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -855,7 +854,6 @@ test "array concatenation sets the sentinel - pointer" {
|
||||
|
||||
test "array multiplication sets the sentinel - value" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -1145,7 +1145,6 @@ test "nan negation f64" {
|
||||
|
||||
test "nan negation f128" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -783,7 +783,6 @@ test "basic @mulWithOverflow" {
|
||||
test "extensive @mulWithOverflow" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
{
|
||||
@ -1055,7 +1054,6 @@ test "@subWithOverflow" {
|
||||
test "@shlWithOverflow" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
{
|
||||
|
||||
@ -24,7 +24,8 @@ test "@max" {
|
||||
|
||||
test "@max on vectors" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -72,7 +73,8 @@ test "@min" {
|
||||
|
||||
test "@min for vectors" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64 and
|
||||
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .sse4_1)) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -5,7 +5,6 @@ const maxInt = std.math.maxInt;
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test "saturating add" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
@ -79,7 +78,6 @@ test "saturating add 128bit" {
|
||||
}
|
||||
|
||||
test "saturating subtraction" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -61,7 +61,6 @@ test "truncate on comptime integer" {
|
||||
|
||||
test "truncate on vectors" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -1142,7 +1142,6 @@ test "loading the second vector from a slice of vectors" {
|
||||
|
||||
test "array of vectors is copied" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
@ -5,7 +5,6 @@ const builtin = @import("builtin");
|
||||
const has_f80_rt = @import("builtin").cpu.arch == .x86_64;
|
||||
|
||||
test "integer widening" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user