[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));