1 // 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.
8 "cmd/compile/internal/gc"
10 "cmd/internal/obj/x86"
14 LeftRdwr uint32 = gc.LeftRead | gc.LeftWrite
15 RightRdwr uint32 = gc.RightRead | gc.RightWrite
18 // This table gives the basic information about instruction
19 // generated by the compiler and processed in the optimizer.
20 // See opt.h for bit definitions.
22 // Instructions not generated need not be listed.
23 // As an exception to that rule, we typically write down all the
24 // size variants of an operation even if we just use a subset.
26 // The table is formatted for 8-space tabs.
27 var progtable = [x86.ALAST]obj.ProgInfo{
28 obj.ATYPE: {Flags: gc.Pseudo | gc.Skip},
29 obj.ATEXT: {Flags: gc.Pseudo},
30 obj.AFUNCDATA: {Flags: gc.Pseudo},
31 obj.APCDATA: {Flags: gc.Pseudo},
32 obj.AUNDEF: {Flags: gc.Break},
33 obj.AUSEFIELD: {Flags: gc.OK},
34 obj.ACHECKNIL: {Flags: gc.LeftRead},
35 obj.AVARDEF: {Flags: gc.Pseudo | gc.RightWrite},
36 obj.AVARKILL: {Flags: gc.Pseudo | gc.RightWrite},
38 // NOP is an internal no-op that also stands
39 // for USED and SET annotations, not the Intel opcode.
40 obj.ANOP: {Flags: gc.LeftRead | gc.RightWrite},
41 x86.AADCL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
42 x86.AADCQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
43 x86.AADCW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
44 x86.AADDB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry},
45 x86.AADDL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry},
46 x86.AADDW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
47 x86.AADDQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry},
48 x86.AADDSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
49 x86.AADDSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
50 x86.AANDB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry},
51 x86.AANDL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry},
52 x86.AANDQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry},
53 x86.AANDW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
54 obj.ACALL: {Flags: gc.RightAddr | gc.Call | gc.KillCarry},
55 x86.ACDQ: {Flags: gc.OK, Reguse: AX, Regset: AX | DX},
56 x86.ACQO: {Flags: gc.OK, Reguse: AX, Regset: AX | DX},
57 x86.ACWD: {Flags: gc.OK, Reguse: AX, Regset: AX | DX},
58 x86.ACLD: {Flags: gc.OK},
59 x86.ASTD: {Flags: gc.OK},
60 x86.ACMPB: {Flags: gc.SizeB | gc.LeftRead | gc.RightRead | gc.SetCarry},
61 x86.ACMPL: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead | gc.SetCarry},
62 x86.ACMPQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead | gc.SetCarry},
63 x86.ACMPW: {Flags: gc.SizeW | gc.LeftRead | gc.RightRead | gc.SetCarry},
64 x86.ACOMISD: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead | gc.SetCarry},
65 x86.ACOMISS: {Flags: gc.SizeF | gc.LeftRead | gc.RightRead | gc.SetCarry},
66 x86.ACVTSD2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
67 x86.ACVTSD2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
68 x86.ACVTSD2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv},
69 x86.ACVTSL2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
70 x86.ACVTSL2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv},
71 x86.ACVTSQ2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
72 x86.ACVTSQ2SS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Conv},
73 x86.ACVTSS2SD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Conv},
74 x86.ACVTSS2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
75 x86.ACVTSS2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
76 x86.ACVTTSD2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
77 x86.ACVTTSD2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
78 x86.ACVTTSS2SL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
79 x86.ACVTTSS2SQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
80 x86.ADECB: {Flags: gc.SizeB | RightRdwr},
81 x86.ADECL: {Flags: gc.SizeL | RightRdwr},
82 x86.ADECQ: {Flags: gc.SizeQ | RightRdwr},
83 x86.ADECW: {Flags: gc.SizeW | RightRdwr},
84 x86.ADIVB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX},
85 x86.ADIVL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
86 x86.ADIVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
87 x86.ADIVW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
88 x86.ADIVSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
89 x86.ADIVSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
90 x86.AIDIVB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX},
91 x86.AIDIVL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
92 x86.AIDIVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
93 x86.AIDIVW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX | DX, Regset: AX | DX},
94 x86.AIMULB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX},
95 x86.AIMULL: {Flags: gc.SizeL | gc.LeftRead | gc.ImulAXDX | gc.SetCarry},
96 x86.AIMULQ: {Flags: gc.SizeQ | gc.LeftRead | gc.ImulAXDX | gc.SetCarry},
97 x86.AIMULW: {Flags: gc.SizeW | gc.LeftRead | gc.ImulAXDX | gc.SetCarry},
98 x86.AINCB: {Flags: gc.SizeB | RightRdwr},
99 x86.AINCL: {Flags: gc.SizeL | RightRdwr},
100 x86.AINCQ: {Flags: gc.SizeQ | RightRdwr},
101 x86.AINCW: {Flags: gc.SizeW | RightRdwr},
102 x86.AJCC: {Flags: gc.Cjmp | gc.UseCarry},
103 x86.AJCS: {Flags: gc.Cjmp | gc.UseCarry},
104 x86.AJEQ: {Flags: gc.Cjmp | gc.UseCarry},
105 x86.AJGE: {Flags: gc.Cjmp | gc.UseCarry},
106 x86.AJGT: {Flags: gc.Cjmp | gc.UseCarry},
107 x86.AJHI: {Flags: gc.Cjmp | gc.UseCarry},
108 x86.AJLE: {Flags: gc.Cjmp | gc.UseCarry},
109 x86.AJLS: {Flags: gc.Cjmp | gc.UseCarry},
110 x86.AJLT: {Flags: gc.Cjmp | gc.UseCarry},
111 x86.AJMI: {Flags: gc.Cjmp | gc.UseCarry},
112 x86.AJNE: {Flags: gc.Cjmp | gc.UseCarry},
113 x86.AJOC: {Flags: gc.Cjmp | gc.UseCarry},
114 x86.AJOS: {Flags: gc.Cjmp | gc.UseCarry},
115 x86.AJPC: {Flags: gc.Cjmp | gc.UseCarry},
116 x86.AJPL: {Flags: gc.Cjmp | gc.UseCarry},
117 x86.AJPS: {Flags: gc.Cjmp | gc.UseCarry},
118 obj.AJMP: {Flags: gc.Jump | gc.Break | gc.KillCarry},
119 x86.ALEAW: {Flags: gc.LeftAddr | gc.RightWrite},
120 x86.ALEAL: {Flags: gc.LeftAddr | gc.RightWrite},
121 x86.ALEAQ: {Flags: gc.LeftAddr | gc.RightWrite},
122 x86.AMOVBLSX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
123 x86.AMOVBLZX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
124 x86.AMOVBQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
125 x86.AMOVBQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
126 x86.AMOVBWSX: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Conv},
127 x86.AMOVBWZX: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Conv},
128 x86.AMOVLQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
129 x86.AMOVLQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
130 x86.AMOVWLSX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
131 x86.AMOVWLZX: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
132 x86.AMOVWQSX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
133 x86.AMOVWQZX: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Conv},
134 x86.AMOVQL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Conv},
135 x86.AMOVB: {Flags: gc.SizeB | gc.LeftRead | gc.RightWrite | gc.Move},
136 x86.AMOVL: {Flags: gc.SizeL | gc.LeftRead | gc.RightWrite | gc.Move},
137 x86.AMOVQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move},
138 x86.AMOVW: {Flags: gc.SizeW | gc.LeftRead | gc.RightWrite | gc.Move},
139 x86.AMOVUPS: {Flags: gc.LeftRead | gc.RightWrite | gc.Move},
140 x86.AMOVSB: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
141 x86.AMOVSL: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
142 x86.AMOVSQ: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
143 x86.AMOVSW: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI},
144 obj.ADUFFCOPY: {Flags: gc.OK, Reguse: DI | SI, Regset: DI | SI | X0},
145 x86.AMOVSD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move},
146 x86.AMOVSS: {Flags: gc.SizeF | gc.LeftRead | gc.RightWrite | gc.Move},
148 // We use MOVAPD as a faster synonym for MOVSD.
149 x86.AMOVAPD: {Flags: gc.SizeD | gc.LeftRead | gc.RightWrite | gc.Move},
150 x86.AMULB: {Flags: gc.SizeB | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX},
151 x86.AMULL: {Flags: gc.SizeL | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX},
152 x86.AMULQ: {Flags: gc.SizeQ | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX},
153 x86.AMULW: {Flags: gc.SizeW | gc.LeftRead | gc.SetCarry, Reguse: AX, Regset: AX | DX},
154 x86.AMULSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
155 x86.AMULSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
156 x86.ANEGB: {Flags: gc.SizeB | RightRdwr | gc.SetCarry},
157 x86.ANEGL: {Flags: gc.SizeL | RightRdwr | gc.SetCarry},
158 x86.ANEGQ: {Flags: gc.SizeQ | RightRdwr | gc.SetCarry},
159 x86.ANEGW: {Flags: gc.SizeW | RightRdwr | gc.SetCarry},
160 x86.ANOTB: {Flags: gc.SizeB | RightRdwr},
161 x86.ANOTL: {Flags: gc.SizeL | RightRdwr},
162 x86.ANOTQ: {Flags: gc.SizeQ | RightRdwr},
163 x86.ANOTW: {Flags: gc.SizeW | RightRdwr},
164 x86.AORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry},
165 x86.AORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry},
166 x86.AORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry},
167 x86.AORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
168 x86.APOPQ: {Flags: gc.SizeQ | gc.RightWrite},
169 x86.APUSHQ: {Flags: gc.SizeQ | gc.LeftRead},
170 x86.APXOR: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
171 x86.ARCLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
172 x86.ARCLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
173 x86.ARCLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
174 x86.ARCLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
175 x86.ARCRB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
176 x86.ARCRL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
177 x86.ARCRQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
178 x86.ARCRW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry | gc.UseCarry},
179 x86.AREP: {Flags: gc.OK, Reguse: CX, Regset: CX},
180 x86.AREPN: {Flags: gc.OK, Reguse: CX, Regset: CX},
181 obj.ARET: {Flags: gc.Break | gc.KillCarry},
182 x86.AROLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
183 x86.AROLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
184 x86.AROLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
185 x86.AROLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
186 x86.ARORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
187 x86.ARORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
188 x86.ARORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
189 x86.ARORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
190 x86.ASALB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
191 x86.ASALL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
192 x86.ASALQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
193 x86.ASALW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
194 x86.ASARB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
195 x86.ASARL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
196 x86.ASARQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
197 x86.ASARW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
198 x86.ASBBB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
199 x86.ASBBL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
200 x86.ASBBQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
201 x86.ASBBW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry | gc.UseCarry},
202 x86.ASETCC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
203 x86.ASETCS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
204 x86.ASETEQ: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
205 x86.ASETGE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
206 x86.ASETGT: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
207 x86.ASETHI: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
208 x86.ASETLE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
209 x86.ASETLS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
210 x86.ASETLT: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
211 x86.ASETMI: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
212 x86.ASETNE: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
213 x86.ASETOC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
214 x86.ASETOS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
215 x86.ASETPC: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
216 x86.ASETPL: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
217 x86.ASETPS: {Flags: gc.SizeB | gc.RightWrite | gc.UseCarry},
218 x86.ASHLB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
219 x86.ASHLL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
220 x86.ASHLQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
221 x86.ASHLW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
222 x86.ASHRB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
223 x86.ASHRL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
224 x86.ASHRQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
225 x86.ASHRW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.ShiftCX | gc.SetCarry},
226 x86.ASQRTSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
227 x86.ASTOSB: {Flags: gc.OK, Reguse: AX | DI, Regset: DI},
228 x86.ASTOSL: {Flags: gc.OK, Reguse: AX | DI, Regset: DI},
229 x86.ASTOSQ: {Flags: gc.OK, Reguse: AX | DI, Regset: DI},
230 x86.ASTOSW: {Flags: gc.OK, Reguse: AX | DI, Regset: DI},
231 obj.ADUFFZERO: {Flags: gc.OK, Reguse: X0 | DI, Regset: DI},
232 x86.ASUBB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry},
233 x86.ASUBL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry},
234 x86.ASUBQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry},
235 x86.ASUBW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
236 x86.ASUBSD: {Flags: gc.SizeD | gc.LeftRead | RightRdwr},
237 x86.ASUBSS: {Flags: gc.SizeF | gc.LeftRead | RightRdwr},
238 x86.ATESTB: {Flags: gc.SizeB | gc.LeftRead | gc.RightRead | gc.SetCarry},
239 x86.ATESTL: {Flags: gc.SizeL | gc.LeftRead | gc.RightRead | gc.SetCarry},
240 x86.ATESTQ: {Flags: gc.SizeQ | gc.LeftRead | gc.RightRead | gc.SetCarry},
241 x86.ATESTW: {Flags: gc.SizeW | gc.LeftRead | gc.RightRead | gc.SetCarry},
242 x86.AUCOMISD: {Flags: gc.SizeD | gc.LeftRead | gc.RightRead},
243 x86.AUCOMISS: {Flags: gc.SizeF | gc.LeftRead | gc.RightRead},
244 x86.AXCHGB: {Flags: gc.SizeB | LeftRdwr | RightRdwr},
245 x86.AXCHGL: {Flags: gc.SizeL | LeftRdwr | RightRdwr},
246 x86.AXCHGQ: {Flags: gc.SizeQ | LeftRdwr | RightRdwr},
247 x86.AXCHGW: {Flags: gc.SizeW | LeftRdwr | RightRdwr},
248 x86.AXORB: {Flags: gc.SizeB | gc.LeftRead | RightRdwr | gc.SetCarry},
249 x86.AXORL: {Flags: gc.SizeL | gc.LeftRead | RightRdwr | gc.SetCarry},
250 x86.AXORQ: {Flags: gc.SizeQ | gc.LeftRead | RightRdwr | gc.SetCarry},
251 x86.AXORW: {Flags: gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry},
252 x86.AXORPS: {Flags: gc.LeftRead | RightRdwr},
255 func progflags(p *obj.Prog) uint32 {
256 flags := progtable[p.As].Flags
257 if flags&gc.ImulAXDX != 0 && p.To.Type != obj.TYPE_NONE {
263 func progcarryflags(p *obj.Prog) uint32 {
264 return progtable[p.As].Flags
267 func proginfo(p *obj.Prog) {
269 *info = progtable[p.As]
271 gc.Fatalf("unknown instruction %v", p)
274 if (info.Flags&gc.ShiftCX != 0) && p.From.Type != obj.TYPE_CONST {
278 if info.Flags&gc.ImulAXDX != 0 {
279 if p.To.Type == obj.TYPE_NONE {
281 info.Regset |= AX | DX
283 info.Flags |= RightRdwr
287 // Addressing makes some registers used.
288 if p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_NONE {
289 info.Regindex |= RtoB(int(p.From.Reg))
291 if p.From.Index != x86.REG_NONE {
292 info.Regindex |= RtoB(int(p.From.Index))
294 if p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_NONE {
295 info.Regindex |= RtoB(int(p.To.Reg))
297 if p.To.Index != x86.REG_NONE {
298 info.Regindex |= RtoB(int(p.To.Index))
300 if gc.Ctxt.Flag_dynlink {
301 // When -dynlink is passed, many operations on external names (and
302 // also calling duffzero/duffcopy) use R15 as a scratch register.
303 if p.As == x86.ALEAQ || info.Flags == gc.Pseudo || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
306 if p.As == obj.ADUFFZERO || p.As == obj.ADUFFCOPY || (p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local) || (p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local) {