blob: ee68399d5adf13ef34e866c9ffa1553abc453bb8 [file] [log] [blame]
Colin Cross7bb052a2015-02-03 12:59:37 -08001// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5#include <u.h>
6#include <libc.h>
7#include "gg.h"
8#include "opt.h"
9
10// Matches real RtoB but can be used in global initializer.
11#define RtoB(r) (1<<((r)-D_AX))
12
13enum {
14 AX = RtoB(D_AX),
15 BX = RtoB(D_BX),
16 CX = RtoB(D_CX),
17 DX = RtoB(D_DX),
18 DI = RtoB(D_DI),
19 SI = RtoB(D_SI),
20
21 LeftRdwr = LeftRead | LeftWrite,
22 RightRdwr = RightRead | RightWrite,
23};
24
25#undef RtoB
26
27// This table gives the basic information about instruction
28// generated by the compiler and processed in the optimizer.
29// See opt.h for bit definitions.
30//
31// Instructions not generated need not be listed.
32// As an exception to that rule, we typically write down all the
33// size variants of an operation even if we just use a subset.
34//
35// The table is formatted for 8-space tabs.
36static ProgInfo progtable[ALAST] = {
37 [ATYPE]= {Pseudo | Skip},
38 [ATEXT]= {Pseudo},
39 [AFUNCDATA]= {Pseudo},
40 [APCDATA]= {Pseudo},
41 [AUNDEF]= {Break},
42 [AUSEFIELD]= {OK},
43 [ACHECKNIL]= {LeftRead},
44 [AVARDEF]= {Pseudo | RightWrite},
45 [AVARKILL]= {Pseudo | RightWrite},
46
47 // NOP is an internal no-op that also stands
48 // for USED and SET annotations, not the Intel opcode.
49 [ANOP]= {LeftRead | RightWrite},
50
51 [AADCL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
52 [AADCQ]= {SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
53 [AADCW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
54
55 [AADDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
56 [AADDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
57 [AADDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
58 [AADDQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
59
60 [AADDSD]= {SizeD | LeftRead | RightRdwr},
61 [AADDSS]= {SizeF | LeftRead | RightRdwr},
62
63 [AANDB]= {SizeB | LeftRead | RightRdwr | SetCarry},
64 [AANDL]= {SizeL | LeftRead | RightRdwr | SetCarry},
65 [AANDQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
66 [AANDW]= {SizeW | LeftRead | RightRdwr | SetCarry},
67
68 [ACALL]= {RightAddr | Call | KillCarry},
69
70 [ACDQ]= {OK, AX, AX | DX},
71 [ACQO]= {OK, AX, AX | DX},
72 [ACWD]= {OK, AX, AX | DX},
73
74 [ACLD]= {OK},
75 [ASTD]= {OK},
76
77 [ACMPB]= {SizeB | LeftRead | RightRead | SetCarry},
78 [ACMPL]= {SizeL | LeftRead | RightRead | SetCarry},
79 [ACMPQ]= {SizeQ | LeftRead | RightRead | SetCarry},
80 [ACMPW]= {SizeW | LeftRead | RightRead | SetCarry},
81
82 [ACOMISD]= {SizeD | LeftRead | RightRead | SetCarry},
83 [ACOMISS]= {SizeF | LeftRead | RightRead | SetCarry},
84
85 [ACVTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
86 [ACVTSD2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
87 [ACVTSD2SS]= {SizeF | LeftRead | RightWrite | Conv},
88 [ACVTSL2SD]= {SizeD | LeftRead | RightWrite | Conv},
89 [ACVTSL2SS]= {SizeF | LeftRead | RightWrite | Conv},
90 [ACVTSQ2SD]= {SizeD | LeftRead | RightWrite | Conv},
91 [ACVTSQ2SS]= {SizeF | LeftRead | RightWrite | Conv},
92 [ACVTSS2SD]= {SizeD | LeftRead | RightWrite | Conv},
93 [ACVTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
94 [ACVTSS2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
95 [ACVTTSD2SL]= {SizeL | LeftRead | RightWrite | Conv},
96 [ACVTTSD2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
97 [ACVTTSS2SL]= {SizeL | LeftRead | RightWrite | Conv},
98 [ACVTTSS2SQ]= {SizeQ | LeftRead | RightWrite | Conv},
99
100 [ADECB]= {SizeB | RightRdwr},
101 [ADECL]= {SizeL | RightRdwr},
102 [ADECQ]= {SizeQ | RightRdwr},
103 [ADECW]= {SizeW | RightRdwr},
104
105 [ADIVB]= {SizeB | LeftRead | SetCarry, AX, AX},
106 [ADIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
107 [ADIVQ]= {SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
108 [ADIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
109
110 [ADIVSD]= {SizeD | LeftRead | RightRdwr},
111 [ADIVSS]= {SizeF | LeftRead | RightRdwr},
112
113 [AIDIVB]= {SizeB | LeftRead | SetCarry, AX, AX},
114 [AIDIVL]= {SizeL | LeftRead | SetCarry, AX|DX, AX|DX},
115 [AIDIVQ]= {SizeQ | LeftRead | SetCarry, AX|DX, AX|DX},
116 [AIDIVW]= {SizeW | LeftRead | SetCarry, AX|DX, AX|DX},
117
118 [AIMULB]= {SizeB | LeftRead | SetCarry, AX, AX},
119 [AIMULL]= {SizeL | LeftRead | ImulAXDX | SetCarry},
120 [AIMULQ]= {SizeQ | LeftRead | ImulAXDX | SetCarry},
121 [AIMULW]= {SizeW | LeftRead | ImulAXDX | SetCarry},
122
123 [AINCB]= {SizeB | RightRdwr},
124 [AINCL]= {SizeL | RightRdwr},
125 [AINCQ]= {SizeQ | RightRdwr},
126 [AINCW]= {SizeW | RightRdwr},
127
128 [AJCC]= {Cjmp | UseCarry},
129 [AJCS]= {Cjmp | UseCarry},
130 [AJEQ]= {Cjmp | UseCarry},
131 [AJGE]= {Cjmp | UseCarry},
132 [AJGT]= {Cjmp | UseCarry},
133 [AJHI]= {Cjmp | UseCarry},
134 [AJLE]= {Cjmp | UseCarry},
135 [AJLS]= {Cjmp | UseCarry},
136 [AJLT]= {Cjmp | UseCarry},
137 [AJMI]= {Cjmp | UseCarry},
138 [AJNE]= {Cjmp | UseCarry},
139 [AJOC]= {Cjmp | UseCarry},
140 [AJOS]= {Cjmp | UseCarry},
141 [AJPC]= {Cjmp | UseCarry},
142 [AJPL]= {Cjmp | UseCarry},
143 [AJPS]= {Cjmp | UseCarry},
144
145 [AJMP]= {Jump | Break | KillCarry},
146
147 [ALEAL]= {LeftAddr | RightWrite},
148 [ALEAQ]= {LeftAddr | RightWrite},
149
150 [AMOVBLSX]= {SizeL | LeftRead | RightWrite | Conv},
151 [AMOVBLZX]= {SizeL | LeftRead | RightWrite | Conv},
152 [AMOVBQSX]= {SizeQ | LeftRead | RightWrite | Conv},
153 [AMOVBQZX]= {SizeQ | LeftRead | RightWrite | Conv},
154 [AMOVBWSX]= {SizeW | LeftRead | RightWrite | Conv},
155 [AMOVBWZX]= {SizeW | LeftRead | RightWrite | Conv},
156 [AMOVLQSX]= {SizeQ | LeftRead | RightWrite | Conv},
157 [AMOVLQZX]= {SizeQ | LeftRead | RightWrite | Conv},
158 [AMOVWLSX]= {SizeL | LeftRead | RightWrite | Conv},
159 [AMOVWLZX]= {SizeL | LeftRead | RightWrite | Conv},
160 [AMOVWQSX]= {SizeQ | LeftRead | RightWrite | Conv},
161 [AMOVWQZX]= {SizeQ | LeftRead | RightWrite | Conv},
162 [AMOVQL]= {SizeL | LeftRead | RightWrite | Conv},
163
164 [AMOVB]= {SizeB | LeftRead | RightWrite | Move},
165 [AMOVL]= {SizeL | LeftRead | RightWrite | Move},
166 [AMOVQ]= {SizeQ | LeftRead | RightWrite | Move},
167 [AMOVW]= {SizeW | LeftRead | RightWrite | Move},
168
169 [AMOVSB]= {OK, DI|SI, DI|SI},
170 [AMOVSL]= {OK, DI|SI, DI|SI},
171 [AMOVSQ]= {OK, DI|SI, DI|SI},
172 [AMOVSW]= {OK, DI|SI, DI|SI},
173 [ADUFFCOPY]= {OK, DI|SI, DI|SI|CX},
174
175 [AMOVSD]= {SizeD | LeftRead | RightWrite | Move},
176 [AMOVSS]= {SizeF | LeftRead | RightWrite | Move},
177
178 // We use MOVAPD as a faster synonym for MOVSD.
179 [AMOVAPD]= {SizeD | LeftRead | RightWrite | Move},
180
181 [AMULB]= {SizeB | LeftRead | SetCarry, AX, AX},
182 [AMULL]= {SizeL | LeftRead | SetCarry, AX, AX|DX},
183 [AMULQ]= {SizeQ | LeftRead | SetCarry, AX, AX|DX},
184 [AMULW]= {SizeW | LeftRead | SetCarry, AX, AX|DX},
185
186 [AMULSD]= {SizeD | LeftRead | RightRdwr},
187 [AMULSS]= {SizeF | LeftRead | RightRdwr},
188
189 [ANEGB]= {SizeB | RightRdwr | SetCarry},
190 [ANEGL]= {SizeL | RightRdwr | SetCarry},
191 [ANEGQ]= {SizeQ | RightRdwr | SetCarry},
192 [ANEGW]= {SizeW | RightRdwr | SetCarry},
193
194 [ANOTB]= {SizeB | RightRdwr},
195 [ANOTL]= {SizeL | RightRdwr},
196 [ANOTQ]= {SizeQ | RightRdwr},
197 [ANOTW]= {SizeW | RightRdwr},
198
199 [AORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
200 [AORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
201 [AORQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
202 [AORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
203
204 [APOPQ]= {SizeQ | RightWrite},
205 [APUSHQ]= {SizeQ | LeftRead},
206
207 [ARCLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
208 [ARCLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
209 [ARCLQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
210 [ARCLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
211
212 [ARCRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
213 [ARCRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
214 [ARCRQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
215 [ARCRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry | UseCarry},
216
217 [AREP]= {OK, CX, CX},
218 [AREPN]= {OK, CX, CX},
219
220 [ARET]= {Break | KillCarry},
221
222 [AROLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
223 [AROLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
224 [AROLQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
225 [AROLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
226
227 [ARORB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
228 [ARORL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
229 [ARORQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
230 [ARORW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
231
232 [ASALB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
233 [ASALL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
234 [ASALQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
235 [ASALW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
236
237 [ASARB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
238 [ASARL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
239 [ASARQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
240 [ASARW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
241
242 [ASBBB]= {SizeB | LeftRead | RightRdwr | SetCarry | UseCarry},
243 [ASBBL]= {SizeL | LeftRead | RightRdwr | SetCarry | UseCarry},
244 [ASBBQ]= {SizeQ | LeftRead | RightRdwr | SetCarry | UseCarry},
245 [ASBBW]= {SizeW | LeftRead | RightRdwr | SetCarry | UseCarry},
246
247 [ASHLB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
248 [ASHLL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
249 [ASHLQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
250 [ASHLW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
251
252 [ASHRB]= {SizeB | LeftRead | RightRdwr | ShiftCX | SetCarry},
253 [ASHRL]= {SizeL | LeftRead | RightRdwr | ShiftCX | SetCarry},
254 [ASHRQ]= {SizeQ | LeftRead | RightRdwr | ShiftCX | SetCarry},
255 [ASHRW]= {SizeW | LeftRead | RightRdwr | ShiftCX | SetCarry},
256
257 [ASTOSB]= {OK, AX|DI, DI},
258 [ASTOSL]= {OK, AX|DI, DI},
259 [ASTOSQ]= {OK, AX|DI, DI},
260 [ASTOSW]= {OK, AX|DI, DI},
261 [ADUFFZERO]= {OK, AX|DI, DI},
262
263 [ASUBB]= {SizeB | LeftRead | RightRdwr | SetCarry},
264 [ASUBL]= {SizeL | LeftRead | RightRdwr | SetCarry},
265 [ASUBQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
266 [ASUBW]= {SizeW | LeftRead | RightRdwr | SetCarry},
267
268 [ASUBSD]= {SizeD | LeftRead | RightRdwr},
269 [ASUBSS]= {SizeF | LeftRead | RightRdwr},
270
271 [ATESTB]= {SizeB | LeftRead | RightRead | SetCarry},
272 [ATESTL]= {SizeL | LeftRead | RightRead | SetCarry},
273 [ATESTQ]= {SizeQ | LeftRead | RightRead | SetCarry},
274 [ATESTW]= {SizeW | LeftRead | RightRead | SetCarry},
275
276 [AUCOMISD]= {SizeD | LeftRead | RightRead},
277 [AUCOMISS]= {SizeF | LeftRead | RightRead},
278
279 [AXCHGB]= {SizeB | LeftRdwr | RightRdwr},
280 [AXCHGL]= {SizeL | LeftRdwr | RightRdwr},
281 [AXCHGQ]= {SizeQ | LeftRdwr | RightRdwr},
282 [AXCHGW]= {SizeW | LeftRdwr | RightRdwr},
283
284 [AXORB]= {SizeB | LeftRead | RightRdwr | SetCarry},
285 [AXORL]= {SizeL | LeftRead | RightRdwr | SetCarry},
286 [AXORQ]= {SizeQ | LeftRead | RightRdwr | SetCarry},
287 [AXORW]= {SizeW | LeftRead | RightRdwr | SetCarry},
288};
289
290void
291proginfo(ProgInfo *info, Prog *p)
292{
293 *info = progtable[p->as];
294 if(info->flags == 0)
295 fatal("unknown instruction %P", p);
296
297 if((info->flags & ShiftCX) && p->from.type != D_CONST)
298 info->reguse |= CX;
299
300 if(info->flags & ImulAXDX) {
301 if(p->to.type == D_NONE) {
302 info->reguse |= AX;
303 info->regset |= AX | DX;
304 } else {
305 info->flags |= RightRdwr;
306 }
307 }
308
309 // Addressing makes some registers used.
310 if(p->from.type >= D_INDIR)
311 info->regindex |= RtoB(p->from.type-D_INDIR);
312 if(p->from.index != D_NONE)
313 info->regindex |= RtoB(p->from.index);
314 if(p->to.type >= D_INDIR)
315 info->regindex |= RtoB(p->to.type-D_INDIR);
316 if(p->to.index != D_NONE)
317 info->regindex |= RtoB(p->to.index);
318}