boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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 }