diff --git a/binutils/testsuite/binutils-all/aarch64/aarch64.exp b/binutils/testsuite/binutils-all/aarch64/aarch64.exp new file mode 100644 index 0000000..e189711 --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/aarch64.exp @@ -0,0 +1,30 @@ +# Copyright (C) 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +if {![istarget "aarch64*-*-*"] + || ![is_elf_format]} then { + return +} + +set tempfile tmpdir/aarch64temp.o +set copyfile tmpdir/aarch64copy + +set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]] +foreach t $test_list { + # We need to strip the ".d", but can leave the dirname. + verbose [file rootname $t] + run_dump_test [file rootname $t] +} diff --git a/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.d b/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.d new file mode 100644 index 0000000..64063e2 --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.d @@ -0,0 +1,29 @@ +#PROG: objcopy +#objdump: -dr +#name: Disassembler detects unallocated instruction encodings. + +.*: +file format .*aarch64.* + +Disassembly of section \.text: + +0000000000000000 <.*>: + 0: 0d0047de .inst 0x0d0047de ; undefined + 4: 0d2047dd .inst 0x0d2047dd ; undefined + 8: 0d0067dc .inst 0x0d0067dc ; undefined + c: 0d2067db .inst 0x0d2067db ; undefined + 10: 0d008bde .inst 0x0d008bde ; undefined + 14: 0d208bdd .inst 0x0d208bdd ; undefined + 18: 0d00abdc .inst 0x0d00abdc ; undefined + 1c: 0d20abdb .inst 0x0d20abdb ; undefined + 20: 0d008fde .inst 0x0d008fde ; undefined + 24: 0d208fdd .inst 0x0d208fdd ; undefined + 28: 0d00afdc .inst 0x0d00afdc ; undefined + 2c: 0d20afdb .inst 0x0d20afdb ; undefined + 30: 0d0097de .inst 0x0d0097de ; undefined + 34: 0d2097dd .inst 0x0d2097dd ; undefined + 38: 0d00b7dc .inst 0x0d00b7dc ; undefined + 3c: 0d20b7db .inst 0x0d20b7db ; undefined + 40: 0d009fde .inst 0x0d009fde ; undefined + 44: 0d209fdd .inst 0x0d209fdd ; undefined + 48: 0d00bfdc .inst 0x0d00bfdc ; undefined + 4c: 0d20bfdb .inst 0x0d20bfdb ; undefined diff --git a/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.s b/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.s new file mode 100644 index 0000000..fb96adc --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/unallocated-encoding.s @@ -0,0 +1,51 @@ + .text +func: + //scale 1, size<0> check for H. + #st1 {v30.h}[0], [x30] + .inst 0x0d0043de | (1 << 10) + #st2 {v29.h, v30.h}[0], [x30] + .inst 0x0d2043dd | (1 << 10) + #st3 {v28.h, v29.h, v30.h}[0], [x30] + .inst 0x0d0063dc | (1 << 10) + #st4 {v27.h, v28.h, v29.h, v30.h}[0], [x30] + .inst 0x0d2063db | (1 << 10) + + //scale 2, size<1> check for S. + #st1 {v30.s}[0], [x30] + .inst 0x0d0083de | (1 << 11) + #st2 {v29.s, v30.s}[0], [x30] + .inst 0x0d2083dd | (1 << 11) + #st3 {v28.s, v29.s, v30.s}[0], [x30] + .inst 0x0d00a3dc | (1 << 11) + #st4 {v27.s, v28.s, v29.s, v30.s}[0], [x30] + .inst 0x0d20a3db | (1 << 11) + + //scale 2, size<1> check for D. + #st1 {v30.d}[0], [x30] + .inst 0x0d0087de | (1 << 11) + #st2 {v29.d, v30.d}[0], [x30] + .inst 0x0d2087dd | (1 << 11) + #st3 {v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d00a7dc | (1 << 11) + #st4 {v27.d, v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d20a7db | (1 << 11) + + //scale 2, S-bit check for D. + #st1 {v30.d}[0], [x30] + .inst 0x0d0087de | (2 << 11) + #st2 {v29.d, v30.d}[0], [x30] + .inst 0x0d2087dd | (2 << 11) + #st3 {v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d00a7dc | (2 << 11) + #st4 {v27.d, v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d20a7db | (2 << 11) + + //scale 2, size<1> & S-bit check for D. + #st1 {v30.d}[0], [x30] + .inst 0x0d0087de | (3 << 11) + #st2 {v29.d, v30.d}[0], [x30] + .inst 0x0d2087dd | (3 << 11) + #st3 {v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d00a7dc | (3 << 11) + #st4 {v27.d, v28.d, v29.d, v30.d}[0], [x30] + .inst 0x0d20a7db | (3 << 11) diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 477edb6..c3670fe 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -422,11 +422,17 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, info->reglist.index = QSsize; break; case 0x1: + if (QSsize & 0x1) + /* UND. */ + return 0; info->qualifier = AARCH64_OPND_QLF_S_H; /* Index encoded in "Q:S:size<1>". */ info->reglist.index = QSsize >> 1; break; case 0x2: + if ((QSsize >> 1) & 0x1) + /* UND. */ + return 0; if ((QSsize & 0x1) == 0) { info->qualifier = AARCH64_OPND_QLF_S_S; @@ -435,12 +441,12 @@ aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED, } else { - info->qualifier = AARCH64_OPND_QLF_S_D; - /* Index encoded in "Q". */ - info->reglist.index = QSsize >> 3; if (extract_field (FLD_S, code, 0)) /* UND */ return 0; + info->qualifier = AARCH64_OPND_QLF_S_D; + /* Index encoded in "Q". */ + info->reglist.index = QSsize >> 3; } break; default: