|
|
1.1 ! root 1: ;;- Machine description Acorn RISC Machine for GNU compiler ! 2: ;; Copyright (C) 1991, 1993 Free Software Foundation, Inc. ! 3: ;; Contributed by Pieter `Tiggr' Schoenmakers ([email protected]) ! 4: ;; and Martin Simmons (@harleqn.co.uk). ! 5: ;; More major hacks by Richard Earnshaw ([email protected]) ! 6: ! 7: ;; This file is part of GNU CC. ! 8: ! 9: ;; GNU CC is free software; you can redistribute it and/or modify ! 10: ;; it under the terms of the GNU General Public License as published by ! 11: ;; the Free Software Foundation; either version 2, or (at your option) ! 12: ;; any later version. ! 13: ! 14: ;; GNU CC is distributed in the hope that it will be useful, ! 15: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: ;; GNU General Public License for more details. ! 18: ! 19: ;; You should have received a copy of the GNU General Public License ! 20: ;; along with GNU CC; see the file COPYING. If not, write to ! 21: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 22: ! 23: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. ! 24: ! 25: ;; Every template must be output by arm_output_asm_insn, since this keeps ! 26: ;; track of the offset of labels within the text segment. This is needed to ! 27: ;; to be able to (correctly) output instructions for loading a value from a ! 28: ;; function's constant pool, since different instructions are needed when the ! 29: ;; constant pool is more than 4095 bytes away from the PC. ! 30: ! 31: ;; There are patterns in this file to support XFmode arithmetic. ! 32: ;; Unfortunately RISCiX doesn't work well with these so they are disabled. ! 33: ;; (See arm.h) ! 34: ! 35: ;; UNSPEC Usage: ! 36: ;; 0 `sin' operation: operand 0 is the result, operand 1 the parameter, ! 37: ;; the mode is MODE_FLOAT ! 38: ;; 1 `cos' operation: operand 0 is the result, operand 1 the parameter, ! 39: ;; the mode is MODE_FLOAT ! 40: ! 41: ;; Attributes ! 42: ! 43: ; condition codes: this one is used by final_prescan_insn to speed up ! 44: ; conditionalizing instructions. It saves having to scan the rtl to see if ! 45: ; it uses or alters the condition codes. ! 46: ! 47: ; USE means that the condition codes are used by the insn in the process of ! 48: ; outputting code, this means (at present) that we can't use the insn in ! 49: ; inlined branches ! 50: ! 51: ; SET means that the purpose of the insn is to set the condition codes in a ! 52: ; well defined manner. ! 53: ! 54: ; CLOB means that the condition codes are altered in an undefined manner, if ! 55: ; they are altered at all ! 56: ! 57: ; JUMP_CLOB is used when the conditions are not defined if a branch is taken, ! 58: ; but are if the branch wasn't taken; the effect is to limit the branch ! 59: ; elimination scanning. ! 60: ! 61: ; NOCOND means that the condition codes are niether altered nor affect the ! 62: ; output of this insn ! 63: ! 64: (define_attr "conds" "use,set,clob,jump_clob,nocond" ! 65: (const_string "nocond")) ! 66: ! 67: ; CPU attribute is used to determine whether condition codes are clobbered ! 68: ; by a call insn: on the arm6 they are if in 32-bit addressing mode; on the ! 69: ; arm2 and arm3 the condition codes are restored by the return. ! 70: ! 71: (define_attr "cpu" "arm2,arm3,arm6" (const (symbol_ref "arm_cpu_attr"))) ! 72: ! 73: ; LENGTH, all instructions are 4 bytes ! 74: (define_attr "length" "" (const_int 1)) ! 75: ! 76: ; An assembler sequence may clobber the condition codes without us knowing ! 77: (define_asm_attributes ! 78: [(set_attr "conds" "clob") ! 79: (set_attr "length" "1")]) ! 80: ! 81: ; TYPE attribute is used to detect floating point instructions which, if ! 82: ; running on a co-processor can run in parallel with other, basic instructions ! 83: ; If write-buffer scheduling is enabled then it can also be used in the ! 84: ; scheduling of writes. ! 85: ! 86: ; Classification of each insn ! 87: ; normal any data instruction that doesn't hit memory or fp regs ! 88: ; block blockage insn, this blocks all functional units ! 89: ; float a floating point arithmetic operation (subject to expansion) ! 90: ; float_em a floating point arithmetic operation that is normally emulated ! 91: ; f_load a floating point load from memory ! 92: ; f_store a floating point store to memory ! 93: ; f_mem_r a transfer of a floating point register to a real reg via mem ! 94: ; r_mem_f the reverse of f_mem_r ! 95: ; f_2_r fast transfer float to arm (no memory needed) ! 96: ; r_2_f fast transfer arm to float ! 97: ; call a subroutine call ! 98: ; load any load from memory ! 99: ; store1 store 1 word to memory from arm registers ! 100: ; store2 store 2 words ! 101: ; store3 store 3 words ! 102: ; store4 store 4 words ! 103: ; ! 104: (define_attr "type" ! 105: "normal,block,float,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" ! 106: (const_string "normal")) ! 107: ! 108: (define_attr "write_conflict" "no,yes" ! 109: (if_then_else (eq_attr "type" ! 110: "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load") ! 111: (const_string "yes") ! 112: (const_string "no"))) ! 113: ! 114: ; The write buffer on some of the arm6 processors is hard to model exactly. ! 115: ; There is room in the buffer for up to two addresses and up to eight words ! 116: ; of memory, but the two needn't be split evenly. When writing the two ! 117: ; addresses are fully pipelined. However, a read from memory that is not ! 118: ; currently in the cache will block until the writes have completed. ! 119: ; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so ! 120: ; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous ! 121: ; (they aren't allowed to be at present) then there is a startup cost of 1MCLK ! 122: ; cycle to add as well. ! 123: ! 124: ;; (define_function_unit {name} {num-units} {n-users} {test} ! 125: ;; {ready-delay} {issue-delay} [{conflict-list}]) ! 126: ;; This is not well tuned, but I don't have all the details. ! 127: (define_function_unit "fpa" 1 1 (eq_attr "type" "float") 5 0) ! 128: ! 129: (define_function_unit "write_buf" 1 2 (eq_attr "type" "store1") 3 3 ! 130: [(eq_attr "write_conflict" "yes")]) ! 131: (define_function_unit "write_buf" 1 2 (eq_attr "type" "store2") 5 5 ! 132: [(eq_attr "write_conflict" "yes")]) ! 133: (define_function_unit "write_buf" 1 2 (eq_attr "type" "store3") 7 7 ! 134: [(eq_attr "write_conflict" "yes")]) ! 135: (define_function_unit "write_buf" 1 2 (eq_attr "type" "store4") 9 9 ! 136: [(eq_attr "write_conflict" "yes")]) ! 137: (define_function_unit "write_buf" 1 2 (eq_attr "type" "r_mem_f") 3 3 ! 138: [(eq_attr "write_conflict" "yes")]) ! 139: ! 140: ;; Note: For DImode insns, there is normally no reason why operands should ! 141: ;; not be in the same register, what we don't want is for something being ! 142: ;; written to partially overlap something that is an input. ! 143: ! 144: ;; Addition insns. ! 145: ! 146: (define_insn "adddi3" ! 147: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 148: (plus:DI (match_operand:DI 1 "s_register_operand" "%0,0") ! 149: (match_operand:DI 2 "s_register_operand" "r,0"))) ! 150: (clobber (reg:CC 24))] ! 151: "" ! 152: "* ! 153: arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands); ! 154: return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands)); ! 155: " ! 156: [(set_attr "conds" "clob") ! 157: (set_attr "length" "2")]) ! 158: ! 159: (define_insn "" ! 160: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 161: (plus:DI (sign_extend:DI ! 162: (match_operand:SI 1 "s_register_operand" "r,r")) ! 163: (match_operand:DI 2 "s_register_operand" "r,0"))) ! 164: (clobber (reg:CC 24))] ! 165: "" ! 166: "* ! 167: arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands); ! 168: return (arm_output_asm_insn (\"adc\\t%R0, %R2, %1, asr #31\", operands)); ! 169: " ! 170: [(set_attr "conds" "clob") ! 171: (set_attr "length" "2")]) ! 172: ! 173: (define_insn "" ! 174: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 175: (plus:DI (zero_extend:DI ! 176: (match_operand:SI 1 "s_register_operand" "r,r")) ! 177: (match_operand:DI 2 "s_register_operand" "r,0"))) ! 178: (clobber (reg:CC 24))] ! 179: "" ! 180: "* ! 181: arm_output_asm_insn (\"adds\\t%0, %2, %1\", operands); ! 182: return (arm_output_asm_insn (\"adc\\t%R0, %R2, #0\", operands)); ! 183: " ! 184: [(set_attr "conds" "clob") ! 185: (set_attr "length" "2")]) ! 186: ! 187: (define_insn "addsi3" ! 188: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 189: (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 190: (match_operand:SI 2 "arm_add_operand" "rL")))] ! 191: "" ! 192: "* ! 193: if (GET_CODE (operands[2]) == CONST_INT ! 194: && !const_ok_for_arm (INTVAL (operands[2]))) ! 195: { ! 196: operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! 197: return arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands); ! 198: } ! 199: return arm_output_asm_insn (\"add\\t%0, %1, %2\", operands); ! 200: ") ! 201: ! 202: (define_insn "" ! 203: [(set (reg:CC_NOOV 24) ! 204: (compare:CC_NOOV (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 205: (match_operand:SI 2 "arm_add_operand" "rL")) ! 206: (const_int 0))) ! 207: (set (match_operand:SI 0 "s_register_operand" "=r") ! 208: (plus:SI (match_dup 1) (match_dup 2)))] ! 209: "" ! 210: "* ! 211: if (GET_CODE (operands[2]) == CONST_INT ! 212: && !const_ok_for_arm (INTVAL (operands[2]))) ! 213: { ! 214: operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! 215: return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 216: } ! 217: return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands)); ! 218: " ! 219: [(set_attr "conds" "set")]) ! 220: ! 221: (define_insn "" ! 222: [(set (reg:CC 24) ! 223: (compare:CC (match_operand:SI 1 "s_register_operand" "r") ! 224: (neg:SI (match_operand:SI 2 "arm_add_operand" "rL")))) ! 225: (set (match_operand:SI 0 "s_register_operand" "=r") ! 226: (plus:SI (match_dup 1) (match_dup 2)))] ! 227: "" ! 228: "* ! 229: if (GET_CODE (operands[2]) == CONST_INT ! 230: && !const_ok_for_arm (INTVAL (operands[2]))) ! 231: { ! 232: operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); ! 233: return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 234: } ! 235: return (arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands)); ! 236: " ! 237: [(set_attr "conds" "set")]) ! 238: ! 239: (define_insn "incscc" ! 240: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 241: (plus:SI (match_operator:SI 2 "comparison_operator" ! 242: [(reg 24) (const_int 0)]) ! 243: (match_operand:SI 1 "s_register_operand" "0,?r")))] ! 244: "" ! 245: "* ! 246: if (which_alternative == 1) ! 247: arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); ! 248: return arm_output_asm_insn (\"add%d2\\t%0, %1, #1\", operands); ! 249: " ! 250: [(set_attr "conds" "use") ! 251: (set_attr "length" "*,2")]) ! 252: ! 253: ; If a constant is too big to fit in a single instruction then the constant ! 254: ; will be pre-loaded into a register taking at least two insns, we might be ! 255: ; able to merge it with an add, but it depends on the exact value. ! 256: ! 257: (define_split ! 258: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 259: (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 260: (match_operand:SI 2 "immediate_operand" "n")))] ! 261: "!(const_ok_for_arm (INTVAL (operands[2])) ! 262: || const_ok_for_arm (-INTVAL (operands[2])))" ! 263: [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) ! 264: (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] ! 265: " ! 266: { ! 267: unsigned int val = (unsigned) INTVAL (operands[2]); ! 268: int i; ! 269: unsigned int temp; ! 270: ! 271: /* this code is similar to the approach followed in movsi, but it must ! 272: generate exactly two insns */ ! 273: ! 274: for (i = 30; i >= 0; i -= 2) ! 275: { ! 276: if (val & (3 << i)) ! 277: { ! 278: i -= 6; ! 279: if (i < 0) i = 0; ! 280: if (const_ok_for_arm (temp = (val & ~(255 << i)))) ! 281: { ! 282: val &= 255 << i; ! 283: break; ! 284: } ! 285: /* we might be able to do this as (larger number - small number) */ ! 286: temp = ((val >> i) & 255) + 1; ! 287: if (temp > 255 && i < 24) ! 288: { ! 289: i += 2; ! 290: temp = ((val >> i) & 255) + 1; ! 291: } ! 292: if (const_ok_for_arm ((temp << i) - val)) ! 293: { ! 294: i = temp << i; ! 295: temp = (unsigned) - (int) (i - val); ! 296: val = i; ! 297: break; ! 298: } ! 299: FAIL; ! 300: } ! 301: } ! 302: /* if we got here, we have found a way of doing it in two instructions. ! 303: the two constants are in val and temp */ ! 304: operands[2] = GEN_INT ((int)val); ! 305: operands[3] = GEN_INT ((int)temp); ! 306: } ! 307: ") ! 308: ! 309: (define_insn "addsf3" ! 310: [(set (match_operand:SF 0 "s_register_operand" "=f,f") ! 311: (plus:SF (match_operand:SF 1 "s_register_operand" "f,f") ! 312: (match_operand:SF 2 "fpu_add_operand" "fG,H")))] ! 313: "" ! 314: "* ! 315: { ! 316: REAL_VALUE_TYPE r; ! 317: ! 318: switch (which_alternative) ! 319: { ! 320: case 0: ! 321: return arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands); ! 322: case 1: ! 323: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! 324: r = REAL_VALUE_NEGATE (r); ! 325: operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! 326: return arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands); ! 327: } ! 328: } ! 329: " ! 330: [(set_attr "type" "float")]) ! 331: ! 332: (define_insn "adddf3" ! 333: [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! 334: (plus:DF (match_operand:DF 1 "s_register_operand" "f,f") ! 335: (match_operand:DF 2 "fpu_add_operand" "fG,H")))] ! 336: "" ! 337: "* ! 338: { ! 339: REAL_VALUE_TYPE r; ! 340: ! 341: switch (which_alternative) ! 342: { ! 343: case 0: ! 344: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! 345: case 1: ! 346: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! 347: r = REAL_VALUE_NEGATE (r); ! 348: operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! 349: return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! 350: } ! 351: } ! 352: " ! 353: [(set_attr "type" "float")]) ! 354: ! 355: (define_insn "" ! 356: [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! 357: (plus:DF (float_extend:DF ! 358: (match_operand:SF 1 "s_register_operand" "f,f")) ! 359: (match_operand:DF 2 "fpu_add_operand" "fG,H")))] ! 360: "" ! 361: "* ! 362: { ! 363: REAL_VALUE_TYPE r; ! 364: ! 365: switch (which_alternative) ! 366: { ! 367: case 0: ! 368: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! 369: case 1: ! 370: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! 371: r = REAL_VALUE_NEGATE (r); ! 372: operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! 373: return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! 374: } ! 375: } ! 376: " ! 377: [(set_attr "type" "float")]) ! 378: ! 379: (define_insn "" ! 380: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 381: (plus:DF (match_operand:DF 1 "s_register_operand" "f") ! 382: (float_extend:DF ! 383: (match_operand:SF 2 "s_register_operand" "f"))))] ! 384: "" ! 385: "* ! 386: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! 387: " ! 388: [(set_attr "type" "float")]) ! 389: ! 390: (define_insn "" ! 391: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 392: (plus:DF (float_extend:DF ! 393: (match_operand:SF 1 "s_register_operand" "f")) ! 394: (float_extend:DF ! 395: (match_operand:SF 2 "s_register_operand" "f"))))] ! 396: "" ! 397: "* ! 398: return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands)); ! 399: " ! 400: [(set_attr "type" "float")]) ! 401: ! 402: (define_insn "addxf3" ! 403: [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! 404: (plus:XF (match_operand:XF 1 "s_register_operand" "f,f") ! 405: (match_operand:XF 2 "fpu_add_operand" "fG,H")))] ! 406: "ENABLE_XF_PATTERNS" ! 407: "* ! 408: { ! 409: REAL_VALUE_TYPE r; ! 410: ! 411: switch (which_alternative) ! 412: { ! 413: case 0: ! 414: return (arm_output_asm_insn (\"adfe\\t%0, %1, %2\", operands)); ! 415: case 1: ! 416: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); ! 417: r = REAL_VALUE_NEGATE (r); ! 418: operands[2] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[2])); ! 419: return arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands); ! 420: } ! 421: } ! 422: " ! 423: [(set_attr "type" "float")]) ! 424: ! 425: (define_insn "subdi3" ! 426: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r") ! 427: (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0") ! 428: (match_operand:DI 2 "s_register_operand" "r,0,0"))) ! 429: (clobber (reg:CC 24))] ! 430: "" ! 431: "* ! 432: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 433: return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands)); ! 434: " ! 435: [(set_attr "conds" "clob") ! 436: (set_attr "length" "2")]) ! 437: ! 438: (define_insn "" ! 439: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 440: (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0") ! 441: (zero_extend:DI ! 442: (match_operand:SI 2 "s_register_operand" "r,r")))) ! 443: (clobber (reg:CC 24))] ! 444: "" ! 445: "* ! 446: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 447: return (arm_output_asm_insn (\"sbc\\t%R0, %R1, #0\", operands)); ! 448: " ! 449: [(set_attr "conds" "clob") ! 450: (set_attr "length" "2")]) ! 451: ! 452: (define_insn "" ! 453: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 454: (minus:DI (match_operand:DI 1 "s_register_operand" "r,0") ! 455: (sign_extend:DI ! 456: (match_operand:SI 2 "s_register_operand" "r,r")))) ! 457: (clobber (reg:CC 24))] ! 458: "" ! 459: "* ! 460: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 461: return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %2, asr #31\", operands)); ! 462: " ! 463: [(set_attr "conds" "clob") ! 464: (set_attr "length" "2")]) ! 465: ! 466: (define_insn "" ! 467: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 468: (minus:DI (zero_extend:DI ! 469: (match_operand:SI 2 "s_register_operand" "r,r")) ! 470: (match_operand:DI 1 "s_register_operand" "?r,0"))) ! 471: (clobber (reg:CC 24))] ! 472: "" ! 473: "* ! 474: arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands); ! 475: return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands)); ! 476: " ! 477: [(set_attr "conds" "clob") ! 478: (set_attr "length" "2")]) ! 479: ! 480: (define_insn "" ! 481: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 482: (minus:DI (sign_extend:DI ! 483: (match_operand:SI 2 "s_register_operand" "r,r")) ! 484: (match_operand:DI 1 "s_register_operand" "?r,0"))) ! 485: (clobber (reg:CC 24))] ! 486: "" ! 487: "* ! 488: arm_output_asm_insn (\"rsbs\\t%0, %1, %2\", operands); ! 489: return (arm_output_asm_insn (\"rsc\\t%R0, %R1, %2, asr #31\", operands)); ! 490: " ! 491: [(set_attr "conds" "clob") ! 492: (set_attr "length" "2")]) ! 493: ! 494: (define_insn "" ! 495: [(set (match_operand:DI 0 "s_register_operand" "=r") ! 496: (minus:DI (zero_extend:DI ! 497: (match_operand:SI 1 "s_register_operand" "r")) ! 498: (zero_extend:DI ! 499: (match_operand:SI 2 "s_register_operand" "r")))) ! 500: (clobber (reg:CC 24))] ! 501: "" ! 502: "* ! 503: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 504: return (arm_output_asm_insn (\"rsc\\t%R0, %1, %1 @ extend carry\", ! 505: operands)); ! 506: " ! 507: [(set_attr "conds" "clob") ! 508: (set_attr "length" "2")]) ! 509: ! 510: (define_insn "subsi3" ! 511: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 512: (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I") ! 513: (match_operand:SI 2 "arm_rhs_operand" "rI,r")))] ! 514: "" ! 515: "* ! 516: switch (which_alternative) ! 517: { ! 518: case 0: ! 519: return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands)); ! 520: case 1: ! 521: return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands)); ! 522: } ! 523: ") ! 524: ! 525: (define_insn "" ! 526: [(set (reg:CC_NOOV 24) ! 527: (compare:CC_NOOV (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I") ! 528: (match_operand:SI 2 "arm_rhs_operand" "rI,r")) ! 529: (const_int 0))) ! 530: (set (match_operand:SI 0 "s_register_operand" "=r,r") ! 531: (minus:SI (match_dup 1) (match_dup 2)))] ! 532: "" ! 533: "* ! 534: switch (which_alternative) ! 535: { ! 536: case 0: ! 537: return arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 538: case 1: ! 539: return arm_output_asm_insn (\"rsbs\\t%0, %2, %1\", operands); ! 540: } ! 541: " ! 542: [(set_attr "conds" "set")]) ! 543: ! 544: (define_insn "decscc" ! 545: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 546: (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") ! 547: (match_operator:SI 2 "comparison_operator" ! 548: [(reg 24) (const_int 0)])))] ! 549: "" ! 550: "* ! 551: if (which_alternative == 1) ! 552: arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); ! 553: return arm_output_asm_insn (\"sub%d2\\t%0, %1, #1\", operands); ! 554: " ! 555: [(set_attr "conds" "use") ! 556: (set_attr "length" "*,2")]) ! 557: ! 558: (define_insn "subsf3" ! 559: [(set (match_operand:SF 0 "s_register_operand" "=f,f") ! 560: (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") ! 561: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] ! 562: "" ! 563: "* ! 564: switch (which_alternative) ! 565: { ! 566: case 0: ! 567: return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands)); ! 568: case 1: ! 569: return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands)); ! 570: } ! 571: " ! 572: [(set_attr "type" "float")]) ! 573: ! 574: (define_insn "subdf3" ! 575: [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! 576: (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! 577: (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] ! 578: "" ! 579: "* ! 580: switch (which_alternative) ! 581: { ! 582: case 0: ! 583: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); ! 584: case 1: ! 585: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); ! 586: } ! 587: " ! 588: [(set_attr "type" "float")]) ! 589: ! 590: (define_insn "" ! 591: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 592: (minus:DF (float_extend:DF ! 593: (match_operand:SF 1 "s_register_operand" "f")) ! 594: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 595: "" ! 596: "* ! 597: return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! 598: " ! 599: [(set_attr "type" "float")]) ! 600: ! 601: (define_insn "" ! 602: [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! 603: (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! 604: (float_extend:DF ! 605: (match_operand:SF 2 "s_register_operand" "f,f"))))] ! 606: "" ! 607: "* ! 608: switch (which_alternative) ! 609: { ! 610: case 0: ! 611: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); ! 612: case 1: ! 613: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); ! 614: } ! 615: " ! 616: [(set_attr "type" "float")]) ! 617: ! 618: (define_insn "" ! 619: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 620: (minus:DF (float_extend:DF ! 621: (match_operand:SF 1 "s_register_operand" "f")) ! 622: (float_extend:DF ! 623: (match_operand:SF 2 "s_register_operand" "f"))))] ! 624: "" ! 625: "* ! 626: return arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands); ! 627: " ! 628: [(set_attr "type" "float")]) ! 629: ! 630: (define_insn "subxf3" ! 631: [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! 632: (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") ! 633: (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] ! 634: "ENABLE_XF_PATTERNS" ! 635: "* ! 636: switch (which_alternative) ! 637: { ! 638: case 0: ! 639: return (arm_output_asm_insn (\"sufe\\t%0, %1, %2\", operands)); ! 640: case 1: ! 641: return (arm_output_asm_insn (\"rsfe\\t%0, %2, %1\", operands)); ! 642: } ! 643: " ! 644: [(set_attr "type" "float")]) ! 645: ! 646: ;; Multiplication insns ! 647: ! 648: ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same ! 649: (define_insn "mulsi3" ! 650: [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") ! 651: (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") ! 652: (match_operand:SI 1 "s_register_operand" "%?r,0")))] ! 653: "" ! 654: "* ! 655: return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands)); ! 656: ") ! 657: ! 658: (define_insn "" ! 659: [(set (reg:CC_NOOV 24) ! 660: (compare:CC_NOOV (mult:SI ! 661: (match_operand:SI 2 "s_register_operand" "r,r") ! 662: (match_operand:SI 1 "s_register_operand" "%?r,0")) ! 663: (const_int 0))) ! 664: (set (match_operand:SI 0 "s_register_operand" "=&r,&r") ! 665: (mult:SI (match_dup 2) (match_dup 1)))] ! 666: "" ! 667: "* ! 668: return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands)); ! 669: " ! 670: [(set_attr "conds" "set")]) ! 671: ! 672: (define_insn "" ! 673: [(set (reg:CC_NOOV 24) ! 674: (compare:CC_NOOV (mult:SI ! 675: (match_operand:SI 2 "s_register_operand" "r,r") ! 676: (match_operand:SI 1 "s_register_operand" "%?r,0")) ! 677: (const_int 0))) ! 678: (clobber (match_scratch:SI 0 "=&r,&r"))] ! 679: "" ! 680: "* ! 681: return (arm_output_asm_insn (\"muls\\t%0, %2, %1\", operands)); ! 682: " ! 683: [(set_attr "conds" "set")]) ! 684: ! 685: ;; Unnamed templates to match MLA instruction. ! 686: ! 687: (define_insn "" ! 688: [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") ! 689: (plus:SI ! 690: (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! 691: (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! 692: (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))] ! 693: "" ! 694: "* ! 695: return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); ! 696: ") ! 697: ! 698: (define_insn "" ! 699: [(set (reg:CC_NOOV 24) ! 700: (compare:CC_NOOV (plus:SI ! 701: (mult:SI ! 702: (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! 703: (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! 704: (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) ! 705: (const_int 0))) ! 706: (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") ! 707: (plus:SI (mult:SI (match_dup 2) (match_dup 1)) ! 708: (match_dup 3)))] ! 709: "" ! 710: "* ! 711: return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands)); ! 712: " ! 713: [(set_attr "conds" "set")]) ! 714: ! 715: (define_insn "" ! 716: [(set (reg:CC_NOOV 24) ! 717: (compare:CC_NOOV (plus:SI ! 718: (mult:SI ! 719: (match_operand:SI 2 "s_register_operand" "r,r,r,r") ! 720: (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) ! 721: (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) ! 722: (const_int 0))) ! 723: (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))] ! 724: "" ! 725: "* ! 726: return (arm_output_asm_insn (\"mlas\\t%0, %2, %1, %3\", operands)); ! 727: " ! 728: [(set_attr "conds" "set")]) ! 729: ! 730: (define_insn "mulsf3" ! 731: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 732: (mult:SF (match_operand:SF 1 "s_register_operand" "f") ! 733: (match_operand:SF 2 "fpu_rhs_operand" "fG")))] ! 734: "" ! 735: "* ! 736: return (arm_output_asm_insn (\"fmls\\t%0, %1, %2\", operands)); ! 737: " ! 738: [(set_attr "type" "float")]) ! 739: ! 740: (define_insn "muldf3" ! 741: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 742: (mult:DF (match_operand:DF 1 "s_register_operand" "f") ! 743: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 744: "" ! 745: "* ! 746: return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! 747: " ! 748: [(set_attr "type" "float")]) ! 749: ! 750: (define_insn "" ! 751: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 752: (mult:DF (float_extend:DF ! 753: (match_operand:SF 1 "s_register_operand" "f")) ! 754: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 755: "" ! 756: "* ! 757: return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! 758: " ! 759: [(set_attr "type" "float")]) ! 760: ! 761: (define_insn "" ! 762: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 763: (mult:DF (match_operand:DF 1 "s_register_operand" "f") ! 764: (float_extend:DF ! 765: (match_operand:SF 2 "s_register_operand" "f"))))] ! 766: "" ! 767: "* ! 768: return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! 769: " ! 770: [(set_attr "type" "float")]) ! 771: ! 772: (define_insn "" ! 773: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 774: (mult:DF (float_extend:DF ! 775: (match_operand:SF 1 "s_register_operand" "f")) ! 776: (float_extend:DF ! 777: (match_operand:SF 2 "s_register_operand" "f"))))] ! 778: "" ! 779: "* ! 780: return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands)); ! 781: " ! 782: [(set_attr "type" "float")]) ! 783: ! 784: (define_insn "mulxf3" ! 785: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 786: (mult:XF (match_operand:XF 1 "s_register_operand" "f") ! 787: (match_operand:XF 2 "fpu_rhs_operand" "fG")))] ! 788: "ENABLE_XF_PATTERNS" ! 789: "* ! 790: return (arm_output_asm_insn (\"mufe\\t%0, %1, %2\", operands)); ! 791: " ! 792: [(set_attr "type" "float")]) ! 793: ! 794: ;; Division insns ! 795: ! 796: (define_insn "divsf3" ! 797: [(set (match_operand:SF 0 "s_register_operand" "=f,f") ! 798: (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") ! 799: (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] ! 800: "" ! 801: "* ! 802: switch (which_alternative) ! 803: { ! 804: case 0: ! 805: return (arm_output_asm_insn (\"fdvs\\t%0, %1, %2\", operands)); ! 806: case 1: ! 807: return (arm_output_asm_insn (\"frds\\t%0, %2, %1\", operands)); ! 808: } ! 809: " ! 810: [(set_attr "type" "float")]) ! 811: ! 812: (define_insn "divdf3" ! 813: [(set (match_operand:DF 0 "s_register_operand" "=f,f") ! 814: (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") ! 815: (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] ! 816: "" ! 817: "* ! 818: switch (which_alternative) ! 819: { ! 820: case 0: ! 821: return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); ! 822: case 1: ! 823: return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); ! 824: } ! 825: " ! 826: [(set_attr "type" "float")]) ! 827: ! 828: (define_insn "" ! 829: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 830: (div:DF (float_extend:DF ! 831: (match_operand:SF 1 "s_register_operand" "f")) ! 832: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 833: "" ! 834: "* ! 835: return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); ! 836: " ! 837: [(set_attr "type" "float")]) ! 838: ! 839: (define_insn "" ! 840: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 841: (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG") ! 842: (float_extend:DF ! 843: (match_operand:SF 2 "s_register_operand" "f"))))] ! 844: "" ! 845: "* ! 846: return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); ! 847: " ! 848: [(set_attr "type" "float")]) ! 849: ! 850: (define_insn "" ! 851: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 852: (div:DF (float_extend:DF ! 853: (match_operand:SF 1 "s_register_operand" "f")) ! 854: (float_extend:DF ! 855: (match_operand:SF 2 "s_register_operand" "f"))))] ! 856: "" ! 857: "* ! 858: return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); ! 859: " ! 860: [(set_attr "type" "float")]) ! 861: ! 862: (define_insn "divxf3" ! 863: [(set (match_operand:XF 0 "s_register_operand" "=f,f") ! 864: (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") ! 865: (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] ! 866: "ENABLE_XF_PATTERNS" ! 867: "* ! 868: switch (which_alternative) ! 869: { ! 870: case 0: ! 871: return (arm_output_asm_insn (\"dvfe\\t%0, %1, %2\", operands)); ! 872: case 1: ! 873: return (arm_output_asm_insn (\"rdfe\\t%0, %2, %1\", operands)); ! 874: } ! 875: " ! 876: [(set_attr "type" "float")]) ! 877: ! 878: ;; Modulo insns ! 879: ! 880: (define_insn "modsf3" ! 881: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 882: (mod:SF (match_operand:SF 1 "s_register_operand" "f") ! 883: (match_operand:SF 2 "fpu_rhs_operand" "fG")))] ! 884: "" ! 885: "* ! 886: return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands)); ! 887: " ! 888: [(set_attr "type" "float")]) ! 889: ! 890: (define_insn "moddf3" ! 891: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 892: (mod:DF (match_operand:DF 1 "s_register_operand" "f") ! 893: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 894: "" ! 895: "* ! 896: return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! 897: " ! 898: [(set_attr "type" "float")]) ! 899: ! 900: (define_insn "" ! 901: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 902: (mod:DF (float_extend:DF ! 903: (match_operand:SF 1 "s_register_operand" "f")) ! 904: (match_operand:DF 2 "fpu_rhs_operand" "fG")))] ! 905: "" ! 906: "* ! 907: return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! 908: " ! 909: [(set_attr "type" "float")]) ! 910: ! 911: (define_insn "" ! 912: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 913: (mod:DF (match_operand:DF 1 "s_register_operand" "f") ! 914: (float_extend:DF ! 915: (match_operand:SF 2 "s_register_operand" "f"))))] ! 916: "" ! 917: "* ! 918: return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! 919: " ! 920: [(set_attr "type" "float")]) ! 921: ! 922: (define_insn "" ! 923: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 924: (mod:DF (float_extend:DF ! 925: (match_operand:SF 1 "s_register_operand" "f")) ! 926: (float_extend:DF ! 927: (match_operand:SF 2 "s_register_operand" "f"))))] ! 928: "" ! 929: "* ! 930: return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands)); ! 931: " ! 932: [(set_attr "type" "float")]) ! 933: ! 934: (define_insn "modxf3" ! 935: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 936: (mod:XF (match_operand:XF 1 "s_register_operand" "f") ! 937: (match_operand:XF 2 "fpu_rhs_operand" "fG")))] ! 938: "ENABLE_XF_PATTERNS" ! 939: "* ! 940: return (arm_output_asm_insn (\"rmfe\\t%0, %1, %2\", operands)); ! 941: " ! 942: [(set_attr "type" "float")]) ! 943: ! 944: ;; Boolean and,ior,xor insns ! 945: ! 946: (define_insn "anddi3" ! 947: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 948: (and:DI (match_operand:DI 1 "s_register_operand" "%0,0") ! 949: (match_operand:DI 2 "s_register_operand" "r,0")))] ! 950: "" ! 951: "* ! 952: arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! 953: return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands)); ! 954: " ! 955: [(set_attr "length" "2")]) ! 956: ! 957: (define_insn "" ! 958: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 959: (and:DI (zero_extend:DI ! 960: (match_operand:SI 2 "s_register_operand" "r,r")) ! 961: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 962: "" ! 963: "* ! 964: arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! 965: return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! 966: " ! 967: [(set_attr "length" "2")]) ! 968: ! 969: (define_insn "" ! 970: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 971: (and:DI (sign_extend:DI ! 972: (match_operand:SI 2 "s_register_operand" "r,r")) ! 973: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 974: "" ! 975: "* ! 976: arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! 977: return arm_output_asm_insn (\"and\\t%R0, %R1, %2, asr #31\", operands); ! 978: " ! 979: [(set_attr "length" "2")]) ! 980: ! 981: (define_insn "andsi3" ! 982: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 983: (and:SI (match_operand:SI 1 "s_register_operand" "r") ! 984: (match_operand:SI 2 "arm_not_operand" "rK")))] ! 985: "" ! 986: "* ! 987: if (GET_CODE (operands[2]) == CONST_INT ! 988: && !const_ok_for_arm (INTVAL (operands[2]))) ! 989: { ! 990: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! 991: return arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! 992: } ! 993: return arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); ! 994: ") ! 995: ! 996: (define_insn "" ! 997: [(set (reg:CC_NOOV 24) ! 998: (compare:CC_NOOV (and:SI (match_operand:SI 1 "s_register_operand" "r") ! 999: (match_operand:SI 2 "arm_not_operand" "rK")) ! 1000: (const_int 0))) ! 1001: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1002: (and:SI (match_dup 1) (match_dup 2)))] ! 1003: "" ! 1004: "* ! 1005: if (GET_CODE (operands[2]) == CONST_INT ! 1006: && !const_ok_for_arm (INTVAL (operands[2]))) ! 1007: { ! 1008: operands[2] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2])); ! 1009: return arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands); ! 1010: } ! 1011: return arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands); ! 1012: " ! 1013: [(set_attr "conds" "set")]) ! 1014: ! 1015: (define_insn "" ! 1016: [(set (reg:CC_NOOV 24) ! 1017: (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r") ! 1018: (match_operand:SI 1 "arm_rhs_operand" "rI")) ! 1019: (const_int 0)))] ! 1020: "" ! 1021: "* ! 1022: return arm_output_asm_insn (\"tst\\t%0, %1\", operands); ! 1023: " ! 1024: [(set_attr "conds" "set")]) ! 1025: ! 1026: (define_insn "" ! 1027: [(set (reg:CC_NOOV 24) ! 1028: (compare:CC_NOOV (and:SI (match_operand:SI 0 "s_register_operand" "r") ! 1029: (match_operand:SI 1 "immediate_operand" "K")) ! 1030: (const_int 0))) ! 1031: (clobber (match_scratch:SI 3 "=r"))] ! 1032: "const_ok_for_arm (~INTVAL (operands[1]))" ! 1033: "* ! 1034: operands[1] = GEN_INT (~INTVAL (operands[1])); ! 1035: return arm_output_asm_insn (\"bics\\t%3, %0, %1\", operands); ! 1036: " ! 1037: [(set_attr "conds" "set")]) ! 1038: ! 1039: (define_insn "" ! 1040: [(set (reg:CC_NOOV 24) ! 1041: (compare:CC_NOOV (zero_extract:SI ! 1042: (match_operand:SI 0 "s_register_operand" "r") ! 1043: (match_operand:SI 1 "immediate_operand" "n") ! 1044: (match_operand:SI 2 "immediate_operand" "n")) ! 1045: (const_int 0)))] ! 1046: "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 ! 1047: && INTVAL (operands[1]) > 0 ! 1048: && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 ! 1049: && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32" ! 1050: "* ! 1051: { ! 1052: unsigned int mask = 0; ! 1053: int cnt = INTVAL (operands[1]); ! 1054: ! 1055: while (cnt--) ! 1056: mask = (mask << 1) | 1; ! 1057: operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2])); ! 1058: return arm_output_asm_insn (\"tst\\t%0, %1\", operands); ! 1059: } ! 1060: " ! 1061: [(set_attr "conds" "set")]) ! 1062: ! 1063: (define_insn "" ! 1064: [(set (reg:CC_NOOV 24) ! 1065: (compare:CC_NOOV (zero_extract:SI ! 1066: (match_operand:QI 0 "memory_operand" "m") ! 1067: (match_operand 1 "immediate_operand" "n") ! 1068: (match_operand 2 "immediate_operand" "n")) ! 1069: (const_int 0))) ! 1070: (clobber (match_scratch:QI 3 "=r"))] ! 1071: "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 8 ! 1072: && INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8" ! 1073: "* ! 1074: { ! 1075: unsigned int mask = 0; ! 1076: int cnt = INTVAL (operands[1]); ! 1077: ! 1078: while (cnt--) ! 1079: mask = (mask << 1) | 1; ! 1080: operands[1] = gen_rtx (CONST_INT, VOIDmode, mask << INTVAL (operands[2])); ! 1081: arm_output_asm_insn (\"ldrb\\t%3, %0\", operands); ! 1082: return arm_output_asm_insn (\"tst\\t%3, %1\", operands); ! 1083: } ! 1084: " ! 1085: [(set_attr "conds" "set") ! 1086: (set_attr "length" "2")]) ! 1087: ! 1088: ;; constants for op 2 will never be given to these patterns. ! 1089: (define_insn "" ! 1090: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1091: (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0")) ! 1092: (match_operand:DI 1 "s_register_operand" "0,r")))] ! 1093: "" ! 1094: "* ! 1095: arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! 1096: return arm_output_asm_insn (\"bic\\t%R0, %R1, %R2\", operands); ! 1097: " ! 1098: [(set_attr "length" "2")]) ! 1099: ! 1100: (define_insn "" ! 1101: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1102: (and:DI (not:DI (zero_extend:DI ! 1103: (match_operand:SI 2 "s_register_operand" "r,r"))) ! 1104: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1105: "" ! 1106: "* ! 1107: arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! 1108: if (REGNO (operands[1]) != REGNO (operands[0])) ! 1109: return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands); ! 1110: return \"\"; ! 1111: " ! 1112: [(set_attr "length" "2,1")]) ! 1113: ! 1114: (define_insn "" ! 1115: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1116: (and:DI (not:DI (sign_extend:DI ! 1117: (match_operand:SI 2 "s_register_operand" "r,r"))) ! 1118: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1119: "" ! 1120: "* ! 1121: arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands); ! 1122: return arm_output_asm_insn (\"bic\\t%R0, %R1, %2, asr #31\", operands); ! 1123: " ! 1124: [(set_attr "length" "2")]) ! 1125: ! 1126: (define_insn "" ! 1127: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1128: (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) ! 1129: (match_operand:SI 1 "s_register_operand" "r")))] ! 1130: "" ! 1131: "* ! 1132: return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands)); ! 1133: ") ! 1134: ! 1135: (define_insn "" ! 1136: [(set (reg:CC_NOOV 24) ! 1137: (compare:CC_NOOV (and:SI ! 1138: (not:SI (match_operand:SI 2 "s_register_operand" "r")) ! 1139: (match_operand:SI 1 "s_register_operand" "r")) ! 1140: (const_int 0))) ! 1141: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1142: (and:SI (not:SI (match_dup 2)) (match_dup 1)))] ! 1143: "" ! 1144: "* ! 1145: return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands)); ! 1146: " ! 1147: [(set_attr "conds" "set")]) ! 1148: ! 1149: (define_insn "" ! 1150: [(set (reg:CC_NOOV 24) ! 1151: (compare:CC_NOOV (and:SI ! 1152: (not:SI (match_operand:SI 2 "s_register_operand" "r")) ! 1153: (match_operand:SI 1 "s_register_operand" "r")) ! 1154: (const_int 0))) ! 1155: (clobber (match_scratch:SI 0 "=r"))] ! 1156: "" ! 1157: "* ! 1158: return (arm_output_asm_insn (\"bics\\t%0, %1, %2\", operands)); ! 1159: " ! 1160: [(set_attr "conds" "set")]) ! 1161: ! 1162: (define_insn "iordi3" ! 1163: [(set (match_operand:DI 0 "s_register_operand" "=&r") ! 1164: (ior:DI (match_operand:DI 1 "s_register_operand" "%0") ! 1165: (match_operand:DI 2 "s_register_operand" "r")))] ! 1166: "" ! 1167: "* ! 1168: arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! 1169: return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands)); ! 1170: " ! 1171: [(set_attr "length" "2")]) ! 1172: ! 1173: (define_insn "" ! 1174: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1175: (ior:DI (zero_extend:DI ! 1176: (match_operand:SI 2 "s_register_operand" "r,r")) ! 1177: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1178: "" ! 1179: "* ! 1180: arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! 1181: if (REGNO (operands[0]) != REGNO (operands[1])) ! 1182: return (arm_output_asm_insn (\"mov\\t%R0, %R1\", operands)); ! 1183: return \"\"; ! 1184: " ! 1185: [(set_attr "length" "2,1")]) ! 1186: ! 1187: (define_insn "" ! 1188: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1189: (ior:DI (sign_extend:DI ! 1190: (match_operand:SI 2 "s_register_operand" "r,r")) ! 1191: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1192: "" ! 1193: "* ! 1194: arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! 1195: return (arm_output_asm_insn (\"orr\\t%R0, %R1, %2, asr #31\", operands)); ! 1196: " ! 1197: [(set_attr "length" "2")]) ! 1198: ! 1199: (define_insn "iorsi3" ! 1200: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1201: (ior:SI (match_operand:SI 1 "s_register_operand" "r") ! 1202: (match_operand:SI 2 "arm_rhs_operand" "rI")))] ! 1203: "" ! 1204: "* ! 1205: return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands)); ! 1206: ") ! 1207: ! 1208: (define_insn "" ! 1209: [(set (reg:CC_NOOV 24) ! 1210: (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") ! 1211: (match_operand:SI 2 "arm_rhs_operand" "rI")) ! 1212: (const_int 0))) ! 1213: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1214: (ior:SI (match_dup 1) (match_dup 2)))] ! 1215: "" ! 1216: "* ! 1217: return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands); ! 1218: " ! 1219: [(set_attr "conds" "set")]) ! 1220: ! 1221: (define_insn "" ! 1222: [(set (reg:CC_NOOV 24) ! 1223: (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") ! 1224: (match_operand:SI 2 "arm_rhs_operand" "rI")) ! 1225: (const_int 0))) ! 1226: (clobber (match_scratch:SI 0 "=r"))] ! 1227: "" ! 1228: "* ! 1229: return arm_output_asm_insn (\"orrs\\t%0, %1, %2\", operands); ! 1230: " ! 1231: [(set_attr "conds" "set")]) ! 1232: ! 1233: (define_insn "xordi3" ! 1234: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1235: (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0") ! 1236: (match_operand:DI 2 "s_register_operand" "r,0")))] ! 1237: "" ! 1238: "* ! 1239: arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); ! 1240: return arm_output_asm_insn (\"eor\\t%R0, %R1, %R2\", operands); ! 1241: " ! 1242: [(set_attr "length" "2")]) ! 1243: ! 1244: (define_insn "" ! 1245: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1246: (xor:DI (zero_extend:DI ! 1247: (match_operand:SI 2 "s_register_operand" "r,r")) ! 1248: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1249: "" ! 1250: "* ! 1251: arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); ! 1252: if (REGNO (operands[0]) != REGNO (operands[1])) ! 1253: return arm_output_asm_insn (\"mov\\t%R0, %R1\", operands); ! 1254: return \"\"; ! 1255: " ! 1256: [(set_attr "length" "2,1")]) ! 1257: ! 1258: (define_insn "" ! 1259: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1260: (xor:DI (sign_extend:DI ! 1261: (match_operand:SI 2 "s_register_operand" "r,r")) ! 1262: (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1263: "" ! 1264: "* ! 1265: arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands); ! 1266: return arm_output_asm_insn (\"eor\\t%R0, %R1, %2, asr #31\", operands); ! 1267: " ! 1268: [(set_attr "length" "2")]) ! 1269: ! 1270: (define_insn "xorsi3" ! 1271: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1272: (xor:SI (match_operand:SI 1 "s_register_operand" "r") ! 1273: (match_operand:SI 2 "arm_rhs_operand" "rI")))] ! 1274: "" ! 1275: "* ! 1276: return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands)); ! 1277: ") ! 1278: ! 1279: (define_insn "" ! 1280: [(set (reg:CC_NOOV 24) ! 1281: (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r") ! 1282: (match_operand:SI 2 "arm_rhs_operand" "rI")) ! 1283: (const_int 0))) ! 1284: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1285: (xor:SI (match_dup 1) (match_dup 2)))] ! 1286: "" ! 1287: "* ! 1288: return arm_output_asm_insn (\"eors\\t%0, %1, %2\", operands); ! 1289: " ! 1290: [(set_attr "conds" "set")]) ! 1291: ! 1292: (define_insn "" ! 1293: [(set (reg:CC_NOOV 24) ! 1294: (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r") ! 1295: (match_operand:SI 1 "arm_rhs_operand" "rI")) ! 1296: (const_int 0)))] ! 1297: "" ! 1298: "* ! 1299: return arm_output_asm_insn (\"teq\\t%0, %1\", operands); ! 1300: " ! 1301: [(set_attr "conds" "set")]) ! 1302: ! 1303: ;; by splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), ! 1304: ;; (NOT D) we can sometimes merge the final NOT into one of the following ! 1305: ;; insns ! 1306: ! 1307: (define_split ! 1308: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1309: (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r")) ! 1310: (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))) ! 1311: (match_operand:SI 3 "arm_rhs_operand" "rI"))) ! 1312: (clobber (match_operand:SI 4 "s_register_operand" "=r"))] ! 1313: "" ! 1314: [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2)) ! 1315: (not:SI (match_dup 3)))) ! 1316: (set (match_dup 0) (not:SI (match_dup 4)))] ! 1317: "" ! 1318: ) ! 1319: ! 1320: (define_insn "" ! 1321: [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") ! 1322: (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0") ! 1323: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) ! 1324: (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] ! 1325: "" ! 1326: "* ! 1327: arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); ! 1328: return arm_output_asm_insn (\"bic\\t%0, %0, %3\", operands); ! 1329: " ! 1330: [(set_attr "length" "2")]) ! 1331: ! 1332: ! 1333: ! 1334: ;; Minimum and maximum insns ! 1335: ! 1336: (define_insn "smaxsi3" ! 1337: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 1338: (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") ! 1339: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! 1340: (clobber (reg:CC 24))] ! 1341: "" ! 1342: "* ! 1343: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 1344: if (which_alternative != 0) ! 1345: arm_output_asm_insn (\"movge\\t%0, %1\", operands); ! 1346: if (which_alternative != 1) ! 1347: return arm_output_asm_insn (\"movlt\\t%0, %2\", operands); ! 1348: return \"\"; ! 1349: " ! 1350: [(set_attr "conds" "clob") ! 1351: (set_attr "length" "2,2,3")]) ! 1352: ! 1353: (define_insn "sminsi3" ! 1354: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 1355: (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") ! 1356: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! 1357: (clobber (reg:CC 24))] ! 1358: "" ! 1359: "* ! 1360: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 1361: if (which_alternative != 0) ! 1362: arm_output_asm_insn (\"movle\\t%0, %1\", operands); ! 1363: if (which_alternative != 1) ! 1364: return arm_output_asm_insn (\"movgt\\t%0, %2\", operands); ! 1365: return \"\"; ! 1366: " ! 1367: [(set_attr "conds" "clob") ! 1368: (set_attr "length" "2,2,3")]) ! 1369: ! 1370: (define_insn "umaxsi3" ! 1371: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 1372: (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") ! 1373: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! 1374: (clobber (reg:CC 24))] ! 1375: "" ! 1376: "* ! 1377: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 1378: if (which_alternative != 0) ! 1379: arm_output_asm_insn (\"movcs\\t%0, %1\", operands); ! 1380: if (which_alternative != 1) ! 1381: return arm_output_asm_insn (\"movcc\\t%0, %2\", operands); ! 1382: return \"\"; ! 1383: " ! 1384: [(set_attr "conds" "clob") ! 1385: (set_attr "length" "2,2,3")]) ! 1386: ! 1387: (define_insn "uminsi3" ! 1388: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 1389: (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") ! 1390: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! 1391: (clobber (reg:CC 24))] ! 1392: "" ! 1393: "* ! 1394: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 1395: if (which_alternative != 0) ! 1396: arm_output_asm_insn (\"movcc\\t%0, %1\", operands); ! 1397: if (which_alternative != 1) ! 1398: return arm_output_asm_insn (\"movcs\\t%0, %2\", operands); ! 1399: return \"\"; ! 1400: " ! 1401: [(set_attr "conds" "clob") ! 1402: (set_attr "length" "2,2,3")]) ! 1403: ! 1404: (define_insn "" ! 1405: [(set (match_operand:SI 0 "memory_operand" "=m") ! 1406: (match_operator:SI 3 "minmax_operator" ! 1407: [(match_operand:SI 1 "s_register_operand" "r") ! 1408: (match_operand:SI 2 "s_register_operand" "r")])) ! 1409: (clobber (reg:CC 24))] ! 1410: "" ! 1411: "* ! 1412: operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1], ! 1413: operands[2]); ! 1414: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 1415: arm_output_asm_insn (\"str%d3\\t%1, %0\", operands); ! 1416: return arm_output_asm_insn (\"str%D3\\t%2, %0\", operands); ! 1417: " ! 1418: [(set_attr "conds" "clob") ! 1419: (set_attr "length" "3") ! 1420: (set_attr "type" "store1")]) ! 1421: ! 1422: (define_insn "" ! 1423: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 1424: (match_operator:SI 4 "shiftable_operator" ! 1425: [(match_operator:SI 5 "minmax_operator" ! 1426: [(match_operand:SI 2 "s_register_operand" "r,r") ! 1427: (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) ! 1428: (match_operand:SI 1 "s_register_operand" "0,?r")])) ! 1429: (clobber (reg:CC 24))] ! 1430: "" ! 1431: "* ! 1432: { ! 1433: char buf[100]; ! 1434: enum rtx_code code = GET_CODE (operands[4]); ! 1435: char *inst = arithmetic_instr (operands[4], TRUE); ! 1436: ! 1437: operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2], ! 1438: operands[3]); ! 1439: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 1440: sprintf (buf, \"%s%%d5\\t%%0, %%1, %%2\", inst); ! 1441: arm_output_asm_insn (buf, operands); ! 1442: if (which_alternative != 0 || operands[3] != const0_rtx ! 1443: || (code != PLUS && code != MINUS && code != IOR && code != XOR)) ! 1444: { ! 1445: sprintf (buf, \"%s%%D5\\t%%0, %%1, %%3\", inst); ! 1446: return arm_output_asm_insn (buf, operands); ! 1447: } ! 1448: return \"\"; ! 1449: } ! 1450: " ! 1451: [(set_attr "conds" "clob") ! 1452: (set_attr "length" "3")]) ! 1453: ! 1454: ! 1455: ;; Shift and rotation insns ! 1456: ! 1457: (define_insn "ashlsi3" ! 1458: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1459: (ashift:SI (match_operand:SI 1 "s_register_operand" "r") ! 1460: (match_operand:SI 2 "arm_rhs_operand" "rn")))] ! 1461: "" ! 1462: "* ! 1463: return (output_shifted_move (ASHIFT, operands)); ! 1464: ") ! 1465: ! 1466: (define_insn "ashrsi3" ! 1467: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1468: (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "r") ! 1469: (match_operand:SI 2 "arm_rhs_operand" "rn")))] ! 1470: "" ! 1471: "* ! 1472: return (output_shifted_move (ASHIFTRT, operands)); ! 1473: ") ! 1474: ! 1475: ;; lshlsi3 is not defined because shift counts cannot be negative ! 1476: ;; An unnamed pattern is needed for expansion of zero_extend. ! 1477: ! 1478: (define_insn "" ! 1479: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1480: (lshift:SI (match_operand:SI 1 "s_register_operand" "r") ! 1481: (match_operand:SI 2 "arm_rhs_operand" "rn")))] ! 1482: "" ! 1483: "* ! 1484: return (output_shifted_move (LSHIFT, operands)); ! 1485: ") ! 1486: ! 1487: (define_insn "lshrsi3" ! 1488: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1489: (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "r") ! 1490: (match_operand:SI 2 "arm_rhs_operand" "rn")))] ! 1491: "" ! 1492: "* ! 1493: return (output_shifted_move (LSHIFTRT, operands)); ! 1494: ") ! 1495: ! 1496: ;; rotlsi3 is not defined yet to see what happens ! 1497: ! 1498: (define_insn "rotrsi3" ! 1499: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 1500: (rotatert:SI (match_operand:SI 1 "s_register_operand" "r,r") ! 1501: (match_operand:SI 2 "arm_rhs_operand" "r,n")))] ! 1502: "" ! 1503: "* ! 1504: switch (which_alternative) ! 1505: { ! 1506: case 0: ! 1507: return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands)); ! 1508: case 1: ! 1509: if (INTVAL(operands[2]) > 31) ! 1510: operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32); ! 1511: return (arm_output_asm_insn (\"mov\\t%0, %1, ror %2\", operands)); ! 1512: } ! 1513: ") ! 1514: ! 1515: (define_insn "" ! 1516: [(set (reg:CC_NOOV 24) ! 1517: (compare:CC_NOOV (match_operator:SI 1 "shift_operator" ! 1518: [(match_operand:SI 2 "s_register_operand" "r") ! 1519: (match_operand:SI 3 "arm_rhs_operand" "rn")]) ! 1520: (const_int 0))) ! 1521: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1522: (match_op_dup 1 [(match_dup 2) (match_dup 3)]))] ! 1523: "" ! 1524: "* ! 1525: { ! 1526: char buf[100]; ! 1527: ! 1528: sprintf (buf, \"movs\\t%%0, %%2, %s %%3\", ! 1529: shift_instr (GET_CODE (operands[1]), &operands[3])); ! 1530: return arm_output_asm_insn (buf, operands); ! 1531: } ! 1532: " ! 1533: [(set_attr "conds" "set")]) ! 1534: ! 1535: (define_insn "" ! 1536: [(set (reg:CC_NOOV 24) ! 1537: (compare:CC_NOOV (match_operator:SI 1 "shift_operator" ! 1538: [(match_operand:SI 2 "s_register_operand" "r") ! 1539: (match_operand:SI 3 "arm_rhs_operand" "rn")]) ! 1540: (const_int 0))) ! 1541: (clobber (match_scratch:SI 0 "=r"))] ! 1542: "" ! 1543: "* ! 1544: { ! 1545: char buf[100]; ! 1546: ! 1547: sprintf (buf, \"movs\\t%%0, %%2, %s %%3\", ! 1548: shift_instr (GET_CODE (operands[1]), &operands[3])); ! 1549: return arm_output_asm_insn (buf, operands); ! 1550: } ! 1551: " ! 1552: [(set_attr "conds" "set")]) ! 1553: ! 1554: (define_insn "" ! 1555: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1556: (not:SI (match_operator:SI 1 "shift_operator" ! 1557: [(match_operand:SI 2 "s_register_operand" "r") ! 1558: (match_operand:SI 3 "arm_rhs_operand" "rn")])))] ! 1559: "" ! 1560: "* ! 1561: { ! 1562: char buf[100]; ! 1563: sprintf (buf, \"mvn\\t%%0, %%2, %s %%3\", ! 1564: shift_instr (GET_CODE (operands[1]), &operands[3])); ! 1565: return arm_output_asm_insn (buf, operands); ! 1566: } ! 1567: ") ! 1568: ! 1569: (define_insn "" ! 1570: [(set (reg:CC_NOOV 24) ! 1571: (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator" ! 1572: [(match_operand:SI 2 "s_register_operand" "r") ! 1573: (match_operand:SI 3 "arm_rhs_operand" "rn")])) ! 1574: (const_int 0))) ! 1575: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1576: (not:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])))] ! 1577: "" ! 1578: "* ! 1579: { ! 1580: char buf[100]; ! 1581: sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\", ! 1582: shift_instr (GET_CODE (operands[1]), &operands[3])); ! 1583: return arm_output_asm_insn (buf, operands); ! 1584: } ! 1585: " ! 1586: [(set_attr "conds" "set")]) ! 1587: ! 1588: (define_insn "" ! 1589: [(set (reg:CC_NOOV 24) ! 1590: (compare:CC_NOOV (not:SI (match_operator:SI 1 "shift_operator" ! 1591: [(match_operand:SI 2 "s_register_operand" "r") ! 1592: (match_operand:SI 3 "arm_rhs_operand" "rn")])) ! 1593: (const_int 0))) ! 1594: (clobber (match_scratch:SI 0 "=r"))] ! 1595: "" ! 1596: "* ! 1597: { ! 1598: char buf[100]; ! 1599: sprintf (buf, \"mvns\\t%%0, %%2, %s %%3\", ! 1600: shift_instr (GET_CODE (operands[1]), &operands[3])); ! 1601: return arm_output_asm_insn (buf, operands); ! 1602: } ! 1603: " ! 1604: [(set_attr "conds" "set")]) ! 1605: ! 1606: ! 1607: ;; Unary arithmetic insns ! 1608: ! 1609: (define_insn "negdi2" ! 1610: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1611: (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1612: "" ! 1613: "* ! 1614: arm_output_asm_insn (\"rsbs\\t%0, %1, #0\", operands); ! 1615: return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands)); ! 1616: " ! 1617: [(set_attr "conds" "clob") ! 1618: (set_attr "length" "2")]) ! 1619: ! 1620: (define_insn "negsi2" ! 1621: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1622: (neg:SI (match_operand:SI 1 "s_register_operand" "r")))] ! 1623: "" ! 1624: "* ! 1625: return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands)); ! 1626: ") ! 1627: ! 1628: (define_insn "negsf2" ! 1629: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1630: (neg:SF (match_operand:SF 1 "s_register_operand" "f")))] ! 1631: "" ! 1632: "* ! 1633: return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands)); ! 1634: " ! 1635: [(set_attr "type" "float")]) ! 1636: ! 1637: (define_insn "negdf2" ! 1638: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1639: (neg:DF (match_operand:DF 1 "s_register_operand" "f")))] ! 1640: "" ! 1641: "* ! 1642: return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands)); ! 1643: " ! 1644: [(set_attr "type" "float")]) ! 1645: ! 1646: (define_insn "" ! 1647: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1648: (neg:DF (float_extend:DF ! 1649: (match_operand:SF 1 "s_register_operand" "f"))))] ! 1650: "" ! 1651: "* ! 1652: return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands)); ! 1653: " ! 1654: [(set_attr "type" "float")]) ! 1655: ! 1656: (define_insn "negxf2" ! 1657: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1658: (neg:XF (match_operand:XF 1 "s_register_operand" "f")))] ! 1659: "ENABLE_XF_PATTERNS" ! 1660: "* ! 1661: return (arm_output_asm_insn (\"mnfe\\t%0, %1\", operands)); ! 1662: " ! 1663: [(set_attr "type" "float")]) ! 1664: ! 1665: ;; abssi2 doesn't really clobber the condition codes if a different register ! 1666: ;; is being set. To keep things simple, assume during rtl manipulations that ! 1667: ;; it does, but tell the final scan operator the truth. Similarly for ! 1668: ;; (neg (abs...)) ! 1669: ! 1670: (define_insn "abssi2" ! 1671: [(set (match_operand:SI 0 "s_register_operand" "=r,&r") ! 1672: (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) ! 1673: (clobber (reg 24))] ! 1674: "" ! 1675: "* ! 1676: switch (which_alternative) ! 1677: { ! 1678: case 0: ! 1679: arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! 1680: return arm_output_asm_insn (\"rsblt\\t%0, %0, #0\", operands); ! 1681: case 1: ! 1682: arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands); ! 1683: return arm_output_asm_insn (\"sub\\t%0, %0, %1, asr #31\", operands); ! 1684: } ! 1685: " ! 1686: [(set_attr "conds" "clob,*") ! 1687: (set_attr "length" "2")]) ! 1688: ! 1689: (define_insn "" ! 1690: [(set (match_operand:SI 0 "s_register_operand" "=r,&r") ! 1691: (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) ! 1692: (clobber (reg 24))] ! 1693: "" ! 1694: "* ! 1695: switch (which_alternative) ! 1696: { ! 1697: case 0: ! 1698: arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! 1699: return arm_output_asm_insn (\"rsbgt\\t%0, %0, #0\", operands); ! 1700: case 1: ! 1701: arm_output_asm_insn (\"eor\\t%0, %1, %1, asr #31\", operands); ! 1702: return arm_output_asm_insn (\"rsb\\t%0, %0, %1, asr #31\", operands); ! 1703: } ! 1704: " ! 1705: [(set_attr "conds" "clob,*") ! 1706: (set_attr "length" "2")]) ! 1707: ! 1708: (define_insn "abssf2" ! 1709: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1710: (abs:SF (match_operand:SF 1 "s_register_operand" "f")))] ! 1711: "" ! 1712: "* ! 1713: return (arm_output_asm_insn (\"abss\\t%0, %1\", operands)); ! 1714: " ! 1715: [(set_attr "type" "float")]) ! 1716: ! 1717: (define_insn "absdf2" ! 1718: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1719: (abs:DF (match_operand:DF 1 "s_register_operand" "f")))] ! 1720: "" ! 1721: "* ! 1722: return (arm_output_asm_insn (\"absd\\t%0, %1\", operands)); ! 1723: " ! 1724: [(set_attr "type" "float")]) ! 1725: ! 1726: (define_insn "" ! 1727: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1728: (abs:DF (float_extend:DF ! 1729: (match_operand:SF 1 "s_register_operand" "f"))))] ! 1730: "" ! 1731: "* ! 1732: return (arm_output_asm_insn (\"absd\\t%0, %1\", operands)); ! 1733: " ! 1734: [(set_attr "type" "float")]) ! 1735: ! 1736: (define_insn "absxf2" ! 1737: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1738: (abs:XF (match_operand:XF 1 "s_register_operand" "f")))] ! 1739: "ENABLE_XF_PATTERNS" ! 1740: "* ! 1741: return (arm_output_asm_insn (\"abse\\t%0, %1\", operands)); ! 1742: " ! 1743: [(set_attr "type" "float")]) ! 1744: ! 1745: (define_insn "sqrtsf2" ! 1746: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1747: (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))] ! 1748: "" ! 1749: "* ! 1750: return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands)); ! 1751: " ! 1752: [(set_attr "type" "float_em")]) ! 1753: ! 1754: (define_insn "sqrtdf2" ! 1755: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1756: (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))] ! 1757: "" ! 1758: "* ! 1759: return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands)); ! 1760: " ! 1761: [(set_attr "type" "float_em")]) ! 1762: ! 1763: (define_insn "" ! 1764: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1765: (sqrt:DF (float_extend:DF ! 1766: (match_operand:SF 1 "s_register_operand" "f"))))] ! 1767: "" ! 1768: "* ! 1769: return (arm_output_asm_insn (\"sqtd\\t%0, %1\", operands)); ! 1770: " ! 1771: [(set_attr "type" "float_em")]) ! 1772: ! 1773: (define_insn "sqrtxf2" ! 1774: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1775: (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))] ! 1776: "ENABLE_XF_PATTERNS" ! 1777: "* ! 1778: return (arm_output_asm_insn (\"sqte\\t%0, %1\", operands)); ! 1779: " ! 1780: [(set_attr "type" "float_em")]) ! 1781: ! 1782: (define_insn "sinsf2" ! 1783: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1784: (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 0))] ! 1785: "" ! 1786: "* ! 1787: return arm_output_asm_insn (\"sins\\t%0, %1\", operands); ! 1788: " ! 1789: [(set_attr "type" "float_em")]) ! 1790: ! 1791: (define_insn "sindf2" ! 1792: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1793: (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 0))] ! 1794: "" ! 1795: "* ! 1796: return arm_output_asm_insn (\"sind\\t%0, %1\", operands); ! 1797: " ! 1798: [(set_attr "type" "float_em")]) ! 1799: ! 1800: (define_insn "" ! 1801: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1802: (unspec:DF [(float_extend:DF ! 1803: (match_operand:SF 1 "s_register_operand" "f"))] 0))] ! 1804: "" ! 1805: "* ! 1806: return arm_output_asm_insn (\"sind\\t%0, %1\", operands); ! 1807: " ! 1808: [(set_attr "type" "float_em")]) ! 1809: ! 1810: (define_insn "sinxf2" ! 1811: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1812: (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 0))] ! 1813: "ENABLE_XF_PATTERNS" ! 1814: "* ! 1815: return arm_output_asm_insn (\"sine\\t%0, %1\", operands); ! 1816: " ! 1817: [(set_attr "type" "float_em")]) ! 1818: ! 1819: (define_insn "cossf2" ! 1820: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1821: (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 1))] ! 1822: "" ! 1823: "* ! 1824: return arm_output_asm_insn (\"coss\\t%0, %1\", operands); ! 1825: " ! 1826: [(set_attr "type" "float_em")]) ! 1827: ! 1828: (define_insn "cosdf2" ! 1829: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1830: (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 1))] ! 1831: "" ! 1832: "* ! 1833: return arm_output_asm_insn (\"cosd\\t%0, %1\", operands); ! 1834: " ! 1835: [(set_attr "type" "float_em")]) ! 1836: ! 1837: (define_insn "" ! 1838: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1839: (unspec:DF [(float_extend:DF ! 1840: (match_operand:SF 1 "s_register_operand" "f"))] 1))] ! 1841: "" ! 1842: "* ! 1843: return arm_output_asm_insn (\"cosd\\t%0, %1\", operands); ! 1844: " ! 1845: [(set_attr "type" "float_em")]) ! 1846: ! 1847: (define_insn "cosxf2" ! 1848: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1849: (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 1))] ! 1850: "ENABLE_XF_PATTERNS" ! 1851: "* ! 1852: return arm_output_asm_insn (\"cose\\t%0, %1\", operands); ! 1853: " ! 1854: [(set_attr "type" "float_em")]) ! 1855: ! 1856: (define_insn "one_cmpldi2" ! 1857: [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") ! 1858: (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] ! 1859: "" ! 1860: "* ! 1861: arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! 1862: return arm_output_asm_insn (\"mvn\\t%R0, %R1\", operands); ! 1863: " ! 1864: [(set_attr "length" "2")]) ! 1865: ! 1866: (define_insn "one_cmplsi2" ! 1867: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1868: (not:SI (match_operand:SI 1 "s_register_operand" "r")))] ! 1869: "" ! 1870: "* ! 1871: return (arm_output_asm_insn (\"mvn\\t%0, %1\", operands)); ! 1872: ") ! 1873: ! 1874: (define_insn "" ! 1875: [(set (reg:CC_NOOV 24) ! 1876: (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) ! 1877: (const_int 0))) ! 1878: (set (match_operand:SI 0 "s_register_operand" "=r") ! 1879: (not:SI (match_dup 1)))] ! 1880: "" ! 1881: "* ! 1882: return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands)); ! 1883: " ! 1884: [(set_attr "conds" "set")]) ! 1885: ! 1886: (define_insn "" ! 1887: [(set (reg:CC_NOOV 24) ! 1888: (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) ! 1889: (const_int 0))) ! 1890: (clobber (match_scratch:SI 0 "=r"))] ! 1891: "" ! 1892: "* ! 1893: return (arm_output_asm_insn (\"mvns\\t%0, %1\", operands)); ! 1894: " ! 1895: [(set_attr "conds" "set")]) ! 1896: ! 1897: ;; Fixed <--> Floating conversion insns ! 1898: ! 1899: (define_insn "floatsisf2" ! 1900: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1901: (float:SF (match_operand:SI 1 "s_register_operand" "r")))] ! 1902: "" ! 1903: "* ! 1904: return (arm_output_asm_insn (\"flts\\t%0, %1\", operands)); ! 1905: " ! 1906: [(set_attr "type" "r_2_f")]) ! 1907: ! 1908: (define_insn "floatsidf2" ! 1909: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1910: (float:DF (match_operand:SI 1 "s_register_operand" "r")))] ! 1911: "" ! 1912: "* ! 1913: return (arm_output_asm_insn (\"fltd\\t%0, %1\", operands)); ! 1914: " ! 1915: [(set_attr "type" "r_2_f")]) ! 1916: ! 1917: (define_insn "floatsixf2" ! 1918: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 1919: (float:XF (match_operand:SI 1 "s_register_operand" "r")))] ! 1920: "ENABLE_XF_PATTERNS" ! 1921: "* ! 1922: return (arm_output_asm_insn (\"flte\\t%0, %1\", operands)); ! 1923: " ! 1924: [(set_attr "type" "r_2_f")]) ! 1925: ! 1926: (define_insn "fix_truncsfsi2" ! 1927: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1928: (fix:SI (match_operand:SF 1 "s_register_operand" "f")))] ! 1929: "" ! 1930: "* ! 1931: return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! 1932: " ! 1933: [(set_attr "type" "f_2_r")]) ! 1934: ! 1935: (define_insn "fix_truncdfsi2" ! 1936: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1937: (fix:SI (match_operand:DF 1 "s_register_operand" "f")))] ! 1938: "" ! 1939: "* ! 1940: return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! 1941: " ! 1942: [(set_attr "type" "f_2_r")]) ! 1943: ! 1944: (define_insn "fix_truncxfsi2" ! 1945: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 1946: (fix:SI (match_operand:XF 1 "s_register_operand" "f")))] ! 1947: "ENABLE_XF_PATTERNS" ! 1948: "* ! 1949: return arm_output_asm_insn (\"fixz\\t%0, %1\", operands); ! 1950: " ! 1951: [(set_attr "type" "f_2_r")]) ! 1952: ! 1953: ;; Truncation insns ! 1954: ! 1955: (define_insn "truncdfsf2" ! 1956: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1957: (float_truncate:SF ! 1958: (match_operand:DF 1 "s_register_operand" "f")))] ! 1959: "" ! 1960: "* ! 1961: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); ! 1962: " ! 1963: [(set_attr "type" "float")]) ! 1964: ! 1965: (define_insn "truncxfsf2" ! 1966: [(set (match_operand:SF 0 "s_register_operand" "=f") ! 1967: (float_truncate:SF ! 1968: (match_operand:XF 1 "s_register_operand" "f")))] ! 1969: "ENABLE_XF_PATTERNS" ! 1970: "* ! 1971: return (arm_output_asm_insn (\"mvfs\\t%0, %1\", operands)); ! 1972: " ! 1973: [(set_attr "type" "float")]) ! 1974: ! 1975: (define_insn "truncxfdf2" ! 1976: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 1977: (float_truncate:DF ! 1978: (match_operand:XF 1 "s_register_operand" "f")))] ! 1979: "ENABLE_XF_PATTERNS" ! 1980: "* ! 1981: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); ! 1982: " ! 1983: [(set_attr "type" "float")]) ! 1984: ! 1985: ;; Zero and sign extension instructions. ! 1986: ! 1987: (define_insn "zero_extendsidi2" ! 1988: [(set (match_operand:DI 0 "s_register_operand" "=r") ! 1989: (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] ! 1990: "" ! 1991: "* ! 1992: if (REGNO (operands[1]) != REGNO (operands[0])) ! 1993: arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! 1994: return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! 1995: " ! 1996: [(set_attr "length" "2")]) ! 1997: ! 1998: (define_insn "zero_extendqidi2" ! 1999: [(set (match_operand:DI 0 "s_register_operand" "=r,r") ! 2000: (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] ! 2001: "" ! 2002: "* ! 2003: switch (which_alternative) ! 2004: { ! 2005: case 0: ! 2006: arm_output_asm_insn (\"and\\t%0, %1, #255\", operands); ! 2007: break; ! 2008: case 1: ! 2009: arm_output_asm_insn (\"ldrb\\t%0, %1\",operands); ! 2010: break; ! 2011: } ! 2012: return arm_output_asm_insn (\"mov\\t%R0, #0\", operands); ! 2013: " ! 2014: [(set_attr "length" "2") ! 2015: (set_attr "type" "*,load")]) ! 2016: ! 2017: (define_insn "extendsidi2" ! 2018: [(set (match_operand:DI 0 "s_register_operand" "=r") ! 2019: (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] ! 2020: "" ! 2021: "* ! 2022: if (REGNO (operands[1]) != REGNO (operands[0])) ! 2023: arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! 2024: return arm_output_asm_insn (\"mov\\t%R0, %0, asr #31\", operands); ! 2025: " ! 2026: [(set_attr "length" "2")]) ! 2027: ! 2028: (define_expand "zero_extendhisi2" ! 2029: [(set (match_dup 2) ! 2030: (ashift:SI (match_operand:HI 1 "s_register_operand" "") ! 2031: (const_int 16))) ! 2032: (set (match_operand:SI 0 "s_register_operand" "") ! 2033: (lshiftrt:SI (match_dup 2) ! 2034: (const_int 16)))] ! 2035: "" ! 2036: " ! 2037: { operands[1] = gen_lowpart (SImode, operands[1]); ! 2038: operands[2] = gen_reg_rtx (SImode); }") ! 2039: ! 2040: (define_insn "zero_extendqihi2" ! 2041: [(set (match_operand:HI 0 "s_register_operand" "=r") ! 2042: (zero_extend:HI ! 2043: (match_operand:QI 1 "s_register_operand" "r")))] ! 2044: "" ! 2045: "* ! 2046: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqihi2\", operands)); ! 2047: ") ! 2048: ! 2049: (define_insn "" ! 2050: [(set (reg:CC_NOOV 24) ! 2051: (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") ! 2052: (const_int 0))) ! 2053: (set (match_operand:SI 0 "s_register_operand" "=r") ! 2054: (zero_extend:HI (match_dup 1)))] ! 2055: "" ! 2056: "* ! 2057: return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); ! 2058: " ! 2059: [(set_attr "conds" "set")]) ! 2060: ! 2061: (define_insn "" ! 2062: [(set (reg:CC_NOOV 24) ! 2063: (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r") ! 2064: (const_int 0)))] ! 2065: "" ! 2066: "* ! 2067: return arm_output_asm_insn (\"tst\\t%0, #255\", operands); ! 2068: " ! 2069: [(set_attr "conds" "set")]) ! 2070: ! 2071: (define_insn "zero_extendqisi2" ! 2072: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 2073: (zero_extend:SI ! 2074: (match_operand:QI 1 "nonimmediate_operand" "r,m")))] ! 2075: "" ! 2076: "* ! 2077: switch (which_alternative) ! 2078: { ! 2079: case 0: ! 2080: return (arm_output_asm_insn (\"and\\t%0, %1, #255\\t@ zero_extendqisi2\", operands)); ! 2081: case 1: ! 2082: return (arm_output_asm_insn (\"ldrb\\t%0, %1\\t@ zero_extendqisi2\", operands)); ! 2083: } ! 2084: " ! 2085: [(set_attr "type" "*,load")]) ! 2086: ! 2087: (define_insn "" ! 2088: [(set (reg:CC_NOOV 24) ! 2089: (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") ! 2090: (const_int 0))) ! 2091: (set (match_operand:SI 0 "s_register_operand" "=r") ! 2092: (zero_extend:SI (match_dup 1)))] ! 2093: "" ! 2094: "* ! 2095: return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); ! 2096: " ! 2097: [(set_attr "conds" "set")]) ! 2098: ! 2099: (define_insn "" ! 2100: [(set (reg:CC_NOOV 24) ! 2101: (compare:CC_NOOV (match_operand:QI 1 "s_register_operand" "r") ! 2102: (const_int 0))) ! 2103: (set (match_operand:QI 0 "s_register_operand" "=r") ! 2104: (match_dup 1))] ! 2105: "" ! 2106: "* ! 2107: return arm_output_asm_insn (\"ands\\t%0, %1, #255\", operands); ! 2108: " ! 2109: [(set_attr "conds" "set")]) ! 2110: ! 2111: (define_expand "extendhisi2" ! 2112: [(set (match_dup 2) ! 2113: (ashift:SI (match_operand:HI 1 "s_register_operand" "") ! 2114: (const_int 16))) ! 2115: (set (match_operand:SI 0 "s_register_operand" "") ! 2116: (ashiftrt:SI (match_dup 2) ! 2117: (const_int 16)))] ! 2118: "" ! 2119: " ! 2120: { operands[1] = gen_lowpart (SImode, operands[1]); ! 2121: operands[2] = gen_reg_rtx (SImode); }") ! 2122: ! 2123: (define_expand "extendqihi2" ! 2124: [(set (match_dup 2) ! 2125: (ashift:SI (match_operand:QI 1 "s_register_operand" "") ! 2126: (const_int 24))) ! 2127: (set (match_operand:HI 0 "s_register_operand" "") ! 2128: (ashiftrt:SI (match_dup 2) ! 2129: (const_int 24)))] ! 2130: "" ! 2131: " ! 2132: { operands[0] = gen_lowpart (SImode, operands[0]); ! 2133: operands[1] = gen_lowpart (SImode, operands[1]); ! 2134: operands[2] = gen_reg_rtx (SImode); }") ! 2135: ! 2136: (define_expand "extendqisi2" ! 2137: [(set (match_dup 2) ! 2138: (ashift:SI (match_operand:QI 1 "s_register_operand" "") ! 2139: (const_int 24))) ! 2140: (set (match_operand:SI 0 "s_register_operand" "") ! 2141: (ashiftrt:SI (match_dup 2) ! 2142: (const_int 24)))] ! 2143: "" ! 2144: " ! 2145: { operands[1] = gen_lowpart (SImode, operands[1]); ! 2146: operands[2] = gen_reg_rtx (SImode); }") ! 2147: ! 2148: (define_insn "extendsfdf2" ! 2149: [(set (match_operand:DF 0 "s_register_operand" "=f") ! 2150: (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))] ! 2151: "" ! 2152: "* ! 2153: return (arm_output_asm_insn (\"mvfd\\t%0, %1\", operands)); ! 2154: " ! 2155: [(set_attr "type" "float")]) ! 2156: ! 2157: (define_insn "extendsfxf2" ! 2158: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 2159: (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))] ! 2160: "ENABLE_XF_PATTERNS" ! 2161: "* ! 2162: return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands)); ! 2163: ") ! 2164: ! 2165: (define_insn "extenddfxf2" ! 2166: [(set (match_operand:XF 0 "s_register_operand" "=f") ! 2167: (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))] ! 2168: "ENABLE_XF_PATTERNS" ! 2169: "* ! 2170: return (arm_output_asm_insn (\"mvfe\\t%0, %1\", operands)); ! 2171: " ! 2172: [(set_attr "type" "float")]) ! 2173: ! 2174: ! 2175: ;; Move insns (including loads and stores) ! 2176: ! 2177: ;; XXX Just some ideas about movti. ! 2178: ;; I don't think these are a good idea on the arm, there just aren't enough ! 2179: ;; registers ! 2180: ;;(define_expand "loadti" ! 2181: ;; [(set (match_operand:TI 0 "s_register_operand" "") ! 2182: ;; (mem:TI (match_operand:SI 1 "address_operand" "")))] ! 2183: ;; "" "") ! 2184: ! 2185: ;;(define_expand "storeti" ! 2186: ;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) ! 2187: ;; (match_operand:TI 1 "s_register_operand" ""))] ! 2188: ;; "" "") ! 2189: ! 2190: ;;(define_expand "movti" ! 2191: ;; [(set (match_operand:TI 0 "general_operand" "") ! 2192: ;; (match_operand:TI 1 "general_operand" ""))] ! 2193: ;; "" ! 2194: ;; " ! 2195: ;;{ ! 2196: ;; rtx insn; ! 2197: ;; ! 2198: ;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) ! 2199: ;; operands[1] = copy_to_reg (operands[1]); ! 2200: ;; if (GET_CODE (operands[0]) == MEM) ! 2201: ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]); ! 2202: ;; else if (GET_CODE (operands[1]) == MEM) ! 2203: ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0)); ! 2204: ;; else ! 2205: ;; FAIL; ! 2206: ;; ! 2207: ;; emit_insn (insn); ! 2208: ;; DONE; ! 2209: ;;}") ! 2210: ! 2211: ;; Recognise garbage generated above. ! 2212: ! 2213: ;;(define_insn "" ! 2214: ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") ! 2215: ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))] ! 2216: ;; "" ! 2217: ;; "* ! 2218: ;; { ! 2219: ;; register mem = (which_alternative < 3); ! 2220: ;; register char *template; ! 2221: ;; ! 2222: ;; operands[mem] = XEXP (operands[mem], 0); ! 2223: ;; switch (which_alternative) ! 2224: ;; { ! 2225: ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break; ! 2226: ;; case 1: template = \"ldmia\\t%1!, %M0\"; break; ! 2227: ;; case 2: template = \"ldmia\\t%1, %M0\"; break; ! 2228: ;; case 3: template = \"stmdb\\t%0!, %M1\"; break; ! 2229: ;; case 4: template = \"stmia\\t%0!, %M1\"; break; ! 2230: ;; case 5: template = \"stmia\\t%0, %M1\"; break; ! 2231: ;; } ! 2232: ;; return (arm_output_asm_insn (template, operands)); ! 2233: ;; }") ! 2234: ! 2235: ! 2236: (define_insn "movdi" ! 2237: [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r") ! 2238: (match_operand:DI 1 "di_operand" "rK,n,o<>,r,F"))] ! 2239: "" ! 2240: "* ! 2241: return (output_move_double (operands)); ! 2242: " ! 2243: [(set_attr "length" "2,8,2,2,8") ! 2244: (set_attr "type" "*,*,load,store2,*")]) ! 2245: ! 2246: (define_expand "movsi" ! 2247: [(set (match_operand:SI 0 "general_operand" "") ! 2248: (match_operand:SI 1 "general_operand" ""))] ! 2249: "" ! 2250: " ! 2251: /* Everything except mem = const or mem = mem can be done easily */ ! 2252: if (GET_CODE (operands[0]) == MEM) ! 2253: operands[1] = force_reg (SImode, operands[1]); ! 2254: if (GET_CODE (operands[1]) == CONST_INT ! 2255: && !(const_ok_for_arm (INTVAL (operands[1])) ! 2256: || const_ok_for_arm (~INTVAL (operands[1])))) ! 2257: { ! 2258: int n = INTVAL (operands[1]); ! 2259: rtx tmpreg, tmpreg2; ! 2260: int i, n_ones = 0, first = 1, last = 0; ! 2261: ! 2262: if (GET_CODE (operands[0]) != REG ! 2263: && GET_CODE (operands[0]) != SUBREG) ! 2264: abort (); ! 2265: for (i = 0; i < 32; i++) ! 2266: if (n & 1 << i) ! 2267: n_ones++; ! 2268: /* These loops go the opposite way around to those in arm.c so that ! 2269: the last constant may be more likely to be eliminted into the ! 2270: next instruction */ ! 2271: ! 2272: if (n_ones > 16) ! 2273: { ! 2274: n = (~n) & 0xffffffff; ! 2275: for (i = 30; i >= 0; i -= 2) ! 2276: { ! 2277: if (n & (3 << i)) ! 2278: { ! 2279: i -= 6; ! 2280: if (i < 0) ! 2281: i = 0; ! 2282: if ((n & (255 << i)) == n) ! 2283: last = 1; ! 2284: if (first) ! 2285: { ! 2286: rtx equal; ! 2287: rtx insn = ! 2288: emit_insn (gen_movsi (tmpreg = (reload_in_progress ! 2289: || reload_completed) ! 2290: ? operands[0] ! 2291: : gen_reg_rtx (SImode), ! 2292: equal = gen_rtx (CONST_INT, VOIDmode, ! 2293: ~(n & (255 << i))))); ! 2294: first = 0; ! 2295: } ! 2296: else ! 2297: { ! 2298: rtx constant; ! 2299: rtx insn = ! 2300: emit_insn (gen_subsi3 (tmpreg2 = (reload_in_progress ! 2301: || reload_completed ! 2302: || last) ! 2303: ? operands[0] ! 2304: : gen_reg_rtx (SImode), ! 2305: tmpreg, ! 2306: constant = gen_rtx (CONST_INT, VOIDmode, ! 2307: n & (255 << i)))); ! 2308: tmpreg = tmpreg2; ! 2309: } ! 2310: n &= ~(255 << i); ! 2311: } ! 2312: } ! 2313: } ! 2314: else ! 2315: { ! 2316: for (i = 30; i >= 0; i -= 2) ! 2317: { ! 2318: if (n & (3 << i)) ! 2319: { ! 2320: i -= 6; ! 2321: if (i < 0) ! 2322: i = 0; ! 2323: if ((n & (255 << i)) == n) ! 2324: last = 1; ! 2325: if (first) ! 2326: { ! 2327: rtx equal; ! 2328: rtx insn = ! 2329: emit_insn (gen_movsi (tmpreg = (reload_in_progress ! 2330: || reload_completed) ! 2331: ? operands[0] ! 2332: : gen_reg_rtx (SImode), ! 2333: equal = gen_rtx (CONST_INT, VOIDmode, ! 2334: n & (255 << i)))); ! 2335: first = 0; ! 2336: } ! 2337: else ! 2338: { ! 2339: rtx constant; ! 2340: rtx insn = ! 2341: emit_insn (gen_addsi3 (tmpreg2 = (reload_in_progress ! 2342: || reload_completed ! 2343: || last) ! 2344: ? operands[0] ! 2345: : gen_reg_rtx (SImode), ! 2346: tmpreg, ! 2347: constant = gen_rtx (CONST_INT, VOIDmode, ! 2348: n & (255 << i)))); ! 2349: tmpreg = tmpreg2; ! 2350: } ! 2351: n &= ~(255 << i); ! 2352: } ! 2353: } ! 2354: } ! 2355: DONE; ! 2356: } ! 2357: ") ! 2358: ! 2359: (define_insn "" ! 2360: [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,r") ! 2361: (match_operand:SI 1 "general_operand" "m,K,r,r,S"))] ! 2362: "(register_operand (operands[0], SImode) ! 2363: && (GET_CODE (operands[1]) != CONST_INT ! 2364: || const_ok_for_arm (INTVAL (operands[1])) ! 2365: || const_ok_for_arm (~INTVAL (operands[1]))) ! 2366: && (GET_CODE (operands[1]) != SYMBOL_REF ! 2367: || CONSTANT_ADDRESS_P (operands[1]))) ! 2368: || register_operand (operands[1], SImode)" ! 2369: "* ! 2370: switch (which_alternative) ! 2371: { ! 2372: case 2: ! 2373: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); ! 2374: case 1: ! 2375: if (!const_ok_for_arm (INTVAL (operands[1]))) ! 2376: { ! 2377: operands[1] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[1])); ! 2378: return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! 2379: } ! 2380: return arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! 2381: case 0: ! 2382: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF ! 2383: && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) ! 2384: return (arm_output_llc (operands)); ! 2385: else ! 2386: return (arm_output_asm_insn (\"ldr\\t%0, %1\", operands)); ! 2387: case 3: ! 2388: return (arm_output_asm_insn (\"str\\t%1, %0\", operands)); ! 2389: case 4: ! 2390: return output_load_symbol (operands); ! 2391: } ! 2392: " ! 2393: [(set_attr "length" "2,*,*,*,4") ! 2394: (set_attr "type" "load,*,*,store1,*")]) ! 2395: ! 2396: ;; If copying one reg to another we can set the condition codes according to ! 2397: ;; its value. Such a move is common after a return from subroutine and the ! 2398: ;; result is being tested against zero. ! 2399: ! 2400: (define_insn "" ! 2401: [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "r") ! 2402: (const_int 0))) ! 2403: (set (match_operand:SI 0 "s_register_operand" "=r") (match_dup 1))] ! 2404: "" ! 2405: "* ! 2406: if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG ! 2407: && REGNO (operands[0]) == REGNO (operands[1])) ! 2408: return arm_output_asm_insn (\"cmp\\t%0, #0\", operands); ! 2409: return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands); ! 2410: " ! 2411: [(set_attr "conds" "set")]) ! 2412: ! 2413: ;; Subroutine to store a half word from a register into memory. ! 2414: ;; Operand 0 is the source register (HImode) ! 2415: ;; Operand 1 is the destination address in a register (SImode) ! 2416: ! 2417: ;; In both this routine and the next, we must be careful not to spill ! 2418: ;; a memory address of reg+large_const into a seperate PLUS insn, since this ! 2419: ;; can generate unrecognizable rtl. ! 2420: ! 2421: (define_expand "storehi" ! 2422: [;; store the low byte ! 2423: (set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3)) ! 2424: ;; extract the high byte ! 2425: (set (match_dup 2) ! 2426: (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) ! 2427: ;; store the high byte ! 2428: (set (mem:QI (match_dup 4)) ! 2429: (subreg:QI (match_dup 2) 0))] ;explicit subreg safe ! 2430: "" ! 2431: " ! 2432: { ! 2433: enum rtx_code code = GET_CODE (operands[1]); ! 2434: ! 2435: if ((code == PLUS || code == MINUS) ! 2436: && (GET_CODE (XEXP (operands[1], 1)) == REG ! 2437: || GET_CODE (XEXP (operands[1], 0)) != REG)) ! 2438: operands[1] = force_reg (SImode, operands[1]); ! 2439: operands[4] = plus_constant (operands[1], 1); ! 2440: operands[3] = gen_lowpart (QImode, operands[0]); ! 2441: operands[0] = gen_lowpart (SImode, operands[0]); ! 2442: operands[2] = gen_reg_rtx (SImode); ! 2443: } ! 2444: ") ! 2445: ! 2446: ;; Subroutine to store a half word integer constant into memory. ! 2447: ;; Operand 0 is the constant ! 2448: ;; Operand 1 is the destination address in a register (SImode) ! 2449: ! 2450: (define_expand "storeinthi" ! 2451: [;; store the low byte ! 2452: (set (mem:QI (match_operand:SI 1 "" "")) (match_operand 0 "" "")) ! 2453: ;; store the high byte ! 2454: (set (mem:QI (match_dup 3)) (match_dup 2))] ! 2455: "" ! 2456: " ! 2457: { ! 2458: int value = INTVAL (operands[0]); ! 2459: enum rtx_code code = GET_CODE (operands[1]); ! 2460: ! 2461: if ((code == PLUS || code == MINUS) ! 2462: && (GET_CODE (XEXP (operands[1], 1)) == REG ! 2463: || GET_CODE (XEXP (operands[1], 0)) != REG)) ! 2464: operands[1] = force_reg (SImode, operands[1]); ! 2465: ! 2466: operands[0] = force_reg (QImode, gen_rtx (CONST_INT, VOIDmode, value & 255)); ! 2467: operands[2] = force_reg (QImode, ! 2468: gen_rtx (CONST_INT, VOIDmode,(value>>8) & 255)); ! 2469: operands[3] = plus_constant (operands[1], 1); ! 2470: } ! 2471: ") ! 2472: ! 2473: (define_expand "movhi" ! 2474: [(set (match_operand:HI 0 "general_operand" "") ! 2475: (match_operand:HI 1 "general_operand" ""))] ! 2476: "" ! 2477: " ! 2478: { ! 2479: rtx insn; ! 2480: ! 2481: if (reload_in_progress || reload_completed) ! 2482: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); ! 2483: else ! 2484: { ! 2485: if (GET_CODE (operands[0]) == MEM) ! 2486: { ! 2487: if (GET_CODE (operands[1]) == CONST_INT) ! 2488: { ! 2489: insn = gen_storeinthi (operands[1], XEXP (operands[0],0)); ! 2490: } ! 2491: else ! 2492: { ! 2493: if (GET_CODE (operands[1]) == MEM) ! 2494: operands[1] = force_reg (HImode, operands[1]); ! 2495: insn = gen_storehi (operands[1], XEXP (operands[0], 0)); ! 2496: } ! 2497: } ! 2498: else if (GET_CODE (operands[1]) == CONST_INT ! 2499: && !(const_ok_for_arm (INTVAL (operands[1])) ! 2500: || const_ok_for_arm (~INTVAL (operands[1])))) ! 2501: { ! 2502: rtx reg, reg2; ! 2503: ! 2504: /* no need to be clever, this will always take two insns. ! 2505: The top sixteen bits should be all zeros or all ones. */ ! 2506: if (INTVAL (operands[1]) < 0) ! 2507: { ! 2508: emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), ! 2509: GEN_INT (INTVAL (operands[1]) ! 2510: | ~(0x0ff00)))); ! 2511: emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg, ! 2512: GEN_INT (-((~INTVAL (operands[1])) ! 2513: & 0xff)))); ! 2514: } ! 2515: else ! 2516: { ! 2517: emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), ! 2518: GEN_INT (INTVAL (operands[1]) & 0xff00))); ! 2519: emit_insn (gen_addsi3 (reg2 = gen_reg_rtx (SImode), reg, ! 2520: GEN_INT (INTVAL (operands[1]) & 0x00ff))); ! 2521: } ! 2522: insn = gen_rtx (SET, HImode, operands[0], ! 2523: gen_rtx (SUBREG, HImode, reg2, 0)); ! 2524: } ! 2525: else ! 2526: insn = gen_rtx (SET, VOIDmode, operands[0], operands[1]); ! 2527: } ! 2528: ! 2529: emit_insn (insn); ! 2530: DONE; ! 2531: }") ! 2532: ! 2533: ;; Pattern to recognise insn generated default case above ! 2534: ! 2535: (define_insn "" ! 2536: [(set (match_operand:HI 0 "general_operand" "=r,r,r,m") ! 2537: (match_operand:HI 1 "general_operand" "r,K,m,r"))] ! 2538: "(register_operand (operands[0], HImode) ! 2539: && (GET_CODE (operands[1]) != CONST_INT ! 2540: || const_ok_for_arm (INTVAL (operands[1])) ! 2541: || const_ok_for_arm (~INTVAL (operands[1])))) ! 2542: || register_operand (operands[1], HImode)" ! 2543: "* ! 2544: switch (which_alternative) ! 2545: { ! 2546: case 1: ! 2547: if (!const_ok_for_arm (INTVAL (operands[1]))) ! 2548: { ! 2549: operands[1] = GEN_INT (~INTVAL (operands[1])); ! 2550: return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! 2551: } ! 2552: /* fall through */ ! 2553: case 0: ! 2554: return arm_output_asm_insn (\"mov\\t%0, %1\\t@movhi\", operands); ! 2555: case 2: ! 2556: return arm_output_asm_insn (\"ldr\\t%0, %1\\t@movhi\", operands); ! 2557: case 3: ! 2558: return arm_output_asm_insn (\"str\\t%1, %0\\t@movhi\", operands); ! 2559: } ! 2560: " ! 2561: [(set_attr "type" "*,*,load,store1")]) ! 2562: ! 2563: (define_expand "reload_outhi" ! 2564: [(parallel [(match_operand:HI 0 "reload_memory_operand" "=o") ! 2565: (match_operand:HI 1 "s_register_operand" "r") ! 2566: (match_operand:SI 2 "s_register_operand" "=&r")])] ! 2567: "" ! 2568: " ! 2569: arm_reload_out_hi (operands); ! 2570: DONE; ! 2571: ") ! 2572: ! 2573: (define_expand "movqi" ! 2574: [(set (match_operand:QI 0 "general_operand" "") ! 2575: (match_operand:QI 1 "general_operand" ""))] ! 2576: "" ! 2577: " ! 2578: /* Everything except mem = const or mem = mem can be done easily */ ! 2579: ! 2580: if (!(reload_in_progress || reload_completed)) ! 2581: { ! 2582: rtx reg; ! 2583: if (GET_CODE (operands[1]) == CONST_INT) ! 2584: { ! 2585: emit_insn (gen_movsi (reg = gen_reg_rtx (SImode), operands[1])); ! 2586: operands[1] = gen_rtx (SUBREG, QImode, reg, 0); ! 2587: } ! 2588: } ! 2589: if (GET_CODE (operands[0]) == MEM) ! 2590: operands[1] = force_reg (QImode, operands[1]); ! 2591: ") ! 2592: ! 2593: ! 2594: (define_insn "" ! 2595: [(set (match_operand:QI 0 "general_operand" "=r,r,r,m") ! 2596: (match_operand:QI 1 "general_operand" "r,K,m,r"))] ! 2597: "register_operand (operands[0], QImode) ! 2598: || register_operand (operands[1], QImode)" ! 2599: "* ! 2600: switch (which_alternative) ! 2601: { ! 2602: case 1: ! 2603: if (INTVAL (operands[1]) < 0) ! 2604: { ! 2605: operands[1] = GEN_INT (~INTVAL (operands[1])); ! 2606: return arm_output_asm_insn (\"mvn\\t%0, %1\", operands); ! 2607: } ! 2608: case 0: ! 2609: return (arm_output_asm_insn (\"mov\\t%0, %1\", operands)); ! 2610: case 2: ! 2611: return (arm_output_asm_insn (\"ldrb\\t%0, %1\", operands)); ! 2612: case 3: ! 2613: return (arm_output_asm_insn (\"strb\\t%1, %0\", operands)); ! 2614: } ! 2615: " ! 2616: [(set_attr "type" "*,*,load,store1")]) ! 2617: ! 2618: (define_insn "movsf" ! 2619: [(set (match_operand:SF 0 "general_operand" "=f,f,f,m,f,r,r,r,m") ! 2620: (match_operand:SF 1 "general_operand" "fG,H,m,f,r,f,r,m,r"))] ! 2621: "" ! 2622: "* ! 2623: { ! 2624: REAL_VALUE_TYPE r; ! 2625: ! 2626: switch (which_alternative) ! 2627: { ! 2628: case 0: ! 2629: return arm_output_asm_insn (\"mvfs\\t%0, %1\", operands); ! 2630: case 1: ! 2631: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 2632: r = REAL_VALUE_NEGATE (r); ! 2633: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 2634: return arm_output_asm_insn (\"mnfs\\t%0, %1\", operands); ! 2635: case 2: ! 2636: return arm_output_asm_insn (\"ldfs\\t%0, %1\", operands); ! 2637: case 3: ! 2638: return arm_output_asm_insn (\"stfs\\t%1, %0\", operands); ! 2639: case 4: ! 2640: arm_output_asm_insn(\"stmfd\\tsp!, {%1}\", operands); ! 2641: return arm_output_asm_insn (\"ldfs\\t%0, [sp],#4\", operands); ! 2642: case 5: ! 2643: arm_output_asm_insn(\"stfs\\t%1, [sp,#-4]!\", operands); ! 2644: return arm_output_asm_insn (\"ldmfd\\tsp!, {%0}\", operands); ! 2645: case 6: ! 2646: return arm_output_asm_insn (\"mov\\t%0, %1\", operands); ! 2647: case 7: ! 2648: return arm_output_asm_insn (\"ldr\\t%0, %1\\t@ float\", operands); ! 2649: case 8: ! 2650: return arm_output_asm_insn (\"str\\t%1, %0\\t@ float\", operands); ! 2651: } ! 2652: } ! 2653: " ! 2654: [(set_attr "length" "1,1,1,1,2,2,1,1,1") ! 2655: (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")]) ! 2656: ! 2657: (define_expand "movdf" ! 2658: [(parallel [(set (match_operand:DF 0 "general_operand" "") ! 2659: (match_operand:DF 1 "general_operand" "")) ! 2660: (clobber (match_scratch:SI 2 ""))])] ! 2661: "" ! 2662: " ! 2663: if (GET_CODE (operands[0]) == MEM) ! 2664: operands[1] = force_reg (DFmode, operands[1]); ! 2665: ") ! 2666: ! 2667: ;; Reloading a df mode value stored in integer regs to memory can require a ! 2668: ;; scratch reg. ! 2669: (define_expand "reload_outdf" ! 2670: [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=o") ! 2671: (match_operand:DF 1 "s_register_operand" "r")) ! 2672: (clobber (match_operand:SI 2 "s_register_operand" "=&r"))])] ! 2673: "" ! 2674: "") ! 2675: ! 2676: (define_insn "" ! 2677: [(set (match_operand:DF 0 "general_operand" "=r,Q,r,o,f,f,f,f,m,!f,!r,r") ! 2678: (match_operand:DF 1 "general_operand" ! 2679: "Q,r,?o,?r,?f,!G,!H,m,f,r,f,??r")) ! 2680: (clobber (match_scratch:SI 2 "=X,X,X,&r,X,X,X,X,X,X,X,X"))] ! 2681: "GET_CODE (operands[0]) != MEM || register_operand (operands[1], DFmode)" ! 2682: "* ! 2683: { ! 2684: REAL_VALUE_TYPE r; ! 2685: rtx ops[3]; ! 2686: ! 2687: switch (which_alternative) ! 2688: { ! 2689: case 0: ! 2690: operands[1] = XEXP (operands[1], 0); ! 2691: return arm_output_asm_insn (\"ldmia\\t%1, {%0, %R0}\\t@ double\", ! 2692: operands); ! 2693: case 1: ! 2694: operands[0] = XEXP (operands[0], 0); ! 2695: return arm_output_asm_insn (\"stmia\\t%0, {%1, %R1}\\t@ double\", ! 2696: operands); ! 2697: case 2: ! 2698: ops[0] = operands[0]; ! 2699: ops[1] = XEXP (XEXP (operands[1], 0), 0); ! 2700: ops[2] = XEXP (XEXP (operands[1], 0), 1); ! 2701: if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2]))) ! 2702: arm_output_asm_insn (\"add\\t%0, %1, %2\", ops); ! 2703: else ! 2704: arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops); ! 2705: return arm_output_asm_insn (\"ldmia\\t%0, {%0, %R0}\\t@ double\", ! 2706: operands); ! 2707: case 3: ! 2708: ! 2709: ops[0] = operands[2]; ! 2710: ops[1] = XEXP (XEXP (operands[0], 0), 0); ! 2711: ops[2] = XEXP (XEXP (operands[0], 0), 1); ! 2712: if (!INTVAL (ops[2]) || const_ok_for_arm (INTVAL (ops[2]))) ! 2713: arm_output_asm_insn (\"add\\t%0, %1, %2\", ops); ! 2714: else ! 2715: arm_output_asm_insn (\"sub\\t%0, %1, #%n2\", ops); ! 2716: return arm_output_asm_insn (\"stmia\\t%2, {%1, %R1}\\t@ double\", ! 2717: operands); ! 2718: case 4: ! 2719: case 5: ! 2720: return arm_output_asm_insn (\"mvfd\\t%0, %1\", operands); ! 2721: case 6: ! 2722: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 2723: r = REAL_VALUE_NEGATE (r); ! 2724: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 2725: return arm_output_asm_insn (\"mnfd\\t%0, %1\", operands); ! 2726: case 7: return arm_output_asm_insn (\"ldfd\\t%0, %1\", operands); ! 2727: case 8: return arm_output_asm_insn (\"stfd\\t%1, %0\", operands); ! 2728: case 9: return output_mov_double_fpu_from_arm (operands); ! 2729: case 10: return output_mov_double_arm_from_fpu (operands); ! 2730: case 11: return output_move_double (operands); ! 2731: } ! 2732: } ! 2733: " ! 2734: [(set_attr "length" "1,1,2,2,1,1,1,1,1,2,2,2") ! 2735: (set_attr "type" ! 2736: "load,store2,load,store2,float,float,float,f_load,f_store,r_mem_f,f_mem_r,*")]) ! 2737: ! 2738: (define_insn "movxf" ! 2739: [(set (match_operand:XF 0 "general_operand" "=f,f,f,m,f,r,r") ! 2740: (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))] ! 2741: "ENABLE_XF_PATTERNS" ! 2742: "* ! 2743: { ! 2744: REAL_VALUE_TYPE r; ! 2745: ! 2746: switch (which_alternative) ! 2747: { ! 2748: case 0: return arm_output_asm_insn (\"mvfe\\t%0, %1\", operands); ! 2749: case 1: ! 2750: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 2751: r = REAL_VALUE_NEGATE (r); ! 2752: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 2753: return arm_output_asm_insn (\"mnfe\\t%0, %1\", operands); ! 2754: case 2: return arm_output_asm_insn (\"ldfe\\t%0, %1\", operands); ! 2755: case 3: return arm_output_asm_insn (\"stfe\\t%1, %0\", operands); ! 2756: case 4: return output_mov_long_double_fpu_from_arm (operands); ! 2757: case 5: return output_mov_long_double_arm_from_fpu (operands); ! 2758: case 6: return output_mov_long_double_arm_from_arm (operands); ! 2759: } ! 2760: } ! 2761: " ! 2762: [(set_attr "length" "1,1,1,1,2,2,3") ! 2763: (set_attr "type" "float,float,f_load,f_store,r_mem_f,f_mem_r,*")]) ! 2764: ! 2765: ! 2766: ;; load- and store-multiple insns ! 2767: ;; The arm can load/store any set of registers, provided that they are in ! 2768: ;; ascending order; but that is beyond GCC so stick with what it knows. ! 2769: ! 2770: (define_expand "load_multiple" ! 2771: [(match_par_dup 3 [(set (match_operand:SI 0 "" "") ! 2772: (match_operand:SI 1 "" "")) ! 2773: (use (match_operand:SI 2 "" ""))])] ! 2774: "" ! 2775: " ! 2776: /* Support only fixed point registers */ ! 2777: if (GET_CODE (operands[2]) != CONST_INT ! 2778: || INTVAL (operands[2]) > 14 ! 2779: || INTVAL (operands[2]) < 2 ! 2780: || GET_CODE (operands[1]) != MEM ! 2781: || GET_CODE (operands[0]) != REG ! 2782: || REGNO (operands[0]) > 14 ! 2783: || REGNO (operands[0]) + INTVAL (operands[2]) > 15) ! 2784: FAIL; ! 2785: ! 2786: operands[3] ! 2787: = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), ! 2788: force_reg (SImode, XEXP (operands[1], 0)), ! 2789: TRUE, FALSE); ! 2790: ") ! 2791: ! 2792: ;; Load multiple with write-back ! 2793: ! 2794: (define_insn "" ! 2795: [(match_parallel 0 "load_multiple_operation" ! 2796: [(set (match_operand:SI 1 "s_register_operand" "+r") ! 2797: (plus:SI (match_dup 1) ! 2798: (match_operand:SI 2 "immediate_operand" "n"))) ! 2799: (set (match_operand:SI 3 "s_register_operand" "=r") ! 2800: (mem:SI (match_dup 1)))])] ! 2801: "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))" ! 2802: "* ! 2803: { ! 2804: rtx ops[3]; ! 2805: int count = XVECLEN (operands[0], 0); ! 2806: ! 2807: ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); ! 2808: ops[1] = SET_DEST (XVECEXP (operands[0], 0, 1)); ! 2809: ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 2)); ! 2810: ! 2811: return arm_output_asm_insn (\"ldmia\\t%0!, {%1-%2}\\t@ load multiple\", ops); ! 2812: } ! 2813: " ! 2814: [(set_attr "type" "load")]) ! 2815: ! 2816: ;; Ordinary load multiple ! 2817: ! 2818: (define_insn "" ! 2819: [(match_parallel 0 "load_multiple_operation" ! 2820: [(set (match_operand:SI 1 "s_register_operand" "=r") ! 2821: (match_operand:SI 2 "indirect_operand" "Q"))])] ! 2822: "" ! 2823: "* ! 2824: { ! 2825: rtx ops[3]; ! 2826: int count = XVECLEN (operands[0], 0); ! 2827: ! 2828: ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); ! 2829: ops[1] = SET_DEST (XVECEXP (operands[0], 0, 0)); ! 2830: ops[2] = SET_DEST (XVECEXP (operands[0], 0, count - 1)); ! 2831: ! 2832: return arm_output_asm_insn (\"ldmia\\t%0, {%1-%2}\\t@ load multiple\", ops); ! 2833: } ! 2834: " ! 2835: [(set_attr "type" "load")]) ! 2836: ! 2837: (define_expand "store_multiple" ! 2838: [(match_par_dup 3 [(set (match_operand:SI 0 "" "") ! 2839: (match_operand:SI 1 "" "")) ! 2840: (use (match_operand:SI 2 "" ""))])] ! 2841: "" ! 2842: " ! 2843: /* Support only fixed point registers */ ! 2844: if (GET_CODE (operands[2]) != CONST_INT ! 2845: || INTVAL (operands[2]) > 14 ! 2846: || INTVAL (operands[2]) < 2 ! 2847: || GET_CODE (operands[1]) != REG ! 2848: || GET_CODE (operands[0]) != MEM ! 2849: || REGNO (operands[1]) > 14 ! 2850: || REGNO (operands[1]) + INTVAL (operands[2]) > 15) ! 2851: FAIL; ! 2852: ! 2853: operands[3] ! 2854: = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), ! 2855: force_reg (SImode, XEXP (operands[0], 0)), ! 2856: TRUE, FALSE); ! 2857: ") ! 2858: ! 2859: ;; Store multiple with write-back ! 2860: ! 2861: (define_insn "" ! 2862: [(match_parallel 0 "store_multiple_operation" ! 2863: [(set (match_operand:SI 1 "s_register_operand" "+r") ! 2864: (plus:SI (match_dup 1) ! 2865: (match_operand:SI 2 "immediate_operand" "n"))) ! 2866: (set (mem:SI (match_dup 1)) ! 2867: (match_operand:SI 3 "s_register_operand" "r"))])] ! 2868: "(INTVAL (operands[2]) == 4 * (XVECLEN (operands[0], 0) - 2))" ! 2869: "* ! 2870: { ! 2871: rtx ops[3]; ! 2872: int count = XVECLEN (operands[0], 0); ! 2873: ! 2874: ops[0] = XEXP (SET_SRC (XVECEXP (operands[0], 0, 0)), 0); ! 2875: ops[1] = SET_SRC (XVECEXP (operands[0], 0, 1)); ! 2876: ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 2)); ! 2877: ! 2878: return arm_output_asm_insn (\"stmia\\t%0!, {%1-%2}\\t@ str multiple\", ops); ! 2879: } ! 2880: " ! 2881: [(set (attr "type") ! 2882: (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4)) ! 2883: (const_string "store2") ! 2884: (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 5)) ! 2885: (const_string "store3")] ! 2886: (const_string "store4")))]) ! 2887: ! 2888: ;; Ordinary store multiple ! 2889: ! 2890: (define_insn "" ! 2891: [(match_parallel 0 "store_multiple_operation" ! 2892: [(set (match_operand:SI 2 "indirect_operand" "=Q") ! 2893: (match_operand:SI 1 "s_register_operand" "r"))])] ! 2894: "" ! 2895: "* ! 2896: { ! 2897: rtx ops[3]; ! 2898: int count = XVECLEN (operands[0], 0); ! 2899: ! 2900: ops[0] = XEXP (SET_DEST (XVECEXP (operands[0], 0, 0)), 0); ! 2901: ops[1] = SET_SRC (XVECEXP (operands[0], 0, 0)); ! 2902: ops[2] = SET_SRC (XVECEXP (operands[0], 0, count - 1)); ! 2903: ! 2904: return arm_output_asm_insn (\"stmia\\t%0, {%1-%2}\\t@ str multiple\", ops); ! 2905: } ! 2906: " ! 2907: [(set (attr "type") ! 2908: (cond [(eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 3)) ! 2909: (const_string "store2") ! 2910: (eq (symbol_ref "XVECLEN (operands[0],0)") (const_int 4)) ! 2911: (const_string "store3")] ! 2912: (const_string "store4")))]) ! 2913: ! 2914: ;; Move a block of memory if it is word aligned and MORE than 2 words long. ! 2915: ;; We could let this apply for blocks of less than this, but it clobbers so ! 2916: ;; many registers that there is then probably a better way. ! 2917: ! 2918: ;; If optimizing, output redundant moves with REG_NOTES on them, this ! 2919: ;; produces better code. ! 2920: ! 2921: (define_expand "movstrsi" ! 2922: [(set (match_operand:BLK 0 "general_operand" "=m") ! 2923: (match_operand:BLK 1 "general_operand" "m")) ! 2924: (use (match_operand:SI 2 "immediate_operand" "n")) ! 2925: (use (match_operand:SI 3 "immediate_operand" "n")) ! 2926: (clobber (reg:SI 0)) ! 2927: (clobber (reg:SI 1)) ! 2928: (clobber (reg:SI 2)) ! 2929: (clobber (reg:SI 3)) ! 2930: (clobber (match_scratch:SI 4 "=+r")) ! 2931: (clobber (match_scratch:SI 5 "=+r"))] ! 2932: "" ! 2933: " ! 2934: { ! 2935: int words_to_go; ! 2936: int i, r; ! 2937: rtx const_sxteen = gen_rtx (CONST_INT, SImode, 16); ! 2938: rtx src = gen_reg_rtx (SImode); ! 2939: rtx dst = gen_reg_rtx (SImode); ! 2940: rtx st_src, st_dst, end_src, end_dst, fin_src, fin_dst; ! 2941: extern int optimize; ! 2942: ! 2943: if (GET_CODE (operands[2]) != CONST_INT ! 2944: || GET_CODE (operands[3]) != CONST_INT ! 2945: || INTVAL (operands[2]) % 4 != 0 ! 2946: || INTVAL (operands[2]) < 4 ! 2947: || INTVAL (operands[2]) > 64 ! 2948: || INTVAL (operands[3]) < 4 ! 2949: || INTVAL (operands[3]) % 4 != 0) ! 2950: FAIL; ! 2951: emit_move_insn (dst, st_dst = force_reg (SImode, XEXP (operands[0], 0))); ! 2952: emit_move_insn (src, st_src = force_reg (SImode, XEXP (operands[1], 0))); ! 2953: fin_src = src; ! 2954: fin_dst = dst; ! 2955: ! 2956: for (i = 0, words_to_go = INTVAL (operands[2]) / 4; words_to_go >= 2; i+=4) ! 2957: { ! 2958: emit_insn (arm_gen_load_multiple (0, words_to_go > 4 ? 4 : words_to_go, ! 2959: src, TRUE, TRUE)); ! 2960: emit_insn (arm_gen_store_multiple (0, words_to_go > 4 ? 4 : words_to_go, ! 2961: dst, TRUE, TRUE)); ! 2962: if (optimize) ! 2963: for (r = (words_to_go > 4) ? 3 : words_to_go - 1; r >= 0; r--) ! 2964: { ! 2965: rtx note; ! 2966: note = emit_move_insn (gen_reg_rtx (SImode), ! 2967: gen_rtx (REG, SImode, r)); ! 2968: REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV, ! 2969: gen_rtx (MEM, SImode, ! 2970: plus_constant (st_src, 4*(i+r))), ! 2971: REG_NOTES (note)); ! 2972: REG_NOTES (note) = gen_rtx (EXPR_LIST, REG_EQUIV, ! 2973: gen_rtx (MEM, SImode, ! 2974: plus_constant (st_dst, 4*(i+r))), ! 2975: REG_NOTES (note)); ! 2976: } ! 2977: words_to_go -= words_to_go < 4 ? words_to_go : 4; ! 2978: } ! 2979: if (words_to_go) ! 2980: { ! 2981: rtx sreg; ! 2982: ! 2983: emit_move_insn (sreg = gen_reg_rtx (SImode), gen_rtx (MEM, SImode, src)); ! 2984: emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4)); ! 2985: emit_move_insn (gen_rtx (MEM, SImode, dst), sreg); ! 2986: emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4)); ! 2987: } ! 2988: if (optimize) ! 2989: { ! 2990: /* Insns for the REG_NOTES: These notes tell the optimiser where the ! 2991: index registers have got to so that consecutive block moves of ! 2992: contiguous data work efficiently */ ! 2993: ! 2994: end_src = emit_move_insn (fin_src, fin_src); ! 2995: REG_NOTES (end_src) = gen_rtx(EXPR_LIST, REG_EQUAL, ! 2996: plus_constant (st_src, INTVAL (operands[2])), ! 2997: REG_NOTES (end_src)); ! 2998: end_dst = emit_move_insn (fin_dst, fin_dst); ! 2999: REG_NOTES (end_dst) = gen_rtx(EXPR_LIST, REG_EQUAL, ! 3000: plus_constant (st_dst, INTVAL (operands[2])), ! 3001: REG_NOTES (end_dst)); ! 3002: } ! 3003: DONE; ! 3004: } ! 3005: ") ! 3006: ! 3007: ! 3008: ;; Comparison and test insns ! 3009: ! 3010: (define_expand "cmpsi" ! 3011: [(set (reg:CC 24) ! 3012: (compare:CC (match_operand:SI 0 "s_register_operand" "") ! 3013: (match_operand:SI 1 "arm_add_operand" "")))] ! 3014: "" ! 3015: " ! 3016: { ! 3017: arm_compare_op0 = operands[0]; ! 3018: arm_compare_op1 = operands[1]; ! 3019: arm_compare_fp = 0; ! 3020: DONE; ! 3021: } ! 3022: ") ! 3023: ! 3024: (define_expand "cmpsf" ! 3025: [(set (reg:CC 24) ! 3026: (compare:CC (match_operand:SF 0 "s_register_operand" "") ! 3027: (match_operand:SF 1 "fpu_rhs_operand" "")))] ! 3028: "" ! 3029: " ! 3030: { ! 3031: arm_compare_op0 = operands[0]; ! 3032: arm_compare_op1 = operands[1]; ! 3033: arm_compare_fp = 1; ! 3034: DONE; ! 3035: } ! 3036: ") ! 3037: ! 3038: (define_expand "cmpdf" ! 3039: [(set (reg:CC 24) ! 3040: (compare:CC (match_operand:DF 0 "s_register_operand" "") ! 3041: (match_operand:DF 1 "fpu_rhs_operand" "")))] ! 3042: "" ! 3043: " ! 3044: { ! 3045: arm_compare_op0 = operands[0]; ! 3046: arm_compare_op1 = operands[1]; ! 3047: arm_compare_fp = 1; ! 3048: DONE; ! 3049: } ! 3050: ") ! 3051: ! 3052: (define_expand "cmpxf" ! 3053: [(set (reg:CC 24) ! 3054: (compare:CC (match_operand:XF 0 "s_register_operand" "") ! 3055: (match_operand:XF 1 "fpu_rhs_operand" "")))] ! 3056: "ENABLE_XF_PATTERNS" ! 3057: " ! 3058: { ! 3059: arm_compare_op0 = operands[0]; ! 3060: arm_compare_op1 = operands[1]; ! 3061: arm_compare_fp = 1; ! 3062: DONE; ! 3063: } ! 3064: ") ! 3065: ! 3066: (define_insn "" ! 3067: [(set (match_operand 0 "cc_register" "") ! 3068: (compare (match_operand:SI 1 "s_register_operand" "r") ! 3069: (match_operand:SI 2 "arm_add_operand" "rL")))] ! 3070: "" ! 3071: "* ! 3072: if (GET_CODE (operands[2]) == CONST_INT ! 3073: && !const_ok_for_arm (INTVAL (operands[2]))) ! 3074: return arm_output_asm_insn (\"cmn\\t%1, #%n2\", operands); ! 3075: return arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 3076: " ! 3077: [(set_attr "conds" "set")]) ! 3078: ! 3079: (define_insn "" ! 3080: [(set (match_operand 0 "cc_register" "") ! 3081: (compare (match_operand:SI 1 "s_register_operand" "r") ! 3082: (neg:SI (match_operand:SI 2 "s_register_operand" "r"))))] ! 3083: "" ! 3084: "* ! 3085: return arm_output_asm_insn (\"cmn\\t%1, %2\", operands); ! 3086: " ! 3087: [(set_attr "conds" "set")]) ! 3088: ! 3089: (define_insn "" ! 3090: [(set (match_operand 0 "cc_register" "") ! 3091: (compare (match_operand:SI 1 "s_register_operand" "r") ! 3092: (match_operator:SI 2 "shift_operator" ! 3093: [(match_operand:SI 3 "s_register_operand" "r") ! 3094: (match_operand:SI 4 "arm_rhs_operand" "rn")])))] ! 3095: "" ! 3096: "* ! 3097: return output_shift_compare (operands, FALSE); ! 3098: " ! 3099: [(set_attr "conds" "set")]) ! 3100: ! 3101: (define_insn "" ! 3102: [(set (match_operand 0 "cc_register" "") ! 3103: (compare (match_operand:SI 1 "s_register_operand" "r") ! 3104: (neg:SI (match_operator:SI 2 "shift_operator" ! 3105: [(match_operand:SI 3 "s_register_operand" "r") ! 3106: (match_operand:SI 4 "arm_rhs_operand" "rn")]))))] ! 3107: "" ! 3108: "* ! 3109: return output_shift_compare (operands, TRUE); ! 3110: " ! 3111: [(set_attr "conds" "set")]) ! 3112: ! 3113: (define_insn "" ! 3114: [(set (reg:CCFP 24) ! 3115: (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f") ! 3116: (match_operand:SF 1 "fpu_add_operand" "fG,H")))] ! 3117: "" ! 3118: "* ! 3119: { ! 3120: REAL_VALUE_TYPE r; ! 3121: ! 3122: switch (which_alternative) ! 3123: { ! 3124: case 0: ! 3125: return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); ! 3126: case 1: ! 3127: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3128: r = REAL_VALUE_NEGATE (r); ! 3129: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3130: return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); ! 3131: } ! 3132: } ! 3133: " ! 3134: [(set_attr "conds" "set") ! 3135: (set_attr "type" "f_2_r")]) ! 3136: ! 3137: (define_insn "" ! 3138: [(set (reg:CCFP 24) ! 3139: (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f") ! 3140: (match_operand:DF 1 "fpu_add_operand" "fG,H")))] ! 3141: "" ! 3142: "* ! 3143: { ! 3144: REAL_VALUE_TYPE r; ! 3145: ! 3146: switch (which_alternative) ! 3147: { ! 3148: case 0: ! 3149: return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); ! 3150: case 1: ! 3151: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3152: r = REAL_VALUE_NEGATE (r); ! 3153: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3154: return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); ! 3155: } ! 3156: } ! 3157: " ! 3158: [(set_attr "conds" "set") ! 3159: (set_attr "type" "f_2_r")]) ! 3160: ! 3161: (define_insn "" ! 3162: [(set (reg:CCFP 24) ! 3163: (compare:CCFP (float_extend:DF ! 3164: (match_operand:SF 0 "s_register_operand" "f,f")) ! 3165: (match_operand:DF 1 "fpu_add_operand" "fG,H")))] ! 3166: "" ! 3167: "* ! 3168: { ! 3169: REAL_VALUE_TYPE r; ! 3170: ! 3171: switch (which_alternative) ! 3172: { ! 3173: case 0: ! 3174: return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); ! 3175: case 1: ! 3176: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3177: r = REAL_VALUE_NEGATE (r); ! 3178: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3179: return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); ! 3180: } ! 3181: } ! 3182: " ! 3183: [(set_attr "conds" "set") ! 3184: (set_attr "type" "f_2_r")]) ! 3185: ! 3186: (define_insn "" ! 3187: [(set (reg:CCFP 24) ! 3188: (compare:CCFP (match_operand:DF 0 "s_register_operand" "f") ! 3189: (float_extend:DF ! 3190: (match_operand:SF 1 "s_register_operand" "f"))))] ! 3191: "" ! 3192: "* ! 3193: return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); ! 3194: " ! 3195: [(set_attr "conds" "set") ! 3196: (set_attr "type" "f_2_r")]) ! 3197: ! 3198: (define_insn "" ! 3199: [(set (reg:CCFP 24) ! 3200: (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f") ! 3201: (match_operand:XF 1 "fpu_add_operand" "fG,H")))] ! 3202: "ENABLE_XF_PATTERNS" ! 3203: "* ! 3204: { ! 3205: REAL_VALUE_TYPE r; ! 3206: ! 3207: switch (which_alternative) ! 3208: { ! 3209: case 0: ! 3210: return arm_output_asm_insn (\"cmf\\t%0, %1\", operands); ! 3211: case 1: ! 3212: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3213: r = REAL_VALUE_NEGATE (r); ! 3214: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3215: return arm_output_asm_insn (\"cnf\\t%0, %1\", operands); ! 3216: } ! 3217: } ! 3218: " ! 3219: [(set_attr "conds" "set") ! 3220: (set_attr "type" "f_2_r")]) ! 3221: ! 3222: (define_insn "" ! 3223: [(set (reg:CCFPE 24) ! 3224: (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f") ! 3225: (match_operand:SF 1 "fpu_add_operand" "fG,H")))] ! 3226: "" ! 3227: "* ! 3228: { ! 3229: REAL_VALUE_TYPE r; ! 3230: ! 3231: switch (which_alternative) ! 3232: { ! 3233: case 0: ! 3234: return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); ! 3235: case 1: ! 3236: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3237: r = REAL_VALUE_NEGATE (r); ! 3238: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3239: return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); ! 3240: } ! 3241: } ! 3242: " ! 3243: [(set_attr "conds" "set") ! 3244: (set_attr "type" "f_2_r")]) ! 3245: ! 3246: (define_insn "" ! 3247: [(set (reg:CCFPE 24) ! 3248: (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f") ! 3249: (match_operand:DF 1 "fpu_add_operand" "fG,H")))] ! 3250: "" ! 3251: "* ! 3252: { ! 3253: REAL_VALUE_TYPE r; ! 3254: ! 3255: switch (which_alternative) ! 3256: { ! 3257: case 0: ! 3258: return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); ! 3259: case 1: ! 3260: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3261: r = REAL_VALUE_NEGATE (r); ! 3262: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3263: return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); ! 3264: } ! 3265: } ! 3266: " ! 3267: [(set_attr "conds" "set") ! 3268: (set_attr "type" "f_2_r")]) ! 3269: ! 3270: (define_insn "" ! 3271: [(set (reg:CCFPE 24) ! 3272: (compare:CCFPE (float_extend:DF ! 3273: (match_operand:SF 0 "s_register_operand" "f,f")) ! 3274: (match_operand:DF 1 "fpu_add_operand" "fG,H")))] ! 3275: "" ! 3276: "* ! 3277: { ! 3278: REAL_VALUE_TYPE r; ! 3279: ! 3280: switch (which_alternative) ! 3281: { ! 3282: case 0: ! 3283: return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); ! 3284: case 1: ! 3285: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3286: r = REAL_VALUE_NEGATE (r); ! 3287: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3288: return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); ! 3289: } ! 3290: } ! 3291: " ! 3292: [(set_attr "conds" "set") ! 3293: (set_attr "type" "f_2_r")]) ! 3294: ! 3295: (define_insn "" ! 3296: [(set (reg:CCFPE 24) ! 3297: (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f") ! 3298: (float_extend:DF ! 3299: (match_operand:SF 1 "s_register_operand" "f"))))] ! 3300: "" ! 3301: "* ! 3302: return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); ! 3303: " ! 3304: [(set_attr "conds" "set") ! 3305: (set_attr "type" "f_2_r")]) ! 3306: ! 3307: (define_insn "" ! 3308: [(set (reg:CCFPE 24) ! 3309: (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f") ! 3310: (match_operand:XF 1 "fpu_add_operand" "fG,H")))] ! 3311: "ENABLE_XF_PATTERNS" ! 3312: "* ! 3313: { ! 3314: REAL_VALUE_TYPE r; ! 3315: ! 3316: switch (which_alternative) ! 3317: { ! 3318: case 0: ! 3319: return arm_output_asm_insn (\"cmfe\\t%0, %1\", operands); ! 3320: case 1: ! 3321: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 3322: r = REAL_VALUE_NEGATE (r); ! 3323: operands[1] = CONST_DOUBLE_FROM_REAL_VALUE (r, GET_MODE (operands[1])); ! 3324: return arm_output_asm_insn (\"cnfe\\t%0, %1\", operands); ! 3325: } ! 3326: } ! 3327: " ! 3328: [(set_attr "conds" "set") ! 3329: (set_attr "type" "f_2_r")]) ! 3330: ! 3331: ; This insn allows redundant compares to be removed by cse, nothing should ! 3332: ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that ! 3333: ; is deleted later on. The match_dup will match the mode here, so that ! 3334: ; mode changes of the condition codes aren't lost by this even though we don't ! 3335: ; specify what they are. ! 3336: ! 3337: (define_insn "" ! 3338: [(set (match_operand 0 "cc_register" "") (match_dup 0))] ! 3339: "" ! 3340: "\\t@ deleted compare" ! 3341: [(set_attr "conds" "set") ! 3342: (set_attr "length" "0")]) ! 3343: ! 3344: ! 3345: ;; Conditional branch insns ! 3346: ! 3347: (define_expand "beq" ! 3348: [(set (pc) ! 3349: (if_then_else (eq (match_dup 1) (const_int 0)) ! 3350: (label_ref (match_operand 0 "" "")) ! 3351: (pc)))] ! 3352: "" ! 3353: " ! 3354: { ! 3355: operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1, ! 3356: arm_compare_fp); ! 3357: } ! 3358: ") ! 3359: ! 3360: (define_expand "bne" ! 3361: [(set (pc) ! 3362: (if_then_else (ne (match_dup 1) (const_int 0)) ! 3363: (label_ref (match_operand 0 "" "")) ! 3364: (pc)))] ! 3365: "" ! 3366: " ! 3367: { ! 3368: operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1, ! 3369: arm_compare_fp); ! 3370: } ! 3371: ") ! 3372: ! 3373: (define_expand "bgt" ! 3374: [(set (pc) ! 3375: (if_then_else (gt (match_dup 1) (const_int 0)) ! 3376: (label_ref (match_operand 0 "" "")) ! 3377: (pc)))] ! 3378: "" ! 3379: " ! 3380: { ! 3381: operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1, ! 3382: arm_compare_fp); ! 3383: } ! 3384: ") ! 3385: ! 3386: (define_expand "ble" ! 3387: [(set (pc) ! 3388: (if_then_else (le (match_dup 1) (const_int 0)) ! 3389: (label_ref (match_operand 0 "" "")) ! 3390: (pc)))] ! 3391: "" ! 3392: " ! 3393: { ! 3394: operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1, ! 3395: arm_compare_fp); ! 3396: } ! 3397: ") ! 3398: ! 3399: (define_expand "bge" ! 3400: [(set (pc) ! 3401: (if_then_else (ge (match_dup 1) (const_int 0)) ! 3402: (label_ref (match_operand 0 "" "")) ! 3403: (pc)))] ! 3404: "" ! 3405: " ! 3406: { ! 3407: operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1, ! 3408: arm_compare_fp); ! 3409: } ! 3410: ") ! 3411: ! 3412: (define_expand "blt" ! 3413: [(set (pc) ! 3414: (if_then_else (lt (match_dup 1) (const_int 0)) ! 3415: (label_ref (match_operand 0 "" "")) ! 3416: (pc)))] ! 3417: "" ! 3418: " ! 3419: { ! 3420: operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1, ! 3421: arm_compare_fp); ! 3422: } ! 3423: ") ! 3424: ! 3425: (define_expand "bgtu" ! 3426: [(set (pc) ! 3427: (if_then_else (gtu (match_dup 1) (const_int 0)) ! 3428: (label_ref (match_operand 0 "" "")) ! 3429: (pc)))] ! 3430: "" ! 3431: " ! 3432: { ! 3433: operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1, ! 3434: arm_compare_fp); ! 3435: } ! 3436: ") ! 3437: ! 3438: (define_expand "bleu" ! 3439: [(set (pc) ! 3440: (if_then_else (leu (match_dup 1) (const_int 0)) ! 3441: (label_ref (match_operand 0 "" "")) ! 3442: (pc)))] ! 3443: "" ! 3444: " ! 3445: { ! 3446: operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1, ! 3447: arm_compare_fp); ! 3448: } ! 3449: ") ! 3450: ! 3451: (define_expand "bgeu" ! 3452: [(set (pc) ! 3453: (if_then_else (geu (match_dup 1) (const_int 0)) ! 3454: (label_ref (match_operand 0 "" "")) ! 3455: (pc)))] ! 3456: "" ! 3457: " ! 3458: { ! 3459: operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1, ! 3460: arm_compare_fp); ! 3461: } ! 3462: ") ! 3463: ! 3464: (define_expand "bltu" ! 3465: [(set (pc) ! 3466: (if_then_else (ltu (match_dup 1) (const_int 0)) ! 3467: (label_ref (match_operand 0 "" "")) ! 3468: (pc)))] ! 3469: "" ! 3470: " ! 3471: { ! 3472: operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1, ! 3473: arm_compare_fp); ! 3474: } ! 3475: ") ! 3476: ! 3477: ;; patterns to match conditional branch insns ! 3478: ! 3479: (define_insn "" ! 3480: [(set (pc) ! 3481: (if_then_else (match_operator 1 "comparison_operator" ! 3482: [(reg 24) (const_int 0)]) ! 3483: (label_ref (match_operand 0 "" "")) ! 3484: (pc)))] ! 3485: "" ! 3486: "* ! 3487: { ! 3488: extern int arm_ccfsm_state; ! 3489: ! 3490: if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! 3491: { ! 3492: arm_ccfsm_state += 2; ! 3493: return \"\"; ! 3494: } ! 3495: return (arm_output_asm_insn (\"b%d1\\t%l0\", operands)); ! 3496: }" ! 3497: [(set_attr "conds" "use")]) ! 3498: ! 3499: (define_insn "" ! 3500: [(set (pc) ! 3501: (if_then_else (match_operator 1 "comparison_operator" ! 3502: [(reg 24) (const_int 0)]) ! 3503: (pc) ! 3504: (label_ref (match_operand 0 "" ""))))] ! 3505: "" ! 3506: "* ! 3507: { ! 3508: extern int arm_ccfsm_state; ! 3509: ! 3510: if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! 3511: { ! 3512: arm_ccfsm_state += 2; ! 3513: return \"\"; ! 3514: } ! 3515: return (arm_output_asm_insn (\"b%D1\\t%l0\", operands)); ! 3516: }" ! 3517: [(set_attr "conds" "use")]) ! 3518: ! 3519: ! 3520: ; scc insns ! 3521: ! 3522: (define_expand "seq" ! 3523: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3524: (eq:SI (match_dup 1) (const_int 0)))] ! 3525: "" ! 3526: " ! 3527: { ! 3528: operands[1] = gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1, ! 3529: arm_compare_fp); ! 3530: } ! 3531: ") ! 3532: ! 3533: (define_expand "sne" ! 3534: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3535: (ne:SI (match_dup 1) (const_int 0)))] ! 3536: "" ! 3537: " ! 3538: { ! 3539: operands[1] = gen_compare_reg (NE, arm_compare_op0, arm_compare_op1, ! 3540: arm_compare_fp); ! 3541: } ! 3542: ") ! 3543: ! 3544: (define_expand "sgt" ! 3545: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3546: (gt:SI (match_dup 1) (const_int 0)))] ! 3547: "" ! 3548: " ! 3549: { ! 3550: operands[1] = gen_compare_reg (GT, arm_compare_op0, arm_compare_op1, ! 3551: arm_compare_fp); ! 3552: } ! 3553: ") ! 3554: ! 3555: (define_expand "sle" ! 3556: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3557: (le:SI (match_dup 1) (const_int 0)))] ! 3558: "" ! 3559: " ! 3560: { ! 3561: operands[1] = gen_compare_reg (LE, arm_compare_op0, arm_compare_op1, ! 3562: arm_compare_fp); ! 3563: } ! 3564: ") ! 3565: ! 3566: (define_expand "sge" ! 3567: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3568: (ge:SI (match_dup 1) (const_int 0)))] ! 3569: "" ! 3570: " ! 3571: { ! 3572: operands[1] = gen_compare_reg (GE, arm_compare_op0, arm_compare_op1, ! 3573: arm_compare_fp); ! 3574: } ! 3575: ") ! 3576: ! 3577: (define_expand "slt" ! 3578: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3579: (lt:SI (match_dup 1) (const_int 0)))] ! 3580: "" ! 3581: " ! 3582: { ! 3583: operands[1] = gen_compare_reg (LT, arm_compare_op0, arm_compare_op1, ! 3584: arm_compare_fp); ! 3585: } ! 3586: ") ! 3587: ! 3588: (define_expand "sgtu" ! 3589: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3590: (gtu:SI (match_dup 1) (const_int 0)))] ! 3591: "" ! 3592: " ! 3593: { ! 3594: operands[1] = gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1, ! 3595: arm_compare_fp); ! 3596: } ! 3597: ") ! 3598: ! 3599: (define_expand "sleu" ! 3600: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3601: (leu:SI (match_dup 1) (const_int 0)))] ! 3602: "" ! 3603: " ! 3604: { ! 3605: operands[1] = gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1, ! 3606: arm_compare_fp); ! 3607: } ! 3608: ") ! 3609: ! 3610: (define_expand "sgeu" ! 3611: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3612: (geu:SI (match_dup 1) (const_int 0)))] ! 3613: "" ! 3614: " ! 3615: { ! 3616: operands[1] = gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1, ! 3617: arm_compare_fp); ! 3618: } ! 3619: ") ! 3620: ! 3621: (define_expand "sltu" ! 3622: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3623: (ltu:SI (match_dup 1) (const_int 0)))] ! 3624: "" ! 3625: " ! 3626: { ! 3627: operands[1] = gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1, ! 3628: arm_compare_fp); ! 3629: } ! 3630: ") ! 3631: ! 3632: (define_insn "" ! 3633: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3634: (match_operator:SI 1 "comparison_operator" [(reg 24) (const_int 0)]))] ! 3635: "" ! 3636: "* ! 3637: arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! 3638: return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 3639: " ! 3640: [(set_attr "conds" "use") ! 3641: (set_attr "length" "2")]) ! 3642: ! 3643: (define_insn "" ! 3644: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3645: (neg:SI (match_operator:SI 1 "comparison_operator" ! 3646: [(reg 24) (const_int 0)])))] ! 3647: "" ! 3648: "* ! 3649: arm_output_asm_insn (\"mvn%d1\\t%0, #0\", operands); ! 3650: return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 3651: " ! 3652: [(set_attr "conds" "use") ! 3653: (set_attr "length" "2")]) ! 3654: ! 3655: (define_insn "" ! 3656: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3657: (not:SI (match_operator:SI 1 "comparison_operator" ! 3658: [(reg 24) (const_int 0)])))] ! 3659: "" ! 3660: "* ! 3661: arm_output_asm_insn (\"mvn%d1\\t%0, #1\", operands); ! 3662: return arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 3663: " ! 3664: [(set_attr "conds" "use") ! 3665: (set_attr "length" "2")]) ! 3666: ! 3667: ! 3668: ;; Jump and linkage insns ! 3669: ! 3670: (define_insn "jump" ! 3671: [(set (pc) ! 3672: (label_ref (match_operand 0 "" "")))] ! 3673: "" ! 3674: "* ! 3675: { ! 3676: extern int arm_ccfsm_state; ! 3677: ! 3678: if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! 3679: { ! 3680: arm_ccfsm_state += 2; ! 3681: return \"\"; ! 3682: } ! 3683: return (arm_output_asm_insn (\"b\\t%l0\", operands)); ! 3684: }") ! 3685: ! 3686: (define_expand "call" ! 3687: [(parallel [(call (match_operand 0 "memory_operand" "") ! 3688: (match_operand 1 "general_operand" "")) ! 3689: (clobber (reg:SI 14))])] ! 3690: "" ! 3691: "") ! 3692: ! 3693: (define_insn "" ! 3694: [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) ! 3695: (match_operand 1 "" "g")) ! 3696: (clobber (reg:SI 14))] ! 3697: "" ! 3698: "* ! 3699: return (output_call (operands)); ! 3700: " ! 3701: [(set (attr "conds") ! 3702: (if_then_else (eq_attr "cpu" "arm6") ! 3703: (const_string "clob") ! 3704: (const_string "nocond"))) ! 3705: ;; length is worst case, normally it is only two ! 3706: (set_attr "length" "3") ! 3707: (set_attr "type" "call")]) ! 3708: ! 3709: (define_insn "" ! 3710: [(call (mem:SI (match_operand 0 "memory_operand" "m")) ! 3711: (match_operand 1 "general_operand" "g")) ! 3712: (clobber (reg:SI 14))] ! 3713: "" ! 3714: "* ! 3715: return (output_call_mem (operands)); ! 3716: " ! 3717: [(set (attr "conds") ! 3718: (if_then_else (eq_attr "cpu" "arm6") ! 3719: (const_string "clob") ! 3720: (const_string "nocond"))) ! 3721: (set_attr "length" "3") ! 3722: (set_attr "type" "call")]) ! 3723: ! 3724: (define_expand "call_value" ! 3725: [(parallel [(set (match_operand 0 "" "=rf") ! 3726: (call (match_operand 1 "memory_operand" "m") ! 3727: (match_operand 2 "general_operand" "g"))) ! 3728: (clobber (reg:SI 14))])] ! 3729: "" ! 3730: "") ! 3731: ! 3732: (define_insn "" ! 3733: [(set (match_operand 0 "" "=rf") ! 3734: (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) ! 3735: (match_operand 2 "general_operand" "g"))) ! 3736: (clobber (reg:SI 14))] ! 3737: "" ! 3738: "* ! 3739: return (output_call (&operands[1])); ! 3740: " ! 3741: [(set (attr "conds") ! 3742: (if_then_else (eq_attr "cpu" "arm6") ! 3743: (const_string "clob") ! 3744: (const_string "nocond"))) ! 3745: (set_attr "length" "3") ! 3746: (set_attr "type" "call")]) ! 3747: ! 3748: (define_insn "" ! 3749: [(set (match_operand 0 "" "=rf") ! 3750: (call (mem:SI (match_operand 1 "memory_operand" "m")) ! 3751: (match_operand 2 "general_operand" "g"))) ! 3752: (clobber (reg:SI 14))] ! 3753: "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))" ! 3754: "* ! 3755: return (output_call_mem (&operands[1])); ! 3756: " ! 3757: [(set (attr "conds") ! 3758: (if_then_else (eq_attr "cpu" "arm6") ! 3759: (const_string "clob") ! 3760: (const_string "nocond"))) ! 3761: (set_attr "length" "3") ! 3762: (set_attr "type" "call")]) ! 3763: ! 3764: ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses ! 3765: ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. ! 3766: ! 3767: (define_insn "" ! 3768: [(call (mem:SI (match_operand:SI 0 "" "i")) ! 3769: (match_operand:SI 1 "general_operand" "g")) ! 3770: (clobber (reg:SI 14))] ! 3771: "GET_CODE (operands[0]) == SYMBOL_REF" ! 3772: "* ! 3773: return (arm_output_asm_insn (\"bl\\t%a0\", operands)); ! 3774: " ! 3775: [(set (attr "conds") ! 3776: (if_then_else (eq_attr "cpu" "arm6") ! 3777: (const_string "clob") ! 3778: (const_string "nocond"))) ! 3779: (set_attr "type" "call")]) ! 3780: ! 3781: (define_insn "" ! 3782: [(set (match_operand 0 "s_register_operand" "=rf") ! 3783: (call (mem:SI (match_operand:SI 1 "" "i")) ! 3784: (match_operand:SI 2 "general_operand" "g"))) ! 3785: (clobber (reg:SI 14))] ! 3786: "GET_CODE(operands[1]) == SYMBOL_REF" ! 3787: "* ! 3788: return (arm_output_asm_insn (\"bl\\t%a1\", operands)); ! 3789: " ! 3790: [(set (attr "conds") ! 3791: (if_then_else (eq_attr "cpu" "arm6") ! 3792: (const_string "clob") ! 3793: (const_string "nocond"))) ! 3794: (set_attr "type" "call")]) ! 3795: ! 3796: ;; Often the return insn will be the same as loading from memory, so set attr ! 3797: (define_insn "return" ! 3798: [(return)] ! 3799: "USE_RETURN_INSN" ! 3800: "* ! 3801: { ! 3802: extern int arm_ccfsm_state; ! 3803: ! 3804: if (arm_ccfsm_state == 2) ! 3805: { ! 3806: arm_ccfsm_state += 2; ! 3807: return \"\"; ! 3808: } ! 3809: return output_return_instruction (NULL, TRUE); ! 3810: }" ! 3811: [(set_attr "type" "load")]) ! 3812: ! 3813: (define_insn "" ! 3814: [(set (pc) ! 3815: (if_then_else (match_operator 0 "comparison_operator" ! 3816: [(reg 24) (const_int 0)]) ! 3817: (return) ! 3818: (pc)))] ! 3819: "USE_RETURN_INSN" ! 3820: "* ! 3821: { ! 3822: extern int arm_ccfsm_state; ! 3823: ! 3824: if (arm_ccfsm_state == 2) ! 3825: { ! 3826: arm_ccfsm_state += 2; ! 3827: return \"\"; ! 3828: } ! 3829: return output_return_instruction (operands[0], TRUE); ! 3830: }" ! 3831: [(set_attr "conds" "use") ! 3832: (set_attr "type" "load")]) ! 3833: ! 3834: (define_insn "" ! 3835: [(set (pc) ! 3836: (if_then_else (match_operator 0 "comparison_operator" ! 3837: [(reg 24) (const_int 0)]) ! 3838: (pc) ! 3839: (return)))] ! 3840: "USE_RETURN_INSN" ! 3841: "* ! 3842: { ! 3843: extern int arm_ccfsm_state; ! 3844: ! 3845: if (arm_ccfsm_state == 2) ! 3846: { ! 3847: arm_ccfsm_state += 2; ! 3848: return \"\"; ! 3849: } ! 3850: return output_return_instruction ! 3851: (gen_rtx (reverse_condition (GET_CODE (operands[0])), ! 3852: GET_MODE (operands[0]), XEXP (operands[0], 0), ! 3853: XEXP (operands[0], 1)), ! 3854: TRUE); ! 3855: }" ! 3856: [(set_attr "conds" "use") ! 3857: (set_attr "type" "load")]) ! 3858: ! 3859: ;; Call subroutine returning any type. ! 3860: ! 3861: (define_expand "untyped_call" ! 3862: [(parallel [(call (match_operand 0 "" "") ! 3863: (const_int 0)) ! 3864: (match_operand 1 "" "") ! 3865: (match_operand 2 "" "")])] ! 3866: "" ! 3867: " ! 3868: { ! 3869: int i; ! 3870: ! 3871: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); ! 3872: ! 3873: for (i = 0; i < XVECLEN (operands[2], 0); i++) ! 3874: { ! 3875: rtx set = XVECEXP (operands[2], 0, i); ! 3876: emit_move_insn (SET_DEST (set), SET_SRC (set)); ! 3877: } ! 3878: ! 3879: /* The optimizer does not know that the call sets the function value ! 3880: registers we stored in the result block. We avoid problems by ! 3881: claiming that all hard registers are used and clobbered at this ! 3882: point. */ ! 3883: emit_insn (gen_blockage ()); ! 3884: ! 3885: DONE; ! 3886: }") ! 3887: ! 3888: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ! 3889: ;; all of memory. This blocks insns from being moved across this point. ! 3890: ! 3891: (define_insn "blockage" ! 3892: [(unspec_volatile [(const_int 0)] 0)] ! 3893: "" ! 3894: "" ! 3895: [(set_attr "length" "0") ! 3896: (set_attr "type" "block")]) ! 3897: ! 3898: (define_insn "tablejump" ! 3899: [(set (pc) ! 3900: (match_operand:SI 0 "s_register_operand" "r")) ! 3901: (use (label_ref (match_operand 1 "" "")))] ! 3902: "" ! 3903: "* ! 3904: return arm_output_asm_insn (\"mov\\tpc, %0\\t@ table jump, label %l1\", ! 3905: operands); ! 3906: ") ! 3907: ! 3908: (define_insn "" ! 3909: [(set (pc) ! 3910: (match_operand:SI 0 "memory_operand" "m")) ! 3911: (use (label_ref (match_operand 1 "" "")))] ! 3912: "" ! 3913: "* ! 3914: return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ table jump, label %l1\", ! 3915: operands); ! 3916: " ! 3917: [(set_attr "type" "load")]) ! 3918: ! 3919: (define_insn "indirect_jump" ! 3920: [(set (pc) ! 3921: (match_operand:SI 0 "s_register_operand" "r"))] ! 3922: "" ! 3923: "* ! 3924: return arm_output_asm_insn (\"mov\\tpc, %0\\t@ indirect jump\", operands); ! 3925: ") ! 3926: ! 3927: (define_insn "" ! 3928: [(set (pc) ! 3929: (match_operand:SI 0 "memory_operand" "m"))] ! 3930: "" ! 3931: "* ! 3932: return arm_output_asm_insn (\"ldr\\tpc, %0\\t@ indirect jump\", operands); ! 3933: " ! 3934: [(set_attr "type" "load")]) ! 3935: ! 3936: ;; Misc insns ! 3937: ! 3938: (define_insn "nop" ! 3939: [(const_int 0)] ! 3940: "" ! 3941: "* ! 3942: return arm_output_asm_insn (\"mov\\tr0, r0\\t@ nop\", operands); ! 3943: ") ! 3944: ! 3945: ;; Patterns to allow combination of arithmetic, cond code and shifts ! 3946: ! 3947: (define_insn "" ! 3948: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3949: (match_operator:SI 1 "shiftable_operator" ! 3950: [(match_operator:SI 3 "shift_operator" ! 3951: [(match_operand:SI 4 "s_register_operand" "r") ! 3952: (match_operand:SI 5 "nonmemory_operand" "rI")]) ! 3953: (match_operand:SI 2 "s_register_operand" "r")]))] ! 3954: "" ! 3955: "* ! 3956: return (output_arithmetic_with_shift (operands, TRUE, FALSE)); ! 3957: ") ! 3958: ! 3959: (define_insn "" ! 3960: [(set (reg:CC_NOOV 24) ! 3961: (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" ! 3962: [(match_operator:SI 3 "shift_operator" ! 3963: [(match_operand:SI 4 "s_register_operand" "r") ! 3964: (match_operand:SI 5 "nonmemory_operand" "rI")]) ! 3965: (match_operand:SI 2 "s_register_operand" "r")]) ! 3966: (const_int 0))) ! 3967: (set (match_operand:SI 0 "s_register_operand" "=r") ! 3968: (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) ! 3969: (match_dup 2)]))] ! 3970: "" ! 3971: "* ! 3972: return (output_arithmetic_with_shift (operands, TRUE, TRUE)); ! 3973: " ! 3974: [(set_attr "conds" "set")]) ! 3975: ! 3976: (define_insn "" ! 3977: [(set (reg:CC_NOOV 24) ! 3978: (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" ! 3979: [(match_operator:SI 3 "shift_operator" ! 3980: [(match_operand:SI 4 "s_register_operand" "r") ! 3981: (match_operand:SI 5 "nonmemory_operand" "rI")]) ! 3982: (match_operand:SI 2 "s_register_operand" "r")]) ! 3983: (const_int 0))) ! 3984: (clobber (match_scratch:SI 0 "=r"))] ! 3985: "" ! 3986: "* ! 3987: return (output_arithmetic_with_shift (operands, TRUE, TRUE)); ! 3988: " ! 3989: [(set_attr "conds" "set")]) ! 3990: ! 3991: (define_insn "" ! 3992: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 3993: (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! 3994: (match_operator:SI 2 "shift_operator" ! 3995: [(match_operand:SI 3 "s_register_operand" "r") ! 3996: (match_operand:SI 4 "nonmemory_operand" "rn")])))] ! 3997: "" ! 3998: "* ! 3999: { ! 4000: rtx ops[6]; ! 4001: ! 4002: ops[0] = operands[0]; ! 4003: ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! 4004: ops[2] = operands[1]; ! 4005: ops[3] = operands[2]; ! 4006: ops[4] = operands[3]; ! 4007: ops[5] = operands[4]; ! 4008: return output_arithmetic_with_shift (ops, FALSE, FALSE); ! 4009: } ! 4010: ") ! 4011: ! 4012: (define_insn "" ! 4013: [(set (reg:CC_NOOV 24) ! 4014: (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! 4015: (match_operator:SI 2 "shift_operator" ! 4016: [(match_operand:SI 3 "s_register_operand" "r") ! 4017: (match_operand:SI 4 "nonmemory_operand" "rn")])) ! 4018: (const_int 0))) ! 4019: (set (match_operand:SI 0 "s_register_operand" "=r") ! 4020: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 4021: (match_dup 4)])))] ! 4022: "" ! 4023: "* ! 4024: { ! 4025: rtx ops[6]; ! 4026: ! 4027: ops[0] = operands[0]; ! 4028: ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! 4029: ops[2] = operands[1]; ! 4030: ops[3] = operands[2]; ! 4031: ops[4] = operands[3]; ! 4032: ops[5] = operands[4]; ! 4033: return output_arithmetic_with_shift (ops, FALSE, TRUE); ! 4034: } ! 4035: " ! 4036: [(set_attr "conds" "set")]) ! 4037: ! 4038: (define_insn "" ! 4039: [(set (reg:CC_NOOV 24) ! 4040: (compare:CC_NOOV (minus:SI (match_operand:SI 1 "s_register_operand" "r") ! 4041: (match_operator:SI 2 "shift_operator" ! 4042: [(match_operand:SI 3 "s_register_operand" "r") ! 4043: (match_operand:SI 4 "nonmemory_operand" "rn")])) ! 4044: (const_int 0))) ! 4045: (clobber (match_scratch:SI 0 "=r"))] ! 4046: "" ! 4047: "* ! 4048: { ! 4049: rtx ops[6]; ! 4050: ! 4051: ops[0] = operands[0]; ! 4052: ops[1] = gen_rtx (MINUS, SImode, operands[1], operands[2]); ! 4053: ops[2] = operands[1]; ! 4054: ops[3] = operands[2]; ! 4055: ops[4] = operands[3]; ! 4056: ops[5] = operands[4]; ! 4057: return output_arithmetic_with_shift (ops, FALSE, TRUE); ! 4058: } ! 4059: " ! 4060: [(set_attr "conds" "set")]) ! 4061: ! 4062: ;; These variants of the above insns can occur if the first operand is the ! 4063: ;; frame pointer and we eliminate that. This is a kludge, but there doesn't ! 4064: ;; seem to be a way around it. Most of the predicates have to be null ! 4065: ;; because the format can be generated part way through reload, so ! 4066: ;; if we don't match it as soon as it becomes available, reload doesn't know ! 4067: ;; how to reload pseudos that haven't got hard registers; the constraints will ! 4068: ;; sort everything out. ! 4069: ! 4070: (define_insn "" ! 4071: [(set (match_operand:SI 0 "" "=&r") ! 4072: (plus:SI (plus:SI (match_operator:SI 5 "shift_operator" ! 4073: [(match_operand:SI 3 "" "r") ! 4074: (match_operand:SI 4 "" "rn")]) ! 4075: (match_operand:SI 2 "" "r")) ! 4076: (match_operand:SI 1 "const_int_operand" "n")))] ! 4077: "reload_in_progress" ! 4078: "* ! 4079: { ! 4080: char instr[100]; ! 4081: sprintf (instr, \"add\\t%%0, %%2, %%3, %s %%4\", ! 4082: shift_instr (GET_CODE (operands[5]), &operands[4])); ! 4083: arm_output_asm_insn (instr, operands); ! 4084: operands[2] = operands[1]; ! 4085: operands[1] = operands[0]; ! 4086: return output_add_immediate (operands); ! 4087: }" ! 4088: ; we have no idea how long the add_immediate is, it could be up to 4. ! 4089: [(set_attr "length" "5")]) ! 4090: ! 4091: (define_insn "" ! 4092: [(set (reg:CC_NOOV 24) ! 4093: (compare:CC_NOOV (plus:SI ! 4094: (plus:SI ! 4095: (match_operator:SI 5 "shift_operator" ! 4096: [(match_operand:SI 3 "" "r") ! 4097: (match_operand:SI 4 "" "rn")]) ! 4098: (match_operand:SI 1 "" "r")) ! 4099: (match_operand:SI 2 "const_int_operand" "n")) ! 4100: (const_int 0))) ! 4101: (set (match_operand:SI 0 "" "=&r") ! 4102: (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)]) ! 4103: (match_dup 1)) ! 4104: (match_dup 2)))] ! 4105: "reload_in_progress" ! 4106: "* ! 4107: { ! 4108: char instr[100]; ! 4109: sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\", ! 4110: shift_instr (GET_CODE (operands[5]), &operands[4])); ! 4111: output_add_immediate (operands); ! 4112: return arm_output_asm_insn (instr, operands); ! 4113: }" ! 4114: [(set_attr "conds" "set") ! 4115: (set_attr "length" "5")]) ! 4116: ! 4117: (define_insn "" ! 4118: [(set (reg:CC_NOOV 24) ! 4119: (compare:CC_NOOV (plus:SI ! 4120: (plus:SI ! 4121: (match_operator:SI 5 "shift_operator" ! 4122: [(match_operand:SI 3 "" "r") ! 4123: (match_operand:SI 4 "" "rn")]) ! 4124: (match_operand:SI 1 "" "r")) ! 4125: (match_operand:SI 2 "const_int_operand" "n")) ! 4126: (const_int 0))) ! 4127: (clobber (match_scratch:SI 0 "=&r"))] ! 4128: "reload_in_progress" ! 4129: "* ! 4130: { ! 4131: char instr[100]; ! 4132: sprintf (instr, \"adds\\t%%0, %%0, %%3, %s %%4\", ! 4133: shift_instr (GET_CODE (operands[5]), &operands[4])); ! 4134: output_add_immediate (operands); ! 4135: return arm_output_asm_insn (instr, operands); ! 4136: }" ! 4137: [(set_attr "conds" "set") ! 4138: (set_attr "length" "5")]) ! 4139: ! 4140: ;; These are similar, but are needed when the mla pattern contains the ! 4141: ;; eliminated register as operand 3. ! 4142: ! 4143: (define_insn "" ! 4144: [(set (match_operand:SI 0 "" "=&r,&r") ! 4145: (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r") ! 4146: (match_operand:SI 2 "" "r,r")) ! 4147: (match_operand:SI 3 "" "r,r")) ! 4148: (match_operand:SI 4 "const_int_operand" "n,n")))] ! 4149: "reload_in_progress" ! 4150: "* ! 4151: arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands); ! 4152: operands[2] = operands[4]; ! 4153: operands[1] = operands[0]; ! 4154: return output_add_immediate (operands); ! 4155: " ! 4156: [(set_attr "length" "5")]) ! 4157: ! 4158: (define_insn "" ! 4159: [(set (reg:CC_NOOV 24) ! 4160: (compare:CC_NOOV (plus:SI (plus:SI (mult:SI ! 4161: (match_operand:SI 3 "" "r") ! 4162: (match_operand:SI 4 "" "r")) ! 4163: (match_operand:SI 1 "" "r")) ! 4164: (match_operand:SI 2 "const_int_operand" "n")) ! 4165: (const_int 0))) ! 4166: (set (match_operand:SI 0 "" "=&r") ! 4167: (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1)) ! 4168: (match_dup 2)))] ! 4169: "reload_in_progress" ! 4170: "* ! 4171: output_add_immediate (operands); ! 4172: return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands); ! 4173: " ! 4174: [(set_attr "length" "5") ! 4175: (set_attr "conds" "set")]) ! 4176: ! 4177: (define_insn "" ! 4178: [(set (reg:CC_NOOV 24) ! 4179: (compare:CC_NOOV (plus:SI (plus:SI (mult:SI ! 4180: (match_operand:SI 3 "" "r") ! 4181: (match_operand:SI 4 "" "r")) ! 4182: (match_operand:SI 1 "" "r")) ! 4183: (match_operand:SI 2 "const_int_operand" "n")) ! 4184: (const_int 0))) ! 4185: (clobber (match_scratch:SI 0 "=&r"))] ! 4186: "reload_in_progress" ! 4187: "* ! 4188: output_add_immediate (operands); ! 4189: return arm_output_asm_insn (\"mlas\\t%0, %3, %4, %0\", operands); ! 4190: " ! 4191: [(set_attr "length" "5") ! 4192: (set_attr "conds" "set")]) ! 4193: ! 4194: ! 4195: ! 4196: ! 4197: (define_insn "" ! 4198: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 4199: (and:SI (match_operator 1 "comparison_operator" ! 4200: [(reg 24) (const_int 0)]) ! 4201: (match_operand:SI 2 "s_register_operand" "r")))] ! 4202: "" ! 4203: "* ! 4204: arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 4205: return arm_output_asm_insn (\"and%d1\\t%0, %2, #1\", operands); ! 4206: " ! 4207: [(set_attr "conds" "use") ! 4208: (set_attr "length" "2")]) ! 4209: ! 4210: (define_insn "" ! 4211: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4212: (ior:SI (match_operator 2 "comparison_operator" ! 4213: [(reg 24) (const_int 0)]) ! 4214: (match_operand:SI 1 "s_register_operand" "0,?r")))] ! 4215: "" ! 4216: "* ! 4217: if (which_alternative != 0) ! 4218: arm_output_asm_insn (\"mov%D2\\t%0, %1\", operands); ! 4219: return arm_output_asm_insn (\"orr%d2\\t%0, %1, #1\", operands); ! 4220: " ! 4221: [(set_attr "conds" "use") ! 4222: (set_attr "length" "1,2")]) ! 4223: ! 4224: (define_insn "" ! 4225: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 4226: (match_operator 1 "comparison_operator" ! 4227: [(match_operand:SI 2 "s_register_operand" "r") ! 4228: (match_operand:SI 3 "arm_add_operand" "rL")])) ! 4229: (clobber (reg 24))] ! 4230: "" ! 4231: "* ! 4232: if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx) ! 4233: return arm_output_asm_insn (\"mov\\t%0, %2, lsr #31\", operands); ! 4234: if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx) ! 4235: { ! 4236: arm_output_asm_insn (\"mvn\\t%0, %2\", operands); ! 4237: return arm_output_asm_insn (\"mov\\t%0, %0, lsr #31\", operands); ! 4238: } ! 4239: if (GET_CODE (operands[1]) == NE) ! 4240: { ! 4241: if (GET_CODE (operands[3]) == CONST_INT ! 4242: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4243: arm_output_asm_insn (\"adds\\t%0, %2, #%n3\", operands); ! 4244: else ! 4245: arm_output_asm_insn (\"subs\\t%0, %2, %3\", operands); ! 4246: return arm_output_asm_insn (\"movne\\t%0, #1\", operands); ! 4247: } ! 4248: if (GET_CODE (operands[3]) == CONST_INT ! 4249: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4250: arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4251: else ! 4252: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4253: arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 4254: return arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! 4255: " ! 4256: [(set_attr "conds" "clob") ! 4257: (set_attr "length" "3")]) ! 4258: ! 4259: (define_insn "" ! 4260: [(set (match_operand:SI 0 "s_register_operand" "=&r") ! 4261: (ior:SI (match_operator 1 "comparison_operator" ! 4262: [(match_operand:SI 2 "s_register_operand" "r") ! 4263: (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! 4264: (match_operator 4 "comparison_operator" ! 4265: [(match_operand:SI 5 "s_register_operand" "r") ! 4266: (match_operand:SI 6 "arm_rhs_operand" "rI")]))) ! 4267: (clobber (reg 24))] ! 4268: "" ! 4269: "* ! 4270: { ! 4271: int dominant = comparison_dominates_p (GET_CODE (operands[4]), ! 4272: GET_CODE (operands[1])); ! 4273: ! 4274: arm_output_asm_insn (dominant ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\", ! 4275: operands); ! 4276: arm_output_asm_insn (\"mov\\t%0, #0\", operands); ! 4277: if (GET_CODE (operands[1]) == GET_CODE (operands[4]) ! 4278: || comparison_dominates_p (GET_CODE (operands[1]), ! 4279: GET_CODE (operands[4])) ! 4280: || dominant) ! 4281: { ! 4282: arm_output_asm_insn (dominant ? \"cmp%D4\\t%2, %3\" : \"cmp%D1\\t%5,%6\", ! 4283: operands); ! 4284: } ! 4285: else ! 4286: { ! 4287: arm_output_asm_insn (\"mov%d1\\t%0, #1\", operands); ! 4288: arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! 4289: } ! 4290: return arm_output_asm_insn (dominant ? \"mov%d1\\t%0, #1\" ! 4291: : \"mov%d4\\t%0, #1\", operands); ! 4292: } ! 4293: " ! 4294: [(set_attr "conds" "clob") ! 4295: ; worst case length ! 4296: (set_attr "length" "5")]) ! 4297: ! 4298: (define_split ! 4299: [(set (pc) ! 4300: (if_then_else (match_operator 5 "equality_operator" ! 4301: [(ior:SI (match_operator 6 "comparison_operator" ! 4302: [(match_operand:SI 0 "s_register_operand" "r") ! 4303: (match_operand:SI 1 "arm_add_operand" "rL")]) ! 4304: (match_operator 7 "comparison_operator" ! 4305: [(match_operand:SI 2 "s_register_operand" "r") ! 4306: (match_operand:SI 3 "arm_add_operand" "rL")])) ! 4307: (const_int 0)]) ! 4308: (label_ref (match_operand 4 "" "")) ! 4309: (pc))) ! 4310: (clobber (reg 24))] ! 4311: "(GET_CODE (operands[6]) == GET_CODE (operands[7]) ! 4312: || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[7])) ! 4313: || comparison_dominates_p (GET_CODE (operands[7]), GET_CODE (operands[6])))" ! 4314: [(set (reg:CC 24) ! 4315: (compare:CC (ior:CC (match_op_dup 6 ! 4316: [(match_dup 0) (match_dup 1)]) ! 4317: (match_op_dup 7 ! 4318: [(match_dup 2) (match_dup 3)])) ! 4319: (const_int 0))) ! 4320: (set (pc) ! 4321: (if_then_else (match_op_dup 5 [(reg:CC 24) (const_int 0)]) ! 4322: (label_ref (match_dup 4)) ! 4323: (pc)))] ! 4324: " ! 4325: { ! 4326: enum rtx_code code = comparison_dominates_p (GET_CODE (operands[6]), ! 4327: GET_CODE (operands[7])) ! 4328: ? GET_CODE (operands[7]) : GET_CODE (operands[6]); ! 4329: ! 4330: if (GET_CODE (operands[5]) == NE) ! 4331: operands[5] = gen_rtx (code, CCmode, ! 4332: XEXP (operands[5], 0), XEXP (operands[5], 1)); ! 4333: else ! 4334: operands[5] = gen_rtx (reverse_condition (code), CCmode, ! 4335: XEXP (operands[5], 0), XEXP (operands[5], 1)); ! 4336: } ! 4337: ") ! 4338: ! 4339: ;; Don't match these patterns if we can use a conditional compare, since they ! 4340: ;; tell the final prescan branch elimator code that full branch inlining ! 4341: ;; can't be done. ! 4342: ! 4343: (define_insn "" ! 4344: [(set (pc) ! 4345: (if_then_else (ne ! 4346: (ior:SI (match_operator 5 "comparison_operator" ! 4347: [(match_operand:SI 0 "s_register_operand" "r") ! 4348: (match_operand:SI 1 "arm_add_operand" "rL")]) ! 4349: (match_operator 6 "comparison_operator" ! 4350: [(match_operand:SI 2 "s_register_operand" "r") ! 4351: (match_operand:SI 3 "arm_rhs_operand" "rL")])) ! 4352: (const_int 0)) ! 4353: (label_ref (match_operand 4 "" "")) ! 4354: (pc))) ! 4355: (clobber (reg 24))] ! 4356: "!(GET_CODE (operands[5]) == GET_CODE (operands[6]) ! 4357: || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[6])) ! 4358: || comparison_dominates_p (GET_CODE (operands[6]), GET_CODE (operands[5])))" ! 4359: "* ! 4360: { ! 4361: extern int arm_ccfsm_state; ! 4362: ! 4363: if (GET_CODE (operands[1]) == CONST_INT ! 4364: && !const_ok_for_arm (INTVAL (operands[1]))) ! 4365: arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands); ! 4366: else ! 4367: arm_output_asm_insn (\"cmp\\t%0, %1\", operands); ! 4368: arm_output_asm_insn (\"b%d5\\t%l4\", operands); ! 4369: if (GET_CODE (operands[3]) == CONST_INT ! 4370: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4371: arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4372: else ! 4373: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4374: if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! 4375: { ! 4376: arm_ccfsm_state += 2; ! 4377: return \"\"; ! 4378: } ! 4379: return arm_output_asm_insn (\"b%d6\\t%l4\", operands); ! 4380: }" ! 4381: [(set_attr "conds" "jump_clob") ! 4382: (set_attr "length" "4")]) ! 4383: ! 4384: (define_insn "" ! 4385: [(set (reg:CC 24) ! 4386: (compare:CC (ior:CC (match_operator 4 "comparison_operator" ! 4387: [(match_operand:SI 0 "s_register_operand" "r") ! 4388: (match_operand:SI 1 "arm_add_operand" "rL")]) ! 4389: (match_operator 5 "comparison_operator" ! 4390: [(match_operand:SI 2 "s_register_operand" "r") ! 4391: (match_operand:SI 3 "arm_add_operand" "rL")])) ! 4392: (const_int 0)))] ! 4393: "(GET_CODE (operands[4]) == GET_CODE (operands[5]) ! 4394: || comparison_dominates_p (GET_CODE (operands[4]), GET_CODE (operands[5])) ! 4395: || comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])))" ! 4396: "* ! 4397: if (comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]))) ! 4398: { ! 4399: if (GET_CODE (operands[3]) == CONST_INT ! 4400: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4401: arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4402: else ! 4403: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4404: if (GET_CODE (operands[1]) == CONST_INT ! 4405: && !const_ok_for_arm (INTVAL (operands[1]))) ! 4406: return arm_output_asm_insn (\"cmn%D5\\t%0, #%n1\", operands); ! 4407: return arm_output_asm_insn (\"cmp%D5\\t%0, %1\", operands); ! 4408: } ! 4409: if (GET_CODE (operands[1]) == CONST_INT ! 4410: && !const_ok_for_arm (INTVAL (operands[1]))) ! 4411: arm_output_asm_insn (\"cmn\\t%0, #%n1\", operands); ! 4412: else ! 4413: arm_output_asm_insn (\"cmp\\t%0, %1\", operands); ! 4414: if (GET_CODE (operands[3]) == CONST_INT ! 4415: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4416: return arm_output_asm_insn (\"cmn%D4\\t%2, #%n3\", operands); ! 4417: return arm_output_asm_insn (\"cmp%D4\\t%2, %3\", operands); ! 4418: " ! 4419: [(set_attr "conds" "set") ! 4420: (set_attr "length" "2")]) ! 4421: ! 4422: (define_insn "" ! 4423: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 4424: (if_then_else (match_operator 3 "equality_operator" ! 4425: [(match_operator 4 "comparison_operator" ! 4426: [(reg 24) (const_int 0)]) ! 4427: (const_int 0)]) ! 4428: (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") ! 4429: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] ! 4430: "" ! 4431: "* ! 4432: if (GET_CODE (operands[3]) == NE) ! 4433: { ! 4434: if (which_alternative != 0) ! 4435: arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands); ! 4436: if (which_alternative != 1) ! 4437: arm_output_asm_insn (\"mov%D4\\t%0, %2\", operands); ! 4438: return \"\"; ! 4439: } ! 4440: if (which_alternative != 0) ! 4441: arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! 4442: if (which_alternative != 1) ! 4443: arm_output_asm_insn (\"mov%d4\\t%0, %2\", operands); ! 4444: return \"\"; ! 4445: " ! 4446: [(set_attr "conds" "use") ! 4447: (set_attr "length" "1,1,2")]) ! 4448: ! 4449: (define_insn "" ! 4450: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4451: (match_operator:SI 5 "shiftable_operator" ! 4452: [(match_operator:SI 4 "comparison_operator" ! 4453: [(match_operand:SI 2 "s_register_operand" "r,r") ! 4454: (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) ! 4455: (match_operand:SI 1 "s_register_operand" "0,?r")])) ! 4456: (clobber (reg 24))] ! 4457: "" ! 4458: "* ! 4459: { ! 4460: char *instr = arithmetic_instr (operands[5], TRUE); ! 4461: char pattern[100]; ! 4462: ! 4463: if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) ! 4464: { ! 4465: sprintf (pattern, \"%s\\t%%0, %%1, %%2, lsr #31\", instr); ! 4466: return arm_output_asm_insn (pattern, operands); ! 4467: } ! 4468: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4469: if (GET_CODE (operands[5]) == AND) ! 4470: arm_output_asm_insn (\"mov%D4\\t%0, #0\", operands); ! 4471: else if (which_alternative != 0) ! 4472: arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! 4473: sprintf (pattern, \"%s%%d4\\t%%0, %%1, #1\", instr); ! 4474: return arm_output_asm_insn (pattern, operands); ! 4475: } ! 4476: " ! 4477: [(set_attr "conds" "clob") ! 4478: (set_attr "length" "3")]) ! 4479: ! 4480: (define_insn "" ! 4481: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4482: (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") ! 4483: (match_operator:SI 4 "comparison_operator" ! 4484: [(match_operand:SI 2 "s_register_operand" "r,r") ! 4485: (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) ! 4486: (clobber (reg 24))] ! 4487: "" ! 4488: "* ! 4489: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4490: if (which_alternative != 0) ! 4491: arm_output_asm_insn (\"mov%D4\\t%0, %1\", operands); ! 4492: return arm_output_asm_insn (\"sub%d4\\t%0, %1, #1\", operands); ! 4493: " ! 4494: [(set_attr "conds" "clob") ! 4495: (set_attr "length" "2,3")]) ! 4496: ! 4497: (define_insn "" ! 4498: [(set (match_operand:SI 0 "s_register_operand" "=&r") ! 4499: (and:SI (match_operator 1 "comparison_operator" ! 4500: [(match_operand:SI 2 "s_register_operand" "r") ! 4501: (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! 4502: (match_operator 4 "comparison_operator" ! 4503: [(match_operand:SI 5 "s_register_operand" "r") ! 4504: (match_operand:SI 6 "arm_rhs_operand" "rI")]))) ! 4505: (clobber (reg 24))] ! 4506: "" ! 4507: "* ! 4508: { ! 4509: int dominant = ! 4510: comparison_dominates_p (reverse_condition (GET_CODE (operands[1])), ! 4511: reverse_condition (GET_CODE (operands[4]))) ! 4512: ? 1 ! 4513: : comparison_dominates_p (reverse_condition (GET_CODE (operands[4])), ! 4514: reverse_condition (GET_CODE (operands[1]))) ! 4515: ? 2 : 0; ! 4516: arm_output_asm_insn (dominant == 2 ? \"cmp\\t%5, %6\" : \"cmp\\t%2, %3\", ! 4517: operands); ! 4518: arm_output_asm_insn (\"mov\\t%0, #1\", operands); ! 4519: if (GET_CODE (operands[1]) == GET_CODE (operands[4]) || dominant) ! 4520: { ! 4521: arm_output_asm_insn (dominant == 2 ? \"cmp%d4\\t%2, %3\" ! 4522: : \"cmp%d1\\t%5, %6\", operands); ! 4523: } ! 4524: else ! 4525: { ! 4526: arm_output_asm_insn (\"mov%D1\\t%0, #0\", operands); ! 4527: arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! 4528: } ! 4529: return arm_output_asm_insn (dominant == 2 ? \"mov%D1\\t%0, #0\" ! 4530: : \"mov%D4\\t%0, #0\", operands); ! 4531: } ! 4532: " ! 4533: [(set_attr "conds" "clob") ! 4534: (set_attr "length" "5")]) ! 4535: ! 4536: (define_split ! 4537: [(set (pc) ! 4538: (if_then_else (match_operator 1 "equality_operator" ! 4539: [(and:SI (match_operator 2 "comparison_operator" ! 4540: [(match_operand:SI 3 "s_register_operand" "r") ! 4541: (match_operand:SI 4 "arm_add_operand" "rL")]) ! 4542: (match_operator 0 "comparison_operator" ! 4543: [(match_operand:SI 5 "s_register_operand" "r") ! 4544: (match_operand:SI 6 "arm_add_operand" "rL")])) ! 4545: (const_int 0)]) ! 4546: (label_ref (match_operand 7 "" "")) ! 4547: (pc))) ! 4548: (clobber (reg 24))] ! 4549: "(GET_CODE (operands[2]) == GET_CODE (operands[0]) ! 4550: || comparison_dominates_p (reverse_condition (GET_CODE (operands[2])), ! 4551: reverse_condition (GET_CODE (operands[0]))) ! 4552: || comparison_dominates_p (reverse_condition (GET_CODE (operands[0])), ! 4553: reverse_condition (GET_CODE (operands[2]))))" ! 4554: [(set (reg:CC 24) ! 4555: (compare:CC (ior:CC (match_op_dup 2 ! 4556: [(match_dup 3) (match_dup 4)]) ! 4557: (match_op_dup 0 ! 4558: [(match_dup 5) (match_dup 6)])) ! 4559: (const_int 0))) ! 4560: (set (pc) ! 4561: (if_then_else (match_op_dup 1 [(reg:CC 24) (const_int 0)]) ! 4562: (label_ref (match_dup 7)) ! 4563: (pc)))] ! 4564: " ! 4565: { ! 4566: /* Use DeMorgans law to convert this into an IOR of the inverse conditions ! 4567: This is safe since we only do it for integer comparisons. */ ! 4568: enum rtx_code code = ! 4569: comparison_dominates_p (reverse_condition (GET_CODE (operands[2])), ! 4570: reverse_condition (GET_CODE (operands[0]))) ! 4571: ? GET_CODE (operands[0]) : GET_CODE (operands[2]); ! 4572: ! 4573: operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[2])), ! 4574: GET_MODE (operands[2]), operands[3], operands[4]); ! 4575: operands[0] = gen_rtx (reverse_condition (GET_CODE (operands[0])), ! 4576: GET_MODE (operands[0]), operands[5], operands[6]); ! 4577: if (GET_CODE (operands[1]) == NE) ! 4578: operands[1] = gen_rtx (code, CCmode, ! 4579: XEXP (operands[1], 0), XEXP (operands[1], 1)); ! 4580: else ! 4581: operands[1] = gen_rtx (reverse_condition (code), CCmode, ! 4582: XEXP (operands[1], 0), XEXP (operands[1], 1)); ! 4583: } ! 4584: ") ! 4585: ! 4586: ;; Don't match these patterns if we can use a conditional compare, since they ! 4587: ;; tell the final prescan branch elimator code that full branch inlining ! 4588: ;; can't be done. ! 4589: ! 4590: (define_insn "" ! 4591: [(set (pc) ! 4592: (if_then_else (eq ! 4593: (and:SI (match_operator 1 "comparison_operator" ! 4594: [(match_operand:SI 2 "s_register_operand" "r") ! 4595: (match_operand:SI 3 "arm_add_operand" "rL")]) ! 4596: (match_operator 4 "comparison_operator" ! 4597: [(match_operand:SI 5 "s_register_operand" "r") ! 4598: (match_operand:SI 6 "arm_rhs_operand" "rL")])) ! 4599: (const_int 0)) ! 4600: (label_ref (match_operand 0 "" "")) ! 4601: (pc))) ! 4602: (clobber (reg 24))] ! 4603: "!(GET_CODE (operands[1]) == GET_CODE (operands[4]) ! 4604: || comparison_dominates_p (reverse_condition (GET_CODE (operands[1])), ! 4605: reverse_condition (GET_CODE (operands[4]))) ! 4606: || comparison_dominates_p (reverse_condition (GET_CODE (operands[4])), ! 4607: reverse_condition (GET_CODE (operands[1]))))" ! 4608: "* ! 4609: { ! 4610: extern int arm_ccfsm_state; ! 4611: ! 4612: if (GET_CODE (operands[3]) == CONST_INT ! 4613: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4614: arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4615: else ! 4616: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4617: arm_output_asm_insn (\"b%D1\\t%l0\", operands); ! 4618: if (GET_CODE (operands[6]) == CONST_INT ! 4619: && !const_ok_for_arm (INTVAL (operands[6]))) ! 4620: arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! 4621: else ! 4622: arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! 4623: if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) ! 4624: { ! 4625: arm_ccfsm_state += 2; ! 4626: return \"\"; ! 4627: } ! 4628: return arm_output_asm_insn (\"b%D4\\t%l0\", operands); ! 4629: }" ! 4630: [(set_attr "conds" "jump_clob") ! 4631: (set_attr "length" "4")]) ! 4632: ! 4633: (define_insn "" ! 4634: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 4635: (neg:SI (match_operator 3 "comparison_operator" ! 4636: [(match_operand:SI 1 "s_register_operand" "r") ! 4637: (match_operand:SI 2 "arm_rhs_operand" "rI")]))) ! 4638: (clobber (reg 24))] ! 4639: "" ! 4640: "* ! 4641: if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx) ! 4642: return arm_output_asm_insn (\"mov\\t%0, %1, asr #31\", operands); ! 4643: if (GET_CODE (operands[3]) == NE) ! 4644: { ! 4645: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 4646: return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands); ! 4647: } ! 4648: if (GET_CODE (operands[3]) == GT) ! 4649: { ! 4650: arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); ! 4651: return arm_output_asm_insn (\"mvnne\\t%0, %0, asr #31\", operands); ! 4652: } ! 4653: arm_output_asm_insn (\"cmp\\t%1, %2\", operands); ! 4654: arm_output_asm_insn (\"mov%D3\\t%0, #0\", operands); ! 4655: return arm_output_asm_insn (\"mvn%d3\\t%0, #0\", operands); ! 4656: " ! 4657: [(set_attr "conds" "clob") ! 4658: (set_attr "length" "3")]) ! 4659: ! 4660: (define_insn "movcond" ! 4661: [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") ! 4662: (if_then_else:SI (match_operator 5 "comparison_operator" ! 4663: [(match_operand:SI 3 "s_register_operand" "r,r,r") ! 4664: (match_operand:SI 4 "arm_add_operand" "rL,rL,rL")]) ! 4665: (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") ! 4666: (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) ! 4667: (clobber (reg 24))] ! 4668: "" ! 4669: "* ! 4670: if (GET_CODE (operands[5]) == LT ! 4671: && (operands[4] == const0_rtx)) ! 4672: { ! 4673: if (which_alternative != 1 && GET_CODE (operands[4]) == REG) ! 4674: { ! 4675: arm_output_asm_insn (\"ands\\t%0, %1, %3, asr #32\", operands); ! 4676: if (operands[2] == const0_rtx) ! 4677: return \"\"; ! 4678: return arm_output_asm_insn (\"movcc\\t%0, %2\", operands); ! 4679: } ! 4680: else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) ! 4681: { ! 4682: arm_output_asm_insn (\"bics\\t%0, %2, %3, asr #32\", operands); ! 4683: if (operands[1] == const0_rtx) ! 4684: return \"\"; ! 4685: return arm_output_asm_insn (\"movcs\\t%0, %1\", operands); ! 4686: } ! 4687: /* The only case that falls through to here is when both ops 1 & 2 ! 4688: are constants */ ! 4689: } ! 4690: if (GET_CODE (operands[5]) == GE ! 4691: && (operands[4] == const0_rtx)) ! 4692: { ! 4693: if (which_alternative != 1 && GET_CODE (operands[1]) == REG) ! 4694: { ! 4695: arm_output_asm_insn (\"bics\\t%0, %1, %3, asr #32\", operands); ! 4696: if (operands[2] == const0_rtx) ! 4697: return \"\"; ! 4698: return arm_output_asm_insn (\"movcs\\t%0, %2\", operands); ! 4699: } ! 4700: else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) ! 4701: { ! 4702: arm_output_asm_insn (\"ands\\t%0, %2, %3, asr #32\", operands); ! 4703: if (operands[1] == const0_rtx) ! 4704: return \"\"; ! 4705: return arm_output_asm_insn (\"movcc\\t%0, %1\", operands); ! 4706: } ! 4707: /* The only case that falls through to here is when both ops 1 & 2 ! 4708: are constants */ ! 4709: } ! 4710: if (GET_CODE (operands[4]) == CONST_INT ! 4711: && !const_ok_for_arm (INTVAL (operands[4]))) ! 4712: arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! 4713: else ! 4714: arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! 4715: if (which_alternative != 0) ! 4716: arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands); ! 4717: if (which_alternative != 1) ! 4718: arm_output_asm_insn (\"mov%D5\\t%0, %2\", operands); ! 4719: return \"\"; ! 4720: " ! 4721: [(set_attr "conds" "clob") ! 4722: (set_attr "length" "2,2,3")]) ! 4723: ! 4724: (define_insn "" ! 4725: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 4726: (if_then_else:SI (match_operator 9 "comparison_operator" ! 4727: [(match_operand:SI 5 "s_register_operand" "r") ! 4728: (match_operand:SI 6 "arm_add_operand" "rL")]) ! 4729: (match_operator:SI 8 "shiftable_operator" ! 4730: [(match_operand:SI 1 "s_register_operand" "r") ! 4731: (match_operand:SI 2 "arm_rhs_operand" "rI")]) ! 4732: (match_operator:SI 7 "shiftable_operator" ! 4733: [(match_operand:SI 3 "s_register_operand" "r") ! 4734: (match_operand:SI 4 "arm_rhs_operand" "rI")]))) ! 4735: (clobber (reg 24))] ! 4736: "" ! 4737: "* ! 4738: { ! 4739: char pattern[100]; ! 4740: ! 4741: if (GET_CODE (operands[6]) == CONST_INT ! 4742: && !const_ok_for_arm (INTVAL (operands[6]))) ! 4743: arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! 4744: else ! 4745: arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! 4746: sprintf (pattern, \"%s%%d9\\t%%0, %%1, %%2\", arithmetic_instr (operands[8], ! 4747: FALSE)); ! 4748: arm_output_asm_insn (pattern, operands); ! 4749: sprintf (pattern, \"%s%%D9\\t%%0, %%3, %%4\", arithmetic_instr (operands[7], ! 4750: FALSE)); ! 4751: return arm_output_asm_insn (pattern, operands); ! 4752: } ! 4753: " ! 4754: [(set_attr "conds" "clob") ! 4755: (set_attr "length" "3")]) ! 4756: ! 4757: (define_insn "" ! 4758: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4759: (if_then_else:SI (match_operator 6 "comparison_operator" ! 4760: [(match_operand:SI 2 "s_register_operand" "r,r") ! 4761: (match_operand:SI 3 "arm_add_operand" "rL,rL")]) ! 4762: (match_operator:SI 7 "shiftable_operator" ! 4763: [(match_operand:SI 4 "s_register_operand" "r,r") ! 4764: (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) ! 4765: (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm"))) ! 4766: (clobber (reg 24))] ! 4767: "" ! 4768: "* ! 4769: { ! 4770: char pattern[100]; ! 4771: ! 4772: /* If we have an operation where (op x 0) is the identity operation and ! 4773: the condtional operator is LT or GE and we are comparing against zero and ! 4774: everything is in registers then we can do this in two instructions */ ! 4775: if (operands[3] == const0_rtx ! 4776: && GET_CODE (operands[7]) != AND ! 4777: && GET_CODE (operands[5]) == REG ! 4778: && GET_CODE (operands[1]) == REG ! 4779: && REGNO (operands[1]) == REGNO (operands[4]) ! 4780: && REGNO (operands[4]) != REGNO (operands[0])) ! 4781: { ! 4782: if (GET_CODE (operands[6]) == LT) ! 4783: { ! 4784: arm_output_asm_insn (\"and\\t%0, %5, %2, asr #31\", operands); ! 4785: sprintf (pattern, \"%s\\t%%0, %%4, %%0\", ! 4786: arithmetic_instr (operands[7], FALSE)); ! 4787: return arm_output_asm_insn (pattern, operands); ! 4788: } ! 4789: else if (GET_CODE (operands[6]) == GE) ! 4790: { ! 4791: arm_output_asm_insn (\"bic\\t%0, %5, %2, asr #31\", operands); ! 4792: sprintf (pattern, \"%s\\t%%0, %%4, %%0\", ! 4793: arithmetic_instr (operands[7], FALSE)); ! 4794: return arm_output_asm_insn (pattern, operands); ! 4795: } ! 4796: } ! 4797: if (GET_CODE (operands[3]) == CONST_INT ! 4798: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4799: arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4800: else ! 4801: arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4802: sprintf (pattern, \"%s%%d6\\t%%0, %%4, %%5\", arithmetic_instr (operands[7], ! 4803: FALSE)); ! 4804: arm_output_asm_insn (pattern, operands); ! 4805: if (which_alternative != 0) ! 4806: { ! 4807: if (GET_CODE (operands[1]) == MEM) ! 4808: arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands); ! 4809: else ! 4810: arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! 4811: } ! 4812: return \"\"; ! 4813: } ! 4814: " ! 4815: [(set_attr "conds" "clob") ! 4816: (set_attr "length" "2,3")]) ! 4817: ! 4818: (define_insn "" ! 4819: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4820: (if_then_else:SI (match_operator 6 "comparison_operator" ! 4821: [(match_operand:SI 4 "s_register_operand" "r,r") ! 4822: (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! 4823: (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm") ! 4824: (match_operator:SI 7 "shiftable_operator" ! 4825: [(match_operand:SI 2 "s_register_operand" "r,r") ! 4826: (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) ! 4827: (clobber (reg 24))] ! 4828: "" ! 4829: "* ! 4830: { ! 4831: char pattern[100]; ! 4832: ! 4833: /* If we have an operation where (op x 0) is the identity operation and ! 4834: the condtional operator is LT or GE and we are comparing against zero and ! 4835: everything is in registers then we can do this in two instructions */ ! 4836: if (operands[5] == const0_rtx ! 4837: && GET_CODE (operands[7]) != AND ! 4838: && GET_CODE (operands[3]) == REG ! 4839: && GET_CODE (operands[1]) == REG ! 4840: && REGNO (operands[1]) == REGNO (operands[2]) ! 4841: && REGNO (operands[2]) != REGNO (operands[0])) ! 4842: { ! 4843: if (GET_CODE (operands[6]) == GE) ! 4844: { ! 4845: arm_output_asm_insn (\"and\\t%0, %3, %4, asr #31\", operands); ! 4846: sprintf (pattern, \"%s\\t%%0, %%2, %%0\", ! 4847: arithmetic_instr (operands[7], FALSE)); ! 4848: return arm_output_asm_insn (pattern, operands); ! 4849: } ! 4850: else if (GET_CODE (operands[6]) == LT) ! 4851: { ! 4852: arm_output_asm_insn (\"bic\\t%0, %3, %4, asr #31\", operands); ! 4853: sprintf (pattern, \"%s\\t%%0, %%2, %%0\", ! 4854: arithmetic_instr (operands[7], FALSE)); ! 4855: return arm_output_asm_insn (pattern, operands); ! 4856: } ! 4857: } ! 4858: if (GET_CODE (operands[5]) == CONST_INT ! 4859: && !const_ok_for_arm (INTVAL (operands[5]))) ! 4860: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 4861: else ! 4862: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 4863: if (which_alternative != 0) ! 4864: { ! 4865: if (GET_CODE (operands[1]) == MEM) ! 4866: arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands); ! 4867: else ! 4868: arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! 4869: } ! 4870: sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! 4871: FALSE)); ! 4872: return arm_output_asm_insn (pattern, operands); ! 4873: } ! 4874: " ! 4875: [(set_attr "conds" "clob") ! 4876: (set_attr "length" "2,3")]) ! 4877: ! 4878: (define_insn "" ! 4879: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4880: (if_then_else:SI (match_operator 6 "comparison_operator" ! 4881: [(match_operand:SI 4 "s_register_operand" "r,r") ! 4882: (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! 4883: (plus:SI ! 4884: (match_operand:SI 2 "s_register_operand" "r,r") ! 4885: (match_operand:SI 3 "arm_add_operand" "rL,rL")) ! 4886: (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm"))) ! 4887: (clobber (reg 24))] ! 4888: "" ! 4889: "* ! 4890: { ! 4891: if (GET_CODE (operands[5]) == CONST_INT ! 4892: && !const_ok_for_arm (INTVAL (operands[5]))) ! 4893: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 4894: else ! 4895: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 4896: if (GET_CODE (operands[3]) == CONST_INT ! 4897: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4898: arm_output_asm_insn (\"sub%d6\\t%0, %2, #%n3\", operands); ! 4899: else ! 4900: arm_output_asm_insn (\"add%d6\\t%0, %2, %3\", operands); ! 4901: if (which_alternative != 0) ! 4902: { ! 4903: if (GET_CODE (operands[1]) == MEM) ! 4904: arm_output_asm_insn (\"ldr%D6\\t%0, %1\", operands); ! 4905: else ! 4906: arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! 4907: } ! 4908: return \"\"; ! 4909: } ! 4910: " ! 4911: [(set_attr "conds" "clob") ! 4912: (set_attr "length" "2,3")]) ! 4913: ! 4914: (define_insn "" ! 4915: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4916: (if_then_else:SI (match_operator 6 "comparison_operator" ! 4917: [(match_operand:SI 4 "s_register_operand" "r,r") ! 4918: (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! 4919: (match_operand:SI 1 "arm_rhsm_operand" "0,?rIm") ! 4920: (plus:SI ! 4921: (match_operand:SI 2 "s_register_operand" "r,r") ! 4922: (match_operand:SI 3 "arm_add_operand" "rL,rL")))) ! 4923: (clobber (reg 24))] ! 4924: "" ! 4925: "* ! 4926: { ! 4927: if (GET_CODE (operands[5]) == CONST_INT ! 4928: && !const_ok_for_arm (INTVAL (operands[5]))) ! 4929: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 4930: else ! 4931: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 4932: if (GET_CODE (operands[3]) == CONST_INT ! 4933: && !const_ok_for_arm (INTVAL (operands[3]))) ! 4934: arm_output_asm_insn (\"sub%D6\\t%0, %2, #%n3\", operands); ! 4935: else ! 4936: arm_output_asm_insn (\"add%D6\\t%0, %2, %3\", operands); ! 4937: if (which_alternative != 0) ! 4938: { ! 4939: if (GET_CODE (operands[6]) == MEM) ! 4940: arm_output_asm_insn (\"ldr%d6\\t%0, %1\", operands); ! 4941: else ! 4942: arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! 4943: } ! 4944: return \"\"; ! 4945: } ! 4946: " ! 4947: [(set_attr "conds" "clob") ! 4948: (set_attr "length" "2,3")]) ! 4949: ! 4950: (define_insn "" ! 4951: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4952: (if_then_else:SI (match_operator 5 "comparison_operator" ! 4953: [(match_operand:SI 3 "s_register_operand" "r,r") ! 4954: (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! 4955: (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! 4956: (not:SI ! 4957: (match_operand:SI 2 "s_register_operand" "r,r")))) ! 4958: (clobber (reg 24))] ! 4959: "" ! 4960: "#" ! 4961: [(set_attr "conds" "clob") ! 4962: (set_attr "length" "2,3")]) ! 4963: ! 4964: ;; if (GET_CODE (operands[3]) == CONST_INT ! 4965: ;; && !const_ok_for_arm (INTVAL (operands[3]))) ! 4966: ;; arm_output_asm_insn (\"cmn\\t%2, #%n3\", operands); ! 4967: ;; else ! 4968: ;; arm_output_asm_insn (\"cmp\\t%2, %3\", operands); ! 4969: ;; if (which_alternative != 0) ! 4970: ;; arm_output_asm_insn (\"mov%d1\\t%0, %4\", operands); ! 4971: ;; return arm_output_asm_insn (\"mvn%D1\\t%0, %5\", operands); ! 4972: ! 4973: (define_insn "" ! 4974: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 4975: (if_then_else:SI (match_operator 5 "comparison_operator" ! 4976: [(match_operand:SI 3 "s_register_operand" "r,r") ! 4977: (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! 4978: (not:SI ! 4979: (match_operand:SI 2 "s_register_operand" "r,r")) ! 4980: (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! 4981: (clobber (reg 24))] ! 4982: "" ! 4983: "* ! 4984: { ! 4985: char pattern[100]; ! 4986: ! 4987: if (GET_CODE (operands[30]) == CONST_INT ! 4988: && !const_ok_for_arm (INTVAL (operands[4]))) ! 4989: arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! 4990: else ! 4991: arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! 4992: if (which_alternative != 0) ! 4993: arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands); ! 4994: return arm_output_asm_insn (\"mvn%d5\\t%0, %2\", operands); ! 4995: ! 4996: } ! 4997: " ! 4998: [(set_attr "conds" "clob") ! 4999: (set_attr "length" "2,3")]) ! 5000: ! 5001: (define_insn "" ! 5002: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 5003: (if_then_else:SI (match_operator 6 "comparison_operator" ! 5004: [(match_operand:SI 4 "s_register_operand" "r,r") ! 5005: (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! 5006: (match_operator:SI 7 "shift_operator" ! 5007: [(match_operand:SI 2 "s_register_operand" "r,r") ! 5008: (match_operand:SI 3 "arm_rhs_operand" "rn,rn")]) ! 5009: (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! 5010: (clobber (reg 24))] ! 5011: "" ! 5012: "* ! 5013: { ! 5014: char pattern[100]; ! 5015: ! 5016: if (GET_CODE (operands[5]) == CONST_INT ! 5017: && !const_ok_for_arm (INTVAL (operands[5]))) ! 5018: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 5019: else ! 5020: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 5021: if (which_alternative != 0) ! 5022: arm_output_asm_insn (\"mov%D6\\t%0, %1\", operands); ! 5023: sprintf (pattern, \"mov%%d6\\t%%0, %%2, %s %%3\", ! 5024: shift_instr (GET_CODE (operands[7]), &operands[3])); ! 5025: return arm_output_asm_insn (pattern, operands); ! 5026: } ! 5027: " ! 5028: [(set_attr "conds" "clob") ! 5029: (set_attr "length" "2,3")]) ! 5030: ! 5031: (define_insn "" ! 5032: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 5033: (if_then_else:SI (match_operator 6 "comparison_operator" ! 5034: [(match_operand:SI 4 "s_register_operand" "r,r") ! 5035: (match_operand:SI 5 "arm_add_operand" "rL,rL")]) ! 5036: (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! 5037: (match_operator:SI 7 "shift_operator" ! 5038: [(match_operand:SI 2 "s_register_operand" "r,r") ! 5039: (match_operand:SI 3 "arm_rhs_operand" "rn,rn")]))) ! 5040: (clobber (reg 24))] ! 5041: "" ! 5042: "* ! 5043: { ! 5044: char pattern[100]; ! 5045: ! 5046: if (GET_CODE (operands[5]) == CONST_INT ! 5047: && !const_ok_for_arm (INTVAL (operands[5]))) ! 5048: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 5049: else ! 5050: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 5051: if (which_alternative != 0) ! 5052: arm_output_asm_insn (\"mov%d6\\t%0, %1\", operands); ! 5053: sprintf (pattern, \"mov%%D6\\t%%0, %%2, %s %%3\", ! 5054: shift_instr (GET_CODE (operands[7]), &operands[3])); ! 5055: return arm_output_asm_insn (pattern, operands); ! 5056: } ! 5057: " ! 5058: [(set_attr "conds" "clob") ! 5059: (set_attr "length" "2,3")]) ! 5060: ! 5061: (define_insn "" ! 5062: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5063: (if_then_else:SI (match_operator 7 "comparison_operator" ! 5064: [(match_operand:SI 5 "s_register_operand" "r") ! 5065: (match_operand:SI 6 "arm_add_operand" "rL")]) ! 5066: (match_operator:SI 8 "shift_operator" ! 5067: [(match_operand:SI 1 "s_register_operand" "r") ! 5068: (match_operand:SI 2 "arm_rhs_operand" "rn")]) ! 5069: (match_operator:SI 9 "shift_operator" ! 5070: [(match_operand:SI 3 "s_register_operand" "r") ! 5071: (match_operand:SI 4 "arm_rhs_operand" "rI")]))) ! 5072: (clobber (reg 24))] ! 5073: "" ! 5074: "* ! 5075: { ! 5076: char pattern[100]; ! 5077: ! 5078: if (GET_CODE (operands[6]) == CONST_INT ! 5079: && !const_ok_for_arm (INTVAL (operands[6]))) ! 5080: arm_output_asm_insn (\"cmn\\t%5, #%n6\", operands); ! 5081: else ! 5082: arm_output_asm_insn (\"cmp\\t%5, %6\", operands); ! 5083: sprintf (pattern, \"mov%%d7\\t%%0, %%1, %s %%2\", ! 5084: shift_instr (GET_CODE (operands[8]), &operands[2])); ! 5085: arm_output_asm_insn (pattern, operands); ! 5086: sprintf (pattern, \"mov%%D7\\t%%0, %%3, %s %%4\", ! 5087: shift_instr (GET_CODE (operands[9]), &operands[4])); ! 5088: return arm_output_asm_insn (pattern, operands); ! 5089: } ! 5090: " ! 5091: [(set_attr "conds" "clob") ! 5092: (set_attr "length" "3")]) ! 5093: ! 5094: (define_insn "" ! 5095: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5096: (if_then_else:SI (match_operator 6 "comparison_operator" ! 5097: [(match_operand:SI 4 "s_register_operand" "r") ! 5098: (match_operand:SI 5 "arm_add_operand" "rL")]) ! 5099: (not:SI (match_operand:SI 1 "s_register_operand" "r")) ! 5100: (match_operator:SI 7 "shiftable_operator" ! 5101: [(match_operand:SI 2 "s_register_operand" "r") ! 5102: (match_operand:SI 3 "arm_rhs_operand" "rI")]))) ! 5103: (clobber (reg 24))] ! 5104: "" ! 5105: "* ! 5106: { ! 5107: char pattern[100]; ! 5108: ! 5109: if (GET_CODE (operands[5]) == CONST_INT ! 5110: && !const_ok_for_arm (INTVAL (operands[5]))) ! 5111: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 5112: else ! 5113: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 5114: arm_output_asm_insn (\"mvn%d6\\t%0, %1\", operands); ! 5115: sprintf (pattern, \"%s%%D6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! 5116: FALSE)); ! 5117: return arm_output_asm_insn (pattern, operands); ! 5118: } ! 5119: " ! 5120: [(set_attr "conds" "clob") ! 5121: (set_attr "length" "3")]) ! 5122: ! 5123: (define_insn "" ! 5124: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5125: (if_then_else:SI (match_operator 6 "comparison_operator" ! 5126: [(match_operand:SI 4 "s_register_operand" "r") ! 5127: (match_operand:SI 5 "arm_add_operand" "rL")]) ! 5128: (match_operator:SI 7 "shiftable_operator" ! 5129: [(match_operand:SI 2 "s_register_operand" "r") ! 5130: (match_operand:SI 3 "arm_rhs_operand" "rI")]) ! 5131: (not:SI (match_operand:SI 1 "s_register_operand" "r")))) ! 5132: (clobber (reg 24))] ! 5133: "" ! 5134: "* ! 5135: { ! 5136: char pattern[100]; ! 5137: ! 5138: if (GET_CODE (operands[5]) == CONST_INT ! 5139: && !const_ok_for_arm (INTVAL (operands[5]))) ! 5140: arm_output_asm_insn (\"cmn\\t%4, #%n5\", operands); ! 5141: else ! 5142: arm_output_asm_insn (\"cmp\\t%4, %5\", operands); ! 5143: arm_output_asm_insn (\"mvn%D6\\t%0, %1\", operands); ! 5144: sprintf (pattern, \"%s%%d6\\t%%0, %%2, %%3\", arithmetic_instr (operands[7], ! 5145: FALSE)); ! 5146: return arm_output_asm_insn (pattern, operands); ! 5147: } ! 5148: " ! 5149: [(set_attr "conds" "clob") ! 5150: (set_attr "length" "3")]) ! 5151: ! 5152: (define_insn "" ! 5153: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 5154: (if_then_else:SI (match_operator 5 "comparison_operator" ! 5155: [(match_operand:SI 3 "s_register_operand" "r,r") ! 5156: (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! 5157: (neg:SI ! 5158: (match_operand:SI 2 "s_register_operand" "r,r")) ! 5159: (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) ! 5160: (clobber (reg:CC 24))] ! 5161: "" ! 5162: "* ! 5163: if (GET_CODE (operands[4]) == CONST_INT ! 5164: && !const_ok_for_arm (INTVAL (operands[4]))) ! 5165: arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! 5166: else ! 5167: arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! 5168: if (which_alternative != 0) ! 5169: arm_output_asm_insn (\"mov%D5\\t%0, %1\", operands); ! 5170: return arm_output_asm_insn (\"rsb%d5\\t%0, %2, #0\", operands); ! 5171: " ! 5172: [(set_attr "conds" "clob") ! 5173: (set_attr "length" "2,3")]) ! 5174: ! 5175: (define_insn "" ! 5176: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 5177: (if_then_else:SI (match_operator 5 "comparison_operator" ! 5178: [(match_operand:SI 3 "s_register_operand" "r,r") ! 5179: (match_operand:SI 4 "arm_add_operand" "rL,rL")]) ! 5180: (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! 5181: (neg:SI ! 5182: (match_operand:SI 2 "s_register_operand" "r,r")))) ! 5183: (clobber (reg:CC 24))] ! 5184: "" ! 5185: "* ! 5186: if (GET_CODE (operands[4]) == CONST_INT ! 5187: && !const_ok_for_arm (INTVAL (operands[4]))) ! 5188: arm_output_asm_insn (\"cmn\\t%3, #%n4\", operands); ! 5189: else ! 5190: arm_output_asm_insn (\"cmp\\t%3, %4\", operands); ! 5191: if (which_alternative != 0) ! 5192: arm_output_asm_insn (\"mov%d5\\t%0, %1\", operands); ! 5193: return arm_output_asm_insn (\"rsb%D5\\t%0, %2, #0\", operands); ! 5194: " ! 5195: [(set_attr "conds" "clob") ! 5196: (set_attr "length" "2,3")]) ! 5197: ! 5198: (define_insn "" ! 5199: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5200: (match_operator:SI 1 "shiftable_operator" ! 5201: [(match_operand:SI 2 "memory_operand" "m") ! 5202: (match_operand:SI 3 "memory_operand" "m")])) ! 5203: (clobber (match_scratch:SI 4 "=r"))] ! 5204: "adjacent_mem_locations (operands[2], operands[3])" ! 5205: "* ! 5206: { ! 5207: rtx ldm[3]; ! 5208: rtx arith[3]; ! 5209: char pattern[100]; ! 5210: int val1 = 0, val2 = 0; ! 5211: ! 5212: sprintf (pattern, \"%s\\t%%0, %%1, %%2\", ! 5213: arithmetic_instr (operands[1], FALSE)); ! 5214: if (REGNO (operands[0]) > REGNO (operands[4])) ! 5215: { ! 5216: ldm[1] = operands[4]; ! 5217: ldm[2] = operands[0]; ! 5218: } ! 5219: else ! 5220: { ! 5221: ldm[1] = operands[0]; ! 5222: ldm[2] = operands[4]; ! 5223: } ! 5224: if (GET_CODE (XEXP (operands[2], 0)) != REG) ! 5225: val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1)); ! 5226: if (GET_CODE (XEXP (operands[3], 0)) != REG) ! 5227: val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); ! 5228: arith[0] = operands[0]; ! 5229: if (val1 < val2) ! 5230: { ! 5231: arith[1] = ldm[1]; ! 5232: arith[2] = ldm[2]; ! 5233: } ! 5234: else ! 5235: { ! 5236: arith[1] = ldm[2]; ! 5237: arith[2] = ldm[1]; ! 5238: } ! 5239: if (val1 && val2) ! 5240: { ! 5241: rtx ops[3]; ! 5242: ldm[0] = ops[0] = operands[4]; ! 5243: ops[1] = XEXP (XEXP (operands[2], 0), 0); ! 5244: ops[2] = XEXP (XEXP (operands[2], 0), 1); ! 5245: output_add_immediate (ops); ! 5246: if (val1 < val2) ! 5247: arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! 5248: else ! 5249: arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! 5250: } ! 5251: else if (val1) ! 5252: { ! 5253: ldm[0] = XEXP (operands[3], 0); ! 5254: if (val1 < val2) ! 5255: arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! 5256: else ! 5257: arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! 5258: } ! 5259: else ! 5260: { ! 5261: ldm[0] = XEXP (operands[2], 0); ! 5262: if (val1 < val2) ! 5263: arm_output_asm_insn (\"ldmia\\t%0, {%1, %2}\", ldm); ! 5264: else ! 5265: arm_output_asm_insn (\"ldmda\\t%0, {%1, %2}\", ldm); ! 5266: } ! 5267: return arm_output_asm_insn (pattern, arith); ! 5268: } ! 5269: " ! 5270: [(set_attr "length" "3") ! 5271: (set_attr "type" "load")]) ! 5272: ! 5273: ;; the arm can support extended pre-inc instructions ! 5274: ! 5275: ;; In all these cases, we use operands 0 and 1 for the register being ! 5276: ;; incremented because those are the operands that local-alloc will ! 5277: ;; tie and these are the pair most likely to be tieable (and the ones ! 5278: ;; that will benefit the most). ! 5279: ! 5280: ;; We reject the frame pointer if it occurs anywhere in these patterns since ! 5281: ;; elimination will cause too many headaches. ! 5282: ! 5283: (define_insn "" ! 5284: [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5285: (match_operand:SI 2 "index_operand" "rJ"))) ! 5286: (match_operand:QI 3 "s_register_operand" "r")) ! 5287: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5288: (plus:SI (match_dup 1) (match_dup 2)))] ! 5289: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5290: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5291: && (GET_CODE (operands[2]) != REG ! 5292: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5293: "* ! 5294: return arm_output_asm_insn (\"strb\\t%3, [%0, %2]!\", operands); ! 5295: " ! 5296: [(set_attr "type" "store1")]) ! 5297: ! 5298: (define_insn "" ! 5299: [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5300: (match_operand:SI 2 "s_register_operand" "r"))) ! 5301: (match_operand:QI 3 "s_register_operand" "r")) ! 5302: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5303: (minus:SI (match_dup 1) (match_dup 2)))] ! 5304: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5305: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5306: && (GET_CODE (operands[2]) != REG ! 5307: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5308: "* ! 5309: return arm_output_asm_insn (\"strb\\t%3, [%0, -%2]!\", operands); ! 5310: " ! 5311: [(set_attr "type" "store1")]) ! 5312: ! 5313: (define_insn "" ! 5314: [(set (match_operand:QI 3 "s_register_operand" "=r") ! 5315: (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5316: (match_operand:SI 2 "index_operand" "rJ")))) ! 5317: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5318: (plus:SI (match_dup 1) (match_dup 2)))] ! 5319: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5320: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5321: && (GET_CODE (operands[2]) != REG ! 5322: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5323: "* ! 5324: return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\", operands); ! 5325: " ! 5326: [(set_attr "type" "load")]) ! 5327: ! 5328: (define_insn "" ! 5329: [(set (match_operand:QI 3 "s_register_operand" "=r") ! 5330: (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5331: (match_operand:SI 2 "s_register_operand" "r")))) ! 5332: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5333: (minus:SI (match_dup 1) (match_dup 2)))] ! 5334: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5335: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5336: && (GET_CODE (operands[2]) != REG ! 5337: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5338: "* ! 5339: return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\", operands); ! 5340: " ! 5341: [(set_attr "type" "load")]) ! 5342: ! 5343: (define_insn "" ! 5344: [(set (match_operand:SI 3 "s_register_operand" "=r") ! 5345: (zero_extend:SI ! 5346: (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5347: (match_operand:SI 2 "index_operand" "rJ"))))) ! 5348: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5349: (plus:SI (match_dup 1) (match_dup 2)))] ! 5350: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5351: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5352: && (GET_CODE (operands[2]) != REG ! 5353: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5354: "* ! 5355: return arm_output_asm_insn (\"ldrb\\t%3, [%0, %2]!\\t@ z_extendqisi\", ! 5356: operands); ! 5357: " ! 5358: [(set_attr "type" "load")]) ! 5359: ! 5360: (define_insn "" ! 5361: [(set (match_operand:SI 3 "s_register_operand" "=r") ! 5362: (zero_extend:SI ! 5363: (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5364: (match_operand:SI 2 "s_register_operand" "r"))))) ! 5365: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5366: (minus:SI (match_dup 1) (match_dup 2)))] ! 5367: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5368: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5369: && (GET_CODE (operands[2]) != REG ! 5370: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5371: "* ! 5372: return arm_output_asm_insn (\"ldrb\\t%3, [%0, -%2]!\\t@ z_extendqisi\", ! 5373: operands); ! 5374: " ! 5375: [(set_attr "type" "load")]) ! 5376: ! 5377: (define_insn "" ! 5378: [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5379: (match_operand:SI 2 "index_operand" "rJ"))) ! 5380: (match_operand:SI 3 "s_register_operand" "r")) ! 5381: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5382: (plus:SI (match_dup 1) (match_dup 2)))] ! 5383: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5384: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5385: && (GET_CODE (operands[2]) != REG ! 5386: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5387: "* ! 5388: return arm_output_asm_insn (\"str\\t%3, [%0, %2]!\", operands); ! 5389: " ! 5390: [(set_attr "type" "store1")]) ! 5391: ! 5392: (define_insn "" ! 5393: [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5394: (match_operand:SI 2 "s_register_operand" "r"))) ! 5395: (match_operand:SI 3 "s_register_operand" "r")) ! 5396: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5397: (minus:SI (match_dup 1) (match_dup 2)))] ! 5398: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5399: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5400: && (GET_CODE (operands[2]) != REG ! 5401: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5402: "* ! 5403: return arm_output_asm_insn (\"str\\t%3, [%0, -%2]!\", operands); ! 5404: " ! 5405: [(set_attr "type" "store1")]) ! 5406: ! 5407: (define_insn "" ! 5408: [(set (match_operand:SI 3 "s_register_operand" "=r") ! 5409: (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5410: (match_operand:SI 2 "index_operand" "rJ")))) ! 5411: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5412: (plus:SI (match_dup 1) (match_dup 2)))] ! 5413: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5414: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5415: && (GET_CODE (operands[2]) != REG ! 5416: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5417: "* ! 5418: return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\", operands); ! 5419: " ! 5420: [(set_attr "type" "load")]) ! 5421: ! 5422: (define_insn "" ! 5423: [(set (match_operand:SI 3 "s_register_operand" "=r") ! 5424: (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5425: (match_operand:SI 2 "s_register_operand" "r")))) ! 5426: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5427: (minus:SI (match_dup 1) (match_dup 2)))] ! 5428: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5429: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5430: && (GET_CODE (operands[2]) != REG ! 5431: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5432: "* ! 5433: return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\", operands); ! 5434: " ! 5435: [(set_attr "type" "load")]) ! 5436: ! 5437: (define_insn "" ! 5438: [(set (match_operand:HI 3 "s_register_operand" "=r") ! 5439: (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") ! 5440: (match_operand:SI 2 "index_operand" "rJ")))) ! 5441: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5442: (plus:SI (match_dup 1) (match_dup 2)))] ! 5443: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5444: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5445: && (GET_CODE (operands[2]) != REG ! 5446: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5447: "* ! 5448: return arm_output_asm_insn (\"ldr\\t%3, [%0, %2]!\\t@ loadhi\", operands); ! 5449: " ! 5450: [(set_attr "type" "load")]) ! 5451: ! 5452: (define_insn "" ! 5453: [(set (match_operand:HI 3 "s_register_operand" "=r") ! 5454: (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5455: (match_operand:SI 2 "s_register_operand" "r")))) ! 5456: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5457: (minus:SI (match_dup 1) (match_dup 2)))] ! 5458: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5459: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5460: && (GET_CODE (operands[2]) != REG ! 5461: || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" ! 5462: "* ! 5463: return arm_output_asm_insn (\"ldr\\t%3, [%0, -%2]!\\t@ loadhi\", operands); ! 5464: " ! 5465: [(set_attr "type" "load")]) ! 5466: ! 5467: (define_insn "" ! 5468: [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" ! 5469: [(match_operand:SI 3 "s_register_operand" "r") ! 5470: (match_operand:SI 4 "const_shift_operand" "n")]) ! 5471: (match_operand:SI 1 "s_register_operand" "0"))) ! 5472: (match_operand:QI 5 "s_register_operand" "r")) ! 5473: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5474: (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 5475: (match_dup 1)))] ! 5476: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5477: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5478: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5479: "* ! 5480: { ! 5481: char instr[100]; ! 5482: ! 5483: sprintf (instr, \"strb\\t%%5, [%%0, %%3, %s %%4]!\", ! 5484: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5485: return arm_output_asm_insn (instr, operands); ! 5486: } ! 5487: " ! 5488: [(set_attr "type" "store1")]) ! 5489: ! 5490: (define_insn "" ! 5491: [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5492: (match_operator:SI 2 "shift_operator" ! 5493: [(match_operand:SI 3 "s_register_operand" "r") ! 5494: (match_operand:SI 4 "const_shift_operand" "n")]))) ! 5495: (match_operand:QI 5 "s_register_operand" "r")) ! 5496: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5497: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 5498: (match_dup 4)])))] ! 5499: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5500: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5501: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5502: "* ! 5503: { ! 5504: char instr[100]; ! 5505: ! 5506: sprintf (instr, \"strb\\t%%5, [%%0, -%%3, %s %%4]!\", ! 5507: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5508: return arm_output_asm_insn (instr, operands); ! 5509: } ! 5510: " ! 5511: [(set_attr "type" "store1")]) ! 5512: ! 5513: (define_insn "" ! 5514: [(set (match_operand:QI 5 "s_register_operand" "=r") ! 5515: (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" ! 5516: [(match_operand:SI 3 "s_register_operand" "r") ! 5517: (match_operand:SI 4 "const_shift_operand" "n")]) ! 5518: (match_operand:SI 1 "s_register_operand" "0")))) ! 5519: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5520: (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 5521: (match_dup 1)))] ! 5522: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5523: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5524: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5525: "* ! 5526: { ! 5527: char instr[100]; ! 5528: ! 5529: sprintf (instr, \"ldrb\\t%%5, [%%0, %%3, %s %%4]!\", ! 5530: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5531: return arm_output_asm_insn (instr, operands); ! 5532: } ! 5533: " ! 5534: [(set_attr "type" "load")]) ! 5535: ! 5536: (define_insn "" ! 5537: [(set (match_operand:QI 5 "s_register_operand" "=r") ! 5538: (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5539: (match_operator:SI 2 "shift_operator" ! 5540: [(match_operand:SI 3 "s_register_operand" "r") ! 5541: (match_operand:SI 4 "const_shift_operand" "n")])))) ! 5542: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5543: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 5544: (match_dup 4)])))] ! 5545: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5546: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5547: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5548: "* ! 5549: { ! 5550: char instr[100]; ! 5551: ! 5552: sprintf (instr, \"ldrb\\t%%5, [%%0, -%%3, %s %%4]!\", ! 5553: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5554: return arm_output_asm_insn (instr, operands); ! 5555: } ! 5556: " ! 5557: [(set_attr "type" "load")]) ! 5558: ! 5559: (define_insn "" ! 5560: [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" ! 5561: [(match_operand:SI 3 "s_register_operand" "r") ! 5562: (match_operand:SI 4 "const_shift_operand" "n")]) ! 5563: (match_operand:SI 1 "s_register_operand" "0"))) ! 5564: (match_operand:SI 5 "s_register_operand" "r")) ! 5565: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5566: (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 5567: (match_dup 1)))] ! 5568: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5569: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5570: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5571: "* ! 5572: { ! 5573: char instr[100]; ! 5574: ! 5575: sprintf (instr, \"str\\t%%5, [%%0, %%3, %s %%4]!\", ! 5576: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5577: return arm_output_asm_insn (instr, operands); ! 5578: } ! 5579: " ! 5580: [(set_attr "type" "store1")]) ! 5581: ! 5582: (define_insn "" ! 5583: [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5584: (match_operator:SI 2 "shift_operator" ! 5585: [(match_operand:SI 3 "s_register_operand" "r") ! 5586: (match_operand:SI 4 "const_shift_operand" "n")]))) ! 5587: (match_operand:SI 5 "s_register_operand" "r")) ! 5588: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5589: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 5590: (match_dup 4)])))] ! 5591: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5592: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5593: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5594: "* ! 5595: { ! 5596: char instr[100]; ! 5597: ! 5598: sprintf (instr, \"str\\t%%5, [%%0, -%%3, %s %%4]!\", ! 5599: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5600: return arm_output_asm_insn (instr, operands); ! 5601: } ! 5602: " ! 5603: [(set_attr "type" "store1")]) ! 5604: ! 5605: (define_insn "" ! 5606: [(set (match_operand:SI 5 "s_register_operand" "=r") ! 5607: (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" ! 5608: [(match_operand:SI 3 "s_register_operand" "r") ! 5609: (match_operand:SI 4 "const_shift_operand" "n")]) ! 5610: (match_operand:SI 1 "s_register_operand" "0")))) ! 5611: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5612: (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 5613: (match_dup 1)))] ! 5614: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5615: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5616: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5617: "* ! 5618: { ! 5619: char instr[100]; ! 5620: ! 5621: sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\", ! 5622: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5623: return arm_output_asm_insn (instr, operands); ! 5624: } ! 5625: " ! 5626: [(set_attr "type" "load")]) ! 5627: ! 5628: (define_insn "" ! 5629: [(set (match_operand:SI 5 "s_register_operand" "=r") ! 5630: (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5631: (match_operator:SI 2 "shift_operator" ! 5632: [(match_operand:SI 3 "s_register_operand" "r") ! 5633: (match_operand:SI 4 "const_shift_operand" "n")])))) ! 5634: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5635: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 5636: (match_dup 4)])))] ! 5637: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5638: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5639: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5640: "* ! 5641: { ! 5642: char instr[100]; ! 5643: ! 5644: sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\", ! 5645: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5646: return arm_output_asm_insn (instr, operands); ! 5647: } ! 5648: " ! 5649: [(set_attr "type" "load")]) ! 5650: ! 5651: (define_insn "" ! 5652: [(set (match_operand:HI 5 "s_register_operand" "=r") ! 5653: (mem:HI (plus:SI (match_operator:SI 2 "shift_operator" ! 5654: [(match_operand:SI 3 "s_register_operand" "r") ! 5655: (match_operand:SI 4 "const_shift_operand" "n")]) ! 5656: (match_operand:SI 1 "s_register_operand" "0")))) ! 5657: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5658: (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 5659: (match_dup 1)))] ! 5660: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5661: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5662: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5663: "* ! 5664: { ! 5665: char instr[100]; ! 5666: ! 5667: sprintf (instr, \"ldr\\t%%5, [%%0, %%3, %s %%4]!\\t@ loadhi\", ! 5668: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5669: return arm_output_asm_insn (instr, operands); ! 5670: } ! 5671: " ! 5672: [(set_attr "type" "load")]) ! 5673: ! 5674: (define_insn "" ! 5675: [(set (match_operand:HI 5 "s_register_operand" "=r") ! 5676: (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") ! 5677: (match_operator:SI 2 "shift_operator" ! 5678: [(match_operand:SI 3 "s_register_operand" "r") ! 5679: (match_operand:SI 4 "const_shift_operand" "n")])))) ! 5680: (set (match_operand:SI 0 "s_register_operand" "=r") ! 5681: (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) ! 5682: (match_dup 4)])))] ! 5683: "REGNO (operands[0]) != FRAME_POINTER_REGNUM ! 5684: && REGNO (operands[1]) != FRAME_POINTER_REGNUM ! 5685: && REGNO (operands[3]) != FRAME_POINTER_REGNUM" ! 5686: "* ! 5687: { ! 5688: char instr[100]; ! 5689: ! 5690: sprintf (instr, \"ldr\\t%%5, [%%0, -%%3, %s %%4]!\\t@ loadhi\", ! 5691: shift_instr (GET_CODE (operands[2]), &operands[4])); ! 5692: return arm_output_asm_insn (instr, operands); ! 5693: } ! 5694: " ! 5695: [(set_attr "type" "load")]) ! 5696: ! 5697: ; It can also support extended post-inc expressions, but combine doesn't ! 5698: ; try these.... ! 5699: ; It doesn't seem worth adding peepholes for anything but the most common ! 5700: ; cases since, unlike combine, the increment must immediately follow the load ! 5701: ; for this pattern to match. ! 5702: ; When loading we must watch to see that the base register isn't trampled by ! 5703: ; the load. In such cases this isn't a post-inc expression. ! 5704: ! 5705: (define_peephole ! 5706: [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r")) ! 5707: (match_operand:QI 2 "s_register_operand" "r")) ! 5708: (set (match_dup 0) ! 5709: (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] ! 5710: "" ! 5711: "* ! 5712: return arm_output_asm_insn (\"strb\\t%2, [%0], %1\", operands); ! 5713: ") ! 5714: ! 5715: (define_peephole ! 5716: [(set (match_operand:QI 0 "s_register_operand" "=r") ! 5717: (mem:QI (match_operand:SI 1 "s_register_operand" "+r"))) ! 5718: (set (match_dup 1) ! 5719: (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! 5720: "REGNO(operands[0]) != REGNO(operands[1]) ! 5721: && (GET_CODE (operands[2]) != REG ! 5722: || REGNO(operands[0]) != REGNO (operands[2]))" ! 5723: "* ! 5724: return arm_output_asm_insn (\"ldrb\\t%0, [%1], %2\", operands); ! 5725: ") ! 5726: ! 5727: (define_peephole ! 5728: [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r")) ! 5729: (match_operand:SI 2 "s_register_operand" "r")) ! 5730: (set (match_dup 0) ! 5731: (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] ! 5732: "" ! 5733: "* ! 5734: return arm_output_asm_insn (\"str\\t%2, [%0], %1\", operands); ! 5735: ") ! 5736: ! 5737: (define_peephole ! 5738: [(set (match_operand:HI 0 "s_register_operand" "=r") ! 5739: (mem:HI (match_operand:SI 1 "s_register_operand" "+r"))) ! 5740: (set (match_dup 1) ! 5741: (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! 5742: "REGNO(operands[0]) != REGNO(operands[1]) ! 5743: && (GET_CODE (operands[2]) != REG ! 5744: || REGNO(operands[0]) != REGNO (operands[2]))" ! 5745: "* ! 5746: return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\\t@ loadhi\", operands); ! 5747: ") ! 5748: ! 5749: (define_peephole ! 5750: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5751: (mem:SI (match_operand:SI 1 "s_register_operand" "+r"))) ! 5752: (set (match_dup 1) ! 5753: (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] ! 5754: "REGNO(operands[0]) != REGNO(operands[1]) ! 5755: && (GET_CODE (operands[2]) != REG ! 5756: || REGNO(operands[0]) != REGNO (operands[2]))" ! 5757: "* ! 5758: return arm_output_asm_insn (\"ldr\\t%0, [%1], %2\", operands); ! 5759: ") ! 5760: ! 5761: ; This pattern is never tried by combine, so do it as a peephole ! 5762: ! 5763: (define_peephole ! 5764: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5765: (match_operand:SI 1 "s_register_operand" "r")) ! 5766: (set (match_operand 2 "cc_register" "") ! 5767: (compare (match_dup 1) (const_int 0)))] ! 5768: "" ! 5769: "* ! 5770: return arm_output_asm_insn (\"subs\\t%0, %1, #0\", operands); ! 5771: " ! 5772: [(set_attr "conds" "set")]) ! 5773: ! 5774: ; Peepholes to spot possible load- and store-multiples, if the ordering is ! 5775: ; reversed, check that the memory references aren't volatile. ! 5776: ! 5777: (define_peephole ! 5778: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5779: (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5780: (const_int 12)))) ! 5781: (set (match_operand:SI 2 "s_register_operand" "=r") ! 5782: (mem:SI (plus:SI (match_dup 1) (const_int 8)))) ! 5783: (set (match_operand:SI 3 "s_register_operand" "=r") ! 5784: (mem:SI (plus:SI (match_dup 1) (const_int 4)))) ! 5785: (set (match_operand:SI 4 "s_register_operand" "=r") ! 5786: (mem:SI (match_dup 1)))] ! 5787: "REGNO (operands[0]) > REGNO (operands[2]) ! 5788: && REGNO (operands[2]) > REGNO (operands[3]) ! 5789: && REGNO (operands[3]) > REGNO (operands[4]) ! 5790: && !(REGNO (operands[1]) == REGNO (operands[0]) ! 5791: || REGNO (operands[1]) == REGNO (operands[2]) ! 5792: || REGNO (operands[1]) == REGNO (operands[3]) ! 5793: || REGNO (operands[1]) == REGNO (operands[4])) ! 5794: && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! 5795: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn)))) ! 5796: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! 5797: (prev_nonnote_insn (insn))))) ! 5798: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! 5799: (prev_nonnote_insn ! 5800: (prev_nonnote_insn (insn))))))" ! 5801: "* ! 5802: return arm_output_asm_insn (\"ldmia\\t%1, {%4, %3, %2, %0}\\t@ phole ldm\", ! 5803: operands); ! 5804: ") ! 5805: ! 5806: (define_peephole ! 5807: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5808: (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5809: (const_int 8)))) ! 5810: (set (match_operand:SI 2 "s_register_operand" "=r") ! 5811: (mem:SI (plus:SI (match_dup 1) (const_int 4)))) ! 5812: (set (match_operand:SI 3 "s_register_operand" "=r") ! 5813: (mem:SI (match_dup 1)))] ! 5814: "REGNO (operands[0]) > REGNO (operands[2]) ! 5815: && REGNO (operands[2]) > REGNO (operands[3]) ! 5816: && !(REGNO (operands[1]) == REGNO (operands[0]) ! 5817: || REGNO (operands[1]) == REGNO (operands[2]) ! 5818: || REGNO (operands[1]) == REGNO (operands[3])) ! 5819: && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! 5820: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn)))) ! 5821: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn ! 5822: (prev_nonnote_insn (insn)))))" ! 5823: "* ! 5824: return arm_output_asm_insn (\"ldmia\\t%1, {%3, %2, %0}\\t@ phole ldm\", ! 5825: operands); ! 5826: ") ! 5827: ! 5828: (define_peephole ! 5829: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 5830: (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5831: (const_int 4)))) ! 5832: (set (match_operand:SI 2 "s_register_operand" "=r") ! 5833: (mem:SI (match_dup 1)))] ! 5834: "REGNO (operands[0]) > REGNO (operands[2]) ! 5835: && !(REGNO (operands[1]) == REGNO (operands[0]) ! 5836: || REGNO (operands[1]) == REGNO (operands[2])) ! 5837: && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))) ! 5838: && !MEM_VOLATILE_P (SET_SRC (PATTERN (prev_nonnote_insn (insn))))" ! 5839: "* ! 5840: return arm_output_asm_insn (\"ldmia\\t%1, {%2, %0}\\t@ phole ldm\", ! 5841: operands); ! 5842: ") ! 5843: ! 5844: (define_peephole ! 5845: [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5846: (const_int 12))) ! 5847: (match_operand:SI 0 "s_register_operand" "r")) ! 5848: (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) ! 5849: (match_operand:SI 2 "s_register_operand" "r")) ! 5850: (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) ! 5851: (match_operand:SI 3 "s_register_operand" "r")) ! 5852: (set (mem:SI (match_dup 1)) ! 5853: (match_operand:SI 4 "s_register_operand" "r"))] ! 5854: "REGNO (operands[0]) > REGNO (operands[2]) ! 5855: && REGNO (operands[2]) > REGNO (operands[3]) ! 5856: && REGNO (operands[3]) > REGNO (operands[4]) ! 5857: && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! 5858: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn)))) ! 5859: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! 5860: (prev_nonnote_insn (insn))))) ! 5861: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! 5862: (prev_nonnote_insn ! 5863: (prev_nonnote_insn (insn))))))" ! 5864: "* ! 5865: return arm_output_asm_insn (\"stmia\\t%1, {%4, %3, %2, %0}\\t@ phole stm\", ! 5866: operands); ! 5867: ") ! 5868: ! 5869: (define_peephole ! 5870: [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5871: (const_int 8))) ! 5872: (match_operand:SI 0 "s_register_operand" "r")) ! 5873: (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) ! 5874: (match_operand:SI 2 "s_register_operand" "r")) ! 5875: (set (mem:SI (match_dup 1)) ! 5876: (match_operand:SI 3 "s_register_operand" "r"))] ! 5877: "REGNO (operands[0]) > REGNO (operands[2]) ! 5878: && REGNO (operands[2]) > REGNO (operands[3]) ! 5879: && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! 5880: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn)))) ! 5881: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn ! 5882: (prev_nonnote_insn (insn)))))" ! 5883: "* ! 5884: return arm_output_asm_insn (\"stmia\\t%1, {%3, %2, %0}\\t@ phole stm\", ! 5885: operands); ! 5886: ") ! 5887: ! 5888: (define_peephole ! 5889: [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") ! 5890: (const_int 4))) ! 5891: (match_operand:SI 0 "s_register_operand" "r")) ! 5892: (set (mem:SI (match_dup 1)) ! 5893: (match_operand:SI 2 "s_register_operand" "r"))] ! 5894: "REGNO (operands[0]) > REGNO (operands[2]) ! 5895: && !MEM_VOLATILE_P (SET_DEST (PATTERN (insn))) ! 5896: && !MEM_VOLATILE_P (SET_DEST (PATTERN (prev_nonnote_insn (insn))))" ! 5897: "* ! 5898: return arm_output_asm_insn (\"stmia\\t%1, {%2, %0}\\t@ phole stm\", ! 5899: operands); ! 5900: ") ! 5901: ! 5902: ;; A call followed by return can be replaced by restoring the regs and ! 5903: ;; jumping to the subroutine, provided we aren't passing the address of ! 5904: ;; any of our local variables. If we call alloca then this is unsafe ! 5905: ;; since restoring the frame frees the memory, which is not what we want. ! 5906: ;; Sometimes the return might have been targeted by the final prescan: ! 5907: ;; if so then emit a propper return insn as well. ! 5908: ;; Unfortunately, if the frame pointer is required, we don't know if the ! 5909: ;; current function has any implicit stack pointer adjustments that will ! 5910: ;; be restored by the return: we can't therefore do a tail call. ! 5911: ;; Another unfortunate that we can't handle is if current_function_args_size ! 5912: ;; is non-zero: in this case elimination of the argument pointer assumed ! 5913: ;; that lr was pushed onto the stack, so eliminating upsets the offset ! 5914: ;; calculations. ! 5915: ! 5916: (define_peephole ! 5917: [(parallel [(call (mem:SI (match_operand:SI 0 "" "i")) ! 5918: (match_operand:SI 1 "general_operand" "g")) ! 5919: (clobber (reg:SI 14))]) ! 5920: (return)] ! 5921: "(GET_CODE (operands[0]) == SYMBOL_REF && USE_RETURN_INSN ! 5922: && !get_frame_size () && !current_function_calls_alloca ! 5923: && !frame_pointer_needed && !current_function_args_size)" ! 5924: "* ! 5925: { ! 5926: extern rtx arm_target_insn; ! 5927: extern int arm_ccfsm_state, arm_current_cc; ! 5928: ! 5929: if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! 5930: { ! 5931: arm_current_cc ^= 1; ! 5932: output_return_instruction (NULL, TRUE); ! 5933: arm_ccfsm_state = 0; ! 5934: arm_target_insn = NULL; ! 5935: } ! 5936: ! 5937: output_return_instruction (NULL, FALSE); ! 5938: return (arm_output_asm_insn (\"b\\t%a0\", operands)); ! 5939: }" ! 5940: [(set (attr "conds") ! 5941: (if_then_else (eq_attr "cpu" "arm6") ! 5942: (const_string "clob") ! 5943: (const_string "nocond"))) ! 5944: (set_attr "length" "2")]) ! 5945: ! 5946: (define_peephole ! 5947: [(parallel [(set (match_operand 0 "s_register_operand" "=rf") ! 5948: (call (mem:SI (match_operand:SI 1 "" "i")) ! 5949: (match_operand:SI 2 "general_operand" "g"))) ! 5950: (clobber (reg:SI 14))]) ! 5951: (return)] ! 5952: "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN ! 5953: && !get_frame_size () && !current_function_calls_alloca ! 5954: && !frame_pointer_needed && !current_function_args_size)" ! 5955: "* ! 5956: { ! 5957: extern rtx arm_target_insn; ! 5958: extern int arm_ccfsm_state, arm_current_cc; ! 5959: ! 5960: if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! 5961: { ! 5962: arm_current_cc ^= 1; ! 5963: output_return_instruction (NULL, TRUE); ! 5964: arm_ccfsm_state = 0; ! 5965: arm_target_insn = NULL; ! 5966: } ! 5967: ! 5968: output_return_instruction (NULL, FALSE); ! 5969: return (arm_output_asm_insn (\"b\\t%a1\", operands)); ! 5970: }" ! 5971: [(set (attr "conds") ! 5972: (if_then_else (eq_attr "cpu" "arm6") ! 5973: (const_string "clob") ! 5974: (const_string "nocond"))) ! 5975: (set_attr "length" "2")]) ! 5976: ! 5977: ;; As above but when this function is not void, we must be returning the ! 5978: ;; result of the called subroutine. ! 5979: ! 5980: (define_peephole ! 5981: [(parallel [(set (match_operand 0 "s_register_operand" "=rf") ! 5982: (call (mem:SI (match_operand:SI 1 "" "i")) ! 5983: (match_operand:SI 2 "general_operand" "g"))) ! 5984: (clobber (reg:SI 14))]) ! 5985: (use (match_dup 0)) ! 5986: (return)] ! 5987: "(GET_CODE (operands[1]) == SYMBOL_REF && USE_RETURN_INSN ! 5988: && !get_frame_size () && !current_function_calls_alloca ! 5989: && !frame_pointer_needed && !current_function_args_size)" ! 5990: "* ! 5991: { ! 5992: extern rtx arm_target_insn; ! 5993: extern int arm_ccfsm_state, arm_current_cc; ! 5994: ! 5995: if (arm_ccfsm_state && arm_target_insn && INSN_DELETED_P (arm_target_insn)) ! 5996: { ! 5997: arm_current_cc ^= 1; ! 5998: output_return_instruction (NULL, TRUE); ! 5999: arm_ccfsm_state = 0; ! 6000: arm_target_insn = NULL; ! 6001: } ! 6002: ! 6003: output_return_instruction (NULL, FALSE); ! 6004: return (arm_output_asm_insn (\"b\\t%a1\", operands)); ! 6005: }" ! 6006: [(set (attr "conds") ! 6007: (if_then_else (eq_attr "cpu" "arm6") ! 6008: (const_string "clob") ! 6009: (const_string "nocond"))) ! 6010: (set_attr "length" "2")]) ! 6011: ! 6012: ;; If calling a subroutine and then jumping back to somewhere else, but not ! 6013: ;; too far away, then we can set the link register with the branch address ! 6014: ;; and jump direct to the subroutine. On return from the subroutine ! 6015: ;; execution continues at the branch; this avoids a prefetch stall. ! 6016: ;; We use the length attribute (via short_branch ()) to establish whether or ! 6017: ;; not this is possible, this is the same asthe sparc does. ! 6018: ! 6019: (define_peephole ! 6020: [(parallel[(call (mem:SI (match_operand:SI 0 "" "i")) ! 6021: (match_operand:SI 1 "general_operand" "g")) ! 6022: (clobber (reg:SI 14))]) ! 6023: (set (pc) ! 6024: (label_ref (match_operand 2 "" "")))] ! 6025: "GET_CODE (operands[0]) == SYMBOL_REF ! 6026: && short_branch (INSN_UID (insn), INSN_UID (operands[2])) ! 6027: && arm_insn_not_targeted (insn)" ! 6028: "* ! 6029: { ! 6030: int backward = arm_backwards_branch (INSN_UID (insn), ! 6031: INSN_UID (operands[2])); ! 6032: ! 6033: #if 0 ! 6034: /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or ! 6035: * above, leaving it out means that the code will still run on an arm 2 or 3 ! 6036: */ ! 6037: if (TARGET_6) ! 6038: { ! 6039: if (backward) ! 6040: arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l2)\", operands); ! 6041: else ! 6042: arm_output_asm_insn (\"add\\tlr, pc, #(%l2 - . -8)\", operands); ! 6043: } ! 6044: else ! 6045: #endif ! 6046: { ! 6047: arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\"); ! 6048: if (backward) ! 6049: arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l2)\", operands); ! 6050: else ! 6051: arm_output_asm_insn (\"add\\tlr, lr, #(%l2 - . -4)\", operands); ! 6052: } ! 6053: return arm_output_asm_insn (\"b\\t%a0\", operands); ! 6054: }" ! 6055: [(set (attr "conds") ! 6056: (if_then_else (eq_attr "cpu" "arm6") ! 6057: (const_string "clob") ! 6058: (const_string "nocond"))) ! 6059: (set (attr "length") ! 6060: (if_then_else (eq_attr "cpu" "arm6") ! 6061: (const_int 2) ! 6062: (const_int 3)))]) ! 6063: ! 6064: (define_peephole ! 6065: [(parallel[(set (match_operand:SI 0 "s_register_operand" "=r") ! 6066: (call (mem:SI (match_operand:SI 1 "" "i")) ! 6067: (match_operand:SI 2 "general_operand" "g"))) ! 6068: (clobber (reg:SI 14))]) ! 6069: (set (pc) ! 6070: (label_ref (match_operand 3 "" "")))] ! 6071: "GET_CODE (operands[0]) == SYMBOL_REF ! 6072: && short_branch (INSN_UID (insn), INSN_UID (operands[3])) ! 6073: && arm_insn_not_targeted (insn)" ! 6074: "* ! 6075: { ! 6076: int backward = arm_backwards_branch (INSN_UID (insn), ! 6077: INSN_UID (operands[3])); ! 6078: ! 6079: #if 0 ! 6080: /* Putting this in means that TARGET_6 code will ONLY run on an arm6 or ! 6081: * above, leaving it out means that the code will still run on an arm 2 or 3 ! 6082: */ ! 6083: if (TARGET_6) ! 6084: { ! 6085: if (backward) ! 6086: arm_output_asm_insn (\"sub\\tlr, pc, #(8 + . -%l3)\", operands); ! 6087: else ! 6088: arm_output_asm_insn (\"add\\tlr, pc, #(%l3 - . -8)\", operands); ! 6089: } ! 6090: else ! 6091: #endif ! 6092: { ! 6093: arm_output_asm_insn (\"mov\\tlr, pc\\t@ protect cc\"); ! 6094: if (backward) ! 6095: arm_output_asm_insn (\"sub\\tlr, lr, #(4 + . -%l3)\", operands); ! 6096: else ! 6097: arm_output_asm_insn (\"add\\tlr, lr, #(%l3 - . -4)\", operands); ! 6098: } ! 6099: return arm_output_asm_insn (\"b\\t%a1\", operands); ! 6100: }" ! 6101: [(set (attr "conds") ! 6102: (if_then_else (eq_attr "cpu" "arm6") ! 6103: (const_string "clob") ! 6104: (const_string "nocond"))) ! 6105: (set (attr "length") ! 6106: (if_then_else (eq_attr "cpu" "arm6") ! 6107: (const_int 2) ! 6108: (const_int 3)))]) ! 6109: ! 6110: (define_split ! 6111: [(set (pc) ! 6112: (if_then_else (match_operator 0 "comparison_operator" ! 6113: [(match_operator:SI 1 "shift_operator" ! 6114: [(match_operand:SI 2 "s_register_operand" "r") ! 6115: (match_operand:SI 3 "nonmemory_operand" "rn")]) ! 6116: (match_operand:SI 4 "s_register_operand" "r")]) ! 6117: (label_ref (match_operand 5 "" "")) ! 6118: (pc))) ! 6119: (clobber (reg 24))] ! 6120: "" ! 6121: [(set (reg:CC 24) ! 6122: (compare:CC (match_dup 4) ! 6123: (match_op_dup 1 [(match_dup 2) (match_dup 3)]))) ! 6124: (set (pc) ! 6125: (if_then_else (match_op_dup 0 [(reg 24) (const_int 0)]) ! 6126: (label_ref (match_dup 5)) ! 6127: (pc)))] ! 6128: " ! 6129: operands[0] = gen_rtx (swap_condition (GET_CODE (operands[0])), VOIDmode, ! 6130: operands[1], operands[2]); ! 6131: ") ! 6132: ! 6133: (define_split ! 6134: [(set (match_operand:SI 0 "s_register_operand" "") ! 6135: (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") ! 6136: (const_int 0)) ! 6137: (neg:SI (match_operator:SI 2 "comparison_operator" ! 6138: [(match_operand:SI 3 "s_register_operand" "") ! 6139: (match_operand:SI 4 "arm_rhs_operand" "")])))) ! 6140: (clobber (match_operand:SI 5 "s_register_operand" ""))] ! 6141: "" ! 6142: [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) ! 6143: (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) ! 6144: (match_dup 5)))] ! 6145: "") ! 6146: ! 6147: ;; This pattern can be used because cc_noov mode implies that the following ! 6148: ;; branch will be an equality (EQ or NE), so the sign extension is not ! 6149: ;; needed. Combine doesn't eliminate these because by the time it sees the ! 6150: ;; branch it no-longer knows that the data came from memory. ! 6151: ! 6152: (define_insn "" ! 6153: [(set (reg:CC_NOOV 24) ! 6154: (compare:CC_NOOV ! 6155: (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "m") 0) ! 6156: (const_int 24)) ! 6157: (match_operand 1 "immediate_operand" "I"))) ! 6158: (clobber (match_scratch:SI 2 "=r"))] ! 6159: "((unsigned long) INTVAL (operands[1])) ! 6160: == (((unsigned long) INTVAL (operands[1])) >> 24) << 24" ! 6161: "* ! 6162: operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); ! 6163: arm_output_asm_insn (\"ldrb\\t%2, %0\", operands); ! 6164: return arm_output_asm_insn (\"cmp\\t%2, %1\", operands); ! 6165: " ! 6166: [(set_attr "conds" "set") ! 6167: (set_attr "length" "2") ! 6168: (set_attr "type" "load")]) ! 6169: ! 6170: (define_expand "save_stack_nonlocal" ! 6171: [(match_operand:DI 0 "memory_operand" "") ! 6172: (match_operand:SI 1 "s_register_operand" "")] ! 6173: "" ! 6174: " ! 6175: { ! 6176: /* We also need to save the frame pointer for non-local gotos */ ! 6177: emit_move_insn (operand_subword (operands[0], 0, 0, DImode), ! 6178: hard_frame_pointer_rtx); ! 6179: emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]); ! 6180: DONE; ! 6181: }") ! 6182: ! 6183: (define_expand "restore_stack_nonlocal" ! 6184: [(match_operand:SI 0 "s_register_operand" "") ! 6185: (match_operand:DI 1 "memory_operand" "")] ! 6186: "" ! 6187: " ! 6188: { ! 6189: /* Restore the frame pointer first, the stack pointer second. */ ! 6190: emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode)); ! 6191: emit_move_insn (hard_frame_pointer_rtx, operand_subword (operands[1], 0, 0, ! 6192: DImode)); ! 6193: DONE; ! 6194: }") ! 6195: ! 6196: ;; This split is only used during output to reduce the number of patterns ! 6197: ;; that need assembler instructions adding to them. We allowed the setting ! 6198: ;; of the conditions to be implicit during rtl generation so that ! 6199: ;; the conditional compare patterns would work. However this conflicts to ! 6200: ;; some extend with the conditional data operations, so we have to split them ! 6201: ;; up again here. ! 6202: ! 6203: (define_split ! 6204: [(set (match_operand:SI 0 "s_register_operand" "") ! 6205: (if_then_else:SI (match_operator 1 "comparison_operator" ! 6206: [(match_operand 2 "" "") (match_operand 3 "" "")]) ! 6207: (match_operand 4 "" "") ! 6208: (match_operand 5 "" ""))) ! 6209: (clobber (reg 24))] ! 6210: "reload_completed" ! 6211: [(set (match_dup 6) (match_dup 7)) ! 6212: (set (match_dup 0) ! 6213: (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)]) ! 6214: (match_dup 4) ! 6215: (match_dup 5)))] ! 6216: " ! 6217: { ! 6218: enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2], ! 6219: operands[3]); ! 6220: ! 6221: operands[6] = gen_rtx (REG, mode, 24); ! 6222: operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]); ! 6223: } ! 6224: ") ! 6225: ! 6226: ! 6227: (define_insn "" ! 6228: [(set (match_operand:SI 0 "s_register_operand" "=r,r") ! 6229: (if_then_else:SI (match_operator 4 "comparison_operator" ! 6230: [(match_operand 3 "cc_register" "") (const_int 0)]) ! 6231: (match_operand:SI 1 "arm_rhs_operand" "0,?rI") ! 6232: (not:SI ! 6233: (match_operand:SI 2 "s_register_operand" "r,r"))))] ! 6234: "" ! 6235: "* ! 6236: if (which_alternative != 0) ! 6237: arm_output_asm_insn (\"mov%d4\\t%0, %1\", operands); ! 6238: return arm_output_asm_insn (\"mvn%D4\\t%0, %2\", operands); ! 6239: " ! 6240: [(set_attr "conds" "use") ! 6241: (set_attr "length" "1,2")]) ! 6242: ! 6243: ;; The next two patterns occur when an AND operation is followed by a ! 6244: ;; scc insn sequence ! 6245: ! 6246: (define_insn "" ! 6247: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 6248: (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") ! 6249: (const_int 1) ! 6250: (match_operand:SI 2 "immediate_operand" "n")))] ! 6251: "" ! 6252: "* ! 6253: operands[2] = GEN_INT (1 << INTVAL (operands[2])); ! 6254: arm_output_asm_insn (\"ands\\t%0, %1, %2\", operands); ! 6255: return arm_output_asm_insn (\"mvnne\\t%0, #0\", operands); ! 6256: " ! 6257: [(set_attr "conds" "clob") ! 6258: (set_attr "length" "2")]) ! 6259: ! 6260: (define_insn "" ! 6261: [(set (match_operand:SI 0 "s_register_operand" "=r") ! 6262: (not:SI ! 6263: (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") ! 6264: (const_int 1) ! 6265: (match_operand:SI 2 "immediate_operand" "n"))))] ! 6266: "" ! 6267: "* ! 6268: operands[2] = GEN_INT (1 << INTVAL (operands[2])); ! 6269: arm_output_asm_insn (\"tst\\t%1, %2\", operands); ! 6270: arm_output_asm_insn (\"mvneq\\t%0, #0\", operands); ! 6271: return arm_output_asm_insn (\"movne\\t%0, #0\", operands); ! 6272: " ! 6273: [(set_attr "conds" "clob") ! 6274: (set_attr "length" "3")])
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.