--- gcc/config/ns32k/ns32k.md 2018/04/24 18:10:24 1.1 +++ gcc/config/ns32k/ns32k.md 2018/04/24 18:28:39 1.1.1.4 @@ -1,15 +1,6 @@ -; BUGS: -;; Insert no-op between an insn with memory read-write operands -;; following by a scale-indexing operation. -;; The Sequent assembler does not allow addresses to be used -;; except in insns which explicitly compute an effective address. -;; I.e., one cannot say "cmpd _p,@_x" -;; Implement unsigned multiplication?? - -;;- Machine description for GNU compiler -;;- ns32000 Version -;; Copyright (C) 1988 Free Software Foundation, Inc. -;; Contributed by Michael Tiemann (tiemann@mcc.com) +;;- Machine description for GNU compiler, ns32000 Version +;; Copyright (C) 1988, 1994 Free Software Foundation, Inc. +;; Contributed by Michael Tiemann (tiemann@cygnus.com) ;; This file is part of GNU CC. @@ -25,9 +16,18 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. +; BUGS: +;; Insert no-op between an insn with memory read-write operands +;; following by a scale-indexing operation. +;; The Sequent assembler does not allow addresses to be used +;; except in insns which explicitly compute an effective address. +;; I.e., one cannot say "cmpd _p,@_x" +;; Implement unsigned multiplication?? + ;;- Instruction patterns. When multiple patterns apply, ;;- the first one in the file is chosen. ;;- @@ -190,7 +190,7 @@ "cmpf %0,%1") (define_insn "movdf" - [(set (match_operand:DF 0 "general_operand" "=&fg<") + [(set (match_operand:DF 0 "general_operand" "=fg<") (match_operand:DF 1 "general_operand" "fFg"))] "" "* @@ -273,7 +273,7 @@ "movmd %1,%0,4") (define_insn "movdi" - [(set (match_operand:DI 0 "general_operand" "=&g<,*f,g") + [(set (match_operand:DI 0 "general_operand" "=g<,*f,g") (match_operand:DI 1 "general_operand" "gF,g,*f"))] "" "* @@ -314,11 +314,13 @@ "lprd sp,%0") (define_insn "movsi" - [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g") - (match_operand:SI 1 "general_operand" "g,?xy,g,*f"))] + [(set (match_operand:SI 0 "general_operand" "=g<,g<,*f,g,x") + (match_operand:SI 1 "general_operand" "g,?xy,g,*f,rmn"))] "" "* { + extern int flag_pic; \ + if (FP_REG_P (operands[0])) { if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 8) @@ -332,18 +334,37 @@ return \"movf %1,tos\;movd tos,%0\"; return \"movf %1,%0\"; } + if (GET_CODE (operands[0]) == REG + && REGNO (operands[0]) == FRAME_POINTER_REGNUM) + return \"lprd fp,%1\"; + if (GET_CODE (operands[1]) == CONST_DOUBLE) + operands[1] + = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1])); if (GET_CODE (operands[1]) == CONST_INT) { int i = INTVAL (operands[1]); - if (i <= 7 && i >= -8) - return \"movqd %1,%0\"; - if (i < 0x4000 && i >= -0x4000 && ! TARGET_32532) + if (! TARGET_32532) + { + if (i <= 7 && i >= -8) + return \"movqd %1,%0\"; + if (i <= 0x1fffffff && i >= -0x20000000) #if defined (GNX_V3) || defined (UTEK_ASM) - return \"addr %c1,%0\"; + return \"addr %c1,%0\"; #else - return \"addr @%c1,%0\"; + return \"addr @%c1,%0\"; #endif - return \"movd %1,%0\"; + return \"movd %$%1,%0\"; + } + else + return output_move_dconst(i, \"%$%1,%0\"); + } + else if (GET_CODE (operands[1]) == CONST && ! flag_pic) + { + /* Must contain symbols so we don`t know how big it is. In + * that case addr might lead to overflow. For PIC symbolic + * address loads always have to be done with addr. + */ + return \"movd %$%1,%0\"; } else if (GET_CODE (operands[1]) == REG) { @@ -367,6 +388,7 @@ } else if (GET_CODE (operands[1]) == MEM) return \"movd %1,%0\"; + /* Check if this effective address can be calculated faster by pulling it apart. */ if (REG_P (operands[0]) @@ -857,8 +879,8 @@ if (i <= 7 && i >= -8) return \"addqd %2,%0\"; - else if (GET_CODE (operands[0]) == REG - && i < 0x4000 && i >= -0x4000 && ! TARGET_32532) + else if (! TARGET_32532 && GET_CODE (operands[0]) == REG + && i <= 0x1fffffff && i >= -0x20000000) return \"addr %c2(%0),%0\"; } return \"addd %2,%0\"; @@ -888,8 +910,8 @@ { if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqw %1,%0\"; - return \"addw %1,%0\"; + return \"addqw %2,%0\"; + return \"addw %2,%0\"; }") (define_insn "addqi3" @@ -916,8 +938,8 @@ { if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-9 && INTVAL(operands[1]) < 8) - return \"addqb %1,%0\"; - return \"addb %1,%0\"; + return \"addqb %2,%0\"; + return \"addb %2,%0\"; }") ;;- All kinds of subtract instructions. @@ -943,10 +965,10 @@ "GET_CODE (operands[0]) == CONST_INT" "* { - if (GET_CODE(operands[0]) == CONST_INT && INTVAL(operands[0]) < 64 - && INTVAL(operands[0]) > -64 && ! TARGET_32532) - return \"adjspb %0\"; - return \"adjspd %0\"; + if (! TARGET_32532 && GET_CODE(operands[0]) == CONST_INT + && INTVAL(operands[0]) < 64 && INTVAL(operands[0]) > -64) + return \"adjspb %$%0\"; + return \"adjspd %$%0\"; }") (define_insn "subsi3" @@ -990,8 +1012,8 @@ { if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqw %$%n1,%0\"; - return \"subw %1,%0\"; + return \"addqw %$%n2,%0\"; + return \"subw %2,%0\"; }") (define_insn "subqi3" @@ -1019,8 +1041,8 @@ { if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >-8 && INTVAL(operands[1]) < 9) - return \"addqb %$%n1,%0\"; - return \"subb %1,%0\"; + return \"addqb %$%n2,%0\"; + return \"subb %2,%0\"; }") ;;- Multiply instructions. @@ -1433,7 +1455,7 @@ { if (INTVAL (operands[2]) == 1) return \"addw %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) + else if (! TARGET_32532 && INTVAL (operands[2]) == 2) return \"addw %0,%0\;addw %0,%0\"; } if (TARGET_32532) @@ -1452,7 +1474,7 @@ { if (INTVAL (operands[2]) == 1) return \"addb %0,%0\"; - else if (INTVAL (operands[2]) == 2 && !TARGET_32532) + else if (! TARGET_32532 && INTVAL (operands[2]) == 2) return \"addb %0,%0\;addb %0,%0\"; } if (TARGET_32532) @@ -1539,27 +1561,6 @@ ;; logical shift instructions -(define_insn "lshlsi3" - [(set (match_operand:SI 0 "general_operand" "=g") - (lshift:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshd %2,%0") - -(define_insn "lshlhi3" - [(set (match_operand:HI 0 "general_operand" "=g") - (lshift:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshw %2,%0") - -(define_insn "lshlqi3" - [(set (match_operand:QI 0 "general_operand" "=g") - (lshift:QI (match_operand:QI 1 "general_operand" "0") - (match_operand:SI 2 "general_operand" "rmn")))] - "" - "lshb %2,%0") - ;; Logical right shift on the 32k works by negating the shift count. (define_expand "lshrsi3" [(set (match_operand:SI 0 "general_operand" "=g") @@ -1872,12 +1873,32 @@ return \"adjspb %$-4\"; }") +;; The exts/ext instructions have the problem that they always access +;; 32 bits even if the bitfield is smaller. For example the instruction +;; extsd 7(r1),r0,2,5 +;; would read not only at address 7(r1) but also at 8(r1) to 10(r1). +;; If these addresses are in a different (unmapped) page a memory fault +;; is the result. +;; +;; Timing considerations: +;; movd 0(r1),r0 3 bytes +;; lshd -26,r0 4 +;; andd 0x1f,r0 5 +;; takes about 13 cycles on the 532 while +;; extsd 7(r1),r0,2,5 5 bytes +;; takes about 21 cycles. +;; +;; The inss/ins instructions suffer from the same problem. +;; +;; A machine specific option (-mbitfield/-mnobitfield) is used +;; to allow/disallow the use of these instructions. + (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g<") (zero_extract:SI (match_operand:SI 1 "register_operand" "g") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "general_operand" "rK")))] - "" + "TARGET_BITFIELD" "* { if (GET_CODE (operands[3]) == CONST_INT) return \"extsd %1,%0,%3,%2\"; @@ -1889,7 +1910,7 @@ (zero_extract:SI (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "general_operand" "rK")))] - "" + "TARGET_BITFIELD" "* { if (GET_CODE (operands[3]) == CONST_INT) return \"extsd %1,%0,%3,%2\"; @@ -1901,7 +1922,7 @@ (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "general_operand" "rn")) (match_operand:SI 3 "general_operand" "rm"))] - "" + "TARGET_BITFIELD" "* { if (GET_CODE (operands[2]) == CONST_INT) { @@ -1926,7 +1947,7 @@ (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "general_operand" "rK")) (match_operand:SI 3 "general_operand" "rm"))] - "" + "TARGET_BITFIELD" "* { if (GET_CODE (operands[2]) == CONST_INT) if (INTVAL (operands[1]) <= 8) @@ -1943,7 +1964,7 @@ (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "general_operand" "rK")) (match_operand:SI 3 "general_operand" "rm"))] - "" + "TARGET_BITFIELD" "* { if (GET_CODE (operands[2]) == CONST_INT) if (INTVAL (operands[1]) <= 8) @@ -2355,32 +2376,18 @@ "" "jump %0") -;;(define_insn "tablejump" -;; [(set (pc) -;; (plus:SI (match_operand:SI 0 "general_operand" "g") -;; (pc)))] -;; "" -;; "cased %0") - (define_insn "tablejump" [(set (pc) - (plus:SI (pc) (match_operand:HI 0 "general_operand" "g"))) + (plus:SI (pc) (match_operand:SI 0 "general_operand" "g"))) (use (label_ref (match_operand 1 "" "")))] "" "* { ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\", CODE_LABEL_NUMBER (operands[1])); - return \"casew %0\"; + return \"cased %0\"; }") -;;(define_insn "" -;; [(set (pc) -;; (plus:SI (match_operand:QI 0 "general_operand" "g") -;; (pc)))] -;; "" -;; "caseb %0") - ;; Scondi instructions (define_insn "seq" [(set (match_operand:SI 0 "general_operand" "=g<") @@ -2597,3 +2604,155 @@ (leu:QI (cc0) (const_int 0)))] "" "slsb %0") + +;; ffs instructions + +(define_insn "ffsqi2" + [(set (match_operand:QI 0 "general_operand" "=g") + (ffs:QI (match_operand:SI 1 "general_operand" "g")))] + "" + "* +{ + return \"movqb 0,%0; ffsd %1,%0; bfs 1f; addqb 1,%0; 1:\"; +}") + +(define_insn "ffshi2" + [(set (match_operand:HI 0 "general_operand" "=g") + (ffs:HI (match_operand:SI 1 "general_operand" "g")))] + "" + "* +{ + return \"movqw 0,%0; ffsd %1,%0; bfs 1f; addqw 1,%0; 1:\"; +}") + +(define_insn "ffssi2" + [(set (match_operand:SI 0 "general_operand" "=g") + (ffs:SI (match_operand:SI 1 "general_operand" "g")))] + "" + "* +{ + return \"movqd 0,%0; ffsd %1,%0; bfs 1f; addqd 1,%0; 1:\"; +}") + +;; Speed up stack adjust followed by a HI fixedpoint push. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) + (set (match_operand:HI 0 "push_operand" "=m") + (match_operand:HI 1 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), + operands); + else + output_asm_insn (\"movzwd %1,tos\", operands); + return \"\"; +}") + +;; Speed up stack adjust followed by a zero_extend:HI(QI) fixedpoint push. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) + (set (match_operand:HI 0 "push_operand" "=m") + (zero_extend:HI (match_operand:QI 1 "general_operand" "g")))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), + operands); + else + output_asm_insn (\"movzbd %1,tos\", operands); + return \"\"; +}") + +;; Speed up stack adjust followed by a sign_extend:HI(QI) fixedpoint push. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -2))) + (set (match_operand:HI 0 "push_operand" "=m") + (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), + operands); + else + output_asm_insn (\"movxbd %1,tos\", operands); + return \"\"; +}") + +;; Speed up stack adjust followed by a QI fixedpoint push. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int -3))) + (set (match_operand:QI 0 "push_operand" "=m") + (match_operand:QI 1 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,tos\"), + operands); + else + output_asm_insn (\"movzbd %1,tos\", operands); + return \"\"; +}") + +;; Speed up stack adjust followed by a SI fixedpoint push. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 4))) + (set (match_operand:SI 0 "push_operand" "=m") + (match_operand:SI 1 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,0(sp)\"), + operands); + else if (GET_CODE (operands[1]) != REG + && GET_CODE (operands[1]) != MEM + && address_operand (operands[1], SImode)) + output_asm_insn (\"addr %a1,0(sp)\", operands); + else + output_asm_insn (\"movd %1,0(sp)\", operands); + return \"\"; +}") + +;; Speed up stack adjust followed by two fullword fixedpoint pushes. + +(define_peephole + [(set (reg:SI 17) (plus:SI (reg:SI 17) (const_int 8))) + (set (match_operand:SI 0 "push_operand" "=m") + (match_operand:SI 1 "general_operand" "g")) + (set (match_operand:SI 2 "push_operand" "=m") + (match_operand:SI 3 "general_operand" "g"))] + "! reg_mentioned_p (stack_pointer_rtx, operands[1]) + && ! reg_mentioned_p (stack_pointer_rtx, operands[3])" + "* +{ + if (GET_CODE (operands[1]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[1]), \"%$%1,4(sp)\"), + operands); + else if (GET_CODE (operands[1]) != REG + && GET_CODE (operands[1]) != MEM + && address_operand (operands[1], SImode)) + output_asm_insn (\"addr %a1,4(sp)\", operands); + else + output_asm_insn (\"movd %1,4(sp)\", operands); + + if (GET_CODE (operands[3]) == CONST_INT) + output_asm_insn (output_move_dconst (INTVAL (operands[3]), \"%$%3,0(sp)\"), + operands); + else if (GET_CODE (operands[3]) != REG + && GET_CODE (operands[3]) != MEM + && address_operand (operands[3], SImode)) + output_asm_insn (\"addr %a3,0(sp)\", operands); + else + output_asm_insn (\"movd %3,0(sp)\", operands); + return \"\"; +}")