Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 1 | #include "libslang.h" |
zonr | 6315f76 | 2010-10-05 15:35:14 +0800 | [diff] [blame] | 2 | #include "slang_rs_reflect_utils.h" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 3 | |
| 4 | #include <assert.h> |
| 5 | #include <getopt.h> |
| 6 | |
| 7 | #include <cstring> |
| 8 | #include <cstdlib> |
Ying Wang | b003707 | 2010-09-08 15:06:34 -0700 | [diff] [blame] | 9 | #include <cstdio> |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 10 | #include <iomanip> |
| 11 | #include <iostream> |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 12 | #include <vector> |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 13 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 14 | #include <sys/stat.h> |
| 15 | #include <fcntl.h> |
| 16 | #include <sys/wait.h> |
| 17 | |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 18 | using namespace std; |
| 19 | |
| 20 | #define ERR_NO_INPUT_FILE "no input file" |
| 21 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 22 | #define NOTE(x) cerr << "note: " NOTE_ ## x << endl |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 23 | #define WARN(x) cerr << "warning: " WARN_ ## x << endl |
| 24 | #define WARN1(x, v1) cerr << "warning: " WARN_ ## x(v1) << endl |
| 25 | #define WARN2(x, v1, v2) cerr << "warning: " WARN_ ## x(v1, v2) << endl |
| 26 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 27 | #define NOTE_MULTIPLE_INPUT_FILES "multiple input files detected: Will enforce ODR (One Definition Rule) during reflection." |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 28 | |
| 29 | #define WARN_UNKNOWN_CPU(v1) "the given CPU " << (v1) << " cannot be recognized, but we'll force passing it to Slang compiler" |
| 30 | |
| 31 | #define WARN_MISMATCH_CPU_TARGET_ARCH(v1, v2) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 32 | "CPU (target: " << (v1) << ") you selected doesn't match the target of enable features you specified or the triple string you given (" << (v2) << ")" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 33 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 34 | #define WARN_MISMATCH_FEATURE_TARGET_ARCH(v1, v2) \ |
| 35 | "Feature (target: " << (v1) << ") you selected doesn't match the target of CPU you specified or the triple string you given (" << (v2) << ")" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 36 | |
| 37 | /* List of all support target, will look like "ArchARM" */ |
| 38 | #define MK_TARGET_ARCH(target) Arch ## target |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 39 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 40 | typedef enum { |
| 41 | ArchNone, |
| 42 | #define DEF_SUPPORT_TARGET(target, name, default_triple) \ |
| 43 | MK_TARGET_ARCH(target), |
| 44 | # include "target.inc" |
| 45 | |
| 46 | MaxTargetArch |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 47 | } TargetArchEnum; |
| 48 | |
| 49 | typedef struct { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 50 | TargetArchEnum Arch; |
| 51 | const char* Name; |
| 52 | const char* DefaultTriple; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 53 | } TargetArch; |
| 54 | |
| 55 | static const TargetArch TargetArchTable[] = { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 56 | { ArchNone, "none", "unknown-unknown-linux" }, |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 57 | #define DEF_SUPPORT_TARGET(target, name, default_triple) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 58 | { MK_TARGET_ARCH(target), name, default_triple }, |
| 59 | # include "target.inc" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 60 | }; |
| 61 | |
| 62 | #if defined(__arm__) |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 63 | # define HOST_ARCH MK_TARGET_ARCH(X86) |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 64 | #elif defined(__i386__) |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 65 | # define HOST_ARCH MK_TARGET_ARCH(ARM) |
| 66 | #elif defined(__x86_64__) |
| 67 | # define HOST_ARCH MK_TARGET_ARCH(X64) |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 68 | #else |
| 69 | # error "We can not find default triple string for your host machine, please define it by yourself via option '--triple' or '-t'" |
| 70 | #endif |
| 71 | |
| 72 | #define DEFAULT_TARGET_TRIPLE_STRING TargetArchTable[HOST_ARCH].DefaultTriple |
| 73 | |
| 74 | /* Lists of all target features, will look like "{Target}FeatureNEON" */ |
| 75 | #define MK_TARGET_FEATURE(target, id) target ## id |
| 76 | typedef enum { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 77 | FeatureNone = 0, |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 78 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 79 | MK_TARGET_FEATURE(target, id), |
| 80 | |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 81 | #define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 82 | target ## FeatureStart, \ |
| 83 | MK_TARGET_FEATURE(target, id) = target ## FeatureStart, |
| 84 | |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 85 | # include "target.inc" |
| 86 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 87 | MaxTargetFeature |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 88 | } TargetFeatureEnum; |
| 89 | |
| 90 | /* Feature as bits using in {Target}TargetCPU, will look like "X{Target}FeatureNEON" */ |
| 91 | #define MK_TARGET_FEATURE_BIT(target, id) X ## target ## id |
| 92 | typedef enum { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 93 | XFeatureNone = 0, |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 94 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 95 | MK_TARGET_FEATURE_BIT(target, id) = 1 << (MK_TARGET_FEATURE(target, id) - target ## FeatureStart), |
| 96 | # include "target.inc" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 97 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 98 | XMaxTargetFeature |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 99 | } TargetFeatureBit; |
| 100 | |
| 101 | typedef struct { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 102 | TargetArchEnum Arch; |
| 103 | TargetFeatureEnum Key; |
| 104 | TargetFeatureBit Bit; |
| 105 | const char* Name; |
| 106 | const char* Desc; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 107 | } TargetFeature; |
| 108 | |
| 109 | /* Should be 1-1 mapping with TargetFeatureEnum */ |
| 110 | static const TargetFeature TargetFeatureTable[] = { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 111 | { ArchNone, FeatureNone, XFeatureNone, "none", "Empty feature" }, /* FeatureNone */ |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 112 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 113 | { MK_TARGET_ARCH(target), MK_TARGET_FEATURE(target, id), MK_TARGET_FEATURE_BIT(target, id), key, description }, |
| 114 | # include "target.inc" |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 115 | }; |
| 116 | |
| 117 | typedef struct { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 118 | TargetArchEnum Arch; |
| 119 | const char* Name; |
| 120 | const char* Desc; |
| 121 | unsigned int FeatureEnabled; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 122 | } TargetCPU; |
| 123 | |
| 124 | /* Sorted by CPU name such that we can call bsearch() to quickly retain the CPU entry corresponding to the name */ |
| 125 | #define E(feature) MK_TARGET_FEATURE_BIT(ARM, feature) |
| 126 | static const TargetCPU TargetCPUTable[] = { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 127 | { MK_TARGET_ARCH(ARM), "arm1020e", "Select the arm1020e processor", E(ArchV5TE) }, |
| 128 | { MK_TARGET_ARCH(ARM), "arm1020t", "Select the arm1020t processor", E(ArchV5T) }, |
| 129 | { MK_TARGET_ARCH(ARM), "arm1022e", "Select the arm1022e processor", E(ArchV5TE) }, |
| 130 | { MK_TARGET_ARCH(ARM), "arm10e", "Select the arm10e processor", E(ArchV5TE) }, |
| 131 | { MK_TARGET_ARCH(ARM), "arm10tdmi", "Select the arm10tdmi processor", E(ArchV5T) }, |
| 132 | { MK_TARGET_ARCH(ARM), "arm1136j-s", "Select the arm1136j-s processor", E(ArchV6) }, |
| 133 | { MK_TARGET_ARCH(ARM), "arm1136jf-s", "Select the arm1136jf-s processor", E(ArchV6) | E(FeatureVFP2) }, |
| 134 | { MK_TARGET_ARCH(ARM), "arm1156t2-s", "Select the arm1156t2-s processor", E(ArchV6T2) | E(FeatureThumb2) }, |
| 135 | { MK_TARGET_ARCH(ARM), "arm1156t2f-s", "Select the arm1156t2f-s processor", E(ArchV6T2) | E(FeatureThumb2) | E(FeatureVFP2) }, |
| 136 | { MK_TARGET_ARCH(ARM), "arm1176jz-s", "Select the arm1176jz-s processor", E(ArchV6) }, |
| 137 | { MK_TARGET_ARCH(ARM), "arm1176jzf-s", "Select the arm1176jzf-s processor", E(ArchV6) | E(FeatureVFP2) }, |
| 138 | { MK_TARGET_ARCH(ARM), "arm710t", "Select the arm710t processor", E(ArchV4T) }, |
| 139 | { MK_TARGET_ARCH(ARM), "arm720t", "Select the arm720t processor", E(ArchV4T) }, |
| 140 | { MK_TARGET_ARCH(ARM), "arm7tdmi", "Select the arm7tdmi processor", E(ArchV4T) }, |
| 141 | { MK_TARGET_ARCH(ARM), "arm7tdmi-s", "Select the arm7tdmi-s processor", E(ArchV4T) }, |
| 142 | { MK_TARGET_ARCH(ARM), "arm8", "Select the arm8 processor", XFeatureNone }, |
| 143 | { MK_TARGET_ARCH(ARM), "arm810", "Select the arm810 processor", XFeatureNone }, |
| 144 | { MK_TARGET_ARCH(ARM), "arm9", "Select the arm9 processor", E(ArchV4T) }, |
| 145 | { MK_TARGET_ARCH(ARM), "arm920", "Select the arm920 processor", E(ArchV4T) }, |
| 146 | { MK_TARGET_ARCH(ARM), "arm920t", "Select the arm920t processor", E(ArchV4T) }, |
| 147 | { MK_TARGET_ARCH(ARM), "arm922t", "Select the arm922t processor", E(ArchV4T) }, |
| 148 | { MK_TARGET_ARCH(ARM), "arm926ej-s", "Select the arm926ej-s processor", E(ArchV5TE) }, |
| 149 | { MK_TARGET_ARCH(ARM), "arm940t", "Select the arm940t processor", E(ArchV4T) }, |
| 150 | { MK_TARGET_ARCH(ARM), "arm946e-s", "Select the arm946e-s processor", E(ArchV5TE) }, |
| 151 | { MK_TARGET_ARCH(ARM), "arm966e-s", "Select the arm966e-s processor", E(ArchV5TE) }, |
| 152 | { MK_TARGET_ARCH(ARM), "arm968e-s", "Select the arm968e-s processor", E(ArchV5TE) }, |
| 153 | { MK_TARGET_ARCH(ARM), "arm9e", "Select the arm9e processor", E(ArchV5TE) }, |
| 154 | { MK_TARGET_ARCH(ARM), "arm9tdmi", "Select the arm9tdmi processor", E(ArchV4T) }, |
| 155 | { MK_TARGET_ARCH(ARM), "cortex-a8", "Select the cortex-a8 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) }, |
| 156 | { MK_TARGET_ARCH(ARM), "cortex-a9", "Select the cortex-a9 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) }, |
| 157 | { MK_TARGET_ARCH(ARM), "ep9312", "Select the ep9312 processor", E(ArchV4T) }, |
| 158 | { MK_TARGET_ARCH(ARM), "generic", "Select the generic processor", XFeatureNone }, |
| 159 | { MK_TARGET_ARCH(ARM), "iwmmxt", "Select the iwmmxt processor", E(ArchV5TE) }, |
| 160 | { MK_TARGET_ARCH(ARM), "mpcore", "Select the mpcore processor", E(ArchV6) | E(FeatureVFP2) }, |
| 161 | { MK_TARGET_ARCH(ARM), "mpcorenovfp", "Select the mpcorenovfp processor", E(ArchV6) }, |
| 162 | { MK_TARGET_ARCH(ARM), "strongarm", "Select the strongarm processor", XFeatureNone }, |
| 163 | { MK_TARGET_ARCH(ARM), "strongarm110", "Select the strongarm110 processor", XFeatureNone }, |
| 164 | { MK_TARGET_ARCH(ARM), "strongarm1100", "Select the strongarm1100 processor", XFeatureNone }, |
| 165 | { MK_TARGET_ARCH(ARM), "strongarm1110", "Select the strongarm1110 processor", XFeatureNone }, |
| 166 | { MK_TARGET_ARCH(ARM), "xscale", "Select the xscale processor", MK_TARGET_FEATURE_BIT(ARM, ArchV5TE) } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 167 | }; |
| 168 | #undef E |
| 169 | static int CompareCPUName(const void* a, const void* b) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 170 | return strcasecmp(((TargetCPU*) a)->Name, ((TargetCPU*) b)->Name); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 171 | } |
| 172 | #define NUM_TARGET_CPU (sizeof(TargetCPUTable) / sizeof(TargetCPU)) |
| 173 | |
| 174 | static struct option* SlangOpts = NULL; |
| 175 | |
| 176 | static const char* CPUString; |
| 177 | static const TargetCPU* CPU; |
| 178 | static const char* TripleString; |
| 179 | static TargetFeatureEnum EnableFeatureValue, DisableFeatureValue; |
| 180 | static SlangCompilerOutputTy OutputFileType; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 181 | static const char* JavaReflectionPackageName; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 182 | |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 183 | static const char* JavaReflectionPathName; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 184 | static const char* OutputPathName; |
| 185 | |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 186 | static std::vector<std::string> IncludePaths; |
| 187 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 188 | static std::string* InputFileNames; |
| 189 | static std::string* OutputFileNames; |
| 190 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 191 | // Where to store the bc file. |
| 192 | // possible values: |
| 193 | // ar: packed as apk resource |
| 194 | // jc: encoded in Java code. |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 195 | static slang::BitCodeStorageType BitCodeStorage(slang::BCST_APK_RESOURCE); |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 196 | |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 197 | static bool Verbose; |
| 198 | static const char* FeatureEnabledList[MaxTargetFeature + 1]; |
Kirk Stewart | 1fd8579 | 2010-07-07 09:51:23 -0700 | [diff] [blame] | 199 | static int AllowRSPrefix = 0; |
Shih-wei Liao | 9c9bbc8 | 2010-08-18 03:08:44 -0700 | [diff] [blame] | 200 | static int Externalize = 0; |
Shih-wei Liao | 24c2008 | 2010-09-21 10:04:05 -0700 | [diff] [blame] | 201 | static int NoLink = 1; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 202 | |
| 203 | /* Construct the command options table used in ParseOption::getopt_long */ |
| 204 | static void ConstructCommandOptions() { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 205 | /* Basic slang command option */ |
| 206 | static struct option BasicSlangOpts[] = { |
| 207 | { "allow-rs-prefix", no_argument, &AllowRSPrefix, 1 }, |
Shih-wei Liao | 9c9bbc8 | 2010-08-18 03:08:44 -0700 | [diff] [blame] | 208 | { "externalize", no_argument, &Externalize, 1 }, |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 209 | { "no-link", no_argument, &NoLink, 1 }, |
Kirk Stewart | 1fd8579 | 2010-07-07 09:51:23 -0700 | [diff] [blame] | 210 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 211 | { "emit-llvm", no_argument, (int*) &OutputFileType, SlangCompilerOutput_LL }, |
| 212 | { "emit-bc", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Bitcode }, |
| 213 | { "emit-asm", no_argument, NULL, 'S' }, |
| 214 | { "emit-obj", no_argument, NULL, 'c' }, |
| 215 | { "emit-nothing", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Nothing }, |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 216 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 217 | { "help", no_argument, NULL, 'h' }, /* -h */ |
| 218 | { "verbose", no_argument, NULL, 'v' }, /* -v */ |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 219 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 220 | { "output-obj-path", required_argument, NULL, 'o' }, /* -o */ |
| 221 | { "cpu", required_argument, NULL, 'u' }, /* -u */ |
| 222 | { "triple", required_argument, NULL, 't' }, /* -t */ |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 223 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 224 | { "output-java-reflection-class", required_argument, NULL, 'j'}, /* -j */ |
| 225 | { "output-java-reflection-path", required_argument, NULL, 'p'}, /* -p */ |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 226 | |
| 227 | { "include-path", required_argument, NULL, 'I'}, /* -I */ |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 228 | { "bitcode-storage", required_argument, NULL, 's'}, /* -s */ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 229 | }; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 230 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 231 | const int NumberOfBasicOptions = sizeof(BasicSlangOpts) / sizeof(struct option); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 232 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 233 | SlangOpts = new struct option [ NumberOfBasicOptions + MaxTargetFeature * 2 /* for --enable-feature and --disable-feature */ ]; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 234 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 235 | /* Fill SlangOpts with basic options */ |
| 236 | memcpy(SlangOpts, BasicSlangOpts, sizeof(BasicSlangOpts)); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 237 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 238 | int i = NumberOfBasicOptions; |
| 239 | /* Add --enable-TARGET_FEATURE option into slang command option */ |
| 240 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
| 241 | SlangOpts[i].name = "enable-" key; \ |
| 242 | SlangOpts[i].has_arg = optional_argument; \ |
| 243 | SlangOpts[i].flag = (int*) &EnableFeatureValue; \ |
| 244 | SlangOpts[i].val = target ## id; \ |
| 245 | i++; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 246 | # include "target.inc" |
| 247 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 248 | /* Add --disable-TARGET_FEATURE option into slang command option */ |
| 249 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
| 250 | SlangOpts[i].name = "disable-" key; \ |
| 251 | SlangOpts[i].has_arg = optional_argument; \ |
| 252 | SlangOpts[i].flag = (int*) &DisableFeatureValue; \ |
| 253 | SlangOpts[i].val = target ## id; \ |
| 254 | i++; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 255 | # include "target.inc" |
| 256 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 257 | /* NULL-terminated the SlangOpts */ |
| 258 | memset(&SlangOpts[i], 0, sizeof(struct option)); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 259 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 260 | return; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 261 | } |
| 262 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 263 | |
| 264 | static void Usage(const char* CommandName); |
| 265 | |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 266 | extern char *optarg; |
| 267 | extern int optind; |
| 268 | extern int optopt; |
| 269 | extern int opterr; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 270 | static int FileCount; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 271 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 272 | static int AddOutputFileSuffix(std::string &pathFile) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 273 | switch (OutputFileType) { |
| 274 | case SlangCompilerOutput_Assembly: |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 275 | pathFile += ".S"; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 276 | break; |
| 277 | case SlangCompilerOutput_LL: |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 278 | pathFile += ".ll"; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 279 | break; |
| 280 | case SlangCompilerOutput_Obj: |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 281 | pathFile += ".o"; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 282 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 283 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 284 | case SlangCompilerOutput_Nothing: |
| 285 | return 0; //strcpy(OutputFileNames[count], "/dev/null"); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 286 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 287 | case SlangCompilerOutput_Bitcode: |
| 288 | default: |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 289 | pathFile += ".bc"; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 290 | break; |
| 291 | } |
| 292 | return 1; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 293 | } |
| 294 | |
| 295 | static bool ParseOption(int Argc, char** Argv) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 296 | assert(SlangOpts != NULL && "Slang command options table was not initialized!"); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 297 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 298 | /* Set default value to option */ |
| 299 | CPU = NULL; |
| 300 | TripleString = DEFAULT_TARGET_TRIPLE_STRING; |
| 301 | EnableFeatureValue = DisableFeatureValue = FeatureNone; |
| 302 | OutputFileType = SlangCompilerOutput_Default; |
| 303 | JavaReflectionPackageName = NULL; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 304 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 305 | JavaReflectionPathName = NULL; |
| 306 | OutputPathName = NULL; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 307 | |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 308 | IncludePaths.clear(); |
| 309 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 310 | InputFileNames = NULL; |
| 311 | OutputFileNames = NULL; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 312 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 313 | Verbose = false; |
| 314 | FeatureEnabledList[0] = NULL; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 315 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 316 | int ch; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 317 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 318 | unsigned int FeatureEnableBits = 0; |
| 319 | unsigned int FeatureDisableBits = 0; |
| 320 | #define ENABLE_FEATURE(x) \ |
| 321 | FeatureEnableBits |= (x) |
| 322 | #define DISABLE_FEATURE(x) \ |
| 323 | FeatureDisableBits |= (x) |
| 324 | TargetArchEnum ExpectedArch = ArchNone; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 325 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 326 | /* Turn off the error message output by getopt_long */ |
| 327 | opterr = 0; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 328 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 329 | while((ch = getopt_long(Argc, Argv, "Schvo:u:t:j:p:I:s:", SlangOpts, NULL)) != -1) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 330 | switch(ch) { |
| 331 | case 'S': |
| 332 | OutputFileType = SlangCompilerOutput_Assembly; |
| 333 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 334 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 335 | case 'c': |
| 336 | OutputFileType = SlangCompilerOutput_Obj; |
| 337 | break; |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 338 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 339 | case 'o': |
| 340 | OutputPathName = optarg; |
| 341 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 342 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 343 | case 'j': |
| 344 | JavaReflectionPackageName = optarg; |
| 345 | break; |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 346 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 347 | case 'p': |
| 348 | JavaReflectionPathName = optarg; |
| 349 | break; |
| 350 | |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 351 | case 'I': |
| 352 | IncludePaths.push_back(optarg); |
| 353 | break; |
| 354 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 355 | case 's': |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 356 | if (!std::strcmp(optarg, "ar")) { |
| 357 | BitCodeStorage = slang::BCST_APK_RESOURCE; |
| 358 | } else if (!std::strcmp(optarg, "jc")) { |
| 359 | BitCodeStorage = slang::BCST_JAVA_CODE; |
| 360 | } else { |
| 361 | cerr << "Error: bit code storage (-s) should be 'ar' or 'jc', saw " |
| 362 | << optarg << endl; |
| 363 | return false; |
| 364 | } |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 365 | break; |
| 366 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 367 | case 'u': |
| 368 | { |
| 369 | CPUString = optarg; |
| 370 | const TargetCPU SearchCPU = { ArchNone, CPUString, NULL, XFeatureNone }; |
| 371 | CPU = (TargetCPU*) bsearch(&SearchCPU, TargetCPUTable, sizeof(TargetCPUTable) / sizeof(TargetCPU), sizeof(TargetCPU), CompareCPUName); |
| 372 | if(CPU == NULL) { |
| 373 | WARN1(UNKNOWN_CPU, SearchCPU.Name); |
| 374 | } else { |
| 375 | CPUString = CPU->Name; |
| 376 | |
| 377 | if(ExpectedArch == ArchNone) |
| 378 | ExpectedArch = CPU->Arch; |
| 379 | else if(ExpectedArch != CPU->Arch) { |
| 380 | WARN2(MISMATCH_CPU_TARGET_ARCH, TargetArchTable[CPU->Arch].Name, TargetArchTable[ExpectedArch].Name); |
| 381 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 382 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 383 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 384 | /* Get CPU Feature and enable its available feature */ |
| 385 | FeatureEnableBits |= CPU->FeatureEnabled; |
| 386 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 387 | } |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 388 | break; |
| 389 | |
| 390 | case 't': |
| 391 | TripleString = optarg; |
| 392 | break; |
| 393 | |
| 394 | case 'h': |
| 395 | Usage(Argv[0]); |
| 396 | return false; |
| 397 | break; |
| 398 | |
| 399 | case 'v': |
| 400 | Verbose = true; |
| 401 | break; |
| 402 | |
| 403 | case 0: |
| 404 | { |
| 405 | if(EnableFeatureValue != FeatureNone || DisableFeatureValue != FeatureNone) { |
| 406 | bool IsDisable = (DisableFeatureValue != FeatureNone); |
| 407 | const TargetFeature* FeatureSelected = &TargetFeatureTable[ ((IsDisable) ? DisableFeatureValue : EnableFeatureValue) ]; |
| 408 | assert(FeatureSelected != NULL && "Unexpected target feature! (not presented in table but parsed!?)"); |
| 409 | |
| 410 | if(ExpectedArch == ArchNone) |
| 411 | ExpectedArch = FeatureSelected->Arch; |
| 412 | else if(FeatureSelected->Arch != ExpectedArch) { |
| 413 | WARN2(MISMATCH_FEATURE_TARGET_ARCH, TargetArchTable[FeatureSelected->Arch].Name, TargetArchTable[ExpectedArch].Name); |
| 414 | break; |
| 415 | } |
| 416 | |
| 417 | if(optarg != NULL && atoi(optarg) == 0) |
| 418 | IsDisable = !IsDisable; |
| 419 | |
| 420 | if(IsDisable) |
| 421 | DISABLE_FEATURE(FeatureSelected->Bit); |
| 422 | else |
| 423 | ENABLE_FEATURE(FeatureSelected->Bit); |
| 424 | } |
| 425 | } |
| 426 | break; |
| 427 | |
| 428 | default: |
| 429 | cerr << "Unknown option: " << Argv[optind - 1] << endl; |
| 430 | return false; |
| 431 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 432 | } |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 433 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 434 | #undef ENABLE_FEATURE |
| 435 | #undef DISABLE_FEATURE |
| 436 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 437 | int CurFeatureEnableListIdx = 0; |
| 438 | /* Add the enable/disable feature string to */ |
| 439 | switch(ExpectedArch) { |
| 440 | case ArchNone: |
| 441 | ExpectedArch = HOST_ARCH; |
| 442 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 443 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 444 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
| 445 | if(FeatureDisableBits & MK_TARGET_FEATURE_BIT(target, id)) \ |
| 446 | FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "-" key; \ |
| 447 | else if(FeatureEnableBits & MK_TARGET_FEATURE_BIT(target, id)) \ |
| 448 | FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "+" key; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 449 | #define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \ |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 450 | case Arch ## target: \ |
| 451 | /* Fix target triple */ \ |
| 452 | if(TripleString == DEFAULT_TARGET_TRIPLE_STRING) \ |
| 453 | TripleString = TargetArchTable[MK_TARGET_ARCH(target)].DefaultTriple; \ |
| 454 | DEF_TARGET_FEATURE(target, id, key, description) |
| 455 | #define HOOK_TARGET_LAST_FEATURE(target, id, key, description) \ |
| 456 | DEF_TARGET_FEATURE(target, id, key, description) \ |
| 457 | FeatureEnabledList[ CurFeatureEnableListIdx++ ] = NULL; /* null-terminator */ \ |
| 458 | break; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 459 | #include "target.inc" |
| 460 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 461 | default: |
| 462 | assert(false && "Unknown / Unsupported CPU architecture"); |
| 463 | break; |
| 464 | } |
| 465 | |
| 466 | Argc -= optind; |
| 467 | if(Argc <= 0) { |
| 468 | cerr << Argv[0] << ": "ERR_NO_INPUT_FILE << endl; |
| 469 | return false; |
| 470 | } |
| 471 | |
| 472 | if(Argc > 1) { |
| 473 | NOTE(MULTIPLE_INPUT_FILES); |
| 474 | } |
| 475 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 476 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 477 | FileCount = Argc; |
| 478 | InputFileNames = new std::string[FileCount]; |
| 479 | OutputFileNames = new std::string[FileCount]; |
| 480 | int count; |
| 481 | for (count = 0; count < FileCount; count++) { |
| 482 | InputFileNames[count].assign(Argv[optind + count]); |
| 483 | |
| 484 | if ( OutputPathName && !strcmp(OutputPathName, "-") ) { |
| 485 | OutputFileNames[count].assign("stdout"); |
| 486 | continue; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 487 | } |
| 488 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 489 | std::string _outF; |
| 490 | if (OutputPathName) { |
| 491 | _outF.assign(OutputPathName); |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 492 | if (_outF[_outF.length()-1] != '/') { |
| 493 | _outF += "/"; |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 494 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 495 | } |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 496 | _outF += slang::RSSlangReflectUtils::BCFileNameFromRSFileName( |
| 497 | InputFileNames[count].c_str()); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 498 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 499 | int status = AddOutputFileSuffix(_outF); |
| 500 | if (status < 0) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 501 | return false; |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 502 | } else if (!status) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 503 | OutputFileNames[count].assign("/dev/null"); |
| 504 | } else { |
| 505 | OutputFileNames[count].assign(_outF); |
| 506 | } |
| 507 | } |
| 508 | |
| 509 | if(Verbose) { |
| 510 | for (count = 0; count < FileCount; count++) { |
| 511 | cout << "Input: " << InputFileNames[count] << endl; |
| 512 | } |
| 513 | |
| 514 | if(CPU != NULL) |
| 515 | cout << "Use CPU: " << CPU->Name << endl; |
| 516 | cout << "Use triple string: " << TripleString << endl; |
| 517 | cout << "Expected architecture: " << TargetArchTable[ExpectedArch].Name << endl; |
| 518 | |
| 519 | cout << "Enable target feature: " << endl; |
| 520 | for(int i=0;FeatureEnabledList[i]!=NULL;i++) |
| 521 | if(*FeatureEnabledList[i] == '+') |
| 522 | cout << "\t" << &FeatureEnabledList[i][1] << endl; |
| 523 | cout << endl; |
| 524 | |
| 525 | cout << "Disable target feature: " << endl; |
| 526 | for(int i=0;FeatureEnabledList[i]!=NULL;i++) |
| 527 | if(*FeatureEnabledList[i] == '-') |
| 528 | cout << "\t" << &FeatureEnabledList[i][1] << endl; |
| 529 | cout << endl; |
| 530 | |
| 531 | cout << "Output to: " << ((strcmp(OutputPathName, "-")) ? OutputPathName : "(standard output)") << ", type: "; |
| 532 | switch(OutputFileType) { |
| 533 | case SlangCompilerOutput_Assembly: cout << "Target Assembly"; break; |
| 534 | case SlangCompilerOutput_LL: cout << "LLVM Assembly"; break; |
| 535 | case SlangCompilerOutput_Bitcode: cout << "Bitcode"; break; |
| 536 | case SlangCompilerOutput_Nothing: cout << "No output (test)"; break; |
| 537 | case SlangCompilerOutput_Obj: cout << "Object file"; break; |
| 538 | default: assert(false && "Unknown output type"); break; |
| 539 | } |
| 540 | cout << endl; |
| 541 | } |
| 542 | |
| 543 | return true; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 544 | } |
| 545 | |
| 546 | static void DestroyCommandOptions() { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 547 | if(SlangOpts != NULL) { |
| 548 | delete [] SlangOpts; |
| 549 | SlangOpts = NULL; |
| 550 | } |
| 551 | return; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 552 | } |
| 553 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 554 | /* |
| 555 | * E.g., replace out/host/linux-x86/bin/slang to out/host/linux-x86/bin/<fileName> |
| 556 | */ |
Shih-wei Liao | a7af2d7 | 2010-08-24 18:43:46 -0700 | [diff] [blame] | 557 | static std::string replaceLastPartWithFile(std::string& cmd, const char* fileName) { |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 558 | size_t pos = cmd.rfind('/'); |
| 559 | if (pos == std::string::npos) { |
Shih-wei Liao | a7af2d7 | 2010-08-24 18:43:46 -0700 | [diff] [blame] | 560 | return std::string(fileName); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 561 | } |
| 562 | |
| 563 | cmd.resize(pos+1); |
| 564 | cmd.append(fileName); |
Shih-wei Liao | f8149d9 | 2010-08-22 05:32:02 -0700 | [diff] [blame] | 565 | return cmd; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 566 | // std::string returnFile = cmd.substr(0, pos+1).append(fileName); // cmd.replace(pos+1, std::string::npos, fileName); |
| 567 | } |
| 568 | |
Ying Wang | 01d8601 | 2010-09-07 18:14:46 -0700 | [diff] [blame] | 569 | #define LINK_FILE "/frameworks/compile/slang/rsScriptC_Lib.bc" |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 570 | |
| 571 | static char* linkFile() { |
| 572 | char* dir = getenv("ANDROID_BUILD_TOP"); |
| 573 | char* dirPath; |
| 574 | bool readyToLink = false; |
| 575 | if (dir) { |
Shih-wei Liao | e14a2ea | 2010-09-20 09:41:51 -0700 | [diff] [blame] | 576 | dirPath = new char[strlen(dir) + strlen(LINK_FILE) + 1]; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 577 | strcpy(dirPath, dir); |
| 578 | strcpy(dirPath + strlen(dir), LINK_FILE); |
| 579 | if (open(dirPath, O_RDONLY) >= 0) { |
| 580 | readyToLink = true; |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | if (!readyToLink) { |
| 585 | /* try cwd */ |
| 586 | int siz = 256; |
| 587 | dir = new char[siz]; |
| 588 | while (!getcwd(dir, siz)) { |
| 589 | siz *= 2; |
| 590 | dir = new char[siz]; |
| 591 | } |
Shih-wei Liao | e14a2ea | 2010-09-20 09:41:51 -0700 | [diff] [blame] | 592 | dirPath = new char[strlen(dir) + strlen(LINK_FILE) + 1]; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 593 | strcpy(dirPath, dir); |
| 594 | strcpy(dirPath + strlen(dir), LINK_FILE); |
Shih-wei Liao | e14a2ea | 2010-09-20 09:41:51 -0700 | [diff] [blame] | 595 | //dirPath[strlen(dir) + LINK_FILE_LENGTH] = '\0'; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 596 | if (open(dirPath, O_RDONLY) < 0) { |
| 597 | cerr << "Error: Couldn't load rs library bitcode file" << endl; |
| 598 | exit(1); |
| 599 | } |
| 600 | } |
| 601 | return dirPath; |
| 602 | } |
| 603 | |
Ying Wang | 01d8601 | 2010-09-07 18:14:46 -0700 | [diff] [blame] | 604 | #define LINK_FILE1 "/frameworks/compile/slang/rslib.bc" |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 605 | #define LINK_FILE1_LENGTH 30 |
| 606 | |
| 607 | static char* linkFile1() { |
| 608 | char* dir = getenv("ANDROID_BUILD_TOP"); |
| 609 | char* dirPath; |
| 610 | bool readyToLink = false; |
| 611 | if (dir) { |
| 612 | dirPath = new char[strlen(dir) + LINK_FILE1_LENGTH]; |
| 613 | strcpy(dirPath, dir); |
| 614 | strcpy(dirPath + strlen(dir), LINK_FILE1); |
| 615 | if (open(dirPath, O_RDONLY) >= 0) { |
| 616 | readyToLink = true; |
| 617 | } |
| 618 | } |
| 619 | |
| 620 | if (!readyToLink) { |
| 621 | /* try cwd */ |
| 622 | int siz = 256; |
| 623 | dir = new char[siz]; |
| 624 | while (!getcwd(dir, siz)) { |
| 625 | siz *= 2; |
| 626 | dir = new char[siz]; |
| 627 | } |
| 628 | dirPath = new char[strlen(dir) + LINK_FILE1_LENGTH]; |
| 629 | strcpy(dirPath, dir); |
| 630 | strcpy(dirPath + strlen(dir), LINK_FILE1); |
| 631 | if (open(dirPath, O_RDONLY) < 0) { |
| 632 | cerr << "Error: Couldn't load rs library bitcode file" << endl; |
| 633 | exit(1); |
| 634 | } |
| 635 | } |
| 636 | return dirPath; |
| 637 | } |
| 638 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 639 | static int waitForChild(pid_t pid) { |
| 640 | pid_t w; |
| 641 | int childExitStatus; |
| 642 | |
| 643 | do { |
| 644 | w = waitpid(pid, &childExitStatus, WUNTRACED | WCONTINUED); |
| 645 | if (w == -1) { |
| 646 | exit(1); |
| 647 | } |
| 648 | if (WIFEXITED(childExitStatus)) { |
| 649 | if (WEXITSTATUS(childExitStatus)) { |
| 650 | cerr << "Linking error" << endl; |
| 651 | exit(1); |
| 652 | } |
| 653 | return 0; |
| 654 | } else if (WIFSIGNALED(childExitStatus)) { |
| 655 | cerr << "Linking: Killed by signal " << WTERMSIG(childExitStatus) << endl; |
| 656 | exit(1); |
| 657 | } else if (WIFSTOPPED(childExitStatus)) { |
| 658 | cerr << "Linking: Stopped by signal " << WSTOPSIG(childExitStatus) << endl; |
| 659 | } else if (WIFCONTINUED(childExitStatus)) { |
| 660 | cerr << "LInking: Continued" << endl; |
| 661 | } |
| 662 | } while (!WIFEXITED(childExitStatus) && !WIFSIGNALED(childExitStatus)); |
| 663 | return 0; |
| 664 | } |
| 665 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 666 | #define SLANG_CALL_AND_CHECK(expr) \ |
| 667 | if(!(expr)) { \ |
| 668 | if(slangGetInfoLog(slang)) \ |
| 669 | cerr << slangGetInfoLog(slang); \ |
| 670 | ret = 1; \ |
| 671 | goto on_slang_error; \ |
| 672 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 673 | |
| 674 | int main(int argc, char** argv) { |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 675 | int ret = 0; |
| 676 | int count; |
Shih-wei Liao | a7af2d7 | 2010-08-24 18:43:46 -0700 | [diff] [blame] | 677 | |
| 678 | std::string command(argv[0]); |
| 679 | // char* command = new char[strlen(argv[0])+16]; strcpy(command, argv[0]); |
Shih-wei Liao | c552b7c | 2010-06-25 11:06:57 -0700 | [diff] [blame] | 680 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 681 | if(argc < 2) { |
| 682 | cerr << argv[0] << ": "ERR_NO_INPUT_FILE << endl; |
| 683 | return 1; |
| 684 | } |
| 685 | |
| 686 | ConstructCommandOptions(); |
| 687 | |
| 688 | if(ParseOption(argc, argv)) { |
| 689 | SlangCompiler* slang = slangCreateCompiler(TripleString, CPUString, FeatureEnabledList); |
| 690 | if(slang == NULL) { |
| 691 | goto on_slang_error; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 692 | } |
| 693 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 694 | slangSetOutputType(slang, OutputFileType); |
| 695 | |
Ying Wang | b003707 | 2010-09-08 15:06:34 -0700 | [diff] [blame] | 696 | for (size_t i = 0; i < IncludePaths.size(); ++i) { |
Ying Wang | e2e522f | 2010-09-01 13:24:01 -0700 | [diff] [blame] | 697 | slangAddIncludePath(slang, IncludePaths[i].c_str()); |
| 698 | } |
| 699 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 700 | if (AllowRSPrefix) |
Shih-wei Liao | 9ef2f78 | 2010-10-01 12:31:37 -0700 | [diff] [blame] | 701 | slangAllowRSPrefix(slang); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 702 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 703 | for (count = 0; count < FileCount; count++) { |
| 704 | /* Start compilation */ |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 705 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 706 | SLANG_CALL_AND_CHECK( slangSetSourceFromFile(slang, InputFileNames[count].c_str()) ); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 707 | |
Shih-wei Liao | 917c3c4 | 2010-08-24 03:38:08 -0700 | [diff] [blame] | 708 | std::string beforeLink; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 709 | if (NoLink) { |
| 710 | SLANG_CALL_AND_CHECK( slangSetOutputToFile(slang, OutputFileNames[count].c_str()) ); |
| 711 | } else { |
Ying Wang | b003707 | 2010-09-08 15:06:34 -0700 | [diff] [blame] | 712 | std::string stem = slang::RSSlangReflectUtils::BCFileNameFromRSFileName( |
| 713 | InputFileNames[count].c_str()); |
| 714 | char tmpFileName[256]; |
| 715 | snprintf(tmpFileName, sizeof(tmpFileName), "/tmp/%s.bc.XXXXXX", stem.c_str()); |
| 716 | int f = mkstemp(tmpFileName); |
| 717 | if (f < 0) { |
| 718 | cerr << "Error: could not create temporary file " << tmpFileName << endl; |
| 719 | return 1; |
| 720 | } |
| 721 | // we don't need the file descriptor |
| 722 | close(f); |
Shih-wei Liao | 917c3c4 | 2010-08-24 03:38:08 -0700 | [diff] [blame] | 723 | |
Ying Wang | b003707 | 2010-09-08 15:06:34 -0700 | [diff] [blame] | 724 | beforeLink.assign(tmpFileName); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 725 | SLANG_CALL_AND_CHECK( slangSetOutputToFile(slang, beforeLink.c_str()) ); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 726 | } |
| 727 | |
| 728 | SLANG_CALL_AND_CHECK( slangCompile(slang) <= 0 ); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 729 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 730 | /* Output log anyway */ |
| 731 | if(slangGetInfoLog(slang)) { |
| 732 | cout << slangGetInfoLog(slang); |
| 733 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 734 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 735 | SLANG_CALL_AND_CHECK( slangReflectToJavaPath(slang, JavaReflectionPathName) ); |
Shih-wei Liao | 6de8927 | 2010-07-15 15:26:20 -0700 | [diff] [blame] | 736 | |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 737 | char realPackageName[0x100]; |
| 738 | SLANG_CALL_AND_CHECK( slangReflectToJava(slang, JavaReflectionPackageName, |
| 739 | realPackageName, sizeof(realPackageName))); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 740 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 741 | if (NoLink) { |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 742 | goto generate_bitcode_accessor; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 743 | } |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 744 | |
Shih-wei Liao | 835a7b7 | 2010-08-06 02:29:11 -0700 | [diff] [blame] | 745 | // llvm-rs-link |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 746 | pid_t pid; |
| 747 | if ((pid = fork()) < 0) { |
Shih-wei Liao | 835a7b7 | 2010-08-06 02:29:11 -0700 | [diff] [blame] | 748 | cerr << "Failed before llvm-rs-link" << endl; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 749 | exit(1); |
| 750 | } else if (pid == 0) { |
Shih-wei Liao | a7af2d7 | 2010-08-24 18:43:46 -0700 | [diff] [blame] | 751 | std::string cmd(command); |
| 752 | cmd = replaceLastPartWithFile(cmd, "llvm-rs-link"); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 753 | |
| 754 | char* link0 = linkFile(); |
| 755 | char* link1 = linkFile1(); |
Shih-wei Liao | 9c9bbc8 | 2010-08-18 03:08:44 -0700 | [diff] [blame] | 756 | if (Externalize) { |
Shih-wei Liao | f8149d9 | 2010-08-22 05:32:02 -0700 | [diff] [blame] | 757 | char* cmdline[] = { (char*)cmd.c_str(), "-e", "-o", (char*)OutputFileNames[count].c_str(), (char*)beforeLink.c_str(), (char*)link0, /*link1,*/ NULL }; |
| 758 | execvp(cmd.c_str(), cmdline); |
Shih-wei Liao | 9c9bbc8 | 2010-08-18 03:08:44 -0700 | [diff] [blame] | 759 | } else { |
Shih-wei Liao | f8149d9 | 2010-08-22 05:32:02 -0700 | [diff] [blame] | 760 | //cerr << cmd << " -o " << OutputFileNames[count] << " " << beforeLink << " " << link0 << endl; |
| 761 | char* cmdline[] = { (char*)cmd.c_str(), "-o", (char*)OutputFileNames[count].c_str(), (char*)beforeLink.c_str(), (char*)link0, /*link1,*/ NULL }; |
| 762 | execvp(cmd.c_str(), cmdline); |
Shih-wei Liao | 9c9bbc8 | 2010-08-18 03:08:44 -0700 | [diff] [blame] | 763 | } |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 764 | } |
| 765 | |
| 766 | waitForChild(pid); |
| 767 | |
| 768 | /* // opt |
| 769 | if ((pid = fork()) < 0) { |
| 770 | cerr << "Failed before opt" << endl; |
| 771 | exit(1); |
| 772 | } else if (pid == 0) { |
| 773 | std::string cmd(command); |
| 774 | replaceLastPartWithFile(cmd, "opt"); |
| 775 | |
| 776 | const char* funcNames = slangExportFuncs(slang); |
| 777 | std::string internalize("-internalize-public-api-list=init,root"); |
| 778 | if (funcNames) { |
| 779 | internalize.append(funcNames); |
| 780 | } |
| 781 | |
| 782 | //cerr << cmd << " -std-link-opts " << internalize << " " << afterLink << " -o " << OutputFileNames[count] << endl; |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 783 | execl(cmd.c_str(), cmd.c_str(), "-std-link-opts", internalize.c_str(), afterLink.c_str(), "-o", OutputFileNames[count].c_str(), NULL); |
| 784 | } |
| 785 | |
| 786 | waitForChild(pid); */ |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 787 | |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 788 | generate_bitcode_accessor: |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 789 | if ((OutputFileType == SlangCompilerOutput_Bitcode) |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 790 | && (BitCodeStorage == slang::BCST_JAVA_CODE) |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 791 | && (OutputFileNames[count] != "stdout")) { |
Ying Wang | 0877f05 | 2010-09-09 17:19:33 -0700 | [diff] [blame] | 792 | slang::RSSlangReflectUtils::BitCodeAccessorContext bc_context; |
| 793 | bc_context.rsFileName = InputFileNames[count].c_str(); |
| 794 | bc_context.bcFileName = OutputFileNames[count].c_str(); |
| 795 | bc_context.reflectPath = JavaReflectionPathName ? JavaReflectionPathName : ""; |
| 796 | bc_context.packageName = realPackageName; |
| 797 | bc_context.bcStorage = BitCodeStorage; |
| 798 | if (!slang::RSSlangReflectUtils::GenerateBitCodeAccessor( |
| 799 | bc_context)) { |
| 800 | ret = 1; |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 801 | } |
| 802 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 803 | } |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 804 | on_slang_error: |
| 805 | delete slang; |
| 806 | } |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 807 | |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 808 | DestroyCommandOptions(); |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 809 | |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 810 | if (ret) exit(1); |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 811 | return ret; |
Shih-wei Liao | 462aefd | 2010-06-04 15:32:04 -0700 | [diff] [blame] | 812 | } |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 813 | |
| 814 | /* |
| 815 | * OUTPUT_OPTION is only used inside Usage() |
| 816 | */ |
| 817 | #define OUTPUT_OPTION(short_name, long_name, desc) \ |
| 818 | do { \ |
| 819 | if(short_name) \ |
| 820 | cout << setw(4) << right << (short_name) << ", "; \ |
| 821 | else \ |
| 822 | cout << " "; \ |
| 823 | cout << setw(17) << left << (long_name); \ |
| 824 | cout << " " << (desc) << endl; \ |
| 825 | } while(false) |
| 826 | |
| 827 | static void Usage(const char* CommandName) { |
| 828 | cout << "Usage: " << CommandName << " [OPTION]... " << "[INPUT FILE]" << endl; |
| 829 | |
| 830 | cout << endl; |
| 831 | |
| 832 | cout << "Basic: " << endl; |
| 833 | |
| 834 | OUTPUT_OPTION("-h", "--help", "Print this help"); |
| 835 | OUTPUT_OPTION("-v", "--verbose", "Be verbose"); |
| 836 | OUTPUT_OPTION(NULL, "--allow-rs-prefix", "Allow user-defined function names with the \"rs\" prefix"); |
Shih-wei Liao | 4c9f742 | 2010-08-05 04:30:02 -0700 | [diff] [blame] | 837 | OUTPUT_OPTION(NULL, "--no-link", "Do not link the system bitcode libraries"); |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 838 | OUTPUT_OPTION("-o", "--output-obj-path=<PATH>", "Write compilation output at this path ('-' means stdout)"); |
| 839 | OUTPUT_OPTION("-j", "--output-java-reflection-class=<PACKAGE NAME>", "Output reflection of exportables in the native domain into Java"); |
| 840 | OUTPUT_OPTION("-p", "--output-java-reflection-path=<PATH>", "Write reflection output at this path"); |
Ying Wang | 3f8b44d | 2010-09-04 01:17:01 -0700 | [diff] [blame] | 841 | OUTPUT_OPTION("-I", "--include-path=<PATH>", "Add a hearder search path"); |
| 842 | OUTPUT_OPTION("-s", "--bitcode-storage=<VALUE>", "Where to store the bc file. 'ar' means apk resource, 'jc' means Java code."); |
Shih-wei Liao | f83d3c3 | 2010-07-30 22:22:49 -0700 | [diff] [blame] | 843 | |
| 844 | cout << endl; |
| 845 | |
| 846 | cout << "Output type:" << endl; |
| 847 | |
| 848 | OUTPUT_OPTION(NULL, "--emit-llvm", "Set output type to LLVM assembly (.ll)"); |
| 849 | OUTPUT_OPTION(NULL, "--emit-bc", "Set output type to Bitcode (.bc) (Default)"); |
| 850 | OUTPUT_OPTION("-S", "--emit-asm", "Set output type to target assmbly code (.S)"); |
| 851 | OUTPUT_OPTION("-c", "--emit-obj", "Set output type to target object file (.o)"); |
| 852 | OUTPUT_OPTION(NULL, "--emit-nothing", "Output nothing"); |
| 853 | |
| 854 | cout << endl; |
| 855 | |
| 856 | cout << "Code generation option: " << endl; |
| 857 | |
| 858 | OUTPUT_OPTION("-u", "--cpu=CPU", "generate the assembly / object file for the CPU"); |
| 859 | cout << endl; |
| 860 | cout << "\tAvailable CPU:" << endl; |
| 861 | |
| 862 | for (unsigned i = 0; i < NUM_TARGET_CPU; i++) |
| 863 | cout << "\t" << setw(13) << right << TargetCPUTable[i].Name << left << ": (" << TargetArchTable[(TargetCPUTable[i].Arch)].Name << ") " << TargetCPUTable[i].Desc << endl; |
| 864 | |
| 865 | cout << endl; |
| 866 | |
| 867 | OUTPUT_OPTION("-t", "--triple=TRIPLE", "generate the assembly / object file for the Triple"); |
| 868 | cout << "\tDefault triple: " << endl; |
| 869 | #define DEF_SUPPORT_TARGET(target, name, default_triple) \ |
| 870 | cout << "\t" << setw(5) << right << name << left << ": " << default_triple << endl; |
| 871 | #include "target.inc" |
| 872 | cout << endl; |
| 873 | |
| 874 | OUTPUT_OPTION(NULL, "--enable-FEATURE", "enable the FEATURE for the generation of the assembly / object file"); |
| 875 | OUTPUT_OPTION(NULL, "--disable-FEATURE", "disable the FEATURE for the generation of the assembly / object file"); |
| 876 | cout << endl; |
| 877 | cout << "\tAvailable features:" << endl; |
| 878 | #define DEF_TARGET_FEATURE(target, id, key, description) \ |
| 879 | cout << "\t" << setw(6) << right << key \ |
| 880 | << left << ": (" << TargetArchTable[MK_TARGET_ARCH(target)].Name << ") " \ |
| 881 | << description << endl; |
| 882 | #include "target.inc" |
| 883 | |
| 884 | cout << endl; |
| 885 | |
| 886 | return; |
| 887 | } |
| 888 | |
| 889 | #undef OUTPUT_OPTION |