1 /*
2  * Test R5900-specific three-operand MULTU and MULTU1.
3  */
4 
5 #include <stdio.h>
6 #include <inttypes.h>
7 #include <assert.h>
8 
multu(uint32_t rs,uint32_t rt)9 static uint64_t multu(uint32_t rs, uint32_t rt)
10 {
11     uint32_t rd, lo, hi;
12     uint64_t r;
13 
14     __asm__ __volatile__ (
15             "    multu %0, %3, %4\n"
16             "    mflo %1\n"
17             "    mfhi %2\n"
18             : "=r" (rd), "=r" (lo), "=r" (hi)
19             : "r" (rs), "r" (rt));
20     r = ((uint64_t)hi << 32) | (uint32_t)lo;
21 
22     assert((uint64_t)rs * rt == r);
23     assert(rd == lo);
24 
25     return r;
26 }
27 
multu1(uint32_t rs,uint32_t rt)28 static uint64_t multu1(uint32_t rs, uint32_t rt)
29 {
30     uint32_t rd, lo, hi;
31     uint64_t r;
32 
33     __asm__ __volatile__ (
34             "    multu1 %0, %3, %4\n"
35             "    mflo1 %1\n"
36             "    mfhi1 %2\n"
37             : "=r" (rd), "=r" (lo), "=r" (hi)
38             : "r" (rs), "r" (rt));
39     r = ((uint64_t)hi << 32) | (uint32_t)lo;
40 
41     assert((uint64_t)rs * rt == r);
42     assert(rd == lo);
43 
44     return r;
45 }
46 
multu_variants(uint32_t rs,uint32_t rt)47 static uint64_t multu_variants(uint32_t rs, uint32_t rt)
48 {
49     uint64_t rd  = multu(rs, rt);
50     uint64_t rd1 = multu1(rs, rt);
51 
52     assert(rd == rd1);
53 
54     return rd;
55 }
56 
main()57 int main()
58 {
59     assert(multu_variants(17, 19) == 323);
60     assert(multu_variants(77773, 99991) == 7776600043);
61     assert(multu_variants(12207031, 305175781) == 3725290219116211);
62 
63     assert(multu_variants(0x80000000U, 0x7FFFFFFF) == 0x3FFFFFFF80000000);
64     assert(multu_variants(0x80000000U, 0x80000000U) ==  0x4000000000000000);
65     assert(multu_variants(0xFFFFFFFFU, 0xFFFFFFFFU) ==  0xFFFFFFFE00000001U);
66 
67     return 0;
68 }
69