instructions.go raw
1 //
2 // Copyright 2024 CloudWeGo Authors
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 // Code generated by "mkasm_amd64.py", DO NOT EDIT.
18
19 package x86_64
20
21 // ADDQ performs "Add".
22 //
23 // Mnemonic : ADD
24 // Supported forms : (8 forms)
25 //
26 // - ADDQ imm32, rax
27 // - ADDQ imm8, r64
28 // - ADDQ imm32, r64
29 // - ADDQ r64, r64
30 // - ADDQ m64, r64
31 // - ADDQ imm8, m64
32 // - ADDQ imm32, m64
33 // - ADDQ r64, m64
34 func (self *Program) ADDQ(v0 interface{}, v1 interface{}) *Instruction {
35 p := self.alloc("ADDQ", 2, Operands{v0, v1})
36 // ADDQ imm32, rax
37 if isImm32(v0) && v1 == RAX {
38 p.domain = DomainGeneric
39 p.add(0, func(m *_Encoding, v []interface{}) {
40 m.emit(0x48)
41 m.emit(0x05)
42 m.imm4(toImmAny(v[0]))
43 })
44 }
45 // ADDQ imm8, r64
46 if isImm8Ext(v0, 8) && isReg64(v1) {
47 p.domain = DomainGeneric
48 p.add(0, func(m *_Encoding, v []interface{}) {
49 m.emit(0x48 | hcode(v[1]))
50 m.emit(0x83)
51 m.emit(0xc0 | lcode(v[1]))
52 m.imm1(toImmAny(v[0]))
53 })
54 }
55 // ADDQ imm32, r64
56 if isImm32Ext(v0, 8) && isReg64(v1) {
57 p.domain = DomainGeneric
58 p.add(0, func(m *_Encoding, v []interface{}) {
59 m.emit(0x48 | hcode(v[1]))
60 m.emit(0x81)
61 m.emit(0xc0 | lcode(v[1]))
62 m.imm4(toImmAny(v[0]))
63 })
64 }
65 // ADDQ r64, r64
66 if isReg64(v0) && isReg64(v1) {
67 p.domain = DomainGeneric
68 p.add(0, func(m *_Encoding, v []interface{}) {
69 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
70 m.emit(0x01)
71 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
72 })
73 p.add(0, func(m *_Encoding, v []interface{}) {
74 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
75 m.emit(0x03)
76 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
77 })
78 }
79 // ADDQ m64, r64
80 if isM64(v0) && isReg64(v1) {
81 p.domain = DomainGeneric
82 p.add(0, func(m *_Encoding, v []interface{}) {
83 m.rexm(1, hcode(v[1]), addr(v[0]))
84 m.emit(0x03)
85 m.mrsd(lcode(v[1]), addr(v[0]), 1)
86 })
87 }
88 // ADDQ imm8, m64
89 if isImm8Ext(v0, 8) && isM64(v1) {
90 p.domain = DomainGeneric
91 p.add(0, func(m *_Encoding, v []interface{}) {
92 m.rexm(1, 0, addr(v[1]))
93 m.emit(0x83)
94 m.mrsd(0, addr(v[1]), 1)
95 m.imm1(toImmAny(v[0]))
96 })
97 }
98 // ADDQ imm32, m64
99 if isImm32Ext(v0, 8) && isM64(v1) {
100 p.domain = DomainGeneric
101 p.add(0, func(m *_Encoding, v []interface{}) {
102 m.rexm(1, 0, addr(v[1]))
103 m.emit(0x81)
104 m.mrsd(0, addr(v[1]), 1)
105 m.imm4(toImmAny(v[0]))
106 })
107 }
108 // ADDQ r64, m64
109 if isReg64(v0) && isM64(v1) {
110 p.domain = DomainGeneric
111 p.add(0, func(m *_Encoding, v []interface{}) {
112 m.rexm(1, hcode(v[0]), addr(v[1]))
113 m.emit(0x01)
114 m.mrsd(lcode(v[0]), addr(v[1]), 1)
115 })
116 }
117 if p.len == 0 {
118 panic("invalid operands for ADDQ")
119 }
120 return p
121 }
122
123 // CALLQ performs "Call Procedure".
124 //
125 // Mnemonic : CALL
126 // Supported forms : (2 forms)
127 //
128 // - CALLQ r64
129 // - CALLQ m64
130 func (self *Program) CALLQ(v0 interface{}) *Instruction {
131 p := self.alloc("CALLQ", 1, Operands{v0})
132 // CALLQ r64
133 if isReg64(v0) {
134 p.domain = DomainGeneric
135 p.add(0, func(m *_Encoding, v []interface{}) {
136 m.rexo(0, v[0], false)
137 m.emit(0xff)
138 m.emit(0xd0 | lcode(v[0]))
139 })
140 }
141 // CALLQ m64
142 if isM64(v0) {
143 p.domain = DomainGeneric
144 p.add(0, func(m *_Encoding, v []interface{}) {
145 m.rexo(0, addr(v[0]), false)
146 m.emit(0xff)
147 m.mrsd(2, addr(v[0]), 1)
148 })
149 }
150 if p.len == 0 {
151 panic("invalid operands for CALLQ")
152 }
153 return p
154 }
155
156 // CMPQ performs "Compare Two Operands".
157 //
158 // Mnemonic : CMP
159 // Supported forms : (8 forms)
160 //
161 // - CMPQ imm32, rax
162 // - CMPQ imm8, r64
163 // - CMPQ imm32, r64
164 // - CMPQ r64, r64
165 // - CMPQ m64, r64
166 // - CMPQ imm8, m64
167 // - CMPQ imm32, m64
168 // - CMPQ r64, m64
169 func (self *Program) CMPQ(v0 interface{}, v1 interface{}) *Instruction {
170 p := self.alloc("CMPQ", 2, Operands{v0, v1})
171 // CMPQ imm32, rax
172 if isImm32(v0) && v1 == RAX {
173 p.domain = DomainGeneric
174 p.add(0, func(m *_Encoding, v []interface{}) {
175 m.emit(0x48)
176 m.emit(0x3d)
177 m.imm4(toImmAny(v[0]))
178 })
179 }
180 // CMPQ imm8, r64
181 if isImm8Ext(v0, 8) && isReg64(v1) {
182 p.domain = DomainGeneric
183 p.add(0, func(m *_Encoding, v []interface{}) {
184 m.emit(0x48 | hcode(v[1]))
185 m.emit(0x83)
186 m.emit(0xf8 | lcode(v[1]))
187 m.imm1(toImmAny(v[0]))
188 })
189 }
190 // CMPQ imm32, r64
191 if isImm32Ext(v0, 8) && isReg64(v1) {
192 p.domain = DomainGeneric
193 p.add(0, func(m *_Encoding, v []interface{}) {
194 m.emit(0x48 | hcode(v[1]))
195 m.emit(0x81)
196 m.emit(0xf8 | lcode(v[1]))
197 m.imm4(toImmAny(v[0]))
198 })
199 }
200 // CMPQ r64, r64
201 if isReg64(v0) && isReg64(v1) {
202 p.domain = DomainGeneric
203 p.add(0, func(m *_Encoding, v []interface{}) {
204 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
205 m.emit(0x39)
206 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
207 })
208 p.add(0, func(m *_Encoding, v []interface{}) {
209 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
210 m.emit(0x3b)
211 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
212 })
213 }
214 // CMPQ m64, r64
215 if isM64(v0) && isReg64(v1) {
216 p.domain = DomainGeneric
217 p.add(0, func(m *_Encoding, v []interface{}) {
218 m.rexm(1, hcode(v[1]), addr(v[0]))
219 m.emit(0x3b)
220 m.mrsd(lcode(v[1]), addr(v[0]), 1)
221 })
222 }
223 // CMPQ imm8, m64
224 if isImm8Ext(v0, 8) && isM64(v1) {
225 p.domain = DomainGeneric
226 p.add(0, func(m *_Encoding, v []interface{}) {
227 m.rexm(1, 0, addr(v[1]))
228 m.emit(0x83)
229 m.mrsd(7, addr(v[1]), 1)
230 m.imm1(toImmAny(v[0]))
231 })
232 }
233 // CMPQ imm32, m64
234 if isImm32Ext(v0, 8) && isM64(v1) {
235 p.domain = DomainGeneric
236 p.add(0, func(m *_Encoding, v []interface{}) {
237 m.rexm(1, 0, addr(v[1]))
238 m.emit(0x81)
239 m.mrsd(7, addr(v[1]), 1)
240 m.imm4(toImmAny(v[0]))
241 })
242 }
243 // CMPQ r64, m64
244 if isReg64(v0) && isM64(v1) {
245 p.domain = DomainGeneric
246 p.add(0, func(m *_Encoding, v []interface{}) {
247 m.rexm(1, hcode(v[0]), addr(v[1]))
248 m.emit(0x39)
249 m.mrsd(lcode(v[0]), addr(v[1]), 1)
250 })
251 }
252 if p.len == 0 {
253 panic("invalid operands for CMPQ")
254 }
255 return p
256 }
257
258 // JBE performs "Jump if below or equal (CF == 1 or ZF == 1)".
259 //
260 // Mnemonic : JBE
261 // Supported forms : (2 forms)
262 //
263 // - JBE rel8
264 // - JBE rel32
265 func (self *Program) JBE(v0 interface{}) *Instruction {
266 p := self.alloc("JBE", 1, Operands{v0})
267 p.branch = _B_conditional
268 // JBE rel8
269 if isRel8(v0) {
270 p.domain = DomainGeneric
271 p.add(0, func(m *_Encoding, v []interface{}) {
272 m.emit(0x76)
273 m.imm1(relv(v[0]))
274 })
275 }
276 // JBE rel32
277 if isRel32(v0) {
278 p.domain = DomainGeneric
279 p.add(0, func(m *_Encoding, v []interface{}) {
280 m.emit(0x0f)
281 m.emit(0x86)
282 m.imm4(relv(v[0]))
283 })
284 }
285 // JBE label
286 if isLabel(v0) {
287 p.add(_F_rel1, func(m *_Encoding, v []interface{}) {
288 m.emit(0x76)
289 m.imm1(relv(v[0]))
290 })
291 p.add(_F_rel4, func(m *_Encoding, v []interface{}) {
292 m.emit(0x0f)
293 m.emit(0x86)
294 m.imm4(relv(v[0]))
295 })
296 }
297 if p.len == 0 {
298 panic("invalid operands for JBE")
299 }
300 return p
301 }
302
303 // JMP performs "Jump Unconditionally".
304 //
305 // Mnemonic : JMP
306 // Supported forms : (2 forms)
307 //
308 // - JMP rel8
309 // - JMP rel32
310 func (self *Program) JMP(v0 interface{}) *Instruction {
311 p := self.alloc("JMP", 1, Operands{v0})
312 p.branch = _B_unconditional
313 // JMP rel8
314 if isRel8(v0) {
315 p.domain = DomainGeneric
316 p.add(0, func(m *_Encoding, v []interface{}) {
317 m.emit(0xeb)
318 m.imm1(relv(v[0]))
319 })
320 }
321 // JMP rel32
322 if isRel32(v0) {
323 p.domain = DomainGeneric
324 p.add(0, func(m *_Encoding, v []interface{}) {
325 m.emit(0xe9)
326 m.imm4(relv(v[0]))
327 })
328 }
329 // JMP label
330 if isLabel(v0) {
331 p.add(_F_rel1, func(m *_Encoding, v []interface{}) {
332 m.emit(0xeb)
333 m.imm1(relv(v[0]))
334 })
335 p.add(_F_rel4, func(m *_Encoding, v []interface{}) {
336 m.emit(0xe9)
337 m.imm4(relv(v[0]))
338 })
339 }
340 if p.len == 0 {
341 panic("invalid operands for JMP")
342 }
343 return p
344 }
345
346 // JMPQ performs "Jump Unconditionally".
347 //
348 // Mnemonic : JMP
349 // Supported forms : (2 forms)
350 //
351 // - JMPQ r64
352 // - JMPQ m64
353 func (self *Program) JMPQ(v0 interface{}) *Instruction {
354 p := self.alloc("JMPQ", 1, Operands{v0})
355 // JMPQ r64
356 if isReg64(v0) {
357 p.domain = DomainGeneric
358 p.add(0, func(m *_Encoding, v []interface{}) {
359 m.rexo(0, v[0], false)
360 m.emit(0xff)
361 m.emit(0xe0 | lcode(v[0]))
362 })
363 }
364 // JMPQ m64
365 if isM64(v0) {
366 p.domain = DomainGeneric
367 p.add(0, func(m *_Encoding, v []interface{}) {
368 m.rexo(0, addr(v[0]), false)
369 m.emit(0xff)
370 m.mrsd(4, addr(v[0]), 1)
371 })
372 }
373 if p.len == 0 {
374 panic("invalid operands for JMPQ")
375 }
376 return p
377 }
378
379 // LEAQ performs "Load Effective Address".
380 //
381 // Mnemonic : LEA
382 // Supported forms : (1 form)
383 //
384 // - LEAQ m, r64
385 func (self *Program) LEAQ(v0 interface{}, v1 interface{}) *Instruction {
386 p := self.alloc("LEAQ", 2, Operands{v0, v1})
387 // LEAQ m, r64
388 if isM(v0) && isReg64(v1) {
389 p.domain = DomainGeneric
390 p.add(0, func(m *_Encoding, v []interface{}) {
391 m.rexm(1, hcode(v[1]), addr(v[0]))
392 m.emit(0x8d)
393 m.mrsd(lcode(v[1]), addr(v[0]), 1)
394 })
395 }
396 if p.len == 0 {
397 panic("invalid operands for LEAQ")
398 }
399 return p
400 }
401
402 // MOVQ performs "Move".
403 //
404 // Mnemonic : MOV
405 // Supported forms : (16 forms)
406 //
407 // - MOVQ imm32, r64
408 // - MOVQ imm64, r64
409 // - MOVQ r64, r64
410 // - MOVQ m64, r64
411 // - MOVQ imm32, m64
412 // - MOVQ r64, m64
413 // - MOVQ mm, r64 [MMX]
414 // - MOVQ r64, mm [MMX]
415 // - MOVQ mm, mm [MMX]
416 // - MOVQ m64, mm [MMX]
417 // - MOVQ mm, m64 [MMX]
418 // - MOVQ xmm, r64 [SSE2]
419 // - MOVQ r64, xmm [SSE2]
420 // - MOVQ xmm, xmm [SSE2]
421 // - MOVQ m64, xmm [SSE2]
422 // - MOVQ xmm, m64 [SSE2]
423 func (self *Program) MOVQ(v0 interface{}, v1 interface{}) *Instruction {
424 p := self.alloc("MOVQ", 2, Operands{v0, v1})
425 // MOVQ imm32, r64
426 if isImm32Ext(v0, 8) && isReg64(v1) {
427 p.domain = DomainGeneric
428 p.add(0, func(m *_Encoding, v []interface{}) {
429 m.emit(0x48 | hcode(v[1]))
430 m.emit(0xc7)
431 m.emit(0xc0 | lcode(v[1]))
432 m.imm4(toImmAny(v[0]))
433 })
434 }
435 // MOVQ imm64, r64
436 if isImm64(v0) && isReg64(v1) {
437 p.domain = DomainGeneric
438 p.add(0, func(m *_Encoding, v []interface{}) {
439 m.emit(0x48 | hcode(v[1]))
440 m.emit(0xb8 | lcode(v[1]))
441 m.imm8(toImmAny(v[0]))
442 })
443 }
444 // MOVQ r64, r64
445 if isReg64(v0) && isReg64(v1) {
446 p.domain = DomainGeneric
447 p.add(0, func(m *_Encoding, v []interface{}) {
448 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
449 m.emit(0x89)
450 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
451 })
452 p.add(0, func(m *_Encoding, v []interface{}) {
453 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
454 m.emit(0x8b)
455 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
456 })
457 }
458 // MOVQ m64, r64
459 if isM64(v0) && isReg64(v1) {
460 p.domain = DomainGeneric
461 p.add(0, func(m *_Encoding, v []interface{}) {
462 m.rexm(1, hcode(v[1]), addr(v[0]))
463 m.emit(0x8b)
464 m.mrsd(lcode(v[1]), addr(v[0]), 1)
465 })
466 }
467 // MOVQ imm32, m64
468 if isImm32Ext(v0, 8) && isM64(v1) {
469 p.domain = DomainGeneric
470 p.add(0, func(m *_Encoding, v []interface{}) {
471 m.rexm(1, 0, addr(v[1]))
472 m.emit(0xc7)
473 m.mrsd(0, addr(v[1]), 1)
474 m.imm4(toImmAny(v[0]))
475 })
476 }
477 // MOVQ r64, m64
478 if isReg64(v0) && isM64(v1) {
479 p.domain = DomainGeneric
480 p.add(0, func(m *_Encoding, v []interface{}) {
481 m.rexm(1, hcode(v[0]), addr(v[1]))
482 m.emit(0x89)
483 m.mrsd(lcode(v[0]), addr(v[1]), 1)
484 })
485 }
486 // MOVQ mm, r64
487 if isMM(v0) && isReg64(v1) {
488 self.require(ISA_MMX)
489 p.domain = DomainMMXSSE
490 p.add(0, func(m *_Encoding, v []interface{}) {
491 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
492 m.emit(0x0f)
493 m.emit(0x7e)
494 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
495 })
496 }
497 // MOVQ r64, mm
498 if isReg64(v0) && isMM(v1) {
499 self.require(ISA_MMX)
500 p.domain = DomainMMXSSE
501 p.add(0, func(m *_Encoding, v []interface{}) {
502 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
503 m.emit(0x0f)
504 m.emit(0x6e)
505 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
506 })
507 }
508 // MOVQ mm, mm
509 if isMM(v0) && isMM(v1) {
510 self.require(ISA_MMX)
511 p.domain = DomainMMXSSE
512 p.add(0, func(m *_Encoding, v []interface{}) {
513 m.rexo(hcode(v[1]), v[0], false)
514 m.emit(0x0f)
515 m.emit(0x6f)
516 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
517 })
518 p.add(0, func(m *_Encoding, v []interface{}) {
519 m.rexo(hcode(v[0]), v[1], false)
520 m.emit(0x0f)
521 m.emit(0x7f)
522 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
523 })
524 }
525 // MOVQ m64, mm
526 if isM64(v0) && isMM(v1) {
527 self.require(ISA_MMX)
528 p.domain = DomainMMXSSE
529 p.add(0, func(m *_Encoding, v []interface{}) {
530 m.rexo(hcode(v[1]), addr(v[0]), false)
531 m.emit(0x0f)
532 m.emit(0x6f)
533 m.mrsd(lcode(v[1]), addr(v[0]), 1)
534 })
535 p.add(0, func(m *_Encoding, v []interface{}) {
536 m.rexm(1, hcode(v[1]), addr(v[0]))
537 m.emit(0x0f)
538 m.emit(0x6e)
539 m.mrsd(lcode(v[1]), addr(v[0]), 1)
540 })
541 }
542 // MOVQ mm, m64
543 if isMM(v0) && isM64(v1) {
544 self.require(ISA_MMX)
545 p.domain = DomainMMXSSE
546 p.add(0, func(m *_Encoding, v []interface{}) {
547 m.rexo(hcode(v[0]), addr(v[1]), false)
548 m.emit(0x0f)
549 m.emit(0x7f)
550 m.mrsd(lcode(v[0]), addr(v[1]), 1)
551 })
552 p.add(0, func(m *_Encoding, v []interface{}) {
553 m.rexm(1, hcode(v[0]), addr(v[1]))
554 m.emit(0x0f)
555 m.emit(0x7e)
556 m.mrsd(lcode(v[0]), addr(v[1]), 1)
557 })
558 }
559 // MOVQ xmm, r64
560 if isXMM(v0) && isReg64(v1) {
561 self.require(ISA_SSE2)
562 p.domain = DomainMMXSSE
563 p.add(0, func(m *_Encoding, v []interface{}) {
564 m.emit(0x66)
565 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
566 m.emit(0x0f)
567 m.emit(0x7e)
568 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
569 })
570 }
571 // MOVQ r64, xmm
572 if isReg64(v0) && isXMM(v1) {
573 self.require(ISA_SSE2)
574 p.domain = DomainMMXSSE
575 p.add(0, func(m *_Encoding, v []interface{}) {
576 m.emit(0x66)
577 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
578 m.emit(0x0f)
579 m.emit(0x6e)
580 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
581 })
582 }
583 // MOVQ xmm, xmm
584 if isXMM(v0) && isXMM(v1) {
585 self.require(ISA_SSE2)
586 p.domain = DomainMMXSSE
587 p.add(0, func(m *_Encoding, v []interface{}) {
588 m.emit(0xf3)
589 m.rexo(hcode(v[1]), v[0], false)
590 m.emit(0x0f)
591 m.emit(0x7e)
592 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
593 })
594 p.add(0, func(m *_Encoding, v []interface{}) {
595 m.emit(0x66)
596 m.rexo(hcode(v[0]), v[1], false)
597 m.emit(0x0f)
598 m.emit(0xd6)
599 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
600 })
601 }
602 // MOVQ m64, xmm
603 if isM64(v0) && isXMM(v1) {
604 self.require(ISA_SSE2)
605 p.domain = DomainMMXSSE
606 p.add(0, func(m *_Encoding, v []interface{}) {
607 m.emit(0xf3)
608 m.rexo(hcode(v[1]), addr(v[0]), false)
609 m.emit(0x0f)
610 m.emit(0x7e)
611 m.mrsd(lcode(v[1]), addr(v[0]), 1)
612 })
613 p.add(0, func(m *_Encoding, v []interface{}) {
614 m.emit(0x66)
615 m.rexm(1, hcode(v[1]), addr(v[0]))
616 m.emit(0x0f)
617 m.emit(0x6e)
618 m.mrsd(lcode(v[1]), addr(v[0]), 1)
619 })
620 }
621 // MOVQ xmm, m64
622 if isXMM(v0) && isM64(v1) {
623 self.require(ISA_SSE2)
624 p.domain = DomainMMXSSE
625 p.add(0, func(m *_Encoding, v []interface{}) {
626 m.emit(0x66)
627 m.rexo(hcode(v[0]), addr(v[1]), false)
628 m.emit(0x0f)
629 m.emit(0xd6)
630 m.mrsd(lcode(v[0]), addr(v[1]), 1)
631 })
632 p.add(0, func(m *_Encoding, v []interface{}) {
633 m.emit(0x66)
634 m.rexm(1, hcode(v[0]), addr(v[1]))
635 m.emit(0x0f)
636 m.emit(0x7e)
637 m.mrsd(lcode(v[0]), addr(v[1]), 1)
638 })
639 }
640 if p.len == 0 {
641 panic("invalid operands for MOVQ")
642 }
643 return p
644 }
645
646 // MOVSD performs "Move Scalar Double-Precision Floating-Point Value".
647 //
648 // Mnemonic : MOVSD
649 // Supported forms : (3 forms)
650 //
651 // - MOVSD xmm, xmm [SSE2]
652 // - MOVSD m64, xmm [SSE2]
653 // - MOVSD xmm, m64 [SSE2]
654 func (self *Program) MOVSD(v0 interface{}, v1 interface{}) *Instruction {
655 p := self.alloc("MOVSD", 2, Operands{v0, v1})
656 // MOVSD xmm, xmm
657 if isXMM(v0) && isXMM(v1) {
658 self.require(ISA_SSE2)
659 p.domain = DomainMMXSSE
660 p.add(0, func(m *_Encoding, v []interface{}) {
661 m.emit(0xf2)
662 m.rexo(hcode(v[1]), v[0], false)
663 m.emit(0x0f)
664 m.emit(0x10)
665 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
666 })
667 p.add(0, func(m *_Encoding, v []interface{}) {
668 m.emit(0xf2)
669 m.rexo(hcode(v[0]), v[1], false)
670 m.emit(0x0f)
671 m.emit(0x11)
672 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
673 })
674 }
675 // MOVSD m64, xmm
676 if isM64(v0) && isXMM(v1) {
677 self.require(ISA_SSE2)
678 p.domain = DomainMMXSSE
679 p.add(0, func(m *_Encoding, v []interface{}) {
680 m.emit(0xf2)
681 m.rexo(hcode(v[1]), addr(v[0]), false)
682 m.emit(0x0f)
683 m.emit(0x10)
684 m.mrsd(lcode(v[1]), addr(v[0]), 1)
685 })
686 }
687 // MOVSD xmm, m64
688 if isXMM(v0) && isM64(v1) {
689 self.require(ISA_SSE2)
690 p.domain = DomainMMXSSE
691 p.add(0, func(m *_Encoding, v []interface{}) {
692 m.emit(0xf2)
693 m.rexo(hcode(v[0]), addr(v[1]), false)
694 m.emit(0x0f)
695 m.emit(0x11)
696 m.mrsd(lcode(v[0]), addr(v[1]), 1)
697 })
698 }
699 if p.len == 0 {
700 panic("invalid operands for MOVSD")
701 }
702 return p
703 }
704
705 // MOVSLQ performs "Move Doubleword to Quadword with Sign-Extension".
706 //
707 // Mnemonic : MOVSXD
708 // Supported forms : (2 forms)
709 //
710 // - MOVSLQ r32, r64
711 // - MOVSLQ m32, r64
712 func (self *Program) MOVSLQ(v0 interface{}, v1 interface{}) *Instruction {
713 p := self.alloc("MOVSLQ", 2, Operands{v0, v1})
714 // MOVSLQ r32, r64
715 if isReg32(v0) && isReg64(v1) {
716 p.domain = DomainGeneric
717 p.add(0, func(m *_Encoding, v []interface{}) {
718 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
719 m.emit(0x63)
720 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
721 })
722 }
723 // MOVSLQ m32, r64
724 if isM32(v0) && isReg64(v1) {
725 p.domain = DomainGeneric
726 p.add(0, func(m *_Encoding, v []interface{}) {
727 m.rexm(1, hcode(v[1]), addr(v[0]))
728 m.emit(0x63)
729 m.mrsd(lcode(v[1]), addr(v[0]), 1)
730 })
731 }
732 if p.len == 0 {
733 panic("invalid operands for MOVSLQ")
734 }
735 return p
736 }
737
738 // MOVSS performs "Move Scalar Single-Precision Floating-Point Values".
739 //
740 // Mnemonic : MOVSS
741 // Supported forms : (3 forms)
742 //
743 // - MOVSS xmm, xmm [SSE]
744 // - MOVSS m32, xmm [SSE]
745 // - MOVSS xmm, m32 [SSE]
746 func (self *Program) MOVSS(v0 interface{}, v1 interface{}) *Instruction {
747 p := self.alloc("MOVSS", 2, Operands{v0, v1})
748 // MOVSS xmm, xmm
749 if isXMM(v0) && isXMM(v1) {
750 self.require(ISA_SSE)
751 p.domain = DomainMMXSSE
752 p.add(0, func(m *_Encoding, v []interface{}) {
753 m.emit(0xf3)
754 m.rexo(hcode(v[1]), v[0], false)
755 m.emit(0x0f)
756 m.emit(0x10)
757 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
758 })
759 p.add(0, func(m *_Encoding, v []interface{}) {
760 m.emit(0xf3)
761 m.rexo(hcode(v[0]), v[1], false)
762 m.emit(0x0f)
763 m.emit(0x11)
764 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
765 })
766 }
767 // MOVSS m32, xmm
768 if isM32(v0) && isXMM(v1) {
769 self.require(ISA_SSE)
770 p.domain = DomainMMXSSE
771 p.add(0, func(m *_Encoding, v []interface{}) {
772 m.emit(0xf3)
773 m.rexo(hcode(v[1]), addr(v[0]), false)
774 m.emit(0x0f)
775 m.emit(0x10)
776 m.mrsd(lcode(v[1]), addr(v[0]), 1)
777 })
778 }
779 // MOVSS xmm, m32
780 if isXMM(v0) && isM32(v1) {
781 self.require(ISA_SSE)
782 p.domain = DomainMMXSSE
783 p.add(0, func(m *_Encoding, v []interface{}) {
784 m.emit(0xf3)
785 m.rexo(hcode(v[0]), addr(v[1]), false)
786 m.emit(0x0f)
787 m.emit(0x11)
788 m.mrsd(lcode(v[0]), addr(v[1]), 1)
789 })
790 }
791 if p.len == 0 {
792 panic("invalid operands for MOVSS")
793 }
794 return p
795 }
796
797 // RET performs "Return from Procedure".
798 //
799 // Mnemonic : RET
800 // Supported forms : (2 forms)
801 //
802 // - RET
803 // - RET imm16
804 func (self *Program) RET(vv ...interface{}) *Instruction {
805 var p *Instruction
806 switch len(vv) {
807 case 0:
808 p = self.alloc("RET", 0, Operands{})
809 case 1:
810 p = self.alloc("RET", 1, Operands{vv[0]})
811 default:
812 panic("instruction RET takes 0 or 1 operands")
813 }
814 // RET
815 if len(vv) == 0 {
816 p.domain = DomainGeneric
817 p.add(0, func(m *_Encoding, v []interface{}) {
818 m.emit(0xc3)
819 })
820 }
821 // RET imm16
822 if len(vv) == 1 && isImm16(vv[0]) {
823 p.domain = DomainGeneric
824 p.add(0, func(m *_Encoding, v []interface{}) {
825 m.emit(0xc2)
826 m.imm2(toImmAny(v[0]))
827 })
828 }
829 if p.len == 0 {
830 panic("invalid operands for RET")
831 }
832 return p
833 }
834
835 // SUBQ performs "Subtract".
836 //
837 // Mnemonic : SUB
838 // Supported forms : (8 forms)
839 //
840 // - SUBQ imm32, rax
841 // - SUBQ imm8, r64
842 // - SUBQ imm32, r64
843 // - SUBQ r64, r64
844 // - SUBQ m64, r64
845 // - SUBQ imm8, m64
846 // - SUBQ imm32, m64
847 // - SUBQ r64, m64
848 func (self *Program) SUBQ(v0 interface{}, v1 interface{}) *Instruction {
849 p := self.alloc("SUBQ", 2, Operands{v0, v1})
850 // SUBQ imm32, rax
851 if isImm32(v0) && v1 == RAX {
852 p.domain = DomainGeneric
853 p.add(0, func(m *_Encoding, v []interface{}) {
854 m.emit(0x48)
855 m.emit(0x2d)
856 m.imm4(toImmAny(v[0]))
857 })
858 }
859 // SUBQ imm8, r64
860 if isImm8Ext(v0, 8) && isReg64(v1) {
861 p.domain = DomainGeneric
862 p.add(0, func(m *_Encoding, v []interface{}) {
863 m.emit(0x48 | hcode(v[1]))
864 m.emit(0x83)
865 m.emit(0xe8 | lcode(v[1]))
866 m.imm1(toImmAny(v[0]))
867 })
868 }
869 // SUBQ imm32, r64
870 if isImm32Ext(v0, 8) && isReg64(v1) {
871 p.domain = DomainGeneric
872 p.add(0, func(m *_Encoding, v []interface{}) {
873 m.emit(0x48 | hcode(v[1]))
874 m.emit(0x81)
875 m.emit(0xe8 | lcode(v[1]))
876 m.imm4(toImmAny(v[0]))
877 })
878 }
879 // SUBQ r64, r64
880 if isReg64(v0) && isReg64(v1) {
881 p.domain = DomainGeneric
882 p.add(0, func(m *_Encoding, v []interface{}) {
883 m.emit(0x48 | hcode(v[0])<<2 | hcode(v[1]))
884 m.emit(0x29)
885 m.emit(0xc0 | lcode(v[0])<<3 | lcode(v[1]))
886 })
887 p.add(0, func(m *_Encoding, v []interface{}) {
888 m.emit(0x48 | hcode(v[1])<<2 | hcode(v[0]))
889 m.emit(0x2b)
890 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
891 })
892 }
893 // SUBQ m64, r64
894 if isM64(v0) && isReg64(v1) {
895 p.domain = DomainGeneric
896 p.add(0, func(m *_Encoding, v []interface{}) {
897 m.rexm(1, hcode(v[1]), addr(v[0]))
898 m.emit(0x2b)
899 m.mrsd(lcode(v[1]), addr(v[0]), 1)
900 })
901 }
902 // SUBQ imm8, m64
903 if isImm8Ext(v0, 8) && isM64(v1) {
904 p.domain = DomainGeneric
905 p.add(0, func(m *_Encoding, v []interface{}) {
906 m.rexm(1, 0, addr(v[1]))
907 m.emit(0x83)
908 m.mrsd(5, addr(v[1]), 1)
909 m.imm1(toImmAny(v[0]))
910 })
911 }
912 // SUBQ imm32, m64
913 if isImm32Ext(v0, 8) && isM64(v1) {
914 p.domain = DomainGeneric
915 p.add(0, func(m *_Encoding, v []interface{}) {
916 m.rexm(1, 0, addr(v[1]))
917 m.emit(0x81)
918 m.mrsd(5, addr(v[1]), 1)
919 m.imm4(toImmAny(v[0]))
920 })
921 }
922 // SUBQ r64, m64
923 if isReg64(v0) && isM64(v1) {
924 p.domain = DomainGeneric
925 p.add(0, func(m *_Encoding, v []interface{}) {
926 m.rexm(1, hcode(v[0]), addr(v[1]))
927 m.emit(0x29)
928 m.mrsd(lcode(v[0]), addr(v[1]), 1)
929 })
930 }
931 if p.len == 0 {
932 panic("invalid operands for SUBQ")
933 }
934 return p
935 }
936
937 // VPERMIL2PD performs "Permute Two-Source Double-Precision Floating-Point Vectors".
938 //
939 // Mnemonic : VPERMIL2PD
940 // Supported forms : (6 forms)
941 //
942 // - VPERMIL2PD imm4, xmm, xmm, xmm, xmm [XOP]
943 // - VPERMIL2PD imm4, m128, xmm, xmm, xmm [XOP]
944 // - VPERMIL2PD imm4, xmm, m128, xmm, xmm [XOP]
945 // - VPERMIL2PD imm4, ymm, ymm, ymm, ymm [XOP]
946 // - VPERMIL2PD imm4, m256, ymm, ymm, ymm [XOP]
947 // - VPERMIL2PD imm4, ymm, m256, ymm, ymm [XOP]
948 func (self *Program) VPERMIL2PD(v0 interface{}, v1 interface{}, v2 interface{}, v3 interface{}, v4 interface{}) *Instruction {
949 p := self.alloc("VPERMIL2PD", 5, Operands{v0, v1, v2, v3, v4})
950 // VPERMIL2PD imm4, xmm, xmm, xmm, xmm
951 if isImm4(v0) && isXMM(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) {
952 self.require(ISA_XOP)
953 p.domain = DomainAMDSpecific
954 p.add(0, func(m *_Encoding, v []interface{}) {
955 m.emit(0xc4)
956 m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5))
957 m.emit(0x79 ^ (hlcode(v[3]) << 3))
958 m.emit(0x49)
959 m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[2]))
960 m.emit((hlcode(v[1]) << 4) | imml(v[0]))
961 })
962 p.add(0, func(m *_Encoding, v []interface{}) {
963 m.emit(0xc4)
964 m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5))
965 m.emit(0xf9 ^ (hlcode(v[3]) << 3))
966 m.emit(0x49)
967 m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[1]))
968 m.emit((hlcode(v[2]) << 4) | imml(v[0]))
969 })
970 }
971 // VPERMIL2PD imm4, m128, xmm, xmm, xmm
972 if isImm4(v0) && isM128(v1) && isXMM(v2) && isXMM(v3) && isXMM(v4) {
973 self.require(ISA_XOP)
974 p.domain = DomainAMDSpecific
975 p.add(0, func(m *_Encoding, v []interface{}) {
976 m.vex3(0xc4, 0b11, 0x81, hcode(v[4]), addr(v[1]), hlcode(v[3]))
977 m.emit(0x49)
978 m.mrsd(lcode(v[4]), addr(v[1]), 1)
979 m.emit((hlcode(v[2]) << 4) | imml(v[0]))
980 })
981 }
982 // VPERMIL2PD imm4, xmm, m128, xmm, xmm
983 if isImm4(v0) && isXMM(v1) && isM128(v2) && isXMM(v3) && isXMM(v4) {
984 self.require(ISA_XOP)
985 p.domain = DomainAMDSpecific
986 p.add(0, func(m *_Encoding, v []interface{}) {
987 m.vex3(0xc4, 0b11, 0x01, hcode(v[4]), addr(v[2]), hlcode(v[3]))
988 m.emit(0x49)
989 m.mrsd(lcode(v[4]), addr(v[2]), 1)
990 m.emit((hlcode(v[1]) << 4) | imml(v[0]))
991 })
992 }
993 // VPERMIL2PD imm4, ymm, ymm, ymm, ymm
994 if isImm4(v0) && isYMM(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) {
995 self.require(ISA_XOP)
996 p.domain = DomainAMDSpecific
997 p.add(0, func(m *_Encoding, v []interface{}) {
998 m.emit(0xc4)
999 m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[2]) << 5))
1000 m.emit(0x7d ^ (hlcode(v[3]) << 3))
1001 m.emit(0x49)
1002 m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[2]))
1003 m.emit((hlcode(v[1]) << 4) | imml(v[0]))
1004 })
1005 p.add(0, func(m *_Encoding, v []interface{}) {
1006 m.emit(0xc4)
1007 m.emit(0xe3 ^ (hcode(v[4]) << 7) ^ (hcode(v[1]) << 5))
1008 m.emit(0xfd ^ (hlcode(v[3]) << 3))
1009 m.emit(0x49)
1010 m.emit(0xc0 | lcode(v[4])<<3 | lcode(v[1]))
1011 m.emit((hlcode(v[2]) << 4) | imml(v[0]))
1012 })
1013 }
1014 // VPERMIL2PD imm4, m256, ymm, ymm, ymm
1015 if isImm4(v0) && isM256(v1) && isYMM(v2) && isYMM(v3) && isYMM(v4) {
1016 self.require(ISA_XOP)
1017 p.domain = DomainAMDSpecific
1018 p.add(0, func(m *_Encoding, v []interface{}) {
1019 m.vex3(0xc4, 0b11, 0x85, hcode(v[4]), addr(v[1]), hlcode(v[3]))
1020 m.emit(0x49)
1021 m.mrsd(lcode(v[4]), addr(v[1]), 1)
1022 m.emit((hlcode(v[2]) << 4) | imml(v[0]))
1023 })
1024 }
1025 // VPERMIL2PD imm4, ymm, m256, ymm, ymm
1026 if isImm4(v0) && isYMM(v1) && isM256(v2) && isYMM(v3) && isYMM(v4) {
1027 self.require(ISA_XOP)
1028 p.domain = DomainAMDSpecific
1029 p.add(0, func(m *_Encoding, v []interface{}) {
1030 m.vex3(0xc4, 0b11, 0x05, hcode(v[4]), addr(v[2]), hlcode(v[3]))
1031 m.emit(0x49)
1032 m.mrsd(lcode(v[4]), addr(v[2]), 1)
1033 m.emit((hlcode(v[1]) << 4) | imml(v[0]))
1034 })
1035 }
1036 if p.len == 0 {
1037 panic("invalid operands for VPERMIL2PD")
1038 }
1039 return p
1040 }
1041
1042 // XORPS performs "Bitwise Logical XOR for Single-Precision Floating-Point Values".
1043 //
1044 // Mnemonic : XORPS
1045 // Supported forms : (2 forms)
1046 //
1047 // - XORPS xmm, xmm [SSE]
1048 // - XORPS m128, xmm [SSE]
1049 func (self *Program) XORPS(v0 interface{}, v1 interface{}) *Instruction {
1050 p := self.alloc("XORPS", 2, Operands{v0, v1})
1051 // XORPS xmm, xmm
1052 if isXMM(v0) && isXMM(v1) {
1053 self.require(ISA_SSE)
1054 p.domain = DomainMMXSSE
1055 p.add(0, func(m *_Encoding, v []interface{}) {
1056 m.rexo(hcode(v[1]), v[0], false)
1057 m.emit(0x0f)
1058 m.emit(0x57)
1059 m.emit(0xc0 | lcode(v[1])<<3 | lcode(v[0]))
1060 })
1061 }
1062 // XORPS m128, xmm
1063 if isM128(v0) && isXMM(v1) {
1064 self.require(ISA_SSE)
1065 p.domain = DomainMMXSSE
1066 p.add(0, func(m *_Encoding, v []interface{}) {
1067 m.rexo(hcode(v[1]), addr(v[0]), false)
1068 m.emit(0x0f)
1069 m.emit(0x57)
1070 m.mrsd(lcode(v[1]), addr(v[0]), 1)
1071 })
1072 }
1073 if p.len == 0 {
1074 panic("invalid operands for XORPS")
1075 }
1076 return p
1077 }
1078