This is the mail archive of the gcc-help@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]

RFC: Very long alternative lists for RTL patterns like move


I realize the main focus right now is getting GCC 6 out the door, but I wanted
to start a discussion on something for GCC 7.  I added many of the global
maintainers and port maintainers, since a lot of us have similar problems.
Sorry for overloading your mailboxes.

I've been wondering if there any way to solve the problems of move insns and
others with very many alternatives.

To give an example, here is the 32-bit floating point move insn on the PowerPC:

(define_mode_iterator FMOVE32 [SF SD])

; Definitions for load to 32-bit fpr register
(define_mode_attr f32_lr  [(SF "f")		  (SD "wz")])
(define_mode_attr f32_lr2 [(SF "wb")		  (SD "wn")])
(define_mode_attr f32_lm  [(SF "m")		  (SD "Z")])
(define_mode_attr f32_lm2 [(SF "o")		  (SD "wn")])
(define_mode_attr f32_li  [(SF "lfs%U1%X1 %0,%1") (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_li2 [(SF "lxssp %0,%1")     (SD "lfiwzx %0,%y1")])
(define_mode_attr f32_lv  [(SF "lxsspx %x0,%y1")  (SD "lxsiwzx %x0,%y1")])

; Definitions for store from 32-bit fpr register
(define_mode_attr f32_sr  [(SF "f")		   (SD "wx")])
(define_mode_attr f32_sr2 [(SF "wb")		   (SD "wn")])
(define_mode_attr f32_sm  [(SF "m")		   (SD "Z")])
(define_mode_attr f32_sm2 [(SF "o")		   (SD "wn")])
(define_mode_attr f32_si  [(SF "stfs%U0%X0 %1,%0") (SD "stfiwx %1,%y0")])
(define_mode_attr f32_si2 [(SF "stxssp %1,%0")     (SD "stfiwx %1,%y0")])
(define_mode_attr f32_sv  [(SF "stxsspx %x1,%y0")  (SD "stxsiwzx %x1,%y0")])

; Definitions for 32-bit fpr direct move
; At present, the decimal modes are not allowed in the traditional altivec
; registers, so restrict the constraints to just the traditional FPRs.
(define_mode_attr f32_dm [(SF "wn") (SD "wh")])

; Definitions for 32-bit VSX
(define_mode_attr f32_vsx [(SF "ww") (SD "wn")])

; Definitions for 32-bit use of altivec registers
(define_mode_attr f32_av  [(SF "wu") (SD "wn")])

(define_insn "mov<mode>_hardfloat"
  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,?<f32_dm>,?r,*c*l,!r,*h")
	(match_operand:FMOVE32 1 "input_operand" "r,m,r,f,<f32_vsx>,j,j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,<f32_av>,r,<f32_dm>,r,h,0"))]
  "(gpc_reg_operand (operands[0], <MODE>mode)
   || gpc_reg_operand (operands[1], <MODE>mode))
   && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
  "@
   mr %0,%1
   lwz%U1%X1 %0,%1
   stw%U0%X0 %1,%0
   fmr %0,%1
   xscpsgndp %x0,%x1,%x1
   xxlxor %x0,%x0,%x0
   li %0,0
   <f32_li>
   <f32_li2>
   <f32_si>
   <f32_si2>
   <f32_lv>
   <f32_sv>
   mtvsrwz %x0,%1
   mfvsrwz %0,%x1
   mt%0 %1
   mf%1 %0
   nop"
  [(set_attr "type" "*,load,store,fp,fp,vecsimple,integer,fpload,fpload,fpstore,fpstore,fpload,fpstore,mffgpr,mftgpr,mtjmpr,mfjmpr,*")
   (set_attr "length" "4")])

The problem is you have count each alternative to get things to line up.

One thing that I do when editing rs6000.md is make the columns line up between
the different operands, and then edit it with a very wide emacs screen, for
example:

(define_insn "mov<mode>_hardfloat"
  [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=!r,!r,m,f,<f32_vsx>,<f32_vsx>,!r,<f32_lr>,<f32_lr2>,<f32_sm>,<f32_sm2>,<f32_av>,Z,      ?<f32_dm>,?r,      *c*l,!r,*h")
	(match_operand:FMOVE32 1 "input_operand"          "r, m,r,f,<f32_vsx>,j,         j,<f32_lm>,<f32_lm2>,<f32_sr>,<f32_sr2>,Z,       <f32_av>,r,        <f32_dm>,r,   h, 0"))]

Before submitting it, I collapse the alternatives down to the original form
(usually).  However, you still have to manually count each alternative to make
sure the instructions and set_attr's are set for the proper one.

I've been thinking that maybe we could introduce some way to make these be easier to specify.

One thought I've had is to have a define_alternative meta patterns.  Something like:

(define_alternative
  (define_insn "mov<move>_hardfloat"
    [(set (match_operand:FMOVE32 0 "non_immediate_operand" "=^")
          (match_operand:FMOVE32 1 "input_operand" "^"))]
    "(gpc_reg_operand (operands[0], <MODE>mode)
     || gpc_reg_operand (operands[1], <MODE>mode))
     && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)"
    "@
     ^"
    [(set_attr "type" "^")
     (set_attr "length" "4")])

  [("!r" "r" "mr %0,%1"        "*")
   ("!r" "m" "lwz%U1%X1 %0,%1" "load")
   ("m"  "r" "stw%U0%X0 %1,%0" "store")
   ...])

Where the ^'s (or some other character/string) are replaced by a comma/newline
separated list to make the original define_insn.  We would need at least
define_insn and define_insn_and_split.  It should make it easy to keep track of
the alternatives, and add new ones.

I don't really care what syntax we use, I'm just getting tired of editing these
overlong move patterns and making sure things line up.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797


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