Mercurial > projects > ldc
annotate gen/abi-x86-64.cpp @ 1138:4c8bb03e4fbc
Update DtoConstFP() to be correct after LLVM r67562, which changed the way the
APFloat constructor expects its i80 APInts to be formatted. (They're now
actually consistent with the x87 format)
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Tue, 24 Mar 2009 15:24:59 +0100 |
parents | 152bd2c804d0 |
children | 3d6a908a34e9 |
rev | line source |
---|---|
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
1 /* TargetABI implementation for x86-64. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
2 * Written for LDC by Frits van Bommel in 2009. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
3 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
4 * extern(D) follows no particular external ABI, but tries to be smart about |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
5 * passing structs and returning them. It should probably be reviewed if the |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
6 * way LLVM implements fastcc on this platform ever changes. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
7 * (Specifically, the number of return registers of various types is hardcoded) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
8 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
9 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
10 * extern(C) implements the C calling convention for x86-64, as found in |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
11 * http://www.x86-64.org/documentation/abi-0.99.pdf |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
12 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
13 * Note: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
14 * Where a discrepancy was found between llvm-gcc and the ABI documentation, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
15 * llvm-gcc behavior was used for compatibility (after it was verified that |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
16 * regular gcc has the same behavior). |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
17 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
18 * LLVM gets it right for most types, but complex numbers and structs need some |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
19 * help. To make sure it gets those right we essentially bitcast small structs |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
20 * to a type to which LLVM assigns the appropriate registers, and pass that |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
21 * instead. Structs that are required to be passed in memory are explicitly |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
22 * marked with the ByVal attribute to ensure no part of them ends up in |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
23 * registers when only a subset of the desired registers are available. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
24 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
25 * We don't perform the same transformation for D-specific types that contain |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
26 * multiple parts, such as dynamic arrays and delegates. They're passed as if |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
27 * the parts were passed as separate parameters. This helps make things like |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
28 * printf("%.*s", o.toString()) work as expected; if we didn't do this that |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
29 * wouldn't work if there were 4 other integer/pointer arguments before the |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
30 * toString() call because the string got bumped to memory with one integer |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
31 * register still free. Keeping it untransformed puts the length in a register |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
32 * and the pointer in memory, as printf expects it. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
33 */ |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
34 |
1063
40d7f9b7357f
Fixed some #includes to be correct for both D1 and D2
Frits van Bommel <fvbommel wxs.nl>
parents:
1054
diff
changeset
|
35 #include "mtype.h" |
40d7f9b7357f
Fixed some #includes to be correct for both D1 and D2
Frits van Bommel <fvbommel wxs.nl>
parents:
1054
diff
changeset
|
36 #include "declaration.h" |
40d7f9b7357f
Fixed some #includes to be correct for both D1 and D2
Frits van Bommel <fvbommel wxs.nl>
parents:
1054
diff
changeset
|
37 #include "aggregate.h" |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
38 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
39 #include "gen/llvm.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
40 #include "gen/tollvm.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
41 #include "gen/logger.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
42 #include "gen/dvalue.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
43 #include "gen/llvmhelpers.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
44 #include "gen/abi.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
45 #include "gen/abi-x86-64.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
46 #include "ir/irfunction.h" |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
47 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
48 #include <cassert> |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
49 #include <map> |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
50 #include <string> |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
51 #include <utility> |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
52 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
53 // Implementation details for extern(C) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
54 namespace { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
55 /** |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
56 * This function helps filter out things that look like structs to C, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
57 * but should be passed to C in separate arguments anyway. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
58 * |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
59 * (e.g. dynamic arrays are passed as separate length and ptr. This |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
60 * is both less work and makes printf("%.*s", o.toString()) work) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
61 */ |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
62 inline bool keepUnchanged(Type* t) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
63 switch (t->ty) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
64 case Tarray: // dynamic array |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
65 case Taarray: // assoc array |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
66 case Tdelegate: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
67 return true; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
68 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
69 default: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
70 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
71 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
72 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
73 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
74 enum ArgClass { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
75 Integer, Sse, SseUp, X87, X87Up, ComplexX87, NoClass, Memory |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
76 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
77 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
78 struct Classification { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
79 bool isMemory; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
80 ArgClass classes[2]; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
81 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
82 Classification() : isMemory(false) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
83 classes[0] = NoClass; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
84 classes[1] = NoClass; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
85 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
86 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
87 void addField(unsigned offset, ArgClass cl) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
88 if (isMemory) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
89 return; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
90 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
91 // Note that we don't need to bother checking if it crosses 8 bytes. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
92 // We don't get here with unaligned fields, and anything that can be |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
93 // big enough to cross 8 bytes (cdoubles, reals, structs and arrays) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
94 // is special-cased in classifyType() |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
95 int idx = (offset < 8 ? 0 : 1); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
96 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
97 ArgClass nw = merge(classes[idx], cl); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
98 if (nw != classes[idx]) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
99 classes[idx] = nw; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
100 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
101 if (nw == Memory) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
102 classes[1-idx] = Memory; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
103 isMemory = true; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
104 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
105 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
106 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
107 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
108 private: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
109 ArgClass merge(ArgClass accum, ArgClass cl) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
110 if (accum == cl) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
111 return accum; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
112 if (accum == NoClass) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
113 return cl; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
114 if (cl == NoClass) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
115 return accum; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
116 if (accum == Memory || cl == Memory) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
117 return Memory; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
118 if (accum == Integer || cl == Integer) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
119 return Integer; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
120 if (accum == X87 || accum == X87Up || accum == ComplexX87 || |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
121 cl == X87 || cl == X87Up || cl == ComplexX87) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
122 return Memory; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
123 return Sse; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
124 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
125 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
126 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
127 void classifyType(Classification& accum, Type* ty, d_uns64 offset) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
128 if (Logger::enabled()) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
129 Logger::cout() << "Classifying " << ty->toChars() << " @ " << offset << '\n'; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
130 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
131 ty = ty->toBasetype(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
132 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
133 if (ty->isintegral() || ty->ty == Tpointer) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
134 accum.addField(offset, Integer); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
135 } else if (ty->ty == Tfloat80 || ty->ty == Timaginary80) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
136 accum.addField(offset, X87); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
137 accum.addField(offset+8, X87Up); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
138 } else if (ty->ty == Tcomplex80) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
139 accum.addField(offset, ComplexX87); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
140 // make sure other half knows about it too: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
141 accum.addField(offset+16, ComplexX87); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
142 } else if (ty->ty == Tcomplex64) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
143 accum.addField(offset, Sse); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
144 accum.addField(offset+8, Sse); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
145 } else if (ty->ty == Tcomplex32) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
146 accum.addField(offset, Sse); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
147 accum.addField(offset+4, Sse); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
148 } else if (ty->isfloating()) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
149 accum.addField(offset, Sse); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
150 } else if (ty->size() > 16 || hasUnalignedFields(ty)) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
151 // This isn't creal, yet is > 16 bytes, so pass in memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
152 // Must be after creal case but before arrays and structs, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
153 // the other types that can get bigger than 16 bytes |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
154 accum.addField(offset, Memory); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
155 } else if (ty->ty == Tsarray) { |
1054
a3d7288c4473
Future-proof the code to classify static array members of structs.
Frits van Bommel <fvbommel wxs.nl>
parents:
1051
diff
changeset
|
156 Type* eltType = ty->nextOf(); |
a3d7288c4473
Future-proof the code to classify static array members of structs.
Frits van Bommel <fvbommel wxs.nl>
parents:
1051
diff
changeset
|
157 d_uns64 eltsize = eltType->size(); |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
158 if (eltsize > 0) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
159 d_uns64 dim = ty->size() / eltsize; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
160 assert(dim <= 16 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
161 && "Array of non-empty type <= 16 bytes but > 16 elements?"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
162 for (d_uns64 i = 0; i < dim; i++) { |
1054
a3d7288c4473
Future-proof the code to classify static array members of structs.
Frits van Bommel <fvbommel wxs.nl>
parents:
1051
diff
changeset
|
163 classifyType(accum, eltType, offset); |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
164 offset += eltsize; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
165 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
166 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
167 } else if (ty->ty == Tstruct) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
168 Array* fields = &((TypeStruct*) ty)->sym->fields; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
169 for (size_t i = 0; i < fields->dim; i++) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
170 VarDeclaration* field = (VarDeclaration*) fields->data[i]; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
171 classifyType(accum, field->type, offset + field->offset); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
172 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
173 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
174 if (Logger::enabled()) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
175 Logger::cout() << "x86-64 ABI: Implicitly handled type: " |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
176 << ty->toChars() << '\n'; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
177 // arrays, delegates, etc. (pointer-sized fields, <= 16 bytes) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
178 assert(offset == 0 || offset == 8 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
179 && "must be aligned and doesn't fit otherwise"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
180 assert(ty->size() % 8 == 0 && "Not a multiple of pointer size?"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
181 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
182 accum.addField(offset, Integer); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
183 if (ty->size() > 8) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
184 accum.addField(offset+8, Integer); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
185 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
186 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
187 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
188 Classification classify(Type* ty) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
189 typedef std::map<Type*, Classification> ClassMap; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
190 static ClassMap cache; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
191 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
192 ClassMap::iterator it = cache.find(ty); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
193 if (it != cache.end()) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
194 return it->second; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
195 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
196 Classification cl; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
197 classifyType(cl, ty, 0); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
198 cache[ty] = cl; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
199 return cl; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
200 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
201 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
202 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
203 /// Returns the type to pass as, or null if no transformation is needed. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
204 LLType* getAbiType(Type* ty) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
205 ty = ty->toBasetype(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
206 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
207 // First, check if there's any need of a transformation: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
208 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
209 if (keepUnchanged(ty)) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
210 return 0; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
211 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
212 if (ty->ty != Tcomplex32 && ty->ty != Tstruct) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
213 return 0; // Nothing to do, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
214 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
215 Classification cl = classify(ty); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
216 assert(!cl.isMemory); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
217 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
218 if (cl.classes[0] == NoClass) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
219 assert(cl.classes[1] == NoClass && "Non-empty struct with empty first half?"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
220 return 0; // Empty structs should also be handled correctly by LLVM |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
221 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
222 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
223 // Okay, we may need to transform. Figure out a canonical type: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
224 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
225 std::vector<const LLType*> parts; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
226 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
227 unsigned size = ty->size(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
228 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
229 switch (cl.classes[0]) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
230 case Integer: { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
231 unsigned bits = (size >= 8 ? 64 : (size * 8)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
232 parts.push_back(LLIntegerType::get(bits)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
233 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
234 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
235 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
236 case Sse: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
237 parts.push_back(size <= 4 ? LLType::FloatTy : LLType::DoubleTy); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
238 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
239 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
240 case X87: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
241 assert(cl.classes[1] == X87Up && "Upper half of real not X87Up?"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
242 /// The type only contains a single real/ireal field, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
243 /// so just use that type. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
244 return const_cast<LLType*>(LLType::X86_FP80Ty); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
245 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
246 default: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
247 assert(0 && "Unanticipated argument class"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
248 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
249 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
250 switch(cl.classes[1]) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
251 case NoClass: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
252 assert(parts.size() == 1); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
253 // No need to use a single-element struct type. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
254 // Just use the element type instead. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
255 return const_cast<LLType*>(parts[0]); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
256 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
257 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
258 case Integer: { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
259 assert(size > 8); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
260 unsigned bits = (size - 8) * 8; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
261 parts.push_back(LLIntegerType::get(bits)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
262 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
263 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
264 case Sse: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
265 parts.push_back(size <= 12 ? LLType::FloatTy : LLType::DoubleTy); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
266 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
267 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
268 case X87Up: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
269 if(cl.classes[0] == X87) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
270 // This won't happen: it was short-circuited while |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
271 // processing the first half. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
272 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
273 // I can't find this anywhere in the ABI documentation, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
274 // but this is what gcc does (both regular and llvm-gcc). |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
275 // (This triggers for types like union { real r; byte b; }) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
276 parts.push_back(LLType::DoubleTy); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
277 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
278 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
279 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
280 default: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
281 assert(0 && "Unanticipated argument class for second half"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
282 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
283 return LLStructType::get(parts); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
284 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
285 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
286 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
287 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
288 // Implementation details for extern(D) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
289 namespace x86_64_D_cc { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
290 struct DRegCount { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
291 unsigned ints; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
292 unsigned sse; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
293 unsigned x87; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
294 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
295 DRegCount(unsigned ints_, unsigned sse_, unsigned x87_) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
296 : ints(ints_), sse(sse_), x87(x87_) {} |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
297 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
298 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
299 // Count the number of registers needed for a simple type. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
300 // (Not a struct or static array) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
301 DRegCount regsNeededForSimpleType(Type* t) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
302 DRegCount r(0, 0, 0); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
303 switch(t->ty) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
304 case Tstruct: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
305 case Tsarray: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
306 assert(0 && "Not a simple type!"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
307 // Return huge numbers if assertions are disabled, so it'll always get |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
308 // bumped to memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
309 r.ints = r.sse = r.x87 = (unsigned)-1; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
310 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
311 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
312 // Floats, doubles and such are passed in SSE registers |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
313 case Tfloat32: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
314 case Tfloat64: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
315 case Timaginary32: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
316 case Timaginary64: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
317 r.sse = 1; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
318 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
319 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
320 case Tcomplex32: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
321 case Tcomplex64: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
322 r.sse = 2; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
323 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
324 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
325 // Reals, ireals and creals are passed in x87 registers |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
326 case Tfloat80: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
327 case Timaginary80: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
328 r.x87 = 1; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
329 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
330 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
331 case Tcomplex80: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
332 r.x87 = 2; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
333 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
334 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
335 // Anything else is passed in one or two integer registers, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
336 // depending on its size. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
337 default: { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
338 int needed = (t->size() + 7) / 8; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
339 assert(needed <= 2); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
340 r.ints = needed; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
341 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
342 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
343 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
344 return r; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
345 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
346 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
347 // Returns true if it's possible (and a good idea) to pass the struct in the |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
348 // specified number of registers. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
349 // (May return false if it's a bad idea to pass the type in registers for |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
350 // reasons other than it not fitting) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
351 // Note that if true is returned, 'left' is also modified to contain the |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
352 // number of registers left. This property is used in the recursive case. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
353 // If false is returned, 'left' is garbage. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
354 bool shouldPassStructInRegs(TypeStruct* t, DRegCount& left) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
355 // If it has unaligned fields, there's probably a reason for it, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
356 // so keep it in memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
357 if (hasUnalignedFields(t)) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
358 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
359 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
360 Array* fields = &t->sym->fields; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
361 d_uns64 nextbyte = 0; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
362 for (d_uns64 i = 0; i < fields->dim; i++) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
363 VarDeclaration* field = (VarDeclaration*) fields->data[i]; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
364 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
365 // This depends on ascending order of field offsets in structs |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
366 // without overlapping fields. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
367 if (field->offset < nextbyte) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
368 // Don't return unions (or structs containing them) in registers. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
369 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
370 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
371 nextbyte = field->offset + field->type->size(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
372 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
373 switch (field->type->ty) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
374 case Tstruct: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
375 if (!shouldPassStructInRegs((TypeStruct*) field->type, left)) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
376 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
377 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
378 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
379 case Tsarray: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
380 // Don't return static arrays in registers |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
381 // (indexing registers doesn't work well) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
382 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
383 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
384 default: { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
385 DRegCount needed = regsNeededForSimpleType(field->type); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
386 if (needed.ints > left.ints || needed.sse > left.sse || needed.x87 > left.x87) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
387 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
388 left.ints -= needed.ints; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
389 left.sse -= needed.sse; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
390 left.x87 -= needed.x87; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
391 break; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
392 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
393 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
394 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
395 return true; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
396 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
397 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
398 // Returns true if the struct fits in return registers in the x86-64 fastcc |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
399 // calling convention. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
400 bool retStructInRegs(TypeStruct* st) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
401 // 'fastcc' allows returns in up to two registers of each kind: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
402 DRegCount state(2, 2, 2); |
1134
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
403 #if 1 //LLVM_REV < 67588 |
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
404 // LLVM before trunk r67588 doesn't allow a second int to be an i1 or |
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
405 // i8. (See <http://llvm.org/PR3861>) |
1131
f2f13f111e2e
Workaround for LLVM PR 3861 (http://llvm.org/PR3861).
Frits van Bommel <fvbommel wxs.nl>
parents:
1063
diff
changeset
|
406 // Rather than complicating shouldPassStructInRegs(), just disallow |
f2f13f111e2e
Workaround for LLVM PR 3861 (http://llvm.org/PR3861).
Frits van Bommel <fvbommel wxs.nl>
parents:
1063
diff
changeset
|
407 // second integers for now. |
1134
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
408 // FIXME: Disabling this for older LLVM only makes the abi dependent on |
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
409 // LLVM revision, which seems like a bad idea. We could extend |
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
410 // i8 parts to i16 to work around this issue until 2.6... |
152bd2c804d0
Update comments now that LLVM PR3861 has been fixed. However, since
Frits van Bommel <fvbommel wxs.nl>
parents:
1131
diff
changeset
|
411 // TODO: Remove this workaround when support for LLVM 2.5 is dropped. |
1131
f2f13f111e2e
Workaround for LLVM PR 3861 (http://llvm.org/PR3861).
Frits van Bommel <fvbommel wxs.nl>
parents:
1063
diff
changeset
|
412 state.ints = 1; |
f2f13f111e2e
Workaround for LLVM PR 3861 (http://llvm.org/PR3861).
Frits van Bommel <fvbommel wxs.nl>
parents:
1063
diff
changeset
|
413 #endif |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
414 return shouldPassStructInRegs(st, state); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
415 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
416 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
417 // Heuristic for determining whether to pass a struct type directly or |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
418 // bump it to memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
419 bool passStructTypeDirectly(TypeStruct* st) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
420 // If the type fits in a reasonable number of registers, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
421 // pass it directly. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
422 // This does not necessarily mean it will actually be passed in |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
423 // registers. For example, x87 registers are never actually used for |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
424 // parameters. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
425 DRegCount state(2, 2, 2); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
426 return shouldPassStructInRegs(st, state); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
427 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
428 // This doesn't work well: Since the register count can differ depending |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
429 // on backend options, there's no way to be exact anyway. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
430 /* |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
431 // Regular fastcc: 6 int, 8 sse, 0 x87 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
432 // fastcc + tailcall: 5 int, 8 sse, 0 x87 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
433 RegCount state(5, 8, 0); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
434 */ |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
435 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
436 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
437 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
438 //////////////////////////////////////////////////////////////////////////////// |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
439 //////////////////////////////////////////////////////////////////////////////// |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
440 //////////////////////////////////////////////////////////////////////////////// |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
441 //////////////////////////////////////////////////////////////////////////////// |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
442 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
443 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
444 /// Just store to memory and it's readable as the other type. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
445 struct X86_64_C_struct_rewrite : ABIRewrite { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
446 // Get struct from ABI-mangled representation |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
447 LLValue* get(Type* dty, DValue* v) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
448 { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
449 LLValue* lval; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
450 if (v->isLVal()) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
451 lval = v->getLVal(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
452 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
453 // No memory location, create one. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
454 LLValue* rval = v->getRVal(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
455 lval = DtoAlloca(rval->getType()); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
456 DtoStore(rval, lval); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
457 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
458 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
459 const LLType* pTy = getPtrToType(DtoType(dty)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
460 return DtoLoad(DtoBitCast(lval, pTy), "get-result"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
461 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
462 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
463 // Get struct from ABI-mangled representation, and store in the provided location. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
464 void getL(Type* dty, DValue* v, llvm::Value* lval) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
465 LLValue* rval = v->getRVal(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
466 const LLType* pTy = getPtrToType(rval->getType()); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
467 DtoStore(rval, DtoBitCast(lval, pTy)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
468 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
469 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
470 // Turn a struct into an ABI-mangled representation |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
471 LLValue* put(Type* dty, DValue* v) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
472 { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
473 LLValue* lval; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
474 if (v->isLVal()) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
475 lval = v->getLVal(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
476 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
477 // No memory location, create one. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
478 LLValue* rval = v->getRVal(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
479 lval = DtoAlloca(rval->getType()); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
480 DtoStore(rval, lval); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
481 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
482 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
483 LLType* abiTy = getAbiType(dty); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
484 assert(abiTy && "Why are we rewriting a non-rewritten type?"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
485 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
486 const LLType* pTy = getPtrToType(abiTy); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
487 return DtoLoad(DtoBitCast(lval, pTy), "put-result"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
488 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
489 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
490 /// should return the transformed type for this rewrite |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
491 const LLType* type(Type* dty, const LLType* t) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
492 { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
493 return getAbiType(dty); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
494 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
495 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
496 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
497 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
498 struct RegCount { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
499 unsigned char int_regs, sse_regs; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
500 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
501 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
502 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
503 struct X86_64TargetABI : TargetABI { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
504 X86_64_C_struct_rewrite struct_rewrite; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
505 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
506 void newFunctionType(TypeFunction* tf) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
507 funcTypeStack.push_back(FuncTypeData(tf->linkage)); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
508 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
509 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
510 bool returnInArg(TypeFunction* tf); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
511 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
512 bool passByVal(Type* t); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
513 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
514 void rewriteFunctionType(TypeFunction* tf); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
515 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
516 void doneWithFunctionType() { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
517 funcTypeStack.pop_back(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
518 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
519 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
520 private: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
521 struct FuncTypeData { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
522 LINK linkage; // Linkage of the function type currently under construction |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
523 RegCount state; // bookkeeping for extern(C) parameter registers |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
524 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
525 FuncTypeData(LINK linkage_) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
526 : linkage(linkage_) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
527 { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
528 state.int_regs = 6; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
529 state.sse_regs = 8; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
530 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
531 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
532 std::vector<FuncTypeData> funcTypeStack; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
533 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
534 LINK linkage() { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
535 assert(funcTypeStack.size() != 0); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
536 return funcTypeStack.back().linkage; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
537 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
538 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
539 RegCount& state() { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
540 assert(funcTypeStack.size() != 0); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
541 return funcTypeStack.back().state; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
542 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
543 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
544 void fixup(IrFuncTyArg& arg); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
545 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
546 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
547 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
548 // The public getter for abi.cpp |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
549 TargetABI* getX86_64TargetABI() { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
550 return new X86_64TargetABI; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
551 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
552 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
553 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
554 bool X86_64TargetABI::returnInArg(TypeFunction* tf) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
555 assert(linkage() == tf->linkage); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
556 Type* rt = tf->next->toBasetype(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
557 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
558 if (tf->linkage == LINKd) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
559 assert(rt->ty != Tsarray && "Update calling convention for static array returns"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
560 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
561 // All non-structs can be returned in registers. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
562 if (rt->ty != Tstruct) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
563 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
564 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
565 // Try to figure out whether the struct fits in return registers |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
566 // and whether it's a good idea to put it there. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
567 return !x86_64_D_cc::retStructInRegs((TypeStruct*) rt); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
568 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
569 if (rt == Type::tvoid || keepUnchanged(rt)) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
570 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
571 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
572 Classification cl = classify(rt); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
573 return cl.isMemory; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
574 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
575 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
576 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
577 bool X86_64TargetABI::passByVal(Type* t) { |
1049 | 578 t = t->toBasetype(); |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
579 if (linkage() == LINKd) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
580 if (t->ty != Tstruct) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
581 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
582 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
583 // Try to be smart about which structs are passed in memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
584 return !x86_64_D_cc::passStructTypeDirectly((TypeStruct*) t); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
585 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
586 // This implements the C calling convention for x86-64. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
587 // It might not be correct for other calling conventions. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
588 Classification cl = classify(t); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
589 if (cl.isMemory) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
590 return true; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
591 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
592 // Figure out how many registers we want for this arg: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
593 RegCount wanted = { 0, 0 }; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
594 for (int i = 0 ; i < 2; i++) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
595 if (cl.classes[i] == Integer) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
596 wanted.int_regs++; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
597 else if (cl.classes[i] == Sse) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
598 wanted.sse_regs++; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
599 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
600 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
601 // See if they're available: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
602 RegCount& state = this->state(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
603 if (wanted.int_regs <= state.int_regs && wanted.sse_regs <= state.sse_regs) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
604 state.int_regs -= wanted.int_regs; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
605 state.sse_regs -= wanted.sse_regs; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
606 } else { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
607 if (keepUnchanged(t)) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
608 // Not enough registers available, but this is passed as if it's |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
609 // multiple arguments. Just use the registers there are, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
610 // automatically spilling the rest to memory. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
611 if (wanted.int_regs > state.int_regs) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
612 state.int_regs = 0; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
613 else |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
614 state.int_regs -= wanted.int_regs; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
615 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
616 if (wanted.sse_regs > state.sse_regs) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
617 state.sse_regs = 0; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
618 else |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
619 state.sse_regs -= wanted.sse_regs; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
620 } else if (t->iscomplex() || t->ty == Tstruct) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
621 // Spill entirely to memory, even if some of the registers are |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
622 // available. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
623 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
624 // FIXME: Don't do this if *none* of the wanted registers are available, |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
625 // (i.e. only when absolutely necessary for abi-compliance) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
626 // so it gets alloca'd by the callee and -scalarrepl can |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
627 // more easily break it up? |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
628 // Note: this won't be necessary if the following LLVM bug gets fixed: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
629 // http://llvm.org/bugs/show_bug.cgi?id=3741 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
630 return true; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
631 } else { |
1048 | 632 assert(t == Type::tfloat80 || t == Type::timaginary80 || t->size() <= 8 |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
633 && "What other big types are there?"); // other than static arrays... |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
634 // In any case, they shouldn't be represented as structs in LLVM: |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
635 assert(!isaStruct(DtoType(t))); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
636 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
637 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
638 // Everything else that's passed in memory is handled by LLVM. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
639 return false; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
640 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
641 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
642 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
643 // Helper function for rewriteFunctionType. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
644 // Return type and parameters are passed here (unless they're already in memory) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
645 // to get the rewrite applied (if necessary). |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
646 void X86_64TargetABI::fixup(IrFuncTyArg& arg) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
647 LLType* abiTy = getAbiType(arg.type); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
648 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
649 if (abiTy && abiTy != arg.ltype) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
650 assert(arg.type == Type::tcomplex32 || arg.type->ty == Tstruct); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
651 arg.ltype = abiTy; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
652 arg.rewrite = &struct_rewrite; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
653 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
654 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
655 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
656 void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
657 // extern(D) is handled entirely by passByVal and returnInArg |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
658 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
659 if (tf->linkage != LINKd) { |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
660 // TODO: See if this is correct for more than just extern(C). |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
661 |
1051
dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
Christian Kamm <kamm incasoftware de>
parents:
1049
diff
changeset
|
662 IrFuncTy& fty = tf->fty; |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
663 |
1051
dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
Christian Kamm <kamm incasoftware de>
parents:
1049
diff
changeset
|
664 if (!fty.arg_sret) { |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
665 Logger::println("x86-64 ABI: Transforming return type"); |
1051
dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
Christian Kamm <kamm incasoftware de>
parents:
1049
diff
changeset
|
666 Type* rt = fty.ret->type->toBasetype(); |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
667 if (rt != Type::tvoid) |
1051
dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
Christian Kamm <kamm incasoftware de>
parents:
1049
diff
changeset
|
668 fixup(*fty.ret); |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
669 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
670 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
671 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
672 Logger::println("x86-64 ABI: Transforming arguments"); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
673 LOG_SCOPE; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
674 |
1051
dc608dc33081
Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the
Christian Kamm <kamm incasoftware de>
parents:
1049
diff
changeset
|
675 for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { |
1047
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
676 IrFuncTyArg& arg = **I; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
677 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
678 if (Logger::enabled()) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
679 Logger::cout() << "Arg: " << arg.type->toChars() << '\n'; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
680 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
681 // Arguments that are in memory are of no interest to us. |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
682 if (arg.byref) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
683 continue; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
684 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
685 Type* ty = arg.type->toBasetype(); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
686 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
687 fixup(arg); |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
688 |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
689 if (Logger::enabled()) |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
690 Logger::cout() << "New arg type: " << *arg.ltype << '\n'; |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
691 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
692 } |
6bb04dbee21f
Some calling convention work for x86-64:
Frits van Bommel <fvbommel wxs.nl>
parents:
diff
changeset
|
693 } |