authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-09 13:38:25-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-16 20:47:30-05:00
logc3d33440f0e68f114996dc74ec15e2b9514c4b3e
tree9b95e20199459b4d93aa660f7dd03151ba487f0a
parent666d76d85c1dc2f107d0a57b424983082672943e

x86_64: pass more behavior tests


7 files changed, 343 insertions(+), 348 deletions(-)

src/arch/x86_64/CodeGen.zig+339-338
...@@ -8998,7 +8998,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -8998,7 +8998,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8998 }) else fallback: {8998 }) else fallback: {
8999 const bin_op = air_datas[@intFromEnum(inst)].bin_op;8999 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
9000 const scalar_ty = cg.typeOf(bin_op.lhs).scalarType(zcu);9000 const scalar_ty = cg.typeOf(bin_op.lhs).scalarType(zcu);
9001 if (scalar_ty.isRuntimeFloat() or ip.isOptionalType(scalar_ty.toIntern())) break :fallback try cg.airCmp(inst, switch (air_tag) {9001 if (intInfo(scalar_ty, cg) == null) break :fallback try cg.airCmp(inst, switch (air_tag) {
9002 else => unreachable,9002 else => unreachable,
9003 .cmp_eq, .cmp_eq_optimized => .eq,9003 .cmp_eq, .cmp_eq_optimized => .eq,
9004 .cmp_neq, .cmp_neq_optimized => .neq,9004 .cmp_neq, .cmp_neq_optimized => .neq,
...@@ -9012,38 +9012,81 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -9012,38 +9012,81 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9012 })) {9012 })) {
9013 else => unreachable,9013 else => unreachable,
9014 inline .e, .ne => |cc| comptime &.{ .{9014 inline .e, .ne => |cc| comptime &.{ .{
9015 .required_features = .{ .avx2, null, null, null },9015 .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } },
9016 .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } },
9017 .patterns = &.{9016 .patterns = &.{
9018 .{ .src = .{ .to_ymm, .mem } },9017 .{ .src = .{ .mem, .imm8 } },
9019 .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } },9018 .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } },
9020 .{ .src = .{ .to_ymm, .to_ymm } },9019 .{ .src = .{ .to_gpr, .imm8 } },
9020 .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } },
9021 .{ .src = .{ .to_gpr, .mem } },
9022 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9023 .{ .src = .{ .to_gpr, .to_gpr } },
9021 },9024 },
9022 .extra_temps = .{9025 .dst_temps = .{.{ .cc = cc }},
9023 .{ .kind = .{ .rc = .sse } },9026 .clobbers = .{ .eflags = true },
9024 .unused,9027 .each = .{ .once = &.{
9025 .unused,9028 .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ },
9026 .unused,9029 } },
9027 .unused,9030 }, .{
9028 .unused,9031 .src_constraints = .{ .{ .int = .word }, .{ .int = .word } },
9032 .patterns = &.{
9033 .{ .src = .{ .mem, .imm16 } },
9034 .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } },
9035 .{ .src = .{ .to_gpr, .imm16 } },
9036 .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } },
9037 .{ .src = .{ .to_gpr, .mem } },
9038 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9039 .{ .src = .{ .to_gpr, .to_gpr } },
9029 },9040 },
9030 .dst_temps = .{.{ .cc = cc }},9041 .dst_temps = .{.{ .cc = cc }},
9031 .clobbers = .{ .eflags = true },9042 .clobbers = .{ .eflags = true },
9032 .each = .{ .once = &.{9043 .each = .{ .once = &.{
9033 .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ },9044 .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ },
9034 .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ },
9035 } },9045 } },
9036 }, .{9046 }, .{
9037 .required_features = .{ .avx, null, null, null },9047 .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } },
9038 .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } },
9039 .patterns = &.{9048 .patterns = &.{
9040 .{ .src = .{ .to_ymm, .mem } },9049 .{ .src = .{ .mem, .imm32 } },
9041 .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } },9050 .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } },
9042 .{ .src = .{ .to_ymm, .to_ymm } },9051 .{ .src = .{ .to_gpr, .imm32 } },
9052 .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } },
9053 .{ .src = .{ .to_gpr, .mem } },
9054 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9055 .{ .src = .{ .to_gpr, .to_gpr } },
9056 },
9057 .dst_temps = .{.{ .cc = cc }},
9058 .clobbers = .{ .eflags = true },
9059 .each = .{ .once = &.{
9060 .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ },
9061 } },
9062 }, .{
9063 .required_features = .{ .@"64bit", null, null, null },
9064 .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } },
9065 .patterns = &.{
9066 .{ .src = .{ .mem, .simm32 } },
9067 .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } },
9068 .{ .src = .{ .to_gpr, .simm32 } },
9069 .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } },
9070 .{ .src = .{ .to_gpr, .mem } },
9071 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9072 .{ .src = .{ .to_gpr, .to_gpr } },
9073 },
9074 .dst_temps = .{.{ .cc = cc }},
9075 .clobbers = .{ .eflags = true },
9076 .each = .{ .once = &.{
9077 .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ },
9078 } },
9079 }, .{
9080 .required_features = .{ .sse, .mmx, null, null },
9081 .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } },
9082 .patterns = &.{
9083 .{ .src = .{ .to_mut_mm, .mem } },
9084 .{ .src = .{ .mem, .to_mut_mm }, .commute = .{ 0, 1 } },
9085 .{ .src = .{ .to_mut_mm, .to_mm } },
9043 },9086 },
9044 .extra_temps = .{9087 .extra_temps = .{
9045 .{ .kind = .{ .rc = .sse } },9088 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },
9046 .unused,9089 .{ .kind = .{ .rc = .mmx } },
9047 .unused,9090 .unused,
9048 .unused,9091 .unused,
9049 .unused,9092 .unused,
...@@ -9052,8 +9095,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -9052,8 +9095,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9052 .dst_temps = .{.{ .cc = cc }},9095 .dst_temps = .{.{ .cc = cc }},
9053 .clobbers = .{ .eflags = true },9096 .clobbers = .{ .eflags = true },
9054 .each = .{ .once = &.{9097 .each = .{ .once = &.{
9055 .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ },9098 .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ },
9056 .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ },9099 .{ ._, .p_, .xor, .src0q, .src1q, ._, ._ },
9100 .{ ._, .p_b, .cmpeq, .tmp1q, .src0q, ._, ._ },
9101 .{ ._, .p_b, .movmsk, .tmp0d, .tmp1q, ._, ._ },
9102 .{ ._, ._, .xor, .tmp0d, .si(0xff), ._, ._ },
9057 } },9103 } },
9058 }, .{9104 }, .{
9059 .required_features = .{ .avx, null, null, null },9105 .required_features = .{ .avx, null, null, null },
...@@ -9117,16 +9163,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -9117,16 +9163,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9117 .{ ._, ._, .xor, .tmp0d, .si(0xffff), ._, ._ },9163 .{ ._, ._, .xor, .tmp0d, .si(0xffff), ._, ._ },
9118 } },9164 } },
9119 }, .{9165 }, .{
9120 .required_features = .{ .sse, .mmx, null, null },9166 .required_features = .{ .avx2, null, null, null },
9121 .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } },9167 .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } },
9122 .patterns = &.{9168 .patterns = &.{
9123 .{ .src = .{ .to_mut_mm, .mem } },9169 .{ .src = .{ .to_ymm, .mem } },
9124 .{ .src = .{ .mem, .to_mut_mm }, .commute = .{ 0, 1 } },9170 .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } },
9125 .{ .src = .{ .to_mut_mm, .to_mm } },9171 .{ .src = .{ .to_ymm, .to_ymm } },
9126 },9172 },
9127 .extra_temps = .{9173 .extra_temps = .{
9128 .{ .type = .u32, .kind = .{ .rc = .general_purpose } },9174 .{ .kind = .{ .rc = .sse } },
9129 .{ .kind = .{ .rc = .mmx } },9175 .unused,
9130 .unused,9176 .unused,
9131 .unused,9177 .unused,
9132 .unused,9178 .unused,
...@@ -9135,76 +9181,30 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -9135,76 +9181,30 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9135 .dst_temps = .{.{ .cc = cc }},9181 .dst_temps = .{.{ .cc = cc }},
9136 .clobbers = .{ .eflags = true },9182 .clobbers = .{ .eflags = true },
9137 .each = .{ .once = &.{9183 .each = .{ .once = &.{
9138 .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ },9184 .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ },
9139 .{ ._, .p_, .xor, .src0q, .src1q, ._, ._ },9185 .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ },
9140 .{ ._, .p_b, .cmpeq, .tmp1q, .src0q, ._, ._ },
9141 .{ ._, .p_b, .movmsk, .tmp0d, .tmp1q, ._, ._ },
9142 .{ ._, ._, .xor, .tmp0d, .si(0xff), ._, ._ },
9143 } },
9144 }, .{
9145 .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } },
9146 .patterns = &.{
9147 .{ .src = .{ .mem, .imm8 } },
9148 .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } },
9149 .{ .src = .{ .to_gpr, .imm8 } },
9150 .{ .src = .{ .imm8, .to_gpr }, .commute = .{ 0, 1 } },
9151 .{ .src = .{ .to_gpr, .mem } },
9152 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9153 .{ .src = .{ .to_gpr, .to_gpr } },
9154 },
9155 .dst_temps = .{.{ .cc = cc }},
9156 .clobbers = .{ .eflags = true },
9157 .each = .{ .once = &.{
9158 .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ },
9159 } },
9160 }, .{
9161 .src_constraints = .{ .{ .int = .word }, .{ .int = .word } },
9162 .patterns = &.{
9163 .{ .src = .{ .mem, .imm16 } },
9164 .{ .src = .{ .imm16, .mem }, .commute = .{ 0, 1 } },
9165 .{ .src = .{ .to_gpr, .imm16 } },
9166 .{ .src = .{ .imm16, .to_gpr }, .commute = .{ 0, 1 } },
9167 .{ .src = .{ .to_gpr, .mem } },
9168 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9169 .{ .src = .{ .to_gpr, .to_gpr } },
9170 },
9171 .dst_temps = .{.{ .cc = cc }},
9172 .clobbers = .{ .eflags = true },
9173 .each = .{ .once = &.{
9174 .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ },
9175 } },9186 } },
9176 }, .{9187 }, .{
9177 .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } },9188 .required_features = .{ .avx, null, null, null },
9189 .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } },
9178 .patterns = &.{9190 .patterns = &.{
9179 .{ .src = .{ .mem, .imm32 } },9191 .{ .src = .{ .to_ymm, .mem } },
9180 .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } },9192 .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } },
9181 .{ .src = .{ .to_gpr, .imm32 } },9193 .{ .src = .{ .to_ymm, .to_ymm } },
9182 .{ .src = .{ .imm32, .to_gpr }, .commute = .{ 0, 1 } },
9183 .{ .src = .{ .to_gpr, .mem } },
9184 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9185 .{ .src = .{ .to_gpr, .to_gpr } },
9186 },9194 },
9187 .dst_temps = .{.{ .cc = cc }},9195 .extra_temps = .{
9188 .clobbers = .{ .eflags = true },9196 .{ .kind = .{ .rc = .sse } },
9189 .each = .{ .once = &.{9197 .unused,
9190 .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ },9198 .unused,
9191 } },9199 .unused,
9192 }, .{9200 .unused,
9193 .required_features = .{ .@"64bit", null, null, null },9201 .unused,
9194 .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } },
9195 .patterns = &.{
9196 .{ .src = .{ .mem, .simm32 } },
9197 .{ .src = .{ .simm32, .mem }, .commute = .{ 0, 1 } },
9198 .{ .src = .{ .to_gpr, .simm32 } },
9199 .{ .src = .{ .simm32, .to_gpr }, .commute = .{ 0, 1 } },
9200 .{ .src = .{ .to_gpr, .mem } },
9201 .{ .src = .{ .mem, .to_gpr }, .commute = .{ 0, 1 } },
9202 .{ .src = .{ .to_gpr, .to_gpr } },
9203 },9202 },
9204 .dst_temps = .{.{ .cc = cc }},9203 .dst_temps = .{.{ .cc = cc }},
9205 .clobbers = .{ .eflags = true },9204 .clobbers = .{ .eflags = true },
9206 .each = .{ .once = &.{9205 .each = .{ .once = &.{
9207 .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ },9206 .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ },
9207 .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ },
9208 } },9208 } },
9209 }, .{9209 }, .{
9210 .required_features = .{ .avx2, null, null, null },9210 .required_features = .{ .avx2, null, null, null },
...@@ -19540,10 +19540,19 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -19540,10 +19540,19 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
19540 .air_ref,19540 .air_ref,
19541 => unreachable, // unmodifiable destination19541 => unreachable, // unmodifiable destination
19542 .register => |dst_reg| {19542 .register => |dst_reg| {
19543 const dst_alias = registerAlias(dst_reg, abi_size);19543 const alias_size = switch (abi_size) {
19544 1 => 4,
19545 else => abi_size,
19546 };
19547 const dst_alias = registerAlias(dst_reg, alias_size);
19544 const dst_lock = self.register_manager.lockReg(dst_reg);19548 const dst_lock = self.register_manager.lockReg(dst_reg);
19545 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);19549 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
1954619550
19551 switch (abi_size) {
19552 1 => try self.asmRegisterRegister(.{ ._, .movzx }, dst_reg.to32(), dst_reg.to8()),
19553 else => {},
19554 }
19555
19547 const resolved_src_mcv = switch (src_mcv) {19556 const resolved_src_mcv = switch (src_mcv) {
19548 else => src_mcv,19557 else => src_mcv,
19549 .air_ref => |src_ref| try self.resolveInst(src_ref),19558 .air_ref => |src_ref| try self.resolveInst(src_ref),
...@@ -19562,19 +19571,20 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -19562,19 +19571,20 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
19562 .reserved_frame,19571 .reserved_frame,
19563 .air_ref,19572 .air_ref,
19564 => unreachable,19573 => unreachable,
19565 .register => |src_reg| try self.asmRegisterRegister(19574 .register => |src_reg| {
19566 .{ .i_, .mul },19575 switch (abi_size) {
19567 dst_alias,19576 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()),
19568 registerAlias(src_reg, abi_size),19577 else => {},
19569 ),19578 }
19579 try self.asmRegisterRegister(
19580 .{ .i_, .mul },
19581 dst_alias,
19582 registerAlias(src_reg, alias_size),
19583 );
19584 },
19570 .immediate => |imm| {19585 .immediate => |imm| {
19571 if (std.math.cast(i32, imm)) |small| {19586 if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |small| {
19572 try self.asmRegisterRegisterImmediate(19587 try self.asmRegisterRegisterImmediate(.{ .i_, .mul }, dst_alias, dst_alias, .s(small));
19573 .{ .i_, .mul },
19574 dst_alias,
19575 dst_alias,
19576 .s(small),
19577 );
19578 } else {19588 } else {
19579 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);19589 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
19580 return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg });19590 return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg });
...@@ -19591,47 +19601,57 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -19591,47 +19601,57 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
19591 .load_tlv,19601 .load_tlv,
19592 .lea_tlv,19602 .lea_tlv,
19593 .lea_frame,19603 .lea_frame,
19594 => try self.asmRegisterRegister(19604 => {
19595 .{ .i_, .mul },19605 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
19596 dst_alias,19606 switch (abi_size) {
19597 registerAlias(try self.copyToTmpRegister(dst_ty, resolved_src_mcv), abi_size),19607 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()),
19598 ),19608 else => {},
19599 .memory, .indirect, .load_frame => try self.asmRegisterMemory(19609 }
19600 .{ .i_, .mul },19610 try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size));
19601 dst_alias,19611 },
19602 switch (resolved_src_mcv) {19612 .memory, .indirect, .load_frame => switch (abi_size) {
19603 .memory => |addr| .{19613 1 => {
19604 .base = .{ .reg = .ds },19614 const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv);
19605 .mod = .{ .rm = .{19615 try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8());
19606 .size = .fromSize(abi_size),19616 try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size));
19607 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse19617 },
19608 return self.asmRegisterRegister(19618 else => try self.asmRegisterMemory(
19609 .{ .i_, .mul },19619 .{ .i_, .mul },
19610 dst_alias,19620 dst_alias,
19611 registerAlias(19621 switch (resolved_src_mcv) {
19612 try self.copyToTmpRegister(dst_ty, resolved_src_mcv),19622 .memory => |addr| .{
19613 abi_size,19623 .base = .{ .reg = .ds },
19624 .mod = .{ .rm = .{
19625 .size = .fromSize(abi_size),
19626 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
19627 return self.asmRegisterRegister(
19628 .{ .i_, .mul },
19629 dst_alias,
19630 registerAlias(
19631 try self.copyToTmpRegister(dst_ty, resolved_src_mcv),
19632 abi_size,
19633 ),
19614 ),19634 ),
19615 ),19635 } },
19616 } },19636 },
19617 },19637 .indirect => |reg_off| .{
19618 .indirect => |reg_off| .{19638 .base = .{ .reg = reg_off.reg },
19619 .base = .{ .reg = reg_off.reg },19639 .mod = .{ .rm = .{
19620 .mod = .{ .rm = .{19640 .size = .fromSize(abi_size),
19621 .size = .fromSize(abi_size),19641 .disp = reg_off.off,
19622 .disp = reg_off.off,19642 } },
19623 } },19643 },
19624 },19644 .load_frame => |frame_addr| .{
19625 .load_frame => |frame_addr| .{19645 .base = .{ .frame = frame_addr.index },
19626 .base = .{ .frame = frame_addr.index },19646 .mod = .{ .rm = .{
19627 .mod = .{ .rm = .{19647 .size = .fromSize(abi_size),
19628 .size = .fromSize(abi_size),19648 .disp = frame_addr.off,
19629 .disp = frame_addr.off,19649 } },
19630 } },19650 },
19651 else => unreachable,
19631 },19652 },
19632 else => unreachable,19653 ),
19633 },19654 },
19634 ),
19635 }19655 }
19636 },19656 },
19637 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented19657 .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented
...@@ -27952,6 +27972,75 @@ fn promoteVarArg(self: *CodeGen, ty: Type) Type {...@@ -27952,6 +27972,75 @@ fn promoteVarArg(self: *CodeGen, ty: Type) Type {
27952 }27972 }
27953}27973}
2795427974
27975fn intInfo(ty: Type, cg: *CodeGen) ?std.builtin.Type.Int {
27976 const zcu = cg.pt.zcu;
27977 const ip = &zcu.intern_pool;
27978 var ty_index = ty.ip_index;
27979 while (true) switch (ip.indexToKey(ty_index)) {
27980 .int_type => |int_type| return int_type,
27981 .ptr_type => |ptr_type| return switch (ptr_type.flags.size) {
27982 .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
27983 .slice => null,
27984 },
27985 .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBitsIgnoreComptime(zcu))
27986 .{ .signedness = .unsigned, .bits = 1 }
27987 else switch (ip.indexToKey(opt_child)) {
27988 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
27989 .one, .many => switch (ptr_type.flags.is_allowzero) {
27990 false => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
27991 true => null,
27992 },
27993 .slice, .c => null,
27994 },
27995 else => null,
27996 },
27997 .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type)
27998 .hasRuntimeBitsIgnoreComptime(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null,
27999 .simple_type => |simple_type| return switch (simple_type) {
28000 .bool => .{ .signedness = .unsigned, .bits = 1 },
28001 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
28002 .isize => .{ .signedness = .signed, .bits = cg.target.ptrBitWidth() },
28003 .usize => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
28004 .c_char => .{ .signedness = cg.target.charSignedness(), .bits = cg.target.cTypeBitSize(.char) },
28005 .c_short => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.short) },
28006 .c_ushort => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.short) },
28007 .c_int => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.int) },
28008 .c_uint => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.int) },
28009 .c_long => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.long) },
28010 .c_ulong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.long) },
28011 .c_longlong => .{ .signedness = .signed, .bits = cg.target.cTypeBitSize(.longlong) },
28012 .c_ulonglong => .{ .signedness = .unsigned, .bits = cg.target.cTypeBitSize(.longlong) },
28013 .f16, .f32, .f64, .f80, .f128, .c_longdouble => null,
28014 .anyopaque,
28015 .void,
28016 .type,
28017 .comptime_int,
28018 .comptime_float,
28019 .noreturn,
28020 .null,
28021 .undefined,
28022 .enum_literal,
28023 .adhoc_inferred_error_set,
28024 .generic_poison,
28025 => unreachable,
28026 },
28027 .struct_type => {
28028 const loaded_struct = ip.loadStructType(ty_index);
28029 switch (loaded_struct.layout) {
28030 .auto, .@"extern" => return null,
28031 .@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip),
28032 }
28033 },
28034 .union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) {
28035 .auto, .@"extern" => null,
28036 .@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) },
28037 },
28038 .enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty,
28039 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
28040 else => return null,
28041 };
28042}
28043
27955const Temp = struct {28044const Temp = struct {
27956 index: Air.Inst.Index,28045 index: Air.Inst.Index,
2795728046
...@@ -29061,197 +29150,112 @@ const Select = struct {...@@ -29061,197 +29150,112 @@ const Select = struct {
2906129150
29062 fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool {29151 fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool {
29063 const zcu = cg.pt.zcu;29152 const zcu = cg.pt.zcu;
29064 switch (constraint) {29153 return switch (constraint) {
29065 .any => return true,29154 .any => true,
29066 .any_bool_vec => return ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type,29155 .any_bool_vec => ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type,
29067 .any_int => return ty.toIntern() == .bool_type or ty.isPtrAtRuntime(zcu) or ty.isAbiInt(zcu),29156 .any_int => intInfo(ty, cg) != null,
29068 .any_signed_int => return ty.isAbiInt(zcu) and ty.intInfo(zcu).signedness == .signed,29157 .any_signed_int => if (intInfo(ty, cg)) |int_info| int_info.signedness == .signed else false,
29069 .any_float => return ty.isRuntimeFloat(),29158 .any_float => ty.isRuntimeFloat(),
29070 .po2_any => return std.math.isPowerOfTwo(ty.abiSize(zcu)),29159 .po2_any => std.math.isPowerOfTwo(ty.abiSize(zcu)),
29071 .bool_vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and29160 .bool_vec => |size| ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and
29072 size.bitSize(cg.target) >= ty.vectorLen(zcu),29161 size.bitSize(cg.target) >= ty.vectorLen(zcu),
29073 .vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and29162 .vec => |size| ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and
29074 size.bitSize(cg.target) >= ty.abiSize(zcu),29163 size.bitSize(cg.target) >= ty.abiSize(zcu),
29075 .signed_int_vec => |size| {29164 .signed_int_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and
29076 if (!ty.isVector(zcu) or size.bitSize(cg.target) < 8 * ty.abiSize(zcu)) return false;29165 if (intInfo(ty.childType(zcu), cg)) |int_info| int_info.signedness == .signed else false,
29077 const scalar_ty = ty.scalarType(zcu);29166 .signed_int_or_full_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and
29078 return scalar_ty.isAbiInt(zcu) and scalar_ty.intInfo(zcu).signedness == .signed;29167 if (intInfo(ty.childType(zcu), cg)) |int_info| switch (int_info.signedness) {
29079 },29168 .signed => true,
29080 .signed_int_or_full_vec => |size| {29169 .unsigned => int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits),
29081 if (!ty.isVector(zcu) or size.bitSize(cg.target) < 8 * ty.abiSize(zcu)) return false;29170 } else false,
29082 const scalar_ty = ty.scalarType(zcu);29171 .unsigned_int_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and
29083 if (scalar_ty.isPtrAtRuntime(zcu)) return true;29172 if (intInfo(ty.childType(zcu), cg)) |int_info| int_info.signedness == .unsigned else false,
29084 if (!scalar_ty.isAbiInt(zcu)) return false;29173 .int_or_vec => |size| if (intInfo(ty, cg)) |int_info|
29085 const scalar_int_info = scalar_ty.intInfo(zcu);29174 size.bitSize(cg.target) >= int_info.bits
29086 return switch (scalar_int_info.signedness) {29175 else
29087 .signed => true,29176 ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu),
29088 .unsigned => scalar_int_info.bits >= 8 and std.math.isPowerOfTwo(scalar_int_info.bits),29177 .exact_remainder_int_or_vec => |of_is| if (intInfo(ty, cg)) |int_info|
29089 };29178 of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1
29090 },29179 else
29091 .unsigned_int_vec => |size| {29180 ty.isVector(zcu) and ty.childType(zcu).toIntern() != .bool_type and
29092 if (!ty.isVector(zcu) or size.bitSize(cg.target) < ty.bitSize(zcu)) return false;29181 of_is.is.bitSize(cg.target) == (8 * ty.abiSize(zcu) - 1) % of_is.of.bitSize(cg.target) + 1,
29093 const scalar_ty = ty.scalarType(zcu);29182 .int => |size| if (intInfo(ty, cg)) |int_info| size.bitSize(cg.target) >= int_info.bits else false,
29094 if (scalar_ty.isPtrAtRuntime(zcu)) return true;29183 .scalar_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info|
29095 return scalar_ty.isAbiInt(zcu) and scalar_ty.intInfo(zcu).signedness == .unsigned;29184 size.bitSize(cg.target) >= int_info.bits
29096 },29185 else
29097 .int_or_vec => |size| {29186 false,
29098 if (ty.isVector(zcu)) return ty.scalarType(zcu).toIntern() != .bool_type and29187 .scalar_signed_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info| switch (int_info.signedness) {
29099 size.bitSize(cg.target) >= 8 * ty.abiSize(zcu);29188 .signed => size.bitSize(cg.target) >= int_info.bits,
29100 if (ty.toIntern() == .bool_type) return true;29189 .unsigned => false,
29101 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();29190 } else false,
29102 return ty.isAbiInt(zcu) and size.bitSize(cg.target) >= ty.intInfo(zcu).bits;29191 .scalar_unsigned_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info| switch (int_info.signedness) {
29103 },29192 .signed => false,
29104 .exact_remainder_int_or_vec => |of_is| {29193 .unsigned => size.bitSize(cg.target) >= int_info.bits,
29105 if (ty.isVector(zcu)) return ty.scalarType(zcu).toIntern() != .bool_type and29194 } else false,
29106 of_is.is.bitSize(cg.target) == (8 * ty.abiSize(zcu) - 1) % of_is.of.bitSize(cg.target) + 1;29195 .scalar_remainder_int => |of_is| if (intInfo(ty.scalarType(zcu), cg)) |int_info|
29107 if (ty.isPtrAtRuntime(zcu))29196 of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1
29108 return of_is.is.bitSize(cg.target) == (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;29197 else
29109 if (!ty.isAbiInt(zcu)) return false;29198 false,
29110 return of_is.is.bitSize(cg.target) == (ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1;29199 .exact_int => |bit_size| if (intInfo(ty, cg)) |int_info| bit_size == int_info.bits else false,
29111 },29200 .exact_signed_int => |bit_size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29112 .int => |size| {29201 .signed => bit_size == int_info.bits,
29113 if (ty.toIntern() == .bool_type) return true;29202 .unsigned => false,
29114 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();29203 } else false,
29115 return ty.isAbiInt(zcu) and size.bitSize(cg.target) >= ty.intInfo(zcu).bits;29204 .exact_unsigned_int => |bit_size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29116 },29205 .signed => false,
29117 .scalar_int => |size| {29206 .unsigned => bit_size == int_info.bits,
29118 const scalar_ty = ty.scalarType(zcu);29207 } else false,
29119 if (scalar_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();29208 .signed_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29120 return scalar_ty.isAbiInt(zcu) and size.bitSize(cg.target) >= scalar_ty.intInfo(zcu).bits;29209 .signed => size.bitSize(cg.target) >= int_info.bits,
29121 },29210 .unsigned => size.bitSize(cg.target) == int_info.bits,
29122 .scalar_signed_int => |size| {29211 } else false,
29123 const scalar_ty = ty.scalarType(zcu);29212 .unsigned_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29124 if (!scalar_ty.isAbiInt(zcu)) return false;29213 .signed => size.bitSize(cg.target) == int_info.bits,
29125 const scalar_int_info = scalar_ty.intInfo(zcu);29214 .unsigned => size.bitSize(cg.target) >= int_info.bits,
29126 return scalar_int_info.signedness == .signed and size.bitSize(cg.target) >= scalar_int_info.bits;29215 } else false,
29127 },29216 .po2_int => |size| if (intInfo(ty, cg)) |int_info|
29128 .scalar_unsigned_int => |size| {29217 std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits
29129 const scalar_ty = ty.scalarType(zcu);29218 else
29130 if (scalar_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();29219 false,
29131 if (!scalar_ty.isAbiInt(zcu)) return false;29220 .signed_po2_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29132 const scalar_int_info = scalar_ty.intInfo(zcu);29221 .signed => std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits,
29133 return scalar_int_info.signedness == .unsigned and size.bitSize(cg.target) >= scalar_int_info.bits;29222 .unsigned => false,
29134 },29223 } else false,
29135 .scalar_remainder_int => |of_is| {29224 .unsigned_po2_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29136 const scalar_ty = ty.scalarType(zcu);29225 .signed => size.bitSize(cg.target) == int_info.bits,
29137 if (scalar_ty.isPtrAtRuntime(zcu))29226 .unsigned => std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits,
29138 return of_is.is.bitSize(cg.target) >= (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;29227 } else false,
29139 if (!scalar_ty.isAbiInt(zcu)) return false;29228 .remainder_int => |of_is| if (intInfo(ty, cg)) |int_info|
29140 return of_is.is.bitSize(cg.target) >= (scalar_ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1;29229 of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1
29141 },29230 else
29142 .exact_int => |bit_size| {29231 false,
29143 if (ty.toIntern() == .bool_type) return bit_size == 1;29232 .exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info|
29144 if (ty.isPtrAtRuntime(zcu)) return bit_size == cg.target.ptrBitWidth();29233 of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1
29145 return ty.isAbiInt(zcu) and bit_size == ty.intInfo(zcu).bits;29234 else
29146 },29235 false,
29147 .exact_signed_int => |bit_size| {29236 .signed_or_exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29148 if (!ty.isAbiInt(zcu)) return false;29237 .signed => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29149 const int_info = ty.intInfo(zcu);29238 .unsigned => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29150 return int_info.signedness == .signed and bit_size == int_info.bits;29239 } else false,
29151 },29240 .unsigned_or_exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29152 .exact_unsigned_int => |bit_size| {29241 .signed => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29153 if (ty.toIntern() == .bool_type) return bit_size == 1;29242 .unsigned => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29154 if (ty.isPtrAtRuntime(zcu)) return bit_size == cg.target.ptrBitWidth();29243 } else false,
29155 if (!ty.isAbiInt(zcu)) return false;29244 .signed_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29156 const int_info = ty.intInfo(zcu);29245 .signed => size.bitSize(cg.target) >= int_info.bits,
29157 return int_info.signedness == .unsigned and bit_size == int_info.bits;29246 .unsigned => false,
29158 },29247 } else false,
29159 .signed_or_exact_int => |size| {29248 .unsigned_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) {
29160 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) == cg.target.ptrBitWidth();29249 .signed => false,
29161 if (!ty.isAbiInt(zcu)) return false;29250 .unsigned => size.bitSize(cg.target) >= int_info.bits,
29162 const int_info = ty.intInfo(zcu);29251 } else false,
29163 return switch (int_info.signedness) {29252 .elem_size_is => |size| size == ty.elemType2(zcu).abiSize(zcu),
29164 .signed => size.bitSize(cg.target) >= int_info.bits,29253 .po2_elem_size => std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)),
29165 .unsigned => size.bitSize(cg.target) == int_info.bits,29254 .elem_int => |size| if (intInfo(ty.elemType2(zcu), cg)) |elem_int_info|
29166 };29255 size.bitSize(cg.target) >= elem_int_info.bits
29167 },29256 else
29168 .unsigned_or_exact_int => |size| {29257 false,
29169 if (ty.toIntern() == .bool_type or ty.isPtrAtRuntime(zcu)) return true;29258 };
29170 if (!ty.isAbiInt(zcu)) return false;
29171 const int_info = ty.intInfo(zcu);
29172 return switch (int_info.signedness) {
29173 .signed => size.bitSize(cg.target) == int_info.bits,
29174 .unsigned => size.bitSize(cg.target) >= int_info.bits,
29175 };
29176 },
29177 .po2_int => |size| {
29178 if (ty.toIntern() == .bool_type) return true;
29179 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();
29180 if (!ty.isAbiInt(zcu)) return false;
29181 const bit_size = ty.intInfo(zcu).bits;
29182 return std.math.isPowerOfTwo(bit_size) and size.bitSize(cg.target) >= bit_size;
29183 },
29184 .signed_po2_int => |size| {
29185 if (!ty.isAbiInt(zcu)) return false;
29186 const int_info = ty.intInfo(zcu);
29187 return int_info.signedness == .signed and std.math.isPowerOfTwo(int_info.bits) and
29188 size.bitSize(cg.target) >= int_info.bits;
29189 },
29190 .unsigned_po2_or_exact_int => |size| {
29191 if (ty.toIntern() == .bool_type) return true;
29192 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();
29193 if (!ty.isAbiInt(zcu)) return false;
29194 const int_info = ty.intInfo(zcu);
29195 return switch (int_info.signedness) {
29196 .signed => size.bitSize(cg.target) == int_info.bits,
29197 .unsigned => std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits,
29198 };
29199 },
29200 .remainder_int => |of_is| {
29201 if (ty.toIntern() == .bool_type) return true;
29202 if (ty.isPtrAtRuntime(zcu))
29203 return of_is.is.bitSize(cg.target) >= (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;
29204 if (!ty.isAbiInt(zcu)) return false;
29205 return of_is.is.bitSize(cg.target) >= (ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1;
29206 },
29207 .exact_remainder_int => |of_is| {
29208 if (ty.isPtrAtRuntime(zcu))
29209 return of_is.is.bitSize(cg.target) == (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;
29210 if (!ty.isAbiInt(zcu)) return false;
29211 return of_is.is.bitSize(cg.target) == (ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1;
29212 },
29213 .signed_or_exact_remainder_int => |of_is| {
29214 if (ty.isPtrAtRuntime(zcu))
29215 return of_is.is.bitSize(cg.target) == (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;
29216 if (!ty.isAbiInt(zcu)) return false;
29217 const int_info = ty.intInfo(zcu);
29218 return switch (int_info.signedness) {
29219 .signed => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29220 .unsigned => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29221 };
29222 },
29223 .unsigned_or_exact_remainder_int => |of_is| {
29224 if (ty.toIntern() == .bool_type) return true;
29225 if (ty.isPtrAtRuntime(zcu))
29226 return of_is.is.bitSize(cg.target) >= (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1;
29227 if (!ty.isAbiInt(zcu)) return false;
29228 const int_info = ty.intInfo(zcu);
29229 return switch (int_info.signedness) {
29230 .signed => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29231 .unsigned => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1,
29232 };
29233 },
29234 .signed_int => |size| {
29235 if (!ty.isAbiInt(zcu)) return false;
29236 const int_info = ty.intInfo(zcu);
29237 return int_info.signedness == .signed and size.bitSize(cg.target) >= int_info.bits;
29238 },
29239 .unsigned_int => |size| {
29240 if (ty.toIntern() == .bool_type) return true;
29241 if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();
29242 if (!ty.isAbiInt(zcu)) return false;
29243 const int_info = ty.intInfo(zcu);
29244 return int_info.signedness == .unsigned and size.bitSize(cg.target) >= int_info.bits;
29245 },
29246 .elem_size_is => |size| return size == ty.elemType2(zcu).abiSize(zcu),
29247 .po2_elem_size => return std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)),
29248 .elem_int => |size| {
29249 const elem_ty = ty.elemType2(zcu);
29250 if (elem_ty.toIntern() == .bool_type) return true;
29251 if (elem_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth();
29252 return elem_ty.isAbiInt(zcu) and size.bitSize(cg.target) >= elem_ty.intInfo(zcu).bits;
29253 },
29254 }
29255 }29259 }
29256 };29260 };
2925729261
...@@ -29431,10 +29435,7 @@ const Select = struct {...@@ -29431,10 +29435,7 @@ const Select = struct {
29431 }),29435 }),
29432 },29436 },
29433 else => {29437 else => {
29434 const scalar_info: InternPool.Key.IntType = if (scalar_ty.isAbiInt(zcu))29438 const scalar_info = intInfo(scalar_ty, cg).?;
29435 scalar_ty.intInfo(zcu)
29436 else
29437 .{ .signedness = .unsigned, .bits = @intCast(scalar_ty.bitSize(zcu)) };
29438 const scalar_int_ty = try pt.intType(scalar_info.signedness, scalar_info.bits);29439 const scalar_int_ty = try pt.intType(scalar_info.signedness, scalar_info.bits);
29439 if (scalar_info.bits <= 64) {29440 if (scalar_info.bits <= 64) {
29440 const int_val: i64 = switch (spec.kind) {29441 const int_val: i64 = switch (spec.kind) {
test/behavior/basic.zig+1-1
...@@ -1169,10 +1169,10 @@ test "arrays and vectors with big integers" {...@@ -1169,10 +1169,10 @@ test "arrays and vectors with big integers" {
1169 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1169 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;1170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;1171 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1172 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1172 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;1173 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1173 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;1174 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1174 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1175 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1175 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
11761176
1177 inline for (.{ u65528, u65529, u65535 }) |Int| {1177 inline for (.{ u65528, u65529, u65535 }) |Int| {
1178 var a: [1]Int = undefined;1178 var a: [1]Int = undefined;
test/behavior/cast.zig-1
...@@ -2539,7 +2539,6 @@ test "@intFromBool on vector" {...@@ -2539,7 +2539,6 @@ test "@intFromBool on vector" {
2539 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO2539 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO2540 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO2541 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2542 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2543 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;2542 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
25442543
2545 const S = struct {2544 const S = struct {
test/behavior/math.zig+1-2
...@@ -472,7 +472,6 @@ test "division" {...@@ -472,7 +472,6 @@ test "division" {
472 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO472 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
473 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO473 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO474 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
475 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
476 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;475 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
477 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;476 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
478477
...@@ -588,7 +587,7 @@ fn testFloatDivision() !void {...@@ -588,7 +587,7 @@ fn testFloatDivision() !void {
588}587}
589588
590test "large integer division" {589test "large integer division" {
591 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;590 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
592 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;591 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
593 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;592 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
594 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;593 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
test/behavior/optional.zig+1-1
...@@ -57,7 +57,7 @@ fn testNullPtrsEql() !void {...@@ -57,7 +57,7 @@ fn testNullPtrsEql() !void {
5757
58test "optional with zero-bit type" {58test "optional with zero-bit type" {
59 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;59 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
60 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;60 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
61 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;61 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
6262
63 const S = struct {63 const S = struct {
test/behavior/packed-union.zig-1
...@@ -138,7 +138,6 @@ test "packed union initialized with a runtime value" {...@@ -138,7 +138,6 @@ test "packed union initialized with a runtime value" {
138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
140 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;140 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
141 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
142 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;141 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
143142
144 const Fields = packed struct {143 const Fields = packed struct {
test/behavior/vector.zig+1-4
...@@ -205,7 +205,6 @@ test "array vector coercion - odd sizes" {...@@ -205,7 +205,6 @@ test "array vector coercion - odd sizes" {
205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO206 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
207 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO207 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
208 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
209 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;208 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
210 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;209 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
211210
...@@ -308,7 +307,6 @@ test "tuple to vector" {...@@ -308,7 +307,6 @@ test "tuple to vector" {
308307
309test "vector casts of sizes not divisible by 8" {308test "vector casts of sizes not divisible by 8" {
310 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO309 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
311 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO310 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
313 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO311 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
314 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO312 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1363,7 +1361,7 @@ test "load packed vector element" {...@@ -1363,7 +1361,7 @@ test "load packed vector element" {
1363 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1364 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1362 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1365 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1363 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1366 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1364 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
1367 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;1365 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
13681366
1369 var x: @Vector(2, u15) = .{ 1, 4 };1367 var x: @Vector(2, u15) = .{ 1, 4 };
...@@ -1411,7 +1409,6 @@ test "store vector with memset" {...@@ -1411,7 +1409,6 @@ test "store vector with memset" {
1411 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1409 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1412 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1410 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1413 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1411 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1414 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1415 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1412 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1416 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO1413 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
1417 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO1414 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO