msp430.md (zero_extendqipsi2): New.
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Tue, 15 Oct 2019 12:24:53 +0000 (12:24 +0000)
committerJozef Lawrynowicz <jozefl@gcc.gnu.org>
Tue, 15 Oct 2019 12:24:53 +0000 (12:24 +0000)
2019-10-15  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

* config/msp430/msp430.md (zero_extendqipsi2): New.
(zero_extendqisi2): Optimize case where src register and base dst
register are the same.
(zero_extendhipsi2): Don't use 430X insn for rYs->r case.
(zero_extendpsisi2): Optimize r->m case.
Add unnamed insn patterns to catch insns combine searches for when
optimizing pointer manipulation.

From-SVN: r276997

gcc/ChangeLog
gcc/config/msp430/msp430.md

index ff2c70f..ba6121f 100644 (file)
@@ -1,5 +1,15 @@
 2019-10-15  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
+       * config/msp430/msp430.md (zero_extendqipsi2): New.
+       (zero_extendqisi2): Optimize case where src register and base dst
+       register are the same.
+       (zero_extendhipsi2): Don't use 430X insn for rYs->r case.
+       (zero_extendpsisi2): Optimize r->m case.
+       Add unnamed insn patterns to catch insns combine searches for when
+       optimizing pointer manipulation.
+
+2019-10-15  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
        * config/msp430/msp430.md: Group zero_extend* insns together.
 
 2019-10-15  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
index 2e8e832..da4abe9 100644 (file)
    SXT%X0\t%0"
 )
 
+;; ------------------------
+;; ZERO EXTEND INSTRUCTIONS
+;; Byte-writes to registers clear bits 19:8
+;;   * Byte-writes to memory do not affect bits 15:8
+;; Word-writes to registers clear bits 19:16
+;; PSImode writes to memory clear bits 15:4 of the second memory word
+;; We define all possible insns since that results in better code than if
+;; they are inferred.
+;; ------------------------
+
 (define_insn "zero_extendqihi2"
   [(set (match_operand:HI                0 "msp430_general_dst_operand" "=rYs,r,r,m")
        (zero_extend:HI (match_operand:QI 1 "msp430_general_operand" "0,rYs,m,0")))]
    AND%X0\t#0xff, %0"
 )
 
+(define_insn "zero_extendqipsi2"
+  [(set (match_operand:PSI                0 "register_operand" "=r,r")
+       (zero_extend:PSI (match_operand:QI 1 "general_operand" "rYs,m")))]
+  "msp430x"
+  "@
+   MOV.B\t%1, %0
+   MOV%X1.B\t%1, %0"
+)
+
 (define_insn "zero_extendqisi2"
-  [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r")
-       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
+  [(set (match_operand:SI 0 "msp430_general_dst_nonv_operand" "=r,r")
+       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,rm")))]
   ""
-  "MOV%X1.B\t%1,%L0 { CLR\t%H0"
+  "@
+  CLR\t%H0
+  MOV%X1.B\t%1,%L0 { CLR\t%H0"
 )
 
 (define_insn "zero_extendhipsi2"
-  [(set (match_operand:PSI                0 "msp430_general_dst_operand" "=r,m")
-       (zero_extend:PSI (match_operand:HI 1 "msp430_general_operand" "rm,r")))]
-  ""
+  [(set (match_operand:PSI                0 "msp430_general_dst_operand" "=r,r,m")
+       (zero_extend:PSI (match_operand:HI 1 "msp430_general_operand"     "rYs,m,r")))]
+  "msp430x"
   "@
-  MOVX\t%1, %0
+  MOV.W\t%1, %0
+  MOV%X1\t%1, %0
   MOVX.A\t%1, %0"
 )
 
 ; the pair is unused and so it can clobber it.  Try compiling 20050826-2.c
 ; at -O2 to see this.
 
+; FIXME we can use MOVA for r->m if m is &abs20 or z16(rdst)
 (define_insn "zero_extendpsisi2"
-  [(set (match_operand:SI                  0 "register_operand" "+r")
-       (zero_extend:SI (match_operand:PSI 1 "register_operand" "r")))]
+  [(set (match_operand:SI                 0 "register_operand" "+r,m")
+       (zero_extend:SI (match_operand:PSI 1 "register_operand" "r,r")))]
   ""
-  "*
-    if (REGNO (operands[1]) == SP_REGNO)
-      /* If the source register is the stack pointer, the value
-         stored in the stack slot will be the value *after* the
-        stack pointer has been decremented.  So allow for that
-        here.  */
-      return \"PUSHM.A\t#1, %1 { ADDX.W\t#4, @r1 { POPX.W\t%L0 { POPX.W\t%H0 ; get stack pointer into %L0:%H0\";
-    else
+  "@
+  * if (REGNO (operands[1]) == SP_REGNO) \
+      /* If the source register is the stack pointer, the value \
+        stored in the stack slot will be the value *after* the \
+        stack pointer has been decremented.  So allow for that \
+        here.  */ \
+      return \"PUSHM.A\t#1, %1 { ADDX.W\t#4, @r1 { POPX.W\t%L0 { POPX.W\t%H0 ; get stack pointer into %L0:%H0\"; \
+    else \
       return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
-  "
+  MOVX.A %1, %0"
+)
+
+;; Below are unnamed insn patterns to catch pointer manipulation insns
+;; generated by combine.
+;; We get large code size bloat when a PSImode pointer is stored in
+;; memory, so we try to avoid that where possible and keep point manipulation
+;; between registers.
+; FIXME many of these should be unnnecessary once combine deals with
+; (sign_extend (zero_extend)) or (sign_extend (subreg)) BZ 91865.
+
+;; This is just another way of writing movqipsi/zero_extendqipsi
+(define_insn ""
+  [(set (match_operand:PSI 0 "register_operand" "=r")
+       (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0)))]
+  "msp430x"
+  "MOV%X1.B\t%1, %0"
 )
 
+(define_insn ""
+  [(set (match_operand:PSI                                0 "register_operand" "=r,r")
+       (sign_extend:PSI (zero_extend:HI (match_operand:QI 1 "general_operand" "rYs,m"))))]
+  "msp430x"
+  "@
+   MOV.B\t%1, %0
+   MOV%X1.B\t%1, %0"
+)
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ashift:SI (zero_extend:SI (match_operand:QI 1 "general_operand" "rm"))
+                  (match_operand:HI 2 "immediate_operand" "M")))]
+  "msp430x"
+  "MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0"
+)
+
+;; We are taking a char and shifting it and putting the result in 2 registers.
+;; the high register will always be for 0 shift counts < 8.
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ashift:SI (zero_extend:SI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0))
+                  (match_operand:HI 2 "immediate_operand" "M")))]
+  "msp430x"
+  "MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0"
+)
+
+;; Same as above but with a NOP sign_extend round the subreg
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ashift:SI (zero_extend:SI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0)))
+                  (match_operand:HI 2 "immediate_operand" "M")))]
+  "msp430x"
+  "MOV%X1.B %1, %L0 { RLAM.W %2, %L0 { CLR %H0"
+)
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (zero_extend:SI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0))))]
+  "msp430x"
+  "MOV%X1.B %1, %L0 { CLR %H0"
+)
+
+(define_insn ""
+  [(set (match_operand:PSI 0 "register_operand" "=r")
+       (ashift:PSI (sign_extend:PSI (subreg:HI (match_operand:QI 1 "general_operand" "rm") 0))
+                   (match_operand:HI 2 "immediate_operand" "M")))]
+  "msp430x"
+  "MOV%X1.B %1, %0 { RLAM.W %2, %0"
+)
+;; END msp430 pointer manipulation combine insn patterns
 
 ;; Eliminate extraneous zero-extends mysteriously created by gcc.
 (define_peephole2