I don't intend this to be the excepted answer, but it does offer some more insight and also offer an inconvenient solution to using just one ldr instruction.
When using this two stage ldr method, the assembler actually adds another 4 bytes of data after your code! In the .text section even, these 4 bytes are the actual address to your .data variable. The first ldr instruction then actually points to this address, you then use the next ldr to use the real address. As tangrs was discussing, this double pointer may be a way to make sure your variables/constants are reachable, especially with the .data section being farther away (64k away in my last run).
Looking at some sample code of the right way to do this:
.text
.global _start
_start:
ldr r0, =x
ldr r0, [r0]
mov r7, #1
swi #0
nop
.data
x: .word 0xf0f0f0f0
The assembler ACTUALLY produces this:
00010074 <_start>:
10074: e59f000c ldr r0, [pc, #12] ; 10088 <_start+0x14>
10078: e5900000 ldr r0, [r0]
1007c: e3a07001 mov r7, #1
10080: ef000000 svc 0x00000000
10084: e1a00000 nop ; (mov r0, r0)
10088: 0002008c andeq r0, r2, ip, lsl #1
Disassembly of section .data:
0002008c <x>:
2008c: f0f0f0f0 ; <UNDEFINED> instruction: 0xf0f0f0f0
The first ldr is pointing 12 bytes after the program counter (considered the current instruction + eight more). This points to address 0x10088 (as noted by objdump), which is pointing to the andeq instruction (not a real instruction in this context). It is really an address, 0x0002008c, which is pointing to our proper address in the .data section for our variable x. Now that we have the address of our variable in r0, we can use ldr on that address to get the real value. It is notable though, that even though the 2nd operand in the source file for both of these ldr instructions looks very different, the machine encoding is for the same ldr encoding; they are both LDR Immediate (though the first ldr variant is also considered LDR Literal, it is just LDR Immediate with 'Rn' hardcoded to '1111', which is just the pc register anyway).
With all of this in mind, though it is inconvenient, we can figure a way to just use the LDR Immediate(Literal) form once. All we have to do is make sure to get the correct immediate value (offset) that corresponds with our real data. Easier done than said:
.text
.global _start
_start:
ldr r0, [pc, #8]
mov r7, #1
swi #0
nop
x: .word 0xf0f0f0f0
Other than only having to use one LDR instruction to achieve the same result, there's one other subtle difference in this version of the source: there is no .data section. This can be done with a data section, but it would put our data in a much higher address, making our offset so much larger that we may have to use extra instructions just to get the offset correct. Another side note is due to this being in the .text (r-x) section, you can't use str on it by default. This is a very small barrier, just use the -N option for ld and your .text section is now rwx. I'm sure that last suggestion will anger the stackoverflow gods, come at me ;)