On Tue, May 7, 2013 at 4:41 AM, DJ Delorie wrote:
> Index: gcc/cfgexpand.c
> ===================================================================
> --- gcc/cfgexpand.c     (revision 198591)
> +++ gcc/cfgexpand.c     (working copy)
> @@ -3090,13 +3090,14 @@ expand_debug_expr (tree exp)
>          size_t, we need to check for mis-matched modes and correct
>          the addend.  */
>        if (op0 && op1
>           && GET_MODE (op0) != VOIDmode && GET_MODE (op1) != VOIDmode
>           && GET_MODE (op0) != GET_MODE (op1))
>         {
> -         if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE 
> (op1)))
> +         /* Don't try to sign-extend SImode to PSImode, for example.  */
> +         if (GET_MODE_BITSIZE (GET_MODE (op0)) <= GET_MODE_BITSIZE (GET_MODE 
> (op1)))
>             op1 = simplify_gen_unary (TRUNCATE, GET_MODE (op0), op1,
>                                       GET_MODE (op1));
>           else
>             /* We always sign-extend, regardless of the signedness of
>                the operand, because the operand is always unsigned
>                here even if the original C expression is signed.  */

Can't you do just nothing if
GET_MODE_BITSIZE (GET_MODE (op0)) == GET_MODE_BITSIZE (GET_MODE (op1))?



> Index: gcc/simplify-rtx.c
> ===================================================================
> --- gcc/simplify-rtx.c  (revision 198591)
> +++ gcc/simplify-rtx.c  (working copy)
> @@ -5787,12 +5787,19 @@ simplify_immed_subreg (enum machine_mode
>  /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
>     Return 0 if no simplifications are possible.  */
>  rtx
>  simplify_subreg (enum machine_mode outermode, rtx op,
>                  enum machine_mode innermode, unsigned int byte)
>  {
> +  /* FIXME: hack to allow building of newlib/libc.a for msp430/430x/large 
> multilib.
> +     The problem is the var-tracking is generating paradoxical SUBREGs.  Not 
> sure why...  */
> +  if (!(GET_MODE (op) == innermode
> +        || GET_MODE (op) == VOIDmode)
> +      || (innermode == VOIDmode)
> +      )
> +    return NULL_RTX;

IMHO this is not OK, at least not so until the "why" is clarified.
Perhaps Alexandre can have a look, he's with RedHat too isn't he? ;-)



> +   (UNS_PROLOGUE_START_MARKER 0)
> +   (UNS_PROLOGUE_END_MARKER 1)
> +   (UNS_EPILOGUE_START_MARKER 2)
> +   (UNS_EPILOGUE_HELPER 3)
> +
> +   (UNS_PUSHM 4)
> +   (UNS_POPM 5)
> +
> +   (UNS_GROW_AND_SWAP 6)
> +   (UNS_SWAP_AND_SHRINK 7)

For UNSPECs and UNSPECVs you should use define_c_enum:

(define_c_enum "unspec" [
  UNS_PROLOGUE_START_MARKER
  UNS_PROLOGUE_END_MARKER
  UNS_EPILOGUE_START_MARKER
  UNS_EPILOGUE_HELPER
...
])

(define_c_enum "unspecv" [
...
])



> +;; This is nasty.  Operand0 is bogus.  It is only there so that we can get a
> +;; mode for the %B0 to work.  We should use operand1 for this, but that does
> +;; not have a mode.
> +;;
> +;; Operand1 is actually a register, but we cannot accept (REG...) because the
> +;; cprop_hardreg pass can and will renumber registers even inside
> +;; unspec_volatiles.  So we take an integer register number parameter and
> +;; fudge it to be a register name when we generate the assembler.  We use %I
> +;; because that is the only operator that will omit the # prefix to an
> +;; integer value.  Unfortunately it also inverts the integer value, so we
> +;; have pre-invert it when generating this insn.  (We could of course add a
> +;; new operator, eg %D, just for this pattern...)
> +;;
> +;; The pushm pattern does not have this problem because of all of the
> +;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
> +(define_insn "popm"
> +  [(unspec_volatile [(match_operand 0 "register_operand" "r")
> +                    (match_operand 1 "immediate_operand" "i")
> +                    (match_operand 2 "immediate_operand" "i")] UNS_POPM)]
> +  ""
> +  "POPM%B0\t%2, r%I1"
> +  )

I don't understand what the problem is here. If the register is
modified by the post-reload passes, apparently there is a side-effect
in this insn that isn't modeled properly, and the pattern hacks around
the real problem. Is it an auto-inc-dec thing? Is it a SET? Something
CLOBBERED?


> +(define_expand "movsi"
> +  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
> +       (match_operand:SI 1 "general_operand" "rmi"))]
> +  ""
> +  ""
> +  )

What is the define_expand for?
If you need it for some reason, you should remove the constraints,
they have no meaning on a define_expand.


> +(define_insn_and_split "movsi_x"
> +  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
> +       (match_operand:SI 1 "general_operand" "rmi"))]
> +  ""
> +  "#"
> +  "reload_completed"
> +  [(set (match_operand:HI 2 "nonimmediate_operand")
> +       (match_operand:HI 4 "general_operand"))
> +   (set (match_operand:HI 3 "nonimmediate_operand")
> +       (match_operand:HI 5 "general_operand"))]
> +  "msp430_split_movsi (operands);"
> +)

> +;; This is weird. GCC testcase execute/20020615-1 compiled at -Os
> +;; results in reload producing:
> +;;    (set:HI r14) (mem:HI (plus (r14) (const_int 4)))
> +;;    (set:HI r15) (mem:HI (plus (r14) (const_int 6)))
> +;; With the first insn corrupting r14 before it is used by the second
> +;; insn.  This should not be happening.  Reload is generating a:
> +;;   (set:SI r14) (mem:SI (plus:PSI (r14) (const_int 4)))
> +;; which is somehow being converted into the two movhi instructions
> +;; above *without* going through the movsi splitter.   I have no
> +;; idea how this happens.  Any the peephole below is to catch this
> +;; case and reverse the order of the instructions.
> +
> +(define_peephole2
> +  [(set (match_operand:HI 0 "register_operand")
> +       (mem:HI (plus:PSI (match_operand:PSI 1 "register_operand")
> +                         (match_operand 2 "immediate_operand"))))
> +   (set (match_operand:HI 3 "register_operand")
> +       (mem:HI (plus:PSI (match_operand:PSI 4 "register_operand")
> +                         (match_operand 5 "immediate_operand"))))]
> +  "   REGNO (operands[0]) == REGNO (operands[4])
> +   && REGNO (operands[3]) == REGNO (operands[0]) + 1
> +   && REGNO (operands[0]) == REGNO (operands[1])
> +   && INTVAL (operands[2]) == INTVAL (operands[5]) - 2"
> +  [(set (match_dup 3) (mem:HI (plus:PSI (match_dup 4) (match_dup 5))))
> +   (set (match_dup 0) (mem:HI (plus:PSI (match_dup 1) (match_dup 2))))]
> +)

Another hack around a real problem, and a potential source of wrong
code. Not OK IMHO.




> +; NOTE - we are playing a dangerous game with GCC here.  We have these two
> +; add patterns and the splitter that follows because our tests have shown
> +; that this results in a significant reduction in code size - because GCC is
> +; able to discard any unused part of the addition.  We have to annotate the
> +; patterns with the set and use of the carry flag because otherwise GCC will
> +; discard parts of the addition when they are actually needed.  But we have
> +; not annotated all the other patterns that set the CARRY flag as doing so
> +; results in an overall increase in code size[1].  Instead we just *hope*
> +; that GCC will not move a carry-setting instruction in between the first
> +; and second adds.

Scary stuff... :-)


> +;; FIXME: GCC currently (8/feb/2013) cannot handle symbol_refs
> +;; in indirect jumps (cf gcc.c-torture/compile/991213-3.c).
> +(define_insn "indirect_jump"
> +  [(set (pc)
> +       (match_operand 0 "nonimmediate_operand" "rYl"))]
> +  ""
> +  "BR%A0\t%0"
> +)



> Index: gcc/config/msp430/t-msp430
> ===================================================================
> --- gcc/config/msp430/t-msp430  (revision 0)
> +++ gcc/config/msp430/t-msp430  (revision 0)
> @@ -0,0 +1,43 @@
> +# Makefile fragment for building GCC for the Renesas RX target.
> +# Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.

Copyright 2012-2013, and not for the RX target.


> +#undef  TARGET_HANDLE_OPTION
> +#define TARGET_HANDLE_OPTION msp430_handle_option

Remove the no-op hook and keep the default?


> +#undef  TARGET_MS_BITFIELD_LAYOUT_P
> +#define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p

Likewise.


> +#undef  TARGET_FRAME_POINTER_REQUIRED
> +#define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required

Likewise.


> +#undef  TARGET_CAN_ELIMINATE
> +#define TARGET_CAN_ELIMINATE           msp430_can_eliminate

Likewise.


> +#undef  TARGET_PROMOTE_PROTOTYPES
> +#define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes

Likewise.


> +/* We use this to wrap all emitted insns in the prologue.  */
> +static rtx
> +F (rtx x)

Perhaps a more descriptive function name? ;-)


> Index: gcc/config/msp430/README.txt
> ===================================================================
> --- gcc/config/msp430/README.txt        (revision 0)
> +++ gcc/config/msp430/README.txt        (revision 0)
> @@ -0,0 +1,7 @@
> +Random Notes
> +------------
> +
> +The MSP430 port does not use leading underscores.  However, the
> +assembler has no way of differentiating between, for example, register
> +R12 and symbol R12.  So, if you do "int r12;" in your C program, you
> +may get an assembler error, and will certainly have runtime problems.

Perhaps put this in the user documentation instead (or as well).


Ciao!
Steven

Reply via email to