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:
Matthew Gretton-Dann 2010-09-17 15:19:14 +00:00
parent 59b42a0df4
commit eab4f823f7
5 changed files with 83 additions and 21 deletions

View file

@ -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>
* config/tc-arm.c (parse_psr): Add condition for matching "APSR" on

View file

@ -9943,30 +9943,68 @@ do_t_ldmstm (void)
{
mask = 1 << inst.operands[0].reg;
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.operands[0].reg <= 7)
{
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.operands[0].writeback
: (inst.operands[0].writeback
== !(inst.operands[1].imm & mask)))
{
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 |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].imm;
narrow = TRUE;
inst.instruction = THUMB_OP16 (inst.instruction);
inst.instruction |= inst.operands[0].reg << 8;
inst.instruction |= inst.operands[1].imm;
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
&& inst.operands[0].writeback)
else if (inst.operands[0] .reg == REG_SP)
{
inst.instruction = THUMB_OP16 (inst.instruction == T_MNEM_stmia
? T_MNEM_push : T_MNEM_pop);
inst.instruction |= inst.operands[1].imm;
narrow = TRUE;
if (inst.operands[0].writeback)
{
inst.instruction =
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;
}
}
}

View file

@ -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>
* gas/arm/msr-reg.s: New file.

View file

@ -48,6 +48,12 @@ Disassembly of section .text:
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]+ <[^>]+> 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]+ <[^>]+> f8c8 9000 str.w r9, \[r8\]

View file

@ -52,6 +52,12 @@ ldmstm:
ldmia r8!, {r9} @ ldr.w r9, [r8], #4
ldmia r8, {r9} @ ldr.w r9, [r8]
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]