summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/arch/ppc64/ppc64asm/inst.go
blob: bd86b9230c40f3abc13420e16d54e15a9dfa78ce (plain) (blame)
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ppc64asm

import (
	"bytes"
	"fmt"
)

type Inst struct {
	Op   Op     // Opcode mnemonic
	Enc  uint32 // Raw encoding bits
	Len  int    // Length of encoding in bytes.
	Args Args   // Instruction arguments, in Power ISA manual order.
}

func (i Inst) String() string {
	var buf bytes.Buffer
	buf.WriteString(i.Op.String())
	for j, arg := range i.Args {
		if arg == nil {
			break
		}
		if j == 0 {
			buf.WriteString(" ")
		} else {
			buf.WriteString(", ")
		}
		buf.WriteString(arg.String())
	}
	return buf.String()
}

// An Op is an instruction operation.
type Op uint16

func (o Op) String() string {
	if int(o) >= len(opstr) || opstr[o] == "" {
		return fmt.Sprintf("Op(%d)", int(o))
	}
	return opstr[o]
}

// An Arg is a single instruction argument, one of these types: Reg, CondReg, SpReg, Imm, PCRel, Label, or Offset.
type Arg interface {
	IsArg()
	String() string
}

// An Args holds the instruction arguments.
// If an instruction has fewer than 4 arguments,
// the final elements in the array are nil.
type Args [5]Arg

// A Reg is a single register. The zero value means R0, not the absence of a register.
// It also includes special registers.
type Reg uint16

const (
	_ Reg = iota
	R0
	R1
	R2
	R3
	R4
	R5
	R6
	R7
	R8
	R9
	R10
	R11
	R12
	R13
	R14
	R15
	R16
	R17
	R18
	R19
	R20
	R21
	R22
	R23
	R24
	R25
	R26
	R27
	R28
	R29
	R30
	R31
	F0
	F1
	F2
	F3
	F4
	F5
	F6
	F7
	F8
	F9
	F10
	F11
	F12
	F13
	F14
	F15
	F16
	F17
	F18
	F19
	F20
	F21
	F22
	F23
	F24
	F25
	F26
	F27
	F28
	F29
	F30
	F31
	V0 // VSX extension, F0 is V0[0:63].
	V1
	V2
	V3
	V4
	V5
	V6
	V7
	V8
	V9
	V10
	V11
	V12
	V13
	V14
	V15
	V16
	V17
	V18
	V19
	V20
	V21
	V22
	V23
	V24
	V25
	V26
	V27
	V28
	V29
	V30
	V31
	VS0
	VS1
	VS2
	VS3
	VS4
	VS5
	VS6
	VS7
	VS8
	VS9
	VS10
	VS11
	VS12
	VS13
	VS14
	VS15
	VS16
	VS17
	VS18
	VS19
	VS20
	VS21
	VS22
	VS23
	VS24
	VS25
	VS26
	VS27
	VS28
	VS29
	VS30
	VS31
	VS32
	VS33
	VS34
	VS35
	VS36
	VS37
	VS38
	VS39
	VS40
	VS41
	VS42
	VS43
	VS44
	VS45
	VS46
	VS47
	VS48
	VS49
	VS50
	VS51
	VS52
	VS53
	VS54
	VS55
	VS56
	VS57
	VS58
	VS59
	VS60
	VS61
	VS62
	VS63
)

func (Reg) IsArg() {}
func (r Reg) String() string {
	switch {
	case R0 <= r && r <= R31:
		return fmt.Sprintf("r%d", int(r-R0))
	case F0 <= r && r <= F31:
		return fmt.Sprintf("f%d", int(r-F0))
	case V0 <= r && r <= V31:
		return fmt.Sprintf("v%d", int(r-V0))
	case VS0 <= r && r <= VS63:
		return fmt.Sprintf("vs%d", int(r-VS0))
	default:
		return fmt.Sprintf("Reg(%d)", int(r))
	}
}

// CondReg is a bit or field in the conditon register.
type CondReg int8

const (
	_ CondReg = iota
	// Condition Regster bits
	Cond0LT
	Cond0GT
	Cond0EQ
	Cond0SO
	Cond1LT
	Cond1GT
	Cond1EQ
	Cond1SO
	Cond2LT
	Cond2GT
	Cond2EQ
	Cond2SO
	Cond3LT
	Cond3GT
	Cond3EQ
	Cond3SO
	Cond4LT
	Cond4GT
	Cond4EQ
	Cond4SO
	Cond5LT
	Cond5GT
	Cond5EQ
	Cond5SO
	Cond6LT
	Cond6GT
	Cond6EQ
	Cond6SO
	Cond7LT
	Cond7GT
	Cond7EQ
	Cond7SO
	// Condition Register Fields
	CR0
	CR1
	CR2
	CR3
	CR4
	CR5
	CR6
	CR7
)

func (CondReg) IsArg() {}
func (c CondReg) String() string {
	switch {
	default:
		return fmt.Sprintf("CondReg(%d)", int(c))
	case c >= CR0:
		return fmt.Sprintf("CR%d", int(c-CR0))
	case c >= Cond0LT && c < CR0:
		return fmt.Sprintf("Cond%d%s", int((c-Cond0LT)/4), [4]string{"LT", "GT", "EQ", "SO"}[(c-Cond0LT)%4])
	}
}

// SpReg is a special register, its meaning depends on Op.
type SpReg uint16

const (
	SpRegZero SpReg = 0
)

func (SpReg) IsArg() {}
func (s SpReg) String() string {
	return fmt.Sprintf("SpReg(%d)", int(s))
}

// PCRel is a PC-relative offset, used only in branch instructions.
type PCRel int32

func (PCRel) IsArg() {}
func (r PCRel) String() string {
	return fmt.Sprintf("PC%+#x", int32(r))
}

// A Label is a code (text) address, used only in absolute branch instructions.
type Label uint32

func (Label) IsArg() {}
func (l Label) String() string {
	return fmt.Sprintf("%#x", uint32(l))
}

// Imm represents an immediate number.
type Imm int32

func (Imm) IsArg() {}
func (i Imm) String() string {
	return fmt.Sprintf("%d", int32(i))
}

// Offset represents a memory offset immediate.
type Offset int32

func (Offset) IsArg() {}
func (o Offset) String() string {
	return fmt.Sprintf("%+d", int32(o))
}