2004-03-29 Bernie Solomon <bernard@ugsolutions.com>
[mono.git] / mono / arch / hppa / hppa-codegen.h
1 typedef enum {
2         hppa_r0 = 0,
3         hppa_r1,
4         hppa_r2,
5         hppa_rp = hppa_r2,
6         hppa_r3,
7         hppa_r4,
8         hppa_r5,
9         hppa_r6,
10         hppa_r7,
11         hppa_r8,
12         hppa_r9,
13         hppa_r10,
14         hppa_r11,
15         hppa_r12,
16         hppa_r13,
17         hppa_r14,
18         hppa_r15,
19         hppa_r16,
20         hppa_r17,
21         hppa_r18,
22         hppa_r19,
23         hppa_r20,
24         hppa_r21,
25         hppa_r22,
26         hppa_r23,
27         hppa_r24,
28         hppa_r25,
29         hppa_r26,
30         hppa_r27,
31         hppa_r28,
32         hppa_r29,
33         hppa_ap = hppa_r29,
34         hppa_r30,
35         hppa_sp = hppa_r30,
36         hppa_r31
37 } HPPAIntRegister;
38
39 #define hppa_nop(p); \
40         do { \
41                 *(p) = 0x08000240; \
42                 p++; \
43         } while (0)
44
45 #define hppa_ldb(p, disp, base, dest); \
46         do { \
47                 int neg = (disp) < 0; \
48                 *(p) = (0x40000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((dest) << 16) | neg); \
49                 p++; \
50         } while (0)
51
52 #define hppa_stb(p, src, disp, base) \
53         do { \
54                 int neg = (disp) < 0; \
55                 *(p) = (0x60000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((src) << 16) | neg); \
56                 p++; \
57         } while (0)
58
59 #define hppa_ldh(p, disp, base, dest) \
60         do { \
61                 int neg = (disp) < 0; \
62                 g_assert(((disp) & 1) == 0); \
63                 *(p) = (0x44000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((dest) << 16) | neg); \
64                 p++; \
65         } while (0)
66
67 #define hppa_sth(p, src, disp, base) \
68         do { \
69                 int neg = (disp) < 0; \
70                 g_assert(((disp) & 1) == 0); \
71                 *(p) = (0x64000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((src) << 16) | neg); \
72                 p++; \
73         } while (0)
74
75 #define hppa_ldw(p, disp, base, dest) \
76         do { \
77                 int neg = (disp) < 0; \
78                 g_assert(((disp) & 3) == 0); \
79                 *(p) = (0x48000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((dest) << 16) | neg); \
80                 p++; \
81         } while (0)
82
83 #define hppa_stw(p, src, disp, base) \
84         do { \
85                 int neg = (disp) < 0; \
86                 g_assert(((disp) & 3) == 0); \
87                 *(p) = (0x68000000 | (((disp) & 0x1fff) << 1) | ((base) << 21) | ((src) << 16) | neg); \
88                 p++; \
89         } while (0)
90
91 #define hppa_copy(p, src, dest) \
92         do { \
93                 *(p) = (0x34000000 | ((src) << 21) | ((dest) << 16)); \
94                 p++; \
95         } while (0)
96
97 #define hppa_ldd_with_flags(p, disp, base, dest, m, a) \
98         do { \
99                 int neg = (disp) < 0; \
100                 int im10a = (disp) >> 3; \
101                 g_assert(((disp) & 7) == 0); \
102                 *(p) = (0x50000000 | (((im10a) & 0x3ff) << 4) | ((base) << 21) | ((dest) << 16) | neg | (m ? 0x8 : 0) | (a ? 0x4 : 0)); \
103                 p++; \
104         } while (0)
105
106 #define hppa_ldd(p, disp, base, dest) \
107         hppa_ldd_with_flags(p, disp, base, dest, 0, 0)
108
109 #define hppa_ldd_mb(p, disp, base, dest) \
110         hppa_ldd_with_flags(p, disp, base, dest, 1, 1)
111
112 #define hppa_std_with_flags(p, src, disp, base, m, a); \
113         do { \
114                 int neg = (disp) < 0; \
115                 int im10a = (disp) >> 3; \
116                 g_assert(((disp) & 7) == 0); \
117                 *(p) = (0x70000000 | (((im10a) & 0x3ff) << 4) | ((base) << 21) | ((src) << 16) | neg | (m ? 0x8 : 0) | (a ? 0x4 : 0)); \
118                 p++; \
119         } while (0)
120
121 #define hppa_std(p, disp, base, dest) \
122         hppa_std_with_flags(p, disp, base, dest, 0, 0)
123
124 #define hppa_std_ma(p, disp, base, dest) \
125         hppa_std_with_flags(p, disp, base, dest, 1, 0)
126
127 #define hppa_fldd_with_flags(p, disp, base, dest, m, a) \
128         do { \
129                 int neg = (disp) < 0; \
130                 int im10a = (disp) >> 3; \
131                 *(p) = (0x50000002 | (((im10a) & 0x3ff) << 4) | ((base) << 21) | ((dest) << 16) | neg | (m ? 0x8 : 0) | (a ? 0x4 : 0)); \
132                 p++; \
133         } while (0)
134
135 #define hppa_fldd(p, disp, base, dest) \
136         hppa_fldd_with_flags(p, disp, base, dest, 0, 0)
137
138 #define hppa_fstd_with_flags(p, src, disp, base, m, a) \
139         do { \
140                 int neg = (disp) < 0; \
141                 int im10a = (disp) >> 3; \
142                 *(p) = (0x70000002 | (((im10a) & 0x3ff) << 4) | ((base) << 21) | ((src) << 16) | neg | (m ? 0x8 : 0) | (a ? 0x4 : 0)); \
143                 p++; \
144         } while (0)
145
146 #define hppa_fstd(p, disp, base, dest) \
147         hppa_fstd_with_flags(p, disp, base, dest, 0, 0)
148
149
150 #define hppa_fldw_with_flags(p, im11a, base, dest, r) \
151         do { \
152                 int neg = (disp) < 0; \
153                 int im11a = (disp) >> 2; \
154                 *(p) = (0x5c000000 | (((im11a) & 0x7ff) << 3) | ((base) << 21) | ((dest) << 16) | neg | ((r) ? 0x2 : 0)); \
155                 p++; \
156         } while (0)
157
158 #define hppa_fldw(p, disp, base, dest) \
159         hppa_fldw_with_flags(p, disp, base, dest, 1)
160
161 #define hppa_fstw_with_flags(p, src, disp, base, r) \
162         do { \
163                 int neg = (disp) < 0; \
164                 int im11a = (disp) >> 2; \
165                 *(p) = (0x7c000000 | (((im11a) & 0x7ff) << 3) | ((base) << 21) | ((src) << 16) | neg | ((r) ? 0x2 : 0)); \
166                 p++; \
167         } while (0)
168
169 #define hppa_fstw(p, src, disp, base) \
170         hppa_fstw_with_flags(p, src, disp, base, 1)
171
172 /* only works on right half SP registers */
173 #define hppa_fcnv(p, src, ssng, dest, dsng) \
174         do { \
175                 *(p) = (0x38000200 | ((src) << 21) | ((ssng) ? 0x80 : 0x800) | (dest) | ((dsng) ? 0x40 : 0x2000)); \
176                 p++; \
177         } while (0)
178
179 #define hppa_fcnv_sng_dbl(p, src, dest) \
180         hppa_fcnv(p, src, 1, dest, 0)
181
182 #define hppa_fcnv_dbl_sng(p, src, dest) \
183         hppa_fcnv(p, src, 0, dest, 1)
184
185 #define hppa_ldil(p, val, dest) \
186         do { \
187                 unsigned int t = (val >> 11) & 0x1fffff; \
188                 unsigned int im21 = ((t & 0x7c) << 14) | ((t & 0x180) << 7) | ((t & 0x3) << 12) | ((t & 0xffe00) >> 8) | ((t & 0x100000) >> 20); \
189                 *(p) = (0x20000000 | im21 | ((dest) << 21)); \
190                 p++; \
191         } while (0)
192
193 #define hppa_ldo(p, off, base, dest) \
194         do { \
195                 int neg = (off) < 0; \
196                 *(p) = (0x34000000 | (((off) & 0x1fff)) << 1 | ((base) << 21) | ((dest) << 16) | neg); \
197                 p++; \
198         } while (0)
199
200 #define hppa_extrdu(p, src, pos, len, dest) \
201         do { \
202                 *(p) = (0xd8000000 | ((src) << 21) | ((dest) << 16) | ((pos) > 32 ? 0x800 : 0) | (((pos) & 31) << 5) | ((len) > 32 ? 0x1000 : 0) | (32 - (len & 31))); \
203                 p++; \
204         } while (0)
205
206 #define hppa_bve(p, reg, link) \
207         do { \
208                 *(p) = (0xE8001000 | ((link ? 7 : 6) << 13) | ((reg) << 21)); \
209                 p++; \
210         } while (0)
211
212 #define hppa_blve(p, reg) \
213         hppa_bve(p, reg, 1)