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