[PATCH 1/9] Gccgo port to s390[x] -- part I

Lynn A. Boger laboger@linux.vnet.ibm.com
Wed Sep 24 18:24:00 GMT 2014


[PATCH 1/9] Gccgo port to s390[x] is a fix for BZ 60406.  When building 
with this patch on ppc64 LE, the failing testcase from the BZ is fixed 
and there are no new failures; however when building with this patch on 
ppc64 BE there are over 20 new failures in the go and libgo testsuites.

I modified the patch for statements.cc and rebuilt and that eliminates 
the regressions and fixes the original problem it was intended to fix 
for both ppc64 BE & LE.  The ABIs are different between BE & LE, so that 
make_func_code_reference on ppc64 BE is not returning the function's 
code address but the function pointer from the .opd.  The first 8 bytes 
of the entry in the .opd is the function's code address.  Here is the 
change to statements.cc that made it work:

-- statements.cc       (revision 215466)
+++ statements.cc       (working copy)
@@ -2355,25 +2355,25 @@
    gogo->start_block(location);

    // For a defer statement, start with a call to
-  // __go_set_defer_retaddr.  */
-  Label* retaddr_label = NULL;
+  // __go_set_defering_fn.  */
    if (may_call_recover)
      {
-      retaddr_label = gogo->add_label_reference("retaddr", location, 
false);
-      Expression* arg = Expression::make_label_addr(retaddr_label, 
location);
-      Expression* call = Runtime::make_call(Runtime::SET_DEFER_RETADDR,
-                                           location, 1, arg);
-
-      // This is a hack to prevent the middle-end from deleting the
-      // label.
-      gogo->start_block(location);
- gogo->add_statement(Statement::make_goto_statement(retaddr_label,
-                                                        location));
-      Block* then_block = gogo->finish_block(location);
-      then_block->determine_types();
-
-      Statement* s = Statement::make_if_statement(call, then_block, NULL,
-                                                 location);
+#if defined(__powerpc64__) && _CALL_ELF != 2
+      Expression* pfn =
+        Expression::make_func_code_reference(function, location);
+      Type* pfntype =
+          Type::make_pointer_type(
+              Type::make_pointer_type(Type::make_void_type()));
+      Expression* fn = Expression::make_unsafe_cast(pfntype, pfn, 
location);
+      Expression* fn_code_addr = Expression::make_unary(OPERATOR_MULT, fn,
+                                                        location);
+#else
+      Expression* fn_code_addr =
+        Expression::make_func_code_reference(function, location);
+#endif
+      Expression* call = Runtime::make_call(Runtime::SET_DEFERING_FN,
+                                            location, 1, fn_code_addr);
+      Statement* s = Statement::make_statement(call, true);
        s->determine_types();
        gogo->add_statement(s);
      }
@@ -2477,12 +2477,8 @@

    gogo->add_statement(call_statement);

-  // If this is a defer statement, the label comes immediately after
-  // the call.
    if (may_call_recover)
      {
-      gogo->add_label_definition("retaddr", location);
-
        Expression_list* vals = new Expression_list();
        vals->push_back(Expression::make_boolean(false, location));
        gogo->add_statement(Statement::make_return_statement(vals, 
location));



More information about the Gcc-patches mailing list