1 /*
2  * Test R5900-specific three-operand MULT and MULT1.
3  */
4 
5 #include <stdio.h>
6 #include <inttypes.h>
7 #include <assert.h>
8 
9 static int64_t mult(int32_t rs, int32_t rt)
10 {
11     int32_t rd, lo, hi;
12     int64_t r;
13 
14     __asm__ __volatile__ (
15             "    mult %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 = ((int64_t)hi << 32) | (uint32_t)lo;
21 
22     assert((int64_t)rs * rt == r);
23     assert(rd == lo);
24 
25     return r;
26 }
27 
28 static int64_t mult1(int32_t rs, int32_t rt)
29 {
30     int32_t rd, lo, hi;
31     int64_t r;
32 
33     __asm__ __volatile__ (
34             "    mult1 %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 = ((int64_t)hi << 32) | (uint32_t)lo;
40 
41     assert((int64_t)rs * rt == r);
42     assert(rd == lo);
43 
44     return r;
45 }
46 
47 static int64_t mult_variants(int32_t rs, int32_t rt)
48 {
49     int64_t rd  = mult(rs, rt);
50     int64_t rd1 = mult1(rs, rt);
51 
52     assert(rd == rd1);
53 
54     return rd;
55 }
56 
57 static void verify_mult_negations(int32_t rs, int32_t rt, int64_t expected)
58 {
59     assert(mult_variants(rs, rt) == expected);
60     assert(mult_variants(-rs, rt) == -expected);
61     assert(mult_variants(rs, -rt) == -expected);
62     assert(mult_variants(-rs, -rt) == expected);
63 }
64 
65 int main()
66 {
67     verify_mult_negations(17, 19, 323);
68     verify_mult_negations(77773, 99991, 7776600043);
69     verify_mult_negations(12207031, 305175781, 3725290219116211);
70 
71     assert(mult_variants(-0x80000000,  0x7FFFFFFF) == -0x3FFFFFFF80000000);
72     assert(mult_variants(-0x80000000, -0x7FFFFFFF) ==  0x3FFFFFFF80000000);
73     assert(mult_variants(-0x80000000, -0x80000000) ==  0x4000000000000000);
74 
75     return 0;
76 }
77