This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
ARM GAS: unpredictable writeback in LDM/STM
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: 17 Sep 2002 20:15:41 +0100
- Subject: ARM GAS: unpredictable writeback in LDM/STM
Hi Guys,
The ARM LDM and STM instructions can be UNPREDICTABLE if the
writeback bit is used incorrectly, but GAS was not issuing warning
about such instructions. The (soon to be applied) patch below adds
these warnings.
I will shortly be checking in a related patch to GCC to make it stop
generating such unpredictable instructions. :-)
Cheers
Nick
2002-09-17 Nick Clifton <nickc@redhat.com>
* config/tc-arm.c (do_ldmstm): Warn about unpredictable
behavior of instructions.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.128
diff -c -3 -p -w -r1.128 tc-arm.c
*** gas/config/tc-arm.c 5 Sep 2002 00:01:16 -0000 1.128
--- gas/config/tc-arm.c 17 Sep 2002 18:53:38 -0000
*************** do_ldmstm (str)
*** 5766,5771 ****
--- 5766,5796 ----
inst.instruction |= LDM_TYPE_2_OR_3;
}
+ if (inst.instruction & WRITE_BACK)
+ {
+ /* Check for unpredictable uses of writeback. */
+ if (inst.instruction & LOAD_BIT)
+ {
+ /* Not allowed in LDM type 2. */
+ if ((inst.instruction & LDM_TYPE_2_OR_3)
+ && ((range & (1 << REG_PC)) == 0))
+ as_warn (_("writeback of base register is UNPREDICTABLE"));
+ /* Only allowed if base reg not in list for other types. */
+ else if (range & (1 << base_reg))
+ as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
+ }
+ else /* STM. */
+ {
+ /* Not allowed for type 2. */
+ if (inst.instruction & LDM_TYPE_2_OR_3)
+ as_warn (_("writeback of base register is UNPREDICTABLE"));
+ /* Only allowed if base reg not in list, or first in list. */
+ else if ((range & (1 << base_reg))
+ && (range & ((1 << base_reg) - 1)))
+ as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
+ }
+ }
+
inst.instruction |= range;
end_of_line (str);
return;