OLD | NEW |
(Empty) | |
| 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===// |
| 2 // |
| 3 // The Subzero Code Generator |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // This file implements the InstARM32 and OperandARM32 classes, |
| 11 // primarily the constructors and the dump()/emit() methods. |
| 12 // |
| 13 //===----------------------------------------------------------------------===// |
| 14 |
| 15 #include "assembler_arm32.h" |
| 16 #include "IceCfg.h" |
| 17 #include "IceCfgNode.h" |
| 18 #include "IceInst.h" |
| 19 #include "IceInstARM32.h" |
| 20 #include "IceOperand.h" |
| 21 #include "IceRegistersARM32.h" |
| 22 #include "IceTargetLoweringARM32.h" |
| 23 |
| 24 namespace Ice { |
| 25 |
| 26 namespace { |
| 27 |
| 28 const struct TypeARM32Attributes_ { |
| 29 const char *WidthString; // b, h, <blank>, or d |
| 30 int8_t SExtAddrOffsetBits; |
| 31 int8_t ZExtAddrOffsetBits; |
| 32 } TypeARM32Attributes[] = { |
| 33 #define X(tag, elementty, width, sbits, ubits) \ |
| 34 { width, sbits, ubits } \ |
| 35 , |
| 36 ICETYPEARM32_TABLE |
| 37 #undef X |
| 38 }; |
| 39 |
| 40 } // end of anonymous namespace |
| 41 |
| 42 const char *InstARM32::getWidthString(Type Ty) { |
| 43 return TypeARM32Attributes[Ty].WidthString; |
| 44 } |
| 45 |
| 46 bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) { |
| 47 int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits |
| 48 : TypeARM32Attributes[Ty].ZExtAddrOffsetBits; |
| 49 if (Bits == 0) |
| 50 return Offset == 0; |
| 51 // Note that encodings for offsets are sign-magnitude for ARM, so we check |
| 52 // with IsAbsoluteUint(). |
| 53 if (isScalarFloatingType(Ty)) |
| 54 return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset); |
| 55 return Utils::IsAbsoluteUint(Bits, Offset); |
| 56 } |
| 57 |
| 58 InstARM32Ret::InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source) |
| 59 : InstARM32(Func, InstARM32::Ret, Source ? 2 : 1, nullptr) { |
| 60 addSource(LR); |
| 61 if (Source) |
| 62 addSource(Source); |
| 63 } |
| 64 |
| 65 // ======================== Dump routines ======================== // |
| 66 |
| 67 void InstARM32::dump(const Cfg *Func) const { |
| 68 if (!ALLOW_DUMP) |
| 69 return; |
| 70 Ostream &Str = Func->getContext()->getStrDump(); |
| 71 Str << "[ARM32] "; |
| 72 Inst::dump(Func); |
| 73 } |
| 74 |
| 75 void InstARM32Ret::emit(const Cfg *Func) const { |
| 76 if (!ALLOW_DUMP) |
| 77 return; |
| 78 assert(getSrcSize() > 0); |
| 79 Variable *LR = llvm::cast<Variable>(getSrc(0)); |
| 80 assert(LR->hasReg()); |
| 81 assert(LR->getRegNum() == RegARM32::Reg_lr); |
| 82 Ostream &Str = Func->getContext()->getStrEmit(); |
| 83 Str << "\tbx\t"; |
| 84 LR->emit(Func); |
| 85 } |
| 86 |
| 87 void InstARM32Ret::emitIAS(const Cfg *Func) const { |
| 88 (void)Func; |
| 89 llvm_unreachable("Not yet implemented"); |
| 90 } |
| 91 |
| 92 void InstARM32Ret::dump(const Cfg *Func) const { |
| 93 if (!ALLOW_DUMP) |
| 94 return; |
| 95 Ostream &Str = Func->getContext()->getStrDump(); |
| 96 Type Ty = (getSrcSize() == 1 ? IceType_void : getSrc(0)->getType()); |
| 97 Str << "ret." << Ty << " "; |
| 98 dumpSources(Func); |
| 99 } |
| 100 |
| 101 } // end of namespace Ice |
OLD | NEW |