Andrew Geissler | 0903674 | 2021-06-25 14:25:14 -0500 | [diff] [blame^] | 1 | From 0061fabeb9393c362601486105202cfe837a5a68 Mon Sep 17 00:00:00 2001 |
| 2 | From: Claudiu Zissulescu <claziss@synopsys.com> |
| 3 | Date: Wed, 9 Jun 2021 12:12:57 +0300 |
| 4 | Subject: [PATCH] arc: Update 64bit move split patterns. |
| 5 | |
| 6 | ARCv2HS can use a limited number of instructions to implement 64bit |
| 7 | moves. The VADD2 is used as a 64bit move, the LDD/STD are 64 bit loads |
| 8 | and stores. All those instructions are not baseline, hence we need to |
| 9 | provide alternatives when they are not available or cannot be generate |
| 10 | due to instruction restriction. |
| 11 | |
| 12 | This patch is cleaning up those move patterns, and updates splits |
| 13 | instruction lengths. |
| 14 | |
| 15 | This is a backport from mainline gcc. |
| 16 | |
| 17 | gcc/ |
| 18 | 2021-06-09 Claudiu Zissulescu <claziss@synopsys.com> |
| 19 | |
| 20 | * config/arc/arc-protos.h (arc_split_move_p): New prototype. |
| 21 | * config/arc/arc.c (arc_split_move_p): New function. |
| 22 | (arc_split_move): Clean up. |
| 23 | * config/arc/arc.md (movdi_insn): Clean up, use arc_split_move_p. |
| 24 | (movdf_insn): Likewise. |
| 25 | * config/arc/simdext.md (mov<VWH>_insn): Likewise. |
| 26 | |
| 27 | Upstream-Status: Backport [https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0061fabeb9393c362601486105202cfe837a5a68] |
| 28 | |
| 29 | Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com> |
| 30 | (cherry picked from commit c0ba7a8af5366c37241f20e8be41e362f7260389) |
| 31 | Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> |
| 32 | --- |
| 33 | gcc/config/arc/arc-protos.h | 1 + |
| 34 | gcc/config/arc/arc.c | 44 ++++++++++++---------- |
| 35 | gcc/config/arc/arc.md | 91 +++++++++------------------------------------ |
| 36 | gcc/config/arc/simdext.md | 38 ++++--------------- |
| 37 | 4 files changed, 52 insertions(+), 122 deletions(-) |
| 38 | |
| 39 | diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h |
| 40 | index 1f56a0d82e4..62d7e45d29d 100644 |
| 41 | --- a/gcc/config/arc/arc-protos.h |
| 42 | +++ b/gcc/config/arc/arc-protos.h |
| 43 | @@ -50,6 +50,7 @@ extern void arc_split_ior (rtx *); |
| 44 | extern bool arc_check_mov_const (HOST_WIDE_INT ); |
| 45 | extern bool arc_split_mov_const (rtx *); |
| 46 | extern bool arc_can_use_return_insn (void); |
| 47 | +extern bool arc_split_move_p (rtx *); |
| 48 | #endif /* RTX_CODE */ |
| 49 | |
| 50 | extern bool arc_ccfsm_branch_deleted_p (void); |
| 51 | diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c |
| 52 | index 3201c3fefd7..db541bc11f5 100644 |
| 53 | --- a/gcc/config/arc/arc.c |
| 54 | +++ b/gcc/config/arc/arc.c |
| 55 | @@ -10129,6 +10129,31 @@ arc_process_double_reg_moves (rtx *operands) |
| 56 | return true; |
| 57 | } |
| 58 | |
| 59 | + |
| 60 | +/* Check if we need to split a 64bit move. We do not need to split it if we can |
| 61 | + use vadd2 or ldd/std instructions. */ |
| 62 | + |
| 63 | +bool |
| 64 | +arc_split_move_p (rtx *operands) |
| 65 | +{ |
| 66 | + machine_mode mode = GET_MODE (operands[0]); |
| 67 | + |
| 68 | + if (TARGET_LL64 |
| 69 | + && ((memory_operand (operands[0], mode) |
| 70 | + && (even_register_operand (operands[1], mode) |
| 71 | + || satisfies_constraint_Cm3 (operands[1]))) |
| 72 | + || (memory_operand (operands[1], mode) |
| 73 | + && even_register_operand (operands[0], mode)))) |
| 74 | + return false; |
| 75 | + |
| 76 | + if (TARGET_PLUS_QMACW |
| 77 | + && even_register_operand (operands[0], mode) |
| 78 | + && even_register_operand (operands[1], mode)) |
| 79 | + return false; |
| 80 | + |
| 81 | + return true; |
| 82 | +} |
| 83 | + |
| 84 | /* operands 0..1 are the operands of a 64 bit move instruction. |
| 85 | split it into two moves with operands 2/3 and 4/5. */ |
| 86 | |
| 87 | @@ -10146,25 +10171,6 @@ arc_split_move (rtx *operands) |
| 88 | return; |
| 89 | } |
| 90 | |
| 91 | - if (TARGET_LL64 |
| 92 | - && ((memory_operand (operands[0], mode) |
| 93 | - && (even_register_operand (operands[1], mode) |
| 94 | - || satisfies_constraint_Cm3 (operands[1]))) |
| 95 | - || (memory_operand (operands[1], mode) |
| 96 | - && even_register_operand (operands[0], mode)))) |
| 97 | - { |
| 98 | - emit_move_insn (operands[0], operands[1]); |
| 99 | - return; |
| 100 | - } |
| 101 | - |
| 102 | - if (TARGET_PLUS_QMACW |
| 103 | - && even_register_operand (operands[0], mode) |
| 104 | - && even_register_operand (operands[1], mode)) |
| 105 | - { |
| 106 | - emit_move_insn (operands[0], operands[1]); |
| 107 | - return; |
| 108 | - } |
| 109 | - |
| 110 | if (TARGET_PLUS_QMACW |
| 111 | && GET_CODE (operands[1]) == CONST_VECTOR) |
| 112 | { |
| 113 | diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md |
| 114 | index 7a52551eef5..91a838a38e4 100644 |
| 115 | --- a/gcc/config/arc/arc.md |
| 116 | +++ b/gcc/config/arc/arc.md |
| 117 | @@ -1329,47 +1329,20 @@ core_3, archs4x, archs4xd, archs4xd_slow" |
| 118 | "register_operand (operands[0], DImode) |
| 119 | || register_operand (operands[1], DImode) |
| 120 | || (satisfies_constraint_Cm3 (operands[1]) |
| 121 | - && memory_operand (operands[0], DImode))" |
| 122 | - "* |
| 123 | -{ |
| 124 | - switch (which_alternative) |
| 125 | - { |
| 126 | - default: |
| 127 | - return \"#\"; |
| 128 | - |
| 129 | - case 0: |
| 130 | - if (TARGET_PLUS_QMACW |
| 131 | - && even_register_operand (operands[0], DImode) |
| 132 | - && even_register_operand (operands[1], DImode)) |
| 133 | - return \"vadd2%?\\t%0,%1,0\"; |
| 134 | - return \"#\"; |
| 135 | - |
| 136 | - case 2: |
| 137 | - if (TARGET_LL64 |
| 138 | - && memory_operand (operands[1], DImode) |
| 139 | - && even_register_operand (operands[0], DImode)) |
| 140 | - return \"ldd%U1%V1 %0,%1%&\"; |
| 141 | - return \"#\"; |
| 142 | - |
| 143 | - case 3: |
| 144 | - if (TARGET_LL64 |
| 145 | - && memory_operand (operands[0], DImode) |
| 146 | - && (even_register_operand (operands[1], DImode) |
| 147 | - || satisfies_constraint_Cm3 (operands[1]))) |
| 148 | - return \"std%U0%V0 %1,%0\"; |
| 149 | - return \"#\"; |
| 150 | - } |
| 151 | -}" |
| 152 | - "&& reload_completed" |
| 153 | + && memory_operand (operands[0], DImode))" |
| 154 | + "@ |
| 155 | + vadd2\\t%0,%1,0 |
| 156 | + # |
| 157 | + ldd%U1%V1\\t%0,%1 |
| 158 | + std%U0%V0\\t%1,%0" |
| 159 | + "&& reload_completed && arc_split_move_p (operands)" |
| 160 | [(const_int 0)] |
| 161 | { |
| 162 | arc_split_move (operands); |
| 163 | DONE; |
| 164 | } |
| 165 | [(set_attr "type" "move,move,load,store") |
| 166 | - ;; ??? The ld/st values could be 4 if it's [reg,bignum]. |
| 167 | - (set_attr "length" "8,16,*,*")]) |
| 168 | - |
| 169 | + (set_attr "length" "8,16,16,16")]) |
| 170 | |
| 171 | ;; Floating point move insns. |
| 172 | |
| 173 | @@ -1408,50 +1381,22 @@ core_3, archs4x, archs4xd, archs4xd_slow" |
| 174 | (define_insn_and_split "*movdf_insn" |
| 175 | [(set (match_operand:DF 0 "move_dest_operand" "=D,r,r,r,r,m") |
| 176 | (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))] |
| 177 | - "register_operand (operands[0], DFmode) |
| 178 | - || register_operand (operands[1], DFmode)" |
| 179 | - "* |
| 180 | -{ |
| 181 | - switch (which_alternative) |
| 182 | - { |
| 183 | - default: |
| 184 | - return \"#\"; |
| 185 | - |
| 186 | - case 2: |
| 187 | - if (TARGET_PLUS_QMACW |
| 188 | - && even_register_operand (operands[0], DFmode) |
| 189 | - && even_register_operand (operands[1], DFmode)) |
| 190 | - return \"vadd2%?\\t%0,%1,0\"; |
| 191 | - return \"#\"; |
| 192 | - |
| 193 | - case 4: |
| 194 | - if (TARGET_LL64 |
| 195 | - && ((even_register_operand (operands[0], DFmode) |
| 196 | - && memory_operand (operands[1], DFmode)) |
| 197 | - || (memory_operand (operands[0], DFmode) |
| 198 | - && even_register_operand (operands[1], DFmode)))) |
| 199 | - return \"ldd%U1%V1 %0,%1%&\"; |
| 200 | - return \"#\"; |
| 201 | - |
| 202 | - case 5: |
| 203 | - if (TARGET_LL64 |
| 204 | - && ((even_register_operand (operands[0], DFmode) |
| 205 | - && memory_operand (operands[1], DFmode)) |
| 206 | - || (memory_operand (operands[0], DFmode) |
| 207 | - && even_register_operand (operands[1], DFmode)))) |
| 208 | - return \"std%U0%V0 %1,%0\"; |
| 209 | - return \"#\"; |
| 210 | - } |
| 211 | -}" |
| 212 | - "reload_completed" |
| 213 | + "(register_operand (operands[0], DFmode) |
| 214 | + || register_operand (operands[1], DFmode))" |
| 215 | + "@ |
| 216 | + # |
| 217 | + # |
| 218 | + vadd2\\t%0,%1,0 |
| 219 | + # |
| 220 | + ldd%U1%V1\\t%0,%1 |
| 221 | + std%U0%V0\\t%1,%0" |
| 222 | + "&& reload_completed && arc_split_move_p (operands)" |
| 223 | [(const_int 0)] |
| 224 | { |
| 225 | arc_split_move (operands); |
| 226 | DONE; |
| 227 | } |
| 228 | [(set_attr "type" "move,move,move,move,load,store") |
| 229 | - (set_attr "predicable" "no,no,no,yes,no,no") |
| 230 | - ;; ??? The ld/st values could be 16 if it's [reg,bignum]. |
| 231 | (set_attr "length" "4,16,8,16,16,16")]) |
| 232 | |
| 233 | (define_insn_and_split "*movdf_insn_nolrsr" |
| 234 | diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md |
| 235 | index f0900757452..36f41a5c3d0 100644 |
| 236 | --- a/gcc/config/arc/simdext.md |
| 237 | +++ b/gcc/config/arc/simdext.md |
| 238 | @@ -1402,41 +1402,19 @@ |
| 239 | (match_operand:VWH 1 "general_operand" "i,r,m,r"))] |
| 240 | "(register_operand (operands[0], <MODE>mode) |
| 241 | || register_operand (operands[1], <MODE>mode))" |
| 242 | - "* |
| 243 | -{ |
| 244 | - switch (which_alternative) |
| 245 | - { |
| 246 | - default: |
| 247 | - return \"#\"; |
| 248 | - |
| 249 | - case 1: |
| 250 | - if (TARGET_PLUS_QMACW |
| 251 | - && even_register_operand (operands[0], <MODE>mode) |
| 252 | - && even_register_operand (operands[1], <MODE>mode)) |
| 253 | - return \"vadd2%?\\t%0,%1,0\"; |
| 254 | - return \"#\"; |
| 255 | - |
| 256 | - case 2: |
| 257 | - if (TARGET_LL64) |
| 258 | - return \"ldd%U1%V1 %0,%1\"; |
| 259 | - return \"#\"; |
| 260 | - |
| 261 | - case 3: |
| 262 | - if (TARGET_LL64) |
| 263 | - return \"std%U0%V0 %1,%0\"; |
| 264 | - return \"#\"; |
| 265 | - } |
| 266 | -}" |
| 267 | - "reload_completed" |
| 268 | + "@ |
| 269 | + # |
| 270 | + vadd2\\t%0,%1,0 |
| 271 | + ldd%U1%V1\\t%0,%1 |
| 272 | + std%U0%V0\\t%1,%0" |
| 273 | + "&& reload_completed && arc_split_move_p (operands)" |
| 274 | [(const_int 0)] |
| 275 | { |
| 276 | arc_split_move (operands); |
| 277 | DONE; |
| 278 | } |
| 279 | - [(set_attr "type" "move,multi,load,store") |
| 280 | - (set_attr "predicable" "no,no,no,no") |
| 281 | - (set_attr "iscompact" "false,false,false,false") |
| 282 | - ]) |
| 283 | + [(set_attr "type" "move,move,load,store") |
| 284 | + (set_attr "length" "16,8,16,16")]) |
| 285 | |
| 286 | (define_expand "movmisalign<mode>" |
| 287 | [(set (match_operand:VWH 0 "general_operand" "") |
| 288 | -- |
| 289 | 2.16.2 |
| 290 | |