blob: 91e5ae8f1a57762c45e677f5767a35454fbc1524 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ArchSpec.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/ArchSpec.h"
11
Eli Friedman50fac2f2010-06-11 04:26:08 +000012#include <stdio.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013
14#include <string>
15
Greg Clayton41f92322010-06-11 03:25:34 +000016#include "llvm/Support/ELF.h"
Stephen Wilsonfacebfc2011-02-24 19:13:58 +000017#include "llvm/Support/Host.h"
Greg Clayton41f92322010-06-11 03:25:34 +000018#include "llvm/Support/MachO.h"
Greg Clayton514487e2011-02-15 21:59:32 +000019#include "lldb/Host/Endian.h"
20#include "lldb/Host/Host.h"
Greg Claytoneb0103f2011-04-07 22:46:35 +000021#include "lldb/Target/Platform.h"
Greg Clayton41f92322010-06-11 03:25:34 +000022
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023using namespace lldb;
24using namespace lldb_private;
25
Greg Clayton64195a22011-02-23 00:35:02 +000026#define ARCH_SPEC_SEPARATOR_CHAR '-'
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027
Greg Clayton64195a22011-02-23 00:35:02 +000028namespace lldb_private {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
Greg Clayton64195a22011-02-23 00:35:02 +000030 struct CoreDefinition
31 {
32 ByteOrder default_byte_order;
33 uint32_t addr_byte_size;
Greg Clayton357132e2011-03-26 19:14:58 +000034 uint32_t min_opcode_byte_size;
35 uint32_t max_opcode_byte_size;
Greg Clayton64195a22011-02-23 00:35:02 +000036 llvm::Triple::ArchType machine;
37 ArchSpec::Core core;
38 const char *name;
39 };
40
41}
42
43// This core information can be looked using the ArchSpec::Core as the index
44static const CoreDefinition g_core_definitions[ArchSpec::kNumCores] =
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045{
Greg Clayton357132e2011-03-26 19:14:58 +000046 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" },
47 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" },
48 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" },
49 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" },
Greg Claytonb5c39fe2011-12-16 18:15:52 +000050 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5e , "armv5e" },
Greg Clayton357132e2011-03-26 19:14:58 +000051 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" },
52 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" },
53 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" },
54 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" },
55 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" },
56 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" },
57 { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" },
Greg Claytonb5c39fe2011-12-16 18:15:52 +000058 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumb , "thumb" },
59 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv4t , "thumbv4t" },
60 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv5 , "thumbv5" },
61 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv5e , "thumbv5e" },
62 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv6 , "thumbv6" },
63 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7 , "thumbv7" },
64 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7f , "thumbv7f" },
65 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7k , "thumbv7k" },
66 { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7s , "thumbv7s" },
67
Greg Clayton64195a22011-02-23 00:35:02 +000068
Greg Clayton357132e2011-03-26 19:14:58 +000069 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "ppc" },
70 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
71 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
72 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
73 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" },
74 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" },
75 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" },
76 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" },
77 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" },
78 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" },
79 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" },
80 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
81 { eByteOrderLittle, 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
Greg Clayton64195a22011-02-23 00:35:02 +000082
Greg Clayton357132e2011-03-26 19:14:58 +000083 { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "ppc64" },
84 { eByteOrderLittle, 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
Greg Clayton64195a22011-02-23 00:35:02 +000085
Greg Clayton357132e2011-03-26 19:14:58 +000086 { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
87 { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
Greg Clayton64195a22011-02-23 00:35:02 +000088
Greg Claytonab65b342011-04-13 22:47:15 +000089 { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" },
90 { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" },
91 { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" },
Greg Clayton64195a22011-02-23 00:35:02 +000092
Greg Claytonab65b342011-04-13 22:47:15 +000093 { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" }
Greg Clayton64195a22011-02-23 00:35:02 +000094};
95
96struct ArchDefinitionEntry
97{
98 ArchSpec::Core core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 uint32_t cpu;
100 uint32_t sub;
Greg Clayton64195a22011-02-23 00:35:02 +0000101};
102
103struct ArchDefinition
104{
105 ArchitectureType type;
106 size_t num_entries;
107 const ArchDefinitionEntry *entries;
108 uint32_t cpu_mask;
109 uint32_t sub_mask;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 const char *name;
111};
112
Greg Clayton41f92322010-06-11 03:25:34 +0000113
Greg Claytonab65b342011-04-13 22:47:15 +0000114uint32_t
115ArchSpec::AutoComplete (const char *name, StringList &matches)
116{
117 uint32_t i;
118 if (name && name[0])
119 {
120 for (i = 0; i < ArchSpec::kNumCores; ++i)
121 {
122 if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
123 matches.AppendString (g_core_definitions[i].name);
124 }
125 }
126 else
127 {
128 for (i = 0; i < ArchSpec::kNumCores; ++i)
129 matches.AppendString (g_core_definitions[i].name);
130 }
131 return matches.GetSize();
132}
133
134
135
Greg Clayton64195a22011-02-23 00:35:02 +0000136#define CPU_ANY (UINT32_MAX)
137
138//===----------------------------------------------------------------------===//
139// A table that gets searched linearly for matches. This table is used to
140// convert cpu type and subtypes to architecture names, and to convert
141// architecture names to cpu types and subtypes. The ordering is important and
142// allows the precedence to be set when the table is built.
143static const ArchDefinitionEntry g_macho_arch_entries[] =
Greg Clayton41f92322010-06-11 03:25:34 +0000144{
Greg Clayton64195a22011-02-23 00:35:02 +0000145 { ArchSpec::eCore_arm_generic , llvm::MachO::CPUTypeARM , CPU_ANY },
146 { ArchSpec::eCore_arm_generic , llvm::MachO::CPUTypeARM , 0 },
147 { ArchSpec::eCore_arm_armv4 , llvm::MachO::CPUTypeARM , 5 },
Greg Claytonb5c39fe2011-12-16 18:15:52 +0000148 { ArchSpec::eCore_arm_armv4t , llvm::MachO::CPUTypeARM , 5 },
Greg Clayton64195a22011-02-23 00:35:02 +0000149 { ArchSpec::eCore_arm_armv6 , llvm::MachO::CPUTypeARM , 6 },
150 { ArchSpec::eCore_arm_armv5 , llvm::MachO::CPUTypeARM , 7 },
Greg Claytonb5c39fe2011-12-16 18:15:52 +0000151 { ArchSpec::eCore_arm_armv5e , llvm::MachO::CPUTypeARM , 7 },
152 { ArchSpec::eCore_arm_armv5t , llvm::MachO::CPUTypeARM , 7 },
Greg Clayton64195a22011-02-23 00:35:02 +0000153 { ArchSpec::eCore_arm_xscale , llvm::MachO::CPUTypeARM , 8 },
154 { ArchSpec::eCore_arm_armv7 , llvm::MachO::CPUTypeARM , 9 },
Greg Claytonded470d2011-03-19 01:12:21 +0000155 { ArchSpec::eCore_arm_armv7f , llvm::MachO::CPUTypeARM , 10 },
156 { ArchSpec::eCore_arm_armv7k , llvm::MachO::CPUTypeARM , 12 },
157 { ArchSpec::eCore_arm_armv7s , llvm::MachO::CPUTypeARM , 11 },
Greg Claytonb5c39fe2011-12-16 18:15:52 +0000158 { ArchSpec::eCore_thumb , llvm::MachO::CPUTypeARM , 0 },
159 { ArchSpec::eCore_thumbv4t , llvm::MachO::CPUTypeARM , 5 },
160 { ArchSpec::eCore_thumbv5 , llvm::MachO::CPUTypeARM , 7 },
161 { ArchSpec::eCore_thumbv5e , llvm::MachO::CPUTypeARM , 7 },
162 { ArchSpec::eCore_thumbv6 , llvm::MachO::CPUTypeARM , 6 },
163 { ArchSpec::eCore_thumbv7 , llvm::MachO::CPUTypeARM , 9 },
164 { ArchSpec::eCore_thumbv7f , llvm::MachO::CPUTypeARM , 10 },
165 { ArchSpec::eCore_thumbv7k , llvm::MachO::CPUTypeARM , 12 },
166 { ArchSpec::eCore_thumbv7s , llvm::MachO::CPUTypeARM , 11 },
Greg Clayton64195a22011-02-23 00:35:02 +0000167 { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , CPU_ANY },
168 { ArchSpec::eCore_ppc_generic , llvm::MachO::CPUTypePowerPC , 0 },
169 { ArchSpec::eCore_ppc_ppc601 , llvm::MachO::CPUTypePowerPC , 1 },
170 { ArchSpec::eCore_ppc_ppc602 , llvm::MachO::CPUTypePowerPC , 2 },
171 { ArchSpec::eCore_ppc_ppc603 , llvm::MachO::CPUTypePowerPC , 3 },
172 { ArchSpec::eCore_ppc_ppc603e , llvm::MachO::CPUTypePowerPC , 4 },
173 { ArchSpec::eCore_ppc_ppc603ev , llvm::MachO::CPUTypePowerPC , 5 },
174 { ArchSpec::eCore_ppc_ppc604 , llvm::MachO::CPUTypePowerPC , 6 },
175 { ArchSpec::eCore_ppc_ppc604e , llvm::MachO::CPUTypePowerPC , 7 },
176 { ArchSpec::eCore_ppc_ppc620 , llvm::MachO::CPUTypePowerPC , 8 },
177 { ArchSpec::eCore_ppc_ppc750 , llvm::MachO::CPUTypePowerPC , 9 },
178 { ArchSpec::eCore_ppc_ppc7400 , llvm::MachO::CPUTypePowerPC , 10 },
179 { ArchSpec::eCore_ppc_ppc7450 , llvm::MachO::CPUTypePowerPC , 11 },
180 { ArchSpec::eCore_ppc_ppc970 , llvm::MachO::CPUTypePowerPC , 100 },
181 { ArchSpec::eCore_ppc64_generic , llvm::MachO::CPUTypePowerPC64 , 0 },
182 { ArchSpec::eCore_ppc64_ppc970_64 , llvm::MachO::CPUTypePowerPC64 , 100 },
183 { ArchSpec::eCore_x86_32_i386 , llvm::MachO::CPUTypeI386 , 3 },
184 { ArchSpec::eCore_x86_32_i486 , llvm::MachO::CPUTypeI386 , 4 },
185 { ArchSpec::eCore_x86_32_i486sx , llvm::MachO::CPUTypeI386 , 0x84 },
186 { ArchSpec::eCore_x86_32_i386 , llvm::MachO::CPUTypeI386 , CPU_ANY },
187 { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPUTypeX86_64 , 3 },
Jason Molenda311186a2011-08-16 01:23:22 +0000188 { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPUTypeX86_64 , 4 },
Greg Clayton64195a22011-02-23 00:35:02 +0000189 { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPUTypeX86_64 , CPU_ANY }
190};
191static const ArchDefinition g_macho_arch_def = {
192 eArchTypeMachO,
193 sizeof(g_macho_arch_entries)/sizeof(g_macho_arch_entries[0]),
194 g_macho_arch_entries,
195 UINT32_MAX, // CPU type mask
196 0x00FFFFFFu, // CPU subtype mask
197 "mach-o"
Greg Clayton41f92322010-06-11 03:25:34 +0000198};
199
Greg Clayton64195a22011-02-23 00:35:02 +0000200//===----------------------------------------------------------------------===//
201// A table that gets searched linearly for matches. This table is used to
202// convert cpu type and subtypes to architecture names, and to convert
203// architecture names to cpu types and subtypes. The ordering is important and
204// allows the precedence to be set when the table is built.
205static const ArchDefinitionEntry g_elf_arch_entries[] =
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206{
Greg Clayton64195a22011-02-23 00:35:02 +0000207 { ArchSpec::eCore_sparc_generic , llvm::ELF::EM_SPARC , LLDB_INVALID_CPUTYPE }, // Sparc
208 { ArchSpec::eCore_x86_32_i386 , llvm::ELF::EM_386 , LLDB_INVALID_CPUTYPE }, // Intel 80386
209 { ArchSpec::eCore_x86_32_i486 , llvm::ELF::EM_486 , LLDB_INVALID_CPUTYPE }, // Intel 486 (deprecated)
210 { ArchSpec::eCore_ppc_generic , llvm::ELF::EM_PPC , LLDB_INVALID_CPUTYPE }, // PowerPC
211 { ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE }, // PowerPC64
212 { ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE }, // ARM
Greg Clayton64195a22011-02-23 00:35:02 +0000213 { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE }, // SPARC V9
214 { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE }, // AMD64
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215};
216
Greg Clayton64195a22011-02-23 00:35:02 +0000217static const ArchDefinition g_elf_arch_def = {
218 eArchTypeELF,
219 sizeof(g_elf_arch_entries)/sizeof(g_elf_arch_entries[0]),
220 g_elf_arch_entries,
221 UINT32_MAX, // CPU type mask
222 UINT32_MAX, // CPU subtype mask
223 "elf",
Greg Clayton41f92322010-06-11 03:25:34 +0000224};
225
Greg Clayton64195a22011-02-23 00:35:02 +0000226//===----------------------------------------------------------------------===//
227// Table of all ArchDefinitions
228static const ArchDefinition *g_arch_definitions[] = {
229 &g_macho_arch_def,
230 &g_elf_arch_def,
231};
Greg Clayton41f92322010-06-11 03:25:34 +0000232
Greg Clayton64195a22011-02-23 00:35:02 +0000233static const size_t k_num_arch_definitions =
234 sizeof(g_arch_definitions) / sizeof(g_arch_definitions[0]);
235
236//===----------------------------------------------------------------------===//
237// Static helper functions.
238
239
240// Get the architecture definition for a given object type.
241static const ArchDefinition *
242FindArchDefinition (ArchitectureType arch_type)
243{
244 for (unsigned int i = 0; i < k_num_arch_definitions; ++i)
245 {
246 const ArchDefinition *def = g_arch_definitions[i];
247 if (def->type == arch_type)
248 return def;
249 }
250 return NULL;
251}
252
253// Get an architecture definition by name.
254static const CoreDefinition *
255FindCoreDefinition (llvm::StringRef name)
256{
257 for (unsigned int i = 0; i < ArchSpec::kNumCores; ++i)
258 {
259 if (name.equals_lower(g_core_definitions[i].name))
260 return &g_core_definitions[i];
261 }
262 return NULL;
263}
264
265static inline const CoreDefinition *
266FindCoreDefinition (ArchSpec::Core core)
267{
268 if (core >= 0 && core < ArchSpec::kNumCores)
269 return &g_core_definitions[core];
270 return NULL;
271}
272
273// Get a definition entry by cpu type and subtype.
274static const ArchDefinitionEntry *
275FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub)
276{
277 if (def == NULL)
278 return NULL;
279
280 const uint32_t cpu_mask = def->cpu_mask;
281 const uint32_t sub_mask = def->sub_mask;
282 const ArchDefinitionEntry *entries = def->entries;
283 for (size_t i = 0; i < def->num_entries; ++i)
284 {
285 if ((entries[i].cpu == (cpu_mask & cpu)) &&
286 (entries[i].sub == (sub_mask & sub)))
287 return &entries[i];
288 }
289 return NULL;
290}
291
292static const ArchDefinitionEntry *
293FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core)
294{
295 if (def == NULL)
296 return NULL;
297
298 const ArchDefinitionEntry *entries = def->entries;
299 for (size_t i = 0; i < def->num_entries; ++i)
300 {
301 if (entries[i].core == core)
302 return &entries[i];
303 }
304 return NULL;
305}
306
307//===----------------------------------------------------------------------===//
308// Constructors and destructors.
309
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310ArchSpec::ArchSpec() :
Greg Clayton514487e2011-02-15 21:59:32 +0000311 m_triple (),
Greg Clayton64195a22011-02-23 00:35:02 +0000312 m_core (kCore_invalid),
313 m_byte_order (eByteOrderInvalid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314{
315}
316
Greg Claytoneb0103f2011-04-07 22:46:35 +0000317ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) :
Greg Clayton514487e2011-02-15 21:59:32 +0000318 m_triple (),
Greg Clayton64195a22011-02-23 00:35:02 +0000319 m_core (kCore_invalid),
320 m_byte_order (eByteOrderInvalid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321{
Greg Clayton64195a22011-02-23 00:35:02 +0000322 if (triple_cstr)
Greg Claytoneb0103f2011-04-07 22:46:35 +0000323 SetTriple(triple_cstr, platform);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324}
325
Greg Clayton64195a22011-02-23 00:35:02 +0000326ArchSpec::ArchSpec(const llvm::Triple &triple) :
Greg Clayton514487e2011-02-15 21:59:32 +0000327 m_triple (),
Greg Clayton64195a22011-02-23 00:35:02 +0000328 m_core (kCore_invalid),
329 m_byte_order (eByteOrderInvalid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330{
Greg Clayton64195a22011-02-23 00:35:02 +0000331 SetTriple(triple);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332}
333
Greg Claytone0d378b2011-03-24 21:19:54 +0000334ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) :
Greg Clayton64195a22011-02-23 00:35:02 +0000335 m_triple (),
336 m_core (kCore_invalid),
337 m_byte_order (eByteOrderInvalid)
338{
339 SetArchitecture (arch_type, cpu, subtype);
340}
341
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342ArchSpec::~ArchSpec()
343{
344}
345
Greg Clayton64195a22011-02-23 00:35:02 +0000346//===----------------------------------------------------------------------===//
347// Assignment and initialization.
348
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349const ArchSpec&
350ArchSpec::operator= (const ArchSpec& rhs)
351{
352 if (this != &rhs)
353 {
Greg Clayton514487e2011-02-15 21:59:32 +0000354 m_triple = rhs.m_triple;
Greg Clayton64195a22011-02-23 00:35:02 +0000355 m_core = rhs.m_core;
Greg Clayton514487e2011-02-15 21:59:32 +0000356 m_byte_order = rhs.m_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 }
358 return *this;
359}
360
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361void
362ArchSpec::Clear()
363{
Greg Clayton514487e2011-02-15 21:59:32 +0000364 m_triple = llvm::Triple();
Greg Clayton64195a22011-02-23 00:35:02 +0000365 m_core = kCore_invalid;
366 m_byte_order = eByteOrderInvalid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
Greg Clayton64195a22011-02-23 00:35:02 +0000369//===----------------------------------------------------------------------===//
370// Predicates.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371
Greg Clayton41f92322010-06-11 03:25:34 +0000372
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373const char *
Greg Clayton64195a22011-02-23 00:35:02 +0000374ArchSpec::GetArchitectureName () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375{
Greg Clayton64195a22011-02-23 00:35:02 +0000376 const CoreDefinition *core_def = FindCoreDefinition (m_core);
377 if (core_def)
378 return core_def->name;
379 return "unknown";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
Greg Clayton64195a22011-02-23 00:35:02 +0000382uint32_t
383ArchSpec::GetMachOCPUType () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384{
Greg Clayton64195a22011-02-23 00:35:02 +0000385 const CoreDefinition *core_def = FindCoreDefinition (m_core);
386 if (core_def)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 {
Greg Clayton64195a22011-02-23 00:35:02 +0000388 const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
389 if (arch_def)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 {
Greg Clayton64195a22011-02-23 00:35:02 +0000391 return arch_def->cpu;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 }
393 }
Greg Clayton64195a22011-02-23 00:35:02 +0000394 return LLDB_INVALID_CPUTYPE;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395}
396
Greg Clayton64195a22011-02-23 00:35:02 +0000397uint32_t
398ArchSpec::GetMachOCPUSubType () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399{
Greg Clayton64195a22011-02-23 00:35:02 +0000400 const CoreDefinition *core_def = FindCoreDefinition (m_core);
401 if (core_def)
402 {
403 const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
404 if (arch_def)
405 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000406 return arch_def->sub;
Greg Clayton64195a22011-02-23 00:35:02 +0000407 }
408 }
409 return LLDB_INVALID_CPUTYPE;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410}
411
Greg Clayton64195a22011-02-23 00:35:02 +0000412llvm::Triple::ArchType
413ArchSpec::GetMachine () const
414{
415 const CoreDefinition *core_def = FindCoreDefinition (m_core);
416 if (core_def)
417 return core_def->machine;
418
419 return llvm::Triple::UnknownArch;
420}
421
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422uint32_t
423ArchSpec::GetAddressByteSize() const
424{
Greg Clayton64195a22011-02-23 00:35:02 +0000425 const CoreDefinition *core_def = FindCoreDefinition (m_core);
426 if (core_def)
427 return core_def->addr_byte_size;
Greg Clayton41f92322010-06-11 03:25:34 +0000428 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431ByteOrder
432ArchSpec::GetDefaultEndian () const
433{
Greg Clayton64195a22011-02-23 00:35:02 +0000434 const CoreDefinition *core_def = FindCoreDefinition (m_core);
435 if (core_def)
436 return core_def->default_byte_order;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 return eByteOrderInvalid;
438}
439
Greg Clayton64195a22011-02-23 00:35:02 +0000440lldb::ByteOrder
441ArchSpec::GetByteOrder () const
442{
443 if (m_byte_order == eByteOrderInvalid)
444 return GetDefaultEndian();
445 return m_byte_order;
446}
447
448//===----------------------------------------------------------------------===//
449// Mutators.
450
451bool
452ArchSpec::SetTriple (const llvm::Triple &triple)
453{
454 m_triple = triple;
455
456 llvm::StringRef arch_name (m_triple.getArchName());
457 const CoreDefinition *core_def = FindCoreDefinition (arch_name);
458 if (core_def)
459 {
460 m_core = core_def->core;
Greg Claytoneb0103f2011-04-07 22:46:35 +0000461 // Set the byte order to the default byte order for an architecture.
462 // This can be modified if needed for cases when cores handle both
463 // big and little endian
464 m_byte_order = core_def->default_byte_order;
Greg Clayton64195a22011-02-23 00:35:02 +0000465 }
466 else
467 {
468 Clear();
469 }
470
471
472 return IsValid();
473}
474
475bool
Greg Claytoneb0103f2011-04-07 22:46:35 +0000476ArchSpec::SetTriple (const char *triple_cstr, Platform *platform)
Greg Clayton64195a22011-02-23 00:35:02 +0000477{
Greg Clayton23aca092011-08-12 23:32:52 +0000478 if (triple_cstr && triple_cstr[0])
Greg Clayton64195a22011-02-23 00:35:02 +0000479 {
480 llvm::StringRef triple_stref (triple_cstr);
481 if (triple_stref.startswith (LLDB_ARCH_DEFAULT))
482 {
483 // Special case for the current host default architectures...
484 if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT))
485 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
486 else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT))
487 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture64);
488 else if (triple_stref.equals (LLDB_ARCH_DEFAULT))
489 *this = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
490 }
491 else
492 {
493 std::string normalized_triple_sstr (llvm::Triple::normalize(triple_stref));
494 triple_stref = normalized_triple_sstr;
Greg Claytoneb0103f2011-04-07 22:46:35 +0000495 llvm::Triple normalized_triple (triple_stref);
496
497 const bool os_specified = normalized_triple.getOSName().size() > 0;
498 const bool vendor_specified = normalized_triple.getVendorName().size() > 0;
499 const bool env_specified = normalized_triple.getEnvironmentName().size() > 0;
500
501 // If we got an arch only, then default the vendor, os, environment
502 // to match the platform if one is supplied
503 if (!(os_specified || vendor_specified || env_specified))
504 {
505 if (platform)
506 {
507 // If we were given a platform, use the platform's system
508 // architecture. If this is not available (might not be
509 // connected) use the first supported architecture.
510 ArchSpec platform_arch (platform->GetSystemArchitecture());
511 if (!platform_arch.IsValid())
512 {
513 if (!platform->GetSupportedArchitectureAtIndex (0, platform_arch))
514 platform_arch.Clear();
515 }
516
517 if (platform_arch.IsValid())
518 {
519 normalized_triple.setVendor(platform_arch.GetTriple().getVendor());
520 normalized_triple.setOS(platform_arch.GetTriple().getOS());
521 normalized_triple.setEnvironment(platform_arch.GetTriple().getEnvironment());
522 }
523 }
524 else
525 {
526 // No platform specified, fall back to the host system for
527 // the default vendor, os, and environment.
Sean Callananbfb237bc2011-11-04 22:46:46 +0000528 llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
Greg Claytoneb0103f2011-04-07 22:46:35 +0000529 normalized_triple.setVendor(host_triple.getVendor());
530 normalized_triple.setOS(host_triple.getOS());
531 normalized_triple.setEnvironment(host_triple.getEnvironment());
532 }
533 }
534 SetTriple (normalized_triple);
Greg Clayton64195a22011-02-23 00:35:02 +0000535 }
536 }
537 else
538 Clear();
539 return IsValid();
540}
541
Greg Clayton64195a22011-02-23 00:35:02 +0000542bool
Greg Claytone0d378b2011-03-24 21:19:54 +0000543ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub)
Greg Clayton64195a22011-02-23 00:35:02 +0000544{
545 m_core = kCore_invalid;
546 bool update_triple = true;
547 const ArchDefinition *arch_def = FindArchDefinition(arch_type);
548 if (arch_def)
549 {
550 const ArchDefinitionEntry *arch_def_entry = FindArchDefinitionEntry (arch_def, cpu, sub);
551 if (arch_def_entry)
552 {
553 const CoreDefinition *core_def = FindCoreDefinition (arch_def_entry->core);
554 if (core_def)
555 {
556 m_core = core_def->core;
557 update_triple = false;
Greg Clayton593577a2011-09-21 03:57:31 +0000558 // Always use the architecture name because it might be more descriptive
559 // than the architecture enum ("armv7" -> llvm::Triple::arm).
560 m_triple.setArchName(llvm::StringRef(core_def->name));
Greg Clayton64195a22011-02-23 00:35:02 +0000561 if (arch_type == eArchTypeMachO)
562 {
563 m_triple.setVendor (llvm::Triple::Apple);
564 m_triple.setOS (llvm::Triple::Darwin);
565 }
566 else
567 {
568 m_triple.setVendor (llvm::Triple::UnknownVendor);
569 m_triple.setOS (llvm::Triple::UnknownOS);
570 }
Greg Clayton593577a2011-09-21 03:57:31 +0000571 // Fall back onto setting the machine type if the arch by name failed...
572 if (m_triple.getArch () == llvm::Triple::UnknownArch)
573 m_triple.setArch (core_def->machine);
Greg Clayton64195a22011-02-23 00:35:02 +0000574 }
575 }
576 }
577 CoreUpdated(update_triple);
578 return IsValid();
579}
580
Greg Clayton357132e2011-03-26 19:14:58 +0000581uint32_t
582ArchSpec::GetMinimumOpcodeByteSize() const
Greg Clayton64195a22011-02-23 00:35:02 +0000583{
Greg Clayton357132e2011-03-26 19:14:58 +0000584 const CoreDefinition *core_def = FindCoreDefinition (m_core);
585 if (core_def)
586 return core_def->min_opcode_byte_size;
587 return 0;
588}
589
590uint32_t
591ArchSpec::GetMaximumOpcodeByteSize() const
592{
593 const CoreDefinition *core_def = FindCoreDefinition (m_core);
594 if (core_def)
595 return core_def->max_opcode_byte_size;
596 return 0;
Greg Clayton64195a22011-02-23 00:35:02 +0000597}
598
599//===----------------------------------------------------------------------===//
600// Helper methods.
601
602void
603ArchSpec::CoreUpdated (bool update_triple)
604{
605 const CoreDefinition *core_def = FindCoreDefinition (m_core);
606 if (core_def)
607 {
608 if (update_triple)
609 m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
610 m_byte_order = core_def->default_byte_order;
611 }
612 else
613 {
614 if (update_triple)
615 m_triple = llvm::Triple();
616 m_byte_order = eByteOrderInvalid;
617 }
618}
619
620//===----------------------------------------------------------------------===//
621// Operators.
622
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623bool
624lldb_private::operator== (const ArchSpec& lhs, const ArchSpec& rhs)
625{
Jim Ingham4d9695a2011-09-15 01:07:30 +0000626 if (lhs.GetByteOrder() != rhs.GetByteOrder())
627 return false;
628
Greg Clayton64195a22011-02-23 00:35:02 +0000629 const ArchSpec::Core lhs_core = lhs.GetCore ();
630 const ArchSpec::Core rhs_core = rhs.GetCore ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631
Jim Ingham4d9695a2011-09-15 01:07:30 +0000632 bool core_match = false;
Greg Clayton64195a22011-02-23 00:35:02 +0000633 if (lhs_core == rhs_core)
Jim Ingham4d9695a2011-09-15 01:07:30 +0000634 core_match = true;
635 else
636 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637
Jim Ingham4d9695a2011-09-15 01:07:30 +0000638 if (lhs_core == ArchSpec::kCore_any || rhs_core == ArchSpec::kCore_any)
639 core_match = true;
640 else
641 {
642 if (lhs_core == ArchSpec::kCore_arm_any)
643 {
644 if ((rhs_core >= ArchSpec::kCore_arm_first && rhs_core <= ArchSpec::kCore_arm_last) || (rhs_core == ArchSpec::kCore_arm_any))
645 core_match = true;
646 }
647 else if (rhs_core == ArchSpec::kCore_arm_any)
648 {
649 if ((lhs_core >= ArchSpec::kCore_arm_first && lhs_core <= ArchSpec::kCore_arm_last) || (lhs_core == ArchSpec::kCore_arm_any))
650 core_match = true;
651 }
652 else if (lhs_core == ArchSpec::kCore_x86_32_any)
653 {
654 if ((rhs_core >= ArchSpec::kCore_x86_32_first && rhs_core <= ArchSpec::kCore_x86_32_last) || (rhs_core == ArchSpec::kCore_x86_32_any))
655 core_match = true;
656 }
657 else if (rhs_core == ArchSpec::kCore_x86_32_any)
658 {
659 if ((lhs_core >= ArchSpec::kCore_x86_32_first && lhs_core <= ArchSpec::kCore_x86_32_last) || (lhs_core == ArchSpec::kCore_x86_32_any))
660 core_match = true;
661 }
662 else if (lhs_core == ArchSpec::kCore_ppc_any)
663 {
664 if ((rhs_core >= ArchSpec::kCore_ppc_first && rhs_core <= ArchSpec::kCore_ppc_last) || (rhs_core == ArchSpec::kCore_ppc_any))
665 core_match = true;
666 }
667 else if (rhs_core == ArchSpec::kCore_ppc_any)
668 {
669 if ((lhs_core >= ArchSpec::kCore_ppc_first && lhs_core <= ArchSpec::kCore_ppc_last) || (lhs_core == ArchSpec::kCore_ppc_any))
670 core_match = true;
671 }
672 else if (lhs_core == ArchSpec::kCore_ppc64_any)
673 {
674 if ((rhs_core >= ArchSpec::kCore_ppc64_first && rhs_core <= ArchSpec::kCore_ppc64_last) || (rhs_core == ArchSpec::kCore_ppc64_any))
675 core_match = true;
676 }
677 else if (rhs_core == ArchSpec::kCore_ppc64_any)
678 {
679 if ((lhs_core >= ArchSpec::kCore_ppc64_first && lhs_core <= ArchSpec::kCore_ppc64_last) || (lhs_core == ArchSpec::kCore_ppc64_any))
680 core_match = true;
681 }
682 }
683 }
684 if (!core_match)
685 return false;
686 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000687 {
Jim Ingham4d9695a2011-09-15 01:07:30 +0000688 const llvm::Triple &lhs_triple = lhs.GetTriple();
689 const llvm::Triple &rhs_triple = rhs.GetTriple();
Greg Clayton593577a2011-09-21 03:57:31 +0000690
691 const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
692 const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
693 if (lhs_triple_vendor != rhs_triple_vendor)
694 {
695 // Only fail if both vendor types are not unknown
696 if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
697 rhs_triple_vendor != llvm::Triple::UnknownVendor)
698 return false;
699 }
700
701 const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
702 const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
703 if (lhs_triple_os != rhs_triple_os)
704 {
705 // Only fail if both os types are not unknown
706 if (lhs_triple_os != llvm::Triple::UnknownOS &&
707 rhs_triple_os != llvm::Triple::UnknownOS)
708 return false;
709 }
710
711 const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
712 const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
713
714 if (lhs_triple_env != rhs_triple_env)
715 {
716 // Only fail if both environment types are not unknown
717 if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
718 rhs_triple_env != llvm::Triple::UnknownEnvironment)
719 return false;
720 }
721 return true;
Greg Clayton64195a22011-02-23 00:35:02 +0000722 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723}
724
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725bool
726lldb_private::operator!= (const ArchSpec& lhs, const ArchSpec& rhs)
727{
728 return !(lhs == rhs);
729}
730
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731bool
732lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
733{
Greg Clayton64195a22011-02-23 00:35:02 +0000734 const ArchSpec::Core lhs_core = lhs.GetCore ();
735 const ArchSpec::Core rhs_core = rhs.GetCore ();
736 return lhs_core < rhs_core;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737}