blob: 2fa1d67c0d85f1f5e81b1479c668bce1903fe47e [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the -arch command line option and creates a TargetInfo
11// that represents them.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang.h"
16#include "clang/Basic/Diagnostic.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/Support/CommandLine.h"
19using namespace llvm;
20using namespace clang;
21
22/// Note: a hard coded list of targets is clearly silly, these should be
23/// dynamicly registered and loadable with "-load".
24enum SupportedTargets {
25 target_ppc, target_ppc64,
26 target_i386, target_x86_64,
27 target_linux_i386
28};
29
30static cl::list<SupportedTargets>
31Archs("arch", cl::desc("Architectures to compile for"),
32 cl::values(clEnumValN(target_ppc, "ppc", "32-bit Darwin PowerPC"),
33 clEnumValN(target_ppc64, "ppc64", "64-bit Darwin PowerPC"),
34 clEnumValN(target_i386, "i386", "32-bit Darwin X86"),
35 clEnumValN(target_x86_64, "x86_64","64-bit Darwin X86"),
36 clEnumValN(target_linux_i386,"linux", "Linux i386"),
37 clEnumValEnd));
38
39//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000040// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000041//===----------------------------------------------------------------------===//
42
43namespace {
44class DarwinTargetInfo : public TargetInfoImpl {
45public:
Chris Lattner1f5ad112006-10-14 18:32:12 +000046 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
47 Defines.push_back("__APPLE__");
48 }
49
Chris Lattner5ba61f02006-10-14 07:39:34 +000050};
51} // end anonymous namespace.
52
53
Chris Lattner1f5ad112006-10-14 18:32:12 +000054/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
55/// not tied to a specific subtarget.
56static void getPowerPCDefines(std::vector<std::string> &Defines, bool is64Bit) {
57 Defines.push_back("__ppc__");
58
59}
60
61/// getX86Defines - Return a set of the X86-specific #defines that are
62/// not tied to a specific subtarget.
63static void getX86Defines(std::vector<std::string> &Defines, bool is64Bit) {
64 Defines.push_back("__i386__");
65
66}
67
Chris Lattner5ba61f02006-10-14 07:39:34 +000068//===----------------------------------------------------------------------===//
69// Specific target implementations.
70//===----------------------------------------------------------------------===//
71
Chris Lattner02dffbd2006-10-14 07:50:21 +000072
Chris Lattner5ba61f02006-10-14 07:39:34 +000073namespace {
74class DarwinPPCTargetInfo : public DarwinTargetInfo {
75public:
Chris Lattner1f5ad112006-10-14 18:32:12 +000076 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
77 DarwinTargetInfo::getTargetDefines(Defines);
78 getPowerPCDefines(Defines, false);
79 }
Chris Lattner5ba61f02006-10-14 07:39:34 +000080};
81} // end anonymous namespace.
82
83namespace {
84class DarwinPPC64TargetInfo : public DarwinTargetInfo {
85public:
Chris Lattner1f5ad112006-10-14 18:32:12 +000086 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
87 DarwinTargetInfo::getTargetDefines(Defines);
88 getPowerPCDefines(Defines, true);
89 }
Chris Lattner5ba61f02006-10-14 07:39:34 +000090};
91} // end anonymous namespace.
92
93namespace {
94class DarwinI386TargetInfo : public DarwinTargetInfo {
95public:
Chris Lattner1f5ad112006-10-14 18:32:12 +000096 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
97 DarwinTargetInfo::getTargetDefines(Defines);
98 getX86Defines(Defines, false);
99 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000100};
101} // end anonymous namespace.
102
103namespace {
104class DarwinX86_64TargetInfo : public DarwinTargetInfo {
105public:
Chris Lattner1f5ad112006-10-14 18:32:12 +0000106 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
107 DarwinTargetInfo::getTargetDefines(Defines);
108 getX86Defines(Defines, true);
109 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000110};
111} // end anonymous namespace.
112
113namespace {
114class LinuxTargetInfo : public DarwinTargetInfo {
115public:
116 LinuxTargetInfo() {
117 // Note: I have no idea if this is right, just for testing.
118 WCharWidth = 2;
119 }
Chris Lattner1f5ad112006-10-14 18:32:12 +0000120
121 virtual void getTargetDefines(std::vector<std::string> &Defines) const {
122 // TODO: linux-specific stuff.
123 getX86Defines(Defines, false);
124 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000125};
126} // end anonymous namespace.
127
128
129//===----------------------------------------------------------------------===//
130// Driver code
131//===----------------------------------------------------------------------===//
132
133/// CreateTarget - Create the TargetInfoImpl object for the specified target
134/// enum value.
135static TargetInfoImpl *CreateTarget(SupportedTargets T) {
136 switch (T) {
137 default: assert(0 && "Unknown target!");
138 case target_ppc: return new DarwinPPCTargetInfo();
139 case target_ppc64: return new DarwinPPC64TargetInfo();
140 case target_i386: return new DarwinI386TargetInfo();
141 case target_x86_64: return new DarwinX86_64TargetInfo();
142 case target_linux_i386: return new LinuxTargetInfo();
143 }
144}
145
146/// CreateTargetInfo - Return the set of target info objects as specified by
147/// the -arch command line option.
148TargetInfo *clang::CreateTargetInfo(Diagnostic &Diags) {
149 // If the user didn't specify at least one architecture, auto-sense the
150 // current host. TODO: This is a hack. :)
151 if (Archs.empty()) {
152#ifndef __APPLE__
153 // Assume non-apple = linux.
154 Archs.push_back(target_linux_i386);
155#elif (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
156 defined(__ppc64__)
157 Archs.push_back(target_ppc64);
158#elif defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)
159 Archs.push_back(target_ppc);
160#elif defined(__x86_64__)
161 Archs.push_back(target_x86_64);
162#elif defined(__i386__) || defined(i386) || defined(_M_IX86)
163 Archs.push_back(target_i386);
164#else
165 // Don't know what this is!
166 return 0;
167#endif
168 }
169
170 // Create the primary target and target info.
171 TargetInfo *TI = new TargetInfo(CreateTarget(Archs[0]), &Diags);
172
173 // Add all secondary targets.
174 for (unsigned i = 1, e = Archs.size(); i != e; ++i)
175 TI->AddSecondaryTarget(CreateTarget(Archs[i]));
176 return TI;
177}