Skip to content

Commit 122d849

Browse files
jthackraydvbuka
authored andcommitted
[AArch64][llvm] Armv9.7-A: Add support for SVE2p3 CVT operations (llvm#163162)
Add instructions for SVE2p3 CVT operations: - FCVTZSN - FCVTZUN - SCVTF - SCVTFLT - UCVTF - UCVTFLT as documented here: * https://developer.arm.com/documentation/ddi0602/2025-09/ * https://developer.arm.com/documentation/109697/2025_09/2025-Architecture-Extensions
1 parent 9114dd1 commit 122d849

File tree

4 files changed

+569
-0
lines changed

4 files changed

+569
-0
lines changed

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4639,6 +4639,15 @@ let Predicates = [HasSVE2p3_or_SME2p3] in {
46394639
def SDOT_ZZZI_BtoH : sve_intx_dot_by_indexed_elem_x<0b0, "sdot">;
46404640
def UDOT_ZZZI_BtoH : sve_intx_dot_by_indexed_elem_x<0b1, "udot">;
46414641

4642+
// SVE2 fp convert, narrow and interleave to integer, rounding toward zero
4643+
defm FCVTZSN_Z2Z : sve2_fp_to_int_downcvt<"fcvtzsn", 0b0>;
4644+
defm FCVTZUN_Z2Z : sve2_fp_to_int_downcvt<"fcvtzun", 0b1>;
4645+
4646+
// SVE2 signed/unsigned integer convert to floating-point
4647+
defm SCVTF_ZZ : sve2_int_to_fp_upcvt<"scvtf", 0b00>;
4648+
defm SCVTFLT_ZZ : sve2_int_to_fp_upcvt<"scvtflt", 0b10>;
4649+
defm UCVTF_ZZ : sve2_int_to_fp_upcvt<"ucvtf", 0b01>;
4650+
defm UCVTFLT_ZZ : sve2_int_to_fp_upcvt<"ucvtflt", 0b11>;
46424651
} // End HasSME2p3orSVE2p3
46434652

46444653
//===----------------------------------------------------------------------===//

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11300,3 +11300,49 @@ class sve_int_mla_cpa<string asm>
1130011300

1130111301
let ElementSize = ZPR64.ElementSize;
1130211302
}
11303+
11304+
//===----------------------------------------------------------------------===//
11305+
// FP to Int down-converts
11306+
//===----------------------------------------------------------------------===//
11307+
class sve2_fp_to_int_downcvt<string asm, ZPRRegOp ZdRC, RegisterOperand ZSrcOp, bits<2> size, bit U>
11308+
: I<(outs ZdRC:$Zd), (ins ZSrcOp:$Zn),
11309+
asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
11310+
bits<5> Zd;
11311+
bits<4> Zn;
11312+
let Inst{31-24} = 0b01100101;
11313+
let Inst{23-22} = size;
11314+
let Inst{21-11} = 0b00110100110;
11315+
let Inst{10} = U;
11316+
let Inst{9-6} = Zn;
11317+
let Inst{5} = 0b0;
11318+
let Inst{4-0} = Zd;
11319+
}
11320+
11321+
multiclass sve2_fp_to_int_downcvt<string asm, bit U> {
11322+
def _HtoB : sve2_fp_to_int_downcvt<asm, ZPR8, ZZ_h_mul_r, 0b01, U>;
11323+
def _StoH : sve2_fp_to_int_downcvt<asm, ZPR16, ZZ_s_mul_r, 0b10, U>;
11324+
def _DtoS : sve2_fp_to_int_downcvt<asm, ZPR32, ZZ_d_mul_r, 0b11, U>;
11325+
}
11326+
11327+
//===----------------------------------------------------------------------===//
11328+
// Int to FP up-converts
11329+
//===----------------------------------------------------------------------===//
11330+
class sve2_int_to_fp_upcvt<string asm, ZPRRegOp ZdRC, ZPRRegOp ZnRC,
11331+
bits<2> size, bits<2> U>
11332+
: I<(outs ZdRC:$Zd), (ins ZnRC:$Zn),
11333+
asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
11334+
bits<5> Zd;
11335+
bits<5> Zn;
11336+
let Inst{31-24} = 0b01100101;
11337+
let Inst{23-22} = size;
11338+
let Inst{21-12} = 0b0011000011;
11339+
let Inst{11-10} = U;
11340+
let Inst{9-5} = Zn;
11341+
let Inst{4-0} = Zd;
11342+
}
11343+
11344+
multiclass sve2_int_to_fp_upcvt<string asm, bits<2> U> {
11345+
def _BtoH : sve2_int_to_fp_upcvt<asm, ZPR16, ZPR8, 0b01, U>;
11346+
def _HtoS : sve2_int_to_fp_upcvt<asm, ZPR32, ZPR16, 0b10, U>;
11347+
def _StoD : sve2_int_to_fp_upcvt<asm, ZPR64, ZPR32, 0b11, U>;
11348+
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p3 2>&1 < %s| FileCheck %s
2+
3+
// --------------------------------------------------------------------------//
4+
// Invalid operand for instruction
5+
6+
fcvtzsn z0.b, { z0.b, z1.b }
7+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
8+
// CHECK-NEXT: fcvtzsn z0.b, { z0.b, z1.b }
9+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
10+
11+
fcvtzsn z0.h, { z0.h, z1.h }
12+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
13+
// CHECK-NEXT: fcvtzsn z0.h, { z0.h, z1.h }
14+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
15+
16+
fcvtzsn z0.s, { z0.s, z1.s }
17+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
18+
// CHECK-NEXT: fcvtzsn z0.s, { z0.s, z1.s }
19+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
20+
21+
fcvtzsn z0.b, { z1.h, z2.h }
22+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
23+
// CHECK-NEXT: fcvtzsn z0.b, { z1.h, z2.h }
24+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
25+
26+
// --------------------------------------------------------------------------//
27+
// Negative tests for instructions that are incompatible with movprfx
28+
29+
movprfx z0, z7
30+
fcvtzsn z0.b, { z2.h, z3.h }
31+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
32+
// CHECK-NEXT: fcvtzsn z0.b, { z2.h, z3.h }
33+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
34+
35+
// --------------------------------------------------------------------------//
36+
// Invalid operand for instruction
37+
38+
fcvtzun z0.b, { z0.b, z1.b }
39+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
40+
// CHECK-NEXT: fcvtzun z0.b, { z0.b, z1.b }
41+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
42+
43+
fcvtzun z0.h, { z0.h, z1.h }
44+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
45+
// CHECK-NEXT: fcvtzun z0.h, { z0.h, z1.h }
46+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
47+
48+
fcvtzun z0.s, { z0.s, z1.s }
49+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
50+
// CHECK-NEXT: fcvtzun z0.s, { z0.s, z1.s }
51+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
52+
53+
fcvtzun z0.b, { z1.h, z2.h }
54+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
55+
// CHECK-NEXT: fcvtzun z0.b, { z1.h, z2.h }
56+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
57+
58+
// --------------------------------------------------------------------------//
59+
// Negative tests for instructions that are incompatible with movprfx
60+
61+
movprfx z0, z7
62+
fcvtzun z0.b, { z2.h, z3.h }
63+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
64+
// CHECK-NEXT: fcvtzun z0.b, { z2.h, z3.h }
65+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
66+
67+
// --------------------------------------------------------------------------//
68+
// Invalid element width
69+
70+
scvtf z0.b, z0.b
71+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
72+
// CHECK-NEXT: scvtf z0.b, z0.b
73+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
74+
75+
scvtf z0.h, z0.h
76+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
77+
// CHECK-NEXT: scvtf z0.h, z0.h
78+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
79+
80+
scvtf z0.s, z0.s
81+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
82+
// CHECK-NEXT: scvtf z0.s, z0.s
83+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
84+
85+
scvtf z0.d, z0.d
86+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
87+
// CHECK-NEXT: scvtf z0.d, z0.d
88+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
89+
90+
// --------------------------------------------------------------------------//
91+
// Negative tests for instructions that are incompatible with movprfx
92+
93+
movprfx z0, z7
94+
scvtf z0.h, z1.b
95+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
96+
// CHECK-NEXT: scvtf z0.h, z1.b
97+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
98+
99+
// --------------------------------------------------------------------------//
100+
// Invalid element width
101+
102+
scvtflt z0.b, z0.b
103+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
104+
// CHECK-NEXT: scvtflt z0.b, z0.b
105+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
106+
107+
scvtflt z0.h, z0.h
108+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
109+
// CHECK-NEXT: scvtflt z0.h, z0.h
110+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
111+
112+
scvtflt z0.s, z0.s
113+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
114+
// CHECK-NEXT: scvtflt z0.s, z0.s
115+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
116+
117+
scvtflt z0.d, z0.d
118+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
119+
// CHECK-NEXT: scvtflt z0.d, z0.d
120+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
121+
122+
// --------------------------------------------------------------------------//
123+
// Negative tests for instructions that are incompatible with movprfx
124+
125+
movprfx z0, z7
126+
scvtflt z0.h, z1.b
127+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
128+
// CHECK-NEXT: scvtflt z0.h, z1.b
129+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
130+
131+
// --------------------------------------------------------------------------//
132+
// Invalid element width
133+
134+
ucvtf z0.b, z0.b
135+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
136+
// CHECK-NEXT: ucvtf z0.b, z0.b
137+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
138+
139+
ucvtf z0.h, z0.h
140+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
141+
// CHECK-NEXT: ucvtf z0.h, z0.h
142+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
143+
144+
ucvtf z0.s, z0.s
145+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
146+
// CHECK-NEXT: ucvtf z0.s, z0.s
147+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
148+
149+
ucvtf z0.d, z0.d
150+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
151+
// CHECK-NEXT: ucvtf z0.d, z0.d
152+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
153+
154+
// --------------------------------------------------------------------------//
155+
// Negative tests for instructions that are incompatible with movprfx
156+
157+
movprfx z0, z7
158+
ucvtf z0.h, z1.b
159+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
160+
// CHECK-NEXT: ucvtf z0.h, z1.b
161+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
162+
163+
// --------------------------------------------------------------------------//
164+
// Invalid element width
165+
166+
ucvtflt z0.b, z0.b
167+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
168+
// CHECK-NEXT: ucvtflt z0.b, z0.b
169+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
170+
171+
ucvtflt z0.h, z0.h
172+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
173+
// CHECK-NEXT: ucvtflt z0.h, z0.h
174+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
175+
176+
ucvtflt z0.s, z0.s
177+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
178+
// CHECK-NEXT: ucvtflt z0.s, z0.s
179+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
180+
181+
ucvtflt z0.d, z0.d
182+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
183+
// CHECK-NEXT: ucvtflt z0.d, z0.d
184+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
185+
186+
// --------------------------------------------------------------------------//
187+
// Negative tests for instructions that are incompatible with movprfx
188+
189+
movprfx z0, z7
190+
ucvtflt z0.h, z1.b
191+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
192+
// CHECK-NEXT: ucvtflt z0.h, z1.b
193+
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

0 commit comments

Comments
 (0)