[llvm-commits] [patch] v2 PR7608 ARMv4 JIT forgets to set the lr register when making a indirect function call

Xerxes Ranby xerxes at zafena.se
Mon Jul 19 11:32:18 PDT 2010


Bob Wilson wrote:
> On Jul 12, 2010, at 1:23 PM, Xerxes Ranby wrote:
>   
>> Bob Wilson wrote:
>>     
>>> I don't think this is good enough.  The "mov lr, pc" instruction must be emitted immediately before the call.  I don't know how to do that without making all the "call_nolink" instructions into pseudo-instructions.
>>>       
>> Where can I find documentation on what pseudo instructions are and how pseudo instructions can resolve this kind of situation?
>>     
>
> Look at ARMCodeEmitter::emitPseudoInstruction for some examples.  Basically you would just change the "call_nolink" instructions to be marked as pseudo instructions and then add code to ARMCodeEmitter to generate both the "mov lr, pc" and "bx" instructions together
Hi I have attached a new patch that basicaly implements what Bob 
suggested, thank you Bob, it marks all the ARM "call_nolink" 
instructions as pseudo instructions and adds code to ARMCodeEmitter to 
generate both the "mov lr, pc" and the branch instructions together. My 
own testing indicates that this work very well and fixes the PR7608 bug 
without introducing any new test regressions.

Index: llvm/lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- llvm.orig/lib/Target/ARM/ARMInstrInfo.td 2010-07-13 
17:41:01.000000000 +0200
+++ llvm/lib/Target/ARM/ARMInstrInfo.td 2010-07-19 17:11:19.000000000 +0200
@@ -961,7 +961,7 @@

// ARMv4T
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
- def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ def BX : PseudoInst<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, HasV4T, IsNotDarwin]> {
@@ -971,7 +971,7 @@
}

// ARMv4
- def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ def BMOVPCRX : PseudoInst<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, NoV4T, IsNotDarwin]> {
@@ -1010,7 +1010,7 @@

// ARMv4T
// Note: Restrict $func to the tGPR regclass to prevent it being in LR.
- def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ def BXr9 : PseudoInst<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, HasV4T, IsDarwin]> {
@@ -1020,7 +1020,7 @@
}

// ARMv4
- def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops),
+ def BMOVPCRXr9 : PseudoInst<(outs), (ins tGPR:$func, variable_ops),
IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsARM, NoV4T, IsDarwin]> {
Index: llvm/lib/Target/ARM/ARMCodeEmitter.cpp
===================================================================
--- llvm.orig/lib/Target/ARM/ARMCodeEmitter.cpp 2010-07-13 
17:41:01.000000000 +0200
+++ llvm/lib/Target/ARM/ARMCodeEmitter.cpp 2010-07-19 17:20:26.000000000 
+0200
@@ -654,6 +654,16 @@
switch (Opcode) {
default:
llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
+ case ARM::BX:
+ case ARM::BMOVPCRX:
+ case ARM::BXr9:
+ case ARM::BMOVPCRXr9: {
+ // First emit mov lr, pc
+ emitWordLE(0xe1a0e00f);
+ // and then emit the branch.
+ emitMiscBranchInstruction(MI);
+ break;
+ }
case TargetOpcode::INLINEASM: {
// We allow inline assembler nodes with empty bodies - they can
// implicitly define registers, which is ok for JIT.


Ok to push?

Cheers
Xerxes

-------------- next part --------------
A non-text attachment was scrubbed...
Name: rawMOVLRPC.patch
Type: text/x-patch
Size: 2515 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100719/010f3356/attachment.bin>


More information about the llvm-commits mailing list