ARM64: initial backend import

This adds a second implementation of the AArch64 architecture to LLVM,
accessible in parallel via the "arm64" triple. The plan over the
coming weeks & months is to merge the two into a single backend,
during which time thorough code review should naturally occur.

Everything will be easier with the target in-tree though, hence this
commit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205090 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover
2014-03-29 10:18:08 +00:00
parent 69bd9577fc
commit 7b837d8c75
394 changed files with 105888 additions and 32 deletions

View File

@@ -167,6 +167,10 @@ void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
resolveARMRelocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
MachoType, Size, Addend);
break;
case Triple::arm64:
resolveARM64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
isPCRel, MachoType, Size, Addend);
break;
}
}
@@ -293,6 +297,55 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
return false;
}
bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress,
uint64_t FinalAddress,
uint64_t Value, bool isPCRel,
unsigned Type, unsigned Size,
int64_t Addend) {
// If the relocation is PC-relative, the value to be encoded is the
// pointer difference.
if (isPCRel)
Value -= FinalAddress;
switch (Type) {
default:
llvm_unreachable("Invalid relocation type!");
case MachO::ARM64_RELOC_UNSIGNED: {
// Mask in the target value a byte at a time (we don't have an alignment
// guarantee for the target address, so this is safest).
uint8_t *p = (uint8_t *)LocalAddress;
for (unsigned i = 0; i < Size; ++i) {
*p++ = (uint8_t)Value;
Value >>= 8;
}
break;
}
case MachO::ARM64_RELOC_BRANCH26: {
// Mask the value into the target address. We know instructions are
// 32-bit aligned, so we can do it all at once.
uint32_t *p = (uint32_t *)LocalAddress;
// The low two bits of the value are not encoded.
Value >>= 2;
// Mask the value to 26 bits.
Value &= 0x3ffffff;
// Insert the value into the instruction.
*p = (*p & ~0x3ffffff) | Value;
break;
}
case MachO::ARM64_RELOC_SUBTRACTOR:
case MachO::ARM64_RELOC_PAGE21:
case MachO::ARM64_RELOC_PAGEOFF12:
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
case MachO::ARM64_RELOC_POINTER_TO_GOT:
case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
case MachO::ARM64_RELOC_ADDEND:
return Error("Relocation type not implemented yet!");
}
return false;
}
relocation_iterator RuntimeDyldMachO::processRelocationRef(
unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,

View File

@@ -34,6 +34,9 @@ class RuntimeDyldMachO : public RuntimeDyldImpl {
bool resolveARMRelocation(uint8_t *LocalAddress, uint64_t FinalAddress,
uint64_t Value, bool isPCRel, unsigned Type,
unsigned Size, int64_t Addend);
bool resolveARM64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
uint64_t Value, bool IsPCRel, unsigned Type,
unsigned Size, int64_t Addend);
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
uint64_t Value, uint32_t Type, int64_t Addend,