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