clean this up.
[oota-llvm.git] / lib / Target / X86 / README-X86-64.txt
1 //===- README_X86_64.txt - Notes for X86-64 code gen ----------------------===//
2
3 Implement different PIC models? Right now we only support Mac OS X with small
4 PIC code model.
5
6 //===---------------------------------------------------------------------===//
7
8 For this:
9
10 extern void xx(void);
11 void bar(void) {
12   xx();
13 }
14
15 gcc compiles to:
16
17 .globl _bar
18 _bar:
19         jmp     _xx
20
21 We need to do the tailcall optimization as well.
22
23 //===---------------------------------------------------------------------===//
24
25 AMD64 Optimization Manual 8.2 has some nice information about optimizing integer
26 multiplication by a constant. How much of it applies to Intel's X86-64
27 implementation? There are definite trade-offs to consider: latency vs. register
28 pressure vs. code size.
29
30 //===---------------------------------------------------------------------===//
31
32 Are we better off using branches instead of cmove to implement FP to
33 unsigned i64?
34
35 _conv:
36         ucomiss LC0(%rip), %xmm0
37         cvttss2siq      %xmm0, %rdx
38         jb      L3
39         subss   LC0(%rip), %xmm0
40         movabsq $-9223372036854775808, %rax
41         cvttss2siq      %xmm0, %rdx
42         xorq    %rax, %rdx
43 L3:
44         movq    %rdx, %rax
45         ret
46
47 instead of
48
49 _conv:
50         movss LCPI1_0(%rip), %xmm1
51         cvttss2siq %xmm0, %rcx
52         movaps %xmm0, %xmm2
53         subss %xmm1, %xmm2
54         cvttss2siq %xmm2, %rax
55         movabsq $-9223372036854775808, %rdx
56         xorq %rdx, %rax
57         ucomiss %xmm1, %xmm0
58         cmovb %rcx, %rax
59         ret
60
61 Seems like the jb branch has high likelyhood of being taken. It would have
62 saved a few instructions.
63
64 //===---------------------------------------------------------------------===//
65
66 Poor codegen:
67
68 int X[2];
69 int b;
70 void test(void) {
71   memset(X, b, 2*sizeof(X[0]));
72 }
73
74 llc:
75         movq _b@GOTPCREL(%rip), %rax
76         movzbq (%rax), %rax
77         movq %rax, %rcx
78         shlq $8, %rcx
79         orq %rax, %rcx
80         movq %rcx, %rax
81         shlq $16, %rax
82         orq %rcx, %rax
83         movq %rax, %rcx
84         shlq $32, %rcx
85         movq _X@GOTPCREL(%rip), %rdx
86         orq %rax, %rcx
87         movq %rcx, (%rdx)
88         ret
89
90 gcc:
91         movq    _b@GOTPCREL(%rip), %rax
92         movabsq $72340172838076673, %rdx
93         movzbq  (%rax), %rax
94         imulq   %rdx, %rax
95         movq    _X@GOTPCREL(%rip), %rdx
96         movq    %rax, (%rdx)
97         ret
98
99 //===---------------------------------------------------------------------===//
100
101 Vararg function prologue can be further optimized. Currently all XMM registers
102 are stored into register save area. Most of them can be eliminated since the
103 upper bound of the number of XMM registers used are passed in %al. gcc produces
104 something like the following:
105
106         movzbl  %al, %edx
107         leaq    0(,%rdx,4), %rax
108         leaq    4+L2(%rip), %rdx
109         leaq    239(%rsp), %rax
110         jmp     *%rdx
111         movaps  %xmm7, -15(%rax)
112         movaps  %xmm6, -31(%rax)
113         movaps  %xmm5, -47(%rax)
114         movaps  %xmm4, -63(%rax)
115         movaps  %xmm3, -79(%rax)
116         movaps  %xmm2, -95(%rax)
117         movaps  %xmm1, -111(%rax)
118         movaps  %xmm0, -127(%rax)
119 L2:
120
121 It jumps over the movaps that do not need to be stored. Hard to see this being
122 significant as it added 5 instruciton (including a indirect branch) to avoid
123 executing 0 to 8 stores in the function prologue.
124
125 Perhaps we can optimize for the common case where no XMM registers are used for
126 parameter passing. i.e. is %al == 0 jump over all stores. Or in the case of a
127 leaf function where we can determine that no XMM input parameter is need, avoid
128 emitting the stores at all.
129
130 //===---------------------------------------------------------------------===//
131
132 AMD64 has a complex calling convention for aggregate passing by value:
133
134 1. If the size of an object is larger than two eightbytes, or in C++, is a non- 
135    POD structure or union type, or contains unaligned fields, it has class 
136    MEMORY.
137 2. Both eightbytes get initialized to class NO_CLASS. 
138 3. Each field of an object is classified recursively so that always two fields
139    are considered. The resulting class is calculated according to the classes
140    of the fields in the eightbyte: 
141    (a) If both classes are equal, this is the resulting class. 
142    (b) If one of the classes is NO_CLASS, the resulting class is the other 
143        class. 
144    (c) If one of the classes is MEMORY, the result is the MEMORY class. 
145    (d) If one of the classes is INTEGER, the result is the INTEGER. 
146    (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, MEMORY is used as
147       class. 
148    (f) Otherwise class SSE is used. 
149 4. Then a post merger cleanup is done: 
150    (a) If one of the classes is MEMORY, the whole argument is passed in memory. 
151    (b) If SSEUP is not preceeded by SSE, it is converted to SSE.
152
153 Currently llvm frontend does not handle this correctly.
154
155 Problem 1:
156     typedef struct { int i; double d; } QuadWordS;
157 It is currently passed in two i64 integer registers. However, gcc compiled
158 callee expects the second element 'd' to be passed in XMM0.
159
160 Problem 2:
161     typedef struct { int32_t i; float j; double d; } QuadWordS;
162 The size of the first two fields == i64 so they will be combined and passed in
163 a integer register RDI. The third field is still passed in XMM0.
164
165 Problem 3:
166     typedef struct { int64_t i; int8_t j; int64_t d; } S;
167     void test(S s)
168 The size of this aggregate is greater than two i64 so it should be passed in 
169 memory. Currently llvm breaks this down and passed it in three integer
170 registers.
171
172 Problem 4:
173 Taking problem 3 one step ahead where a function expects a aggregate value
174 in memory followed by more parameter(s) passed in register(s).
175     void test(S s, int b)
176
177 LLVM IR does not allow parameter passing by aggregates, therefore it must break
178 the aggregates value (in problem 3 and 4) into a number of scalar values:
179     void %test(long %s.i, byte %s.j, long %s.d);
180
181 However, if the backend were to lower this code literally it would pass the 3
182 values in integer registers. To force it be passed in memory, the frontend
183 should change the function signiture to:
184     void %test(long %undef1, long %undef2, long %undef3, long %undef4, 
185                long %undef5, long %undef6,
186                long %s.i, byte %s.j, long %s.d);
187 And the callee would look something like this:
188     call void %test( undef, undef, undef, undef, undef, undef,
189                      %tmp.s.i, %tmp.s.j, %tmp.s.d );
190 The first 6 undef parameters would exhaust the 6 integer registers used for
191 parameter passing. The following three integer values would then be forced into
192 memory.
193
194 For problem 4, the parameter 'd' would be moved to the front of the parameter
195 list so it will be passed in register:
196     void %test(int %d,
197                long %undef1, long %undef2, long %undef3, long %undef4, 
198                long %undef5, long %undef6,
199                long %s.i, byte %s.j, long %s.d);
200
201 //===---------------------------------------------------------------------===//
202
203 Right now the asm printer assumes GlobalAddress are accessed via RIP relative
204 addressing. Therefore, it is not possible to generate this:
205         movabsq $__ZTV10polynomialIdE+16, %rax
206
207 That is ok for now since we currently only support small model. So the above
208 is selected as
209         leaq __ZTV10polynomialIdE+16(%rip), %rax
210
211 This is probably slightly slower but is much shorter than movabsq. However, if
212 we were to support medium or larger code models, we need to use the movabs
213 instruction. We should probably introduce something like AbsoluteAddress to
214 distinguish it from GlobalAddress so the asm printer and JIT code emitter can
215 do the right thing.
216
217 //===---------------------------------------------------------------------===//
218
219 It's not possible to reference AH, BH, CH, and DH registers in an instruction
220 requiring REX prefix. However, divb and mulb both produce results in AH. If isel
221 emits a CopyFromReg which gets turned into a movb and that can be allocated a
222 r8b - r15b.
223
224 To get around this, isel emits a CopyFromReg from AX and then right shift it
225 down by 8 and truncate it. It's not pretty but it works. We need some register
226 allocation magic to make the hack go away (e.g. putting additional constraints
227 on the result of the movb).
228
229 //===---------------------------------------------------------------------===//
230
231 The x86-64 ABI for hidden-argument struct returns requires that the
232 incoming value of %rdi be copied into %rax by the callee upon return.
233
234 The idea is that it saves callers from having to remember this value,
235 which would often require a callee-saved register. Callees usually
236 need to keep this value live for most of their body anyway, so it
237 doesn't add a significant burden on them.
238
239 We currently implement this in codegen, however this is suboptimal
240 because it means that it would be quite awkward to implement the
241 optimization for callers.
242
243 A better implementation would be to relax the LLVM IR rules for sret
244 arguments to allow a function with an sret argument to have a non-void
245 return type, and to have the front-end to set up the sret argument value
246 as the return value of the function. The front-end could more easily
247 emit uses of the returned struct value to be in terms of the function's
248 lowered return value, and it would free non-C frontends from a
249 complication only required by a C-based ABI.
250
251 //===---------------------------------------------------------------------===//
252
253 We get a redundant zero extension for code like this:
254
255 int mask[1000];
256 int foo(unsigned x) {
257  if (x < 10)
258    x = x * 45;
259  else
260    x = x * 78;
261  return mask[x];
262 }
263
264 _foo:
265 LBB1_0: ## entry
266         cmpl    $9, %edi
267         jbe     LBB1_3  ## bb
268 LBB1_1: ## bb1
269         imull   $78, %edi, %eax
270 LBB1_2: ## bb2
271         movl    %eax, %eax                    <----
272         movq    _mask@GOTPCREL(%rip), %rcx
273         movl    (%rcx,%rax,4), %eax
274         ret
275 LBB1_3: ## bb
276         imull   $45, %edi, %eax
277         jmp     LBB1_2  ## bb2
278   
279 Before regalloc, we have:
280
281         %reg1025<def> = IMUL32rri8 %reg1024, 45, %EFLAGS<imp-def>
282         JMP mbb<bb2,0x203afb0>
283     Successors according to CFG: 0x203afb0 (#3)
284
285 bb1: 0x203af60, LLVM BB @0x1e02310, ID#2:
286     Predecessors according to CFG: 0x203aec0 (#0)
287         %reg1026<def> = IMUL32rri8 %reg1024, 78, %EFLAGS<imp-def>
288     Successors according to CFG: 0x203afb0 (#3)
289
290 bb2: 0x203afb0, LLVM BB @0x1e02340, ID#3:
291     Predecessors according to CFG: 0x203af10 (#1) 0x203af60 (#2)
292         %reg1027<def> = PHI %reg1025, mbb<bb,0x203af10>,
293                             %reg1026, mbb<bb1,0x203af60>
294         %reg1029<def> = MOVZX64rr32 %reg1027
295
296 so we'd have to know that IMUL32rri8 leaves the high word zero extended and to
297 be able to recognize the zero extend.  This could also presumably be implemented
298 if we have whole-function selectiondags.
299
300 //===---------------------------------------------------------------------===//