1;;- Machine description for Blackfin for GNU compiler 2;; Copyright 2005 Free Software Foundation, Inc. 3;; Contributed by Analog Devices. 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 2, 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 COPYING. If not, write to 19;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20;; Boston, MA 02110-1301, USA. 21 22; operand punctuation marks: 23; 24; X -- integer value printed as log2 25; Y -- integer value printed as log2(~value) - for bitclear 26; h -- print half word register, low part 27; d -- print half word register, high part 28; D -- print operand as dregs pairs 29; w -- print operand as accumulator register word (a0w, a1w) 30; H -- high part of double mode operand 31; T -- byte register representation Oct. 02 2001 32 33; constant operand classes 34; 35; J 2**N 5bit imm scaled 36; Ks7 -64 .. 63 signed 7bit imm 37; Ku5 0..31 unsigned 5bit imm 38; Ks4 -8 .. 7 signed 4bit imm 39; Ks3 -4 .. 3 signed 3bit imm 40; Ku3 0 .. 7 unsigned 3bit imm 41; Pn 0, 1, 2 constants 0, 1 or 2, corresponding to n 42; 43; register operands 44; d (r0..r7) 45; a (p0..p5,fp,sp) 46; e (a0, a1) 47; b (i0..i3) 48; f (m0..m3) 49; B 50; c (i0..i3,m0..m3) CIRCREGS 51; C (CC) CCREGS 52; 53 54;; Define constants for hard registers. 55 56(define_constants 57 [(REG_R0 0) 58 (REG_R1 1) 59 (REG_R2 2) 60 (REG_R3 3) 61 (REG_R4 4) 62 (REG_R5 5) 63 (REG_R6 6) 64 (REG_R7 7) 65 66 (REG_P0 8) 67 (REG_P1 9) 68 (REG_P2 10) 69 (REG_P3 11) 70 (REG_P4 12) 71 (REG_P5 13) 72 (REG_P6 14) 73 (REG_P7 15) 74 75 (REG_SP 14) 76 (REG_FP 15) 77 78 (REG_I0 16) 79 (REG_I1 17) 80 (REG_I2 18) 81 (REG_I3 19) 82 83 (REG_B0 20) 84 (REG_B1 21) 85 (REG_B2 22) 86 (REG_B3 23) 87 88 (REG_L0 24) 89 (REG_L1 25) 90 (REG_L2 26) 91 (REG_L3 27) 92 93 (REG_M0 28) 94 (REG_M1 29) 95 (REG_M2 30) 96 (REG_M3 31) 97 98 (REG_A0 32) 99 (REG_A1 33) 100 101 (REG_CC 34) 102 (REG_RETS 35) 103 (REG_RETI 36) 104 (REG_RETX 37) 105 (REG_RETN 38) 106 (REG_RETE 39) 107 108 (REG_ASTAT 40) 109 (REG_SEQSTAT 41) 110 (REG_USP 42) 111 112 (REG_ARGP 43)]) 113 114;; Constants used in UNSPECs and UNSPEC_VOLATILEs. 115 116(define_constants 117 [(UNSPEC_CBRANCH_TAKEN 0) 118 (UNSPEC_CBRANCH_NOPS 1) 119 (UNSPEC_RETURN 2) 120 (UNSPEC_MOVE_PIC 3) 121 (UNSPEC_LIBRARY_OFFSET 4) 122 (UNSPEC_PUSH_MULTIPLE 5)]) 123 124(define_constants 125 [(UNSPEC_VOLATILE_EH_RETURN 0) 126 (UNSPEC_VOLATILE_CSYNC 1) 127 (UNSPEC_VOLATILE_SSYNC 2)]) 128 129(define_attr "type" 130 "move,mvi,mcld,mcst,dsp32,mult,alu0,shft,brcc,br,call,misc,sync,compare,dummy" 131 (const_string "misc")) 132 133;; Scheduling definitions 134 135(define_automaton "bfin") 136 137(define_cpu_unit "core" "bfin") 138 139(define_insn_reservation "alu" 1 140 (eq_attr "type" "move,mvi,mcst,dsp32,alu0,shft,brcc,br,call,misc,sync,compare") 141 "core") 142 143(define_insn_reservation "imul" 3 144 (eq_attr "type" "mult") 145 "core*3") 146 147(define_insn_reservation "load" 1 148 (eq_attr "type" "mcld") 149 "core") 150 151;; Make sure genautomata knows about the maximum latency that can be produced 152;; by the adjust_cost function. 153(define_insn_reservation "dummy" 5 154 (eq_attr "type" "mcld") 155 "core") 156 157;; Operand and operator predicates 158 159(include "predicates.md") 160 161 162;;; FRIO branches have been optimized for code density 163;;; this comes at a slight cost of complexity when 164;;; a compiler needs to generate branches in the general 165;;; case. In order to generate the correct branching 166;;; mechanisms the compiler needs keep track of instruction 167;;; lengths. The follow table describes how to count instructions 168;;; for the FRIO architecture. 169;;; 170;;; unconditional br are 12-bit imm pcrelative branches *2 171;;; conditional br are 10-bit imm pcrelative branches *2 172;;; brcc 10-bit: 173;;; 1024 10-bit imm *2 is 2048 (-1024..1022) 174;;; br 12-bit : 175;;; 4096 12-bit imm *2 is 8192 (-4096..4094) 176;;; NOTE : For brcc we generate instructions such as 177;;; if cc jmp; jump.[sl] offset 178;;; offset of jump.[sl] is from the jump instruction but 179;;; gcc calculates length from the if cc jmp instruction 180;;; furthermore gcc takes the end address of the branch instruction 181;;; as (pc) for a forward branch 182;;; hence our range is (-4094, 4092) instead of (-4096, 4094) for a br 183;;; 184;;; The way the (pc) rtx works in these calculations is somewhat odd; 185;;; for backward branches it's the address of the current instruction, 186;;; for forward branches it's the previously known address of the following 187;;; instruction - we have to take this into account by reducing the range 188;;; for a forward branch. 189 190;; Lengths for type "mvi" insns are always defined by the instructions 191;; themselves. 192(define_attr "length" "" 193 (cond [(eq_attr "type" "mcld") 194 (if_then_else (match_operand 1 "effective_address_32bit_p" "") 195 (const_int 4) (const_int 2)) 196 197 (eq_attr "type" "mcst") 198 (if_then_else (match_operand 0 "effective_address_32bit_p" "") 199 (const_int 4) (const_int 2)) 200 201 (eq_attr "type" "move") (const_int 2) 202 203 (eq_attr "type" "dsp32") (const_int 4) 204 (eq_attr "type" "call") (const_int 4) 205 206 (eq_attr "type" "br") 207 (if_then_else (and 208 (le (minus (match_dup 0) (pc)) (const_int 4092)) 209 (ge (minus (match_dup 0) (pc)) (const_int -4096))) 210 (const_int 2) 211 (const_int 4)) 212 213 (eq_attr "type" "brcc") 214 (cond [(and 215 (le (minus (match_dup 3) (pc)) (const_int 1020)) 216 (ge (minus (match_dup 3) (pc)) (const_int -1024))) 217 (const_int 2) 218 (and 219 (le (minus (match_dup 3) (pc)) (const_int 4092)) 220 (ge (minus (match_dup 3) (pc)) (const_int -4094))) 221 (const_int 4)] 222 (const_int 6)) 223 ] 224 225 (const_int 2))) 226 227;; Conditional moves 228 229(define_expand "movsicc" 230 [(set (match_operand:SI 0 "register_operand" "") 231 (if_then_else:SI (match_operand 1 "comparison_operator" "") 232 (match_operand:SI 2 "register_operand" "") 233 (match_operand:SI 3 "register_operand" "")))] 234 "" 235{ 236 operands[1] = bfin_gen_compare (operands[1], SImode); 237}) 238 239(define_insn "*movsicc_insn1" 240 [(set (match_operand:SI 0 "register_operand" "=da,da,da") 241 (if_then_else:SI 242 (eq:BI (match_operand:BI 3 "cc_operand" "C,C,C") 243 (const_int 0)) 244 (match_operand:SI 1 "register_operand" "da,0,da") 245 (match_operand:SI 2 "register_operand" "0,da,da")))] 246 "" 247 "@ 248 if !cc %0 =%1; /* movsicc-1a */ 249 if cc %0 =%2; /* movsicc-1b */ 250 if !cc %0 =%1; if cc %0=%2; /* movsicc-1 */" 251 [(set_attr "length" "2,2,4") 252 (set_attr "type" "move")]) 253 254(define_insn "*movsicc_insn2" 255 [(set (match_operand:SI 0 "register_operand" "=da,da,da") 256 (if_then_else:SI 257 (ne:BI (match_operand:BI 3 "cc_operand" "C,C,C") 258 (const_int 0)) 259 (match_operand:SI 1 "register_operand" "0,da,da") 260 (match_operand:SI 2 "register_operand" "da,0,da")))] 261 "" 262 "@ 263 if !cc %0 =%2; /* movsicc-2b */ 264 if cc %0 =%1; /* movsicc-2a */ 265 if cc %0 =%1; if !cc %0=%2; /* movsicc-1 */" 266 [(set_attr "length" "2,2,4") 267 (set_attr "type" "move")]) 268 269;; Insns to load HIGH and LO_SUM 270 271(define_insn "movsi_high" 272 [(set (match_operand:SI 0 "register_operand" "=x") 273 (high:SI (match_operand:SI 1 "immediate_operand" "i")))] 274 "reload_completed" 275 "%d0 = %d1;" 276 [(set_attr "type" "mvi") 277 (set_attr "length" "4")]) 278 279(define_insn "movstricthi_high" 280 [(set (match_operand:SI 0 "register_operand" "+x") 281 (ior:SI (and:SI (match_dup 0) (const_int 65535)) 282 (match_operand:SI 1 "immediate_operand" "i")))] 283 "reload_completed" 284 "%d0 = %d1;" 285 [(set_attr "type" "mvi") 286 (set_attr "length" "4")]) 287 288(define_insn "movsi_low" 289 [(set (match_operand:SI 0 "register_operand" "=x") 290 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 291 (match_operand:SI 2 "immediate_operand" "i")))] 292 "reload_completed" 293 "%h0 = %h2;" 294 [(set_attr "type" "mvi") 295 (set_attr "length" "4")]) 296 297(define_insn "movsi_high_pic" 298 [(set (match_operand:SI 0 "register_operand" "=x") 299 (high:SI (unspec:SI [(match_operand:SI 1 "" "")] 300 UNSPEC_MOVE_PIC)))] 301 "" 302 "%d0 = %1@GOT_LOW;" 303 [(set_attr "type" "mvi") 304 (set_attr "length" "4")]) 305 306(define_insn "movsi_low_pic" 307 [(set (match_operand:SI 0 "register_operand" "=x") 308 (lo_sum:SI (match_operand:SI 1 "register_operand" "0") 309 (unspec:SI [(match_operand:SI 2 "" "")] 310 UNSPEC_MOVE_PIC)))] 311 "" 312 "%h0 = %h2@GOT_HIGH;" 313 [(set_attr "type" "mvi") 314 (set_attr "length" "4")]) 315 316;;; Move instructions 317 318(define_insn_and_split "movdi_insn" 319 [(set (match_operand:DI 0 "nonimmediate_operand" "=x,mx,r") 320 (match_operand:DI 1 "general_operand" "iFx,r,mx"))] 321 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 322 "#" 323 "reload_completed" 324 [(set (match_dup 2) (match_dup 3)) 325 (set (match_dup 4) (match_dup 5))] 326{ 327 rtx lo_half[2], hi_half[2]; 328 split_di (operands, 2, lo_half, hi_half); 329 330 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1])) 331 { 332 operands[2] = hi_half[0]; 333 operands[3] = hi_half[1]; 334 operands[4] = lo_half[0]; 335 operands[5] = lo_half[1]; 336 } 337 else 338 { 339 operands[2] = lo_half[0]; 340 operands[3] = lo_half[1]; 341 operands[4] = hi_half[0]; 342 operands[5] = hi_half[1]; 343 } 344}) 345 346(define_insn "movbi" 347 [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,mr,C,d,C") 348 (match_operand:BI 1 "general_operand" "x,xKs3,mr,d,d,C,P0"))] 349 350 "" 351 "@ 352 %0 = %1; 353 %0 = %1 (X); 354 %0 = %1; 355 %0 = %1; 356 CC = %1; 357 %0 = CC; 358 R0 = R0 | R0; CC = AC0;" 359 [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0") 360 (set_attr "length" "2,2,*,*,2,2,4")]) 361 362(define_insn "movpdi" 363 [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e") 364 (match_operand:PDI 1 "general_operand" " e,e,>"))] 365 "" 366 "@ 367 %0 = %1; 368 %0 = %x1; %0 = %w1; 369 %w0 = %1; %x0 = %1;" 370 [(set_attr "type" "move,mcst,mcld")]) 371 372(define_insn "*pushsi_insn" 373 [(set (mem:SI (pre_dec:SI (reg:SI REG_SP))) 374 (match_operand:SI 0 "register_operand" "xy"))] 375 "" 376 "[--SP] = %0;" 377 [(set_attr "type" "mcst") 378 (set_attr "length" "2")]) 379 380(define_insn "*popsi_insn" 381 [(set (match_operand:SI 0 "register_operand" "=xy") 382 (mem:SI (post_inc:SI (reg:SI REG_SP))))] 383 "" 384 "%0 = [SP++];" 385 [(set_attr "type" "mcld") 386 (set_attr "length" "2")]) 387 388;; The first alternative is used to make reload choose a limited register 389;; class when faced with a movsi_insn that had its input operand replaced 390;; with a PLUS. We generally require fewer secondary reloads this way. 391(define_insn "*movsi_insn" 392 [(set (match_operand:SI 0 "nonimmediate_operand" "=da,x*y,da,x,x,x,da,mr") 393 (match_operand:SI 1 "general_operand" "da,x*y,xKs7,xKsh,xKuh,ix,mr,da"))] 394 395 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 396 "@ 397 %0 = %1; 398 %0 = %1; 399 %0 = %1 (X); 400 %0 = %1 (X); 401 %0 = %1 (Z); 402 # 403 %0 = %1; 404 %0 = %1;" 405 [(set_attr "type" "move,move,mvi,mvi,mvi,*,mcld,mcst") 406 (set_attr "length" "2,2,2,4,4,*,*,*")]) 407 408(define_insn "*movv2hi_insn" 409 [(set (match_operand:V2HI 0 "nonimmediate_operand" "=da,d,m") 410 (match_operand:V2HI 1 "general_operand" "d,m,d"))] 411 412 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 413 "%0 = %1;" 414 [(set_attr "type" "move,mcld,mcst") 415 (set_attr "length" "2,*,*")]) 416 417(define_insn "*movhi_insn" 418 [(set (match_operand:HI 0 "nonimmediate_operand" "=x,da,x,d,mr") 419 (match_operand:HI 1 "general_operand" "x,xKs7,xKsh,mr,d"))] 420 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 421 "@ 422 %0 = %1; 423 %0 = %1 (X); 424 %0 = %1 (X); 425 %0 = W %1 (X); 426 W %0 = %1;" 427 [(set_attr "type" "move,mvi,mvi,mcld,mcst") 428 (set_attr "length" "2,2,4,*,*")]) 429 430(define_insn "*movqi_insn" 431 [(set (match_operand:QI 0 "nonimmediate_operand" "=x,da,x,d,mr") 432 (match_operand:QI 1 "general_operand" "x,xKs7,xKsh,mr,d"))] 433 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 434 "@ 435 %0 = %1; 436 %0 = %1 (X); 437 %0 = %1 (X); 438 %0 = B %1 (X); 439 B %0 = %1;" 440 [(set_attr "type" "move,mvi,mvi,mcld,mcst") 441 (set_attr "length" "2,2,4,*,*")]) 442 443(define_insn "*movsf_insn" 444 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,da,mr") 445 (match_operand:SF 1 "general_operand" "x,Fx,mr,da"))] 446 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 447 "@ 448 %0 = %1; 449 # 450 %0 = %1; 451 %0 = %1;" 452 [(set_attr "type" "move,*,mcld,mcst")]) 453 454(define_insn_and_split "movdf_insn" 455 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,mx,r") 456 (match_operand:DF 1 "general_operand" "iFx,r,mx"))] 457 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 458 "#" 459 "reload_completed" 460 [(set (match_dup 2) (match_dup 3)) 461 (set (match_dup 4) (match_dup 5))] 462{ 463 rtx lo_half[2], hi_half[2]; 464 split_di (operands, 2, lo_half, hi_half); 465 466 if (reg_overlap_mentioned_p (lo_half[0], hi_half[1])) 467 { 468 operands[2] = hi_half[0]; 469 operands[3] = hi_half[1]; 470 operands[4] = lo_half[0]; 471 operands[5] = lo_half[1]; 472 } 473 else 474 { 475 operands[2] = lo_half[0]; 476 operands[3] = lo_half[1]; 477 operands[4] = hi_half[0]; 478 operands[5] = hi_half[1]; 479 } 480}) 481 482;; This is the main "hook" for PIC code. When generating 483;; PIC, movsi is responsible for determining when the source address 484;; needs PIC relocation and appropriately calling legitimize_pic_address 485;; to perform the actual relocation. 486 487(define_expand "movsi" 488 [(set (match_operand:SI 0 "nonimmediate_operand" "") 489 (match_operand:SI 1 "general_operand" ""))] 490 "" 491 "expand_move (operands, SImode);") 492 493(define_expand "movv2hi" 494 [(set (match_operand:V2HI 0 "nonimmediate_operand" "") 495 (match_operand:V2HI 1 "general_operand" ""))] 496 "" 497 "expand_move (operands, V2HImode);") 498 499(define_expand "movdi" 500 [(set (match_operand:DI 0 "nonimmediate_operand" "") 501 (match_operand:DI 1 "general_operand" ""))] 502 "" 503 "expand_move (operands, DImode);") 504 505(define_expand "movsf" 506 [(set (match_operand:SF 0 "nonimmediate_operand" "") 507 (match_operand:SF 1 "general_operand" ""))] 508 "" 509 "expand_move (operands, SFmode);") 510 511(define_expand "movdf" 512 [(set (match_operand:DF 0 "nonimmediate_operand" "") 513 (match_operand:DF 1 "general_operand" ""))] 514 "" 515 "expand_move (operands, DFmode);") 516 517(define_expand "movhi" 518 [(set (match_operand:HI 0 "nonimmediate_operand" "") 519 (match_operand:HI 1 "general_operand" ""))] 520 "" 521 "expand_move (operands, HImode);") 522 523(define_expand "movqi" 524 [(set (match_operand:QI 0 "nonimmediate_operand" "") 525 (match_operand:QI 1 "general_operand" ""))] 526 "" 527 " expand_move (operands, QImode); ") 528 529;; Some define_splits to break up SI/SFmode loads of immediate constants. 530 531(define_split 532 [(set (match_operand:SI 0 "register_operand" "") 533 (match_operand:SI 1 "symbolic_or_const_operand" ""))] 534 "reload_completed 535 /* Always split symbolic operands; split integer constants that are 536 too large for a single instruction. */ 537 && (GET_CODE (operands[1]) != CONST_INT 538 || (INTVAL (operands[1]) < -32768 539 || INTVAL (operands[1]) >= 65536 540 || (INTVAL (operands[1]) >= 32768 && PREG_P (operands[0]))))" 541 [(set (match_dup 0) (high:SI (match_dup 1))) 542 (set (match_dup 0) (lo_sum:SI (match_dup 0) (match_dup 1)))] 543{ 544 if (GET_CODE (operands[1]) == CONST_INT 545 && split_load_immediate (operands)) 546 DONE; 547 /* ??? Do something about TARGET_LOW_64K. */ 548}) 549 550(define_split 551 [(set (match_operand:SF 0 "register_operand" "") 552 (match_operand:SF 1 "immediate_operand" ""))] 553 "reload_completed" 554 [(set (match_dup 2) (high:SI (match_dup 3))) 555 (set (match_dup 2) (lo_sum:SI (match_dup 2) (match_dup 3)))] 556{ 557 long values; 558 REAL_VALUE_TYPE value; 559 560 gcc_assert (GET_CODE (operands[1]) == CONST_DOUBLE); 561 562 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]); 563 REAL_VALUE_TO_TARGET_SINGLE (value, values); 564 565 operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0])); 566 operands[3] = GEN_INT (trunc_int_for_mode (values, SImode)); 567 if (values >= -32768 && values < 65536) 568 { 569 emit_move_insn (operands[2], operands[3]); 570 DONE; 571 } 572 if (split_load_immediate (operands + 2)) 573 DONE; 574}) 575 576;; Sadly, this can't be a proper named movstrict pattern, since the compiler 577;; expects to be able to use registers for operand 1. 578;; Note that the asm instruction is defined by the manual to take an unsigned 579;; constant, but it doesn't matter to the assembler, and the compiler only 580;; deals with sign-extended constants. Hence "Ksh". 581(define_insn "*movstricthi" 582 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+x")) 583 (match_operand:HI 1 "immediate_operand" "Ksh"))] 584 "" 585 "%h0 = %1;" 586 [(set_attr "type" "mvi") 587 (set_attr "length" "4")]) 588 589;; Sign and zero extensions 590 591(define_insn "extendhisi2" 592 [(set (match_operand:SI 0 "register_operand" "=d, d") 593 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))] 594 "" 595 "@ 596 %0 = %h1 (X); 597 %0 = W %h1 (X);" 598 [(set_attr "type" "alu0,mcld")]) 599 600(define_insn "zero_extendhisi2" 601 [(set (match_operand:SI 0 "register_operand" "=d, d") 602 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d, m")))] 603 "" 604 "@ 605 %0 = %h1 (Z); 606 %0 = W%h1 (Z);" 607 [(set_attr "type" "alu0,mcld")]) 608 609(define_insn "zero_extendbisi2" 610 [(set (match_operand:SI 0 "register_operand" "=d") 611 (zero_extend:SI (match_operand:BI 1 "nonimmediate_operand" "C")))] 612 "" 613 "%0 = %1;" 614 [(set_attr "type" "compare")]) 615 616(define_insn "extendqihi2" 617 [(set (match_operand:HI 0 "register_operand" "=d, d") 618 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))] 619 "" 620 "@ 621 %0 = B %1 (X); 622 %0 = %T1 (X);" 623 [(set_attr "type" "mcld,alu0")]) 624 625(define_insn "extendqisi2" 626 [(set (match_operand:SI 0 "register_operand" "=d, d") 627 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))] 628 "" 629 "@ 630 %0 = B %1 (X); 631 %0 = %T1 (X);" 632 [(set_attr "type" "mcld,alu0")]) 633 634 635(define_insn "zero_extendqihi2" 636 [(set (match_operand:HI 0 "register_operand" "=d, d") 637 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m, d")))] 638 "" 639 "@ 640 %0 = B %1 (Z); 641 %0 = %T1 (Z);" 642 [(set_attr "type" "mcld,alu0")]) 643 644 645(define_insn "zero_extendqisi2" 646 [(set (match_operand:SI 0 "register_operand" "=d, d") 647 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m, d")))] 648 "" 649 "@ 650 %0 = B %1 (Z); 651 %0 = %T1 (Z);" 652 [(set_attr "type" "mcld,alu0")]) 653 654;; DImode logical operations 655 656(define_code_macro any_logical [and ior xor]) 657(define_code_attr optab [(and "and") 658 (ior "ior") 659 (xor "xor")]) 660(define_code_attr op [(and "&") 661 (ior "|") 662 (xor "^")]) 663(define_code_attr high_result [(and "0") 664 (ior "%H1") 665 (xor "%H1")]) 666 667(define_insn "<optab>di3" 668 [(set (match_operand:DI 0 "register_operand" "=d") 669 (any_logical:DI (match_operand:DI 1 "register_operand" "0") 670 (match_operand:DI 2 "register_operand" "d")))] 671 "" 672 "%0 = %1 <op> %2;\\n\\t%H0 = %H1 <op> %H2;" 673 [(set_attr "length" "4")]) 674 675(define_insn "*<optab>di_zesidi_di" 676 [(set (match_operand:DI 0 "register_operand" "=d") 677 (any_logical:DI (zero_extend:DI 678 (match_operand:SI 2 "register_operand" "d")) 679 (match_operand:DI 1 "register_operand" "d")))] 680 "" 681 "%0 = %1 <op> %2;\\n\\t%H0 = <high_result>;" 682 [(set_attr "length" "4")]) 683 684(define_insn "*<optab>di_sesdi_di" 685 [(set (match_operand:DI 0 "register_operand" "=d") 686 (any_logical:DI (sign_extend:DI 687 (match_operand:SI 2 "register_operand" "d")) 688 (match_operand:DI 1 "register_operand" "0"))) 689 (clobber (match_scratch:SI 3 "=&d"))] 690 "" 691 "%0 = %1 <op> %2;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 <op> %3;" 692 [(set_attr "length" "8")]) 693 694(define_insn "negdi2" 695 [(set (match_operand:DI 0 "register_operand" "=d") 696 (neg:DI (match_operand:DI 1 "register_operand" "d"))) 697 (clobber (match_scratch:SI 2 "=&d")) 698 (clobber (reg:CC REG_CC))] 699 "" 700 "%2 = 0; %2 = %2 - %1; cc = ac0; cc = !cc; %2 = cc;\\n\\t%0 = -%1; %H0 = -%H1; %H0 = %H0 - %2;" 701 [(set_attr "length" "16")]) 702 703(define_insn "one_cmpldi2" 704 [(set (match_operand:DI 0 "register_operand" "=d") 705 (not:DI (match_operand:DI 1 "register_operand" "d")))] 706 "" 707 "%0 = ~%1;\\n\\t%H0 = ~%H1;" 708 [(set_attr "length" "4")]) 709 710;; DImode zero and sign extend patterns 711 712(define_insn_and_split "zero_extendsidi2" 713 [(set (match_operand:DI 0 "register_operand" "=d") 714 (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))] 715 "" 716 "#" 717 "reload_completed" 718 [(set (match_dup 3) (const_int 0))] 719{ 720 split_di (operands, 1, operands + 2, operands + 3); 721 if (REGNO (operands[0]) != REGNO (operands[1])) 722 emit_move_insn (operands[2], operands[1]); 723}) 724 725(define_insn "zero_extendqidi2" 726 [(set (match_operand:DI 0 "register_operand" "=d") 727 (zero_extend:DI (match_operand:QI 1 "register_operand" "d")))] 728 "" 729 "%0 = %T1 (Z);\\n\\t%H0 = 0;" 730 [(set_attr "length" "4")]) 731 732(define_insn "zero_extendhidi2" 733 [(set (match_operand:DI 0 "register_operand" "=d") 734 (zero_extend:DI (match_operand:HI 1 "register_operand" "d")))] 735 "" 736 "%0 = %h1 (Z);\\n\\t%H0 = 0;" 737 [(set_attr "length" "4")]) 738 739(define_insn_and_split "extendsidi2" 740 [(set (match_operand:DI 0 "register_operand" "=d") 741 (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))] 742 "" 743 "#" 744 "reload_completed" 745 [(set (match_dup 3) (match_dup 1)) 746 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))] 747{ 748 split_di (operands, 1, operands + 2, operands + 3); 749 if (REGNO (operands[0]) != REGNO (operands[1])) 750 emit_move_insn (operands[2], operands[1]); 751}) 752 753(define_insn_and_split "extendqidi2" 754 [(set (match_operand:DI 0 "register_operand" "=d") 755 (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))] 756 "" 757 "#" 758 "reload_completed" 759 [(set (match_dup 2) (sign_extend:SI (match_dup 1))) 760 (set (match_dup 3) (sign_extend:SI (match_dup 1))) 761 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))] 762{ 763 split_di (operands, 1, operands + 2, operands + 3); 764}) 765 766(define_insn_and_split "extendhidi2" 767 [(set (match_operand:DI 0 "register_operand" "=d") 768 (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))] 769 "" 770 "#" 771 "reload_completed" 772 [(set (match_dup 2) (sign_extend:SI (match_dup 1))) 773 (set (match_dup 3) (sign_extend:SI (match_dup 1))) 774 (set (match_dup 3) (ashiftrt:SI (match_dup 3) (const_int 31)))] 775{ 776 split_di (operands, 1, operands + 2, operands + 3); 777}) 778 779;; DImode arithmetic operations 780 781(define_insn "adddi3" 782 [(set (match_operand:DI 0 "register_operand" "=&d,&d,&d") 783 (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0") 784 (match_operand:DI 2 "nonmemory_operand" "Kn7,Ks7,d"))) 785 (clobber (match_scratch:SI 3 "=&d,&d,&d")) 786 (clobber (reg:CC 34))] 787 "" 788 "@ 789 %0 += %2; cc = ac0; %3 = cc; %H0 += -1; %H0 = %H0 + %3; 790 %0 += %2; cc = ac0; %3 = cc; %H0 = %H0 + %3; 791 %0 = %0 + %2; cc = ac0; %3 = cc; %H0 = %H0 + %H2; %H0 = %H0 + %3;" 792 [(set_attr "type" "alu0") 793 (set_attr "length" "10,8,10")]) 794 795(define_insn "subdi3" 796 [(set (match_operand:DI 0 "register_operand" "=&d") 797 (minus:DI (match_operand:DI 1 "register_operand" "0") 798 (match_operand:DI 2 "register_operand" "d"))) 799 (clobber (reg:CC 34))] 800 "" 801 "%0 = %1-%2;\\n\\tcc = ac0;\\n\\t%H0 = %H1-%H2;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:" 802 [(set_attr "length" "10")]) 803 804(define_insn "*subdi_di_zesidi" 805 [(set (match_operand:DI 0 "register_operand" "=d") 806 (minus:DI (match_operand:DI 1 "register_operand" "0") 807 (zero_extend:DI 808 (match_operand:SI 2 "register_operand" "d")))) 809 (clobber (match_scratch:SI 3 "=&d")) 810 (clobber (reg:CC 34))] 811 "" 812 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%H0 = %H1 - %3;" 813 [(set_attr "length" "10")]) 814 815(define_insn "*subdi_zesidi_di" 816 [(set (match_operand:DI 0 "register_operand" "=d") 817 (minus:DI (zero_extend:DI 818 (match_operand:SI 2 "register_operand" "d")) 819 (match_operand:DI 1 "register_operand" "0"))) 820 (clobber (match_scratch:SI 3 "=&d")) 821 (clobber (reg:CC 34))] 822 "" 823 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\tcc = ! cc;\\n\\t%3 = cc;\\n\\t%3 = -%3;\\n\\t%H0 = %3 - %H1" 824 [(set_attr "length" "12")]) 825 826(define_insn "*subdi_di_sesidi" 827 [(set (match_operand:DI 0 "register_operand" "=d") 828 (minus:DI (match_operand:DI 1 "register_operand" "0") 829 (sign_extend:DI 830 (match_operand:SI 2 "register_operand" "d")))) 831 (clobber (match_scratch:SI 3 "=&d")) 832 (clobber (reg:CC 34))] 833 "" 834 "%0 = %1 - %2;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %H1 - %3;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:" 835 [(set_attr "length" "14")]) 836 837(define_insn "*subdi_sesidi_di" 838 [(set (match_operand:DI 0 "register_operand" "=d") 839 (minus:DI (sign_extend:DI 840 (match_operand:SI 2 "register_operand" "d")) 841 (match_operand:DI 1 "register_operand" "0"))) 842 (clobber (match_scratch:SI 3 "=&d")) 843 (clobber (reg:CC 34))] 844 "" 845 "%0 = %2 - %1;\\n\\tcc = ac0;\\n\\t%3 = %2;\\n\\t%3 >>>= 31;\\n\\t%H0 = %3 - %H1;\\n\\tif cc jump 1f;\\n\\t%H0 += -1;\\n\\t1:" 846 [(set_attr "length" "14")]) 847 848;; Combined shift/add instructions 849 850(define_insn "" 851 [(set (match_operand:SI 0 "register_operand" "=a,d") 852 (ashift:SI (plus:SI (match_operand:SI 1 "register_operand" "%0,0") 853 (match_operand:SI 2 "register_operand" "a,d")) 854 (match_operand:SI 3 "pos_scale_operand" "P1P2,P1P2")))] 855 "" 856 "%0 = (%0 + %2) << %3;" /* "shadd %0,%2,%3;" */ 857 [(set_attr "type" "alu0")]) 858 859(define_insn "" 860 [(set (match_operand:SI 0 "register_operand" "=a") 861 (plus:SI (match_operand:SI 1 "register_operand" "a") 862 (mult:SI (match_operand:SI 2 "register_operand" "a") 863 (match_operand:SI 3 "scale_by_operand" "i"))))] 864 "" 865 "%0 = %1 + (%2 << %X3);" 866 [(set_attr "type" "alu0")]) 867 868(define_insn "" 869 [(set (match_operand:SI 0 "register_operand" "=a") 870 (plus:SI (match_operand:SI 1 "register_operand" "a") 871 (ashift:SI (match_operand:SI 2 "register_operand" "a") 872 (match_operand:SI 3 "pos_scale_operand" "i"))))] 873 "" 874 "%0 = %1 + (%2 << %3);" 875 [(set_attr "type" "alu0")]) 876 877(define_insn "" 878 [(set (match_operand:SI 0 "register_operand" "=a") 879 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "a") 880 (match_operand:SI 2 "scale_by_operand" "i")) 881 (match_operand:SI 3 "register_operand" "a")))] 882 "" 883 "%0 = %3 + (%1 << %X2);" 884 [(set_attr "type" "alu0")]) 885 886(define_insn "" 887 [(set (match_operand:SI 0 "register_operand" "=a") 888 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "a") 889 (match_operand:SI 2 "pos_scale_operand" "i")) 890 (match_operand:SI 3 "register_operand" "a")))] 891 "" 892 "%0 = %3 + (%1 << %2);" 893 [(set_attr "type" "alu0")]) 894 895(define_insn "mulhisi3" 896 [(set (match_operand:SI 0 "register_operand" "=d") 897 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%d")) 898 (sign_extend:SI (match_operand:HI 2 "register_operand" "d"))))] 899 "" 900 "%0 = %h1 * %h2 (IS);" 901 [(set_attr "type" "dsp32")]) 902 903(define_insn "umulhisi3" 904 [(set (match_operand:SI 0 "register_operand" "=d") 905 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%d")) 906 (zero_extend:SI (match_operand:HI 2 "register_operand" "d"))))] 907 "" 908 "%0 = %h1 * %h2 (FU);" 909 [(set_attr "type" "dsp32")]) 910 911;; The processor also supports ireg += mreg or ireg -= mreg, but these 912;; are unusable if we don't ensure that the corresponding lreg is zero. 913;; The same applies to the add/subtract constant versions involving 914;; iregs 915 916(define_insn "addsi3" 917 [(set (match_operand:SI 0 "register_operand" "=ad,a,d") 918 (plus:SI (match_operand:SI 1 "register_operand" "%0, a,d") 919 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7, a,d")))] 920 "" 921 "@ 922 %0 += %2; 923 %0 = %1 + %2; 924 %0 = %1 + %2;" 925 [(set_attr "type" "alu0") 926 (set_attr "length" "2,2,2")]) 927 928(define_expand "subsi3" 929 [(set (match_operand:SI 0 "register_operand" "") 930 (minus:SI (match_operand:SI 1 "register_operand" "") 931 (match_operand:SI 2 "reg_or_7bit_operand" "")))] 932 "" 933 "") 934 935(define_insn "" 936 [(set (match_operand:SI 0 "register_operand" "=da,d,a") 937 (minus:SI (match_operand:SI 1 "register_operand" "0,d,0") 938 (match_operand:SI 2 "reg_or_7bit_operand" "Ks7,d,a")))] 939 "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -64" 940{ 941 static const char *const strings_subsi3[] = { 942 "%0 += -%2;", 943 "%0 = %1 - %2;", 944 "%0 -= %2;", 945 }; 946 947 if (CONSTANT_P (operands[2]) && INTVAL (operands[2]) < 0) { 948 rtx tmp_op = operands[2]; 949 operands[2] = GEN_INT (-INTVAL (operands[2])); 950 output_asm_insn ("%0 += %2;", operands); 951 operands[2] = tmp_op; 952 return ""; 953 } 954 955 return strings_subsi3[which_alternative]; 956} 957 [(set_attr "type" "alu0")]) 958 959;; Bit test instructions 960 961(define_insn "*not_bittst" 962 [(set (match_operand:BI 0 "cc_operand" "=C") 963 (eq:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d") 964 (const_int 1) 965 (match_operand:SI 2 "immediate_operand" "Ku5")) 966 (const_int 0)))] 967 "" 968 "cc = !BITTST (%1,%2);" 969 [(set_attr "type" "alu0")]) 970 971(define_insn "*bittst" 972 [(set (match_operand:BI 0 "cc_operand" "=C") 973 (ne:BI (zero_extract:SI (match_operand:SI 1 "register_operand" "d") 974 (const_int 1) 975 (match_operand:SI 2 "immediate_operand" "Ku5")) 976 (const_int 0)))] 977 "" 978 "cc = BITTST (%1,%2);" 979 [(set_attr "type" "alu0")]) 980 981(define_insn_and_split "*bit_extract" 982 [(set (match_operand:SI 0 "register_operand" "=d") 983 (zero_extract:SI (match_operand:SI 1 "register_operand" "d") 984 (const_int 1) 985 (match_operand:SI 2 "immediate_operand" "Ku5"))) 986 (clobber (reg:BI REG_CC))] 987 "" 988 "#" 989 "" 990 [(set (reg:BI REG_CC) 991 (ne:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2)) 992 (const_int 0))) 993 (set (match_dup 0) 994 (ne:SI (reg:BI REG_CC) (const_int 0)))]) 995 996(define_insn_and_split "*not_bit_extract" 997 [(set (match_operand:SI 0 "register_operand" "=d") 998 (zero_extract:SI (not:SI (match_operand:SI 1 "register_operand" "d")) 999 (const_int 1) 1000 (match_operand:SI 2 "immediate_operand" "Ku5"))) 1001 (clobber (reg:BI REG_CC))] 1002 "" 1003 "#" 1004 "" 1005 [(set (reg:BI REG_CC) 1006 (eq:BI (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2)) 1007 (const_int 0))) 1008 (set (match_dup 0) 1009 (ne:SI (reg:BI REG_CC) (const_int 0)))]) 1010 1011(define_insn "*andsi_insn" 1012 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") 1013 (and:SI (match_operand:SI 1 "register_operand" "%0,d,d,d") 1014 (match_operand:SI 2 "rhs_andsi3_operand" "L,M1,M2,d")))] 1015 "" 1016 "@ 1017 BITCLR (%0,%Y2); 1018 %0 = %T1 (Z); 1019 %0 = %h1 (Z); 1020 %0 = %1 & %2;" 1021 [(set_attr "type" "alu0")]) 1022 1023(define_expand "andsi3" 1024 [(set (match_operand:SI 0 "register_operand" "") 1025 (and:SI (match_operand:SI 1 "register_operand" "") 1026 (match_operand:SI 2 "general_operand" "")))] 1027 "" 1028{ 1029 if (highbits_operand (operands[2], SImode)) 1030 { 1031 operands[2] = GEN_INT (exact_log2 (-INTVAL (operands[2]))); 1032 emit_insn (gen_ashrsi3 (operands[0], operands[1], operands[2])); 1033 emit_insn (gen_ashlsi3 (operands[0], operands[0], operands[2])); 1034 DONE; 1035 } 1036 if (! rhs_andsi3_operand (operands[2], SImode)) 1037 operands[2] = force_reg (SImode, operands[2]); 1038}) 1039 1040(define_insn "iorsi3" 1041 [(set (match_operand:SI 0 "register_operand" "=d,d") 1042 (ior:SI (match_operand:SI 1 "register_operand" "%0,d") 1043 (match_operand:SI 2 "regorlog2_operand" "J,d")))] 1044 "" 1045 "@ 1046 BITSET (%0, %X2); 1047 %0 = %1 | %2;" 1048 [(set_attr "type" "alu0")]) 1049 1050(define_insn "xorsi3" 1051 [(set (match_operand:SI 0 "register_operand" "=d,d") 1052 (xor:SI (match_operand:SI 1 "register_operand" "%0,d") 1053 (match_operand:SI 2 "regorlog2_operand" "J,d")))] 1054 "" 1055 "@ 1056 BITTGL (%0, %X2); 1057 %0 = %1 ^ %2;" 1058 [(set_attr "type" "alu0")]) 1059 1060(define_insn "smaxsi3" 1061 [(set (match_operand:SI 0 "register_operand" "=d") 1062 (smax:SI (match_operand:SI 1 "register_operand" "d") 1063 (match_operand:SI 2 "register_operand" "d")))] 1064 "" 1065 "%0 =max(%1,%2);" 1066 [(set_attr "type" "dsp32")]) 1067 1068(define_insn "sminsi3" 1069 [(set (match_operand:SI 0 "register_operand" "=d") 1070 (smin:SI (match_operand:SI 1 "register_operand" "d") 1071 (match_operand:SI 2 "register_operand" "d")))] 1072 "" 1073 "%0 =min(%1,%2);" 1074 [(set_attr "type" "dsp32")]) 1075 1076(define_insn "abssi2" 1077 [(set (match_operand:SI 0 "register_operand" "=d") 1078 (abs:SI (match_operand:SI 1 "register_operand" " d")))] 1079 "" 1080 "%0 =abs %1;" 1081 [(set_attr "type" "dsp32")]) 1082 1083 1084(define_insn "negsi2" 1085 [(set (match_operand:SI 0 "register_operand" "=d") 1086 (neg:SI (match_operand:SI 1 "register_operand" " d")))] 1087 "" 1088 "%0 =-%1;" 1089 [(set_attr "type" "alu0")]) 1090 1091(define_insn "one_cmplsi2" 1092 [(set (match_operand:SI 0 "register_operand" "=d") 1093 (not:SI (match_operand:SI 1 "register_operand" " d")))] 1094 "" 1095 "%0 =~%1;" 1096 [(set_attr "type" "alu0")]) 1097 1098(define_insn "mulsi3" 1099 [(set (match_operand:SI 0 "register_operand" "=d") 1100 (mult:SI (match_operand:SI 1 "register_operand" "%0") 1101 (match_operand:SI 2 "register_operand" "d")))] 1102 "" 1103 "%0 *=%2;" 1104 [(set_attr "type" "mult")]) 1105 1106(define_expand "ashlsi3" 1107 [(set (match_operand:SI 0 "register_operand" "") 1108 (ashift:SI (match_operand:SI 1 "register_operand" "") 1109 (match_operand:SI 2 "nonmemory_operand" "")))] 1110 "" 1111{ 1112 if (GET_CODE (operands[2]) == CONST_INT 1113 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31) 1114 { 1115 emit_insn (gen_movsi (operands[0], const0_rtx)); 1116 DONE; 1117 } 1118}) 1119 1120(define_insn_and_split "*ashlsi3_insn" 1121 [(set (match_operand:SI 0 "register_operand" "=d,a,a,a") 1122 (ashift:SI (match_operand:SI 1 "register_operand" "0,a,a,a") 1123 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1,P2,?P3P4")))] 1124 "" 1125 "@ 1126 %0 <<= %2; 1127 %0 = %1 + %1; 1128 %0 = %1 << %2; 1129 #" 1130 "PREG_P (operands[0]) && INTVAL (operands[2]) > 2" 1131 [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 2))) 1132 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))] 1133 "operands[3] = GEN_INT (INTVAL (operands[2]) - 2);" 1134 [(set_attr "type" "shft")]) 1135 1136(define_insn "ashrsi3" 1137 [(set (match_operand:SI 0 "register_operand" "=d") 1138 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 1139 (match_operand:SI 2 "nonmemory_operand" "dKu5")))] 1140 "" 1141 "%0 >>>= %2;" 1142 [(set_attr "type" "shft")]) 1143 1144(define_insn "ror_one" 1145 [(set (match_operand:SI 0 "register_operand" "=d") 1146 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (const_int 1)) 1147 (ashift:SI (zero_extend:SI (reg:BI REG_CC)) (const_int 31)))) 1148 (set (reg:BI REG_CC) 1149 (zero_extract:BI (match_dup 1) (const_int 1) (const_int 0)))] 1150 "" 1151 "%0 = ROT %1 BY -1;" 1152 [(set_attr "type" "shft") 1153 (set_attr "length" "4")]) 1154 1155(define_insn "rol_one" 1156 [(set (match_operand:SI 0 "register_operand" "+d") 1157 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1)) 1158 (zero_extend:SI (reg:BI REG_CC)))) 1159 (set (reg:BI REG_CC) 1160 (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))] 1161 "" 1162 "%0 = ROT %1 BY 1;" 1163 [(set_attr "type" "shft") 1164 (set_attr "length" "4")]) 1165 1166(define_expand "lshrdi3" 1167 [(set (match_operand:DI 0 "register_operand" "") 1168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 1169 (match_operand:DI 2 "general_operand" "")))] 1170 "" 1171{ 1172 rtx lo_half[2], hi_half[2]; 1173 1174 if (operands[2] != const1_rtx) 1175 FAIL; 1176 if (! rtx_equal_p (operands[0], operands[1])) 1177 emit_move_insn (operands[0], operands[1]); 1178 1179 split_di (operands, 2, lo_half, hi_half); 1180 1181 emit_move_insn (bfin_cc_rtx, const0_rtx); 1182 emit_insn (gen_ror_one (hi_half[0], hi_half[0])); 1183 emit_insn (gen_ror_one (lo_half[0], lo_half[0])); 1184 DONE; 1185}) 1186 1187(define_expand "ashrdi3" 1188 [(set (match_operand:DI 0 "register_operand" "") 1189 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 1190 (match_operand:DI 2 "general_operand" "")))] 1191 "" 1192{ 1193 rtx lo_half[2], hi_half[2]; 1194 1195 if (operands[2] != const1_rtx) 1196 FAIL; 1197 if (! rtx_equal_p (operands[0], operands[1])) 1198 emit_move_insn (operands[0], operands[1]); 1199 1200 split_di (operands, 2, lo_half, hi_half); 1201 1202 emit_insn (gen_compare_lt (gen_rtx_REG (BImode, REG_CC), 1203 hi_half[1], const0_rtx)); 1204 emit_insn (gen_ror_one (hi_half[0], hi_half[0])); 1205 emit_insn (gen_ror_one (lo_half[0], lo_half[0])); 1206 DONE; 1207}) 1208 1209(define_expand "ashldi3" 1210 [(set (match_operand:DI 0 "register_operand" "") 1211 (ashift:DI (match_operand:DI 1 "register_operand" "") 1212 (match_operand:DI 2 "general_operand" "")))] 1213 "" 1214{ 1215 rtx lo_half[2], hi_half[2]; 1216 1217 if (operands[2] != const1_rtx) 1218 FAIL; 1219 if (! rtx_equal_p (operands[0], operands[1])) 1220 emit_move_insn (operands[0], operands[1]); 1221 1222 split_di (operands, 2, lo_half, hi_half); 1223 1224 emit_move_insn (bfin_cc_rtx, const0_rtx); 1225 emit_insn (gen_rol_one (lo_half[0], lo_half[0])); 1226 emit_insn (gen_rol_one (hi_half[0], hi_half[0])); 1227 DONE; 1228}) 1229 1230(define_insn "lshrsi3" 1231 [(set (match_operand:SI 0 "register_operand" "=d,a") 1232 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0,a") 1233 (match_operand:SI 2 "nonmemory_operand" "dKu5,P1P2")))] 1234 "" 1235 "@ 1236 %0 >>= %2; 1237 %0 = %1 >> %2;" 1238 [(set_attr "type" "shft")]) 1239 1240;; A pattern to reload the equivalent of 1241;; (set (Dreg) (plus (FP) (large_constant))) 1242;; or 1243;; (set (dagreg) (plus (FP) (arbitrary_constant))) 1244;; using a scratch register 1245(define_expand "reload_insi" 1246 [(parallel [(set (match_operand:SI 0 "register_operand" "=w") 1247 (match_operand:SI 1 "fp_plus_const_operand" "")) 1248 (clobber (match_operand:SI 2 "register_operand" "=&a"))])] 1249 "" 1250{ 1251 rtx fp_op = XEXP (operands[1], 0); 1252 rtx const_op = XEXP (operands[1], 1); 1253 rtx primary = operands[0]; 1254 rtx scratch = operands[2]; 1255 1256 emit_move_insn (scratch, const_op); 1257 emit_insn (gen_addsi3 (scratch, scratch, fp_op)); 1258 emit_move_insn (primary, scratch); 1259 DONE; 1260}) 1261 1262;; Jump instructions 1263 1264(define_insn "jump" 1265 [(set (pc) 1266 (label_ref (match_operand 0 "" "")))] 1267 "" 1268{ 1269 if (get_attr_length (insn) == 2) 1270 return "jump.s %0;"; 1271 else 1272 return "jump.l %0;"; 1273} 1274 [(set_attr "type" "br")]) 1275 1276(define_insn "indirect_jump" 1277 [(set (pc) 1278 (match_operand:SI 0 "register_operand" "a"))] 1279 "" 1280 "jump (%0);" 1281 [(set_attr "type" "misc")]) 1282 1283(define_expand "tablejump" 1284 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "a")) 1285 (use (label_ref (match_operand 1 "" "")))])] 1286 "" 1287{ 1288 /* In PIC mode, the table entries are stored PC relative. 1289 Convert the relative address to an absolute address. */ 1290 if (flag_pic) 1291 { 1292 rtx op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 1293 1294 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], 1295 op1, NULL_RTX, 0, OPTAB_DIRECT); 1296 } 1297}) 1298 1299(define_insn "*tablejump_internal" 1300 [(set (pc) (match_operand:SI 0 "register_operand" "a")) 1301 (use (label_ref (match_operand 1 "" "")))] 1302 "" 1303 "jump (%0);" 1304 [(set_attr "type" "misc")]) 1305 1306;; Call instructions.. 1307 1308(define_expand "call" 1309 [(parallel [(call (match_operand:SI 0 "" "") 1310 (match_operand 1 "" "")) 1311 (use (match_operand 2 "" ""))])] 1312 "" 1313{ 1314 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 0); 1315 DONE; 1316}) 1317 1318(define_expand "sibcall" 1319 [(parallel [(call (match_operand:SI 0 "" "") 1320 (match_operand 1 "" "")) 1321 (use (match_operand 2 "" "")) 1322 (return)])] 1323 "" 1324{ 1325 bfin_expand_call (NULL_RTX, operands[0], operands[1], operands[2], 1); 1326 DONE; 1327}) 1328 1329(define_expand "call_value" 1330 [(parallel [(set (match_operand 0 "register_operand" "") 1331 (call (match_operand:SI 1 "" "") 1332 (match_operand 2 "" ""))) 1333 (use (match_operand 3 "" ""))])] 1334 "" 1335{ 1336 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 0); 1337 DONE; 1338}) 1339 1340(define_expand "sibcall_value" 1341 [(parallel [(set (match_operand 0 "register_operand" "") 1342 (call (match_operand:SI 1 "" "") 1343 (match_operand 2 "" ""))) 1344 (use (match_operand 3 "" "")) 1345 (return)])] 1346 "" 1347{ 1348 bfin_expand_call (operands[0], operands[1], operands[2], operands[3], 1); 1349 DONE; 1350}) 1351 1352(define_insn "*call_symbol" 1353 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q")) 1354 (match_operand 1 "general_operand" "g")) 1355 (use (match_operand 2 "" ""))] 1356 "! SIBLING_CALL_P (insn) 1357 && !TARGET_ID_SHARED_LIBRARY 1358 && GET_CODE (operands[0]) == SYMBOL_REF 1359 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))" 1360 "call %0;" 1361 [(set_attr "type" "call") 1362 (set_attr "length" "4")]) 1363 1364(define_insn "*sibcall_symbol" 1365 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "Q")) 1366 (match_operand 1 "general_operand" "g")) 1367 (use (match_operand 2 "" "")) 1368 (return)] 1369 "SIBLING_CALL_P (insn) 1370 && !TARGET_ID_SHARED_LIBRARY 1371 && GET_CODE (operands[0]) == SYMBOL_REF 1372 && !bfin_longcall_p (operands[0], INTVAL (operands[2]))" 1373 "jump.l %0;" 1374 [(set_attr "type" "br") 1375 (set_attr "length" "4")]) 1376 1377(define_insn "*call_value_symbol" 1378 [(set (match_operand 0 "register_operand" "=d") 1379 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q")) 1380 (match_operand 2 "general_operand" "g"))) 1381 (use (match_operand 3 "" ""))] 1382 "! SIBLING_CALL_P (insn) 1383 && !TARGET_ID_SHARED_LIBRARY 1384 && GET_CODE (operands[1]) == SYMBOL_REF 1385 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))" 1386 "call %1;" 1387 [(set_attr "type" "call") 1388 (set_attr "length" "4")]) 1389 1390(define_insn "*sibcall_value_symbol" 1391 [(set (match_operand 0 "register_operand" "=d") 1392 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "Q")) 1393 (match_operand 2 "general_operand" "g"))) 1394 (use (match_operand 3 "" "")) 1395 (return)] 1396 "SIBLING_CALL_P (insn) 1397 && !TARGET_ID_SHARED_LIBRARY 1398 && GET_CODE (operands[1]) == SYMBOL_REF 1399 && !bfin_longcall_p (operands[1], INTVAL (operands[3]))" 1400 "jump.l %1;" 1401 [(set_attr "type" "br") 1402 (set_attr "length" "4")]) 1403 1404(define_insn "*call_insn" 1405 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "a")) 1406 (match_operand 1 "general_operand" "g")) 1407 (use (match_operand 2 "" ""))] 1408 "! SIBLING_CALL_P (insn)" 1409 "call (%0);" 1410 [(set_attr "type" "call") 1411 (set_attr "length" "2")]) 1412 1413(define_insn "*sibcall_insn" 1414 [(call (mem:SI (match_operand:SI 0 "register_no_elim_operand" "z")) 1415 (match_operand 1 "general_operand" "g")) 1416 (use (match_operand 2 "" "")) 1417 (return)] 1418 "SIBLING_CALL_P (insn)" 1419 "jump (%0);" 1420 [(set_attr "type" "br") 1421 (set_attr "length" "2")]) 1422 1423(define_insn "*call_value_insn" 1424 [(set (match_operand 0 "register_operand" "=d") 1425 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "a")) 1426 (match_operand 2 "general_operand" "g"))) 1427 (use (match_operand 3 "" ""))] 1428 "! SIBLING_CALL_P (insn)" 1429 "call (%1);" 1430 [(set_attr "type" "call") 1431 (set_attr "length" "2")]) 1432 1433(define_insn "*sibcall_value_insn" 1434 [(set (match_operand 0 "register_operand" "=d") 1435 (call (mem:SI (match_operand:SI 1 "register_no_elim_operand" "z")) 1436 (match_operand 2 "general_operand" "g"))) 1437 (use (match_operand 3 "" "")) 1438 (return)] 1439 "SIBLING_CALL_P (insn)" 1440 "jump (%1);" 1441 [(set_attr "type" "br") 1442 (set_attr "length" "2")]) 1443 1444;; Block move patterns 1445 1446;; We cheat. This copies one more word than operand 2 indicates. 1447 1448(define_insn "rep_movsi" 1449 [(set (match_operand:SI 0 "register_operand" "=&a") 1450 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0") 1451 (ashift:SI (match_operand:SI 2 "register_operand" "a") 1452 (const_int 2))) 1453 (const_int 4))) 1454 (set (match_operand:SI 1 "register_operand" "=&b") 1455 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1") 1456 (ashift:SI (match_dup 2) (const_int 2))) 1457 (const_int 4))) 1458 (set (mem:BLK (match_dup 3)) 1459 (mem:BLK (match_dup 4))) 1460 (use (match_dup 2)) 1461 (clobber (match_scratch:HI 5 "=&d"))] 1462 "" 1463 "%5 = [%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || [%3++] = %5 || %5 = [%4++]; [%3++] = %5;" 1464 [(set_attr "type" "misc") 1465 (set_attr "length" "16")]) 1466 1467(define_insn "rep_movhi" 1468 [(set (match_operand:SI 0 "register_operand" "=&a") 1469 (plus:SI (plus:SI (match_operand:SI 3 "register_operand" "0") 1470 (ashift:SI (match_operand:SI 2 "register_operand" "a") 1471 (const_int 1))) 1472 (const_int 2))) 1473 (set (match_operand:SI 1 "register_operand" "=&b") 1474 (plus:SI (plus:SI (match_operand:SI 4 "register_operand" "1") 1475 (ashift:SI (match_dup 2) (const_int 1))) 1476 (const_int 2))) 1477 (set (mem:BLK (match_dup 3)) 1478 (mem:BLK (match_dup 4))) 1479 (use (match_dup 2)) 1480 (clobber (match_scratch:HI 5 "=&d"))] 1481 "" 1482 "%h5 = W[%4++]; lsetup (1f, 1f) LC1 = %2; 1: MNOP || W [%3++] = %5 || %h5 = W [%4++]; W [%3++] = %5;" 1483 [(set_attr "type" "misc") 1484 (set_attr "length" "16")]) 1485 1486(define_expand "movmemsi" 1487 [(match_operand:BLK 0 "general_operand" "") 1488 (match_operand:BLK 1 "general_operand" "") 1489 (match_operand:SI 2 "const_int_operand" "") 1490 (match_operand:SI 3 "const_int_operand" "")] 1491 "" 1492{ 1493 if (bfin_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 1494 DONE; 1495 FAIL; 1496}) 1497 1498;; Conditional branch patterns 1499;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu 1500 1501;; The only outcome of this pattern is that global variables 1502;; bfin_compare_op[01] are set for use in bcond patterns. 1503 1504(define_expand "cmpbi" 1505 [(set (cc0) (compare (match_operand:BI 0 "register_operand" "") 1506 (match_operand:BI 1 "immediate_operand" "")))] 1507 "" 1508{ 1509 bfin_compare_op0 = operands[0]; 1510 bfin_compare_op1 = operands[1]; 1511 DONE; 1512}) 1513 1514(define_expand "cmpsi" 1515 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 1516 (match_operand:SI 1 "reg_or_const_int_operand" "")))] 1517 "" 1518{ 1519 bfin_compare_op0 = operands[0]; 1520 bfin_compare_op1 = operands[1]; 1521 DONE; 1522}) 1523 1524(define_insn "compare_eq" 1525 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1526 (eq:BI (match_operand:SI 1 "register_operand" "d,a") 1527 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))] 1528 "" 1529 "cc =%1==%2;" 1530 [(set_attr "type" "compare")]) 1531 1532(define_insn "compare_ne" 1533 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1534 (ne:BI (match_operand:SI 1 "register_operand" "d,a") 1535 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))] 1536 "0" 1537 "cc =%1!=%2;" 1538 [(set_attr "type" "compare")]) 1539 1540(define_insn "compare_lt" 1541 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1542 (lt:BI (match_operand:SI 1 "register_operand" "d,a") 1543 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))] 1544 "" 1545 "cc =%1<%2;" 1546 [(set_attr "type" "compare")]) 1547 1548(define_insn "compare_le" 1549 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1550 (le:BI (match_operand:SI 1 "register_operand" "d,a") 1551 (match_operand:SI 2 "reg_or_const_int_operand" "dKs3,aKs3")))] 1552 "" 1553 "cc =%1<=%2;" 1554 [(set_attr "type" "compare")]) 1555 1556(define_insn "compare_leu" 1557 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1558 (leu:BI (match_operand:SI 1 "register_operand" "d,a") 1559 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))] 1560 "" 1561 "cc =%1<=%2 (iu);" 1562 [(set_attr "type" "compare")]) 1563 1564(define_insn "compare_ltu" 1565 [(set (match_operand:BI 0 "cc_operand" "=C,C") 1566 (ltu:BI (match_operand:SI 1 "register_operand" "d,a") 1567 (match_operand:SI 2 "reg_or_const_int_operand" "dKu3,aKu3")))] 1568 "" 1569 "cc =%1<%2 (iu);" 1570 [(set_attr "type" "compare")]) 1571 1572(define_expand "beq" 1573 [(set (match_dup 1) (match_dup 2)) 1574 (set (pc) 1575 (if_then_else (match_dup 3) 1576 (label_ref (match_operand 0 "" "")) 1577 (pc)))] 1578 "" 1579{ 1580 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1; 1581 operands[1] = bfin_cc_rtx; /* hard register: CC */ 1582 operands[2] = gen_rtx_EQ (BImode, op0, op1); 1583 /* If we have a BImode input, then we already have a compare result, and 1584 do not need to emit another comparison. */ 1585 if (GET_MODE (bfin_compare_op0) == BImode) 1586 { 1587 gcc_assert (bfin_compare_op1 == const0_rtx); 1588 emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0])); 1589 DONE; 1590 } 1591 1592 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx); 1593}) 1594 1595(define_expand "bne" 1596 [(set (match_dup 1) (match_dup 2)) 1597 (set (pc) 1598 (if_then_else (match_dup 3) 1599 (label_ref (match_operand 0 "" "")) 1600 (pc)))] 1601 "" 1602{ 1603 rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1; 1604 /* If we have a BImode input, then we already have a compare result, and 1605 do not need to emit another comparison. */ 1606 if (GET_MODE (bfin_compare_op0) == BImode) 1607 { 1608 rtx cmp = gen_rtx_NE (BImode, op0, op1); 1609 1610 gcc_assert (bfin_compare_op1 == const0_rtx); 1611 emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0])); 1612 DONE; 1613 } 1614 1615 operands[1] = bfin_cc_rtx; /* hard register: CC */ 1616 operands[2] = gen_rtx_EQ (BImode, op0, op1); 1617 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx); 1618}) 1619 1620(define_expand "bgt" 1621 [(set (match_dup 1) (match_dup 2)) 1622 (set (pc) 1623 (if_then_else (match_dup 3) 1624 (label_ref (match_operand 0 "" "")) 1625 (pc)))] 1626 "" 1627{ 1628 operands[1] = bfin_cc_rtx; 1629 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1); 1630 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx); 1631}) 1632 1633(define_expand "bgtu" 1634 [(set (match_dup 1) (match_dup 2)) 1635 (set (pc) 1636 (if_then_else (match_dup 3) 1637 (label_ref (match_operand 0 "" "")) 1638 (pc)))] 1639 "" 1640{ 1641 operands[1] = bfin_cc_rtx; 1642 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1); 1643 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx); 1644}) 1645 1646(define_expand "blt" 1647 [(set (match_dup 1) (match_dup 2)) 1648 (set (pc) 1649 (if_then_else (match_dup 3) 1650 (label_ref (match_operand 0 "" "")) 1651 (pc)))] 1652 "" 1653{ 1654 operands[1] = bfin_cc_rtx; 1655 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1); 1656 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx); 1657}) 1658 1659(define_expand "bltu" 1660 [(set (match_dup 1) (match_dup 2)) 1661 (set (pc) 1662 (if_then_else (match_dup 3) 1663 (label_ref (match_operand 0 "" "")) 1664 (pc)))] 1665 "" 1666{ 1667 operands[1] = bfin_cc_rtx; 1668 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1); 1669 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx); 1670}) 1671 1672 1673(define_expand "bge" 1674 [(set (match_dup 1) (match_dup 2)) 1675 (set (pc) 1676 (if_then_else (match_dup 3) 1677 (label_ref (match_operand 0 "" "")) 1678 (pc)))] 1679 "" 1680{ 1681 operands[1] = bfin_cc_rtx; 1682 operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1); 1683 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx); 1684}) 1685 1686(define_expand "bgeu" 1687 [(set (match_dup 1) (match_dup 2)) 1688 (set (pc) 1689 (if_then_else (match_dup 3) 1690 (label_ref (match_operand 0 "" "")) 1691 (pc)))] 1692 "" 1693{ 1694 operands[1] = bfin_cc_rtx; 1695 operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1); 1696 operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx); 1697}) 1698 1699(define_expand "ble" 1700 [(set (match_dup 1) (match_dup 2)) 1701 (set (pc) 1702 (if_then_else (match_dup 3) 1703 (label_ref (match_operand 0 "" "")) 1704 (pc)))] 1705 "" 1706{ 1707 operands[1] = bfin_cc_rtx; 1708 operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1); 1709 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx); 1710}) 1711 1712(define_expand "bleu" 1713 [(set (match_dup 1) (match_dup 2)) 1714 (set (pc) 1715 (if_then_else (match_dup 3) 1716 (label_ref (match_operand 0 "" "")) 1717 (pc))) 1718 ] 1719 "" 1720{ 1721 operands[1] = bfin_cc_rtx; 1722 operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1); 1723 operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx); 1724}) 1725 1726(define_insn "cbranchbi4" 1727 [(set (pc) 1728 (if_then_else 1729 (match_operator 0 "bfin_cbranch_operator" 1730 [(match_operand:BI 1 "cc_operand" "C") 1731 (match_operand:BI 2 "immediate_operand" "P0")]) 1732 (label_ref (match_operand 3 "" "")) 1733 (pc)))] 1734 "" 1735{ 1736 asm_conditional_branch (insn, operands, 0, 0); 1737 return ""; 1738} 1739 [(set_attr "type" "brcc")]) 1740 1741;; Special cbranch patterns to deal with the speculative load problem - see 1742;; bfin_reorg for details. 1743 1744(define_insn "cbranch_predicted_taken" 1745 [(set (pc) 1746 (if_then_else 1747 (match_operator 0 "bfin_cbranch_operator" 1748 [(match_operand:BI 1 "cc_operand" "C") 1749 (match_operand:BI 2 "immediate_operand" "P0")]) 1750 (label_ref (match_operand 3 "" "")) 1751 (pc))) 1752 (unspec [(const_int 0)] UNSPEC_CBRANCH_TAKEN)] 1753 "" 1754{ 1755 asm_conditional_branch (insn, operands, 0, 1); 1756 return ""; 1757} 1758 [(set_attr "type" "brcc")]) 1759 1760(define_insn "cbranch_with_nops" 1761 [(set (pc) 1762 (if_then_else 1763 (match_operator 0 "bfin_cbranch_operator" 1764 [(match_operand:BI 1 "cc_operand" "C") 1765 (match_operand:BI 2 "immediate_operand" "P0")]) 1766 (label_ref (match_operand 3 "" "")) 1767 (pc))) 1768 (unspec [(match_operand 4 "immediate_operand" "")] UNSPEC_CBRANCH_NOPS)] 1769 "reload_completed" 1770{ 1771 asm_conditional_branch (insn, operands, INTVAL (operands[4]), 0); 1772 return ""; 1773} 1774 [(set_attr "type" "brcc") 1775 (set_attr "length" "6")]) 1776 1777;; setcc insns. */ 1778(define_expand "seq" 1779 [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3))) 1780 (set (match_operand:SI 0 "register_operand" "") 1781 (ne:SI (match_dup 1) (const_int 0)))] 1782 "" 1783{ 1784 operands[2] = bfin_compare_op0; 1785 operands[3] = bfin_compare_op1; 1786 operands[1] = bfin_cc_rtx; 1787}) 1788 1789(define_expand "slt" 1790 [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3))) 1791 (set (match_operand:SI 0 "register_operand" "") 1792 (ne:SI (match_dup 1) (const_int 0)))] 1793 "" 1794{ 1795 operands[2] = bfin_compare_op0; 1796 operands[3] = bfin_compare_op1; 1797 operands[1] = bfin_cc_rtx; 1798}) 1799 1800(define_expand "sle" 1801 [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3))) 1802 (set (match_operand:SI 0 "register_operand" "") 1803 (ne:SI (match_dup 1) (const_int 0)))] 1804 "" 1805{ 1806 operands[2] = bfin_compare_op0; 1807 operands[3] = bfin_compare_op1; 1808 operands[1] = bfin_cc_rtx; 1809}) 1810 1811(define_expand "sltu" 1812 [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3))) 1813 (set (match_operand:SI 0 "register_operand" "") 1814 (ne:SI (match_dup 1) (const_int 0)))] 1815 "" 1816{ 1817 operands[2] = bfin_compare_op0; 1818 operands[3] = bfin_compare_op1; 1819 operands[1] = bfin_cc_rtx; 1820}) 1821 1822(define_expand "sleu" 1823 [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3))) 1824 (set (match_operand:SI 0 "register_operand" "") 1825 (ne:SI (match_dup 1) (const_int 0)))] 1826 "" 1827{ 1828 operands[2] = bfin_compare_op0; 1829 operands[3] = bfin_compare_op1; 1830 operands[1] = bfin_cc_rtx; 1831}) 1832 1833(define_insn "nop" 1834 [(const_int 0)] 1835 "" 1836 "nop;") 1837 1838;;;;;;;;;;;;;;;;;;;; CC2dreg ;;;;;;;;;;;;;;;;;;;;;;;;; 1839(define_insn "movsibi" 1840 [(set (match_operand:BI 0 "cc_operand" "=C") 1841 (ne:BI (match_operand:SI 1 "register_operand" "d") 1842 (const_int 0)))] 1843 "" 1844 "CC = %1;" 1845 [(set_attr "length" "2")]) 1846 1847(define_insn "movbisi" 1848 [(set (match_operand:SI 0 "register_operand" "=d") 1849 (ne:SI (match_operand:BI 1 "cc_operand" "C") 1850 (const_int 0)))] 1851 "" 1852 "%0 = CC;" 1853 [(set_attr "length" "2")]) 1854 1855(define_insn "" 1856 [(set (match_operand:BI 0 "cc_operand" "=C") 1857 (eq:BI (match_operand:BI 1 "cc_operand" " 0") 1858 (const_int 0)))] 1859 "" 1860 "%0 = ! %0;" /* NOT CC;" */ 1861 [(set_attr "type" "compare")]) 1862 1863;; Vector and DSP insns 1864 1865(define_insn "" 1866 [(set (match_operand:SI 0 "register_operand" "=d") 1867 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") 1868 (const_int 24)) 1869 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d") 1870 (const_int 8))))] 1871 "" 1872 "%0 = ALIGN8(%1, %2);" 1873 [(set_attr "type" "dsp32")]) 1874 1875(define_insn "" 1876 [(set (match_operand:SI 0 "register_operand" "=d") 1877 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") 1878 (const_int 16)) 1879 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d") 1880 (const_int 16))))] 1881 "" 1882 "%0 = ALIGN16(%1, %2);" 1883 [(set_attr "type" "dsp32")]) 1884 1885(define_insn "" 1886 [(set (match_operand:SI 0 "register_operand" "=d") 1887 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") 1888 (const_int 8)) 1889 (lshiftrt:SI (match_operand:SI 2 "register_operand" "d") 1890 (const_int 24))))] 1891 "" 1892 "%0 = ALIGN24(%1, %2);" 1893 [(set_attr "type" "dsp32")]) 1894 1895;; Prologue and epilogue. 1896 1897(define_expand "prologue" 1898 [(const_int 1)] 1899 "" 1900 "bfin_expand_prologue (); DONE;") 1901 1902(define_expand "epilogue" 1903 [(const_int 1)] 1904 "" 1905 "bfin_expand_epilogue (1, 0); DONE;") 1906 1907(define_expand "sibcall_epilogue" 1908 [(const_int 1)] 1909 "" 1910 "bfin_expand_epilogue (0, 0); DONE;") 1911 1912(define_expand "eh_return" 1913 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")] 1914 UNSPEC_VOLATILE_EH_RETURN)] 1915 "" 1916{ 1917 emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]); 1918 emit_insn (gen_eh_return_internal ()); 1919 emit_barrier (); 1920 DONE; 1921}) 1922 1923(define_insn_and_split "eh_return_internal" 1924 [(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN)] 1925 "" 1926 "#" 1927 "reload_completed" 1928 [(const_int 1)] 1929 "bfin_expand_epilogue (1, 1); DONE;") 1930 1931(define_insn "link" 1932 [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS)) 1933 (set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -8))) (reg:SI REG_FP)) 1934 (set (reg:SI REG_FP) 1935 (plus:SI (reg:SI REG_SP) (const_int -8))) 1936 (set (reg:SI REG_SP) 1937 (plus:SI (reg:SI REG_SP) (match_operand:SI 0 "immediate_operand" "i")))] 1938 "" 1939 "LINK %Z0;" 1940 [(set_attr "length" "4")]) 1941 1942(define_insn "unlink" 1943 [(set (reg:SI REG_FP) (mem:SI (reg:SI REG_FP))) 1944 (set (reg:SI REG_RETS) (mem:SI (plus:SI (reg:SI REG_FP) (const_int 4)))) 1945 (set (reg:SI REG_SP) (plus:SI (reg:SI REG_FP) (const_int 8)))] 1946 "" 1947 "UNLINK;" 1948 [(set_attr "length" "4")]) 1949 1950;; This pattern is slightly clumsy. The stack adjust must be the final SET in 1951;; the pattern, otherwise dwarf2out becomes very confused about which reg goes 1952;; where on the stack, since it goes through all elements of the parallel in 1953;; sequence. 1954(define_insn "push_multiple" 1955 [(match_parallel 0 "push_multiple_operation" 1956 [(unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_PUSH_MULTIPLE)])] 1957 "" 1958{ 1959 output_push_multiple (insn, operands); 1960 return ""; 1961}) 1962 1963(define_insn "pop_multiple" 1964 [(match_parallel 0 "pop_multiple_operation" 1965 [(set (reg:SI REG_SP) 1966 (plus:SI (reg:SI REG_SP) (match_operand:SI 1 "immediate_operand" "i")))])] 1967 "" 1968{ 1969 output_pop_multiple (insn, operands); 1970 return ""; 1971}) 1972 1973(define_insn "return_internal" 1974 [(return) 1975 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_RETURN)] 1976 "reload_completed" 1977{ 1978 switch (INTVAL (operands[0])) 1979 { 1980 case EXCPT_HANDLER: 1981 return "rtx;"; 1982 case NMI_HANDLER: 1983 return "rtn;"; 1984 case INTERRUPT_HANDLER: 1985 return "rti;"; 1986 case SUBROUTINE: 1987 return "rts;"; 1988 } 1989 gcc_unreachable (); 1990}) 1991 1992(define_insn "csync" 1993 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)] 1994 "" 1995 "csync;" 1996 [(set_attr "type" "sync")]) 1997 1998(define_insn "ssync" 1999 [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_SSYNC)] 2000 "" 2001 "ssync;" 2002 [(set_attr "type" "sync")]) 2003 2004(define_insn "trap" 2005 [(trap_if (const_int 1) (const_int 3))] 2006 "" 2007 "excpt 3;" 2008 [(set_attr "type" "misc") 2009 (set_attr "length" "2")]) 2010 2011(define_insn "trapifcc" 2012 [(trap_if (reg:BI REG_CC) (const_int 3))] 2013 "" 2014 "if !cc jump 4 (bp); excpt 3;" 2015 [(set_attr "type" "misc") 2016 (set_attr "length" "4")]) 2017 2018;;; Vector instructions 2019 2020(define_insn "addv2hi3" 2021 [(set (match_operand:V2HI 0 "register_operand" "=d") 2022 (plus:V2HI (match_operand:V2HI 1 "register_operand" "d") 2023 (match_operand:V2HI 2 "register_operand" "d")))] 2024 "" 2025 "%0 = %1 +|+ %2;" 2026 [(set_attr "type" "dsp32")]) 2027 2028(define_insn "subv2hi3" 2029 [(set (match_operand:V2HI 0 "register_operand" "=d") 2030 (minus:V2HI (match_operand:V2HI 1 "register_operand" "d") 2031 (match_operand:V2HI 2 "register_operand" "d")))] 2032 "" 2033 "%0 = %1 -|- %2;" 2034 [(set_attr "type" "dsp32")]) 2035 2036(define_insn "sminv2hi3" 2037 [(set (match_operand:V2HI 0 "register_operand" "=d") 2038 (smin:V2HI (match_operand:V2HI 1 "register_operand" "d") 2039 (match_operand:V2HI 2 "register_operand" "d")))] 2040 "" 2041 "%0 = MIN (%1, %2) (V);" 2042 [(set_attr "type" "dsp32")]) 2043 2044(define_insn "smaxv2hi3" 2045 [(set (match_operand:V2HI 0 "register_operand" "=d") 2046 (smax:V2HI (match_operand:V2HI 1 "register_operand" "d") 2047 (match_operand:V2HI 2 "register_operand" "d")))] 2048 "" 2049 "%0 = MAX (%1, %2) (V);" 2050 [(set_attr "type" "dsp32")]) 2051 2052(define_insn "mulv2hi3" 2053 [(set (match_operand:V2HI 0 "register_operand" "=d") 2054 (mult:V2HI (match_operand:V2HI 1 "register_operand" "d") 2055 (match_operand:V2HI 2 "register_operand" "d")))] 2056 "" 2057 "%h0 = %h1 * %h2, %d0 = %d1 * %d2 (IS);" 2058 [(set_attr "type" "dsp32")]) 2059 2060(define_insn "negv2hi2" 2061 [(set (match_operand:V2HI 0 "register_operand" "=d") 2062 (neg:V2HI (match_operand:V2HI 1 "register_operand" "d")))] 2063 "" 2064 "%0 = - %1 (V);" 2065 [(set_attr "type" "dsp32")]) 2066 2067(define_insn "absv2hi2" 2068 [(set (match_operand:V2HI 0 "register_operand" "=d") 2069 (abs:V2HI (match_operand:V2HI 1 "register_operand" "d")))] 2070 "" 2071 "%0 = ABS %1 (V);" 2072 [(set_attr "type" "dsp32")]) 2073 2074