~ubuntu-branches/ubuntu/trusty/gnustep-base/trusty

« back to all changes in this revision

Viewing changes to Source/mframe/powerpc/darwin

Tags: upstream-1.20.0
ImportĀ upstreamĀ versionĀ 1.20.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* See ../README for copyright */
2
 
 
3
 
/*
4
 
 * The first eight words of non-FP are in registers (offset 4 in frame).
5
 
 * The first 13 FP args are in registers (offset 40 in frame).
6
 
 * If the method returns a structure, it's address is passed as an invisible
7
 
 * first argument, so only seven words of non-FP are passed in the registers.
8
 
 * Structures are always passed by reference.
9
 
 * Floats are placed in the frame as doubles.
10
 
 */
11
 
 
12
 
#define MFRAME_STRUCT_BYREF     0
13
 
#define MFRAME_SMALL_STRUCT     0
14
 
#define MFRAME_ARGS_SIZE        144
15
 
#define MFRAME_RESULT_SIZE      16
16
 
#define MFRAME_FLT_IN_FRAME_AS_DBL      1
17
 
 
18
 
/*
19
 
 * Structures are passed by reference as an invisible first argument, so
20
 
 * they go in the first register space for non-FP arguments - at offset 4.
21
 
 */
22
 
#define MFRAME_GET_STRUCT_ADDR(ARGS, TYPES) \
23
 
((*(TYPES)==_C_STRUCT_B || *(TYPES)==_C_UNION_B || *(TYPES)==_C_ARY_B) ? \
24
 
      *(void**)(((char*)(ARGS))+4): (void*)0)
25
 
 
26
 
#define MFRAME_SET_STRUCT_ADDR(ARGS, TYPES, ADDR) \
27
 
({if (*(TYPES)==_C_STRUCT_B || *(TYPES)==_C_UNION_B || *(TYPES)==_C_ARY_B) \
28
 
      *(void**)(((char*)(ARGS))+4) = (ADDR);})
29
 
 
30
 
/*
31
 
 * Typedef for structure to keep track of argument info while processing
32
 
 * a method.
33
 
 */
34
 
typedef struct rs6000_args 
35
 
{
36
 
  int int_args;         /* Number of integer arguments so far.          */
37
 
  int float_args;       /* Number of FP arguments so far.               */
38
 
  int regs_position;    /* The current position for non-FP args.        */
39
 
  int stack_position;   /* The current position in the stack frame.     */
40
 
} MFRAME_ARGS;
41
 
 
42
 
 
43
 
/*
44
 
 * Initialize a variable to keep track of argument info while processing a
45
 
 * method.  Keeps count of the number of arguments of each type seen and
46
 
 * the current offset in the non-FP registers.  This offset is adjusted
47
 
 * to take account of an invisible first argument used to return structures.
48
 
 */
49
 
 
50
 
#define MFRAME_INIT_ARGS(CUM, RTYPE) \
51
 
({ \
52
 
  (CUM).int_args = 0; \
53
 
  (CUM).float_args = 0; \
54
 
  (CUM).stack_position = 0; \
55
 
  (CUM).regs_position = \
56
 
    ((*(RTYPE)==_C_STRUCT_B || *(RTYPE)==_C_UNION_B || *(RTYPE)==_C_ARY_B) ? \
57
 
        sizeof(void*) : 4); \
58
 
})
59
 
 
60
 
#define MFRAME_ARG_ENCODING(CUM, TYPE, STACK, DEST) \
61
 
({  \
62
 
  const char* type = (TYPE); \
63
 
\
64
 
  (TYPE) = objc_skip_typespec(type); \
65
 
  if (*type == _C_FLT || *type == _C_DBL) \
66
 
    { \
67
 
      if (++(CUM).float_args > 13) \
68
 
        { \
69
 
          (CUM).stack_position += ROUND ((CUM).stack_position, \
70
 
                                           __alignof__(double)); \
71
 
          sprintf((DEST), "%.*s%d", (TYPE)-type, type, (CUM).stack_position); \
72
 
          (STACK) = ROUND ((CUM).stack_position, sizeof(double)); \
73
 
        } \
74
 
      else \
75
 
        { \
76
 
          sprintf((DEST), "%.*s+%d", (TYPE)-type, type, \
77
 
                40 + sizeof (double) * ((CUM).float_args - 1)); \
78
 
        } \
79
 
    } \
80
 
  else \
81
 
    { \
82
 
      int align, size; \
83
 
\
84
 
      if (*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) \
85
 
        { \
86
 
          align = __alignof__(void*); \
87
 
          size = sizeof (void*); \
88
 
        } \
89
 
      else \
90
 
        { \
91
 
          align = __alignof__(int); \
92
 
          size = objc_sizeof_type (type); \
93
 
        } \
94
 
\
95
 
      if (++(CUM).int_args > 8) \
96
 
        { \
97
 
          (CUM).stack_position += ROUND ((CUM).stack_position, align); \
98
 
          sprintf((DEST), "%.*s%d", (TYPE)-type, type, (CUM).stack_position); \
99
 
          (STACK) = ROUND ((CUM).stack_position, size); \
100
 
        } \
101
 
      else \
102
 
        { \
103
 
            (CUM).regs_position = ROUND((CUM).regs_position, align); \
104
 
          sprintf(dest, "%.*s+%d", (TYPE)-type, type, (CUM).regs_position); \
105
 
          (CUM).regs_position += ROUND (size, align); \
106
 
        } \
107
 
    } \
108
 
  (DEST)=&(DEST)[strlen(DEST)]; \
109
 
  if (*(TYPE) == '+') \
110
 
    { \
111
 
      (TYPE)++; \
112
 
    } \
113
 
  if (*(TYPE) == '-') \
114
 
    { \
115
 
      (TYPE)++; \
116
 
    } \
117
 
  while (isdigit(*(TYPE))) \
118
 
    { \
119
 
      (TYPE)++; \
120
 
    } \
121
 
})