2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
* config/tc-arm.c (do_t_ldmstm): Add logic to handle single-register list for ldm/stm. 2010-09-17 Tejas Belagod <tejas.belagod@arm.com> * gas/arm/thumb2_ldmstm.d: Change single-register stmia to use 16-bit str encoding instead of str.w. Likewise for ldmia. * gas/arm/thumb2_ldmstm.s: Change stmia comment. Add tests for T1 ldmia-to-ldr.
This commit is contained in:
parent
59b42a0df4
commit
eab4f823f7
5 changed files with 83 additions and 21 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
||||||
|
|
||||||
|
* config/tc-arm.c (do_t_ldmstm): Add logic to handle single-register
|
||||||
|
list for ldm/stm.
|
||||||
|
|
||||||
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
||||||
|
|
||||||
* config/tc-arm.c (parse_psr): Add condition for matching "APSR" on
|
* config/tc-arm.c (parse_psr): Add condition for matching "APSR" on
|
||||||
|
|
|
@ -9943,30 +9943,68 @@ do_t_ldmstm (void)
|
||||||
{
|
{
|
||||||
mask = 1 << inst.operands[0].reg;
|
mask = 1 << inst.operands[0].reg;
|
||||||
|
|
||||||
if (inst.operands[0].reg <= 7
|
if (inst.operands[0].reg <= 7)
|
||||||
&& (inst.instruction == T_MNEM_stmia
|
|
||||||
? inst.operands[0].writeback
|
|
||||||
: (inst.operands[0].writeback
|
|
||||||
== !(inst.operands[1].imm & mask))))
|
|
||||||
{
|
{
|
||||||
if (inst.instruction == T_MNEM_stmia
|
if (inst.instruction == T_MNEM_stmia
|
||||||
&& (inst.operands[1].imm & mask)
|
? inst.operands[0].writeback
|
||||||
&& (inst.operands[1].imm & (mask - 1)))
|
: (inst.operands[0].writeback
|
||||||
as_warn (_("value stored for r%d is UNKNOWN"),
|
== !(inst.operands[1].imm & mask)))
|
||||||
inst.operands[0].reg);
|
{
|
||||||
|
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 UNKNOWN"),
|
||||||
|
inst.operands[0].reg);
|
||||||
|
|
||||||
inst.instruction = THUMB_OP16 (inst.instruction);
|
inst.instruction = THUMB_OP16 (inst.instruction);
|
||||||
inst.instruction |= inst.operands[0].reg << 8;
|
inst.instruction |= inst.operands[0].reg << 8;
|
||||||
inst.instruction |= inst.operands[1].imm;
|
inst.instruction |= inst.operands[1].imm;
|
||||||
narrow = TRUE;
|
narrow = TRUE;
|
||||||
|
}
|
||||||
|
else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
|
||||||
|
{
|
||||||
|
/* This means 1 register in reg list one of 3 situations:
|
||||||
|
1. Instruction is stmia, but without writeback.
|
||||||
|
2. lmdia without writeback, but with Rn not in
|
||||||
|
reglist.
|
||||||
|
3. ldmia with writeback, but with Rn in reglist.
|
||||||
|
Case 3 is UNPREDICTABLE behaviour, so we handle
|
||||||
|
case 1 and 2 which can be converted into a 16-bit
|
||||||
|
str or ldr. The SP cases are handled below. */
|
||||||
|
unsigned long opcode;
|
||||||
|
/* First, record an error for Case 3. */
|
||||||
|
if (inst.operands[1].imm & mask
|
||||||
|
&& inst.operands[0].writeback)
|
||||||
|
inst.error =
|
||||||
|
_("having the base register in the register list when "
|
||||||
|
"using write back is UNPREDICTABLE");
|
||||||
|
|
||||||
|
opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
|
||||||
|
: T_MNEM_ldr);
|
||||||
|
inst.instruction = THUMB_OP16 (opcode);
|
||||||
|
inst.instruction |= inst.operands[0].reg << 3;
|
||||||
|
inst.instruction |= (ffs (inst.operands[1].imm)-1);
|
||||||
|
narrow = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (inst.operands[0] .reg == REG_SP
|
else if (inst.operands[0] .reg == REG_SP)
|
||||||
&& inst.operands[0].writeback)
|
|
||||||
{
|
{
|
||||||
inst.instruction = THUMB_OP16 (inst.instruction == T_MNEM_stmia
|
if (inst.operands[0].writeback)
|
||||||
? T_MNEM_push : T_MNEM_pop);
|
{
|
||||||
inst.instruction |= inst.operands[1].imm;
|
inst.instruction =
|
||||||
narrow = TRUE;
|
THUMB_OP16 (inst.instruction == T_MNEM_stmia
|
||||||
|
? T_MNEM_push : T_MNEM_pop);
|
||||||
|
inst.instruction |= inst.operands[1].imm;
|
||||||
|
narrow = TRUE;
|
||||||
|
}
|
||||||
|
else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
|
||||||
|
{
|
||||||
|
inst.instruction =
|
||||||
|
THUMB_OP16 (inst.instruction == T_MNEM_stmia
|
||||||
|
? T_MNEM_str_sp : T_MNEM_ldr_sp);
|
||||||
|
inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
|
||||||
|
narrow = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
||||||
|
|
||||||
|
* gas/arm/thumb2_ldmstm.d: Change single-register stmia to use 16-bit
|
||||||
|
str encoding instead of str.w. Likewise for ldmia.
|
||||||
|
* gas/arm/thumb2_ldmstm.s: Change stmia comment. Add tests for T1
|
||||||
|
ldmia-to-ldr.
|
||||||
|
|
||||||
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
2010-09-17 Tejas Belagod <tejas.belagod@arm.com>
|
||||||
|
|
||||||
* gas/arm/msr-reg.s: New file.
|
* gas/arm/msr-reg.s: New file.
|
||||||
|
|
|
@ -48,6 +48,12 @@ Disassembly of section .text:
|
||||||
0[0-9a-f]+ <[^>]+> f858 9b04 ldr.w r9, \[r8\], #4
|
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]+ <[^>]+> f8d8 9000 ldr.w r9, \[r8\]
|
||||||
0[0-9a-f]+ <[^>]+> f840 1b04 str.w r1, \[r0\], #4
|
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]+ <[^>]+> 6001 str r1, \[r0, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 680a ldr r2, \[r1, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 6807 ldr r7, \[r0, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 9700 str r7, \[sp, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 9000 str r0, \[sp, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 9f00 ldr r7, \[sp, #0\]
|
||||||
|
0[0-9a-f]+ <[^>]+> 9800 ldr r0, \[sp, #0\]
|
||||||
0[0-9a-f]+ <[^>]+> f848 9b04 str.w r9, \[r8\], #4
|
0[0-9a-f]+ <[^>]+> f848 9b04 str.w r9, \[r8\], #4
|
||||||
0[0-9a-f]+ <[^>]+> f8c8 9000 str.w r9, \[r8\]
|
0[0-9a-f]+ <[^>]+> f8c8 9000 str.w r9, \[r8\]
|
||||||
|
|
|
@ -52,6 +52,12 @@ ldmstm:
|
||||||
ldmia r8!, {r9} @ ldr.w r9, [r8], #4
|
ldmia r8!, {r9} @ ldr.w r9, [r8], #4
|
||||||
ldmia r8, {r9} @ ldr.w r9, [r8]
|
ldmia r8, {r9} @ ldr.w r9, [r8]
|
||||||
stmia.w r0!, {r1} @ str.w r1, [r0], #4
|
stmia.w r0!, {r1} @ str.w r1, [r0], #4
|
||||||
stmia r0, {r1} @ str.w r1, [r0]
|
stmia r0, {r1} @ T1 str r1, [r0]
|
||||||
|
ldmia r1, {r2} @ T1 ldr r2, [r1]
|
||||||
|
ldmia r0, {r7} @ T1 ldr r7, [r0]
|
||||||
|
stmia sp, {r7} @ T1 str r7, [sp]
|
||||||
|
stmia sp, {r0} @ T1 str r0, [sp]
|
||||||
|
ldmia sp, {r7} @ T1 ldr r7, [sp]
|
||||||
|
ldmia sp, {r0} @ T1 ldr r0, [sp]
|
||||||
stmia r8!, {r9} @ str.w r9, [r8], #4
|
stmia r8!, {r9} @ str.w r9, [r8], #4
|
||||||
stmia r8, {r9} @ str.w r9, [r8]
|
stmia r8, {r9} @ str.w r9, [r8]
|
||||||
|
|
Loading…
Reference in a new issue