diff mbox series

[committed] Work around ft32 port issue

Message ID 3d8b7666-e64d-ea30-b00a-9587ec46959e@redhat.com
State New
Headers show
Series [committed] Work around ft32 port issue | expand

Commit Message

Jeff Law Oct. 15, 2018, 11:22 p.m. UTC
I sent mail to James about a month ago, but never heard back....  So...

This patch works around a problem in the ft32 port that shows up when
building newlib.

 The assembler was complaining about a line like this:

        ldi.b  $r1,_ctype_-0x800000+1($r0)

That's certainly an odd looking address computation.

It corresponds to this in the .final dump:



(insn 8 7 9 (set (reg:QI 3 $r1 [orig:53 *_3 ] [53])
        (mem:QI (plus:SI (reg/v:SI 2 $r0 [orig:49 c ] [49])
                (const:SI (plus:SI (symbol_ref:SI ("_ctype_") [flags
0x1040]  <var_decl 0x7ff18f27d090 _ctype_>)
                        (const_int 1 [0x1])))) [0 *_3+0 S1 A8])) "j.c":7
31 {*movqi}
     (expr_list:REG_EQUIV (mem:QI (plus:SI (reg/v:SI 2 $r0 [orig:49 c ]
[49])
                (const:SI (plus:SI (symbol_ref:SI ("_ctype_") [flags
0x1040]  <var_decl 0x7ff18f27d090 _ctype_>)
                        (const_int 1 [0x1])))) [0 *_3+0 S1 A8])
        (nil)))


Presumably the -0x8000000+1 is to deal with some oddity in the ft32
port, but there's no comments where this happens:

#define ASM_OUTPUT_SYMBOL_REF(stream, sym) \
  do { \
    assemble_name (stream, XSTR (sym, 0)); \
    int section_debug = in_section && \
      (SECTION_STYLE (in_section) == SECTION_NAMED) && \
      (in_section->named.common.flags & SECTION_DEBUG); \
    if (!section_debug && SYMBOL_REF_FLAGS (sym) & 0x1000) \
      asm_fprintf (stream, "-0x800000"); \
  } while (0)


Essentially it's some section encoding and ultimately I don't think it's
terribly important.  The assembler simply won't accept the insn in question.

Arguably it could/should, since it's really just a reg+disp address
where the disp isn't know until link time.  If I simplify the line to:

	ldi.b $r1,_ctype($r0)

The assembler still complains.  After a bit more poking around I think
we're just formatting the address totally wrong.

AFAICT the ft32 wants:

	ldi.b $r1,$r0,<constant part>

So it would seem that just fixing ft32_print_operand_address to emit it
in that format would be sufficient.  However, I'm not familiar enough
with this port to know if there are other contexts where it wants the
<constant>(register) style formatting.

Can you take a look and take appropriate action.

Testcase, compile with -O2.

extern const char _ctype_[];
int
tolower (int c)
{
  return
    (((((_ctype_) + sizeof (""[c]))[(int) (c)]) & (01 | 02)) == 01)
    ? (c) - 'A' + 'a' : c;
}


My patch is a hack, plain and simple.  It disables addressing modes such
as reg + sym +- const_int.  I doubt it matters in any significant way.
With the maintainer unresponsive, this patch seems like a reasonable
minimal effort workaround.

Jeff
commit 73262eafbf11463163d9cd805648ee2d704a677a
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Mon Oct 15 23:22:05 2018 +0000

            * config/ft32/ft32.md (ft32_general_movsrc_operand): Disable
            reg + sym +- const_int addressing modes.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@265179 138bc75d-0d04-0410-961f-82ee72b054a4
diff mbox series

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 789e43b2388..0f4e293d06f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@ 
+2018-10-12  Jeff Law  <law@redhat.com>
+
+	* config/ft32/ft32.md (ft32_general_movsrc_operand): Disable
+	reg + sym +- const_int addressing modes.
+
 2018-10-15  David Malcolm  <dmalcolm@redhat.com>
 
 	* common.opt (fdiagnostics-minimum-margin-width=): New option.
diff --git a/gcc/config/ft32/predicates.md b/gcc/config/ft32/predicates.md
index bac2e8ef5aa..0c147ec1aab 100644
--- a/gcc/config/ft32/predicates.md
+++ b/gcc/config/ft32/predicates.md
@@ -23,6 +23,11 @@ 
 ;; -------------------------------------------------------------------------
 
 ;; Nonzero if OP can be source of a simple move operation.
+;;
+;; The CONST_INT could really be CONST if we were to fix
+;; ft32_print_operand_address to format the address correctly.
+;; It might require assembler/linker work as well to ensure
+;; the right relocation is emitted.
 
 (define_predicate "ft32_general_movsrc_operand"
   (match_code "mem,const_int,reg,subreg,symbol_ref,label_ref,const")
@@ -34,7 +39,7 @@ 
   if (MEM_P (op)
       && GET_CODE (XEXP (op, 0)) == PLUS
       && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
-      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST)
+      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
     return 1;
 
   return general_operand (op, mode);