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; |