| ... | ... | @@ -8998,7 +8998,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 8998 | 8998 | }) else fallback: { |
| 8999 | 8999 | const bin_op = air_datas[@intFromEnum(inst)].bin_op; |
| 9000 | 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 | 9002 | else => unreachable, |
| 9003 | 9003 | .cmp_eq, .cmp_eq_optimized => .eq, |
| 9004 | 9004 | .cmp_neq, .cmp_neq_optimized => .neq, |
| ... | ... | @@ -9012,38 +9012,81 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9012 | 9012 | })) { |
| 9013 | 9013 | else => unreachable, |
| 9014 | 9014 | inline .e, .ne => |cc| comptime &.{ .{ |
| 9015 | | .required_features = .{ .avx2, null, null, null }, |
| 9016 | | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, |
| 9015 | .src_constraints = .{ .{ .int = .byte }, .{ .int = .byte } }, |
| 9017 | 9016 | .patterns = &.{ |
| 9018 | | .{ .src = .{ .to_ymm, .mem } }, |
| 9019 | | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| 9020 | | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 9017 | .{ .src = .{ .mem, .imm8 } }, |
| 9018 | .{ .src = .{ .imm8, .mem }, .commute = .{ 0, 1 } }, |
| 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 = .{ |
| 9023 | | .{ .kind = .{ .rc = .sse } }, |
| 9024 | | .unused, |
| 9025 | | .unused, |
| 9026 | | .unused, |
| 9027 | | .unused, |
| 9028 | | .unused, |
| 9025 | .dst_temps = .{.{ .cc = cc }}, |
| 9026 | .clobbers = .{ .eflags = true }, |
| 9027 | .each = .{ .once = &.{ |
| 9028 | .{ ._, ._, .cmp, .src0b, .src1b, ._, ._ }, |
| 9029 | } }, |
| 9030 | }, .{ |
| 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 | 9041 | .dst_temps = .{.{ .cc = cc }}, |
| 9031 | 9042 | .clobbers = .{ .eflags = true }, |
| 9032 | 9043 | .each = .{ .once = &.{ |
| 9033 | | .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 9034 | | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 9044 | .{ ._, ._, .cmp, .src0w, .src1w, ._, ._ }, |
| 9035 | 9045 | } }, |
| 9036 | 9046 | }, .{ |
| 9037 | | .required_features = .{ .avx, null, null, null }, |
| 9038 | | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, |
| 9047 | .src_constraints = .{ .{ .int = .dword }, .{ .int = .dword } }, |
| 9039 | 9048 | .patterns = &.{ |
| 9040 | | .{ .src = .{ .to_ymm, .mem } }, |
| 9041 | | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| 9042 | | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 9049 | .{ .src = .{ .mem, .imm32 } }, |
| 9050 | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, |
| 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 | 9087 | .extra_temps = .{ |
| 9045 | | .{ .kind = .{ .rc = .sse } }, |
| 9046 | | .unused, |
| 9088 | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 9089 | .{ .kind = .{ .rc = .mmx } }, |
| 9047 | 9090 | .unused, |
| 9048 | 9091 | .unused, |
| 9049 | 9092 | .unused, |
| ... | ... | @@ -9052,8 +9095,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9052 | 9095 | .dst_temps = .{.{ .cc = cc }}, |
| 9053 | 9096 | .clobbers = .{ .eflags = true }, |
| 9054 | 9097 | .each = .{ .once = &.{ |
| 9055 | | .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 9056 | | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 9098 | .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ }, |
| 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 | 9105 | .required_features = .{ .avx, null, null, null }, |
| ... | ... | @@ -9117,16 +9163,16 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9117 | 9163 | .{ ._, ._, .xor, .tmp0d, .si(0xffff), ._, ._ }, |
| 9118 | 9164 | } }, |
| 9119 | 9165 | }, .{ |
| 9120 | | .required_features = .{ .sse, .mmx, null, null }, |
| 9121 | | .src_constraints = .{ .{ .int = .qword }, .{ .int = .qword } }, |
| 9166 | .required_features = .{ .avx2, null, null, null }, |
| 9167 | .src_constraints = .{ .{ .int = .yword }, .{ .int = .yword } }, |
| 9122 | 9168 | .patterns = &.{ |
| 9123 | | .{ .src = .{ .to_mut_mm, .mem } }, |
| 9124 | | .{ .src = .{ .mem, .to_mut_mm }, .commute = .{ 0, 1 } }, |
| 9125 | | .{ .src = .{ .to_mut_mm, .to_mm } }, |
| 9169 | .{ .src = .{ .to_ymm, .mem } }, |
| 9170 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| 9171 | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 9126 | 9172 | }, |
| 9127 | 9173 | .extra_temps = .{ |
| 9128 | | .{ .type = .u32, .kind = .{ .rc = .general_purpose } }, |
| 9129 | | .{ .kind = .{ .rc = .mmx } }, |
| 9174 | .{ .kind = .{ .rc = .sse } }, |
| 9175 | .unused, |
| 9130 | 9176 | .unused, |
| 9131 | 9177 | .unused, |
| 9132 | 9178 | .unused, |
| ... | ... | @@ -9135,76 +9181,30 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 9135 | 9181 | .dst_temps = .{.{ .cc = cc }}, |
| 9136 | 9182 | .clobbers = .{ .eflags = true }, |
| 9137 | 9183 | .each = .{ .once = &.{ |
| 9138 | | .{ ._, .p_, .xor, .tmp1q, .tmp1q, ._, ._ }, |
| 9139 | | .{ ._, .p_, .xor, .src0q, .src1q, ._, ._ }, |
| 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, ._, ._ }, |
| 9184 | .{ ._, .vp_, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 9185 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 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 | 9190 | .patterns = &.{ |
| 9179 | | .{ .src = .{ .mem, .imm32 } }, |
| 9180 | | .{ .src = .{ .imm32, .mem }, .commute = .{ 0, 1 } }, |
| 9181 | | .{ .src = .{ .to_gpr, .imm32 } }, |
| 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 } }, |
| 9191 | .{ .src = .{ .to_ymm, .mem } }, |
| 9192 | .{ .src = .{ .mem, .to_ymm }, .commute = .{ 0, 1 } }, |
| 9193 | .{ .src = .{ .to_ymm, .to_ymm } }, |
| 9186 | 9194 | }, |
| 9187 | | .dst_temps = .{.{ .cc = cc }}, |
| 9188 | | .clobbers = .{ .eflags = true }, |
| 9189 | | .each = .{ .once = &.{ |
| 9190 | | .{ ._, ._, .cmp, .src0d, .src1d, ._, ._ }, |
| 9191 | | } }, |
| 9192 | | }, .{ |
| 9193 | | .required_features = .{ .@"64bit", null, null, null }, |
| 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 } }, |
| 9195 | .extra_temps = .{ |
| 9196 | .{ .kind = .{ .rc = .sse } }, |
| 9197 | .unused, |
| 9198 | .unused, |
| 9199 | .unused, |
| 9200 | .unused, |
| 9201 | .unused, |
| 9203 | 9202 | }, |
| 9204 | 9203 | .dst_temps = .{.{ .cc = cc }}, |
| 9205 | 9204 | .clobbers = .{ .eflags = true }, |
| 9206 | 9205 | .each = .{ .once = &.{ |
| 9207 | | .{ ._, ._, .cmp, .src0q, .src1q, ._, ._ }, |
| 9206 | .{ ._, .v_pd, .xor, .tmp0y, .src0y, .src1y, ._ }, |
| 9207 | .{ ._, .vp_, .@"test", .tmp0y, .tmp0y, ._, ._ }, |
| 9208 | 9208 | } }, |
| 9209 | 9209 | }, .{ |
| 9210 | 9210 | .required_features = .{ .avx2, null, null, null }, |
| ... | ... | @@ -19540,10 +19540,19 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv |
| 19540 | 19540 | .air_ref, |
| 19541 | 19541 | => unreachable, // unmodifiable destination |
| 19542 | 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 | 19548 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| 19545 | 19549 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| 19546 | 19550 | |
| 19551 | switch (abi_size) { |
| 19552 | 1 => try self.asmRegisterRegister(.{ ._, .movzx }, dst_reg.to32(), dst_reg.to8()), |
| 19553 | else => {}, |
| 19554 | } |
| 19555 | |
| 19547 | 19556 | const resolved_src_mcv = switch (src_mcv) { |
| 19548 | 19557 | else => src_mcv, |
| 19549 | 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 | 19571 | .reserved_frame, |
| 19563 | 19572 | .air_ref, |
| 19564 | 19573 | => unreachable, |
| 19565 | | .register => |src_reg| try self.asmRegisterRegister( |
| 19566 | | .{ .i_, .mul }, |
| 19567 | | dst_alias, |
| 19568 | | registerAlias(src_reg, abi_size), |
| 19569 | | ), |
| 19574 | .register => |src_reg| { |
| 19575 | switch (abi_size) { |
| 19576 | 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()), |
| 19577 | else => {}, |
| 19578 | } |
| 19579 | try self.asmRegisterRegister( |
| 19580 | .{ .i_, .mul }, |
| 19581 | dst_alias, |
| 19582 | registerAlias(src_reg, alias_size), |
| 19583 | ); |
| 19584 | }, |
| 19570 | 19585 | .immediate => |imm| { |
| 19571 | | if (std.math.cast(i32, imm)) |small| { |
| 19572 | | try self.asmRegisterRegisterImmediate( |
| 19573 | | .{ .i_, .mul }, |
| 19574 | | dst_alias, |
| 19575 | | dst_alias, |
| 19576 | | .s(small), |
| 19577 | | ); |
| 19586 | if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |small| { |
| 19587 | try self.asmRegisterRegisterImmediate(.{ .i_, .mul }, dst_alias, dst_alias, .s(small)); |
| 19578 | 19588 | } else { |
| 19579 | 19589 | const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv); |
| 19580 | 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 | 19601 | .load_tlv, |
| 19592 | 19602 | .lea_tlv, |
| 19593 | 19603 | .lea_frame, |
| 19594 | | => try self.asmRegisterRegister( |
| 19595 | | .{ .i_, .mul }, |
| 19596 | | dst_alias, |
| 19597 | | registerAlias(try self.copyToTmpRegister(dst_ty, resolved_src_mcv), abi_size), |
| 19598 | | ), |
| 19599 | | .memory, .indirect, .load_frame => try self.asmRegisterMemory( |
| 19600 | | .{ .i_, .mul }, |
| 19601 | | dst_alias, |
| 19602 | | switch (resolved_src_mcv) { |
| 19603 | | .memory => |addr| .{ |
| 19604 | | .base = .{ .reg = .ds }, |
| 19605 | | .mod = .{ .rm = .{ |
| 19606 | | .size = .fromSize(abi_size), |
| 19607 | | .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse |
| 19608 | | return self.asmRegisterRegister( |
| 19609 | | .{ .i_, .mul }, |
| 19610 | | dst_alias, |
| 19611 | | registerAlias( |
| 19612 | | try self.copyToTmpRegister(dst_ty, resolved_src_mcv), |
| 19613 | | abi_size, |
| 19604 | => { |
| 19605 | const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv); |
| 19606 | switch (abi_size) { |
| 19607 | 1 => try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()), |
| 19608 | else => {}, |
| 19609 | } |
| 19610 | try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size)); |
| 19611 | }, |
| 19612 | .memory, .indirect, .load_frame => switch (abi_size) { |
| 19613 | 1 => { |
| 19614 | const src_reg = try self.copyToTmpRegister(dst_ty, resolved_src_mcv); |
| 19615 | try self.asmRegisterRegister(.{ ._, .movzx }, src_reg.to32(), src_reg.to8()); |
| 19616 | try self.asmRegisterRegister(.{ .i_, .mul }, dst_alias, registerAlias(src_reg, alias_size)); |
| 19617 | }, |
| 19618 | else => try self.asmRegisterMemory( |
| 19619 | .{ .i_, .mul }, |
| 19620 | dst_alias, |
| 19621 | switch (resolved_src_mcv) { |
| 19622 | .memory => |addr| .{ |
| 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 | | ), |
| 19616 | | } }, |
| 19617 | | }, |
| 19618 | | .indirect => |reg_off| .{ |
| 19619 | | .base = .{ .reg = reg_off.reg }, |
| 19620 | | .mod = .{ .rm = .{ |
| 19621 | | .size = .fromSize(abi_size), |
| 19622 | | .disp = reg_off.off, |
| 19623 | | } }, |
| 19624 | | }, |
| 19625 | | .load_frame => |frame_addr| .{ |
| 19626 | | .base = .{ .frame = frame_addr.index }, |
| 19627 | | .mod = .{ .rm = .{ |
| 19628 | | .size = .fromSize(abi_size), |
| 19629 | | .disp = frame_addr.off, |
| 19630 | | } }, |
| 19635 | } }, |
| 19636 | }, |
| 19637 | .indirect => |reg_off| .{ |
| 19638 | .base = .{ .reg = reg_off.reg }, |
| 19639 | .mod = .{ .rm = .{ |
| 19640 | .size = .fromSize(abi_size), |
| 19641 | .disp = reg_off.off, |
| 19642 | } }, |
| 19643 | }, |
| 19644 | .load_frame => |frame_addr| .{ |
| 19645 | .base = .{ .frame = frame_addr.index }, |
| 19646 | .mod = .{ .rm = .{ |
| 19647 | .size = .fromSize(abi_size), |
| 19648 | .disp = frame_addr.off, |
| 19649 | } }, |
| 19650 | }, |
| 19651 | else => unreachable, |
| 19631 | 19652 | }, |
| 19632 | | else => unreachable, |
| 19633 | | }, |
| 19634 | | ), |
| 19653 | ), |
| 19654 | }, |
| 19635 | 19655 | } |
| 19636 | 19656 | }, |
| 19637 | 19657 | .register_pair, .register_triple, .register_quadruple => unreachable, // unimplemented |
| ... | ... | @@ -27952,6 +27972,75 @@ fn promoteVarArg(self: *CodeGen, ty: Type) Type { |
| 27952 | 27972 | } |
| 27953 | 27973 | } |
| 27954 | 27974 | |
| 27975 | fn 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 | |
| 27955 | 28044 | const Temp = struct { |
| 27956 | 28045 | index: Air.Inst.Index, |
| 27957 | 28046 | |
| ... | ... | @@ -29061,197 +29150,112 @@ const Select = struct { |
| 29061 | 29150 | |
| 29062 | 29151 | fn accepts(constraint: Constraint, ty: Type, cg: *CodeGen) bool { |
| 29063 | 29152 | const zcu = cg.pt.zcu; |
| 29064 | | switch (constraint) { |
| 29065 | | .any => return true, |
| 29066 | | .any_bool_vec => return 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), |
| 29068 | | .any_signed_int => return ty.isAbiInt(zcu) and ty.intInfo(zcu).signedness == .signed, |
| 29069 | | .any_float => return ty.isRuntimeFloat(), |
| 29070 | | .po2_any => return std.math.isPowerOfTwo(ty.abiSize(zcu)), |
| 29071 | | .bool_vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and |
| 29153 | return switch (constraint) { |
| 29154 | .any => true, |
| 29155 | .any_bool_vec => ty.isVector(zcu) and ty.childType(zcu).toIntern() == .bool_type, |
| 29156 | .any_int => intInfo(ty, cg) != null, |
| 29157 | .any_signed_int => if (intInfo(ty, cg)) |int_info| int_info.signedness == .signed else false, |
| 29158 | .any_float => ty.isRuntimeFloat(), |
| 29159 | .po2_any => std.math.isPowerOfTwo(ty.abiSize(zcu)), |
| 29160 | .bool_vec => |size| ty.isVector(zcu) and ty.scalarType(zcu).toIntern() == .bool_type and |
| 29072 | 29161 | size.bitSize(cg.target) >= ty.vectorLen(zcu), |
| 29073 | | .vec => |size| return ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and |
| 29162 | .vec => |size| ty.isVector(zcu) and ty.scalarType(zcu).toIntern() != .bool_type and |
| 29074 | 29163 | size.bitSize(cg.target) >= ty.abiSize(zcu), |
| 29075 | | .signed_int_vec => |size| { |
| 29076 | | if (!ty.isVector(zcu) or size.bitSize(cg.target) < 8 * ty.abiSize(zcu)) return false; |
| 29077 | | const scalar_ty = ty.scalarType(zcu); |
| 29078 | | return scalar_ty.isAbiInt(zcu) and scalar_ty.intInfo(zcu).signedness == .signed; |
| 29079 | | }, |
| 29080 | | .signed_int_or_full_vec => |size| { |
| 29081 | | if (!ty.isVector(zcu) or size.bitSize(cg.target) < 8 * ty.abiSize(zcu)) return false; |
| 29082 | | const scalar_ty = ty.scalarType(zcu); |
| 29083 | | if (scalar_ty.isPtrAtRuntime(zcu)) return true; |
| 29084 | | if (!scalar_ty.isAbiInt(zcu)) return false; |
| 29085 | | const scalar_int_info = scalar_ty.intInfo(zcu); |
| 29086 | | return switch (scalar_int_info.signedness) { |
| 29087 | | .signed => true, |
| 29088 | | .unsigned => scalar_int_info.bits >= 8 and std.math.isPowerOfTwo(scalar_int_info.bits), |
| 29089 | | }; |
| 29090 | | }, |
| 29091 | | .unsigned_int_vec => |size| { |
| 29092 | | if (!ty.isVector(zcu) or size.bitSize(cg.target) < ty.bitSize(zcu)) return false; |
| 29093 | | const scalar_ty = ty.scalarType(zcu); |
| 29094 | | if (scalar_ty.isPtrAtRuntime(zcu)) return true; |
| 29095 | | return scalar_ty.isAbiInt(zcu) and scalar_ty.intInfo(zcu).signedness == .unsigned; |
| 29096 | | }, |
| 29097 | | .int_or_vec => |size| { |
| 29098 | | if (ty.isVector(zcu)) return ty.scalarType(zcu).toIntern() != .bool_type and |
| 29099 | | size.bitSize(cg.target) >= 8 * ty.abiSize(zcu); |
| 29100 | | if (ty.toIntern() == .bool_type) return true; |
| 29101 | | if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth(); |
| 29102 | | return ty.isAbiInt(zcu) and size.bitSize(cg.target) >= ty.intInfo(zcu).bits; |
| 29103 | | }, |
| 29104 | | .exact_remainder_int_or_vec => |of_is| { |
| 29105 | | if (ty.isVector(zcu)) return ty.scalarType(zcu).toIntern() != .bool_type and |
| 29106 | | of_is.is.bitSize(cg.target) == (8 * ty.abiSize(zcu) - 1) % of_is.of.bitSize(cg.target) + 1; |
| 29107 | | if (ty.isPtrAtRuntime(zcu)) |
| 29108 | | return of_is.is.bitSize(cg.target) == (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1; |
| 29109 | | if (!ty.isAbiInt(zcu)) return false; |
| 29110 | | return of_is.is.bitSize(cg.target) == (ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1; |
| 29111 | | }, |
| 29112 | | .int => |size| { |
| 29113 | | if (ty.toIntern() == .bool_type) return true; |
| 29114 | | if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth(); |
| 29115 | | return ty.isAbiInt(zcu) and size.bitSize(cg.target) >= ty.intInfo(zcu).bits; |
| 29116 | | }, |
| 29117 | | .scalar_int => |size| { |
| 29118 | | const scalar_ty = ty.scalarType(zcu); |
| 29119 | | if (scalar_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth(); |
| 29120 | | return scalar_ty.isAbiInt(zcu) and size.bitSize(cg.target) >= scalar_ty.intInfo(zcu).bits; |
| 29121 | | }, |
| 29122 | | .scalar_signed_int => |size| { |
| 29123 | | const scalar_ty = ty.scalarType(zcu); |
| 29124 | | if (!scalar_ty.isAbiInt(zcu)) return false; |
| 29125 | | const scalar_int_info = scalar_ty.intInfo(zcu); |
| 29126 | | return scalar_int_info.signedness == .signed and size.bitSize(cg.target) >= scalar_int_info.bits; |
| 29127 | | }, |
| 29128 | | .scalar_unsigned_int => |size| { |
| 29129 | | const scalar_ty = ty.scalarType(zcu); |
| 29130 | | if (scalar_ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) >= cg.target.ptrBitWidth(); |
| 29131 | | if (!scalar_ty.isAbiInt(zcu)) return false; |
| 29132 | | const scalar_int_info = scalar_ty.intInfo(zcu); |
| 29133 | | return scalar_int_info.signedness == .unsigned and size.bitSize(cg.target) >= scalar_int_info.bits; |
| 29134 | | }, |
| 29135 | | .scalar_remainder_int => |of_is| { |
| 29136 | | const scalar_ty = ty.scalarType(zcu); |
| 29137 | | if (scalar_ty.isPtrAtRuntime(zcu)) |
| 29138 | | return of_is.is.bitSize(cg.target) >= (cg.target.ptrBitWidth() - 1) % of_is.of.bitSize(cg.target) + 1; |
| 29139 | | if (!scalar_ty.isAbiInt(zcu)) return false; |
| 29140 | | return of_is.is.bitSize(cg.target) >= (scalar_ty.intInfo(zcu).bits - 1) % of_is.of.bitSize(cg.target) + 1; |
| 29141 | | }, |
| 29142 | | .exact_int => |bit_size| { |
| 29143 | | if (ty.toIntern() == .bool_type) return bit_size == 1; |
| 29144 | | if (ty.isPtrAtRuntime(zcu)) return bit_size == cg.target.ptrBitWidth(); |
| 29145 | | return ty.isAbiInt(zcu) and bit_size == ty.intInfo(zcu).bits; |
| 29146 | | }, |
| 29147 | | .exact_signed_int => |bit_size| { |
| 29148 | | if (!ty.isAbiInt(zcu)) return false; |
| 29149 | | const int_info = ty.intInfo(zcu); |
| 29150 | | return int_info.signedness == .signed and bit_size == int_info.bits; |
| 29151 | | }, |
| 29152 | | .exact_unsigned_int => |bit_size| { |
| 29153 | | if (ty.toIntern() == .bool_type) return bit_size == 1; |
| 29154 | | if (ty.isPtrAtRuntime(zcu)) return bit_size == cg.target.ptrBitWidth(); |
| 29155 | | if (!ty.isAbiInt(zcu)) return false; |
| 29156 | | const int_info = ty.intInfo(zcu); |
| 29157 | | return int_info.signedness == .unsigned and bit_size == int_info.bits; |
| 29158 | | }, |
| 29159 | | .signed_or_exact_int => |size| { |
| 29160 | | if (ty.isPtrAtRuntime(zcu)) return size.bitSize(cg.target) == cg.target.ptrBitWidth(); |
| 29161 | | if (!ty.isAbiInt(zcu)) return false; |
| 29162 | | const int_info = ty.intInfo(zcu); |
| 29163 | | return switch (int_info.signedness) { |
| 29164 | | .signed => size.bitSize(cg.target) >= int_info.bits, |
| 29165 | | .unsigned => size.bitSize(cg.target) == int_info.bits, |
| 29166 | | }; |
| 29167 | | }, |
| 29168 | | .unsigned_or_exact_int => |size| { |
| 29169 | | if (ty.toIntern() == .bool_type or ty.isPtrAtRuntime(zcu)) return true; |
| 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 | | } |
| 29164 | .signed_int_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and |
| 29165 | if (intInfo(ty.childType(zcu), cg)) |int_info| int_info.signedness == .signed else false, |
| 29166 | .signed_int_or_full_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and |
| 29167 | if (intInfo(ty.childType(zcu), cg)) |int_info| switch (int_info.signedness) { |
| 29168 | .signed => true, |
| 29169 | .unsigned => int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits), |
| 29170 | } else false, |
| 29171 | .unsigned_int_vec => |size| ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu) and |
| 29172 | if (intInfo(ty.childType(zcu), cg)) |int_info| int_info.signedness == .unsigned else false, |
| 29173 | .int_or_vec => |size| if (intInfo(ty, cg)) |int_info| |
| 29174 | size.bitSize(cg.target) >= int_info.bits |
| 29175 | else |
| 29176 | ty.isVector(zcu) and size.bitSize(cg.target) >= 8 * ty.abiSize(zcu), |
| 29177 | .exact_remainder_int_or_vec => |of_is| if (intInfo(ty, cg)) |int_info| |
| 29178 | of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 29179 | else |
| 29180 | ty.isVector(zcu) and ty.childType(zcu).toIntern() != .bool_type and |
| 29181 | of_is.is.bitSize(cg.target) == (8 * ty.abiSize(zcu) - 1) % of_is.of.bitSize(cg.target) + 1, |
| 29182 | .int => |size| if (intInfo(ty, cg)) |int_info| size.bitSize(cg.target) >= int_info.bits else false, |
| 29183 | .scalar_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info| |
| 29184 | size.bitSize(cg.target) >= int_info.bits |
| 29185 | else |
| 29186 | false, |
| 29187 | .scalar_signed_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info| switch (int_info.signedness) { |
| 29188 | .signed => size.bitSize(cg.target) >= int_info.bits, |
| 29189 | .unsigned => false, |
| 29190 | } else false, |
| 29191 | .scalar_unsigned_int => |size| if (intInfo(ty.scalarType(zcu), cg)) |int_info| switch (int_info.signedness) { |
| 29192 | .signed => false, |
| 29193 | .unsigned => size.bitSize(cg.target) >= int_info.bits, |
| 29194 | } else false, |
| 29195 | .scalar_remainder_int => |of_is| if (intInfo(ty.scalarType(zcu), cg)) |int_info| |
| 29196 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 29197 | else |
| 29198 | false, |
| 29199 | .exact_int => |bit_size| if (intInfo(ty, cg)) |int_info| bit_size == int_info.bits else false, |
| 29200 | .exact_signed_int => |bit_size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29201 | .signed => bit_size == int_info.bits, |
| 29202 | .unsigned => false, |
| 29203 | } else false, |
| 29204 | .exact_unsigned_int => |bit_size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29205 | .signed => false, |
| 29206 | .unsigned => bit_size == int_info.bits, |
| 29207 | } else false, |
| 29208 | .signed_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29209 | .signed => size.bitSize(cg.target) >= int_info.bits, |
| 29210 | .unsigned => size.bitSize(cg.target) == int_info.bits, |
| 29211 | } else false, |
| 29212 | .unsigned_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29213 | .signed => size.bitSize(cg.target) == int_info.bits, |
| 29214 | .unsigned => size.bitSize(cg.target) >= int_info.bits, |
| 29215 | } else false, |
| 29216 | .po2_int => |size| if (intInfo(ty, cg)) |int_info| |
| 29217 | std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits |
| 29218 | else |
| 29219 | false, |
| 29220 | .signed_po2_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29221 | .signed => std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits, |
| 29222 | .unsigned => false, |
| 29223 | } else false, |
| 29224 | .unsigned_po2_or_exact_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29225 | .signed => size.bitSize(cg.target) == int_info.bits, |
| 29226 | .unsigned => std.math.isPowerOfTwo(int_info.bits) and size.bitSize(cg.target) >= int_info.bits, |
| 29227 | } else false, |
| 29228 | .remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| |
| 29229 | of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 29230 | else |
| 29231 | false, |
| 29232 | .exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| |
| 29233 | of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1 |
| 29234 | else |
| 29235 | false, |
| 29236 | .signed_or_exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29237 | .signed => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1, |
| 29238 | .unsigned => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1, |
| 29239 | } else false, |
| 29240 | .unsigned_or_exact_remainder_int => |of_is| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29241 | .signed => of_is.is.bitSize(cg.target) == (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1, |
| 29242 | .unsigned => of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1, |
| 29243 | } else false, |
| 29244 | .signed_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29245 | .signed => size.bitSize(cg.target) >= int_info.bits, |
| 29246 | .unsigned => false, |
| 29247 | } else false, |
| 29248 | .unsigned_int => |size| if (intInfo(ty, cg)) |int_info| switch (int_info.signedness) { |
| 29249 | .signed => false, |
| 29250 | .unsigned => size.bitSize(cg.target) >= int_info.bits, |
| 29251 | } else false, |
| 29252 | .elem_size_is => |size| size == ty.elemType2(zcu).abiSize(zcu), |
| 29253 | .po2_elem_size => std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)), |
| 29254 | .elem_int => |size| if (intInfo(ty.elemType2(zcu), cg)) |elem_int_info| |
| 29255 | size.bitSize(cg.target) >= elem_int_info.bits |
| 29256 | else |
| 29257 | false, |
| 29258 | }; |
| 29255 | 29259 | } |
| 29256 | 29260 | }; |
| 29257 | 29261 | |
| ... | ... | @@ -29431,10 +29435,7 @@ const Select = struct { |
| 29431 | 29435 | }), |
| 29432 | 29436 | }, |
| 29433 | 29437 | else => { |
| 29434 | | const scalar_info: InternPool.Key.IntType = if (scalar_ty.isAbiInt(zcu)) |
| 29435 | | scalar_ty.intInfo(zcu) |
| 29436 | | else |
| 29437 | | .{ .signedness = .unsigned, .bits = @intCast(scalar_ty.bitSize(zcu)) }; |
| 29438 | const scalar_info = intInfo(scalar_ty, cg).?; |
| 29438 | 29439 | const scalar_int_ty = try pt.intType(scalar_info.signedness, scalar_info.bits); |
| 29439 | 29440 | if (scalar_info.bits <= 64) { |
| 29440 | 29441 | const int_val: i64 = switch (spec.kind) { |