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

Side by Side 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, 1 month 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 unified diff | Download patch
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 20 matching lines...) Expand all
31 31
32 // The following define individual bits. 32 // The following define individual bits.
33 static constexpr IValueT B0 = 1; 33 static constexpr IValueT B0 = 1;
34 static constexpr IValueT B1 = 1 << 1; 34 static constexpr IValueT B1 = 1 << 1;
35 static constexpr IValueT B2 = 1 << 2; 35 static constexpr IValueT B2 = 1 << 2;
36 static constexpr IValueT B3 = 1 << 3; 36 static constexpr IValueT B3 = 1 << 3;
37 static constexpr IValueT B4 = 1 << 4; 37 static constexpr IValueT B4 = 1 << 4;
38 static constexpr IValueT B5 = 1 << 5; 38 static constexpr IValueT B5 = 1 << 5;
39 static constexpr IValueT B6 = 1 << 6; 39 static constexpr IValueT B6 = 1 << 6;
40 static constexpr IValueT B21 = 1 << 21; 40 static constexpr IValueT B21 = 1 << 21;
41 static constexpr IValueT B22 = 1 << 22;
41 static constexpr IValueT B24 = 1 << 24; 42 static constexpr IValueT B24 = 1 << 24;
43 static constexpr IValueT B25 = 1 << 25;
42 44
43 // Constants used for the decoding or encoding of the individual fields of 45 // Constants used for the decoding or encoding of the individual fields of
44 // instructions. Based on ARM section A5.1. 46 // instructions. Based on ARM section A5.1.
45 static constexpr IValueT L = 1 << 20; // load (or store) 47 static constexpr IValueT L = 1 << 20; // load (or store)
46 static constexpr IValueT W = 1 << 21; // writeback base register 48 static constexpr IValueT W = 1 << 21; // writeback base register
47 // (or leave unchanged) 49 // (or leave unchanged)
48 static constexpr IValueT B = 1 << 22; // unsigned byte (or word) 50 static constexpr IValueT B = 1 << 22; // unsigned byte (or word)
49 static constexpr IValueT U = 1 << 23; // positive (or negative) 51 static constexpr IValueT U = 1 << 23; // positive (or negative)
50 // offset/index 52 // offset/index
51 static constexpr IValueT P = 1 << 24; // offset/pre-indexed 53 static constexpr IValueT P = 1 << 24; // offset/pre-indexed
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 bool canEncodeBranchOffset(IOffsetT Offset) { 217 bool canEncodeBranchOffset(IOffsetT Offset) {
216 return Utils::IsAligned(Offset, 4) && 218 return Utils::IsAligned(Offset, 4) &&
217 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 219 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
218 } 220 }
219 221
220 } // end of anonymous namespace 222 } // end of anonymous namespace
221 223
222 namespace Ice { 224 namespace Ice {
223 namespace ARM32 { 225 namespace ARM32 {
224 226
227 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
228 const Assembler &Asm) const {
229 static constexpr const size_t FixupSize = sizeof(IValueT);
230 if (!BuildDefs::dump())
231 return FixupSize;
232 Ostream &Str = Ctx->getStrEmit();
233 IValueT Inst = Asm.load<IValueT>(position());
234 Str << "\t";
235 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.
236 Str << "movw";
237 else
238 Str << "movt";
239 Str << "\t" << RegARM32::RegNames[(Inst >> kRdShift) & 0xF] << ", #:";
240 if (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC)
241 Str << "lower";
242 else
243 Str << "upper";
244 Str << "16:" << symbol(Ctx) << "\t@ .word ";
245 IValueT HexMask = 0xF;
246 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.
247 Str.write_hex((Inst >> 4 * (HexDigit - 1)) & HexMask);
248 }
249 Str << "\n";
250 return FixupSize;
251 }
252
253 MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
254 const Constant *Value) {
255 MoveRelocatableFixup *F =
256 new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
257 F->set_kind(IsMovW ? llvm::ELF::R_ARM_MOVW_ABS_NC
258 : llvm::ELF::R_ARM_MOVT_ABS);
259 F->set_value(Value);
260 Buffer.installFixup(F);
261 return F;
262 }
263
225 void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) { 264 void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
226 if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) { 265 if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
227 // Generate label name so that branches can find it. 266 // Generate label name so that branches can find it.
228 constexpr SizeT InstSize = 0; 267 constexpr SizeT InstSize = 0;
229 emitTextInst(Node->getAsmName() + ":", InstSize); 268 emitTextInst(Node->getAsmName() + ":", InstSize);
230 } 269 }
231 SizeT NodeNumber = Node->getIndex(); 270 SizeT NodeNumber = Node->getIndex();
232 assert(!getPreliminary()); 271 assert(!getPreliminary());
233 Label *L = getOrCreateCfgNodeLabel(NodeNumber); 272 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
234 this->bind(L); 273 this->bind(L);
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 // assembler. 560 // assembler.
522 constexpr bool SetFlags = false; 561 constexpr bool SetFlags = false;
523 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 562 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
524 // Conditions of rule violated. 563 // Conditions of rule violated.
525 return setNeedsTextFixup(); 564 return setNeedsTextFixup();
526 constexpr IValueT Rn = 0; 565 constexpr IValueT Rn = 0;
527 constexpr IValueT Mov = B3 | B2 | B0; // 1101. 566 constexpr IValueT Mov = B3 | B2 | B0; // 1101.
528 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src); 567 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src);
529 } 568 }
530 569
570 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
571 CondARM32::Cond Cond) {
572 (void)Cond;
Jim Stichnoth 2015/10/28 22:28:55 Remove this?
Karl 2015/10/29 16:57:53 Done.
573 IValueT Rd;
574 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
575 return setNeedsTextFixup();
576 if (auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
577 // MOV (immediate) - ARM section A8.8.102, encoding A2:
578 // movw<c> <Rd>, #<imm16>
579 //
580 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
581 // and iiiiiiiiiiiiiiii=imm16.
582 if (!isConditionDefined(Cond))
583 // Conditions of rule violated.
584 return setNeedsTextFixup();
585 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
586 // 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.
587 // fixup to install the correct bits.
588 constexpr bool IsMovW = true;
589 emitFixup(createMoveFixup(IsMovW, Src));
590 constexpr IValueT Imm16 = 0;
591 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
592 B24 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
593 (Imm16 & 0xfff);
594 emitInst(Encoding);
595 }
596 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
597 }
598
599 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
600 CondARM32::Cond Cond) {
601 (void)Cond;
Jim Stichnoth 2015/10/28 22:28:55 remove?
Karl 2015/10/29 16:57:53 Done.
602 IValueT Rd;
603 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
604 return setNeedsTextFixup();
605 if (auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
606 // MOVT - ARM section A8.8.102, encoding A2:
607 // movt<c> <Rd>, #<imm16>
608 //
609 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
610 // and iiiiiiiiiiiiiiii=imm16.
611 if (!isConditionDefined(Cond))
612 // Conditions of rule violated.
613 return setNeedsTextFixup();
614 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
615 // Use 0 for the lower 16 bits of the relocatable, and add a
616 // fixup to install the correct bits.
617 constexpr bool IsMovW = false;
618 emitFixup(createMoveFixup(IsMovW, Src));
619 constexpr IValueT Imm16 = 0;
620 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
621 B24 | B22 | ((Imm16 >> 12) << 16) |
622 Rd << kRdShift | (Imm16 & 0xfff);
623 emitInst(Encoding);
624 }
625 setNeedsTextFixup();
Karl 2015/10/29 16:57:53 Removed this also.
626 }
627
531 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 628 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
532 CondARM32::Cond Cond) { 629 CondARM32::Cond Cond) {
533 IValueT Rt; 630 IValueT Rt;
534 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 631 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
535 return setNeedsTextFixup(); 632 return setNeedsTextFixup();
536 IValueT Address; 633 IValueT Address;
537 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) 634 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset)
538 return setNeedsTextFixup(); 635 return setNeedsTextFixup();
539 // STR (immediate) - ARM section A8.8.204, encoding A1: 636 // STR (immediate) - ARM section A8.8.204, encoding A1:
540 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 637 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 // Conditions of rule violated. 703 // Conditions of rule violated.
607 return setNeedsTextFixup(); 704 return setNeedsTextFixup();
608 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); 705 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value);
609 return; 706 return;
610 } 707 }
611 } 708 }
612 } 709 }
613 710
614 } // end of namespace ARM32 711 } // end of namespace ARM32
615 } // end of namespace Ice 712 } // end of namespace Ice
OLDNEW
« 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