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