diff options
author | Paul Brook <paul@codesourcery.com> | 2007-05-25 23:13:24 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2007-05-25 23:13:24 +0000 |
commit | efd81785d9f5514e7923ad65b452d5a704989707 (patch) | |
tree | a1d0282fea6b096f0ac01e23e1b128cf89ed3fa0 /gas/config/tc-arm.c | |
parent | 4e591bc17f3673b8ce16210891aa9557e2bd5a9f (diff) | |
download | gdb-efd81785d9f5514e7923ad65b452d5a704989707.zip gdb-efd81785d9f5514e7923ad65b452d5a704989707.tar.gz gdb-efd81785d9f5514e7923ad65b452d5a704989707.tar.bz2 |
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.
Diffstat (limited to 'gas/config/tc-arm.c')
-rw-r--r-- | gas/config/tc-arm.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 2a9c7ab..2cb28d4 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -555,6 +555,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 @@ -8439,7 +8441,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; @@ -9486,6 +9502,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. */ |