[llvm-commits] [LLVMdev] Help with PPC64 JIT

Will Schmidt will_schmidt at vnet.ibm.com
Thu Aug 2 10:23:17 PDT 2012


On Tue, 2012-07-31 at 11:43 -0300, Adhemerval Zanella wrote:
> The modifications I have done so far are in attachments. Basically it
> adds the PPC64 machine
> name in Target, add some relocation support in Elf Runtime class. I'm
> still figuring out a
> lot of internal llvm and the patch is still WIP.


Thanks for sharing. :-)   One comment below.


> 
> 
> 
> 
> 
> differences
> between files
> attachment
> (mcjit-ppc64.patch)
> 
> Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
> ===================================================================
> --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp  (revision
> 160672)
> +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp  (working copy)
> @@ -307,6 +307,57 @@
>    }
>  }
> 
> +
> +#define PPC_LO(v) ((v) & 0xffff)
> +#define PPC_HI(v) (((v) >> 16) & 0xffff)
> +#define PPC_HA(v) PPC_HI ((v) + 0x8000)
> +#define BIT_INSERT(var, val, mask) \
> +  ((var) = ((var) & ~(uint64_t) (mask)) | ((val) & (mask)))
> +
> +void RuntimeDyldELF::resolvePPC64Relocation(uint8_t *LocalAddress,
> +                                           uint64_t FinalAddress,
> +                                           uint64_t Value,
> +                                           uint32_t Type,
> +                                           int64_t Addend) {
> +  switch (Type) {
> +  default:
> +    llvm_unreachable("Relocation type not implemented yet!");
> +  break;
> +  case ELF::R_PPC64_ADDR16_LO :
> +    *(uint16_t*)(LocalAddress) = PPC_LO (Value);
> +    break;
> +  case ELF::R_PPC64_ADDR16_HA :
> +    *(uint16_t*)(LocalAddress) = PPC_HA (Value);
> +    break;
> +  case ELF::R_PPC64_ADDR14 :
> +    {
> +      if (((Value + 0x8000) >= 0x10000) || ((Value & 3) != 0))
> +       // TODO add more info
> +       llvm_unreachable("Relocation R_PPC64_REL24 overflow");
> +      int64_t insn = *(int64_t*)(LocalAddress);
> +      BIT_INSERT (insn, Value, 0xFFFC);

> +      insn &= ~(1 << 21);
> +      if ((insn & (0x14 << 21)) == (0x04 << 21))
> +       insn |= 0x02 << 21;
> +      else if ((insn & (0x14 << 21)) == (0x10 << 21))
> +       insn |= 0x08 << 21;

^^ Could use a comment to explain what it's checking for.  I've not
lined up all the bits to verify, but per a side conversation, I believe
this was handling some branch prediction indicators.   That may be the
intent behind "// TODO add more info", but I wanted to call this out in
case it wasn't. 

Thanks,
-Will

> +      *(int64_t*)(LocalAddress) = insn;
> +    } break;
> +  case ELF::R_PPC64_REL24 :
> +    {
> +      int32_t delta = static_cast<int32_t>(FinalAddress - Value);
> +      if (delta << 6 >> 6 != delta)
> +       // TODO add more info
> +       llvm_unreachable("Relocation R_PPC64_REL24 overflow");
> +      uint32_t *Target = (uint32_t*)(LocalAddress);
> +      *Target = (*Target & 0xFC000003) | (delta & 0x3FFFFFC);
> +    } break;
> +  case ELF::R_PPC64_ADDR64 :
> +    *(uint64_t*)(LocalAddress) = Value;
> +    break;
> +  }
> +}
> + 




More information about the llvm-commits mailing list