/*
 * Test code generation for 32-bit shifts by a constant amount
 */

typedef unsigned long ui32;
typedef long i32;

#define UI32 ((ui32) 0xdeadb0d1UL)
#define I32 ((i32) 0xdeadb0d1L)

ui32 left[65] = {
	UI32 << 0, UI32 << 1, UI32 << 2, UI32 << 3, UI32 << 4,
	UI32 << 5, UI32 << 6, UI32 << 7, UI32 << 8, UI32 << 9,
	UI32 << 10, UI32 << 11, UI32 << 12, UI32 << 13, UI32 << 14,
	UI32 << 15, UI32 << 16, UI32 << 17, UI32 << 18, UI32 << 19,
	UI32 << 20, UI32 << 21, UI32 << 22, UI32 << 23, UI32 << 24,
	UI32 << 25, UI32 << 26, UI32 << 27, UI32 << 28, UI32 << 29,
	UI32 << 30, UI32 << 31, UI32 << 32,
};

ui32 lright[65] = {
	UI32 >> 0, UI32 >> 1, UI32 >> 2, UI32 >> 3, UI32 >> 4,
	UI32 >> 5, UI32 >> 6, UI32 >> 7, UI32 >> 8, UI32 >> 9,
	UI32 >> 10, UI32 >> 11, UI32 >> 12, UI32 >> 13, UI32 >> 14,
	UI32 >> 15, UI32 >> 16, UI32 >> 17, UI32 >> 18, UI32 >> 19,
	UI32 >> 20, UI32 >> 21, UI32 >> 22, UI32 >> 23, UI32 >> 24,
	UI32 >> 25, UI32 >> 26, UI32 >> 27, UI32 >> 28, UI32 >> 29,
	UI32 >> 30, UI32 >> 31, UI32 >> 32,
};

i32 aright[65] = {
	I32 >> 0, I32 >> 1, I32 >> 2, I32 >> 3, I32 >> 4,
	I32 >> 5, I32 >> 6, I32 >> 7, I32 >> 8, I32 >> 9,
	I32 >> 10, I32 >> 11, I32 >> 12, I32 >> 13, I32 >> 14,
	I32 >> 15, I32 >> 16, I32 >> 17, I32 >> 18, I32 >> 19,
	I32 >> 20, I32 >> 21, I32 >> 22, I32 >> 23, I32 >> 24,
	I32 >> 25, I32 >> 26, I32 >> 27, I32 >> 28, I32 >> 29,
	I32 >> 30, I32 >> 31, I32 >> 32,
};

extern uitest(ui32 v);
extern itest(i32 v);

main()
{
	uitest(UI32);
	itest(I32);
	exit(0);
}

/* test logical shifts by a constant */
uitest(ui32 v)
{
	register int i = -1;
	char *s = "ASL failed at %02d: 0x%08lx 0x%08lx\n";

#define DO(N) if (v << N != left[++i]) printf(s, i, left[i], v << N)
	DO(0); DO(1); DO(2); DO(3); DO(4);
	DO(5); DO(6); DO(7); DO(8); DO(9);
	DO(10); DO(11); DO(12); DO(13); DO(14);
	DO(15); DO(16); DO(17); DO(18); DO(19);
	DO(20); DO(21); DO(22); DO(23); DO(24);
	DO(25); DO(26); DO(27); DO(28); DO(29);
	DO(30); DO(31); DO(32);
#undef DO

	i = -1; s = "LSR failed at %02d: 0x%08lx 0x%08lx\n";
#define DO(N) if (v >> N != lright[++i]) printf(s, i, lright[i], v >> N)
	DO(0); DO(1); DO(2); DO(3); DO(4);
	DO(5); DO(6); DO(7); DO(8); DO(9);
	DO(10); DO(11); DO(12); DO(13); DO(14);
	DO(15); DO(16); DO(17); DO(18); DO(19);
	DO(20); DO(21); DO(22); DO(23); DO(24);
	DO(25); DO(26); DO(27); DO(28); DO(29);
	DO(30); DO(31); DO(32);
#undef DO
}

/* test arithmetic shifts by a constant */
itest(i32 v)
{
	register int i = -1;
	char *s = "ASR failed at %02d: 0x%08lx 0x%08lx\n";

#define DO(N) if (v >> N != aright[++i]) printf(s, i, aright[i], v >> N)
	DO(0); DO(1); DO(2); DO(3); DO(4);
	DO(5); DO(6); DO(7); DO(8); DO(9);
	DO(10); DO(11); DO(12); DO(13); DO(14);
	DO(15); DO(16); DO(17); DO(18); DO(19);
	DO(20); DO(21); DO(22); DO(23); DO(24);
	DO(25); DO(26); DO(27); DO(28); DO(29);
	DO(30); DO(31); DO(32);
#undef DO
}
