1;; Machine description for GNU compiler, OpenRISC 1000 family, OR32 ISA 2;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 3;; 2009, 2010 Free Software Foundation, Inc. 4;; Copyright (C) 2010 Embecosm Limited 5 6;; Contributed by Damjan Lampret <damjanl@bsemi.com> in 1999. 7;; Major optimizations by Matjaz Breskvar <matjazb@bsemi.com> in 2005. 8;; Floating point additions by Jungsook Yang <jungsook.yang@uci.edu> 9;; Julius Baxter <julius@orsoc.se> in 2010 10;; Updated for GCC 4.5 by Jeremy Bennett <jeremy.bennett@embecosm.com> 11;; and Joern Rennecke <joern.rennecke@embecosm.com> in 2010 12 13;; This file is part of GNU CC. 14 15;; This program is free software; you can redistribute it and/or modify it 16;; under the terms of the GNU General Public License as published by the Free 17;; Software Foundation; either version 3 of the License, or (at your option) 18;; any later version. 19;; 20;; This program is distributed in the hope that it will be useful, but WITHOUT 21;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 23;; more details. 24;; 25;; You should have received a copy of the GNU General Public License along 26;; with this program. If not, see <http://www.gnu.org/licenses/>. */ 27 28(define_constants [ 29 (SP_REG 1) 30 (FP_REG 2) ; hard frame pointer 31 (CC_REG 34) 32 33 ;; unspec values 34 (UNSPEC_FRAME 0) 35 (UNSPEC_GOT 1) 36 (UNSPEC_GOTOFFHI 2) 37 (UNSPEC_GOTOFFLO 3) 38 (UNSPEC_TPOFFLO 4) 39 (UNSPEC_TPOFFHI 5) 40 (UNSPEC_GOTTPOFFLO 6) 41 (UNSPEC_GOTTPOFFHI 7) 42 (UNSPEC_GOTTPOFFLD 8) 43 (UNSPEC_TLSGDLO 9) 44 (UNSPEC_TLSGDHI 10) 45 (UNSPEC_SET_GOT 101) 46 (UNSPEC_CMPXCHG 201) 47 (UNSPEC_FETCH_AND_OP 202) 48]) 49 50(include "predicates.md") 51 52(include "constraints.md") 53 54(define_attr "type" 55 "unknown,load,store,move,extend,logic,add,mul,shift,compare,branch,jump,fp,jump_restore" 56 (const_string "unknown")) 57 58;; Number of machine instructions required to implement an insn. 59(define_attr "length" "" (const_int 1)) 60 61;; Single delay slot after branch or jump instructions, wich may contain any 62;; instruction but another branch or jump. 63;; If TARGET_DELAY_OFF is not true, then never use delay slots. 64;; If TARGET_DELAY_ON is not true, no instruction will be allowed to 65;; fill the slot, and so it will be filled by a nop instead. 66(define_delay 67 (and (match_test "!TARGET_DELAY_OFF") (eq_attr "type" "branch,jump")) 68 [(and (match_test "TARGET_DELAY_ON") 69 (eq_attr "type" "!branch,jump") 70 (eq_attr "length" "1")) (nil) (nil)]) 71 72;; ALU is modelled as a single functional unit, which is reserved for varying 73;; numbers of slots. 74;; 75;; I think this is all incorrect for the OR1K. The latency says when the 76;; result will be ready, not how long the pipeline takes to execute. 77(define_cpu_unit "or1k_alu") 78(define_insn_reservation "bit_unit" 3 (eq_attr "type" "shift") "or1k_alu") 79(define_insn_reservation "lsu_load" 3 (eq_attr "type" "load") "or1k_alu*3") 80(define_insn_reservation "lsu_store" 2 (eq_attr "type" "store") "or1k_alu") 81(define_insn_reservation "alu_unit" 2 82 (eq_attr "type" "add,logic,extend,move,compare") 83 "or1k_alu") 84(define_insn_reservation "mul_unit" 16 (eq_attr "type" "mul") "or1k_alu*16") 85 86;; AI = Atomic Integers 87;; We do not support DI in our atomic operations. 88(define_mode_iterator AI [QI HI SI]) 89 90;; Note: We use 'mult' here for nand since it does not have its own RTX class. 91(define_code_iterator atomic_op [plus minus and ior xor mult]) 92(define_code_attr op_name 93 [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "nand")]) 94(define_code_attr op_insn 95 [(plus "add") (minus "sub") (and "and") (ior "or") (xor "xor") (mult "and")]) 96(define_code_attr post_op_insn 97 [(plus "") (minus "") (and "") (ior "") (xor "") 98 (mult "l.xori \t%3,%3,0xffff # fetch_nand: invert")]) 99 100;; Called after register allocation to add any instructions needed for the 101;; prologue. Using a prologue insn is favored compared to putting all of the 102;; instructions in output_function_prologue(), since it allows the scheduler 103;; to intermix instructions with the saves of the caller saved registers. In 104;; some cases, it might be necessary to emit a barrier instruction as the last 105;; insn to prevent such scheduling. 106 107(define_expand "prologue" 108 [(use (const_int 1))] 109 "" 110{ 111 or1k_expand_prologue (); 112 DONE; 113}) 114 115;; Called after register allocation to add any instructions needed for the 116;; epilogue. Using an epilogue insn is favored compared to putting all of the 117;; instructions in output_function_epilogue(), since it allows the scheduler 118;; to intermix instructions with the restores of the caller saved registers. 119;; In some cases, it might be necessary to emit a barrier instruction as the 120;; first insn to prevent such scheduling. 121(define_expand "epilogue" 122 [(use (const_int 2))] 123 "" 124{ 125 or1k_expand_epilogue (); 126 DONE; 127}) 128 129(define_insn "frame_alloc_fp" 130 [(set (reg:SI SP_REG) 131 (plus:SI (reg:SI SP_REG) 132 (match_operand:SI 0 "nonmemory_operand" "r,I"))) 133 (clobber (mem:QI (plus:SI (reg:SI FP_REG) 134 (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))] 135 "" 136 "@ 137 l.add\tr1,r1,%0\t# allocate frame 138 l.addi\tr1,r1,%0\t# allocate frame" 139 [(set_attr "type" "add") 140 (set_attr "length" "1")]) 141 142(define_insn "frame_dealloc_fp" 143 [(set (reg:SI SP_REG) (reg:SI FP_REG)) 144 (clobber (mem:QI (plus:SI (reg:SI FP_REG) 145 (unspec:SI [(const_int FP_REG)] UNSPEC_FRAME))))] 146 "" 147 "l.ori\tr1,r2,0\t# deallocate frame" 148 [(set_attr "type" "logic") 149 (set_attr "length" "1")]) 150 151(define_insn "frame_dealloc_sp" 152 [(set (reg:SI SP_REG) 153 (plus:SI (reg:SI SP_REG) 154 (match_operand:SI 0 "nonmemory_operand" "r,I"))) 155 (clobber (mem:QI (plus:SI (reg:SI SP_REG) 156 (unspec:SI [(const_int SP_REG)] UNSPEC_FRAME))))] 157 "" 158 "@ 159 l.add \tr1,r1,%0 160 l.addi \tr1,r1,%0" 161 [(set_attr "type" "add") 162 (set_attr "length" "1")]) 163 164(define_insn "return_internal" 165 [(return) 166 (use (match_operand 0 "pmode_register_operand" ""))] 167 "" 168 "l.jr \t%0\t# return_internal%(" 169 [(set_attr "type" "jump") 170 (set_attr "length" "1")]) 171 172 173 174;; 175;; movQI 176;; 177 178(define_expand "movqi" 179 [(set (match_operand:QI 0 "general_operand" "") 180 (match_operand:QI 1 "general_operand" ""))] 181 "" 182 " 183 if (can_create_pseudo_p()) 184 { 185 if (GET_CODE (operands[1]) == CONST_INT) 186 { 187 rtx reg = gen_reg_rtx (SImode); 188 189 emit_insn (gen_movsi (reg, operands[1])); 190 operands[1] = gen_lowpart (QImode, reg); 191 } 192 if (GET_CODE (operands[1]) == MEM && optimize > 0) 193 { 194 rtx reg = gen_reg_rtx (SImode); 195 196 emit_insn (gen_rtx_SET (SImode, reg, 197 gen_rtx_ZERO_EXTEND (SImode, 198 operands[1]))); 199 200 operands[1] = gen_lowpart (QImode, reg); 201 } 202 if (GET_CODE (operands[0]) != REG) 203 operands[1] = force_reg (QImode, operands[1]); 204 } 205") 206 207(define_insn "*movqi_internal" 208 [(set (match_operand:QI 0 "nonimmediate_operand" "=m,r,r,r,r") 209 (match_operand:QI 1 "general_operand" "r,r,I,K,m"))] 210 "" 211 "@ 212 l.sb \t%0,%1\t # movqi 213 l.ori \t%0,%1,0\t # movqi: move reg to reg 214 l.addi \t%0,r0,%1\t # movqi: move immediate 215 l.ori \t%0,r0,%1\t # movqi: move immediate 216 l.lbz \t%0,%1\t # movqi" 217 [(set_attr "type" "store,add,add,logic,load")]) 218 219 220;; 221;; movHI 222;; 223 224(define_expand "movhi" 225 [(set (match_operand:HI 0 "general_operand" "") 226 (match_operand:HI 1 "general_operand" ""))] 227 "" 228 " 229 if (can_create_pseudo_p()) 230 { 231 if (GET_CODE (operands[1]) == CONST_INT) 232 { 233 rtx reg = gen_reg_rtx (SImode); 234 235 emit_insn (gen_movsi (reg, operands[1])); 236 operands[1] = gen_lowpart (HImode, reg); 237 } 238 else if (GET_CODE (operands[1]) == MEM && optimize > 0) 239 { 240 rtx reg = gen_reg_rtx (SImode); 241 242 emit_insn (gen_rtx_SET (SImode, reg, 243 gen_rtx_ZERO_EXTEND (SImode, 244 operands[1]))); 245 operands[1] = gen_lowpart (HImode, reg); 246 } 247 if (GET_CODE (operands[0]) != REG) 248 operands[1] = force_reg (HImode, operands[1]); 249 } 250") 251 252(define_insn "*movhi_internal" 253 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r,r,r,r") 254 (match_operand:HI 1 "general_operand" "r,r,I,K,m"))] 255 "" 256 "@ 257 l.sh \t%0,%1\t # movhi 258 l.ori \t%0,%1,0\t # movhi: move reg to reg 259 l.addi \t%0,r0,%1\t # movhi: move immediate 260 l.ori \t%0,r0,%1\t # movhi: move immediate 261 l.lhz \t%0,%1\t # movhi" 262 [(set_attr "type" "store,add,add,logic,load")]) 263 264(define_expand "movsi" 265 [(set (match_operand:SI 0 "general_operand" "") 266 (match_operand:SI 1 "general_operand" ""))] 267 "" 268{ 269 if (or1k_expand_move (SImode, operands)) DONE; 270}) 271 272;; 273;; movSI 274;; 275 276(define_insn "*movsi_insn" 277 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m") 278 (match_operand:SI 1 "input_operand" "I,K,M,r,m,r"))] 279 "(register_operand (operands[0], SImode) 280 || (register_operand (operands[1], SImode)) 281 || (operands[1] == const0_rtx))" 282 "@ 283 l.addi \t%0,r0,%1\t # move immediate I 284 l.ori \t%0,r0,%1\t # move immediate K 285 l.movhi \t%0,hi(%1)\t # move immediate M 286 l.ori \t%0,%1,0\t # move reg to reg 287 l.lwz \t%0,%1\t # SI load 288 l.sw \t%0,%1\t # SI store" 289 [(set_attr "type" "add,load,store,add,logic,move") 290 (set_attr "length" "1,1,1,1,1,1")]) 291 292(define_insn "movsi_lo_sum" 293 [(set (match_operand:SI 0 "register_operand" "=r") 294 (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 295 (match_operand:SI 2 "immediate_operand" "i")))] 296 "" 297 "l.ori \t%0,%1,lo(%2) # movsi_lo_sum" 298 [(set_attr "type" "logic") 299 (set_attr "length" "1")]) 300 301(define_insn "movsi_high" 302 [(set (match_operand:SI 0 "register_operand" "=r") 303 (high:SI (match_operand:SI 1 "immediate_operand" "i")))] 304 "" 305 "l.movhi \t%0,hi(%1) # movsi_high" 306[(set_attr "type" "move") 307 (set_attr "length" "1")]) 308 309(define_insn "movsi_gotofflo" 310 [(set (match_operand:SI 0 "register_operand" "=r") 311 (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r") 312 (match_operand 2 "" ""))] UNSPEC_GOTOFFLO))] 313 "flag_pic" 314 "l.ori \t%0,%1,gotofflo(%2) # movsi_gotofflo" 315 [(set_attr "type" "logic") 316 (set_attr "length" "1")]) 317 318(define_insn "movsi_gotoffhi" 319 [(set (match_operand:SI 0 "register_operand" "=r") 320 (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFFHI))] 321 "flag_pic" 322 "l.movhi \t%0,gotoffhi(%1) # movsi_gotoffhi" 323 [(set_attr "type" "move") 324 (set_attr "length" "1")]) 325 326(define_insn "movsi_got" 327 [(set (match_operand:SI 0 "register_operand" "=r") 328 (unspec:SI [(match_operand 1 "symbolic_operand" "")] UNSPEC_GOT)) 329 (use (reg:SI 16))] 330 "flag_pic" 331 "l.lwz \t%0, got(%1)(r16)" 332 [(set_attr "type" "load")] 333) 334 335(define_insn "movsi_tlsgdlo" 336 [(set (match_operand:SI 0 "register_operand" "=r") 337 (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r") 338 (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TLSGDLO))] 339 "" 340 "l.ori \t%0,%1,tlsgdlo(%2) # movsi_tlsgdlo" 341 [(set_attr "type" "logic") 342 (set_attr "length" "1")]) 343 344(define_insn "movsi_tlsgdhi" 345 [(set (match_operand:SI 0 "register_operand" "=r") 346 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TLSGDHI))] 347 "" 348 "l.movhi \t%0,tlsgdhi(%1) # movsi_tlsgdhi" 349[(set_attr "type" "move") 350 (set_attr "length" "1")]) 351 352(define_insn "movsi_gottpofflo" 353 [(set (match_operand:SI 0 "register_operand" "=r") 354 (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r") 355 (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_GOTTPOFFLO))] 356 "" 357 "l.ori \t%0,%1,gottpofflo(%2) # movsi_gottpofflo" 358 [(set_attr "type" "logic") 359 (set_attr "length" "1")]) 360 361(define_insn "movsi_gottpoffhi" 362 [(set (match_operand:SI 0 "register_operand" "=r") 363 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_GOTTPOFFHI))] 364 "" 365 "l.movhi \t%0,gottpoffhi(%1) # movsi_gottpoffhi" 366[(set_attr "type" "move") 367 (set_attr "length" "1")]) 368 369(define_insn "load_gottpoff" 370 [(set (match_operand:SI 0 "register_operand" "=r") 371 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_GOTTPOFFLD))] 372 "" 373 "l.lwz \t%0,0(%1) # load_gottpoff" 374[(set_attr "type" "load") 375 (set_attr "length" "1")]) 376 377(define_insn "movsi_tpofflo" 378 [(set (match_operand:SI 0 "register_operand" "=r") 379 (unspec:SI [(lo_sum:SI (match_operand:SI 1 "register_operand" "r") 380 (match_operand:SI 2 "immediate_operand" "i"))] UNSPEC_TPOFFLO))] 381 "" 382 "l.ori \t%0,%1,tpofflo(%2) # movsi_tpofflo" 383 [(set_attr "type" "logic") 384 (set_attr "length" "1")]) 385 386(define_insn "movsi_tpoffhi" 387 [(set (match_operand:SI 0 "register_operand" "=r") 388 (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_TPOFFHI))] 389 "" 390 "l.movhi \t%0,tpoffhi(%1) # movsi_tpoffhi" 391[(set_attr "type" "move") 392 (set_attr "length" "1")]) 393 394 395(define_insn_and_split "movsi_insn_big" 396 [(set (match_operand:SI 0 "register_operand" "=r") 397 (match_operand:SI 1 "immediate_operand" "i"))] 398 "GET_CODE (operands[1]) != CONST_INT" 399 ;; the switch of or1k bfd to Rela allows us to schedule insns separately. 400 "l.movhi \t%0,hi(%1)\;l.ori \t%0,%0,lo(%1)" 401 "(GET_CODE (operands[1]) != CONST_INT 402 || ! (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'I', \"I\") 403 || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'K', \"K\") 404 || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'M', \"M\"))) 405 && reload_completed 406 && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM" 407 [(pc)] 408{ 409 if (!or1k_expand_symbol_ref(SImode, operands)) 410 { 411 emit_insn (gen_movsi_high (operands[0], operands[1])); 412 emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1])); 413 } 414 DONE; 415} 416 [(set_attr "type" "move") 417 (set_attr "length" "2")]) 418 419 420;; 421;; Conditional Branches & Moves 422;; 423 424(define_expand "addsicc" 425 [(match_operand:SI 0 "register_operand" "") 426 (match_operand 1 "comparison_operator" "") 427 (match_operand:SI 2 "register_operand" "") 428 (match_operand:SI 3 "register_operand" "")] 429 "" 430 "FAIL;") 431 432(define_expand "addhicc" 433 [(match_operand:HI 0 "register_operand" "") 434 (match_operand 1 "comparison_operator" "") 435 (match_operand:HI 2 "register_operand" "") 436 (match_operand:HI 3 "register_operand" "")] 437 "" 438 "FAIL;") 439 440(define_expand "addqicc" 441 [(match_operand:QI 0 "register_operand" "") 442 (match_operand 1 "comparison_operator" "") 443 (match_operand:QI 2 "register_operand" "") 444 (match_operand:QI 3 "register_operand" "")] 445 "" 446 "FAIL;") 447 448 449;; 450;; conditional moves 451;; 452 453(define_expand "movsicc" 454 [(set (match_operand:SI 0 "register_operand" "") 455 (if_then_else:SI (match_operand 1 "comparison_operator" "") 456 (match_operand:SI 2 "register_operand" "") 457 (match_operand:SI 3 "register_operand" "")))] 458 "TARGET_MASK_CMOV" 459 " 460{ 461 if (or1k_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 462 DONE; 463}") 464 465(define_expand "movhicc" 466 [(set (match_operand:HI 0 "register_operand" "") 467 (if_then_else:SI (match_operand 1 "comparison_operator" "") 468 (match_operand:HI 2 "register_operand" "") 469 (match_operand:HI 3 "register_operand" "")))] 470 "" 471 " 472{ 473 FAIL; 474}") 475 476(define_expand "movqicc" 477 [(set (match_operand:QI 0 "register_operand" "") 478 (if_then_else:SI (match_operand 1 "comparison_operator" "") 479 (match_operand:QI 2 "register_operand" "") 480 (match_operand:QI 3 "register_operand" "")))] 481 "" 482 " 483{ 484 FAIL; 485}") 486 487 488;; We use the BASE_REGS for the cmov input operands because, if rA is 489;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 490;; because we may switch the operands and rB may end up being rA. 491 492(define_insn "cmov" 493 [(set (match_operand:SI 0 "register_operand" "=r") 494 (if_then_else:SI 495 (match_operator 1 "comparison_operator" 496 [(match_operand 4 "cc_reg_operand" "") 497 (const_int 0)]) 498 (match_operand:SI 2 "register_operand" "r") 499 (match_operand:SI 3 "register_operand" "r")))] 500 "TARGET_MASK_CMOV" 501 "* 502 return or1k_output_cmov(operands); 503 ") 504 505;; 506;; .................... 507;; 508;; COMPARISONS 509;; 510;; .................... 511 512;; Flow here is rather complex: 513;; 514;; 1) The cmp{si,di,sf,df} routine is called. It deposits the 515;; arguments into the branch_cmp array, and the type into 516;; branch_type. No RTL is generated. 517;; 518;; 2) The appropriate branch define_expand is called, which then 519;; creates the appropriate RTL for the comparison and branch. 520;; Different CC modes are used, based on what type of branch is 521;; done, so that we can constrain things appropriately. There 522;; are assumptions in the rest of GCC that break if we fold the 523;; operands into the branches for integer operations, and use cc0 524;; for floating point, so we use the fp status register instead. 525;; If needed, an appropriate temporary is created to hold the 526;; of the integer compare. 527 528;; Compare insns are next. Note that the RS/6000 has two types of compares, 529;; signed & unsigned, and one type of branch. 530;; 531;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 532;; insns, and branches. We store the operands of compares until we see 533;; how it is used. 534 535;; JPB 31-Aug-10: cmpxx appears to be obsolete in GCC 4.5. Needs more 536;; investigation. 537 538;;(define_expand "cmpsi" 539;; [(set (reg:CC CC_REG) 540;; (compare:CC (match_operand:SI 0 "register_operand" "") 541;; (match_operand:SI 1 "nonmemory_operand" "")))] 542;; "" 543;; { 544;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 545;; operands[0] = force_reg (SImode, operands[0]); 546;; or1k_compare_op0 = operands[0]; 547;; or1k_compare_op1 = operands[1]; 548;; DONE; 549;; }) 550 551;; (define_expand "cmpsf" 552;; [(set (reg:CC CC_REG) 553;; (compare:CC (match_operand:SF 0 "register_operand" "") 554;; (match_operand:SF 1 "register_operand" "")))] 555;; "TARGET_HARD_FLOAT" 556;; { 557;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 558;; operands[0] = force_reg (SFmode, operands[0]); 559;; or1k_compare_op0 = operands[0]; 560;; or1k_compare_op1 = operands[1]; 561;; DONE; 562;; }) 563 564(define_expand "cbranchsi4" 565 [(match_operator 0 "comparison_operator" 566 [(match_operand:SI 1 "register_operand") 567 (match_operand:SI 2 "nonmemory_operand")]) 568 (match_operand 3 "")] 569 "" 570 { 571 or1k_expand_conditional_branch (operands, SImode); 572 DONE; 573 }) 574 575(define_expand "cbranchsf4" 576 [(match_operator 0 "comparison_operator" 577 [(match_operand:SF 1 "register_operand") 578 (match_operand:SF 2 "register_operand")]) 579 (match_operand 3 "")] 580 "TARGET_HARD_FLOAT" 581 { 582 or1k_expand_conditional_branch (operands, SFmode); 583 DONE; 584 }) 585 586;; 587;; Setting a CCxx registers from comparision 588;; 589 590 591 592;; Here are the actual compare insns. 593(define_insn "*cmpsi_eq" 594 [(set (reg:CCEQ CC_REG) 595 (compare:CCEQ (match_operand:SI 0 "register_operand" "r,r") 596 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 597 "" 598 "@ 599 l.sfeqi\t%0,%1 # cmpsi_eq 600 l.sfeq \t%0,%1 # cmpsi_eq" 601 [(set_attr "type" "compare") 602 (set_attr "length" "1")]) 603 604(define_insn "*cmpsi_ne" 605 [(set (reg:CCNE CC_REG) 606 (compare:CCNE (match_operand:SI 0 "register_operand" "r,r") 607 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 608 "" 609 "@ 610 l.sfnei\t%0,%1 # cmpsi_ne 611 l.sfne \t%0,%1 # cmpsi_ne" 612 [(set_attr "type" "compare") 613 (set_attr "length" "1")]) 614 615(define_insn "*cmpsi_gt" 616 [(set (reg:CCGT CC_REG) 617 (compare:CCGT (match_operand:SI 0 "register_operand" "r,r") 618 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 619 "" 620 "@ 621 l.sfgtsi\t%0,%1 # cmpsi_gt 622 l.sfgts \t%0,%1 # cmpsi_gt" 623 [(set_attr "type" "compare") 624 (set_attr "length" "1")]) 625 626(define_insn "*cmpsi_gtu" 627 [(set (reg:CCGTU CC_REG) 628 (compare:CCGTU (match_operand:SI 0 "register_operand" "r,r") 629 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 630 "" 631 "@ 632 l.sfgtui\t%0,%1 # cmpsi_gtu 633 l.sfgtu \t%0,%1 # cmpsi_gtu" 634 [(set_attr "type" "compare") 635 (set_attr "length" "1")]) 636 637(define_insn "*cmpsi_lt" 638 [(set (reg:CCLT CC_REG) 639 (compare:CCLT (match_operand:SI 0 "register_operand" "r,r") 640 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 641 "" 642 "@ 643 l.sfltsi\t%0,%1 # cmpsi_lt 644 l.sflts \t%0,%1 # cmpsi_lt" 645 [(set_attr "type" "compare") 646 (set_attr "length" "1")]) 647 648(define_insn "*cmpsi_ltu" 649 [(set (reg:CCLTU CC_REG) 650 (compare:CCLTU (match_operand:SI 0 "register_operand" "r,r") 651 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 652 "" 653 "@ 654 l.sfltui\t%0,%1 # cmpsi_ltu 655 l.sfltu \t%0,%1 # cmpsi_ltu" 656 [(set_attr "type" "compare") 657 (set_attr "length" "1")]) 658 659(define_insn "*cmpsi_ge" 660 [(set (reg:CCGE CC_REG) 661 (compare:CCGE (match_operand:SI 0 "register_operand" "r,r") 662 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 663 "" 664 "@ 665 l.sfgesi\t%0,%1 # cmpsi_ge 666 l.sfges \t%0,%1 # cmpsi_ge" 667 [(set_attr "type" "compare") 668 (set_attr "length" "1")]) 669 670 671(define_insn "*cmpsi_geu" 672 [(set (reg:CCGEU CC_REG) 673 (compare:CCGEU (match_operand:SI 0 "register_operand" "r,r") 674 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 675 "" 676 "@ 677 l.sfgeui\t%0,%1 # cmpsi_geu 678 l.sfgeu \t%0,%1 # cmpsi_geu" 679 [(set_attr "type" "compare") 680 (set_attr "length" "1")]) 681 682 683(define_insn "*cmpsi_le" 684 [(set (reg:CCLE CC_REG) 685 (compare:CCLE (match_operand:SI 0 "register_operand" "r,r") 686 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 687 "" 688 "@ 689 l.sflesi\t%0,%1 # cmpsi_le 690 l.sfles \t%0,%1 # cmpsi_le" 691 [(set_attr "type" "compare") 692 (set_attr "length" "1")]) 693 694(define_insn "*cmpsi_leu" 695 [(set (reg:CCLEU CC_REG) 696 (compare:CCLEU (match_operand:SI 0 "register_operand" "r,r") 697 (match_operand:SI 1 "nonmemory_operand" "I,r")))] 698 "" 699 "@ 700 l.sfleui\t%0,%1 # cmpsi_leu 701 l.sfleu \t%0,%1 # cmpsi_leu" 702 [(set_attr "type" "compare") 703 (set_attr "length" "1")]) 704 705;; Single precision floating point evaluation instructions 706(define_insn "*cmpsf_eq" 707 [(set (reg:CCEQ CC_REG) 708 (compare:CCEQ (match_operand:SF 0 "register_operand" "r,r") 709 (match_operand:SF 1 "register_operand" "r,r")))] 710 "TARGET_HARD_FLOAT" 711 "lf.sfeq.s\t%0,%1 # cmpsf_eq" 712 [(set_attr "type" "compare") 713 (set_attr "length" "1")]) 714 715(define_insn "*cmpsf_ne" 716 [(set (reg:CCNE CC_REG) 717 (compare:CCNE (match_operand:SF 0 "register_operand" "r,r") 718 (match_operand:SF 1 "register_operand" "r,r")))] 719 "TARGET_HARD_FLOAT" 720 "lf.sfne.s\t%0,%1 # cmpsf_ne" 721 [(set_attr "type" "compare") 722 (set_attr "length" "1")]) 723 724 725(define_insn "*cmpsf_gt" 726 [(set (reg:CCGT CC_REG) 727 (compare:CCGT (match_operand:SF 0 "register_operand" "r,r") 728 (match_operand:SF 1 "register_operand" "r,r")))] 729 "TARGET_HARD_FLOAT" 730 "lf.sfgt.s\t%0,%1 # cmpsf_gt" 731 [(set_attr "type" "compare") 732 (set_attr "length" "1")]) 733 734(define_insn "*cmpsf_ge" 735 [(set (reg:CCGE CC_REG) 736 (compare:CCGE (match_operand:SF 0 "register_operand" "r,r") 737 (match_operand:SF 1 "register_operand" "r,r")))] 738 "TARGET_HARD_FLOAT" 739 "lf.sfge.s\t%0,%1 # cmpsf_ge" 740 [(set_attr "type" "compare") 741 (set_attr "length" "1")]) 742 743 744(define_insn "*cmpsf_lt" 745 [(set (reg:CCLT CC_REG) 746 (compare:CCLT (match_operand:SF 0 "register_operand" "r,r") 747 (match_operand:SF 1 "register_operand" "r,r")))] 748 "TARGET_HARD_FLOAT" 749 "lf.sflt.s\t%0,%1 # cmpsf_lt" 750 [(set_attr "type" "compare") 751 (set_attr "length" "1")]) 752 753(define_insn "*cmpsf_le" 754 [(set (reg:CCLE CC_REG) 755 (compare:CCLE (match_operand:SF 0 "register_operand" "r,r") 756 (match_operand:SF 1 "register_operand" "r,r")))] 757 "TARGET_HARD_FLOAT" 758 "lf.sfle.s\t%0,%1 # cmpsf_le" 759 [(set_attr "type" "compare") 760 (set_attr "length" "1")]) 761 762(define_insn "*bf" 763 [(set (pc) 764 (if_then_else (match_operator 1 "comparison_operator" 765 [(match_operand 2 766 "cc_reg_operand" "") 767 (const_int 0)]) 768 (label_ref (match_operand 0 "" "")) 769 (pc)))] 770 "" 771 "* 772 return or1k_output_bf(operands); 773 " 774 [(set_attr "type" "branch") 775 (set_attr "length" "1")]) 776 777;; 778;; 779;; 780;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 781;; 782;; 783(define_insn_and_split "movdi" 784 [(set (match_operand:DI 0 "nonimmediate_operand" "=r, r, m, r") 785 (match_operand:DI 1 "general_operand" " r, m, r, n"))] 786 "" 787 "* 788 return or1k_output_move_double (operands); 789 " 790 "&& reload_completed && CONSTANT_P (operands[1])" 791 [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] 792 "operands[2] = operand_subword (operands[0], 0, 0, DImode); 793 operands[3] = operand_subword (operands[1], 0, 0, DImode); 794 operands[4] = operand_subword (operands[0], 1, 0, DImode); 795 operands[5] = operand_subword (operands[1], 1, 0, DImode);" 796 [(set_attr "length" "2,2,2,3")]) 797 798;; Moving double and single precision floating point values 799 800 801(define_insn "movdf" 802 [(set (match_operand:DF 0 "nonimmediate_operand" "=r, r, m, r") 803 (match_operand:DF 1 "general_operand" " r, m, r, i"))] 804 "" 805 "* 806 return or1k_output_move_double (operands); 807 " 808 [(set_attr "length" "2,2,2,3")]) 809 810 811(define_insn "movsf" 812 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 813 (match_operand:SF 1 "general_operand" "r,m,r"))] 814 "" 815 "@ 816 l.ori \t%0,%1,0\t # movsf 817 l.lwz \t%0,%1\t # movsf 818 l.sw \t%0,%1\t # movsf" 819 [(set_attr "type" "move,load,store") 820 (set_attr "length" "1,1,1")]) 821 822 823;; 824;; extendqisi2 825;; 826 827(define_expand "extendqisi2" 828 [(use (match_operand:SI 0 "register_operand" "")) 829 (use (match_operand:QI 1 "nonimmediate_operand" ""))] 830 "" 831 " 832{ 833 if (TARGET_MASK_SEXT) 834 emit_insn (gen_extendqisi2_sext(operands[0], operands[1])); 835 else { 836 if ( GET_CODE(operands[1]) == MEM ) { 837 emit_insn (gen_extendqisi2_no_sext_mem(operands[0], operands[1])); 838 } 839 else { 840 emit_insn (gen_extendqisi2_no_sext_reg(operands[0], operands[1])); 841 } 842 } 843 DONE; 844}") 845 846(define_insn "extendqisi2_sext" 847 [(set (match_operand:SI 0 "register_operand" "=r,r") 848 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 849 "TARGET_MASK_SEXT" 850 "@ 851 l.extbs \t%0,%1\t # extendqisi2_has_signed_extend 852 l.lbs \t%0,%1\t # extendqisi2_has_signed_extend" 853 [(set_attr "length" "1,1") 854 (set_attr "type" "extend,load")]) 855 856(define_insn "extendqisi2_no_sext_mem" 857 [(set (match_operand:SI 0 "register_operand" "=r") 858 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 859 "!TARGET_MASK_SEXT" 860 "l.lbs \t%0,%1\t # extendqisi2_no_sext_mem" 861 [(set_attr "length" "1") 862 (set_attr "type" "load")]) 863 864(define_expand "extendqisi2_no_sext_reg" 865 [(set (match_dup 2) 866 (ashift:SI (match_operand:QI 1 "register_operand" "") 867 (const_int 24))) 868 (set (match_operand:SI 0 "register_operand" "") 869 (ashiftrt:SI (match_dup 2) 870 (const_int 24)))] 871 "!TARGET_MASK_SEXT" 872 " 873{ 874 operands[1] = gen_lowpart (SImode, operands[1]); 875 operands[2] = gen_reg_rtx (SImode); }") 876 877;; 878;; extendhisi2 879;; 880 881(define_expand "extendhisi2" 882 [(use (match_operand:SI 0 "register_operand" "")) 883 (use (match_operand:HI 1 "nonimmediate_operand" ""))] 884 "" 885 " 886{ 887 if (TARGET_MASK_SEXT) 888 emit_insn (gen_extendhisi2_sext(operands[0], operands[1])); 889 else { 890 if ( GET_CODE(operands[1]) == MEM ) { 891 emit_insn (gen_extendhisi2_no_sext_mem(operands[0], operands[1])); 892 } 893 else { 894 emit_insn (gen_extendhisi2_no_sext_reg(operands[0], operands[1])); 895 } 896 } 897 DONE; 898}") 899 900(define_insn "extendhisi2_sext" 901 [(set (match_operand:SI 0 "register_operand" "=r,r") 902 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 903 "TARGET_MASK_SEXT" 904 "@ 905 l.exths \t%0,%1\t # extendhisi2_has_signed_extend 906 l.lhs \t%0,%1\t # extendhisi2_has_signed_extend" 907 [(set_attr "length" "1,1") 908 (set_attr "type" "extend,load")]) 909 910(define_insn "extendhisi2_no_sext_mem" 911 [(set (match_operand:SI 0 "register_operand" "=r") 912 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 913 "!TARGET_MASK_SEXT" 914 "l.lhs \t%0,%1\t # extendhisi2_no_sext_mem" 915 [(set_attr "length" "1") 916 (set_attr "type" "load")]) 917 918(define_expand "extendhisi2_no_sext_reg" 919 [(set (match_dup 2) 920 (ashift:SI (match_operand:HI 1 "register_operand" "") 921 (const_int 16))) 922 (set (match_operand:SI 0 "register_operand" "") 923 (ashiftrt:SI (match_dup 2) 924 (const_int 16)))] 925 "!TARGET_MASK_SEXT" 926 " 927{ 928 operands[1] = gen_lowpart (SImode, operands[1]); 929 operands[2] = gen_reg_rtx (SImode); }") 930 931 932;; 933;; zero_extend<m><n>2 934;; 935 936(define_insn "zero_extendqisi2" 937 [(set (match_operand:SI 0 "register_operand" "=r,r") 938 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 939 "" 940 "@ 941 l.andi \t%0,%1,0xff\t # zero_extendqisi2 942 l.lbz \t%0,%1\t # zero_extendqisi2" 943 [(set_attr "type" "logic,load") 944 (set_attr "length" "1,1")]) 945 946 947(define_insn "zero_extendhisi2" 948 [(set (match_operand:SI 0 "register_operand" "=r,r") 949 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 950 "" 951 "@ 952 l.andi \t%0,%1,0xffff\t # zero_extendqisi2 953 l.lhz \t%0,%1\t # zero_extendqisi2" 954 [(set_attr "type" "logic,load") 955 (set_attr "length" "1,1")]) 956 957;; 958;; Shift/rotate operations 959;; 960 961(define_insn "ashlsi3" 962 [(set (match_operand:SI 0 "register_operand" "=r,r") 963 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 964 (match_operand:SI 2 "nonmemory_operand" "r,L")))] 965 "" 966 "@ 967 l.sll \t%0,%1,%2 # ashlsi3 968 l.slli \t%0,%1,%2 # ashlsi3" 969 [(set_attr "type" "shift,shift") 970 (set_attr "length" "1,1")]) 971 972(define_insn "ashrsi3" 973 [(set (match_operand:SI 0 "register_operand" "=r,r") 974 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 975 (match_operand:SI 2 "nonmemory_operand" "r,L")))] 976 "" 977 "@ 978 l.sra \t%0,%1,%2 # ashrsi3 979 l.srai \t%0,%1,%2 # ashrsi3" 980 [(set_attr "type" "shift,shift") 981 (set_attr "length" "1,1")]) 982 983(define_insn "lshrsi3" 984 [(set (match_operand:SI 0 "register_operand" "=r,r") 985 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 986 (match_operand:SI 2 "nonmemory_operand" "r,L")))] 987 "" 988 "@ 989 l.srl \t%0,%1,%2 # lshrsi3 990 l.srli \t%0,%1,%2 # lshrsi3" 991 [(set_attr "type" "shift,shift") 992 (set_attr "length" "1,1")]) 993 994(define_insn "rotrsi3" 995 [(set (match_operand:SI 0 "register_operand" "=r,r") 996 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") 997 (match_operand:SI 2 "nonmemory_operand" "r,L")))] 998 "TARGET_MASK_ROR" 999 "@ 1000 l.ror \t%0,%1,%2 # rotrsi3 1001 l.rori \t%0,%1,%2 # rotrsi3" 1002 [(set_attr "type" "shift,shift") 1003 (set_attr "length" "1,1")]) 1004 1005;; 1006;; Logical bitwise operations 1007;; 1008 1009(define_insn "andsi3" 1010 [(set (match_operand:SI 0 "register_operand" "=r,r") 1011 (and:SI (match_operand:SI 1 "register_operand" "%r,r") 1012 (match_operand:SI 2 "nonmemory_operand" "r,K")))] 1013 "" 1014 "@ 1015 l.and \t%0,%1,%2 # andsi3 1016 l.andi \t%0,%1,%2 # andsi3" 1017 [(set_attr "type" "logic,logic") 1018 (set_attr "length" "1,1")]) 1019 1020(define_insn "iorsi3" 1021 [(set (match_operand:SI 0 "register_operand" "=r,r") 1022 (ior:SI (match_operand:SI 1 "register_operand" "%r,r") 1023 (match_operand:SI 2 "nonmemory_operand" "r,K")))] 1024 "" 1025 "@ 1026 l.or \t%0,%1,%2 # iorsi3 1027 l.ori \t%0,%1,%2 # iorsi3" 1028 [(set_attr "type" "logic,logic") 1029 (set_attr "length" "1,1")]) 1030 1031(define_insn "xorsi3" 1032 [(set (match_operand:SI 0 "register_operand" "=r,r") 1033 (xor:SI (match_operand:SI 1 "register_operand" "%r,r") 1034 (match_operand:SI 2 "nonmemory_operand" "r,I")))] 1035 "" 1036 "@ 1037 l.xor \t%0,%1,%2 # xorsi3 1038 l.xori \t%0,%1,%2 # xorsi3" 1039 [(set_attr "type" "logic,logic") 1040 (set_attr "length" "1,1")]) 1041 1042(define_insn "one_cmplqi2" 1043 [(set (match_operand:QI 0 "register_operand" "=r") 1044 (not:QI (match_operand:QI 1 "register_operand" "r")))] 1045 "" 1046 "l.xori \t%0,%1,0x00ff # one_cmplqi2" 1047 [(set_attr "type" "logic") 1048 (set_attr "length" "1")]) 1049 1050(define_insn "one_cmplsi2" 1051 [(set (match_operand:SI 0 "register_operand" "=r") 1052 (not:SI (match_operand:SI 1 "register_operand" "r")))] 1053 "" 1054 "l.xori \t%0,%1,0xffff # one_cmplsi2" 1055 [(set_attr "type" "logic") 1056 (set_attr "length" "1")]) 1057 1058;; 1059;; Arithmetic operations 1060;; 1061 1062(define_insn "negsi2" 1063 [(set (match_operand:SI 0 "register_operand" "=r") 1064 (neg:SI (match_operand:SI 1 "register_operand" "r")))] 1065 "" 1066 "l.sub \t%0,r0,%1 # negsi2" 1067 [(set_attr "type" "add") 1068 (set_attr "length" "1")]) 1069 1070(define_insn "addsi3" 1071 [(set (match_operand:SI 0 "register_operand" "=r,r") 1072 (plus:SI (match_operand:SI 1 "register_operand" "%r,r") 1073 (match_operand:SI 2 "nonmemory_operand" "r,I")))] 1074 "" 1075 "@ 1076 l.add \t%0,%1,%2 # addsi3 1077 l.addi \t%0,%1,%2 # addsi3" 1078 [(set_attr "type" "add,add") 1079 (set_attr "length" "1,1")]) 1080 1081(define_insn "subsi3" 1082 [(set (match_operand:SI 0 "register_operand" "=r,r") 1083 (minus:SI (match_operand:SI 1 "register_operand" "r,r") 1084 (match_operand:SI 2 "nonmemory_operand" "r,I")))] 1085 "" 1086 "@ 1087 l.sub \t%0,%1,%2 # subsi3 1088 l.addi \t%0,%1,%n2 # subsi3" 1089 [(set_attr "type" "add,add")] 1090) 1091 1092;; 1093;; mul and div 1094;; 1095 1096(define_insn "mulsi3" 1097 [(set (match_operand:SI 0 "register_operand" "=r") 1098 (mult:SI (match_operand:SI 1 "register_operand" "r") 1099 (match_operand:SI 2 "register_operand" "r")))] 1100 "TARGET_HARD_MUL" 1101 "l.mul \t%0,%1,%2 # mulsi3" 1102 [(set_attr "type" "mul") 1103 (set_attr "length" "1")]) 1104 1105(define_insn "divsi3" 1106 [(set (match_operand:SI 0 "register_operand" "=r") 1107 (div:SI (match_operand:SI 1 "register_operand" "r") 1108 (match_operand:SI 2 "register_operand" "r")))] 1109 "TARGET_HARD_DIV" 1110 "l.div \t%0,%1,%2 # divsi3" 1111 [(set_attr "type" "mul") 1112 (set_attr "length" "1")]) 1113 1114(define_insn "udivsi3" 1115 [(set (match_operand:SI 0 "register_operand" "=r") 1116 (udiv:SI (match_operand:SI 1 "register_operand" "r") 1117 (match_operand:SI 2 "register_operand" "r")))] 1118 "TARGET_HARD_DIV" 1119 "l.divu \t%0,%1,%2 # udivsi3" 1120 [(set_attr "type" "mul") 1121 (set_attr "length" "1")]) 1122 1123;; 1124;; jumps 1125;; 1126 1127;; jump 1128 1129(define_expand "jump" 1130 [(set (pc) 1131 (label_ref (match_operand 0 "" "")))] 1132 "" 1133 " 1134{ 1135 emit_jump_insn (gen_jump_internal (operands[0])); 1136 DONE; 1137}") 1138 1139(define_insn "jump_internal" 1140 [(set (pc) 1141 (label_ref (match_operand 0 "" "")))] 1142 "" 1143 "l.j \t%l0 # jump_internal%(" 1144 [(set_attr "type" "jump") 1145 (set_attr "length" "1")]) 1146 1147;; indirect jump 1148 1149(define_expand "indirect_jump" 1150 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1151 "" 1152 " 1153{ 1154 emit_jump_insn (gen_indirect_jump_internal (operands[0])); 1155 DONE; 1156 1157}") 1158 1159(define_insn "indirect_jump_internal" 1160 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 1161 "" 1162 "l.jr \t%0 # indirect_jump_internal%(" 1163 [(set_attr "type" "jump") 1164 (set_attr "length" "1")]) 1165 1166;; 1167;; calls 1168;; 1169 1170;; call 1171 1172(define_expand "call" 1173 [(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "") 1174 (match_operand 1 "" "i")) 1175 (clobber (reg:SI 9)) 1176 (use (reg:SI 16))])] 1177 "" 1178 " 1179{ 1180 emit_call_insn (gen_call_internal (operands[0], operands[1])); 1181 DONE; 1182}") 1183 1184(define_insn "call_internal" 1185[(parallel [(call (match_operand:SI 0 "sym_ref_mem_operand" "") 1186 (match_operand 1 "" "i")) 1187 (clobber (reg:SI 9)) 1188 (use (reg:SI 16))])] 1189 "" 1190 { 1191 if (flag_pic) 1192 { 1193 crtl->uses_pic_offset_table = 1; 1194 return "l.jal \tplt(%S0)# call_internal%("; 1195 } 1196 1197 return "l.jal \t%S0# call_internal%("; 1198 } 1199 [(set_attr "type" "jump") 1200 (set_attr "length" "1")]) 1201 1202;; call value 1203 1204(define_expand "call_value" 1205 [(parallel [(set (match_operand 0 "register_operand" "=r") 1206 (call (match_operand:SI 1 "sym_ref_mem_operand" "") 1207 (match_operand 2 "" "i"))) 1208 (clobber (reg:SI 9)) 1209 (use (reg:SI 16))])] 1210 "" 1211 " 1212{ 1213 emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2])); 1214 DONE; 1215}") 1216 1217(define_insn "call_value_internal" 1218[(parallel [(set (match_operand 0 "register_operand" "=r") 1219 (call (match_operand:SI 1 "sym_ref_mem_operand" "") 1220 (match_operand 2 "" "i"))) 1221 (clobber (reg:SI 9)) 1222 (use (reg:SI 16))])] 1223 "" 1224 { 1225 if (flag_pic) 1226 { 1227 crtl->uses_pic_offset_table = 1; 1228 return "l.jal \tplt(%S1) # call_value_internal%("; 1229 } 1230 return "l.jal \t%S1 # call_value_internal%("; 1231 } 1232 [(set_attr "type" "jump") 1233 (set_attr "length" "1")]) 1234 1235;; indirect call value 1236 1237(define_expand "call_value_indirect" 1238 [(parallel [(set (match_operand 0 "register_operand" "=r") 1239 (call (mem:SI (match_operand:SI 1 "register_operand" "r")) 1240 (match_operand 2 "" "i"))) 1241 (clobber (reg:SI 9)) 1242 (use (reg:SI 16))])] 1243 "" 1244 " 1245{ 1246 emit_call_insn (gen_call_value_indirect_internal (operands[0], operands[1], operands[2])); 1247 DONE; 1248}") 1249 1250(define_insn "call_value_indirect_internal" 1251 [(parallel [(set (match_operand 0 "register_operand" "=r") 1252 (call (mem:SI (match_operand:SI 1 "register_operand" "r")) 1253 (match_operand 2 "" "i"))) 1254 (clobber (reg:SI 9)) 1255 (use (reg:SI 16))])] 1256 "" 1257 "l.jalr \t%1 # call_value_indirect_internal%(" 1258 [(set_attr "type" "jump") 1259 (set_attr "length" "1")]) 1260 1261;; indirect call 1262 1263(define_expand "call_indirect" 1264 [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) 1265 (match_operand 1 "" "i")) 1266 (clobber (reg:SI 9)) 1267 (use (reg:SI 16))])] 1268 "" 1269 " 1270{ 1271 emit_call_insn (gen_call_indirect_internal (operands[0], operands[1])); 1272 DONE; 1273}") 1274 1275(define_insn "call_indirect_internal" 1276[(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) 1277 (match_operand 1 "" "i")) 1278 (clobber (reg:SI 9)) 1279 (use (reg:SI 16))])] 1280 "" 1281 "l.jalr \t%0 # call_indirect_internal%(" 1282 [(set_attr "type" "jump") 1283 (set_attr "length" "1")]) 1284 1285;; table jump 1286 1287(define_expand "tablejump" 1288 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 1289 (use (label_ref (match_operand 1 "" "")))] 1290 "" 1291 " 1292{ 1293 if (CASE_VECTOR_PC_RELATIVE || flag_pic) 1294 operands[0] 1295 = force_reg (Pmode, 1296 gen_rtx_PLUS (Pmode, operands[0], 1297 gen_rtx_LABEL_REF (Pmode, operands[1]))); 1298 emit_jump_insn (gen_tablejump_internal (operands[0], operands[1])); 1299 DONE; 1300}") 1301 1302(define_insn "tablejump_internal" 1303 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 1304 (use (label_ref (match_operand 1 "" "")))] 1305 "" 1306 "l.jr \t%0 # tablejump_internal%(" 1307 [(set_attr "type" "jump") 1308 (set_attr "length" "1")]) 1309 1310 1311;; no-op 1312 1313(define_insn "nop" 1314 [(const_int 0)] 1315 "" 1316 "l.nop" 1317 [(set_attr "type" "logic") 1318 (set_attr "length" "1")]) 1319 1320;; 1321;; floating point 1322;; 1323 1324;; floating point arithmetic 1325 1326(define_insn "addsf3" 1327 [(set (match_operand:SF 0 "register_operand" "=r") 1328 (plus:SF (match_operand:SF 1 "register_operand" "r") 1329 (match_operand:SF 2 "register_operand" "r")))] 1330 "TARGET_HARD_FLOAT" 1331 "lf.add.s\t%0,%1,%2 # addsf3" 1332 [(set_attr "type" "fp") 1333 (set_attr "length" "1")]) 1334 1335(define_insn "adddf3" 1336 [(set (match_operand:DF 0 "register_operand" "=r") 1337 (plus:DF (match_operand:DF 1 "register_operand" "r") 1338 (match_operand:DF 2 "register_operand" "r")))] 1339 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 1340 "lf.add.d\t%0,%1,%2 # adddf3" 1341 [(set_attr "type" "fp") 1342 (set_attr "length" "1")]) 1343 1344(define_insn "subsf3" 1345 [(set (match_operand:SF 0 "register_operand" "=r") 1346 (minus:SF (match_operand:SF 1 "register_operand" "r") 1347 (match_operand:SF 2 "register_operand" "r")))] 1348 "TARGET_HARD_FLOAT" 1349 "lf.sub.s\t%0,%1,%2 # subsf3" 1350 [(set_attr "type" "fp") 1351 (set_attr "length" "1")]) 1352 1353(define_insn "subdf3" 1354 [(set (match_operand:DF 0 "register_operand" "=r") 1355 (minus:DF (match_operand:DF 1 "register_operand" "r") 1356 (match_operand:DF 2 "register_operand" "r")))] 1357 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 1358 "lf.sub.d\t%0,%1,%2 # subdf3" 1359 [(set_attr "type" "fp") 1360 (set_attr "length" "1")]) 1361 1362(define_insn "mulsf3" 1363 [(set (match_operand:SF 0 "register_operand" "=r") 1364 (mult:SF (match_operand:SF 1 "register_operand" "r") 1365 (match_operand:SF 2 "register_operand" "r")))] 1366 "TARGET_HARD_FLOAT" 1367 "lf.mul.s\t%0,%1,%2 # mulsf3" 1368 [(set_attr "type" "fp") 1369 (set_attr "length" "1")]) 1370 1371(define_insn "muldf3" 1372 [(set (match_operand:DF 0 "register_operand" "=r") 1373 (mult:DF (match_operand:DF 1 "register_operand" "r") 1374 (match_operand:DF 2 "register_operand" "r")))] 1375 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 1376 "lf.mul.d\t%0,%1,%2 # muldf3" 1377 [(set_attr "type" "fp") 1378 (set_attr "length" "1")]) 1379 1380(define_insn "divsf3" 1381 [(set (match_operand:SF 0 "register_operand" "=r") 1382 (div:SF (match_operand:SF 1 "register_operand" "r") 1383 (match_operand:SF 2 "register_operand" "r")))] 1384 "TARGET_HARD_FLOAT" 1385 "lf.div.s\t%0,%1,%2 # divsf3" 1386 [(set_attr "type" "fp") 1387 (set_attr "length" "1")]) 1388 1389(define_insn "divdf3" 1390 [(set (match_operand:DF 0 "register_operand" "=r") 1391 (div:DF (match_operand:DF 1 "register_operand" "r") 1392 (match_operand:DF 2 "register_operand" "r")))] 1393 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 1394 "lf.div.d\t%0,%1,%2 # divdf3" 1395 [(set_attr "type" "fp") 1396 (set_attr "length" "1")]) 1397 1398;; Conversion between fixed point and floating point. 1399 1400 1401(define_insn "floatsisf2" 1402 [(set (match_operand:SF 0 "register_operand" "=r") 1403 (float:SF (match_operand:SI 1 "register_operand" "r")))] 1404 "TARGET_HARD_FLOAT" 1405 "lf.itof.s\t%0, %1 # floatsisf2" 1406 [(set_attr "type" "fp") 1407 (set_attr "length" "1")]) 1408 1409;; not working 1410(define_insn "fixunssfsi2" 1411 [(set (match_operand:SI 0 "register_operand" "=r") 1412 (fix:SI (match_operand:SF 1 "register_operand" "r")))] 1413 "TARGET_HARD_FLOAT" 1414 "lf.ftoi.s\t%0, %1 # fixunssfsi2" 1415 [(set_attr "type" "fp") 1416 (set_attr "length" "1")]) 1417 1418;; The insn to set GOT. 1419;; TODO: support for no-delay target 1420(define_insn "set_got" 1421 [(set (match_operand:SI 0 "register_operand" "=r") 1422 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 1423 (clobber (reg:SI 9)) 1424 (clobber (reg:SI 16))] 1425 "" 1426 "l.jal \t8 1427 \tl.movhi \tr16,gotpchi(_GLOBAL_OFFSET_TABLE_-4) 1428 \tl.ori \tr16,r16,gotpclo(_GLOBAL_OFFSET_TABLE_+0) 1429 \tl.add \tr16,r16,r9" 1430 [(set_attr "length" "16")]) 1431 1432(define_expand "atomic_compare_and_swap<mode>" 1433 [(match_operand:SI 0 "register_operand") ;; bool output 1434 (match_operand:AI 1 "register_operand") ;; val output 1435 (match_operand:AI 2 "memory_operand") ;; memory 1436 (match_operand:AI 3 "register_operand") ;; expected 1437 (match_operand:AI 4 "register_operand") ;; desired 1438 (match_operand:SI 5 "const_int_operand") ;; is_weak 1439 (match_operand:SI 6 "const_int_operand") ;; mod_s 1440 (match_operand:SI 7 "const_int_operand")] ;; mod_f 1441 "0" 1442{ 1443 if (<MODE>mode == SImode) 1444 emit_insn (gen_cmpxchg (operands[0], operands[1], operands[2], operands[3], 1445 operands[4])); 1446 else 1447 or1k_expand_cmpxchg_qihi (operands[0], operands[1], operands[2], 1448 operands[3], operands[4], INTVAL (operands[5]), 1449 (enum memmodel) INTVAL (operands[6]), 1450 (enum memmodel) INTVAL (operands[7])); 1451 DONE; 1452}) 1453 1454(define_insn "cmpxchg" 1455 [(set (match_operand:SI 0 "register_operand" "=&r") 1456 (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")] 1457 UNSPEC_CMPXCHG)) 1458 (set (match_dup 2) 1459 (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")] 1460 UNSPEC_CMPXCHG)) 1461 (set (match_operand:SI 1 "register_operand" "=&r") 1462 (unspec_volatile:SI [(match_dup 2) (match_dup 3) 1463 (match_operand:SI 4 "register_operand" "r")] 1464 UNSPEC_CMPXCHG))] 1465 "" 1466 " 1467 l.lwa \t%1,%2 # cmpxchg: load 1468 l.sfeq \t%1,%3 # cmpxchg: cmp 1469 l.bnf \t1f # cmpxchg: not expected 1470 l.ori \t%0,r0,0 # cmpxchg: result = 0 1471 l.swa \t%2,%4 # cmpxchg: store new 1472 l.bnf \t1f # cmpxchg: done 1473 l.nop 1474 l.ori \t%0,r0,1 # cmpxchg: result = 1 14751:") 1476 1477(define_insn "cmpxchg_mask" 1478 [(set (match_operand:SI 0 "register_operand" "=&r") 1479 (unspec_volatile:SI [(match_operand:SI 2 "memory_operand" "+m")] 1480 UNSPEC_CMPXCHG)) 1481 (set (match_dup 2) 1482 (unspec_volatile:SI [(match_operand:SI 3 "register_operand" "r")] 1483 UNSPEC_CMPXCHG)) 1484 (set (match_operand:SI 1 "register_operand" "=&r") 1485 (unspec_volatile:SI [(match_dup 2) (match_dup 3) 1486 (match_operand:SI 4 "register_operand" "r") 1487 (match_operand:SI 5 "register_operand" "r")] 1488 UNSPEC_CMPXCHG)) 1489 (clobber (match_scratch:SI 6 "=&r"))] 1490 "" 1491 " 1492 l.lwa \t%6,%2 # cmpxchg: load 1493 l.and \t%1,%6,%5 # cmpxchg: mask 1494 l.sfeq \t%1,%3 # cmpxchg: cmp 1495 l.bnf \t1f # cmpxchg: not expected 1496 l.ori \t%0,r0,0 # cmpxchg: result = 0 1497 l.xor \t%6,%6,%1 # cmpxchg: clear 1498 l.or \t%6,%6,%4 # cmpxchg: set 1499 l.swa \t%2,%6 # cmpxchg: store new 1500 l.bnf \t1f # cmpxchg: done 1501 l.nop 1502 l.ori \t%0,r0,1 # cmpxchg: result = 1 15031: 1504 ") 1505 1506(define_expand "atomic_fetch_<op_name><mode>" 1507 [(match_operand:AI 0 "register_operand") 1508 (match_operand:AI 1 "memory_operand") 1509 (match_operand:AI 2 "register_operand") 1510 (match_operand:SI 3 "const_int_operand") 1511 (atomic_op:AI (match_dup 0) (match_dup 1))] 1512 "" 1513{ 1514 rtx ret = gen_reg_rtx (<MODE>mode); 1515 if (<MODE>mode != SImode) 1516 or1k_expand_fetch_op_qihi (operands[0], operands[1], operands[2], ret, 1517 gen_fetch_and_<op_name>_mask); 1518 else 1519 emit_insn (gen_fetch_and_<op_name> (operands[0], operands[1], operands[2], 1520 ret)); 1521 DONE; 1522}) 1523 1524(define_expand "atomic_<op_name>_fetch<mode>" 1525 [(match_operand:AI 0 "register_operand") 1526 (match_operand:AI 1 "memory_operand") 1527 (match_operand:AI 2 "register_operand") 1528 (match_operand:SI 3 "const_int_operand") 1529 (atomic_op:AI (match_dup 0) (match_dup 1))] 1530 "" 1531{ 1532 rtx ret = gen_reg_rtx (<MODE>mode); 1533 if (<MODE>mode != SImode) 1534 or1k_expand_fetch_op_qihi (ret, operands[1], operands[2], operands[0], 1535 gen_fetch_and_<op_name>_mask); 1536 else 1537 emit_insn (gen_fetch_and_<op_name> (ret, operands[1], operands[2], 1538 operands[0])); 1539 DONE; 1540}) 1541 1542(define_insn "fetch_and_<op_name>" 1543 [(set (match_operand:SI 0 "register_operand" "=&r") 1544 (match_operand:SI 1 "memory_operand" "+m")) 1545 (set (match_operand:SI 3 "register_operand" "=&r") 1546 (unspec_volatile:SI [(match_dup 1) 1547 (match_operand:SI 2 "register_operand" "r")] 1548 UNSPEC_FETCH_AND_OP)) 1549 (set (match_dup 1) 1550 (match_dup 3)) 1551 (atomic_op:SI (match_dup 0) (match_dup 1))] 1552 "" 1553 " 15541: 1555 l.lwa \t%0,%1 # fetch_<op_name>: load 1556 l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic 1557 <post_op_insn> 1558 l.swa \t%1,%3 # fetch_<op_name>: store new 1559 l.bnf \t1b # fetch_<op_name>: done 1560 l.nop 1561 ") 1562 1563(define_insn "fetch_and_<op_name>_mask" 1564 [(set (match_operand:SI 0 "register_operand" "=&r") 1565 (match_operand:SI 1 "memory_operand" "+m")) 1566 (set (match_operand:SI 3 "register_operand" "=&r") 1567 (unspec_volatile:SI [(match_dup 1) 1568 (match_operand:SI 2 "register_operand" "r") 1569 (match_operand:SI 4 "register_operand" "r")] 1570 UNSPEC_FETCH_AND_OP)) 1571 (set (match_dup 1) 1572 (unspec_volatile:SI [(match_dup 3) (match_dup 4)] UNSPEC_FETCH_AND_OP)) 1573 (clobber (match_scratch:SI 5 "=&r")) 1574 (atomic_op:SI (match_dup 0) (match_dup 1))] 1575 "" 1576 " 15771: 1578 l.lwa \t%0,%1 # fetch_<op_name>: load 1579 l.and \t%5,%0,%4 # fetch_<op_name>: mask 1580 l.xor \t%5,%0,%5 # fetch_<op_name>: clear 1581 l.<op_insn>\t\t%3,%0,%2 # fetch_<op_name>: logic 1582 <post_op_insn> 1583 l.and \t%3,%3,%4 # fetch_<op_name>: mask result 1584 l.or \t%3,%5,%3 # fetch_<op_name>: set 1585 l.swa \t%1,%3 # fetch_<op_name>: store new 1586 l.bnf \t1b # fetch_<op_name>: done 1587 l.nop 1588 ") 1589 1590;; Local variables: 1591;; mode:emacs-lisp 1592;; comment-start: ";; " 1593;; eval: (set-syntax-table (copy-sequence (syntax-table))) 1594;; eval: (modify-syntax-entry ?[ "(]") 1595;; eval: (modify-syntax-entry ?] ")[") 1596;; eval: (modify-syntax-entry ?{ "(}") 1597;; eval: (modify-syntax-entry ?} "){") 1598;; eval: (setq indent-tabs-mode t) 1599;; End: 1600