1/* addsub.s Test file for AArch64 add-subtract instructions. 2 3 Copyright (C) 2012-2016 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 171func: 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