1 ;; Machine Description for Renesas RL78 processors 2 ;; Copyright (C) 2011-2022 Free Software Foundation, Inc. 3 ;; Contributed by Red Hat. 4 5 ;; This file is part of GCC. 6 7 ;; GCC is free software; you can redistribute it and/or modify 8 ;; it under the terms of the GNU General Public License as published by 9 ;; the Free Software Foundation; either version 3, or (at your option) 10 ;; any later version. 11 12 ;; GCC is distributed in the hope that it will be useful, 13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 ;; GNU General Public License for more details. 16 17 ;; You should have received a copy of the GNU General Public License 18 ;; along with GCC; see the file COPYING3. If not see 19 ;; <http://www.gnu.org/licenses/>. 20 22 ;;---------- Moving ------------------------ 23 24 (define_expand "movqi" 25 [(set (match_operand:QI 0 "nonimmediate_operand") 26 (match_operand:QI 1 "general_operand"))] 27 "" 28 { 29 if (MEM_P (operands[0]) && MEM_P (operands[1])) 30 operands[1] = copy_to_mode_reg (QImode, operands[1]); 31 if (rl78_far_p (operands[0]) && rl78_far_p (operands[1])) 32 operands[1] = copy_to_mode_reg (QImode, operands[1]); 33 34 /* GCC can generate (SUBREG (SYMBOL_REF)) when it has to store a symbol 35 into a bitfield, or a packed ordinary field. We can handle this 36 provided that the destination is a register. If not, then load the 37 source into a register first. */ 38 if (GET_CODE (operands[1]) == SUBREG 39 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 40 && ! REG_P (operands[0])) 41 operands[1] = copy_to_mode_reg (QImode, operands[1]); 42 43 /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). 44 cf. g++.dg/abi/packed.C. */ 45 if (GET_CODE (operands[1]) == SUBREG 46 && GET_CODE (XEXP (operands[1], 0)) == CONST 47 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS 48 && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF 49 && ! REG_P (operands[0])) 50 operands[1] = copy_to_mode_reg (QImode, operands[1]); 51 52 if (CONST_INT_P (operands[1]) && ! IN_RANGE (INTVAL (operands[1]), (HOST_WIDE_INT_M1U << 8) + 1, (1 << 8) - 1)) 53 FAIL; 54 } 55 ) 56 57 (define_expand "movhi" 58 [(set (match_operand:HI 0 "nonimmediate_operand") 59 (match_operand:HI 1 "general_operand"))] 60 "" 61 { 62 if (MEM_P (operands[0]) && MEM_P (operands[1])) 63 operands[1] = copy_to_mode_reg (HImode, operands[1]); 64 if (rl78_far_p (operands[0]) && rl78_far_p (operands[1])) 65 operands[1] = copy_to_mode_reg (HImode, operands[1]); 66 67 /* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)), 68 but it does. Since this makes no sense, reject it here. */ 69 if (GET_CODE (operands[1]) == SUBREG 70 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) 71 FAIL; 72 /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). */ 73 if (GET_CODE (operands[1]) == SUBREG 74 && GET_CODE (XEXP (operands[1], 0)) == CONST 75 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS 76 && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF) 77 FAIL; 78 } 79 ) 80 81 (define_insn_and_split "movsi" 82 [(set (match_operand:SI 0 "nonimmediate_operand" "=vYS,v,Wfr") 83 (match_operand:SI 1 "general_operand" "viYS,Wfr,v"))] 84 "" 85 "#" 86 "" 87 [(set (match_operand:HI 2 "nonimmediate_operand") 88 (match_operand:HI 4 "general_operand")) 89 (set (match_operand:HI 3 "nonimmediate_operand") 90 (match_operand:HI 5 "general_operand"))] 91 "rl78_split_movsi (operands, SImode);" 92 [(set_attr "valloc" "op1")] 93 ) 94 95 (define_insn_and_split "movsf" 96 [(set (match_operand:SF 0 "nonimmediate_operand" "=vYS,v,Wfr") 97 (match_operand:SF 1 "general_operand" "viYS,Wfr,v"))] 98 "" 99 "#" 100 "" 101 [(set (match_operand:HI 2 "nonimmediate_operand") 102 (match_operand:HI 4 "general_operand")) 103 (set (match_operand:HI 3 "nonimmediate_operand") 104 (match_operand:HI 5 "general_operand"))] 105 "rl78_split_movsi (operands, SFmode);" 106 [(set_attr "valloc" "op1")] 107 ) 108 109 (define_expand "bswaphi2" 110 [(set (match_operand:HI 0 "nonimmediate_operand") 111 (bswap:HI (match_operand:HI 1 "general_operand")))] 112 "" 113 "if (rl78_force_nonfar_2 (operands, gen_bswaphi2)) 114 DONE;" 115 ) 116 117 ;;---------- Conversions ------------------------ 118 119 (define_expand "zero_extendqihi2" 120 [(set (match_operand:HI 0 "nonimmediate_operand") 121 (zero_extend:HI (match_operand:QI 1 "general_operand")))] 122 "" 123 "if (rl78_force_nonfar_2 (operands, gen_zero_extendqihi2)) 124 DONE;" 125 ) 126 127 (define_expand "extendqihi2" 128 [(set (match_operand:HI 0 "nonimmediate_operand") 129 (sign_extend:HI (match_operand:QI 1 "general_operand")))] 130 "" 131 "if (rl78_force_nonfar_2 (operands, gen_extendqihi2)) 132 DONE;" 133 ) 134 135 ;;---------- Arithmetic ------------------------ 136 137 (define_expand "add<mode>3" 138 [(set (match_operand:QHI 0 "nonimmediate_operand") 139 (plus:QHI (match_operand:QHI 1 "general_operand") 140 (match_operand:QHI 2 "general_operand"))) 141 ] 142 "" 143 "if (rl78_force_nonfar_3 (operands, gen_add<mode>3)) 144 DONE;" 145 ) 146 147 (define_expand "sub<mode>3" 148 [(set (match_operand:QHI 0 "nonimmediate_operand") 149 (minus:QHI (match_operand:QHI 1 "general_operand") 150 (match_operand:QHI 2 "general_operand"))) 151 ] 152 "" 153 "if (rl78_force_nonfar_3 (operands, gen_sub<mode>3)) 154 DONE;" 155 ) 156 157 (define_expand "neg<mode>2" 158 [(set (match_operand:QHI 0 "nonimmediate_operand") 159 (minus:QHI (const_int 0) 160 (match_operand:QHI 1 "general_operand"))) 161 ] 162 "" 163 "if (rl78_force_nonfar_2 (operands, gen_neg<mode>2)) 164 DONE;" 165 ) 166 167 (define_expand "umulqihi3" 168 [(set (match_operand:HI 0 "register_operand") 169 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand")) 170 (zero_extend:HI (match_operand:QI 2 "register_operand"))))] 171 "" 172 "" 173 ) 174 175 (define_expand "andqi3" 176 [(set (match_operand:QI 0 "rl78_nonimmediate_operand") 177 (and:QI (match_operand:QI 1 "rl78_general_operand") 178 (match_operand:QI 2 "rl78_general_operand"))) 179 ] 180 "" 181 "if (rl78_force_nonfar_3 (operands, gen_andqi3)) 182 DONE;" 183 ) 184 185 (define_expand "iorqi3" 186 [(set (match_operand:QI 0 "rl78_nonimmediate_operand") 187 (ior:QI (match_operand:QI 1 "rl78_general_operand") 188 (match_operand:QI 2 "rl78_general_operand"))) 189 ] 190 "" 191 "if (rl78_force_nonfar_3 (operands, gen_iorqi3)) 192 DONE;" 193 ) 194 195 (define_expand "xorqi3" 196 [(set (match_operand:QI 0 "rl78_nonimmediate_operand") 197 (xor:QI (match_operand:QI 1 "rl78_general_operand") 198 (match_operand:QI 2 "rl78_general_operand"))) 199 ] 200 "" 201 "if (rl78_force_nonfar_3 (operands, gen_xorqi3)) 202 DONE;" 203 ) 204 205 (define_expand "one_cmplqi2" 206 [(set (match_operand:QI 0 "nonimmediate_operand") 207 (xor:QI (match_operand:QI 1 "general_operand") 208 (const_int -1))) 209 ] 210 "" 211 "if (rl78_force_nonfar_2 (operands, gen_one_cmplqi2)) 212 DONE;" 213 ) 214 215 ;;---------- Shifts ------------------------ 216 217 (define_expand "ashl<mode>3" 218 [(set (match_operand:QHI 0 "nonimmediate_operand") 219 (ashift:QHI (match_operand:QHI 1 "general_operand") 220 (match_operand:QI 2 "general_operand"))) 221 ] 222 "" 223 "if (rl78_force_nonfar_3 (operands, gen_ashl<mode>3)) 224 DONE;" 225 ) 226 227 (define_expand "ashr<mode>3" 228 [(set (match_operand:QHI 0 "nonimmediate_operand") 229 (ashiftrt:QHI (match_operand:QHI 1 "general_operand") 230 (match_operand:QI 2 "general_operand"))) 231 ] 232 "" 233 "if (rl78_force_nonfar_3 (operands, gen_ashr<mode>3)) 234 DONE;" 235 ) 236 237 (define_expand "lshr<mode>3" 238 [(set (match_operand:QHI 0 "nonimmediate_operand") 239 (lshiftrt:QHI (match_operand:QHI 1 "general_operand") 240 (match_operand:QI 2 "general_operand"))) 241 ] 242 "" 243 "if (rl78_force_nonfar_3 (operands, gen_lshr<mode>3)) 244 DONE;" 245 ) 246 247 (define_expand "ashrsi3" 248 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 249 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 250 (match_operand:SI 2 "nonmemory_operand"))) 251 (clobber (reg:HI X_REG))]) 252 ] 253 "" 254 "" 255 ) 256 257 (define_expand "lshrsi3" 258 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 259 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 260 (match_operand:SI 2 "nonmemory_operand"))) 261 (clobber (reg:HI X_REG))]) 262 ] 263 "" 264 "" 265 ) 266 267 (define_expand "ashlsi3" 268 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 269 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 270 (match_operand:SI 2 "nonmemory_operand"))) 271 (clobber (reg:HI X_REG))]) 272 ] 273 "" 274 "" 275 ) 276 277 ;;---------- Branching ------------------------ 278 279 (define_expand "indirect_jump" 280 [(set (pc) 281 (match_operand:HI 0 "nonimmediate_operand"))] 282 "" 283 "" 284 ) 285 286 (define_expand "call" 287 [(call (match_operand:HI 0 "memory_operand") 288 (match_operand 1 ""))] 289 "" 290 "" 291 ) 292 293 (define_expand "call_value" 294 [(set (match_operand 0 "register_operand") 295 (call (match_operand:HI 1 "memory_operand") 296 (match_operand 2 "")))] 297 "" 298 "" 299 ) 300 301 (define_expand "cbranchqi4" 302 [(set (pc) (if_then_else 303 (match_operator 0 "rl78_cmp_operator" 304 [(match_operand:QI 1 "general_operand") 305 (match_operand:QI 2 "general_operand")]) 306 (label_ref (match_operand 3 "" "")) 307 (pc)))] 308 "" 309 "rl78_expand_compare (operands);" 310 ) 311 312 (define_expand "cbranchhi4" 313 [(set (pc) (if_then_else 314 (match_operator 0 "rl78_cmp_operator" 315 [(match_operand:HI 1 "general_operand") 316 (match_operand:HI 2 "general_operand")]) 317 (label_ref (match_operand 3 "" "")) 318 (pc)))] 319 "" 320 "rl78_expand_compare (operands);" 321 ) 322 323 (define_expand "cbranchsi4" 324 [(parallel [(set (pc) (if_then_else 325 (match_operator 0 "rl78_cmp_operator" 326 [(match_operand:SI 1 "general_operand") 327 (match_operand:SI 2 "nonmemory_operand")]) 328 (label_ref (match_operand 3 "" "")) 329 (pc))) 330 (clobber (reg:HI AX_REG)) 331 ])] 332 "1" 333 "rl78_expand_compare (operands);" 334 ) 335