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

Xerxes Ranby xerxes at zafena.se
Thu Jul 22 01:46:45 PDT 2010


Bob Wilson wrote:
> Wait a minute....  How does EmitMiscBranchInstruction() know how to encode those BX instructions?
Whats going on in emitMiscBranchInstruction() when encoding BX, BXr9, 
BMOVPCRX, BMOVPCRXr9 are

  // Part of binary is determined by TableGn.
  unsigned Binary = getBinaryCodeForInstr(MI);

  // Set the conditional execution predicate
  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
  // Set branch register containing branch address
  Binary |= getMachineOpValue(MI, 0);

  emitWordLE(Binary);

All encoding except the conditional execution predicate and the branch 
register was already set by TableGn.
The emitMiscBranchInstruction() only needed to fill in the low nibble 
with the branch address and the high nibble  with the conditional 
execution code.
>   You need to add the encoding bits in the .td file.  Instead of declaring them as PseudoInsts, declare them as real instructions (similar to BRIND), but set the format to "Pseudo".
>   

I have attached a new patch that sets the format to "Pseudo" for the 
ABXIx2 class only used by BX, BXr9, BMOVPCRX and BMOVPCRXr9.
I have also made sure mov lr, pc gets set the same conditional execution 
predicate as the branch it belongs to.

Index: llvm/lib/Target/ARM/ARMCodeEmitter.cpp
===================================================================
--- llvm.orig/lib/Target/ARM/ARMCodeEmitter.cpp    2010-07-19 
22:43:33.000000000 +0200
+++ llvm/lib/Target/ARM/ARMCodeEmitter.cpp    2010-07-22 
10:25:28.000000000 +0200
@@ -654,6 +654,19 @@
   switch (Opcode) {
   default:
     llvm_unreachable("ARMCodeEmitter::emitPseudoInstruction");
+  case ARM::BX:
+  case ARM::BMOVPCRX:
+  case ARM::BXr9:
+  case ARM::BMOVPCRXr9: {
+    // First emit mov lr, pc
+    unsigned Binary = 0x01a0e00f;
+    Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+    emitWordLE(Binary);
+
+    // 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.
Index: llvm/lib/Target/ARM/ARMInstrFormats.td
===================================================================
--- llvm.orig/lib/Target/ARM/ARMInstrFormats.td    2010-07-22 
00:06:34.000000000 +0200
+++ llvm/lib/Target/ARM/ARMInstrFormats.td    2010-07-22 
09:11:36.000000000 +0200
@@ -313,7 +313,7 @@
 }
 class ABXIx2<dag oops, dag iops, InstrItinClass itin,
              string asm, list<dag> pattern>
-  : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, BrMiscFrm, 
itin,
+  : XI<oops, iops, AddrModeNone, Size8Bytes, IndexModeNone, Pseudo, itin,
        asm, "", pattern>;
 
 // BR_JT instructions

Ok to push?

Xerxes
-------------- next part --------------
A non-text attachment was scrubbed...
Name: condPredMOVLRPC.patch
Type: text/x-patch
Size: 1485 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100722/cc37b7b2/attachment.bin>


More information about the llvm-commits mailing list