From 7a0a1f09c46d945c469b5830a74a7ac6369b673b Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Sat, 14 Feb 1998 05:14:13 +0000 Subject: [PATCH] arm.md (movsfcc): Also validate operands[3] when compiling hard float. * arm.md (movsfcc): Also validate operands[3] when compiling hard float. (movdfcc): Only accept fpu_add_operand for operands[3]. From-SVN: r17974 --- gcc/ChangeLog | 6 ++ gcc/config/arm/arm.md | 239 ++++++++++++++++++++++++++++-------------- 2 files changed, 169 insertions(+), 76 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5042d585f353..df8af471a5ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Sat Feb 14 05:08:21 1998 Richard Earnshaw (rearnsha@arm.com) + + * arm.md (movsfcc): Also validate operands[3] when compiling hard + float. + (movdfcc): Only accept fpu_add_operand for operands[3]. + Sat Feb 14 02:02:41 1998 Jeffrey A Law (law@cygnus.com) * varasm.c (output_constant_pool): Bring back 'done' label inside diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index afc2794ea1e3..ec70983d6eeb 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1,7 +1,7 @@ ;;- Machine description for Advanced RISC Machines' ARM for GNU compiler ;; Copyright (C) 1991, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) -;; and Martin Simmons (@harleqn.co.uk). +;; and Martin Simmons (@harleqn.co.uk). ;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk) ;; This file is part of GNU CC. @@ -859,6 +859,34 @@ "umull%?\\t%Q0, %R0, %1, %2" [(set_attr "type" "mult")]) +(define_insn "smulsi3_highpart" + [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") + (truncate:SI + (lshiftrt:DI + (mult:DI (sign_extend:DI + (match_operand:SI 1 "s_register_operand" "%r,0")) + (sign_extend:DI + (match_operand:SI 2 "s_register_operand" "r,r"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=&r,&r"))] + "arm_fast_multiply" + "smull%?\\t%3, %0, %2, %1" +[(set_attr "type" "mult")]) + +(define_insn "umulsi3_highpart" + [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") + (truncate:SI + (lshiftrt:DI + (mult:DI (zero_extend:DI + (match_operand:SI 1 "s_register_operand" "%r,0")) + (zero_extend:DI + (match_operand:SI 2 "s_register_operand" "r,r"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=&r,&r"))] + "arm_fast_multiply" + "umull%?\\t%3, %0, %2, %1" +[(set_attr "type" "mult")]) + (define_insn "mulsf3" [(set (match_operand:SF 0 "s_register_operand" "=f") (mult:SF (match_operand:SF 1 "s_register_operand" "f") @@ -1180,7 +1208,21 @@ " { HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << INTVAL (operands[1])) - 1; + rtx target, subtarget; + target = operands[0]; + /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical + subreg as the final target. */ + if (GET_CODE (target) == SUBREG) + { + subtarget = gen_reg_rtx (SImode); + if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target))) + < GET_MODE_SIZE (SImode)) + target = SUBREG_REG (target); + } + else + subtarget = target; + if (GET_CODE (operands[3]) == CONST_INT) { /* Since we are inserting a known constant, we may be able to @@ -1191,7 +1233,7 @@ << INTVAL (operands[2])); emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2))); - emit_insn (gen_iorsi3 (operands[0], op1, + emit_insn (gen_iorsi3 (subtarget, op1, GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2])))); } @@ -1212,7 +1254,7 @@ emit_insn (gen_iorsi3 (op1, gen_rtx (LSHIFTRT, SImode, operands[0], operands[1]), op0)); - emit_insn (gen_rotlsi3 (operands[0], op1, operands[1])); + emit_insn (gen_rotlsi3 (subtarget, op1, operands[1])); } else if ((INTVAL (operands[1]) + INTVAL (operands[2]) == 32) && ! (const_ok_for_arm (mask) @@ -1226,8 +1268,9 @@ emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - INTVAL (operands[1])))); emit_insn (gen_ashlsi3 (op1, operands[0], operands[1])); - emit_insn (gen_iorsi3 (operands[0], gen_rtx (LSHIFTRT, SImode, op1, - operands[1]), op0)); + emit_insn (gen_iorsi3 (subtarget, + gen_rtx (LSHIFTRT, SImode, op1, + operands[1]), op0)); } else { @@ -1270,7 +1313,17 @@ if (INTVAL (operands[2]) != 0) op1 = gen_rtx (ASHIFT, SImode, op1, operands[2]); - emit_insn (gen_iorsi3 (operands[0], op1, op2)); + emit_insn (gen_iorsi3 (subtarget, op1, op2)); + } + + if (subtarget != target) + { + /* If TARGET is still a SUBREG, then it must be wider than a word, + so we must be careful only to set the subword we were asked to. */ + if (GET_CODE (target) == SUBREG) + emit_move_insn (target, subtarget); + else + emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget)); } DONE; @@ -2551,23 +2604,24 @@ (define_expand "storehi" [;; store the low byte - (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3)) + (set (match_operand 1 "" "") (match_dup 3)) ;; extract the high byte (set (match_dup 2) (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) ;; store the high byte - (set (mem:QI (match_dup 4)) - (subreg:QI (match_dup 2) 0))] ;explicit subreg safe + (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe "" " { - enum rtx_code code = GET_CODE (operands[1]); + rtx addr = XEXP (operands[1], 0); + enum rtx_code code = GET_CODE (addr); - if ((code == PLUS || code == MINUS) - && (GET_CODE (XEXP (operands[1], 1)) == REG - || GET_CODE (XEXP (operands[1], 0)) != REG)) - operands[1] = force_reg (SImode, operands[1]); - operands[4] = plus_constant (operands[1], 1); + if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) + || code == MINUS) + addr = force_reg (SImode, addr); + + operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1)); + operands[1] = change_address (operands[1], QImode, NULL_RTX); operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); operands[2] = gen_reg_rtx (SImode); @@ -2575,21 +2629,22 @@ ") (define_expand "storehi_bigend" - [(set (mem:QI (match_dup 4)) (match_dup 3)) + [(set (match_dup 4) (match_dup 3)) (set (match_dup 2) (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) - (set (mem:QI (match_operand 1 "" "")) - (subreg:QI (match_dup 2) 0))] + (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))] "" " { - enum rtx_code code = GET_CODE (operands[1]); - if ((code == PLUS || code == MINUS) - && (GET_CODE (XEXP (operands[1], 1)) == REG - || GET_CODE (XEXP (operands[1], 0)) != REG)) - operands[1] = force_reg (SImode, operands[1]); + rtx addr = XEXP (operands[1], 0); + enum rtx_code code = GET_CODE (addr); + + if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) + || code == MINUS) + addr = force_reg (SImode, addr); - operands[4] = plus_constant (operands[1], 1); + operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1)); + operands[1] = change_address (operands[1], QImode, NULL_RTX); operands[3] = gen_lowpart (QImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]); operands[2] = gen_reg_rtx (SImode); @@ -2598,19 +2653,19 @@ ;; Subroutine to store a half word integer constant into memory. (define_expand "storeinthi" - [(set (mem:QI (match_operand:SI 0 "" "")) + [(set (match_operand 0 "" "") (subreg:QI (match_operand 1 "" "") 0)) - (set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))] + (set (match_dup 3) (subreg:QI (match_dup 2) 0))] "" " { HOST_WIDE_INT value = INTVAL (operands[1]); - enum rtx_code code = GET_CODE (operands[0]); + rtx addr = XEXP (operands[0], 0); + enum rtx_code code = GET_CODE (addr); - if ((code == PLUS || code == MINUS) - && (GET_CODE (XEXP (operands[0], 1)) == REG - || GET_CODE (XEXP (operands[0], 0)) != REG)) - operands[0] = force_reg (SImode, operands[0]); + if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) + || code == MINUS) + addr = force_reg (SImode, addr); operands[1] = gen_reg_rtx (SImode); if (BYTES_BIG_ENDIAN) @@ -2636,7 +2691,8 @@ } } - operands[3] = plus_constant (operands[0], 1); + operands[3] = change_address (operands[0], QImode, plus_constant (addr, 1)); + operands[0] = change_address (operands[0], QImode, NULL_RTX); } ") @@ -2667,16 +2723,15 @@ DONE; } if (GET_CODE (operands[1]) == CONST_INT) - emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1])); + emit_insn (gen_storeinthi (operands[0], operands[1])); else { if (GET_CODE (operands[1]) == MEM) operands[1] = force_reg (HImode, operands[1]); if (BYTES_BIG_ENDIAN) - emit_insn (gen_storehi_bigend (operands[1], - XEXP (operands[0], 0))); + emit_insn (gen_storehi_bigend (operands[1], operands[0])); else - emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0))); + emit_insn (gen_storehi (operands[1], operands[0])); } DONE; } @@ -3152,9 +3207,10 @@ FAIL; operands[3] - = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), - force_reg (SImode, XEXP (operands[1], 0)), - TRUE, FALSE); + = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), + force_reg (SImode, XEXP (operands[1], 0)), + TRUE, FALSE, RTX_UNCHANGING_P(operands[1]), + MEM_IN_STRUCT_P(operands[1])); ") ;; Load multiple with write-back @@ -3221,9 +3277,10 @@ FAIL; operands[3] - = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), - force_reg (SImode, XEXP (operands[0], 0)), - TRUE, FALSE); + = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), + force_reg (SImode, XEXP (operands[0], 0)), + TRUE, FALSE, RTX_UNCHANGING_P (operands[0]), + MEM_IN_STRUCT_P(operands[0])); ") ;; Store multiple with write-back @@ -3859,8 +3916,16 @@ " { enum rtx_code code = GET_CODE (operands[1]); - rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1, - arm_compare_fp); + rtx ccreg; + + /* When compiling for SOFT_FLOAT, ensure both arms are in registers. + Otherwise, ensure it is a valid FP add operand */ + if ((! TARGET_HARD_FLOAT) + || (! fpu_add_operand (operands[3], SFmode))) + operands[3] = force_reg (SFmode, operands[3]); + + ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1, + arm_compare_fp); operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx); }") @@ -3869,7 +3934,7 @@ [(set (match_operand:DF 0 "s_register_operand" "") (if_then_else:DF (match_operand 1 "comparison_operator" "") (match_operand:DF 2 "s_register_operand" "") - (match_operand:DF 3 "nonmemory_operand" "")))] + (match_operand:DF 3 "fpu_add_operand" "")))] "TARGET_HARD_FLOAT" " { @@ -3881,57 +3946,77 @@ }") (define_insn "*movsicc_insn" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r") + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") (if_then_else:SI (match_operator 3 "comparison_operator" [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SI 1 "arm_not_operand" "0,0,?rI,?rI,K,K") - (match_operand:SI 2 "arm_not_operand" "rI,K,rI,K,rI,K")))] + (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") + (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] "" "@ mov%D3\\t%0, %2 mvn%D3\\t%0, #%B2 + mov%d3\\t%0, %1 + mvn%d3\\t%0, #%B1 mov%d3\\t%0, %1\;mov%D3\\t%0, %2 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" - [(set_attr "length" "4,4,8,8,8,8") + [(set_attr "length" "4,4,4,4,8,8,8,8") (set_attr "conds" "use")]) (define_insn "*movsfcc_hard_insn" - [(set (match_operand:SF 0 "s_register_operand" "=f,f") - (if_then_else:SF (match_operator 3 "comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SF 1 "s_register_operand" "0,0") - (match_operand:SF 2 "fpu_add_operand" "fG,H")))] + [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f") + (if_then_else:SF + (match_operator 3 "comparison_operator" + [(match_operand 4 "cc_register" "") (const_int 0)]) + (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H") + (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))] "TARGET_HARD_FLOAT" "@ mvf%D3s\\t%0, %2 - mnf%D3s\\t%0, #%N2" - [(set_attr "type" "ffarith") + mnf%D3s\\t%0, #%N2 + mvf%d3s\\t%0, %1 + mnf%d3s\\t%0, #%N1 + mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2 + mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2 + mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2 + mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2" + [(set_attr "length" "4,4,4,4,8,8,8,8") + (set_attr "type" "ffarith") (set_attr "conds" "use")]) (define_insn "*movsfcc_soft_insn" - [(set (match_operand:SF 0 "s_register_operand" "=r") + [(set (match_operand:SF 0 "s_register_operand" "=r,r") (if_then_else:SF (match_operator 3 "comparison_operator" [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:SF 1 "s_register_operand" "0") - (match_operand:SF 2 "s_register_operand" "r")))] + (match_operand:SF 1 "s_register_operand" "0,r") + (match_operand:SF 2 "s_register_operand" "r,0")))] "TARGET_SOFT_FLOAT" - "mov%D3\\t%0, %2" + "@ + mov%D3\\t%0, %2 + mov%d3\\t%0, %1" [(set_attr "conds" "use")]) (define_insn "*movdfcc_insn" - [(set (match_operand:DF 0 "s_register_operand" "=f,f") - (if_then_else:DF (match_operator 3 "comparison_operator" - [(match_operand 4 "cc_register" "") (const_int 0)]) - (match_operand:DF 1 "s_register_operand" "0,0") - (match_operand:DF 2 "fpu_add_operand" "fG,H")))] + [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f") + (if_then_else:DF + (match_operator 3 "comparison_operator" + [(match_operand 4 "cc_register" "") (const_int 0)]) + (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H") + (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))] "TARGET_HARD_FLOAT" "@ mvf%D3d\\t%0, %2 - mnf%D3d\\t%0, #%N2" - [(set_attr "type" "ffarith") + mnf%D3d\\t%0, #%N2 + mvf%d3d\\t%0, %1 + mnf%d3d\\t%0, #%N1 + mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2 + mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2 + mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2 + mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2" + [(set_attr "length" "4,4,4,4,8,8,8,8") + (set_attr "type" "ffarith") (set_attr "conds" "use")]) ;; Jump and linkage insns @@ -4158,14 +4243,17 @@ DONE; }") +;; The USE in this pattern is needed to tell flow analysis that this is +;; a CASESI insn. It has no other purpose. (define_insn "casesi_internal" - [(set (pc) - (if_then_else - (leu (match_operand:SI 0 "s_register_operand" "r") - (match_operand:SI 1 "arm_rhs_operand" "rI")) - (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) - (label_ref (match_operand 2 "" "")))) - (label_ref (match_operand 3 "" ""))))] + [(parallel [(set (pc) + (if_then_else + (leu (match_operand:SI 0 "s_register_operand" "r") + (match_operand:SI 1 "arm_rhs_operand" "rI")) + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) + (label_ref (match_operand 2 "" "")))) + (label_ref (match_operand 3 "" "")))) + (use (label_ref (match_dup 2)))])] "" "* if (flag_pic) @@ -5663,8 +5751,7 @@ "sub%?s\\t%0, %1, #0" [(set_attr "conds" "set")]) -; Peepholes to spot possible load- and store-multiples, if the ordering is -; reversed, check that the memory references aren't volatile. +; Peepholes to spot possible load- and store-multiples. (define_peephole [(set (match_operand:SI 0 "s_register_operand" "=r") -- 2.43.5