1  /* Checks proper behavior of __morestack function - specifically, GPR
       2     values surviving, stack parameters being copied, and vararg
       3     pointer being correct.  */
       4  
       5  /* { dg-do run } */
       6  /* { dg-options "-O2 -fsplit-stack" } */
       7  
       8  #include <stdlib.h>
       9  
      10  void *orig_r15;
      11  
      12  /* 1. Function "test" saves registers, makes a stack frame, puts known
      13   *    values in registers, and calls __morestack, telling it to jump to
      14   *    testinner, with return address pointing to "testret".
      15   * 2. "testinner" checks that parameter registers match what has been
      16   *    passed from "test", stack parameters were copied properly to
      17   *    the new stack, and the argument pointer matches the calling
      18   *    function's stack pointer.  It then leaves new values in volatile
      19   *    registers (including return value registers) and returns.
      20   * 3. "testret" checks that return value registers contain the expected
      21   *    return value, callee-saved GPRs match the values from "test",
      22   *    and then returns to main. */
      23  
      24  extern unsigned long testparams[3];
      25  
      26  #ifdef __s390x__
      27  
      28  asm(
      29    ".global test\n"
      30    "test:\n"
      31    ".type test, @function\n"
      32    /* Save registers.  */
      33    "stmg %r6, %r15, 0x30(%r15)\n"
      34    /* Save original sp in a global.  */
      35    "larl %r1, orig_r15\n"
      36    "stg %r15, 0(%r1)\n"
      37    /* Make a stack frame.  */
      38    "aghi %r15, -168\n"
      39    /* A stack parameter.  */
      40    "lghi %r1, 0x1240\n"
      41    "stg %r1, 160(%r15)\n"
      42    /* Registers.  */
      43    "lghi %r0, 0x1230\n"
      44    "lghi %r2, 0x1232\n"
      45    "lghi %r3, 0x1233\n"
      46    "lghi %r4, 0x1234\n"
      47    "lghi %r5, 0x1235\n"
      48    "lghi %r6, 0x1236\n"
      49    "lghi %r7, 0x1237\n"
      50    "lghi %r8, 0x1238\n"
      51    "lghi %r9, 0x1239\n"
      52    "lghi %r10, 0x123a\n"
      53    "lghi %r11, 0x123b\n"
      54    "lghi %r12, 0x123c\n"
      55    "lghi %r13, 0x123d\n"
      56    /* Fake return address.  */
      57    "larl %r14, testret\n"
      58    /* Call morestack.  */
      59    "larl %r1, testparams\n"
      60    "jg __morestack\n"
      61  
      62    /* Entry point.  */
      63    "testinner:\n"
      64    /* Check registers.  */
      65    "cghi %r0, 0x1230\n"
      66    "jne testerr\n"
      67    "cghi %r2, 0x1232\n"
      68    "jne testerr\n"
      69    "cghi %r3, 0x1233\n"
      70    "jne testerr\n"
      71    "cghi %r4, 0x1234\n"
      72    "jne testerr\n"
      73    "cghi %r5, 0x1235\n"
      74    "jne testerr\n"
      75    "cghi %r6, 0x1236\n"
      76    "jne testerr\n"
      77    /* Check stack param.  */
      78    "lg %r0, 0xa0(%r15)\n"
      79    "cghi %r0, 0x1240\n"
      80    "jne testerr\n"
      81    /* Check argument pointer.  */
      82    "aghi %r1, 8\n"
      83    "larl %r2, orig_r15\n"
      84    "cg %r1, 0(%r2)\n"
      85    "jne testerr\n"
      86    /* Modify volatile registers.  */
      87    "lghi %r0, 0x1250\n"
      88    "lghi %r1, 0x1251\n"
      89    "lghi %r2, 0x1252\n"
      90    "lghi %r3, 0x1253\n"
      91    "lghi %r4, 0x1254\n"
      92    "lghi %r5, 0x1255\n"
      93    /* Return.  */
      94    "br %r14\n"
      95  
      96    /* Returns here.  */
      97    "testret:\n"
      98    /* Check return registers.  */
      99    "cghi %r2, 0x1252\n"
     100    "jne testerr\n"
     101    /* Check callee-saved registers.  */
     102    "cghi %r6, 0x1236\n"
     103    "jne testerr\n"
     104    "cghi %r7, 0x1237\n"
     105    "jne testerr\n"
     106    "cghi %r8, 0x1238\n"
     107    "jne testerr\n"
     108    "cghi %r9, 0x1239\n"
     109    "jne testerr\n"
     110    "cghi %r10, 0x123a\n"
     111    "jne testerr\n"
     112    "cghi %r11, 0x123b\n"
     113    "jne testerr\n"
     114    "cghi %r12, 0x123c\n"
     115    "jne testerr\n"
     116    "cghi %r13, 0x123d\n"
     117    "jne testerr\n"
     118    /* Return.  */
     119    "lmg %r6, %r15, 0xd8(%r15)\n"
     120    "br %r14\n" 
     121  
     122    /* Parameters block.  */
     123    ".section .data\n"
     124    ".align 8\n"
     125    "testparams:\n"
     126    ".quad 160\n"
     127    ".quad 8\n"
     128    ".quad testinner-testparams\n"
     129    ".text\n"
     130  );
     131  
     132  #else
     133  
     134  asm(
     135    ".global test\n"
     136    "test:\n"
     137    ".type test, @function\n"
     138    /* Save registers.  */
     139    "stm %r6, %r15, 0x18(%r15)\n"
     140    /* Save original sp in a global.  */
     141    "larl %r1, orig_r15\n"
     142    "st %r15, 0(%r1)\n"
     143    /* Make a stack frame.  */
     144    "ahi %r15, -0x68\n"
     145    /* A stack parameter.  */
     146    "lhi %r1, 0x1240\n"
     147    "st %r1, 0x60(%r15)\n"
     148    "lhi %r1, 0x1241\n"
     149    "st %r1, 0x64(%r15)\n"
     150    /* Registers.  */
     151    "lhi %r0, 0x1230\n"
     152    "lhi %r2, 0x1232\n"
     153    "lhi %r3, 0x1233\n"
     154    "lhi %r4, 0x1234\n"
     155    "lhi %r5, 0x1235\n"
     156    "lhi %r6, 0x1236\n"
     157    "lhi %r7, 0x1237\n"
     158    "lhi %r8, 0x1238\n"
     159    "lhi %r9, 0x1239\n"
     160    "lhi %r10, 0x123a\n"
     161    "lhi %r11, 0x123b\n"
     162    "lhi %r12, 0x123c\n"
     163    "lhi %r13, 0x123d\n"
     164    /* Fake return address.  */
     165    "larl %r14, testret\n"
     166    /* Call morestack.  */
     167    "larl %r1, testparams\n"
     168    "jg __morestack\n"
     169  
     170    /* Entry point.  */
     171    "testinner:\n"
     172    /* Check registers.  */
     173    "chi %r0, 0x1230\n"
     174    "jne testerr\n"
     175    "chi %r2, 0x1232\n"
     176    "jne testerr\n"
     177    "chi %r3, 0x1233\n"
     178    "jne testerr\n"
     179    "chi %r4, 0x1234\n"
     180    "jne testerr\n"
     181    "chi %r5, 0x1235\n"
     182    "jne testerr\n"
     183    "chi %r6, 0x1236\n"
     184    "jne testerr\n"
     185    /* Check stack param.  */
     186    "l %r0, 0x60(%r15)\n"
     187    "chi %r0, 0x1240\n"
     188    "jne testerr\n"
     189    "l %r0, 0x64(%r15)\n"
     190    "chi %r0, 0x1241\n"
     191    "jne testerr\n"
     192    /* Check argument pointer.  */
     193    "ahi %r1, 8\n"
     194    "larl %r2, orig_r15\n"
     195    "c %r1, 0(%r2)\n"
     196    "jne testerr\n"
     197    /* Modify volatile registers.  */
     198    "lhi %r0, 0x1250\n"
     199    "lhi %r1, 0x1251\n"
     200    "lhi %r2, 0x1252\n"
     201    "lhi %r3, 0x1253\n"
     202    "lhi %r4, 0x1254\n"
     203    "lhi %r5, 0x1255\n"
     204    /* Return.  */
     205    "br %r14\n"
     206  
     207    /* Returns here.  */
     208    "testret:\n"
     209    /* Check return registers.  */
     210    "chi %r2, 0x1252\n"
     211    "jne testerr\n"
     212    "chi %r3, 0x1253\n"
     213    "jne testerr\n"
     214    /* Check callee-saved registers.  */
     215    "chi %r6, 0x1236\n"
     216    "jne testerr\n"
     217    "chi %r7, 0x1237\n"
     218    "jne testerr\n"
     219    "chi %r8, 0x1238\n"
     220    "jne testerr\n"
     221    "chi %r9, 0x1239\n"
     222    "jne testerr\n"
     223    "chi %r10, 0x123a\n"
     224    "jne testerr\n"
     225    "chi %r11, 0x123b\n"
     226    "jne testerr\n"
     227    "chi %r12, 0x123c\n"
     228    "jne testerr\n"
     229    "chi %r13, 0x123d\n"
     230    "jne testerr\n"
     231    /* Return.  */
     232    "lm %r6, %r15, 0x80(%r15)\n"
     233    "br %r14\n" 
     234  
     235    /* Parameters block.  */
     236    ".section .data\n"
     237    ".align 4\n"
     238    "testparams:\n"
     239    ".long 96\n"
     240    ".long 8\n"
     241    ".long testinner-testparams\n"
     242    ".text\n"
     243  );
     244  
     245  #endif
     246  
     247  _Noreturn void testerr (void) {
     248    exit(1);
     249  }
     250  
     251  extern void test (void);
     252  
     253  int main (void) {
     254    test();
     255    /* Now try again, with huge stack frame requested - to exercise
     256       both paths in __morestack (new allocation needed or not).  */
     257    testparams[0] = 1000000;
     258    test();
     259    return 0;
     260  }