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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 // Extract out a Bit in Value. | 188 // Extract out a Bit in Value. |
189 bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; } | 189 bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; } |
190 | 190 |
191 // Returns the GPR register at given Shift in Value. | 191 // Returns the GPR register at given Shift in Value. |
192 RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { | 192 RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { |
193 return decodeGPRRegister((Value >> Shift) & 0xF); | 193 return decodeGPRRegister((Value >> Shift) & 0xF); |
194 } | 194 } |
195 | 195 |
196 IValueT getEncodedGPRegNum(const Variable *Var) { | 196 IValueT getEncodedGPRegNum(const Variable *Var) { |
197 assert(Var->hasReg()); | 197 assert(Var->hasReg()); |
198 int32_t Reg = Var->getRegNum(); | 198 auto Reg = Var->getRegNum(); |
199 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) | 199 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) |
200 : RegARM32::getEncodedGPR(Reg); | 200 : RegARM32::getEncodedGPR(Reg); |
201 } | 201 } |
202 | 202 |
203 IValueT getEncodedSRegNum(const Variable *Var) { | 203 IValueT getEncodedSRegNum(const Variable *Var) { |
204 assert(Var->hasReg()); | 204 assert(Var->hasReg()); |
205 return RegARM32::getEncodedSReg(Var->getRegNum()); | 205 return RegARM32::getEncodedSReg(Var->getRegNum()); |
206 } | 206 } |
207 | 207 |
208 IValueT getEncodedDRegNum(const Variable *Var) { | 208 IValueT getEncodedDRegNum(const Variable *Var) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 const AssemblerARM32::TargetInfo &TInfo, | 463 const AssemblerARM32::TargetInfo &TInfo, |
464 EncodedImmAddress ImmEncoding) { | 464 EncodedImmAddress ImmEncoding) { |
465 Value = 0; // Make sure initialized. | 465 Value = 0; // Make sure initialized. |
466 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 466 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
467 // Should be a stack variable, with an offset. | 467 // Should be a stack variable, with an offset. |
468 if (Var->hasReg()) | 468 if (Var->hasReg()) |
469 return CantEncode; | 469 return CantEncode; |
470 IOffsetT Offset = Var->getStackOffset(); | 470 IOffsetT Offset = Var->getStackOffset(); |
471 if (!Utils::IsAbsoluteUint(12, Offset)) | 471 if (!Utils::IsAbsoluteUint(12, Offset)) |
472 return CantEncode; | 472 return CantEncode; |
473 int32_t BaseRegNum = Var->getBaseRegNum(); | 473 auto BaseRegNum = Var->getBaseRegNum(); |
474 if (BaseRegNum == Variable::NoRegister) | 474 if (BaseRegNum == RegNumT::NoRegister) |
475 BaseRegNum = TInfo.FrameOrStackReg; | 475 BaseRegNum = TInfo.FrameOrStackReg; |
476 Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset, | 476 Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset, |
477 OperandARM32Mem::Offset); | 477 OperandARM32Mem::Offset); |
478 return EncodedAsImmRegOffset; | 478 return EncodedAsImmRegOffset; |
479 } | 479 } |
480 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { | 480 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { |
481 Variable *Var = Mem->getBase(); | 481 Variable *Var = Mem->getBase(); |
482 if (!Var->hasReg()) | 482 if (!Var->hasReg()) |
483 return CantEncode; | 483 return CantEncode; |
484 IValueT Rn = getEncodedGPRegNum(Var); | 484 IValueT Rn = getEncodedGPRegNum(Var); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
578 llvm::report_fatal_error(std::string(InstName) + ": " + RegName + | 578 llvm::report_fatal_error(std::string(InstName) + ": " + RegName + |
579 "=pc not allowed"); | 579 "=pc not allowed"); |
580 } | 580 } |
581 | 581 |
582 void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags, | 582 void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags, |
583 const char *InstName) { | 583 const char *InstName) { |
584 if (BuildDefs::minimal()) | 584 if (BuildDefs::minimal()) |
585 return; | 585 return; |
586 if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc)) | 586 if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc)) |
587 llvm::report_fatal_error(std::string(InstName) + ": " + | 587 llvm::report_fatal_error(std::string(InstName) + ": " + |
588 RegARM32::getRegName(Reg) + | 588 RegARM32::getRegName(RegNumT::fixme(Reg)) + |
John
2016/02/10 16:01:51
this does not look like a "fixme" issue -- reg is
Jim Stichnoth
2016/02/10 17:47:20
Done.
| |
589 "=pc not allowed when CC=1"); | 589 "=pc not allowed when CC=1"); |
590 } | 590 } |
591 | 591 |
592 } // end of anonymous namespace | 592 } // end of anonymous namespace |
593 | 593 |
594 namespace Ice { | 594 namespace Ice { |
595 namespace ARM32 { | 595 namespace ARM32 { |
596 | 596 |
597 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, | 597 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, |
598 const Assembler &Asm) const { | 598 const Assembler &Asm) const { |
599 if (!BuildDefs::dump()) | 599 if (!BuildDefs::dump()) |
600 return InstARM32::InstSize; | 600 return InstARM32::InstSize; |
601 Ostream &Str = Ctx->getStrEmit(); | 601 Ostream &Str = Ctx->getStrEmit(); |
602 IValueT Inst = Asm.load<IValueT>(position()); | 602 IValueT Inst = Asm.load<IValueT>(position()); |
603 Str << "\t" | 603 Str << "\t" |
604 "mov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t" | 604 "mov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t" |
605 << RegARM32::getRegName((Inst >> kRdShift) & 0xF) | 605 << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF)) |
606 << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper") | 606 << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper") |
607 << "16:" << symbol(Ctx, &Asm) << "\t@ .word " | 607 << "16:" << symbol(Ctx, &Asm) << "\t@ .word " |
608 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; | 608 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; |
609 return InstARM32::InstSize; | 609 return InstARM32::InstSize; |
610 } | 610 } |
611 | 611 |
612 // This fixup points to an ARM32 instruction with the following format: | 612 // This fixup points to an ARM32 instruction with the following format: |
613 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { | 613 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { |
614 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, | 614 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, |
615 // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt. | 615 // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt. |
(...skipping 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3051 constexpr const char *Vsqrts = "vsqrts"; | 3051 constexpr const char *Vsqrts = "vsqrts"; |
3052 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); | 3052 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); |
3053 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); | 3053 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); |
3054 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; | 3054 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; |
3055 constexpr IValueT S0 = 0; | 3055 constexpr IValueT S0 = 0; |
3056 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); | 3056 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); |
3057 } | 3057 } |
3058 | 3058 |
3059 } // end of namespace ARM32 | 3059 } // end of namespace ARM32 |
3060 } // end of namespace Ice | 3060 } // end of namespace Ice |
OLD | NEW |