OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |