~drgeo-developers/drgeo/trunk

« back to all changes in this revision

Viewing changes to VMs/iPad/source/Cross/plugins/IA32ABI/dabusinessppc.h

  • Committer: Hilaire Fernandes
  • Date: 2012-01-27 21:15:40 UTC
  • Revision ID: hilaire.fernandes@gmail.com-20120127211540-912spf97bhpx6mve
Initial additions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2008 Cadence Design Systems, Inc.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0
 
5
 */
 
6
/*
 
7
 *  dabusiness.h
 
8
 *
 
9
 *  Written by Eliot Miranda 11/07.
 
10
 *  Changes by John M McIntosh 12/1/08 to support powerpc
 
11
 *
 
12
 * Body of the various callIA32XXXReturn functions.
 
13
 * Call a foreign function according to IA32-ish ABI rules.
 
14
 */
 
15
        long i, size;
 
16
        double  floatStorageArea[13];
 
17
        sqInt funcAlien, resultMaybeAlien;
 
18
        char *argvec;
 
19
#if STACK_ALIGN_BYTES
 
20
        char *argstart;
 
21
#endif
 
22
 
 
23
 
 
24
        for (i = numArgs, size = 0; --i >= 0;) {
 
25
                sqInt arg = argVector[i];
 
26
                if (objIsAlien(arg) && sizeField(arg))
 
27
                        size += moduloPOT(sizeof(long),abs(sizeField(arg)));
 
28
                else if (interpreterProxy->isFloatObject(arg)) {
 
29
                                if (hasTypeArray) 
 
30
                                        size += figureOutFloatSize(typeSignatureArray,i);
 
31
                                else
 
32
                                        size += sizeof(double);
 
33
                }
 
34
                else /* assume an integebr or pointer.  check below. */
 
35
                        size += sizeof(long);
 
36
        }
 
37
 
 
38
#if STACK_ALIGN_BYTES
 
39
        /* At point of call stack must be aligned to STACK_ALIGN_BYTES.  So alloca
 
40
         * at least enough for this plus the argvector, and start writing argvector
 
41
         * at aligned point.  Then just prior to call cut-back stack to aligned.
 
42
         */
 
43
        argvec = alloca(STACK_ALIGN_BYTES + moduloPOT(STACK_ALIGN_BYTES,size));
 
44
        argvec = alignModuloPOT(STACK_ALIGN_BYTES, argvec);
 
45
        argstart = argvec;
 
46
#endif
 
47
        gpRegCount = 0;
 
48
        fpRegCount = 0;
 
49
        
 
50
        for (i = 0; i < numArgs; i++) {
 
51
                sqInt arg = argVector[i];
 
52
                if (isSmallInt(arg)) {
 
53
                        *(long *)argvec = intVal(arg);
 
54
                        if (gpRegCount < 8) gpRegCount++;
 
55
                        argvec += sizeof(long);
 
56
                }
 
57
                else if (objIsAlien(arg)) {
 
58
                        long  argByteSize;
 
59
 
 
60
                        if (!(size = sizeField(arg)))
 
61
                                size = argByteSize = sizeof(void *);
 
62
                        else
 
63
                                argByteSize = abs(size);
 
64
                        switch (argByteSize) {
 
65
                                case (1):
 
66
                                        memcpy(argvec+3, startOfDataWithSize(arg,size), argByteSize);
 
67
                                        break;
 
68
                                case (2):
 
69
                                        memcpy(argvec+2, startOfDataWithSize(arg,size), argByteSize);
 
70
                                        break;
 
71
                                case (3):
 
72
                                        memcpy(argvec+1, startOfDataWithSize(arg,size), argByteSize);
 
73
                                        break;
 
74
                                default: 
 
75
                                        memcpy(argvec, startOfDataWithSize(arg,size), argByteSize);
 
76
                        }
 
77
                        long internalSructureSize = moduloPOT(sizeof(long), argByteSize);
 
78
                        if (gpRegCount < 8) gpRegCount += (internalSructureSize+3)/4;
 
79
                        if (gpRegCount > 8) gpRegCount = 8;
 
80
 
 
81
                        if (hasTypeArray) {
 
82
                                double v;
 
83
                                int sizeOfFloat = figureOutFloatSize(typeSignatureArray,i);
 
84
                                if (sizeOfFloat > 0) {
 
85
                                        if (sizeOfFloat == sizeof(float)) {
 
86
                                                float fv = *(float*)argvec;
 
87
                                                v = fv;
 
88
                                        } else {
 
89
                                                v = *(double*)argvec;
 
90
                                        }
 
91
                                        if (fpRegCount < 13) {  /* 13 registers for floating point numbers */
 
92
                                                floatStorageArea[fpRegCount++] = v;
 
93
                                        }
 
94
                                }
 
95
                        }
 
96
                        argvec += internalSructureSize;
 
97
                }
 
98
                else if (interpreterProxy->isFloatObject(arg)) {
 
99
                        double v = interpreterProxy->floatValueOf(arg);
 
100
                        if (interpreterProxy->failed())
 
101
                                return PrimErrBadArgument;
 
102
                        if (hasTypeArray && figureOutFloatSize(typeSignatureArray,i) == sizeof(float)) {
 
103
                                float floatv = v;
 
104
                                *(float *)argvec = floatv;
 
105
                                argvec += sizeof(float);                        
 
106
                                if (gpRegCount < 8) gpRegCount += 1;
 
107
                        } else {
 
108
                                *(double *)argvec = v;
 
109
                                argvec += sizeof(double);                       
 
110
                                if (gpRegCount < 8) gpRegCount += 2;
 
111
                        }
 
112
                        
 
113
                        if (fpRegCount < 13) {  /* 13 registers for floating point numbers */
 
114
                                floatStorageArea[fpRegCount++] = v;
 
115
                        }
 
116
                        
 
117
                        if (gpRegCount > 8) gpRegCount = 8;
 
118
                }       else if (objIsUnsafeAlien(arg)) {
 
119
                        sqInt bitsObj = interpreterProxy->fetchPointerofObject(0,arg);
 
120
                                void *v = interpreterProxy->firstIndexableField(bitsObj);
 
121
                                *(void **)argvec = v;
 
122
                                if (gpRegCount < 8) gpRegCount++;
 
123
                                argvec += sizeof(long);
 
124
                }else {
 
125
                        long v = interpreterProxy->signed32BitValueOf(arg);
 
126
                        if (interpreterProxy->failed())
 
127
                                return PrimErrBadArgument;
 
128
                        *(long *)argvec = v;
 
129
                        gpRegCount++;
 
130
                        if (gpRegCount < 8) gpRegCount++;
 
131
                        argvec += sizeof(long);
 
132
                }
 
133
        }
 
134
 
 
135
        funcAlien = interpreterProxy->stackValue(funcOffset);
 
136
        ffiStackIndex = (argvec-argstart)/4;
 
137
        GPRegsLocation = ffiStackLocation = (long *) argstart;
 
138
        FPRegsLocation = &floatStorageArea[0];
 
139
        f = *(void **)startOfParameterData(funcAlien);
 
140
#if STACK_ALIGN_BYTES
 
141
        /* cut stack back to start of aligned args */
 
142
//      setsp(0);
 
143
#endif
 
144
        ffiCallAddressOf(f);
 
145