Print this page
new smatch
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/sparse-llvm.c
+++ new/usr/src/tools/smatch/src/sparse-llvm.c
1 1 /*
2 2 * Example usage:
3 3 * ./sparse-llvm hello.c | llc | as -o hello.o
4 4 */
5 5
6 6 #include <llvm-c/Core.h>
7 7 #include <llvm-c/BitWriter.h>
8 8 #include <llvm-c/Analysis.h>
9 9 #include <llvm-c/Target.h>
10 10
11 11 #include <stdbool.h>
12 12 #include <stdio.h>
13 13 #include <unistd.h>
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 #include <string.h>
15 15 #include <assert.h>
16 16
17 17 #include "symbol.h"
18 18 #include "expression.h"
19 19 #include "linearize.h"
20 20 #include "flow.h"
21 21
22 22 struct function {
23 23 LLVMBuilderRef builder;
24 - LLVMTypeRef type;
25 24 LLVMValueRef fn;
26 25 LLVMModuleRef module;
27 26 };
28 27
29 -static inline bool symbol_is_fp_type(struct symbol *sym)
30 -{
31 - if (!sym)
32 - return false;
28 +static LLVMTypeRef symbol_type(struct symbol *sym);
33 29
34 - return sym->ctype.base_type == &fp_type;
35 -}
36 -
37 -static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym);
38 -
39 -static LLVMTypeRef func_return_type(LLVMModuleRef module, struct symbol *sym)
30 +static LLVMTypeRef func_return_type(struct symbol *sym)
40 31 {
41 - return symbol_type(module, sym->ctype.base_type);
32 + return symbol_type(sym->ctype.base_type);
42 33 }
43 34
44 -static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
35 +static LLVMTypeRef sym_func_type(struct symbol *sym)
45 36 {
46 - LLVMTypeRef *arg_type;
47 - LLVMTypeRef func_type;
48 - LLVMTypeRef ret_type;
37 + int n_arg = symbol_list_size(sym->arguments);
38 + LLVMTypeRef *arg_type = calloc(n_arg, sizeof(LLVMTypeRef));
39 + LLVMTypeRef ret_type = func_return_type(sym);
49 40 struct symbol *arg;
50 - int n_arg = 0;
41 + int idx = 0;
51 42
52 - /* to avoid strangeness with varargs [for now], we build
53 - * the function and type anew, for each call. This
54 - * is probably wrong. We should look up the
55 - * symbol declaration info.
56 - */
57 -
58 - ret_type = func_return_type(module, sym);
59 -
60 - /* count args, build argument type information */
61 43 FOR_EACH_PTR(sym->arguments, arg) {
62 - n_arg++;
63 - } END_FOR_EACH_PTR(arg);
64 -
65 - arg_type = calloc(n_arg, sizeof(LLVMTypeRef));
66 -
67 - int idx = 0;
68 - FOR_EACH_PTR(sym->arguments, arg) {
69 44 struct symbol *arg_sym = arg->ctype.base_type;
70 45
71 - arg_type[idx++] = symbol_type(module, arg_sym);
46 + arg_type[idx++] = symbol_type(arg_sym);
72 47 } END_FOR_EACH_PTR(arg);
73 - func_type = LLVMFunctionType(ret_type, arg_type, n_arg,
74 - sym->variadic);
75 48
76 - return func_type;
49 + return LLVMFunctionType(ret_type, arg_type, n_arg, sym->variadic);
77 50 }
78 51
79 -static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
52 +static LLVMTypeRef sym_array_type(struct symbol *sym)
80 53 {
81 54 LLVMTypeRef elem_type;
82 55 struct symbol *base_type;
83 56
84 57 base_type = sym->ctype.base_type;
85 58 /* empty struct is undefined [6.7.2.1(8)] */
86 59 assert(base_type->bit_size > 0);
87 60
88 - elem_type = symbol_type(module, base_type);
61 + elem_type = symbol_type(base_type);
89 62 if (!elem_type)
90 63 return NULL;
91 64
92 65 return LLVMArrayType(elem_type, sym->bit_size / base_type->bit_size);
93 66 }
94 67
95 68 #define MAX_STRUCT_MEMBERS 64
96 69
97 -static LLVMTypeRef sym_struct_type(LLVMModuleRef module, struct symbol *sym)
70 +static LLVMTypeRef sym_struct_type(struct symbol *sym)
98 71 {
99 72 LLVMTypeRef elem_types[MAX_STRUCT_MEMBERS];
100 73 struct symbol *member;
101 74 char buffer[256];
102 75 LLVMTypeRef ret;
103 76 unsigned nr = 0;
104 77
105 78 snprintf(buffer, sizeof(buffer), "struct.%s", sym->ident ? sym->ident->name : "anno");
106 79 ret = LLVMStructCreateNamed(LLVMGetGlobalContext(), buffer);
107 80 /* set ->aux to avoid recursion */
108 81 sym->aux = ret;
109 82
110 83 FOR_EACH_PTR(sym->symbol_list, member) {
111 84 LLVMTypeRef member_type;
112 85
113 86 assert(nr < MAX_STRUCT_MEMBERS);
114 87
115 - member_type = symbol_type(module, member);
88 + member_type = symbol_type(member);
116 89
117 90 elem_types[nr++] = member_type;
118 91 } END_FOR_EACH_PTR(member);
119 92
120 93 LLVMStructSetBody(ret, elem_types, nr, 0 /* packed? */);
121 94 return ret;
122 95 }
123 96
124 -static LLVMTypeRef sym_union_type(LLVMModuleRef module, struct symbol *sym)
97 +static LLVMTypeRef sym_union_type(struct symbol *sym)
125 98 {
126 99 LLVMTypeRef elements;
127 100 unsigned union_size;
128 101
129 102 /*
130 103 * There's no union support in the LLVM API so we treat unions as
131 104 * opaque structs. The downside is that we lose type information on the
132 105 * members but as LLVM doesn't care, neither do we.
133 106 */
134 107 union_size = sym->bit_size / 8;
135 108
136 109 elements = LLVMArrayType(LLVMInt8Type(), union_size);
137 110
138 111 return LLVMStructType(&elements, 1, 0 /* packed? */);
139 112 }
140 113
141 -static LLVMTypeRef sym_ptr_type(LLVMModuleRef module, struct symbol *sym)
114 +static LLVMTypeRef sym_ptr_type(struct symbol *sym)
142 115 {
143 116 LLVMTypeRef type;
144 117
145 118 /* 'void *' is treated like 'char *' */
146 119 if (is_void_type(sym->ctype.base_type))
147 120 type = LLVMInt8Type();
148 121 else
149 - type = symbol_type(module, sym->ctype.base_type);
122 + type = symbol_type(sym->ctype.base_type);
150 123
151 124 return LLVMPointerType(type, 0);
152 125 }
153 126
154 127 static LLVMTypeRef sym_basetype_type(struct symbol *sym)
155 128 {
156 129 LLVMTypeRef ret = NULL;
157 130
158 - if (symbol_is_fp_type(sym)) {
131 + if (is_float_type(sym)) {
159 132 switch (sym->bit_size) {
160 133 case 32:
161 134 ret = LLVMFloatType();
162 135 break;
163 136 case 64:
164 137 ret = LLVMDoubleType();
165 138 break;
166 139 case 80:
167 140 ret = LLVMX86FP80Type();
168 141 break;
169 142 default:
170 143 die("invalid bit size %d for type %d", sym->bit_size, sym->type);
171 144 break;
172 145 }
173 146 } else {
174 147 switch (sym->bit_size) {
175 148 case -1:
176 149 ret = LLVMVoidType();
177 150 break;
178 151 case 1:
179 152 ret = LLVMInt1Type();
180 153 break;
181 154 case 8:
182 155 ret = LLVMInt8Type();
183 156 break;
184 157 case 16:
185 158 ret = LLVMInt16Type();
186 159 break;
187 160 case 32:
188 161 ret = LLVMInt32Type();
189 162 break;
190 163 case 64:
191 164 ret = LLVMInt64Type();
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
192 165 break;
193 166 default:
194 167 die("invalid bit size %d for type %d", sym->bit_size, sym->type);
195 168 break;
196 169 }
197 170 }
198 171
199 172 return ret;
200 173 }
201 174
202 -static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
175 +static LLVMTypeRef symbol_type(struct symbol *sym)
203 176 {
204 177 LLVMTypeRef ret = NULL;
205 178
206 179 /* don't cache the result for SYM_NODE */
207 180 if (sym->type == SYM_NODE)
208 - return symbol_type(module, sym->ctype.base_type);
181 + return symbol_type(sym->ctype.base_type);
209 182
210 183 if (sym->aux)
211 184 return sym->aux;
212 185
213 186 switch (sym->type) {
214 187 case SYM_BITFIELD:
188 + ret = LLVMIntType(sym->bit_size);
189 + break;
190 + case SYM_RESTRICT:
215 191 case SYM_ENUM:
216 - ret = symbol_type(module, sym->ctype.base_type);
192 + ret = symbol_type(sym->ctype.base_type);
217 193 break;
218 194 case SYM_BASETYPE:
219 195 ret = sym_basetype_type(sym);
220 196 break;
221 197 case SYM_PTR:
222 - ret = sym_ptr_type(module, sym);
198 + ret = sym_ptr_type(sym);
223 199 break;
224 200 case SYM_UNION:
225 - ret = sym_union_type(module, sym);
201 + ret = sym_union_type(sym);
226 202 break;
227 203 case SYM_STRUCT:
228 - ret = sym_struct_type(module, sym);
204 + ret = sym_struct_type(sym);
229 205 break;
230 206 case SYM_ARRAY:
231 - ret = sym_array_type(module, sym);
207 + ret = sym_array_type(sym);
232 208 break;
233 209 case SYM_FN:
234 - ret = sym_func_type(module, sym);
210 + ret = sym_func_type(sym);
235 211 break;
236 212 default:
237 213 assert(0);
238 214 }
239 215
240 216 /* cache the result */
241 217 sym->aux = ret;
242 218 return ret;
243 219 }
244 220
245 -static LLVMTypeRef int_type_by_size(int size)
221 +static LLVMTypeRef insn_symbol_type(struct instruction *insn)
246 222 {
247 - switch (size) {
248 - case 1: return LLVMInt1Type();
223 + if (insn->type)
224 + return symbol_type(insn->type);
225 +
226 + switch (insn->size) {
249 227 case 8: return LLVMInt8Type();
250 228 case 16: return LLVMInt16Type();
251 229 case 32: return LLVMInt32Type();
252 230 case 64: return LLVMInt64Type();
253 231
254 232 default:
255 - die("invalid bit size %d", size);
233 + die("invalid bit size %d", insn->size);
256 234 break;
257 235 }
236 +
258 237 return NULL; /* not reached */
259 238 }
260 239
261 -static LLVMTypeRef insn_symbol_type(LLVMModuleRef module, struct instruction *insn)
262 -{
263 - if (insn->type)
264 - return symbol_type(module, insn->type);
265 -
266 - return int_type_by_size(insn->size);
267 -}
268 -
269 240 static LLVMLinkage data_linkage(struct symbol *sym)
270 241 {
271 242 if (sym->ctype.modifiers & MOD_STATIC)
272 243 return LLVMPrivateLinkage;
273 244
274 245 return LLVMExternalLinkage;
275 246 }
276 247
277 248 static LLVMLinkage function_linkage(struct symbol *sym)
278 249 {
279 250 if (sym->ctype.modifiers & MOD_STATIC)
280 251 return LLVMInternalLinkage;
281 252
282 253 return LLVMExternalLinkage;
283 254 }
284 255
285 256 #define MAX_PSEUDO_NAME 64
286 257
287 -static void pseudo_name(pseudo_t pseudo, char *buf)
258 +static const char *pseudo_name(pseudo_t pseudo, char *buf)
288 259 {
289 260 switch (pseudo->type) {
290 261 case PSEUDO_REG:
291 - snprintf(buf, MAX_PSEUDO_NAME, "R%d", pseudo->nr);
262 + snprintf(buf, MAX_PSEUDO_NAME, "R%d.", pseudo->nr);
292 263 break;
293 - case PSEUDO_SYM:
294 - assert(0);
264 + case PSEUDO_PHI:
265 + snprintf(buf, MAX_PSEUDO_NAME, "PHI%d.", pseudo->nr);
295 266 break;
267 + case PSEUDO_SYM:
296 268 case PSEUDO_VAL:
297 - assert(0);
269 + case PSEUDO_ARG:
270 + case PSEUDO_VOID:
271 + buf[0] = '\0';
298 272 break;
299 - case PSEUDO_ARG: {
273 + case PSEUDO_UNDEF:
300 274 assert(0);
301 275 break;
302 - }
303 - case PSEUDO_PHI:
304 - snprintf(buf, MAX_PSEUDO_NAME, "PHI%d", pseudo->nr);
305 - break;
306 276 default:
307 277 assert(0);
308 278 }
279 +
280 + return buf;
309 281 }
310 282
311 -static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *insn, pseudo_t pseudo)
283 +static LLVMValueRef get_sym_value(LLVMModuleRef module, struct symbol *sym)
312 284 {
285 + const char *name = show_ident(sym->ident);
286 + LLVMTypeRef type = symbol_type(sym);
313 287 LLVMValueRef result = NULL;
288 + struct expression *expr;
314 289
315 - switch (pseudo->type) {
316 - case PSEUDO_REG:
317 - result = pseudo->priv;
318 - break;
319 - case PSEUDO_SYM: {
320 - struct symbol *sym = pseudo->sym;
321 - struct expression *expr;
290 + assert(sym->bb_target == NULL);
322 291
323 - assert(sym->bb_target == NULL);
292 + expr = sym->initializer;
293 + if (expr && !sym->ident) {
294 + switch (expr->type) {
295 + case EXPR_STRING: {
296 + const char *s = expr->string->data;
297 + LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
298 + LLVMValueRef data;
324 299
325 - expr = sym->initializer;
326 - if (expr) {
327 - switch (expr->type) {
328 - case EXPR_STRING: {
329 - const char *s = expr->string->data;
330 - LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) };
331 - LLVMValueRef data;
300 + data = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str");
301 + LLVMSetLinkage(data, LLVMPrivateLinkage);
302 + LLVMSetGlobalConstant(data, 1);
303 + LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
332 304
333 - data = LLVMAddGlobal(fn->module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str");
334 - LLVMSetLinkage(data, LLVMPrivateLinkage);
335 - LLVMSetGlobalConstant(data, 1);
336 - LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true));
305 + result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
306 + return result;
307 + }
308 + default:
309 + break;
310 + }
311 + }
337 312
338 - result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices));
339 - break;
340 - }
341 - case EXPR_SYMBOL: {
342 - struct symbol *sym = expr->symbol;
313 + if (LLVMGetTypeKind(type) == LLVMFunctionTypeKind) {
314 + result = LLVMGetNamedFunction(module, name);
315 + if (!result)
316 + result = LLVMAddFunction(module, name, type);
317 + } else {
318 + result = LLVMGetNamedGlobal(module, name);
319 + if (!result)
320 + result = LLVMAddGlobal(module, type, name);
321 + }
343 322
344 - result = LLVMGetNamedGlobal(fn->module, show_ident(sym->ident));
345 - assert(result != NULL);
346 - break;
347 - }
348 - default:
349 - assert(0);
350 - }
351 - } else {
352 - const char *name = show_ident(sym->ident);
353 - LLVMTypeRef type = symbol_type(fn->module, sym);
323 + return result;
324 +}
354 325
355 - if (LLVMGetTypeKind(type) == LLVMFunctionTypeKind) {
356 - result = LLVMGetNamedFunction(fn->module, name);
357 - if (!result)
358 - result = LLVMAddFunction(fn->module, name, type);
359 - } else {
360 - result = LLVMGetNamedGlobal(fn->module, name);
361 - if (!result)
362 - result = LLVMAddGlobal(fn->module, type, name);
363 - }
326 +static LLVMValueRef constant_value(unsigned long long val, LLVMTypeRef dtype)
327 +{
328 + LLVMValueRef result;
329 +
330 + switch (LLVMGetTypeKind(dtype)) {
331 + case LLVMPointerTypeKind:
332 + if (val != 0) { // for example: ... = (void*) 0x123;
333 + LLVMTypeRef itype = LLVMIntType(bits_in_pointer);
334 + result = LLVMConstInt(itype, val, 1);
335 + result = LLVMConstIntToPtr(result, dtype);
336 + } else {
337 + result = LLVMConstPointerNull(dtype);
364 338 }
365 339 break;
340 + case LLVMIntegerTypeKind:
341 + result = LLVMConstInt(dtype, val, 1);
342 + break;
343 + case LLVMArrayTypeKind:
344 + case LLVMStructTypeKind:
345 + if (val != 0)
346 + return NULL;
347 + result = LLVMConstNull(dtype);
348 + break;
349 + default:
350 + return NULL;
366 351 }
352 + return result;
353 +}
354 +
355 +static LLVMValueRef val_to_value(unsigned long long val, struct symbol *ctype)
356 +{
357 + LLVMValueRef result;
358 + LLVMTypeRef dtype;
359 +
360 + assert(ctype);
361 + dtype = symbol_type(ctype);
362 + result = constant_value(val, dtype);
363 + if (result)
364 + return result;
365 + sparse_error(ctype->pos, "no value possible for %s", show_typename(ctype));
366 + return LLVMGetUndef(symbol_type(ctype));
367 +}
368 +
369 +static LLVMValueRef pseudo_to_value(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
370 +{
371 + LLVMValueRef result = NULL;
372 +
373 + switch (pseudo->type) {
374 + case PSEUDO_REG:
375 + result = pseudo->priv;
376 + break;
377 + case PSEUDO_SYM:
378 + result = get_sym_value(fn->module, pseudo->sym);
379 + break;
367 380 case PSEUDO_VAL:
368 - result = LLVMConstInt(int_type_by_size(pseudo->size), pseudo->value, 1);
381 + result = val_to_value(pseudo->value, ctype);
369 382 break;
370 383 case PSEUDO_ARG: {
371 384 result = LLVMGetParam(fn->fn, pseudo->nr - 1);
372 385 break;
373 386 }
374 387 case PSEUDO_PHI:
375 388 result = pseudo->priv;
376 389 break;
377 390 case PSEUDO_VOID:
378 391 result = NULL;
379 392 break;
393 + case PSEUDO_UNDEF:
394 + result = LLVMGetUndef(symbol_type(ctype));
395 + break;
380 396 default:
381 397 assert(0);
382 398 }
383 399
384 400 return result;
385 401 }
386 402
403 +static LLVMValueRef pseudo_to_rvalue(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
404 +{
405 + LLVMValueRef val = pseudo_to_value(fn, ctype, pseudo);
406 + LLVMTypeRef dtype = symbol_type(ctype);
407 + char name[MAX_PSEUDO_NAME];
408 +
409 + pseudo_name(pseudo, name);
410 + return LLVMBuildBitCast(fn->builder, val, dtype, name);
411 +}
412 +
413 +static LLVMValueRef value_to_ivalue(struct function *fn, struct symbol *ctype, LLVMValueRef val)
414 +{
415 + const char *name = LLVMGetValueName(val);
416 + LLVMTypeRef dtype = symbol_type(ctype);
417 +
418 + if (LLVMGetTypeKind(LLVMTypeOf(val)) == LLVMPointerTypeKind) {
419 + LLVMTypeRef dtype = LLVMIntType(bits_in_pointer);
420 + val = LLVMBuildPtrToInt(fn->builder, val, dtype, name);
421 + }
422 + if (ctype && is_int_type(ctype)) {
423 + val = LLVMBuildIntCast(fn->builder, val, dtype, name);
424 + }
425 + return val;
426 +}
427 +
428 +static LLVMValueRef value_to_pvalue(struct function *fn, struct symbol *ctype, LLVMValueRef val)
429 +{
430 + const char *name = LLVMGetValueName(val);
431 + LLVMTypeRef dtype = symbol_type(ctype);
432 +
433 + assert(is_ptr_type(ctype));
434 + switch (LLVMGetTypeKind(LLVMTypeOf(val))) {
435 + case LLVMIntegerTypeKind:
436 + val = LLVMBuildIntToPtr(fn->builder, val, dtype, name);
437 + break;
438 + case LLVMPointerTypeKind:
439 + val = LLVMBuildBitCast(fn->builder, val, dtype, name);
440 + break;
441 + default:
442 + break;
443 + }
444 + return val;
445 +}
446 +
447 +static LLVMValueRef adjust_type(struct function *fn, struct symbol *ctype, LLVMValueRef val)
448 +{
449 + if (is_int_type(ctype))
450 + return value_to_ivalue(fn, ctype, val);
451 + if (is_ptr_type(ctype))
452 + return value_to_pvalue(fn, ctype, val);
453 + return val;
454 +}
455 +
456 +/*
457 + * Get the LLVMValue corresponding to the pseudo
458 + * and force the type corresponding to ctype.
459 + */
460 +static LLVMValueRef get_operand(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
461 +{
462 + LLVMValueRef target = pseudo_to_value(fn, ctype, pseudo);
463 + return adjust_type(fn, ctype, target);
464 +}
465 +
466 +/*
467 + * Get the LLVMValue corresponding to the pseudo
468 + * and force the type corresponding to ctype but
469 + * map all pointers to intptr_t.
470 + */
471 +static LLVMValueRef get_ioperand(struct function *fn, struct symbol *ctype, pseudo_t pseudo)
472 +{
473 + LLVMValueRef target = pseudo_to_value(fn, ctype, pseudo);
474 + return value_to_ivalue(fn, ctype, target);
475 +}
476 +
387 477 static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValueRef off)
388 478 {
389 479 LLVMTypeRef type = LLVMTypeOf(base);
390 480 unsigned int as = LLVMGetPointerAddressSpace(type);
391 481 LLVMTypeRef bytep = LLVMPointerType(LLVMInt8Type(), as);
392 482 LLVMValueRef addr;
483 + const char *name = LLVMGetValueName(off);
393 484
394 485 /* convert base to char* type */
395 - base = LLVMBuildPointerCast(builder, base, bytep, "");
486 + base = LLVMBuildPointerCast(builder, base, bytep, name);
396 487 /* addr = base + off */
397 - addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, "");
488 + addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, name);
398 489 /* convert back to the actual pointer type */
399 - addr = LLVMBuildPointerCast(builder, addr, type, "");
490 + addr = LLVMBuildPointerCast(builder, addr, type, name);
400 491 return addr;
401 492 }
402 493
403 494 static LLVMRealPredicate translate_fop(int opcode)
404 495 {
405 496 static const LLVMRealPredicate trans_tbl[] = {
406 - [OP_SET_EQ] = LLVMRealOEQ,
407 - [OP_SET_NE] = LLVMRealUNE,
408 - [OP_SET_LE] = LLVMRealOLE,
409 - [OP_SET_GE] = LLVMRealOGE,
410 - [OP_SET_LT] = LLVMRealOLT,
411 - [OP_SET_GT] = LLVMRealOGT,
412 - /* Are these used with FP? */
413 - [OP_SET_B] = LLVMRealOLT,
414 - [OP_SET_A] = LLVMRealOGT,
415 - [OP_SET_BE] = LLVMRealOLE,
416 - [OP_SET_AE] = LLVMRealOGE,
497 + [OP_FCMP_ORD] = LLVMRealORD,
498 + [OP_FCMP_OEQ] = LLVMRealOEQ,
499 + [OP_FCMP_ONE] = LLVMRealONE,
500 + [OP_FCMP_OLE] = LLVMRealOLE,
501 + [OP_FCMP_OGE] = LLVMRealOGE,
502 + [OP_FCMP_OLT] = LLVMRealOLT,
503 + [OP_FCMP_OGT] = LLVMRealOGT,
504 + [OP_FCMP_UEQ] = LLVMRealUEQ,
505 + [OP_FCMP_UNE] = LLVMRealUNE,
506 + [OP_FCMP_ULE] = LLVMRealULE,
507 + [OP_FCMP_UGE] = LLVMRealUGE,
508 + [OP_FCMP_ULT] = LLVMRealULT,
509 + [OP_FCMP_UGT] = LLVMRealUGT,
510 + [OP_FCMP_UNO] = LLVMRealUNO,
417 511 };
418 512
419 513 return trans_tbl[opcode];
420 514 }
421 515
422 516 static LLVMIntPredicate translate_op(int opcode)
423 517 {
424 518 static const LLVMIntPredicate trans_tbl[] = {
425 519 [OP_SET_EQ] = LLVMIntEQ,
426 520 [OP_SET_NE] = LLVMIntNE,
427 521 [OP_SET_LE] = LLVMIntSLE,
428 522 [OP_SET_GE] = LLVMIntSGE,
429 523 [OP_SET_LT] = LLVMIntSLT,
430 524 [OP_SET_GT] = LLVMIntSGT,
431 525 [OP_SET_B] = LLVMIntULT,
432 526 [OP_SET_A] = LLVMIntUGT,
433 527 [OP_SET_BE] = LLVMIntULE,
434 528 [OP_SET_AE] = LLVMIntUGE,
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
435 529 };
436 530
437 531 return trans_tbl[opcode];
438 532 }
439 533
440 534 static void output_op_binary(struct function *fn, struct instruction *insn)
441 535 {
442 536 LLVMValueRef lhs, rhs, target;
443 537 char target_name[64];
444 538
445 - lhs = pseudo_to_value(fn, insn, insn->src1);
539 + lhs = get_ioperand(fn, insn->type, insn->src1);
540 + rhs = get_ioperand(fn, insn->type, insn->src2);
446 541
447 - rhs = pseudo_to_value(fn, insn, insn->src2);
448 -
449 542 pseudo_name(insn->target, target_name);
450 543
451 544 switch (insn->opcode) {
452 545 /* Binary */
453 546 case OP_ADD:
454 - if (symbol_is_fp_type(insn->type))
455 - target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
456 - else
457 - target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
547 + target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
458 548 break;
459 549 case OP_SUB:
460 - if (symbol_is_fp_type(insn->type))
461 - target = LLVMBuildFSub(fn->builder, lhs, rhs, target_name);
462 - else
463 - target = LLVMBuildSub(fn->builder, lhs, rhs, target_name);
550 + target = LLVMBuildSub(fn->builder, lhs, rhs, target_name);
464 551 break;
465 - case OP_MULU:
466 - if (symbol_is_fp_type(insn->type))
467 - target = LLVMBuildFMul(fn->builder, lhs, rhs, target_name);
468 - else
469 - target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
470 - break;
471 - case OP_MULS:
472 - assert(!symbol_is_fp_type(insn->type));
552 + case OP_MUL:
473 553 target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
474 554 break;
475 555 case OP_DIVU:
476 - if (symbol_is_fp_type(insn->type))
477 - target = LLVMBuildFDiv(fn->builder, lhs, rhs, target_name);
478 - else
479 - target = LLVMBuildUDiv(fn->builder, lhs, rhs, target_name);
556 + target = LLVMBuildUDiv(fn->builder, lhs, rhs, target_name);
480 557 break;
481 558 case OP_DIVS:
482 - assert(!symbol_is_fp_type(insn->type));
559 + assert(!is_float_type(insn->type));
483 560 target = LLVMBuildSDiv(fn->builder, lhs, rhs, target_name);
484 561 break;
485 562 case OP_MODU:
486 - assert(!symbol_is_fp_type(insn->type));
563 + assert(!is_float_type(insn->type));
487 564 target = LLVMBuildURem(fn->builder, lhs, rhs, target_name);
488 565 break;
489 566 case OP_MODS:
490 - assert(!symbol_is_fp_type(insn->type));
567 + assert(!is_float_type(insn->type));
491 568 target = LLVMBuildSRem(fn->builder, lhs, rhs, target_name);
492 569 break;
493 570 case OP_SHL:
494 - assert(!symbol_is_fp_type(insn->type));
571 + assert(!is_float_type(insn->type));
495 572 target = LLVMBuildShl(fn->builder, lhs, rhs, target_name);
496 573 break;
497 574 case OP_LSR:
498 - assert(!symbol_is_fp_type(insn->type));
575 + assert(!is_float_type(insn->type));
499 576 target = LLVMBuildLShr(fn->builder, lhs, rhs, target_name);
500 577 break;
501 578 case OP_ASR:
502 - assert(!symbol_is_fp_type(insn->type));
579 + assert(!is_float_type(insn->type));
503 580 target = LLVMBuildAShr(fn->builder, lhs, rhs, target_name);
504 581 break;
582 +
583 + /* floating-point */
584 + case OP_FADD:
585 + target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
586 + break;
587 + case OP_FSUB:
588 + target = LLVMBuildFSub(fn->builder, lhs, rhs, target_name);
589 + break;
590 + case OP_FMUL:
591 + target = LLVMBuildFMul(fn->builder, lhs, rhs, target_name);
592 + break;
593 + case OP_FDIV:
594 + target = LLVMBuildFDiv(fn->builder, lhs, rhs, target_name);
595 + break;
505 596
506 597 /* Logical */
507 598 case OP_AND:
508 - assert(!symbol_is_fp_type(insn->type));
599 + assert(!is_float_type(insn->type));
509 600 target = LLVMBuildAnd(fn->builder, lhs, rhs, target_name);
510 601 break;
511 602 case OP_OR:
512 - assert(!symbol_is_fp_type(insn->type));
603 + assert(!is_float_type(insn->type));
513 604 target = LLVMBuildOr(fn->builder, lhs, rhs, target_name);
514 605 break;
515 606 case OP_XOR:
516 - assert(!symbol_is_fp_type(insn->type));
607 + assert(!is_float_type(insn->type));
517 608 target = LLVMBuildXor(fn->builder, lhs, rhs, target_name);
518 609 break;
519 - case OP_AND_BOOL: {
520 - LLVMValueRef lhs_nz, rhs_nz;
521 - LLVMTypeRef dst_type;
522 -
523 - lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, "");
524 - rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
525 - target = LLVMBuildAnd(fn->builder, lhs_nz, rhs_nz, target_name);
526 -
527 - dst_type = insn_symbol_type(fn->module, insn);
528 - target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
529 - break;
530 - }
531 - case OP_OR_BOOL: {
532 - LLVMValueRef lhs_nz, rhs_nz;
533 - LLVMTypeRef dst_type;
534 -
535 - lhs_nz = LLVMBuildIsNotNull(fn->builder, lhs, "");
536 - rhs_nz = LLVMBuildIsNotNull(fn->builder, rhs, "");
537 - target = LLVMBuildOr(fn->builder, lhs_nz, rhs_nz, target_name);
538 -
539 - dst_type = insn_symbol_type(fn->module, insn);
540 - target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
541 - break;
542 - }
543 610 default:
544 611 assert(0);
545 612 break;
546 613 }
547 614
615 + target = adjust_type(fn, insn->type, target);
548 616 insn->target->priv = target;
549 617 }
550 618
551 619 static void output_op_compare(struct function *fn, struct instruction *insn)
552 620 {
553 621 LLVMValueRef lhs, rhs, target;
554 622 char target_name[64];
555 623
556 - lhs = pseudo_to_value(fn, insn, insn->src1);
557 -
624 + lhs = pseudo_to_value(fn, NULL, insn->src1);
558 625 if (insn->src2->type == PSEUDO_VAL)
559 - rhs = LLVMConstInt(LLVMTypeOf(lhs), insn->src2->value, 1);
626 + rhs = constant_value(insn->src2->value, LLVMTypeOf(lhs));
560 627 else
561 - rhs = pseudo_to_value(fn, insn, insn->src2);
628 + rhs = pseudo_to_value(fn, NULL, insn->src2);
629 + if (!rhs)
630 + rhs = LLVMGetUndef(symbol_type(insn->type));
562 631
563 632 pseudo_name(insn->target, target_name);
564 633
565 - LLVMTypeRef dst_type = insn_symbol_type(fn->module, insn);
634 + LLVMTypeRef dst_type = insn_symbol_type(insn);
566 635
567 - if (LLVMGetTypeKind(LLVMTypeOf(lhs)) == LLVMIntegerTypeKind) {
636 + switch (LLVMGetTypeKind(LLVMTypeOf(lhs))) {
637 + case LLVMPointerTypeKind:
638 + lhs = value_to_pvalue(fn, &ptr_ctype, lhs);
639 + rhs = value_to_pvalue(fn, &ptr_ctype, rhs);
640 + /* fall through */
641 +
642 + case LLVMIntegerTypeKind: {
568 643 LLVMIntPredicate op = translate_op(insn->opcode);
569 644
645 + if (LLVMGetTypeKind(LLVMTypeOf(rhs)) == LLVMPointerTypeKind) {
646 + LLVMTypeRef ltype = LLVMTypeOf(lhs);
647 + rhs = LLVMBuildPtrToInt(fn->builder, rhs, ltype, "");
648 + }
570 649 target = LLVMBuildICmp(fn->builder, op, lhs, rhs, target_name);
571 - } else {
650 + break;
651 + }
652 + case LLVMHalfTypeKind:
653 + case LLVMFloatTypeKind:
654 + case LLVMDoubleTypeKind:
655 + case LLVMX86_FP80TypeKind:
656 + case LLVMFP128TypeKind:
657 + case LLVMPPC_FP128TypeKind: {
572 658 LLVMRealPredicate op = translate_fop(insn->opcode);
573 659
574 660 target = LLVMBuildFCmp(fn->builder, op, lhs, rhs, target_name);
661 + break;
575 662 }
663 + default:
664 + assert(0);
665 + }
576 666
577 667 target = LLVMBuildZExt(fn->builder, target, dst_type, target_name);
578 668
579 669 insn->target->priv = target;
580 670 }
581 671
582 672 static void output_op_ret(struct function *fn, struct instruction *insn)
583 673 {
584 674 pseudo_t pseudo = insn->src;
585 675
586 676 if (pseudo && pseudo != VOID) {
587 - LLVMValueRef result = pseudo_to_value(fn, insn, pseudo);
588 -
677 + LLVMValueRef result = get_operand(fn, insn->type, pseudo);
589 678 LLVMBuildRet(fn->builder, result);
590 679 } else
591 680 LLVMBuildRetVoid(fn->builder);
592 681 }
593 682
594 683 static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *insn)
595 684 {
596 685 LLVMTypeRef int_type, addr_type;
597 686 LLVMValueRef src, off, addr;
598 687 unsigned int as;
599 688
600 689 /* int type large enough to hold a pointer */
601 690 int_type = LLVMIntType(bits_in_pointer);
602 691 off = LLVMConstInt(int_type, insn->offset, 0);
603 692
604 693 /* convert src to the effective pointer type */
605 - src = pseudo_to_value(fn, insn, insn->src);
694 + src = pseudo_to_value(fn, insn->type, insn->src);
606 695 as = LLVMGetPointerAddressSpace(LLVMTypeOf(src));
607 - addr_type = LLVMPointerType(insn_symbol_type(fn->module, insn), as);
608 - src = LLVMBuildPointerCast(fn->builder, src, addr_type, "");
696 + addr_type = LLVMPointerType(insn_symbol_type(insn), as);
697 + src = LLVMBuildPointerCast(fn->builder, src, addr_type, LLVMGetValueName(src));
609 698
610 699 /* addr = src + off */
611 700 addr = calc_gep(fn->builder, src, off);
612 701 return addr;
613 702 }
614 703
615 704
616 705 static void output_op_load(struct function *fn, struct instruction *insn)
617 706 {
618 707 LLVMValueRef addr, target;
708 + char name[MAX_PSEUDO_NAME];
619 709
620 710 addr = calc_memop_addr(fn, insn);
621 711
622 712 /* perform load */
623 - target = LLVMBuildLoad(fn->builder, addr, "load_target");
713 + pseudo_name(insn->target, name);
714 + target = LLVMBuildLoad(fn->builder, addr, name);
624 715
625 716 insn->target->priv = target;
626 717 }
627 718
628 719 static void output_op_store(struct function *fn, struct instruction *insn)
629 720 {
630 - LLVMValueRef addr, target, target_in;
721 + LLVMValueRef addr, target_in;
631 722
632 723 addr = calc_memop_addr(fn, insn);
633 724
634 - target_in = pseudo_to_value(fn, insn, insn->target);
725 + target_in = pseudo_to_rvalue(fn, insn->type, insn->target);
635 726
636 727 /* perform store */
637 - target = LLVMBuildStore(fn->builder, target_in, addr);
638 -
639 - insn->target->priv = target;
728 + LLVMBuildStore(fn->builder, target_in, addr);
640 729 }
641 730
642 731 static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
643 732 {
644 733 if (LLVMTypeOf(value) != LLVMInt1Type())
645 - value = LLVMBuildIsNotNull(fn->builder, value, "cond");
734 + value = LLVMBuildIsNotNull(fn->builder, value, LLVMGetValueName(value));
646 735
647 736 return value;
648 737 }
649 738
650 739 static void output_op_cbr(struct function *fn, struct instruction *br)
651 740 {
652 741 LLVMValueRef cond = bool_value(fn,
653 - pseudo_to_value(fn, br, br->cond));
742 + pseudo_to_value(fn, NULL, br->cond));
654 743
655 744 LLVMBuildCondBr(fn->builder, cond,
656 745 br->bb_true->priv,
657 746 br->bb_false->priv);
658 747 }
659 748
660 749 static void output_op_br(struct function *fn, struct instruction *br)
661 750 {
662 751 LLVMBuildBr(fn->builder, br->bb_true->priv);
663 752 }
664 753
665 754 static void output_op_sel(struct function *fn, struct instruction *insn)
666 755 {
667 756 LLVMValueRef target, src1, src2, src3;
757 + char name[MAX_PSEUDO_NAME];
668 758
669 - src1 = bool_value(fn, pseudo_to_value(fn, insn, insn->src1));
670 - src2 = pseudo_to_value(fn, insn, insn->src2);
671 - src3 = pseudo_to_value(fn, insn, insn->src3);
759 + src1 = bool_value(fn, pseudo_to_value(fn, NULL, insn->src1));
760 + src2 = get_operand(fn, insn->type, insn->src2);
761 + src3 = get_operand(fn, insn->type, insn->src3);
672 762
673 - target = LLVMBuildSelect(fn->builder, src1, src2, src3, "select");
763 + pseudo_name(insn->target, name);
764 + target = LLVMBuildSelect(fn->builder, src1, src2, src3, name);
674 765
675 - insn->target->priv = target;
766 + insn->target->priv = adjust_type(fn, insn->type, target);
676 767 }
677 768
678 769 static void output_op_switch(struct function *fn, struct instruction *insn)
679 770 {
680 771 LLVMValueRef sw_val, target;
681 772 struct basic_block *def = NULL;
682 773 struct multijmp *jmp;
683 774 int n_jmp = 0;
684 775
685 776 FOR_EACH_PTR(insn->multijmp_list, jmp) {
686 - if (jmp->begin == jmp->end) { /* case N */
687 - n_jmp++;
688 - } else if (jmp->begin < jmp->end) { /* case M..N */
689 - assert(0);
777 + if (jmp->begin <= jmp->end) {
778 + n_jmp += (jmp->end - jmp->begin) + 1;
690 779 } else /* default case */
691 780 def = jmp->target;
692 781 } END_FOR_EACH_PTR(jmp);
693 782
694 - sw_val = pseudo_to_value(fn, insn, insn->target);
783 + sw_val = get_ioperand(fn, insn->type, insn->cond);
695 784 target = LLVMBuildSwitch(fn->builder, sw_val,
696 785 def ? def->priv : NULL, n_jmp);
697 786
698 787 FOR_EACH_PTR(insn->multijmp_list, jmp) {
699 - if (jmp->begin == jmp->end) { /* case N */
700 - LLVMAddCase(target,
701 - LLVMConstInt(LLVMInt32Type(), jmp->begin, 0),
702 - jmp->target->priv);
703 - } else if (jmp->begin < jmp->end) { /* case M..N */
704 - assert(0);
788 + long long val;
789 +
790 + for (val = jmp->begin; val <= jmp->end; val++) {
791 + LLVMValueRef Val = val_to_value(val, insn->type);
792 + LLVMAddCase(target, Val, jmp->target->priv);
705 793 }
706 794 } END_FOR_EACH_PTR(jmp);
707 -
708 - insn->target->priv = target;
709 795 }
710 796
711 797 static void output_op_call(struct function *fn, struct instruction *insn)
712 798 {
713 799 LLVMValueRef target, func;
800 + struct symbol *ctype;
714 801 int n_arg = 0, i;
715 802 struct pseudo *arg;
716 803 LLVMValueRef *args;
804 + char name[64];
717 805
718 - FOR_EACH_PTR(insn->arguments, arg) {
719 - n_arg++;
720 - } END_FOR_EACH_PTR(arg);
721 -
806 + n_arg = pseudo_list_size(insn->arguments);
722 807 args = calloc(n_arg, sizeof(LLVMValueRef));
723 808
809 + PREPARE_PTR_LIST(insn->fntypes, ctype);
810 + if (insn->func->type == PSEUDO_REG || insn->func->type == PSEUDO_PHI)
811 + func = get_operand(fn, ctype, insn->func);
812 + else
813 + func = pseudo_to_value(fn, ctype, insn->func);
724 814 i = 0;
725 815 FOR_EACH_PTR(insn->arguments, arg) {
726 - args[i++] = pseudo_to_value(fn, insn, arg);
816 + NEXT_PTR_LIST(ctype);
817 + args[i++] = pseudo_to_rvalue(fn, ctype, arg);
727 818 } END_FOR_EACH_PTR(arg);
819 + FINISH_PTR_LIST(ctype);
728 820
729 - func = pseudo_to_value(fn, insn, insn->func);
730 - target = LLVMBuildCall(fn->builder, func, args, n_arg, "");
821 + pseudo_name(insn->target, name);
822 + target = LLVMBuildCall(fn->builder, func, args, n_arg, name);
731 823
732 824 insn->target->priv = target;
733 825 }
734 826
735 827 static void output_op_phisrc(struct function *fn, struct instruction *insn)
736 828 {
737 829 LLVMValueRef v;
738 830 struct instruction *phi;
739 831
740 832 assert(insn->target->priv == NULL);
741 833
742 834 /* target = src */
743 - v = pseudo_to_value(fn, insn, insn->phi_src);
835 + v = get_operand(fn, insn->type, insn->phi_src);
744 836
745 837 FOR_EACH_PTR(insn->phi_users, phi) {
746 838 LLVMValueRef load, ptr;
747 839
748 840 assert(phi->opcode == OP_PHI);
749 841 /* phi must be load from alloca */
750 842 load = phi->target->priv;
751 843 assert(LLVMGetInstructionOpcode(load) == LLVMLoad);
752 844 ptr = LLVMGetOperand(load, 0);
753 845 /* store v to alloca */
754 846 LLVMBuildStore(fn->builder, v, ptr);
755 847 } END_FOR_EACH_PTR(phi);
756 848 }
757 849
758 850 static void output_op_phi(struct function *fn, struct instruction *insn)
759 851 {
760 852 LLVMValueRef load = insn->target->priv;
761 853
762 854 /* forward load */
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
763 855 assert(LLVMGetInstructionOpcode(load) == LLVMLoad);
764 856 /* forward load has no parent block */
765 857 assert(!LLVMGetInstructionParent(load));
766 858 /* finalize load in current block */
767 859 LLVMInsertIntoBuilder(fn->builder, load);
768 860 }
769 861
770 862 static void output_op_ptrcast(struct function *fn, struct instruction *insn)
771 863 {
772 864 LLVMValueRef src, target;
865 + LLVMTypeRef dtype;
866 + struct symbol *otype = insn->orig_type;
867 + LLVMOpcode op;
773 868 char target_name[64];
774 869
775 - src = insn->src->priv;
776 - if (!src)
777 - src = pseudo_to_value(fn, insn, insn->src);
778 -
870 + src = get_operand(fn, otype, insn->src);
779 871 pseudo_name(insn->target, target_name);
780 872
781 - assert(!symbol_is_fp_type(insn->type));
873 + dtype = symbol_type(insn->type);
874 + switch (insn->opcode) {
875 + case OP_UTPTR:
876 + case OP_SEXT: // FIXME
877 + assert(is_int_type(otype));
878 + assert(is_ptr_type(insn->type));
879 + op = LLVMIntToPtr;
880 + break;
881 + case OP_PTRTU:
882 + assert(is_ptr_type(otype));
883 + assert(is_int_type(insn->type));
884 + op = LLVMPtrToInt;
885 + break;
886 + case OP_PTRCAST:
887 + case OP_ZEXT: // FIXME
888 + assert(is_ptr_type(otype));
889 + assert(is_ptr_type(insn->type));
890 + op = LLVMBitCast;
891 + break;
892 + default:
893 + assert(0);
894 + }
782 895
783 - target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
784 -
896 + target = LLVMBuildCast(fn->builder, op, src, dtype, target_name);
785 897 insn->target->priv = target;
786 898 }
787 899
788 900 static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOpcode op)
789 901 {
790 902 LLVMValueRef src, target;
903 + LLVMTypeRef dtype;
904 + struct symbol *otype = insn->orig_type;
791 905 char target_name[64];
792 906
793 - src = insn->src->priv;
794 - if (!src)
795 - src = pseudo_to_value(fn, insn, insn->src);
907 + if (is_ptr_type(insn->type)) // cast to void* is OP_CAST ...
908 + return output_op_ptrcast(fn, insn);
796 909
910 + assert(is_int_type(insn->type));
911 +
912 + src = get_operand(fn, otype, insn->src);
797 913 pseudo_name(insn->target, target_name);
798 914
799 - assert(!symbol_is_fp_type(insn->type));
915 + dtype = symbol_type(insn->type);
916 + if (is_ptr_type(otype)) {
917 + op = LLVMPtrToInt;
918 + } else if (is_float_type(otype)) {
919 + assert(op == LLVMFPToUI || op == LLVMFPToSI);
920 + } else if (is_int_type(otype)) {
921 + unsigned int width = otype->bit_size;
922 + if (insn->size < width)
923 + op = LLVMTrunc;
924 + else if (insn->size == width)
925 + op = LLVMBitCast;
926 + } else {
927 + assert(0);
928 + }
800 929
801 - if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
802 - target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
803 - else
804 - target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
930 + target = LLVMBuildCast(fn->builder, op, src, dtype, target_name);
931 + insn->target->priv = target;
932 +}
805 933
934 +static void output_op_fpcast(struct function *fn, struct instruction *insn)
935 +{
936 + LLVMTypeRef dtype = symbol_type(insn->type);
937 + LLVMValueRef src, target;
938 + struct symbol *otype = insn->orig_type;
939 + char name[64];
940 +
941 + assert(is_float_type(insn->type));
942 +
943 + pseudo_name(insn->target, name);
944 + src = get_operand(fn, otype, insn->src);
945 + switch (insn->opcode) {
946 + case OP_FCVTF:
947 + target = LLVMBuildFPCast(fn->builder, src, dtype, name);
948 + break;
949 + case OP_SCVTF:
950 + target = LLVMBuildSIToFP(fn->builder, src, dtype, name);
951 + break;
952 + case OP_UCVTF:
953 + target = LLVMBuildUIToFP(fn->builder, src, dtype, name);
954 + break;
955 + default:
956 + assert(0);
957 + }
806 958 insn->target->priv = target;
807 959 }
808 960
961 +static void output_op_setval(struct function *fn, struct instruction *insn)
962 +{
963 + struct expression *val = insn->val;
964 + LLVMValueRef target;
965 +
966 + switch (val->type) {
967 + case EXPR_LABEL:
968 + target = LLVMBlockAddress(fn->fn, val->symbol->bb_target->priv);
969 + break;
970 + default:
971 + assert(0);
972 + }
973 +
974 + insn->target->priv = target;
975 +}
976 +
977 +static void output_op_setfval(struct function *fn, struct instruction *insn)
978 +{
979 + LLVMTypeRef dtype = symbol_type(insn->type);
980 + LLVMValueRef target;
981 +
982 + target = LLVMConstReal(dtype, insn->fvalue);
983 + insn->target->priv = target;
984 +}
985 +
809 986 static void output_insn(struct function *fn, struct instruction *insn)
810 987 {
811 988 switch (insn->opcode) {
812 989 case OP_RET:
813 990 output_op_ret(fn, insn);
814 991 break;
815 992 case OP_BR:
816 993 output_op_br(fn, insn);
817 994 break;
818 995 case OP_CBR:
819 996 output_op_cbr(fn, insn);
820 997 break;
821 998 case OP_SYMADDR:
822 999 assert(0);
823 1000 break;
824 1001 case OP_SETVAL:
825 - assert(0);
1002 + output_op_setval(fn, insn);
826 1003 break;
1004 + case OP_SETFVAL:
1005 + output_op_setfval(fn, insn);
1006 + break;
827 1007 case OP_SWITCH:
828 1008 output_op_switch(fn, insn);
829 1009 break;
830 1010 case OP_COMPUTEDGOTO:
831 1011 assert(0);
832 1012 break;
833 1013 case OP_PHISOURCE:
834 1014 output_op_phisrc(fn, insn);
835 1015 break;
836 1016 case OP_PHI:
837 1017 output_op_phi(fn, insn);
838 1018 break;
839 1019 case OP_LOAD:
840 1020 output_op_load(fn, insn);
841 1021 break;
842 - case OP_LNOP:
843 - assert(0);
844 - break;
845 1022 case OP_STORE:
846 1023 output_op_store(fn, insn);
847 1024 break;
848 - case OP_SNOP:
849 - assert(0);
850 - break;
851 1025 case OP_INLINED_CALL:
852 - assert(0);
853 1026 break;
854 1027 case OP_CALL:
855 1028 output_op_call(fn, insn);
856 1029 break;
857 - case OP_CAST:
1030 + case OP_ZEXT:
858 1031 output_op_cast(fn, insn, LLVMZExt);
859 1032 break;
860 - case OP_SCAST:
1033 + case OP_SEXT:
861 1034 output_op_cast(fn, insn, LLVMSExt);
862 1035 break;
863 - case OP_FPCAST:
864 - assert(0);
1036 + case OP_TRUNC:
1037 + output_op_cast(fn, insn, LLVMTrunc);
865 1038 break;
1039 + case OP_FCVTU:
1040 + output_op_cast(fn, insn, LLVMFPToUI);
1041 + break;
1042 + case OP_FCVTS:
1043 + output_op_cast(fn, insn, LLVMFPToSI);
1044 + break;
1045 + case OP_UCVTF: case OP_SCVTF:
1046 + case OP_FCVTF:
1047 + output_op_fpcast(fn, insn);
1048 + break;
1049 + case OP_UTPTR:
1050 + case OP_PTRTU:
866 1051 case OP_PTRCAST:
867 1052 output_op_ptrcast(fn, insn);
868 1053 break;
869 1054 case OP_BINARY ... OP_BINARY_END:
870 1055 output_op_binary(fn, insn);
871 1056 break;
872 - case OP_BINCMP ... OP_BINCMP_END:
1057 + case OP_FPCMP ... OP_BINCMP_END:
873 1058 output_op_compare(fn, insn);
874 1059 break;
875 1060 case OP_SEL:
876 1061 output_op_sel(fn, insn);
877 1062 break;
878 1063 case OP_SLICE:
879 1064 assert(0);
880 1065 break;
881 1066 case OP_NOT: {
882 1067 LLVMValueRef src, target;
883 1068 char target_name[64];
884 1069
885 - src = pseudo_to_value(fn, insn, insn->src);
1070 + src = pseudo_to_value(fn, insn->type, insn->src);
886 1071
887 1072 pseudo_name(insn->target, target_name);
888 1073
889 1074 target = LLVMBuildNot(fn->builder, src, target_name);
890 1075
891 1076 insn->target->priv = target;
892 1077 break;
893 1078 }
894 - case OP_NEG:
895 - assert(0);
1079 + case OP_FNEG:
1080 + case OP_NEG: {
1081 + LLVMValueRef src, target;
1082 + char target_name[64];
1083 +
1084 + src = pseudo_to_value(fn, insn->type, insn->src);
1085 +
1086 + pseudo_name(insn->target, target_name);
1087 +
1088 + if (insn->opcode == OP_FNEG)
1089 + target = LLVMBuildFNeg(fn->builder, src, target_name);
1090 + else
1091 + target = LLVMBuildNeg(fn->builder, src, target_name);
1092 +
1093 + insn->target->priv = target;
896 1094 break;
1095 + }
897 1096 case OP_CONTEXT:
898 1097 assert(0);
899 1098 break;
900 1099 case OP_RANGE:
901 1100 assert(0);
902 1101 break;
903 1102 case OP_NOP:
904 1103 assert(0);
905 1104 break;
906 1105 case OP_DEATHNOTE:
907 1106 break;
908 1107 case OP_ASM:
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
909 1108 assert(0);
910 1109 break;
911 1110 case OP_COPY:
912 1111 assert(0);
913 1112 break;
914 1113 default:
915 1114 break;
916 1115 }
917 1116 }
918 1117
919 -static void output_bb(struct function *fn, struct basic_block *bb, unsigned long generation)
1118 +static void output_bb(struct function *fn, struct basic_block *bb)
920 1119 {
921 1120 struct instruction *insn;
922 1121
923 - bb->generation = generation;
924 -
925 1122 FOR_EACH_PTR(bb->insns, insn) {
926 1123 if (!insn->bb)
927 1124 continue;
928 1125
929 1126 output_insn(fn, insn);
930 1127 }
931 1128 END_FOR_EACH_PTR(insn);
932 1129 }
933 1130
934 1131 #define MAX_ARGS 64
935 1132
936 1133 static void output_fn(LLVMModuleRef module, struct entrypoint *ep)
937 1134 {
938 - unsigned long generation = ++bb_generation;
939 1135 struct symbol *sym = ep->name;
940 1136 struct symbol *base_type = sym->ctype.base_type;
941 - struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
942 - LLVMTypeRef arg_types[MAX_ARGS];
943 - LLVMTypeRef return_type;
944 1137 struct function function = { .module = module };
945 1138 struct basic_block *bb;
946 - struct symbol *arg;
947 - const char *name;
948 1139 int nr_args = 0;
1140 + int i;
949 1141
950 - FOR_EACH_PTR(base_type->arguments, arg) {
951 - struct symbol *arg_base_type = arg->ctype.base_type;
952 -
953 - arg_types[nr_args++] = symbol_type(module, arg_base_type);
954 - } END_FOR_EACH_PTR(arg);
955 -
956 - name = show_ident(sym->ident);
957 -
958 - return_type = symbol_type(module, ret_type);
959 -
960 - function.type = LLVMFunctionType(return_type, arg_types, nr_args, 0);
961 -
962 - function.fn = LLVMAddFunction(module, name, function.type);
1142 + function.fn = get_sym_value(module, sym);
963 1143 LLVMSetFunctionCallConv(function.fn, LLVMCCallConv);
964 -
965 1144 LLVMSetLinkage(function.fn, function_linkage(sym));
966 1145
967 1146 function.builder = LLVMCreateBuilder();
968 1147
969 - static int nr_bb;
1148 + /* give a name to each argument */
1149 + nr_args = symbol_list_size(base_type->arguments);
1150 + for (i = 0; i < nr_args; i++) {
1151 + char name[MAX_PSEUDO_NAME];
1152 + LLVMValueRef arg;
970 1153
971 - FOR_EACH_PTR(ep->bbs, bb) {
972 - if (bb->generation == generation)
973 - continue;
1154 + arg = LLVMGetParam(function.fn, i);
1155 + snprintf(name, sizeof(name), "ARG%d.", i+1);
1156 + LLVMSetValueName(arg, name);
1157 + }
974 1158
1159 + /* create the BBs */
1160 + FOR_EACH_PTR(ep->bbs, bb) {
1161 + static int nr_bb;
975 1162 LLVMBasicBlockRef bbr;
976 1163 char bbname[32];
977 1164 struct instruction *insn;
978 1165
979 1166 sprintf(bbname, "L%d", nr_bb++);
980 1167 bbr = LLVMAppendBasicBlock(function.fn, bbname);
981 1168
982 1169 bb->priv = bbr;
983 1170
984 1171 /* allocate alloca for each phi */
985 1172 FOR_EACH_PTR(bb->insns, insn) {
986 1173 LLVMBasicBlockRef entrybbr;
987 1174 LLVMTypeRef phi_type;
988 1175 LLVMValueRef ptr;
989 1176
990 1177 if (!insn->bb || insn->opcode != OP_PHI)
991 1178 continue;
992 1179 /* insert alloca into entry block */
993 1180 entrybbr = LLVMGetEntryBasicBlock(function.fn);
994 1181 LLVMPositionBuilderAtEnd(function.builder, entrybbr);
995 - phi_type = insn_symbol_type(module, insn);
1182 + phi_type = insn_symbol_type(insn);
996 1183 ptr = LLVMBuildAlloca(function.builder, phi_type, "");
997 1184 /* emit forward load for phi */
998 1185 LLVMClearInsertionPosition(function.builder);
999 1186 insn->target->priv = LLVMBuildLoad(function.builder, ptr, "phi");
1000 1187 } END_FOR_EACH_PTR(insn);
1001 1188 }
1002 1189 END_FOR_EACH_PTR(bb);
1003 1190
1004 1191 FOR_EACH_PTR(ep->bbs, bb) {
1005 - if (bb->generation == generation)
1006 - continue;
1007 -
1008 1192 LLVMPositionBuilderAtEnd(function.builder, bb->priv);
1009 1193
1010 - output_bb(&function, bb, generation);
1194 + output_bb(&function, bb);
1011 1195 }
1012 1196 END_FOR_EACH_PTR(bb);
1013 1197 }
1014 1198
1015 1199 static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym)
1016 1200 {
1017 1201 struct expression *initializer = sym->initializer;
1018 1202 LLVMValueRef initial_value;
1019 1203 LLVMValueRef data;
1020 1204 const char *name;
1021 1205
1022 1206 if (initializer) {
1023 1207 switch (initializer->type) {
1024 1208 case EXPR_VALUE:
1025 - initial_value = LLVMConstInt(symbol_type(module, sym), initializer->value, 1);
1209 + initial_value = LLVMConstInt(symbol_type(sym), initializer->value, 1);
1026 1210 break;
1211 + case EXPR_FVALUE:
1212 + initial_value = LLVMConstReal(symbol_type(sym), initializer->fvalue);
1213 + break;
1027 1214 case EXPR_SYMBOL: {
1028 1215 struct symbol *sym = initializer->symbol;
1029 1216
1030 1217 initial_value = LLVMGetNamedGlobal(module, show_ident(sym->ident));
1031 1218 if (!initial_value)
1032 1219 initial_value = output_data(module, sym);
1033 1220 break;
1034 1221 }
1035 1222 case EXPR_STRING: {
1036 1223 const char *s = initializer->string->data;
1037 1224
1038 1225 initial_value = LLVMConstString(strdup(s), strlen(s) + 1, true);
1039 1226 break;
1040 1227 }
1041 1228 default:
1042 - assert(0);
1229 + warning(initializer->pos, "can't initialize type: %s", show_typename(sym));
1230 + initial_value = NULL;
1231 + break;
1043 1232 }
1044 1233 } else {
1045 - LLVMTypeRef type = symbol_type(module, sym);
1234 + LLVMTypeRef type = symbol_type(sym);
1046 1235
1047 1236 initial_value = LLVMConstNull(type);
1048 1237 }
1049 1238
1050 - name = show_ident(sym->ident);
1239 + if (!initial_value)
1240 + return NULL;
1051 1241
1242 + name = sym->ident ? show_ident(sym->ident) : "" ;
1243 +
1052 1244 data = LLVMAddGlobal(module, LLVMTypeOf(initial_value), name);
1053 1245
1054 1246 LLVMSetLinkage(data, data_linkage(sym));
1055 1247 if (sym->ctype.modifiers & MOD_CONST)
1056 1248 LLVMSetGlobalConstant(data, 1);
1057 1249 if (sym->ctype.modifiers & MOD_TLS)
1058 1250 LLVMSetThreadLocal(data, 1);
1059 1251 if (sym->ctype.alignment)
1060 1252 LLVMSetAlignment(data, sym->ctype.alignment);
1061 1253
1062 1254 if (!(sym->ctype.modifiers & MOD_EXTERN))
1063 1255 LLVMSetInitializer(data, initial_value);
1064 1256
1065 1257 return data;
1066 1258 }
1067 1259
1068 1260 static int is_prototype(struct symbol *sym)
1069 1261 {
1070 1262 if (sym->type == SYM_NODE)
1071 1263 sym = sym->ctype.base_type;
1072 1264 return sym && sym->type == SYM_FN && !sym->stmt;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1073 1265 }
1074 1266
1075 1267 static int compile(LLVMModuleRef module, struct symbol_list *list)
1076 1268 {
1077 1269 struct symbol *sym;
1078 1270
1079 1271 FOR_EACH_PTR(list, sym) {
1080 1272 struct entrypoint *ep;
1081 1273 expand_symbol(sym);
1082 1274
1083 - if (is_prototype(sym))
1275 + if (is_prototype(sym)) {
1276 + // this will do the LLVMAddFunction() we want
1277 + get_sym_value(module, sym);
1084 1278 continue;
1279 + }
1085 1280
1086 1281 ep = linearize_symbol(sym);
1087 1282 if (ep)
1088 1283 output_fn(module, ep);
1089 1284 else
1090 1285 output_data(module, sym);
1091 1286 }
1092 1287 END_FOR_EACH_PTR(sym);
1093 1288
1094 1289 return 0;
1095 1290 }
1096 1291
1097 1292 #ifndef LLVM_DEFAULT_TARGET_TRIPLE
1098 1293 #define LLVM_DEFAULT_TARGET_TRIPLE LLVM_HOSTTRIPLE
1099 1294 #endif
1100 1295
1101 1296 #define X86_LINUX_LAYOUT \
1102 1297 "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" \
1103 1298 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-" \
1104 1299 "a0:0:64-f80:32:32-n8:16:32-S128"
1105 1300
1106 1301 #define X86_64_LINUX_LAYOUT \
1107 1302 "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" \
1108 1303 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" \
1109 1304 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
1110 1305
1111 1306 static void set_target(LLVMModuleRef module)
1112 1307 {
1113 1308 char target[] = LLVM_DEFAULT_TARGET_TRIPLE;
1114 1309 const char *arch, *vendor, *os, *env, *layout = NULL;
1115 1310 char triple[256];
1116 1311
1117 1312 arch = strtok(target, "-");
1118 1313 vendor = strtok(NULL, "-");
1119 1314 os = strtok(NULL, "-");
1120 1315 env = strtok(NULL, "-");
1121 1316
1122 1317 if (!os)
1123 1318 return;
1124 1319 if (!env)
1125 1320 env = "unknown";
1126 1321
1127 1322 if (!strcmp(arch, "x86_64") && !strcmp(os, "linux")) {
1128 1323 if (arch_m64) {
1129 1324 layout = X86_64_LINUX_LAYOUT;
1130 1325 } else {
1131 1326 arch = "i386";
1132 1327 layout = X86_LINUX_LAYOUT;
1133 1328 }
1134 1329 }
1135 1330
1136 1331 /* unsupported target */
1137 1332 if (!layout)
1138 1333 return;
1139 1334
1140 1335 snprintf(triple, sizeof(triple), "%s-%s-%s-%s", arch, vendor, os, env);
1141 1336 LLVMSetTarget(module, triple);
1142 1337 LLVMSetDataLayout(module, layout);
1143 1338 }
1144 1339
1145 1340 int main(int argc, char **argv)
1146 1341 {
1147 1342 struct string_list *filelist = NULL;
1148 1343 struct symbol_list *symlist;
1149 1344 LLVMModuleRef module;
1150 1345 char *file;
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
1151 1346
1152 1347 symlist = sparse_initialize(argc, argv, &filelist);
1153 1348
1154 1349 module = LLVMModuleCreateWithName("sparse");
1155 1350 set_target(module);
1156 1351
1157 1352 compile(module, symlist);
1158 1353
1159 1354 /* need ->phi_users */
1160 1355 dbg_dead = 1;
1161 - FOR_EACH_PTR_NOTAG(filelist, file) {
1356 + FOR_EACH_PTR(filelist, file) {
1162 1357 symlist = sparse(file);
1163 1358 if (die_if_error)
1164 1359 return 1;
1165 1360 compile(module, symlist);
1166 - } END_FOR_EACH_PTR_NOTAG(file);
1361 + } END_FOR_EACH_PTR(file);
1167 1362
1168 1363 LLVMVerifyModule(module, LLVMPrintMessageAction, NULL);
1169 1364
1170 1365 LLVMWriteBitcodeToFD(module, STDOUT_FILENO, 0, 0);
1171 1366
1172 1367 LLVMDisposeModule(module);
1173 1368
1174 1369 report_stats();
1175 1370 return 0;
1176 1371 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX