1;; Machine description for Moxie 2;; Copyright (C) 2009-2013 Free Software Foundation, Inc. 3;; Contributed by Anthony Green <green@moxielogic.com> 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; 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;; ------------------------------------------------------------------------- 22;; Moxie specific constraints, predicates and attributes 23;; ------------------------------------------------------------------------- 24 25(include "constraints.md") 26(include "predicates.md") 27 28; Most instructions are two bytes long. 29(define_attr "length" "" (const_int 2)) 30 31;; ------------------------------------------------------------------------- 32;; nop instruction 33;; ------------------------------------------------------------------------- 34 35(define_insn "nop" 36 [(const_int 0)] 37 "" 38 "nop") 39 40;; ------------------------------------------------------------------------- 41;; Arithmetic instructions 42;; ------------------------------------------------------------------------- 43 44(define_insn "addsi3" 45 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 46 (plus:SI 47 (match_operand:SI 1 "register_operand" "0,0,0") 48 (match_operand:SI 2 "moxie_add_operand" "I,N,r")))] 49 "" 50 "@ 51 inc %0, %2 52 dec %0, -%2 53 add.l %0, %2") 54 55(define_insn "subsi3" 56 [(set (match_operand:SI 0 "register_operand" "=r,r") 57 (minus:SI 58 (match_operand:SI 1 "register_operand" "0,0") 59 (match_operand:SI 2 "moxie_sub_operand" "I,r")))] 60 "" 61 "@ 62 dec %0, %2 63 sub.l %0, %2") 64 65(define_insn "mulsi3" 66 [(set (match_operand:SI 0 "register_operand" "=r") 67 (mult:SI 68 (match_operand:SI 1 "register_operand" "0") 69 (match_operand:SI 2 "register_operand" "r")))] 70 "" 71 "mul.l %0, %2") 72 73(define_insn "divsi3" 74 [(set (match_operand:SI 0 "register_operand" "=r") 75 (div:SI 76 (match_operand:SI 1 "register_operand" "0") 77 (match_operand:SI 2 "register_operand" "r")))] 78 "" 79 "div.l %0, %2") 80 81(define_insn "udivsi3" 82 [(set (match_operand:SI 0 "register_operand" "=r") 83 (udiv:SI 84 (match_operand:SI 1 "register_operand" "0") 85 (match_operand:SI 2 "register_operand" "r")))] 86 "" 87 "udiv.l %0, %2") 88 89(define_insn "modsi3" 90 [(set (match_operand:SI 0 "register_operand" "=r") 91 (mod:SI 92 (match_operand:SI 1 "register_operand" "0") 93 (match_operand:SI 2 "register_operand" "r")))] 94 "" 95 "mod.l %0, %2") 96 97(define_insn "umodsi3" 98 [(set (match_operand:SI 0 "register_operand" "=r") 99 (umod:SI 100 (match_operand:SI 1 "register_operand" "0") 101 (match_operand:SI 2 "register_operand" "r")))] 102 "" 103 "umod.l %0, %2") 104 105;; ------------------------------------------------------------------------- 106;; Unary arithmetic instructions 107;; ------------------------------------------------------------------------- 108 109(define_insn "negsi2" 110 [(set (match_operand:SI 0 "register_operand" "=r") 111 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 112 "" 113 "neg %0, %1") 114 115(define_insn "one_cmplsi2" 116 [(set (match_operand:SI 0 "register_operand" "=r") 117 (not:SI (match_operand:SI 1 "register_operand" "r")))] 118 "" 119 "not %0, %1") 120 121;; ------------------------------------------------------------------------- 122;; Logical operators 123;; ------------------------------------------------------------------------- 124 125(define_insn "andsi3" 126 [(set (match_operand:SI 0 "register_operand" "=r") 127 (and:SI (match_operand:SI 1 "register_operand" "0") 128 (match_operand:SI 2 "register_operand" "r")))] 129 "" 130{ 131 return "and %0, %2"; 132}) 133 134(define_insn "xorsi3" 135 [(set (match_operand:SI 0 "register_operand" "=r") 136 (xor:SI (match_operand:SI 1 "register_operand" "0") 137 (match_operand:SI 2 "register_operand" "r")))] 138 "" 139{ 140 return "xor %0, %2"; 141}) 142 143(define_insn "iorsi3" 144 [(set (match_operand:SI 0 "register_operand" "=r") 145 (ior:SI (match_operand:SI 1 "register_operand" "0") 146 (match_operand:SI 2 "register_operand" "r")))] 147 "" 148{ 149 return "or %0, %2"; 150}) 151 152;; ------------------------------------------------------------------------- 153;; Shifters 154;; ------------------------------------------------------------------------- 155 156(define_insn "ashlsi3" 157 [(set (match_operand:SI 0 "register_operand" "=r") 158 (ashift:SI (match_operand:SI 1 "register_operand" "0") 159 (match_operand:SI 2 "register_operand" "r")))] 160 "" 161{ 162 return "ashl %0, %2"; 163}) 164 165(define_insn "ashrsi3" 166 [(set (match_operand:SI 0 "register_operand" "=r") 167 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 168 (match_operand:SI 2 "register_operand" "r")))] 169 "" 170{ 171 return "ashr %0, %2"; 172}) 173 174(define_insn "lshrsi3" 175 [(set (match_operand:SI 0 "register_operand" "=r") 176 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 177 (match_operand:SI 2 "register_operand" "r")))] 178 "" 179{ 180 return "lshr %0, %2"; 181}) 182 183;; ------------------------------------------------------------------------- 184;; Move instructions 185;; ------------------------------------------------------------------------- 186 187;; SImode 188 189;; Push a register onto the stack 190(define_insn "movsi_push" 191 [(set (mem:SI (pre_dec:SI (reg:SI 1))) 192 (match_operand:SI 0 "register_operand" "r"))] 193 "" 194 "push $sp, %0") 195 196;; Pop a register from the stack 197(define_insn "movsi_pop" 198 [(set (match_operand:SI 1 "register_operand" "=r") 199 (mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))] 200 "" 201 "pop %0, %1") 202 203(define_expand "movsi" 204 [(set (match_operand:SI 0 "general_operand" "") 205 (match_operand:SI 1 "general_operand" ""))] 206 "" 207 " 208{ 209 /* If this is a store, force the value into a register. */ 210 if (! (reload_in_progress || reload_completed)) 211 { 212 if (MEM_P (operands[0])) 213 { 214 operands[1] = force_reg (SImode, operands[1]); 215 if (MEM_P (XEXP (operands[0], 0))) 216 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); 217 } 218 else 219 if (MEM_P (operands[1]) 220 && MEM_P (XEXP (operands[1], 0))) 221 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0))); 222 } 223}") 224 225(define_insn "*movsi" 226 [(set (match_operand:SI 0 "general_operand" "=r,r,r,W,A,r,r,B,r") 227 (match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 228 "register_operand (operands[0], SImode) 229 || register_operand (operands[1], SImode)" 230 "@ 231 xor %0, %0 232 mov %0, %1 233 ldi.l %0, %1 234 st.l %0, %1 235 sta.l %0, %1 236 ld.l %0, %1 237 lda.l %0, %1 238 sto.l %0, %1 239 ldo.l %0, %1" 240 [(set_attr "length" "2,2,6,2,6,2,6,6,6")]) 241 242(define_expand "movqi" 243 [(set (match_operand:QI 0 "general_operand" "") 244 (match_operand:QI 1 "general_operand" ""))] 245 "" 246 " 247{ 248 /* If this is a store, force the value into a register. */ 249 if (MEM_P (operands[0])) 250 operands[1] = force_reg (QImode, operands[1]); 251}") 252 253(define_insn "*movqi" 254 [(set (match_operand:QI 0 "general_operand" "=r,r,r,W,A,r,r,B,r") 255 (match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 256 "register_operand (operands[0], QImode) 257 || register_operand (operands[1], QImode)" 258 "@ 259 xor %0, %0 260 mov %0, %1 261 ldi.b %0, %1 262 st.b %0, %1 263 sta.b %0, %1 264 ld.b %0, %1 265 lda.b %0, %1 266 sto.b %0, %1 267 ldo.b %0, %1" 268 [(set_attr "length" "2,2,6,2,6,2,6,6,6")]) 269 270(define_expand "movhi" 271 [(set (match_operand:HI 0 "general_operand" "") 272 (match_operand:HI 1 "general_operand" ""))] 273 "" 274 " 275{ 276 /* If this is a store, force the value into a register. */ 277 if (MEM_P (operands[0])) 278 operands[1] = force_reg (HImode, operands[1]); 279}") 280 281(define_insn "*movhi" 282 [(set (match_operand:HI 0 "general_operand" "=r,r,r,W,A,r,r,B,r") 283 (match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 284 "(register_operand (operands[0], HImode) 285 || register_operand (operands[1], HImode))" 286 "@ 287 xor %0, %0 288 mov %0, %1 289 ldi.s %0, %1 290 st.s %0, %1 291 sta.s %0, %1 292 ld.s %0, %1 293 lda.s %0, %1 294 sto.s %0, %1 295 ldo.s %0, %1" 296 [(set_attr "length" "2,2,6,2,6,2,6,6,6")]) 297 298;; ------------------------------------------------------------------------- 299;; Compare instructions 300;; ------------------------------------------------------------------------- 301 302(define_constants 303 [(CC_REG 11)]) 304 305(define_expand "cbranchsi4" 306 [(set (reg:CC CC_REG) 307 (compare:CC 308 (match_operand:SI 1 "general_operand" "") 309 (match_operand:SI 2 "general_operand" ""))) 310 (set (pc) 311 (if_then_else (match_operator 0 "comparison_operator" 312 [(reg:CC CC_REG) (const_int 0)]) 313 (label_ref (match_operand 3 "" "")) 314 (pc)))] 315 "" 316 " 317 /* Force the compare operands into registers. */ 318 if (GET_CODE (operands[1]) != REG) 319 operands[1] = force_reg (SImode, operands[1]); 320 if (GET_CODE (operands[2]) != REG) 321 operands[2] = force_reg (SImode, operands[2]); 322 ") 323 324(define_insn "*cmpsi" 325 [(set (reg:CC CC_REG) 326 (compare 327 (match_operand:SI 0 "register_operand" "r") 328 (match_operand:SI 1 "register_operand" "r")))] 329 "" 330 "cmp %0, %1") 331 332 333;; ------------------------------------------------------------------------- 334;; Branch instructions 335;; ------------------------------------------------------------------------- 336 337(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu]) 338(define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu") 339 (gt "gt") (gtu "gtu") (ge "ge") (le "le") 340 (geu "geu") (leu "leu") ]) 341(define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu") 342 (gt "le") (gtu "leu") (ge "lt") (le "gt") 343 (geu "ltu") (leu "gtu") ]) 344 345(define_insn "*b<cond:code>" 346 [(set (pc) 347 (if_then_else (cond (reg:CC CC_REG) 348 (const_int 0)) 349 (label_ref (match_operand 0 "" "")) 350 (pc)))] 351 "" 352{ 353 if (get_attr_length (insn) == 2) 354 return "b<CC> %l0"; 355 else 356 return "b<rCC> .+6\n\tjmpa %l0"; 357} 358 [(set (attr "length") 359 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022)) 360 (const_int 2) (const_int 8)))]) 361 362;; ------------------------------------------------------------------------- 363;; Call and Jump instructions 364;; ------------------------------------------------------------------------- 365 366(define_expand "call" 367 [(call (match_operand:QI 0 "memory_operand" "") 368 (match_operand 1 "general_operand" ""))] 369 "" 370{ 371 gcc_assert (MEM_P (operands[0])); 372}) 373 374(define_insn "*call" 375 [(call (mem:QI (match_operand:SI 376 0 "nonmemory_operand" "i,r")) 377 (match_operand 1 "" ""))] 378 "" 379 "@ 380 jsra %0 381 jsr %0" 382 [(set_attr "length" "6,2")]) 383 384(define_expand "call_value" 385 [(set (match_operand 0 "" "") 386 (call (match_operand:QI 1 "memory_operand" "") 387 (match_operand 2 "" "")))] 388 "" 389{ 390 gcc_assert (MEM_P (operands[1])); 391}) 392 393(define_insn "*call_value" 394 [(set (match_operand 0 "register_operand" "=r") 395 (call (mem:QI (match_operand:SI 396 1 "immediate_operand" "i")) 397 (match_operand 2 "" "")))] 398 "" 399 "jsra %1" 400 [(set_attr "length" "6")]) 401 402(define_insn "*call_value_indirect" 403 [(set (match_operand 0 "register_operand" "=r") 404 (call (mem:QI (match_operand:SI 405 1 "register_operand" "r")) 406 (match_operand 2 "" "")))] 407 "" 408 "jsr %1") 409 410(define_insn "indirect_jump" 411 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))] 412 "" 413 "jmp %0") 414 415(define_insn "jump" 416 [(set (pc) 417 (label_ref (match_operand 0 "" "")))] 418 "" 419 "jmpa %l0" 420 [(set_attr "length" "6")]) 421 422 423;; ------------------------------------------------------------------------- 424;; Prologue & Epilogue 425;; ------------------------------------------------------------------------- 426 427(define_expand "prologue" 428 [(clobber (const_int 0))] 429 "" 430 " 431{ 432 moxie_expand_prologue (); 433 DONE; 434} 435") 436 437(define_expand "epilogue" 438 [(return)] 439 "" 440 " 441{ 442 moxie_expand_epilogue (); 443 DONE; 444} 445") 446 447(define_insn "returner" 448 [(return)] 449 "reload_completed" 450 "ret") 451