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 249