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