343-i64-vararg-switch.c (1100B)
1 /* Pair-valued variadic arguments and switch controls must retain their high 2 * word on RV32. The two case labels deliberately share the same low word. */ 3 typedef unsigned long long u64; 4 typedef signed long long i64; 5 6 #ifndef CCSCM 7 #include <stdarg.h> 8 #else 9 typedef char *va_list; 10 #define va_start(ap, n) __builtin_va_start(ap, n) 11 #define va_arg(ap, t) __builtin_va_arg(ap, t) 12 #define va_end(ap) __builtin_va_end(ap) 13 #endif 14 15 static u64 read_pairs(int marker, ...) 16 { 17 va_list ap; 18 u64 a; 19 int middle; 20 i64 b; 21 va_start(ap, marker); 22 a = va_arg(ap, u64); 23 middle = va_arg(ap, int); 24 b = va_arg(ap, i64); 25 va_end(ap); 26 return a + (u64)middle + (u64)b + (u64)marker; 27 } 28 29 static int classify(u64 x) 30 { 31 switch (x) { 32 case 2ULL: return 1; 33 case 0x100000002ULL: return 2; 34 default: return 3; 35 } 36 } 37 38 int main(void) 39 { 40 if (read_pairs(7, 0x100000000ULL, 5, (i64)-3LL) 41 != 0x100000009ULL) return 1; 42 if (classify(2ULL) != 1) return 2; 43 if (classify(0x100000002ULL) != 2) return 3; 44 if (classify(0x200000002ULL) != 3) return 4; 45 return 0; 46 }