1
2
3
4
5 package riscv64asm
6
7 import (
8 "strings"
9 )
10
11
12
13
14 func GNUSyntax(inst Inst) string {
15 op := strings.ToLower(inst.Op.String())
16 var args []string
17 for _, a := range inst.Args {
18 if a == nil {
19 break
20 }
21 args = append(args, strings.ToLower(a.String()))
22 }
23
24 switch inst.Op {
25 case ADDI, ADDIW, ANDI, ORI, SLLI, SLLIW, SRAI, SRAIW, SRLI, SRLIW, XORI:
26 if inst.Op == ADDI {
27 if inst.Args[1].(Reg) == X0 && inst.Args[0].(Reg) != X0 {
28 op = "li"
29 args[1] = args[2]
30 args = args[:len(args)-1]
31 break
32 }
33
34 if inst.Args[2].(Simm).Imm == 0 {
35 if inst.Args[0].(Reg) == X0 && inst.Args[1].(Reg) == X0 {
36 op = "nop"
37 args = nil
38 } else {
39 op = "mv"
40 args = args[:len(args)-1]
41 }
42 }
43 }
44
45 if inst.Op == ANDI && inst.Args[2].(Simm).Imm == 255 {
46 op = "zext.b"
47 args = args[:len(args)-1]
48 }
49
50 if inst.Op == ADDIW && inst.Args[2].(Simm).Imm == 0 {
51 op = "sext.w"
52 args = args[:len(args)-1]
53 }
54
55 if inst.Op == XORI && inst.Args[2].(Simm).String() == "-1" {
56 op = "not"
57 args = args[:len(args)-1]
58 }
59
60 case ADD:
61 if inst.Args[1].(Reg) == X0 {
62 op = "mv"
63 args[1] = args[2]
64 args = args[:len(args)-1]
65 }
66
67 case BEQ:
68 if inst.Args[1].(Reg) == X0 {
69 op = "beqz"
70 args[1] = args[2]
71 args = args[:len(args)-1]
72 }
73
74 case BGE:
75 if inst.Args[1].(Reg) == X0 {
76 op = "bgez"
77 args[1] = args[2]
78 args = args[:len(args)-1]
79 } else if inst.Args[0].(Reg) == X0 {
80 op = "blez"
81 args[0], args[1] = args[1], args[2]
82 args = args[:len(args)-1]
83 }
84
85 case BLT:
86 if inst.Args[1].(Reg) == X0 {
87 op = "bltz"
88 args[1] = args[2]
89 args = args[:len(args)-1]
90 } else if inst.Args[0].(Reg) == X0 {
91 op = "bgtz"
92 args[0], args[1] = args[1], args[2]
93 args = args[:len(args)-1]
94 }
95
96 case BNE:
97 if inst.Args[1].(Reg) == X0 {
98 op = "bnez"
99 args[1] = args[2]
100 args = args[:len(args)-1]
101 }
102
103 case CSRRC:
104 if inst.Args[0].(Reg) == X0 {
105 op = "csrc"
106 args[0], args[1] = args[1], args[2]
107 args = args[:len(args)-1]
108 }
109
110 case CSRRCI:
111 if inst.Args[0].(Reg) == X0 {
112 op = "csrci"
113 args[0], args[1] = args[1], args[2]
114 args = args[:len(args)-1]
115 }
116
117 case CSRRS:
118 if inst.Args[2].(Reg) == X0 {
119 switch inst.Args[1].(CSR) {
120 case FCSR:
121 op = "frcsr"
122 args = args[:len(args)-2]
123
124 case FFLAGS:
125 op = "frflags"
126 args = args[:len(args)-2]
127
128 case FRM:
129 op = "frrm"
130 args = args[:len(args)-2]
131
132
133
134 case CYCLE:
135 op = "rdcycle"
136 args = args[:len(args)-2]
137
138 case INSTRET:
139 op = "rdinstret"
140 args = args[:len(args)-2]
141
142 case TIME:
143 op = "rdtime"
144 args = args[:len(args)-2]
145
146 default:
147 op = "csrr"
148 args = args[:len(args)-1]
149 }
150 } else if inst.Args[0].(Reg) == X0 {
151 op = "csrs"
152 args[0], args[1] = args[1], args[2]
153 args = args[:len(args)-1]
154 }
155
156 case CSRRSI:
157 if inst.Args[0].(Reg) == X0 {
158 op = "csrsi"
159 args[0], args[1] = args[1], args[2]
160 args = args[:len(args)-1]
161 }
162
163 case CSRRW:
164 switch inst.Args[1].(CSR) {
165 case FCSR:
166 op = "fscsr"
167 if inst.Args[0].(Reg) == X0 {
168 args[0] = args[2]
169 args = args[:len(args)-2]
170 } else {
171 args[1] = args[2]
172 args = args[:len(args)-1]
173 }
174
175 case FFLAGS:
176 op = "fsflags"
177 if inst.Args[0].(Reg) == X0 {
178 args[0] = args[2]
179 args = args[:len(args)-2]
180 } else {
181 args[1] = args[2]
182 args = args[:len(args)-1]
183 }
184
185 case FRM:
186 op = "fsrm"
187 if inst.Args[0].(Reg) == X0 {
188 args[0] = args[2]
189 args = args[:len(args)-2]
190 } else {
191 args[1] = args[2]
192 args = args[:len(args)-1]
193 }
194
195 case CYCLE:
196 if inst.Args[0].(Reg) == X0 && inst.Args[2].(Reg) == X0 {
197 op = "unimp"
198 args = nil
199 }
200
201 default:
202 if inst.Args[0].(Reg) == X0 {
203 op = "csrw"
204 args[0], args[1] = args[1], args[2]
205 args = args[:len(args)-1]
206 }
207 }
208
209 case CSRRWI:
210 if inst.Args[0].(Reg) == X0 {
211 op = "csrwi"
212 args[0], args[1] = args[1], args[2]
213 args = args[:len(args)-1]
214 }
215
216
217 case FENCE:
218 if inst.Args[0].(MemOrder).String() == "iorw" &&
219 inst.Args[1].(MemOrder).String() == "iorw" {
220 args = nil
221 }
222
223 case FSGNJX_D:
224 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
225 op = "fabs.d"
226 args = args[:len(args)-1]
227 }
228
229 case FSGNJX_S:
230 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
231 op = "fabs.s"
232 args = args[:len(args)-1]
233 }
234
235 case FSGNJ_D:
236 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
237 op = "fmv.d"
238 args = args[:len(args)-1]
239 }
240
241 case FSGNJ_S:
242 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
243 op = "fmv.s"
244 args = args[:len(args)-1]
245 }
246
247 case FSGNJN_D:
248 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
249 op = "fneg.d"
250 args = args[:len(args)-1]
251 }
252
253 case FSGNJN_S:
254 if inst.Args[1].(Reg) == inst.Args[2].(Reg) {
255 op = "fneg.s"
256 args = args[:len(args)-1]
257 }
258
259 case JAL:
260 if inst.Args[0].(Reg) == X0 {
261 op = "j"
262 args[0] = args[1]
263 args = args[:len(args)-1]
264 } else if inst.Args[0].(Reg) == X1 {
265 op = "jal"
266 args[0] = args[1]
267 args = args[:len(args)-1]
268 }
269
270 case JALR:
271 if inst.Args[0].(Reg) == X1 && inst.Args[1].(RegOffset).Ofs.Imm == 0 {
272 args[0] = inst.Args[1].(RegOffset).OfsReg.String()
273 args = args[:len(args)-1]
274 }
275
276 if inst.Args[0].(Reg) == X0 {
277 if inst.Args[1].(RegOffset).OfsReg == X1 && inst.Args[1].(RegOffset).Ofs.Imm == 0 {
278 op = "ret"
279 args = nil
280 } else if inst.Args[1].(RegOffset).Ofs.Imm == 0 {
281 op = "jr"
282 args[0] = inst.Args[1].(RegOffset).OfsReg.String()
283 args = args[:len(args)-1]
284 } else {
285 op = "jr"
286 args[0] = inst.Args[1].(RegOffset).String()
287 args = args[:len(args)-1]
288 }
289 }
290
291 case SLTIU:
292 if inst.Args[2].(Simm).String() == "1" {
293 op = "seqz"
294 args = args[:len(args)-1]
295 }
296
297 case SLT:
298 if inst.Args[1].(Reg) == X0 {
299 op = "sgtz"
300 args[1] = args[2]
301 args = args[:len(args)-1]
302 } else if inst.Args[2].(Reg) == X0 {
303 op = "sltz"
304 args = args[:len(args)-1]
305 }
306
307 case SLTU:
308 if inst.Args[1].(Reg) == X0 {
309 op = "snez"
310 args[1] = args[2]
311 args = args[:len(args)-1]
312 }
313
314 case SUB:
315 if inst.Args[1].(Reg) == X0 {
316 op = "neg"
317 args[1] = args[2]
318 args = args[:len(args)-1]
319 }
320
321 case SUBW:
322 if inst.Args[1].(Reg) == X0 {
323 op = "negw"
324 args[1] = args[2]
325 args = args[:len(args)-1]
326 }
327 }
328
329 if args != nil {
330 op += " " + strings.Join(args, ",")
331 }
332 return op
333 }
334
View as plain text