Implement the ldr-pseudo opcode for ARM assembly
authorDavid Peixotto <dpeixott@codeaurora.org>
Thu, 19 Dec 2013 18:12:36 +0000 (18:12 +0000)
committerDavid Peixotto <dpeixott@codeaurora.org>
Thu, 19 Dec 2013 18:12:36 +0000 (18:12 +0000)
commit0fa193b08627927ccaa0804a34d80480894614b8
treee78debe0830293b2d1833e63b92eba04254726bd
parent6075fa1e0eba255e217095bd2573339e64de8c8d
Implement the ldr-pseudo opcode for ARM assembly

The ldr-pseudo opcode is a convenience for loading 32-bit constants.
It is converted into a pc-relative load from a constant pool. For
example,

  ldr r0, =0x10001
  ldr r1, =bar

will generate this output in the final assembly

  ldr r0, .Ltmp0
  ldr r1, .Ltmp1
  ...
  .Ltmp0: .long 0x10001
  .Ltmp1: .long bar

Sketch of the LDR pseudo implementation:
  Keep a map from Section => ConstantPool

  When parsing ldr r0, =val
    parse val as an MCExpr
    get ConstantPool for current Section
    Label = CreateTempSymbol()
    remember val in ConstantPool at next free slot
    add operand to ldr that is MCSymbolRef of Label

  On finishParse() callback
    Write out all non-empty constant pools
    for each Entry in ConstantPool
      Emit Entry.Label
      Emit Entry.Value

Possible improvements to be added in a later patch:
  1. Does not convert load of small constants to mov
     (e.g. ldr r0, =0x1 => mov r0, 0x1)
  2. Does reuse constant pool entries for same constant

The implementation was tested for ARM, Thumb1, and Thumb2 targets on
linux and darwin.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197708 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/ldr-pseudo-darwin.s [new file with mode: 0644]
test/MC/ARM/ldr-pseudo-obj-errors.s [new file with mode: 0644]
test/MC/ARM/ldr-pseudo-parse-errors.s [new file with mode: 0644]
test/MC/ARM/ldr-pseudo.s [new file with mode: 0644]