xref: /qemu/tests/tcg/mips/user/isa/r5900/test_r5900_multu.c (revision 073d9f2ce051d7a4bad9aa7bfdacf97394c57c05)
1667eded2SFredrik Noring /*
2*bec4d66bSFredrik Noring  * Test R5900-specific three-operand MULTU and MULTU1.
3667eded2SFredrik Noring  */
4667eded2SFredrik Noring 
5667eded2SFredrik Noring #include <stdio.h>
6667eded2SFredrik Noring #include <inttypes.h>
7667eded2SFredrik Noring #include <assert.h>
8667eded2SFredrik Noring 
multu(uint32_t rs,uint32_t rt)9667eded2SFredrik Noring static uint64_t multu(uint32_t rs, uint32_t rt)
10667eded2SFredrik Noring {
11667eded2SFredrik Noring     uint32_t rd, lo, hi;
12667eded2SFredrik Noring     uint64_t r;
13667eded2SFredrik Noring 
14667eded2SFredrik Noring     __asm__ __volatile__ (
15667eded2SFredrik Noring             "    multu %0, %3, %4\n"
16667eded2SFredrik Noring             "    mflo %1\n"
17667eded2SFredrik Noring             "    mfhi %2\n"
18667eded2SFredrik Noring             : "=r" (rd), "=r" (lo), "=r" (hi)
19667eded2SFredrik Noring             : "r" (rs), "r" (rt));
20667eded2SFredrik Noring     r = ((uint64_t)hi << 32) | (uint32_t)lo;
21667eded2SFredrik Noring 
22667eded2SFredrik Noring     assert((uint64_t)rs * rt == r);
23667eded2SFredrik Noring     assert(rd == lo);
24667eded2SFredrik Noring 
25667eded2SFredrik Noring     return r;
26667eded2SFredrik Noring }
27667eded2SFredrik Noring 
multu1(uint32_t rs,uint32_t rt)28*bec4d66bSFredrik Noring static uint64_t multu1(uint32_t rs, uint32_t rt)
29*bec4d66bSFredrik Noring {
30*bec4d66bSFredrik Noring     uint32_t rd, lo, hi;
31*bec4d66bSFredrik Noring     uint64_t r;
32*bec4d66bSFredrik Noring 
33*bec4d66bSFredrik Noring     __asm__ __volatile__ (
34*bec4d66bSFredrik Noring             "    multu1 %0, %3, %4\n"
35*bec4d66bSFredrik Noring             "    mflo1 %1\n"
36*bec4d66bSFredrik Noring             "    mfhi1 %2\n"
37*bec4d66bSFredrik Noring             : "=r" (rd), "=r" (lo), "=r" (hi)
38*bec4d66bSFredrik Noring             : "r" (rs), "r" (rt));
39*bec4d66bSFredrik Noring     r = ((uint64_t)hi << 32) | (uint32_t)lo;
40*bec4d66bSFredrik Noring 
41*bec4d66bSFredrik Noring     assert((uint64_t)rs * rt == r);
42*bec4d66bSFredrik Noring     assert(rd == lo);
43*bec4d66bSFredrik Noring 
44*bec4d66bSFredrik Noring     return r;
45*bec4d66bSFredrik Noring }
46*bec4d66bSFredrik Noring 
multu_variants(uint32_t rs,uint32_t rt)47*bec4d66bSFredrik Noring static uint64_t multu_variants(uint32_t rs, uint32_t rt)
48*bec4d66bSFredrik Noring {
49*bec4d66bSFredrik Noring     uint64_t rd  = multu(rs, rt);
50*bec4d66bSFredrik Noring     uint64_t rd1 = multu1(rs, rt);
51*bec4d66bSFredrik Noring 
52*bec4d66bSFredrik Noring     assert(rd == rd1);
53*bec4d66bSFredrik Noring 
54*bec4d66bSFredrik Noring     return rd;
55*bec4d66bSFredrik Noring }
56*bec4d66bSFredrik Noring 
main()57667eded2SFredrik Noring int main()
58667eded2SFredrik Noring {
59*bec4d66bSFredrik Noring     assert(multu_variants(17, 19) == 323);
60*bec4d66bSFredrik Noring     assert(multu_variants(77773, 99991) == 7776600043);
61*bec4d66bSFredrik Noring     assert(multu_variants(12207031, 305175781) == 3725290219116211);
62667eded2SFredrik Noring 
63*bec4d66bSFredrik Noring     assert(multu_variants(0x80000000U, 0x7FFFFFFF) == 0x3FFFFFFF80000000);
64*bec4d66bSFredrik Noring     assert(multu_variants(0x80000000U, 0x80000000U) ==  0x4000000000000000);
65*bec4d66bSFredrik Noring     assert(multu_variants(0xFFFFFFFFU, 0xFFFFFFFFU) ==  0xFFFFFFFE00000001U);
66667eded2SFredrik Noring 
67667eded2SFredrik Noring     return 0;
68667eded2SFredrik Noring }
69