diff options
author | Tim Northover <tnorthover@apple.com> | 2013-07-01 19:23:10 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2013-07-01 19:23:10 +0000 |
commit | 8625fd8cad18731d042dad5f22ad926ed9f99b66 (patch) | |
tree | 9a42be1a6f96a51d891cee5d19e489e802a3d5f2 /llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | |
parent | 8b30c13e12b5ebc60f5f84f2ccfbc9c64199cf96 (diff) | |
download | bcm5719-llvm-8625fd8cad18731d042dad5f22ad926ed9f99b66.tar.gz bcm5719-llvm-8625fd8cad18731d042dad5f22ad926ed9f99b66.zip |
AArch64: correct CodeGen of MOVZ/MOVK combinations.
According to the AArch64 ELF specification (4.6.8), it's the
assembler's responsibility to make sure the shift amount is correct in
relocated MOVZ/MOVK instructions.
This wasn't being obeyed by either the MCJIT CodeGen or RuntimeDyldELF
(which happened to work out well for JIT tests). This commit should
make us compliant in this area.
llvm-svn: 185360
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 722ed10f733..cb3b5129f23 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -334,8 +334,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, *TargetPtr &= 0xff80001fU; // Immediate goes in bits 20:5 of MOVZ/MOVK instruction *TargetPtr |= Result >> (48 - 5); - // Shift is "lsl #48", in bits 22:21 - *TargetPtr |= 3 << 21; + // Shift must be "lsl #48", in bits 22:21 + assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation"); break; } case ELF::R_AARCH64_MOVW_UABS_G2_NC: { @@ -347,8 +347,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, *TargetPtr &= 0xff80001fU; // Immediate goes in bits 20:5 of MOVZ/MOVK instruction *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5)); - // Shift is "lsl #32", in bits 22:21 - *TargetPtr |= 2 << 21; + // Shift must be "lsl #32", in bits 22:21 + assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation"); break; } case ELF::R_AARCH64_MOVW_UABS_G1_NC: { @@ -359,8 +359,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, *TargetPtr &= 0xff80001fU; // Immediate goes in bits 20:5 of MOVZ/MOVK instruction *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5)); - // Shift is "lsl #16", in bits 22:21 - *TargetPtr |= 1 << 21; + // Shift must be "lsl #16", in bits 22:2 + assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation"); break; } case ELF::R_AARCH64_MOVW_UABS_G0_NC: { @@ -371,7 +371,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, *TargetPtr &= 0xff80001fU; // Immediate goes in bits 20:5 of MOVZ/MOVK instruction *TargetPtr |= ((Result & 0xffffU) << 5); - // Shift is "lsl #0", in bits 22:21. No action needed. + // Shift must be "lsl #0", in bits 22:21. + assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation"); break; } } |