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

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 movw and movt 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 << "\tmov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t"
235 << RegARM32::RegNames[(Inst >> kRdShift) & 0xF]
236 << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper")
237 << "16:" << symbol(Ctx) << "\t@ .word "
238 << llvm::format_hex_no_prefix(Inst, 8) << "\n";
239 return FixupSize;
240 }
241
242 MoveRelocatableFixup *AssemblerARM32::createMoveFixup(bool IsMovW,
243 const Constant *Value) {
244 MoveRelocatableFixup *F =
245 new (allocate<MoveRelocatableFixup>()) MoveRelocatableFixup();
246 F->set_kind(IsMovW ? llvm::ELF::R_ARM_MOVW_ABS_NC
247 : llvm::ELF::R_ARM_MOVT_ABS);
248 F->set_value(Value);
249 Buffer.installFixup(F);
250 return F;
251 }
252
225 void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) { 253 void AssemblerARM32::bindCfgNodeLabel(const CfgNode *Node) {
226 GlobalContext *Ctx = Node->getCfg()->getContext(); 254 GlobalContext *Ctx = Node->getCfg()->getContext();
227 if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) { 255 if (BuildDefs::dump() && !Ctx->getFlags().getDisableHybridAssembly()) {
228 // Generate label name so that branches can find it. 256 // Generate label name so that branches can find it.
229 constexpr SizeT InstSize = 0; 257 constexpr SizeT InstSize = 0;
230 emitTextInst(Node->getAsmName() + ":", InstSize); 258 emitTextInst(Node->getAsmName() + ":", InstSize);
231 } 259 }
232 SizeT NodeNumber = Node->getIndex(); 260 SizeT NodeNumber = Node->getIndex();
233 assert(!getPreliminary()); 261 assert(!getPreliminary());
234 Label *L = getOrCreateCfgNodeLabel(NodeNumber); 262 Label *L = getOrCreateCfgNodeLabel(NodeNumber);
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 IValueT Rd; 538 IValueT Rd;
511 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 539 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
512 return setNeedsTextFixup(); 540 return setNeedsTextFixup();
513 IValueT Src; 541 IValueT Src;
514 // TODO(kschimpf) Handle other forms of mov. 542 // TODO(kschimpf) Handle other forms of mov.
515 if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8) 543 if (decodeOperand(OpSrc, Src) != DecodedAsRotatedImm8)
516 return setNeedsTextFixup(); 544 return setNeedsTextFixup();
517 // MOV (immediate) - ARM section A8.8.102, encoding A1: 545 // MOV (immediate) - ARM section A8.8.102, encoding A1:
518 // mov{S}<c> <Rd>, #<RotatedImm8> 546 // mov{S}<c> <Rd>, #<RotatedImm8>
519 // 547 //
520 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 548 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, and
521 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 549 // iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this assembler.
522 // assembler.
523 constexpr bool SetFlags = false; 550 constexpr bool SetFlags = false;
524 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags)) 551 if ((Rd == RegARM32::Encoded_Reg_pc && SetFlags))
525 // Conditions of rule violated. 552 // Conditions of rule violated.
526 return setNeedsTextFixup(); 553 return setNeedsTextFixup();
527 constexpr IValueT Rn = 0; 554 constexpr IValueT Rn = 0;
528 constexpr IValueT Mov = B3 | B2 | B0; // 1101. 555 constexpr IValueT Mov = B3 | B2 | B0; // 1101.
529 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src); 556 emitType01(Cond, kInstTypeDataImmediate, Mov, SetFlags, Rn, Rd, Src);
530 } 557 }
531 558
559 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
560 CondARM32::Cond Cond) {
561 IValueT Rd;
562 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
563 return setNeedsTextFixup();
564 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
565 if (Src == nullptr)
Karl 2015/10/29 18:35:06 Added fallback if not relocatable constant.
566 return setNeedsTextFixup();
567 // MOV (immediate) - ARM section A8.8.102, encoding A2:
568 // movw<c> <Rd>, #<imm16>
569 //
570 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
571 // iiiiiiiiiiiiiiii=imm16.
572 if (!isConditionDefined(Cond))
573 // Conditions of rule violated.
574 return setNeedsTextFixup();
575 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
576 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
577 // install the correct bits.
578 constexpr bool IsMovW = true;
579 emitFixup(createMoveFixup(IsMovW, Src));
580 constexpr IValueT Imm16 = 0;
581 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
582 B24 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
583 (Imm16 & 0xfff);
584 emitInst(Encoding);
585 }
586
587 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
588 CondARM32::Cond Cond) {
589 IValueT Rd;
590 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
591 return setNeedsTextFixup();
592 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
593 if (Src == nullptr)
Karl 2015/10/29 18:35:06 Added fallback if not relocatable constant.
594 return setNeedsTextFixup();
595 // MOVT - ARM section A8.8.102, encoding A2:
596 // movt<c> <Rd>, #<imm16>
597 //
598 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
599 // iiiiiiiiiiiiiiii=imm16.
600 if (!isConditionDefined(Cond))
601 // Conditions of rule violated.
602 return setNeedsTextFixup();
603 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
604 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
605 // install the correct bits.
606 constexpr bool IsMovW = false;
607 emitFixup(createMoveFixup(IsMovW, Src));
608 constexpr IValueT Imm16 = 0;
609 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 |
610 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift |
611 (Imm16 & 0xfff);
612 emitInst(Encoding);
613 }
614
532 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, 615 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
533 const Operand *OpSrc1, bool SetFlags, 616 const Operand *OpSrc1, bool SetFlags,
534 CondARM32::Cond Cond) { 617 CondARM32::Cond Cond) {
535 IValueT Rd; 618 IValueT Rd;
536 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 619 if (decodeOperand(OpRd, Rd) != DecodedAsRegister)
537 return setNeedsTextFixup(); 620 return setNeedsTextFixup();
538 IValueT Rn; 621 IValueT Rn;
539 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 622 if (decodeOperand(OpRn, Rn) != DecodedAsRegister)
540 return setNeedsTextFixup(); 623 return setNeedsTextFixup();
541 constexpr IValueT Sbc = B2 | B1; // 0110 624 constexpr IValueT Sbc = B2 | B1; // 0110
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 // Conditions of rule violated. 734 // Conditions of rule violated.
652 return setNeedsTextFixup(); 735 return setNeedsTextFixup();
653 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); 736 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value);
654 return; 737 return;
655 } 738 }
656 } 739 }
657 } 740 }
658 741
659 } // end of namespace ARM32 742 } // end of namespace ARM32
660 } // end of namespace Ice 743 } // 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