[patch] MIPS/gcc: Revert removal of DImode shifts for 32-bit targets

Nigel Stephens nigel@mips.com
Tue Aug 3 10:05:00 GMT 2004



Richard Sandiford wrote:

>I think we should only use define_expands if there's a truly
>MIPS-specific feature in the expansion (as there is in the block
>move stuff, for example, where we use left/right loads and stores).
>
>  
>

Fair enough.

>Now obviously I'm only guessing what insn sequence you're using,
>  
>

OK, the simplest thing is for me to attach the define_insns. See below.

Note that there is one slightly controversial aspect of these sequences, 
which is that they don't truncate the shift count, so a shift outside of 
the range 0 to 63 will generate an "unusual" result.  This didn't cause 
any regression failures, and I believe that this is strictly speaking 
acceptable for C, since a shift is undefined outside of this range - but 
it could cause some "buggy" code to break. It wouldn't be hard to add an 
extra mask with 0x3f if people were nervous about this - it's just that 
I didn't have enough spare temp registers within the constraints of the 
existing DImode patterns.

---- cut here ---

;; XXX Would be better done using define_expand, so it can be scheduled
;; XXX Note won't handle a shift count outside the range 0 - 63
(define_insn "ashldi3_internal_movc"
  [(set (match_operand:DI 0 "register_operand" "=&d")
    (ashift:DI (match_operand:DI 1 "register_operand" "d")
           (match_operand:SI 2 "register_operand" "d")))
   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
  "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
   && ISA_HAS_CONDMOVE"
  "subu\t%3,%.,%2\;\
sll\t%M0,%M1,%2\;\
srl\t%3,%L1,%3\;\
sll\t%L0,%L1,%2\;\
movz\t%3,%.,%2\;\
or\t%M0,%M0,%3\;\
and\t%3,%2,32\;\
movn\t%M0,%L0,%3\;\
movn\t%L0,%.,%3"
  [(set_attr "type"    "darith")
   (set_attr "mode"    "DI")
   (set_attr "length"    "36")])

;; Same length as before, but avoids branches
;; XXX Note won't handle a shift count outside the range 0 - 63
(define_insn "ashrdi3_internal_movc"
  [(set (match_operand:DI 0 "register_operand" "=&d")
    (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
             (match_operand:SI 2 "register_operand" "d")))
   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
  "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
   && ISA_HAS_CONDMOVE"
  "subu\t%3,%.,%2\;\
srl\t%L0,%L1,%2\;\
sll\t%3,%M1,%3\;\
sra\t%M0,%M1,%2\;\
movz\t%3,%.,%2\;\
or\t%L0,%L0,%3\;\
and\t%3,%2,32\;\
movn\t%L0,%M0,%3\;\
movn\t%M0,%.,%3\;\
movn\t%3,%L0,%3\;\
sra\t%3,%3,31\;\
or\t%M0,%M0,%3"
  [(set_attr "type"    "darith")
   (set_attr "mode"    "DI")
   (set_attr "length"    "48")])

;;; XXX Note won't handle a shift count outside the range 0 - 63
(define_insn "lshrdi3_internal_movc"
  [(set (match_operand:DI 0 "register_operand" "=&d")
    (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
             (match_operand:SI 2 "register_operand" "d")))
   (clobber (match_operand:SI 3 "register_operand" "=&d"))]
  "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16
   && ISA_HAS_CONDMOVE"
  "subu\t%3,%.,%2\;\
srl\t%L0,%L1,%2\;\
sll\t%3,%M1,%3\;\
srl\t%M0,%M1,%2\;\
movz\t%3,%.,%2\;\
or\t%L0,%L0,%3\;\
and\t%3,%2,32\;\
movn\t%L0,%M0,%3\;\
movn\t%M0,%.,%3"
  [(set_attr "type"    "darith")
   (set_attr "mode"    "DI")
   (set_attr "length"    "36")])



More information about the Gcc-patches mailing list