conv_intwiden_u.c (1320B)
1 /* Unsigned integer widening: unsigned char/short -> int -> long via 2 * zero-extension. High source values exercise the zero bits so UXTB/UXTH 3 * (ubfm aliases) and the implicit 32->64 zero-extend (uxtw / mov w which 4 * zero-extends to x) are genuinely required. volatile sources defeat folding. 5 * 6 * uc = 200 : (int)uc = 200 (uxtb w / and w,#0xff) 7 * us = 300 : (int)us = 300 (uxth w / and w,#0xffff) 8 * ui = 0x80000005 : (unsigned long)ui (uxtw / 32->64 zero ext) 9 * Reduce to 42 with masks/mods so the result is deterministic. */ 10 int test_main(void) { 11 volatile unsigned char uc = 200; 12 volatile unsigned short us = 300; 13 volatile unsigned int ui = 0x80000005u; 14 unsigned int a = (unsigned int)uc; /* 200, uxtb */ 15 unsigned int b = (unsigned int)us; /* 300, uxth */ 16 unsigned long c = (unsigned long)ui; /* 0x0000000080000005, uxtw -> x */ 17 /* Zero-extension correctness: high half is 0 (a sign-extend would make it 18 * 0xFFFFFFFF since bit 31 is set). c>>32 == 0 confirms the uxtw path. */ 19 unsigned long hi = c >> 32; /* 0 when correctly zero-extended */ 20 unsigned long lo_nib = c & 0xFu; /* 5 */ 21 unsigned long acc = (a % 100) + (b % 100) + lo_nib + hi; /* 0+0+5+0 = 5 */ 22 return (int)(acc + 37); /* 5 + 37 = 42 */ 23 }