eed59c1e6c
Here's what's new in this release of Firefox: * New Default Theme An updated Default Theme now presents a uniform appearance across all three platforms - a new crisp, clear look for Windows users. Finetuning for GNOME will follow in future releases. * Comprehensive Data Migration Switching to Firefox has never been easier now that Firefox imports data like Favorites, History, Settings, Cookies and Passwords from Internet Explorer. Firefox can also import from Mozilla 1.x, Netscape 4.x, 6.x and 7.x, and Opera. MacOS X and Linux migrators for browsers like Safari, OmniWeb, Konqueror etc. will arrive in future releases. * Extension/Theme Manager New Extension and Theme Managers provide a convenient way to manage and update your add-ons. SmartUpdate also notifies you of updates to Firefox. * Help A new online help system is available. * Lots of bug fixes and improvements Copy Image, the ability to delete individual items from Autocomplete lists, SMB/SFTP support on GNOME via gnome-vfs, better Bookmarks, Search and many other refinements fine tune the browsing experience. For Linux/GTK2 Users * Look and Feel Updates Ongoing improvements have been made to improve the way Firefox adheres to your GTK2 themes, such as menus. * Talkback for GTK2 Help us nail down crashes by submitting talkback reports with this crash reporting tool.
179 lines
6.1 KiB
Text
179 lines
6.1 KiB
Text
$NetBSD: patch-bu,v 1.2 2004/06/23 16:47:12 taya Exp $
|
|
|
|
--- xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp.orig 2004-05-30 21:38:13.000000000 +0900
|
|
+++ xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_amd64.cpp 2004-05-30 21:37:22.000000000 +0900
|
|
@@ -0,0 +1,174 @@
|
|
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
+// Platform specific code to invoke XPCOM methods on native objects
|
|
+
|
|
+#include "xptcprivate.h"
|
|
+
|
|
+// 6 integral parameters are passed in registers
|
|
+const PRUint32 GPR_COUNT = 6;
|
|
+
|
|
+// 8 floating point parameters are passed in SSE registers
|
|
+const PRUint32 FPR_COUNT = 8;
|
|
+
|
|
+// Remember that these 'words' are 64-bit long
|
|
+static inline void
|
|
+invoke_count_words(PRUint32 paramCount, nsXPTCVariant * s,
|
|
+ PRUint32 & nr_gpr, PRUint32 & nr_fpr, PRUint32 & nr_stack)
|
|
+{
|
|
+ nr_gpr = 1; // skip one GP register for 'that'
|
|
+ nr_fpr = 0;
|
|
+ nr_stack = 0;
|
|
+
|
|
+ /* Compute number of eightbytes of class MEMORY. */
|
|
+ for (uint32 i = 0; i < paramCount; i++, s++) {
|
|
+ if (!s->IsPtrData()
|
|
+ && (s->type == nsXPTType::T_FLOAT || s->type == nsXPTType::T_DOUBLE)) {
|
|
+ if (nr_fpr < FPR_COUNT)
|
|
+ nr_fpr++;
|
|
+ else
|
|
+ nr_stack++;
|
|
+ }
|
|
+ else {
|
|
+ if (nr_gpr < GPR_COUNT)
|
|
+ nr_gpr++;
|
|
+ else
|
|
+ nr_stack++;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+invoke_copy_to_stack(PRUint64 * d, PRUint32 paramCount, nsXPTCVariant * s,
|
|
+ PRUint64 * gpregs, double * fpregs)
|
|
+{
|
|
+ PRUint32 nr_gpr = 1; // skip one GP register for 'that'
|
|
+ PRUint32 nr_fpr = 0;
|
|
+ PRUint64 value;
|
|
+
|
|
+ for (uint32 i = 0; i < paramCount; i++, s++) {
|
|
+ if (s->IsPtrData())
|
|
+ value = (PRUint64) s->ptr;
|
|
+ else {
|
|
+ switch (s->type) {
|
|
+ case nsXPTType::T_FLOAT: break;
|
|
+ case nsXPTType::T_DOUBLE: break;
|
|
+ case nsXPTType::T_I8: value = s->val.i8; break;
|
|
+ case nsXPTType::T_I16: value = s->val.i16; break;
|
|
+ case nsXPTType::T_I32: value = s->val.i32; break;
|
|
+ case nsXPTType::T_I64: value = s->val.i64; break;
|
|
+ case nsXPTType::T_U8: value = s->val.u8; break;
|
|
+ case nsXPTType::T_U16: value = s->val.u16; break;
|
|
+ case nsXPTType::T_U32: value = s->val.u32; break;
|
|
+ case nsXPTType::T_U64: value = s->val.u64; break;
|
|
+ case nsXPTType::T_BOOL: value = s->val.b; break;
|
|
+ case nsXPTType::T_CHAR: value = s->val.c; break;
|
|
+ case nsXPTType::T_WCHAR: value = s->val.wc; break;
|
|
+ default: value = (PRUint64) s->val.p; break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) {
|
|
+ if (nr_fpr < FPR_COUNT)
|
|
+ fpregs[nr_fpr++] = s->val.d;
|
|
+ else {
|
|
+ *((double *)d) = s->val.d;
|
|
+ d++;
|
|
+ }
|
|
+ }
|
|
+ else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
|
|
+ if (nr_fpr < FPR_COUNT)
|
|
+ // The value in %xmm register is already prepared to
|
|
+ // be retrieved as a float. Therefore, we pass the
|
|
+ // value verbatim, as a double without conversion.
|
|
+ fpregs[nr_fpr++] = s->val.d;
|
|
+ else {
|
|
+ *((float *)d) = s->val.f;
|
|
+ d++;
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ if (nr_gpr < GPR_COUNT)
|
|
+ gpregs[nr_gpr++] = value;
|
|
+ else
|
|
+ *d++ = value;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+extern "C"
|
|
+XPTC_PUBLIC_API(nsresult)
|
|
+XPTC_InvokeByIndex(nsISupports * that, PRUint32 methodIndex,
|
|
+ PRUint32 paramCount, nsXPTCVariant * params)
|
|
+{
|
|
+ PRUint32 nr_gpr, nr_fpr, nr_stack;
|
|
+ invoke_count_words(paramCount, params, nr_gpr, nr_fpr, nr_stack);
|
|
+
|
|
+ // Stack, if used, must be 16-bytes aligned
|
|
+ if (nr_stack)
|
|
+ nr_stack = (nr_stack + 1) & ~1;
|
|
+
|
|
+ // Load parameters to stack, if necessary
|
|
+ PRUint64 *stack = (PRUint64 *) __builtin_alloca(nr_stack * 8);
|
|
+ PRUint64 gpregs[GPR_COUNT];
|
|
+ double fpregs[FPR_COUNT];
|
|
+ invoke_copy_to_stack(stack, paramCount, params, gpregs, fpregs);
|
|
+
|
|
+ // Load FPR registers from fpregs[]
|
|
+ register double d0 asm("xmm0");
|
|
+ register double d1 asm("xmm1");
|
|
+ register double d2 asm("xmm2");
|
|
+ register double d3 asm("xmm3");
|
|
+ register double d4 asm("xmm4");
|
|
+ register double d5 asm("xmm5");
|
|
+ register double d6 asm("xmm6");
|
|
+ register double d7 asm("xmm7");
|
|
+
|
|
+ switch (nr_fpr) {
|
|
+#define ARG_FPR(N) \
|
|
+ case N+1: d##N = fpregs[N];
|
|
+ ARG_FPR(7);
|
|
+ ARG_FPR(6);
|
|
+ ARG_FPR(5);
|
|
+ ARG_FPR(4);
|
|
+ ARG_FPR(3);
|
|
+ ARG_FPR(2);
|
|
+ ARG_FPR(1);
|
|
+ ARG_FPR(0);
|
|
+ case 0:;
|
|
+#undef ARG_FPR
|
|
+ }
|
|
+
|
|
+ // Load GPR registers from gpregs[]
|
|
+ register PRUint64 a0 asm("rdi");
|
|
+ register PRUint64 a1 asm("rsi");
|
|
+ register PRUint64 a2 asm("rdx");
|
|
+ register PRUint64 a3 asm("rcx");
|
|
+ register PRUint64 a4 asm("r8");
|
|
+ register PRUint64 a5 asm("r9");
|
|
+
|
|
+ switch (nr_gpr) {
|
|
+#define ARG_GPR(N) \
|
|
+ case N+1: a##N = gpregs[N];
|
|
+ ARG_GPR(5);
|
|
+ ARG_GPR(4);
|
|
+ ARG_GPR(3);
|
|
+ ARG_GPR(2);
|
|
+ ARG_GPR(1);
|
|
+ case 1: a0 = (PRUint64) that;
|
|
+ case 0:;
|
|
+#undef ARG_GPR
|
|
+ }
|
|
+
|
|
+ // Ensure that assignments to SSE registers won't be optimized away
|
|
+ asm("" ::
|
|
+ "x" (d0), "x" (d1), "x" (d2), "x" (d3),
|
|
+ "x" (d4), "x" (d5), "x" (d6), "x" (d7));
|
|
+
|
|
+ // Get pointer to method
|
|
+ PRUint64 methodAddress = *((PRUint64 *)that);
|
|
+ methodAddress += 8 * methodIndex;
|
|
+ methodAddress = *((PRUint64 *)methodAddress);
|
|
+
|
|
+ typedef PRUint32 (*Method)(PRUint64, PRUint64, PRUint64, PRUint64, PRUint64, PRUint64);
|
|
+ PRUint32 result = ((Method)methodAddress)(a0, a1, a2, a3, a4, a5);
|
|
+ return result;
|
|
+}
|