1;; Machine description for C-SKY processors. 2;; Copyright (C) 2018-2021 Free Software Foundation, Inc. 3;; Contributed by C-SKY Microsystems and Mentor Graphics. 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 by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but 13;; WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15;; General Public License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. */ 20 21 22;; ------------------------------------------------------------------------ 23;; Constant 24;; ------------------------------------------------------------------------ 25 26;; Register numbering. 27 28(define_constants 29 [(CSKY_NGPR_REGS 32) 30 (CSKY_NPARM_REGS 4) 31 (CSKY_FIRST_PARM_REGNUM 0) 32 (CSKY_FIRST_RET_REGNUM 0) 33 (CSKY_FIRST_VFP_REGNUM 52) 34 (CSKY_LAST_VFP_REGNUM 67) 35 (CSKY_FIRST_HIGH_REGNUM 16) 36 (CSKY_LAST_HIGH_REGNUM 31) 37 (CSKY_FIRST_MINI_REGNUM 0) 38 (CSKY_LAST_MINI_REGNUM 7) 39 (CSKY_T0_REGNUM 12) 40 (CSKY_T1_REGNUM 13) 41 (CSKY_SP_REGNUM 14) 42 (CSKY_CC_REGNUM 33) 43 (CSKY_HI_REGNUM 34) 44 (CSKY_LO_REGNUM 35) 45 (CSKY_LR_REGNUM 15) 46 (CSKY_LAST_HIGH_UNFIXED_REGNUM 25) 47 (CSKY_GB_REGNUM 28) 48 (CSKY_TLS_REGNUM 31) 49 (CSKY_FIRST_EH_RETDATA_REGNUM 0) 50 (CSKY_LAST_EH_RETDATA_REGNUM 1) 51 (CSKY_EH_STACKADJ_REGNUM 2) 52 (CSKY_STACKADJUST_REGNUM 4) 53 (CSKY_NPARM_FREGS 4) 54]) 55 56;; Supported TLS relocations. 57 58(define_constants 59 [(TLS_GD32 0) 60 (TLS_LDM32 1) 61 (TLS_LDO32 2) 62 (TLS_IE32 3) 63 (TLS_LE32 4) 64]) 65 66;; Unspec constants. 67 68(define_c_enum "unspec" 69 [ 70 ; Push or pop multiple operation: operand 0 is the first register, 71 ; subsequent registers are in parallel (use ...) expressions. 72 UNSPEC_PUSHPOP_MULT 73 74 ; Represent TLS base, TLS offset, and TLS base + offset, respectively. 75 UNSPEC_TLS_BASE 76 UNSPEC_TLS_LABEL 77 UNSPEC_TLS 78 79 ; PIC symbol relocations. 80 UNSPEC_PIC_SYMBOL_GOTPC 81 UNSPEC_PIC_SYMBOL_GOTPC_GRS 82 UNSPEC_PIC_SYMBOL_GOTOFF 83 UNSPEC_PIC_SYMBOL_GOT 84 UNSPEC_PIC_SYMBOL_PLT 85 UNSPEC_PIC_SYMBOL_BSR 86 UNSPEC_PIC_SYMBOL_GRS 87 88 ; casesi dispatch table. 89 UNSPEC_CSKY_CASESI 90 ]) 91 92 93(define_c_enum "unspecv" 94 [ 95 ; Used for constant pools. 96 VUNSPEC_ALIGN 97 VUNSPEC_POOL_LABEL 98 VUNSPEC_POOL_4 99 VUNSPEC_POOL_8 100 VUNSPEC_SYMBOL_REF 101 102 ; Support for the eh_return pattern. 103 VUNSPEC_EH_RETURN 104 VUNSPEC_BLOCKAGE 105 ]) 106 107 108;; ------------------------------------------------------------------------ 109;; Attributes 110;; ------------------------------------------------------------------------ 111 112;; LENGTH of an instruction (in bytes). 113 114(define_attr "length" "" 115 (if_then_else (match_test "CSKY_TARGET_ARCH (CK801)") 116 (const_int 2) 117 (const_int 4))) 118 119;; Used for ck801 to represent whether we need to use bsr for long 120;; distance jumps. If set to yes, the function will save lr in the 121;; prologue. 122 123(define_attr "far_jump" "yes,no" (const_string "no")) 124 125;; Used for insn schedule. 126 127(define_attr "type" 128 "alu,load,store,cmp,branch,cbranch,addsub,alu_ix,branch_jmp,call_jsr,call" 129 (const_string "alu")) 130 131 132;; ------------------------------------------------------------------------ 133;; Include files 134;; ------------------------------------------------------------------------ 135 136(include "constraints.md") 137(include "predicates.md") 138(include "csky_insn_fpu.md") 139(include "csky_insn_dsp.md") 140(include "csky_pipeline_ck801.md") 141(include "csky_pipeline_ck802.md") 142(include "csky_pipeline_ck803.md") 143(include "csky_pipeline_ck810.md") 144 145;; ------------------------------------------------------------------------ 146;; Mov insns 147;; ------------------------------------------------------------------------ 148 149(define_mode_iterator QHI [QI HI]) 150 151(define_expand "movsi" 152 [(set (match_operand:SI 0 "general_operand" "") 153 (match_operand:SI 1 "general_operand" ""))] 154 "" 155 " 156 { 157 rtx scratch = !can_create_pseudo_p () ? operands[0] : 0; 158 if (can_create_pseudo_p () && MEM_P (operands[0])) 159 { 160 operands[1] = force_reg (SImode, operands[1]); 161 emit_insn (gen_rtx_SET (operands[0], operands[1])); 162 DONE; 163 } 164 165 /* Recognize the case where operand[1] is a reference to thread-local 166 data and load its address to a register. */ 167 if (csky_tls_referenced_p (operands[1])) 168 { 169 rtx tmp = operands[1]; 170 rtx addend = NULL; 171 172 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) 173 { 174 addend = XEXP (XEXP (tmp, 0), 1); 175 tmp = XEXP (XEXP (tmp, 0), 0); 176 } 177 178 gcc_assert (GET_CODE (tmp) == SYMBOL_REF); 179 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0); 180 181 tmp = csky_legitimize_tls_address (tmp, scratch); 182 if (addend) 183 { 184 tmp = gen_rtx_PLUS (SImode, tmp, addend); 185 tmp = force_operand (tmp, operands[0]); 186 } 187 operands[1] = tmp; 188 } 189 else if (flag_pic 190 && (CONSTANT_P (operands[1]) 191 || csky_symbol_mentioned_p (operands[1]) 192 || csky_label_mentioned_p (operands[1]))) 193 operands[1] = csky_legitimize_pic_address (operands[1], scratch, true); 194 }" 195) 196 197;; Note that we conservatively estimate all load and store insns as having 198;; a size of 4 bytes throughout even though some variants can be encoded 199;; as 2-byte machine instructions. Getting more accurate instruction counts 200;; would be better handled by calling into a C function than encoding it 201;; as an RTL conditional here. 202;; Also note that we don't count the extra space required for constant 203;; pool entries here; that's handled by the constant pool entries themselves. 204;; In -mno-constpool cases where we're relying on the assembler to create 205;; the constant pool, we'll undercount branch lengths, but in that case the 206;; assembler also handles branch relaxation as needed. It's only ck801 that 207;; requires compiler cooperation when long branches are needed. 208 209(define_insn "*cskyv2_movsi" 210 [(set (match_operand:SI 0 "nonimmediate_operand" "=b,r,r,r, r, r, r,r, m,r,*y,*r,*v,*r,*v") 211 (match_operand:SI 1 "general_operand" " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))] 212 "CSKY_ISA_FEATURE (E2)" 213 "* return csky_output_move (insn, operands, SImode);" 214 [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4") 215 (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")] 216) 217 218(define_insn "*ck801_movsi" 219 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,a, a,r,r, m,r") 220 (match_operand:SI 1 "general_operand" "r, Up,T,m,miF,r,c"))] 221 "CSKY_ISA_FEATURE (E1)" 222 "* return csky_output_ck801_move (insn, operands, SImode);" 223 [(set_attr "length" "2,2,2,4,4,4,2") 224 (set_attr "type" "alu,alu,alu,load,load,store,alu")] 225) 226 227;; Convert negative assignments to zero minus positive numbers. 228(define_split 229 [(set (match_operand:SI 0 "register_operand" "") 230 (match_operand:SI 1 "const_int_operand" ""))] 231 "satisfies_constraint_T (operands[1])" 232 [(set (match_dup 0) (match_dup 2)) 233 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] 234 "operands[2] = const0_rtx;" 235) 236 237;; Convert const assignments to small number of assignments and left shift. 238(define_split 239 [(set (match_operand:SI 0 "register_operand" "") 240 (match_operand:SI 1 "const_int_operand" ""))] 241 "" 242 [(set (match_dup 0) (match_dup 1)) 243 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))] 244 " 245 { 246 unsigned int base, shift; 247 248 if (!csky_shifted_imm8_constant (INTVAL (operands[1]), &base, &shift)) 249 FAIL; 250 if (shift == 0) 251 FAIL; 252 operands[1] = GEN_INT (base); 253 operands[2] = GEN_INT (shift); 254 }" 255) 256 257 258(define_expand "movhi" 259 [(set (match_operand:HI 0 "general_operand" "") 260 (match_operand:HI 1 "general_operand" ""))] 261 "" 262 " 263 { 264 if (GET_CODE (operands[0]) == MEM) 265 operands[1] = force_reg (HImode, operands[1]); 266 else if (CONSTANT_P (operands[1]) 267 && (GET_CODE (operands[1]) != CONST_INT 268 || (! CSKY_CONST_OK_FOR_I (INTVAL (operands[1])) 269 && ! CSKY_CONST_OK_FOR_Ub (INTVAL (operands[1])) 270 && ! CSKY_CONST_OK_FOR_Uc (INTVAL (operands[1])))) 271 && ! reload_completed && ! reload_in_progress) 272 { 273 rtx reg = gen_reg_rtx (SImode); 274 emit_insn (gen_movsi (reg, operands[1])); 275 operands[1] = gen_lowpart (HImode, reg); 276 } 277 }" 278) 279 280(define_insn "*cskyv2_movhi" 281 [(set (match_operand:HI 0 "nonimmediate_operand" "=b,r,r,r, r, r, r,r, m,r,*y,*r,*v,*r,*v") 282 (match_operand:HI 1 "general_operand" " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))] 283 "CSKY_ISA_FEATURE (E2)" 284 "* return csky_output_move (insn, operands, HImode);" 285 [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4") 286 (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")] 287) 288 289(define_insn "*ck801_movhi" 290 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,a, a,r,r, m,r") 291 (match_operand:HI 1 "general_operand" "r, Up,T,m,miF,r,c"))] 292 "CSKY_ISA_FEATURE (E1)" 293 "* return csky_output_ck801_move (insn, operands, HImode);" 294 [(set_attr "length" "2,2,2,4,4,4,2") 295 (set_attr "type" "alu,alu,alu,load,load,store,alu")] 296) 297 298 299(define_expand "movqi" 300 [(set (match_operand:QI 0 "general_operand" "") 301 (match_operand:QI 1 "general_operand" ""))] 302 "" 303 " 304 { 305 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM) 306 operands[1] = force_reg (QImode, operands[1]); 307 else if (CONSTANT_P (operands[1]) 308 && (GET_CODE (operands[1]) != CONST_INT 309 || (! CSKY_CONST_OK_FOR_I (INTVAL (operands[1])) 310 && ! CSKY_CONST_OK_FOR_Ub (INTVAL (operands[1])) 311 && ! CSKY_CONST_OK_FOR_Uc (INTVAL (operands[1])))) 312 && ! reload_completed && ! reload_in_progress) 313 { 314 rtx reg = gen_reg_rtx (SImode); 315 emit_insn (gen_movsi (reg, operands[1])); 316 operands[1] = gen_lowpart (QImode, reg); 317 } 318 }" 319) 320 321(define_insn "*cskyv2_movqi" 322 [(set (match_operand:QI 0 "nonimmediate_operand" "=b,r,r,r, r, r, r,r, m,r,*y,*r,*v,*r,*v") 323 (match_operand:QI 1 "general_operand" " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))] 324 "CSKY_ISA_FEATURE (E2)" 325 "* return csky_output_move (insn, operands, QImode);" 326 [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4") 327 (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")] 328) 329 330(define_insn "*ck801_movqi" 331 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,a, a,r,r, m,r") 332 (match_operand:QI 1 "general_operand" "r, Up,T,m,miF,r,c"))] 333 "CSKY_ISA_FEATURE (E1)" 334 "* return csky_output_ck801_move (insn, operands, QImode);" 335 [(set_attr "length" "2,2,2,4,4,4,2") 336 (set_attr "type" "alu,alu,alu,load,load,store,alu")] 337) 338 339 340(define_expand "movdi" 341 [(set (match_operand:DI 0 "general_operand" "") 342 (match_operand:DI 1 "general_operand" ""))] 343 "" 344 "if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM) 345 operands[1] = force_reg (DImode, operands[1]);" 346) 347 348;; Convert negative assignments to zero minus positive numbers. 349(define_split 350 [(set (match_operand:QHI 0 "register_operand" "") 351 (match_operand:QHI 1 "const_int_operand" ""))] 352 "satisfies_constraint_T (operands[1])" 353 [(set (match_dup 4) (match_dup 2)) 354 (set (match_dup 4) (match_dup 3)) 355 (set (match_dup 0) (match_dup 5))] 356 " 357 { 358 int low; 359 360 if (TARGET_BIG_ENDIAN) 361 low = 4 - mode_size[GET_MODE (operands[0])]; 362 else 363 low = 0; 364 operands[2] = const0_rtx; 365 if (can_create_pseudo_p ()) 366 operands[4] = gen_reg_rtx (SImode); 367 else 368 operands[4] = gen_rtx_REG (SImode, REGNO (operands[0])); 369 operands[3] = gen_rtx_PLUS (SImode, operands[4], operands[1]); 370 operands[5] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[4], low); 371 }" 372) 373 374;; Convert const assignments to small number of assignments and left shift. 375(define_split 376 [(set (match_operand:QHI 0 "register_operand" "") 377 (match_operand:QHI 1 "const_int_operand" ""))] 378 "" 379 [(set (match_dup 3) (match_dup 1)) 380 (set (match_dup 3) (ashift:SI (match_dup 3) (match_dup 2))) 381 (set (match_dup 0) (match_dup 4))] 382 " 383 { 384 unsigned int base, shift; 385 int low; 386 387 if (!csky_shifted_imm8_constant (INTVAL (operands[1]), &base, &shift)) 388 FAIL; 389 if (shift == 0) 390 FAIL; 391 392 if (TARGET_BIG_ENDIAN) 393 low = 4 - mode_size[GET_MODE (operands[0])]; 394 else 395 low = 0; 396 397 operands[1] = GEN_INT (base); 398 operands[2] = GEN_INT (shift); 399 if (can_create_pseudo_p ()) 400 operands[3] = gen_reg_rtx (SImode); 401 else 402 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 403 operands[4] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3], low); 404 }" 405) 406 407 408(define_insn "*csky_movdi" 409 [(set (match_operand:DI 0 "nonimmediate_operand" "=b,r,r, r,r, m,*r,*y,*v,*r,*v") 410 (match_operand:DI 1 "general_operand" " b,r,Ud,m,miF,r,*y,*r,*r,*v,*v"))] 411 "CSKY_ISA_FEATURE (E2)" 412 "* return csky_output_movedouble (operands, DImode);" 413 [(set_attr "length" "4,8,8,8,8,8,16,16,16,16,16") 414 (set_attr "type" "alu,alu,alu,load,load,store,alu,alu,alu,alu,alu")] 415) 416 417(define_insn "*ck801_movdi" 418 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,a, a,r,r, m") 419 (match_operand:DI 1 "general_operand" "r, Up,T,m,miF,r"))] 420 "CSKY_ISA_FEATURE (E1)" 421 "* return csky_output_ck801_movedouble (operands, DImode);" 422 [(set_attr "length" "4,4,4,8,8,8") 423 (set_attr "type" "alu,alu,alu,load,load,store")] 424) 425 426;; Float mov instructions. 427 428(define_expand "movsf" 429 [(set (match_operand:SF 0 "general_operand" "") 430 (match_operand:SF 1 "general_operand" ""))] 431 "" 432 " 433 if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ()) 434 operands[1] = force_reg (SFmode, operands[1]); 435 " 436) 437 438;; FIXME: maybe the vreg load/stores should have their own type attr. 439(define_insn "*csky_movsf_fpv2" 440 [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v") 441 (match_operand:SF 1 "general_operand" " b,r,r,v,m,mF,r,v,Q,v,m"))] 442 "CSKY_ISA_FEATURE (fpv2_sf)" 443 "* return csky_output_move (insn, operands, SFmode);" 444 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4") 445 (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")] 446) 447 448(define_insn "*ck801_movsf" 449 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r, m") 450 (match_operand:SF 1 "general_operand" " r,m,mF,r"))] 451 "CSKY_ISA_FEATURE (E1)" 452 "* return csky_output_ck801_move (insn, operands, SFmode);" 453 [(set_attr "length" "2,4,4,4") 454 (set_attr "type" "alu,load,load,store")] 455) 456 457(define_insn "*csky_movsf" 458 [(set (match_operand:SF 0 "nonimmediate_operand" "=b,r,r,r, m") 459 (match_operand:SF 1 "general_operand" " b,r,m,mF,r"))] 460 "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_sf)" 461 "* return csky_output_move (insn, operands, SFmode);" 462 [(set_attr "length" "2,4,4,4,4") 463 (set_attr "type" "alu,alu,load,load,store")] 464) 465 466 467(define_expand "movdf" 468 [(set (match_operand:DF 0 "general_operand" "") 469 (match_operand:DF 1 "general_operand" ""))] 470 "" 471 " 472 if (GET_CODE (operands[0]) == MEM && can_create_pseudo_p ()) 473 operands[1] = force_reg (DFmode, operands[1]); 474 " 475) 476 477;; FIXME: maybe the vreg load/stores should have their own type attr. 478(define_insn "*csky_movdf_fpv2" 479 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,v,r,r,r, m,Q,v,v,v") 480 (match_operand:DF 1 "general_operand" "b,r,r,v,m,mF,r,v,Q,v,m"))] 481 "CSKY_ISA_FEATURE (fpv2_df)" 482 "* return csky_output_movedouble (operands, DFmode);" 483 [(set_attr "length" "4,8,8,8,8,8,8,8,8,8,8") 484 (set_attr "type" "alu,alu,alu,alu,load,load,store,alu,alu,alu,alu")] 485) 486 487(define_insn "*ck801_movdf" 488 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r, m") 489 (match_operand:DF 1 "general_operand" " r,m,mF,r"))] 490 "CSKY_ISA_FEATURE (E1)" 491 "* return csky_output_ck801_movedouble (operands, DFmode);" 492 [(set_attr "length" "4,8,8,8") 493 (set_attr "type" "alu,load,load,store")] 494) 495 496(define_insn "*csky_movdf" 497 [(set (match_operand:DF 0 "nonimmediate_operand" "=b,r,r,r, m") 498 (match_operand:DF 1 "general_operand" " b,r,m,mF,r"))] 499 "CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (fpv2_df)" 500 "* return csky_output_movedouble (operands, DFmode);" 501 [(set_attr "length" "4,8,8,8,8") 502 (set_attr "type" "alu,alu,load,load,store")] 503) 504 505;; The only CCmode move supported is a nop. Without this pattern, 506;; CSE is unable to eliminate redundant comparisons in conditional 507;; execution expressions. 508 509(define_insn "*movcc_nop" 510 [(set (reg:CC CSKY_CC_REGNUM) (reg:CC CSKY_CC_REGNUM))] 511 "" 512 "" 513 [(set_attr "length" "0")] 514) 515 516;; ------------------------------------------------------------------------ 517;; Conditional mov insns 518;; ------------------------------------------------------------------------ 519 520;; Only handle integer comparisons because float and double require 521;; library calls. 522 523(define_expand "movsicc" 524 [(set (match_operand 0 "register_operand" "") 525 (if_then_else:SI (match_operand 1 "ordered_comparison_operator" "") 526 (match_operand:SI 2 "register_operand" "") 527 (match_operand:SI 3 "register_operand" "")))] 528 "CSKY_ISA_FEATURE (E2)" 529 " 530 { 531 bool invert = csky_emit_compare (GET_CODE (operands[1]), 532 XEXP (operands[1], 0), 533 XEXP (operands[1], 1)); 534 535 if (invert) 536 emit_insn (gen_movf (operands[0], operands[2], operands[3])); 537 else 538 emit_insn (gen_movt (operands[0], operands[2], operands[3])); 539 DONE; 540 }") 541 542(define_insn "movt" 543 [(set (match_operand:SI 0 "register_operand" "=r, r") 544 (if_then_else:SI (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 545 (match_operand:SI 1 "register_operand" "r, 0") 546 (match_operand:SI 2 "register_operand" "0, r")))] 547 "CSKY_ISA_FEATURE (E2)" 548 "@ 549 movt\t%0, %1 550 movf\t%0, %2" 551 [(set_attr "length" "4,4")] 552) 553 554(define_insn "movf" 555 [(set (match_operand:SI 0 "register_operand" "=r, r") 556 (if_then_else:SI (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 557 (match_operand:SI 1 "register_operand" "r, 0") 558 (match_operand:SI 2 "register_operand" "0, r")))] 559 "CSKY_ISA_FEATURE (E2)" 560 "@ 561 movf\t%0, %1 562 movt\t%0, %2" 563 [(set_attr "length" "4,4")] 564) 565 566(define_expand "cstoresi4" 567 [(set (match_operand:SI 0 "register_operand" "") 568 (match_operator 1 "ordered_comparison_operator" 569 [(match_operand:SI 2 "csky_compare_operand" "") 570 (match_operand:SI 3 "nonmemory_operand" "")]))] 571 "" 572 " 573 { 574 bool invert = csky_emit_compare (GET_CODE (operands[1]), 575 operands[2], operands[3]); 576 577 if (invert) 578 emit_insn (gen_mvcv (operands[0])); 579 else if (CSKY_ISA_FEATURE (E1)) 580 { 581 emit_insn (gen_movsi (operands[0], const0_rtx)); 582 emit_insn (gen_ck801_addc (operands[0], operands[0], operands[0])); 583 } 584 else 585 emit_insn (gen_mvc (operands[0])); 586 DONE; 587 }" 588) 589 590(define_insn "mvc" 591 [(set (match_operand:SI 0 "register_operand" "=r") 592 (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))] 593 "CSKY_ISA_FEATURE (E2)" 594 "mvc\t%0" 595) 596 597(define_insn "mvcv" 598 [(set (match_operand:SI 0 "register_operand" "=r") 599 (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))] 600 "" 601 "mvcv\t%0" 602) 603 604;; ------------------------------------------------------------------------ 605;; Arithmetic insns 606;; ------------------------------------------------------------------------ 607 608(define_insn "abssi2" 609 [(set (match_operand:SI 0 "register_operand" "=r") 610 (abs:SI (match_operand:SI 1 "register_operand" "r")))] 611 "CSKY_ISA_FEATURE (2E3)" 612 "abs\t%0, %1" 613 [(set_attr "type" "alu")] 614) 615 616(define_insn "extvsi" 617 [(set (match_operand:SI 0 "register_operand" "=r") 618 (sign_extract:SI (match_operand:SI 1 "register_operand" "r") 619 (match_operand:SI 2 "const_int_operand" "") 620 (match_operand:SI 3 "const_int_operand" "")))] 621 "CSKY_ISA_FEATURE (2E3)" 622 { 623 operands[2] = GEN_INT (INTVAL (operands[3]) + INTVAL (operands[2]) - 1); 624 return \"sext\t%0, %1, %2, %3\"; 625 } 626) 627 628(define_insn "insvsi" 629 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 630 (match_operand:SI 1 "const_int_operand" "i") 631 (match_operand:SI 2 "const_int_operand" "i")) 632 (match_operand:SI 3 "register_operand" "r"))] 633 "CSKY_ISA_FEATURE (2E3)" 634 { 635 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1); 636 return \"ins\t%0, %3, %1, %2\"; 637 } 638) 639 640(define_expand "bseti" 641 [(set (match_operand:SI 0 "register_operand" "") 642 (ior:SI (match_operand:SI 1 "register_operand" "") 643 (ashift:SI (const_int 1) 644 (match_operand:SI 2 "csky_literal_K_operand" ""))))] 645 "" 646 "") 647 648(define_insn "smart_bseti" 649 [(set (match_operand:SI 0 "register_operand" "=r") 650 (ior:SI (match_operand:SI 1 "register_operand" "0") 651 (ashift:SI (const_int 1) 652 (match_operand:SI 2 "csky_literal_K_operand" "K"))))] 653 "TARGET_MINI_REGISTERS" 654 "bseti\t%0, %2" 655 [(set_attr "length" "2")]) 656 657(define_insn "fast_bseti" 658 [(set (match_operand:SI 0 "register_operand" "=a,r") 659 (ior:SI (match_operand:SI 1 "register_operand" "0,r") 660 (ashift:SI (const_int 1) 661 (match_operand:SI 2 "csky_literal_K_operand" "K,K"))))] 662 "!TARGET_MINI_REGISTERS" 663 "bseti\t%0, %1, %2" 664 [(set_attr "length" "2,4")]) 665 666(define_expand "bclri" 667 [(set (match_operand:SI 0 "register_operand" "") 668 (and:SI (match_operand:SI 1 "register_operand" "") 669 (not:SI (ashift:SI (const_int 1) 670 (match_operand:SI 2 "csky_literal_K_operand" "")))))] 671 "" 672 "") 673 674(define_insn "smart_bclri" 675 [(set (match_operand:SI 0 "register_operand" "=r") 676 (and:SI (match_operand:SI 1 "register_operand" "0") 677 (not:SI (ashift:SI (const_int 1) 678 (match_operand:SI 2 "csky_literal_K_operand" "K")))))] 679 "TARGET_MINI_REGISTERS" 680 "bclri\t%0, %2" 681 [(set_attr "length" "2")]) 682 683(define_insn "fast_bclri" 684 [(set (match_operand:SI 0 "register_operand" "=a,r") 685 (and:SI (match_operand:SI 1 "register_operand" "0,r") 686 (not:SI (ashift:SI (const_int 1) 687 (match_operand:SI 2 "csky_literal_K_operand" "K,K")))))] 688 "!TARGET_MINI_REGISTERS" 689 "bclri\t%0, %1, %2" 690 [(set_attr "length" "2,4")]) 691 692 693;; Shift instructions. 694 695(define_expand "ashlsi3" 696 [(set (match_operand:SI 0 "register_operand" "") 697 (ashift:SI (match_operand:SI 1 "register_operand" "") 698 (match_operand:SI 2 "csky_arith_K_operand" "")))] 699 "" 700 "" 701) 702 703(define_insn "*cskyv2_ashlsi3" 704 [(set (match_operand:SI 0 "register_operand" "=b,r,a,r") 705 (ashift:SI (match_operand:SI 1 "register_operand" "0,r,a,r") 706 (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))] 707 "CSKY_ISA_FEATURE (E2)" 708 "@ 709 lsl %0, %1, %2 710 lsl %0, %1, %2 711 lsli %0, %1, %2 712 lsli %0, %1, %2" 713 [(set_attr "length" "2,4,2,4")] 714) 715 716(define_insn "ck801_ashlsi3" 717 [(set (match_operand:SI 0 "register_operand" "=a,r") 718 (ashift:SI (match_operand:SI 1 "register_operand" "a,0") 719 (match_operand:SI 2 "csky_arith_K_operand" "K,r")))] 720 "CSKY_ISA_FEATURE (E1)" 721 "@ 722 lsli %0, %1, %2 723 lsl %0, %1, %2" 724) 725 726 727(define_expand "ashrsi3" 728 [(set (match_operand:SI 0 "register_operand" "") 729 (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 730 (match_operand:SI 2 "csky_arith_K_operand" "")))] 731 "" 732 "" 733) 734 735(define_insn "*cskyv2_ashrsi3" 736 [(set (match_operand:SI 0 "register_operand" "=b,r,a,r") 737 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,r,a,r") 738 (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))] 739 "CSKY_ISA_FEATURE (E2)" 740 "@ 741 asr %0, %1, %2 742 asr %0, %1, %2 743 asri %0, %1, %2 744 asri %0, %1, %2" 745 [(set_attr "length" "2,4,2,4")] 746) 747 748(define_insn "*ck801_ashrsi3" 749 [(set (match_operand:SI 0 "register_operand" "=a,r") 750 (ashiftrt:SI (match_operand:SI 1 "register_operand" "a,0") 751 (match_operand:SI 2 "csky_arith_K_operand" "K,r")))] 752 "CSKY_ISA_FEATURE (E1)" 753 "@ 754 asri %0, %1, %2 755 asr %0, %1, %2" 756) 757 758 759(define_expand "lshrsi3" 760 [(set (match_operand:SI 0 "register_operand" "") 761 (lshiftrt:SI (match_operand:SI 1 "register_operand" "") 762 (match_operand:SI 2 "csky_arith_K_operand" "")))] 763 "" 764 "" 765) 766 767(define_insn "*cskyv2_lshrsi3" 768 [(set (match_operand:SI 0 "register_operand" "=b,r,a,r") 769 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,r,a,r") 770 (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))] 771 "CSKY_ISA_FEATURE (E2)" 772 "@ 773 lsr %0, %1, %2 774 lsr %0, %1, %2 775 lsri %0, %1, %2 776 lsri %0, %1, %2" 777 [(set_attr "length" "2,4,2,4")] 778) 779 780(define_insn "ck801_lshrsi3" 781 [(set (match_operand:SI 0 "register_operand" "=a,r") 782 (lshiftrt:SI (match_operand:SI 1 "register_operand" "a,0") 783 (match_operand:SI 2 "csky_arith_K_operand" "K,r")))] 784 "CSKY_ISA_FEATURE (E1)" 785 "@ 786 lsri %0, %1, %2 787 lsr %0, %1, %2" 788) 789 790 791(define_expand "rotlsi3" 792 [(set (match_operand:SI 0 "register_operand" "") 793 (rotate:SI (match_operand:SI 1 "register_operand" "") 794 (match_operand:SI 2 "csky_arith_K_operand" "")))] 795 "" 796 "" 797) 798 799(define_insn "*cskyv2_rotlsi3" 800 [(set (match_operand:SI 0 "register_operand" "=b,r,r") 801 (rotate:SI (match_operand:SI 1 "register_operand" "0,r,r") 802 (match_operand:SI 2 "csky_arith_K_operand" "b,r,K")))] 803 "CSKY_ISA_FEATURE (E2)" 804 "@ 805 rotl %0, %1, %2 806 rotl %0, %1, %2 807 rotli %0, %1, %2" 808 [(set_attr "length" "2,4,4")] 809) 810 811(define_insn "*ck801_rotlsi3" 812 [(set (match_operand:SI 0 "register_operand" "=r") 813 (rotate:SI (match_operand:SI 1 "register_operand" "0") 814 (match_operand:SI 2 "csky_arith_K_operand" "r")))] 815 "CSKY_ISA_FEATURE (E1)" 816 "rotl %0, %1, %2" 817) 818 819 820;; Add instructions. 821;; C-SKY addi and subi machine instructions only accept positive immediate 822;; values, so we have to special case immediates <= 0 in these patterns. 823 824(define_expand "addsi3" 825 [(set (match_operand:SI 0 "register_operand" "") 826 (plus:SI (match_operand:SI 1 "register_operand" "") 827 (match_operand:SI 2 "nonmemory_operand" "")))] 828 "" 829 "" 830) 831 832(define_insn "smart_addsi3" 833 [(set (match_operand:SI 0 "register_operand" "=a,r,a,a,a,a, r,r") 834 (plus:SI (match_operand:SI 1 "register_operand" "%a,0,0,a,0,a, r,r") 835 (match_operand:SI 2 "nonmemory_operand" "a, r,N,L,T,Us,M,Um")))] 836 "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2) 837 && operands[0] != stack_pointer_rtx 838 && operands[1] != stack_pointer_rtx" 839 "@ 840 addu\t%0, %1, %2 841 addu\t%0, %1, %2 842 addi\t%0, %1, %2 843 addi\t%0, %1, %2 844 subi\t%0, %1, %M2 845 subi\t%0, %1, %M2 846 addi\t%0, %1, %2 847 subi\t%0, %1, %M2" 848 [(set_attr "length" "2,2,2,2,2,2,4,4") 849 (set_attr "type" "addsub")] 850) 851 852(define_insn_and_split "*smart_addsi3_sp" 853 [(set (match_operand:SI 0 "register_operand" "=z,z, z,a,&a,z,a,r") 854 (plus:SI (match_operand:SI 1 "register_operand" "0, 0, 0,z, z,a,z,r") 855 (match_operand:SI 2 "nonmemory_operand" "P, Ug,r,Uq,i,a,a,M")))] 856 "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2) 857 && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)" 858 "@ 859 addi\t%0, %1, %2 860 subi\t%0, %1, %M2 861 addu\t%0, %1, %2 862 addi\t%0, %1, %2 863 # 864 addu\t%0, %1, %2 865 addu\t%0, %1, %2 866 addi\t%0, %1, %2" 867 "(operands[0] != stack_pointer_rtx 868 && operands[1] == stack_pointer_rtx 869 && !satisfies_constraint_Uq (operands[2]))" 870 [(set (match_dup 0) 871 (plus:SI (match_dup 1) (match_dup 0)))] 872 "emit_move_insn (operands[0], operands[2]);" 873 [(set_attr "type" "addsub")] 874) 875 876(define_insn "*ck801_addsi3" 877 [(set (match_operand:SI 0 "register_operand" "=r,a,a,a,a,a, !z,!z,!z,a") 878 (plus:SI (match_operand:SI 1 "register_operand" "%0,a,0,a,0,a, 0, 0, 0, !z") 879 (match_operand:SI 2 "nonmemory_operand" "r, a,N,L,T,Us,P, Ug,r, Uq")))] 880 "CSKY_ISA_FEATURE (E1)" 881 "@ 882 addu\t%0, %1, %2 883 addu\t%0, %1, %2 884 addi\t%0, %1, %2 885 addi\t%0, %1, %2 886 subi\t%0, %1, %M2 887 subi\t%0, %1, %M2 888 addi\t%0, %1, %2 889 subi\t%0, %1, %M2 890 addu\t%0, %1, %2 891 addi\t%0, %1, %2" 892 [(set_attr "type" "addsub")] 893) 894 895(define_insn "fast_addsi3" 896 [(set (match_operand:SI 0 "register_operand" "=r,r, r") 897 (plus:SI (match_operand:SI 1 "register_operand" "%r,r, r") 898 (match_operand:SI 2 "nonmemory_operand" "M, Um,r")))] 899 "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)" 900 "@ 901 addi\t%0, %1, %2 902 subi\t%0, %1, %M2 903 addu\t%0, %1, %2" 904 [(set_attr "type" "addsub")] 905) 906 907(define_expand "adddi3" 908 [(parallel [(set (match_operand:DI 0 "register_operand" "") 909 (plus:DI (match_operand:DI 1 "register_operand" "") 910 (match_operand:DI 2 "csky_arith_int1_operand" ""))) 911 (clobber (reg:CC CSKY_CC_REGNUM))])] 912 "" 913 " 914 if (CSKY_ISA_FEATURE (E1) && (GET_CODE (operands[2]) != REG)) 915 operands[2] = force_reg (DImode, operands[2]); 916 " 917) 918 919/* Note that the csky addc instruction both reads and writes the carry bit. 920 The purpose of the initial cmplt instruction in the expansion is to 921 clear the carry bit before adding the lo words. */ 922 923(define_insn_and_split "*cskyv2_adddi3" 924 [(set (match_operand:DI 0 "register_operand" "=&b,&r") 925 (plus:DI (match_operand:DI 1 "register_operand" "%0,r") 926 (match_operand:DI 2 "register_operand" "b, r"))) 927 (clobber (reg:CC CSKY_CC_REGNUM))] 928 "CSKY_ISA_FEATURE (E2)" 929 "#" 930 "reload_completed" 931 [(const_int 0)] 932 { 933 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 934 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 935 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 936 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 937 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 938 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 939 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 940 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 941 942 emit_insn (gen_cmpltsi_r (copy_rtx (l1), copy_rtx (l1))); 943 emit_insn (gen_cskyv2_addc (l0, l1, l2)); 944 emit_insn (gen_cskyv2_addc (h0, h1, h2)); 945 DONE; 946 } 947 [(set_attr "length" "6,12")] 948) 949 950(define_insn_and_split "*ck801_adddi3" 951 [(set (match_operand:DI 0 "register_operand" "=r") 952 (plus:DI (match_operand:DI 1 "register_operand" "%0") 953 (match_operand:DI 2 "register_operand" "r"))) 954 (clobber (reg:CC CSKY_CC_REGNUM))] 955 "CSKY_ISA_FEATURE (E1)" 956 "#" 957 "reload_completed" 958 [(const_int 0)] 959 { 960 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 961 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 962 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 963 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 964 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 965 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 966 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 967 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 968 969 emit_insn (gen_cmpltsi_r (copy_rtx (l1), copy_rtx (l1))); 970 emit_insn (gen_ck801_addc (l0, l1, l2)); 971 emit_insn (gen_ck801_addc (h0, h1, h2)); 972 DONE; 973 } 974 [(set_attr "length" "6")] 975) 976 977;; Special case for "longlong += 1". 978 979(define_insn_and_split "*cskyv2_adddi1_1" 980 [(set (match_operand:DI 0 "register_operand" "=&r") 981 (plus:DI (match_operand:DI 1 "register_operand" "0") 982 (const_int 1))) 983 (clobber (reg:CC CSKY_CC_REGNUM))] 984 "CSKY_ISA_FEATURE (E2)" 985 "#" 986 "reload_completed" 987 [(const_int 0)] 988 { 989 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 990 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 991 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 992 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 993 994 if (TARGET_MINI_REGISTERS) 995 { 996 emit_insn (gen_smart_addsi3 (l0, copy_rtx (l0), 997 gen_int_mode (1, SImode))); 998 emit_insn (gen_smart_cmpnesi_i (copy_rtx (l0), 999 gen_int_mode (0, SImode))); 1000 emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0), 1001 gen_int_mode (1, SImode))); 1002 } 1003 else 1004 { 1005 emit_insn (gen_fast_addsi3 (l0, copy_rtx (l0), 1006 gen_int_mode (1, SImode))); 1007 emit_insn (gen_fast_cmpnesi_i (copy_rtx (l0), 1008 gen_int_mode (0, SImode))); 1009 emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0), 1010 gen_int_mode (1, SImode))); 1011 } 1012 DONE; 1013 } 1014 [(set (attr "length") 1015 (if_then_else (match_test "TARGET_MINI_REGISTERS") 1016 (const_int 8) 1017 (const_int 12)))] 1018) 1019 1020;; sub instructions. 1021 1022(define_expand "subsi3" 1023 [(set (match_operand:SI 0 "register_operand" "") 1024 (minus:SI (match_operand:SI 1 "register_operand" "") 1025 (match_operand:SI 2 "nonmemory_operand" "")))] 1026 "" 1027 "" 1028) 1029 1030(define_insn "smart_subsi3" 1031 [(set (match_operand:SI 0 "register_operand" "=a,a,a,a,a,a") 1032 (minus:SI (match_operand:SI 1 "register_operand" "a, 0,0,a,0,a") 1033 (match_operand:SI 2 "nonmemory_operand" "a, a,N,L,T,Us")))] 1034 "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2) 1035 && operands[0] != stack_pointer_rtx 1036 && operands[1] != stack_pointer_rtx" 1037 "@ 1038 subu\t%0, %1, %2 1039 subu\t%0, %1, %2 1040 subi\t%0, %1, %2 1041 subi\t%0, %1, %2 1042 addi\t%0, %1, %M2 1043 addi\t%0, %1, %M2" 1044 [(set_attr "length" "2,2,2,2,2,2") 1045 (set_attr "type" "addsub")] 1046) 1047 1048(define_insn "*smart_subsi3_sp" 1049 [(set (match_operand:SI 0 "register_operand" "=z,z, z,a, a,r") 1050 (minus:SI (match_operand:SI 1 "register_operand" "0, 0, 0,z, a,r") 1051 (match_operand:SI 2 "nonmemory_operand" "P, Ug,a,Ur,a,M")))] 1052 "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2) 1053 && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)" 1054 "@ 1055 subi\t%0, %1, %2 1056 addi\t%0, %1, %M2 1057 subu\t%0, %1, %2 1058 addi\t%0, %1, %M2 1059 subu\t%0, %1, %2 1060 subi\t%0, %1, %2" 1061 [(set_attr "length" "2,2,2,2,2,4") 1062 (set_attr "type" "addsub")] 1063) 1064 1065(define_insn "*ck801_subsi3" 1066 [(set (match_operand:SI 0 "register_operand" "=a,a,a,a,a,a") 1067 (minus:SI (match_operand:SI 1 "register_operand" "0, a,0,a,0,a") 1068 (match_operand:SI 2 "nonmemory_operand" "a, a,N,L,T,Us")))] 1069 "CSKY_ISA_FEATURE (E1) 1070 && operands[0] != stack_pointer_rtx 1071 && operands[1] != stack_pointer_rtx" 1072 "@ 1073 subu\t%0, %1, %2 1074 subu\t%0, %1, %2 1075 subi\t%0, %1, %2 1076 subi\t%0, %1, %2 1077 addi\t%0, %1, %M2 1078 addi\t%0, %1, %M2" 1079 [(set_attr "type" "addsub")] 1080) 1081 1082(define_insn "*ck801_subsi3_sp" 1083 [(set (match_operand:SI 0 "register_operand" "=a,z,z, z") 1084 (minus:SI (match_operand:SI 1 "register_operand" "z, 0,0, 0") 1085 (match_operand:SI 2 "nonmemory_operand" "Ur,P,Ug,r")))] 1086 "CSKY_ISA_FEATURE (E1) 1087 && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)" 1088 "@ 1089 addi\t%0, %1, %M2 1090 subi\t%0, %1, %2 1091 addi\t%0, %1, %M2 1092 subu\t%0, %1, %2" 1093 [(set_attr "type" "addsub")] 1094) 1095 1096(define_insn "fast_subsi3" 1097 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1098 (minus:SI (match_operand:SI 1 "register_operand" "r, r,r") 1099 (match_operand:SI 2 "nonmemory_operand" "r, M,Um")))] 1100 "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)" 1101 "@ 1102 subu\t%0, %1, %2 1103 subi\t%0, %1, %2 1104 addi\t%0, %1, %M2" 1105 [(set_attr "type" "addsub")] 1106) 1107 1108(define_expand "subdi3" 1109 [(parallel [(set (match_operand:DI 0 "register_operand" "") 1110 (minus:DI (match_operand:DI 1 "register_operand" "") 1111 (match_operand:DI 2 "register_operand" ""))) 1112 (clobber (reg:CC CSKY_CC_REGNUM))])] 1113 "" 1114 "" 1115) 1116 1117/* Note that the csky subc instruction both reads and writes the C bit. 1118 The purpose of the initial cmphs instruction in the expansion is to 1119 set the C bit before subtracting the lo words. */ 1120 1121(define_insn_and_split "*cskyv2_subdi3" 1122 [(set (match_operand:DI 0 "register_operand" "=&b,&r") 1123 (minus:DI (match_operand:DI 1 "register_operand" "0, r") 1124 (match_operand:DI 2 "register_operand" "b, r"))) 1125 (clobber (reg:CC CSKY_CC_REGNUM))] 1126 "CSKY_ISA_FEATURE (E2)" 1127 "#" 1128 "reload_completed" 1129 [(const_int 0)] 1130 { 1131 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1132 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1133 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1134 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1135 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1136 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1137 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1138 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1139 1140 emit_insn (gen_cmpgeusi_r (copy_rtx (l1), copy_rtx (l1))); 1141 emit_insn (gen_cskyv2_subc (l0, l1, l2)); 1142 emit_insn (gen_cskyv2_subc (h0, h1, h2)); 1143 DONE; 1144 } 1145 [(set_attr "length" "6,12")] 1146) 1147 1148(define_insn_and_split "*ck801_subdi3" 1149 [(set (match_operand:DI 0 "register_operand" "=r") 1150 (minus:DI (match_operand:DI 1 "register_operand" "0") 1151 (match_operand:DI 2 "register_operand" "r"))) 1152 (clobber (reg:CC CSKY_CC_REGNUM))] 1153 "CSKY_ISA_FEATURE (E1)" 1154 "#" 1155 "reload_completed" 1156 [(const_int 0)] 1157 { 1158 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1159 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1160 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1161 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1162 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1163 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1164 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1165 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1166 1167 emit_insn (gen_cmpgeusi_r (copy_rtx (l1), copy_rtx (l1))); 1168 emit_insn (gen_ck801_subc (l0, l1, l2)); 1169 emit_insn (gen_ck801_subc (h0, h1, h2)); 1170 DONE; 1171 } 1172 [(set_attr "length" "6")] 1173) 1174 1175;; Special case for "longlong -= 1". 1176 1177(define_insn_and_split "*cskyv2_subdi1_1" 1178 [(set (match_operand:DI 0 "register_operand" "=&r") 1179 (plus:DI (match_operand:DI 1 "register_operand" "0") 1180 (const_int -1))) 1181 (clobber (reg:CC CSKY_CC_REGNUM))] 1182 "CSKY_ISA_FEATURE (E2)" 1183 "#" 1184 "reload_completed" 1185 [(const_int 0)] 1186 { 1187 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1188 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1189 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1190 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1191 1192 if (TARGET_MINI_REGISTERS) 1193 { 1194 emit_insn (gen_smart_cmpnesi_i (copy_rtx (l0), 1195 gen_int_mode (0, SImode))); 1196 emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0), 1197 gen_int_mode (-1, SImode))); 1198 emit_insn (gen_smart_subsi3 (l0, copy_rtx (l0), 1199 gen_int_mode (1, SImode))); 1200 } 1201 else 1202 { 1203 emit_insn (gen_fast_cmpnesi_i (copy_rtx (l0), 1204 gen_int_mode (0, SImode))); 1205 emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0), 1206 gen_int_mode (-1, SImode))); 1207 emit_insn (gen_fast_subsi3 (l0, copy_rtx (l0), 1208 gen_int_mode (1, SImode))); 1209 } 1210 DONE; 1211 } 1212 [(set (attr "length") 1213 (if_then_else (match_test "TARGET_MINI_REGISTERS") 1214 (const_int 8) 1215 (const_int 12)))] 1216) 1217 1218;; Add with carry. 1219 1220(define_insn "cskyv2_addc" 1221 [(set (match_operand:SI 0 "register_operand" "=r,r") 1222 (plus:SI (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1223 (plus:SI (match_operand:SI 1 "register_operand" "%0,r") 1224 (match_operand:SI 2 "register_operand" "r,r")))) 1225 (set (reg:CC CSKY_CC_REGNUM) 1226 (compare:CC 1227 (plus:SI (match_dup 1) (match_dup 2)) 1228 (match_dup 1)))] 1229 "CSKY_ISA_FEATURE (E2)" 1230 "addc\t%0, %1, %2" 1231 [(set_attr "length" "2,4") 1232 (set_attr "type" "addsub")] 1233) 1234 1235(define_insn "ck801_addc" 1236 [(set (match_operand:SI 0 "register_operand" "=r") 1237 (plus:SI (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1238 (plus:SI (match_operand:SI 1 "register_operand" "%0") 1239 (match_operand:SI 2 "register_operand" "r")))) 1240 (set (reg:CC CSKY_CC_REGNUM) 1241 (compare:CC 1242 (plus:SI (match_dup 1) (match_dup 2)) 1243 (match_dup 1)))] 1244 "CSKY_ISA_FEATURE (E1)" 1245 "addc\t%0, %1, %2" 1246 [(set_attr "length" "2") 1247 (set_attr "type" "addsub")] 1248) 1249 1250;; Subtract with borrow. 1251;; Note that in these insns, the sense of C bit is reversed; they subtract 1 1252;; if the C bit is not set, and on output the bit is set to 0 for borrow 1253;; and 1 for no borrow. 1254 1255(define_insn "cskyv2_subc" 1256 [(set (match_operand:SI 0 "register_operand" "=r,r") 1257 (minus:SI (match_operand:SI 1 "register_operand" "0, r") 1258 (plus:SI (match_operand:SI 2 "register_operand" "r, r") 1259 (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0))))) 1260 (set (reg:CC CSKY_CC_REGNUM) 1261 (not (compare:CC (match_dup 1) (match_dup 2))))] 1262 "CSKY_ISA_FEATURE (E2)" 1263 "subc\t%0, %1, %2" 1264 [(set_attr "length" "2,4") 1265 (set_attr "type" "addsub")] 1266) 1267 1268(define_insn "ck801_subc" 1269 [(set (match_operand:SI 0 "register_operand" "=r") 1270 (minus:SI (match_operand:SI 1 "register_operand" "0") 1271 (plus:SI (match_operand:SI 2 "register_operand" "r") 1272 (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0))))) 1273 (set (reg:CC CSKY_CC_REGNUM) 1274 (not (compare:CC (match_dup 1) (match_dup 2))))] 1275 "CSKY_ISA_FEATURE (E1)" 1276 "subc\t%0, %1, %2" 1277 [(set_attr "length" "2") 1278 (set_attr "type" "addsub")] 1279) 1280 1281;; ------------------------------------------------------------------------ 1282;; Multiplication insns 1283;; ------------------------------------------------------------------------ 1284 1285(define_expand "mulsi3" 1286 [(set (match_operand:SI 0 "register_operand" "") 1287 (mult:SI (match_operand:SI 1 "register_operand" "") 1288 (match_operand:SI 2 "register_operand" "")))] 1289 "" 1290 "" 1291) 1292 1293(define_insn "*cskyv2_mulsi3" 1294 [(set (match_operand:SI 0 "register_operand" "=r") 1295 (mult:SI (match_operand:SI 1 "register_operand" "%r") 1296 (match_operand:SI 2 "register_operand" "r")))] 1297 "CSKY_ISA_FEATURE (E2)" 1298 "mult\t%0, %1, %2" 1299) 1300 1301(define_insn "*ck801_mulsi3" 1302 [(set (match_operand:SI 0 "register_operand" "=r") 1303 (mult:SI (match_operand:SI 1 "register_operand" "%0") 1304 (match_operand:SI 2 "register_operand" "r")))] 1305 "CSKY_ISA_FEATURE (E1)" 1306 "mult\t%0, %1, %2" 1307) 1308 1309(define_insn "mulhisi3" 1310 [(set (match_operand:SI 0 "register_operand" "=r") 1311 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) 1312 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] 1313 "CSKY_ISA_FEATURE (2E3)" 1314 "mulsh\t%0, %1, %2" 1315) 1316 1317 1318;; ------------------------------------------------------------------------ 1319;; Conditional add insns 1320;; ------------------------------------------------------------------------ 1321 1322(define_expand "addsicc" 1323 [(match_operand:SI 0 "register_operand" "") 1324 (match_operand 1 "ordered_comparison_operator" "") 1325 (match_operand:SI 2 "register_operand" "") 1326 (match_operand:SI 3 "csky_literal_K_Uh_operand" "")] 1327 "CSKY_ISA_FEATURE (E2)" 1328 " 1329 { 1330 bool invert = csky_emit_compare (GET_CODE (operands[1]), 1331 XEXP (operands[1], 0), 1332 XEXP (operands[1], 1)); 1333 if (invert) 1334 emit_insn (gen_cskyv2_addcc_invert (operands[0], operands[2], 1335 operands[3])); 1336 else 1337 emit_insn (gen_cskyv2_addcc (operands[0], operands[2], operands[3])); 1338 1339 DONE; 1340 }" 1341) 1342 1343(define_insn_and_split "cskyv2_addcc" 1344 [(set (match_operand:SI 0 "register_operand" "=r,r,&r,&r") 1345 (if_then_else:SI 1346 (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1347 (plus:SI (match_operand:SI 1 "register_operand" "0,0,r,r") 1348 (match_operand:SI 2 "csky_literal_K_Uh_operand" "K,Uh,K,Uh")) 1349 (match_dup 1)))] 1350 "CSKY_ISA_FEATURE (E2)" 1351 "@ 1352 inct\t%0, %1, %2 1353 dect\t%0, %1, %M2 1354 # 1355 #" 1356 "reload_completed && !rtx_equal_p (operands[0], operands[1])" 1357 [(set (match_dup 0) 1358 (if_then_else:SI (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1359 (plus:SI (match_dup 0) (match_dup 2))))] 1360 { 1361 emit_insn (gen_movf (copy_rtx (operands[0]), 1362 copy_rtx (operands[1]), 1363 copy_rtx (operands[0]))); 1364 } 1365 [(set_attr "length" "4,4,8,8") 1366 (set_attr "type" "addsub")] 1367) 1368 1369(define_insn_and_split "cskyv2_addcc_invert" 1370 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 1371 (if_then_else:SI 1372 (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1373 (plus:SI (match_operand:SI 1 "register_operand" "0,0,r,r") 1374 (match_operand:SI 2 "csky_literal_K_Uh_operand" "K,Uh,K,Uh")) 1375 (match_dup 1)))] 1376 "CSKY_ISA_FEATURE (E2)" 1377 "@ 1378 incf\t%0, %1, %2 1379 decf\t%0, %1, %M2 1380 # 1381 #" 1382 "reload_completed && !rtx_equal_p (operands[0], operands[1])" 1383 [(set (match_dup 0) 1384 (if_then_else:SI (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 1385 (plus:SI (match_dup 0) (match_dup 2))))] 1386 { 1387 emit_insn (gen_movt (copy_rtx (operands[0]), 1388 copy_rtx (operands[1]), 1389 copy_rtx (operands[0]))); 1390 } 1391 [(set_attr "length" "4,4,8,8") 1392 (set_attr "type" "addsub")] 1393) 1394 1395 1396;; ------------------------------------------------------------------------ 1397;; Extzv insns 1398;; ------------------------------------------------------------------------ 1399 1400(define_expand "extzvsi" 1401 [(set (match_operand:SI 0 "register_operand" "") 1402 (zero_extract:SI (match_operand:SI 1 "register_operand" "") 1403 (match_operand:SI 2 "const_int_operand" "") 1404 (match_operand:SI 3 "const_int_operand" "")))] 1405 "" 1406 "{ 1407 /* ck802 has xtrb but not zext, so we'll use xtrb if we can. */ 1408 if (CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (2E3) 1409 && (INTVAL (operands[2]) == 8) 1410 && (INTVAL (operands[3]) % 8 == 0)) 1411 { 1412 rtx xtrb = gen_rtx_SET (operands[0], 1413 gen_rtx_ZERO_EXTRACT (SImode, 1414 operands[1], 1415 operands[2], 1416 operands[3])); 1417 emit (gen_rtx_PARALLEL (VOIDmode, 1418 gen_rtvec (2, xtrb, 1419 gen_hard_reg_clobber (CCmode, 33)))); 1420 DONE; 1421 } 1422 else if (!CSKY_ISA_FEATURE (2E3)) 1423 { 1424 /* Use lsri and lsli to do extzv on targets without zext. */ 1425 rtx lshft = GEN_INT (32 - (INTVAL (operands[2]) 1426 + INTVAL (operands[3]))); 1427 rtx rshft = GEN_INT (32 - INTVAL (operands[2])); 1428 rtx tmp1 = gen_reg_rtx (SImode); 1429 rtx tmp2 = gen_reg_rtx (SImode); 1430 1431 emit_insn (gen_rtx_SET (tmp1, operands[1])); 1432 emit_insn (gen_rtx_SET (tmp2, gen_rtx_ASHIFT (SImode, tmp1, lshft))); 1433 emit_insn (gen_rtx_SET (operands[0], 1434 gen_rtx_LSHIFTRT (SImode, tmp2, rshft))); 1435 DONE; 1436 } 1437 else 1438 { 1439 emit_insn (gen_cskyv2_extzv (operands[0], operands[1], 1440 operands[2], operands[3])); 1441 DONE; 1442 } 1443}") 1444 1445(define_insn "cskyv2_extzv" 1446 [(set (match_operand:SI 0 "register_operand" "=r") 1447 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1448 (match_operand:SI 2 "csky_literal_K_operand" "K") 1449 (match_operand:SI 3 "csky_literal_K_operand" "K")))] 1450 "CSKY_ISA_FEATURE (2E3)" 1451 { 1452 operands[2] = GEN_INT (INTVAL (operands[3]) + INTVAL (operands[2]) - 1); 1453 return \"zext\t%0, %1, %2, %3\"; 1454 } 1455) 1456 1457(define_insn "*cskyv2_xtrb0" 1458 [(set (match_operand:SI 0 "register_operand" "=r,r") 1459 (zero_extract:SI (match_operand:SI 1 "register_operand" "0,r") 1460 (const_int 8) 1461 (const_int 24))) 1462 (clobber (reg:CC CSKY_CC_REGNUM))] 1463 "CSKY_ISA_FEATURE (E2)" 1464 "@ 1465 lsri\t%0, %0, 24 1466 xtrb0\t%0, %1" 1467) 1468 1469(define_insn "*cskyv2_xtrb1" 1470 [(set (match_operand:SI 0 "register_operand" "=r") 1471 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1472 (const_int 8) 1473 (const_int 16))) 1474 (clobber (reg:CC CSKY_CC_REGNUM))] 1475 "CSKY_ISA_FEATURE (E2)" 1476 "xtrb1\t%0, %1" 1477) 1478 1479(define_insn "*cskyv2_xtrb2" 1480 [(set (match_operand:SI 0 "register_operand" "=r") 1481 (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1482 (const_int 8) 1483 (const_int 8))) 1484 (clobber (reg:CC CSKY_CC_REGNUM))] 1485 "CSKY_ISA_FEATURE (E2)" 1486 "xtrb2\t%0, %1" 1487) 1488 1489 1490;; ------------------------------------------------------------------------- 1491;; Zero extension instructions 1492;; ------------------------------------------------------------------------- 1493 1494(define_insn "zero_extendhisi2" 1495 [(set (match_operand:SI 0 "register_operand" "=r") 1496 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))] 1497 "" 1498 "zexth\t%0, %1" 1499) 1500 1501(define_insn "*cskyv2_zextend_ldh" 1502 [(set (match_operand:SI 0 "register_operand" "=r") 1503 (zero_extend:SI (match_operand:HI 1 "csky_simple_mem_operand" "m")))] 1504 "" 1505 "ld.h\t%0, %1" 1506 [(set_attr "length" "4") 1507 (set_attr "type" "load")] 1508) 1509 1510(define_insn "zero_extendqisi2" 1511 [(set (match_operand:SI 0 "register_operand" "=r") 1512 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1513 "" 1514 "zextb\t%0, %1" 1515) 1516 1517(define_insn "*cskyv2_zextend_ldb" 1518 [(set (match_operand:SI 0 "register_operand" "=r") 1519 (zero_extend:SI (match_operand:QI 1 "csky_simple_mem_operand" "m")))] 1520 "" 1521 "ld.b\t%0, %1" 1522 [(set_attr "length" "4") 1523 (set_attr "type" "load")] 1524) 1525 1526(define_insn "zero_extendqihi2" 1527 [(set (match_operand:HI 0 "register_operand" "=r") 1528 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1529 "" 1530 "zextb\t%0, %1" 1531) 1532 1533(define_insn "*cskyv2_zextend_ldbhi" 1534 [(set (match_operand:HI 0 "register_operand" "=r") 1535 (zero_extend:HI (match_operand:QI 1 "csky_simple_mem_operand" "m")))] 1536 "" 1537 "ld.b\t%0, %1" 1538 [(set_attr "length" "4") 1539 (set_attr "type" "load")] 1540) 1541 1542;; ------------------------------------------------------------------------- 1543;; clzm2 instructions 1544;; ------------------------------------------------------------------------- 1545 1546(define_insn "clzsi2" 1547 [(set (match_operand:SI 0 "register_operand" "=r") 1548 (clz:SI (match_operand:SI 1 "register_operand" "r")))] 1549 "CSKY_ISA_FEATURE (E2)" 1550 "ff1 %0,%1" 1551) 1552 1553;; ------------------------------------------------------------------------- 1554;; one_cmplm2 instructions 1555;; ------------------------------------------------------------------------- 1556 1557(define_expand "one_cmplsi2" 1558 [(set (match_operand:SI 0 "register_operand" "") 1559 (not:SI (match_operand:SI 1 "register_operand" "")))] 1560 "" 1561 "" 1562) 1563 1564(define_insn "cskyv2_one_cmplsi2" 1565 [(set (match_operand:SI 0 "register_operand" "=b,r") 1566 (not:SI (match_operand:SI 1 "register_operand" "0,r")))] 1567 "CSKY_ISA_FEATURE (E2)" 1568 "not %0, %1" 1569 [(set_attr "length" "2,4") 1570 (set_attr "type" "alu,alu")] 1571) 1572 1573(define_insn "ck801_one_cmplsi2" 1574 [(set (match_operand:SI 0 "register_operand" "=r") 1575 (not:SI (match_operand:SI 1 "register_operand" "0")))] 1576 "CSKY_ISA_FEATURE (E1)" 1577 "not %0, %1" 1578 [(set_attr "length" "2") 1579 (set_attr "type" "alu")] 1580) 1581 1582;; ------------------------------------------------------------------------- 1583;; Sign extension instructions 1584;; ------------------------------------------------------------------------- 1585 1586;; One test shows that the following code helps to 1587;; reduce one 'load' and two 'mov'. 1588(define_expand "extendsidi2" 1589 [(set (match_operand:DI 0 "register_operand" "=r") 1590 (match_operand:SI 1 "register_operand" "r"))] 1591 "" 1592 "{ 1593 int low, high; 1594 1595 if (TARGET_BIG_ENDIAN) 1596 low = 4, high = 0; 1597 else 1598 low = 0, high = 4; 1599 1600 emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, operands[0], low), 1601 operands[1])); 1602 1603 emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, operands[0], high), 1604 gen_rtx_ASHIFTRT (SImode, 1605 gen_rtx_SUBREG (SImode, 1606 operands[0], 1607 low), 1608 GEN_INT (31)))); 1609 DONE; 1610 }" 1611) 1612 1613(define_insn "extendhisi2" 1614 [(set (match_operand:SI 0 "register_operand" "=r") 1615 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] 1616 "" 1617 "sexth %0, %1" 1618) 1619 1620(define_insn "*cskyv2_sextend_ldhs" 1621 [(set (match_operand:SI 0 "register_operand" "=r") 1622 (sign_extend:SI (match_operand:HI 1 "csky_simple_mem_operand" "m")))] 1623 "CSKY_ISA_FEATURE (E2)" 1624 "ld.hs\t%0, %1" 1625 [(set_attr "length" "4") 1626 (set_attr "type" "load")] 1627) 1628 1629;; qi -> si 1630(define_insn "extendqisi2" 1631 [(set (match_operand:SI 0 "register_operand" "=r") 1632 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] 1633 "" 1634 "sextb %0, %1" 1635) 1636 1637;; qi -> hi 1638(define_insn "extendqihi2" 1639 [(set (match_operand:HI 0 "register_operand" "=r") 1640 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))] 1641 "" 1642 "sextb %0, %1" 1643) 1644 1645;; ------------------------------------------------------------------------- 1646;; And instructions 1647;; ------------------------------------------------------------------------- 1648 1649(define_expand "andsi3" 1650 [(set (match_operand:SI 0 "register_operand" "") 1651 (and:SI (match_operand:SI 1 "register_operand" "") 1652 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))] 1653 "" 1654 "") 1655 1656(define_insn_and_split "cskyv2_andsi3" 1657 [(set (match_operand:SI 0 "register_operand" "=b,r,r,&r") 1658 (and:SI (match_operand:SI 1 "register_operand" "%0,r,r,r") 1659 (match_operand:SI 2 "csky_arith_any_imm_operand" "b,r,O,i")))] 1660 "CSKY_ISA_FEATURE (E2)" 1661 "@ 1662 and\t%0, %1, %2 1663 and\t%0, %1, %2 1664 andi\t%0, %1, %2 1665 #" 1666 "(CONST_INT_P (operands[2]) 1667 && (operands[2] == const0_rtx 1668 || !csky_arith_O_operand (operands[2], SImode)))" 1669 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))] 1670 { 1671 if (csky_split_and (operands)) 1672 DONE; 1673 } 1674 [(set_attr "length" "2,4,4,8") 1675 (set_attr "type" "alu,alu,alu,alu")] 1676) 1677 1678(define_insn_and_split "ck801_andsi3" 1679 [(set (match_operand:SI 0 "register_operand" "=r,&r") 1680 (and:SI (match_operand:SI 1 "register_operand" "%0,r") 1681 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))] 1682 "CSKY_ISA_FEATURE (E1)" 1683 "@ 1684 and\t%0, %1, %2 1685 #" 1686 "CONST_INT_P (operands[2])" 1687 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))] 1688 { 1689 if (csky_split_and (operands)) 1690 DONE; 1691 } 1692 [(set_attr "length" "2,4") 1693 (set_attr "type" "alu,alu")] 1694) 1695 1696;; Note that the operands for the andnsi3 patterns are reversed compared 1697;; to the actual machine insn: operand 1 is the inverted operand. 1698 1699(define_insn "cskyv2_andnsi3" 1700 [(use (and:SI (not:SI (match_operand:SI 1 "csky_arith_O_operand" "b,r,O")) 1701 (match_operand:SI 2 "register_operand" "0,r,r"))) 1702 (set (match_operand:SI 0 "register_operand" "=b,r,r") 1703 (and:SI (not:SI (match_dup 1)) 1704 (match_dup 2)))] 1705 "CSKY_ISA_FEATURE (E2)" 1706 "@ 1707 andn\t%0, %2, %1 1708 andn\t%0, %2, %1 1709 andni\t%0, %2, %1" 1710 [(set_attr "length" "2,4,4") 1711 (set_attr "type" "alu,alu,alu")] 1712) 1713 1714(define_insn "ck801_andnsi3" 1715 [(use (and:SI (not:SI (match_operand:SI 1 "register_operand" "r")) 1716 (match_operand:SI 2 "register_operand" "0"))) 1717 (set (match_operand:SI 0 "register_operand" "=r") 1718 (and:SI (not:SI (match_dup 1)) 1719 (match_dup 2)))] 1720 "CSKY_ISA_FEATURE (E1)" 1721 "andn\t%0, %2, %1" 1722) 1723 1724(define_expand "anddi3" 1725 [(set (match_operand:DI 0 "register_operand" "") 1726 (and:DI (match_operand:DI 1 "register_operand" "") 1727 (match_operand:DI 2 "csky_arith_any_imm_operand" "")))] 1728 "" 1729 " 1730 { 1731 if (CONST_INT_P (operands[2])) 1732 { 1733 HOST_WIDE_INT ival = INTVAL (operands[2]); 1734 if (ival == (HOST_WIDE_INT) 0xffffffff) 1735 { 1736 emit_move_insn (gen_lowpart (SImode, operands[0]), 1737 gen_lowpart (SImode, operands[1])); 1738 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx); 1739 DONE; 1740 } 1741 else if (ival == (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) -1 << 32)) 1742 { 1743 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx); 1744 emit_move_insn (gen_highpart (SImode, operands[0]), 1745 gen_highpart (SImode, operands[1])); 1746 DONE; 1747 } 1748 else 1749 FAIL; 1750 } 1751 }") 1752 1753 1754 1755(define_insn_and_split "*cskyv2_anddi3" 1756 [(set (match_operand:DI 0 "register_operand" "=&b,&r") 1757 (and:DI (match_operand:DI 1 "register_operand" "%0,r") 1758 (match_operand:DI 2 "register_operand" "b,r")))] 1759 "CSKY_ISA_FEATURE (E2)" 1760 "#" 1761 "reload_completed" 1762 [(const_int 0)] 1763 { 1764 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1765 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1766 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1767 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1768 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1769 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1770 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1771 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1772 1773 emit_insn (gen_cskyv2_andsi3 (l0, l1, l2)); 1774 emit_insn (gen_cskyv2_andsi3 (h0, h1, h2)); 1775 DONE; 1776 } 1777 [(set_attr "length" "4,8")] 1778) 1779 1780(define_insn_and_split "*ck801_anddi3" 1781 [(set (match_operand:DI 0 "register_operand" "=&r") 1782 (and:DI (match_operand:DI 1 "register_operand" "%0") 1783 (match_operand:DI 2 "register_operand" "r")))] 1784 "CSKY_ISA_FEATURE (E1)" 1785 "#" 1786 "reload_completed" 1787 [(const_int 0)] 1788 { 1789 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1790 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1791 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1792 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1793 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1794 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1795 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1796 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1797 1798 emit_insn (gen_ck801_andsi3 (l0, l1, l2)); 1799 emit_insn (gen_ck801_andsi3 (h0, h1, h2)); 1800 DONE; 1801 } 1802 [(set_attr "length" "4")] 1803) 1804 1805 1806;; ------------------------------------------------------------------------- 1807;; Ior instructions 1808;; ------------------------------------------------------------------------- 1809 1810(define_expand "iorsi3" 1811 [(set (match_operand:SI 0 "register_operand" "") 1812 (ior:SI (match_operand:SI 1 "register_operand" "") 1813 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))] 1814 "" 1815 "") 1816 1817(define_insn_and_split "cskyv2_iorsi3" 1818 [(set (match_operand:SI 0 "register_operand" "=b,r,r,&r") 1819 (ior:SI (match_operand:SI 1 "register_operand" "%0,r,r,r") 1820 (match_operand:SI 2 "csky_arith_any_imm_operand" "b, r,I,i")))] 1821 "CSKY_ISA_FEATURE (E2)" 1822 "@ 1823 or\t%0, %1, %2 1824 or\t%0, %1, %2 1825 ori\t%0, %1, %2 1826 #" 1827 "(CONST_INT_P (operands[2]) 1828 && (operands[2] == const0_rtx 1829 || !csky_literal_I_operand (operands[2], SImode)))" 1830 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))] 1831 { 1832 if (csky_split_ior (operands)) 1833 DONE; 1834 } 1835 [(set_attr "length" "2,4,4,8") 1836 (set_attr "type" "alu,alu,alu,alu")] 1837) 1838 1839(define_insn_and_split "ck801_iorsi3" 1840 [(set (match_operand:SI 0 "register_operand" "=r,&r") 1841 (ior:SI (match_operand:SI 1 "register_operand" "%0,r") 1842 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))] 1843 "CSKY_ISA_FEATURE (E1)" 1844 "@ 1845 or\t%0, %1, %2 1846 #" 1847 "CONST_INT_P (operands[2])" 1848 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))] 1849 { 1850 if (csky_split_ior (operands)) 1851 DONE; 1852 } 1853 [(set_attr "length" "2,4") 1854 (set_attr "type" "alu,alu")] 1855) 1856 1857(define_expand "iordi3" 1858 [(set (match_operand:DI 0 "register_operand" "") 1859 (ior:DI (match_operand:DI 1 "register_operand" "") 1860 (match_operand:DI 2 "register_operand" "")))] 1861 "" 1862 "" 1863) 1864 1865(define_insn_and_split "*cskyv2_iordi3" 1866 [(set (match_operand:DI 0 "register_operand" "=&b,&r") 1867 (ior:DI (match_operand:DI 1 "register_operand" "%0, r") 1868 (match_operand:DI 2 "register_operand" "b, r")))] 1869 "CSKY_ISA_FEATURE (E2)" 1870 "#" 1871 "reload_completed" 1872 [(const_int 0)] 1873 { 1874 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1875 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1876 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1877 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1878 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1879 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1880 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1881 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1882 1883 emit_insn (gen_cskyv2_iorsi3 (l0, l1, l2)); 1884 emit_insn (gen_cskyv2_iorsi3 (h0, h1, h2)); 1885 DONE; 1886 } 1887 [(set_attr "length" "4,8")] 1888) 1889 1890(define_insn_and_split "*ck801_iordi3" 1891 [(set (match_operand:DI 0 "register_operand" "=&r") 1892 (ior:DI (match_operand:DI 1 "register_operand" "%0") 1893 (match_operand:DI 2 "register_operand" "r")))] 1894 "CSKY_ISA_FEATURE (E1)" 1895 "#" 1896 "reload_completed" 1897 [(const_int 0)] 1898 { 1899 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1900 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1901 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1902 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1903 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1904 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1905 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1906 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1907 1908 emit_insn (gen_ck801_iorsi3 (l0, l1, l2)); 1909 emit_insn (gen_ck801_iorsi3 (h0, h1, h2)); 1910 DONE; 1911 } 1912 [(set_attr "length" "4")] 1913) 1914 1915 1916;; ------------------------------------------------------------------------- 1917;; Xor instructions 1918;; ------------------------------------------------------------------------- 1919 1920(define_expand "xorsi3" 1921 [(set (match_operand:SI 0 "register_operand" "") 1922 (xor:SI (match_operand:SI 1 "register_operand" "") 1923 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))] 1924 "" 1925 "") 1926 1927(define_insn_and_split "cskyv2_xorsi3" 1928 [(set (match_operand:SI 0 "register_operand" "=b,r,r,&r") 1929 (xor:SI (match_operand:SI 1 "register_operand" "%0,r,r,r") 1930 (match_operand:SI 2 "csky_arith_any_imm_operand" "b, r,O,i")))] 1931 "CSKY_ISA_FEATURE (E2)" 1932 "@ 1933 xor\t%0, %1, %2 1934 xor\t%0, %1, %2 1935 xori\t%0, %1, %2 1936 #" 1937 "(CONST_INT_P (operands[2]) 1938 && (operands[2] == const0_rtx 1939 || !csky_arith_O_operand (operands[2], SImode)))" 1940 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))] 1941 { 1942 if (csky_split_xor (operands)) 1943 DONE; 1944 } 1945 [(set_attr "length" "2,4,4,8") 1946 (set_attr "type" "alu,alu,alu,alu")] 1947) 1948 1949(define_insn_and_split "ck801_xorsi3" 1950 [(set (match_operand:SI 0 "register_operand" "=r,&r") 1951 (xor:SI (match_operand:SI 1 "register_operand" "%0,r") 1952 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))] 1953 "CSKY_ISA_FEATURE (E1)" 1954 "@ 1955 xor\t%0, %1, %2 1956 #" 1957 "CONST_INT_P (operands[2])" 1958 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))] 1959 { 1960 if (csky_split_xor (operands)) 1961 DONE; 1962 } 1963 [(set_attr "length" "2,4") 1964 (set_attr "type" "alu,alu")] 1965) 1966 1967(define_expand "xordi3" 1968 [(set (match_operand:DI 0 "register_operand" "") 1969 (xor:DI (match_operand:DI 1 "register_operand" "") 1970 (match_operand:DI 2 "register_operand" "")))] 1971 "" 1972 "" 1973) 1974 1975(define_insn_and_split "*cskyv2_xordi3" 1976 [(set (match_operand:DI 0 "register_operand" "=&b,&r") 1977 (xor:DI (match_operand:DI 1 "register_operand" "%0, r") 1978 (match_operand:DI 2 "register_operand" "b, r")))] 1979 "CSKY_ISA_FEATURE (E2)" 1980 "#" 1981 "reload_completed" 1982 [(const_int 0)] 1983 { 1984 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 1985 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 1986 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 1987 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 1988 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 1989 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 1990 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 1991 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 1992 1993 emit_insn (gen_cskyv2_xorsi3 (l0, l1, l2)); 1994 emit_insn (gen_cskyv2_xorsi3 (h0, h1, h2)); 1995 DONE; 1996 } 1997 [(set_attr "length" "4,8")] 1998) 1999 2000(define_insn_and_split "*ck801_xordi3" 2001 [(set (match_operand:DI 0 "register_operand" "=&r") 2002 (xor:DI (match_operand:DI 1 "register_operand" "%0") 2003 (match_operand:DI 2 "register_operand" "r")))] 2004 "CSKY_ISA_FEATURE (E1)" 2005 "#" 2006 "reload_completed" 2007 [(const_int 0)] 2008 { 2009 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD; 2010 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0; 2011 rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo); 2012 rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi); 2013 rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo); 2014 rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi); 2015 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo); 2016 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi); 2017 2018 emit_insn (gen_ck801_xorsi3 (l0, l1, l2)); 2019 emit_insn (gen_ck801_xorsi3 (h0, h1, h2)); 2020 DONE; 2021 } 2022 [(set_attr "length" "4")] 2023) 2024 2025;; ------------------------------------------------------------------------- 2026;; Div instructions 2027;; ------------------------------------------------------------------------- 2028 2029(define_insn "divsi3" 2030 [(set (match_operand:SI 0 "register_operand" "=r") 2031 (div:SI (match_operand:SI 1 "register_operand" "r") 2032 (match_operand:SI 2 "register_operand" "r")))] 2033 "TARGET_DIV" 2034 "divs\t%0, %1, %2" 2035) 2036 2037(define_insn "udivsi3" 2038 [(set (match_operand:SI 0 "register_operand" "=r") 2039 (udiv:SI (match_operand:SI 1 "register_operand" "r") 2040 (match_operand:SI 2 "register_operand" "r")))] 2041 "TARGET_DIV" 2042 "divu\t%0, %1, %2" 2043) 2044 2045 2046;; ----------------------------------------------------------------- 2047;; Multiple load and store insns 2048;; ----------------------------------------------------------------- 2049 2050(define_expand "load_multiple" 2051 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 2052 (match_operand:SI 1 "" "")) 2053 (use (match_operand:SI 2 "" ""))])] 2054 "TARGET_MULTIPLE_STLD" 2055 "{ 2056 int regno, count, i; 2057 rtx base,src; 2058 2059 if (GET_CODE (operands[2]) != CONST_INT 2060 || INTVAL (operands[2]) < 2 2061 || INTVAL (operands[2]) > CSKY_MAX_MULTIPLE_STLD 2062 || GET_CODE (operands[1]) != MEM 2063 || !REG_P (XEXP (operands[1], 0)) 2064 || XEXP (operands[1], 0) != stack_pointer_rtx 2065 || GET_CODE (operands[0]) != REG 2066 || (REGNO (XEXP (operands[1], 0)) > REGNO (operands[0]) 2067 && (REGNO (XEXP (operands[1], 0)) 2068 < REGNO (operands[0]) + INTVAL (operands[2])))) 2069 FAIL; 2070 2071 count = INTVAL (operands[2]); 2072 regno = REGNO (operands[0]); 2073 2074 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 2075 2076 base = force_reg (SImode, XEXP (operands[1], 0)); 2077 src = replace_equiv_address (operands[1], base); 2078 2079 for (i = 0; i < count; i++) 2080 XVECEXP (operands[3], 0, i) 2081 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i), 2082 adjust_address_nv (src, SImode, i * 4)); 2083 }" 2084) 2085 2086(define_expand "store_multiple" 2087 [(match_par_dup 3 [(set (match_operand:SI 0 "") 2088 (match_operand:SI 1 "")) 2089 (use (match_operand:SI 2 ""))])] 2090 "TARGET_MULTIPLE_STLD" 2091 "{ 2092 int regno, count, i; 2093 rtx base, dest; 2094 2095 /* Support only storing a constant number of registers to memory and 2096 only if at least two registers. */ 2097 if (GET_CODE (operands[2]) != CONST_INT 2098 || INTVAL (operands[2]) < 2 2099 || INTVAL (operands[2]) > CSKY_MAX_MULTIPLE_STLD 2100 || GET_CODE (operands[0]) != MEM 2101 || !REG_P (XEXP (operands[0], 0)) 2102 || XEXP (operands[0], 0) != stack_pointer_rtx 2103 || GET_CODE (operands[1]) != REG 2104 || (REGNO (XEXP (operands[0], 0)) >= REGNO (operands[1]) 2105 && (REGNO (XEXP (operands[0], 0)) 2106 < REGNO (operands[1]) + INTVAL (operands[2])))) 2107 FAIL; 2108 2109 count = INTVAL (operands[2]); 2110 regno = REGNO (operands[1]); 2111 2112 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 2113 2114 base = force_reg (SImode, XEXP (operands[0], 0)); 2115 dest = replace_equiv_address (operands[0], base); 2116 2117 for (i = 0; i < count; i++) 2118 XVECEXP (operands[3], 0, i) 2119 = gen_rtx_SET (adjust_address_nv (dest, SImode, i * 4), 2120 gen_rtx_REG (SImode, regno + i)); 2121 }" 2122) 2123 2124 2125(define_insn "*csky_ldmsi12" 2126 [(match_parallel 0 "csky_load_multiple_operation" 2127 [(set (match_operand:SI 1 "register_operand" "=r") 2128 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2129 (set (match_operand:SI 3 "register_operand" "=r") 2130 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2131 (set (match_operand:SI 4 "register_operand" "=r") 2132 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2133 (set (match_operand:SI 5 "register_operand" "=r") 2134 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2135 (set (match_operand:SI 6 "register_operand" "=r") 2136 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2137 (set (match_operand:SI 7 "register_operand" "=r") 2138 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2139 (set (match_operand:SI 8 "register_operand" "=r") 2140 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2141 (set (match_operand:SI 9 "register_operand" "=r") 2142 (mem:SI (plus:SI (match_dup 2) (const_int 28)))) 2143 (set (match_operand:SI 10 "register_operand" "=r") 2144 (mem:SI (plus:SI (match_dup 2) (const_int 32)))) 2145 (set (match_operand:SI 11 "register_operand" "=r") 2146 (mem:SI (plus:SI (match_dup 2) (const_int 36)))) 2147 (set (match_operand:SI 12 "register_operand" "=r") 2148 (mem:SI (plus:SI (match_dup 2) (const_int 40)))) 2149 (set (match_operand:SI 13 "register_operand" "=r") 2150 (mem:SI (plus:SI (match_dup 2) (const_int 44)))) 2151 ])] 2152 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 12" 2153 { 2154 static char load_op[256] = {0}; 2155 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2156 const char *reg_rz = reg_names[count]; 2157 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2158 return load_op; 2159 } 2160) 2161 2162(define_insn "*csky_ldmsi11" 2163 [(match_parallel 0 "csky_load_multiple_operation" 2164 [(set (match_operand:SI 1 "register_operand" "=r") 2165 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2166 (set (match_operand:SI 3 "register_operand" "=r") 2167 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2168 (set (match_operand:SI 4 "register_operand" "=r") 2169 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2170 (set (match_operand:SI 5 "register_operand" "=r") 2171 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2172 (set (match_operand:SI 6 "register_operand" "=r") 2173 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2174 (set (match_operand:SI 7 "register_operand" "=r") 2175 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2176 (set (match_operand:SI 8 "register_operand" "=r") 2177 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2178 (set (match_operand:SI 9 "register_operand" "=r") 2179 (mem:SI (plus:SI (match_dup 2) (const_int 28)))) 2180 (set (match_operand:SI 10 "register_operand" "=r") 2181 (mem:SI (plus:SI (match_dup 2) (const_int 32)))) 2182 (set (match_operand:SI 11 "register_operand" "=r") 2183 (mem:SI (plus:SI (match_dup 2) (const_int 36)))) 2184 (set (match_operand:SI 12 "register_operand" "=r") 2185 (mem:SI (plus:SI (match_dup 2) (const_int 40)))) 2186 ])] 2187 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 11" 2188 { 2189 static char load_op[256] = {0}; 2190 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2191 const char *reg_rz = reg_names[count]; 2192 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2193 return load_op; 2194 } 2195) 2196 2197(define_insn "*csky_ldmsi10" 2198 [(match_parallel 0 "csky_load_multiple_operation" 2199 [(set (match_operand:SI 1 "register_operand" "=r") 2200 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2201 (set (match_operand:SI 3 "register_operand" "=r") 2202 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2203 (set (match_operand:SI 4 "register_operand" "=r") 2204 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2205 (set (match_operand:SI 5 "register_operand" "=r") 2206 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2207 (set (match_operand:SI 6 "register_operand" "=r") 2208 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2209 (set (match_operand:SI 7 "register_operand" "=r") 2210 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2211 (set (match_operand:SI 8 "register_operand" "=r") 2212 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2213 (set (match_operand:SI 9 "register_operand" "=r") 2214 (mem:SI (plus:SI (match_dup 2) (const_int 28)))) 2215 (set (match_operand:SI 10 "register_operand" "=r") 2216 (mem:SI (plus:SI (match_dup 2) (const_int 32)))) 2217 (set (match_operand:SI 11 "register_operand" "=r") 2218 (mem:SI (plus:SI (match_dup 2) (const_int 36)))) 2219 ])] 2220 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 10" 2221 { 2222 static char load_op[256] = {0}; 2223 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2224 const char *reg_rz = reg_names[count]; 2225 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2226 return load_op; 2227 } 2228) 2229 2230(define_insn "*csky_ldmsi9" 2231 [(match_parallel 0 "csky_load_multiple_operation" 2232 [(set (match_operand:SI 1 "register_operand" "=r") 2233 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2234 (set (match_operand:SI 3 "register_operand" "=r") 2235 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2236 (set (match_operand:SI 4 "register_operand" "=r") 2237 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2238 (set (match_operand:SI 5 "register_operand" "=r") 2239 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2240 (set (match_operand:SI 6 "register_operand" "=r") 2241 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2242 (set (match_operand:SI 7 "register_operand" "=r") 2243 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2244 (set (match_operand:SI 8 "register_operand" "=r") 2245 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2246 (set (match_operand:SI 9 "register_operand" "=r") 2247 (mem:SI (plus:SI (match_dup 2) (const_int 28)))) 2248 (set (match_operand:SI 10 "register_operand" "=r") 2249 (mem:SI (plus:SI (match_dup 2) (const_int 32)))) 2250 ])] 2251 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 9" 2252 { 2253 static char load_op[256] = {0}; 2254 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2255 const char *reg_rz = reg_names[count]; 2256 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2257 return load_op; 2258 } 2259) 2260 2261(define_insn "*csky_ldmsi8" 2262 [(match_parallel 0 "csky_load_multiple_operation" 2263 [(set (match_operand:SI 1 "register_operand" "=r") 2264 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2265 (set (match_operand:SI 3 "register_operand" "=r") 2266 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2267 (set (match_operand:SI 4 "register_operand" "=r") 2268 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2269 (set (match_operand:SI 5 "register_operand" "=r") 2270 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2271 (set (match_operand:SI 6 "register_operand" "=r") 2272 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2273 (set (match_operand:SI 7 "register_operand" "=r") 2274 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2275 (set (match_operand:SI 8 "register_operand" "=r") 2276 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2277 (set (match_operand:SI 9 "register_operand" "=r") 2278 (mem:SI (plus:SI (match_dup 2) (const_int 28)))) 2279 ])] 2280 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 8" 2281 { 2282 static char load_op[256] = {0}; 2283 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2284 const char *reg_rz = reg_names[count]; 2285 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2286 return load_op; 2287 } 2288) 2289 2290(define_insn "*csky_ldmsi7" 2291 [(match_parallel 0 "csky_load_multiple_operation" 2292 [(set (match_operand:SI 1 "register_operand" "=r") 2293 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2294 (set (match_operand:SI 3 "register_operand" "=r") 2295 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2296 (set (match_operand:SI 4 "register_operand" "=r") 2297 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2298 (set (match_operand:SI 5 "register_operand" "=r") 2299 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2300 (set (match_operand:SI 6 "register_operand" "=r") 2301 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2302 (set (match_operand:SI 7 "register_operand" "=r") 2303 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2304 (set (match_operand:SI 8 "register_operand" "=r") 2305 (mem:SI (plus:SI (match_dup 2) (const_int 24)))) 2306 ])] 2307 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 7" 2308 { 2309 static char load_op[256] = {0}; 2310 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2311 const char *reg_rz = reg_names[count]; 2312 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2313 return load_op; 2314 } 2315) 2316 2317(define_insn "*csky_ldmsi6" 2318 [(match_parallel 0 "csky_load_multiple_operation" 2319 [(set (match_operand:SI 1 "register_operand" "=r") 2320 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2321 (set (match_operand:SI 3 "register_operand" "=r") 2322 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2323 (set (match_operand:SI 4 "register_operand" "=r") 2324 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2325 (set (match_operand:SI 5 "register_operand" "=r") 2326 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2327 (set (match_operand:SI 6 "register_operand" "=r") 2328 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2329 (set (match_operand:SI 7 "register_operand" "=r") 2330 (mem:SI (plus:SI (match_dup 2) (const_int 20)))) 2331 ])] 2332 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 6" 2333 { 2334 static char load_op[256] = {0}; 2335 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2336 const char *reg_rz = reg_names[count]; 2337 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2338 return load_op; 2339 } 2340) 2341 2342 2343(define_insn "*csky_ldmsi5" 2344 [(match_parallel 0 "csky_load_multiple_operation" 2345 [(set (match_operand:SI 1 "register_operand" "=r") 2346 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2347 (set (match_operand:SI 3 "register_operand" "=r") 2348 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2349 (set (match_operand:SI 4 "register_operand" "=r") 2350 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2351 (set (match_operand:SI 5 "register_operand" "=r") 2352 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2353 (set (match_operand:SI 6 "register_operand" "=r") 2354 (mem:SI (plus:SI (match_dup 2) (const_int 16)))) 2355 ])] 2356 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 5" 2357 { 2358 static char load_op[256] = {0}; 2359 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2360 const char *reg_rz = reg_names[count]; 2361 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2362 return load_op; 2363 } 2364) 2365 2366 2367(define_insn "*csky_ldmsi4" 2368 [(match_parallel 0 "csky_load_multiple_operation" 2369 [(set (match_operand:SI 1 "register_operand" "=r") 2370 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2371 (set (match_operand:SI 3 "register_operand" "=r") 2372 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2373 (set (match_operand:SI 4 "register_operand" "=r") 2374 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2375 (set (match_operand:SI 5 "register_operand" "=r") 2376 (mem:SI (plus:SI (match_dup 2) (const_int 12)))) 2377 ])] 2378 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 4" 2379 { 2380 static char load_op[256] = {0}; 2381 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2382 const char *reg_rz = reg_names[count]; 2383 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2384 return load_op; 2385 } 2386) 2387 2388 2389(define_insn "*csky_ldmsi3" 2390 [(match_parallel 0 "csky_load_multiple_operation" 2391 [(set (match_operand:SI 1 "register_operand" "=r") 2392 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2393 (set (match_operand:SI 3 "register_operand" "=r") 2394 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2395 (set (match_operand:SI 4 "register_operand" "=r") 2396 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 2397 ])] 2398 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 3" 2399 { 2400 static char load_op[256] = {0}; 2401 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2402 const char *reg_rz = reg_names[count]; 2403 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2404 return load_op; 2405 } 2406) 2407 2408 2409(define_insn "*csky_ldmsi2" 2410 [(match_parallel 0 "csky_load_multiple_operation" 2411 [(set (match_operand:SI 1 "register_operand" "=r") 2412 (mem:SI (match_operand:SI 2 "register_operand" "r"))) 2413 (set (match_operand:SI 3 "register_operand" "=r") 2414 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 2415 ])] 2416 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 2" 2417 { 2418 static char load_op[256] = {0}; 2419 int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1; 2420 const char *reg_rz = reg_names[count]; 2421 sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz); 2422 return load_op; 2423 } 2424) 2425 2426(define_insn "*csky_stmsi12" 2427 [(match_parallel 0 "csky_store_multiple_operation" 2428 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2429 (match_operand:SI 2 "register_operand" "r")) 2430 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2431 (match_operand:SI 3 "register_operand" "r")) 2432 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2433 (match_operand:SI 4 "register_operand" "r")) 2434 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2435 (match_operand:SI 5 "register_operand" "r")) 2436 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2437 (match_operand:SI 6 "register_operand" "r")) 2438 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2439 (match_operand:SI 7 "register_operand" "r")) 2440 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2441 (match_operand:SI 8 "register_operand" "r")) 2442 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 2443 (match_operand:SI 9 "register_operand" "r")) 2444 (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) 2445 (match_operand:SI 10 "register_operand" "r")) 2446 (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) 2447 (match_operand:SI 11 "register_operand" "r")) 2448 (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) 2449 (match_operand:SI 12 "register_operand" "r")) 2450 (set (mem:SI (plus:SI (match_dup 1) (const_int 44))) 2451 (match_operand:SI 13 "register_operand" "r")) 2452 ])] 2453 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 12" 2454 { 2455 static char load_op[256] = {0}; 2456 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2457 const char *reg_rz = reg_names[end]; 2458 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2459 return load_op; 2460 } 2461) 2462 2463 2464(define_insn "*csky_stmsi11" 2465 [(match_parallel 0 "csky_store_multiple_operation" 2466 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2467 (match_operand:SI 2 "register_operand" "r")) 2468 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2469 (match_operand:SI 3 "register_operand" "r")) 2470 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2471 (match_operand:SI 4 "register_operand" "r")) 2472 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2473 (match_operand:SI 5 "register_operand" "r")) 2474 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2475 (match_operand:SI 6 "register_operand" "r")) 2476 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2477 (match_operand:SI 7 "register_operand" "r")) 2478 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2479 (match_operand:SI 8 "register_operand" "r")) 2480 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 2481 (match_operand:SI 9 "register_operand" "r")) 2482 (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) 2483 (match_operand:SI 10 "register_operand" "r")) 2484 (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) 2485 (match_operand:SI 11 "register_operand" "r")) 2486 (set (mem:SI (plus:SI (match_dup 1) (const_int 40))) 2487 (match_operand:SI 12 "register_operand" "r")) 2488 ])] 2489 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 11" 2490 { 2491 static char load_op[256] = {0}; 2492 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2493 const char *reg_rz = reg_names[end]; 2494 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2495 return load_op; 2496 } 2497) 2498 2499 2500(define_insn "*csky_stmsi10" 2501 [(match_parallel 0 "csky_store_multiple_operation" 2502 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2503 (match_operand:SI 2 "register_operand" "r")) 2504 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2505 (match_operand:SI 3 "register_operand" "r")) 2506 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2507 (match_operand:SI 4 "register_operand" "r")) 2508 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2509 (match_operand:SI 5 "register_operand" "r")) 2510 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2511 (match_operand:SI 6 "register_operand" "r")) 2512 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2513 (match_operand:SI 7 "register_operand" "r")) 2514 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2515 (match_operand:SI 8 "register_operand" "r")) 2516 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 2517 (match_operand:SI 9 "register_operand" "r")) 2518 (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) 2519 (match_operand:SI 10 "register_operand" "r")) 2520 (set (mem:SI (plus:SI (match_dup 1) (const_int 36))) 2521 (match_operand:SI 11 "register_operand" "r")) 2522 ])] 2523 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 10" 2524 { 2525 static char load_op[256] = {0}; 2526 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2527 const char *reg_rz = reg_names[end]; 2528 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2529 return load_op; 2530 } 2531) 2532 2533 2534(define_insn "*csky_stmsi9" 2535 [(match_parallel 0 "csky_store_multiple_operation" 2536 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2537 (match_operand:SI 2 "register_operand" "r")) 2538 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2539 (match_operand:SI 3 "register_operand" "r")) 2540 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2541 (match_operand:SI 4 "register_operand" "r")) 2542 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2543 (match_operand:SI 5 "register_operand" "r")) 2544 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2545 (match_operand:SI 6 "register_operand" "r")) 2546 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2547 (match_operand:SI 7 "register_operand" "r")) 2548 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2549 (match_operand:SI 8 "register_operand" "r")) 2550 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 2551 (match_operand:SI 9 "register_operand" "r")) 2552 (set (mem:SI (plus:SI (match_dup 1) (const_int 32))) 2553 (match_operand:SI 10 "register_operand" "r")) 2554 ])] 2555 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 9" 2556 { 2557 static char load_op[256] = {0}; 2558 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2559 const char *reg_rz = reg_names[end]; 2560 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2561 return load_op; 2562 } 2563) 2564 2565 2566(define_insn "*csky_stmsi8" 2567 [(match_parallel 0 "csky_store_multiple_operation" 2568 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2569 (match_operand:SI 2 "register_operand" "r")) 2570 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2571 (match_operand:SI 3 "register_operand" "r")) 2572 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2573 (match_operand:SI 4 "register_operand" "r")) 2574 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2575 (match_operand:SI 5 "register_operand" "r")) 2576 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2577 (match_operand:SI 6 "register_operand" "r")) 2578 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2579 (match_operand:SI 7 "register_operand" "r")) 2580 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2581 (match_operand:SI 8 "register_operand" "r")) 2582 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 2583 (match_operand:SI 9 "register_operand" "r")) 2584 ])] 2585 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 8" 2586 { 2587 static char load_op[256] = {0}; 2588 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2589 const char *reg_rz = reg_names[end]; 2590 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2591 return load_op; 2592 } 2593) 2594 2595 2596(define_insn "*csky_stmsi7" 2597 [(match_parallel 0 "csky_store_multiple_operation" 2598 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2599 (match_operand:SI 2 "register_operand" "r")) 2600 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2601 (match_operand:SI 3 "register_operand" "r")) 2602 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2603 (match_operand:SI 4 "register_operand" "r")) 2604 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2605 (match_operand:SI 5 "register_operand" "r")) 2606 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2607 (match_operand:SI 6 "register_operand" "r")) 2608 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2609 (match_operand:SI 7 "register_operand" "r")) 2610 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 2611 (match_operand:SI 8 "register_operand" "r")) 2612 ])] 2613 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 7" 2614 { 2615 static char load_op[256] = {0}; 2616 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2617 const char *reg_rz = reg_names[end]; 2618 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2619 return load_op; 2620 } 2621) 2622 2623 2624(define_insn "*csky_stmsi6" 2625 [(match_parallel 0 "csky_store_multiple_operation" 2626 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2627 (match_operand:SI 2 "register_operand" "r")) 2628 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2629 (match_operand:SI 3 "register_operand" "r")) 2630 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2631 (match_operand:SI 4 "register_operand" "r")) 2632 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2633 (match_operand:SI 5 "register_operand" "r")) 2634 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2635 (match_operand:SI 6 "register_operand" "r")) 2636 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 2637 (match_operand:SI 7 "register_operand" "r")) 2638 ])] 2639 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 6" 2640 { 2641 static char load_op[256] = {0}; 2642 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2643 const char *reg_rz = reg_names[end]; 2644 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2645 return load_op; 2646 } 2647) 2648 2649(define_insn "*csky_stmsi5" 2650 [(match_parallel 0 "csky_store_multiple_operation" 2651 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2652 (match_operand:SI 2 "register_operand" "r")) 2653 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2654 (match_operand:SI 3 "register_operand" "r")) 2655 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2656 (match_operand:SI 4 "register_operand" "r")) 2657 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2658 (match_operand:SI 5 "register_operand" "r")) 2659 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 2660 (match_operand:SI 6 "register_operand" "r")) 2661 ])] 2662 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 5" 2663 { 2664 static char load_op[256] = {0}; 2665 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2666 const char *reg_rz = reg_names[end]; 2667 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2668 return load_op; 2669 } 2670) 2671 2672 2673(define_insn "*csky_stmsi4" 2674 [(match_parallel 0 "csky_store_multiple_operation" 2675 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2676 (match_operand:SI 2 "register_operand" "r")) 2677 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2678 (match_operand:SI 3 "register_operand" "r")) 2679 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2680 (match_operand:SI 4 "register_operand" "r")) 2681 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 2682 (match_operand:SI 5 "register_operand" "r")) 2683 ])] 2684 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 4" 2685 { 2686 static char load_op[256] = {0}; 2687 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2688 const char *reg_rz = reg_names[end]; 2689 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2690 return load_op; 2691 } 2692) 2693 2694 2695(define_insn "*csky_stmsi3" 2696 [(match_parallel 0 "csky_store_multiple_operation" 2697 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2698 (match_operand:SI 2 "register_operand" "r")) 2699 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2700 (match_operand:SI 3 "register_operand" "r")) 2701 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 2702 (match_operand:SI 4 "register_operand" "r")) 2703 ])] 2704 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 3" 2705 { 2706 static char load_op[256] = {0}; 2707 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2708 const char *reg_rz = reg_names[end]; 2709 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2710 return load_op; 2711 } 2712) 2713 2714 2715(define_insn "*csky_stmsi2" 2716 [(match_parallel 0 "csky_store_multiple_operation" 2717 [(set (mem:SI (match_operand:SI 1 "register_operand" "r")) 2718 (match_operand:SI 2 "register_operand" "r")) 2719 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 2720 (match_operand:SI 3 "register_operand" "r")) 2721 ])] 2722 "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 2" 2723 { 2724 static char load_op[256] = {0}; 2725 int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1; 2726 const char *reg_rz = reg_names[end]; 2727 sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz); 2728 return load_op; 2729 } 2730) 2731 2732 2733;; ------------------------------------------------------------------------ 2734;; Jump and linkage insns 2735;; ------------------------------------------------------------------------ 2736 2737(define_expand "tablejump" 2738 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r")) 2739 (use (label_ref (match_operand 1 "" "")))])] 2740 "" 2741 " 2742 if (flag_pic) 2743 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], 2744 pic_offset_table_rtx, NULL_RTX, 2745 1, OPTAB_DIRECT); 2746 " 2747) 2748 2749(define_insn "*tablejump" 2750 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 2751 (use (label_ref (match_operand 1 "" "")))] 2752 "" 2753 "jmp %0" 2754 [(set_attr "type" "branch_jmp")] 2755) 2756 2757(define_expand "jump" 2758 [(set (pc) (label_ref (match_operand 0 "" "")))] 2759 "" 2760 "" 2761) 2762 2763(define_insn "*csky_jump" 2764 [(set (pc) (label_ref (match_operand 0 "" "")))] 2765 "CSKY_ISA_FEATURE (E2)" 2766 "jbr %l0" 2767 [(set_attr "type" "branch")] 2768) 2769 2770;; The length of bsr is not really 5; it's used to distinguish from br32. 2771;; Since the length attribute is treated specially it doesn't seem possible 2772;; to compute the far_jump attribute directly and use that. 2773 2774(define_insn "*ck801_ck802_jump" 2775 [(set (pc) (label_ref (match_operand 0 "" "")))] 2776 "CSKY_ISA_FEATURE (E1) || CSKY_ISA_FEATURE (E2)" 2777 "*{ 2778 if (get_attr_length (insn) != 5) 2779 return \"jbr\\t%l0\"; 2780 else 2781 return \"bsr\\t%l0\\t//far jump\"; 2782 }" 2783 [(set_attr "type" "branch") 2784 (set (attr "far_jump") 2785 (if_then_else 2786 (eq_attr "length" "5") 2787 (const_string "yes") 2788 (const_string "no"))) 2789 (set (attr "length") 2790 (if_then_else 2791 (and (ge (minus (match_dup 0) (pc)) (const_int -1024)) 2792 (le (minus (match_dup 0) (pc)) (const_int 1022))) 2793 (const_int 2) 2794 (if_then_else 2795 (and (ge (minus (match_dup 0) (pc)) (const_int -65536)) 2796 (le (minus (match_dup 0) (pc)) (const_int 65534))) 2797 (const_int 4) 2798 (const_int 5))))] 2799) 2800 2801(define_insn "indirect_jump" 2802 [(set (pc) (match_operand:SI 0 "register_operand" "b,r"))] 2803 "" 2804 "@ 2805 jmp\t%0 2806 jmp\t%0" 2807 [(set_attr "length" "2,4") 2808 (set_attr "type" "branch_jmp")] 2809) 2810 2811 2812;; ------------------------------------------------------------------------ 2813;; Conditional jump insns 2814;; ------------------------------------------------------------------------ 2815 2816(define_expand "cbranchsi4" 2817 [(set (pc) 2818 (if_then_else (match_operator 0 "ordered_comparison_operator" 2819 [(match_operand:SI 1 "csky_compare_operand") 2820 (match_operand:SI 2 "nonmemory_operand")]) 2821 (label_ref (match_operand 3 "")) 2822 (pc)))] 2823 "" 2824 "{ 2825 enum rtx_code code = GET_CODE (operands[0]); 2826 2827 if (CSKY_ISA_FEATURE (2E3) 2828 && (code == LE || code == LT || code == GT 2829 || code == GE || code == EQ || code == NE) 2830 && operands[2] == const0_rtx) 2831 { 2832 /* These cases match the jbez, jbnez, etc insns below. 2833 TODO: Handling this in the expander is suboptimal since it 2834 fails to detect cases where the constant 0 would fall out 2835 from subsequent forward propagation or loop optimizers; maybe 2836 it would be better to have a splitter here, but when to split? */ 2837 } 2838 else 2839 { 2840 bool invert = csky_emit_compare (code, operands[1], operands[2]); 2841 2842 if (invert) 2843 emit_jump_insn (gen_csky_jbf (operands[3])); 2844 else 2845 emit_jump_insn (gen_csky_jbt (operands[3])); 2846 DONE; 2847 } 2848 }" 2849) 2850 2851(define_insn "csky_jbt" 2852 [(set (pc) 2853 (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2854 (label_ref (match_operand 0 "" "")) 2855 (pc)))] 2856 "CSKY_ISA_FEATURE (2E3)" 2857 "jbt\t%l0" 2858 [(set_attr "type" "cbranch")] 2859) 2860 2861(define_insn "csky_jbf" 2862 [(set (pc) 2863 (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2864 (label_ref (match_operand 0 "" "")) 2865 (pc)))] 2866 "CSKY_ISA_FEATURE (2E3)" 2867 "jbf\t%l0" 2868 [(set_attr "type" "cbranch")] 2869) 2870 2871 2872;;; CK802 has 32-bit jbt/jbf instructions, but no insn other 2873;;; than bsr for far jumps. 2874 2875(define_insn "ck802_jbt" 2876 [(set (pc) (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2877 (label_ref (match_operand 0 "" "")) 2878 (pc)))] 2879 "CSKY_ISA_FEATURE (E2)" 2880 { 2881 if (get_attr_length (insn) == 6) 2882 return \"jbf\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\"; 2883 else 2884 return \"jbt\\t%l0\"; 2885 } 2886 [(set_attr "type" "cbranch") 2887 (set (attr "far_jump") 2888 (if_then_else 2889 (eq_attr "length" "6") 2890 (const_string "yes") 2891 (const_string "no"))) 2892 (set (attr "length") 2893 (if_then_else 2894 (and (ge (minus (match_dup 0) (pc)) (const_int -1024)) 2895 (le (minus (match_dup 0) (pc)) (const_int 1022))) 2896 (const_int 2) 2897 (if_then_else 2898 (and (ge (minus (match_dup 0) (pc)) (const_int -65534)) 2899 (le (minus (match_dup 0) (pc)) (const_int 65534))) 2900 (const_int 4) 2901 (const_int 6))))] 2902) 2903 2904(define_insn "ck802_jbf" 2905 [(set (pc) (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2906 (label_ref (match_operand 0 "" "")) 2907 (pc)))] 2908 "CSKY_ISA_FEATURE (E2)" 2909 { 2910 if (get_attr_length (insn) == 6) 2911 return \"jbt\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\"; 2912 else 2913 return \"jbf\\t%l0\"; 2914 } 2915 [(set_attr "type" "cbranch") 2916 (set (attr "far_jump") 2917 (if_then_else 2918 (eq_attr "length" "6") 2919 (const_string "yes") 2920 (const_string "no"))) 2921 (set (attr "length") 2922 (if_then_else 2923 (and (ge (minus (match_dup 0) (pc)) (const_int -1024)) 2924 (le (minus (match_dup 0) (pc)) (const_int 1022))) 2925 (const_int 2) 2926 (if_then_else 2927 (and (ge (minus (match_dup 0) (pc)) (const_int -65534)) 2928 (le (minus (match_dup 0) (pc)) (const_int 65534))) 2929 (const_int 4) 2930 (const_int 6))))] 2931) 2932 2933;; The length of the bsr case is not really 7; it's used to distinguish 2934;; from br32. 2935;; Note that we have to adjust the backward range of the jbr case to 2936;; account for the jbf in front of it. 2937(define_insn "ck801_jbt" 2938 [(set (pc) (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2939 (label_ref (match_operand 0 "" "")) 2940 (pc)))] 2941 "CSKY_ISA_FEATURE (E1)" 2942 { 2943 if (get_attr_length (insn) == 6) 2944 return \"jbf\\t.LCB%=\;jbr\\t%l0\\n.LCB%=:\"; 2945 else if (get_attr_length (insn) == 7) 2946 return \"jbf\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\"; 2947 else 2948 return \"jbt\\t%l0\"; 2949 } 2950 [(set_attr "type" "cbranch") 2951 (set (attr "far_jump") 2952 (if_then_else 2953 (eq_attr "length" "7") 2954 (const_string "yes") 2955 (const_string "no"))) 2956 (set (attr "length") 2957 (if_then_else 2958 (and (ge (minus (match_dup 0) (pc)) (const_int -1024)) 2959 (le (minus (match_dup 0) (pc)) (const_int 1022))) 2960 (const_int 2) 2961 (if_then_else 2962 (and (ge (minus (match_dup 0) (pc)) (const_int -65534)) 2963 (le (minus (match_dup 0) (pc)) (const_int 65534))) 2964 (const_int 6) 2965 (const_int 7))))] 2966) 2967 2968(define_insn "ck801_jbf" 2969 [(set (pc) 2970 (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0)) 2971 (label_ref (match_operand 0 "" "")) 2972 (pc)))] 2973 "CSKY_ISA_FEATURE (E1)" 2974 { 2975 if (get_attr_length (insn) == 6) 2976 return \"jbt\\t.LCB%=\;jbr\\t%l0\\n.LCB%=:\"; 2977 else if (get_attr_length (insn) == 7) 2978 return \"jbt\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\"; 2979 else 2980 return \"jbf\\t%l0\"; 2981 } 2982 [(set_attr "type" "cbranch") 2983 (set (attr "far_jump") 2984 (if_then_else 2985 (eq_attr "length" "7") 2986 (const_string "yes") 2987 (const_string "no"))) 2988 (set (attr "length") 2989 (if_then_else 2990 (and (ge (minus (match_dup 0) (pc)) (const_int -1024)) 2991 (le (minus (match_dup 0) (pc)) (const_int 1022))) 2992 (const_int 2) 2993 (if_then_else 2994 (and (ge (minus (match_dup 0) (pc)) (const_int -65534)) 2995 (le (minus (match_dup 0) (pc)) (const_int 65534))) 2996 (const_int 6) 2997 (const_int 7))))] 2998) 2999 3000(define_code_iterator zero_cond [lt le gt ge eq ne]) 3001 3002(define_code_attr inst [(lt "jblz") (le "jblsz") (gt "jbhz") (ge "jbhsz") (eq "jbez") (ne "jbnez")]) 3003 3004(define_insn "*<inst>" 3005 [(set (pc) 3006 (if_then_else (zero_cond (match_operand:SI 0 "register_operand" "r") 3007 (const_int 0)) 3008 (label_ref (match_operand 1 "" "")) 3009 (pc)))] 3010 "CSKY_ISA_FEATURE (2E3)" 3011 "<inst>\t%0, %l1" 3012 [(set_attr "type" "cbranch")] 3013) 3014 3015;; ------------------------------------------------------------------------ 3016;; return insns 3017;; ------------------------------------------------------------------------ 3018 3019(define_insn "simple_return" 3020 [(simple_return)] 3021 "reload_completed" 3022 "* 3023 return csky_output_return_instruction (); 3024 " 3025) 3026 3027(define_expand "eh_return" 3028 [(use (match_operand 0 "general_operand" ""))] 3029 "" 3030 "{ 3031 emit_insn (gen_csky_eh_return (operands[0])); 3032 DONE; 3033 }" 3034) 3035 3036;; We can't expand this before we know where the link register is stored. 3037(define_insn_and_split "csky_eh_return" 3038 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 3039 VUNSPEC_EH_RETURN) 3040 (clobber (match_scratch:SI 1 "=&r"))] 3041 "" 3042 "#" 3043 "reload_completed" 3044 [(const_int 0)] 3045 "{ 3046 csky_set_eh_return_address (operands[0], operands[1]); 3047 DONE; 3048 }" 3049) 3050 3051;; ------------------------------------------------------------------------- 3052;; SImode signed integer comparisons 3053;; ------------------------------------------------------------------------- 3054 3055(define_insn "*cmpnesi_r" 3056 [(set (reg:CC CSKY_CC_REGNUM) 3057 (ne:CC (match_operand:SI 0 "register_operand" "b,r") 3058 (match_operand:SI 1 "register_operand" "b,r")))] 3059 "" 3060 "@ 3061 cmpne\t%0, %1 3062 cmpne\t%0, %1" 3063 [(set_attr "length" "2,4") 3064 (set_attr "type" "cmp")] 3065) 3066 3067;; cmpnei range is 0-31 for Smart mode. 3068(define_insn "smart_cmpnesi_i" 3069 [(set (reg:CC CSKY_CC_REGNUM) 3070 (ne:CC (match_operand:SI 0 "register_operand" "a") 3071 (match_operand:SI 1 "csky_literal_K_operand" "K")))] 3072 "TARGET_MINI_REGISTERS" 3073 "cmpnei\t%0, %1" 3074 [(set_attr "type" "cmp")] 3075) 3076 3077;; cmpnei range is 0 - 65536 for Fast mode. 3078(define_insn "fast_cmpnesi_i" 3079 [(set (reg:CC CSKY_CC_REGNUM) 3080 (ne:CC (match_operand:SI 0 "register_operand" "r") 3081 (match_operand:SI 1 "csky_literal_I_operand" "I")))] 3082 "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)" 3083 "cmpnei\t%0, %1" 3084 [(set_attr "type" "cmp")] 3085) 3086 3087(define_insn "*cmpgtsi" 3088 [(set (reg:CC CSKY_CC_REGNUM) 3089 (gt:CC (match_operand:SI 0 "register_operand" "b,r") 3090 (match_operand:SI 1 "register_operand" "b,r")))] 3091 "" 3092 "cmplt\t%1, %0" 3093 [(set_attr "length" "2,4") 3094 (set_attr "type" "cmp")] 3095) 3096 3097(define_insn "cmpltsi_r" 3098 [(set (reg:CC CSKY_CC_REGNUM) 3099 (lt:CC (match_operand:SI 0 "register_operand" "b,r") 3100 (match_operand:SI 1 "register_operand" "b,r")))] 3101 "" 3102 "cmplt\t%0, %1" 3103 [(set_attr "length" "2,4") 3104 (set_attr "type" "cmp")] 3105) 3106 3107;; cmplti range is 1-32 for Smart mode. 3108(define_insn "*smart_cmpltsi_i" 3109 [(set (reg:CC CSKY_CC_REGNUM) 3110 (lt:CC (match_operand:SI 0 "register_operand" "a") 3111 (match_operand:SI 1 "csky_literal_J_operand" "J")))] 3112 "TARGET_MINI_REGISTERS" 3113 "cmplti\t%0, %1" 3114 [(set_attr "length" "2") 3115 (set_attr "type" "cmp")] 3116) 3117 3118 3119;; cmplti range is 1-65536 for Fast mode. 3120(define_insn "*fast_cmpltsi_i" 3121 [(set (reg:CC CSKY_CC_REGNUM) 3122 (lt:CC (match_operand:SI 0 "register_operand" "a,r") 3123 (match_operand:SI 1 "csky_literal_Uk_operand" "J,Uk")))] 3124 "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)" 3125 "cmplti\t%0, %1" 3126 [(set_attr "length" "2,4") 3127 (set_attr "type" "cmp")] 3128) 3129 3130; Covers cmplti x,0. 3131(define_insn "*cskyv2_cmpltsi_0" 3132 [(set (reg:CC CSKY_CC_REGNUM) 3133 (lt:CC (match_operand:SI 0 "register_operand" "a,r") 3134 (const_int 0)))] 3135 "CSKY_ISA_FEATURE (E2)" 3136 "btsti\t%0, 31" 3137 [(set_attr "length" "2,4") 3138 (set_attr "type" "cmp")] 3139) 3140 3141(define_insn "*ck801_cmpltsi_0" 3142 [(set (reg:CC CSKY_CC_REGNUM) 3143 (lt:CC (match_operand:SI 0 "register_operand" "a") 3144 (const_int 0)))] 3145 "CSKY_ISA_FEATURE (E1)" 3146 "btsti\t%0, 31" 3147 [(set_attr "type" "cmp")] 3148) 3149 3150;; Decrement and test instructions. 3151;; In theory decne could be used in conjunction with jbt to implement 3152;; doloop_end, but that seems to encourage the loop optimizer to introduce 3153;; an additional induction variable and doesn't actually result in tighter 3154;; loop code for that reason. 3155 3156(define_insn "*cskyv2_declt" 3157 [(set (match_operand:SI 0 "register_operand" "=r") 3158 (plus:SI (match_operand:SI 1 "register_operand" "r") 3159 (match_operand:SI 2 "const_int_operand" "Uh"))) 3160 (set (reg:CC CSKY_CC_REGNUM) 3161 (lt:CC (plus:SI (match_dup 1) (match_dup 2)) 3162 (const_int 0)))] 3163 "CSKY_ISA_FEATURE (2E3)" 3164 "declt\t%0, %1, %M2" 3165) 3166 3167(define_insn "*cskyv2_decgt" 3168 [(set (match_operand:SI 0 "register_operand" "=r") 3169 (plus:SI (match_operand:SI 1 "register_operand" "r") 3170 (match_operand:SI 2 "const_int_operand" "Uh"))) 3171 (set (reg:CC CSKY_CC_REGNUM) 3172 (gt:CC (plus:SI (match_dup 1) (match_dup 2)) 3173 (const_int 0)))] 3174 "CSKY_ISA_FEATURE (2E3)" 3175 "decgt\t%0, %1, %M2" 3176) 3177 3178(define_insn "*cskyv2_decne" 3179 [(set (match_operand:SI 0 "register_operand" "=r") 3180 (plus:SI (match_operand:SI 1 "register_operand" "r") 3181 (match_operand:SI 2 "const_int_operand" "Uh"))) 3182 (set (reg:CC CSKY_CC_REGNUM) 3183 (ne:CC (plus:SI (match_dup 1) (match_dup 2)) 3184 (const_int 0)))] 3185 "CSKY_ISA_FEATURE (2E3)" 3186 "decne\t%0, %1, %M2" 3187) 3188 3189;; ------------------------------------------------------------------------- 3190;; SImode unsigned integer comparisons 3191;; ------------------------------------------------------------------------- 3192 3193(define_insn "cmpgeusi_r" 3194 [(set (reg:CC CSKY_CC_REGNUM) 3195 (geu:CC (match_operand:SI 0 "register_operand" "b,r") 3196 (match_operand:SI 1 "register_operand" "b,r")))] 3197 "" 3198 "cmphs\t%0, %1" 3199 [(set_attr "length" "2,4") 3200 (set_attr "type" "cmp")] 3201) 3202 3203(define_insn "*smart_cmpgeusi_i" 3204 [(set (reg:CC CSKY_CC_REGNUM) 3205 (geu:CC (match_operand:SI 0 "register_operand" "a") 3206 (match_operand:SI 1 "csky_literal_J_operand" "J")))] 3207 "TARGET_MINI_REGISTERS" 3208 "cmphsi\t%0, %1" 3209 [(set_attr "length" "2") 3210 (set_attr "type" "cmp")] 3211) 3212 3213(define_insn "*fast_cmpgeusi_i" 3214 [(set (reg:CC CSKY_CC_REGNUM) 3215 (geu:CC (match_operand:SI 0 "register_operand" "a,r") 3216 (match_operand:SI 1 "csky_literal_Uk_operand" "J,Uk")))] 3217 "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)" 3218 "cmphsi\t%0, %1" 3219 [(set_attr "length" "2,4") 3220 (set_attr "type" "cmp")] 3221) 3222 3223(define_insn "*cmpleusi" 3224 [(set (reg:CC CSKY_CC_REGNUM) 3225 (leu:CC (match_operand:SI 0 "register_operand" "b,r") 3226 (match_operand:SI 1 "register_operand" "b,r")))] 3227 "" 3228 "cmphs\t%1, %0" 3229 [(set_attr "length" "2,4") 3230 (set_attr "type" "cmp")] 3231) 3232 3233;; ------------------------------------------------------------------------- 3234;; Function call insns 3235;; ------------------------------------------------------------------------- 3236 3237(define_expand "call" 3238 [(parallel [(call (match_operand:SI 0 "" "") (match_operand 1 "" "")) 3239 (clobber (reg:SI CSKY_LR_REGNUM))])] 3240 "" 3241 " 3242 { 3243 rtx pic_ref; 3244 rtx addr_ref = XEXP (operands[0], 0); 3245 3246 if (flag_pic 3247 && (CONSTANT_P (addr_ref) 3248 || csky_symbol_mentioned_p (addr_ref) 3249 || csky_label_mentioned_p (addr_ref))) 3250 { 3251 pic_ref = csky_legitimize_pic_address (addr_ref, 0, false); 3252 operands[0] = gen_rtx_MEM (GET_MODE (pic_ref), pic_ref); 3253 } 3254 3255 if (GET_CODE (operands[0]) == MEM 3256 && ! register_operand (XEXP (operands[0], 0), SImode) 3257 && ! csky_symbolic_address_p (XEXP (operands[0], 0)) 3258 && ! (flag_pic 3259 && csky_unspec_operand (XEXP (operands[0], 0), SImode))) 3260 operands[0] = gen_rtx_MEM (GET_MODE (operands[0]), 3261 force_reg (Pmode, XEXP (operands[0], 0))); 3262 }" 3263) 3264 3265 3266(define_insn "*call_internal" 3267 [(call (mem:SI (match_operand:SI 0 "csky_call_address_operand" "b,r,S")) 3268 (match_operand 1 "" "")) 3269 (clobber (reg:SI CSKY_LR_REGNUM))] 3270 "" 3271 "@ 3272 jsr\t%0 3273 jsr\t%0 3274 jbsr\t%0" 3275 [(set_attr "length" "2,4,4") 3276 (set_attr "type" "call_jsr,call_jsr,call")] 3277) 3278 3279(define_insn "*call_internal_pic" 3280 [(call (mem:SI (match_operand:SI 0 "csky_unspec_operand" "X")) 3281 (match_operand 1 "" "")) 3282 (clobber (reg:SI CSKY_LR_REGNUM))] 3283 "flag_pic" 3284 "* return csky_output_call (operands, 0);" 3285 [(set_attr "length" "4")] 3286) 3287 3288(define_expand "call_value" 3289 [(parallel [(set (match_operand 0 "register_operand" "") 3290 (call (match_operand:SI 1 "" "") (match_operand 2 "" ""))) 3291 (clobber (reg:SI CSKY_LR_REGNUM))])] 3292 "" 3293 "{ 3294 rtx pic_ref; 3295 rtx addr_ref = XEXP (operands[1], 0); 3296 3297 if (flag_pic 3298 && (CONSTANT_P (addr_ref) 3299 || csky_symbol_mentioned_p (addr_ref) 3300 || csky_label_mentioned_p (addr_ref))) 3301 { 3302 pic_ref = csky_legitimize_pic_address (addr_ref, 0, false); 3303 operands[1] = gen_rtx_MEM (GET_MODE (pic_ref), pic_ref); 3304 } 3305 3306 if (GET_CODE (operands[1]) == MEM 3307 && ! register_operand (XEXP (operands[1], 0), SImode) 3308 && ! csky_symbolic_address_p (XEXP (operands[1], 0)) 3309 && ! (flag_pic 3310 && csky_unspec_operand (XEXP (operands[1], 0), SImode))) 3311 operands[1] = gen_rtx_MEM (GET_MODE (operands[1]), 3312 force_reg (Pmode, XEXP (operands[1], 0))); 3313 }") 3314 3315;; Call subroutine returning any type. 3316 3317(define_expand "untyped_call" 3318 [(parallel [(call (match_operand 0 "" "") 3319 (const_int 0)) 3320 (match_operand 1 "" "") 3321 (match_operand 2 "" "")])] 3322 "" 3323{ 3324 int i; 3325 3326 emit_call_insn (gen_call (operands[0], const0_rtx)); 3327 3328 for (i = 0; i < XVECLEN (operands[2], 0); i++) 3329 { 3330 rtx set = XVECEXP (operands[2], 0, i); 3331 emit_move_insn (SET_DEST (set), SET_SRC (set)); 3332 } 3333 3334 /* The optimizer does not know that the call sets the function value 3335 registers we stored in the result block. We avoid problems by 3336 claiming that all hard registers are used and clobbered at this 3337 point. */ 3338 emit_insn (gen_blockage ()); 3339 3340 DONE; 3341}) 3342 3343;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 3344;; all of memory. This blocks insns from being moved across this point. 3345 3346(define_insn "blockage" 3347 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 3348 "" 3349 "" 3350 [(set_attr "length" "0")]) 3351 3352(define_insn "*call_value_internal_vs" 3353 [(set (match_operand:SF 0 "register_operand" "=v,v,v") 3354 (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S")) 3355 (match_operand 2 "" ""))) 3356 (clobber (reg:SI CSKY_LR_REGNUM))] 3357 "TARGET_HARD_FLOAT_ABI" 3358 "@ 3359 jsr\t%1 3360 jsr\t%1 3361 jbsr\t%1" 3362 [(set_attr "length" "2,4,4") 3363 (set_attr "type" "call_jsr,call_jsr,call")] 3364) 3365 3366(define_insn "*call_value_internal_vd" 3367 [(set (match_operand:DF 0 "register_operand" "=v,v,v") 3368 (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S")) 3369 (match_operand 2 "" ""))) 3370 (clobber (reg:SI CSKY_LR_REGNUM))] 3371 "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU" 3372 "@ 3373 jsr\t%1 3374 jsr\t%1 3375 jbsr\t%1" 3376 [(set_attr "length" "2,4,4") 3377 (set_attr "type" "call_jsr,call_jsr,call")] 3378) 3379 3380(define_insn "*call_value_internal_pic_vs" 3381 [(set (match_operand:SF 0 "register_operand" "=v") 3382 (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X")) 3383 (match_operand 2 "" ""))) 3384 (clobber (reg:SI CSKY_LR_REGNUM))] 3385 "flag_pic && TARGET_HARD_FLOAT_ABI" 3386 "* return csky_output_call (operands, 1);" 3387) 3388 3389(define_insn "*call_value_internal_pic_vd" 3390 [(set (match_operand:DF 0 "register_operand" "=v") 3391 (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X")) 3392 (match_operand 2 "" ""))) 3393 (clobber (reg:SI CSKY_LR_REGNUM))] 3394 "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU" 3395 "* return csky_output_call (operands, 1);" 3396) 3397 3398(define_insn "*call_value_internal" 3399 [(set (match_operand 0 "register_operand" "=r,r,r") 3400 (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S")) 3401 (match_operand 2 "" ""))) 3402 (clobber (reg:SI CSKY_LR_REGNUM))] 3403 "" 3404 "@ 3405 jsr\t%1 3406 jsr\t%1 3407 jbsr\t%1" 3408 [(set_attr "length" "2,4,4") 3409 (set_attr "type" "call_jsr,call_jsr,call")] 3410) 3411 3412(define_insn "*call_value_internal_pic" 3413 [(set (match_operand 0 "register_operand" "=r") 3414 (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X")) 3415 (match_operand 2 "" ""))) 3416 (clobber (reg:SI CSKY_LR_REGNUM))] 3417 "flag_pic" 3418 "* return csky_output_call (operands, 1);" 3419) 3420 3421(define_insn "*call_value_struct" 3422 [(set (match_parallel 0 "" 3423 [(expr_list (match_operand 3 "register_operand" "") 3424 (match_operand 4 "immediate_operand" "")) 3425 (expr_list (match_operand 5 "register_operand" "") 3426 (match_operand 6 "immediate_operand" ""))]) 3427 (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b,r,S")) 3428 (match_operand 2 "" ""))) 3429 (clobber (reg:SI CSKY_LR_REGNUM))] 3430 "" 3431 "@ 3432 jsr\t%1 3433 jsr\t%1 3434 jbsr\t%1" 3435 [(set_attr "length" "2,4,4") 3436 (set_attr "type" "call_jsr,call_jsr,call")] 3437) 3438 3439(define_insn "*call_value_struct_pic" 3440 [(set (match_parallel 0 "" 3441 [(expr_list (match_operand 3 "register_operand" "") 3442 (match_operand 4 "immediate_operand" "")) 3443 (expr_list (match_operand 5 "register_operand" "") 3444 (match_operand 6 "immediate_operand" ""))]) 3445 (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X")) 3446 (match_operand 2 "" ""))) 3447 (clobber (reg:SI CSKY_LR_REGNUM))] 3448 "flag_pic" 3449 "* return csky_output_call (operands, 1);" 3450) 3451 3452 3453;; ------------------------------------------------------------- 3454;; prologue & epilogue 3455;; ------------------------------------------------------------- 3456 3457(define_expand "prologue" 3458 [(clobber (const_int 0))] 3459 "" 3460 " 3461 { 3462 csky_expand_prologue (); 3463 DONE; 3464 }" 3465) 3466 3467(define_expand "epilogue" 3468 [(clobber (const_int 0))] 3469 "" 3470 " 3471 { 3472 csky_expand_epilogue (); 3473 DONE; 3474 }" 3475) 3476 3477/* TODO: pushpop */ 3478;; Push multiple registers to the stack. Registers are in parallel (use ...) 3479;; expressions. For simplicity, the first register is also in the unspec 3480;; part. 3481(define_insn "*push_multi" 3482 [(match_parallel 2 "registers_push" 3483 [(set (match_operand:BLK 0 "push_memory_operand" "") 3484 (unspec:BLK [(match_operand:SI 1 "register_operand" "")] 3485 UNSPEC_PUSHPOP_MULT))])] 3486 "" 3487 { 3488 int num_saves = XVECLEN (operands[2], 0); 3489 int i; 3490 char pattern[100]; 3491 3492 strcpy (pattern, \"push\\t%1\"); 3493 3494 for (i = 1; i < num_saves; i++) 3495 { 3496 strcat (pattern, \", \"); 3497 strcat (pattern, 3498 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 3499 } 3500 3501 output_asm_insn (pattern, operands); 3502 3503 return \"\"; 3504 } 3505 [(set (attr "length") 3506 (symbol_ref "csky_compute_pushpop_length (operands)"))] 3507) 3508 3509;; Pop (as used in epilogue RTL) 3510;; 3511(define_insn "*pop_multi" 3512 [(match_parallel 2 "registers_pop" 3513 [(return) 3514 (set (match_operand:SI 1 "register_operand" "") 3515 (unspec:SI [(match_operand:SI 0 "pop_memory_operand" "")] 3516 UNSPEC_PUSHPOP_MULT))])] 3517 "" 3518 { 3519 int num_saves = XVECLEN (operands[2], 0); 3520 int i; 3521 char pattern[100]; 3522 3523 strcpy (pattern, \"pop\\t%1\"); 3524 3525 for (i = 2; i < num_saves; i++) 3526 { 3527 strcat (pattern, \", \"); 3528 strcat (pattern, 3529 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 3530 } 3531 3532 output_asm_insn (pattern, operands); 3533 3534 return \"\"; 3535 } 3536 [(set (attr "length") 3537 (symbol_ref "csky_compute_pushpop_length (operands)"))] 3538) 3539 3540 3541;; ------------------------------------------------------------------------- 3542;; PIC related insns 3543;; ------------------------------------------------------------------------- 3544 3545(define_insn "prologue_get_pc" 3546 [(set (reg:SI 28) 3547 (match_operand:SI 0 "" "X"))] 3548 "(GET_CODE (operands[0]) == UNSPEC) 3549 && (XINT (operands[0], 1) == UNSPEC_PIC_SYMBOL_GOTPC_GRS)" 3550 { 3551 operands[0] = XVECEXP (operands[0], 0, 0); 3552 output_asm_insn (\"grs\tgb, %0\", operands); 3553 default_internal_label (asm_out_file, \"L\", 3554 CODE_LABEL_NUMBER (XEXP (operands[0], 0))); 3555 return \"\"; 3556 } 3557) 3558 3559(define_insn "*pic_got_pc" 3560 [(set (match_operand:SI 0 "register_operand" "=r") 3561 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOTPC))] 3562 "flag_pic" 3563 "lrw\t%0, %1@GOTPC" 3564) 3565 3566(define_insn "*pic_symbol_gotoff" 3567 [(set (match_operand:SI 0 "register_operand" "=r") 3568 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOTOFF))] 3569 "flag_pic" 3570 "lrw\t%0, %1@GOTOFF" 3571) 3572 3573(define_insn "*pic_symbol_got" 3574 [(set (match_operand:SI 0 "register_operand" "=r") 3575 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOT))] 3576 "flag_pic" 3577 "lrw\t%0, %1@GOT" 3578) 3579 3580(define_insn "*pic_symbol_plt" 3581 [(set (match_operand:SI 0 "register_operand" "=r") 3582 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_PLT))] 3583 "flag_pic" 3584 "lrw\t%0, %1@PLT" 3585) 3586 3587(define_insn "*pic_symbol_grs" 3588 [(set (match_operand:SI 0 "register_operand" "=r") 3589 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GRS))] 3590 "flag_pic" 3591 "grs\t%0, %1" 3592) 3593 3594(define_expand "builtin_setjmp_receiver" 3595 [(label_ref (match_operand 0 "" ""))] 3596 "flag_pic" 3597 "{ 3598 rtx l1 = gen_label_rtx(); 3599 rtx grs_label = gen_rtx_LABEL_REF (SImode, l1); 3600 rtx reg_gb = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM); 3601 rtx reg_temp = gen_rtx_REG (SImode, 12); 3602 3603 rtx tmp0_unspec = gen_rtx_UNSPEC (Pmode, 3604 gen_rtvec (1, grs_label), 3605 UNSPEC_PIC_SYMBOL_GOTPC_GRS); 3606 rtx tmp1_unspec = gen_rtx_UNSPEC (Pmode, 3607 gen_rtvec (1, grs_label), 3608 UNSPEC_PIC_SYMBOL_GOTPC); 3609 3610 emit_insn (gen_prologue_get_pc (tmp0_unspec)); 3611 emit_move_insn (reg_temp, tmp1_unspec); 3612 emit_insn (gen_addsi3 (reg_gb, reg_gb, reg_temp)); 3613 emit_use (reg_gb); 3614 3615 DONE; 3616 }" 3617) 3618 3619;; ------------------------------------------------------------------------- 3620;; TLS related insns 3621;; ------------------------------------------------------------------------- 3622 3623 3624;; UNSPEC_TLS can take either 2 or 3 operands. Operand 0 is the symbol_ref, 3625;; operand 1 is a CONST_INT identifying the TLS model, and the optional 3626;; operand 3 is an UNSPEC_TLS_LABEL. 3627;; The 3-operand case is for TLS_GD32, TLS_LDM32, and TLS_IE32. 3628;; The 2-operand case is for TLS_LE32 and TLS_LDO32. 3629 3630;; Move PC-relative TLS label to reg. This is used for the TLS_GD32 3631;; and TLS_GD32 models (when setting up a call to tls_get_addr) and 3632;; also TLS_IE32. 3633 3634(define_insn "*tls_pcrel_label" 3635 [(set (match_operand:SI 0 "register_operand" "=r") 3636 (unspec:SI [(match_operand:SI 1 "const_int_operand" "")] 3637 UNSPEC_TLS_LABEL))] 3638 "TARGET_TLS" 3639 "grs\t%0, .LTLS%1" 3640 [(set_attr "length" "4")] 3641) 3642 3643;; This pattern is used to load the TLS base for the same models as above. 3644;; The embedded UNSPEC_TLS_LABEL only identifies the label to emit and 3645;; doesn't generate a reference to it; that's handled by the *tls_pcrel_label 3646;; pattern above. The label offset needs to be added to the result stored 3647;; in operand 0 by this insn. 3648 3649(define_insn "*tls_get_symbol_1" 3650 [(set (match_operand:SI 0 "register_operand" "=r") 3651 (unspec:SI [(match_operand 1 "" "") 3652 (match_operand 2 "" "") 3653 (unspec:SI [(match_operand 3 "" "")] UNSPEC_TLS_LABEL)] 3654 UNSPEC_TLS))] 3655 "TARGET_TLS" 3656 { 3657 default_internal_label (asm_out_file, \"LTLS\", INTVAL (operands[3])); 3658 switch (INTVAL (operands[2])) 3659 { 3660 case TLS_GD32: 3661 return \"lrw\t%0, %1@TLSGD32\"; 3662 case TLS_LDM32: 3663 return \"lrw\t%0, %1@TLSLDM32\"; 3664 case TLS_IE32: 3665 return \"lrw\t%0, %1@GOTTPOFF\"; 3666 default: 3667 return \"\"; 3668 } 3669 } 3670) 3671 3672;; This pattern matches the two-operand form of UNSPEC_TLS. 3673 3674(define_insn "*tls_get_symbol_2" 3675 [(set (match_operand:SI 0 "register_operand" "=r") 3676 (unspec:SI [(match_operand 1 "" "") 3677 (match_operand 2 "" "")] 3678 UNSPEC_TLS))] 3679 "TARGET_TLS" 3680 { 3681 switch (INTVAL (operands[2])) 3682 { 3683 case TLS_LE32: 3684 return \"lrw\t%0, %1@TPOFF\"; 3685 case TLS_LDO32: 3686 return \"lrw\t%0, %1@TLSLDO32\"; 3687 default: 3688 return \"\"; 3689 } 3690 } 3691) 3692 3693 3694;; ------------------------------------------------------------- 3695;; Misc insns 3696;; ------------------------------------------------------------- 3697 3698(define_insn "nop" 3699 [(const_int 0)] 3700 "" 3701 "nop" 3702 [(set_attr "length" "2")] 3703) 3704 3705(define_insn "trap" 3706 [(trap_if (const_int 1) (const_int 0))] 3707 "" 3708 "bkpt" 3709 [(set (attr "length") (const_int 2)) 3710 (set_attr "type" "alu")] 3711) 3712 3713 3714;; ------------------------------------------------------------- 3715;; Special patterns for dealing with the constant pool 3716;; ------------------------------------------------------------- 3717 3718(define_insn "align_4" 3719 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] 3720 "" 3721 { 3722 assemble_align(32); 3723 return \"\"; 3724 } 3725 [(set_attr "length" "0")] 3726) 3727 3728(define_insn "csky_constpool_label" 3729 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_LABEL)] 3730 "" 3731 { 3732 char tmp_label[15]; 3733 ASM_GENERATE_INTERNAL_LABEL (tmp_label, \"LCP\", INTVAL (operands[0])); 3734 assemble_label (asm_out_file, tmp_label); 3735 return \"\"; 3736 } 3737 [(set_attr "length" "0")] 3738) 3739 3740(define_insn "consttable_4" 3741 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] 3742 "" 3743 { 3744 if (CONST_DOUBLE_P (operands[0])) 3745 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 3746 SFmode, BITS_PER_WORD); 3747 else 3748 { 3749 assemble_integer (operands[0], 4, BITS_PER_WORD, 1); 3750 mark_symbol_refs_as_used (operands[0]); 3751 } 3752 return \"\"; 3753 } 3754 [(set_attr "length" "4")] 3755) 3756 3757(define_insn "consttable_8" 3758 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] 3759 "" 3760 { 3761 if (CONST_DOUBLE_P (operands[0])) 3762 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 3763 DFmode, BITS_PER_WORD); 3764 else 3765 assemble_integer (operands[0], 8, BITS_PER_WORD, 1); 3766 return \"\"; 3767 } 3768 [(set_attr "length" "8")] 3769) 3770 3771;;FIXME record the deferred symbol_ref information with use insn 3772(define_insn "*cskyv2_use_symbol_ref" 3773 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_SYMBOL_REF)] 3774 "" 3775 "" 3776 [(set_attr "length" "0")] 3777) 3778 3779 3780;; ------------------------------------------------------------ 3781;; switch case optimize 3782;; ------------------------------------------------------------ 3783 3784(define_expand "casesi" 3785 [(match_operand:SI 0 "register_operand" "") ; index to jump on 3786 (match_operand:SI 1 "const_int_operand" "") ; lower bound 3787 (match_operand:SI 2 "const_int_operand" "") ; total range (max - min) 3788 (match_operand:SI 3 "" "") ; table label 3789 (match_operand:SI 4 "" "")] ; Out of range label (default:) 3790 "TARGET_CASESI" 3791 " 3792 { 3793 enum insn_code code; 3794 if (operands[1] != const0_rtx) 3795 { 3796 rtx reg = gen_reg_rtx (SImode); 3797 emit_insn (gen_subsi3 (reg, 3798 operands[0], 3799 GEN_INT (INTVAL (operands[1])))); 3800 operands[0] = reg; 3801 } 3802 3803 code = CODE_FOR_csky_casesi_internal; 3804 3805 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode)) 3806 operands[2] = force_reg (SImode,operands[2]); 3807 3808 emit_jump_insn (GEN_FCN ((int) code) (operands[0],operands[2], 3809 operands[3],operands[4])); 3810 DONE; 3811 }" 3812) 3813 3814(define_expand "csky_casesi_internal" 3815 [(match_operand:SI 0 "register_operand" "") 3816 (match_operand:SI 1 "csky_literal_Uk_operand" "") 3817 (match_operand 2 "" "") 3818 (match_operand 3 "" "")] 3819 "" 3820 { 3821 rtx reg0; 3822 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]); 3823 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1], 3824 operands[3])); 3825 reg0 = gen_rtx_REG (SImode, 0); 3826 emit_move_insn (reg0, operands[0]); 3827 emit_jump_insn (gen_csky_casesi_dispatch (operands[2])); 3828 DONE; 3829 } 3830) 3831 3832(define_insn "csky_casesi_dispatch" 3833 [(parallel [(set (pc) (unspec [(reg:SI 0) 3834 (label_ref (match_operand 0 "" ""))] 3835 UNSPEC_CSKY_CASESI)) 3836 (clobber (reg:SI CSKY_LR_REGNUM))])] 3837 "" 3838 "*return csky_output_casesi (operands);" 3839 [(set_attr "length" "4")] 3840) 3841 3842;; ------------------------------------------------------------------------ 3843;; index insns 3844;; ------------------------------------------------------------------------ 3845 3846(define_insn "*cskyv2_indexsi_t" 3847 [(set (match_operand:SI 0 "register_operand" "=r") 3848 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 3849 (const_int 4)) 3850 (match_operand:SI 2 "register_operand" "r")))] 3851 "CSKY_ISA_FEATURE (E2)" 3852 "ixw\t%0, %2, %1" 3853) 3854 3855(define_insn "*cskyv2_indexhi_t" 3856 [(set (match_operand:SI 0 "register_operand" "=r") 3857 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 3858 (const_int 2)) 3859 (match_operand:SI 2 "register_operand" "r")))] 3860 "CSKY_ISA_FEATURE (E2)" 3861 "ixh\t%0, %2, %1" 3862) 3863 3864(define_insn "*cskyv2_indexdi_t" 3865 [(set (match_operand:SI 0 "register_operand" "=r") 3866 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") 3867 (const_int 8)) 3868 (match_operand:SI 2 "register_operand" "r")))] 3869 "CSKY_ISA_FEATURE (2E3)" 3870 "ixd\t%0, %2, %1" 3871) 3872 3873;; ------------------------------------------------------------------------ 3874;; swap insns 3875;; ------------------------------------------------------------------------ 3876 3877(define_insn "bswapsi2" 3878 [(set (match_operand:SI 0 "register_operand" "=r") 3879 (bswap:SI (match_operand:SI 1 "register_operand" "r")))] 3880 "CSKY_ISA_FEATURE (E2)" 3881 "revb\t%0, %1" 3882) 3883