Fix comment.
[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 Make use of "Red Zone".
9
10 //===---------------------------------------------------------------------===//
11
12 Implement __int128 and long double support.
13
14 //===---------------------------------------------------------------------===//
15
16 For this:
17
18 extern void xx(void);
19 void bar(void) {
20   xx();
21 }
22
23 gcc compiles to:
24
25 .globl _bar
26 _bar:
27         jmp     _xx
28
29 We need to do the tailcall optimization as well.
30
31 //===---------------------------------------------------------------------===//
32
33 AMD64 Optimization Manual 8.2 has some nice information about optimizing integer
34 multiplication by a constant. How much of it applies to Intel's X86-64
35 implementation? There are definite trade-offs to consider: latency vs. register
36 pressure vs. code size.
37
38 //===---------------------------------------------------------------------===//
39
40 Are we better off using branches instead of cmove to implement FP to
41 unsigned i64?
42
43 _conv:
44         ucomiss LC0(%rip), %xmm0
45         cvttss2siq      %xmm0, %rdx
46         jb      L3
47         subss   LC0(%rip), %xmm0
48         movabsq $-9223372036854775808, %rax
49         cvttss2siq      %xmm0, %rdx
50         xorq    %rax, %rdx
51 L3:
52         movq    %rdx, %rax
53         ret
54
55 instead of
56
57 _conv:
58         movss LCPI1_0(%rip), %xmm1
59         cvttss2siq %xmm0, %rcx
60         movaps %xmm0, %xmm2
61         subss %xmm1, %xmm2
62         cvttss2siq %xmm2, %rax
63         movabsq $-9223372036854775808, %rdx
64         xorq %rdx, %rax
65         ucomiss %xmm1, %xmm0
66         cmovb %rcx, %rax
67         ret
68
69 Seems like the jb branch has high likelyhood of being taken. It would have
70 saved a few instructions.
71
72 //===---------------------------------------------------------------------===//
73
74 Poor codegen:
75
76 int X[2];
77 int b;
78 void test(void) {
79   memset(X, b, 2*sizeof(X[0]));
80 }
81
82 llc:
83         movq _b@GOTPCREL(%rip), %rax
84         movzbq (%rax), %rax
85         movq %rax, %rcx
86         shlq $8, %rcx
87         orq %rax, %rcx
88         movq %rcx, %rax
89         shlq $16, %rax
90         orq %rcx, %rax
91         movq %rax, %rcx
92         shlq $32, %rcx
93         movq _X@GOTPCREL(%rip), %rdx
94         orq %rax, %rcx
95         movq %rcx, (%rdx)
96         ret
97
98 gcc:
99         movq    _b@GOTPCREL(%rip), %rax
100         movabsq $72340172838076673, %rdx
101         movzbq  (%rax), %rax
102         imulq   %rdx, %rax
103         movq    _X@GOTPCREL(%rip), %rdx
104         movq    %rax, (%rdx)
105         ret
106
107 //===---------------------------------------------------------------------===//
108
109 Vararg function prologue can be further optimized. Currently all XMM registers
110 are stored into register save area. Most of them can be eliminated since the
111 upper bound of the number of XMM registers used are passed in %al. gcc produces
112 something like the following:
113
114         movzbl  %al, %edx
115         leaq    0(,%rdx,4), %rax
116         leaq    4+L2(%rip), %rdx
117         leaq    239(%rsp), %rax
118         jmp     *%rdx
119         movaps  %xmm7, -15(%rax)
120         movaps  %xmm6, -31(%rax)
121         movaps  %xmm5, -47(%rax)
122         movaps  %xmm4, -63(%rax)
123         movaps  %xmm3, -79(%rax)
124         movaps  %xmm2, -95(%rax)
125         movaps  %xmm1, -111(%rax)
126         movaps  %xmm0, -127(%rax)
127 L2:
128
129 It jumps over the movaps that do not need to be stored. Hard to see this being
130 significant as it added 5 instruciton (including a indirect branch) to avoid
131 executing 0 to 8 stores in the function prologue.
132
133 Perhaps we can optimize for the common case where no XMM registers are used for
134 parameter passing. i.e. is %al == 0 jump over all stores. Or in the case of a
135 leaf function where we can determine that no XMM input parameter is need, avoid
136 emitting the stores at all.
137
138 //===---------------------------------------------------------------------===//
139
140 AMD64 has a complex calling convention for aggregate passing by value:
141
142 1. If the size of an object is larger than two eightbytes, or in C++, is a non- 
143    POD structure or union type, or contains unaligned fields, it has class 
144    MEMORY.
145 2. Both eightbytes get initialized to class NO_CLASS. 
146 3. Each field of an object is classified recursively so that always two fields
147    are considered. The resulting class is calculated according to the classes
148    of the fields in the eightbyte: 
149    (a) If both classes are equal, this is the resulting class. 
150    (b) If one of the classes is NO_CLASS, the resulting class is the other 
151        class. 
152    (c) If one of the classes is MEMORY, the result is the MEMORY class. 
153    (d) If one of the classes is INTEGER, the result is the INTEGER. 
154    (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, MEMORY is used as
155       class. 
156    (f) Otherwise class SSE is used. 
157 4. Then a post merger cleanup is done: 
158    (a) If one of the classes is MEMORY, the whole argument is passed in memory. 
159    (b) If SSEUP is not preceeded by SSE, it is converted to SSE.
160
161 Currently llvm frontend does not handle this correctly.
162
163 Problem 1:
164     typedef struct { int i; double d; } QuadWordS;
165 It is currently passed in two i64 integer registers. However, gcc compiled
166 callee expects the second element 'd' to be passed in XMM0.
167
168 Problem 2:
169     typedef struct { int32_t i; float j; double d; } QuadWordS;
170 The size of the first two fields == i64 so they will be combined and passed in
171 a integer register RDI. The third field is still passed in XMM0.
172
173 Problem 3:
174     typedef struct { int64_t i; int8_t j; int64_t d; } S;
175     void test(S s)
176 The size of this aggregate is greater than two i64 so it should be passed in 
177 memory. Currently llvm breaks this down and passed it in three integer
178 registers.
179
180 Problem 4:
181 Taking problem 3 one step ahead where a function expects a aggregate value
182 in memory followed by more parameter(s) passed in register(s).
183     void test(S s, int b)
184
185 LLVM IR does not allow parameter passing by aggregates, therefore it must break
186 the aggregates value (in problem 3 and 4) into a number of scalar values:
187     void %test(long %s.i, byte %s.j, long %s.d);
188
189 However, if the backend were to lower this code literally it would pass the 3
190 values in integer registers. To force it be passed in memory, the frontend
191 should change the function signiture to:
192     void %test(long %undef1, long %undef2, long %undef3, long %undef4, 
193                long %undef5, long %undef6,
194                long %s.i, byte %s.j, long %s.d);
195 And the callee would look something like this:
196     call void %test( undef, undef, undef, undef, undef, undef,
197                      %tmp.s.i, %tmp.s.j, %tmp.s.d );
198 The first 6 undef parameters would exhaust the 6 integer registers used for
199 parameter passing. The following three integer values would then be forced into
200 memory.
201
202 For problem 4, the parameter 'd' would be moved to the front of the parameter
203 list so it will be passed in register:
204     void %test(int %d,
205                long %undef1, long %undef2, long %undef3, long %undef4, 
206                long %undef5, long %undef6,
207                long %s.i, byte %s.j, long %s.d);
208
209 //===---------------------------------------------------------------------===//
210
211 Right now the asm printer assumes GlobalAddress are accessed via RIP relative
212 addressing. Therefore, it is not possible to generate this:
213         movabsq $__ZTV10polynomialIdE+16, %rax
214
215 That is ok for now since we currently only support small model. So the above
216 is selected as
217         leaq __ZTV10polynomialIdE+16(%rip), %rax
218
219 This is probably slightly slower but is much shorter than movabsq. However, if
220 we were to support medium or larger code models, we need to use the movabs
221 instruction. We should probably introduce something like AbsoluteAddress to
222 distinguish it from GlobalAddress so the asm printer and JIT code emitter can
223 do the right thing.