2 /* { dg-options "-std=c99" } */
4 extern int printf (const char *, ...);
5 extern void abort (void) __attribute__((noreturn
));
7 typedef unsigned long uint32
;
8 typedef unsigned long long uint64
;
10 extern uint32
__mspabi_divul (uint32
, uint32
);
11 extern uint32
__mspabi_divlu (uint32
, uint32
);
12 extern uint64
__mspabi_divull (uint64
, uint64
);
13 extern uint64
__mspabi_divllu (uint64
, uint64
);
15 uint32
func1 (uint32
, uint32
) __attribute__ ((noinline
));
16 uint32
func2 (uint32
, uint32
) __attribute__ ((noinline
));
17 uint32
func3 (uint32
, uint32
) __attribute__ ((noinline
));
18 uint64
func4 (uint64
, uint64
) __attribute__ ((noinline
));
19 uint64
func5 (uint64
, uint64
) __attribute__ ((noinline
));
20 uint64
func6 (uint64
, uint64
) __attribute__ ((noinline
));
30 if (func1 (7UL, 3UL) != 2UL)
33 printf ("FAIL: func1: 7 / 3 returns %lu\n", func1 (7UL, 3UL));
38 if (func2 (7UL, 3UL) != 2UL)
41 printf ("FAIL: func2: 7 / 3 returns %lu\n", func2 (7UL, 3UL));
46 if (func3 (7UL, 3UL) != 2UL)
49 printf ("FAIL: func4: 7 / 3 returns %lu\n", func3 (7UL, 3UL));
54 if (func4 (7ULL, 3ULL) != 2ULL)
57 printf ("FAIL: func4: 7 / 3 returns %llu\n", func4 (7ULL, 3ULL));
62 if (func5 (7ULL, 3ULL) != 2ULL)
65 printf ("FAIL: func5: 7 / 3 returns %llu\n", func5 (7ULL, 3ULL));
70 if (func6 (7ULL, 3ULL) != 2ULL)
73 printf ("FAIL: func6: 7 / 3 returns %llu\n", func6 (7ULL, 3ULL));
84 /* At high levels of optimization gcc will probably fold func1 and func4 into
85 main, but this does not really matter. Those two functions are just there
86 for a sanity check at low levels of optimization. */
88 uint32
func1 (uint32 a
, uint32 b
) { return a
/ b
; }
89 uint32
func2 (uint32 a
, uint32 b
) { return __mspabi_divul (a
, b
); }
90 uint32
func3 (uint32 a
, uint32 b
) { return __mspabi_divlu (a
, b
); }
91 uint64
func4 (uint64 a
, uint64 b
) { return a
/ b
; }
92 uint64
func5 (uint64 a
, uint64 b
) { return __mspabi_divull (a
, b
); }
95 func6 (uint64 a
, uint64 b
)
99 /* This test function is special. The correctly spelt ABI function
100 __mspabi_divull takes its first argument in registers R8::R11 and its
101 second argument in registers R12::R15, but GCC knows that __mspabi_divllu
102 is not the correct spelling and so it will use the normal function
103 calling convention - first argument in R12::R15, second argument on the
106 The stub function for __mspabi_divllu in libgcc just does a BRAnch to
107 the real __mspabi_divull function - it does *not* rearrange the arguments
108 or pull anything off the stack. This is correct, because in real code
109 that calls __mspabi_divllu, compiled by *old* versions of gcc, the
110 arguments will already be in the special ABI mandated locations.
112 As a result, in order to test __mspabi_divllu here, we have to put the
113 arguments into the correct registers ourselves and call __mspabi_divllu
114 manually. This does lead to some very inefficient code generation, but
115 that is not our concern here. */
117 #ifdef __MSP430X_LARGE__
118 __asm ("mov %A1, r8\n\
126 calla #__mspabi_divllu\n\
131 : "=r" (ret
) : "r" (a
), "m" (b
));
133 __asm ("mov %A1, r8\n\
141 call #__mspabi_divllu\n\
146 : "=r" (ret
) : "r" (a
), "m" (b
));