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 const 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 const auto BaseRegNum = |
474 if (BaseRegNum == Variable::NoRegister) | 474 Var->hasReg() ? Var->getBaseRegNum() : TInfo.FrameOrStackReg; |
475 BaseRegNum = TInfo.FrameOrStackReg; | |
476 Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset, | 475 Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset, |
477 OperandARM32Mem::Offset); | 476 OperandARM32Mem::Offset); |
478 return EncodedAsImmRegOffset; | 477 return EncodedAsImmRegOffset; |
479 } | 478 } |
480 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { | 479 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { |
481 Variable *Var = Mem->getBase(); | 480 Variable *Var = Mem->getBase(); |
482 if (!Var->hasReg()) | 481 if (!Var->hasReg()) |
483 return CantEncode; | 482 return CantEncode; |
484 IValueT Rn = getEncodedGPRegNum(Var); | 483 IValueT Rn = getEncodedGPRegNum(Var); |
485 if (Mem->isRegReg()) { | 484 if (Mem->isRegReg()) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 llvm::report_fatal_error(std::string(InstName) + ": " + RegName + | 577 llvm::report_fatal_error(std::string(InstName) + ": " + RegName + |
579 "=pc not allowed"); | 578 "=pc not allowed"); |
580 } | 579 } |
581 | 580 |
582 void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags, | 581 void verifyRegNotPcWhenSetFlags(IValueT Reg, bool SetFlags, |
583 const char *InstName) { | 582 const char *InstName) { |
584 if (BuildDefs::minimal()) | 583 if (BuildDefs::minimal()) |
585 return; | 584 return; |
586 if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc)) | 585 if (SetFlags && (Reg == RegARM32::Encoded_Reg_pc)) |
587 llvm::report_fatal_error(std::string(InstName) + ": " + | 586 llvm::report_fatal_error(std::string(InstName) + ": " + |
588 RegARM32::getRegName(Reg) + | 587 RegARM32::getRegName(RegARM32::Reg_pc) + |
589 "=pc not allowed when CC=1"); | 588 "=pc not allowed when CC=1"); |
590 } | 589 } |
591 | 590 |
592 } // end of anonymous namespace | 591 } // end of anonymous namespace |
593 | 592 |
594 namespace Ice { | 593 namespace Ice { |
595 namespace ARM32 { | 594 namespace ARM32 { |
596 | 595 |
597 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, | 596 size_t MoveRelocatableFixup::emit(GlobalContext *Ctx, |
598 const Assembler &Asm) const { | 597 const Assembler &Asm) const { |
599 if (!BuildDefs::dump()) | 598 if (!BuildDefs::dump()) |
600 return InstARM32::InstSize; | 599 return InstARM32::InstSize; |
601 Ostream &Str = Ctx->getStrEmit(); | 600 Ostream &Str = Ctx->getStrEmit(); |
602 IValueT Inst = Asm.load<IValueT>(position()); | 601 IValueT Inst = Asm.load<IValueT>(position()); |
603 Str << "\t" | 602 Str << "\t" |
604 "mov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t" | 603 "mov" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "w" : "t") << "\t" |
605 << RegARM32::getRegName((Inst >> kRdShift) & 0xF) | 604 << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF)) |
606 << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper") | 605 << ", #:" << (kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ? "lower" : "upper") |
607 << "16:" << symbol(Ctx, &Asm) << "\t@ .word " | 606 << "16:" << symbol(Ctx, &Asm) << "\t@ .word " |
608 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; | 607 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; |
609 return InstARM32::InstSize; | 608 return InstARM32::InstSize; |
610 } | 609 } |
611 | 610 |
612 // This fixup points to an ARM32 instruction with the following format: | 611 // This fixup points to an ARM32 instruction with the following format: |
613 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { | 612 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { |
614 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, | 613 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, |
615 // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt. | 614 // 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"; | 3050 constexpr const char *Vsqrts = "vsqrts"; |
3052 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); | 3051 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); |
3053 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); | 3052 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); |
3054 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; | 3053 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; |
3055 constexpr IValueT S0 = 0; | 3054 constexpr IValueT S0 = 0; |
3056 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); | 3055 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); |
3057 } | 3056 } |
3058 | 3057 |
3059 } // end of namespace ARM32 | 3058 } // end of namespace ARM32 |
3060 } // end of namespace Ice | 3059 } // end of namespace Ice |
OLD | NEW |