OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [testsuite/] [gcc.target/] [sparc/] [struct-ret-check.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 326 jeremybenn
/* Copyright (C) 2006 Free Software Foundation, Inc. */
2
/* Contributed by Carlos O'Donell on 2006-03-14 */
3
 
4
/* Test that GCC follows the SPARC 32-bit psABI with regards to
5
   structure return checking in a callee. When -mstd-struct-return
6
   is specificed then gcc will emit code to skip the unimp insn. */
7
 
8
/* Origin: Carlos O'Donell <carlos@codesourcery.com> */
9
/* { dg-do run { target sparc*-*-solaris* sparc*-*-linux* sparc*-*-*bsd* } } */
10
/* { dg-options "-mstd-struct-return" } */
11
/* { dg-require-effective-target ilp32 } */
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <signal.h>
15
 
16
/* Local declaration of div_t structure */
17
struct mydiv_t {
18
  int rem;
19
  int quot;
20
};
21
 
22
/* Global check variable used by signal handler */
23
int check = 1;
24
struct mydiv_t dcheck;
25
 
26
struct mydiv_t foo (void)
27
{
28
  struct mydiv_t bar;
29
  bar.rem = 3;
30
  bar.quot = 4;
31
  return bar;
32
}
33
 
34
void handle_sigill (int signum)
35
{
36
  if (signum == SIGILL && check == 2)
37
    {
38
      /* We expected a SIGILL due to a mismatch in unimp size
39
         and struct mydiv_t size */
40
      exit (0);
41
    }
42
  else
43
    abort ();
44
}
45
 
46
/* Implement 3 checks to validate SPARC 32-bit psABI callee
47
   returns struct
48
 
49
   Test1: Save area is valid. unimp size is valid.
50
   Success: Save area modified correctly.
51
   Failure: Save area unmodified.
52
 
53
   Test2: Save area is valid. unimp size is invalid (invalid insn).
54
   Success: Save area unmodified. check == 2.
55
   Failure: Save area modified or check == 1.
56
 
57
   Test3: Save area is invalid. unimp size is invalid (invalid size).
58
   Success: Will raise a SIGILL.
59
   Failure: SIGSEGV caused by write to invalid save area. */
60
 
61
int main (void)
62
{
63
  dcheck.rem = 1;
64
  dcheck.quot = 2;
65
 
66
  /*** Test1 ***/
67
  /* Insert a call, insert unimp by hand */
68
  __asm__ ("st %1, [ %%sp + 0x40 ]\n\t"
69
           "call foo\n\t"
70
           " nop\n\t"
71
           "unimp %2\n\t"
72
           : "=m" (dcheck)
73
           : "r" (&dcheck), "i" (sizeof(struct mydiv_t))
74
           : "memory");
75
 
76
  /* If the caller doesn't adjust the return, then it crashes.
77
     Check the result too. */
78
 
79
  if ((dcheck.rem != 3) || (dcheck.quot !=4))
80
    abort ();
81
 
82
 
83
  /*** Test 2 ***/
84
  dcheck.rem = 1;
85
  dcheck.quot = 2;
86
 
87
  /* Ignore the return of the function */
88
  __asm__ ("st %3, [ %%sp + 0x40 ]\n\t"
89
           "call foo\n\t"
90
           " nop\n\t"
91
           "mov %2, %0\n\t"
92
           : "+r" (check), "=m" (dcheck)
93
           : "i" (0x2), "r" (&dcheck)
94
           : "memory");
95
 
96
  /* If the caller does an unconditional adjustment it will skip
97
     the mov, and then we can fail the test based on check's value
98
     We pass a valid pointer to a save area in order to check if
99
     caller incorrectly wrote to the save area aswell. There may
100
     be a case where the unimp check and skip is correct, but the
101
     write to the save area still occurs. */
102
 
103
  if (check != 2)
104
    abort ();
105
 
106
  if ((dcheck.rem != 1) || (dcheck.quot != 2))
107
    abort ();
108
 
109
  /*** Test 3 ***/
110
  /* Prepare a test that must SIGILL. According to the spec
111
     if the sizes of the save area and return don't match then
112
     the copy is ignored and we return to the unimp. */
113
 
114
  signal (SIGILL, handle_sigill);
115
 
116
  __asm__ ("st %%g0, [ %%sp + 0x40 ]\n\t"
117
           "call foo\n\t"
118
           " nop\n\t"
119
           "unimp %0\n\t"
120
           : /* No outputs */
121
           : "i" (sizeof(struct mydiv_t)-1)
122
           : "memory");
123
 
124
  /* NEVER REACHED */
125
  exit (0);
126
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.