/
encoding.go
116 lines (104 loc) · 2.86 KB
/
encoding.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package amd64
func zeroOperand(asm *Assembler, insn *instruction) {
asm.byte(byte(insn.opcode))
}
func oneOperand(asm *Assembler, insn *instruction, dst Operand) {
variant, _ := insn.findVariant(asm, dst.Qualifiers(), nil, nil)
if variant == nil {
return
}
insn = variant
encoding, _ := insn.encoding.(func(*Assembler, *instruction, Operand))
if encoding == nil {
encoding = encodingM
}
encoding(asm, insn, dst)
}
func twoOperands(asm *Assembler, insn *instruction, dst Operand, src Operand) {
variant, key := insn.findVariant(asm, dst.Qualifiers(), src.Qualifiers(), nil)
if variant == nil {
return
}
insn = variant
encoding, _ := insn.encoding.(func(*Assembler, *instruction, Operand, Operand))
if encoding == nil {
if key[0].RM > 0 {
encoding = encodingMR
} else {
encoding = encodingRM
}
if key[1].IMM > 0 {
encoding = encodingMI
}
}
encoding(asm, insn, dst, src)
}
func threeOperands(asm *Assembler, insn *instruction, dst, src1, src2 Operand) {
variant, _ := insn.findVariant(asm, dst.Qualifiers(), src1.Qualifiers(), src2.Qualifiers())
if variant == nil {
return
}
insn = variant
encoding, _ := insn.encoding.(func(*Assembler, *instruction, Operand, Operand, Operand))
encoding(asm, insn, dst, src1, src2)
}
// dst: rm
func encodingM(asm *Assembler, insn *instruction, dst Operand) {
dst.rex(asm, nil)
asm.byte(byte(insn.opcode))
dst.modrm(asm, byte(insn.opcodeReg))
}
// dst: rm
// src: imm
func encodingMI(asm *Assembler, insn *instruction, dst Operand, src Operand) {
dst.rex(asm, src)
asm.byte(byte(insn.opcode))
dst.modrm(asm, byte(insn.opcodeReg))
asm.imm(src.(Immediate))
}
// dst: rm
// src: reg
func encodingMR(asm *Assembler, insn *instruction, dst Operand, src Operand) {
dst.rex(asm, src)
asm.byte(byte(insn.opcode))
dst.modrm(asm, src.(Register).Value())
}
// dst: reg
// src: rm
func encodingRM(asm *Assembler, insn *instruction, dst Operand, src Operand) {
src.vex(asm, insn, nil)
src.rex(asm, dst)
asm.byte(byte(insn.opcode))
src.modrm(asm, dst.(Register).Value())
}
// dst: al/ax/eax/rax
// src: imm8/16/32
func encodingI(asm *Assembler, insn *instruction, dst Operand, src Operand) {
dst.rex(asm, src)
asm.byte(byte(insn.opcode))
asm.imm(src.(Immediate))
}
// dst: reg
// src: rm
func encodingA(asm *Assembler, insn *instruction, dst Operand, src Operand) {
src.rex(asm, dst)
src.vex(asm, insn, nil)
asm.byte(byte(insn.opcode))
src.modrm(asm, dst.(Register).Value())
}
// dst: rm
// src: reg
func encodingB(asm *Assembler, insn *instruction, dst Operand, src Operand) {
dst.rex(asm, src)
dst.vex(asm, insn, nil)
asm.byte(byte(insn.opcode))
dst.modrm(asm, src.(Register).Value())
}
// dst: modrm reg
// src1: vex.vvvv
// src2: modrm rm
func encodingB3(asm *Assembler, insn *instruction, dst, src1, src2 Operand) {
src2.vex(asm, insn, src1)
asm.byte(byte(insn.opcode))
src2.modrm(asm, dst.(Register).Value())
}