1;; Machine Description for Renesas RL78 processors 2;; Copyright (C) 2011-2013 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 21(define_constants 22 [ 23 (AX_REG 0) 24 (X_REG 0) 25 (A_REG 1) 26 (BC_REG 2) 27 (C_REG 2) 28 (B_REG 3) 29 (DE_REG 4) 30 (E_REG 4) 31 (D_REG 5) 32 (HL_REG 6) 33 (L_REG 6) 34 (H_REG 7) 35 36 (FP_REG 22) 37 (SP_REG 32) 38 (CC_REG 33) 39 (ES_REG 35) 40 (CS_REG 36) 41 42 (UNS_PROLOG 1) 43 (UNS_EPILOG 1) 44 (UNS_RETI 2) 45 (UNS_RETB 3) 46 47 (UNS_SET_RB 10) 48 49 (UNS_TRAMPOLINE_INIT 20) 50 (UNS_TRAMPOLINE_UNINIT 21) 51 (UNS_NONLOCAL_GOTO 22) 52 53 ]) 54 55(define_insn "nop" 56 [(const_int 0)] 57 "" 58 "nop" 59 ) 60 61(define_mode_iterator QHI [QI HI]) 62 63(include "predicates.md") 64(include "constraints.md") 65(include "rl78-expand.md") 66(include "rl78-virt.md") 67(include "rl78-real.md") 68 69 70;; Function Prologue/Epilogue Instructions 71 72(define_expand "prologue" 73 [(const_int 0)] 74 "" 75 "rl78_expand_prologue (); DONE;" 76) 77 78(define_expand "epilogue" 79 [(const_int 0)] 80 "" 81 "rl78_expand_epilogue (); DONE;" 82) 83 84(define_expand "sibcall_epilogue" 85 [(return)] 86 "" 87 "FAIL;" 88) 89 90(define_insn "rl78_return" 91 [(return)] 92 "" 93 "ret" 94) 95 96(define_insn "interrupt_return" 97 [(unspec_volatile [(return)] UNS_RETI) ] 98 "" 99 "reti" 100) 101 102(define_insn "brk_interrupt_return" 103 [(unspec_volatile [(return)] UNS_RETB) ] 104 "" 105 "retb" 106) 107 108(define_expand "eh_return" 109 [(match_operand:HI 0 "" "")] 110 "" 111 "rl78_expand_eh_epilogue (operands[0]); 112 emit_barrier (); 113 DONE;" 114) 115 116;; These are used only by prologue/epilogue so it's "safe" to pass 117;; virtual registers. 118(define_insn "push" 119 [(set (reg:HI SP_REG) 120 (plus:HI (reg:HI SP_REG) 121 (const_int -2))) 122 (set (mem:HI (reg:HI SP_REG)) 123 (match_operand:HI 0 "register_operand" "ABDT,vZint"))] 124 "" 125 "@ 126 push\t%v0 127 push\t%v0 ; %0" 128) 129 130(define_insn "pop" 131 [(set (match_operand:HI 0 "register_operand" "=ABDT,vZint") 132 (mem:HI (reg:HI SP_REG))) 133 (set (reg:HI SP_REG) 134 (plus:HI (reg:HI SP_REG) 135 (const_int 2)))] 136 "" 137 "@ 138 pop\t%v0 139 pop\t%v0 ; %0" 140) 141 142(define_insn "sel_rb" 143 [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)] 144 "" 145 "sel\trb%u0" 146 ) 147 148(define_insn "trampoline_init" 149 [(set (match_operand 0 "register_operand" "=Z08W") 150 (unspec_volatile [(match_operand 1 "register_operand" "Z08W") 151 (match_operand 2 "register_operand" "Z10W") 152 ] UNS_TRAMPOLINE_INIT)) 153 ] 154 "" 155 "call !!___trampoline_init ; %0 <= %1 %2" 156 ) 157 158(define_insn "trampoline_uninit" 159 [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT) 160 ] 161 "" 162 "call !!___trampoline_uninit" 163 ) 164 165;; GCC restores $fp *before* using it to access values on the *old* 166;; frame. So, we do it ourselves, to ensure this is not the case. 167;; Note that while %1 is usually a label_ref, we allow for a 168;; non-immediate as well. 169(define_expand "nonlocal_goto" 170 [(set (pc) 171 (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore) 172 (match_operand 1 "" "vi") ;; target 173 (match_operand 2 "" "vi") ;; sp 174 (match_operand 3 "" "vi") ;; ? 175 ] UNS_NONLOCAL_GOTO)) 176 ] 177 "" 178 "emit_jump_insn (gen_nonlocal_goto_insn (operands[0], operands[1], operands[2], operands[3])); 179 emit_barrier (); 180 DONE;" 181 ) 182 183(define_insn "nonlocal_goto_insn" 184 [(set (pc) 185 (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore) 186 (match_operand 1 "" "vi") ;; target 187 (match_operand 2 "" "vi") ;; sp 188 (match_operand 3 "" "vi") ;; ? 189 ] UNS_NONLOCAL_GOTO)) 190 ] 191 "" 192 "; nonlocal goto 193 movw ax, %3 194 movw r22, ax 195 movw ax, %2 196 movw sp, ax 197 movw ax, %1 198 br ax 199" 200 ) 201 202;;====================================================================== 203;; 204;; "macro" insns - cases where inline chunks of code are more 205;; efficient than anything else. 206 207(define_expand "addsi3" 208 [(set (match_operand:SI 0 "register_operand" "=&v") 209 (plus:SI (match_operand:SI 1 "nonmemory_operand" "vi") 210 (match_operand 2 "nonmemory_operand" "vi"))) 211 ] 212 "" 213 "if (!nonmemory_operand (operands[1], SImode)) 214 operands[1] = force_reg (SImode, operands[1]); 215 if (!nonmemory_operand (operands[1], SImode)) 216 operands[2] = force_reg (SImode, operands[2]);" 217) 218 219(define_insn "addsi3_internal" 220 [(set (match_operand:SI 0 "register_operand" "=&v") 221 (plus:SI (match_operand:SI 1 "nonmemory_operand" "vi") 222 (match_operand:SI 2 "nonmemory_operand" "vi"))) 223 ] 224 "" 225 "; addSI macro %0 = %1 + %2 226 movw ax, %h1 227 addw ax, %h2 228 movw %h0, ax 229 movw ax,%H1 230 sknc 231 incw ax 232 addw ax,%H2 233 movw %H0,ax 234 ; end of addSI macro" 235 [(set_attr "valloc" "macax")] 236) 237 238(define_expand "mulsi3" 239 [(set (match_operand:SI 0 "register_operand" "=&v") 240 (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") 241 (match_operand:SI 2 "nonmemory_operand" "vi"))) 242 ] 243 "! RL78_MUL_NONE" 244 "" 245) 246 247;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it 248;; because we're only using the lower 16 bits (which is the upper 16 249;; bits of the result). 250(define_insn "mulsi3_rl78" 251 [(set (match_operand:SI 0 "register_operand" "=&v") 252 (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") 253 (match_operand:SI 2 "nonmemory_operand" "vi"))) 254 ] 255 "RL78_MUL_RL78" 256 "; mulsi macro %0 = %1 * %2 257 movw ax, %h1 258 movw bc, %h2 259 MULHU ; bcax = bc * ax 260 movw %h0, ax 261 movw ax, bc 262 movw 0xffff0, ax 263 movw ax, %H1 264 movw bc, %h2 265 MACHU ; MACR += bc * ax 266 movw ax, %h1 267 movw bc, %H2 268 MACHU ; MACR += bc * ax 269 movw ax, 0xffff0 270 movw %H0, ax 271 ; end of mulsi macro" 272 [(set_attr "valloc" "macax")] 273 ) 274 275;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH. 276;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH. 277;; 0xF00E0 is MDCL. 0xF00E2 is MDCH. 278;; 0xF00E8 is MDUC. 279;; Warning: this matches the silicon not the documentation. 280(define_insn "mulsi3_g13" 281 [(set (match_operand:SI 0 "register_operand" "=&v") 282 (mult:SI (match_operand:SI 1 "nonmemory_operand" "vi") 283 (match_operand:SI 2 "nonmemory_operand" "vi"))) 284 ] 285 "RL78_MUL_G13" 286 "; mulsi macro %0 = %1 * %2 287 mov a, #0x00 288 mov !0xf00e8, a ; MDUC 289 movw ax, %h1 290 movw 0xffff0, ax ; MDAL 291 movw ax, %h2 292 movw 0xffff2, ax ; MDAH 293 nop ; mdb = mdal * mdah 294 movw ax, 0xffff6 ; MDBL 295 movw %h0, ax 296 297 mov a, #0x40 298 mov !0xf00e8, a ; MDUC 299 movw ax, 0xffff4 ; MDBH 300 movw !0xf00e0, ax ; MDCL 301 movw ax, #0 302 movw !0xf00e2, ax ; MDCL 303 movw ax, %H1 304 movw 0xffff0, ax ; MDAL 305 movw ax, %h2 306 movw 0xffff2, ax ; MDAH 307 nop ; mdc += mdal * mdah 308 309 mov a, #0x40 310 mov !0xf00e8, a ; MDUC 311 movw ax, %h1 312 movw 0xffff0, ax ; MDAL 313 movw ax, %H2 314 movw 0xffff2, ax ; MDAH 315 nop ; mdc += mdal * mdah 316 movw ax, !0xf00e0 ; MDCL 317 movw %H0, ax 318 ; end of mulsi macro" 319 [(set_attr "valloc" "macax")] 320 ) 321