Added tests for Task.WhenAll w/ empty list
[mono.git] / mono / arch / arm / arm-fpa-codegen.h
1 /*
2  * Copyright 2005 Novell Inc
3  * Copyright 2011 Xamarin Inc
4  */
5
6 #ifndef __MONO_ARM_FPA_CODEGEN_H__
7 #define __MONO_ARM_FPA_CODEGEN_H__
8
9 #include "arm-codegen.h"
10
11 enum {
12         /* FPA registers */
13         ARM_FPA_F0,
14         ARM_FPA_F1,
15         ARM_FPA_F2,
16         ARM_FPA_F3,
17         ARM_FPA_F4,
18         ARM_FPA_F5,
19         ARM_FPA_F6,
20         ARM_FPA_F7,
21
22         /* transfer length for LDF/STF (T0/T1), already shifted */
23         ARM_FPA_SINGLE = 0,
24         ARM_FPA_DOUBLE = 1 << 15,
25
26         ARM_FPA_ADF = 0 << 20,
27         ARM_FPA_MUF = 1 << 20,
28         ARM_FPA_SUF = 2 << 20,
29         ARM_FPA_RSF = 3 << 20,
30         ARM_FPA_DVF = 4 << 20,
31         ARM_FPA_RDF = 5 << 20,
32         ARM_FPA_POW = 6 << 20,
33         ARM_FPA_RPW = 7 << 20,
34         ARM_FPA_RMF = 8 << 20,
35         ARM_FPA_FML = 9 << 20,
36         ARM_FPA_FDV = 10 << 20,
37         ARM_FPA_FRD = 11 << 20,
38         ARM_FPA_POL = 12 << 20,
39
40         /* monadic */
41         ARM_FPA_MVF = (0 << 20) | (1 << 15),
42         ARM_FPA_MNF = (1 << 20) | (1 << 15),
43         ARM_FPA_ABS = (2 << 20) | (1 << 15),
44         ARM_FPA_RND = (3 << 20) | (1 << 15),
45         ARM_FPA_SQT = (4 << 20) | (1 << 15),
46         ARM_FPA_LOG = (5 << 20) | (1 << 15),
47         ARM_FPA_LGN = (6 << 20) | (1 << 15),
48         ARM_FPA_EXP = (7 << 20) | (1 << 15),
49         ARM_FPA_SIN = (8 << 20) | (1 << 15),
50         ARM_FPA_COS = (9 << 20) | (1 << 15),
51         ARM_FPA_TAN = (10 << 20) | (1 << 15),
52         ARM_FPA_ASN = (11 << 20) | (1 << 15),
53         ARM_FPA_ACS = (12 << 20) | (1 << 15),
54         ARM_FPA_ATN = (13 << 20) | (1 << 15),
55         ARM_FPA_URD = (14 << 20) | (1 << 15),
56         ARM_FPA_NRM = (15 << 20) | (1 << 15),
57
58         /* round modes */
59         ARM_FPA_ROUND_NEAREST = 0,
60         ARM_FPA_ROUND_PINF = 1,
61         ARM_FPA_ROUND_MINF = 2,
62         ARM_FPA_ROUND_ZERO = 3,
63
64         /* round precision */
65         ARM_FPA_ROUND_SINGLE = 0,
66         ARM_FPA_ROUND_DOUBLE = 1,
67
68         /* constants */
69         ARM_FPA_CONST_0 = 8,
70         ARM_FPA_CONST_1_0 = 9,
71         ARM_FPA_CONST_2_0 = 10,
72         ARM_FPA_CONST_3_0 = 11,
73         ARM_FPA_CONST_4_0 = 12,
74         ARM_FPA_CONST_5_0 = 13,
75         ARM_FPA_CONST_0_5 = 14,
76         ARM_FPA_CONST_10 = 15,
77         
78         /* compares */
79         ARM_FPA_CMF = 4,
80         ARM_FPA_CNF = 5,
81         ARM_FPA_CMFE = 6,
82         ARM_FPA_CNFE = 7,
83
84         /* CPRT ops */
85         ARM_FPA_FLT = 0,
86         ARM_FPA_FIX = 1,
87         ARM_FPA_WFS = 2,
88         ARM_FPA_RFS = 3,
89         ARM_FPA_WFC = 4,
90         ARM_FPA_RFC = 5
91 };
92
93 #define ARM_DEF_FPA_LDF_STF(cond,post,ls,fptype,wback,basereg,fdreg,offset)     \
94         ((offset) >= 0? (offset)>>2: -(offset)>>2)      |       \
95         ((1 << 8) | (fptype))                           |       \
96         ((fdreg) << 12)                                 |       \
97         ((basereg) << 16)                               |       \
98         ((ls) << 20)                                    |       \
99         ((wback) << 21)                                 |       \
100         (((offset) >= 0) << 23)                         |       \
101         ((wback) << 21)                                 |       \
102         ((post) << 24)                                  |       \
103         (6 << 25)                                       |       \
104         ARM_DEF_COND(cond)
105
106 /* FP load and stores */
107 #define ARM_FPA_LDFS_COND(p,freg,base,offset,cond)      \
108         ARM_EMIT((p), ARM_DEF_FPA_LDF_STF((cond),1,ARMOP_LDR,ARM_FPA_SINGLE,0,(base),(freg),(offset)))
109 #define ARM_FPA_LDFS(p,freg,base,offset)        \
110         ARM_FPA_LDFS_COND(p,freg,base,offset,ARMCOND_AL)
111
112 #define ARM_FPA_LDFD_COND(p,freg,base,offset,cond)      \
113         ARM_EMIT((p), ARM_DEF_FPA_LDF_STF((cond),1,ARMOP_LDR,ARM_FPA_DOUBLE,0,(base),(freg),(offset)))
114 #define ARM_FPA_LDFD(p,freg,base,offset)        \
115         ARM_FPA_LDFD_COND(p,freg,base,offset,ARMCOND_AL)
116
117 #define ARM_FPA_STFS_COND(p,freg,base,offset,cond)      \
118         ARM_EMIT((p), ARM_DEF_FPA_LDF_STF((cond),1,ARMOP_STR,ARM_FPA_SINGLE,0,(base),(freg),(offset)))
119 #define ARM_FPA_STFS(p,freg,base,offset)        \
120         ARM_FPA_STFS_COND(p,freg,base,offset,ARMCOND_AL)
121
122 #define ARM_FPA_STFD_COND(p,freg,base,offset,cond)      \
123         ARM_EMIT((p), ARM_DEF_FPA_LDF_STF((cond),1,ARMOP_STR,ARM_FPA_DOUBLE,0,(base),(freg),(offset)))
124 #define ARM_FPA_STFD(p,freg,base,offset)        \
125         ARM_FPA_STFD_COND(p,freg,base,offset,ARMCOND_AL)
126
127 #define ARM_DEF_FPA_CPDO_MONADIC(cond,op,dreg,sreg,round,prec)  \
128         (1 << 8) | (14 << 24)           |       \
129         (op)                            |       \
130         ((sreg) << 0)                   |       \
131         ((round) << 5)                  |       \
132         ((dreg) << 12)                  |       \
133         ((prec) << 7)                   |       \
134         ARM_DEF_COND(cond)
135
136 #define ARM_DEF_FPA_CPDO_DYADIC(cond,op,dreg,sreg1,sreg2,round,prec)    \
137         (1 << 8) | (14 << 24)           |       \
138         (op)                            |       \
139         ((sreg1) << 16)                 |       \
140         ((sreg2) << 0)                  |       \
141         ((round) << 5)                  |       \
142         ((dreg) << 12)                  |       \
143         ((prec) << 7)                   |       \
144         ARM_DEF_COND(cond)
145
146 #define ARM_DEF_FPA_CMP(cond,op,sreg1,sreg2)    \
147         (1 << 4) | (1 << 8) | (15 << 12)        |       \
148         (1 << 20) | (14 << 24)                  |       \
149         (op) << 21                              |       \
150         (sreg1) << 16                           |       \
151         (sreg2)                                 |       \
152         ARM_DEF_COND(cond)
153
154 #define ARM_DEF_FPA_CPRT(cond,op,fn,fm,rd,ftype,round)  \
155         (1 << 4) | (1 << 8) | (14 << 24)        |       \
156         (op) << 20                              |       \
157         (fm)                                    |       \
158         (fn) << 16                              |       \
159         (rd) << 12                              |       \
160         ((round) << 5)                          |       \
161         ((ftype) << 7)                          |       \
162         ARM_DEF_COND(cond)
163
164
165 #include "arm_fpamacros.h"
166
167 #define ARM_FPA_RNDDZ_COND(p,dreg,sreg,cond) \
168         ARM_EMIT((p), ARM_DEF_FPA_CPDO_MONADIC((cond),ARM_FPA_RND,(dreg),(sreg),ARM_FPA_ROUND_ZERO,ARM_FPA_ROUND_DOUBLE))
169 #define ARM_FPA_RNDDZ(p,dreg,sreg)      ARM_FPA_RNDD_COND(p,dreg,sreg,ARMCOND_AL)
170
171 /* compares */
172 #define ARM_FPA_FCMP_COND(p,op,sreg1,sreg2,cond)        \
173         ARM_EMIT(p, ARM_DEF_FPA_CMP(cond,op,sreg1,sreg2))
174 #define ARM_FPA_FCMP(p,op,sreg1,sreg2) ARM_FPA_FCMP_COND(p,op,sreg1,sreg2,ARMCOND_AL)
175
176 /* coprocessor register transfer */
177 #define ARM_FPA_FLTD(p,fn,rd)   \
178         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_FLT,(fn),0,(rd),ARM_FPA_ROUND_DOUBLE,ARM_FPA_ROUND_NEAREST))
179 #define ARM_FPA_FLTS(p,fn,rd)   \
180         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_FLT,(fn),0,(rd),ARM_FPA_ROUND_SINGLE,ARM_FPA_ROUND_NEAREST))
181
182 #define ARM_FPA_FIXZ(p,rd,fm)   \
183         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_FIX,0,(fm),(rd),0,ARM_FPA_ROUND_ZERO))
184
185 #define ARM_FPA_WFS(p,rd)       \
186         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_WFS,0,0,(rd),0,ARM_FPA_ROUND_NEAREST))
187
188 #define ARM_FPA_RFS(p,rd)       \
189         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_RFS,0,0,(rd),0,ARM_FPA_ROUND_NEAREST))
190
191 #define ARM_FPA_WFC(p,rd)       \
192         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_WFC,0,0,(rd),0,ARM_FPA_ROUND_NEAREST))
193
194 #define ARM_FPA_RFC(p,rd)       \
195         ARM_EMIT(p, ARM_DEF_FPA_CPRT(ARMCOND_AL,ARM_FPA_RFC,0,0,(rd),0,ARM_FPA_ROUND_NEAREST))
196
197 #endif /* __MONO_ARM_FPA_CODEGEN_H__ */
198