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 #define UNOPdd(op) \ 56 fd_d = 0; \ 57 __asm__ __volatile__( \ 58 op" %1, %2" "\n\t" \ 59 "cfc1 %0, $31" "\n\t" \ 60 : "=r" (fcsr), "=f"(fd_d) \ 61 : "f"(fs_d[i]) \ 62 ); 63 64 #define UNOPff(op) \ 65 fd_f = 0; \ 66 __asm__ __volatile__( \ 67 op" %1, %2" "\n\t" \ 68 "cfc1 %0, $31" "\n\t" \ 69 : "=r" (fcsr), "=f"(fd_f) \ 70 : "f"(fs_f[i]) \ 71 ); 72 73 #define UNOPfd(op) \ 74 fd_d = 0; \ 75 __asm__ __volatile__( \ 76 op" %1, %2" "\n\t" \ 77 "cfc1 %0, $31" "\n\t" \ 78 : "=r" (fcsr), "=f"(fd_d) \ 79 : "f"(fs_f[i]) \ 80 ); 81 82 #define UNOPdf(op) \ 83 fd_f = 0; \ 84 __asm__ __volatile__( \ 85 op" %1, %2" "\n\t" \ 86 "cfc1 %0, $31" "\n\t" \ 87 : "=r" (fcsr), "=f"(fd_f) \ 88 : "f"(fs_d[i]) \ 89 ); 90 91 #define UNOPfw(op) \ 92 fd_w = 0; \ 93 __asm__ __volatile__( \ 94 op" $f0, %2" "\n\t" \ 95 "mfc1 %1, $f0" "\n\t" \ 96 "cfc1 %0, $31" "\n\t" \ 97 : "=r" (fcsr), "=r"(fd_w) \ 98 : "f"(fs_f[i]) \ 99 : "$f0" \ 100 ); 101 102 #define UNOPdw(op) \ 103 fd_w = 0; \ 104 __asm__ __volatile__( \ 105 op" $f0, %2" "\n\t" \ 106 "mfc1 %1, $f0" "\n\t" \ 107 "cfc1 %0, $31" "\n\t" \ 108 : "=r" (fcsr), "=r"(fd_w) \ 109 : "f"(fs_d[i]) \ 110 : "$f0" \ 111 ); 112 113 #define UNOPwd(op) \ 114 fd_d = 0; \ 115 __asm__ __volatile__( \ 116 "mtc1 %2, $f0" "\n\t" \ 117 op" %1, $f0" "\n\t" \ 118 "cfc1 %0, $31" "\n\t" \ 119 : "=r" (fcsr), "=f"(fd_d) \ 120 : "r"(fs_w[i]) \ 121 : "$f0" \ 122 ); 123 124 #define UNOPwf(op) \ 125 fd_f = 0; \ 126 __asm__ __volatile__( \ 127 "mtc1 %2, $f0" "\n\t" \ 128 op" %1, $f0" "\n\t" \ 129 "cfc1 %0, $31" "\n\t" \ 130 : "=r" (fcsr), "=f"(fd_f) \ 131 : "r"(fs_w[i]) \ 132 : "$f0" \ 133 ); 134 135 #define UNOPld(op) \ 136 fd_d = 0; \ 137 __asm__ __volatile__( \ 138 "dmtc1 %2, $f0" "\n\t" \ 139 op" %1, $f0" "\n\t" \ 140 "cfc1 %0, $31" "\n\t" \ 141 : "=r" (fcsr), "=f"(fd_d) \ 142 : "r"(fs_l[i]) \ 143 : "$f0" \ 144 ); 145 146 #define UNOPdl(op) \ 147 fd_l = 0; \ 148 __asm__ __volatile__( \ 149 op" $f0, %2" "\n\t" \ 150 "dmfc1 %1, $f0" "\n\t" \ 151 "cfc1 %0, $31" "\n\t" \ 152 : "=r" (fcsr), "=r"(fd_l) \ 153 : "f"(fs_d[i]) \ 154 : "$f0" \ 155 ); 156 157 #define UNOPls(op) \ 158 fd_f = 0; \ 159 __asm__ __volatile__( \ 160 "dmtc1 %2, $f0" "\n\t" \ 161 op" %1, $f0" "\n\t" \ 162 "cfc1 %0, $31" "\n\t" \ 163 : "=r" (fcsr), "=f"(fd_f) \ 164 : "r"(fs_l[i]) \ 165 : "$f0" \ 166 ); 167 168 #define UNOPsl(op) \ 169 fd_l = 0; \ 170 __asm__ __volatile__( \ 171 op" $f0, %2" "\n\t" \ 172 "dmfc1 %1, $f0" "\n\t" \ 173 "cfc1 %0, $31" "\n\t" \ 174 : "=r" (fcsr), "=r"(fd_l) \ 175 : "f"(fs_f[i]) \ 176 : "$f0" \ 177 ); 178 179 #define BINOPf(op) \ 180 fd_f = 0; \ 181 __asm__ __volatile__( \ 182 op" %1, %2, %3" "\n\t" \ 183 "cfc1 %0, $31" "\n\t" \ 184 : "=r" (fcsr), "=f" (fd_f) \ 185 : "f" (fs_f[i]), "f" (ft_f[i]) \ 186 ); 187 188 #define BINOPd(op) \ 189 fd_d = 0; \ 190 __asm__ __volatile__( \ 191 op" %1, %2, %3" "\n\t" \ 192 "cfc1 %0, $31" "\n\t" \ 193 : "=r" (fcsr), "=f"(fd_d) \ 194 : "f" (fs_d[i]), "f" (ft_d[i]) \ 195 ); 196 197 #define TRIOPf(op) \ 198 fd_f = 0; \ 199 __asm__ __volatile__( \ 200 op" %1, %2, %3, %4" "\n\t" \ 201 "cfc1 %0, $31" "\n\t" \ 202 : "=r" (fcsr), "=f" (fd_f) \ 203 : "f" (fr_f[i]), "f" (fs_f[i]) , "f" (ft_f[i]) \ 204 ); 205 206 #define TRIOPd(op) \ 207 fd_d = 0; \ 208 __asm__ __volatile__( \ 209 op" %1, %2, %3, %4" "\n\t" \ 210 "cfc1 %0, $31" "\n\t" \ 211 : "=r" (fcsr), "=f"(fd_d) \ 212 : "f" (fr_d[i]), "f" (fs_d[i]) , "f" (ft_d[i]) \ 213 ); 214 215 /* Conditional macros.*/ 216 #define TESTINST1s(instruction, RDval) \ 217 { \ 218 float outf = 0; \ 219 __asm__ __volatile__( \ 220 ".set noreorder" "\n\t" \ 221 "mov.s $f1, %1" "\n\t" \ 222 "mov.s $f2, %2" "\n\t" \ 223 "mtc1 $zero, $f0" "\n\t" \ 224 "c.eq.s $f1, $f2" "\n\t" \ 225 instruction" end"instruction"s"#RDval "\n\t" \ 226 "nop" "\n\t" \ 227 "add.s $f0, $f0, $f1" "\n\t" \ 228 "end"instruction"s"#RDval":" "\n\t" \ 229 "add.s $f0, $f0, $f2" "\n\t" \ 230 "mov.s %0, $f0" "\n\t" \ 231 ".set reorder" "\n\t" \ 232 : "=f" (outf) \ 233 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 234 : "$f0", "$f1", "$f2" \ 235 ); \ 236 printf("%s, c.eq.s out=%f, fs=%f, ft=%f\n", \ 237 instruction, outf, fs_f[i], ft_f[i]); \ 238 } 239 240 #define TESTINST1d(instruction, RDval) \ 241 { \ 242 double outd = 0; \ 243 __asm__ __volatile__( \ 244 ".set noreorder" "\n\t" \ 245 "mov.d $f1, %1" "\n\t" \ 246 "mov.d $f2, %2" "\n\t" \ 247 "dmtc1 $zero, $f0" "\n\t" \ 248 "c.eq.d $f1, $f2" "\n\t" \ 249 instruction" end"instruction"d"#RDval "\n\t" \ 250 "nop" "\n\t" \ 251 "add.d $f0, $f0, $f1" "\n\t" \ 252 "end"instruction"d"#RDval":" "\n\t" \ 253 "add.d $f0, $f0, $f2" "\n\t" \ 254 "mov.d %0, $f0" "\n\t" \ 255 ".set reorder" "\n\t" \ 256 : "=f" (outd) \ 257 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 258 : "$f0", "$f1", "$f2" \ 259 ); \ 260 printf("%s, c.eq.d out=%f, fs=%f, ft=%f\n", \ 261 instruction, outd, fs_d[i], ft_d[i]); \ 262 } 263 264 #define TESTINST2s(instruction, RDval) \ 265 { \ 266 float outf = 0; \ 267 __asm__ __volatile__( \ 268 ".set noreorder" "\n\t" \ 269 "mov.s $f1, %1" "\n\t" \ 270 "mov.s $f2, %2" "\n\t" \ 271 "mtc1 $zero, $f0" "\n\t" \ 272 "c.eq.s $f1, $f2" "\n\t" \ 273 instruction" end"instruction"s"#RDval "\n\t" \ 274 "add.s $f0, $f0, $f1" "\n\t" \ 275 "end"instruction"s"#RDval":" "\n\t" \ 276 "add.s $f0, $f0, $f2" "\n\t" \ 277 "mov.s %0, $f0" "\n\t" \ 278 ".set reorder" "\n\t" \ 279 : "=f" (outf) \ 280 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 281 : "$f0", "$f1", "$f2" \ 282 ); \ 283 printf("%s, c.eq.s out=%f, fs=%f, ft=%f\n", \ 284 instruction, outf, fs_f[i], ft_f[i]); \ 285 } 286 287 #define TESTINST2d(instruction, RDval) \ 288 { \ 289 double outd = 0; \ 290 __asm__ __volatile__( \ 291 ".set noreorder" "\n\t" \ 292 "mov.d $f1, %1" "\n\t" \ 293 "mov.d $f2, %2" "\n\t" \ 294 "dmtc1 $zero, $f0" "\n\t" \ 295 "c.eq.d $f1, $f2" "\n\t" \ 296 instruction" end"instruction"d"#RDval "\n\t" \ 297 "add.d $f0, $f0, $f1" "\n\t" \ 298 "end"instruction"d"#RDval":" "\n\t" \ 299 "add.d $f0, $f0, $f2" "\n\t" \ 300 "mov.d %0, $f0" "\n\t" \ 301 ".set reorder" "\n\t" \ 302 : "=f" (outd) \ 303 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 304 : "$f0", "$f1", "$f2" \ 305 ); \ 306 printf("%s, c.eq.d out=%f, fs=%f, ft=%f\n", \ 307 instruction, outd, fs_d[i], ft_d[i]); \ 308 } 309 310 #define TESTINST_CONDs(instruction, RDval) \ 311 { \ 312 float outf = 0; \ 313 __asm__ __volatile__( \ 314 ".set noreorder" "\n\t" \ 315 "mov.s $f1, %1" "\n\t" \ 316 "mov.s $f2, %2" "\n\t" \ 317 "mov.s $f0, %1" "\n\t" \ 318 instruction" $f1, $f2" "\n\t" \ 319 "bc1f end"instruction"s"#RDval "\n\t" \ 320 "nop" "\n\t" \ 321 "add.s $f0, $f0, $f2" "\n\t" \ 322 "end"instruction"s"#RDval":" "\n\t" \ 323 "mov.s %0, $f0" "\n\t" \ 324 ".set reorder" "\n\t" \ 325 : "=f" (outf) \ 326 : "f" (fs_f[i]) , "f" (ft_f[i]) \ 327 : "$f0", "$f1", "$f2" \ 328 ); \ 329 printf("%s, bc1f out=%f, fs=%f, ft=%f\n", \ 330 instruction, outf, fs_f[i], ft_f[i]); \ 331 } 332 333 #define TESTINST_CONDd(instruction, RDval) \ 334 { \ 335 double outd = 0; \ 336 __asm__ __volatile__( \ 337 ".set noreorder" "\n\t" \ 338 "mov.d $f1, %1" "\n\t" \ 339 "mov.d $f2, %2" "\n\t" \ 340 "mov.d $f0, %1" "\n\t" \ 341 instruction" $f1, $f2" "\n\t" \ 342 "bc1f end"instruction"d"#RDval "\n\t" \ 343 "nop" "\n\t" \ 344 "add.d $f0, $f0, $f2" "\n\t" \ 345 "end"instruction"d"#RDval":" "\n\t" \ 346 "mov.d %0, $f0" "\n\t" \ 347 ".set reorder" "\n\t" \ 348 : "=f" (outd) \ 349 : "f" (fs_d[i]) , "f" (ft_d[i]) \ 350 : "$f0", "$f1", "$f2" \ 351 ); \ 352 printf("%s, bc1f out=%f, fs=%f, ft=%f\n", \ 353 instruction, outd, fs_d[i], ft_d[i]); \ 354 } 355