]> gitweb @ CieloNegro.org - pkgsrc-firefox3.git/blob - patches/patch-bu
Initial revision of the upstream www/firefox3
[pkgsrc-firefox3.git] / patches / patch-bu
1 $NetBSD: patch-bu,v 1.1.1.1 2008/06/28 10:01:07 tnn Exp $
2
3 diff -ruN ../Orig/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp ./xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp
4 --- ../Orig/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp      1970-01-01 09:00:00.000000000 +0900
5 +++ ./xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp    2005-12-07 00:07:35.000000000 +0900
6 @@ -0,0 +1,174 @@
7 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
8 +// Platform specific code to invoke XPCOM methods on native objects
9 +
10 +#include "xptcprivate.h"
11 +
12 +// 6 integral parameters are passed in registers
13 +const PRUint32 GPR_COUNT = 6;
14 +
15 +// 8 floating point parameters are passed in SSE registers
16 +const PRUint32 FPR_COUNT = 8;
17 +
18 +// Remember that these 'words' are 64-bit long
19 +static inline void
20 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant * s,
21 +                   PRUint32 & nr_gpr, PRUint32 & nr_fpr, PRUint32 & nr_stack)
22 +{
23 +    nr_gpr = 1; // skip one GP register for 'that'
24 +    nr_fpr = 0;
25 +    nr_stack = 0;
26 +
27 +    /* Compute number of eightbytes of class MEMORY.  */
28 +    for (uint32 i = 0; i < paramCount; i++, s++) {
29 +        if (!s->IsPtrData()
30 +            && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) {
31 +            if (nr_fpr < FPR_COUNT)
32 +                nr_fpr++;
33 +            else
34 +                nr_stack++;
35 +        }
36 +        else {
37 +            if (nr_gpr < GPR_COUNT)
38 +                nr_gpr++;
39 +            else
40 +                nr_stack++;
41 +        }
42 +    }
43 +}
44 +
45 +static void
46 +invoke_copy_to_stack(PRUint64 * d, PRUint32 paramCount, nsXPTCVariant * s,
47 +                     PRUint64 * gpregs, double * fpregs)
48 +{
49 +    PRUint32 nr_gpr = 1; // skip one GP register for 'that'
50 +    PRUint32 nr_fpr = 0;
51 +    PRUint64 value;
52 +
53 +    for (uint32 i = 0; i < paramCount; i++, s++) {
54 +        if (s->IsPtrData())
55 +            value = (PRUint64) s->ptr;
56 +        else {
57 +            switch (s->type) {
58 +            case nsXPTType::T_FLOAT:                                break;
59 +            case nsXPTType::T_DOUBLE:                               break;
60 +            case nsXPTType::T_I8:     value = s->val.i8;            break;
61 +            case nsXPTType::T_I16:    value = s->val.i16;           break;
62 +            case nsXPTType::T_I32:    value = s->val.i32;           break;
63 +            case nsXPTType::T_I64:    value = s->val.i64;           break;
64 +            case nsXPTType::T_U8:     value = s->val.u8;            break;
65 +            case nsXPTType::T_U16:    value = s->val.u16;           break;
66 +            case nsXPTType::T_U32:    value = s->val.u32;           break;
67 +            case nsXPTType::T_U64:    value = s->val.u64;           break;
68 +            case nsXPTType::T_BOOL:   value = s->val.b;             break;
69 +            case nsXPTType::T_CHAR:   value = s->val.c;             break;
70 +            case nsXPTType::T_WCHAR:  value = s->val.wc;            break;
71 +            default:                  value = (PRUint64) s->val.p;  break;
72 +            }
73 +        }
74 +
75 +        if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
76 +            if (nr_fpr < FPR_COUNT)
77 +                fpregs[nr_fpr++] = s->val.d;
78 +            else {
79 +                *((double *)d) = s->val.d;
80 +                d++;
81 +            }
82 +        }
83 +        else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
84 +            if (nr_fpr < FPR_COUNT)
85 +                // The value in %xmm register is already prepared to
86 +                // be retrieved as a float. Therefore, we pass the
87 +                // value verbatim, as a double without conversion.
88 +                fpregs[nr_fpr++] = s->val.d;
89 +            else {
90 +                *((float *)d) = s->val.f;
91 +                d++;
92 +            }
93 +        }
94 +        else {
95 +            if (nr_gpr < GPR_COUNT)
96 +                gpregs[nr_gpr++] = value;
97 +            else
98 +                *d++ = value;
99 +        }
100 +    }
101 +}
102 +
103 +extern "C"
104 +XPTC_PUBLIC_API(nsresult)
105 +XPTC_InvokeByIndex(nsISupports * that, PRUint32 methodIndex,
106 +                   PRUint32 paramCount, nsXPTCVariant * params)
107 +{
108 +    PRUint32 nr_gpr, nr_fpr, nr_stack;
109 +    invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack);
110 +    
111 +    // Stack, if used, must be 16-bytes aligned
112 +    if (nr_stack)
113 +        nr_stack = (nr_stack + 1) & ~1;
114 +
115 +    // Load parameters to stack, if necessary
116 +    PRUint64 *stack = (PRUint64 *) __builtin_alloca(nr_stack * 8);
117 +    PRUint64 gpregs[GPR_COUNT];
118 +    double fpregs[FPR_COUNT];
119 +    invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs);
120 +
121 +    // Load FPR registers from fpregs[]
122 +    register double d0 asm("xmm0");
123 +    register double d1 asm("xmm1");
124 +    register double d2 asm("xmm2");
125 +    register double d3 asm("xmm3");
126 +    register double d4 asm("xmm4");
127 +    register double d5 asm("xmm5");
128 +    register double d6 asm("xmm6");
129 +    register double d7 asm("xmm7");
130 +
131 +    switch (nr_fpr) {
132 +#define ARG_FPR(N) \
133 +    case N+1: d##N = fpregs[N];
134 +        ARG_FPR(7);
135 +        ARG_FPR(6);
136 +        ARG_FPR(5);
137 +        ARG_FPR(4);
138 +        ARG_FPR(3);
139 +        ARG_FPR(2);
140 +        ARG_FPR(1);
141 +        ARG_FPR(0);
142 +    case 0:;
143 +#undef ARG_FPR
144 +    }
145 +    
146 +    // Load GPR registers from gpregs[]
147 +    register PRUint64 a0 asm("rdi");
148 +    register PRUint64 a1 asm("rsi");
149 +    register PRUint64 a2 asm("rdx");
150 +    register PRUint64 a3 asm("rcx");
151 +    register PRUint64 a4 asm("r8");
152 +    register PRUint64 a5 asm("r9");
153 +    
154 +    switch (nr_gpr) {
155 +#define ARG_GPR(N) \
156 +    case N+1: a##N = gpregs[N];
157 +        ARG_GPR(5);
158 +        ARG_GPR(4);
159 +        ARG_GPR(3);
160 +        ARG_GPR(2);
161 +        ARG_GPR(1);
162 +    case 1: a0 = (PRUint64) that;
163 +    case 0:;
164 +#undef ARG_GPR
165 +    }
166 +
167 +    // Ensure that assignments to SSE registers won't be optimized away
168 +    asm("" ::
169 +        "x" (d0), "x" (d1), "x" (d2), "x" (d3),
170 +        "x" (d4), "x" (d5), "x" (d6), "x" (d7));
171 +    
172 +    // Get pointer to method
173 +    PRUint64 methodAddress = *((PRUint64 *)that);
174 +    methodAddress += 8 * methodIndex;
175 +    methodAddress = *((PRUint64 *)methodAddress);
176 +    
177 +    typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64);
178 +    PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5);
179 +    return result;
180 +}