1
2
3
4
5 package s390xasm
6
7 import (
8 "encoding/binary"
9 "fmt"
10 )
11
12
13
14
15
16
17 type instFormat struct {
18 Op Op
19 Mask uint64
20 Value uint64
21 DontCare uint64
22 Args [8]*argField
23 }
24
25
26
27
28 type argField struct {
29 Type ArgType
30 flags uint16
31 BitField
32 }
33
34
35 func (a argField) Parse(i uint64) Arg {
36 switch a.Type {
37 default:
38 return nil
39 case TypeUnknown:
40 return nil
41 case TypeReg:
42 return R0 + Reg(a.BitField.Parse(i))
43 case TypeFPReg:
44 return F0 + Reg(a.BitField.Parse(i))
45 case TypeCReg:
46 return C0 + Reg(a.BitField.Parse(i))
47 case TypeACReg:
48 return A0 + Reg(a.BitField.Parse(i))
49 case TypeBaseReg:
50 return B0 + Base(a.BitField.Parse(i))
51 case TypeIndexReg:
52 return X0 + Index(a.BitField.Parse(i))
53 case TypeDispUnsigned:
54 return Disp12(a.BitField.Parse(i))
55 case TypeDispSigned20:
56 return Disp20(a.BitField.ParseSigned(i))
57 case TypeVecReg:
58 m := i >> 24
59 if ((m>>3)&0x1 == 1) && (a.BitField.Offs == 8) {
60 return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
61 } else if ((m>>2)&0x1 == 1) && (a.BitField.Offs == 12) {
62 return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
63 } else if ((m>>1)&0x1 == 1) && (a.BitField.Offs == 16) {
64 return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
65 } else if ((m)&0x1 == 1) && (a.BitField.Offs == 32) {
66 return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
67 } else {
68 return V0 + VReg(a.BitField.Parse(i))
69 }
70 case TypeImmSigned8:
71 return Sign8(a.BitField.ParseSigned(i))
72 case TypeImmSigned16:
73 return Sign16(a.BitField.ParseSigned(i))
74 case TypeImmSigned32:
75 return Sign32(a.BitField.ParseSigned(i))
76 case TypeImmUnsigned:
77 return Imm(a.BitField.Parse(i))
78 case TypeRegImSigned12:
79 return RegIm12(a.BitField.ParseSigned(i))
80 case TypeRegImSigned16:
81 return RegIm16(a.BitField.ParseSigned(i))
82 case TypeRegImSigned24:
83 return RegIm24(a.BitField.ParseSigned(i))
84 case TypeRegImSigned32:
85 return RegIm32(a.BitField.ParseSigned(i))
86 case TypeMask:
87 return Mask(a.BitField.Parse(i))
88 case TypeLen:
89 return Len(a.BitField.Parse(i))
90 }
91 }
92
93 type ArgType int8
94
95 const (
96 TypeUnknown ArgType = iota
97 TypeReg
98 TypeFPReg
99 TypeACReg
100 TypeCReg
101 TypeVecReg
102 TypeImmUnsigned
103 TypeImmSigned8
104 TypeImmSigned16
105 TypeImmSigned32
106 TypeBaseReg
107 TypeIndexReg
108 TypeDispUnsigned
109 TypeDispSigned20
110 TypeRegImSigned12
111 TypeRegImSigned16
112 TypeRegImSigned24
113 TypeRegImSigned32
114 TypeMask
115 TypeLen
116 TypeLast
117 )
118
119 func (t ArgType) String() string {
120 switch t {
121 default:
122 return fmt.Sprintf("ArgType(%d)", int(t))
123 case TypeUnknown:
124 return "Unknown"
125 case TypeReg:
126 return "Reg"
127 case TypeFPReg:
128 return "FPReg"
129 case TypeACReg:
130 return "ACReg"
131 case TypeCReg:
132 return "CReg"
133 case TypeDispUnsigned:
134 return "DispUnsigned"
135 case TypeDispSigned20:
136 return "DispSigned20"
137 case TypeBaseReg:
138 return "BaseReg"
139 case TypeIndexReg:
140 return "IndexReg"
141 case TypeVecReg:
142 return "VecReg"
143 case TypeImmSigned8:
144 return "ImmSigned8"
145 case TypeImmSigned16:
146 return "ImmSigned16"
147 case TypeImmSigned32:
148 return "ImmSigned32"
149 case TypeImmUnsigned:
150 return "ImmUnsigned"
151 case TypeRegImSigned12:
152 return "RegImSigned12"
153 case TypeRegImSigned16:
154 return "RegImSigned16"
155 case TypeRegImSigned24:
156 return "RegImSigned24"
157 case TypeRegImSigned32:
158 return "RegImSigned32"
159 case TypeMask:
160 return "Mask"
161 case TypeLen:
162 return "Len"
163 }
164 }
165
166 func (t ArgType) GoString() string {
167 s := t.String()
168 if t > 0 && t < TypeLast {
169 return "Type" + s
170 }
171 return s
172 }
173
174 var (
175
176 errShort = fmt.Errorf("truncated instruction")
177 errUnknown = fmt.Errorf("unknown instruction")
178 )
179
180 var decoderCover []bool
181
182
183
184 func Decode(src []byte) (inst Inst, err error) {
185 if len(src) < 2 {
186 return inst, errShort
187 }
188 if decoderCover == nil {
189 decoderCover = make([]bool, len(instFormats))
190 }
191 bit_check := binary.BigEndian.Uint16(src[:2])
192 bit_check = bit_check >> 14
193 l := int(0)
194 if (bit_check & 0x03) == 0 {
195 l = 2
196 } else if bit_check&0x03 == 3 {
197 l = 6
198 } else if (bit_check&0x01 == 1) || (bit_check&0x02 == 2) {
199 l = 4
200 }
201 inst.Len = l
202 ui_extn := uint64(0)
203 switch l {
204 case 2:
205 ui_extn = uint64(binary.BigEndian.Uint16(src[:inst.Len]))
206 inst.Enc = ui_extn
207 ui_extn = ui_extn << 48
208 case 4:
209 ui_extn = uint64(binary.BigEndian.Uint32(src[:inst.Len]))
210 inst.Enc = ui_extn
211 ui_extn = ui_extn << 32
212 case 6:
213 u1 := binary.BigEndian.Uint32(src[:(inst.Len - 2)])
214 u2 := binary.BigEndian.Uint16(src[(inst.Len - 2):inst.Len])
215 ui_extn = uint64(u1)<<16 | uint64(u2)
216 ui_extn = ui_extn << 16
217 inst.Enc = ui_extn
218 default:
219 return inst, errShort
220 }
221 for _, iform := range instFormats {
222 if ui_extn&iform.Mask != iform.Value {
223 continue
224 }
225 if (iform.DontCare & ^(ui_extn)) != iform.DontCare {
226 continue
227 }
228 for j, argfield := range iform.Args {
229 if argfield == nil {
230 break
231 }
232 inst.Args[j] = argfield.Parse(ui_extn)
233 }
234 inst.Op = iform.Op
235 break
236 }
237 if inst.Op == 0 && inst.Enc != 0 {
238 return inst, errUnknown
239 }
240 return inst, nil
241 }
242
View as plain text