From patchwork Fri Oct 29 14:35:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Koning X-Patchwork-Id: 69594 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 49396B70E0 for ; Sat, 30 Oct 2010 01:35:36 +1100 (EST) Received: (qmail 26508 invoked by alias); 29 Oct 2010 14:35:34 -0000 Received: (qmail 26177 invoked by uid 22791); 29 Oct 2010 14:35:31 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_00, SARE_RAND_2, TW_OV, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from ausc60pc101.us.dell.com (HELO ausc60pc101.us.dell.com) (143.166.85.206) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 29 Oct 2010 14:35:23 +0000 X-Loopcount0: from 10.152.240.141 From: Paul Koning Subject: [PATCH] pdp11: fix a number of ICE Date: Fri, 29 Oct 2010 10:35:18 -0400 Message-Id: <622B1D25-3730-418E-A803-5805B0FDE4ED@dell.com> To: gcc-patches Mime-Version: 1.0 (Apple Message framework v1081) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch corrects many of the ICE in the testsuite. It's not error free yet, but this reduces the number of c-torture compile testsuite failures from over 400 to about 140. Tested by test build, make check. Committed. paul ChangeLog: 2010-10-29 Paul Koning * config/pdp11/pdp11-protos.h (pdp11_cannot_change_mode_class, pdp11_secondary_memory_needed): Declare. * config/pdp11/predicates.md (float_operand): New predicate. * config/pdp11/pdp11.md (RETVAL_REGNUM): New constant. (cbranchdf4, movdf): Change predicate. (movsf): Handle FPU register case. (truncdfsf2, extendsfdf2): Add FPU register case. * config/pdp11/pdp11.c (TARGET_SECONDARY_RELOAD, TARGET_REGISTER_MOVE_COST, TARGET_PREFERRED_RELOAD_CLASS, TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Define. (pdp11_register_move_cost): Update cost matrix. (pdp11_cannot_change_mode_class, pdp11_preferred_reload_class, pdp11_preferred_output_reload_class, pdp11_secondary_reload, pdp11_secondary_memory_needed): New function. (pdp11_return_in_memory): Add other float types. * config/pdp11/pdp11.h (HARD_REGNO_MODE_OK): Add other float types. (SECONDARY_MEMORY_NEEDED, CANNOT_CHANGE_MODE_CLASS): Define. (PREFERRED_RELOAD_CLASS, SECONDARY_RELOAD_CLASS, REGISTER_MOVE_COST): Delete. (BASE_RETURN_VALUE_REG): Add other float types. Index: config/pdp11/pdp11-protos.h =================================================================== --- config/pdp11/pdp11-protos.h (revision 165973) +++ config/pdp11/pdp11-protos.h (working copy) @@ -31,7 +31,11 @@ extern const char *output_block_move (rtx *); extern const char *output_jump (enum rtx_code, int, int); extern void print_operand_address (FILE *, rtx); -extern int pdp11_register_move_cost (enum reg_class, enum reg_class); +extern bool pdp11_cannot_change_mode_class (enum machine_mode, + enum machine_mode, enum reg_class); +extern bool pdp11_secondary_memory_needed (reg_class_t, reg_class_t, + enum machine_mode); + #endif /* RTX_CODE */ extern void output_ascii (FILE *, const char *, int); Index: config/pdp11/predicates.md =================================================================== --- config/pdp11/predicates.md (revision 165973) +++ config/pdp11/predicates.md (working copy) @@ -35,3 +35,12 @@ sh = INTVAL (op); return (abs (sh) > 1 && abs (sh) <= 4); }) + +;; Accept anything general-operand accepts, except that registers must +;; be FPU registers. +(define_predicate "float_operand" + (if_then_else (match_code "reg") + (ior + (match_test "REGNO_REG_CLASS (REGNO (op)) == LOAD_FPU_REGS") + (match_test "REGNO_REG_CLASS (REGNO (op)) == NO_LOAD_FPU_REGS")) + (match_test "general_operand (op, mode)"))) Index: config/pdp11/pdp11.md =================================================================== --- config/pdp11/pdp11.md (revision 165973) +++ config/pdp11/pdp11.md (working copy) @@ -25,6 +25,7 @@ (define_constants [ ;; Register numbers + (RETVAL_REGNUM 0) (FRAME_POINTER_REGNUM 5) (STACK_POINTER_REGNUM 6) (PC_REGNUM 7) @@ -196,7 +197,7 @@ (define_expand "cbranchdf4" [(set (cc0) (compare (match_operand:DF 1 "general_operand") - (match_operand:DF 2 "general_operand"))) + (match_operand:DF 2 "register_or_const0_operand"))) (set (pc) (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)]) @@ -318,11 +319,9 @@ }" [(set_attr "length" "2,4,4,6")]) -;; do we have to supply all these moves? e.g. to -;; NO_LOAD_FPU_REGs ? (define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,g") - (match_operand:DF 1 "general_operand" "fFR,a,Q,a,g"))] + [(set (match_operand:DF 0 "float_operand" "=a,fR,a,Q,g") + (match_operand:DF 1 "float_operand" "fFR,a,Q,a,g"))] "TARGET_FPU" "* if (which_alternative ==0 || which_alternative == 2) return \"ldd %1, %0\"; @@ -334,11 +333,17 @@ [(set_attr "length" "2,2,10,10,32")]) (define_insn "movsf" - [(set (match_operand:SF 0 "general_operand" "=g,r,g") - (match_operand:SF 1 "general_operand" "r,rmF,g"))] + [(set (match_operand:SF 0 "float_operand" "=a,fR,a,Q,g") + (match_operand:SF 1 "float_operand" "fFR,a,Q,a,g"))] "TARGET_FPU" - "* return output_move_double (operands);" - [(set_attr "length" "16,16,16")]) + "* if (which_alternative ==0 || which_alternative == 2) + return \"{ldcfd|movof} %1, %0\"; + else if (which_alternative == 1 || which_alternative == 3) + return \"{stcdf|movfo} %1, %0\"; + else + return output_move_double (operands); " +;; just a guess.. + [(set_attr "length" "2,2,10,10,16")]) ;; maybe fiddle a bit with move_ratio, then ;; let constraints only accept a register ... @@ -386,15 +391,11 @@ ;;- truncation instructions (define_insn "truncdfsf2" - [(set (match_operand:SF 0 "general_operand" "=r,R,Q") - (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] + [(set (match_operand:SF 0 "general_operand" "=f,R,Q") + (float_truncate:SF (match_operand:DF 1 "register_operand" "f,a,a")))] "TARGET_FPU" "* if (which_alternative ==0) { - output_asm_insn(\"{stcdf|movfo} %1, -(sp)\", operands); - output_asm_insn(\"mov (sp)+, %0\", operands); - operands[0] = gen_rtx_REG (HImode, REGNO (operands[0])+1); - output_asm_insn(\"mov (sp)+, %0\", operands); return \"\"; } else if (which_alternative == 1) @@ -402,7 +403,7 @@ else return \"{stcdf|movfo} %1, %0\"; " - [(set_attr "length" "6,2,4")]) + [(set_attr "length" "0,2,4")]) (define_expand "truncsihi2" @@ -439,14 +440,14 @@ ;;- sign extension instructions (define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=a,a,a") - (float_extend:DF (match_operand:SF 1 "general_operand" "r,R,Q")))] + [(set (match_operand:DF 0 "register_operand" "=f,a,a") + (float_extend:DF (match_operand:SF 1 "general_operand" "f,R,Q")))] "TARGET_FPU" "@ - mov %1, -(sp)\;{ldcfd|movof} (sp)+,%0 + /* nothing */ {ldcfd|movof} %1, %0 {ldcfd|movof} %1, %0" - [(set_attr "length" "4,2,4")]) + [(set_attr "length" "0,2,4")]) ;; does movb sign extend in register-to-register move? (define_insn "extendqihi2" @@ -856,6 +857,7 @@ }" [(set_attr "length" "4,8,8,12,4,4,8,6,6,12")]) +;; FIXME This definition is wrong, PR/41822 (define_insn "andhi3" [(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q") (and:HI (match_operand:HI 1 "general_operand" "0,0,0,0") Index: config/pdp11/pdp11.c =================================================================== --- config/pdp11/pdp11.c (revision 165973) +++ config/pdp11/pdp11.c (working copy) @@ -216,7 +216,17 @@ #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init -struct gcc_target targetm = TARGET_INITIALIZER; +#undef TARGET_SECONDARY_RELOAD +#define TARGET_SECONDARY_RELOAD pdp11_secondary_reload + +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost + +#undef TARGET_PREFERRED_RELOAD_CLASS +#define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class + +#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS +#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class /* Implement TARGET_HANDLE_OPTION. */ @@ -417,7 +427,7 @@ /* get ACs */ for (i = AC5_REGNUM; i >= AC0_REGNUM; i--) - if (df_regs_ever_live_p (i) && call_used_regs[i]) + if (df_regs_ever_live_p (i) && ! call_used_regs[i]) via_ac = i; for (i = AC5_REGNUM; i >= AC0_REGNUM; i--) @@ -1054,22 +1064,23 @@ /* NO MUL GEN LFPU NLFPU FPU ALL */ /* NO */ { 0, 0, 0, 0, 0, 0, 0}, -/* MUL */ { 0, 2, 2, 10, 22, 22, 22}, -/* GEN */ { 0, 2, 2, 10, 22, 22, 22}, -/* LFPU */ { 0, 10, 10, 2, 2, 2, 10}, -/* NLFPU */ { 0, 22, 22, 2, 2, 2, 22}, -/* FPU */ { 0, 22, 22, 2, 2, 2, 22}, -/* ALL */ { 0, 22, 22, 10, 22, 22, 22} +/* MUL */ { 0, 2, 2, 22, 22, 22, 22}, +/* GEN */ { 0, 2, 2, 22, 22, 22, 22}, +/* LFPU */ { 0, 22, 22, 2, 2, 2, 22}, +/* NLFPU */ { 0, 22, 22, 2, 10, 10, 22}, +/* FPU */ { 0, 22, 22, 2, 10, 10, 22}, +/* ALL */ { 0, 22, 22, 22, 22, 22, 22} } ; /* -- note that some moves are tremendously expensive, because they require lots of tricks! do we have to charge the costs incurred by secondary reload class - -- as we do here with 22 -- or not ? */ + -- as we do here with 10 -- or not ? */ -int -pdp11_register_move_cost (enum reg_class c1, enum reg_class c2) +static int +pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, + reg_class_t c1, reg_class_t c2) { return move_costs[(int)c1][(int)c2]; } @@ -1634,6 +1645,108 @@ return 0; } +/* Implement CANNOT_CHANGE_MODE_CLASS. */ +bool +pdp11_cannot_change_mode_class (enum machine_mode from, + enum machine_mode to, + enum reg_class rclass) +{ + /* Also, FPU registers contain a whole float value and the parts of + it are not separately accessible. + + So we disallow all mode changes involving FPRs. */ + if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to)) + return true; + + return reg_classes_intersect_p (FPU_REGS, rclass); +} + +/* TARGET_PREFERRED_RELOAD_CLASS + + Given an rtx X being reloaded into a reg required to be + in class CLASS, return the class of reg to actually use. + In general this is just CLASS; but on some machines + in some cases it is preferable to use a more restrictive class. + +loading is easier into LOAD_FPU_REGS than FPU_REGS! */ + +static reg_class_t +pdp11_preferred_reload_class (rtx x, reg_class_t class) +{ + if (class == FPU_REGS) + return LOAD_FPU_REGS; + if (class == ALL_REGS) + { + if (FLOAT_MODE_P (GET_MODE (x))) + return LOAD_FPU_REGS; + else + return GENERAL_REGS; + } + return class; +} + +/* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS + + Given an rtx X being reloaded into a reg required to be + in class CLASS, return the class of reg to actually use. + In general this is just CLASS; but on some machines + in some cases it is preferable to use a more restrictive class. + +loading is easier into LOAD_FPU_REGS than FPU_REGS! */ + +static reg_class_t +pdp11_preferred_output_reload_class (rtx x, reg_class_t class) +{ + if (class == FPU_REGS) + return LOAD_FPU_REGS; + if (class == ALL_REGS) + { + if (FLOAT_MODE_P (GET_MODE (x))) + return LOAD_FPU_REGS; + else + return GENERAL_REGS; + } + return class; +} + + +/* TARGET_SECONDARY_RELOAD. + + FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an + intermediate register (AC0-AC3: LOAD_FPU_REGS). Everything else + can be loade/stored directly. */ +reg_class_t +pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED, + rtx x, + reg_class_t reload_class, + enum machine_mode reload_mode ATTRIBUTE_UNUSED, + secondary_reload_info *sri ATTRIBUTE_UNUSED) +{ + if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG || + REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS) + return NO_REGS; + + return LOAD_FPU_REGS; +} + +/* Target routine to check if register to register move requires memory. + + The answer is yes if we're going between general register and FPU + registers. The mode doesn't matter in making this check. +*/ +bool +pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ + int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS || + c1 == FPU_REGS); + int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS || + c2 == FPU_REGS); + + return (fromfloat != tofloat); +} + + /* A copy of output_addr_const modified for pdp11 expression syntax. output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't use, and for debugging output, which we don't support with this port either. @@ -1751,7 +1864,7 @@ ac0 if DFmode and FPU present - compatibility problem with libraries for non-floating point.... */ return (TYPE_MODE (type) == DImode - || (TYPE_MODE (type) == DFmode && ! TARGET_AC0)); + || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)); } /* Worker function for TARGET_FUNCTION_VALUE. @@ -1854,3 +1967,5 @@ ? GET_MODE_SIZE (mode) : int_size_in_bytes (type)); } + +struct gcc_target targetm = TARGET_INITIALIZER; Index: config/pdp11/pdp11.h =================================================================== --- config/pdp11/pdp11.h (revision 165973) +++ config/pdp11/pdp11.h (working copy) @@ -215,15 +215,19 @@ /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the pdp, the cpu registers can hold any mode - check alignment + On the pdp, the cpu registers can hold any mode other than float + (because otherwise we may end up being asked to move from CPU to FPU + register, which isn't a valid operation on the PDP11). + For CPU registers, check alignment. - FPU can only hold DF - simplifies life! + FPU accepts SF and DF but actually holds a DF - simplifies life! */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ (((REGNO) <= PC_REGNUM)? \ ((GET_MODE_BITSIZE(MODE) <= 16) \ - || (GET_MODE_BITSIZE(MODE) >= 32 && !((REGNO) & 1))) \ - :(MODE) == DFmode) + || (GET_MODE_BITSIZE(MODE) >= 32 && \ + !((REGNO) & 1) && !FLOAT_MODE_P (MODE))) \ + :FLOAT_MODE_P (MODE)) /* Value is 1 if it is a good idea to tie two pseudo registers @@ -322,19 +326,10 @@ #define IRA_COVER_CLASSES { GENERAL_REGS, FPU_REGS, LIM_REG_CLASSES } -/* Given an rtx X being reloaded into a reg required to be - in class CLASS, return the class of reg to actually use. - In general this is just CLASS; but on some machines - in some cases it is preferable to use a more restrictive class. +/* Hook for testing if memory is needed for moving between registers. */ +#define SECONDARY_MEMORY_NEEDED(class1, class2, m) \ + pdp11_secondary_memory_needed (class1, class2, m) -loading is easier into LOAD_FPU_REGS than FPU_REGS! */ - -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ -(((CLASS) != FPU_REGS)?(CLASS):LOAD_FPU_REGS) - -#define SECONDARY_RELOAD_CLASS(CLASS,MODE,x) \ -(((CLASS) == NO_LOAD_FPU_REGS && !(REG_P(x) && LOAD_FPU_REG_P(REGNO(x))))?LOAD_FPU_REGS:NO_REGS) - /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ @@ -343,6 +338,8 @@ 1 \ ) +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + pdp11_cannot_change_mode_class (FROM, TO, CLASS) /* Stack layout; function entry, exit and calling. */ @@ -386,7 +383,7 @@ If the precise function being called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. */ #define BASE_RETURN_VALUE_REG(MODE) \ - ((MODE) == DFmode ? 8 : 0) + (FLOAT_MODE_P (MODE) ? AC0_REGNUM : RETVAL_REGNUM) /* 1 if N is a possible register number for function argument passing. - not used on pdp */ @@ -674,10 +671,6 @@ /* #define NO_FUNCTION_CSE */ -/* cost of moving one register class to another */ -#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \ - pdp11_register_move_cost (CLASS1, CLASS2) - /* Tell emit-rtl.c how to initialize special values on a per-function base. */ extern struct rtx_def *cc0_reg_rtx;