mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
x86_64: rewrite scalar @byteSwap
This commit is contained in:
parent
cec6867d76
commit
82eedf56d7
@ -2418,7 +2418,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
}
|
||||
|
||||
fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
@setEvalBranchQuota(12_500);
|
||||
@setEvalBranchQuota(12_600);
|
||||
const pt = cg.pt;
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
@ -2477,7 +2477,6 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
|
||||
.ctz => try cg.airCtz(inst),
|
||||
.popcount => try cg.airPopCount(inst),
|
||||
.byte_swap => try cg.airByteSwap(inst),
|
||||
.bit_reverse => try cg.airBitReverse(inst),
|
||||
.splat => try cg.airSplat(inst),
|
||||
.select => try cg.airSelect(inst),
|
||||
@ -30086,6 +30085,656 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
};
|
||||
try res[0].finish(inst, &.{ty_op.operand}, &ops, cg);
|
||||
},
|
||||
.byte_swap => |air_tag| if (use_old) try cg.airByteSwap(inst) else fallback: {
|
||||
const ty_op = air_datas[@intFromEnum(inst)].ty_op;
|
||||
if (ty_op.ty.toType().isVector(zcu)) break :fallback try cg.airByteSwap(inst);
|
||||
var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
|
||||
var res: [1]Temp = undefined;
|
||||
cg.select(&res, &.{ty_op.ty.toType()}, &ops, comptime &.{ .{
|
||||
.src_constraints = .{ .{ .exact_int = 8 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mut_mem, .none, .none } },
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.each = .{ .once = &.{} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .exact_int = 16 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
|
||||
.{ ._, ._, .movbe, .dst0w, .src0w, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_int = 16 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._r, .ro, .dst0w, .ui(8), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .exact_int = 32 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0d, .src0d, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_int = 32 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0d, ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .signed_int = .dword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0d, .src0d, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .dword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0d, ._, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .dword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0d, .src0d, ._, ._ },
|
||||
.{ ._, ._r, .sh, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .dword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0d, ._, ._, ._ },
|
||||
.{ ._, ._r, .sh, .dst0d, .uia(32, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .exact_int = 64 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0q, .src0q, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .exact_int = 64 }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0q, ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .signed_int = .qword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0q, .src0q, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .signed_int = .qword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0q, ._, ._, ._ },
|
||||
.{ ._, ._r, .sa, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .movbe, null, null, null },
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .mem, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .rc = .general_purpose }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .movbe, .dst0q, .src0q, ._, ._ },
|
||||
.{ ._, ._r, .sh, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.src_constraints = .{ .{ .unsigned_int = .qword }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mut_gpr, .none, .none } },
|
||||
},
|
||||
.dst_temps = .{ .{ .ref = .src0 }, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .bswap, .dst0q, ._, ._, ._ },
|
||||
.{ ._, ._r, .sh, .dst0q, .uia(64, .src0, .sub_bit_size), ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .movbe, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp2q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .movbe, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp2q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .movbe, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .exact_remainder_unsigned_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .si(0), ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp2q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp2q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp2q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .movbe, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp3q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .movbe, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .xword, .is = .qword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-16, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
|
||||
.{ ._, ._, .mov, .memad(.dst0q, .add_size, -8), .tmp2q, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp3q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ .@"0:", ._, .movbe, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .remainder_signed_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .movsx, .tmp2q, .mem(.src0b), ._, ._ },
|
||||
.{ ._, ._r, .sa, .tmp2q, .ui(63), ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp3q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", .movbe, null, null },
|
||||
.src_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
|
||||
.{ .@"0:", ._, .movbe, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
}, .{
|
||||
.required_features = .{ .@"64bit", null, null, null },
|
||||
.src_constraints = .{ .{ .remainder_unsigned_int = .{ .of = .xword, .is = .xword } }, .any, .any },
|
||||
.patterns = &.{
|
||||
.{ .src = .{ .to_mem, .none, .none } },
|
||||
},
|
||||
.extra_temps = .{
|
||||
.{ .type = .usize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .isize, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.{ .type = .u64, .kind = .{ .rc = .general_purpose } },
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
.unused,
|
||||
},
|
||||
.dst_temps = .{ .mem, .unused },
|
||||
.clobbers = .{ .eflags = true },
|
||||
.each = .{ .once = &.{
|
||||
.{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
|
||||
.{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
|
||||
.{ .@"0:", ._, .mov, .tmp3q, .lea(.tmp1q), ._, ._ },
|
||||
.{ ._, ._, .bswap, .tmp3q, ._, ._, ._ },
|
||||
.{ ._, ._, .mov, .tmp4q, .tmp3q, ._, ._ },
|
||||
.{ ._, ._rd, .sh, .tmp3q, .tmp2q, .uia(64, .src0, .sub_bit_size_rem_64), ._ },
|
||||
.{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
|
||||
.{ ._, ._, .mov, .memi(.dst0q, .tmp0), .tmp3q, ._, ._ },
|
||||
.{ ._, ._, .lea, .tmp1p, .lead(.tmp1, 8), ._, ._ },
|
||||
.{ ._, ._, .sub, .tmp0d, .si(8), ._, ._ },
|
||||
.{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
|
||||
} },
|
||||
} }) catch |err| switch (err) {
|
||||
error.SelectFailed => return cg.fail("failed to select {s} {} {}", .{
|
||||
@tagName(air_tag),
|
||||
ty_op.ty.toType().fmt(pt),
|
||||
ops[0].tracking(cg),
|
||||
}),
|
||||
else => |e| return e,
|
||||
};
|
||||
try res[0].finish(inst, &.{ty_op.operand}, &ops, cg);
|
||||
},
|
||||
|
||||
.cmp_vector, .cmp_vector_optimized => |air_tag| if (use_old) try cg.airCmpVector(inst) else fallback: {
|
||||
const ty_pl = air_datas[@intFromEnum(inst)].ty_pl;
|
||||
|
||||
@ -55,6 +55,17 @@ fn DoubleBits(comptime Type: type) type {
|
||||
.vector => |vector| @Vector(vector.len, ResultScalar),
|
||||
};
|
||||
}
|
||||
fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type {
|
||||
const ResultScalar = switch (@typeInfo(Scalar(Type))) {
|
||||
.int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = std.mem.alignForward(u16, int.bits, multiple) } }),
|
||||
.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)) {
|
||||
@ -19262,6 +19273,14 @@ test clz {
|
||||
try test_clz.testIntVectors();
|
||||
}
|
||||
|
||||
inline fn byteSwap(comptime Type: type, rhs: Type) RoundBitsUp(Type, 8) {
|
||||
return @byteSwap(@as(RoundBitsUp(Type, 8), rhs));
|
||||
}
|
||||
test byteSwap {
|
||||
const test_byte_swap = unary(byteSwap, .{});
|
||||
try test_byte_swap.testInts();
|
||||
}
|
||||
|
||||
inline fn sqrt(comptime Type: type, rhs: Type) @TypeOf(@sqrt(rhs)) {
|
||||
return @sqrt(rhs);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user