From 2fe076f06f988de188f77589cbd690ac4db1be33 Mon Sep 17 00:00:00 2001 From: Dan HorĂ¡k Date: Wed, 3 Feb 2021 12:07:56 +0100 Subject: Fix parameter passing on ppc64le (mozb#1690152) --- mozilla-1690152.patch | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 mozilla-1690152.patch (limited to 'mozilla-1690152.patch') diff --git a/mozilla-1690152.patch b/mozilla-1690152.patch new file mode 100644 index 0000000..fb672d3 --- /dev/null +++ b/mozilla-1690152.patch @@ -0,0 +1,97 @@ + +# HG changeset patch +# User Cameron Kaiser +# Date 1612231460 0 +# Node ID 579a66fd796690fb752485215b2edaa6167ebf16 +# Parent a00504e040bfd34d01c74d478beb9d308ec085be +Bug 1690152 - on ppc64 properly skip parameter slots if we overflow GPRs while still having FPRs to burn. r=tcampbell + +Differential Revision: https://phabricator.services.mozilla.com/D103724 + +diff --git a/xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc64_linux.cpp b/xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc64_linux.cpp +--- a/xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc64_linux.cpp ++++ b/xpcom/reflect/xptcall/md/unix/xptcinvoke_ppc64_linux.cpp +@@ -86,27 +86,37 @@ extern "C" void invoke_copy_to_stack(uin + case nsXPTType::T_WCHAR: value = s->val.wc; break; + default: value = (uint64_t) s->val.p; break; + } + } + + if (!s->IsIndirect() && s->type == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) { + fpregs[nr_fpr++] = s->val.d; +- nr_gpr++; ++ // Even if we have enough FPRs, still skip space in ++ // the parameter area if we ran out of placeholder GPRs. ++ if (nr_gpr < GPR_COUNT) { ++ nr_gpr++; ++ } else { ++ d++; ++ } + } else { + *((double *)d) = s->val.d; + d++; + } + } + else if (!s->IsIndirect() && s->type == nsXPTType::T_FLOAT) { + if (nr_fpr < FPR_COUNT) { + // Single-precision floats are passed in FPRs too. + fpregs[nr_fpr++] = s->val.f; +- nr_gpr++; ++ if (nr_gpr < GPR_COUNT) { ++ nr_gpr++; ++ } else { ++ d++; ++ } + } else { + #ifdef __LITTLE_ENDIAN__ + *((float *)d) = s->val.f; + #else + // Big endian needs adjustment to point to the least + // significant word. + float* p = (float*)d; + p++; +diff --git a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp +--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp ++++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp +@@ -98,27 +98,37 @@ PrepareAndDispatch(nsXPTCStubBase * self + nr_gpr++; + else + ap++; + } + + if (!param.IsOut() && type == nsXPTType::T_DOUBLE) { + if (nr_fpr < FPR_COUNT) { + dp->val.d = fpregs[nr_fpr++]; +- nr_gpr++; ++ // Even if we have enough FPRs, still skip space in ++ // the parameter area if we ran out of placeholder GPRs. ++ if (nr_gpr < GPR_COUNT) { ++ nr_gpr++; ++ } else { ++ ap++; ++ } + } else { + dp->val.d = *(double*)ap++; + } + continue; + } + if (!param.IsOut() && type == nsXPTType::T_FLOAT) { + if (nr_fpr < FPR_COUNT) { + // Single-precision floats are passed in FPRs too. + dp->val.f = (float)fpregs[nr_fpr++]; +- nr_gpr++; ++ if (nr_gpr < GPR_COUNT) { ++ nr_gpr++; ++ } else { ++ ap++; ++ } + } else { + #ifdef __LITTLE_ENDIAN__ + dp->val.f = *(float*)ap++; + #else + // Big endian needs adjustment to point to the least + // significant word. + float* p = (float*)ap; + p++; + -- cgit