17b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===- subzero/crosstest/test_stacksave.c - Implementation for tests ------===//
27b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//
37b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//                        The Subzero Code Generator
47b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//
57b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// This file is distributed under the University of Illinois Open Source
67b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// License. See LICENSE.TXT for details.
77b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//
87b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===----------------------------------------------------------------------===//
97b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//
107b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// This aims to test that C99's VLAs (which use stacksave/stackrestore
117b34b59756adbfb4ce623c3252386851c98b0070Jan Voung// intrinsics) work fine.
127b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//
137b34b59756adbfb4ce623c3252386851c98b0070Jan Voung//===----------------------------------------------------------------------===//
147b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
157b34b59756adbfb4ce623c3252386851c98b0070Jan Voung#include <stdint.h>
167b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
177b34b59756adbfb4ce623c3252386851c98b0070Jan Voung#include "test_stacksave.h"
187b34b59756adbfb4ce623c3252386851c98b0070Jan VoungDECLARE_TESTS()
197b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
207b34b59756adbfb4ce623c3252386851c98b0070Jan Voung/* NOTE: This has 0 stacksaves, because the vla isn't in a loop,
217b34b59756adbfb4ce623c3252386851c98b0070Jan Voung * so the vla can just be freed by the epilogue.
227b34b59756adbfb4ce623c3252386851c98b0070Jan Voung */
237b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_basic_vla(uint32_t size, uint32_t start, uint32_t inc) {
247b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  uint32_t vla[size];
257b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  uint32_t mid = start + ((size - start) / 2);
267b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  for (uint32_t i = start; i < size; ++i) {
277b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    vla[i] = i + inc;
287b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  }
297b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  return (vla[start] << 2) + (vla[mid] << 1) + vla[size - 1];
307b34b59756adbfb4ce623c3252386851c98b0070Jan Voung}
317b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
32dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnothstatic uint32_t __attribute__((noinline)) foo(uint32_t x) { return x * x; }
337b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
347b34b59756adbfb4ce623c3252386851c98b0070Jan Voung/* NOTE: This has 1 stacksave, because the vla is in a loop and should
357b34b59756adbfb4ce623c3252386851c98b0070Jan Voung * be freed before the next iteration.
367b34b59756adbfb4ce623c3252386851c98b0070Jan Voung */
377b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_vla_in_loop(uint32_t size, uint32_t start, uint32_t inc) {
387b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  uint32_t sum = 0;
397b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  for (uint32_t i = start; i < size; ++i) {
407b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    uint32_t size1 = size - i;
417b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    uint32_t vla[size1];
427b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    for (uint32_t j = 0; j < size1; ++j) {
437b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      /* Adjust stack again with a function call. */
447b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      vla[j] = foo(start * j + inc);
457b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    }
467b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    for (uint32_t j = 0; j < size1; ++j) {
477b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      sum += vla[j];
487b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    }
497b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  }
507b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  return sum;
517b34b59756adbfb4ce623c3252386851c98b0070Jan Voung}
527b34b59756adbfb4ce623c3252386851c98b0070Jan Voung
537b34b59756adbfb4ce623c3252386851c98b0070Jan Vounguint32_t test_two_vlas_in_loops(uint32_t size, uint32_t start, uint32_t inc) {
547b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  uint32_t sum = 0;
557b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  for (uint32_t i = start; i < size; ++i) {
567b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    uint32_t size1 = size - i;
577b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    uint32_t vla1[size1];
587b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    for (uint32_t j = 0; j < size1; ++j) {
597b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      uint32_t size2 = size - j;
607b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      uint32_t start2 = 0;
617b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      uint32_t mid2 = size2 / 2;
627b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      uint32_t vla2[size2];
637b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      for (uint32_t k = start2; k < size2; ++k) {
647b34b59756adbfb4ce623c3252386851c98b0070Jan Voung        /* Adjust stack again with a function call. */
657b34b59756adbfb4ce623c3252386851c98b0070Jan Voung        vla2[k] = foo(start * k + inc);
667b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      }
677b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      vla1[j] = (vla2[start2] << 2) + (vla2[mid2] << 1) + vla2[size2 - 1];
687b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    }
697b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    for (uint32_t j = 0; j < size1; ++j) {
707b34b59756adbfb4ce623c3252386851c98b0070Jan Voung      sum += vla1[j];
717b34b59756adbfb4ce623c3252386851c98b0070Jan Voung    }
727b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  }
737b34b59756adbfb4ce623c3252386851c98b0070Jan Voung  return sum;
747b34b59756adbfb4ce623c3252386851c98b0070Jan Voung}
75