| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 1 | //===-- ARMSubtarget.cpp - ARM Subtarget Information ------------*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file implements the ARM specific subclass of TargetSubtarget. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "ARMSubtarget.h" | 
|  | 15 | #include "ARMGenSubtarget.inc" | 
| Evan Cheng | 43b9ca6 | 2009-08-28 23:18:09 +0000 | [diff] [blame] | 16 | #include "llvm/GlobalValue.h" | 
| Anton Korobeynikov | 77d1943 | 2009-06-08 22:53:56 +0000 | [diff] [blame] | 17 | #include "llvm/Target/TargetOptions.h" | 
| Bob Wilson | 4582530 | 2009-06-22 21:01:46 +0000 | [diff] [blame] | 18 | #include "llvm/Support/CommandLine.h" | 
| David Goodwin | 0d412c2 | 2009-11-10 00:48:55 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/SmallVector.h" | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 20 | using namespace llvm; | 
|  | 21 |  | 
| Bob Wilson | 4582530 | 2009-06-22 21:01:46 +0000 | [diff] [blame] | 22 | static cl::opt<bool> | 
|  | 23 | ReserveR9("arm-reserve-r9", cl::Hidden, | 
|  | 24 | cl::desc("Reserve R9, making it unavailable as GPR")); | 
|  | 25 |  | 
| Anton Korobeynikov | 2522908 | 2009-11-24 00:44:37 +0000 | [diff] [blame] | 26 | static cl::opt<bool> | 
|  | 27 | UseMOVT("arm-use-movt", | 
|  | 28 | cl::init(true), cl::Hidden); | 
|  | 29 |  | 
| Daniel Dunbar | 31b44e8 | 2009-08-02 22:11:08 +0000 | [diff] [blame] | 30 | ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, | 
| Evan Cheng | 03da4db | 2009-10-16 06:11:08 +0000 | [diff] [blame] | 31 | bool isT) | 
| Anton Korobeynikov | bf16a17 | 2010-03-06 19:39:36 +0000 | [diff] [blame] | 32 | : ARMArchVersion(V4) | 
| Anton Korobeynikov | 0b91cc4 | 2009-05-23 19:51:43 +0000 | [diff] [blame] | 33 | , ARMFPUType(None) | 
| Jim Grosbach | 71fcb4f | 2010-03-25 23:47:34 +0000 | [diff] [blame] | 34 | , UseNEONForSinglePrecisionFP(false) | 
| Jim Grosbach | a43386b | 2010-03-25 23:11:16 +0000 | [diff] [blame] | 35 | , SlowVMLx(false) | 
| Evan Cheng | 03da4db | 2009-10-16 06:11:08 +0000 | [diff] [blame] | 36 | , IsThumb(isT) | 
| Anton Korobeynikov | 12694bd | 2009-06-01 20:00:48 +0000 | [diff] [blame] | 37 | , ThumbMode(Thumb1) | 
| David Goodwin | 17199b5 | 2009-09-30 00:10:16 +0000 | [diff] [blame] | 38 | , PostRAScheduler(false) | 
| Bob Wilson | 4582530 | 2009-06-22 21:01:46 +0000 | [diff] [blame] | 39 | , IsR9Reserved(ReserveR9) | 
| Anton Korobeynikov | 2522908 | 2009-11-24 00:44:37 +0000 | [diff] [blame] | 40 | , UseMovt(UseMOVT) | 
| Anton Korobeynikov | 0a65a37 | 2010-03-14 18:42:38 +0000 | [diff] [blame] | 41 | , HasFP16(false) | 
| Jim Grosbach | 151cd8f | 2010-05-05 23:44:43 +0000 | [diff] [blame] | 42 | , HasHardwareDivide(false) | 
|  | 43 | , HasT2ExtractPack(false) | 
| Lauro Ramos Venancio | 048e16ff | 2007-02-13 19:52:28 +0000 | [diff] [blame] | 44 | , stackAlignment(4) | 
| Anton Korobeynikov | 08bf4c0 | 2009-05-23 19:50:50 +0000 | [diff] [blame] | 45 | , CPUString("generic") | 
| Lauro Ramos Venancio | 048e16ff | 2007-02-13 19:52:28 +0000 | [diff] [blame] | 46 | , TargetType(isELF) // Default to ELF unless otherwise specified. | 
|  | 47 | , TargetABI(ARM_ABI_APCS) { | 
| Anton Korobeynikov | 77d1943 | 2009-06-08 22:53:56 +0000 | [diff] [blame] | 48 | // default to soft float ABI | 
|  | 49 | if (FloatABIType == FloatABI::Default) | 
|  | 50 | FloatABIType = FloatABI::Soft; | 
|  | 51 |  | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 52 | // Determine default and user specified characteristics | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 53 |  | 
|  | 54 | // Parse features string. | 
| Anton Korobeynikov | 08bf4c0 | 2009-05-23 19:50:50 +0000 | [diff] [blame] | 55 | CPUString = ParseSubtargetFeatures(FS, CPUString); | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 56 |  | 
| Anton Korobeynikov | bf16a17 | 2010-03-06 19:39:36 +0000 | [diff] [blame] | 57 | // When no arch is specified either by CPU or by attributes, make the default | 
|  | 58 | // ARMv4T. | 
|  | 59 | if (CPUString == "generic" && (FS.empty() || FS == "generic")) | 
|  | 60 | ARMArchVersion = V4T; | 
|  | 61 |  | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 62 | // Set the boolean corresponding to the current target triple, or the default | 
|  | 63 | // if one cannot be determined, to true. | 
| Evan Cheng | ec415ef | 2009-03-08 04:02:49 +0000 | [diff] [blame] | 64 | unsigned Len = TT.length(); | 
| Evan Cheng | 0ee0da8 | 2009-03-09 20:25:39 +0000 | [diff] [blame] | 65 | unsigned Idx = 0; | 
| Anton Korobeynikov | b6f4538 | 2009-05-29 23:41:08 +0000 | [diff] [blame] | 66 |  | 
| Evan Cheng | 0ee0da8 | 2009-03-09 20:25:39 +0000 | [diff] [blame] | 67 | if (Len >= 5 && TT.substr(0, 4) == "armv") | 
|  | 68 | Idx = 4; | 
| Bob Wilson | 4824956 | 2009-06-22 21:28:22 +0000 | [diff] [blame] | 69 | else if (Len >= 6 && TT.substr(0, 5) == "thumb") { | 
| Anton Korobeynikov | 12694bd | 2009-06-01 20:00:48 +0000 | [diff] [blame] | 70 | IsThumb = true; | 
| Evan Cheng | 0ee0da8 | 2009-03-09 20:25:39 +0000 | [diff] [blame] | 71 | if (Len >= 7 && TT[5] == 'v') | 
|  | 72 | Idx = 6; | 
|  | 73 | } | 
|  | 74 | if (Idx) { | 
|  | 75 | unsigned SubVer = TT[Idx]; | 
| Anton Korobeynikov | bf16a17 | 2010-03-06 19:39:36 +0000 | [diff] [blame] | 76 | if (SubVer >= '7' && SubVer <= '9') { | 
|  | 77 | ARMArchVersion = V7A; | 
| Jim Grosbach | 92d99900 | 2010-05-05 20:44:35 +0000 | [diff] [blame] | 78 | if (Len >= Idx+2 && TT[Idx+1] == 'm') | 
|  | 79 | ARMArchVersion = V7M; | 
| Anton Korobeynikov | bf16a17 | 2010-03-06 19:39:36 +0000 | [diff] [blame] | 80 | } else if (SubVer == '6') { | 
|  | 81 | ARMArchVersion = V6; | 
|  | 82 | if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') | 
|  | 83 | ARMArchVersion = V6T2; | 
|  | 84 | } else if (SubVer == '5') { | 
|  | 85 | ARMArchVersion = V5T; | 
|  | 86 | if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') | 
|  | 87 | ARMArchVersion = V5TE; | 
|  | 88 | } else if (SubVer == '4') { | 
|  | 89 | if (Len >= Idx+2 && TT[Idx+1] == 't') | 
|  | 90 | ARMArchVersion = V4T; | 
|  | 91 | else | 
|  | 92 | ARMArchVersion = V4; | 
| Evan Cheng | ec415ef | 2009-03-08 04:02:49 +0000 | [diff] [blame] | 93 | } | 
|  | 94 | } | 
|  | 95 |  | 
| Evan Cheng | 6ab54fd | 2009-08-01 00:16:10 +0000 | [diff] [blame] | 96 | // Thumb2 implies at least V6T2. | 
| Anton Korobeynikov | bf16a17 | 2010-03-06 19:39:36 +0000 | [diff] [blame] | 97 | if (ARMArchVersion >= V6T2) | 
|  | 98 | ThumbMode = Thumb2; | 
|  | 99 | else if (ThumbMode >= Thumb2) | 
| Evan Cheng | 6ab54fd | 2009-08-01 00:16:10 +0000 | [diff] [blame] | 100 | ARMArchVersion = V6T2; | 
|  | 101 |  | 
| Evan Cheng | 0ee0da8 | 2009-03-09 20:25:39 +0000 | [diff] [blame] | 102 | if (Len >= 10) { | 
| Evan Cheng | 181fe36 | 2007-01-19 19:22:40 +0000 | [diff] [blame] | 103 | if (TT.find("-darwin") != std::string::npos) | 
| Evan Cheng | 0ee0da8 | 2009-03-09 20:25:39 +0000 | [diff] [blame] | 104 | // arm-darwin | 
| Evan Cheng | 181fe36 | 2007-01-19 19:22:40 +0000 | [diff] [blame] | 105 | TargetType = isDarwin; | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 106 | } | 
|  | 107 |  | 
| Lauro Ramos Venancio | 048e16ff | 2007-02-13 19:52:28 +0000 | [diff] [blame] | 108 | if (TT.find("eabi") != std::string::npos) | 
|  | 109 | TargetABI = ARM_ABI_AAPCS; | 
|  | 110 |  | 
|  | 111 | if (isAAPCS_ABI()) | 
|  | 112 | stackAlignment = 8; | 
|  | 113 |  | 
| Evan Cheng | a0ca298 | 2009-06-18 23:14:30 +0000 | [diff] [blame] | 114 | if (isTargetDarwin()) | 
| Bob Wilson | 4582530 | 2009-06-22 21:01:46 +0000 | [diff] [blame] | 115 | IsR9Reserved = ReserveR9 | (ARMArchVersion < V6); | 
| David Goodwin | 9a051a5 | 2009-10-01 21:46:35 +0000 | [diff] [blame] | 116 |  | 
| Evan Cheng | 03da4db | 2009-10-16 06:11:08 +0000 | [diff] [blame] | 117 | if (!isThumb() || hasThumb2()) | 
|  | 118 | PostRAScheduler = true; | 
| Evan Cheng | 10043e2 | 2007-01-19 07:51:42 +0000 | [diff] [blame] | 119 | } | 
| Evan Cheng | 43b9ca6 | 2009-08-28 23:18:09 +0000 | [diff] [blame] | 120 |  | 
|  | 121 | /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. | 
| Evan Cheng | 1b38952 | 2009-09-03 07:04:02 +0000 | [diff] [blame] | 122 | bool | 
| Dan Gohman | bcaf681 | 2010-04-15 01:51:59 +0000 | [diff] [blame] | 123 | ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV, | 
|  | 124 | Reloc::Model RelocM) const { | 
| Evan Cheng | 1b38952 | 2009-09-03 07:04:02 +0000 | [diff] [blame] | 125 | if (RelocM == Reloc::Static) | 
| Evan Cheng | 43b9ca6 | 2009-08-28 23:18:09 +0000 | [diff] [blame] | 126 | return false; | 
| Evan Cheng | 1b38952 | 2009-09-03 07:04:02 +0000 | [diff] [blame] | 127 |  | 
| Jeffrey Yasskin | 091217b | 2010-01-27 20:34:15 +0000 | [diff] [blame] | 128 | // Materializable GVs (in JIT lazy compilation mode) do not require an extra | 
|  | 129 | // load from stub. | 
|  | 130 | bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); | 
| Evan Cheng | 1b38952 | 2009-09-03 07:04:02 +0000 | [diff] [blame] | 131 |  | 
|  | 132 | if (!isTargetDarwin()) { | 
|  | 133 | // Extra load is needed for all externally visible. | 
|  | 134 | if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) | 
|  | 135 | return false; | 
|  | 136 | return true; | 
|  | 137 | } else { | 
|  | 138 | if (RelocM == Reloc::PIC_) { | 
|  | 139 | // If this is a strong reference to a definition, it is definitely not | 
|  | 140 | // through a stub. | 
|  | 141 | if (!isDecl && !GV->isWeakForLinker()) | 
|  | 142 | return false; | 
|  | 143 |  | 
|  | 144 | // Unless we have a symbol with hidden visibility, we have to go through a | 
|  | 145 | // normal $non_lazy_ptr stub because this symbol might be resolved late. | 
|  | 146 | if (!GV->hasHiddenVisibility())  // Non-hidden $non_lazy_ptr reference. | 
|  | 147 | return true; | 
|  | 148 |  | 
|  | 149 | // If symbol visibility is hidden, we have a stub for common symbol | 
|  | 150 | // references and external declarations. | 
|  | 151 | if (isDecl || GV->hasCommonLinkage()) | 
|  | 152 | // Hidden $non_lazy_ptr reference. | 
|  | 153 | return true; | 
|  | 154 |  | 
|  | 155 | return false; | 
|  | 156 | } else { | 
|  | 157 | // If this is a strong reference to a definition, it is definitely not | 
|  | 158 | // through a stub. | 
|  | 159 | if (!isDecl && !GV->isWeakForLinker()) | 
|  | 160 | return false; | 
|  | 161 |  | 
|  | 162 | // Unless we have a symbol with hidden visibility, we have to go through a | 
|  | 163 | // normal $non_lazy_ptr stub because this symbol might be resolved late. | 
|  | 164 | if (!GV->hasHiddenVisibility())  // Non-hidden $non_lazy_ptr reference. | 
|  | 165 | return true; | 
|  | 166 | } | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | return false; | 
| Evan Cheng | 43b9ca6 | 2009-08-28 23:18:09 +0000 | [diff] [blame] | 170 | } | 
| David Goodwin | 0d412c2 | 2009-11-10 00:48:55 +0000 | [diff] [blame] | 171 |  | 
|  | 172 | bool ARMSubtarget::enablePostRAScheduler( | 
|  | 173 | CodeGenOpt::Level OptLevel, | 
|  | 174 | TargetSubtarget::AntiDepBreakMode& Mode, | 
| David Goodwin | b9fe5d5 | 2009-11-13 19:52:48 +0000 | [diff] [blame] | 175 | RegClassVector& CriticalPathRCs) const { | 
| David Goodwin | 0d412c2 | 2009-11-10 00:48:55 +0000 | [diff] [blame] | 176 | Mode = TargetSubtarget::ANTIDEP_CRITICAL; | 
| David Goodwin | b9fe5d5 | 2009-11-13 19:52:48 +0000 | [diff] [blame] | 177 | CriticalPathRCs.clear(); | 
|  | 178 | CriticalPathRCs.push_back(&ARM::GPRRegClass); | 
| David Goodwin | 0d412c2 | 2009-11-10 00:48:55 +0000 | [diff] [blame] | 179 | return PostRAScheduler && OptLevel >= CodeGenOpt::Default; | 
|  | 180 | } |