Home | History | Annotate | Download | only in aarch64
      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 
    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