Source file src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
1
2
3
4
5 package x86asm
6
7 import (
8 "fmt"
9 "strings"
10 )
11
12 type SymLookup func(uint64) (string, uint64)
13
14
15
16
17
18
19
20
21 func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
22 if symname == nil {
23 symname = func(uint64) (string, uint64) { return "", 0 }
24 }
25 var args []string
26 for i := len(inst.Args) - 1; i >= 0; i-- {
27 a := inst.Args[i]
28 if a == nil {
29 continue
30 }
31 args = append(args, plan9Arg(&inst, pc, symname, a))
32 }
33
34 var rep string
35 var last Prefix
36 for _, p := range inst.Prefix {
37 if p == 0 || p.IsREX() || p.IsVEX() {
38 break
39 }
40
41 switch {
42
43 case p&0xFF00 == PrefixImplicit:
44 continue
45
46
47 case p&0xFF == PrefixREP:
48 rep = "REP; "
49 case p&0xFF == PrefixREPN:
50 rep = "REPNE; "
51 default:
52 last = p
53 }
54 }
55
56 prefix := ""
57 switch last & 0xFF {
58 case 0, 0x66, 0x67:
59
60 default:
61 prefix += last.String() + " "
62 }
63
64 op := inst.Op.String()
65 if plan9Suffix[inst.Op] {
66 s := inst.DataSize
67 if inst.MemBytes != 0 {
68 s = inst.MemBytes * 8
69 }
70 switch s {
71 case 8:
72 op += "B"
73 case 16:
74 op += "W"
75 case 32:
76 op += "L"
77 case 64:
78 op += "Q"
79 }
80 }
81
82 if args != nil {
83 op += " " + strings.Join(args, ", ")
84 }
85
86 return rep + prefix + op
87 }
88
89 func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
90 switch a := arg.(type) {
91 case Reg:
92 return plan9Reg[a]
93 case Rel:
94 if pc == 0 {
95 break
96 }
97
98
99
100
101
102 addr := pc + uint64(inst.Len) + uint64(a)
103 if s, base := symname(addr); s != "" && addr == base {
104 return fmt.Sprintf("%s(SB)", s)
105 }
106 return fmt.Sprintf("%#x", addr)
107
108 case Imm:
109 if s, base := symname(uint64(a)); s != "" {
110 suffix := ""
111 if uint64(a) != base {
112 suffix = fmt.Sprintf("%+d", uint64(a)-base)
113 }
114 return fmt.Sprintf("$%s%s(SB)", s, suffix)
115 }
116 if inst.Mode == 32 {
117 return fmt.Sprintf("$%#x", uint32(a))
118 }
119 if Imm(int32(a)) == a {
120 return fmt.Sprintf("$%#x", int64(a))
121 }
122 return fmt.Sprintf("$%#x", uint64(a))
123 case Mem:
124 if s, disp := memArgToSymbol(a, pc, inst.Len, symname); s != "" {
125 suffix := ""
126 if disp != 0 {
127 suffix = fmt.Sprintf("%+d", disp)
128 }
129 return fmt.Sprintf("%s%s(SB)", s, suffix)
130 }
131 s := ""
132 if a.Segment != 0 {
133 s += fmt.Sprintf("%s:", plan9Reg[a.Segment])
134 }
135 if a.Disp != 0 {
136 s += fmt.Sprintf("%#x", a.Disp)
137 } else {
138 s += "0"
139 }
140 if a.Base != 0 {
141 s += fmt.Sprintf("(%s)", plan9Reg[a.Base])
142 }
143 if a.Index != 0 && a.Scale != 0 {
144 s += fmt.Sprintf("(%s*%d)", plan9Reg[a.Index], a.Scale)
145 }
146 return s
147 }
148 return arg.String()
149 }
150
151 func memArgToSymbol(a Mem, pc uint64, instrLen int, symname SymLookup) (string, int64) {
152 if a.Segment != 0 || a.Disp == 0 || a.Index != 0 || a.Scale != 0 {
153 return "", 0
154 }
155
156 var disp uint64
157 switch a.Base {
158 case IP, EIP, RIP:
159 disp = uint64(a.Disp + int64(pc) + int64(instrLen))
160 case 0:
161 disp = uint64(a.Disp)
162 default:
163 return "", 0
164 }
165
166 s, base := symname(disp)
167 return s, int64(disp) - int64(base)
168 }
169
170 var plan9Suffix = [maxOp + 1]bool{
171 ADC: true,
172 ADD: true,
173 AND: true,
174 BSF: true,
175 BSR: true,
176 BT: true,
177 BTC: true,
178 BTR: true,
179 BTS: true,
180 CMP: true,
181 CMPXCHG: true,
182 CVTSI2SD: true,
183 CVTSI2SS: true,
184 CVTSD2SI: true,
185 CVTSS2SI: true,
186 CVTTSD2SI: true,
187 CVTTSS2SI: true,
188 DEC: true,
189 DIV: true,
190 FLDENV: true,
191 FRSTOR: true,
192 IDIV: true,
193 IMUL: true,
194 IN: true,
195 INC: true,
196 LEA: true,
197 MOV: true,
198 MOVNTI: true,
199 MUL: true,
200 NEG: true,
201 NOP: true,
202 NOT: true,
203 OR: true,
204 OUT: true,
205 POP: true,
206 POPA: true,
207 PUSH: true,
208 PUSHA: true,
209 RCL: true,
210 RCR: true,
211 ROL: true,
212 ROR: true,
213 SAR: true,
214 SBB: true,
215 SHL: true,
216 SHLD: true,
217 SHR: true,
218 SHRD: true,
219 SUB: true,
220 TEST: true,
221 XADD: true,
222 XCHG: true,
223 XOR: true,
224 }
225
226 var plan9Reg = [...]string{
227 AL: "AL",
228 CL: "CL",
229 BL: "BL",
230 DL: "DL",
231 AH: "AH",
232 CH: "CH",
233 BH: "BH",
234 DH: "DH",
235 SPB: "SP",
236 BPB: "BP",
237 SIB: "SI",
238 DIB: "DI",
239 R8B: "R8",
240 R9B: "R9",
241 R10B: "R10",
242 R11B: "R11",
243 R12B: "R12",
244 R13B: "R13",
245 R14B: "R14",
246 R15B: "R15",
247 AX: "AX",
248 CX: "CX",
249 BX: "BX",
250 DX: "DX",
251 SP: "SP",
252 BP: "BP",
253 SI: "SI",
254 DI: "DI",
255 R8W: "R8",
256 R9W: "R9",
257 R10W: "R10",
258 R11W: "R11",
259 R12W: "R12",
260 R13W: "R13",
261 R14W: "R14",
262 R15W: "R15",
263 EAX: "AX",
264 ECX: "CX",
265 EDX: "DX",
266 EBX: "BX",
267 ESP: "SP",
268 EBP: "BP",
269 ESI: "SI",
270 EDI: "DI",
271 R8L: "R8",
272 R9L: "R9",
273 R10L: "R10",
274 R11L: "R11",
275 R12L: "R12",
276 R13L: "R13",
277 R14L: "R14",
278 R15L: "R15",
279 RAX: "AX",
280 RCX: "CX",
281 RDX: "DX",
282 RBX: "BX",
283 RSP: "SP",
284 RBP: "BP",
285 RSI: "SI",
286 RDI: "DI",
287 R8: "R8",
288 R9: "R9",
289 R10: "R10",
290 R11: "R11",
291 R12: "R12",
292 R13: "R13",
293 R14: "R14",
294 R15: "R15",
295 IP: "IP",
296 EIP: "IP",
297 RIP: "IP",
298 F0: "F0",
299 F1: "F1",
300 F2: "F2",
301 F3: "F3",
302 F4: "F4",
303 F5: "F5",
304 F6: "F6",
305 F7: "F7",
306 M0: "M0",
307 M1: "M1",
308 M2: "M2",
309 M3: "M3",
310 M4: "M4",
311 M5: "M5",
312 M6: "M6",
313 M7: "M7",
314 X0: "X0",
315 X1: "X1",
316 X2: "X2",
317 X3: "X3",
318 X4: "X4",
319 X5: "X5",
320 X6: "X6",
321 X7: "X7",
322 X8: "X8",
323 X9: "X9",
324 X10: "X10",
325 X11: "X11",
326 X12: "X12",
327 X13: "X13",
328 X14: "X14",
329 X15: "X15",
330 CS: "CS",
331 SS: "SS",
332 DS: "DS",
333 ES: "ES",
334 FS: "FS",
335 GS: "GS",
336 GDTR: "GDTR",
337 IDTR: "IDTR",
338 LDTR: "LDTR",
339 MSW: "MSW",
340 TASK: "TASK",
341 CR0: "CR0",
342 CR1: "CR1",
343 CR2: "CR2",
344 CR3: "CR3",
345 CR4: "CR4",
346 CR5: "CR5",
347 CR6: "CR6",
348 CR7: "CR7",
349 CR8: "CR8",
350 CR9: "CR9",
351 CR10: "CR10",
352 CR11: "CR11",
353 CR12: "CR12",
354 CR13: "CR13",
355 CR14: "CR14",
356 CR15: "CR15",
357 DR0: "DR0",
358 DR1: "DR1",
359 DR2: "DR2",
360 DR3: "DR3",
361 DR4: "DR4",
362 DR5: "DR5",
363 DR6: "DR6",
364 DR7: "DR7",
365 DR8: "DR8",
366 DR9: "DR9",
367 DR10: "DR10",
368 DR11: "DR11",
369 DR12: "DR12",
370 DR13: "DR13",
371 DR14: "DR14",
372 DR15: "DR15",
373 TR0: "TR0",
374 TR1: "TR1",
375 TR2: "TR2",
376 TR3: "TR3",
377 TR4: "TR4",
378 TR5: "TR5",
379 TR6: "TR6",
380 TR7: "TR7",
381 }
382
View as plain text