ftmemsim-valgrind/none/tests/mips64/arithmetic_instruction.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

373 lines
16 KiB
C

#include <stdio.h>
#include "const.h"
#include "macro_int.h"
#if (__mips_isa_rev < 6)
typedef enum {
ADD=0, ADDI, ADDIU, ADDU,
CLO, CLZ, DADD, DADDI,
DADDIU, DADDU, DCLO, DCLZ,
DDIV, DDIVU, DIV, DIVU,
DMULT, DMULTU, DSUB, DSUBU,
MADD, MADDU, MSUB, MSUBU,
MUL, MULT, MULTU, MOVN,
MOVZ, SEB, SEH, SLT,
SLTI, SLTIU, SLTU, SUB,
SUBU
} arithmetic_op;
#else
typedef enum {
ADD=0, ADDIU, ADDU,
CLO, CLZ, DCLO, DCLZ,
DADD, DADDIU, DADDU,
DSUB, DSUBU, SUB, SUBU,
SEB, SEH,
SLT, SLTI, SLTIU, SLTU
} arithmetic_op;
#endif
int main()
{
arithmetic_op op;
int i;
init_reg_val2();
for (op = ADD; op <= SUBU; op++) {
for (i = 0; i < N; i++) {
switch(op) {
case ADD:
/* If either GPR rt or GPR rs does not contain sign-extended
32-bit values (bits 63..31 equal), then the result of the
operation is UNPREDICTABLE. */
TEST1("add $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
#if (__mips_isa_rev < 6)
case ADDI:
/* If GPR rs does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the result of the operation
is UNPREDICTABLE. */
TEST2("addi $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("addi $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("addi $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("addi $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
break;
#endif
case ADDIU:
/* If GPR rs does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the result of the operation
is UNPREDICTABLE. */
TEST2("addiu $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("addiu $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("addiu $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("addiu $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
break;
case ADDU:
/* If either GPR rt or GPR rs does not contain sign-extended
32-bit values (bits 63..31 equal), then the result of the
operation is UNPREDICTABLE. */
TEST1("addu $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
case CLO:
/* If GPR rs does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE. */
TEST3("clo $t0, $t1", reg_val1[i], t0, t1);
break;
case CLZ:
/* If GPR rs does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE. */
TEST3("clz $t0, $t1", reg_val1[i], t0, t1);
break;
case DADD:
/* If the addition results in 64-bit 2âs complement arithmetic
overflow, then the destination register is not modified and
an IntegerOverflow exception occurs. */
TEST1("dadd $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
#if (__mips_isa_rev < 6)
case DADDI:
/* If the addition results in 64-bit 2âs complement arithmetic
overflow, then the destination register is not modified and
an Integer Overflow exception occurs. */
TEST2("daddi $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("daddi $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("daddi $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("daddi $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
TEST2("daddi $t0, $t1, 0xff", reg_val2[i], 0xff, t0, t1);
TEST2("daddi $t2, $t3, 0xffff", reg_val2[i], 0xffff, t2, t3);
TEST2("daddi $a0, $a1, 0x0", reg_val2[i], 0x0, a0, a1);
TEST2("daddi $s0, $s1, 0x23", reg_val2[i], 0x23, s0, s1);
break;
#endif
case DADDIU:
/* No Integer Overflow exception occurs under any
circumstances. */
TEST2("daddiu $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("daddiu $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("daddiu $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("daddiu $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
TEST2("daddiu $t0, $t1, 0xff", reg_val2[i], 0xff, t0, t1);
TEST2("daddiu $t2, $t3, 0xffff", reg_val2[i], 0xffff, t2, t3);
TEST2("daddiu $a0, $a1, 0x0", reg_val2[i], 0x0, a0, a1);
TEST2("daddiu $s0, $s1, 0x23", reg_val2[i], 0x23, s0, s1);
break;
case DADDU:
/* No Integer Overflow exception occurs under any
circumstances. */
TEST1("daddu $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
TEST1("daddu $s0, $s1, $s2", reg_val2[i], reg_val2[N-i-1],
s0, s1, s2);
break;
case DCLO:
/* No arithmetic exception occurs under any circumstances. */
TEST3("dclo $t0, $t1", reg_val1[i], t0, t1);
TEST3("dclo $v0, $v1", reg_val2[i], v0, v1);
break;
case DCLZ:
/* No arithmetic exception occurs under any circumstances. */
TEST3("dclz $t0, $t1", reg_val1[i], t0, t1);
TEST3("dclz $v0, $v1", reg_val2[i], v0, v1);
break;
#if (__mips_isa_rev < 6)
case DDIV:
/* If the divisor in GPR rt is zero, the arithmetic result value
is UNPREDICTABLE. */
if (reg_val1[N-i-1] != 0)
TEST4("ddiv $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
if (reg_val2[N-i-1] != 0)
TEST4("ddiv $v0, $v1", reg_val2[i], reg_val2[N-i-1], v0, v1);
break;
case DDIVU:
/* If the divisor in GPR rt is zero, the arithmetic result value
is UNPREDICTABLE. */
if (reg_val1[N-i-1] != 0)
TEST4("ddivu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
if (reg_val2[N-i-1] != 0)
TEST4("ddivu $v0, $v1", reg_val2[i], reg_val2[N-i-1], v0, v1);
break;
case DIV:
/* If either GPR rt or GPR rs does not contain sign-extended
32-bit values (bits 63..31 equal), then the result of the
operation is UNPREDICTABLE.
If the divisor in GPR rt is zero, the arithmetic result
value is UNPREDICTABLE. */
if (reg_val1[N-i-1] != 0)
TEST4("div $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case DIVU:
/* If either GPR rt or GPR rs does not contain sign-extended
32-bit values (bits 63..31 equal), then the result of the
operation is UNPREDICTABLE.
If the divisor in GPR rt is zero, the arithmetic result
value is UNPREDICTABLE. */
if (reg_val1[N-i-1] != 0)
TEST4("divu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case DMULT:
/* No arithmetic exception occurs under any circumstances. */
TEST4("dmult $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
TEST4("dmult $v0, $v1", reg_val2[i], reg_val2[N-i-1], v0, v1);
break;
case DMULTU:
/* No arithmetic exception occurs under any circumstances. */
TEST4("dmultu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
TEST4("dmultu $v0, $v1", reg_val2[i], reg_val2[N-i-1], v0, v1);
break;
#endif
case DSUB:
/* If the subtraction results in 64-bit 2âs complement
arithmetic overflow, then the destination register is not
modified and an Integer Overflow exception occurs. */
TEST1("dsub $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
case DSUBU:
/* No Integer Overflow exception occurs under any
circumstances. */
TEST1("dsubu $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
TEST1("dsubu $s0, $s1, $s2", reg_val2[i], reg_val2[N-i-1],
s0, s1, s2);
break;
#if (__mips_isa_rev < 6)
case MADD:
/* If GPRs rs or rt do not contain sign-extended 32-bit
values (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE. */
TEST5("madd $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MADDU:
/* If GPRs rs or rt do not contain sign-extended 32-bit
values (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE. */
TEST5("maddu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MSUB:
/* If GPR rs or rt do not contain a sign-extended 32-bit
value (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE. */
TEST5("msub $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MSUBU:
/* If GPRs rs or rt do not contain sign-extended 32-bit
values (bits 63..31 equal), then the results of the operation
are UNPREDICTABLE.
This instruction does not provide the capability of writing
directly to a target GPR. */
TEST5("msubu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MUL:
/* On 64-bit processors, if either GPR rt or GPR rs does not
contain sign-extended 32-bit values (bits 63..31 equal), then
the result of the operation is UNPREDICTABLE. */
TEST1("mul $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
case MULT:
/* On 64-bit processors, if either GPR rt or GPR rs does not
contain sign-extended 32-bit values (bits 63..31 equal), then
the result of the operation is UNPREDICTABLE. */
TEST4("mult $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MULTU:
/* On 64-bit processors, if either GPR rt or GPR rs does not
contain sign-extended 32-bit values (bits 63..31 equal), then
the result of the operation is UNPREDICTABLE. */
TEST4("multu $t0, $t1", reg_val1[i], reg_val1[N-i-1], t0, t1);
break;
case MOVN:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST1("movn $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
TEST1("movn $s0, $s1, $s2", reg_val2[i], reg_val2[N-i-1],
s0, s1, s2);
break;
case MOVZ:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST1("movz $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
TEST1("movz $s0, $s1, $s2", reg_val2[i], reg_val2[N-i-1],
s0, s1, s2);
break;
#endif
case SEB:
#if (__mips==64) && (__mips_isa_rev>=2)
/* If GPR rt does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the result of the operation
is UNPREDICTABLE. */
TEST3("seb $t0, $t1", reg_val1[i], t0, t1);
#endif
break;
case SEH:
#if (__mips==64) && (__mips_isa_rev>=2)
/* If GPR rt does not contain a sign-extended 32-bit
value (bits 63..31 equal), then the result of the operation
is UNPREDICTABLE. */
TEST3("seh $t0, $t1", reg_val1[i], t0, t1);
#endif
break;
case SLT:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST1("slt $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
case SLTI:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST2("slti $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("slti $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("slti $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("slti $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
TEST2("slti $t0, $t1, 0xff", reg_val2[i], 0xff, t0, t1);
TEST2("slti $t2, $t3, 0xffff", reg_val2[i], 0xffff, t2, t3);
TEST2("slti $a0, $a1, 0x0", reg_val2[i], 0x0, a0, a1);
TEST2("slti $s0, $s1, 0x23", reg_val2[i], 0x23, s0, s1);
break;
case SLTIU:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST2("sltiu $t0, $t1, 0xff", reg_val1[i], 0xff, t0, t1);
TEST2("sltiu $t2, $t3, 0xffff", reg_val1[i], 0xffff, t2, t3);
TEST2("sltiu $a0, $a1, 0x0", reg_val1[i], 0x0, a0, a1);
TEST2("sltiu $s0, $s1, 0x23", reg_val1[i], 0x23, s0, s1);
TEST2("sltiu $t0, $t1, 0xff", reg_val2[i], 0xff, t0, t1);
TEST2("sltiu $t2, $t3, 0xffff", reg_val2[i], 0xffff, t2, t3);
TEST2("sltiu $a0, $a1, 0x0", reg_val2[i], 0x0, a0, a1);
TEST2("sltiu $s0, $s1, 0x23", reg_val2[i], 0x23, s0, s1);
break;
case SLTU:
/* The arithmetic comparison does not cause an Integer Overflow
exception. */
TEST1("sltu $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
TEST1("sltu $s0, $s1, $s2", reg_val2[i], reg_val2[N-i-1],
s0, s1, s2);
break;
case SUB:
/* On 64-bit processors, if either GPR rt or GPR rs does not
contain sign-extended 32-bit values (bits 63..31 equal), then
the result of the operation is UNPREDICTABLE. */
if (i < 8 || (i > 15 && i < 22))
TEST1("sub $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
case SUBU:
/* On 64-bit processors, if either GPR rt or GPR rs does not
contain sign-extended 32-bit values (bits 63..31 equal), then
the result of the operation is UNPREDICTABLE. */
TEST1("subu $t0, $t1, $t2", reg_val1[i], reg_val1[N-i-1],
t0, t1, t2);
break;
default:
printf("Error!\n");
break;
}
}
}
return 0;
}