First set of licensing changes
[mono.git] / mono / arch / arm / arm-vfp-codegen.h
1 //
2 // Copyright 2011 Xamarin Inc
3 //
4 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
6 #ifndef __MONO_ARM_VFP_CODEGEN_H__
7 #define __MONO_ARM_VFP_CODEGEN_H__
8
9 #include "arm-codegen.h"
10
11 enum {
12         /* VFP registers */
13         ARM_VFP_F0,
14         ARM_VFP_F1,
15         ARM_VFP_F2,
16         ARM_VFP_F3,
17         ARM_VFP_F4,
18         ARM_VFP_F5,
19         ARM_VFP_F6,
20         ARM_VFP_F7,
21         ARM_VFP_F8,
22         ARM_VFP_F9,
23         ARM_VFP_F10,
24         ARM_VFP_F11,
25         ARM_VFP_F12,
26         ARM_VFP_F13,
27         ARM_VFP_F14,
28         ARM_VFP_F15,
29         ARM_VFP_F16,
30         ARM_VFP_F17,
31         ARM_VFP_F18,
32         ARM_VFP_F19,
33         ARM_VFP_F20,
34         ARM_VFP_F21,
35         ARM_VFP_F22,
36         ARM_VFP_F23,
37         ARM_VFP_F24,
38         ARM_VFP_F25,
39         ARM_VFP_F26,
40         ARM_VFP_F27,
41         ARM_VFP_F28,
42         ARM_VFP_F29,
43         ARM_VFP_F30,
44         ARM_VFP_F31,
45
46         ARM_VFP_D0 = ARM_VFP_F0,
47         ARM_VFP_D1 = ARM_VFP_F2,
48         ARM_VFP_D2 = ARM_VFP_F4,
49         ARM_VFP_D3 = ARM_VFP_F6,
50         ARM_VFP_D4 = ARM_VFP_F8,
51         ARM_VFP_D5 = ARM_VFP_F10,
52         ARM_VFP_D6 = ARM_VFP_F12,
53         ARM_VFP_D7 = ARM_VFP_F14,
54         ARM_VFP_D8 = ARM_VFP_F16,
55         ARM_VFP_D9 = ARM_VFP_F18,
56         ARM_VFP_D10 = ARM_VFP_F20,
57         ARM_VFP_D11 = ARM_VFP_F22,
58         ARM_VFP_D12 = ARM_VFP_F24,
59         ARM_VFP_D13 = ARM_VFP_F26,
60         ARM_VFP_D14 = ARM_VFP_F28,
61         ARM_VFP_D15 = ARM_VFP_F30,
62
63         ARM_VFP_COPROC_SINGLE = 10,
64         ARM_VFP_COPROC_DOUBLE = 11,
65
66 #define ARM_VFP_OP(p,q,r,s) (((p) << 23) | ((q) << 21) | ((r) << 20) | ((s) << 6))
67 #define ARM_VFP_OP2(Fn,N) (ARM_VFP_OP (1,1,1,1) | ((Fn) << 16) | ((N) << 7))
68
69         ARM_VFP_MUL = ARM_VFP_OP (0,1,0,0),
70         ARM_VFP_NMUL = ARM_VFP_OP (0,1,0,1),
71         ARM_VFP_ADD = ARM_VFP_OP (0,1,1,0),
72         ARM_VFP_SUB = ARM_VFP_OP (0,1,1,1),
73         ARM_VFP_DIV = ARM_VFP_OP (1,0,0,0),
74
75         ARM_VFP_CPY = ARM_VFP_OP2 (0,0),
76         ARM_VFP_ABS = ARM_VFP_OP2 (0,1),
77         ARM_VFP_NEG = ARM_VFP_OP2 (1,0),
78         ARM_VFP_SQRT = ARM_VFP_OP2 (1,1),
79         ARM_VFP_CMP = ARM_VFP_OP2 (4,0),
80         ARM_VFP_CMPE = ARM_VFP_OP2 (4,1),
81         ARM_VFP_CMPZ = ARM_VFP_OP2 (5,0),
82         ARM_VFP_CMPEZ = ARM_VFP_OP2 (5,1),
83         ARM_VFP_CVT = ARM_VFP_OP2 (7,1),
84         ARM_VFP_UITO = ARM_VFP_OP2 (8,0),
85         ARM_VFP_SITO = ARM_VFP_OP2 (8,1),
86         ARM_VFP_TOUI = ARM_VFP_OP2 (12,0),
87         ARM_VFP_TOSI = ARM_VFP_OP2 (13,0),
88         ARM_VFP_TOUIZ = ARM_VFP_OP2 (12,1),
89         ARM_VFP_TOSIZ = ARM_VFP_OP2 (13,1),
90
91         ARM_VFP_SID = 0,
92         ARM_VFP_SCR = 1 << 1,
93         ARM_VFP_EXC = 8 << 1
94 };
95
96 #define ARM_DEF_VFP_DYADIC(cond,cp,op,Fd,Fn,Fm) \
97         (14 << 24)                              |       \
98         ((cp) << 8)                             |       \
99         (op)                                    |       \
100         (((Fd) >> 1) << 12)                     |       \
101         (((Fd) & 1) << 22)                      |       \
102         (((Fn) >> 1) << 16)                     |       \
103         (((Fn) & 1) << 7)                       |       \
104         (((Fm) >> 1) << 0)                      |       \
105         (((Fm) & 1) << 5)                       |       \
106         ARM_DEF_COND(cond)
107
108 #define ARM_DEF_VFP_MONADIC(cond,cp,op,Fd,Fm)   \
109         (14 << 24)                              |       \
110         ((cp) << 8)                             |       \
111         (op)                                    |       \
112         (((Fd) >> 1) << 12)                     |       \
113         (((Fd) & 1) << 22)                      |       \
114         (((Fm) >> 1) << 0)                      |       \
115         (((Fm) & 1) << 5)                       |       \
116         ARM_DEF_COND(cond)
117
118 #define ARM_DEF_VFP_LSF(cond,cp,post,ls,wback,basereg,Fd,offset)        \
119         ((offset) >= 0? (offset)>>2: -(offset)>>2)      |       \
120         (6 << 25)                                       |       \
121         ((cp) << 8)                                     |       \
122         (((Fd) >> 1) << 12)                             |       \
123         (((Fd) & 1) << 22)                              |       \
124         ((basereg) << 16)                               |       \
125         ((ls) << 20)                                    |       \
126         ((wback) << 21)                                 |       \
127         (((offset) >= 0) << 23)                         |       \
128         ((wback) << 21)                                 |       \
129         ((post) << 24)                                  |       \
130         ARM_DEF_COND(cond)
131
132 #define ARM_DEF_VFP_CPT(cond,cp,op,L,Fn,Rd)     \
133         (14 << 24)                              |       \
134         (1 << 4)                                |       \
135         ((cp) << 8)                             |       \
136         ((op) << 21)                            |       \
137         ((L) << 20)                             |       \
138         ((Rd) << 12)                            |       \
139         (((Fn) >> 1) << 16)                     |       \
140         (((Fn) & 1) << 7)                       |       \
141         ARM_DEF_COND(cond)
142
143 /* FP load and stores */
144 #define ARM_FLDS_COND(p,freg,base,offset,cond)  \
145         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_SINGLE,1,ARMOP_LDR,0,(base),(freg),(offset)))
146 #define ARM_FLDS(p,freg,base,offset)    \
147         ARM_FLDS_COND(p,freg,base,offset,ARMCOND_AL)
148
149 #define ARM_FLDD_COND(p,freg,base,offset,cond)  \
150         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_DOUBLE,1,ARMOP_LDR,0,(base),(freg),(offset)))
151 #define ARM_FLDD(p,freg,base,offset)    \
152         ARM_FLDD_COND(p,freg,base,offset,ARMCOND_AL)
153
154 #define ARM_FSTS_COND(p,freg,base,offset,cond)  \
155         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_SINGLE,1,ARMOP_STR,0,(base),(freg),(offset)))
156 #define ARM_FSTS(p,freg,base,offset)    \
157         ARM_FSTS_COND(p,freg,base,offset,ARMCOND_AL)
158
159 #define ARM_FSTD_COND(p,freg,base,offset,cond)  \
160         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_DOUBLE,1,ARMOP_STR,0,(base),(freg),(offset)))
161 #define ARM_FSTD(p,freg,base,offset)    \
162         ARM_FSTD_COND(p,freg,base,offset,ARMCOND_AL)
163
164 #define ARM_FLDMD_COND(p,first_reg,nregs,base,cond)                                                     \
165         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_DOUBLE,0,ARMOP_LDR,0,(base),(first_reg),((nregs) * 2) << 2))
166
167 #define ARM_FLDMD(p,first_reg,nregs,base)               \
168         ARM_FLDMD_COND(p,first_reg,nregs,base,ARMCOND_AL)
169
170 #define ARM_FSTMD_COND(p,first_reg,nregs,base,cond)                                                     \
171         ARM_EMIT((p), ARM_DEF_VFP_LSF((cond),ARM_VFP_COPROC_DOUBLE,0,ARMOP_STR,0,(base),(first_reg),((nregs) * 2) << 2))
172
173 #define ARM_FSTMD(p,first_reg,nregs,base)               \
174         ARM_FSTMD_COND(p,first_reg,nregs,base,ARMCOND_AL)
175
176 #include <mono/arch/arm/arm_vfpmacros.h>
177
178 /* coprocessor register transfer */
179 #define ARM_FMSR(p,freg,reg)    \
180         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_SINGLE,0,0,(freg),(reg)))
181 #define ARM_FMRS(p,reg,freg)    \
182         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_SINGLE,0,1,(freg),(reg)))
183
184 #define ARM_FMDLR(p,freg,reg)   \
185         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,0,0,(freg),(reg)))
186 #define ARM_FMRDL(p,reg,freg)   \
187         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,0,1,(freg),(reg)))
188 #define ARM_FMDHR(p,freg,reg)   \
189         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,1,0,(freg),(reg)))
190 #define ARM_FMRDH(p,reg,freg)   \
191         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,1,1,(freg),(reg)))
192
193 #define ARM_FMXR(p,freg,reg)    \
194         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_SINGLE,7,0,(freg),(reg)))
195 #define ARM_FMRX(p,reg,fcreg)   \
196         ARM_EMIT((p), ARM_DEF_VFP_CPT(ARMCOND_AL,ARM_VFP_COPROC_SINGLE,7,1,(fcreg),(reg)))
197
198 #define ARM_FMSTAT(p)   \
199         ARM_FMRX((p),ARMREG_R15,ARM_VFP_SCR)
200
201 #define ARM_DEF_MCRR(cond,cp,rn,rd,Fm,M) \
202         ((Fm) << 0) |                                      \
203         (1 << 4)   |                                       \
204         ((M) << 5) |                                       \
205         ((cp) << 8) |                                      \
206         ((rd) << 12) |                                     \
207         ((rn) << 16) |                                     \
208         ((2) << 21) |                                      \
209         (12 << 24) |                                       \
210         ARM_DEF_COND(cond)
211
212 #define ARM_FMDRR(p,rd,rn,dm)   \
213         ARM_EMIT((p), ARM_DEF_MCRR(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,(rn),(rd),(dm) >> 1, (dm) & 1))
214
215 #define ARM_DEF_FMRRD(cond,cp,rn,rd,Dm,D)               \
216         ((Dm) << 0) |                                      \
217         (1 << 4)   |                                       \
218         ((cp) << 8) |                                      \
219         ((rd) << 12) |                                     \
220         ((rn) << 16) |                                     \
221         ((0xc5) << 20) |                                           \
222         ARM_DEF_COND(cond)
223
224 #define ARM_FMRRD(p,rd,rn,dm)   \
225         ARM_EMIT((p), ARM_DEF_FMRRD(ARMCOND_AL,ARM_VFP_COPROC_DOUBLE,(rn),(rd),(dm) >> 1, (dm) & 1))
226
227 #define ARM_DEF_FUITOS(cond,Dd,D,Fm,M) ((cond) << 28) | ((0x1d) << 23) | ((D) << 22) | ((0x3) << 20) | ((8) << 16) | ((Dd) << 12) | ((0xa) << 8) | ((1) << 6) | ((M) << 5) | ((Fm) << 0)
228
229 #define ARM_FUITOS(p,dreg,sreg) \
230         ARM_EMIT((p), ARM_DEF_FUITOS (ARMCOND_AL, (dreg) >> 1, (dreg) & 1, (sreg) >> 1, (sreg) & 1))
231
232 #define ARM_DEF_FUITOD(cond,Dd,D,Fm,M) ((cond) << 28) | ((0x1d) << 23) | ((D) << 22) | ((0x3) << 20) | ((8) << 16) | ((Dd) << 12) | ((0xb) << 8) | ((1) << 6) | ((M) << 5) | ((Fm) << 0)
233
234 #define ARM_FUITOD(p,dreg,sreg) \
235         ARM_EMIT((p), ARM_DEF_FUITOD (ARMCOND_AL, (dreg) >> 1, (dreg) & 1, (sreg) >> 1, (sreg) & 1))
236
237 #define ARM_DEF_FSITOS(cond,Dd,D,Fm,M) ((cond) << 28) | ((0x1d) << 23) | ((D) << 22) | ((0x3) << 20) | ((8) << 16) | ((Dd) << 12) | ((0xa) << 8) | ((1) << 7) | ((1) << 6) | ((M) << 5) | ((Fm) << 0)
238
239 #define ARM_FSITOS(p,dreg,sreg) \
240         ARM_EMIT((p), ARM_DEF_FSITOS (ARMCOND_AL, (dreg) >> 1, (dreg) & 1, (sreg) >> 1, (sreg) & 1))
241
242 #define ARM_DEF_FSITOD(cond,Dd,D,Fm,M) ((cond) << 28) | ((0x1d) << 23) | ((D) << 22) | ((0x3) << 20) | ((8) << 16) | ((Dd) << 12) | ((0xb) << 8) | ((1) << 7) | ((1) << 6) | ((M) << 5) | ((Fm) << 0)
243
244 #define ARM_FSITOD(p,dreg,sreg) \
245         ARM_EMIT((p), ARM_DEF_FSITOD (ARMCOND_AL, (dreg) >> 1, (dreg) & 1, (sreg) >> 1, (sreg) & 1))
246
247 #endif /* __MONO_ARM_VFP_CODEGEN_H__ */
248