David Peixotto
2013-Nov-01 18:16 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
In an earlier email[1] I proposed adding support for the ldr pseud-instruction to the ARM integrated assembler. After some discussion the overall consensus seemed to be that it was worth adding. One concern was that we needed to have adequate testing. I promised to provide more details on what the behavior should be and provide some tests before starting the implementation. The FileCheck-ified tests are attached to this email. They currently pass when using gcc to assemble the test. Here are the specific behaviors that are checked in the test: 1. Check that constants that fit into imm12 are converted to mov ldr r0, =0x3 2. Check that large constants are converted to ldr from constant pool ldr r0, =0x103 3. Duplicate constants should be merged to the same constant pool location ldr r0, =0x103 ... ldr r0, =0x103 4. A section defined in multiple pieces is merged and uses a single constant pool For example, .section e, "ax", %progbits f6: ldr r0, =0x103 .section f, "ax", %progbits f7: add r0, r0, r0 .section e, "ax", %progbits f8: add r0, r0, r0 ldr r0, =0x105 should only produce one constant pool for section e. 5. Check that symbols can be loaded using ldr pseudo ldr r0, =foo 6. Check that ldr pseudo can be used with expressions ldr r0, =0x101+6 ldr r0, =bar+4 7. Check that it is used correctly in a macro .macro useit_in_a_macro ldr r0, =0x101 ldr r0, =bar .endm .section k, "ax", %progbits f14: useit_in_a_macro 8. Check that an error is issued when the constant pool would be placed too far away ldr r0, =0x101 @... lots of instructions Error: invalid literal constant: pool needs to be closer I have not yet looked into the code to see where/how this feature can be implemented. Any pointers or feedback is welcome. I've filed a Bug[2] to track this issue. [1]: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-October/066808.html [2]: http://llvm.org/bugs/show_bug.cgi?id=17769 -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -------------- next part -------------- A non-text attachment was scrubbed... Name: ldr_pseudo.s Type: application/octet-stream Size: 4328 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131101/f3dd6cc3/attachment.obj>
Jim Grosbach
2013-Nov-01 18:36 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
Hi David, In these examples, I don’t see the directive that indicates where the assembler should place the constant pool? -Jim On Nov 1, 2013, at 11:16 AM, David Peixotto <dpeixott at codeaurora.org> wrote:> In an earlier email[1] I proposed adding support for the ldr > pseud-instruction to the ARM integrated assembler. After some discussion the > overall consensus seemed to be that it was worth adding. One concern was > that we needed to have adequate testing. I promised to provide more details > on what the behavior should be and provide some tests before starting the > implementation. The FileCheck-ified tests are attached to this email. They > currently pass when using gcc to assemble the test. > > Here are the specific behaviors that are checked in the test: > > 1. Check that constants that fit into imm12 are converted to mov > ldr r0, =0x3 > 2. Check that large constants are converted to ldr from constant pool > ldr r0, =0x103 > 3. Duplicate constants should be merged to the same constant pool location > ldr r0, =0x103 > ... > ldr r0, =0x103 > 4. A section defined in multiple pieces is merged and uses a single constant > pool > For example, > > .section e, "ax", %progbits > f6: > ldr r0, =0x103 > .section f, "ax", %progbits > f7: add r0, r0, r0 > .section e, "ax", %progbits > f8: > add r0, r0, r0 > ldr r0, =0x105 > > should only produce one constant pool for section e. > > 5. Check that symbols can be loaded using ldr pseudo > ldr r0, =foo > > 6. Check that ldr pseudo can be used with expressions > ldr r0, =0x101+6 > ldr r0, =bar+4 > > 7. Check that it is used correctly in a macro > .macro useit_in_a_macro > ldr r0, =0x101 > ldr r0, =bar > .endm > .section k, "ax", %progbits > f14: > useit_in_a_macro > > 8. Check that an error is issued when the constant pool would be placed too > far away > ldr r0, =0x101 > @... lots of instructions > Error: invalid literal constant: pool needs to be closer > > I have not yet looked into the code to see where/how this feature can be > implemented. Any pointers or feedback is welcome. I've filed a Bug[2] to > track this issue. > > [1]: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-October/066808.html > [2]: http://llvm.org/bugs/show_bug.cgi?id=17769 > > -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted > by The Linux Foundation > > > > <ldr_pseudo.s>_______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Tim Northover
2013-Nov-01 18:40 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
Hi David,> 8. Check that an error is issued when the constant pool would be placed too > far awayI'd say this one is actually the most involved constraint but there don't actually seem to be any tests in the attached file for it. And I believe the directive Jim's referring to is ".ltorg". It's presumably going to have some interesting quirks of its own. Cheers. Tim.
David Peixotto
2013-Nov-01 18:54 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
Hi Jim,> In these examples, I don't see the directive that indicates where the > assembler should place the constant pool? >As Tim mentioned, the directive in question is .ltorg. I had planned to implement that in a separate step once the initial support for ldr-pseudo was complete. The .ltorg directive is only required when the constant pool would be placed too far away for the offset to be encoded in the pc-relative load. It gives the programmer an escape, but is not required for an initial implementation. I was thinking that without the .ltorg directive the constant pool would go at the end of the section.
David Peixotto
2013-Nov-01 19:00 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
Hi Tim,> > 8. Check that an error is issued when the constant pool would be > > placed too far away > > I'd say this one is actually the most involved constraint but there don't > actually seem to be any tests in the attached file for it.I put the test in a separate file and forgot to attach it earlier. I've attached it to this email. I can't say how difficult this will be to implement, but Jim also indicated it could be tricky so I believe you both :). I only have a simple test for this now, but I'd welcome suggestions on improving it or any hits on the implementation.> And I believe the directive Jim's referring to is ".ltorg". It's > presumably going to have some interesting quirks of its own.Yes, I replied to Jim saying that I was planning to implement .ltorg in a separate step. -------------- next part -------------- A non-text attachment was scrubbed... Name: ldr_pseudo_errors.s Type: application/octet-stream Size: 17617 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131101/2215fd20/attachment.obj>
David Peixotto
2013-Nov-01 19:06 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
> > I was thinking that without the .ltorg directive the constant pool > > would go at the end of the section. > > > So where does the assembler place the constant pool(s) if that directive > isn't present? I was under the impression it was always required.>From my understanding it is not required. I see that GCC will place it atthe end of the section. I don't know if it will ever place it anywhere besides the end of the section when there is no .ltorg directive. Here is the relevant section from the gcc docs (https://sourceware.org/binutils/docs/as/ARM-Directives.html): """ .ltorg This directive causes the current contents of the literal pool to be dumped into the current section (which is assumed to be the .text section) at the current location (aligned to a word boundary). GAS maintains a separate literal pool for each section and each sub-section. The .ltorg directive will only affect the literal pool of the current section and sub-section. At the end of assembly all remaining, un-empty literal pools will automatically be dumped. """
Jim Grosbach
2013-Nov-01 19:06 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
On Nov 1, 2013, at 12:06 PM, David Peixotto <dpeixott at codeaurora.org> wrote:>>> I was thinking that without the .ltorg directive the constant pool >>> would go at the end of the section. >>> >> So where does the assembler place the constant pool(s) if that directive >> isn't present? I was under the impression it was always required. > > From my understanding it is not required. I see that GCC will place it at > the end of the section. I don't know if it will ever place it anywhere > besides the end of the section when there is no .ltorg directive. > > Here is the relevant section from the gcc docs > (https://sourceware.org/binutils/docs/as/ARM-Directives.html): > > """ > .ltorg > This directive causes the current contents of the literal pool to be dumped > into the current section (which is assumed to be the .text section) at the > current location (aligned to a word boundary). GAS maintains a separate > literal pool for each section and each sub-section. The .ltorg directive > will only affect the literal pool of the current section and sub-section. At > the end of assembly all remaining, un-empty literal pools will automatically > be dumped. > """ >What does ARM’s documentation say?
David Peixotto
2013-Nov-11 22:26 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
I have attached an initial patch that implements the ldr pseudo. It still needs some clean up and more tests, but I would like some feedback on the approach I used and if there are any objections to implementing it this way. Here is my approach: Add a finishParse() callback to the target asm parser This callback is invoked when the parse has finished successfully. It will be used to write out constant pools for the ldr pseudo. LDR pseudo implementation Keep a map from Section => ConstantPool When parsing ldr r0, =val parse val as an MCExpr get ConstantPool for current Section remember val in ConstantPool (at next available Offset) add operand to ldr that is MCExpr of (ConstantPool.Label + Offset) On finishParse() callback Write out all non-empty constant pool vals to the end of their sections Missing features 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 It currently passes the tests I shared earlier (including the error message) except that ldr is not yet converted to mov when possible. Please let me know if you have any issues with this method of implementation. Thanks, -David -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation> -----Original Message----- > From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On > Behalf Of David Peixotto > Sent: Friday, November 01, 2013 11:16 AM > To: llvmdev at cs.uiuc.edu > Subject: [LLVMdev] Implementing the ldr pseudo instruction in ARM > integrated assembler > > In an earlier email[1] I proposed adding support for the ldr pseud- > instruction to the ARM integrated assembler. After some discussion the > overall consensus seemed to be that it was worth adding. One concern was > that we needed to have adequate testing. I promised to provide more > details on what the behavior should be and provide some tests before > starting the implementation. The FileCheck-ified tests are attached to > this email. They currently pass when using gcc to assemble the test. > > Here are the specific behaviors that are checked in the test: > > 1. Check that constants that fit into imm12 are converted to mov > ldr r0, =0x3 > 2. Check that large constants are converted to ldr from constant pool > ldr r0, =0x103 > 3. Duplicate constants should be merged to the same constant pool location > ldr r0, =0x103 > ... > ldr r0, =0x103 > 4. A section defined in multiple pieces is merged and uses a single > constant pool > For example, > > .section e, "ax", %progbits > f6: > ldr r0, =0x103 > .section f, "ax", %progbits > f7: add r0, r0, r0 > .section e, "ax", %progbits > f8: > add r0, r0, r0 > ldr r0, =0x105 > > should only produce one constant pool for section e. > > 5. Check that symbols can be loaded using ldr pseudo > ldr r0, =foo > > 6. Check that ldr pseudo can be used with expressions > ldr r0, =0x101+6 > ldr r0, =bar+4 > > 7. Check that it is used correctly in a macro > .macro useit_in_a_macro > ldr r0, =0x101 > ldr r0, =bar > .endm > .section k, "ax", %progbits > f14: > useit_in_a_macro > > 8. Check that an error is issued when the constant pool would be placed > too far away > ldr r0, =0x101 > @... lots of instructions > Error: invalid literal constant: pool needs to be closer > > I have not yet looked into the code to see where/how this feature can be > implemented. Any pointers or feedback is welcome. I've filed a Bug[2] to > track this issue. > > [1]: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-October/066808.html > [2]: http://llvm.org/bugs/show_bug.cgi?id=17769 > > -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > hosted by The Linux Foundation > >-------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-PR17769-Initial-implementation-of-ldr-pseudo.patch Type: application/octet-stream Size: 11398 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131111/b0ffc376/attachment.obj>
Amara Emerson
2013-Nov-12 13:42 UTC
[LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
Hi David, Thanks for your efforts here. I have a few comments on your patch, although I realise it's still a work in progress. +class ConstantPool { + MCSymbol *Label; + typedef std::vector<const MCExpr*> EntryVecTy; Use a SmallVector here? + MCSymbol *getLabel() {return Label;} + size_t getNumEntries() {return Entries.size();} + const MCExpr *getEntry(size_t Num) {return Entries[Num];} These can be const. + int64_t ConstantPoolCounter; This can be unsigned. + case AsmToken::Equal: { + const MCSection *Section getParser().getStreamer().getCurrentSection().first; + assert(Section); We should probably check here that the mnemonic is actually 'ldr', e.g. see the AsmToken::Identifier case. +@ RUN: clang -target arm -integrated-as -c %s -o %t1 2> %t2; echo "ok" +@ RUN: cat %t2 | FileCheck %s Clang tests shouldn't be in the LLVM regression suite. Use llvm-mc instead for assembling. I'm not very familiar with the code around the asm parser, so I expect more detailed comments from others to follow. Cheers, Amara
Reasonably Related Threads
- [LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
- [LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
- [LLVMdev] [LLVM] Forward temp label references on ARM in LDR with .ltorg in inline assembly are broken in trunk
- [LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler
- [LLVMdev] Implementing the ldr pseudo instruction in ARM integrated assembler