aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJozef Lawrynowicz <jozef.l@mittosystems.com>2019-10-15 12:24:53 +0000
committerJozef Lawrynowicz <jozefl@gcc.gnu.org>2019-10-15 12:24:53 +0000
commita0a9a3fc22d4d4a38c1d6a31669c926734308745 (patch)
treeffca4c449ba5675f445e65a7c0b30ce1586a2511
parent582b4055ca4dc4260ab1092c6b39b3e792362c23 (diff)
downloadgcc-a0a9a3fc22d4d4a38c1d6a31669c926734308745.zip
gcc-a0a9a3fc22d4d4a38c1d6a31669c926734308745.tar.gz
gcc-a0a9a3fc22d4d4a38c1d6a31669c926734308745.tar.bz2
msp430.md (zero_extendqipsi2): New.
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/msp430/msp430.md126
2 files changed, 118 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff2c70f..ba6121f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index 2e8e832..da4abe9 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -553,6 +553,16 @@
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")))]
@@ -564,19 +574,31 @@
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"
)
@@ -616,22 +638,90 @@
; 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