1
2
3
4
5 package loong64asm
6
7 import (
8 "fmt"
9 "strings"
10 )
11
12
13 type Inst struct {
14 Op Op
15 Enc uint32
16 Args Args
17 }
18
19 func (i Inst) String() string {
20 var op string = i.Op.String()
21 var args []string
22
23 for _, arg := range i.Args {
24 if arg == nil {
25 break
26 }
27 args = append(args, arg.String())
28 }
29
30 switch i.Op {
31 case OR:
32 if i.Args[2].(Reg) == R0 {
33 op = "move"
34 args = args[0:2]
35 }
36
37 case ANDI:
38 if i.Args[0].(Reg) == R0 && i.Args[1].(Reg) == R0 {
39 return "nop"
40 }
41
42 case JIRL:
43 if i.Args[0].(Reg) == R0 && i.Args[1].(Reg) == R1 && i.Args[2].(OffsetSimm).Imm == 0 {
44 return "ret"
45 } else if i.Args[0].(Reg) == R0 && i.Args[2].(OffsetSimm).Imm == 0 {
46 return "jr " + args[1]
47 }
48
49 case BLT:
50 if i.Args[0].(Reg) == R0 {
51 op = "bgtz"
52 args = args[1:]
53 } else if i.Args[1].(Reg) == R0 {
54 op = "bltz"
55 args = append(args[:1], args[2:]...)
56 }
57
58 case BGE:
59 if i.Args[0].(Reg) == R0 {
60 op = "blez"
61 args = args[1:]
62 } else if i.Args[1].(Reg) == R0 {
63 op = "bgez"
64 args = append(args[:1], args[2:]...)
65 }
66 }
67
68 if len(args) == 0 {
69 return op
70 } else {
71 return op + " " + strings.Join(args, ", ")
72 }
73 }
74
75
76 type Op uint16
77
78
79
80
81
82 func (op Op) String() string {
83 if (op >= Op(len(opstr))) || (opstr[op] == "") {
84 return fmt.Sprintf("Op(%d)", int(op))
85 }
86
87 return opstr[op]
88 }
89
90
91
92
93 type Args [5]Arg
94
95
96 type Arg interface {
97 String() string
98 }
99
100
101
102 type Reg uint16
103
104 const (
105
106 R0 Reg = iota
107 R1
108 R2
109 R3
110 R4
111 R5
112 R6
113 R7
114 R8
115 R9
116 R10
117 R11
118 R12
119 R13
120 R14
121 R15
122 R16
123 R17
124 R18
125 R19
126 R20
127 R21
128 R22
129 R23
130 R24
131 R25
132 R26
133 R27
134 R28
135 R29
136 R30
137 R31
138
139
140 F0
141 F1
142 F2
143 F3
144 F4
145 F5
146 F6
147 F7
148 F8
149 F9
150 F10
151 F11
152 F12
153 F13
154 F14
155 F15
156 F16
157 F17
158 F18
159 F19
160 F20
161 F21
162 F22
163 F23
164 F24
165 F25
166 F26
167 F27
168 F28
169 F29
170 F30
171 F31
172 )
173
174 func (r Reg) String() string {
175 switch {
176 case r == R0:
177 return "$zero"
178
179 case r == R1:
180 return "$ra"
181
182 case r == R2:
183 return "$tp"
184
185 case r == R3:
186 return "$sp"
187
188 case (r >= R4) && (r <= R11):
189 return fmt.Sprintf("$a%d", int(r-R4))
190
191 case (r >= R12) && (r <= R20):
192 return fmt.Sprintf("$t%d", int(r-R12))
193
194 case r == R21:
195 return "$r21"
196
197 case r == R22:
198 return "$fp"
199
200 case (r >= R23) && (r <= R31):
201 return fmt.Sprintf("$s%d", int(r-R23))
202
203 case (r >= F0) && (r <= F7):
204 return fmt.Sprintf("$fa%d", int(r-F0))
205
206 case (r >= F8) && (r <= F23):
207 return fmt.Sprintf("$ft%d", int(r-F8))
208
209 case (r >= F24) && (r <= F31):
210 return fmt.Sprintf("$fs%d", int(r-F24))
211
212 default:
213 return fmt.Sprintf("Unknown(%d)", int(r))
214 }
215 }
216
217
218 type Fcsr uint8
219
220 const (
221 FCSR0 Fcsr = iota
222 FCSR1
223 FCSR2
224 FCSR3
225 )
226
227 func (f Fcsr) String() string {
228 return fmt.Sprintf("$fcsr%d", uint8(f))
229 }
230
231
232 type Fcc uint8
233
234 const (
235 FCC0 Fcc = iota
236 FCC1
237 FCC2
238 FCC3
239 FCC4
240 FCC5
241 FCC6
242 FCC7
243 )
244
245 func (f Fcc) String() string {
246 return fmt.Sprintf("$fcc%d", uint8(f))
247 }
248
249
250 type Uimm struct {
251 Imm uint32
252 Decimal bool
253 }
254
255 func (i Uimm) String() string {
256 if i.Decimal == true {
257 return fmt.Sprintf("%d", i.Imm)
258 } else {
259 return fmt.Sprintf("%#x", i.Imm)
260 }
261 }
262
263 type Simm16 struct {
264 Imm int16
265 Width uint8
266 }
267
268 func (si Simm16) String() string {
269 return fmt.Sprintf("%d", int32(si.Imm))
270 }
271
272 type Simm32 struct {
273 Imm int32
274 Width uint8
275 }
276
277 func (si Simm32) String() string {
278 return fmt.Sprintf("%d", int32(si.Imm))
279 }
280
281 type OffsetSimm struct {
282 Imm int32
283 Width uint8
284 }
285
286 func (o OffsetSimm) String() string {
287 return fmt.Sprintf("%d", int32(o.Imm))
288 }
289
290 type SaSimm int16
291
292 func (s SaSimm) String() string {
293 return fmt.Sprintf("%#x", int(s))
294 }
295
296 type CodeSimm int16
297
298 func (c CodeSimm) String() string {
299 return fmt.Sprintf("%#x", int(c))
300 }
301
View as plain text