1 #include "const.h" 2 3 typedef enum { 4 ABSS=0, ABSD, ADDS, ADDD, 5 DIVS, DIVD, MULS, MULD, 6 NEGS, NEGD, SQRTS, SQRTD, 7 SUBS, SUBD, RECIPS, RECIPD, 8 RSQRTS, RSQRTD, MSUBS, MSUBD, 9 MADDS, MADDD, NMADDS, NMADDD, 10 NMSUBS, NMSUBD 11 } flt_art_op_t; 12 13 typedef enum { 14 CEILWS=0, CEILWD, FLOORWS, FLOORWD, 15 ROUNDWS, ROUNDWD, TRUNCWS, TRUNCWD, 16 CEILLS, CEILLD, FLOORLS, FLOORLD, 17 ROUNDLS, ROUNDLD, TRUNCLS, TRUNCLD 18 } flt_dir_op_t; 19 20 typedef enum { 21 CVTDS, CVTDW, CVTSD, CVTSW, 22 CVTWS, CVTWD, CVTDL, CVTLS, 23 CVTLD, CVTSL, 24 } flt_round_op_t; 25 26 const char *flt_art_op_names[] = { 27 "abs.s", "abs.d", "add.s", "add.d", 28 "div.s", "div.d", "mul.s", "mul.d", 29 "neg.s", "neg.d", "sqrt.s", "sqrt.d", 30 "sub.s", "sub.d", "recip.s", "recip.d", 31 "rsqrt.s", "rsqrt.d", "msub.s", "msub.d", 32 "madd.s", "madd.d", "nmadd.s", "nmadd.d", 33 "nmsub.s", "nmsub.d" 34 }; 35 36 const char *flt_dir_op_names[] = { 37 "ceil.w.s", "ceil.w.d", 38 "floor.w.s", "floor.w.d", 39 "round.w.s", "round.w.d", 40 "trunc.w.s", "trunc.w.d", 41 "ceil.l.s", "ceil.l.d", 42 "floor.l.s", "floor.l.d", 43 "round.l.s", "round.l.d", 44 "trunc.l.s", "trunc.l.d" 45 }; 46 47 const char *flt_round_op_names[] = { 48 "cvt.d.s", "cvt.d.w", 49 "cvt.s.d", "cvt.s.w", 50 "cvt.w.s", "cvt.w.d", 51 "cvt.d.l", "cvt.l.s", 52 "cvt.l.d", "cvt.s.l", 53 }; 54 55 #if defined(__mips_hard_float) 56 #define UNOPdd(op) \ 57 fd_d = 0; \ 58 __asm__ __volatile__( \ 59 op" %1, %2" "\n\t" \ 60 "cfc1 %0, $31" "\n\t" \ 61 : "=r" (fcsr), "=f"(fd_d) \ 62 : "f"(fs_d[i]) \ 63 ); 64 65 #define UNOPff(op) \ 66 fd_f = 0; \ 67 __asm__ __volatile__( \ 68 op" %1, %2" "\n\t" \ 69 "cfc1 %0, $31" "\n\t" \ 70 : "=r" (fcsr), "=f"(fd_f) \ 71 : "f"(fs_f[i]) \ 72 ); 73 74 #define UNOPfd(op) \ 75 fd_d = 0; \ 76 __asm__ __volatile__( \ 77 op" %1, %2" "\n\t" \ 78 "cfc1 %0, $31" "\n\t" \ 79 : "=r" (fcsr), "=f"(fd_d) \ 80 : "f"(fs_f[i]) \ 81 ); 82 83 #define UNOPdf(op) \ 84 fd_f = 0; \ 85 __asm__ __volatile__( \ 86 op" %1, %2" "\n\t" \ 87 "cfc1 %0, $31" "\n\t" \ 88 : "=r" (fcsr), "=f"(fd_f) \ 89 : "f"(fs_d[i]) \ 90 ); 91 92 #define UNOPfw(op) \ 93 fd_w = 0; \ 94 __asm__ __volatile__( \ 95 op" $f0, %2" "\n\t" \ 96 "mfc1 %1, $f0" "\n\t" \ 97 "cfc1 %0, $31" "\n\t" \ 98 : "=r" (fcsr), "=r"(fd_w) \ 99 : "f"(fs_f[i]) \ 100 : "$f0" \ 101 ); 102 103 #define UNOPdw(op) \ 104 fd_w = 0; \ 105 __asm__ __volatile__( \ 106 op" $f0, %2" "\n\t" \ 107 "mfc1 %1, $f0" "\n\t" \ 108 "cfc1 %0, $31" "\n\t" \ 109 : "=r" (fcsr), "=r"(fd_w) \ 110 : "f"(fs_d[i]) \ 111 : "$f0" \ 112 ); 113 114 #define UNOPwd(op) \ 115 fd_d = 0; \ 116 __asm__ __volatile__( \ 117 "mtc1 %2, $f0" "\n\t" \ 118 op" %1, $f0" "\n\t" \ 119 "cfc1 %0, $31" "\n\t" \ 120 : "=r" (fcsr), "=f"(fd_d) \ 121 : "r"(fs_w[i]) \ 122 : "$f0" \ 123 ); 124 125 #define UNOPwf(op) \ 126 fd_f = 0; \ 127 __asm__ __volatile__( \ 128 "mtc1 %2, $f0" "\n\t" \ 129 op" %1, $f0" "\n\t" \ 130 "cfc1 %0, $31" "\n\t" \ 131 : "=r" (fcsr), "=f"(fd_f) \ 132 : "r"(fs_w[i]) \ 133 : "$f0" \ 134 ); 135 136 #define UNOPld(op) \ 137 fd_d = 0; \ 138 __asm__ __volatile__( \ 139 "dmtc1 %2, $f0" "\n\t" \ 140 op" %1, $f0" "\n\t" \ 141 "cfc1 %0, $31" "\n\t" \ 142 : "=r" (fcsr), "=f"(fd_d) \ 143 : "r"(fs_l[i]) \ 144 : "$f0" \ 145 ); 146 147 #define UNOPdl(op) \ 148 fd_l = 0; \ 149 __asm__ __volatile__( \ 150 op" $f0, %2" "\n\t" \ 151 "dmfc1 %1, $f0" "\n\t" \ 152 "cfc1 %0, $31" "\n\t" \ 153 : "=r" (fcsr), "=r"(fd_l) \ 154 : "f"(fs_d[i]) \ 155 : "$f0" \ 156 ); 157 158 #define UNOPls(op) \ 159 fd_f = 0; \ 160 __asm__ __volatile__( \ 161 "dmtc1 %2, $f0" "\n\t" \ 162 op" %1, $f0" "\n\t" \ 163 "cfc1 %0, $31" "\n\t" \ 164 : "=r" (fcsr), "=f"(fd_f) \ 165 : "r"(fs_l[i]) \ 166 : "$f0" \ 167 ); 168 169 #define UNOPsl(op) \ 170 fd_l = 0; \ 171 __asm__ __volatile__( \ 172 op" $f0, %2" "\n\t" \ 173 "dmfc1 %1, $f0" "\n\t" \ 174 "cfc1 %0, $31" "\n\t" \ 175 : "=r" (fcsr), "=r"(fd_l) \ 176 : "f"(fs_f[i]) \ 177 : "$f0" \ 178 ); 179 180 #define BINOPf(op) \ 181 fd_f = 0; \ 182 __asm__ __volatile__( \ 183 op" %1, %2, %3" "\n\t" \ 184 "cfc1 %0, $31" "\n\t" \ 185 : "=r" (fcsr), "=f" (fd_f) \ 186 : "f" (fs_f[i]), "f" (ft_f[i]) \ 187 ); 188 189 #define BINOPd(op) \ 190 fd_d = 0; \ 191 __asm__ __volatile__( \ 192 op" %1, %2, %3" "\n\t" \ 193 "cfc1 %0, $31" "\n\t" \ 194 : "=r" (fcsr), "=f"(fd_d) \ 195 : "f" (fs_d[i]), "f" (ft_d[i]) \ 196 ); 197 198 #define TRIOPf(op) \ 199 fd_f = 0; \ 200 __asm__ __volatile__( \ 201 op" %1, %2, %3, %4" "\n\t" \ 202 "cfc1 %0, $31" "\n\t" \ 203 : "=r" (fcsr), "=f" (fd_f) \ 204 : "f" (fr_f[i]), "f" (fs_f[i]) , "f" (ft_f[i]) \ 205 ); 206 207 #define TRIOPd(op) \ 208 fd_d = 0; \ 209 __asm__ __volatile__( \ 210 op" %1, %2, %3, %4" "\n\t" \ 211 "cfc1 %0, $31" "\n\t" \ 212 : "=r" (fcsr), "=f"(fd_d) \ 213 : "f" (fr_d[i]), "f" (fs_d[i]) , "f" (ft_d[i]) \ 214 ); 215 216 /* Conditional macros.*/ 217 #define TESTINST1s(instruction, RDval) \ 218 { \ 219 float outf = 0; \ 220 __asm__ __volatile__( \ 221 ".set noreorder" "\n\t" \ 222 "mov.s $f1, %1" "\n\t" \ 223 "mov.s $f2, %2" "\n\t" \ 224 "mtc1 $zero, $f0" "\n\t" \ 225 "c.eq.s $f1, $f2" "\n\t" \ 226 instruction" end"instruction"s"#RDval "\n\t" \ 227 "nop" "\n\t" \ 228 "add.s $f0, $f0, $f1" "\n\t" \ 229 "end"instruction"s"#RDval":" "\n\t" \ 230 "add.s $f0, $f0, $f2" "\n\t" \ 231 "mov.s %0, $f0" "\n\t" \ 232 ".set reorder" "\n\t" \ 233 : "=f" (outf) \ 234 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 235 : "$f0", "$f1", "$f2" \ 236 ); \ 237 printf("%s, c.eq.s out=%f, fs=%f, ft=%f\n", \ 238 instruction, outf, fs_f[i], ft_f[i]); \ 239 } 240 241 #define TESTINST1d(instruction, RDval) \ 242 { \ 243 double outd = 0; \ 244 __asm__ __volatile__( \ 245 ".set noreorder" "\n\t" \ 246 "mov.d $f1, %1" "\n\t" \ 247 "mov.d $f2, %2" "\n\t" \ 248 "dmtc1 $zero, $f0" "\n\t" \ 249 "c.eq.d $f1, $f2" "\n\t" \ 250 instruction" end"instruction"d"#RDval "\n\t" \ 251 "nop" "\n\t" \ 252 "add.d $f0, $f0, $f1" "\n\t" \ 253 "end"instruction"d"#RDval":" "\n\t" \ 254 "add.d $f0, $f0, $f2" "\n\t" \ 255 "mov.d %0, $f0" "\n\t" \ 256 ".set reorder" "\n\t" \ 257 : "=f" (outd) \ 258 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 259 : "$f0", "$f1", "$f2" \ 260 ); \ 261 printf("%s, c.eq.d out=%f, fs=%f, ft=%f\n", \ 262 instruction, outd, fs_d[i], ft_d[i]); \ 263 } 264 265 #define TESTINST2s(instruction, RDval) \ 266 { \ 267 float outf = 0; \ 268 __asm__ __volatile__( \ 269 ".set noreorder" "\n\t" \ 270 "mov.s $f1, %1" "\n\t" \ 271 "mov.s $f2, %2" "\n\t" \ 272 "mtc1 $zero, $f0" "\n\t" \ 273 "c.eq.s $f1, $f2" "\n\t" \ 274 instruction" end"instruction"s"#RDval "\n\t" \ 275 "add.s $f0, $f0, $f1" "\n\t" \ 276 "end"instruction"s"#RDval":" "\n\t" \ 277 "add.s $f0, $f0, $f2" "\n\t" \ 278 "mov.s %0, $f0" "\n\t" \ 279 ".set reorder" "\n\t" \ 280 : "=f" (outf) \ 281 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 282 : "$f0", "$f1", "$f2" \ 283 ); \ 284 printf("%s, c.eq.s out=%f, fs=%f, ft=%f\n", \ 285 instruction, outf, fs_f[i], ft_f[i]); \ 286 } 287 288 #define TESTINST2d(instruction, RDval) \ 289 { \ 290 double outd = 0; \ 291 __asm__ __volatile__( \ 292 ".set noreorder" "\n\t" \ 293 "mov.d $f1, %1" "\n\t" \ 294 "mov.d $f2, %2" "\n\t" \ 295 "dmtc1 $zero, $f0" "\n\t" \ 296 "c.eq.d $f1, $f2" "\n\t" \ 297 instruction" end"instruction"d"#RDval "\n\t" \ 298 "add.d $f0, $f0, $f1" "\n\t" \ 299 "end"instruction"d"#RDval":" "\n\t" \ 300 "add.d $f0, $f0, $f2" "\n\t" \ 301 "mov.d %0, $f0" "\n\t" \ 302 ".set reorder" "\n\t" \ 303 : "=f" (outd) \ 304 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 305 : "$f0", "$f1", "$f2" \ 306 ); \ 307 printf("%s, c.eq.d out=%f, fs=%f, ft=%f\n", \ 308 instruction, outd, fs_d[i], ft_d[i]); \ 309 } 310 311 #define TESTINST_CONDs(instruction, RDval) \ 312 { \ 313 float outf = 0; \ 314 __asm__ __volatile__( \ 315 ".set noreorder" "\n\t" \ 316 "mov.s $f1, %1" "\n\t" \ 317 "mov.s $f2, %2" "\n\t" \ 318 "mov.s $f0, %1" "\n\t" \ 319 instruction" $f1, $f2" "\n\t" \ 320 "bc1f end"instruction"s"#RDval "\n\t" \ 321 "nop" "\n\t" \ 322 "add.s $f0, $f0, $f2" "\n\t" \ 323 "end"instruction"s"#RDval":" "\n\t" \ 324 "mov.s %0, $f0" "\n\t" \ 325 ".set reorder" "\n\t" \ 326 : "=f" (outf) \ 327 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 328 : "$f0", "$f1", "$f2" \ 329 ); \ 330 printf("%s, bc1f out=%f, fs=%f, ft=%f\n", \ 331 instruction, outf, fs_f[i], ft_f[i]); \ 332 } 333 334 #define TESTINST_CONDd(instruction, RDval) \ 335 { \ 336 double outd = 0; \ 337 __asm__ __volatile__( \ 338 ".set noreorder" "\n\t" \ 339 "mov.d $f1, %1" "\n\t" \ 340 "mov.d $f2, %2" "\n\t" \ 341 "mov.d $f0, %1" "\n\t" \ 342 instruction" $f1, $f2" "\n\t" \ 343 "bc1f end"instruction"d"#RDval "\n\t" \ 344 "nop" "\n\t" \ 345 "add.d $f0, $f0, $f2" "\n\t" \ 346 "end"instruction"d"#RDval":" "\n\t" \ 347 "mov.d %0, $f0" "\n\t" \ 348 ".set reorder" "\n\t" \ 349 : "=f" (outd) \ 350 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 351 : "$f0", "$f1", "$f2" \ 352 ); \ 353 printf("%s, bc1f out=%f, fs=%f, ft=%f\n", \ 354 instruction, outd, fs_d[i], ft_d[i]); \ 355 } 356 #endif 357