From a0a9a3fc22d4d4a38c1d6a31669c926734308745 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Tue, 15 Oct 2019 12:24:53 +0000 Subject: [PATCH] msp430.md (zero_extendqipsi2): New. 2019-10-15 Jozef Lawrynowicz * 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 | 10 +++ gcc/config/msp430/msp430.md | 126 ++++++++++++++++++++++++++++++------ 2 files changed, 118 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff2c70f30bd..ba6121f8ca6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-10-15 Jozef Lawrynowicz + + * 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 * config/msp430/msp430.md: Group zero_extend* insns together. diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index 2e8e8326232..da4abe94031 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 -- 2.30.2