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

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 nits. 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 eb785ffa27c704484518a52cff8d5195979651a2..5b4d5896fafe9576a23a98c4851baa78368c1ab5 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,43 @@ 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 << "\t";
+ if (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC)
Jim Stichnoth 2015/10/28 22:28:55 What do you think of a long statement like Str <
Karl 2015/10/29 16:57:53 Done.
+ Str << "movw";
+ else
+ Str << "movt";
+ Str << "\t" << RegARM32::RegNames[(Inst >> kRdShift) & 0xF] << ", #:";
+ if (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC)
+ Str << "lower";
+ else
+ Str << "upper";
+ Str << "16:" << symbol(Ctx) << "\t@ .word ";
+ IValueT HexMask = 0xF;
+ for (int HexDigit = 2 * FixupSize; HexDigit > 0; --HexDigit) {
Jim Stichnoth 2015/10/28 22:28:55 Can you use llvm::format_hex_no_prefix() ? This i
Karl 2015/10/29 16:57:53 Done.
+ Str.write_hex((Inst >> 4 * (HexDigit - 1)) & HexMask);
+ }
+ Str << "\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) {
if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
// Generate label name so that branches can find it.
@@ -528,6 +567,64 @@ 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) {
+ (void)Cond;
Jim Stichnoth 2015/10/28 22:28:55 Remove this?
Karl 2015/10/29 16:57:53 Done.
+ IValueT Rd;
+ if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ if (auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
+ // 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
Jim Stichnoth 2015/10/28 22:28:55 reflow comment to 80-col
Karl 2015/10/29 16:57:53 Done.
+ // 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);
+ }
+ setNeedsTextFixup();
Jim Stichnoth 2015/10/28 22:28:55 This call is a little puzzling because I think it
Karl 2015/10/29 16:57:53 Hmm, this is a mistake. It shouldn't even be there
+}
+
+void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
+ CondARM32::Cond Cond) {
+ (void)Cond;
Jim Stichnoth 2015/10/28 22:28:55 remove?
Karl 2015/10/29 16:57:53 Done.
+ IValueT Rd;
+ if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
+ return setNeedsTextFixup();
+ if (auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
+ // 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);
+ }
+ setNeedsTextFixup();
Karl 2015/10/29 16:57:53 Removed this also.
+}
+
void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
CondARM32::Cond Cond) {
IValueT Rt;
« 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