]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/testsuite/gas/aarch64/addsub.s
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / testsuite / gas / aarch64 / addsub.s
1 /* addsub.s Test file for AArch64 add-subtract instructions.
2
3 Copyright (C) 2012-2021 Free Software Foundation, Inc.
4 Contributed by ARM Ltd.
5
6 This file is part of GAS.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the license, or
11 (at your option) any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING3. If not,
20 see <http://www.gnu.org/licenses/>. */
21
22 // TODO: also cover the addsub_imm instructions.
23
24 /*
25 * Adjust Rm
26 */
27 .macro adjust_rm op, rd, rn, rm_r, rm_n, extend, amount
28 // for 64-bit instruction, Rm is Xm when <extend> is explicitely
29 // or implicitly UXTX, SXTX or LSL; otherwise it Wm.
30 .ifc \rm_r, X
31 .ifnc \extend, UXTX
32 .ifnc \extend, SXTX
33 .ifnc \extend, LSL
34 .ifb \amount
35 \op \rd, \rn, W\()\rm_n, \extend
36 .else
37 \op \rd, \rn, W\()\rm_n, \extend #\amount
38 .endif
39 .exitm
40 .endif
41 .endif
42 .endif
43 .endif
44
45 .ifb \amount
46 \op \rd, \rn, \rm_r\()\rm_n, \extend
47 .else
48 \op \rd, \rn, \rm_r\()\rm_n, \extend #\amount
49 .endif
50 .endm
51
52 /*
53 * Emitting addsub_ext instruction
54 */
55 .macro do_addsub_ext type, op, Rn, reg, extend, amount
56 .ifc \type, 0
57 // normal add/adds/sub/subs
58 .ifb \extend
59 \op \reg\()16, \Rn, \reg\()1
60 .else
61 .ifb \amount
62 adjust_rm \op, \reg\()16, \Rn, \reg, 1, \extend
63 .else
64 adjust_rm \op, \reg\()16, \Rn, \reg, 1, \extend, \amount
65 .endif
66 .endif
67 .else
68 .ifc \type, 1
69 // adds/subs with ZR as Rd
70 .ifb \extend
71 \op \reg\()ZR, \Rn, \reg\()1
72 .else
73 .ifb \amount
74 adjust_rm \op, \reg\()ZR, \Rn, \reg, 1, \extend
75 .else
76 adjust_rm \op, \reg\()ZR, \Rn, \reg, 1, \extend, \amount
77 .endif
78 .endif
79 .else
80 // cmn/cmp
81 .ifb \extend
82 \op \Rn, \reg\()1
83 .else
84 .ifb \amount
85 \op \Rn, \reg\()1, \extend
86 .else
87 \op \Rn, \reg\()1, \extend #\amount
88 .endif
89 .endif
90 .endif
91 .endif
92 .endm
93
94 /*
95 * Optional extension and optional shift amount
96 */
97 .macro do_extend type, op, Rn, reg
98 // <extend> absent
99 // note that when SP is not used, the GAS will encode it as addsub_shift
100 do_addsub_ext \type, \op, \Rn, \reg
101 // optional absent <amount>
102 .irp extend, UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW, SXTX
103 .irp amount, , 0, 1, 2, 3, 4
104 do_addsub_ext \type, \op, \Rn, \reg, \extend, \amount
105 .endr
106 .endr
107 // when <extend> is LSL, <amount> cannot be absent
108 // note that when SP is not used, the GAS will encode it as addsub_shift
109 .irp amount, 0, 1, 2, 3, 4
110 do_addsub_ext \type, \op, \Rn, \reg, LSL, \amount
111 .endr
112 .endm
113
114 /*
115 * Leaf macro emitting addsub_shift instruction
116 */
117 .macro do_addsub_shift type, op, R, reg, shift, amount
118 .ifc \type, 0
119 // normal add/adds/sub/subs
120 .ifb \shift
121 \op \reg\()16, \R, \reg\()1
122 .else
123 \op \reg\()16, \R, \reg\()1, \shift #\amount
124 .endif
125 .else
126 .ifc \type, 1
127 // adds/subs with ZR as Rd
128 .ifb \shift
129 \op \reg\()ZR, \R, \reg\()1
130 .else
131 \op \reg\()ZR, \R, \reg\()1, \shift #\amount
132 .endif
133 .else
134 .ifc \type, 2
135 // cmn/cmp/neg/negs
136 .ifb \shift
137 \op \R, \reg\()1
138 .else
139 \op \R, \reg\()1, \shift #\amount
140 .endif
141 .else
142 // sub/subs with ZR as Rn
143 .ifb \shift
144 \op \R, \reg\()ZR, \reg\()1
145 .else
146 \op \R, \reg\()ZR, \reg\()1, \shift #\amount
147 .endif
148 .endif
149 .endif
150 .endif
151 .endm
152
153 /*
154 * Optional shift and optional shift amount
155 */
156 .macro do_shift type, op, R, reg
157 // <shift> absent
158 do_addsub_shift \type, \op, \R, \reg
159 // optional absent <amount>
160 .irp shift, LSL, LSR, ASR
161 .irp amount, 0, 1, 2, 3, 4, 5, 16, 31
162 // amount cannot be absent when shift is present.
163 do_addsub_shift \type, \op, \R, \reg, \shift, \amount
164 .endr
165 .ifc \reg, X
166 do_addsub_shift \type, \op, \R, \reg, \shift, 63
167 .endif
168 .endr
169 .endm
170
171 func:
172 /*
173 * Add-subtract (extended register)
174 */
175
176 .irp op, ADD, ADDS, SUB, SUBS
177 do_extend 0, \op, W7, W
178 do_extend 0, \op, WSP, W
179 do_extend 0, \op, X7, X
180 do_extend 0, \op, SP, X
181 .endr
182
183 .irp op, ADDS, SUBS
184 do_extend 1, \op, W7, W
185 do_extend 1, \op, WSP, W
186 do_extend 1, \op, X7, X
187 do_extend 1, \op, SP, X
188 .endr
189
190 .irp op, CMN, CMP
191 do_extend 2, \op, W7, W
192 do_extend 2, \op, WSP, W
193 do_extend 2, \op, X7, X
194 do_extend 2, \op, SP, X
195 .endr
196
197 /*
198 * Add-subtract (shift register)
199 */
200
201 .irp op, ADD, ADDS, SUB, SUBS
202 do_shift 0, \op, W7, W
203 do_shift 0, \op, X7, X
204 .endr
205
206 .irp op, ADDS, SUBS
207 do_shift 1, \op, W7, W
208 do_shift 1, \op, X7, X
209 .endr
210
211 .irp op, CMN, CMP
212 do_shift 2, \op, W7, W
213 do_shift 2, \op, X7, X
214 .endr
215
216 .irp op, SUB, SUBS
217 do_shift 3, \op, W7, W
218 do_shift 3, \op, X7, X
219 .endr
220
221 .irp op, NEG, NEGS
222 do_shift 2, \op, W7, W
223 do_shift 2, \op, X7, X
224 .endr
225
226 /*
227 * Check for correct aliasing
228 */
229
230 .irp op, NEGS
231 do_shift 2, \op, WZR, W
232 do_shift 2, \op, XZR, X
233 .endr
234
235 .irp op, SUBS
236 do_shift 3, \op, W7, W
237 do_shift 3, \op, X7, X
238 do_shift 0, \op, WZR, W
239 do_shift 0, \op, XZR, X
240 .endr