This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Attempting to add udivmodsi4 for ColdFire.



I'm trying to add in the long divide instructions that the 68020
supports which are in the coldfire 5407, etc.

The current m68k.md looks like:

(define_insn "udivmodsi4"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
	(udiv:SI (match_operand:SI 1 "general_operand" "0")
		 (match_operand:SI 2 "general_src_operand" "dmSTK")))
   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
	(umod:SI (match_dup 1) (match_dup 2)))]
  "TARGET_68020 && !TARGET_COLDFIRE"
  "*
{
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
    return \"divu%.l %2,%0\";
  else
    return \"divul%.l %2,%3:%0\";
}")

And I've changed it to:

(define_expand "udivmodsi4"
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
	(udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
		 (match_operand:SI 2 "general_src_operand" "")))
   (set (match_operand:SI 3 "nonimmediate_operand" "")
	(umod:SI (match_dup 1) (match_dup 2)))]
  "TARGET_68020 || TARGET_CF_HWDIV"
  "")

(define_insn "udivmodsi4_cf"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
	(udiv:SI (match_operand:SI 1 "nonimmediate_operand" "0")
		 (match_operand:SI 2 "general_src_operand" "d<Q>U")))
   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
	(umod:SI (match_dup 1) (match_dup 2)))]
  "TARGET_CF_HWDIV"
  "*
{
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
    return \"divu%.l %2,%0\";
  else if (find_reg_note (insn, REG_UNUSED, operands[0]))
    return \"remu%.l %2,%3:%0\";
  else
    return \"remu%.l %2,%3:%0\;divu%.l %2,%0\";
}")

(define_insn "udivmodsi4_68k"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
	(udiv:SI (match_operand:SI 1 "general_operand" "0")
		 (match_operand:SI 2 "general_src_operand" "dmSTK")))
   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
	(umod:SI (match_dup 1) (match_dup 2)))]
  "TARGET_68020"
  "*
{
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
    return \"divu%.l %2,%0\";
  else
    return \"divul%.l %2,%3:%0\";
}")

Where TARGET_CF_HWDIV is true if building for a coldfire that supports
the divide instructions that the 68020 has.  When I do, the compiler
build fails on _divdi3.o with:

/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-304/gcc/libgcc2.c: In function `__divdi3':
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-304/gcc/libgcc2.c:748: Unrecognizable insn:
(insn/i 114 113 116 (set (reg:SI 64)
        (udiv:SI (reg:SI 63)
            (reg/v:SI 52))) -1 (insn_list 113 (nil))
    (expr_list:REG_DEAD (reg:SI 63)
        (expr_list:REG_DEAD (reg/v:SI 52)
            (nil))))
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-304/gcc/libgcc2.c:748: Internal compiler error in extract_insn, at recog.c:2218

Since there is noe -m on the command line, then by default,
target_flags is 0x7 which indicates that TARGET_68020 is true, and
TARGE_CF_HWDIV is false.

Any ideas why this instruction was rejected?

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]