1 $NetBSD: patch-bu,v 1.1.1.1 2008/06/28 10:01:07 tnn Exp $
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
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
10 +#include "xptcprivate.h"
12 +// 6 integral parameters are passed in registers
13 +const PRUint32 GPR_COUNT = 6;
15 +// 8 floating point parameters are passed in SSE registers
16 +const PRUint32 FPR_COUNT = 8;
18 +// Remember that these 'words' are 64-bit long
20 +invoke_count_words(PRUint32 paramCount, nsXPTCVariant * s,
21 + PRUint32 & nr_gpr, PRUint32 & nr_fpr, PRUint32 & nr_stack)
23 + nr_gpr = 1; // skip one GP register for 'that'
27 + /* Compute number of eightbytes of class MEMORY. */
28 + for (uint32 i = 0; i < paramCount; i++, s++) {
30 + && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) {
31 + if (nr_fpr < FPR_COUNT)
37 + if (nr_gpr < GPR_COUNT)
46 +invoke_copy_to_stack(PRUint64 * d, PRUint32 paramCount, nsXPTCVariant * s,
47 + PRUint64 * gpregs, double * fpregs)
49 + PRUint32 nr_gpr = 1; // skip one GP register for 'that'
50 + PRUint32 nr_fpr = 0;
53 + for (uint32 i = 0; i < paramCount; i++, s++) {
55 + value = (PRUint64) s->ptr;
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;
75 + if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
76 + if (nr_fpr < FPR_COUNT)
77 + fpregs[nr_fpr++] = s->val.d;
79 + *((double *)d) = s->val.d;
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;
90 + *((float *)d) = s->val.f;
95 + if (nr_gpr < GPR_COUNT)
96 + gpregs[nr_gpr++] = value;
104 +XPTC_PUBLIC_API(nsresult)
105 +XPTC_InvokeByIndex(nsISupports * that, PRUint32 methodIndex,
106 + PRUint32 paramCount, nsXPTCVariant * params)
108 + PRUint32 nr_gpr, nr_fpr, nr_stack;
109 + invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack);
111 + // Stack, if used, must be 16-bytes aligned
113 + nr_stack = (nr_stack + 1) & ~1;
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);
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");
132 +#define ARG_FPR(N) \
133 + case N+1: d##N = fpregs[N];
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");
155 +#define ARG_GPR(N) \
156 + case N+1: a##N = gpregs[N];
162 + case 1: a0 = (PRUint64) that;
167 + // Ensure that assignments to SSE registers won't be optimized away
169 + "x" (d0), "x" (d1), "x" (d2), "x" (d3),
170 + "x" (d4), "x" (d5), "x" (d6), "x" (d7));
172 + // Get pointer to method
173 + PRUint64 methodAddress = *((PRUint64 *)that);
174 + methodAddress += 8 * methodIndex;
175 + methodAddress = *((PRUint64 *)methodAddress);
177 + typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64);
178 + PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5);