1;; GCC machine description for Matsushita MN10300 2;; Copyright (C) 1996-2020 Free Software Foundation, Inc. 3;; Contributed by Jeff Law (law@cygnus.com). 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;; The original PO technology requires these to be ordered by speed, 22;; so that assigner will pick the fastest. 23 24;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 25 26(define_constants [ 27 (PIC_REG 6) 28 (SP_REG 9) 29 (MDR_REG 50) 30 (CC_REG 51) 31 32 (UNSPEC_PIC 1) 33 (UNSPEC_GOT 2) 34 (UNSPEC_GOTOFF 3) 35 (UNSPEC_PLT 4) 36 (UNSPEC_GOTSYM_OFF 5) 37 38 (UNSPEC_EXT 6) 39 (UNSPEC_BSCH 7) 40 41 ;; This is used to encode LIW patterns. 42 (UNSPEC_LIW 8) 43 ;; This is for the low overhead loop instructions. 44 (UNSPEC_SETLB 9) 45]) 46 47(include "predicates.md") 48(include "constraints.md") 49 50;; Processor type. This attribute must exactly match the processor_type 51;; enumeration in mn10300.h. 52(define_attr "cpu" "mn10300,am33,am33_2,am34" 53 (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu"))) 54 55;; Used to control the "enabled" attribute on a per-instruction basis. 56(define_attr "isa" "base,am33,am33_2,am34" 57 (const_string "base")) 58 59(define_attr "enabled" "" 60 (cond [(eq_attr "isa" "base") 61 (const_int 1) 62 63 (and (eq_attr "isa" "am33") 64 (match_test "TARGET_AM33")) 65 (const_int 1) 66 67 (and (eq_attr "isa" "am33_2") 68 (match_test "TARGET_AM33_2")) 69 (const_int 1) 70 71 (and (eq_attr "isa" "am34") 72 (match_test "TARGET_AM34")) 73 (const_int 1) 74 ] 75 (const_int 0)) 76) 77 78(define_mode_iterator INT [QI HI SI]) 79 80 81;; Bundling of smaller insns into a long instruction word (LIW) 82(define_automaton "liw_bundling") 83(automata_option "ndfa") 84 85(define_cpu_unit "liw_op1_u,liw_op2_u" "liw_bundling") 86 87(define_attr "liw" "op1,op2,both,either" 88 (const_string "both")) 89;; Note: this list must match the one defined for liw_op_names[]. 90(define_attr "liw_op" "add,cmp,sub,mov,and,or,xor,asr,lsr,asl,none,max" 91 (const_string "none")) 92 93(define_insn_reservation "liw_op1" 1 94 (and (ior (eq_attr "cpu" "am33") 95 (eq_attr "cpu" "am33_2") 96 (eq_attr "cpu" "am34")) 97 (eq_attr "liw" "op1")) 98 "liw_op1_u"); 99(define_insn_reservation "liw_op2" 1 100 (and (ior (eq_attr "cpu" "am33") 101 (eq_attr "cpu" "am33_2") 102 (eq_attr "cpu" "am34")) 103 (eq_attr "liw" "op2")) 104 "liw_op2_u"); 105(define_insn_reservation "liw_both" 1 106 (and (ior (eq_attr "cpu" "am33") 107 (eq_attr "cpu" "am33_2") 108 (eq_attr "cpu" "am34")) 109 (eq_attr "liw" "both")) 110 "liw_op1_u + liw_op2_u"); 111(define_insn_reservation "liw_either" 1 112 (and (ior (eq_attr "cpu" "am33") 113 (eq_attr "cpu" "am33_2") 114 (eq_attr "cpu" "am34")) 115 (eq_attr "liw" "either")) 116 "liw_op1_u | liw_op2_u"); 117 118;; ---------------------------------------------------------------------- 119;; Pipeline description. 120;; ---------------------------------------------------------------------- 121 122;; The AM33 only has a single pipeline. It has five stages (fetch, 123;; decode, execute, memory access, writeback) each of which normally 124;; takes a single CPU clock cycle. 125 126;; The timings attribute consists of two numbers, the first is the 127;; throughput, which is the number of cycles the instruction takes 128;; to execute and generate a result. The second is the latency 129;; which is the effective number of cycles the instruction takes to 130;; execute if its result is used by the following instruction. The 131;; latency is always greater than or equal to the throughput. 132;; These values were taken from the Appendix of the "MN103E Series 133;; Instruction Manual" and the timings for the AM34. 134 135;; Note - it would be nice to use strings rather than integers for 136;; the possible values of this attribute, so that we can have the 137;; gcc build mechanism check for values that are not supported by 138;; the reservations below. But this will not work because the code 139;; in mn10300_adjust_sched_cost() needs integers not strings. 140 141(define_attr "timings" "" (const_int 11)) 142 143(define_automaton "pipelining") 144(define_cpu_unit "throughput" "pipelining") 145 146(define_insn_reservation "throughput__1_latency__1" 1 147 (eq_attr "timings" "11") "throughput") 148(define_insn_reservation "throughput__1_latency__2" 2 149 (eq_attr "timings" "12") "throughput,nothing") 150(define_insn_reservation "throughput__1_latency__3" 3 151 (eq_attr "timings" "13") "throughput,nothing*2") 152(define_insn_reservation "throughput__1_latency__4" 4 153 (eq_attr "timings" "14") "throughput,nothing*3") 154(define_insn_reservation "throughput__2_latency__2" 2 155 (eq_attr "timings" "22") "throughput*2") 156(define_insn_reservation "throughput__2_latency__3" 3 157 (eq_attr "timings" "23") "throughput*2,nothing") 158(define_insn_reservation "throughput__2_latency__4" 4 159 (eq_attr "timings" "24") "throughput*2,nothing*2") 160(define_insn_reservation "throughput__2_latency__5" 5 161 (eq_attr "timings" "25") "throughput*2,nothing*3") 162(define_insn_reservation "throughput__3_latency__3" 3 163 (eq_attr "timings" "33") "throughput*3") 164(define_insn_reservation "throughput__3_latency__7" 7 165 (eq_attr "timings" "37") "throughput*3,nothing*4") 166(define_insn_reservation "throughput__4_latency__4" 4 167 (eq_attr "timings" "44") "throughput*4") 168(define_insn_reservation "throughput__4_latency__7" 7 169 (eq_attr "timings" "47") "throughput*4,nothing*3") 170(define_insn_reservation "throughput__4_latency__8" 8 171 (eq_attr "timings" "48") "throughput*4,nothing*4") 172(define_insn_reservation "throughput__5_latency__5" 5 173 (eq_attr "timings" "55") "throughput*5") 174(define_insn_reservation "throughput__6_latency__6" 6 175 (eq_attr "timings" "66") "throughput*6") 176(define_insn_reservation "throughput__7_latency__7" 7 177 (eq_attr "timings" "77") "throughput*7") 178(define_insn_reservation "throughput__7_latency__8" 8 179 (eq_attr "timings" "78") "throughput*7,nothing") 180(define_insn_reservation "throughput__8_latency__8" 8 181 (eq_attr "timings" "88") "throughput*8") 182(define_insn_reservation "throughput__9_latency__9" 9 183 (eq_attr "timings" "99") "throughput*9") 184(define_insn_reservation "throughput__8_latency_14" 14 185 (eq_attr "timings" "814") "throughput*8,nothing*6") 186(define_insn_reservation "throughput__9_latency_10" 10 187 (eq_attr "timings" "910") "throughput*9,nothing") 188(define_insn_reservation "throughput_10_latency_10" 10 189 (eq_attr "timings" "1010") "throughput*10") 190(define_insn_reservation "throughput_12_latency_16" 16 191 (eq_attr "timings" "1216") "throughput*12,nothing*4") 192(define_insn_reservation "throughput_13_latency_13" 13 193 (eq_attr "timings" "1313") "throughput*13") 194(define_insn_reservation "throughput_14_latency_14" 14 195 (eq_attr "timings" "1414") "throughput*14") 196(define_insn_reservation "throughput_13_latency_17" 17 197 (eq_attr "timings" "1317") "throughput*13,nothing*4") 198(define_insn_reservation "throughput_23_latency_27" 27 199 (eq_attr "timings" "2327") "throughput*23,nothing*4") 200(define_insn_reservation "throughput_25_latency_31" 31 201 (eq_attr "timings" "2531") "throughput*25,nothing*6") 202(define_insn_reservation "throughput_38_latency_39" 39 203 (eq_attr "timings" "3839") "throughput*38,nothing") 204(define_insn_reservation "throughput_39_latency_40" 40 205 (eq_attr "timings" "3940") "throughput*39,nothing") 206(define_insn_reservation "throughput_40_latency_40" 40 207 (eq_attr "timings" "4040") "throughput*40") 208(define_insn_reservation "throughput_41_latency_42" 42 209 (eq_attr "timings" "4142") "throughput*41,nothing") 210(define_insn_reservation "throughput_42_latency_43" 44 211 (eq_attr "timings" "4243") "throughput*42,nothing") 212(define_insn_reservation "throughput_43_latency_44" 44 213 (eq_attr "timings" "4344") "throughput*43,nothing") 214(define_insn_reservation "throughput_45_latency_46" 46 215 (eq_attr "timings" "4546") "throughput*45,nothing") 216(define_insn_reservation "throughput_47_latency_53" 53 217 (eq_attr "timings" "4753") "throughput*47,nothing*6") 218 219;; Note - the conflict between memory load/store instructions 220;; and floating point instructions described in section 1-7-4 221;; of Chapter 3 of the MN103E Series Instruction Manual is 222;; handled by the mn10300_adjust_sched_cost function. 223 224;; ---------------------------------------------------------------------- 225;; MOVE INSTRUCTIONS 226;; ---------------------------------------------------------------------- 227 228;; movqi 229 230(define_expand "movqi" 231 [(set (match_operand:QI 0 "nonimmediate_operand") 232 (match_operand:QI 1 "general_operand"))] 233 "" 234{ 235 /* One of the ops has to be in a register. */ 236 if (!register_operand (operand0, QImode) 237 && !register_operand (operand1, QImode)) 238 operands[1] = force_reg (QImode, operand1); 239}) 240 241(define_insn "*movqi_internal" 242 [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") 243 (match_operand:QI 1 "general_operand" " 0,D*r, i,m,D,d,*z"))] 244 "(register_operand (operands[0], QImode) 245 || register_operand (operands[1], QImode))" 246{ 247 switch (which_alternative) 248 { 249 case 0: 250 return ""; 251 case 1: 252 case 2: 253 case 5: 254 case 6: 255 return "mov %1,%0"; 256 case 3: 257 case 4: 258 return "movbu %1,%0"; 259 default: 260 gcc_unreachable (); 261 } 262} 263 [(set_attr_alternative "timings" 264 [(const_int 11) 265 (const_int 11) 266 (const_int 11) 267 (if_then_else (eq_attr "cpu" "am34") 268 (const_int 13) (const_int 24)) 269 (if_then_else (eq_attr "cpu" "am34") 270 (const_int 11) (const_int 22)) 271 (const_int 11) 272 (const_int 11) 273 ])] 274) 275 276;; movhi 277 278(define_expand "movhi" 279 [(set (match_operand:HI 0 "nonimmediate_operand") 280 (match_operand:HI 1 "general_operand"))] 281 "" 282{ 283 /* One of the ops has to be in a register. */ 284 if (!register_operand (operand1, HImode) 285 && !register_operand (operand0, HImode)) 286 operands[1] = force_reg (HImode, operand1); 287}) 288 289(define_insn "*movhi_internal" 290 [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") 291 (match_operand:HI 1 "general_operand" " 0, i,D*r,m,D,d,*z"))] 292 "(register_operand (operands[0], HImode) 293 || register_operand (operands[1], HImode))" 294{ 295 switch (which_alternative) 296 { 297 case 0: 298 return ""; 299 case 1: 300 /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes. 301 We have "MOV imm16,Dn" at 3 bytes. The only win for the 4 byte 302 movu is for an 8-bit unsigned move into Rn. */ 303 if (TARGET_AM33 304 && CONST_INT_P (operands[1]) 305 && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff) 306 && REGNO_EXTENDED_P (REGNO (operands[0]), 1)) 307 return "movu %1,%0"; 308 /* FALLTHRU */ 309 case 5: 310 case 6: 311 case 2: 312 return "mov %1,%0"; 313 case 3: 314 case 4: 315 return "movhu %1,%0"; 316 default: 317 gcc_unreachable (); 318 } 319} 320 [(set_attr_alternative "timings" 321 [(const_int 11) 322 (const_int 11) 323 (if_then_else (eq_attr "cpu" "am34") 324 (const_int 11) (const_int 22)) 325 (if_then_else (eq_attr "cpu" "am34") 326 (const_int 13) (const_int 24)) 327 (if_then_else (eq_attr "cpu" "am34") 328 (const_int 11) (const_int 22)) 329 (if_then_else (eq_attr "cpu" "am34") 330 (const_int 11) (const_int 22)) 331 (if_then_else (eq_attr "cpu" "am34") 332 (const_int 11) (const_int 22)) 333 ])] 334) 335 336;; movsi and helpers 337 338;; We use this to handle addition of two values when one operand is the 339;; stack pointer and the other is a memory reference of some kind. Reload 340;; does not handle them correctly without this expander. 341(define_expand "reload_plus_sp_const" 342 [(set (match_operand:SI 0 "register_operand" "=r") 343 (match_operand:SI 1 "impossible_plus_operand" "")) 344 (clobber (match_operand:SI 2 "register_operand" "=&A"))] 345 "" 346{ 347 rtx dest, scratch, other; 348 349 dest = operands[0]; 350 scratch = operands[2]; 351 352 other = XEXP (operands[1], 1); 353 if (other == stack_pointer_rtx) 354 other = XEXP (operands[1], 0); 355 356 if (true_regnum (other) == true_regnum (dest)) 357 { 358 gcc_assert (true_regnum (scratch) != true_regnum (dest)); 359 emit_move_insn (scratch, stack_pointer_rtx); 360 emit_insn (gen_addsi3 (dest, dest, scratch)); 361 } 362 else if (TARGET_AM33 || REGNO_REG_CLASS (true_regnum (dest)) == ADDRESS_REGS) 363 { 364 emit_move_insn (dest, stack_pointer_rtx); 365 if (other == stack_pointer_rtx) 366 emit_insn (gen_addsi3 (dest, dest, dest)); 367 else if (other != const0_rtx) 368 emit_insn (gen_addsi3 (dest, dest, other)); 369 } 370 else 371 { 372 emit_move_insn (scratch, stack_pointer_rtx); 373 if (other == stack_pointer_rtx) 374 { 375 emit_move_insn (dest, scratch); 376 emit_insn (gen_addsi3 (dest, dest, dest)); 377 } 378 else if (other != const0_rtx) 379 { 380 emit_move_insn (dest, other); 381 emit_insn (gen_addsi3 (dest, dest, scratch)); 382 } 383 else 384 emit_move_insn (dest, scratch); 385 } 386 DONE; 387}) 388 389(define_expand "movsi" 390 [(set (match_operand:SI 0 "nonimmediate_operand") 391 (match_operand:SI 1 "general_operand"))] 392 "" 393{ 394 /* One of the ops has to be in a register. */ 395 if (!register_operand (operand1, SImode) 396 && !register_operand (operand0, SImode)) 397 operands[1] = force_reg (SImode, operand1); 398 if (flag_pic) 399 { 400 rtx temp; 401 if (SYMBOLIC_CONST_P (operands[1])) 402 { 403 if (MEM_P (operands[0])) 404 operands[1] = force_reg (Pmode, operands[1]); 405 else 406 { 407 temp = (!can_create_pseudo_p () 408 ? operands[0] 409 : gen_reg_rtx (Pmode)); 410 operands[1] = mn10300_legitimize_pic_address (operands[1], temp); 411 } 412 } 413 else if (GET_CODE (operands[1]) == CONST 414 && GET_CODE (XEXP (operands[1], 0)) == PLUS 415 && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0))) 416 { 417 temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); 418 temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0), 419 temp); 420 operands[1] = expand_binop (SImode, add_optab, temp, 421 XEXP (XEXP (operands[1], 0), 1), 422 (!can_create_pseudo_p () 423 ? temp 424 : gen_reg_rtx (Pmode)), 425 0, OPTAB_LIB_WIDEN); 426 } 427 } 428}) 429 430(define_insn "*movsi_internal" 431 [(set (match_operand:SI 0 "nonimmediate_operand" 432 "=r,r,r,r,m,r, A,*y,*y,*z,*d") 433 (match_operand:SI 1 "general_operand" 434 " 0,O,i,r,r,m,*y, A, i,*d,*z"))] 435 "register_operand (operands[0], SImode) 436 || register_operand (operands[1], SImode)" 437{ 438 switch (which_alternative) 439 { 440 case 0: 441 return ""; 442 case 1: /* imm-reg. */ 443 case 2: 444 /* See movhi for a discussion of sizes for 8-bit movu. Note that the 445 24-bit movu is 6 bytes, which is the same size as the full 32-bit 446 mov form for An and Dn. So again movu is only a win for Rn. */ 447 if (TARGET_AM33 448 && CONST_INT_P (operands[1]) 449 && REGNO_EXTENDED_P (REGNO (operands[0]), 1)) 450 { 451 HOST_WIDE_INT val = INTVAL (operands[1]); 452 if (IN_RANGE (val, 0x80, 0xff) 453 || IN_RANGE (val, 0x800000, 0xffffff)) 454 return "movu %1,%0"; 455 } 456 /* FALLTHRU */ 457 case 3: /* reg-reg */ 458 case 4: /* reg-mem */ 459 case 5: /* mem-reg */ 460 case 6: /* sp-reg */ 461 case 7: /* reg-sp */ 462 case 8: /* imm-sp */ 463 case 9: /* reg-mdr */ 464 case 10: /* mdr-reg */ 465 return "mov %1,%0"; 466 default: 467 gcc_unreachable (); 468 } 469} 470 [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*") 471 (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*") 472 (set_attr "liw_op" "mov") 473 (set_attr_alternative "timings" 474 [(const_int 11) 475 (const_int 22) 476 (const_int 22) 477 (const_int 11) 478 (if_then_else (eq_attr "cpu" "am34") 479 (const_int 11) (const_int 22)) 480 (if_then_else (eq_attr "cpu" "am34") 481 (const_int 13) (const_int 24)) 482 (if_then_else (eq_attr "cpu" "am34") 483 (const_int 11) (const_int 22)) 484 (if_then_else (eq_attr "cpu" "am34") 485 (const_int 13) (const_int 24)) 486 (const_int 11) 487 (const_int 11) 488 (const_int 11) 489 ])] 490) 491 492(define_expand "movsf" 493 [(set (match_operand:SF 0 "nonimmediate_operand") 494 (match_operand:SF 1 "general_operand"))] 495 "TARGET_AM33_2" 496{ 497 /* One of the ops has to be in a register. */ 498 if (!register_operand (operand1, SFmode) 499 && !register_operand (operand0, SFmode)) 500 operands[1] = force_reg (SFmode, operand1); 501}) 502 503(define_insn "*movsf_internal" 504 [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d") 505 (match_operand:SF 1 "general_operand" " 0,F,F,r,f,f,r,m,r,Q,f,d,z"))] 506 "TARGET_AM33_2 507 && (register_operand (operands[0], SFmode) 508 || register_operand (operands[1], SFmode))" 509{ 510 switch (which_alternative) 511 { 512 case 0: 513 return ""; 514 case 1: 515 case 3: 516 case 7: 517 case 8: 518 case 11: 519 case 12: 520 return "mov %1,%0"; 521 case 2: 522 case 4: 523 case 5: 524 case 6: 525 case 9: 526 case 10: 527 return "fmov %1,%0"; 528 default: 529 gcc_unreachable (); 530 } 531} 532 [(set_attr_alternative "timings" 533 [(const_int 11) 534 (const_int 22) 535 (if_then_else (eq_attr "cpu" "am34") 536 (const_int 47) (const_int 25)) 537 (const_int 11) 538 (if_then_else (eq_attr "cpu" "am34") 539 (const_int 13) (const_int 14)) 540 (if_then_else (eq_attr "cpu" "am34") 541 (const_int 13) (const_int 12)) 542 (if_then_else (eq_attr "cpu" "am34") 543 (const_int 13) (const_int 14)) 544 (if_then_else (eq_attr "cpu" "am34") 545 (const_int 13) (const_int 24)) 546 (if_then_else (eq_attr "cpu" "am34") 547 (const_int 13) (const_int 24)) 548 (if_then_else (eq_attr "cpu" "am34") 549 (const_int 13) (const_int 24)) 550 (if_then_else (eq_attr "cpu" "am34") 551 (const_int 13) (const_int 24)) 552 (const_int 22) 553 (const_int 22) 554 ])] 555) 556 557;; If the flags register is not live, generate CLR instead of MOV 0. 558;; For MN103, this is only legal for DATA_REGS; for AM33 this is legal 559;; but not a win for ADDRESS_REGS. 560(define_peephole2 561 [(set (match_operand:INT 0 "register_operand" "") (const_int 0))] 562 "peep2_regno_dead_p (0, CC_REG) 563 && (REGNO_DATA_P (REGNO (operands[0]), 1) 564 || REGNO_EXTENDED_P (REGNO (operands[0]), 1))" 565 [(parallel [(set (match_dup 0) (const_int 0)) 566 (clobber (reg:CC CC_REG))])] 567) 568 569(define_insn "*mov<mode>_clr" 570 [(set (match_operand:INT 0 "register_operand" "=D") 571 (const_int 0)) 572 (clobber (reg:CC CC_REG))] 573 "" 574 "clr %0" 575) 576 577;; ---------------------------------------------------------------------- 578;; ADD INSTRUCTIONS 579;; ---------------------------------------------------------------------- 580 581(define_insn "addsi3" 582 [(set (match_operand:SI 0 "register_operand" "=r,r,r,!*y,!r") 583 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0, r") 584 (match_operand:SI 2 "nonmemory_operand" "r,O,i, i, r"))) 585 (clobber (reg:CC CC_REG))] 586 "" 587 { return mn10300_output_add (operands, false); } 588 [(set_attr "timings" "11,11,11,11,22") 589 (set_attr "liw" "either,either,*,*,*") 590 (set_attr "liw_op" "add")] 591) 592 593;; Note that ADD IMM,SP does not set the flags, so omit that here. 594(define_insn "*addsi3_flags" 595 [(set (reg CC_REG) 596 (compare (plus:SI (match_operand:SI 1 "register_operand" "%0, r") 597 (match_operand:SI 2 "nonmemory_operand" "ri, r")) 598 (const_int 0))) 599 (set (match_operand:SI 0 "register_operand" "=r,!r") 600 (plus:SI (match_dup 1) (match_dup 2)))] 601 "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" 602 { return mn10300_output_add (operands, true); } 603 [(set_attr "timings" "11,22")] 604) 605 606;; A helper to expand the above, with the CC_MODE filled in. 607(define_expand "addsi3_flags" 608 [(parallel [(set (reg:CCZNC CC_REG) 609 (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2)) 610 (const_int 0))) 611 (set (match_operand:SI 0 "register_operand") 612 (plus:SI (match_operand:SI 1 "register_operand") 613 (match_operand:SI 2 "nonmemory_operand")))])] 614 "" 615) 616 617(define_insn "addc_internal" 618 [(set (match_operand:SI 0 "register_operand" "=D,r,r") 619 (plus:SI 620 (plus:SI 621 (ltu:SI (reg:CC CC_REG) (const_int 0)) 622 (match_operand:SI 1 "register_operand" "%0,0,r")) 623 (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r"))) 624 (clobber (reg:CC CC_REG))] 625 "reload_completed" 626 "@ 627 addc %2,%0 628 addc %2,%0 629 addc %2,%1,%0" 630 [(set_attr "isa" "*,am33,am33")] 631) 632 633(define_expand "adddi3" 634 [(set (match_operand:DI 0 "register_operand" "") 635 (plus:DI (match_operand:DI 1 "register_operand" "") 636 (match_operand:DI 2 "nonmemory_operand" "")))] 637 "" 638{ 639 rtx op0l, op0h, op1l, op1h, op2l, op2h; 640 641 op0l = gen_lowpart (SImode, operands[0]); 642 op1l = gen_lowpart (SImode, operands[1]); 643 op2l = gen_lowpart (SImode, operands[2]); 644 op0h = gen_highpart (SImode, operands[0]); 645 op1h = gen_highpart (SImode, operands[1]); 646 op2h = gen_highpart_mode (SImode, DImode, operands[2]); 647 648 if (!reg_or_am33_const_operand (op2h, SImode)) 649 op2h = force_reg (SImode, op2h); 650 651 emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h)); 652 DONE; 653}) 654 655;; Note that reload only supports one commutative operand. Thus we cannot 656;; auto-swap both the high and low outputs with their matching constraints. 657;; For MN103, we're strapped for registers but thankfully the alternatives 658;; are few. For AM33, it becomes much easier to not represent the early 659;; clobber and 6 permutations of immediate and three-operand adds, but 660;; instead allocate a scratch register and do the expansion by hand. 661 662(define_insn_and_split "adddi3_internal" 663 [(set (match_operand:SI 0 "register_operand" "=r, r, r") 664 (plus:SI (match_operand:SI 2 "register_operand" "%0, 0, r") 665 (match_operand:SI 3 "nonmemory_operand" "ri,ri,ri"))) 666 (set (match_operand:SI 1 "register_operand" "=D, D, r") 667 (plus:SI 668 (plus:SI 669 (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2)) 670 (match_operand:SI 4 "register_operand" " 1, D, r")) 671 (match_operand:SI 5 "reg_or_am33_const_operand" " D, 1,ri"))) 672 (clobber (match_scratch:SI 6 "=X, X,&r")) 673 (clobber (reg:CC CC_REG))] 674 "" 675 "#" 676 "reload_completed" 677 [(const_int 0)] 678{ 679 rtx op0l = operands[0]; 680 rtx op0h = operands[1]; 681 rtx op1l = operands[2]; 682 rtx op2l = operands[3]; 683 rtx op1h = operands[4]; 684 rtx op2h = operands[5]; 685 rtx scratch = operands[6]; 686 rtx x; 687 688 if (reg_overlap_mentioned_p (op0l, op1h)) 689 { 690 emit_move_insn (scratch, op0l); 691 op1h = scratch; 692 if (reg_overlap_mentioned_p (op0l, op2h)) 693 op2h = scratch; 694 } 695 else if (reg_overlap_mentioned_p (op0l, op2h)) 696 { 697 emit_move_insn (scratch, op0l); 698 op2h = scratch; 699 } 700 701 if (rtx_equal_p (op0l, op1l)) 702 ; 703 else if (rtx_equal_p (op0l, op2l)) 704 x = op1l, op1l = op2l, op2l = x; 705 else 706 { 707 gcc_assert (TARGET_AM33); 708 if (!REG_P (op2l)) 709 { 710 emit_move_insn (op0l, op2l); 711 op2l = op1l; 712 op1l = op0l; 713 } 714 } 715 emit_insn (gen_addsi3_flags (op0l, op1l, op2l)); 716 717 if (rtx_equal_p (op0h, op1h)) 718 ; 719 else if (rtx_equal_p (op0h, op2h)) 720 x = op1h, op1h = op2h, op2h = x; 721 else 722 { 723 gcc_assert (TARGET_AM33); 724 if (!REG_P (op2h)) 725 { 726 emit_move_insn (op0h, op2h); 727 op2h = op1h; 728 op1h = op0h; 729 } 730 } 731 emit_insn (gen_addc_internal (op0h, op1h, op2h)); 732 DONE; 733} 734 [(set_attr "isa" "*,*,am33")] 735) 736 737;; The following pattern is generated by combine when it proves that one 738;; of the inputs to the low-part of the double-word add is zero, and thus 739;; no carry is generated into the high-part. 740 741(define_insn_and_split "*adddi3_degenerate" 742 [(set (match_operand:SI 0 "register_operand" "=&r,&r") 743 (match_operand:SI 2 "nonmemory_operand" " 0, 0")) 744 (set (match_operand:SI 1 "register_operand" "=r , r") 745 (plus:SI (match_operand:SI 3 "register_operand" "%1 , r") 746 (match_operand:SI 4 "nonmemory_operand" "ri, r"))) 747 (clobber (reg:CC CC_REG))] 748 "" 749 "#" 750 "" 751 [(const_int 0)] 752{ 753 rtx scratch = NULL_RTX; 754 if (!rtx_equal_p (operands[0], operands[2])) 755 { 756 if (reg_overlap_mentioned_p (operands[0], operands[3]) 757 || reg_overlap_mentioned_p (operands[0], operands[4])) 758 { 759 scratch = gen_reg_rtx (SImode); 760 emit_move_insn (scratch, operands[2]); 761 } 762 else 763 emit_move_insn (operands[0], operands[2]); 764 } 765 emit_insn (gen_addsi3 (operands[1], operands[3], operands[4])); 766 if (scratch) 767 emit_move_insn (operands[0], scratch); 768 DONE; 769}) 770 771;; ---------------------------------------------------------------------- 772;; SUBTRACT INSTRUCTIONS 773;; ---------------------------------------------------------------------- 774 775(define_insn "subsi3" 776 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 777 (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r") 778 (match_operand:SI 2 "nonmemory_operand" "r,O,i,r"))) 779 (clobber (reg:CC CC_REG))] 780 "" 781 "@ 782 sub %2,%0 783 sub %2,%0 784 sub %2,%0 785 sub %2,%1,%0" 786 [(set_attr "isa" "*,*,*,am33") 787 (set_attr "liw" "either,either,*,*") 788 (set_attr "liw_op" "sub") 789 (set_attr "timings" "11,11,11,22")] 790) 791 792(define_insn "*subsi3_flags" 793 [(set (reg CC_REG) 794 (compare (minus:SI (match_operand:SI 1 "register_operand" "0, r") 795 (match_operand:SI 2 "nonmemory_operand" "ri,r")) 796 (const_int 0))) 797 (set (match_operand:SI 0 "register_operand" "=r, r") 798 (minus:SI (match_dup 1) (match_dup 2)))] 799 "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" 800 "@ 801 sub %2,%0 802 sub %2,%1,%0" 803 [(set_attr "isa" "*,am33") 804 (set_attr "timings" "11,22")] 805) 806 807;; A helper to expand the above, with the CC_MODE filled in. 808(define_expand "subsi3_flags" 809 [(parallel [(set (reg:CCZNC CC_REG) 810 (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2)) 811 (const_int 0))) 812 (set (match_operand:SI 0 "register_operand") 813 (minus:SI (match_operand:SI 1 "register_operand") 814 (match_operand:SI 2 "nonmemory_operand")))])] 815 "" 816) 817 818(define_insn "subc_internal" 819 [(set (match_operand:SI 0 "register_operand" "=D,r,r") 820 (minus:SI 821 (minus:SI (match_operand:SI 1 "register_operand" " 0,0,r") 822 (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r")) 823 (geu:SI (reg:CC CC_REG) (const_int 0)))) 824 (clobber (reg:CC CC_REG))] 825 "reload_completed" 826 "@ 827 subc %2,%0 828 subc %2,%0 829 subc %2,%1,%0" 830 [(set_attr "isa" "*,am33,am33")] 831) 832 833(define_expand "subdi3" 834 [(set (match_operand:DI 0 "register_operand" "") 835 (minus:DI (match_operand:DI 1 "register_operand" "") 836 (match_operand:DI 2 "nonmemory_operand" "")))] 837 "" 838{ 839 rtx op0l, op0h, op1l, op1h, op2l, op2h; 840 841 op0l = gen_lowpart (SImode, operands[0]); 842 op1l = gen_lowpart (SImode, operands[1]); 843 op2l = gen_lowpart (SImode, operands[2]); 844 op0h = gen_highpart (SImode, operands[0]); 845 op1h = gen_highpart (SImode, operands[1]); 846 op2h = gen_highpart_mode (SImode, DImode, operands[2]); 847 848 if (!reg_or_am33_const_operand (op2h, SImode)) 849 op2h = force_reg (SImode, op2h); 850 851 emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op1h, op2l, op2h)); 852 DONE; 853}) 854 855;; As with adddi3, the use of the scratch register helps reduce the 856;; number of permutations for AM33. 857;; ??? The early clobber on op0 avoids a reload bug wherein both output 858;; registers are set the same. Consider negate, where both op2 and op3 859;; are 0, are csed to the same input register, and reload fails to undo 860;; the cse when satisfying the matching constraints. 861 862(define_insn_and_split "subdi3_internal" 863 [(set (match_operand:SI 0 "register_operand" "=&r, r") 864 (minus:SI 865 (match_operand:SI 2 "register_operand" " 0, r") 866 (match_operand:SI 4 "nonmemory_operand" " ri,ri"))) 867 (set (match_operand:SI 1 "register_operand" "=D , r") 868 (minus:SI 869 (minus:SI 870 (match_operand:SI 3 "register_operand" " 1, r") 871 (match_operand:SI 5 "reg_or_am33_const_operand" " D,ri")) 872 (ltu:SI (match_dup 2) (match_dup 4)))) 873 (clobber (match_scratch:SI 6 "=X ,&r")) 874 (clobber (reg:CC CC_REG))] 875 "" 876 "#" 877 "reload_completed" 878 [(const_int 0)] 879{ 880 rtx op0l = operands[0]; 881 rtx op0h = operands[1]; 882 rtx op1l = operands[2]; 883 rtx op1h = operands[3]; 884 rtx op2l = operands[4]; 885 rtx op2h = operands[5]; 886 rtx scratch = operands[6]; 887 888 if (reg_overlap_mentioned_p (op0l, op1h)) 889 { 890 emit_move_insn (scratch, op0l); 891 op1h = scratch; 892 if (reg_overlap_mentioned_p (op0l, op2h)) 893 op2h = scratch; 894 } 895 else if (reg_overlap_mentioned_p (op0l, op2h)) 896 { 897 emit_move_insn (scratch, op0l); 898 op2h = scratch; 899 } 900 901 if (!rtx_equal_p (op0l, op1l)) 902 { 903 gcc_assert (TARGET_AM33); 904 if (!REG_P (op2l)) 905 { 906 emit_move_insn (op0l, op1l); 907 op1l = op0l; 908 } 909 } 910 emit_insn (gen_subsi3_flags (op0l, op1l, op2l)); 911 912 if (!rtx_equal_p (op0h, op1h)) 913 { 914 gcc_assert (TARGET_AM33); 915 if (!REG_P (op2h)) 916 { 917 emit_move_insn (op0h, op1h); 918 op1h = op0h; 919 } 920 } 921 emit_insn (gen_subc_internal (op0h, op1h, op2h)); 922 DONE; 923} 924 [(set_attr "isa" "*,am33")] 925) 926 927;; The following pattern is generated by combine when it proves that one 928;; of the inputs to the low-part of the double-word sub is zero, and thus 929;; no carry is generated into the high-part. 930 931(define_insn_and_split "*subdi3_degenerate" 932 [(set (match_operand:SI 0 "register_operand" "=&r,&r") 933 (match_operand:SI 2 "nonmemory_operand" " 0, 0")) 934 (set (match_operand:SI 1 "register_operand" "=r , r") 935 (minus:SI (match_operand:SI 3 "register_operand" " 1, r") 936 (match_operand:SI 4 "nonmemory_operand" " ri, r"))) 937 (clobber (reg:CC CC_REG))] 938 "" 939 "#" 940 "" 941 [(const_int 0)] 942{ 943 rtx scratch = NULL_RTX; 944 if (!rtx_equal_p (operands[0], operands[2])) 945 { 946 gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1])); 947 if (reg_overlap_mentioned_p (operands[0], operands[3]) 948 || reg_overlap_mentioned_p (operands[0], operands[4])) 949 { 950 scratch = gen_reg_rtx (SImode); 951 emit_move_insn (scratch, operands[2]); 952 } 953 else 954 emit_move_insn (operands[0], operands[2]); 955 } 956 emit_insn (gen_subsi3 (operands[1], operands[3], operands[4])); 957 if (scratch) 958 emit_move_insn (operands[0], scratch); 959 DONE; 960}) 961 962(define_insn_and_split "negsi2" 963 [(set (match_operand:SI 0 "register_operand" "=D,&r") 964 (neg:SI (match_operand:SI 1 "register_operand" " 0, r"))) 965 (clobber (reg:CC CC_REG))] 966 "" 967 "#" 968 "&& reload_completed" 969 [(const_int 0)] 970{ 971 /* Recall that twos-compliment is ones-compliment plus one. When 972 allocated in DATA_REGS this is 2+1 bytes; otherwise (for am33) 973 this is 3+3 bytes. 974 975 For AM33, it would have been possible to load zero and use the 976 three-address subtract to have a total size of 3+4*N bytes for 977 multiple negations, plus increased throughput. Not attempted here. */ 978 979 if (true_regnum (operands[0]) == true_regnum (operands[1])) 980 { 981 emit_insn (gen_one_cmplsi2 (operands[0], operands[0])); 982 emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx)); 983 } 984 else 985 { 986 emit_move_insn (operands[0], const0_rtx); 987 emit_insn (gen_subsi3 (operands[0], operands[0], operands[1])); 988 } 989 DONE; 990}) 991 992;; ---------------------------------------------------------------------- 993;; MULTIPLY INSTRUCTIONS 994;; ---------------------------------------------------------------------- 995 996;; ??? Note that AM33 has a third multiply variant that puts the high part 997;; into the MDRQ register, however this variant also constrains the inputs 998;; to be in DATA_REGS and thus isn't as helpful as it might be considering 999;; the existence of the 4-operand multiply. Nor is there a set of divide 1000;; insns that use MDRQ. Given that there is an IMM->MDRQ insn, this would 1001;; have been very handy for starting udivmodsi4... 1002 1003(define_expand "mulsidi3" 1004 [(set (match_operand:DI 0 "register_operand" "") 1005 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 1006 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))] 1007 "" 1008{ 1009 emit_insn (gen_mulsidi3_internal (gen_lowpart (SImode, operands[0]), 1010 gen_highpart (SImode, operands[0]), 1011 operands[1], operands[2])); 1012 DONE; 1013}) 1014 1015(define_insn "mulsidi3_internal" 1016 [(set (match_operand:SI 0 "register_operand" "=D,r") 1017 (mult:SI (match_operand:SI 2 "register_operand" "%0,r") 1018 (match_operand:SI 3 "register_operand" " D,r"))) 1019 (set (match_operand:SI 1 "register_operand" "=z,r") 1020 (truncate:SI 1021 (ashiftrt:DI 1022 (mult:DI (sign_extend:DI (match_dup 2)) 1023 (sign_extend:DI (match_dup 3))) 1024 (const_int 32)))) 1025 (clobber (reg:CC CC_REG))] 1026 "" 1027{ 1028 if (which_alternative == 1) 1029 return "mul %2,%3,%1,%0"; 1030 else if (TARGET_MULT_BUG) 1031 return "nop\;nop\;mul %3,%0"; 1032 else 1033 return "mul %3,%0"; 1034} 1035 [(set_attr "isa" "*,am33") 1036 (set (attr "timings") 1037 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 1038) 1039 1040(define_expand "umulsidi3" 1041 [(set (match_operand:DI 0 "register_operand" "") 1042 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 1043 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))) 1044 (clobber (reg:CC CC_REG))] 1045 "" 1046{ 1047 emit_insn (gen_umulsidi3_internal (gen_lowpart (SImode, operands[0]), 1048 gen_highpart (SImode, operands[0]), 1049 operands[1], operands[2])); 1050 DONE; 1051}) 1052 1053(define_insn "umulsidi3_internal" 1054 [(set (match_operand:SI 0 "register_operand" "=D,r") 1055 (mult:SI (match_operand:SI 2 "register_operand" "%0,r") 1056 (match_operand:SI 3 "register_operand" " D,r"))) 1057 (set (match_operand:SI 1 "register_operand" "=z,r") 1058 (truncate:SI 1059 (lshiftrt:DI 1060 (mult:DI (zero_extend:DI (match_dup 2)) 1061 (zero_extend:DI (match_dup 3))) 1062 (const_int 32)))) 1063 (clobber (reg:CC CC_REG))] 1064 "" 1065{ 1066 if (which_alternative == 1) 1067 return "mulu %2,%3,%1,%0"; 1068 else if (TARGET_MULT_BUG) 1069 return "nop\;nop\;mulu %3,%0"; 1070 else 1071 return "mulu %3,%0"; 1072} 1073 [(set_attr "isa" "*,am33") 1074 (set (attr "timings") 1075 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 1076) 1077 1078(define_expand "mulsi3" 1079 [(parallel [(set (match_operand:SI 0 "register_operand") 1080 (mult:SI (match_operand:SI 1 "register_operand") 1081 (match_operand:SI 2 "reg_or_am33_const_operand"))) 1082 (clobber (match_scratch:SI 3)) 1083 (clobber (reg:CC CC_REG))])] 1084 "" 1085) 1086 1087(define_insn "*mulsi3" 1088 [(set (match_operand:SI 0 "register_operand" "=D, r,r") 1089 (mult:SI (match_operand:SI 2 "register_operand" "%0, 0,r") 1090 (match_operand:SI 3 "reg_or_am33_const_operand" " D,ri,r"))) 1091 (clobber (match_scratch:SI 1 "=z, z,r")) 1092 (clobber (reg:CC CC_REG))] 1093 "" 1094{ 1095 if (which_alternative == 2) 1096 return "mul %2,%3,%1,%0"; 1097 else if (TARGET_MULT_BUG) 1098 return "nop\;nop\;mul %3,%0"; 1099 else 1100 return "mul %3,%0"; 1101} 1102 [(set_attr "isa" "*,am33,am33") 1103 (set (attr "timings") 1104 (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 1105) 1106 1107(define_expand "udivmodsi4" 1108 [(parallel [(set (match_operand:SI 0 "register_operand") 1109 (udiv:SI (match_operand:SI 1 "register_operand") 1110 (match_operand:SI 2 "register_operand"))) 1111 (set (match_operand:SI 3 "register_operand") 1112 (umod:SI (match_dup 1) (match_dup 2))) 1113 (use (const_int 0)) 1114 (clobber (reg:CC CC_REG))])] 1115 "" 1116) 1117 1118;; Note the trick to get reload to put the zero into the MDR register, 1119;; rather than exposing the load early and letting CSE or someone try 1120;; to share the zeros between division insns. Which tends to result 1121;; in sequences like 0->r0->d0->mdr. 1122 1123(define_insn "*udivmodsi4" 1124 [(set (match_operand:SI 0 "register_operand" "=D") 1125 (udiv:SI (match_operand:SI 2 "register_operand" " 0") 1126 (match_operand:SI 3 "register_operand" " D"))) 1127 (set (match_operand:SI 1 "register_operand" "=z") 1128 (umod:SI (match_dup 2) (match_dup 3))) 1129 (use (match_operand:SI 4 "nonmemory_operand" " 1")) 1130 (clobber (reg:CC CC_REG))] 1131 "" 1132 "divu %3,%0" 1133 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1134 (const_int 3839) (const_int 4243)))] 1135) 1136 1137(define_expand "divmodsi4" 1138 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1139 (div:SI (match_operand:SI 1 "register_operand" "") 1140 (match_operand:SI 2 "register_operand" ""))) 1141 (set (match_operand:SI 3 "register_operand" "") 1142 (mod:SI (match_dup 1) (match_dup 2))) 1143 (use (match_dup 4)) 1144 (clobber (reg:CC CC_REG))])] 1145 "" 1146{ 1147 operands[4] = gen_reg_rtx (SImode); 1148 emit_insn (gen_ext_internal (operands[4], operands[1])); 1149}) 1150 1151;; ??? Ideally we'd represent this via shift, but it seems like adding a 1152;; special-case pattern for (ashiftrt x 31) is just as likely to result 1153;; in poor register allocation choices. 1154(define_insn "ext_internal" 1155 [(set (match_operand:SI 0 "register_operand" "=z") 1156 (unspec:SI [(match_operand:SI 1 "register_operand" "D")] UNSPEC_EXT))] 1157 "" 1158 "ext %1" 1159) 1160 1161(define_insn "*divmodsi4" 1162 [(set (match_operand:SI 0 "register_operand" "=D") 1163 (div:SI (match_operand:SI 2 "register_operand" " 0") 1164 (match_operand:SI 3 "register_operand" " D"))) 1165 (set (match_operand:SI 1 "register_operand" "=z") 1166 (mod:SI (match_dup 2) (match_dup 3))) 1167 (use (match_operand:SI 4 "register_operand" " 1")) 1168 (clobber (reg:CC CC_REG))] 1169 "" 1170 "div %3,%0"; 1171 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1172 (const_int 3839) (const_int 4243)))] 1173) 1174 1175 1176;; ---------------------------------------------------------------------- 1177;; AND INSTRUCTIONS 1178;; ---------------------------------------------------------------------- 1179 1180(define_insn "andsi3" 1181 [(set (match_operand:SI 0 "register_operand" "=D,D,r") 1182 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1183 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 1184 (clobber (reg:CC CC_REG))] 1185 "" 1186 "@ 1187 and %2,%0 1188 and %2,%0 1189 and %2,%1,%0" 1190 [(set_attr "isa" "*,*,am33") 1191 (set_attr "liw" "*,op1,*") 1192 (set_attr "liw_op" "and") 1193 (set_attr "timings" "22,11,11")] 1194) 1195 1196(define_insn "*andsi3_flags" 1197 [(set (reg CC_REG) 1198 (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1199 (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1200 (const_int 0))) 1201 (set (match_operand:SI 0 "register_operand" "=D,D,r") 1202 (and:SI (match_dup 1) (match_dup 2)))] 1203 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 1204 "@ 1205 and %2,%0 1206 and %2,%0 1207 and %2,%1,%0" 1208 [(set_attr "isa" "*,*,am33") 1209 (set_attr "timings" "22,11,11")] 1210) 1211 1212;; Make sure we generate extensions instead of ANDs. 1213 1214(define_split 1215 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1216 (and:SI (match_operand:SI 1 "register_operand" "") 1217 (const_int 255))) 1218 (clobber (reg:CC CC_REG))])] 1219 "" 1220 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 1221 { operands[1] = gen_lowpart (QImode, operands[1]); } 1222) 1223 1224(define_split 1225 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1226 (and:SI (match_operand:SI 1 "register_operand" "") 1227 (const_int 65535))) 1228 (clobber (reg:CC CC_REG))])] 1229 "" 1230 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 1231 { operands[1] = gen_lowpart (HImode, operands[1]); } 1232) 1233 1234;; Split AND by an appropriate constant into two shifts. Recall that 1235;; operations with a full 32-bit immediate require an extra cycle, so 1236;; this is a size optimization with no speed penalty. This only applies 1237;; do DATA_REGS; the shift insns that AM33 adds are too large for a win. 1238 1239(define_split 1240 [(parallel [(set (match_operand:SI 0 "register_operand" "") 1241 (and:SI (match_dup 0) 1242 (match_operand:SI 1 "const_int_operand" ""))) 1243 (clobber (reg:CC CC_REG))])] 1244 "reload_completed 1245 && REGNO_DATA_P (true_regnum (operands[0]), 1) 1246 && mn10300_split_and_operand_count (operands[1]) != 0" 1247 [(const_int 0)] 1248{ 1249 int count = mn10300_split_and_operand_count (operands[1]); 1250 if (count > 0) 1251 { 1252 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (count))); 1253 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (count))); 1254 } 1255 else 1256 { 1257 emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (-count))); 1258 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (-count))); 1259 } 1260 DONE; 1261}) 1262 1263;; ---------------------------------------------------------------------- 1264;; OR INSTRUCTIONS 1265;; ---------------------------------------------------------------------- 1266 1267(define_insn "iorsi3" 1268 [(set (match_operand:SI 0 "register_operand" "=D,D,r") 1269 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1270 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 1271 (clobber (reg:CC CC_REG))] 1272 "" 1273 "@ 1274 or %2,%0 1275 or %2,%0 1276 or %2,%1,%0" 1277 [(set_attr "isa" "*,*,am33") 1278 (set_attr "liw" "*,op1,*") 1279 (set_attr "liw_op" "or") 1280 (set_attr "timings" "22,11,11")] 1281) 1282 1283(define_insn "*iorsi3_flags" 1284 [(set (reg CC_REG) 1285 (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1286 (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1287 (const_int 0))) 1288 (set (match_operand:SI 0 "register_operand" "=D,D,r") 1289 (ior:SI (match_dup 1) (match_dup 2)))] 1290 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 1291 "@ 1292 or %2,%0 1293 or %2,%0 1294 or %2,%1,%0" 1295 [(set_attr "isa" "*,*,am33") 1296 (set_attr "timings" "22,11,11")] 1297) 1298 1299;; ---------------------------------------------------------------------- 1300;; XOR INSTRUCTIONS 1301;; ---------------------------------------------------------------------- 1302 1303(define_insn "xorsi3" 1304 [(set (match_operand:SI 0 "register_operand" "=D,D,r") 1305 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1306 (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 1307 (clobber (reg:CC CC_REG))] 1308 "" 1309 "@ 1310 xor %2,%0 1311 xor %2,%0 1312 xor %2,%1,%0" 1313 [(set_attr "isa" "*,*,am33") 1314 (set_attr "liw" "*,op1,*") 1315 (set_attr "liw_op" "xor") 1316 (set_attr "timings" "22,11,11")] 1317) 1318 1319(define_insn "*xorsi3_flags" 1320 [(set (reg CC_REG) 1321 (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1322 (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1323 (const_int 0))) 1324 (set (match_operand:SI 0 "register_operand" "=D,D,r") 1325 (xor:SI (match_dup 1) (match_dup 2)))] 1326 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 1327 "@ 1328 xor %2,%0 1329 xor %2,%0 1330 xor %2,%1,%0" 1331 [(set_attr "isa" "*,*,am33") 1332 (set_attr "timings" "22,11,11")] 1333) 1334 1335;; ---------------------------------------------------------------------- 1336;; NOT INSTRUCTIONS 1337;; ---------------------------------------------------------------------- 1338 1339(define_insn "one_cmplsi2" 1340 [(set (match_operand:SI 0 "register_operand" "=D") 1341 (not:SI (match_operand:SI 1 "register_operand" " 0"))) 1342 (clobber (reg:CC CC_REG))] 1343 "" 1344 "not %0" 1345) 1346 1347(define_insn "*one_cmplsi2_flags" 1348 [(set (reg CC_REG) 1349 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 1350 (const_int 0))) 1351 (set (match_operand:SI 0 "register_operand" "=D") 1352 (not:SI (match_dup 1)))] 1353 "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 1354 "not %0" 1355) 1356 1357;; ---------------------------------------------------------------------- 1358;; COMPARE AND BRANCH INSTRUCTIONS 1359;; ---------------------------------------------------------------------- 1360 1361;; We expand the comparison into a single insn so that it will not be split 1362;; up by reload. 1363(define_expand "cbranchsi4" 1364 [(set (pc) 1365 (if_then_else 1366 (match_operator 0 "ordered_comparison_operator" 1367 [(match_operand:SI 1 "register_operand") 1368 (match_operand:SI 2 "nonmemory_operand")]) 1369 (label_ref (match_operand 3 "")) 1370 (pc)))] 1371 "" 1372 "" 1373) 1374 1375(define_insn_and_split "*cbranchsi4_cmp" 1376 [(set (pc) 1377 (if_then_else (match_operator 3 "ordered_comparison_operator" 1378 [(match_operand:SI 0 "register_operand" "r") 1379 (match_operand:SI 1 "nonmemory_operand" "ri")]) 1380 (match_operand 2 "label_ref_operand" "") 1381 (pc)))] 1382 "" 1383 "#" 1384 "reload_completed" 1385 [(const_int 0)] 1386{ 1387 mn10300_split_cbranch (CCmode, operands[3], operands[2]); 1388 DONE; 1389}) 1390 1391(define_insn "cmpsi" 1392 [(set (reg CC_REG) 1393 (compare (match_operand:SI 0 "register_operand" "r,r,r") 1394 (match_operand:SI 1 "nonmemory_operand" "r,O,i")))] 1395 "reload_completed" 1396{ 1397 /* The operands of CMP must be distinct registers. In the case where 1398 we've failed to optimize the comparison of a register to itself, we 1399 must use another method to set the Z flag. We can achieve this 1400 effect with a BTST 0,D0. This will not alter the contents of D0; 1401 the use of d0 is arbitrary; any data register would work. */ 1402 if (rtx_equal_p (operands[0], operands[1])) 1403 return "btst 0,d0"; 1404 else 1405 return "cmp %1,%0"; 1406} 1407 [(set_attr_alternative "timings" 1408 [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) 1409 (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) 1410 (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))]) 1411 (set_attr "liw" "either,either,*") 1412 (set_attr "liw_op" "cmp")] 1413) 1414 1415(define_insn "*integer_conditional_branch" 1416 [(set (pc) 1417 (if_then_else (match_operator 0 "comparison_operator" 1418 [(match_operand 2 "int_mode_flags" "") 1419 (const_int 0)]) 1420 (label_ref (match_operand 1 "" "")) 1421 (pc)))] 1422 "reload_completed" 1423 "b%b0 %1" 1424) 1425 1426(define_insn_and_split "*cbranchsi4_btst" 1427 [(set (pc) 1428 (if_then_else 1429 (match_operator 3 "CCZN_comparison_operator" 1430 [(and:SI (match_operand:SI 0 "register_operand" "D") 1431 (match_operand:SI 1 "immediate_operand" "i")) 1432 (const_int 0)]) 1433 (match_operand 2 "label_ref_operand" "") 1434 (pc)))] 1435 "" 1436 "#" 1437 "reload_completed" 1438 [(const_int 0)] 1439{ 1440 mn10300_split_cbranch (CCZNmode, operands[3], operands[2]); 1441 DONE; 1442}) 1443 1444(define_insn "*btstsi" 1445 [(set (reg:CCZN CC_REG) 1446 (compare:CCZN 1447 (and:SI (match_operand:SI 0 "register_operand" "D") 1448 (match_operand:SI 1 "immediate_operand" "i")) 1449 (const_int 0)))] 1450 "reload_completed" 1451 "btst %1,%0" 1452) 1453 1454(define_expand "cbranchsf4" 1455 [(set (pc) 1456 (if_then_else 1457 (match_operator 0 "ordered_comparison_operator" 1458 [(match_operand:SF 1 "register_operand") 1459 (match_operand:SF 2 "nonmemory_operand")]) 1460 (label_ref (match_operand 3 "")) 1461 (pc)))] 1462 "TARGET_AM33_2" 1463 "" 1464) 1465 1466(define_insn_and_split "*cbranchsf4_cmp" 1467 [(set (pc) 1468 (if_then_else (match_operator 3 "ordered_comparison_operator" 1469 [(match_operand:SF 0 "register_operand" "f") 1470 (match_operand:SF 1 "nonmemory_operand" "fF")]) 1471 (match_operand 2 "label_ref_operand" "") 1472 (pc))) 1473 ] 1474 "TARGET_AM33_2" 1475 "#" 1476 "&& reload_completed" 1477 [(const_int 0)] 1478{ 1479 mn10300_split_cbranch (CC_FLOATmode, operands[3], operands[2]); 1480 DONE; 1481}) 1482 1483(define_insn "*am33_cmpsf" 1484 [(set (reg:CC_FLOAT CC_REG) 1485 (compare:CC_FLOAT (match_operand:SF 0 "register_operand" "f") 1486 (match_operand:SF 1 "nonmemory_operand" "fF")))] 1487 "TARGET_AM33_2 && reload_completed" 1488 "fcmp %1, %0" 1489 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1490 (const_int 17) (const_int 25)))] 1491) 1492 1493(define_insn "*float_conditional_branch" 1494 [(set (pc) 1495 (if_then_else (match_operator 0 "comparison_operator" 1496 [(reg:CC_FLOAT CC_REG) (const_int 0)]) 1497 (label_ref (match_operand 1 "" "")) 1498 (pc)))] 1499 "TARGET_AM33_2 && reload_completed" 1500 "fb%b0 %1" 1501 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1502 (const_int 44) (const_int 33)))] 1503) 1504 1505;; Unconditional and other jump instructions. 1506 1507(define_insn "jump" 1508 [(set (pc) 1509 (label_ref (match_operand 0 "" "")))] 1510 "" 1511 "jmp %l0" 1512 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1513 (const_int 11) (const_int 44)))] 1514) 1515 1516(define_insn "indirect_jump" 1517 [(set (pc) (match_operand:SI 0 "register_operand" "a"))] 1518 "" 1519 "jmp (%0)" 1520 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1521 (const_int 11) (const_int 33)))] 1522) 1523 1524(define_expand "builtin_setjmp_receiver" 1525 [(match_operand 0 "" "")] 1526 "flag_pic" 1527{ 1528 emit_insn (gen_load_pic ()); 1529 DONE; 1530}) 1531 1532(define_expand "casesi" 1533 [(match_operand:SI 0 "register_operand") 1534 (match_operand:SI 1 "immediate_operand") 1535 (match_operand:SI 2 "immediate_operand") 1536 (match_operand 3 "" "") (match_operand 4 "")] 1537 "" 1538{ 1539 rtx table = gen_reg_rtx (SImode); 1540 rtx index = gen_reg_rtx (SImode); 1541 rtx addr = gen_reg_rtx (Pmode); 1542 rtx test; 1543 1544 emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3])); 1545 emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1])))); 1546 test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]); 1547 emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4])); 1548 1549 emit_insn (gen_ashlsi3 (index, index, const2_rtx)); 1550 emit_move_insn (addr, gen_rtx_MEM (SImode, 1551 gen_rtx_PLUS (SImode, table, index))); 1552 if (flag_pic) 1553 emit_insn (gen_addsi3 (addr, addr, table)); 1554 1555 emit_jump_insn (gen_tablejump (addr, operands[3])); 1556 DONE; 1557}) 1558 1559(define_insn "tablejump" 1560 [(set (pc) (match_operand:SI 0 "register_operand" "a")) 1561 (use (label_ref (match_operand 1 "" "")))] 1562 "" 1563 "jmp (%0)" 1564 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1565 (const_int 11) (const_int 33)))] 1566) 1567 1568;; Call subroutine with no return value. 1569 1570(define_expand "call" 1571 [(call (match_operand:QI 0 "general_operand") 1572 (match_operand:SI 1 "general_operand"))] 1573 "" 1574{ 1575 rtx fn = XEXP (operands[0], 0); 1576 1577 if (flag_pic && GET_CODE (fn) == SYMBOL_REF) 1578 { 1579 if (MN10300_GLOBAL_P (fn)) 1580 { 1581 /* The PLT code won't run on AM30, but then, there's no 1582 shared library support for AM30 either, so we just assume 1583 the linker is going to adjust all @PLT relocs to the 1584 actual symbols. */ 1585 emit_use (pic_offset_table_rtx); 1586 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); 1587 } 1588 else 1589 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); 1590 } 1591 if (! call_address_operand (fn, VOIDmode)) 1592 fn = force_reg (SImode, fn); 1593 1594 XEXP (operands[0], 0) = fn; 1595}) 1596 1597(define_insn "*call_internal" 1598 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S")) 1599 (match_operand:SI 1 "" ""))] 1600 "" 1601 "@ 1602 calls %C0 1603 call %C0,[],0" 1604 [(set_attr_alternative "timings" 1605 [(if_then_else (eq_attr "cpu" "am34") 1606 (const_int 33) (const_int 44)) 1607 (if_then_else (eq_attr "cpu" "am34") 1608 (const_int 55) (const_int 33)) 1609 ]) 1610 ] 1611) 1612 1613;; Call subroutine, returning value in operand 0 1614;; (which must be a hard register). 1615 1616(define_expand "call_value" 1617 [(set (match_operand 0 "") 1618 (call (match_operand:QI 1 "general_operand") 1619 (match_operand:SI 2 "general_operand")))] 1620 "" 1621{ 1622 rtx fn = XEXP (operands[1], 0); 1623 1624 if (flag_pic && GET_CODE (fn) == SYMBOL_REF) 1625 { 1626 if (MN10300_GLOBAL_P (fn)) 1627 { 1628 /* The PLT code won't run on AM30, but then, there's no 1629 shared library support for AM30 either, so we just assume 1630 the linker is going to adjust all @PLT relocs to the 1631 actual symbols. */ 1632 emit_use (pic_offset_table_rtx); 1633 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); 1634 } 1635 else 1636 fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); 1637 } 1638 if (! call_address_operand (fn, VOIDmode)) 1639 fn = force_reg (SImode, fn); 1640 1641 XEXP (operands[1], 0) = fn; 1642}) 1643 1644(define_insn "call_value_internal" 1645 [(set (match_operand 0 "" "") 1646 (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S")) 1647 (match_operand:SI 2 "" "")))] 1648 "" 1649 "@ 1650 calls %C1 1651 call %C1,[],0" 1652 [(set_attr_alternative "timings" 1653 [(if_then_else (eq_attr "cpu" "am34") 1654 (const_int 33) (const_int 44)) 1655 (if_then_else (eq_attr "cpu" "am34") 1656 (const_int 55) (const_int 33)) 1657 ]) 1658 ] 1659) 1660 1661(define_expand "untyped_call" 1662 [(parallel [(call (match_operand 0 "") 1663 (const_int 0)) 1664 (match_operand 1 "") 1665 (match_operand 2 "")])] 1666 "" 1667{ 1668 int i; 1669 1670 emit_call_insn (gen_call (operands[0], const0_rtx)); 1671 1672 for (i = 0; i < XVECLEN (operands[2], 0); i++) 1673 { 1674 rtx set = XVECEXP (operands[2], 0, i); 1675 emit_move_insn (SET_DEST (set), SET_SRC (set)); 1676 } 1677 DONE; 1678}) 1679 1680(define_insn "nop" 1681 [(const_int 0)] 1682 "" 1683 "nop" 1684) 1685 1686;; ---------------------------------------------------------------------- 1687;; EXTEND INSTRUCTIONS 1688;; ---------------------------------------------------------------------- 1689 1690(define_insn "zero_extendqisi2" 1691 [(set (match_operand:SI 0 "register_operand" "=D,D,r") 1692 (zero_extend:SI 1693 (match_operand:QI 1 "nonimmediate_operand" " 0,m,r")))] 1694 "" 1695 "@ 1696 extbu %0 1697 movbu %1,%0 1698 extbu %1,%0" 1699 [(set_attr "isa" "*,*,am33") 1700 (set_attr_alternative "timings" 1701 [(const_int 11) 1702 (if_then_else (eq_attr "cpu" "am34") 1703 (const_int 13) (const_int 24)) 1704 (const_int 11) 1705 ])] 1706) 1707 1708(define_insn "zero_extendhisi2" 1709 [(set (match_operand:SI 0 "register_operand" "=D,D,r") 1710 (zero_extend:SI 1711 (match_operand:HI 1 "nonimmediate_operand" " 0,m,r")))] 1712 "" 1713 "@ 1714 exthu %0 1715 movhu %1,%0 1716 exthu %1,%0" 1717 [(set_attr "isa" "*,*,am33") 1718 (set_attr_alternative "timings" 1719 [(const_int 11) 1720 (if_then_else (eq_attr "cpu" "am34") 1721 (const_int 13) (const_int 24)) 1722 (const_int 11)])] 1723) 1724 1725(define_insn "extendqisi2" 1726 [(set (match_operand:SI 0 "register_operand" "=D,r") 1727 (sign_extend:SI 1728 (match_operand:QI 1 "register_operand" "0,r")))] 1729 "" 1730 "@ 1731 extb %0 1732 extb %1,%0" 1733 [(set_attr "isa" "*,am33")] 1734) 1735 1736(define_insn "extendhisi2" 1737 [(set (match_operand:SI 0 "register_operand" "=D,r") 1738 (sign_extend:SI 1739 (match_operand:HI 1 "register_operand" "0,r")))] 1740 "" 1741 "@ 1742 exth %0 1743 exth %1,%0" 1744 [(set_attr "isa" "*,am33")] 1745) 1746 1747;; ---------------------------------------------------------------------- 1748;; SHIFTS 1749;; ---------------------------------------------------------------------- 1750 1751(define_insn "ashlsi3" 1752 [(set (match_operand:SI 0 "register_operand" "=r,D,d,d,D,D,D,r") 1753 (ashift:SI 1754 (match_operand:SI 1 "register_operand" " 0,0,0,0,0,0,0,r") 1755 (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r"))) 1756 (clobber (reg:CC CC_REG))] 1757 "" 1758 "@ 1759 add %0,%0 1760 asl2 %0 1761 asl2 %0\;add %0,%0 1762 asl2 %0\;asl2 %0 1763 asl %S2,%0 1764 asl %S2,%0 1765 asl %S2,%0 1766 asl %2,%1,%0" 1767 [(set_attr "isa" "*,*,*,*,*,*,*,am33") 1768 (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*") 1769 (set_attr "liw_op" "asl") 1770 (set_attr "timings" "11,11,22,22,11,11,11,11")] 1771) 1772 1773(define_insn "lshrsi3" 1774 [(set (match_operand:SI 0 "register_operand" "=D,D,D,r") 1775 (lshiftrt:SI 1776 (match_operand:SI 1 "register_operand" "0,0,0,r") 1777 (match_operand:QI 2 "nonmemory_operand" "D,O,i,r"))) 1778 (clobber (reg:CC CC_REG))] 1779 "" 1780 "@ 1781 lsr %S2,%0 1782 lsr %S2,%0 1783 lsr %S2,%0 1784 lsr %2,%1,%0" 1785 [(set_attr "isa" "*,*,*,am33") 1786 (set_attr "liw" "op2,op2,*,*") 1787 (set_attr "liw_op" "lsr")] 1788) 1789 1790(define_insn "ashrsi3" 1791 [(set (match_operand:SI 0 "register_operand" "=D,D,D,r") 1792 (ashiftrt:SI 1793 (match_operand:SI 1 "register_operand" "0,0,0,r") 1794 (match_operand:QI 2 "nonmemory_operand" "D,O,i,r"))) 1795 (clobber (reg:CC CC_REG))] 1796 "" 1797 "@ 1798 asr %S2,%0 1799 asr %S2,%0 1800 asr %S2,%0 1801 asr %2,%1,%0" 1802 [(set_attr "isa" "*,*,*,am33") 1803 (set_attr "liw" "op2,op2,*,*") 1804 (set_attr "liw_op" "asr")] 1805) 1806 1807;; ---------------------------------------------------------------------- 1808;; MISCELLANEOUS 1809;; ---------------------------------------------------------------------- 1810 1811;; Note the use of the (const_int 0) when generating the insn that matches 1812;; the bsch pattern. This ensures that the destination register is 1813;; initialised with 0 which will make the BSCH instruction set searching 1814;; at bit 31. 1815;; 1816;; The XOR in the instruction sequence below is there because the BSCH 1817;; instruction returns the bit number of the highest set bit and we want 1818;; the number of zero bits above that bit. The AM33 does not have a 1819;; reverse subtraction instruction, but we can use a simple xor instead 1820;; since we know that the top 27 bits are clear. 1821(define_expand "clzsi2" 1822 [(parallel [(set (match_operand:SI 0 "register_operand") 1823 (unspec:SI [(match_operand:SI 1 "register_operand") 1824 (const_int 0)] UNSPEC_BSCH)) 1825 (clobber (reg:CC CC_REG))]) 1826 (parallel [(set (match_dup 0) 1827 (xor:SI (match_dup 0) 1828 (const_int 31))) 1829 (clobber (reg:CC CC_REG))])] 1830 "TARGET_AM33" 1831) 1832 1833(define_insn "*bsch" 1834 [(set (match_operand:SI 0 "register_operand" "=r") 1835 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 1836 (match_operand:SI 2 "nonmemory_operand" "0")] 1837 UNSPEC_BSCH)) 1838 (clobber (reg:CC CC_REG))] 1839 "TARGET_AM33" 1840 "bsch %1, %0" 1841) 1842 1843;; ---------------------------------------------------------------------- 1844;; FP INSTRUCTIONS 1845;; ---------------------------------------------------------------------- 1846 1847(define_insn "abssf2" 1848 [(set (match_operand:SF 0 "register_operand" "=f,f") 1849 (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))] 1850 "TARGET_AM33_2" 1851 "@ 1852 fabs %0 1853 fabs %1, %0" 1854 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1855 (const_int 17) (const_int 14)))] 1856) 1857 1858(define_insn "negsf2" 1859 [(set (match_operand:SF 0 "register_operand" "=f,f") 1860 (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))] 1861 "TARGET_AM33_2" 1862 "@ 1863 fneg %0 1864 fneg %1, %0" 1865 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1866 (const_int 17) (const_int 14)))] 1867) 1868 1869(define_expand "sqrtsf2" 1870 [(set (match_operand:SF 0 "register_operand" "") 1871 (sqrt:SF (match_operand:SF 1 "register_operand" "")))] 1872 "TARGET_AM33_2 && flag_unsafe_math_optimizations" 1873{ 1874 rtx scratch = gen_reg_rtx (SFmode); 1875 emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode))); 1876 emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)), 1877 scratch)); 1878 DONE; 1879}) 1880 1881(define_insn "rsqrtsf2" 1882 [(set (match_operand:SF 0 "register_operand" "=f,f") 1883 (div:SF (match_operand:SF 2 "const_1f_operand" "F,F") 1884 (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f")))) 1885 (clobber (reg:CC_FLOAT CC_REG))] 1886 "TARGET_AM33_2" 1887 "@ 1888 frsqrt %0 1889 frsqrt %1, %0" 1890 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1891 (const_int 4753) (const_int 2327)))] 1892) 1893 1894(define_insn "addsf3" 1895 [(set (match_operand:SF 0 "register_operand" "=f,f") 1896 (plus:SF (match_operand:SF 1 "register_operand" "%0,f") 1897 (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 1898 (clobber (reg:CC_FLOAT CC_REG))] 1899 "TARGET_AM33_2" 1900 "@ 1901 fadd %2, %0 1902 fadd %2, %1, %0" 1903 [(set_attr_alternative "timings" 1904 [(if_then_else (eq_attr "cpu" "am34") 1905 (const_int 17) (const_int 14)) 1906 (if_then_else (eq_attr "cpu" "am34") 1907 (const_int 17) (const_int 25)) 1908 ])] 1909) 1910 1911(define_insn "subsf3" 1912 [(set (match_operand:SF 0 "register_operand" "=f,f") 1913 (minus:SF (match_operand:SF 1 "register_operand" "0,f") 1914 (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 1915 (clobber (reg:CC_FLOAT CC_REG))] 1916 "TARGET_AM33_2" 1917 "@ 1918 fsub %2, %0 1919 fsub %2, %1, %0" 1920 [(set_attr_alternative "timings" 1921 [(if_then_else (eq_attr "cpu" "am34") 1922 (const_int 17) (const_int 14)) 1923 (if_then_else (eq_attr "cpu" "am34") 1924 (const_int 17) (const_int 25)) 1925 ])] 1926) 1927 1928(define_insn "mulsf3" 1929 [(set (match_operand:SF 0 "register_operand" "=f,f") 1930 (mult:SF (match_operand:SF 1 "register_operand" "%0,f") 1931 (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 1932 (clobber (reg:CC_FLOAT CC_REG)) 1933 ] 1934 "TARGET_AM33_2" 1935 "@ 1936 fmul %2, %0 1937 fmul %2, %1, %0" 1938 [(set_attr_alternative "timings" 1939 [(if_then_else (eq_attr "cpu" "am34") 1940 (const_int 17) (const_int 14)) 1941 (if_then_else (eq_attr "cpu" "am34") 1942 (const_int 17) (const_int 25)) 1943 ])] 1944) 1945 1946(define_insn "divsf3" 1947 [(set (match_operand:SF 0 "register_operand" "=f,f") 1948 (div:SF (match_operand:SF 1 "register_operand" "0,f") 1949 (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 1950 (clobber (reg:CC_FLOAT CC_REG))] 1951 "TARGET_AM33_2" 1952 "@ 1953 fdiv %2, %0 1954 fdiv %2, %1, %0" 1955 [(set_attr_alternative "timings" 1956 [(if_then_else (eq_attr "cpu" "am34") 1957 (const_int 2531) (const_int 1216)) 1958 (if_then_else (eq_attr "cpu" "am34") 1959 (const_int 2531) (const_int 1317)) 1960 ])] 1961) 1962 1963(define_insn "fmasf4" 1964 [(set (match_operand:SF 0 "register_operand" "=c") 1965 (fma:SF (match_operand:SF 1 "register_operand" "f") 1966 (match_operand:SF 2 "register_operand" "f") 1967 (match_operand:SF 3 "register_operand" "f"))) 1968 (clobber (reg:CC_FLOAT CC_REG)) 1969 ] 1970 "TARGET_AM33_2" 1971 "fmadd %1, %2, %3, %0" 1972 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1973 (const_int 17) (const_int 24)))] 1974) 1975 1976(define_insn "fmssf4" 1977 [(set (match_operand:SF 0 "register_operand" "=c") 1978 (fma:SF (match_operand:SF 1 "register_operand" "f") 1979 (match_operand:SF 2 "register_operand" "f") 1980 (neg:SF (match_operand:SF 3 "register_operand" "f")))) 1981 (clobber (reg:CC_FLOAT CC_REG)) 1982 ] 1983 "TARGET_AM33_2" 1984 "fmsub %1, %2, %3, %0" 1985 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1986 (const_int 17) (const_int 24)))] 1987) 1988 1989(define_insn "fnmasf4" 1990 [(set (match_operand:SF 0 "register_operand" "=c") 1991 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 1992 (match_operand:SF 2 "register_operand" "f") 1993 (match_operand:SF 3 "register_operand" "f"))) 1994 (clobber (reg:CC_FLOAT CC_REG)) 1995 ] 1996 "TARGET_AM33_2" 1997 "fnmadd %1, %2, %3, %0" 1998 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 1999 (const_int 17) (const_int 24)))] 2000) 2001 2002(define_insn "fnmssf4" 2003 [(set (match_operand:SF 0 "register_operand" "=c") 2004 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 2005 (match_operand:SF 2 "register_operand" "f") 2006 (neg:SF (match_operand:SF 3 "register_operand" "f")))) 2007 (clobber (reg:CC_FLOAT CC_REG)) 2008 ] 2009 "TARGET_AM33_2" 2010 "fnmsub %1, %2, %3, %0" 2011 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 2012 (const_int 17) (const_int 24)))] 2013) 2014 2015;; ---------------------------------------------------------------------- 2016;; PROLOGUE/EPILOGUE 2017;; ---------------------------------------------------------------------- 2018(define_expand "prologue" 2019 [(const_int 0)] 2020 "" 2021 { mn10300_expand_prologue (); DONE; } 2022) 2023 2024(define_expand "epilogue" 2025 [(return)] 2026 "" 2027 { mn10300_expand_epilogue (); DONE; } 2028) 2029 2030(define_insn "return" 2031 [(return)] 2032 "mn10300_can_use_rets_insn ()" 2033{ 2034 /* The RETF insn is 4 cycles faster than RETS, though 1 byte larger. */ 2035 if (optimize_insn_for_speed_p () && mn10300_can_use_retf_insn ()) 2036 return "retf [],0"; 2037 else 2038 return "rets"; 2039}) 2040 2041(define_insn "return_ret" 2042 [(return) 2043 (use (match_operand:SI 0 "const_int_operand" ""))] 2044 "" 2045{ 2046 /* The RETF insn is up to 3 cycles faster than RET. */ 2047 fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file); 2048 mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL)); 2049 fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0])); 2050 return ""; 2051}) 2052 2053;; This instruction matches one generated by mn10300_gen_multiple_store() 2054(define_insn "store_movm" 2055 [(match_parallel 0 "mn10300_store_multiple_operation" 2056 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])] 2057 "" 2058{ 2059 fputs ("\tmovm ", asm_out_file); 2060 mn10300_print_reg_list (asm_out_file, 2061 mn10300_store_multiple_regs (operands[0])); 2062 fprintf (asm_out_file, ",(sp)\n"); 2063 return ""; 2064} 2065 ;; Assume that no more than 8 registers will be pushed. 2066 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 2067 (const_int 99) (const_int 88)))] 2068) 2069 2070(define_expand "load_pic" 2071 [(const_int 0)] 2072 "flag_pic" 2073{ 2074 if (TARGET_AM33) 2075 emit_insn (gen_am33_load_pic (pic_offset_table_rtx)); 2076 else if (mn10300_frame_size () == 0) 2077 emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx)); 2078 else 2079 emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx)); 2080 DONE; 2081}) 2082 2083(define_insn "am33_load_pic" 2084 [(set (match_operand:SI 0 "register_operand" "=a") 2085 (unspec:SI [(const_int 0)] UNSPEC_GOT)) 2086 (clobber (reg:CC CC_REG))] 2087 "TARGET_AM33" 2088{ 2089 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 2090 return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0"; 2091} 2092 [(set_attr "timings" "33")] 2093) 2094 2095;; Load pic register with push/pop of stack. 2096(define_insn "mn10300_load_pic0" 2097 [(set (match_operand:SI 0 "register_operand" "=a") 2098 (unspec:SI [(const_int 0)] UNSPEC_GOT)) 2099 (clobber (reg:SI MDR_REG)) 2100 (clobber (reg:CC CC_REG))] 2101 "" 2102{ 2103 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 2104 return ("add -4,sp\;" 2105 "calls .LPIC%=\n" 2106 ".LPIC%=:\;" 2107 "movm (sp),[%0]\;" 2108 "add %1-(.LPIC%=-.),%0"); 2109} 2110 [(set_attr "timings" "88")] 2111) 2112 2113;; Load pic register re-using existing stack space. 2114(define_insn "mn10300_load_pic1" 2115 [(set (match_operand:SI 0 "register_operand" "=a") 2116 (unspec:SI [(const_int 0)] UNSPEC_GOT)) 2117 (clobber (mem:SI (reg:SI SP_REG))) 2118 (clobber (reg:SI MDR_REG)) 2119 (clobber (reg:CC CC_REG))] 2120 "" 2121{ 2122 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 2123 return ("calls .LPIC%=\n" 2124 ".LPIC%=:\;" 2125 "mov (sp),%0\;" 2126 "add %1-(.LPIC%=-.),%0"); 2127} 2128 [(set_attr "timings" "66")] 2129) 2130 2131;; The mode on operand 3 has been deliberately omitted because it 2132;; can be either SI (for arithmetic operations) or QI (for shifts). 2133(define_insn "liw" 2134 [(set (match_operand:SI 0 "register_operand" "=r") 2135 (unspec:SI [(match_dup 0) 2136 (match_operand 2 "liw_operand" "rO") 2137 (match_operand:SI 4 "const_int_operand" "")] 2138 UNSPEC_LIW)) 2139 (set (match_operand:SI 1 "register_operand" "=r") 2140 (unspec:SI [(match_dup 1) 2141 (match_operand 3 "liw_operand" "rO") 2142 (match_operand:SI 5 "const_int_operand" "")] 2143 UNSPEC_LIW))] 2144 "TARGET_ALLOW_LIW" 2145 "%W4_%W5 %2, %0, %3, %1" 2146 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 2147 (const_int 13) (const_int 12)))] 2148) 2149 2150;; The mode on operand 1 has been deliberately omitted because it 2151;; can be either SI (for arithmetic operations) or QI (for shifts). 2152(define_insn "cmp_liw" 2153 [(set (reg:CC CC_REG) 2154 (compare:CC (match_operand:SI 2 "register_operand" "r") 2155 (match_operand 3 "liw_operand" "rO"))) 2156 (set (match_operand:SI 0 "register_operand" "=r") 2157 (unspec:SI [(match_dup 0) 2158 (match_operand 1 "liw_operand" "rO") 2159 (match_operand:SI 4 "const_int_operand" "")] 2160 UNSPEC_LIW))] 2161 "TARGET_ALLOW_LIW" 2162 "cmp_%W4 %3, %2, %1, %0" 2163 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 2164 (const_int 13) (const_int 12)))] 2165) 2166 2167(define_insn "liw_cmp" 2168 [(set (match_operand:SI 0 "register_operand" "=r") 2169 (unspec:SI [(match_dup 0) 2170 (match_operand 1 "liw_operand" "rO") 2171 (match_operand:SI 4 "const_int_operand" "")] 2172 UNSPEC_LIW)) 2173 (set (reg:CC CC_REG) 2174 (compare:CC (match_operand:SI 2 "register_operand" "r") 2175 (match_operand 3 "liw_operand" "rO")))] 2176 "TARGET_ALLOW_LIW" 2177 "%W4_cmp %1, %0, %3, %2" 2178 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 2179 (const_int 13) (const_int 12)))] 2180) 2181 2182;; Note - in theory the doloop patterns could be used here to express 2183;; the SETLB and Lcc instructions. In practice this does not work because 2184;; the acceptable forms of the doloop patterns do not include UNSPECs 2185;; and without them gcc's basic block reordering code can duplicate the 2186;; doloop_end pattern, leading to bogus multiple decrements of the loop 2187;; counter. 2188 2189(define_insn "setlb" 2190 [(unspec [(const_int 0)] UNSPEC_SETLB)] 2191 "TARGET_AM33 && TARGET_ALLOW_SETLB" 2192 "setlb" 2193) 2194 2195(define_insn "Lcc" 2196 [(set (pc) 2197 (if_then_else (match_operator 0 "comparison_operator" 2198 [(reg:CC CC_REG) (const_int 0)]) 2199 (label_ref (match_operand 1 "" "")) 2200 (pc))) 2201 (unspec [(const_int 1)] UNSPEC_SETLB)] 2202 "TARGET_AM33 && TARGET_ALLOW_SETLB" 2203 "L%b0 # loop back to: %1" 2204) 2205 2206(define_insn "FLcc" 2207 [(set (pc) 2208 (if_then_else (match_operator 0 "comparison_operator" 2209 [(reg:CC_FLOAT CC_REG) (const_int 0)]) 2210 (label_ref (match_operand 1 "" "")) 2211 (pc))) 2212 (unspec [(const_int 2)] UNSPEC_SETLB)] 2213 "TARGET_AM33_2 && TARGET_ALLOW_SETLB" 2214 "FL%b0 # loop back to: %1" 2215 [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))] 2216) 2217