Files
tms-c-compiler/scripts/m4/mul.c
T
arti 00522b56fc tests: exercise wide 32-bit products and unsigned umul16
Add runtime markers for a full-width 32x32 multiply (0x12345678 * 0x9abcdef0
= 0x242d2080) and for a wide-dividend remainder, so a 16-bit-truncated MPYS or
a wrong FS1 cannot still produce the expected small results.  Compute the 16x16
unsigned product in unsigned arithmetic to remove the signed-overflow
annotation, and reject a regressed nuw nsw multiply in the optimized IR.
2026-11-12 06:17:29 +00:00

45 lines
1.8 KiB
C

/* m4 mul.c -- 32-bit multiply/divide marker test.
*
* Markers (0x20 bits apart, written by mul_test):
* 018A8000 mul(6,7) == 42
* 018A8020 umul16(0xffff,0xffff) == 0xfffe0001 (16x16 MPYU path)
* 018A8040 sdiv(100,7) == 14
* 018A8060 udiv(0xfffffffe,7) == 613566756
* 018A8080 srem(100,7) == 2
* 018A80A0 urem(100,7) == 2
* 018A80C0 sdiv(-100,7) == -14
* 018A80E0 srem(-100,7) == -2
* 018A8140 mul(0x12345678,0x9ABCDEF0) == 0x242D2080 (wide 32x32 product)
* 018A8160 urem(0xfffffffe,7) == 2 (wide quotient in the remainder)
*/
#define MARK(n) (*(volatile unsigned int *)(0x018A8000u + (n)*0x20u))
int mul(int a, int b) { return a * b; }
/* A 16x16 unsigned product: both operands are masked to 16 bits, which is the
* form the target selects to MPYU. The product must be computed in unsigned
* arithmetic: 0xffff * 0xffff does not fit in signed int, so `int * int` would
* be signed overflow and the optimizer could narrow or rename the result. */
int umul16(int a, int b) {
return (int)((unsigned)(a & 0xffff) * (unsigned)(b & 0xffff));
}
int sdiv(int a, int b) { return a / b; }
unsigned udiv(unsigned a, unsigned b) { return a / b; }
int srem(int a, int b) { return a % b; }
unsigned urem(unsigned a, unsigned b) { return a % b; }
int mul_test(void) {
MARK(0) = (unsigned)mul(6, 7);
MARK(1) = (unsigned)umul16(0xffff, 0xffff);
MARK(2) = (unsigned)sdiv(100, 7);
MARK(3) = udiv(0xfffffffeu, 7u);
MARK(4) = (unsigned)srem(100, 7);
MARK(5) = urem(100u, 7u);
MARK(6) = (unsigned)sdiv(-100, 7);
MARK(7) = (unsigned)srem(-100, 7);
MARK(10) = (unsigned)mul(0x12345678, 0x9ABCDEF0);
MARK(11) = urem(0xfffffffeu, 7u);
return 0;
}