(new_automatic_it_block): Likewise.
(handle_it_block): Record whether current instruction is
conditionally executed.
* gas/config/tc-arm.c (depr_insn_mask): New structure.
(depr_it_insns): New variable.
(it_fsm_post_encode): Warn on deprecated uses.
* gas/config/tc-arm.h (current_it): Add new fields.
* gas/testsuite/gas/arm/armv8-a-it-bad.d: New testcase.
* gas/testsuite/gas/arm/armv8-a-it-bad.l: Likewise.
* gas/testsuite/gas/arm/armv8-a-it-bad.s: Likewise.
* gas/testsuite/gas/arm/ldr-t-bad.s: Update testcase.
* gas/testsuite/gas/arm/ldr-t.d: Likewise.
* gas/testsuite/gas/arm/ldr-t.s: Likewise.
* gas/testsuite/gas/arm/neon-cond-bad-inc.s: Likewise.
* gas/testsuite/gas/arm/sp-pc-validations-bad-t: Likewise.
* gas/testsuite/gas/arm/vfp-fma-inc.s: Likewise.
* gas/testsuite/gas/arm/vfp-neon-syntax-inc.s: Likewise.
2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+ * config/tc-arm.c (do_t_it): Fully initialise now_it.
+ (new_automatic_it_block): Likewise.
+ (handle_it_block): Record whether current instruction is
+ conditionally executed.
+ * config/tc-arm.c (depr_insn_mask): New structure.
+ (depr_it_insns): New variable.
+ (it_fsm_post_encode): Warn on deprecated uses.
+ * config/tc-arm.h (current_it): Add new fields.
+
+2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
* config/tc-arm.c (deprecated_coproc_regs_s): New structure.
(deprecated_coproc_regs): New variable.
(deprecated_coproc_reg_count): Likewise.
set_it_insn_type (IT_INSN);
now_it.mask = (inst.instruction & 0xf) | 0x10;
now_it.cc = cond;
+ now_it.warn_deprecated = FALSE;
/* If the condition is a negative condition, invert the mask. */
if ((cond & 0x1) == 0x0)
unsigned int mask = inst.instruction & 0x000f;
if ((mask & 0x7) == 0)
- /* no conversion needed */;
+ {
+ /* No conversion needed. */
+ now_it.block_length = 1;
+ }
else if ((mask & 0x3) == 0)
- mask ^= 0x8;
+ {
+ mask ^= 0x8;
+ now_it.block_length = 2;
+ }
else if ((mask & 0x1) == 0)
- mask ^= 0xC;
+ {
+ mask ^= 0xC;
+ now_it.block_length = 3;
+ }
else
- mask ^= 0xE;
+ {
+ mask ^= 0xE;
+ now_it.block_length = 4;
+ }
inst.instruction &= 0xfff0;
inst.instruction |= mask;
now_it.block_length = 1;
mapping_state (MAP_THUMB);
now_it.insn = output_it_inst (cond, now_it.mask, NULL);
+ now_it.warn_deprecated = FALSE;
+ now_it.insn_cond = TRUE;
}
/* Close an automatic IT block.
handle_it_state (void)
{
now_it.state_handled = 1;
+ now_it.insn_cond = FALSE;
switch (now_it.state)
{
}
else
{
+ now_it.insn_cond = TRUE;
now_it_add_mask (inst.cond);
}
case NEUTRAL_IT_INSN:
now_it.block_length++;
+ now_it.insn_cond = TRUE;
if (now_it.block_length > 4)
force_automatic_it_block_close ();
now_it.mask <<= 1;
now_it.mask &= 0x1f;
is_last = (now_it.mask == 0x10);
+ now_it.insn_cond = TRUE;
switch (inst.it_insn_type)
{
return SUCCESS;
}
+struct depr_insn_mask
+{
+ unsigned long pattern;
+ unsigned long mask;
+ const char* description;
+};
+
+/* List of 16-bit instruction patterns deprecated in an IT block in
+ ARMv8. */
+static const struct depr_insn_mask depr_it_insns[] = {
+ { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
+ { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
+ { 0xa000, 0xb800, N_("ADR") },
+ { 0x4800, 0xf800, N_("Literal loads") },
+ { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
+ { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
+ { 0, 0, NULL }
+};
+
static void
it_fsm_post_encode (void)
{
if (!now_it.state_handled)
handle_it_state ();
+ if (now_it.insn_cond
+ && !now_it.warn_deprecated
+ && warn_on_deprecated
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
+ {
+ if (inst.instruction >= 0x10000)
+ {
+ as_warn (_("it blocks containing wide Thumb instructions are "
+ "deprecated in ARMv8"));
+ now_it.warn_deprecated = TRUE;
+ }
+ else
+ {
+ const struct depr_insn_mask *p = depr_it_insns;
+
+ while (p->mask != 0)
+ {
+ if ((inst.instruction & p->mask) == p->pattern)
+ {
+ as_warn (_("it blocks containing 16-bit Thumb intsructions "
+ "of the following class are deprecated in ARMv8: "
+ "%s"), p->description);
+ now_it.warn_deprecated = TRUE;
+ break;
+ }
+
+ ++p;
+ }
+ }
+
+ if (now_it.block_length > 1)
+ {
+ as_warn (_("it blocks of more than one conditional instruction are "
+ "deprecated in ARMv8"));
+ now_it.warn_deprecated = TRUE;
+ }
+ }
+
is_last = (now_it.mask == 0x10);
if (is_last)
{
int block_length;
char *insn;
int state_handled;
+ int warn_deprecated;
+ int insn_cond;
};
#ifdef OBJ_ELF
2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+ * gas/arm/armv8-a-it-bad.d: New testcase.
+ * gas/arm/armv8-a-it-bad.l: Likewise.
+ * gas/arm/armv8-a-it-bad.s: Likewise.
+ * gas/arm/ldr-t-bad.s: Update testcase.
+ * gas/arm/ldr-t.d: Likewise.
+ * gas/arm/ldr-t.s: Likewise.
+ * gas/arm/neon-cond-bad-inc.s: Likewise.
+ * gas/arm/sp-pc-validations-bad-t: Likewise.
+ * gas/arm/vfp-fma-inc.s: Likewise.
+ * gas/arm/vfp-neon-syntax-inc.s: Likewise.
+
+2012-08-24 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
+
* gas/arm/armv8-a-bad.l: Update testcase.
* gas/arm/armv8-a-bad.s: Likewise.
--- /dev/null
+#name: Deprecated IT blocks (ARM v8)
+#error-output: armv8-a-it-bad.l
+#as: -mimplicit-it=always
--- /dev/null
+.*: Assembler messages:
+.*:7: Warning: it blocks containing wide Thumb instructions are deprecated in ARMv8
+.*:15: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:20: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:30: Warning: it blocks containing wide Thumb instructions are deprecated in ARMv8
+.*:36: Warning: it blocks of more than one conditional instruction are deprecated in ARMv8
+.*:40: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:43: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Miscellaneous 16-bit instructions
+.*:49: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Literal loads
+.*:52: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Hi-register ADD, MOV, CMP, BX, BLX using pc
+.*:55: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:55: Error: r15 not allowed here -- `addeq r0,pc,pc'
+.*:58: Warning: it blocks containing 16-bit Thumb intsructions of the following class are deprecated in ARMv8: Short branches, Undefined, SVC, LDM/STM
+.*:58: Error: r15 not allowed here -- `addeq pc,r0,r0'
--- /dev/null
+.syntax unified
+.arch armv8-a
+
+.thumb
+@ Wide instruction in IT block is deprecated.
+it eq
+ldrdeq r0, [r1]
+
+@ This IT block is not deprecated.
+it eq
+moveq r2, r3
+
+@ IT block of more than one instruction is deprecated.
+itt eq
+moveq r0, r1
+moveq r2, r3
+
+@ Even for auto IT blocks
+moveq r2, r3
+movne r2, r3
+
+adds r0, r1
+
+@ This automatic IT block is valid
+moveq r2,r3
+
+add r0, r1, r2
+
+@ This one is too wide.
+ldrdeq r0, [r1]
+
+add r0, r1, r2
+
+@ Test automatic IT block generation at end of a file.
+movne r0, r1
+moveq r1, r0
+
+@ Test the various classes of 16-bit instructions that are deprecated.
+it eq
+svceq 0
+
+it eq
+uxtheq r0, r1
+
+it eq
+addeq r0, pc, #0
+
+it eq
+ldreq r0, [pc, #4]
+
+it eq
+bxeq pc
+
+it eq
+addeq r0, pc, pc
+
+it eq
+addeq pc, r0, r0
.syntax unified
-
+.arch armv7-a
.thumb
@ldr-immediate
0+10 <[^>]+> f8df f004 ldr.w pc, \[pc, #4\] ; 0+18 <[^>]+0x18>
0+14 <[^>]+> bfa2 ittt ge
0+16 <[^>]+> 4901 ldrge r1, \[pc, #4\] ; \(0+1c <[^>]+0x1c>\)
-0+18 <[^>]+> 46c0 nopge ; \(mov r8, r8\)
-0+1a <[^>]+> 46c0 nopge ; \(mov r8, r8\)
+0+18 <[^>]+> bf00 nopge
+0+1a <[^>]+> bf00 nopge
0+1c <[^>]+> bfa8 it ge
0+1e <[^>]+> f8df f004 ldrge.w pc, \[pc, #4\] ; 0+24 <[^>]+0x24>
0+22 <[^>]+> bfa2 ittt ge
0+24 <[^>]+> f85f 1ab8 ldrge.w r1, \[pc, #-2744\] ; fffff570 <[^>]+>
-0+28 <[^>]+> 46c0 nopge ; \(mov r8, r8\)
-0+2a <[^>]+> 46c0 nopge ; \(mov r8, r8\)
+0+28 <[^>]+> bf00 nopge
+0+2a <[^>]+> bf00 nopge
0+2c <[^>]+> bfa8 it ge
0+2e <[^>]+> f85f fab6 ldrge.w pc, \[pc, #-2742\] ; fffff57a <[^>]+>
0+32 <[^>]+> f85f 1ab9 ldr.w r1, \[pc, #-2745\] ; fffff57b <[^>]+>
0+36 <[^>]+> f85f fab6 ldr.w pc, \[pc, #-2742\] ; fffff582 <[^>]+>
0+3a <[^>]+> bfa2 ittt ge
0+3c <[^>]+> 5851 ldrge r1, \[r2, r1\]
-0+3e <[^>]+> 46c0 nopge ; \(mov r8, r8\)
-0+40 <[^>]+> 46c0 nopge ; \(mov r8, r8\)
+0+3e <[^>]+> bf00 nopge
+0+40 <[^>]+> bf00 nopge
0+42 <[^>]+> bfa8 it ge
0+44 <[^>]+> f852 f001 ldrge.w pc, \[r2, r1\]
0+48 <[^>]+> 58d1 ldr r1, \[r2, r3\]
.syntax unified
-
+.arch armv7-a
.thumb
.global foo
foo:
# Check for illegal conditional Neon instructions in ARM mode. The instructions
# which overlap with VFP are the tricky cases, so test those.
-
.include "itblock.s"
-
.syntax unified
+ .arch armv7-a
+ .fpu neon
.text
func:
itblock 4 eq
.syntax unified
+.arch armv7-a
.thumb
-
.macro it_test opcode operands:vararg
itt eq
\opcode\()eq r15, \operands
.syntax unified
+ .arch armv7-a
+ .fpu neon-vfpv4
.include "itblock.s"
@ VFP with Neon-style syntax
.syntax unified
+ .arch armv7-a
.include "itblock.s"