ftmemsim-valgrind/none/tests/mips64/fpu_arithmetic.c
Petar Jovanovic 9fc2bfba5c mips: add tests for mips32/mips64 R6
This set of tests covers MIPS r6 specific instructions:

  none/tests/mips32/MIPS32r6int
  none/tests/mips32/branch_pc
  none/tests/mips32/branches_r6
  none/tests/mips32/fp_r6
  none/tests/mips32/pc_instructions_r6

  none/tests/mips64/MIPS64r6int
  none/tests/mips64/branch_pc
  none/tests/mips64/branches_r6
  none/tests/mips64/fp_r6
  none/tests/mips64/pc_instructions_r6
  none/tests/mips64/r6_instructions

The following tests had to be changed to be applicaple for Rev6:

  none/tests/libvex_test.c

  none/tests/mips32/LoadStore
  none/tests/mips32/LoadStore1
  none/tests/mips32/MIPS32int
  none/tests/mips32/MoveIns
  none/tests/mips32/branches
  none/tests/mips32/change_fp_mode
  none/tests/mips32/mips32_dsp
  none/tests/mips32/vfp

  none/tests/mips64/arithmetic_instruction
  none/tests/mips64/branches
  none/tests/mips64/fpu_arithmetic
  none/tests/mips64/fpu_load_store
  none/tests/mips64/load_store
  none/tests/mips64/load_store_multiple
  none/tests/mips64/move_instructions

The following tests are not applicable for Rev6:

  none/tests/mips32/fpu_branches
  none/tests/mips32/unaligned_load_store

  none/tests/mips64/branch_and_jump_instructions
  none/tests/mips64/change_fp_mode
  none/tests/mips64/fpu_branches
  none/tests/mips64/load_store_unaligned
  none/tests/mips64/unaligned_load
  none/tests/mips64/unaligned_load_store.

Contributed by:
  Tamara Vlahovic, Aleksandar Rikalo and Aleksandra Karadzic.

Related BZ issue - #387410.
2018-02-01 18:37:28 +01:00

179 lines
6.1 KiB
C

#include <stdio.h>
#include <math.h>
#include "rounding_mode.h"
#include "macro_fpu.h"
#if defined(__mips_hard_float)
int arithmeticOperations(flt_art_op_t op)
{
double fd_d = 0;
float fd_f = 0;
int i = 0;
int fcsr = 0;
round_mode_t rm;
for (rm = TO_NEAREST; rm <= TO_MINUS_INFINITY; rm ++) {
set_rounding_mode(rm);
printf("roundig mode: %s\n", round_mode_name[rm]);
for (i = 0; i < MAX_ARR; i++) {
switch(op) {
case ABSS:
UNOPff("abs.s");
printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
break;
case ABSD:
UNOPdd("abs.d");
printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
break;
case ADDS:
BINOPf("add.s");
printf("%s %f %f %f\n",
flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
break;
case ADDD:
BINOPd("add.d");
printf("%s %lf %lf %lf\n",
flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
break;
case DIVS:
BINOPf("div.s");
printf("%s %f %f %f\n",
flt_art_op_names[op], roundf(fd_f), fs_f[i], ft_f[i]);
break;
case DIVD:
BINOPd("div.d");
printf("%s %lf %lf %lf\n",
flt_art_op_names[op], round(fd_d), fs_d[i], ft_d[i]);
break;
case MULS:
BINOPf("mul.s");
printf("%s %f %f %f\n",
flt_art_op_names[op], roundf(fd_f), fs_f[i], ft_f[i]);
break;
case MULD:
BINOPd("mul.d");
printf("%s %lf %lf %lf\n",
flt_art_op_names[op], round(fd_d), fs_d[i], ft_d[i]);
break;
case NEGS:
UNOPff("neg.s");
printf("%s %f %f\n", flt_art_op_names[op], fd_f, fs_f[i]);
break;
case NEGD:
UNOPdd("neg.d");
printf("%s %lf %lf\n", flt_art_op_names[op], fd_d, fs_d[i]);
break;
case SQRTS:
UNOPff("sqrt.s");
printf("%s %f %f\n",
flt_art_op_names[op], roundf(fd_f), fs_f[i]);
break;
case SQRTD:
UNOPdd("sqrt.d");
printf("%s %lf %lf\n",
flt_art_op_names[op], round(fd_d), fs_d[i]);
break;
case SUBS:
BINOPf("sub.s");
printf("%s %f %f %f\n",
flt_art_op_names[op], fd_f, fs_f[i], ft_f[i]);
break;
case SUBD:
BINOPd("sub.d");
printf("%s %lf %lf %lf\n",
flt_art_op_names[op], fd_d, fs_d[i], ft_d[i]);
break;
case RECIPS:
UNOPff("recip.s");
printf("%s %f %f\n",
flt_art_op_names[op], roundf(fd_f), fs_f[i]);
break;
case RECIPD:
UNOPdd("recip.d");
printf("%s %lf %lf\n",
flt_art_op_names[op], round(fd_d), fs_d[i]);
break;
case RSQRTS:
if (fs_f[i] >= 0) {
UNOPff("rsqrt.s");
printf("%s %f %f\n",
flt_art_op_names[op], roundf(fd_f), fs_f[i]);
}
break;
case RSQRTD:
if (fs_d[i] >= 0) {
UNOPdd("rsqrt.d");
printf("%s %lf %lf\n",
flt_art_op_names[op], round(fd_d), fs_d[i]);
}
break;
#if (__mips_isa_rev < 6)
case MSUBS:
TRIOPf("msub.s");
printf("%s %f %f %f %f\n",flt_art_op_names[op], roundf(fd_f),
fr_f[i], fs_f[i], ft_f[i]);
break;
case MSUBD:
TRIOPd("msub.d");
printf("%s %lf %lf %lf %lf\n", flt_art_op_names[op], round(fd_d),
fr_d[i], fs_d[i], ft_d[i]);
break;
case MADDS:
TRIOPf("madd.s");
printf("%s %f %f %f %f\n", flt_art_op_names[op], roundf(fd_f),
fr_f[i], fs_f[i], ft_f[i]);
break;
case MADDD:
TRIOPd("madd.d");
printf("%s %lf %lf %lf %lf\n", flt_art_op_names[op], round(fd_d),
fr_d[i], fs_d[i], ft_d[i]);
break;
case NMADDS:
TRIOPf("nmadd.s");
printf("%s %f %f %f %f\n", flt_art_op_names[op], roundf(fd_f),
fr_f[i], fs_f[i], ft_f[i]);
break;
case NMADDD:
TRIOPd("nmadd.d");
printf("%s %lf %lf %lf %lf\n", flt_art_op_names[op], round(fd_d),
fr_d[i], fs_d[i], ft_d[i]);
break;
case NMSUBS:
TRIOPf("nmsub.s");
printf("%s %f %f %f %f\n", flt_art_op_names[op], roundf(fd_f),
fr_f[i], fs_f[i], ft_f[i]);
break;
case NMSUBD:
TRIOPd("nmsub.d");
printf("%s 0x%lf %lf %lf %lf\n", flt_art_op_names[op],
round(fd_d), fr_d[i], fs_d[i],
ft_d[i]);
break;
#endif
default:
printf("error\n");
break;
}
}
}
return 0;
}
#endif
int main()
{
#if defined(__mips_hard_float)
flt_art_op_t op;
#if (__mips_isa_rev < 6)
int end = NMSUBD;
#else
int end = RSQRTD;
#endif
printf("-------------------------- %s --------------------------\n",
"test FPU Arithmetic Operations");
for (op = ABSS; op <= end; op++) {
arithmeticOperations(op);
}
#endif
return 0;
}