bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx      |    7 ++++++-
 bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx      |    3 ++-
 bridges/source/cpp_uno/gcc3_linux_x86-64/call.s       |   11 ++++++++---
 bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx  |   18 +++++++++++++-----
 bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.cxx     |    7 ++++++-
 bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.hxx     |    3 ++-
 bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx    |   12 +++++++++---
 bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx |   18 +++++++++++++-----
 testtools/com/sun/star/comp/bridge/TestComponent.java |    5 +++++
 testtools/source/bridgetest/bridgetest.cxx            |    6 ++++++
 testtools/source/bridgetest/cli/cli_cs_testobj.cs     |    2 ++
 testtools/source/bridgetest/cppobj.cxx                |    1 +
 testtools/source/bridgetest/idl/bridgetest.idl        |    6 ++++++
 13 files changed, 79 insertions(+), 20 deletions(-)

New commits:
commit d5a100f59467d94945656b54563e5ecdde2ca724
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Mon Aug 2 15:57:32 2021 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Mon Aug 2 18:21:30 2021 +0200

    tdf#143450: Special integre+fp struct return case needs a fix too, of course
    
    ...similar to ca344be7aabf88dddde38841e6af6292ece6829b "tdf#143450: Fix 
special
    fp+integer struct return case for gcc_*_x86-64"
    
    Change-Id: Ia8110d632a1c5f328822c434efc5b09bd53ec9e8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119883
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx 
b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
index f36678ed3695..243e42d057e8 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
@@ -269,7 +269,12 @@ x86_64::ReturnKind 
x86_64::getReturnKind(typelib_TypeDescriptionReference * type
     if (n == 2 && (classes[0] == X86_64_SSE_CLASS || classes[0] == 
X86_64_SSESF_CLASS)
         && (classes[1] == X86_64_INTEGER_CLASS || classes[1] == 
X86_64_INTEGERSI_CLASS))
     {
-        return ReturnKind::RegistersSpecial;
+        return ReturnKind::RegistersFpInt;
+    }
+    if (n == 2 && (classes[0] == X86_64_INTEGER_CLASS || classes[0] == 
X86_64_INTEGERSI_CLASS)
+        && (classes[1] == X86_64_SSE_CLASS || classes[1] == 
X86_64_SSESF_CLASS))
+    {
+        return ReturnKind::RegistersIntFp;
     }
     return ReturnKind::RegistersGeneral;
 }
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx 
b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
index db1ed75aa243..3ef80543ac76 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
@@ -54,7 +54,8 @@ bool return_in_hidden_param( typelib_TypeDescriptionReference 
*pTypeRef ) noexce
 enum class ReturnKind {
     Memory,
     RegistersGeneral,
-    RegistersSpecial
+    RegistersFpInt,
+    RegistersIntFp
 };
 
 ReturnKind getReturnKind(typelib_TypeDescriptionReference * type) noexcept;
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s 
b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
index ee8403ab7180..53bfea8b254f 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
@@ -55,17 +55,22 @@ privateSnippetExecutor:
        
        call    cpp_vtable_call
 
-       cmp     $1, %rax
-       je      .Lspecial
+       testl   %eax, %eax
+       je      .Lfpint
+       jg      .Lintfp
 
        movq    -144(%rbp), %rax                # Potential return value 
(general case)
        movq    -136(%rbp), %rdx                # Potential return value 
(general case)
        movq    -144(%rbp), %xmm0               # Potential return value 
(general case)
        movq    -136(%rbp), %xmm1               # Potential return value 
(general case)
        jmp     .Lfinish
-.Lspecial:
+.Lfpint:
        movq    -144(%rbp), %xmm0               # Return value (special fp and 
integer case)
        movq    -136(%rbp), %rax                # Return value (special fp and 
integer case)
+       jmp     .Lfinish
+.Lintfp:
+       movq    -144(%rbp), %rax                # Return value (special integer 
and fp case)
+       movq    -136(%rbp), %xmm0               # Return value (special integer 
and fp case)
 
 .Lfinish:
        leave
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx 
b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
index 4bf5061a472f..de393582f99a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
@@ -246,16 +246,24 @@ static int cpp2uno_call(
         {
             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
         }
-        return returnKind == x86_64::ReturnKind::RegistersSpecial ? 1 : 0;
+        switch (returnKind) {
+        case x86_64::ReturnKind::RegistersFpInt:
+            return 0;
+        case x86_64::ReturnKind::RegistersIntFp:
+            return 1;
+        default:
+            return -1;
+        }
     }
 }
 
-// Returns 0 for the general case where potential return values from 
privateSnippetExecutor can be
+// Returns -1 for the general case where potential return values from 
privateSnippetExecutor can be
 // copied from pRegisterReturn to both %rax and %rdx (in that order) and to 
%xmm0 and %xmm1 (in that
 // order)---each specific return type will only require a subset of that copy 
operations, but the
-// other copies to those non--callee-saved registers will be redundant and 
harmless.  And returns 1
-// for the special case where return values from privateSnippetExecutor must 
be copied from
-// pRegisterReturn to %xmm0 and %rax (in that order).
+// other copies to those non--callee-saved registers will be redundant and 
harmless.  Returns 0 for
+// the special case where return values from privateSnippetExecutor must be 
copied from
+// pRegisterReturn to %xmm0 and %rax (in that order).  Returns 1 for the 
special case where return
+// privateSnippetExecutor must be copied from pRegisterReturn to %rax and 
%xmm0 (in that order).
 int cpp_vtable_call(
     sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     void ** gpreg, void ** fpreg, void ** ovrflw,
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.cxx 
b/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.cxx
index 355a0a7500d7..8f6ca30957ed 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.cxx
@@ -268,7 +268,12 @@ x86_64::ReturnKind 
x86_64::getReturnKind(typelib_TypeDescriptionReference * type
     if (n == 2 && (classes[0] == X86_64_SSE_CLASS || classes[0] == 
X86_64_SSESF_CLASS)
         && (classes[1] == X86_64_INTEGER_CLASS || classes[1] == 
X86_64_INTEGERSI_CLASS))
     {
-        return ReturnKind::RegistersSpecial;
+        return ReturnKind::RegistersFpInt;
+    }
+    if (n == 2 && (classes[0] == X86_64_INTEGER_CLASS || classes[0] == 
X86_64_INTEGERSI_CLASS)
+        && (classes[1] == X86_64_SSE_CLASS || classes[1] == 
X86_64_SSESF_CLASS))
+    {
+        return ReturnKind::RegistersIntFp;
     }
     return ReturnKind::RegistersGeneral;
 }
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.hxx 
b/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.hxx
index db1ed75aa243..3ef80543ac76 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/abi.hxx
@@ -54,7 +54,8 @@ bool return_in_hidden_param( typelib_TypeDescriptionReference 
*pTypeRef ) noexce
 enum class ReturnKind {
     Memory,
     RegistersGeneral,
-    RegistersSpecial
+    RegistersFpInt,
+    RegistersIntFp
 };
 
 ReturnKind getReturnKind(typelib_TypeDescriptionReference * type) noexcept;
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx 
b/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
index a0654104012d..2c7332a16a2b 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
@@ -55,8 +55,9 @@ void privateSnippetExecutor()
 
          "    call  _cpp_vtable_call\n"
 
-         "    cmp   $1, %rax\n"
-         "    je    .Lspecial\n"
+         "    testl  %eax, %eax\n"
+         "    je    .Lfpint\n"
+         "    jg    .Lintfp\n"
 
          "    movq  -144(%rbp), %rax        # Potential return value (general 
case)\n"
          "    movq  -136(%rbp), %rdx        # Potential return value (general 
case)\n"
@@ -64,9 +65,14 @@ void privateSnippetExecutor()
          "    movq  -136(%rbp), %xmm1       # Potential return value (general 
case)\n"
          "    jmp   .Lfinish\n"
 
-         ".Lspecial:\n"
+         ".Lfpint:\n"
          "    movq  -144(%rbp), %xmm0       # Return value (special fp and 
integer case)\n"
          "    movq  -136(%rbp), %rax        # Return value (special fp and 
integer case)\n"
+         "    jmp   .Lfinish\n"
+
+         ".Lintfp:\n"
+         "    movq  -144(%rbp), %rax        # Return value (special integer 
and fp case)\n"
+         "    movq  -136(%rbp), %xmm0       # Return value (special integer 
and fp case)\n"
 
          ".Lfinish:\n"
          "    addq  $160, %rsp\n"
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx 
b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
index 4a150ef81a9a..efdf211d8a6e 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
@@ -248,16 +248,24 @@ static int cpp2uno_call(
         {
             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
         }
-        return returnKind == x86_64::ReturnKind::RegistersSpecial ? 1 : 0;
+        switch (returnKind) {
+        case x86_64::ReturnKind::RegistersFpInt:
+            return 0;
+        case x86_64::ReturnKind::RegistersIntFp:
+            return 1;
+        default:
+            return -1;
+        }
     }
 }
 
-// Returns 0 for the general case where potential return values from 
privateSnippetExecutor can be
+// Returns -1 for the general case where potential return values from 
privateSnippetExecutor can be
 // copied from pRegisterReturn to both %rax and %rdx (in that order) and to 
%xmm0 and %xmm1 (in that
 // order)---each specific return type will only require a subset of that copy 
operations, but the
-// other copies to those non--callee-saved registers will be redundant and 
harmless.  And returns 1
-// for the special case where return values from privateSnippetExecutor must 
be copied from
-// pRegisterReturn to %xmm0 and %rax (in that order).
+// other copies to those non--callee-saved registers will be redundant and 
harmless.  Returns 0 for
+// the special case where return values from privateSnippetExecutor must be 
copied from
+// pRegisterReturn to %xmm0 and %rax (in that order).  Returns 1 for the 
special case where return
+// privateSnippetExecutor must be copied from pRegisterReturn to %rax and 
%xmm0 (in that order).
 int cpp_vtable_call(
     sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     void ** gpreg, void ** fpreg, void ** ovrflw,
diff --git a/testtools/com/sun/star/comp/bridge/TestComponent.java 
b/testtools/com/sun/star/comp/bridge/TestComponent.java
index e5cb2c49a907..dcc835125219 100644
--- a/testtools/com/sun/star/comp/bridge/TestComponent.java
+++ b/testtools/com/sun/star/comp/bridge/TestComponent.java
@@ -42,6 +42,7 @@ import test.testtools.bridgetest.TwoFloats;
 import test.testtools.bridgetest.FourFloats;
 import test.testtools.bridgetest.MixedFloatAndInteger;
 import test.testtools.bridgetest.DoubleHyper;
+import test.testtools.bridgetest.HyperDouble;
 import test.testtools.bridgetest.FloatFloatLongByte;
 import test.testtools.bridgetest.ThreeByteStruct;
 import test.testtools.bridgetest.XBridgeTest;
@@ -510,6 +511,10 @@ public class TestComponent {
             return s;
         }
 
+        public HyperDouble echoHyperDouble(HyperDouble s) throws 
com.sun.star.uno.RuntimeException {
+            return s;
+        }
+
         public FloatFloatLongByte echoFloatFloatLongByte(FloatFloatLongByte s)
             throws com.sun.star.uno.RuntimeException
         {
diff --git a/testtools/source/bridgetest/bridgetest.cxx 
b/testtools/source/bridgetest/bridgetest.cxx
index 2d3de2aca07f..6228d9423411 100644
--- a/testtools/source/bridgetest/bridgetest.cxx
+++ b/testtools/source/bridgetest/bridgetest.cxx
@@ -490,6 +490,12 @@ static bool performTest(
             bRet &= check(out.a == in.a, "double and hyper struct test: 
double")
                 && check(out.b == in.b, "double and hyper struct test: hyper");
         }
+        {
+            HyperDouble in(12, 13.0);
+            HyperDouble out = xLBT->echoHyperDouble(in);
+            bRet &= check(out.a == in.a, "hyper and double struct test: hyper")
+                && check(out.b == in.b, "hyper and double struct test: 
double");
+        }
         {
             FloatFloatLongByte in(20.0f, 21.0f, 22, '3');
             FloatFloatLongByte out = xLBT->echoFloatFloatLongByte(in);
diff --git a/testtools/source/bridgetest/cli/cli_cs_testobj.cs 
b/testtools/source/bridgetest/cli/cli_cs_testobj.cs
index fb4148cc2a68..8d209ec44f01 100644
--- a/testtools/source/bridgetest/cli/cli_cs_testobj.cs
+++ b/testtools/source/bridgetest/cli/cli_cs_testobj.cs
@@ -261,6 +261,8 @@ public class BridgeTestObject : WeakBase, XRecursiveCall, 
XBridgeTest2
 
     public DoubleHyper echoDoubleHyper(Mix s) { return s; }
 
+    public HyperDouble echoHyperDouble(Mix s) { return s; }
+
     public FloatFloatLongByte echoFloatFloatLongByte(Mix s) { return s; }
 
     public ThreeByteStruct echoThreeByteStruct(/*[in]*/ThreeByteStruct arg)
diff --git a/testtools/source/bridgetest/cppobj.cxx 
b/testtools/source/bridgetest/cppobj.cxx
index 27b06ea7f0ad..e4666c4d22a3 100644
--- a/testtools/source/bridgetest/cppobj.cxx
+++ b/testtools/source/bridgetest/cppobj.cxx
@@ -246,6 +246,7 @@ public:
     virtual MixedFloatAndInteger SAL_CALL echoMixedFloatAndInteger(const 
MixedFloatAndInteger& rStruct) override
         { return rStruct; }
     virtual DoubleHyper SAL_CALL echoDoubleHyper(DoubleHyper const & s) 
override { return s; }
+    virtual HyperDouble SAL_CALL echoHyperDouble(HyperDouble const & s) 
override { return s; }
     virtual FloatFloatLongByte SAL_CALL 
echoFloatFloatLongByte(FloatFloatLongByte const & s)
         override
     { return s; }
diff --git a/testtools/source/bridgetest/idl/bridgetest.idl 
b/testtools/source/bridgetest/idl/bridgetest.idl
index d9732edde7a8..82d63c37e9e3 100644
--- a/testtools/source/bridgetest/idl/bridgetest.idl
+++ b/testtools/source/bridgetest/idl/bridgetest.idl
@@ -126,6 +126,10 @@ struct DoubleHyper {
     double a;
     hyper b;
 };
+struct HyperDouble {
+    hyper a;
+    double b;
+};
 struct FloatFloatLongByte {
     float a;
     float b;
@@ -340,6 +344,8 @@ interface XBridgeTestBase : com::sun::star::uno::XInterface
 
     DoubleHyper echoDoubleHyper([in] DoubleHyper s);
 
+    HyperDouble echoHyperDouble([in] HyperDouble s);
+
     FloatFloatLongByte echoFloatFloatLongByte([in] FloatFloatLongByte s);
 
     /**

Reply via email to