Attempting to add udivmodsi4 for ColdFire.

Peter Barada pbarada@mail.wm.sps.mot.com
Thu Mar 7 16:14:00 GMT 2002


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)



More information about the Gcc mailing list