--- gcc/config/pdp11/pdp11.md 2018/04/24 18:21:49 1.1 +++ gcc/config/pdp11/pdp11.md 2018/04/24 18:29:23 1.1.1.2 @@ -1,5 +1,5 @@ ;;- Machine description for the pdp11 for GNU C compiler -;; Copyright (C) 1994 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. ;; Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at). ;; This file is part of GNU CC. @@ -63,7 +63,7 @@ ;; length default is 1 word each (define_attr "length" "" (const_int 1)) -;; a users asm staement +;; a user's asm statement (define_asm_attributes [(set_attr "type" "unknown") ; all bets are off how long it is - make it 256, forces long jumps @@ -265,7 +265,7 @@ ;; and match them for register allocation. ;; problem with too short jump distance! we need an assembler which can -;; make this legal for all jump distances! +;; make this valid for all jump distances! ;; e.g. gas! ;; these must be changed to check for CC_IN_FCCR if float is to be @@ -365,7 +365,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return output_jump(\"blo\", \"bhos\", get_attr_length(insn));" + "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) (pc)) (const_int -128)) @@ -538,7 +538,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return output_jump(\"bhos\", \"blo\", get_attr_length(insn));" + "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));" [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) (pc)) (const_int -128)) @@ -572,7 +572,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return output_jump(\"blo\", \"bhos\", get_attr_length(insn));" + "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));" [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0) (pc)) (const_int -128)) @@ -679,7 +679,7 @@ [(set_attr "length" "8,8,8")]) ;; maybe fiddle a bit with move_ratio, then -;; let contraints only accept a register ... +;; let constraints only accept a register ... (define_expand "movstrhi" [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "=g,g")) @@ -718,11 +718,24 @@ ;;- truncation instructions (define_insn "truncdfsf2" - [(set (match_operand:SF 0 "memory_operand" "=R,Q") - (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a")))] + [(set (match_operand:SF 0 "general_operand" "=r,R,Q") + (float_truncate:SF (match_operand:DF 1 "register_operand" "a,a,a")))] "TARGET_FPU" - "stcdf %1, %0" - [(set_attr "length" "1,2")]) + "* if (which_alternative ==0) + { + output_asm_insn(\"stcdf %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) + return \"stcdf %1, %0\"; + else + return \"stcdf %1, %0\"; + " + [(set_attr "length" "3,1,2")]) + (define_expand "truncsihi2" [(set (match_operand:HI 0 "general_operand" "=g") @@ -758,11 +771,14 @@ ;;- sign extension instructions (define_insn "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "=a,a") - (float_extend:SF (match_operand:SF 1 "memory_operand" "R,Q")))] + [(set (match_operand:DF 0 "register_operand" "=a,a,a") + (float_extend:SF (match_operand:SF 1 "general_operand" "r,R,Q")))] "TARGET_FPU" - "ldcfd %1, %0" - [(set_attr "length" "1,2")]) + "@ + mov %1, -(sp)\;ldcfd (sp)+,%0 + ldcfd %1, %0 + ldcfd %1, %0" + [(set_attr "length" "2,1,2")]) ;; does movb sign extend in register-to-register move? (define_insn "extendqihi2" @@ -881,17 +897,35 @@ [(set_attr "length" "6")]) ;; make float to int and vice versa -;; using the cc_status.flag field we coulf probably cut down +;; using the cc_status.flag field we could probably cut down ;; on seti and setl ;; assume that we are normally in double and integer mode - ;; what do pdp library routines do to fpu mode ? (define_insn "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "=a,a") - (float:DF (match_operand:SI 1 "memory_operand" "R,Q")))] + [(set (match_operand:DF 0 "register_operand" "=a,a,a") + (float:DF (match_operand:SI 1 "general_operand" "r,R,Q")))] "TARGET_FPU" - "setl\;ldcld %1, %0\;seti" - [(set_attr "length" "3,4")]) + "* if (which_alternative ==0) + { + rtx latehalf[2]; + + latehalf[0] = NULL; + latehalf[1] = gen_rtx(REG, HImode, REGNO (operands[0])+1); + output_asm_insn(\"mov %1, -(sp)\", latehalf); + output_asm_insn(\"mov %1, -(sp)\", operands); + + output_asm_insn(\"setl\", operands); + output_asm_insn(\"ldcld (sp)+, %0\", operands); + output_asm_insn(\"seti\", operands); + return \"\"; + } + else if (which_alternative == 1) + return \"setl\;ldcld %1, %0\;seti\"; + else + return \"setl\;ldcld %1, %0\;seti\"; + " + [(set_attr "length" "5,3,4")]) (define_insn "floathidf2" [(set (match_operand:DF 0 "register_operand" "=a,a") @@ -902,11 +936,25 @@ ;; cut float to int (define_insn "fix_truncdfsi2" - [(set (match_operand:SI 0 "memory_operand" "=R,Q") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a"))))] + [(set (match_operand:SI 0 "general_operand" "=r,R,Q") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "a,a,a"))))] "TARGET_FPU" - "setl\;stcdl %1, %0\;seti" - [(set_attr "length" "3,4")]) + "* if (which_alternative ==0) + { + output_asm_insn(\"setl\", operands); + output_asm_insn(\"stcdl %1, -(sp)\", operands); + output_asm_insn(\"seti\", 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) + return \"setl\;stcdl %1, %0\;seti\"; + else + return \"setl\;stcdl %1, %0\;seti\"; + " + [(set_attr "length" "5,3,4")]) (define_insn "fix_truncdfhi2" [(set (match_operand:HI 0 "general_operand" "=rR,Q") @@ -1015,7 +1063,7 @@ ;;- subtract instructions ;; we don't have to care for constant second -;; args, since they are cononical plus:xx now! +;; args, since they are canonical plus:xx now! ;; also for minus:DF ?? (define_insn "subdf3" @@ -1058,7 +1106,7 @@ output_asm_insn (\"sub %2, %0\", lateoperands); return \"\"; }" -;; offsetable memory addresses always are expensive!!! +;; offsettable memory addresses always are expensive!!! [(set_attr "length" "3,5,6,8")]) (define_insn "subhi3" @@ -1447,7 +1495,7 @@ [(const_int 7) (const_int 14)])]) -;; the following is illegal - too complex!!! - just say 14 !!! +;; the following is invalid - too complex!!! - just say 14 !!! ; [(set (attr "length") (plus (and (match_dup 2) ; (const_int 7)) ; (and (match_dup 2) @@ -1670,18 +1718,35 @@ [(set_attr "length" "1,2")]) ;; 32 bit result -(define_insn "mulhisi3" +(define_expand "mulhisi3" + [(set (match_dup 3) + (match_operand:HI 1 "general_operand" "g,g")) + (set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! + (mult:SI (truncate:HI + (match_dup 0)) + (match_operand:HI 2 "general_operand" "rR,Qi")))] + "TARGET_45" + "operands[3] = gen_lowpart(HImode, operands[1]);") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! - (mult:SI (match_operand:HI 1 "register_operand" "%0,0") + (mult:SI (truncate:HI + (match_operand:SI 1 "register_operand" "%0,0")) (match_operand:HI 2 "general_operand" "rR,Qi")))] "TARGET_45" "mul %2, %0" [(set_attr "length" "1,2")]) -;;- divide -;; how can I use the remainder ? - -;; modsidi and move upper register to lower ???? +;(define_insn "mulhisi3" +; [(set (match_operand:SI 0 "register_operand" "=r,r") ; even numbered! +; (mult:SI (truncate:HI +; (match_operand:SI 1 "register_operand" "%0,0")) +; (match_operand:HI 2 "general_operand" "rR,Qi")))] +; "TARGET_45" +; "mul %2, %0" +; [(set_attr "length" "1,2")]) +;;- divide (define_insn "divdf3" [(set (match_operand:DF 0 "register_operand" "=a,a,a") (div:DF (match_operand:DF 1 "register_operand" "0,0,0") @@ -1690,269 +1755,64 @@ "divd %2, %0" [(set_attr "length" "1,2,5")]) -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r,r") - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0,0") - (sign_extend:SI (match_operand:HI 2 "general_operand" "rR,Q")))))] - "TARGET_45" - "div %2,%0" - [(set_attr "length" "1,2")]) - -;; - problem matching the (sign_extend:SI (const_int ...)) -; used without -O -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r") - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand 2 "immediate_operand" "n")))))] - "TARGET_45" - "div %2,%0" - [(set_attr "length" "2")]) - -; used with -O -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r") - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i"))))] - "TARGET_45" - "div %2,%0" - [(set_attr "length" "2")]) - + (define_expand "divhi3" - [(set (match_dup 3) - (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) - (set (match_operand:HI 0 "general_operand" "g") - (truncate:HI - (div:SI - (match_dup 3) - (sign_extend:SI (match_operand:HI 2 "general_operand" "g")))))] - "TARGET_45" - "operands[3] = gen_reg_rtx (SImode);") - -(define_expand "udivqi" - [(set (subreg:HI (match_dup 3) 1) - (zero_extend:HI (match_operand:QI 1 "general_operand" "g"))) - (set (subreg:HI (match_dup 3) 0) - (const_int 0)) - (set (match_dup 4) - (sign_extend:HI (match_operand:QI 2 "general_operand" "g"))) - (set (match_dup 5) - (and:HI (match_dup 4) - (const_int 255))) - (set (match_dup 6) - (truncate:HI - (div:SI - (match_dup 3) - (sign_extend:SI (match_dup 5))))) - (set (match_operand:QI 0 "general_operand" "g") - (truncate:QI (match_dup 6)))] - "TARGET_45" - " -{ - operands[3] = gen_reg_rtx (SImode); - operands[4] = gen_reg_rtx (HImode); - operands[5] = gen_reg_rtx (HImode); - operands[6] = gen_reg_rtx (HImode); -}") - -;; we must restrict it to divide by 15-bit constant... -(define_expand "udivhi3" - [(set (subreg:HI (match_dup 3) 1) - (match_operand:HI 1 "general_operand" "g")) - (set (subreg:HI (match_dup 3) 0) - (const_int 0)) - (set (match_operand:HI 0 "general_operand" "g") - (truncate:HI - (div:SI - (match_dup 3) - (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n")))))] - "TARGET_45" - " -{ - operands[3] = gen_reg_rtx (SImode); - - if (GET_CODE (operands[2]) != CONST_INT - || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) - FAIL; -}") - -(define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r,r") 1) - (truncate:HI - (mod:SI - (match_operand:SI 1 "general_operand" "0,0") - (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rR,Q")))))] + [(set (subreg:HI (match_dup 1) 0) + (div:HI (match_operand:SI 1 "general_operand" "0") + (match_operand:HI 2 "general_operand" "g"))) + (set (match_operand:HI 0 "general_operand" "=r") + (subreg:HI (match_dup 1) 0))] "TARGET_45" - "div %2,%0" - [(set_attr "length" "1,2")]) + "") -;; (sign_extend:SI (const_int )) -; w/o -O -(define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) - (truncate:HI - (mod:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand 2 "immediate_operand" "i")))))] - "TARGET_45" - "div %2,%0" - [(set_attr "length" "2")]) -; w/ -O (define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) - (truncate:HI - (mod:SI - (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i"))))] + [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) + (div:HI (match_operand:SI 1 "general_operand" "0") + (match_operand:HI 2 "general_operand" "g")))] "TARGET_45" "div %2,%0" [(set_attr "length" "2")]) (define_expand "modhi3" - [(set (match_dup 3) - (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) - (set (subreg:HI (match_dup 3) 1) - (truncate:HI - (mod:SI - (match_dup 3) - (sign_extend:SI (match_operand:HI 2 "general_operand" "g"))))) - (set (match_operand:HI 0 "general_operand" "g") - (subreg:HI (match_dup 3) 1))] - "TARGET_45" - "operands[3] = gen_reg_rtx (SImode);") - -;; we must restrict it to mod by 15 bit constant -(define_expand "umodhi3" - [(set (subreg:HI (match_dup 3) 0) - (match_operand:HI 1 "general_operand" "g")) - (set (subreg:HI (match_dup 3) 1) - (const_int 0)) - (set (subreg:HI (match_dup 3) 1) - (truncate:HI - (mod:SI - (match_dup 3) - (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n"))))) - (set (match_operand:HI 0 "general_operand" "g") - (subreg:HI (match_dup 3) 1))] + [(set (subreg:HI (match_dup 1) 1) + (mod:HI (match_operand:SI 1 "general_operand" "0") + (match_operand:HI 2 "general_operand" "g"))) + (set (match_operand:HI 0 "general_operand" "=r") + (subreg:HI (match_dup 1) 1))] "TARGET_45" - " -{ - operands[3] = gen_reg_rtx (SImode); - - if (GET_CODE (operands[2]) != CONST_INT - || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) - FAIL; -}") - -(define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r,r") 0) - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0,0") - (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rR,Q"))))) - (set (subreg:HI (match_dup 0) 1) - (truncate:HI - (mod:SI - (match_dup 1) - (sign_extend:SI (match_dup 2)))))] - "TARGET_45" - "div %2, %0" - [(set_attr "length" "1,2")]) + "") -;; (sign_extend:SI (const_int)) -; w/o -O -(define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand 2 "immediate_operand" "i"))))) - (set (subreg:HI (match_dup 0) 1) - (truncate:HI - (mod:SI - (match_dup 1) - (sign_extend:SI (match_dup 2)))))] - "TARGET_45" - "div %2, %0" - [(set_attr "length" "2")]) -; w/ -O (define_insn "" - [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "immediate_operand" "i")))) - (set (subreg:HI (match_dup 0) 1) - (truncate:HI - (mod:SI - (match_dup 1) - (match_dup 2))))] + [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 1) + (mod:HI (match_operand:SI 1 "general_operand" "0") + (match_operand:HI 2 "general_operand" "g")))] "TARGET_45" - "div %2, %0" + "div %2,%0" [(set_attr "length" "2")]) -(define_expand "divmodhi4" - [(set (match_dup 4) - (sign_extend:SI (match_operand:HI 1 "general_operand" "g"))) - (set (subreg:HI (match_dup 4) 0) - (truncate:HI - (div:SI - (match_dup 4) - (sign_extend:SI (match_operand:HI 2 "general_operand" "g"))))) - (set (subreg:HI (match_dup 4) 1) - (truncate:HI - (mod:SI - (match_dup 4) - (sign_extend:SI (match_dup 2))))) - (set (match_operand:HI 0 "general_operand" "g") - (subreg:HI (match_dup 4) 0)) - (set (match_operand:HI 3 "general_operand" "g") - (subreg:HI (match_dup 4) 1))] - "TARGET_45" - "operands[4] = gen_reg_rtx(SImode);") - -(define_expand "udivmodhi4" - [(set (subreg:HI (match_dup 3) 1) - (match_operand:HI 1 "general_operand" "g")) - (set (subreg:HI (match_dup 3) 0) - (const_int 0)) - (set (subreg:HI (match_dup 4) 0) - (truncate:HI - (div:SI - (match_dup 4) - (sign_extend:SI (match_operand:HI 2 "immediate15_operand" "n"))))) - (set (subreg:HI (match_dup 4) 1) - (truncate:HI - (mod:SI - (match_dup 4) - (sign_extend:SI (match_dup 2))))) - (set (match_operand:HI 0 "general_operand" "g") - (subreg:HI (match_dup 4) 0)) - (set (match_operand:HI 3 "general_operand" "g") - (subreg:HI (match_dup 4) 1))] - "TARGET_45" - " -{ - operands[3] = gen_reg_rtx (SImode); - - if (GET_CODE (operands[2]) != CONST_INT - || ((INTVAL (operands[2]) & 0x8000) != 0x0000)) - FAIL; -}") - -;; truncate used in div/mod patterns -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=r,r") - (truncate:QI (match_operand:HI 1 "general_operand" "0,r")))] - "TARGET_45" - "@ - ; nop - movb %1, %0" - [(set_attr "length" "0,1")]) +;(define_expand "divmodhi4" +; [(parallel [(set (subreg:HI (match_dup 1) 0) +; (div:HI (match_operand:SI 1 "general_operand" "0") +; (match_operand:HI 2 "general_operand" "g"))) +; (set (subreg:HI (match_dup 1) 1) +; (mod:HI (match_dup 1) +; (match_dup 2)))]) +; (set (match_operand:HI 3 "general_operand" "=r") +; (subreg:HI (match_dup 1) 1)) +; (set (match_operand:HI 0 "general_operand" "=r") +; (subreg:HI (match_dup 1) 0))] +; "TARGET_45" +; "") +; +;(define_insn "" +; [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 0) +; (div:HI (match_operand:SI 1 "general_operand" "0") +; (match_operand:HI 2 "general_operand" "g"))) +; (set (subreg:HI (match_dup 0) 1) +; (mod:HI (match_dup 1) +; (match_dup 2)))] +; "TARGET_45" +; "div %2, %0") +; ;; is rotate doing the right thing to be included here ????