1
2
3
4
5 package ppc64asm
6
7 import (
8 "encoding/binary"
9 "fmt"
10 "log"
11 )
12
13 const debugDecode = false
14
15 const prefixOpcode = 1
16
17
18
19
20
21
22
23
24
25
26
27
28 type instFormat struct {
29 Op Op
30 Mask uint64
31 Value uint64
32 DontCare uint64
33 Args [6]*argField
34 }
35
36
37
38
39 type argField struct {
40 Type ArgType
41 Shift uint8
42 BitFields
43 }
44
45
46 func (a argField) Parse(i [2]uint32) Arg {
47 switch a.Type {
48 default:
49 return nil
50 case TypeUnknown:
51 return nil
52 case TypeReg:
53 return R0 + Reg(a.BitFields.Parse(i))
54 case TypeCondRegBit:
55 return Cond0LT + CondReg(a.BitFields.Parse(i))
56 case TypeCondRegField:
57 return CR0 + CondReg(a.BitFields.Parse(i))
58 case TypeFPReg:
59 return F0 + Reg(a.BitFields.Parse(i))
60 case TypeVecReg:
61 return V0 + Reg(a.BitFields.Parse(i))
62 case TypeVecSReg:
63 return VS0 + Reg(a.BitFields.Parse(i))
64 case TypeVecSpReg:
65 return VS0 + Reg(a.BitFields.Parse(i))*2
66 case TypeMMAReg:
67 return A0 + Reg(a.BitFields.Parse(i))
68 case TypeSpReg:
69 return SpReg(a.BitFields.Parse(i))
70 case TypeImmSigned:
71 return Imm(a.BitFields.ParseSigned(i) << a.Shift)
72 case TypeImmUnsigned:
73 return Imm(a.BitFields.Parse(i) << a.Shift)
74 case TypePCRel:
75 return PCRel(a.BitFields.ParseSigned(i) << a.Shift)
76 case TypeLabel:
77 return Label(a.BitFields.ParseSigned(i) << a.Shift)
78 case TypeOffset:
79 return Offset(a.BitFields.ParseSigned(i) << a.Shift)
80 }
81 }
82
83 type ArgType int8
84
85 const (
86 TypeUnknown ArgType = iota
87 TypePCRel
88 TypeLabel
89 TypeReg
90 TypeCondRegBit
91 TypeCondRegField
92 TypeFPReg
93 TypeVecReg
94 TypeVecSReg
95 TypeVecSpReg
96 TypeMMAReg
97 TypeSpReg
98 TypeImmSigned
99 TypeImmUnsigned
100 TypeOffset
101 TypeLast
102 )
103
104 func (t ArgType) String() string {
105 switch t {
106 default:
107 return fmt.Sprintf("ArgType(%d)", int(t))
108 case TypeUnknown:
109 return "Unknown"
110 case TypeReg:
111 return "Reg"
112 case TypeCondRegBit:
113 return "CondRegBit"
114 case TypeCondRegField:
115 return "CondRegField"
116 case TypeFPReg:
117 return "FPReg"
118 case TypeVecReg:
119 return "VecReg"
120 case TypeVecSReg:
121 return "VecSReg"
122 case TypeVecSpReg:
123 return "VecSpReg"
124 case TypeMMAReg:
125 return "MMAReg"
126 case TypeSpReg:
127 return "SpReg"
128 case TypeImmSigned:
129 return "ImmSigned"
130 case TypeImmUnsigned:
131 return "ImmUnsigned"
132 case TypePCRel:
133 return "PCRel"
134 case TypeLabel:
135 return "Label"
136 case TypeOffset:
137 return "Offset"
138 }
139 }
140
141 func (t ArgType) GoString() string {
142 s := t.String()
143 if t > 0 && t < TypeLast {
144 return "Type" + s
145 }
146 return s
147 }
148
149 var (
150
151 errShort = fmt.Errorf("truncated instruction")
152 errUnknown = fmt.Errorf("unknown instruction")
153 )
154
155 var decoderCover []bool
156
157
158
159 func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
160 if len(src) < 4 {
161 return inst, errShort
162 }
163 if decoderCover == nil {
164 decoderCover = make([]bool, len(instFormats))
165 }
166 inst.Len = 4
167 ui_extn := [2]uint32{ord.Uint32(src[:inst.Len]), 0}
168 ui := uint64(ui_extn[0]) << 32
169 inst.Enc = ui_extn[0]
170 opcode := inst.Enc >> 26
171 if opcode == prefixOpcode {
172
173 inst.Len = 8
174 if len(src) < 8 {
175 return inst, errShort
176 }
177
178 ui_extn[1] = ord.Uint32(src[4:inst.Len])
179 ui |= uint64(ui_extn[1])
180 inst.SuffixEnc = ui_extn[1]
181 }
182 for i, iform := range instFormats {
183 if ui&iform.Mask != iform.Value {
184 continue
185 }
186 if ui&iform.DontCare != 0 {
187 if debugDecode {
188 log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op)
189 }
190
191 }
192 for i, argfield := range iform.Args {
193 if argfield == nil {
194 break
195 }
196 inst.Args[i] = argfield.Parse(ui_extn)
197 }
198 inst.Op = iform.Op
199 if debugDecode {
200 log.Printf("%#x: search entry %d", ui, i)
201 continue
202 }
203 break
204 }
205 if inst.Op == 0 && inst.Enc != 0 {
206 return inst, errUnknown
207 }
208 return inst, nil
209 }
210
View as plain text