diff options
author | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-01-11 18:00:17 +0000 |
---|---|---|
committer | Richard Earnshaw <richard.earnshaw@arm.com> | 2002-01-11 18:00:17 +0000 |
commit | e28cd48c21973334312e56c432a475303c59ef65 (patch) | |
tree | 7b57279072020c340ab13866610324492ac68fab /gas/config/tc-arm.c | |
parent | b21b22e0688fffcd43af44aa3b234c7a5a4cd954 (diff) | |
download | gdb-e28cd48c21973334312e56c432a475303c59ef65.zip gdb-e28cd48c21973334312e56c432a475303c59ef65.tar.gz gdb-e28cd48c21973334312e56c432a475303c59ef65.tar.bz2 |
* tc-arm.c ((do_ldst): Fix handling an immediate expression pseudo
op that can be translated into a mvn instruction.
* gas/arm/ldconst.s gas/arm/ldconst.d: New files. Test ldr with
immediate pseudo-operations.
* gas/arm/arm.exp: Run it.
Diffstat (limited to 'gas/config/tc-arm.c')
-rw-r--r-- | gas/config/tc-arm.c | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 657317c..504adfe 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -475,6 +475,7 @@ struct reg_entry int number; }; +/* Some well known registers that we refer to directly elsewhere. */ #define REG_SP 13 #define REG_LR 14 #define REG_PC 15 @@ -4888,32 +4889,48 @@ do_ldst (str) return; } - if (inst.reloc.exp.X_op == O_constant - && (value = validate_immediate (inst.reloc.exp.X_add_number)) != FAIL) - { - /* This can be done with a mov instruction. */ - inst.instruction &= LITERAL_MASK; - inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT); - inst.instruction |= (value & 0xfff); - end_of_line (str); - return; - } - else + if (inst.reloc.exp.X_op == O_constant) { - /* Insert into literal pool. */ - if (add_to_lit_pool () == FAIL) + value = validate_immediate (inst.reloc.exp.X_add_number); + + if (value != FAIL) { - if (!inst.error) - inst.error = _("literal pool insertion failed"); + /* This can be done with a mov instruction. */ + inst.instruction &= LITERAL_MASK; + inst.instruction |= (INST_IMMEDIATE + | (OPCODE_MOV << DATA_OP_SHIFT)); + inst.instruction |= value & 0xfff; + end_of_line (str); return; } - /* Change the instruction exp to point to the pool. */ - inst.reloc.type = BFD_RELOC_ARM_LITERAL; - inst.reloc.pc_rel = 1; - inst.instruction |= (REG_PC << 16); - pre_inc = 1; + value = validate_immediate (~inst.reloc.exp.X_add_number); + + if (value != FAIL) + { + /* This can be done with a mvn instruction. */ + inst.instruction &= LITERAL_MASK; + inst.instruction |= (INST_IMMEDIATE + | (OPCODE_MVN << DATA_OP_SHIFT)); + inst.instruction |= value & 0xfff; + end_of_line (str); + return; + } } + + /* Insert into literal pool. */ + if (add_to_lit_pool () == FAIL) + { + if (!inst.error) + inst.error = _("literal pool insertion failed"); + return; + } + + /* Change the instruction exp to point to the pool. */ + inst.reloc.type = BFD_RELOC_ARM_LITERAL; + inst.reloc.pc_rel = 1; + inst.instruction |= (REG_PC << 16); + pre_inc = 1; } else { @@ -5841,7 +5858,7 @@ do_fpa_ldmstm (str) abort (); } - if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ed/fd format. */ + if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */ { int reg; int write_back; @@ -7995,7 +8012,6 @@ md_begin () default: mach = bfd_mach_arm_4; break; - } /* Catch special cases. */ |