Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(609)

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1669443002: Subzero. Uses fixups to calculate addend to relocations. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 2044050216fcfb223d3093e5e07d897c6af17d3c..7e177ed4eb3a03fa665d9b999a29d98eb4dc59e0 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -506,6 +506,20 @@ bool canEncodeBranchOffset(IOffsetT Offset) {
Utils::IsInt(kBranchOffsetBits, Offset >> 2);
}
+IValueT encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
+ // Adjust offset to the way ARM CPUs read PC.
+ Offset -= kPCReadOffset;
+
+ bool IsGoodOffset = canEncodeBranchOffset(Offset);
Jim Stichnoth 2016/02/03 23:18:27 Maybe just: assert(canEncodeBranchOffset(Offset)
John 2016/02/04 18:28:50 Done.
+ assert(IsGoodOffset);
+ (void)IsGoodOffset;
+
+ // Properly preserve only the bits supported in the instruction.
+ Offset >>= 2;
+ Offset &= kBranchOffsetMask;
+ return (Inst & ~kBranchOffsetMask) | Offset;
+}
+
IValueT encodeRegister(const Operand *OpReg, RegSetWanted WantedRegSet,
const char *RegName, const char *InstName) {
IValueT Reg = 0;
@@ -595,6 +609,19 @@ size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
return InstARM32::InstSize;
}
+// This fixup points to an ARM32 instruction with the following format:
+void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
+ // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
+ // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt.
+
+ const IValueT Inst = Asm->load<IValueT>(position());
+ constexpr IValueT Imm16Mask = 0x000F0FFF;
+ const IValueT Imm16 =
+ offset() >> (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? 0 : 16) & 0xffff;
+ Asm->store(position(),
+ (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff));
+}
+
MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
const Constant *Value) {
MoveRelocatableFixup *F =
@@ -618,6 +645,15 @@ size_t BlRelocatableFixup::emit(GlobalContext *Ctx,
return InstARM32::InstSize;
}
+void BlRelocatableFixup::emitOffset(Assembler *Asm) const {
+ // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
+ // iiiiiiiiiiiiiiiiiiiiiiii=
+ // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
+ const IValueT Inst = Asm->load<IValueT>(position());
+ constexpr IValueT OffsetMask = 0x00FFFFFF;
+ Asm->store(position(), encodeBranchOffset(offset(), Inst & ~OffsetMask));
+}
+
void AssemblerARM32::padWithNop(intptr_t Padding) {
constexpr intptr_t InstWidth = sizeof(IValueT);
assert(Padding % InstWidth == 0 &&
@@ -667,20 +703,6 @@ Label *AssemblerARM32::getOrCreateLabel(SizeT Number, LabelVector &Labels) {
return L;
}
-IValueT AssemblerARM32::encodeBranchOffset(IOffsetT Offset, IValueT Inst) {
- // Adjust offset to the way ARM CPUs read PC.
- Offset -= kPCReadOffset;
-
- bool IsGoodOffset = canEncodeBranchOffset(Offset);
- assert(IsGoodOffset);
- (void)IsGoodOffset;
-
- // Properly preserve only the bits supported in the instruction.
- Offset >>= 2;
- Offset &= kBranchOffsetMask;
- return (Inst & ~kBranchOffsetMask) | Offset;
-}
-
// Pull out offset from branch Inst.
IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) {
// Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC.

Powered by Google App Engine
This is Rietveld 408576698