2003-10-13 Bernie Solomon <bernard@ugsolutions.com>
[mono.git] / mono / arch / sparc / sparc-codegen.h
1 #ifndef __SPARC_CODEGEN_H__
2 #define __SPARC_CODEGEN_H__
3
4 #if SIZEOF_VOID_P == 8
5 #define SPARCV9 1
6 #else
7 #define SPARCV9 0
8 #endif
9
10 typedef enum {
11         sparc_r0 = 0,
12         sparc_r1 = 1,
13         sparc_r2 = 2,
14         sparc_r3 = 3,
15         sparc_r4 = 4,
16         sparc_r5 = 5,
17         sparc_r6 = 6,
18         sparc_r7 = 7,
19         sparc_r8 = 8,
20         sparc_r9 = 9,
21         sparc_r10 = 10,
22         sparc_r11 = 11,
23         sparc_r12 = 12,
24         sparc_r13 = 13,
25         sparc_r14 = 14,
26         sparc_r15 = 15,
27         sparc_r16 = 16,
28         sparc_r17 = 17,
29         sparc_r18 = 18,
30         sparc_r19 = 19,
31         sparc_r20 = 20,
32         sparc_r21 = 21,
33         sparc_r22 = 22,
34         sparc_r23 = 23,
35         sparc_r24 = 24,
36         sparc_r25 = 25,
37         sparc_r26 = 26,
38         sparc_r27 = 27,
39         sparc_r28 = 28,
40         sparc_r29 = 29,
41         sparc_r30 = 30,
42         sparc_r31 = 31,
43         /* aliases */
44         /* global registers */
45         sparc_g0 = 0, sparc_zero = 0,
46         sparc_g1 = 1,
47         sparc_g2 = 2,
48         sparc_g3 = 3,
49         sparc_g4 = 4,
50         sparc_g5 = 5,
51         sparc_g6 = 6,
52         sparc_g7 = 7,
53         /* out registers */
54         sparc_o0 = 8,
55         sparc_o1 = 9,
56         sparc_o2 = 10,
57         sparc_o3 = 11,
58         sparc_o4 = 12,
59         sparc_o5 = 13,
60         sparc_o6 = 14, sparc_sp = 14,
61         sparc_o7 = 15, sparc_callsite = 15,
62         /* local registers */
63         sparc_l0 = 16,
64         sparc_l1 = 17,
65         sparc_l2 = 18,
66         sparc_l3 = 19,
67         sparc_l4 = 20,
68         sparc_l5 = 21,
69         sparc_l6 = 22,
70         sparc_l7 = 23,
71         /* in registers */
72         sparc_i0 = 24,
73         sparc_i1 = 25,
74         sparc_i2 = 26,
75         sparc_i3 = 27,
76         sparc_i4 = 28,
77         sparc_i5 = 29,
78         sparc_i6 = 30, sparc_fp = 30,
79         sparc_i7 = 31,
80         sparc_nreg = 32,
81         /* floating point registers */
82         sparc_f0 = 0,
83         sparc_f1 = 1,
84         sparc_f2 = 2,
85         sparc_f3 = 3,
86         sparc_f4 = 4,
87         sparc_f5 = 5,
88         sparc_f6 = 6,
89         sparc_f7 = 7,
90         sparc_f8 = 8,
91         sparc_f9 = 9,
92         sparc_f10 = 10,
93         sparc_f11 = 11,
94         sparc_f12 = 12,
95         sparc_f13 = 13,
96         sparc_f14 = 14,
97         sparc_f15 = 15,
98         sparc_f16 = 16,
99         sparc_f17 = 17,
100         sparc_f18 = 18,
101         sparc_f19 = 19,
102         sparc_f20 = 20,
103         sparc_f21 = 21,
104         sparc_f22 = 22,
105         sparc_f23 = 23,
106         sparc_f24 = 24,
107         sparc_f25 = 25,
108         sparc_f26 = 26,
109         sparc_f27 = 27,
110         sparc_f28 = 28,
111         sparc_f29 = 29,
112         sparc_f30 = 30,
113         sparc_f31 = 31,
114 } SparcRegister;
115
116 typedef enum {
117         sparc_bn   = 0, sparc_bnever = 0,
118         sparc_be   = 1,
119         sparc_ble  = 2,
120         sparc_bl   = 3,
121         sparc_bleu = 4,
122         sparc_bcs  = 5, sparc_blu = 5,
123         sparc_bneg = 6,
124         sparc_bvs  = 7, sparc_boverflow = 7,
125         sparc_ba   = 8, sparc_balways = 8,
126         sparc_bne  = 9,
127         sparc_bg   = 10,
128         sparc_bge  = 11,
129         sparc_bgu  = 12,
130         sparc_bcc  = 13, sparc_beu = 13,
131         sparc_bpos = 14,
132         sparc_bvc  = 15
133 } SparcCond;
134
135 typedef enum {
136         /* with fcmp */
137         sparc_feq = 0,
138         sparc_fl  = 1,
139         sparc_fg  = 2,
140         sparc_unordered = 3,
141         /* branch ops */
142         sparc_fba   = 8,
143         sparc_fbn   = 0,
144         sparc_fbu   = 7,
145         sparc_fbg   = 6,
146         sparc_fbug  = 5,
147         sparc_fbl   = 4,
148         sparc_fbul  = 3,
149         sparc_fblg  = 2,
150         sparc_fbne  = 1,
151         sparc_fbe   = 9,
152         sparc_fbue  = 10,
153         sparc_fbge  = 11,
154         sparc_fbuge = 12,
155         sparc_fble  = 13,
156         sparc_fbule = 14,
157         sparc_fbo   = 15
158 } SparcFCond;
159
160 typedef enum {
161         /* fop1 format */
162         sparc_fitos_val = 196,
163         sparc_fitod_val = 200,
164         sparc_fitoq_val = 204,
165         sparc_fstoi_val = 209,
166         sparc_fdtoi_val = 210,
167         sparc_fqtoi_val = 211,
168         sparc_fstod_val = 201,
169         sparc_fstoq_val = 205,
170         sparc_fdtos_val = 198,
171         sparc_fdtoq_val = 206,
172         sparc_fqtos_val = 199,
173         sparc_fqtod_val = 203,
174         sparc_fmovs_val  = 1,
175         sparc_fnegs_val  = 5,
176         sparc_fabss_val  = 9,
177         sparc_fsqrts_val = 41,
178         sparc_fsqrtd_val = 42,
179         sparc_fsqrtq_val = 43,
180         sparc_fadds_val  = 65,
181         sparc_faddd_val  = 66,
182         sparc_faddq_val  = 67,
183         sparc_fsubs_val  = 69,
184         sparc_fsubd_val  = 70,
185         sparc_fsubq_val  = 71,
186         sparc_fmuls_val  = 73,
187         sparc_fmuld_val  = 74,
188         sparc_fmulq_val  = 75,
189         sparc_fsmuld_val = 105,
190         sparc_fdmulq_val = 111,
191         sparc_fdivs_val  = 77,
192         sparc_fdivd_val  = 78,
193         sparc_fdivq_val  = 79,
194         /* fop2 format */
195         sparc_fcmps_val  = 81,
196         sparc_fcmpd_val  = 82,
197         sparc_fcmpq_val  = 83,
198         sparc_fcmpes_val = 85,
199         sparc_fcmped_val = 86,
200         sparc_fcmpeq_val = 87
201 } SparcFOp;
202
203 typedef struct {
204         unsigned int op   : 2; /* always 1 */
205         unsigned int disp : 30;
206 } sparc_format1;
207
208 typedef struct {
209         unsigned int op   : 2; /* always 0 */
210         unsigned int rd   : 5;
211         unsigned int op2  : 3;
212         unsigned int disp : 22;
213 } sparc_format2a;
214
215 typedef struct {
216         unsigned int op   : 2; /* always 0 */
217         unsigned int a    : 1;
218         unsigned int cond : 4;
219         unsigned int op2  : 3;
220         unsigned int disp : 22;
221 } sparc_format2b;
222
223 typedef struct {
224         unsigned int op   : 2; /* 2 or 3 */
225         unsigned int rd   : 5;
226         unsigned int op3  : 6;
227         unsigned int rs1  : 5;
228         unsigned int i    : 1;
229         unsigned int asi  : 8;
230         unsigned int rs2  : 5;
231 } sparc_format3a;
232
233 typedef struct {
234         unsigned int op   : 2; /* 2 or 3 */
235         unsigned int rd   : 5;
236         unsigned int op3  : 6;
237         unsigned int rs1  : 5;
238         unsigned int i    : 1;
239         unsigned int x    : 1;
240         unsigned int asi  : 7;
241         unsigned int rs2  : 5;
242 } sparc_format3ax;
243
244 typedef struct {
245         unsigned int op   : 2; /* 2 or 3 */
246         unsigned int rd   : 5;
247         unsigned int op3  : 6;
248         unsigned int rs1  : 5;
249         unsigned int i    : 1;
250         unsigned int imm  : 13;
251 } sparc_format3b;
252
253 typedef struct {
254         unsigned int op   : 2; /* 2 or 3 */
255         unsigned int rd   : 5;
256         unsigned int op3  : 6;
257         unsigned int rs1  : 5;
258         unsigned int i    : 1;
259         unsigned int x    : 1;
260         unsigned int imm  : 12;
261 } sparc_format3bx;
262
263 typedef struct {
264         unsigned int op   : 2; /* 2 or 3 */
265         unsigned int rd   : 5;
266         unsigned int op3  : 6;
267         unsigned int rs1  : 5;
268         unsigned int opf  : 9;
269         unsigned int rs2  : 5;
270 } sparc_format3c;
271
272 /* for use in logical ops, use 0 to not set flags */
273 #define sparc_cc 16
274
275 #define sparc_encode_call(ins,addr) \
276         do {    \
277                 sparc_format1 *__f = (sparc_format1*)(ins);     \
278                 __f->op = 1;    \
279                 __f->disp = ((unsigned int)(addr) >> 2);        \
280                 (ins) = (unsigned int*)__f + 1; \
281         } while (0)
282
283 #define sparc_encode_format2a(ins,val,oper,dest) \
284         do {    \
285                 sparc_format2a *__f = (sparc_format2a*)(ins);   \
286                 __f->op = 0;    \
287                 __f->rd = (dest);       \
288                 __f->op2 = (oper);      \
289                 __f->disp = (val) & 0x3fffff;   \
290                 (ins) = (unsigned int*)__f + 1; \
291         } while (0)
292
293 #define sparc_encode_format2b(ins,aval,bcond,oper,disp22) \
294         do {    \
295                 sparc_format2b *__f = (sparc_format2b*)(ins);   \
296                 __f->op = 0;    \
297                 __f->a = (aval);        \
298                 __f->cond = (bcond);    \
299                 __f->op2 = (oper);      \
300                 __f->disp = (disp22);   \
301                 (ins) = (unsigned int*)__f + 1; \
302         } while (0)
303
304 #define sparc_encode_format3a(ins,opval,asival,r1,r2,oper,dest) \
305         do {    \
306                 sparc_format3a *__f = (sparc_format3a*)(ins);   \
307                 __f->op = (opval);      \
308                 __f->asi = (asival);    \
309                 __f->i = 0;     \
310                 __f->rd = (dest);       \
311                 __f->rs1 = (r1);        \
312                 __f->rs2 = (r2);        \
313                 __f->op3 = (oper);      \
314                 (ins) = (unsigned int*)__f + 1; \
315         } while (0)
316
317 #define sparc_encode_format3ax(ins,opval,asival,r1,r2,oper,dest) \
318         do {    \
319                 sparc_format3ax *__f = (sparc_format3ax*)(ins); \
320                 __f->op = (opval);      \
321                 __f->asi = (asival);    \
322                 __f->i = 0;     \
323                 __f->x = 1;     \
324                 __f->rd = (dest);       \
325                 __f->rs1 = (r1);        \
326                 __f->rs2 = (r2);        \
327                 __f->op3 = (oper);      \
328                 (ins) = (unsigned int*)__f + 1; \
329         } while (0)
330
331 #define sparc_encode_format3b(ins,opval,r1,val,oper,dest) \
332         do {    \
333                 sparc_format3b *__f = (sparc_format3b*)(ins);   \
334                 __f->op = (opval);      \
335                 __f->imm = (val);       \
336                 __f->i = 1;     \
337                 __f->rd = (dest);       \
338                 __f->rs1 = (r1);        \
339                 __f->op3 = (oper);      \
340                 (ins) = (unsigned int*)__f + 1; \
341         } while (0)
342
343 #define sparc_encode_format3bx(ins,opval,r1,val,oper,dest) \
344         do {    \
345                 sparc_format3bx *__f = (sparc_format3bx*)(ins); \
346                 __f->op = (opval);      \
347                 __f->imm = (val);       \
348                 __f->i = 1;     \
349                 __f->x = 1;     \
350                 __f->rd = (dest);       \
351                 __f->rs1 = (r1);        \
352                 __f->op3 = (oper);      \
353                 (ins) = (unsigned int*)__f + 1; \
354         } while (0)
355
356 #define sparc_encode_format3c(ins,opval,opfval,r1,oper,r2,dest) \
357         do {    \
358                 sparc_format3c *__f = (sparc_format3c*)(ins);   \
359                 __f->op = (opval);      \
360                 __f->opf = (opfval);    \
361                 __f->rd = (dest);       \
362                 __f->rs1 = (r1);        \
363                 __f->rs2 = (r2);        \
364                 __f->op3 = (oper);      \
365                 (ins) = (unsigned int*)__f + 1; \
366         } while (0)
367
368 /* is it useful to provide a non-default value? */
369 #define sparc_asi 0x0
370
371 /* load */
372 #define sparc_ldsb(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),9,(dest))
373 #define sparc_ldsb_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),9,(dest))
374
375 #define sparc_ldsh(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),10,(dest))
376 #define sparc_ldsh_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),10,(dest))
377
378 #define sparc_ldub(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),1,(dest))
379 #define sparc_ldub_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),1,(dest))
380
381 #define sparc_lduh(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),2,(dest))
382 #define sparc_lduh_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),2,(dest))
383
384 #define sparc_ld(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),0,(dest))
385 #define sparc_ld_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),0,(dest))
386
387 #if SPARCV9
388 #define sparc_ldx(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),11,(dest))
389 #define sparc_ldx_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),11,(dest))
390 #endif
391
392 #define sparc_ldd(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),3,(dest))
393 #define sparc_ldd_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),3,(dest))
394
395 #define sparc_ldf(ins,base,disp,dest) sparc_encode_format3a((ins),3,0,(base),(disp),32,(dest))
396 #define sparc_ldf_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),32,(dest))
397
398 #define sparc_lddf(ins,base,disp,dest) sparc_encode_format3a((ins),3,0,(base),(disp),35,(dest))
399 #define sparc_lddf_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),35,(dest))
400
401 /* store */
402 #define sparc_stb(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),5,(src))
403 #define sparc_stb_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),5,(src))
404
405 #define sparc_sth(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),6,(src))
406 #define sparc_sth_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),6,(src))
407
408 #define sparc_st(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),4,(src))
409 #define sparc_st_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),4,(src))
410
411 #if SPARCV9
412 #define sparc_stx(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),14,(src))
413 #define sparc_stx_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),14,(src))
414 #endif
415
416 #define sparc_std(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),7,(src))
417 #define sparc_std_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),7,(src))
418
419 #define sparc_stf(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),36,(src))
420 #define sparc_stf_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),36,(src))
421
422 #define sparc_stdf(ins,src,base,disp) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),39,(src))
423 #define sparc_stdf_imm(ins,src,base,disp) sparc_encode_format3b((ins),3,(base),(disp),39,(src))
424
425 /* swap */
426 #define sparc_ldstub(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),13,(dest))
427 #define sparc_ldstub_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),13,(dest))
428
429 #define sparc_swap(ins,base,disp,dest) sparc_encode_format3a((ins),3,sparc_asi,(base),(disp),15,(dest))
430 #define sparc_swap_imm(ins,base,disp,dest) sparc_encode_format3b((ins),3,(base),(disp),15,(dest))
431
432 /* misc */
433 /* note: with sethi val is the full 32 bit value (think of it as %hi(val)) */
434 #define sparc_sethi(ins,val,dest) sparc_encode_format2a((ins),((val)>>10),4,(dest))
435
436 #define sparc_nop(ins) sparc_sethi((ins),0,sparc_zero)
437
438 #define sparc_save(ins,src,disp,dest) sparc_encode_format3a((ins),2,0,(src),(disp),60,(dest))
439 #define sparc_save_imm(ins,src,disp,dest) sparc_encode_format3b((ins),2,(src),(disp),60,(dest))
440
441 #define sparc_restore(ins,src,disp,dest) sparc_encode_format3a((ins),2,0,(src),(disp),61,(dest))
442 #define sparc_restore_imm(ins,src,disp,dest) sparc_encode_format3b((ins),2,(src),(disp),61,(dest))
443
444 #define sparc_jmpl(ins,base,disp,dest) sparc_encode_format3a((ins),2,0,(base),(disp),56,(dest))
445 #define sparc_jmpl_imm(ins,base,disp,dest) sparc_encode_format3b((ins),2,(base),(disp),56,(dest))
446
447 #define sparc_call_simple(ins,addr) sparc_encode_call((ins),((unsigned int)(addr)>>2))
448
449 #define sparc_rdy(ins,dest) sparc_encode_format3a((ins),2,0,0,0,40,(dest))
450
451 #define sparc_wry(ins,base,disp) sparc_encode_format3a((ins),2,0,(base),(disp),48,0)
452 #define sparc_wry_imm(ins,base,disp) sparc_encode_format3b((ins),2,(base),(disp),48,0)
453
454 /* stbar, unimp, flush */
455 #define sparc_stbar(ins) sparc_encode_format3a((ins),2,0,15,0,40,0)
456 #define sparc_unimp(ins,val) sparc_encode_format2b((ins),0,0,0,(val))
457
458 #define sparc_flush(ins,base,disp) sparc_encode_format3a((ins),2,0,(base),(disp),59,0)
459 #define sparc_flush_imm(ins,base,disp) sparc_encode_format3b((ins),2,(base),(disp),59,0)
460
461 /* trap */
462
463 /* alu fop */
464 /* provide wrappers for: fitos, fitod, fstoi, fdtoi, fstod, fdtos, fmov, fneg, fabs */
465
466 #define sparc_fop(ins,r1,op,r2,dest) sparc_encode_format3c((ins),2,(op),(r1),52,(r2),(dest))
467 #define sparc_fcmp(ins,r1,op,r2) sparc_encode_format3c((ins),2,(op),(r1),53,(r2),0)
468
469 /* format 1 fops */
470 #define sparc_fadds(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_fadds_val, r2, dest )
471 #define sparc_faddd(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_faddd_val, r2, dest )
472 #define sparc_faddq(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_faddq_val, r2, dest )
473
474 #define sparc_fsubs(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_fsubs_val, r2, dest ) 
475 #define sparc_fsubd(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_fsubd_val, r2, dest ) 
476 #define sparc_fsubq(ins, r1, r2, dest) sparc_fop( ins, r1, sparc_fsubq_val, r2, dest ) 
477
478 #define sparc_fmuls( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fmuls_val, r2, dest )
479 #define sparc_fmuld( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fmuld_val, r2, dest )
480 #define sparc_fmulq( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fmulq_val, r2, dest )
481
482 #define sparc_fsmuld( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fsmuld_val, r2, dest )
483 #define sparc_fdmulq( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fdmulq_val, r2, dest )
484
485 #define sparc_fdivs( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fdivs_val, r2, dest )
486 #define sparc_fdivd( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fdivd_val, r2, dest )
487 #define sparc_fdivq( ins, r1, r2, dest ) sparc_fop( ins, r1, sparc_fdivq_val, r2, dest )
488
489 #define sparc_fitos( ins, r2, dest ) sparc_fop( ins, 0, sparc_fitos_val, r2, dest )
490 #define sparc_fitod( ins, r2, dest ) sparc_fop( ins, 0, sparc_fitod_val, r2, dest )
491 #define sparc_fitoq( ins, r2, dest ) sparc_fop( ins, 0, sparc_fitoq_val, r2, dest )
492
493 #define sparc_fstoi( ins, r2, dest ) sparc_fop( ins, 0, sparc_fstoi_val, r2, dest )
494 #define sparc_fdtoi( ins, r2, dest ) sparc_fop( ins, 0, sparc_fdtoi_val, r2, dest )
495 #define sparc_fqtoi( ins, r2, dest ) sparc_fop( ins, 0, sparc_fqtoi_val, r2, dest )
496
497 #define sparc_fstod( ins, r2, dest ) sparc_fop( ins, 0, sparc_fstod_val, r2, dest )
498 #define sparc_fstoq( ins, r2, dest ) sparc_fop( ins, 0, sparc_fstoq_val, r2, dest )
499
500 #define sparc_fdtos( ins, r2, dest ) sparc_fop( ins, 0, sparc_fdtos_val, r2, dest )
501 #define sparc_fdtoq( ins, r2, dest ) sparc_fop( ins, 0, sparc_fdtoq_val, r2, dest )
502
503 #define sparc_fqtos( ins, r2, dest ) sparc_fop( ins, 0, sparc_fqtos_val, r2, dest )
504 #define sparc_fqtod( ins, r2, dest ) sparc_fop( ins, 0, sparc_fqtod_val, r2, dest )
505
506 #define sparc_fmovs( ins, r2, dest ) sparc_fop( ins, 0, sparc_fmovs_val, r2, dest )
507 #define sparc_fnegs( ins, r2, dest ) sparc_fop( ins, 0, sparc_fnegs_val, r2, dest )
508 #define sparc_fabss( ins, r2, dest ) sparc_fop( ins, 0, sparc_fabss_val, r2, dest )
509
510 #define sparc_fsqrts( ins, r2, dest ) sparc_fop( ins, 0, sparc_fsqrts_val, r2, dest )
511 #define sparc_fsqrtd( ins, r2, dest ) sparc_fop( ins, 0, sparc_fsqrtd_val, r2, dest )
512 #define sparc_fsqrtq( ins, r2, dest ) sparc_fop( ins, 0, sparc_fsqrtq_val, r2, dest )
513
514 /* format 2 fops */
515
516 #define sparc_fcmps( ins, r1, r2 ) sparc_fcmp( ins, r1, sparc_fcmps_val, r2 )
517 #define sparc_fcmpd( ins, r1, r2 ) sparc_fcmp( ins, r1, sparc_fcmpd_val, r2 )
518 #define sparc_fcmpq( ins, r1, r2 ) sparc_fcmp( ins, r1, sparc_fcmpq_val, r2 )
519 #define sparc_fcmpes( ins, r1, r2 ) sparc_fcmpes( ins, r1, sparc_fcmpes_val, r2 )
520 #define sparc_fcmped( ins, r1, r2 ) sparc_fcmped( ins, r1, sparc_fcmped_val, r2 )
521 #define sparc_fcmpeq( ins, r1, r2 ) sparc_fcmpeq( ins, r1, sparc_fcmpeq_val, r2 ) 
522
523 /* logical */
524 #define sparc_and(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|1,(dest))
525 #define sparc_and_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|1,(dest))
526
527 #define sparc_andn(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|5,(dest))
528 #define sparc_andn_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|5,(dest))
529
530 #define sparc_or(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|2,(dest))
531 #define sparc_or_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|2,(dest))
532
533 #define sparc_orn(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|6,(dest))
534 #define sparc_orn_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|6,(dest))
535
536 #define sparc_xor(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|3,(dest))
537 #define sparc_xor_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(r2),(imm)|3,(dest))
538
539 #define sparc_xnor(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|7,(dest))
540 #define sparc_xnor_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|7,(dest))
541
542 /* shift */
543 #define sparc_sll(ins,src,disp,dest) sparc_encode_format3a((ins),2,0,(src),(disp),37,(dest))
544 #define sparc_sll_imm(ins,src,disp,dest) sparc_encode_format3b((ins),2,(src),(disp),37,(dest))
545
546 #if SPARCV9
547 #define sparc_sllx(ins,src,disp,dest) sparc_encode_format3ax((ins),2,0,(src),(disp),37,(dest))
548 #define sparc_sllx_imm(ins,src,disp,dest) sparc_encode_format3bx((ins),2,(src),(disp),37,(dest))
549 #endif
550
551 #define sparc_srl(ins,src,disp,dest) sparc_encode_format3a((ins),2,0,(src),(disp),38,(dest))
552 #define sparc_srl_imm(ins,src,disp,dest) sparc_encode_format3b((ins),2,(src),(disp),38,(dest))
553
554 #if SPARCV9
555 #define sparc_srlx(ins,src,disp,dest) sparc_encode_format3ax((ins),2,0,(src),(disp),38,(dest))
556 #define sparc_srlx_imm(ins,src,disp,dest) sparc_encode_format3bx((ins),2,(src),(disp),38,(dest))
557 #endif
558
559 #define sparc_sra(ins,src,disp,dest) sparc_encode_format3a((ins),2,0,(src),(disp),39,(dest))
560 #define sparc_sra_imm(ins,src,disp,dest) sparc_encode_format3b((ins),2,(src),(disp),39,(dest))
561
562 /* alu */
563 #define sparc_add(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|0,(dest))
564 #define sparc_add_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|0,(dest))
565
566 #define sparc_addx(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|8,(dest))
567 #define sparc_addx_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|8,(dest))
568
569 #define sparc_sub(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|4,(dest))
570 #define sparc_sub_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|4,(dest))
571
572 #define sparc_subx(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|12,(dest))
573 #define sparc_subx_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|12,(dest))
574
575 #define sparc_muls(ins,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),36,(dest))
576 #define sparc_muls_imm(ins,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),36,(dest))
577
578 #define sparc_umul(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|10,(dest))
579 #define sparc_umul_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|10,(dest))
580
581 #define sparc_smul(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|11,(dest))
582 #define sparc_smul_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|11,(dest))
583
584 #define sparc_udiv(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|14,(dest))
585 #define sparc_udiv_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|14,(dest))
586
587 #define sparc_sdiv(ins,setcc,r1,r2,dest) sparc_encode_format3a((ins),2,0,(r1),(r2),(setcc)|15,(dest))
588 #define sparc_sdiv_imm(ins,setcc,r1,imm,dest) sparc_encode_format3b((ins),2,(r1),(imm),(setcc)|15,(dest))
589
590
591 /* branch */
592 #define sparc_branch(ins,aval,condval,displ) sparc_encode_format2b((ins),(aval),(condval),2,(displ))
593 /* FIXME: float condition codes are different: unify. */
594 #define sparc_fbranch(ins,aval,condval,displ) sparc_encode_format2b((ins),(aval),(condval),6,(displ))
595
596 /* synthetic instructions */
597 #define sparc_cmp(ins,r1,r2) sparc_sub((ins),sparc_cc,(r1),(r2),sparc_g0)
598 #define sparc_cmp_imm(ins,r1,imm) sparc_sub_imm((ins),sparc_cc,(r1),(imm),sparc_g0)
599 #define sparc_jmp(ins,base,disp) sparc_jmpl((ins),(base),(disp),sparc_g0)
600 #define sparc_jmp_imm(ins,base,disp) sparc_jmpl_imm((ins),(base),(disp),sparc_g0)
601 #define sparc_call(ins,base,disp) sparc_jmpl((ins),(base),(disp),sparc_o7)
602 #define sparc_call_imm(ins,base,disp) sparc_jmpl_imm((ins),(base),(disp),sparc_o7)
603
604 #define sparc_test(ins,reg) sparc_or ((ins),sparc_cc,sparc_g0,(reg),sparc_g0)
605
606 #define sparc_ret(ins) sparc_jmpl_imm((ins),sparc_i7,8,sparc_g0)
607 #define sparc_retl(ins) sparc_jmpl_imm((ins),sparc_o7,8,sparc_g0)
608 #define sparc_restore_simple(ins) sparc_restore((ins),sparc_g0,sparc_g0,sparc_g0)
609
610 #define sparc_set(ins,val,reg)  \
611         do {    \
612                 if (((guint32)(val) & 0x1fff) == 0)     \
613                         sparc_sethi((ins),(guint32)(val),(reg));        \
614                 else if (((gint32)(val) >= -4096) && ((gint32)(val) <= 4095))   \
615                         sparc_or_imm((ins),FALSE,sparc_g0,(gint32)(val),(reg)); \
616                 else {  \
617                         sparc_sethi((ins),(guint32)(val),(reg));        \
618                         sparc_or_imm((ins),FALSE,(reg),(guint32)(val)&0x3ff,(reg));     \
619                 }       \
620         } while (0)
621
622 #if SPARCV9
623 #define sparc_set_ptr(ins,ptr,reg) \
624         do {    \
625                 guint32 top_word = ((guint64)ptr) >> 32; \
626                 guint32 bottom_word = ((guint64)ptr) & 0xffffffff; \
627                 sparc_set((ins),top_word,sparc_g1); \
628                 sparc_set((ins),bottom_word,(reg));     \
629                 sparc_sllx_imm((ins),sparc_g1,32,sparc_g1);     \
630                 sparc_or((ins),FALSE,(reg),sparc_g1,(reg));     \
631         } while (0)
632 #else
633 #define sparc_set_ptr(ins,val,reg) sparc_set(ins,val,reg)
634 #endif
635
636 #define sparc_not(ins,reg) sparc_xnor((ins),FALSE,(reg),sparc_g0,(reg))
637 #define sparc_neg(ins,reg) sparc_sub((ins),FALSE,sparc_g0,(reg),(reg))
638 #define sparc_clr_reg(ins,reg) sparc_or((ins),FALSE,sparc_g0,sparc_g0,(reg))
639
640 #define sparc_mov_reg_reg(ins,src,dest) sparc_or_imm((ins),FALSE,(src),0,(dest))
641
642
643 #endif /* __SPARC_CODEGEN_H__ */
644