Mercurial > hg > CbC > CbC_gcc
diff gcc/config/mn10300/mn10300.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/config/mn10300/mn10300.md Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/mn10300/mn10300.md Fri Oct 27 22:46:09 2017 +0900 @@ -1,7 +1,5 @@ ;; GCC machine description for Matsushita MN10300 -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -;; 2005, 2006, 2007, 2008, 2009, 2010, 2011 -;; Free Software Foundation, Inc. +;; Copyright (C) 1996-2017 Free Software Foundation, Inc. ;; Contributed by Jeff Law (law@cygnus.com). ;; This file is part of GCC. @@ -42,6 +40,8 @@ ;; This is used to encode LIW patterns. (UNSPEC_LIW 8) + ;; This is for the low overhead loop instructions. + (UNSPEC_SETLB 9) ]) (include "predicates.md") @@ -61,15 +61,15 @@ (const_int 1) (and (eq_attr "isa" "am33") - (ne (symbol_ref "TARGET_AM33") (const_int 0))) + (match_test "TARGET_AM33")) (const_int 1) (and (eq_attr "isa" "am33_2") - (ne (symbol_ref "TARGET_AM33_2") (const_int 0))) + (match_test "TARGET_AM33_2")) (const_int 1) (and (eq_attr "isa" "am34") - (ne (symbol_ref "TARGET_AM34") (const_int 0))) + (match_test "TARGET_AM34")) (const_int 1) ] (const_int 0)) @@ -239,8 +239,8 @@ }) (define_insn "*movqi_internal" - [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m") - (match_operand:QI 1 "general_operand" " 0,D*r, i,m,D"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") + (match_operand:QI 1 "general_operand" " 0,D*r, i,m,D,d,*z"))] "(register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" { @@ -250,6 +250,8 @@ return ""; case 1: case 2: + case 5: + case 6: return "mov %1,%0"; case 3: case 4: @@ -266,6 +268,8 @@ (const_int 13) (const_int 24)) (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) + (const_int 11) + (const_int 11) ])] ) @@ -283,8 +287,8 @@ }) (define_insn "*movhi_internal" - [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m") - (match_operand:HI 1 "general_operand" " 0, i,D*r,m,D"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") + (match_operand:HI 1 "general_operand" " 0, i,D*r,m,D,d,*z"))] "(register_operand (operands[0], HImode) || register_operand (operands[1], HImode))" { @@ -302,6 +306,8 @@ && REGNO_EXTENDED_P (REGNO (operands[0]), 1)) return "movu %1,%0"; /* FALLTHRU */ + case 5: + case 6: case 2: return "mov %1,%0"; case 3: @@ -320,6 +326,10 @@ (const_int 13) (const_int 24)) (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) + (if_then_else (eq_attr "cpu" "am34") + (const_int 11) (const_int 22)) + (if_then_else (eq_attr "cpu" "am34") + (const_int 11) (const_int 22)) ])] ) @@ -491,8 +501,8 @@ }) (define_insn "*movsf_internal" - [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q") - (match_operand:SF 1 "general_operand" " 0,F,F,r,f,f,r,m,r,Q,f"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d") + (match_operand:SF 1 "general_operand" " 0,F,F,r,f,f,r,m,r,Q,f,d,z"))] "TARGET_AM33_2 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" @@ -505,6 +515,8 @@ case 3: case 7: case 8: + case 11: + case 12: return "mov %1,%0"; case 2: case 4: @@ -537,6 +549,8 @@ (const_int 13) (const_int 24)) (if_then_else (eq_attr "cpu" "am34") (const_int 13) (const_int 24)) + (const_int 22) + (const_int 22) ])] ) @@ -578,12 +592,12 @@ ;; Note that ADD IMM,SP does not set the flags, so omit that here. (define_insn "*addsi3_flags" - [(set (match_operand:SI 0 "register_operand" "=r,!r") - (plus:SI (match_operand:SI 1 "register_operand" "%0, r") - (match_operand:SI 2 "nonmemory_operand" "ri, r"))) - (set (reg CC_REG) - (compare (plus:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (plus:SI (match_operand:SI 1 "register_operand" "%0, r") + (match_operand:SI 2 "nonmemory_operand" "ri, r")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=r,!r") + (plus:SI (match_dup 1) (match_dup 2)))] "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" { return mn10300_output_add (operands, true); } [(set_attr "timings" "11,22")] @@ -591,12 +605,12 @@ ;; A helper to expand the above, with the CC_MODE filled in. (define_expand "addsi3_flags" - [(parallel [(set (match_operand:SI 0 "register_operand") + [(parallel [(set (reg:CCZNC CC_REG) + (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2)) + (const_int 0))) + (set (match_operand:SI 0 "register_operand") (plus:SI (match_operand:SI 1 "register_operand") - (match_operand:SI 2 "nonmemory_operand"))) - (set (reg:CCZNC CC_REG) - (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2)) - (const_int 0)))])] + (match_operand:SI 2 "nonmemory_operand")))])] "" ) @@ -777,12 +791,12 @@ ) (define_insn "*subsi3_flags" - [(set (match_operand:SI 0 "register_operand" "=r, r") - (minus:SI (match_operand:SI 1 "register_operand" "0, r") - (match_operand:SI 2 "nonmemory_operand" "ri,r"))) - (set (reg CC_REG) - (compare (minus:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (minus:SI (match_operand:SI 1 "register_operand" "0, r") + (match_operand:SI 2 "nonmemory_operand" "ri,r")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=r, r") + (minus:SI (match_dup 1) (match_dup 2)))] "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" "@ sub %2,%0 @@ -793,12 +807,12 @@ ;; A helper to expand the above, with the CC_MODE filled in. (define_expand "subsi3_flags" - [(parallel [(set (match_operand:SI 0 "register_operand") + [(parallel [(set (reg:CCZNC CC_REG) + (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2)) + (const_int 0))) + (set (match_operand:SI 0 "register_operand") (minus:SI (match_operand:SI 1 "register_operand") - (match_operand:SI 2 "nonmemory_operand"))) - (set (reg:CCZNC CC_REG) - (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2)) - (const_int 0)))])] + (match_operand:SI 2 "nonmemory_operand")))])] "" ) @@ -983,7 +997,7 @@ ;; ??? Note that AM33 has a third multiply variant that puts the high part ;; into the MDRQ register, however this variant also constrains the inputs ;; to be in DATA_REGS and thus isn't as helpful as it might be considering -;; the existance of the 4-operand multiply. Nor is there a set of divide +;; the existence of the 4-operand multiply. Nor is there a set of divide ;; insns that use MDRQ. Given that there is an IMM->MDRQ insn, this would ;; have been very handy for starting udivmodsi4... @@ -1181,12 +1195,12 @@ ) (define_insn "*andsi3_flags" - [(set (match_operand:SI 0 "register_operand" "=D,D,r") - (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) - (set (reg CC_REG) - (compare (and:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") + (match_operand:SI 2 "nonmemory_operand" " i,D,r")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=D,D,r") + (and:SI (match_dup 1) (match_dup 2)))] "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" "@ and %2,%0 @@ -1268,12 +1282,12 @@ ) (define_insn "*iorsi3_flags" - [(set (match_operand:SI 0 "register_operand" "=D,D,r") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) - (set (reg CC_REG) - (compare (ior:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") + (match_operand:SI 2 "nonmemory_operand" " i,D,r")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=D,D,r") + (ior:SI (match_dup 1) (match_dup 2)))] "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" "@ or %2,%0 @@ -1304,12 +1318,12 @@ ) (define_insn "*xorsi3_flags" - [(set (match_operand:SI 0 "register_operand" "=D,D,r") - (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) - (set (reg CC_REG) - (compare (xor:SI (match_dup 1) (match_dup 2)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") + (match_operand:SI 2 "nonmemory_operand" " i,D,r")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=D,D,r") + (xor:SI (match_dup 1) (match_dup 2)))] "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" "@ xor %2,%0 @@ -1332,11 +1346,11 @@ ) (define_insn "*one_cmplsi2_flags" - [(set (match_operand:SI 0 "register_operand" "=D") - (not:SI (match_operand:SI 1 "register_operand" " 0"))) - (set (reg CC_REG) - (compare (not:SI (match_dup 1)) - (const_int 0)))] + [(set (reg CC_REG) + (compare (not:SI (match_operand:SI 1 "register_operand" "0")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=D") + (not:SI (match_dup 1)))] "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" "not %0" ) @@ -1375,7 +1389,7 @@ DONE; }) -(define_insn "*cmpsi" +(define_insn "cmpsi" [(set (reg CC_REG) (compare (match_operand:SI 0 "register_operand" "r,r,r") (match_operand:SI 1 "nonmemory_operand" "r,O,i")))] @@ -1792,13 +1806,27 @@ ) ;; ---------------------------------------------------------------------- -;; MISCELANEOUS +;; MISCELLANEOUS ;; ---------------------------------------------------------------------- +;; Note the use of the (const_int 0) when generating the insn that matches +;; the bsch pattern. This ensures that the destination register is +;; initialised with 0 which will make the BSCH instruction set searching +;; at bit 31. +;; +;; The XOR in the instruction sequence below is there because the BSCH +;; instruction returns the bit number of the highest set bit and we want +;; the number of zero bits above that bit. The AM33 does not have a +;; reverse subtraction instruction, but we can use a simple xor instead +;; since we know that the top 27 bits are clear. (define_expand "clzsi2" - [(parallel [(set (match_operand:SI 0 "register_operand" "") - (unspec:SI [(match_operand:SI 1 "register_operand" "") + [(parallel [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SI 1 "register_operand") (const_int 0)] UNSPEC_BSCH)) + (clobber (reg:CC CC_REG))]) + (parallel [(set (match_dup 0) + (xor:SI (match_dup 0) + (const_int 31))) (clobber (reg:CC CC_REG))])] "TARGET_AM33" ) @@ -1810,7 +1838,7 @@ UNSPEC_BSCH)) (clobber (reg:CC CC_REG))] "TARGET_AM33" - "bsch %1,%0" + "bsch %1, %0" ) ;; ---------------------------------------------------------------------- @@ -2018,7 +2046,7 @@ { /* The RETF insn is up to 3 cycles faster than RET. */ fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file); - mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ()); + mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL)); fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0])); return ""; }) @@ -2031,8 +2059,7 @@ { fputs ("\tmovm ", asm_out_file); mn10300_print_reg_list (asm_out_file, - mn10300_store_multiple_operation (operands[0], - VOIDmode)); + mn10300_store_multiple_regs (operands[0])); fprintf (asm_out_file, ",(sp)\n"); return ""; } @@ -2152,3 +2179,39 @@ [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 13) (const_int 12)))] ) + +;; Note - in theory the doloop patterns could be used here to express +;; the SETLB and Lcc instructions. In practice this does not work because +;; the acceptable forms of the doloop patterns do not include UNSPECs +;; and without them gcc's basic block reordering code can duplicate the +;; doloop_end pattern, leading to bogus multiple decrements of the loop +;; counter. + +(define_insn "setlb" + [(unspec [(const_int 0)] UNSPEC_SETLB)] + "TARGET_AM33 && TARGET_ALLOW_SETLB" + "setlb" +) + +(define_insn "Lcc" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(reg:CC CC_REG) (const_int 0)]) + (label_ref (match_operand 1 "" "")) + (pc))) + (unspec [(const_int 1)] UNSPEC_SETLB)] + "TARGET_AM33 && TARGET_ALLOW_SETLB" + "L%b0 # loop back to: %1" +) + +(define_insn "FLcc" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(reg:CC_FLOAT CC_REG) (const_int 0)]) + (label_ref (match_operand 1 "" "")) + (pc))) + (unspec [(const_int 2)] UNSPEC_SETLB)] + "TARGET_AM33_2 && TARGET_ALLOW_SETLB" + "FL%b0 # loop back to: %1" + [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))] +)