This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Thumb-2 subs pc
- From: Paul Brook <paul at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Sat, 26 May 2007 00:20:45 +0100
- Subject: Thumb-2 subs pc
For historical reasons ARM returns frm an exception handler using subs pc, lr,
#const or movs pc, lr. On Thumb-2 these use a special encoding and
the "normal" ecodings are either reserved or mean something else.
The patch below fixes the encoding of these instructions. I have not attempted
to catch all the invalid forms of these instructions. That will come as a
later.
Tested on arm-none-eabi.
Applied to CVS head.
Paul
2007-03-25 Paul Brook <paul@codesourcery.com>
gas/
* config/tc-arm.c (T2_SUBS_PC_LR): Define.
(do_t_add_sub): Correctly encode subs pc, lr, #const.
(do_t_mov_cmp): Correctly encode movs pc, lr.
gas/testsulte/
* gas/arm/thumb32.s: Add tests for subs pc, lr.
* gas/arm/thumb32.d: Change error-output: to stderr:.
Update expected output.
Index: gas/testsuite/gas/arm/thumb32.d
===================================================================
--- gas/testsuite/gas/arm/thumb32.d (revision 172261)
+++ gas/testsuite/gas/arm/thumb32.d (working copy)
@@ -3,7 +3,7 @@
# objdump: -dr --prefix-addresses --show-raw-insn
# The arm-aout and arm-pe ports do not support Thumb branch relocations.
# not-target: *-*-*aout* *-*-pe
-# error-output: thumb32.l
+# stderr: thumb32.l
.*: +file format .*arm.*
@@ -959,3 +959,7 @@ Disassembly of section .text:
0[0-9a-f]+ <[^>]+> e80d c010 srsdb sp, #16
0[0-9a-f]+ <[^>]+> e9ad c015 srsia sp!, #21
0[0-9a-f]+ <[^>]+> e9ad c00a srsia sp!, #10
+0[0-9a-f]+ <[^>]+> f3de 8f00 subs pc, lr, #0
+0[0-9a-f]+ <[^>]+> f3de 8f00 subs pc, lr, #0
+0[0-9a-f]+ <[^>]+> f3de 8f04 subs pc, lr, #4
+0[0-9a-f]+ <[^>]+> f3de 8fff subs pc, lr, #255
Index: gas/testsuite/gas/arm/thumb32.s
===================================================================
--- gas/testsuite/gas/arm/thumb32.s (revision 172261)
+++ gas/testsuite/gas/arm/thumb32.s (working copy)
@@ -775,3 +775,8 @@ srs:
srsdb sp, #16
srsia sp!, #21
srsia sp!, #10
+
+ movs pc, lr
+ subs pc, lr, #0
+ subs pc, lr, #4
+ subs pc, lr, #255
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c (revision 172261)
+++ gas/config/tc-arm.c (working copy)
@@ -560,6 +560,8 @@ struct asm_opcode
#define OPCODE_MASK 0xfe1fffff
#define V4_STR_BIT 0x00000020
+#define T2_SUBS_PC_LR 0xf3de8f00
+
#define DATA_OP_SHIFT 21
#define T2_OPCODE_MASK 0xfe1fffff
@@ -8444,7 +8446,21 @@ do_t_add_sub (void)
if (inst.size_req == 4
|| (inst.size_req != 2 && !opcode))
{
- if (Rs == REG_PC)
+ if (Rd == REG_PC)
+ {
+ constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
+ _("only SUBS PC, LR, #const allowed"));
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+ constraint (inst.reloc.exp.X_add_number < 0
+ || inst.reloc.exp.X_add_number > 0xff,
+ _("immediate value out of range"));
+ inst.instruction = T2_SUBS_PC_LR
+ | inst.reloc.exp.X_add_number;
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ return;
+ }
+ else if (Rs == REG_PC)
{
/* Always use addw/subw. */
inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
@@ -9502,6 +9519,16 @@ do_t_mov_cmp (void)
|| inst.operands[1].shifted)
narrow = FALSE;
+ /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
+ if (opcode == T_MNEM_movs && inst.operands[1].isreg
+ && !inst.operands[1].shifted
+ && inst.operands[0].reg == REG_PC
+ && inst.operands[1].reg == REG_LR)
+ {
+ inst.instruction = T2_SUBS_PC_LR;
+ return;
+ }
+
if (!inst.operands[1].isreg)
{
/* Immediate operand. */