| ... | @@ -3758,12 +3758,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -3758,12 +3758,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 3758 | } else if (dst_tag == .float and src_tag == .float) { | 3758 | } else if (dst_tag == .float and src_tag == .float) { |
| 3759 | assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target)); | 3759 | assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target)); |
| 3760 | try dst_vi.value.defMove(isel, ty_op.operand); | 3760 | try dst_vi.value.defMove(isel, ty_op.operand); |
| 3761 | } else if (dst_ty.isAbiInt(zcu) and src_tag == .float) { | 3761 | } else if (dst_ty.isAbiInt(zcu) and src_tag == .float and isel.canUseFprForFloat(src_ty)) { |
| 3762 | const dst_int_info = dst_ty.intInfo(zcu); | 3762 | const dst_int_info = dst_ty.intInfo(zcu); |
| 3763 | assert(dst_int_info.bits == src_ty.floatBits(isel.target)); | 3763 | assert(dst_int_info.bits == src_ty.floatBits(isel.target)); |
| 3764 | | 3764 | |
| 3765 | try dst_vi.value.reextendToGarbage(isel); | 3765 | try dst_vi.value.reextendToGarbage(isel); |
| 3766 | const dst_reg = try dst_vi.value.defRegMod(isel, .fromFloating(dst_int_info.bits)) orelse break :unused; | 3766 | const dst_reg = try dst_vi.value.defRegMod(isel, .fromFloatBits(dst_int_info.bits)) orelse break :unused; |
| 3767 | const src_vi = try isel.use(ty_op.operand); | 3767 | const src_vi = try isel.use(ty_op.operand); |
| 3768 | const src_mat = try src_vi.matReg(isel); | 3768 | const src_mat = try src_vi.matReg(isel); |
| 3769 | const src_reg = src_mat.reg(); | 3769 | const src_reg = src_mat.reg(); |
| ... | @@ -3773,12 +3773,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, | ... | @@ -3773,12 +3773,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, |
| 3773 | 64 => .@"movfr2gr.d"(dst_reg, src_reg), | 3773 | 64 => .@"movfr2gr.d"(dst_reg, src_reg), |
| 3774 | }); | 3774 | }); |
| 3775 | try src_mat.finish(isel); | 3775 | try src_mat.finish(isel); |
| 3776 | } else if (dst_tag == .float and src_ty.isAbiInt(zcu)) { | 3776 | } else if (dst_tag == .float and src_ty.isAbiInt(zcu) and isel.canUseFprForFloat(dst_ty)) { |
| 3777 | const src_int_info = src_ty.intInfo(zcu); | 3777 | const src_int_info = src_ty.intInfo(zcu); |
| 3778 | assert(dst_ty.floatBits(isel.target) == src_int_info.bits); | 3778 | assert(dst_ty.floatBits(isel.target) == src_int_info.bits); |
| 3779 | | 3779 | |
| 3780 | try dst_vi.value.reextendToGarbage(isel); | 3780 | try dst_vi.value.reextendToGarbage(isel); |
| 3781 | const dst_reg = try dst_vi.value.defRegMod(isel, .fromFloating(src_int_info.bits)) orelse break :unused; | 3781 | const dst_reg = try dst_vi.value.defRegMod(isel, .fromFloatBits(src_int_info.bits)) orelse break :unused; |
| 3782 | const src_vi = try isel.use(ty_op.operand); | 3782 | const src_vi = try isel.use(ty_op.operand); |
| 3783 | const src_mat = try src_vi.matReg(isel); | 3783 | const src_mat = try src_vi.matReg(isel); |
| 3784 | const src_reg = src_mat.reg(); | 3784 | const src_reg = src_mat.reg(); |
| ... | @@ -7258,6 +7258,32 @@ fn gprAlignment(isel: *Select) std.mem.Alignment { | ... | @@ -7258,6 +7258,32 @@ fn gprAlignment(isel: *Select) std.mem.Alignment { |
| 7258 | }; | 7258 | }; |
| 7259 | } | 7259 | } |
| 7260 | | 7260 | |
| | 7261 | fn fprBits(isel: *Select) u7 { |
| | 7262 | const cpu = &isel.target.cpu; |
| | 7263 | if (cpu.has(.loongarch, .d)) { |
| | 7264 | return 64; |
| | 7265 | } else if (cpu.has(.loongarch, .f)) { |
| | 7266 | return 32; |
| | 7267 | } else { |
| | 7268 | return 0; |
| | 7269 | } |
| | 7270 | } |
| | 7271 | |
| | 7272 | fn vectorBits(isel: *Select) u7 { |
| | 7273 | const cpu = &isel.target.cpu; |
| | 7274 | if (cpu.has(.loongarch, .lasx)) { |
| | 7275 | return 256; |
| | 7276 | } else if (cpu.has(.loongarch, .lsx)) { |
| | 7277 | return 128; |
| | 7278 | } else { |
| | 7279 | return isel.fprBits(); |
| | 7280 | } |
| | 7281 | } |
| | 7282 | |
| | 7283 | fn canUseFprForFloat(isel: *Select, ty: ZigType) bool { |
| | 7284 | return ty.floatBits(isel.target) <= isel.fprBits(); |
| | 7285 | } |
| | 7286 | |
| 7261 | fn typeOfField(isel: *Select, ty: ZigType, offset: u64) ?ZigType { | 7287 | fn typeOfField(isel: *Select, ty: ZigType, offset: u64) ?ZigType { |
| 7262 | const zcu = isel.pt.zcu; | 7288 | const zcu = isel.pt.zcu; |
| 7263 | const ip = &zcu.intern_pool; | 7289 | const ip = &zcu.intern_pool; |