Add support for AArch32 CRC instruction in ARMv8.
authorKyrylo Tkachov <ktkachov@sourceware.org>
Mon, 11 Mar 2013 11:09:33 +0000 (11:09 +0000)
committerKyrylo Tkachov <ktkachov@sourceware.org>
Mon, 11 Mar 2013 11:09:33 +0000 (11:09 +0000)
gas/ChangeLog
2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* config/tc-arm.c (crc_ext_armv8): New feature set.
(UNPRED_REG): New macro.
(do_crc32_1): New function.
(do_crc32b, do_crc32h, do_crc32w, do_crc32cb,
do_crc32ch, do_crc32cw): Likewise.
(TUEc): New macro.
(insns): Add entries for crc32 mnemonics.
(arm_extensions): Add entry for crc.

include/opcode/ChangeLog
2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* arm.h (CRC_EXT_ARMV8): New constant.
(ARCH_CRC_ARMV8): New macro.

opcodes/ChangeLog
2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* arm-dis.c (arm_opcodes): Add entries for CRC instructions.
(thumb32_opcodes): Likewise.
(print_insn_thumb32): Handle 'S' control char.

gas/testsuite/ChangeLog
2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* gas/arm/crc32-bad.d: New file.
* gas/arm/crc32-bad.l: Likewise.
* gas/arm/crc32-bad.s: Likewise.
* gas/arm/crc32.d: Likewise.
* gas/arm/crc32.s: Likewise.

12 files changed:
gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/crc32-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/crc32-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/crc32-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/crc32.d [new file with mode: 0644]
gas/testsuite/gas/arm/crc32.s [new file with mode: 0644]
include/opcode/ChangeLog
include/opcode/arm.h
opcodes/ChangeLog
opcodes/arm-dis.c

index ce3be4b..de1a91e 100644 (file)
@@ -1,3 +1,14 @@
+2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/tc-arm.c (crc_ext_armv8): New feature set.
+       (UNPRED_REG): New macro.
+       (do_crc32_1): New function.
+       (do_crc32b, do_crc32h, do_crc32w, do_crc32cb,
+       do_crc32ch, do_crc32cw): Likewise.
+       (TUEc): New macro.
+       (insns): Add entries for crc32 mnemonics.
+       (arm_extensions): Add entry for crc.
+
 2013-03-08  Chung-Lin Tang  <cltang@codesourcery.com>
 
        * write.h (struct fix): Add fx_dot_frag field.
index 51ab230..ff8505c 100644 (file)
@@ -238,6 +238,8 @@ static const arm_feature_set fpu_neon_ext_armv8 =
   ARM_FEATURE (0, FPU_NEON_EXT_ARMV8);
 static const arm_feature_set fpu_crypto_ext_armv8 =
   ARM_FEATURE (0, FPU_CRYPTO_EXT_ARMV8);
+static const arm_feature_set crc_ext_armv8 =
+  ARM_FEATURE (0, CRC_EXT_ARMV8);
 
 static int mfloat_abi_opt = -1;
 /* Record user cpu selection for object attributes.  */
@@ -748,6 +750,7 @@ struct asm_opcode
 #define BAD_PC_WRITEBACK \
        _("cannot use writeback with PC-relative addressing")
 #define BAD_RANGE     _("branch out of range")
+#define UNPRED_REG(R)  _("using " R " results in unpredictable behaviour")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -16314,6 +16317,63 @@ do_sha256su0 (void)
 {
   do_crypto_2op_1 (N_32, 1);
 }
+
+static void
+do_crc32_1 (unsigned int poly, unsigned int sz)
+{
+  unsigned int Rd = inst.operands[0].reg;
+  unsigned int Rn = inst.operands[1].reg;
+  unsigned int Rm = inst.operands[2].reg;
+
+  set_it_insn_type (OUTSIDE_IT_INSN);
+  inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
+  inst.instruction |= LOW4 (Rn) << 16;
+  inst.instruction |= LOW4 (Rm);
+  inst.instruction |= sz << (thumb_mode ? 4 : 21);
+  inst.instruction |= poly << (thumb_mode ? 20 : 9);
+
+  if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
+    as_warn (UNPRED_REG ("r15"));
+  if (thumb_mode && (Rd == REG_SP || Rn == REG_SP || Rm == REG_SP))
+    as_warn (UNPRED_REG ("r13"));
+}
+
+static void
+do_crc32b (void)
+{
+  do_crc32_1 (0, 0);
+}
+
+static void
+do_crc32h (void)
+{
+  do_crc32_1 (0, 1);
+}
+
+static void
+do_crc32w (void)
+{
+  do_crc32_1 (0, 2);
+}
+
+static void
+do_crc32cb (void)
+{
+  do_crc32_1 (1, 0);
+}
+
+static void
+do_crc32ch (void)
+{
+  do_crc32_1 (1, 1);
+}
+
+static void
+do_crc32cw (void)
+{
+  do_crc32_1 (1, 2);
+}
+
 \f
 /* Overall per-instruction processing. */
 
@@ -17799,6 +17859,13 @@ static struct asm_barrier_opt barrier_opt_names[] =
   { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
     THUMB_VARIANT, do_##ae, do_##te }
 
+/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
+   Used by mnemonics that have very minimal differences in the encoding for
+   ARM and Thumb variants and can be handled in a common function.  */
+#define TUEc(mnem, op, top, nops, ops, en) \
+  { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
+    THUMB_VARIANT, do_##en, do_##en }
+
 /* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
    condition code field.  */
 #define TUF(mnem, op, top, nops, ops, ae, te)                          \
@@ -18537,6 +18604,17 @@ static const struct asm_opcode insns[] =
   nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
 
 #undef  ARM_VARIANT
+#define ARM_VARIANT & crc_ext_armv8
+#undef  THUMB_VARIANT
+#define THUMB_VARIANT & crc_ext_armv8
+  TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
+  TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
+  TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
+  TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
+  TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
+  TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
+
+#undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_fpa_ext_v1  /* Core FPA instruction set (V1).  */
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT NULL
@@ -23991,6 +24069,7 @@ struct arm_option_extension_value_table
 #define ARM_EXT_OPT(N, V, AA) { N, sizeof (N) - 1, V, AA }
 static const struct arm_option_extension_value_table arm_extensions[] =
 {
+  ARM_EXT_OPT ("crc",  ARCH_CRC_ARMV8, ARM_FEATURE (ARM_EXT_V8, 0)),
   ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
                                   ARM_FEATURE (ARM_EXT_V8, 0)),
   ARM_EXT_OPT ("fp",     FPU_ARCH_VFP_ARMV8,
index d89f44f..7b2cdab 100644 (file)
@@ -1,3 +1,11 @@
+2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gas/arm/crc32-bad.d: New file.
+       * gas/arm/crc32-bad.l: Likewise.
+       * gas/arm/crc32-bad.s: Likewise.
+       * gas/arm/crc32.d: Likewise.
+       * gas/arm/crc32.s: Likewise.
+
 2013-03-05  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        * gas/aarch64/diagnostic.s: Add test.
diff --git a/gas/testsuite/gas/arm/crc32-bad.d b/gas/testsuite/gas/arm/crc32-bad.d
new file mode 100644 (file)
index 0000000..34e0b6c
--- /dev/null
@@ -0,0 +1,21 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: Unpredictable ARMv8 CRC32 instructions.
+#as: -march=armv8-a+crc
+#stderr: crc32-bad.l
+
+.*: +file format .*arm.*
+
+
+Disassembly of section .text:
+0+0 <[^>]*> e101f042   crc32b  pc, r1, r2      ; <UNPREDICTABLE>
+0+4 <[^>]*> e12f0042   crc32h  r0, pc, r2      ; <UNPREDICTABLE>
+0+8 <[^>]*> e141004f   crc32w  r0, r1, pc      ; <UNPREDICTABLE>
+0+c <[^>]*> e10f0242   crc32cb r0, pc, r2      ; <UNPREDICTABLE>
+0+10 <[^>]*> e121f242  crc32ch pc, r1, r2      ; <UNPREDICTABLE>
+0+14 <[^>]*> e14f0242  crc32cw r0, pc, r2      ; <UNPREDICTABLE>
+0+18 <[^>]*> fac1 fd82         crc32b  sp, r1, r2      ; <UNPREDICTABLE>
+0+1c <[^>]*> facf f092         crc32h  r0, pc, r2      ; <UNPREDICTABLE>
+0+20 <[^>]*> fac1 f0ad         crc32w  r0, r1, sp      ; <UNPREDICTABLE>
+0+24 <[^>]*> fadf f082         crc32cb r0, pc, r2      ; <UNPREDICTABLE>
+0+28 <[^>]*> fad1 fd92         crc32ch sp, r1, r2      ; <UNPREDICTABLE>
+0+2c <[^>]*> fadf f0a2         crc32cw r0, pc, r2      ; <UNPREDICTABLE>
diff --git a/gas/testsuite/gas/arm/crc32-bad.l b/gas/testsuite/gas/arm/crc32-bad.l
new file mode 100644 (file)
index 0000000..ea520aa
--- /dev/null
@@ -0,0 +1,13 @@
+[^:]*: Assembler messages:
+[^:]*:4: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:5: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:6: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:7: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:8: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:9: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:12: Warning: using r13 results in unpredictable behaviour
+[^:]*.s:13: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:14: Warning: using r13 results in unpredictable behaviour
+[^:]*.s:15: Warning: using r15 results in unpredictable behaviour
+[^:]*.s:16: Warning: using r13 results in unpredictable behaviour
+[^:]*.s:17: Warning: using r15 results in unpredictable behaviour
diff --git a/gas/testsuite/gas/arm/crc32-bad.s b/gas/testsuite/gas/arm/crc32-bad.s
new file mode 100644 (file)
index 0000000..4e497e3
--- /dev/null
@@ -0,0 +1,17 @@
+.section .text
+.syntax unified
+.arm
+crc32b r15, r1, r2
+crc32h r0, r15, r2
+crc32w r0, r1, r15
+crc32cb r0, r15, r2
+crc32ch r15, r1, r2
+crc32cw r0, r15, r2
+
+.thumb
+crc32b r13, r1, r2
+crc32h r0, r15, r2
+crc32w r0, r1, r13
+crc32cb r0, r15, r2
+crc32ch r13, r1, r2
+crc32cw r0, r15, r2
diff --git a/gas/testsuite/gas/arm/crc32.d b/gas/testsuite/gas/arm/crc32.d
new file mode 100644 (file)
index 0000000..e511f5e
--- /dev/null
@@ -0,0 +1,21 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: ARMv8 CRC32 instructions
+#as: -march=armv8-a+crc
+
+.*: *file format .*arm.*
+
+
+Disassembly of section .text:
+0+0 <[^>]*> e1010042   crc32b  r0, r1, r2
+0+4 <[^>]*> e1210042   crc32h  r0, r1, r2
+0+8 <[^>]*> e1410042   crc32w  r0, r1, r2
+0+c <[^>]*> e1010242   crc32cb r0, r1, r2
+0+10 <[^>]*> e1210242  crc32ch r0, r1, r2
+0+14 <[^>]*> e1410242  crc32cw r0, r1, r2
+0+18 <[^>]*> fac1 f082         crc32b  r0, r1, r2
+0+1c <[^>]*> fac1 f092         crc32h  r0, r1, r2
+0+20 <[^>]*> fac1 f0a2         crc32w  r0, r1, r2
+0+24 <[^>]*> fad1 f082         crc32cb r0, r1, r2
+0+28 <[^>]*> fad1 f092         crc32ch r0, r1, r2
+0+2c <[^>]*> fad1 f0a2         crc32cw r0, r1, r2
+
diff --git a/gas/testsuite/gas/arm/crc32.s b/gas/testsuite/gas/arm/crc32.s
new file mode 100644 (file)
index 0000000..63c1d68
--- /dev/null
@@ -0,0 +1,17 @@
+.section .text
+.syntax unified
+.arm
+crc32b r0, r1, r2
+crc32h r0, r1, r2
+crc32w r0, r1, r2
+crc32cb r0, r1, r2
+crc32ch r0, r1, r2
+crc32cw r0, r1, r2
+
+.thumb
+crc32b r0, r1, r2
+crc32h r0, r1, r2
+crc32w r0, r1, r2
+crc32cb r0, r1, r2
+crc32ch r0, r1, r2
+crc32cw r0, r1, r2
index fc2b40e..a46900a 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * arm.h (CRC_EXT_ARMV8): New constant.
+       (ARCH_CRC_ARMV8): New macro.
+
 2013-02-28  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        * aarch64.h (AARCH64_FEATURE_CRC): New macro.
index 1ac38a0..851fd3c 100644 (file)
@@ -81,6 +81,7 @@
 #define FPU_VFP_EXT_ARMV8 0x00020000   /* FP for ARMv8.  */
 #define FPU_NEON_EXT_ARMV8 0x00010000  /* Neon for ARMv8.  */
 #define FPU_CRYPTO_EXT_ARMV8 0x00008000        /* Crypto for ARMv8.  */
+#define CRC_EXT_ARMV8   0x00004000     /* CRC32 for ARMv8.  */
 
 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
 #define FPU_ARCH_NEON_VFP_ARMV8 ARM_FEATURE(0, FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
 #define FPU_ARCH_CRYPTO_NEON_VFP_ARMV8 \
   ARM_FEATURE(0, FPU_CRYPTO_ARMV8 | FPU_NEON_ARMV8 | FPU_VFP_ARMV8)
+#define ARCH_CRC_ARMV8 ARM_FEATURE(0, CRC_EXT_ARMV8)
 
 #define FPU_ARCH_ENDIAN_PURE ARM_FEATURE (0, FPU_ENDIAN_PURE)
 
index f311e1d..d7fe4a5 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-11  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * arm-dis.c (arm_opcodes): Add entries for CRC instructions.
+       (thumb32_opcodes): Likewise.
+       (print_insn_thumb32): Handle 'S' control char.
+
 2013-03-08  Yann Sionneau  <yann.sionneau@gmail.com>
 
        * lm32-desc.c: Regenerate.
index ad7a67f..0b1ed1a 100644 (file)
@@ -903,6 +903,13 @@ static const struct opcode32 arm_opcodes[] =
   {ARM_EXT_V8,  0x01d00c9f, 0x0ff00fff, "ldab%c\t%12-15r, [%16-19R]"},
   {ARM_EXT_V8,  0x01e0fc90, 0x0ff0fff0, "stlh%c\t%0-3r, [%16-19R]"},
   {ARM_EXT_V8,  0x01f00c9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
+  /* CRC32 instructions.  */
+  {CRC_EXT_ARMV8, 0xe1000040, 0xfff00ff0, "crc32b\t%12-15R, %16-19R, %0-3R"},
+  {CRC_EXT_ARMV8, 0xe1200040, 0xfff00ff0, "crc32h\t%12-15R, %16-19R, %0-3R"},
+  {CRC_EXT_ARMV8, 0xe1400040, 0xfff00ff0, "crc32w\t%12-15R, %16-19R, %0-3R"},
+  {CRC_EXT_ARMV8, 0xe1000240, 0xfff00ff0, "crc32cb\t%12-15R, %16-19R, %0-3R"},
+  {CRC_EXT_ARMV8, 0xe1200240, 0xfff00ff0, "crc32ch\t%12-15R, %16-19R, %0-3R"},
+  {CRC_EXT_ARMV8, 0xe1400240, 0xfff00ff0, "crc32cw\t%12-15R, %16-19R, %0-3R"},
 
   /* Virtualization Extension instructions.  */
   {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
@@ -1455,7 +1462,8 @@ static const struct opcode16 thumb_opcodes[] =
        %<bitfield>d    print bitfield in decimal
        %<bitfield>W    print bitfield*4 in decimal
        %<bitfield>r    print bitfield as an ARM register
-       %<bitfield>R    as %<>r bit r15 is UNPREDICTABLE
+       %<bitfield>R    as %<>r but r15 is UNPREDICTABLE
+       %<bitfield>S    as %<>R but r13 is UNPREDICTABLE
        %<bitfield>c    print bitfield as a condition code
 
        %<bitfield>'c   print specified char iff bitfield is all ones
@@ -1490,6 +1498,14 @@ static const struct opcode32 thumb32_opcodes[] =
   {ARM_EXT_V8, 0xe8d00fef, 0xfff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
   {ARM_EXT_V8, 0xe8d000ff, 0xfff000ff, "ldaexd%c\t%12-15r, %8-11r, [%16-19R]"},
 
+  /* CRC32 instructions.  */
+  {CRC_EXT_ARMV8, 0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11S, %16-19S, %0-3S"},
+  {CRC_EXT_ARMV8, 0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11S, %16-19S, %0-3S"},
+  {CRC_EXT_ARMV8, 0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11S, %16-19S, %0-3S"},
+  {CRC_EXT_ARMV8, 0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11S, %16-19S, %0-3S"},
+  {CRC_EXT_ARMV8, 0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11S, %16-19S, %0-3S"},
+  {CRC_EXT_ARMV8, 0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11S, %16-19S, %0-3S"},
+
   /* V7 instructions.  */
   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
@@ -4427,6 +4443,10 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
                      value_in_comment = val * 4;
                      break;
 
+                   case 'S':
+                     if (val == 13)
+                       is_unpredictable = TRUE;
+                     /* Fall through.  */
                    case 'R':
                      if (val == 15)
                        is_unpredictable = TRUE;