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

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1424863005: Handle MOV (immediate) and MOVT to load ARM global addresses. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix movw and movt Created 5 years, 2 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
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 3dbbb29f0be6fde664abdf2b6b64b253e1f8a8fa..7fce7503e123a4a86c8796b8da71a123a8179dad 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -38,7 +38,9 @@ static constexpr IValueT B4 = 1 << 4;
static constexpr IValueT B5 = 1 << 5;
static constexpr IValueT B6 = 1 << 6;
static constexpr IValueT B21 = 1 << 21;
+static constexpr IValueT B22 = 1 << 22;
static constexpr IValueT B24 = 1 << 24;
+static constexpr IValueT B25 = 1 << 25;
// Constants used for the decoding or encoding of the individual fields of
// instructions. Based on ARM section A5.1.
@@ -222,6 +224,32 @@ bool canEncodeBranchOffset(IOffsetT Offset) {
namespace Ice {
namespace ARM32 {
+size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
+ const Assembler &Asm) const {
+ static constexpr const size_t FixupSize = sizeof(IValueT);
+ if (!BuildDefs::dump())
+ return FixupSize;
+ Ostream &Str = Ctx->getStrEmit();
+ IValueT Inst = Asm.load<IValueT>(position());
+ Str << "\tmov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t"
+ << RegARM32::RegNames[(Inst >> kRdShift) & 0xF]
+ << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper")
+ << "16:" << symbol(Ctx) << "\t@ .word "
+ << llvm::format_hex_no_prefix(Inst, 8) << "\n";
+ return FixupSize;
+}
+
+MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
+ const Constant *Value) {
+ MoveRelocatableFixup *F =
+ new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
+ F->set_kind(IsMovW ? llvm::ELF::R_ARM_MOVW_ABS_NC
+ : llvm::ELF::R_ARM_MOVT_ABS);
+ F->set_value(Value);
+ Buffer.installFixup(F);
+ return F;
+}
+
void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
GlobalContext *Ctx = Node->getCfg()->getContext();
if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
@@ -517,9 +545,8 @@ void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
// MOV (immediate) - ARM section A8.8.102, encoding A1:
// mov{S}<c> <Rd>, #<RotatedImm8>
//
- // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
- // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
- // assembler.
+ // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, and
+ // iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this assembler.
constexpr bool SetFlags = false;
if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
// Conditions of rule violated.
@@ -529,6 +556,62 @@ void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src);
}
+void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
+ CondARM32::Cond Cond) {
+ IValueT Rd;
+ if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
+ if (Src == nullptr)
Karl 2015/10/29 18:35:06 Added fallback if not relocatable constant.
+ return setNeedsTextFixup();
+ // MOV (immediate) - ARM section A8.8.102, encoding A2:
+ // movw<c> <Rd>, #<imm16>
+ //
+ // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
+ // iiiiiiiiiiiiiiii=imm16.
+ if (!isConditionDefined(Cond))
+ // Conditions of rule violated.
+ return setNeedsTextFixup();
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
+ // install the correct bits.
+ constexpr bool IsMovW = true;
+ emitFixup(createMoveFixup(IsMovW, Src));
+ constexpr IValueT Imm16 = 0;
+ const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
+ B24 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
+ (Imm16 & 0xfff);
+ emitInst(Encoding);
+}
+
+void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
+ CondARM32::Cond Cond) {
+ IValueT Rd;
+ if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
+ if (Src == nullptr)
Karl 2015/10/29 18:35:06 Added fallback if not relocatable constant.
+ return setNeedsTextFixup();
+ // MOVT - ARM section A8.8.102, encoding A2:
+ // movt<c> <Rd>, #<imm16>
+ //
+ // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
+ // iiiiiiiiiiiiiiii=imm16.
+ if (!isConditionDefined(Cond))
+ // Conditions of rule violated.
+ return setNeedsTextFixup();
+ AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+ // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
+ // install the correct bits.
+ constexpr bool IsMovW = false;
+ emitFixup(createMoveFixup(IsMovW, Src));
+ constexpr IValueT Imm16 = 0;
+ const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
+ B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
+ (Imm16 & 0xfff);
+ emitInst(Encoding);
+}
+
void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
const Operand *OpSrc1, bool SetFlags,
CondARM32::Cond Cond) {
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698