Chromium Code Reviews| 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; |