#include <inttypes.h>
#include <stdio.h>

static int64_t passthrough(int64_t a) { return a; }

static int64_t neg(int64_t a) { return -a; }

static int64_t neg_extravar(int64_t a) {
  int64_t neg = -a;
  return neg;
}

static int64_t rec_many_args(int64_t rdi, int64_t rsi, int64_t rdx, int64_t rcx,
                             int64_t r8, int64_t r9, int64_t s1) {
  if (s1 == INT64_MIN) {
    return INT64_MIN;
  } else {
    return rec_many_args(rdi, rsi, rdx, rcx, r8, r9, s1 - 1);
  }
}

static int64_t many_args(int64_t rdi, int64_t rsi, int64_t rdx, int64_t rcx,
                         int64_t r8, int64_t r9, int64_t s1) {

  int64_t s2 =
      rec_many_args(0xfffffffffffffff0, 0xfffffffffffffff1, 0xfffffffffffffff3,
                    0xfffffffffffffff4, 0xfffffffffffffff5, 0xfffffffffffffff6,
                    INT64_MIN + 80000);
  return s2;
}

static void printer(int64_t *a, int64_t *b) {
  fprintf(stdout, "%" PRId64 " = -%" PRId64 "\n", *a, *b);
}

static void caller(void) {
  int64_t a = passthrough(INT64_MAX);
  int64_t b = neg(a);
  printer(&a, &b);
}

static int *grow_stack(int size) {
  int a[size];
  for (int i = 0; i < size; i++) {
    a[i] = 0;
  }
  return a;
}

static int64_t *large_stack() {
  uint64_t a[100000000];
  return a;
}

static void simple_printer(void) { fprintf(stderr, "I wonder who called me?"); }

static void modifier(void) {
  uint64_t *p;
  // without frame-pointer
  // *(&p + 1) = (uint64_t *)simple_printer;

  // with frame-pointer
  *(&p + 2) = (uint64_t *)simple_printer;
}

static void modifier_indexed(uint64_t *p) {
  // without frame-pointer
  (&p)[1] = (uint64_t *)simple_printer;

  // with frame-pointer
  (&p)[2] = (uint64_t *)simple_printer;
}

int main(void) {
  // caller();
  // many_args(0xfffffffffffffff0, 0xfffffffffffffff1, 0xfffffffffffffff3,
  //          0xfffffffffffffff4, 0xfffffffffffffff5, 0xfffffffffffffff6,
  //          0xfffffffffffffff7);
  //  modifier_indexed(NULL);
  // modifier();
  large_stack();
  fprintf(stderr, "main exiting");
  return 0;
}