1;; Machine description for Moxie 2;; Copyright (C) 2009-2018 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\\t%0, %2 52 dec\\t%0, -%2 53 add\\t%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\\t%0, %2 63 sub\\t%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\\t%0, %2") 72 73(define_code_iterator EXTEND [sign_extend zero_extend]) 74(define_code_attr mul [(sign_extend "mul") (zero_extend "umul")]) 75 76(define_insn "<mul>si3_highpart" 77 [(set (match_operand:SI 0 "register_operand" "=r") 78 (truncate:SI 79 (lshiftrt:DI 80 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "0")) 81 (EXTEND:DI (match_operand:SI 2 "register_operand" "r"))) 82 (const_int 32))))] 83 "TARGET_HAS_MULX" 84 "<mul>.x\\t%0, %2") 85 86(define_expand "<mul>sidi3" 87 [(set (match_operand:DI 0 "register_operand" "") 88 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "0")) 89 (EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))] 90 "TARGET_HAS_MULX" 91{ 92 rtx hi = gen_reg_rtx (SImode); 93 rtx lo = gen_reg_rtx (SImode); 94 95 emit_insn (gen_<mul>si3_highpart (hi, operands[1], operands[2])); 96 emit_insn (gen_mulsi3 (lo, operands[1], operands[2])); 97 emit_move_insn (gen_lowpart (SImode, operands[0]), lo); 98 emit_move_insn (gen_highpart (SImode, operands[0]), hi); 99 DONE; 100}) 101 102(define_insn "divsi3" 103 [(set (match_operand:SI 0 "register_operand" "=r") 104 (div:SI 105 (match_operand:SI 1 "register_operand" "0") 106 (match_operand:SI 2 "register_operand" "r")))] 107 "" 108 "div\\t%0, %2") 109 110(define_insn "udivsi3" 111 [(set (match_operand:SI 0 "register_operand" "=r") 112 (udiv:SI 113 (match_operand:SI 1 "register_operand" "0") 114 (match_operand:SI 2 "register_operand" "r")))] 115 "" 116 "udiv\\t%0, %2") 117 118(define_insn "modsi3" 119 [(set (match_operand:SI 0 "register_operand" "=r") 120 (mod:SI 121 (match_operand:SI 1 "register_operand" "0") 122 (match_operand:SI 2 "register_operand" "r")))] 123 "" 124 "mod\\t%0, %2") 125 126(define_insn "umodsi3" 127 [(set (match_operand:SI 0 "register_operand" "=r") 128 (umod:SI 129 (match_operand:SI 1 "register_operand" "0") 130 (match_operand:SI 2 "register_operand" "r")))] 131 "" 132 "umod\\t%0, %2") 133 134;; ------------------------------------------------------------------------- 135;; Unary arithmetic instructions 136;; ------------------------------------------------------------------------- 137 138(define_insn "negsi2" 139 [(set (match_operand:SI 0 "register_operand" "=r") 140 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 141 "" 142 "neg\\t%0, %1") 143 144(define_insn "one_cmplsi2" 145 [(set (match_operand:SI 0 "register_operand" "=r") 146 (not:SI (match_operand:SI 1 "register_operand" "r")))] 147 "" 148 "not\\t%0, %1") 149 150;; ------------------------------------------------------------------------- 151;; Logical operators 152;; ------------------------------------------------------------------------- 153 154(define_insn "andsi3" 155 [(set (match_operand:SI 0 "register_operand" "=r") 156 (and:SI (match_operand:SI 1 "register_operand" "0") 157 (match_operand:SI 2 "register_operand" "r")))] 158 "" 159{ 160 return "and\\t%0, %2"; 161}) 162 163(define_insn "xorsi3" 164 [(set (match_operand:SI 0 "register_operand" "=r") 165 (xor:SI (match_operand:SI 1 "register_operand" "0") 166 (match_operand:SI 2 "register_operand" "r")))] 167 "" 168{ 169 return "xor\\t%0, %2"; 170}) 171 172(define_insn "iorsi3" 173 [(set (match_operand:SI 0 "register_operand" "=r") 174 (ior:SI (match_operand:SI 1 "register_operand" "0") 175 (match_operand:SI 2 "register_operand" "r")))] 176 "" 177{ 178 return "or\\t%0, %2"; 179}) 180 181;; ------------------------------------------------------------------------- 182;; Shifters 183;; ------------------------------------------------------------------------- 184 185(define_insn "ashlsi3" 186 [(set (match_operand:SI 0 "register_operand" "=r") 187 (ashift:SI (match_operand:SI 1 "register_operand" "0") 188 (match_operand:SI 2 "register_operand" "r")))] 189 "" 190{ 191 return "ashl\\t%0, %2"; 192}) 193 194(define_insn "ashrsi3" 195 [(set (match_operand:SI 0 "register_operand" "=r") 196 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 197 (match_operand:SI 2 "register_operand" "r")))] 198 "" 199{ 200 return "ashr\\t%0, %2"; 201}) 202 203(define_insn "lshrsi3" 204 [(set (match_operand:SI 0 "register_operand" "=r") 205 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 206 (match_operand:SI 2 "register_operand" "r")))] 207 "" 208{ 209 return "lshr\\t%0, %2"; 210}) 211 212;; ------------------------------------------------------------------------- 213;; Move instructions 214;; ------------------------------------------------------------------------- 215 216;; SImode 217 218;; Push a register onto the stack 219(define_insn "movsi_push" 220 [(set (mem:SI (pre_dec:SI (reg:SI 1))) 221 (match_operand:SI 0 "register_operand" "r"))] 222 "" 223 "push\\t$sp, %0") 224 225;; Pop a register from the stack 226(define_insn "movsi_pop" 227 [(set (match_operand:SI 1 "register_operand" "=r") 228 (mem:SI (post_inc:SI (match_operand:SI 0 "register_operand" "r"))))] 229 "" 230 "pop\\t%0, %1") 231 232(define_expand "movsi" 233 [(set (match_operand:SI 0 "general_operand" "") 234 (match_operand:SI 1 "general_operand" ""))] 235 "" 236 " 237{ 238 /* If this is a store, force the value into a register. */ 239 if (! (reload_in_progress || reload_completed)) 240 { 241 if (MEM_P (operands[0])) 242 { 243 operands[1] = force_reg (SImode, operands[1]); 244 if (MEM_P (XEXP (operands[0], 0))) 245 operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); 246 } 247 else 248 if (MEM_P (operands[1]) 249 && MEM_P (XEXP (operands[1], 0))) 250 operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0))); 251 } 252}") 253 254(define_insn "*movsi" 255 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r") 256 (match_operand:SI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 257 "register_operand (operands[0], SImode) 258 || register_operand (operands[1], SImode)" 259 "@ 260 xor\\t%0, %0 261 mov\\t%0, %1 262 ldi.l\\t%0, %1 263 st.l\\t%0, %1 264 sta.l\\t%0, %1 265 ld.l\\t%0, %1 266 lda.l\\t%0, %1 267 sto.l\\t%0, %1 268 ldo.l\\t%0, %1" 269 [(set_attr "length" "2,2,6,2,6,2,6,4,4")]) 270 271(define_insn "zero_extendqisi2" 272 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 273 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,W,A,B")))] 274 "" 275 "@ 276 zex.b\\t%0, %1 277 ld.b\\t%0, %1 278 lda.b\\t%0, %1 279 ldo.b\\t%0, %1" 280 [(set_attr "length" "2,2,6,4")]) 281 282(define_insn "zero_extendhisi2" 283 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 284 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,W,A,B")))] 285 "" 286 "@ 287 zex.s\\t%0, %1 288 ld.s\\t%0, %1 289 lda.s\\t%0, %1 290 ldo.s\\t%0, %1" 291 [(set_attr "length" "2,2,6,4")]) 292 293(define_insn "extendqisi2" 294 [(set (match_operand:SI 0 "register_operand" "=r") 295 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))] 296 "" 297 "@ 298 sex.b\\t%0, %1" 299 [(set_attr "length" "2")]) 300 301(define_insn "extendhisi2" 302 [(set (match_operand:SI 0 "register_operand" "=r") 303 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] 304 "" 305 "@ 306 sex.s\\t%0, %1" 307 [(set_attr "length" "2")]) 308 309(define_expand "movqi" 310 [(set (match_operand:QI 0 "general_operand" "") 311 (match_operand:QI 1 "general_operand" ""))] 312 "" 313 " 314{ 315 /* If this is a store, force the value into a register. */ 316 if (MEM_P (operands[0])) 317 operands[1] = force_reg (QImode, operands[1]); 318}") 319 320(define_insn "*movqi" 321 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r") 322 (match_operand:QI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 323 "register_operand (operands[0], QImode) 324 || register_operand (operands[1], QImode)" 325 "@ 326 xor\\t%0, %0 327 mov\\t%0, %1 328 ldi.b\\t%0, %1 329 st.b\\t%0, %1 330 sta.b\\t%0, %1 331 ld.b\\t%0, %1 332 lda.b\\t%0, %1 333 sto.b\\t%0, %1 334 ldo.b\\t%0, %1" 335 [(set_attr "length" "2,2,6,2,6,2,6,4,4")]) 336 337(define_expand "movhi" 338 [(set (match_operand:HI 0 "general_operand" "") 339 (match_operand:HI 1 "general_operand" ""))] 340 "" 341 " 342{ 343 /* If this is a store, force the value into a register. */ 344 if (MEM_P (operands[0])) 345 operands[1] = force_reg (HImode, operands[1]); 346}") 347 348(define_insn "*movhi" 349 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,W,A,r,r,B,r") 350 (match_operand:HI 1 "moxie_general_movsrc_operand" "O,r,i,r,r,W,A,r,B"))] 351 "(register_operand (operands[0], HImode) 352 || register_operand (operands[1], HImode))" 353 "@ 354 xor\\t%0, %0 355 mov\\t%0, %1 356 ldi.s\\t%0, %1 357 st.s\\t%0, %1 358 sta.s\\t%0, %1 359 ld.s\\t%0, %1 360 lda.s\\t%0, %1 361 sto.s\\t%0, %1 362 ldo.s\\t%0, %1" 363 [(set_attr "length" "2,2,6,2,6,2,6,4,4")]) 364 365;; ------------------------------------------------------------------------- 366;; Compare instructions 367;; ------------------------------------------------------------------------- 368 369(define_constants 370 [(CC_REG 19)]) 371 372(define_expand "cbranchsi4" 373 [(set (reg:CC CC_REG) 374 (compare:CC 375 (match_operand:SI 1 "general_operand" "") 376 (match_operand:SI 2 "general_operand" ""))) 377 (set (pc) 378 (if_then_else (match_operator 0 "comparison_operator" 379 [(reg:CC CC_REG) (const_int 0)]) 380 (label_ref (match_operand 3 "" "")) 381 (pc)))] 382 "" 383 " 384 /* Force the compare operands into registers. */ 385 if (GET_CODE (operands[1]) != REG) 386 operands[1] = force_reg (SImode, operands[1]); 387 if (GET_CODE (operands[2]) != REG) 388 operands[2] = force_reg (SImode, operands[2]); 389 ") 390 391(define_insn "*cmpsi" 392 [(set (reg:CC CC_REG) 393 (compare 394 (match_operand:SI 0 "register_operand" "r") 395 (match_operand:SI 1 "register_operand" "r")))] 396 "" 397 "cmp\\t%0, %1") 398 399 400;; ------------------------------------------------------------------------- 401;; Branch instructions 402;; ------------------------------------------------------------------------- 403 404(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu]) 405(define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu") 406 (gt "gt") (gtu "gtu") (ge "ge") (le "le") 407 (geu "geu") (leu "leu") ]) 408(define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu") 409 (gt "le") (gtu "leu") (ge "lt") (le "gt") 410 (geu "ltu") (leu "gtu") ]) 411 412(define_insn "*b<cond:code>" 413 [(set (pc) 414 (if_then_else (cond (reg:CC CC_REG) 415 (const_int 0)) 416 (label_ref (match_operand 0 "" "")) 417 (pc)))] 418 "" 419{ 420 if (get_attr_length (insn) == 2) 421 return "b<CC>\\t%l0"; 422 else 423 return "b<rCC>\\t.+6\n\tjmpa %l0"; 424} 425 [(set (attr "length") 426 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022)) 427 (const_int 2) (const_int 8)))]) 428 429;; ------------------------------------------------------------------------- 430;; Call and Jump instructions 431;; ------------------------------------------------------------------------- 432 433(define_expand "call" 434 [(call (match_operand:QI 0 "memory_operand" "") 435 (match_operand 1 "general_operand" ""))] 436 "" 437{ 438 gcc_assert (MEM_P (operands[0])); 439}) 440 441(define_insn "*call" 442 [(call (mem:QI (match_operand:SI 443 0 "nonmemory_operand" "i,r")) 444 (match_operand 1 "" ""))] 445 "" 446 "@ 447 jsra\\t%0 448 jsr\\t%0" 449 [(set_attr "length" "6,2")]) 450 451(define_expand "call_value" 452 [(set (match_operand 0 "" "") 453 (call (match_operand:QI 1 "memory_operand" "") 454 (match_operand 2 "" "")))] 455 "" 456{ 457 gcc_assert (MEM_P (operands[1])); 458}) 459 460(define_insn "*call_value" 461 [(set (match_operand 0 "register_operand" "=r") 462 (call (mem:QI (match_operand:SI 463 1 "immediate_operand" "i")) 464 (match_operand 2 "" "")))] 465 "" 466 "jsra\\t%1" 467 [(set_attr "length" "6")]) 468 469(define_insn "*call_value_indirect" 470 [(set (match_operand 0 "register_operand" "=r") 471 (call (mem:QI (match_operand:SI 472 1 "register_operand" "r")) 473 (match_operand 2 "" "")))] 474 "" 475 "jsr\\t%1") 476 477(define_insn "indirect_jump" 478 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))] 479 "" 480 "jmp\\t%0") 481 482(define_insn "jump" 483 [(set (pc) 484 (label_ref (match_operand 0 "" "")))] 485 "" 486 "jmpa\\t%l0" 487 [(set_attr "length" "6")]) 488 489 490;; ------------------------------------------------------------------------- 491;; Prologue & Epilogue 492;; ------------------------------------------------------------------------- 493 494(define_expand "prologue" 495 [(clobber (const_int 0))] 496 "" 497 " 498{ 499 moxie_expand_prologue (); 500 DONE; 501} 502") 503 504(define_expand "epilogue" 505 [(return)] 506 "" 507 " 508{ 509 moxie_expand_epilogue (); 510 DONE; 511} 512") 513 514(define_insn "returner" 515 [(return)] 516 "reload_completed" 517 "ret") 518