Author: dcoakley
Date: 2011-06-17 15:59:39 -0400 (Fri, 17 Jun 2011)
New Revision: 3652

Modified:
   trunk/osprey/common/com/x8664/targ_sim.cxx
   trunk/osprey/common/com/x8664/targ_sim.h
   trunk/osprey/wgen/wgen_expr.cxx
Log:
Fix handling of complex values for x86 targets to follow the ABI.

A complex long double field is now returned in the register pair
(%st0, %st1) as specified by the AMD64 ABI.

Approved by: Jian-Xin Lai


Modified: trunk/osprey/common/com/x8664/targ_sim.cxx
===================================================================
--- trunk/osprey/common/com/x8664/targ_sim.cxx  2011-06-17 19:45:27 UTC (rev 
3651)
+++ trunk/osprey/common/com/x8664/targ_sim.cxx  2011-06-17 19:59:39 UTC (rev 
3652)
@@ -178,9 +178,12 @@
   if (class1 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGER_CLASS)
     return X86_64_INTEGER_CLASS;
 
-  /* rule 5: if one of the classes is X87 or X87UP, result is MEMORY */
+  /* rule 5: if one of the classes is X87, X87UP, or COMPLEX_X87 class,
+     result is MEMORY */
   if (class1 == X86_64_X87_CLASS || class2 == X86_64_X87_CLASS ||
-      class1 == X86_64_X87UP_CLASS || class2 == X86_64_X87UP_CLASS)
+      class1 == X86_64_X87UP_CLASS || class2 == X86_64_X87UP_CLASS ||
+      class1 == X86_64_COMPLEX_X87_CLASS ||
+      class2 == X86_64_COMPLEX_X87_CLASS)
     return X86_64_MEMORY_CLASS;
   
   /* rule 6: otherwise, SSE class */
@@ -258,10 +261,13 @@
     case MTYPE_F8:
       classes[0] = X86_64_SSE_CLASS;
       return 1;
-    case MTYPE_C10:
     case MTYPE_F10:
       classes[0] = X86_64_X87_CLASS;
-      return 0;
+      classes[1] = X86_64_X87UP_CLASS;
+      return 2;
+    case MTYPE_C10:
+      classes[0] = X86_64_COMPLEX_X87_CLASS;
+      return 1;
     case MTYPE_C4:
       classes[0] = X86_64_SSE_CLASS;
       return 1;
@@ -577,9 +583,7 @@
         info.mtype [0] = mtype;
         info.preg  [0] = PR_first_reg(SIM_INFO.flt_results);
       }
-
       else {
-
         info.count     = 2;
         info.mtype [0] = Mtype_complex_to_real(mtype);
         info.mtype [1] = Mtype_complex_to_real(mtype);
@@ -600,9 +604,7 @@
         info.mtype [0] = mtype;
         info.preg  [0] = First_X87_Preg_Return_Offset;
       }
-
       else {
-
         info.count     = 2;
         info.mtype [0] = Mtype_complex_to_real(mtype);
         info.mtype [1] = Mtype_complex_to_real(mtype);
@@ -645,30 +647,56 @@
               info.return_via_first_arg = FALSE;
               info.count = n;
 
-             if (classes[0] == X86_64_SSE_CLASS) {
-               info.mtype[0] = SIM_INFO.dbl_type;
-               info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
-               next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
-               next_int_return_num = PR_first_reg(SIM_INFO.int_results);
+             if (classes[0] == X86_64_X87_CLASS) {
+                  info.count = 1;
+                  info.mtype[0] = MTYPE_F10;
+                  info.preg[0]  = First_X87_Preg_Return_Offset;
+              }
+              else if (classes[0] == X86_64_COMPLEX_X87_CLASS) {
+                  if (Is_Target_32bit()) {
+                    info.count = 0;
+                    info.return_via_first_arg = TRUE;
+                  }
+                  else if (level == Use_Simulated) {
+            
+                    info.count     = 1;
+                    info.mtype [0] = MTYPE_C10;
+                    info.preg  [0] = First_X87_Preg_Return_Offset;
+                  }
+                  else {
+                    info.count     = 2;
+                    info.mtype [0] = Mtype_complex_to_real(MTYPE_C10);
+                    info.mtype [1] = Mtype_complex_to_real(MTYPE_C10);
+                    info.preg  [0] = First_X87_Preg_Return_Offset;
+                    info.preg  [1] = Last_X87_Preg_Return_Offset;
+                  }
+              } 
+              else {
+                if (classes[0] == X86_64_SSE_CLASS) {
+                 info.mtype[0] = SIM_INFO.dbl_type;
+                 info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
+                 next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
+                 next_int_return_num = PR_first_reg(SIM_INFO.int_results);
+               }
+               else {
+                 info.mtype[0] = SIM_INFO.int_type;
+                 info.preg[0] = PR_first_reg(SIM_INFO.int_results);
+                 next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
+                 next_int_return_num = PR_last_reg(SIM_INFO.int_results);
+               }
+  
+               if (n > 1) {
+                 if (classes[1] == X86_64_SSE_CLASS) {
+                   info.mtype[1] = SIM_INFO.dbl_type;
+                   info.preg[1] = next_float_return_num;
+                 }
+                 else {
+                   info.mtype[1] = SIM_INFO.int_type;
+                   info.preg[1] = next_int_return_num;
+                 }
+               }
              }
-             else {
-               info.mtype[0] = SIM_INFO.int_type;
-               info.preg[0] = PR_first_reg(SIM_INFO.int_results);
-               next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
-               next_int_return_num = PR_last_reg(SIM_INFO.int_results);
-             }
-
-             if (n > 1) {
-               if (classes[1] == X86_64_SSE_CLASS) {
-                 info.mtype[1] = SIM_INFO.dbl_type;
-                 info.preg[1] = next_float_return_num;
-               }
-               else {
-                 info.mtype[1] = SIM_INFO.int_type;
-                 info.preg[1] = next_int_return_num;
-               }
-             }
-            }
+           }
         }
       }
       break;
@@ -941,6 +969,13 @@
          INT Save_Current_Float_Param_Num = Current_Float_Param_Num;
           ploc.size = TY_size (ty);
          INT n = Classify_Aggregate(ty, classes);
+          // handle X87 X87UP and COMPLEX_X87 cases
+          if (n != 0 && (classes[0] == X86_64_X87_CLASS ||
+                         classes[0] == X86_64_X87UP_CLASS ||
+                         classes[0] == X86_64_COMPLEX_X87_CLASS)) {
+             // x87, x87up and complex_x87 are passed in memory
+             n = 0;
+          }
          if (n > 0) { // passed in registers
            if (classes[0] == X86_64_SSE_CLASS) {
              ++Current_Float_Param_Num;

Modified: trunk/osprey/common/com/x8664/targ_sim.h
===================================================================
--- trunk/osprey/common/com/x8664/targ_sim.h    2011-06-17 19:45:27 UTC (rev 
3651)
+++ trunk/osprey/common/com/x8664/targ_sim.h    2011-06-17 19:59:39 UTC (rev 
3652)
@@ -110,6 +110,7 @@
     X86_64_X87_CLASS,
     X86_64_X87UP_CLASS,
     X86_64_SSEUP_CLASS,
+    X86_64_COMPLEX_X87_CLASS
 };
 
 #define MAX_CLASSES 4

Modified: trunk/osprey/wgen/wgen_expr.cxx
===================================================================
--- trunk/osprey/wgen/wgen_expr.cxx     2011-06-17 19:45:27 UTC (rev 3651)
+++ trunk/osprey/wgen/wgen_expr.cxx     2011-06-17 19:59:39 UTC (rev 3652)
@@ -10144,6 +10144,13 @@
          else {
            enum X86_64_PARM_CLASS classes[MAX_CLASSES];
            INT n = Classify_Aggregate(ty_idx, classes);
+            // handle X87 X87UP and COMPLEX_X87 cases
+            if (n != 0 && (classes[0] == X86_64_X87_CLASS ||
+                           classes[0] == X86_64_X87UP_CLASS ||
+                           classes[0] == X86_64_COMPLEX_X87_CLASS)) {
+               // x87, x87up and complex_x87 are passed in memory
+               n = 0;
+            }
            if (n == 0) { /* can only pass in memory */
              /* increment overflow_arg_area pointer by 8 */
              INT delta = ((TY_size(ty_idx) + 7) / 8) * 8;


------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to