1// Some simple operations on S, D and Q registers (loads, stores and moves) are
2// also avaliable in MVE, even in the integer-only version. Some of these
3// instructions (operating on D or Q registers, or FP16 values) are only
4// available for certain targets.
5
6// Note that it's not always obvious which instructions are available, for
7// example several instructions operating on D registers are available for
8// single-precision only FPUs.
9
10// All of these instructions are rejected if no VFP or MVE features are
11// present.
12// RUN: not llvm-mc -triple=thumbv8.1m.main -show-encoding 2>%t < %s
13// RUN: FileCheck %s < %t --check-prefix=NOFP16 --check-prefix=NOFP32 --check-prefix=NOFP64
14
15// VFP and NEON implementations by default have FP32 and FP64, but not FP16.
16// The VFPv3 FP16 extension just added conversion instructions, which we don't
17// care about here.
18// RUN: not llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+vfp2 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP32 --check-prefix=FP64
19// RUN: FileCheck %s < %t --check-prefix=NOFP16
20// RUN: not llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+fp-armv8,+neon 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP32 --check-prefix=FP64
21// RUN: FileCheck %s < %t --check-prefix=NOFP16
22
23// The v8.2A FP16 extension added loads, stores and moves for FP16.
24// RUN: llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+fp-armv8,+fullfp16 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP16 --check-prefix=FP32 --check-prefix=FP64
25
26// M-profile FPUs (e.g. Cortex-M4/M7/M33) do not have FP16 instructions, and
27// the FP64 instructions are optional. They are also limited to 16 D registers,
28// but we don't test that here.
29// RUN: not llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+vfp4d16sp 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP32
30// RUN: FileCheck %s < %t --check-prefix=NOFP16 --check-prefix=NOFP64
31// RUN: not llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+vfp4,-d32 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP32 --check-prefix=FP64
32// RUN: FileCheck %s < %t --check-prefix=NOFP16
33
34// Integer-only MVE, which can be combined with different options for scalar
35// FPU (or lack thereof), and has all of the move and store instructions
36// regardless of the scalar FPU.
37// RUN: llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+mve 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP16 --check-prefix=FP32 --check-prefix=FP64
38// RUN: llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+mve,+fp-armv8-sp,+fullfp16 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP16 --check-prefix=FP32 --check-prefix=FP64
39// RUN: llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+mve,+fp-armv8,+fullfp16 2>%t < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP16 --check-prefix=FP32 --check-prefix=FP64
40
41// Maximal v8.1M target: MVE with FP, and scalar FP with double-precision.
42// RUN: llvm-mc -triple=thumbv8.1m.main -show-encoding -mattr=+mve.fp < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FP16 --check-prefix=FP32 --check-prefix=FP64
43
44vldmia  r0, {d0}
45# FP32: vldmia  r0, {d0}               @ encoding: [0x90,0xec,0x02,0x0b]
46# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
47
48vpop    {d0-d15}
49# FP32: vpop {{.*}}                     @ encoding: [0xbd,0xec,0x20,0x0b]
50# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
51
52vpop.64    {d0-d15}
53# FP32: vpop {{.*}}                     @ encoding: [0xbd,0xec,0x20,0x0b]
54# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
55
56vstmia  r0, {d0}
57# FP32: vstmia  r0, {d0}                @ encoding: [0x80,0xec,0x02,0x0b]
58# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
59
60vpush    {d0-d15}
61# FP32: vpush {{.*}}                    @ encoding: [0x2d,0xed,0x20,0x0b]
62# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
63
64vpush.64    {d0-d15}
65# FP32: vpush {{.*}}                    @ encoding: [0x2d,0xed,0x20,0x0b]
66# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
67
68vldmia  r0, {s0}
69# FP32: vldmia  r0, {s0}                @ encoding: [0x90,0xec,0x01,0x0a]
70# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
71
72vpop {s0-s31}
73# FP32: vpop {{.*}}                     @ encoding: [0xbd,0xec,0x20,0x0a]
74# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
75
76vpop.32 {s0-s31}
77# FP32: vpop {{.*}}                     @ encoding: [0xbd,0xec,0x20,0x0a]
78# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
79
80vstmia  r0, {s0}
81# FP32: vstmia  r0, {s0}                @ encoding: [0x80,0xec,0x01,0x0a]
82# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
83
84vpush {s0-s31}
85# FP32: vpush {{.*}}                    @ encoding: [0x2d,0xed,0x20,0x0a]
86# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
87
88vpush.32 {s0-s31}
89# FP32: vpush {{.*}}                    @ encoding: [0x2d,0xed,0x20,0x0a]
90# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
91
92fldmdbx r0!, {d0}
93# FP32: fldmdbx r0!, {d0}               @ encoding: [0x30,0xed,0x03,0x0b]
94# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
95
96fstmiax r0, {d0}
97# FP32: fstmiax r0, {d0}                @ encoding: [0x80,0xec,0x03,0x0b]
98# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
99
100vldr.16 s0, [r0]
101# FP16: vldr.16 s0, [r0]                @ encoding: [0x90,0xed,0x00,0x09]
102# NOFP16: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: 16-bit fp registers
103
104vldr s0, [r0]
105# FP32: vldr    s0, [r0]                @ encoding: [0x90,0xed,0x00,0x0a]
106# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
107
108vldr d0, [r0]
109# FP32: vldr    d0, [r0]                @ encoding: [0x90,0xed,0x00,0x0b]
110# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
111
112vstr.16 s0, [r0]
113# FP16: vstr.16 s0, [r0]                @ encoding: [0x80,0xed,0x00,0x09]
114# NOFP16: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: 16-bit fp registers
115
116vstr s0, [r0]
117# FP32: vstr    s0, [r0]                @ encoding: [0x80,0xed,0x00,0x0a]
118# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
119
120vstr d0, [r0]
121# FP32: vstr    d0, [r0]                @ encoding: [0x80,0xed,0x00,0x0b]
122# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
123
124vmov.f16 r0, s0
125# FP16: vmov.f16        r0, s0          @ encoding: [0x10,0xee,0x10,0x09]
126# NOFP16: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: 16-bit fp registers
127
128vmov.f16 s0, r0
129# FP16: vmov.f16        s0, r0          @ encoding: [0x00,0xee,0x10,0x09]
130# NOFP16: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: 16-bit fp registers
131
132vmov s0, r0
133# FP32: vmov    s0, r0                  @ encoding: [0x00,0xee,0x10,0x0a]
134# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
135
136vmov r0, s0
137# FP32: vmov    r0, s0                  @ encoding: [0x10,0xee,0x10,0x0a]
138# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
139
140vmov r0, r1, d0
141# FP32: vmov    r0, r1, d0              @ encoding: [0x51,0xec,0x10,0x0b]
142# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
143
144vmov d0, r0, r1
145# FP32: vmov    d0, r0, r1              @ encoding: [0x41,0xec,0x10,0x0b]
146# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
147
148vmov r0, r1, s0, s1
149# FP32: vmov    r0, r1, s0, s1          @ encoding: [0x51,0xec,0x10,0x0a]
150# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
151
152vmov s0, s1, r0, r1
153# FP32: vmov    s0, s1, r0, r1          @ encoding: [0x41,0xec,0x10,0x0a]
154# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
155
156vmov.f32 s0, s1
157# FP32: vmov.f32        s0, s1          @ encoding: [0xb0,0xee,0x60,0x0a]
158# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
159
160vmov.f64 d0, d1
161# FP64: vmov.f64        d0, d1          @ encoding: [0xb0,0xee,0x41,0x0b]
162# NOFP64: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: 64-bit fp registers
163
164vmov.32 r0, d1[0]
165# FP32: vmov.32 r0, d1[0]               @ encoding: [0x11,0xee,0x10,0x0b]
166# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: error: instruction requires: fp registers
167
168vmrs apsr_nzcv, fpscr
169# FP32: vmrs    APSR_nzcv, fpscr        @ encoding: [0xf1,0xee,0x10,0xfa]
170# NOFP32: :[[@LINE-2]]:{{[0-9]+}}: {{note|error}}: instruction requires: fp registers
171