From: Nick Clifton Date: Thu, 27 May 2010 10:40:36 +0000 (+0000) Subject: * config/tc-arm.c (encode_thumb2_ldmstm): Make warning about X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1e5b037994b0e1cc7564bf8268af05678318c70c;p=binutils-gdb.git * config/tc-arm.c (encode_thumb2_ldmstm): Make warning about writeback when base register is in register list an error, and correct check. (do_t_ldmstm): Change warnings. * gas/arm/thumb2_ldmstm.d: Add new testcases. * gas/arm/thumb2_ldmstm.s: Likeiwse. * gas/arm/thumb2_ldmstm_bad.d: Add testcases to check for UNPREDICTABLE ldm/stm. * gas/arm/thumb2_ldmstm_bad.l: Likewise. * gas/arm/thumb2_ldmstm_bad.s: Likewise. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index d0be0a3e123..bce83da542b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2010-05-27 Matthew Gretton-Dann + + * config/tc-arm.c (encode_thumb2_ldmstm): Make warning about + writeback when base register is in register list an error, and + correct check. + (do_t_ldmstm): Change warnings. + 2010-05-26 Catherine Moore * config/tc-mips.c (is_opcode_valid): Remove expansionp. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index bc0329469b4..6675935f6c6 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -9760,6 +9760,12 @@ encode_thumb2_ldmstm (int base, unsigned mask, bfd_boolean writeback) if (mask & (1 << 13)) inst.error = _("SP not allowed in register list"); + + if ((mask & (1 << base)) != 0 + && writeback) + inst.error = _("having the base register in the register list when " + "using write back is UNPREDICTABLE"); + if (load) { if (mask & (1 << 15)) @@ -9769,19 +9775,11 @@ encode_thumb2_ldmstm (int base, unsigned mask, bfd_boolean writeback) else set_it_insn_type_last (); } - - if ((mask & (1 << base)) != 0 - && writeback) - as_warn (_("base register should not be in register list " - "when written back")); } else { if (mask & (1 << 15)) inst.error = _("PC not allowed in register list"); - - if (mask & (1 << base)) - as_warn (_("value stored for r%d is UNPREDICTABLE"), base); } if ((mask & (mask - 1)) == 0) @@ -9847,7 +9845,7 @@ do_t_ldmstm (void) if (inst.instruction == T_MNEM_stmia && (inst.operands[1].imm & mask) && (inst.operands[1].imm & (mask - 1))) - as_warn (_("value stored for r%d is UNPREDICTABLE"), + as_warn (_("value stored for r%d is UNKNOWN"), inst.operands[0].reg); inst.instruction = THUMB_OP16 (inst.instruction); @@ -9887,7 +9885,7 @@ do_t_ldmstm (void) as_warn (_("this instruction will write back the base register")); if ((inst.operands[1].imm & (1 << inst.operands[0].reg)) && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1))) - as_warn (_("value stored for r%d is UNPREDICTABLE"), + as_warn (_("value stored for r%d is UNKNOWN"), inst.operands[0].reg); } else diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d8bbb30fa20..26df217ec78 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2010-05-27 Matthew Gretton-Dann + + * gas/arm/thumb2_ldmstm.d: Add new testcases. + * gas/arm/thumb2_ldmstm.s: Likeiwse. + * gas/arm/thumb2_ldmstm_bad.d: Add testcases to check for + UNPREDICTABLE ldm/stm. + * gas/arm/thumb2_ldmstm_bad.l: Likewise. + * gas/arm/thumb2_ldmstm_bad.s: Likewise. + 2010-05-26 Catherine Moore Maxim Kuvyrkov diff --git a/gas/testsuite/gas/arm/t16-bad.l b/gas/testsuite/gas/arm/t16-bad.l index 9643dbf71d7..68ec987d545 100644 --- a/gas/testsuite/gas/arm/t16-bad.l +++ b/gas/testsuite/gas/arm/t16-bad.l @@ -181,7 +181,7 @@ [^:]*:124: Error: lo register required -- `stmia r8!,{r1,r2}' [^:]*:125: Error: lo register required -- `stmia r7!,{r8}' [^:]*:126: Warning: this instruction will write back the base register -[^:]*:127: Warning: value stored for r7 is UNPREDICTABLE +[^:]*:127: Warning: value stored for r7 is UNKNOWN [^:]*:129: Error: invalid register list to push/pop instruction -- `push {r8,r9}' [^:]*:130: Error: invalid register list to push/pop instruction -- `pop {r8,r9}' [^:]*:133: Error: immediate value out of range -- `bkpt #257' diff --git a/gas/testsuite/gas/arm/thumb2_ldmstm.d b/gas/testsuite/gas/arm/thumb2_ldmstm.d index 2f50486489c..50d3ee68588 100644 --- a/gas/testsuite/gas/arm/thumb2_ldmstm.d +++ b/gas/testsuite/gas/arm/thumb2_ldmstm.d @@ -1,6 +1,8 @@ -# name: Thumb-2 LDM/STM single reg +# name: Thumb-2 LDM/STM # as: -march=armv6t2 # objdump: -dr --prefix-addresses --show-raw-insn +# not-target: *-*-*aout* + .*: +file format .*arm.* @@ -25,3 +27,27 @@ Disassembly of section .text: 0[0-9a-f]+ <[^>]+> f846 cc04 str.w ip, \[r6, #-4\] 0[0-9a-f]+ <[^>]+> f846 bd04 str.w fp, \[r6, #-4\]! 0[0-9a-f]+ <[^>]+> f845 8d04 str.w r8, \[r5, #-4\]! +0[0-9a-f]+ <[^>]+> c80e ldmia r0!, {r1, r2, r3} +0[0-9a-f]+ <[^>]+> c80f ldmia r0, {r0, r1, r2, r3} +0[0-9a-f]+ <[^>]+> c802 ldmia r0!, {r1} +0[0-9a-f]+ <[^>]+> e890 0f00 ldmia.w r0, {r8, r9, sl, fp} +0[0-9a-f]+ <[^>]+> e8b0 000e ldmia.w r0!, {r1, r2, r3} +0[0-9a-f]+ <[^>]+> e8b0 0f00 ldmia.w r0!, {r8, r9, sl, fp} +0[0-9a-f]+ <[^>]+> e8b0 5000 ldmia.w r0!, {ip, lr} +0[0-9a-f]+ <[^>]+> e8b0 9000 ldmia.w r0!, {ip, pc} +0[0-9a-f]+ <[^>]+> bf08 it eq +0[0-9a-f]+ <[^>]+> e8b0 9000 ldmiaeq.w r0!, {ip, pc} +0[0-9a-f]+ <[^>]+> c00f stmia r0!, {r0, r1, r2, r3} +0[0-9a-f]+ <[^>]+> c0f0 stmia r0!, {r4, r5, r6, r7} +0[0-9a-f]+ <[^>]+> e8a0 00f0 stmia.w r0!, {r4, r5, r6, r7} +0[0-9a-f]+ <[^>]+> e8a0 0f00 stmia.w r0!, {r8, r9, sl, fp} +0[0-9a-f]+ <[^>]+> e880 000f stmia.w r0, {r0, r1, r2, r3} +0[0-9a-f]+ <[^>]+> e880 0f00 stmia.w r0, {r8, r9, sl, fp} +0[0-9a-f]+ <[^>]+> f850 1b04 ldr.w r1, \[r0\], #4 +0[0-9a-f]+ <[^>]+> f8d0 1000 ldr.w r1, \[r0\] +0[0-9a-f]+ <[^>]+> f858 9b04 ldr.w r9, \[r8\], #4 +0[0-9a-f]+ <[^>]+> f8d8 9000 ldr.w r9, \[r8\] +0[0-9a-f]+ <[^>]+> f840 1b04 str.w r1, \[r0\], #4 +0[0-9a-f]+ <[^>]+> f8c0 1000 str.w r1, \[r0\] +0[0-9a-f]+ <[^>]+> f848 9b04 str.w r9, \[r8\], #4 +0[0-9a-f]+ <[^>]+> f8c8 9000 str.w r9, \[r8\] diff --git a/gas/testsuite/gas/arm/thumb2_ldmstm.s b/gas/testsuite/gas/arm/thumb2_ldmstm.s index fd4410af3c4..6cbcc1779b0 100644 --- a/gas/testsuite/gas/arm/thumb2_ldmstm.s +++ b/gas/testsuite/gas/arm/thumb2_ldmstm.s @@ -22,3 +22,36 @@ ldmstm: stmdb r6!, {fp} stmdb r5!, {r8} + @ Valid Thumb-2 encodings of LDM/LDMIA/LDMFD as specified by section + @ A8.6.53 of the ARM ARM + ldmia r0!, {r1-r3} @ Encoding T1 + ldmia r0, {r0-r3} @ Encoding T1 + ldmia r0!, {r1} @ Encoding T1 + ldmia r0, {r8-r11} @ Encoding T2 + ldmia.w r0!, {r1-r3} @ Encoding T2 + ldmia r0!, {r8-r11} @ Encoding T2 + ldmia r0!, {r12, r14} @ Encoding T2 + ldmia r0!, {r12, pc} @ Encoding T2 + it eq + ldmiaeq r0!, {r12, pc} @ Encoding T2 + + @ Valid Thumb-2 encodings of STM/STMIA/STMEA as specified by section + @ A8.6.189 of the ARMARM. + stmia r0!, {r0-r3} @ Encoding T1, Allowed as r0 is lowest reg + stmia r0!, {r4-r7} @ Encoding T1 + stmia.w r0!, {r4-r7} @ Encoding T2 + stmia r0!, {r8-r11} @ Encoding T2 + stmia r0, {r0-r3} @ Encoding T2 + stmia r0, {r8-r11} @ Encoding T2 + + @ The following are technically UNPREDICTABLE if we assemble them + @ as written, but gas translates (stm|ldm) rn(!), {rd} into an + @ equivalent, and well-defined, (ldr, str) rd, [rn], (#4). + ldmia.w r0!, {r1} @ ldr.w r1, [r0], #4 + ldmia.w r0, {r1} @ ldr.w r1, [r0] + ldmia r8!, {r9} @ ldr.w r9, [r8], #4 + ldmia r8, {r9} @ ldr.w r9, [r8] + stmia.w r0!, {r1} @ str.w r1, [r0], #4 + stmia r0, {r1} @ str.w r1, [r0] + stmia r8!, {r9} @ str.w r9, [r8], #4 + stmia r8, {r9} @ str.w r9, [r8] diff --git a/gas/testsuite/gas/arm/thumb2_ldmstm_bad.d b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.d new file mode 100644 index 00000000000..05d53144522 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.d @@ -0,0 +1,3 @@ +#name: Invalid Thumb-2 LDM/STM instructions +#as: -march=armv6t2 +#error-output: thumb2_ldmstm_bad.l diff --git a/gas/testsuite/gas/arm/thumb2_ldmstm_bad.l b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.l new file mode 100644 index 00000000000..70c4bdee4d4 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.l @@ -0,0 +1,12 @@ +[^:]*: Assembler messages: +[^:]*:6: Error: r15 not allowed here -- `ldmia r15,{r0-r3}' +[^:]*:7: Error: r15 not allowed here -- `ldmia r15!,{r0-r3}' +[^:]*:8: Error: LR and PC should not both be in register list -- `ldmia r1,{r14,r15}' +[^:]*:9: Error: having the base register in the register list when using write back is UNPREDICTABLE -- `ldmia r0!,{r0-r3}' +[^:]*:12: Error: branch must be last instruction in IT block -- `ldmiaeq r0,{r12,r15}' +[^:]*:13: Error: having the base register in the register list when using write back is UNPREDICTABLE -- `ldmiaeq r0!,{r0,r1}' +[^:]*:17: Error: having the base register in the register list when using write back is UNPREDICTABLE -- `stmia.w r0!,{r0-r3}' +[^:]*:18: Warning: value stored for r1 is UNKNOWN +[^:]*:19: Error: r15 not allowed here -- `stmia r15!,{r0-r3}' +[^:]*:20: Error: r15 not allowed here -- `stmia r15,{r0-r3}' +[^:]*:21: Error: having the base register in the register list when using write back is UNPREDICTABLE -- `stmia r8!,{r0-r11}' diff --git a/gas/testsuite/gas/arm/thumb2_ldmstm_bad.s b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.s new file mode 100644 index 00000000000..70d4bdd269e --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_ldmstm_bad.s @@ -0,0 +1,30 @@ +.syntax unified +.thumb +ldmstm_bad: + @ UNPREDICTABLE Thumb-2 encodings of LDM/LDMIA/LDMFD as specified + @ by section A8.6.53 of the ARMARM. + ldmia r15, {r0-r3} @ Encoding T2, UNPREDICTABLE + ldmia r15!, {r0-r3} @ Encoding T2, UNPREDICTABLE + ldmia r1, {r14, r15} @ Encoding T2, UNPREDICTABLE + ldmia r0!, {r0-r3} @ Encoding T2, UNPREDICTABLE + + itt eq + ldmiaeq r0, {r12, r15} @ Encoding T2, UNPREDICTABLE + ldmiaeq r0!, {r0, r1} @ Encoding T2, UNPREDICTABLE + + @ UNPREDICTABLE Thumb-2 encodings of STM/STMIA/STMEA as specified + @ by section A8.6.189 of the ARMARM. + stmia.w r0!, {r0-r3} @ Encoding T2, UNPREDICTABLE + stmia r1!, {r0-r3} @ Encoding T1, r1 is UNKNOWN + stmia r15!, {r0-r3} @ Encoding T2, UNPREDICTABLE + stmia r15, {r0-r3} @ Encoding T2, UNPREDICTABLE + stmia r8!, {r0-r11} @ Encoding T2, UNPREDICTABLE + + @ The following are technically UNDEFINED, but gas converts them to + @ an equivalent, and well-defined instruction automatically. + @stmia.w r0!, {r1} @ str.w r1, [r0], #4 + @stmia r8!, {r9} @ str.w r9, [r8], #4 + @stmia r8, {r9} @ str.w r9, [r8] + @ldmia.w r0!, {r1} @ ldr.w r1, [r0], #4 + @ldmia r8!, {r9} @ ldr.w r9, [r8], #4 + @ldmia r8, {r9} @ ldr.w r9, [r8]