1// Copyright 2016, VIXL authors 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are met: 6// 7// * Redistributions of source code must retain the above copyright notice, 8// this list of conditions and the following disclaimer. 9// * Redistributions in binary form must reproduce the above copyright notice, 10// this list of conditions and the following disclaimer in the documentation 11// and/or other materials provided with the distribution. 12// * Neither the name of ARM Limited nor the names of its contributors may be 13// used to endorse or promote products derived from this software without 14// specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27// Test description for instructions of the following forms: 28// MNEMONIC{<c>}.W <Rd>, <Rn>, <Rm> 29// MNEMONIC{<c>}.W <Rd>, SP, <Rm> 30// MNEMONIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } 31// MNEMONIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } 32// 33// MNEMONIC{<c>}.N <Rdm>, SP, <Rdm> 34// MNEMONIC{<c>}.N SP, SP, <Rm> 35// MNEMONIC{<c>}.N <Rd>, <Rn>, <Rm> 36// MNEMONIC{<c>}.N <Rdn>, <Rdn>, <Rm> ; rm is not SP 37// MNEMONIC{<c>}.N <Rdn>, <Rdn>, <Rm> ; low registers 38// 39// Note that this test only covers the cases where the optional shift 40// operand is not provided. The shift operands are tested in 41// "cond-rd-rn-operand-rm-shift-amount-*-t32.json". 42 43{ 44 "mnemonics": [ 45 "Adc", // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 46 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 47 48 "Adcs", // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 49 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 50 51 "Add", // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 52 // ADD<c>{<q>} <Rdn>, <Rm> ; T2 53 // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2 54 // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1 55 // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2 56 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 57 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 58 59 "Adds", // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 60 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 61 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 62 63 "And", // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 64 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 65 66 "Ands", // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 67 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 68 69 "Bic", // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 70 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 71 72 "Bics", // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 73 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 74 75 "Eor", // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 76 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 77 78 "Eors", // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 79 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 80 81 "Orn", // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 82 83 "Orns", // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 84 85 "Orr", // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 86 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 87 88 "Orrs", // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 89 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 90 91 "Rsb", // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 92 93 "Rsbs", // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 94 95 "Sbc", // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 96 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 97 98 "Sbcs", // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 99 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 100 101 "Sub", // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 102 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 103 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 104 // SUB{<c>} {<Rd>}, SP, <Rm> ; T1 105 106 "Subs", // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1 107 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 108 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 109 110 "Sxtab", // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 111 "Sxtab16", // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 112 "Sxtah", // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 113 "Uxtab", // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 114 "Uxtab16", // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 115 "Uxtah", // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 116 117 // Shift instructions that alias to MOV. 118 // Note that we are not giving them a different input for their 119 // last operand since they are already tested in 120 // "cond-rd-operand-rn-shift-rs-t32.json". 121 // TODO: Add tests for MOV <Rd>, <Rn>, <shift>, <Rs>. 122 "Asr", // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 123 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 124 125 "Asrs", // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 126 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 127 128 "Lsl", // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 129 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 130 131 "Lsls", // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 132 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 133 134 "Lsr", // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 135 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 136 137 "Lsrs", // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 138 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 139 140 "Ror", // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 141 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 142 143 "Rors" // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 144 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2 145 ], 146 "description": { 147 "operands": [ 148 { 149 "name": "cond", 150 "type": "Condition" 151 }, 152 { 153 "name": "rd", 154 "type": "AllRegistersButPC" 155 }, 156 { 157 "name": "rn", 158 "type": "AllRegistersButPC" 159 }, 160 { 161 "name": "op", 162 "wrapper": "Operand", 163 "operands": [ 164 { 165 "name": "rm", 166 "type": "AllRegistersButPC" 167 } 168 ] 169 } 170 ], 171 "inputs": [ 172 { 173 "name": "apsr", 174 "type": "NZCV" 175 }, 176 { 177 "name": "rd", 178 "type": "Register" 179 }, 180 { 181 "name": "rn", 182 "type": "Register" 183 }, 184 { 185 "name": "rm", 186 "type": "Register" 187 } 188 ] 189 }, 190 "test-files": [ 191 { 192 "type": "assembler", 193 "test-cases": [ 194 { 195 "name": "Unconditionnal", 196 "operands": [ 197 "cond", "rd", "rn", "rm" 198 ], 199 "operand-filter": "cond == 'al'", 200 "operand-limit": 500 201 } 202 ] 203 }, 204 // Test cases where an IT instruction is allowed. 205 { 206 "name": "all-low-in-it-block", 207 "type": "assembler", 208 "mnemonics": [ 209 "Add", // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 210 "Sub" // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1 211 ], 212 "test-cases": [ 213 { 214 "name": "InITBlock", 215 "operands": [ 216 "cond", "rd", "rn", "rm" 217 ], 218 // Generate an extra IT instruction. 219 "in-it-block": "{cond}", 220 "operand-filter": "cond != 'al' and register_is_low(rd) and register_is_low(rn) and register_is_low(rm)", 221 "operand-limit": 500 222 } 223 ] 224 }, 225 { 226 "name": "all-low-rd-is-rn-in-it-block", 227 "type": "assembler", 228 "mnemonics": [ 229 "Adc", // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 230 "And", // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 231 "Asr", // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 232 "Bic", // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 233 "Eor", // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 234 "Lsl", // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 235 "Lsr", // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 236 "Orr", // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 237 "Ror", // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1 238 "Sbc" // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1 239 ], 240 "test-cases": [ 241 { 242 "name": "InITBlock", 243 "operands": [ 244 "cond", "rd", "rn", "rm" 245 ], 246 // Generate an extra IT instruction. 247 "in-it-block": "{cond}", 248 "operand-filter": "cond != 'al' and rd == rn and register_is_low(rn) and register_is_low(rm)", 249 "operand-limit": 500 250 } 251 ] 252 }, 253 { 254 "name": "rd-is-rn-in-it-block", 255 "type": "assembler", 256 "mnemonics": [ 257 "Add" // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2 258 ], 259 "test-cases": [ 260 { 261 "name": "InITBlock", 262 "operands": [ 263 "cond", "rd", "rn", "rm" 264 ], 265 // Generate an extra IT instruction. 266 "in-it-block": "{cond}", 267 "operand-filter": "cond != 'al' and rd == rn and rm != 'r13'", 268 "operand-limit": 500 269 } 270 ] 271 }, 272 // Special case for a conditional ADD instruction with rn as SP. 273 { 274 "name": "rn-is-sp-in-it-block", 275 "type": "assembler", 276 "mnemonics": [ 277 "Add" // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1 278 ], 279 "test-cases": [ 280 { 281 "name": "InITBlock", 282 "operands": [ 283 "cond", "rd", "rn", "rm" 284 ], 285 // Generate an extra IT instruction. 286 "in-it-block": "{cond}", 287 "operand-filter": "cond != 'al' and rd == rm and register_is_low(rm) and rn == 'r13'" 288 } 289 ] 290 }, 291 // Special case for a conditional ADD instruction with rd and rn as SP. 292 { 293 "name": "rd-is-rn-is-sp-in-it-block", 294 "type": "assembler", 295 "mnemonics": [ 296 "Add" // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2 297 ], 298 "test-cases": [ 299 { 300 "name": "InITBlock", 301 "operands": [ 302 "cond", "rd", "rn", "rm" 303 ], 304 // Generate an extra IT instruction. 305 "in-it-block": "{cond}", 306 "operand-filter": "cond != 'al' and rd == 'r13' and rn == 'r13'" 307 } 308 ] 309 }, 310 { 311 "type": "simulator", 312 "test-cases": [ 313 { 314 "name": "Condition", 315 "operands": [ 316 "cond" 317 ], 318 "inputs": [ 319 "apsr" 320 ] 321 }, 322 // Test combinations of registers values with rd == rn. 323 { 324 "name": "RdIsRn", 325 "operands": [ 326 "cond", "rd", "rn", "rm" 327 ], 328 "inputs": [ 329 "apsr", "rd", "rn", "rm" 330 ], 331 "operand-filter": "rd == rn and rn != rm", 332 "operand-limit": 10, 333 "input-filter": "rd == rn", 334 "input-limit": 200 335 }, 336 // Test combinations of registers values with rd == rm. 337 { 338 "name": "RdIsRm", 339 "operands": [ 340 "cond", "rd", "rn", "rm" 341 ], 342 "inputs": [ 343 "apsr", "rd", "rn", "rm" 344 ], 345 "operand-filter": "rd == rm and rn != rm", 346 "operand-limit": 10, 347 "input-filter": "rd == rm", 348 "input-limit": 200 349 }, 350 // Test combinations of registers values. 351 { 352 "name": "RdIsNotRnIsNotRm", 353 "operands": [ 354 "cond", "rd", "rn", "rm" 355 ], 356 "inputs": [ 357 "apsr", "rd", "rn", "rm" 358 ], 359 "operand-filter": "rd != rn != rm", 360 "operand-limit": 10, 361 "input-limit": 200 362 } 363 ] 364 } 365 ] 366} 367