Annotation of gcc/config/sparc.md, revision 1.1.1.3

1.1       root        1: ;;- Machine description for SPARC chip for GNU C compiler
                      2: ;;   Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
                      3: ;;   Contributed by Michael Tiemann ([email protected])
                      4: 
                      5: ;; This file is part of GNU CC.
                      6: 
                      7: ;; GNU CC is free software; you can redistribute it and/or modify
                      8: ;; it under the terms of the GNU General Public License as published by
                      9: ;; the Free Software Foundation; either version 2, or (at your option)
                     10: ;; any later version.
                     11: 
                     12: ;; GNU CC is distributed in the hope that it will be useful,
                     13: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: ;; GNU General Public License for more details.
                     16: 
                     17: ;; You should have received a copy of the GNU General Public License
                     18: ;; along with GNU CC; see the file COPYING.  If not, write to
                     19: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: 
                     21: 
                     22: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
                     23: 
                     24: ;; Insn type.  Used to default other attribute values.
                     25: 
                     26: ;; type "unary" insns have one input operand (1) and one output operand (0)
                     27: ;; type "binary" insns have two input operands (1,2) and one output (0)
                     28: ;; type "compare" insns have one or two input operands (0,1) and no output
                     29: ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
                     30: 
                     31: (define_attr "type"
                     32:   "move,unary,binary,compare,load,store,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
                     33:   (const_string "binary"))
                     34: 
                     35: ;; Set true if insn uses call-clobbered intermediate register.
                     36: (define_attr "use_clobbered" "false,true"
                     37:   (if_then_else (and (eq_attr "type" "address")
                     38:                     (match_operand 0 "clobbered_register" ""))
                     39:                (const_string "true")
                     40:                (const_string "false")))
                     41: 
                     42: ;; Length (in # of insns).
                     43: (define_attr "length" ""
                     44:   (cond [(eq_attr "type" "load,fpload")
                     45:         (if_then_else (match_operand 1 "symbolic_memory_operand" "")
                     46:                       (const_int 2) (const_int 1))
                     47: 
                     48:         (eq_attr "type" "store,fpstore")
                     49:         (if_then_else (match_operand 0 "symbolic_memory_operand" "")
                     50:                       (const_int 2) (const_int 1))
                     51: 
                     52:         (eq_attr "type" "address") (const_int 2)
                     53: 
                     54:         (eq_attr "type" "binary")
                     55:         (if_then_else (ior (match_operand 2 "arith_operand" "")
                     56:                            (match_operand 2 "arith_double_operand" ""))
                     57:                       (const_int 1) (const_int 3))
                     58: 
1.1.1.2   root       59:         (eq_attr "type" "multi") (const_int 2)
                     60: 
1.1       root       61:         (eq_attr "type" "move,unary")
                     62:         (if_then_else (ior (match_operand 1 "arith_operand" "")
                     63:                            (match_operand 1 "arith_double_operand" ""))
                     64:                       (const_int 1) (const_int 2))]
                     65: 
                     66:        (const_int 1)))
                     67: 
                     68: (define_asm_attributes
                     69:   [(set_attr "length" "1")
                     70:    (set_attr "type" "multi")])
                     71: 
                     72: ;; Attributes for instruction and branch scheduling
                     73: 
                     74: (define_attr "in_call_delay" "false,true"
                     75:   (cond [(eq_attr "type" "branch,call,call_no_delay_slot,multi")
                     76:                (const_string "false")
                     77:         (eq_attr "type" "load,fpload,store,fpstore")
                     78:                (if_then_else (eq_attr "length" "1")
                     79:                              (const_string "true")
                     80:                              (const_string "false"))
                     81:         (eq_attr "type" "address")
                     82:                (if_then_else (eq_attr "use_clobbered" "false")
                     83:                              (const_string "true")
                     84:                              (const_string "false"))]
                     85:        (if_then_else (eq_attr "length" "1")
                     86:                      (const_string "true")
                     87:                      (const_string "false"))))
                     88: 
                     89: (define_delay (eq_attr "type" "call")
                     90:   [(eq_attr "in_call_delay" "true") (nil) (nil)])
                     91: 
                     92: ;; ??? Should implement the notion of predelay slots for floating point
                     93: ;; branches.  This would allow us to remove the nop always inserted before
                     94: ;; a floating point branch.
                     95: 
                     96: (define_attr "in_branch_delay" "false,true"
                     97:   (if_then_else (and (eq_attr "type" "!branch,call,call_no_delay_slot,multi")
                     98:                     (eq_attr "length" "1"))
                     99:                (const_string "true")
                    100:                (const_string "false")))
                    101: 
                    102: (define_delay (eq_attr "type" "branch")
                    103:   [(eq_attr "in_branch_delay" "true")
                    104:    (nil) (eq_attr "in_branch_delay" "true")])
                    105: 
                    106: ;; Function units of the SPARC
                    107: 
                    108: ;; (define_function_unit {name} {num-units} {n-users} {test}
                    109: ;;                       {ready-delay} {busy-delay} [{conflict-list}])
                    110: 
                    111: ;; The integer ALU.
                    112: ;; (Noted only for documentation; units that take one cycle do not need to
                    113: ;; be specified.)
                    114: 
                    115: ;; (define_function_unit "alu" 1 0
                    116: ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
                    117: 
                    118: ;; Memory with load-delay of 1 (i.e., 2 cycle load).
                    119: (define_function_unit "memory" 1 0 (eq_attr "type" "load,fpload") 2 0)
                    120: 
                    121: ;; SPARC has two floating-point units: the FP ALU,
                    122: ;; and the FP MUL/DIV/SQRT unit.
                    123: ;; Instruction timings on the CY7C602 are as follows
                    124: ;; FABSs       4
                    125: ;; FADDs/d     5/5
                    126: ;; FCMPs/d     4/4
                    127: ;; FDIVs/d     23/37
                    128: ;; FMOVs       4
                    129: ;; FMULs/d     5/7
                    130: ;; FNEGs       4
                    131: ;; FSQRTs/d    34/63
                    132: ;; FSUBs/d     5/5
                    133: ;; FdTOi/s     5/5
                    134: ;; FsTOi/d     5/5
                    135: ;; FiTOs/d     9/5
                    136: 
                    137: ;; The CY7C602 can only support 2 fp isnsn simultaneously.
1.1.1.3 ! root      138: ;; More insns cause the chip to stall.
        !           139: 
        !           140: (define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 5 0)
        !           141: (define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 7 0)
        !           142: (define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 37 0)
        !           143: (define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 63 0)
1.1       root      144: 
                    145: ;; Compare instructions.
                    146: ;; This controls RTL generation and register allocation.
                    147: 
                    148: ;; We generate RTL for comparisons and branches by having the cmpxx 
                    149: ;; patterns store away the operands.  Then, the scc and bcc patterns
                    150: ;; emit RTL for both the compare and the branch.
                    151: ;;
                    152: ;; We do this because we want to generate different code for an sne and
                    153: ;; seq insn.  In those cases, if the second operand of the compare is not
                    154: ;; const0_rtx, we want to compute the xor of the two operands and test
                    155: ;; it against zero.
                    156: ;;
                    157: ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
                    158: ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
                    159: ;; insns that actually require more than one machine instruction.
                    160: 
                    161: ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
                    162: 
                    163: (define_expand "cmpsi"
                    164:   [(set (reg:CC 0)
                    165:        (compare:CC (match_operand:SI 0 "register_operand" "")
                    166:                    (match_operand:SI 1 "arith_operand" "")))]
                    167:   ""
                    168:   "
                    169: {
                    170:   sparc_compare_op0 = operands[0];
                    171:   sparc_compare_op1 = operands[1];
                    172:   DONE;
                    173: }")
                    174: 
                    175: (define_expand "cmpsf"
                    176:   [(set (reg:CCFP 0)
                    177:        (compare:CCFP (match_operand:SF 0 "register_operand" "")
                    178:                      (match_operand:SF 1 "register_operand" "")))]
                    179:   ""
                    180:   "
                    181: {
                    182:   sparc_compare_op0 = operands[0];
                    183:   sparc_compare_op1 = operands[1];
                    184:   DONE;
                    185: }")
                    186: 
                    187: (define_expand "cmpdf"
                    188:   [(set (reg:CCFP 0)
                    189:        (compare:CCFP (match_operand:DF 0 "register_operand" "")
                    190:                      (match_operand:DF 1 "register_operand" "")))]
                    191:   ""
                    192:   "
                    193: {
                    194:   sparc_compare_op0 = operands[0];
                    195:   sparc_compare_op1 = operands[1];
                    196:   DONE;
                    197: }")
                    198: 
1.1.1.3 ! root      199: (define_expand "cmptf"
        !           200:   [(set (reg:CCFP 0)
        !           201:        (compare:CCFP (match_operand:TF 0 "register_operand" "")
        !           202:                      (match_operand:TF 1 "register_operand" "")))]
        !           203:   ""
        !           204:   "
        !           205: {
        !           206:   sparc_compare_op0 = operands[0];
        !           207:   sparc_compare_op1 = operands[1];
        !           208:   DONE;
        !           209: }")
        !           210: 
1.1       root      211: ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
                    212: ;; without jumps using the addx/subx instructions.  For the rest, we do
                    213: ;; branches.  Seq_special and sne_special clobber the CC reg, because they
                    214: ;; generate addcc/subcc instructions.
                    215: 
                    216: (define_expand "seq_special"
                    217:   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
                    218:                              (match_operand:SI 2 "register_operand" "")))
                    219:    (parallel [(set (match_operand:SI 0 "register_operand" "")
                    220:                   (eq:SI (match_dup 3) (const_int 0)))
                    221:              (clobber (reg:CC 0))])]
                    222:             
                    223:   ""
                    224:   "{ operands[3] = gen_reg_rtx (SImode); }")
                    225: 
                    226: (define_expand "sne_special"
                    227:   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
                    228:                              (match_operand:SI 2 "register_operand" "")))
                    229:    (parallel [(set (match_operand:SI 0 "register_operand" "")
                    230:                   (ne:SI (match_dup 3) (const_int 0)))
                    231:              (clobber (reg:CC 0))])]
                    232:   ""
                    233:   "{ operands[3] = gen_reg_rtx (SImode); }")
                    234: 
                    235: (define_expand "seq"
                    236:   [(set (match_operand:SI 0 "register_operand" "")
                    237:        (eq:SI (match_dup 1) (const_int 0)))]
                    238:   ""
                    239:   "
                    240: { if (GET_MODE (sparc_compare_op0) == SImode)
                    241:     {
                    242:       emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
                    243:                                  sparc_compare_op1));
                    244:       DONE;
                    245:     }
                    246:   else
                    247:     operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
                    248: }")
                    249: 
                    250: (define_expand "sne"
                    251:   [(set (match_operand:SI 0 "register_operand" "")
                    252:        (ne:SI (match_dup 1) (const_int 0)))]
                    253:   ""
                    254:   "
                    255: { if (GET_MODE (sparc_compare_op0) == SImode)
                    256:     {
                    257:       emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
                    258:                                  sparc_compare_op1));
                    259:       DONE;
                    260:     }
                    261:   else
                    262:     operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
                    263: }")
                    264: 
                    265: (define_expand "sgt"
                    266:   [(set (match_operand:SI 0 "register_operand" "")
                    267:        (gt:SI (match_dup 1) (const_int 0)))]
                    268:   ""
                    269:   "
                    270: { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
                    271: 
                    272: (define_expand "slt"
                    273:   [(set (match_operand:SI 0 "register_operand" "")
                    274:        (lt:SI (match_dup 1) (const_int 0)))]
                    275:   ""
                    276:   "
                    277: { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
                    278: 
                    279: (define_expand "sge"
                    280:   [(set (match_operand:SI 0 "register_operand" "")
                    281:        (ge:SI (match_dup 1) (const_int 0)))]
                    282:   ""
                    283:   "
                    284: { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
                    285: 
                    286: (define_expand "sle"
                    287:   [(set (match_operand:SI 0 "register_operand" "")
                    288:        (le:SI (match_dup 1) (const_int 0)))]
                    289:   ""
                    290:   "
                    291: { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
                    292: 
                    293: (define_expand "sgtu"
                    294:   [(set (match_operand:SI 0 "register_operand" "")
                    295:        (gtu:SI (match_dup 1) (const_int 0)))]
                    296:   ""
                    297:   "
                    298: {
                    299:   rtx tem;
                    300: 
                    301:   /* We can do ltu easily, so if both operands are registers, swap them and
                    302:      do a LTU.  */
                    303:   if ((GET_CODE (sparc_compare_op0) == REG
                    304:        || GET_CODE (sparc_compare_op0) == SUBREG)
                    305:       && (GET_CODE (sparc_compare_op1) == REG
                    306:          || GET_CODE (sparc_compare_op1) == SUBREG))
                    307:     {
                    308:       tem = sparc_compare_op0;
                    309:       sparc_compare_op0 = sparc_compare_op1;
                    310:       sparc_compare_op1 = tem;
                    311:       emit_insn (gen_sltu (operands[0]));
                    312:       DONE;
                    313:     }
                    314: 
                    315:   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
                    316: }")
                    317: 
                    318: (define_expand "sltu"
                    319:   [(set (match_operand:SI 0 "register_operand" "")
                    320:        (ltu:SI (match_dup 1) (const_int 0)))]
                    321:   ""
                    322:   "
                    323: { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
                    324: }")
                    325: 
                    326: (define_expand "sgeu"
                    327:   [(set (match_operand:SI 0 "register_operand" "")
                    328:        (geu:SI (match_dup 1) (const_int 0)))]
                    329:   ""
                    330:   "
                    331: { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
                    332: }")
                    333: 
                    334: (define_expand "sleu"
                    335:   [(set (match_operand:SI 0 "register_operand" "")
                    336:        (leu:SI (match_dup 1) (const_int 0)))]
                    337:   ""
                    338:   "
                    339: {
                    340:   rtx tem;
                    341: 
                    342:   /* We can do geu easily, so if both operands are registers, swap them and
                    343:      do a GEU.  */
                    344:   if ((GET_CODE (sparc_compare_op0) == REG
                    345:        || GET_CODE (sparc_compare_op0) == SUBREG)
                    346:       && (GET_CODE (sparc_compare_op1) == REG
                    347:          || GET_CODE (sparc_compare_op1) == SUBREG))
                    348:     {
                    349:       tem = sparc_compare_op0;
                    350:       sparc_compare_op0 = sparc_compare_op1;
                    351:       sparc_compare_op1 = tem;
                    352:       emit_insn (gen_sgeu (operands[0]));
                    353:       DONE;
                    354:     }
                    355: 
                    356:   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
                    357: }")
                    358: 
                    359: ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
                    360: 
                    361: (define_insn ""
                    362:   [(set (reg:CC 0)
                    363:        (compare:CC (match_operand:SI 0 "register_operand" "rJ")
                    364:                    (match_operand:SI 1 "arith_operand" "rI")))]
                    365:   ""
                    366:   "cmp %r0,%1"
                    367:   [(set_attr "type" "compare")])
                    368: 
                    369: (define_insn ""
1.1.1.3 ! root      370:   [(set (reg:CCFPE 0)
        !           371:        (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
        !           372:                       (match_operand:DF 1 "register_operand" "f")))]
        !           373:   ""
        !           374:   "fcmped %0,%1"
        !           375:   [(set_attr "type" "fpcmp")])
        !           376: 
        !           377: (define_insn ""
        !           378:   [(set (reg:CCFPE 0)
        !           379:        (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
        !           380:                       (match_operand:SF 1 "register_operand" "f")))]
        !           381:   ""
        !           382:   "fcmpes %0,%1"
        !           383:   [(set_attr "type" "fpcmp")])
        !           384: 
        !           385: (define_insn ""
        !           386:   [(set (reg:CCFPE 0)
        !           387:        (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
        !           388:                       (match_operand:TF 1 "register_operand" "f")))]
        !           389:   ""
        !           390:   "fcmpeq %0,%1"
        !           391:   [(set_attr "type" "fpcmp")])
        !           392: 
        !           393: (define_insn ""
1.1       root      394:   [(set (reg:CCFP 0)
                    395:        (compare:CCFP (match_operand:DF 0 "register_operand" "f")
                    396:                      (match_operand:DF 1 "register_operand" "f")))]
                    397:   ""
1.1.1.3 ! root      398:   "fcmpd %0,%1"
1.1       root      399:   [(set_attr "type" "fpcmp")])
                    400: 
                    401: (define_insn ""
                    402:   [(set (reg:CCFP 0)
                    403:        (compare:CCFP (match_operand:SF 0 "register_operand" "f")
                    404:                      (match_operand:SF 1 "register_operand" "f")))]
                    405:   ""
1.1.1.3 ! root      406:   "fcmps %0,%1"
        !           407:   [(set_attr "type" "fpcmp")])
        !           408: 
        !           409: (define_insn ""
        !           410:   [(set (reg:CCFP 0)
        !           411:        (compare:CCFP (match_operand:TF 0 "register_operand" "f")
        !           412:                      (match_operand:TF 1 "register_operand" "f")))]
        !           413:   ""
        !           414:   "fcmpq %0,%1"
1.1       root      415:   [(set_attr "type" "fpcmp")])
                    416: 
                    417: ;; The SEQ and SNE patterns are special because they can be done
                    418: ;; without any branching and do not involve a COMPARE.
                    419: 
                    420: (define_insn ""
                    421:   [(set (match_operand:SI 0 "register_operand" "=r")
                    422:        (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
                    423:    (clobber (reg:CC 0))]
                    424:   ""
                    425:   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
                    426:   [(set_attr "type" "unary")
                    427:    (set_attr "length" "2")])
                    428: 
                    429: (define_insn ""
                    430:   [(set (match_operand:SI 0 "register_operand" "=r")
                    431:        (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
                    432:                       (const_int 0))))
                    433:    (clobber (reg:CC 0))]
                    434:   ""
                    435:   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
                    436:   [(set_attr "type" "unary")
                    437:    (set_attr "length" "2")])
                    438: 
                    439: (define_insn ""
                    440:   [(set (match_operand:SI 0 "register_operand" "=r")
                    441:        (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
                    442:    (clobber (reg:CC 0))]
                    443:   ""
                    444:   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
                    445:   [(set_attr "type" "unary")
                    446:    (set_attr "length" "2")])
                    447: 
                    448: (define_insn ""
                    449:   [(set (match_operand:SI 0 "register_operand" "=r")
                    450:        (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
                    451:                       (const_int 0))))
                    452:    (clobber (reg:CC 0))]
                    453:   ""
                    454:   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
                    455:   [(set_attr "type" "unary")
                    456:    (set_attr "length" "2")])
                    457: 
                    458: ;; We can also do (x + (i == 0)) and related, so put them in.
                    459: 
                    460: (define_insn ""
                    461:   [(set (match_operand:SI 0 "register_operand" "=r")
                    462:        (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
                    463:                        (const_int 0))
                    464:                 (match_operand:SI 2 "register_operand" "r")))
                    465:    (clobber (reg:CC 0))]
                    466:   ""
                    467:   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
                    468:   [(set_attr "length" "2")])
                    469: 
                    470: (define_insn ""
                    471:   [(set (match_operand:SI 0 "register_operand" "=r")
                    472:        (minus:SI (match_operand:SI 2 "register_operand" "r")
                    473:                  (ne:SI (match_operand:SI 1 "register_operand" "r")
                    474:                         (const_int 0))))
                    475:    (clobber (reg:CC 0))]
                    476:   ""
                    477:   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
                    478:   [(set_attr "length" "2")])
                    479: 
                    480: (define_insn ""
                    481:   [(set (match_operand:SI 0 "register_operand" "=r")
                    482:        (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
                    483:                        (const_int 0))
                    484:                 (match_operand:SI 2 "register_operand" "r")))
                    485:    (clobber (reg:CC 0))]
                    486:   ""
                    487:   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
                    488:   [(set_attr "length" "2")])
                    489: 
                    490: (define_insn ""
                    491:   [(set (match_operand:SI 0 "register_operand" "=r")
                    492:        (minus:SI (match_operand:SI 2 "register_operand" "r")
                    493:                  (eq:SI (match_operand:SI 1 "register_operand" "r")
                    494:                         (const_int 0))))
                    495:    (clobber (reg:CC 0))]
                    496:   ""
                    497:   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
1.1.1.2   root      498:   [(set_attr "length" "2")])
1.1       root      499: 
                    500: ;; We can also do GEU and LTU directly, but these operate after a
                    501: ;; compare.
                    502: 
                    503: (define_insn ""
                    504:   [(set (match_operand:SI 0 "register_operand" "=r")
                    505:        (ltu:SI (reg:CC 0) (const_int 0)))]
                    506:   ""
                    507:   "addx %%g0,0,%0"
                    508:   [(set_attr "type" "misc")])
                    509: 
                    510: (define_insn ""
                    511:   [(set (match_operand:SI 0 "register_operand" "=r")
                    512:        (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
                    513:   ""
                    514:   "subx %%g0,0,%0"
                    515:   [(set_attr "type" "misc")])
                    516: 
                    517: ;; ??? Combine should canonicalize these next two to the same pattern.
                    518: (define_insn ""
                    519:   [(set (match_operand:SI 0 "register_operand" "=r")
                    520:        (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
                    521:                  (match_operand:SI 1 "arith_operand" "rI")))]
                    522:   ""
                    523:   "subx %%g0,%1,%0"
                    524:   [(set_attr "type" "unary")])
                    525: 
                    526: (define_insn ""
                    527:   [(set (match_operand:SI 0 "register_operand" "=r")
                    528:        (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
                    529:                         (match_operand:SI 1 "arith_operand" "rI"))))]
                    530:   ""
                    531:   "subx %%g0,%1,%0"
                    532:   [(set_attr "type" "unary")])
                    533: 
                    534: (define_insn ""
                    535:   [(set (match_operand:SI 0 "register_operand" "=r")
                    536:        (geu:SI (reg:CC 0) (const_int 0)))]
                    537:   ""
                    538:   "subx %%g0,-1,%0"
                    539:   [(set_attr "type" "misc")])
                    540: 
                    541: (define_insn ""
                    542:   [(set (match_operand:SI 0 "register_operand" "=r")
                    543:        (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
                    544:   ""
                    545:   "addx %%g0,-1,%0"
                    546:   [(set_attr "type" "misc")])
                    547: 
                    548: ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
                    549: 
                    550: (define_insn ""
                    551:   [(set (match_operand:SI 0 "register_operand" "=r")
                    552:        (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
                    553:                 (match_operand:SI 1 "arith_operand" "rI")))]
                    554:   ""
                    555:   "addx %%g0,%1,%0"
                    556:   [(set_attr "type" "unary")])
                    557: 
                    558: (define_insn ""
                    559:   [(set (match_operand:SI 0 "register_operand" "=r")
                    560:        (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
                    561:                 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                    562:                          (match_operand:SI 2 "arith_operand" "rI"))))]
                    563:   ""
1.1.1.2   root      564:   "addx %1,%2,%0")
1.1       root      565: 
                    566: (define_insn ""
                    567:   [(set (match_operand:SI 0 "register_operand" "=r")
                    568:        (minus:SI (match_operand:SI 1 "register_operand" "r")
                    569:                  (ltu:SI (reg:CC 0) (const_int 0))))]
                    570:   ""
                    571:   "subx %1,0,%0"
                    572:   [(set_attr "type" "unary")])
                    573: 
                    574: ;; ??? Combine should canonicalize these next two to the same pattern.
                    575: (define_insn ""
                    576:   [(set (match_operand:SI 0 "register_operand" "=r")
                    577:        (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
                    578:                            (match_operand:SI 2 "arith_operand" "rI"))
                    579:                  (ltu:SI (reg:CC 0) (const_int 0))))]
                    580:   ""
1.1.1.2   root      581:   "subx %1,%2,%0")
1.1       root      582: 
                    583: (define_insn ""
                    584:   [(set (match_operand:SI 0 "register_operand" "=r")
                    585:        (minus:SI (match_operand:SI 1 "register_operand" "r")
                    586:                  (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
                    587:                           (match_operand:SI 2 "arith_operand" "rI"))))]
                    588:   ""
1.1.1.2   root      589:   "subx %1,%2,%0")
1.1       root      590: 
                    591: (define_insn ""
                    592:   [(set (match_operand:SI 0 "register_operand" "=r")
                    593:        (plus:SI (geu:SI (reg:CC 0) (const_int 0))
                    594:                 (match_operand:SI 1 "register_operand" "r")))]
                    595:   ""
                    596:   "subx %1,-1,%0"
                    597:   [(set_attr "type" "unary")])
                    598: 
                    599: (define_insn ""
                    600:   [(set (match_operand:SI 0 "register_operand" "=r")
                    601:        (minus:SI (match_operand:SI 1 "register_operand" "r")
                    602:                  (geu:SI (reg:CC 0) (const_int 0))))]
                    603:   ""
                    604:   "addx %1,-1,%0"
                    605:   [(set_attr "type" "unary")])
                    606: 
                    607: ;; Now we have the generic scc insns.  These will be done using a jump.
                    608: ;; We have to exclude the cases above, since we will not want combine to
                    609: ;; turn something that does not require a jump into something that does.
                    610: (define_insn ""
                    611:   [(set (match_operand:SI 0 "register_operand" "=r")
                    612:        (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))]
                    613:   ""
                    614:   "* return output_scc_insn (operands, insn); "
1.1.1.2   root      615:   [(set_attr "type" "multi")
                    616:    (set_attr "length" "3")])
1.1       root      617: 
                    618: ;; These control RTL generation for conditional jump insns
                    619: 
                    620: (define_expand "beq"
                    621:   [(set (pc)
                    622:        (if_then_else (eq (match_dup 1) (const_int 0))
                    623:                      (label_ref (match_operand 0 "" ""))
                    624:                      (pc)))]
                    625:   ""
                    626:   "
                    627: { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
                    628: 
                    629: (define_expand "bne"
                    630:   [(set (pc)
                    631:        (if_then_else (ne (match_dup 1) (const_int 0))
                    632:                      (label_ref (match_operand 0 "" ""))
                    633:                      (pc)))]
                    634:   ""
                    635:   "
                    636: { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
                    637: 
                    638: (define_expand "bgt"
                    639:   [(set (pc)
                    640:        (if_then_else (gt (match_dup 1) (const_int 0))
                    641:                      (label_ref (match_operand 0 "" ""))
                    642:                      (pc)))]
                    643:   ""
                    644:   "
                    645: { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
                    646: 
                    647: (define_expand "bgtu"
                    648:   [(set (pc)
                    649:        (if_then_else (gtu (match_dup 1) (const_int 0))
                    650:                      (label_ref (match_operand 0 "" ""))
                    651:                      (pc)))]
                    652:   ""
                    653:   "
                    654: { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
                    655: }")
                    656: 
                    657: (define_expand "blt"
                    658:   [(set (pc)
                    659:        (if_then_else (lt (match_dup 1) (const_int 0))
                    660:                      (label_ref (match_operand 0 "" ""))
                    661:                      (pc)))]
                    662:   ""
                    663:   "
                    664: { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
                    665: 
                    666: (define_expand "bltu"
                    667:   [(set (pc)
                    668:        (if_then_else (ltu (match_dup 1) (const_int 0))
                    669:                      (label_ref (match_operand 0 "" ""))
                    670:                      (pc)))]
                    671:   ""
                    672:   "
                    673: { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
                    674: }")
                    675: 
                    676: (define_expand "bge"
                    677:   [(set (pc)
                    678:        (if_then_else (ge (match_dup 1) (const_int 0))
                    679:                      (label_ref (match_operand 0 "" ""))
                    680:                      (pc)))]
                    681:   ""
                    682:   "
                    683: { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
                    684: 
                    685: (define_expand "bgeu"
                    686:   [(set (pc)
                    687:        (if_then_else (geu (match_dup 1) (const_int 0))
                    688:                      (label_ref (match_operand 0 "" ""))
                    689:                      (pc)))]
                    690:   ""
                    691:   "
                    692: { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
                    693: }")
                    694: 
                    695: (define_expand "ble"
                    696:   [(set (pc)
                    697:        (if_then_else (le (match_dup 1) (const_int 0))
                    698:                      (label_ref (match_operand 0 "" ""))
                    699:                      (pc)))]
                    700:   ""
                    701:   "
                    702: { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
                    703: 
                    704: (define_expand "bleu"
                    705:   [(set (pc)
                    706:        (if_then_else (leu (match_dup 1) (const_int 0))
                    707:                      (label_ref (match_operand 0 "" ""))
                    708:                      (pc)))]
                    709:   ""
                    710:   "
                    711: { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
                    712: }")
                    713: 
                    714: ;; Now match both normal and inverted jump.
                    715: 
                    716: (define_insn ""
                    717:   [(set (pc)
                    718:        (if_then_else (match_operator 0 "noov_compare_op"
                    719:                                      [(reg 0) (const_int 0)])
                    720:                      (label_ref (match_operand 1 "" ""))
                    721:                      (pc)))]
                    722:   ""
                    723:   "*
                    724: {
                    725:   return output_cbranch (operands[0], 1, 0,
                    726:                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                    727:                         ! final_sequence);
                    728: }"
                    729:   [(set_attr "type" "branch")])
                    730: 
                    731: (define_insn ""
                    732:   [(set (pc)
                    733:        (if_then_else (match_operator 0 "noov_compare_op"
                    734:                                      [(reg 0) (const_int 0)])
                    735:                      (pc)
                    736:                      (label_ref (match_operand 1 "" ""))))]
                    737:   ""
                    738:   "*
                    739: {
                    740:   return output_cbranch (operands[0], 1, 1,
                    741:                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
                    742:                         ! final_sequence);
                    743: }"
                    744:   [(set_attr "type" "branch")])
                    745: 
                    746: ;; Move instructions
                    747: 
                    748: (define_expand "movsi"
                    749:   [(set (match_operand:SI 0 "general_operand" "")
                    750:        (match_operand:SI 1 "general_operand" ""))]
                    751:   ""
                    752:   "
                    753: {
                    754:   if (emit_move_sequence (operands, SImode, 0))
                    755:     DONE;
                    756: }")
                    757: 
                    758: (define_expand "reload_insi"
                    759:   [(set (match_operand:SI 0 "register_operand" "=r")
                    760:        (match_operand:SI 1 "general_operand" ""))
                    761:    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
                    762:   ""
                    763:   "
                    764: {
                    765:   if (emit_move_sequence (operands, SImode, operands[2]))
                    766:     DONE;
                    767: 
                    768:   /* We don't want the clobber emitted, so handle this ourselves.  */
                    769:   emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
                    770:   DONE;
                    771: }")
                    772: 
                    773: ;; We must support both 'r' and 'f' registers here, because combine may
                    774: ;; convert SFmode hard registers to SImode hard registers when simplifying
                    775: ;; subreg sets.
                    776: 
                    777: ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1.1.1.2   root      778: ;; problems with register allocation.  Reload might try to put an integer
1.1       root      779: ;; in an fp register, or an fp number is an integer register.
                    780: 
                    781: (define_insn ""
                    782:   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,Q,Q,rf")
                    783:        (match_operand:SI 1 "move_operand" "rI,K,Q,!Q,rJ,!f,!fr"))]
                    784:   "register_operand (operands[0], SImode)
                    785:    || register_operand (operands[1], SImode)
                    786:    || operands[1] == const0_rtx"
                    787:   "@
                    788:    mov %1,%0
                    789:    sethi %%hi(%a1),%0
                    790:    ld %1,%0
                    791:    ld %1,%0
                    792:    st %r1,%0
                    793:    st %r1,%0
                    794:    st %r1,[%%fp-4]\;ld [%%fp-4],%0"
1.1.1.2   root      795:   [(set_attr "type" "move,move,load,load,store,store,multi")
                    796:    (set_attr "length" "*,1,*,*,*,*,*")])
1.1       root      797: 
                    798: ;; Special pic pattern, for loading the address of a label into a register.
                    799: ;; It clobbers o7 because the call puts the return address (i.e. pc value)
                    800: ;; there.
                    801: 
                    802: (define_insn ""
                    803:   [(set (match_operand:SI 0 "register_operand" "=r")
                    804:        (match_operand:SI 1 "move_pic_label" "i"))
                    805:    (set (reg:SI 15) (pc))]
                    806:   ""
                    807:   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
                    808:   [(set_attr "type" "multi")
                    809:    (set_attr "length" "4")])
                    810: 
                    811: (define_insn ""
                    812:   [(set (match_operand:DI 0 "register_operand" "=r")
                    813:        (high:DI (match_operand 1 "" "")))]
                    814:   "check_pic (1)"
                    815:   "*
                    816: {
                    817:   rtx op0 = operands[0];
                    818:   rtx op1 = operands[1];
                    819: 
                    820:   if (GET_CODE (op1) == CONST_INT)
                    821:     {
                    822:       operands[0] = operand_subword (op0, 1, 0, DImode);
                    823:       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
                    824: 
                    825:       operands[0] = operand_subword (op0, 0, 0, DImode);
                    826:       if (INTVAL (op1) < 0)
                    827:        output_asm_insn (\"mov -1,%0\", operands);
                    828:       else
                    829:        output_asm_insn (\"mov 0,%0\", operands);
                    830:     }
                    831:   else if (GET_CODE (op1) == CONST_DOUBLE)
                    832:     {
                    833:       operands[0] = operand_subword (op0, 1, 0, DImode);
1.1.1.2   root      834:       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1.1       root      835:       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
                    836: 
                    837:       operands[0] = operand_subword (op0, 0, 0, DImode);
1.1.1.2   root      838:       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1.1       root      839:       output_asm_insn (singlemove_string (operands), operands);
                    840:     }
                    841:   else
                    842:     abort ();
                    843: }"
                    844:   [(set_attr "type" "move")
                    845:    (set_attr "length" "2")])
                    846: 
1.1.1.2   root      847: ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
                    848: ;; confuse them with real addresses.
                    849: (define_insn ""
                    850:   [(set (match_operand:SI 0 "register_operand" "=r")
                    851:        (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
                    852:   "check_pic (1)"
                    853:   "sethi %%hi(%a1),%0"
                    854:   [(set_attr "type" "move")
                    855:    (set_attr "length" "1")])
                    856: 
1.1       root      857: (define_insn ""
                    858:   [(set (match_operand:SI 0 "register_operand" "=r")
                    859:        (high:SI (match_operand 1 "" "")))]
                    860:   "check_pic (1)"
                    861:   "sethi %%hi(%a1),%0"
                    862:   [(set_attr "type" "move")
                    863:    (set_attr "length" "1")])
                    864: 
                    865: (define_insn ""
                    866:   [(set (match_operand:HI 0 "register_operand" "=r")
                    867:        (high:HI (match_operand 1 "" "")))]
                    868:   "check_pic (1)"
                    869:   "sethi %%hi(%a1),%0"
                    870:   [(set_attr "type" "move")
                    871:    (set_attr "length" "1")])
                    872: 
                    873: (define_insn ""
                    874:   [(set (match_operand:DI 0 "register_operand" "=r")
1.1.1.3 ! root      875:        (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1.1       root      876:                   (match_operand:DI 2 "immediate_operand" "in")))]
                    877:   ""
1.1.1.2   root      878:   "*
                    879: {
                    880:   /* Don't output a 64 bit constant, since we can't trust the assembler to
                    881:      handle it correctly.  */
                    882:   if (GET_CODE (operands[2]) == CONST_DOUBLE)
                    883:     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
                    884:   return \"or %R1,%%lo(%a2),%R0\";
                    885: }"
                    886:   ;; Need to set length for this arith insn because operand2
                    887:   ;; is not an "arith_operand".
                    888:   [(set_attr "length" "1")])
                    889: 
                    890: ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
                    891: ;; confuse them with real addresses.
                    892: (define_insn ""
                    893:   [(set (match_operand:SI 0 "register_operand" "=r")
                    894:        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
                    895:                   (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
                    896:   ""
                    897:   "or %1,%%lo(%a2),%0"
1.1       root      898:   ;; Need to set length for this arith insn because operand2
                    899:   ;; is not an "arith_operand".
                    900:   [(set_attr "length" "1")])
                    901: 
                    902: (define_insn ""
                    903:   [(set (match_operand:SI 0 "register_operand" "=r")
                    904:        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
                    905:                   (match_operand:SI 2 "immediate_operand" "in")))]
                    906:   ""
                    907:   "or %1,%%lo(%a2),%0"
                    908:   ;; Need to set length for this arith insn because operand2
                    909:   ;; is not an "arith_operand".
                    910:   [(set_attr "length" "1")])
                    911: 
                    912: (define_insn ""
                    913:   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
                    914:        (match_operand:SI 1 "reg_or_0_operand" "rJ"))
                    915:    (clobber (match_scratch:SI 2 "=&r"))]
                    916:   ""
                    917:   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
                    918:   [(set_attr "type" "store")
                    919:    (set_attr "length" "2")])
                    920: 
                    921: (define_expand "movhi"
                    922:   [(set (match_operand:HI 0 "general_operand" "")
                    923:        (match_operand:HI 1 "general_operand" ""))]
                    924:   ""
                    925:   "
                    926: {
                    927:   if (emit_move_sequence (operands, HImode, 0))
                    928:     DONE;
                    929: }")
                    930: 
                    931: (define_insn ""
                    932:   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
                    933:        (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
                    934:   "register_operand (operands[0], HImode)
                    935:    || register_operand (operands[1], HImode)
                    936:    || operands[1] == const0_rtx"
                    937:   "@
                    938:    mov %1,%0
                    939:    sethi %%hi(%a1),%0
                    940:    lduh %1,%0
                    941:    sth %r1,%0"
                    942:   [(set_attr "type" "move,move,load,store")
                    943:    (set_attr "length" "*,1,*,1")])
                    944: 
                    945: (define_insn ""
                    946:   [(set (match_operand:HI 0 "register_operand" "=r")
                    947:        (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
                    948:                   (match_operand 2 "immediate_operand" "in")))]
                    949:   ""
                    950:   "or %1,%%lo(%a2),%0"
                    951:   [(set_attr "length" "1")])
                    952: 
                    953: (define_insn ""
                    954:   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
                    955:        (match_operand:HI 1 "reg_or_0_operand" "rJ"))
                    956:    (clobber (match_scratch:SI 2 "=&r"))]
                    957:   ""
                    958:   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
                    959:   [(set_attr "type" "store")
                    960:    (set_attr "length" "2")])
                    961: 
                    962: (define_expand "movqi"
                    963:   [(set (match_operand:QI 0 "general_operand" "")
                    964:        (match_operand:QI 1 "general_operand" ""))]
                    965:   ""
                    966:   "
                    967: {
                    968:   if (emit_move_sequence (operands, QImode, 0))
                    969:     DONE;
                    970: }")
                    971: 
                    972: (define_insn ""
                    973:   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
                    974:        (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
                    975:   "register_operand (operands[0], QImode)
                    976:    || register_operand (operands[1], QImode)
                    977:    || operands[1] == const0_rtx"
                    978:   "@
                    979:    mov %1,%0
                    980:    sethi %%hi(%a1),%0
                    981:    ldub %1,%0
                    982:    stb %r1,%0"
                    983:   [(set_attr "type" "move,move,load,store")
                    984:    (set_attr "length" "*,1,*,1")])
                    985: 
                    986: (define_insn ""
                    987:   [(set (match_operand:QI 0 "register_operand" "=r")
                    988:        (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
                    989:                              (match_operand 2 "immediate_operand" "in")) 0))]
                    990:   ""
                    991:   "or %1,%%lo(%a2),%0"
                    992:   [(set_attr "length" "1")])
                    993: 
                    994: (define_insn ""
                    995:   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
                    996:        (match_operand:QI 1 "reg_or_0_operand" "rJ"))
                    997:    (clobber (match_scratch:SI 2 "=&r"))]
                    998:   ""
                    999:   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
                   1000:   [(set_attr "type" "store")
                   1001:    (set_attr "length" "2")])
                   1002: 
                   1003: ;; The definition of this insn does not really explain what it does,
                   1004: ;; but it should suffice
                   1005: ;; that anything generated as this insn will be recognized as one
                   1006: ;; and that it will not successfully combine with anything.
                   1007: (define_expand "movstrsi"
                   1008:   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
                   1009:                   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1.1.1.2   root     1010:              (use (match_operand:SI 2 "nonmemory_operand" ""))
1.1       root     1011:              (use (match_operand:SI 3 "immediate_operand" ""))
                   1012:              (clobber (match_dup 0))
                   1013:              (clobber (match_dup 1))
                   1014:              (clobber (match_scratch:SI 4 ""))
                   1015:              (clobber (reg:SI 0))
                   1016:              (clobber (reg:SI 1))])]
                   1017:   ""
                   1018:   "
                   1019: {
1.1.1.2   root     1020:   /* If the size isn't known, don't emit inline code.  output_block_move
                   1021:      would output code that's much slower than the library function.
                   1022:      Also don't output code for large blocks.  */
                   1023:   if (GET_CODE (operands[2]) != CONST_INT
                   1024:       || GET_CODE (operands[3]) != CONST_INT
                   1025:       || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1.1       root     1026:     FAIL;
                   1027: 
                   1028:   operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
                   1029:   operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
                   1030:   operands[2] = force_not_mem (operands[2]);
                   1031: }")
                   1032: 
                   1033: (define_insn ""
                   1034:   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
                   1035:        (mem:BLK (match_operand:SI 1 "register_operand" "r")))
1.1.1.2   root     1036:    (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1.1       root     1037:    (use (match_operand:SI 3 "immediate_operand" "i"))
                   1038:    (clobber (match_dup 0))
                   1039:    (clobber (match_dup 1))
                   1040:    (clobber (match_scratch:SI 4 "=&r"))
                   1041:    (clobber (reg:SI 0))
                   1042:    (clobber (reg:SI 1))]
                   1043:   ""
                   1044:   "* return output_block_move (operands);"
1.1.1.2   root     1045:   [(set_attr "type" "multi")
                   1046:    (set_attr "length" "6")])
1.1       root     1047: 
                   1048: ;; Floating point move insns
                   1049: 
1.1.1.3 ! root     1050: ;; This pattern forces (set (reg:TF ...) (const_double ...))
        !          1051: ;; to be reloaded by putting the constant into memory.
        !          1052: ;; It must come before the more general movtf pattern.
        !          1053: (define_insn ""
        !          1054:   [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
        !          1055:        (match_operand:TF 1 "" "?E,m,G"))]
        !          1056:   "GET_CODE (operands[1]) == CONST_DOUBLE"
        !          1057:   "*
        !          1058: {
        !          1059:   switch (which_alternative)
        !          1060:     {
        !          1061:     case 0:
        !          1062:       return output_move_quad (operands);
        !          1063:     case 1:
        !          1064:       return output_fp_move_quad (operands);
        !          1065:     case 2:
        !          1066:       operands[1] = adj_offsettable_operand (operands[0], 4);
        !          1067:       operands[2] = adj_offsettable_operand (operands[0], 8);
        !          1068:       operands[3] = adj_offsettable_operand (operands[0], 12);
        !          1069:       return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
        !          1070:     }
        !          1071: }"
        !          1072:   [(set_attr "type" "load,fpload,store")
        !          1073:    (set_attr "length" "5,5,5")])
        !          1074: 
        !          1075: (define_expand "movtf"
        !          1076:   [(set (match_operand:TF 0 "general_operand" "")
        !          1077:        (match_operand:TF 1 "general_operand" ""))]
        !          1078:   ""
        !          1079:   "
        !          1080: {
        !          1081:   if (emit_move_sequence (operands, TFmode, 0))
        !          1082:     DONE;
        !          1083: }")
        !          1084: 
        !          1085: (define_insn ""
        !          1086:   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
        !          1087:        (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
        !          1088:   "register_operand (operands[0], TFmode)
        !          1089:    || register_operand (operands[1], TFmode)"
        !          1090:   "*
        !          1091: {
        !          1092:   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
        !          1093:     return output_fp_move_quad (operands);
        !          1094:   return output_move_quad (operands);
        !          1095: }"
        !          1096:   [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
        !          1097:    (set_attr "length" "4,4,5,5,5,5,5,5")])
        !          1098: 
        !          1099: (define_insn ""
        !          1100:   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
        !          1101:        (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
        !          1102:    (clobber (match_scratch:SI 2 "=&r,&r"))]
        !          1103:   ""
        !          1104:   "*
        !          1105: {
        !          1106:   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
        !          1107:   if (which_alternative == 0)
        !          1108:     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
        !          1109:   else
        !          1110:     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
        !          1111: }"
        !          1112:   [(set_attr "type" "store")
        !          1113:    (set_attr "length" "5")])
        !          1114: 
1.1       root     1115: ;; This pattern forces (set (reg:DF ...) (const_double ...))
                   1116: ;; to be reloaded by putting the constant into memory.
                   1117: ;; It must come before the more general movdf pattern.
                   1118: (define_insn ""
1.1.1.3 ! root     1119:   [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
        !          1120:        (match_operand:DF 1 "" "?E,m,G"))]
1.1       root     1121:   "GET_CODE (operands[1]) == CONST_DOUBLE"
                   1122:   "*
                   1123: {
                   1124:   switch (which_alternative)
                   1125:     {
                   1126:     case 0:
                   1127:       return output_move_double (operands);
                   1128:     case 1:
                   1129:       return output_fp_move_double (operands);
1.1.1.3 ! root     1130:     case 2:
1.1       root     1131:       operands[1] = adj_offsettable_operand (operands[0], 4);
                   1132:       return \"st %%g0,%0\;st %%g0,%1\";
                   1133:     }
                   1134: }"
1.1.1.3 ! root     1135:   [(set_attr "type" "load,fpload,store")
        !          1136:    (set_attr "length" "3,3,3")])
1.1       root     1137: 
                   1138: (define_expand "movdf"
                   1139:   [(set (match_operand:DF 0 "general_operand" "")
                   1140:        (match_operand:DF 1 "general_operand" ""))]
                   1141:   ""
                   1142:   "
                   1143: {
                   1144:   if (emit_move_sequence (operands, DFmode, 0))
                   1145:     DONE;
                   1146: }")
                   1147: 
                   1148: (define_insn ""
                   1149:   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
                   1150:        (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
                   1151:   "register_operand (operands[0], DFmode)
                   1152:    || register_operand (operands[1], DFmode)"
                   1153:   "*
                   1154: {
                   1155:   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
                   1156:     return output_fp_move_double (operands);
                   1157:   return output_move_double (operands);
                   1158: }"
                   1159:   [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
                   1160:    (set_attr "length" "2,2,3,3,3,3,3,3")])
                   1161: 
                   1162: (define_insn ""
                   1163:   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
                   1164:        (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
                   1165:    (clobber (match_scratch:SI 2 "=&r,&r"))]
                   1166:   ""
                   1167:   "*
                   1168: {
                   1169:   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
                   1170:   if (which_alternative == 0)
                   1171:     return \"std %1,[%2+%%lo(%a0)]\";
                   1172:   else
                   1173:     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
                   1174: }"
                   1175:   [(set_attr "type" "store")
                   1176:    (set_attr "length" "3")])
                   1177: 
                   1178: ;; Double-word move insns.
                   1179: 
                   1180: (define_expand "movdi"
                   1181:   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
                   1182:        (match_operand:DI 1 "general_operand" ""))]
                   1183:   ""
                   1184:   "
                   1185: {
                   1186:   if (emit_move_sequence (operands, DImode, 0))
                   1187:     DONE;
                   1188: }")
                   1189: 
                   1190: (define_insn ""
                   1191:   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,?f,?f,?f,?r,?Q")
                   1192:        (match_operand:DI 1 "general_operand" "r,r,Q,i,r,f,Q,f,f"))]
                   1193:   "register_operand (operands[0], DImode)
                   1194:    || register_operand (operands[1], DImode)
                   1195:    || operands[1] == const0_rtx"
                   1196:   "*
                   1197: {
                   1198:   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
                   1199:     return output_fp_move_double (operands);
                   1200:   return output_move_double (operands);
                   1201: }"
1.1.1.2   root     1202:   [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore")
1.1       root     1203:    (set_attr "length" "2,3,3,3,3,2,3,3,3")])
                   1204: 
                   1205: ;; Floating-point move insns.
                   1206: 
1.1.1.3 ! root     1207: ;; This pattern forces (set (reg:SF ...) (const_double ...))
        !          1208: ;; to be reloaded by putting the constant into memory.
        !          1209: ;; It must come before the more general movsf pattern.
        !          1210: (define_insn ""
        !          1211:   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
        !          1212:        (match_operand:SF 1 "" "?E,m,G"))]
        !          1213:   "GET_CODE (operands[1]) == CONST_DOUBLE"
        !          1214:   "*
        !          1215: {
        !          1216:   switch (which_alternative)
        !          1217:     {
        !          1218:     case 0:
        !          1219:       return singlemove_string (operands);
        !          1220:     case 1:
        !          1221:       return \"ld %1,%0\";
        !          1222:     case 2:
        !          1223:       return \"st %%g0,%0\";
        !          1224:     }
        !          1225: }"
        !          1226:   [(set_attr "type" "load,fpload,store")
        !          1227:    (set_attr "length" "2,1,1")])
        !          1228: 
1.1       root     1229: (define_expand "movsf"
                   1230:   [(set (match_operand:SF 0 "general_operand" "")
                   1231:        (match_operand:SF 1 "general_operand" ""))]
                   1232:   ""
                   1233:   "
                   1234: {
                   1235:   if (emit_move_sequence (operands, SFmode, 0))
                   1236:     DONE;
                   1237: }")
                   1238: 
                   1239: (define_insn ""
                   1240:   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
                   1241:        (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
                   1242:   "register_operand (operands[0], SFmode)
                   1243:    || register_operand (operands[1], SFmode)"
                   1244:   "@
                   1245:    fmovs %1,%0
                   1246:    mov %1,%0
                   1247:    st %r1,[%%fp-4]\;ld [%%fp-4],%0
                   1248:    ld %1,%0
                   1249:    ld %1,%0
                   1250:    st %r1,%0
                   1251:    st %r1,%0"
1.1.1.2   root     1252:   [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
1.1       root     1253: 
                   1254: (define_insn ""
                   1255:   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
                   1256:        (match_operand:SF 1 "reg_or_0_operand" "rfG"))
                   1257:    (clobber (match_scratch:SI 2 "=&r"))]
                   1258:   ""
                   1259:   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
                   1260:   [(set_attr "type" "store")
                   1261:    (set_attr "length" "2")])
                   1262: 
                   1263: ;;- zero extension instructions
                   1264: 
                   1265: ;; These patterns originally accepted general_operands, however, slightly
                   1266: ;; better code is generated by only accepting register_operands, and then
                   1267: ;; letting combine generate the ldu[hb] insns.
                   1268: 
                   1269: (define_expand "zero_extendhisi2"
                   1270:   [(set (match_operand:SI 0 "register_operand" "")
                   1271:        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
                   1272:   ""
                   1273:   "
                   1274: {
                   1275:   rtx temp = gen_reg_rtx (SImode);
                   1276:   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
                   1277: 
                   1278:   if (GET_CODE (operand1) == SUBREG)
                   1279:     operand1 = XEXP (operand1, 0);
                   1280: 
                   1281:   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
                   1282:                          shift_16));
                   1283:   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
                   1284:   DONE;
                   1285: }")
                   1286: 
                   1287: (define_insn ""
                   1288:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1289:        (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
                   1290:   ""
                   1291:   "lduh %1,%0"
                   1292:   [(set_attr "type" "load")])
                   1293: 
                   1294: (define_expand "zero_extendqihi2"
                   1295:   [(set (match_operand:HI 0 "register_operand" "")
                   1296:        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
                   1297:   ""
                   1298:   "")
                   1299: 
                   1300: (define_insn ""
                   1301:   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
                   1302:        (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
                   1303:   "GET_CODE (operands[1]) != CONST_INT"
                   1304:   "@
                   1305:    and %1,0xff,%0;
                   1306:    mov (%1 & 0xff),%0
                   1307:    ldub %1,%0"
                   1308:   [(set_attr "type" "unary,move,load")
                   1309:    (set_attr "length" "1")])
                   1310: 
                   1311: (define_expand "zero_extendqisi2"
                   1312:   [(set (match_operand:SI 0 "register_operand" "")
                   1313:        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
                   1314:   ""
                   1315:   "")
                   1316: 
                   1317: (define_insn ""
                   1318:   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
                   1319:        (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
                   1320:   "GET_CODE (operands[1]) != CONST_INT"
                   1321:   "@
                   1322:    and %1,0xff,%0
                   1323:    mov (%1 & 0xff),%0
                   1324:    ldub %1,%0"
                   1325:   [(set_attr "type" "unary,move,load")
                   1326:    (set_attr "length" "1")])
                   1327: 
                   1328: (define_insn ""
                   1329:   [(set (reg:CC 0)
                   1330:        (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
                   1331:                    (const_int 0)))]
                   1332:   ""
                   1333:   "andcc %0,0xff,%%g0"
                   1334:   [(set_attr "type" "compare")])
                   1335: 
                   1336: (define_insn ""
                   1337:   [(set (reg:CC 0)
                   1338:        (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
                   1339:                    (const_int 0)))
                   1340:    (set (match_operand:SI 0 "register_operand" "=r")
                   1341:        (zero_extend:SI (match_dup 1)))]
                   1342:   ""
                   1343:   "andcc %1,0xff,%0"
                   1344:   [(set_attr "type" "unary")])
                   1345: 
                   1346: ;;- sign extension instructions
                   1347: 
                   1348: ;; These patterns originally accepted general_operands, however, slightly
                   1349: ;; better code is generated by only accepting register_operands, and then
                   1350: ;; letting combine generate the lds[hb] insns.
                   1351: 
                   1352: (define_expand "extendhisi2"
                   1353:   [(set (match_operand:SI 0 "register_operand" "")
                   1354:        (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
                   1355:   ""
                   1356:   "
                   1357: {
                   1358:   rtx temp = gen_reg_rtx (SImode);
                   1359:   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
                   1360: 
                   1361:   if (GET_CODE (operand1) == SUBREG)
                   1362:     operand1 = XEXP (operand1, 0);
                   1363: 
                   1364:   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
                   1365:                          shift_16));
                   1366:   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
                   1367:   DONE;
                   1368: }")
                   1369: 
                   1370: (define_insn ""
                   1371:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1372:        (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
                   1373:   ""
                   1374:   "ldsh %1,%0"
                   1375:   [(set_attr "type" "load")])
                   1376: 
                   1377: (define_expand "extendqihi2"
                   1378:   [(set (match_operand:HI 0 "register_operand" "")
                   1379:        (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
                   1380:   ""
                   1381:   "
                   1382: {
                   1383:   rtx temp = gen_reg_rtx (SImode);
                   1384:   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
                   1385: 
                   1386:   if (GET_CODE (operand1) == SUBREG)
                   1387:     operand1 = XEXP (operand1, 0);
                   1388:   if (GET_CODE (operand0) == SUBREG)
                   1389:     operand0 = XEXP (operand0, 0);
                   1390:   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
                   1391:                          shift_24));
                   1392:   if (GET_MODE (operand0) != SImode)
                   1393:     operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
                   1394:   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
                   1395:   DONE;
                   1396: }")
                   1397: 
                   1398: (define_insn ""
                   1399:   [(set (match_operand:HI 0 "register_operand" "=r")
                   1400:        (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
                   1401:   ""
                   1402:   "ldsb %1,%0"
                   1403:   [(set_attr "type" "load")])
                   1404: 
                   1405: (define_expand "extendqisi2"
                   1406:   [(set (match_operand:SI 0 "register_operand" "")
                   1407:        (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
                   1408:   ""
                   1409:   "
                   1410: {
                   1411:   rtx temp = gen_reg_rtx (SImode);
                   1412:   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
                   1413: 
                   1414:   if (GET_CODE (operand1) == SUBREG)
                   1415:     operand1 = XEXP (operand1, 0);
                   1416:   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
                   1417:                          shift_24));
                   1418:   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
                   1419:   DONE;
                   1420: }")
                   1421: 
                   1422: (define_insn ""
                   1423:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1424:        (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
                   1425:   ""
                   1426:   "ldsb %1,%0"
                   1427:   [(set_attr "type" "load")])
                   1428: 
1.1.1.2   root     1429: ;; Special pattern for optimizing bit-field compares.  This is needed
                   1430: ;; because combine uses this as a canonical form.
                   1431: 
                   1432: (define_insn ""
                   1433:   [(set (reg:CC 0)
                   1434:        (compare:CC
                   1435:         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
                   1436:                          (match_operand:SI 1 "small_int" "n")
                   1437:                          (match_operand:SI 2 "small_int" "n"))
                   1438:         (const_int 0)))]
                   1439:   "INTVAL (operands[2]) > 19"
                   1440:   "*
                   1441: {
                   1442:   int len = INTVAL (operands[1]);
                   1443:   int pos = 32 - INTVAL (operands[2]) - len;
                   1444:   unsigned mask = ((1 << len) - 1) << pos;
                   1445: 
                   1446:   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
                   1447:   return \"andcc %0,%1,%%g0\";
                   1448: }")
                   1449: 
1.1.1.3 ! root     1450: ;; Conversions between float, double and long double.
1.1       root     1451: 
                   1452: (define_insn "extendsfdf2"
                   1453:   [(set (match_operand:DF 0 "register_operand" "=f")
                   1454:        (float_extend:DF
                   1455:         (match_operand:SF 1 "register_operand" "f")))]
                   1456:   ""
                   1457:   "fstod %1,%0"
                   1458:   [(set_attr "type" "fp")])
                   1459: 
1.1.1.3 ! root     1460: (define_insn "extendsftf2"
        !          1461:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          1462:        (float_extend:TF
        !          1463:         (match_operand:SF 1 "register_operand" "f")))]
        !          1464:   ""
        !          1465:   "fstoq %1,%0"
        !          1466:   [(set_attr "type" "fp")])
        !          1467: 
        !          1468: (define_insn "extenddftf2"
        !          1469:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          1470:        (float_extend:TF
        !          1471:         (match_operand:DF 1 "register_operand" "f")))]
        !          1472:   ""
        !          1473:   "fdtoq %1,%0"
        !          1474:   [(set_attr "type" "fp")])
        !          1475: 
1.1       root     1476: (define_insn "truncdfsf2"
                   1477:   [(set (match_operand:SF 0 "register_operand" "=f")
                   1478:        (float_truncate:SF
                   1479:         (match_operand:DF 1 "register_operand" "f")))]
                   1480:   ""
                   1481:   "fdtos %1,%0"
                   1482:   [(set_attr "type" "fp")])
1.1.1.3 ! root     1483: 
        !          1484: (define_insn "trunctfsf2"
        !          1485:   [(set (match_operand:SF 0 "register_operand" "=f")
        !          1486:        (float_truncate:SF
        !          1487:         (match_operand:TF 1 "register_operand" "f")))]
        !          1488:   ""
        !          1489:   "fqtos %1,%0"
        !          1490:   [(set_attr "type" "fp")])
        !          1491: 
        !          1492: (define_insn "trunctfdf2"
        !          1493:   [(set (match_operand:DF 0 "register_operand" "=f")
        !          1494:        (float_truncate:DF
        !          1495:         (match_operand:TF 1 "register_operand" "f")))]
        !          1496:   ""
        !          1497:   "fqtod %1,%0"
        !          1498:   [(set_attr "type" "fp")])
1.1       root     1499: 
                   1500: ;; Conversion between fixed point and floating point.
                   1501: 
                   1502: (define_insn "floatsisf2"
                   1503:   [(set (match_operand:SF 0 "general_operand" "=f")
                   1504:        (float:SF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
                   1505:   ""
                   1506:   "* return output_floatsisf2 (operands);"
                   1507:   [(set_attr "type" "fp")
                   1508:    (set_attr "length" "3")])
                   1509: 
                   1510: (define_insn "floatsidf2"
                   1511:   [(set (match_operand:DF 0 "general_operand" "=f")
                   1512:        (float:DF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
                   1513:   ""
                   1514:   "* return output_floatsidf2 (operands);"
                   1515:   [(set_attr "type" "fp")
                   1516:    (set_attr "length" "3")])
                   1517: 
1.1.1.3 ! root     1518: (define_insn "floatsitf2"
        !          1519:   [(set (match_operand:TF 0 "general_operand" "=f")
        !          1520:        (float:TF (match_operand:SI 1 "nonimmediate_operand" "rfm")))]
        !          1521:   ""
        !          1522:   "* return output_floatsitf2 (operands);"
        !          1523:   [(set_attr "type" "fp")
        !          1524:    (set_attr "length" "3")])
        !          1525: 
1.1       root     1526: ;; Convert a float to an actual integer.
                   1527: ;; Truncation is performed as part of the conversion.
                   1528: 
                   1529: (define_insn "fix_truncsfsi2"
                   1530:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   1531:        (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))
                   1532:    (clobber (match_scratch:SF 2 "=&f"))]
                   1533:   ""
                   1534:   "*
                   1535: {
                   1536:   if (FP_REG_P (operands[1]))
                   1537:     output_asm_insn (\"fstoi %1,%2\", operands);
                   1538:   else
                   1539:     output_asm_insn (\"ld %1,%2\;fstoi %2,%2\", operands);
                   1540:   if (GET_CODE (operands[0]) == MEM)
                   1541:     return \"st %2,%0\";
                   1542:   else
                   1543:     return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
                   1544: }"
                   1545:   [(set_attr "type" "fp")
                   1546:    (set_attr "length" "3")])
                   1547: 
                   1548: (define_insn "fix_truncdfsi2"
                   1549:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   1550:        (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))
                   1551:    (clobber (match_scratch:DF 2 "=&f"))]
                   1552:   ""
                   1553:   "*
                   1554: {
                   1555:   if (FP_REG_P (operands[1]))
                   1556:     output_asm_insn (\"fdtoi %1,%2\", operands);
                   1557:   else
                   1558:     {
                   1559:       rtx xoperands[3];
                   1560:       xoperands[0] = operands[2];
                   1561:       xoperands[1] = operands[1];
                   1562:       output_asm_insn (output_fp_move_double (xoperands), xoperands);
                   1563:       output_asm_insn (\"fdtoi %2,%2\", operands);
                   1564:     }
                   1565:   if (GET_CODE (operands[0]) == MEM)
                   1566:     return \"st %2,%0\";
                   1567:   else
                   1568:     return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
                   1569: }"
                   1570:   [(set_attr "type" "fp")
                   1571:    (set_attr "length" "3")])
1.1.1.3 ! root     1572: 
        !          1573: (define_insn "fix_trunctfsi2"
        !          1574:   [(set (match_operand:SI 0 "general_operand" "=rm")
        !          1575:        (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm"))))
        !          1576:    (clobber (match_scratch:DF 2 "=&f"))]
        !          1577:   ""
        !          1578:   "*
        !          1579: {
        !          1580:   if (FP_REG_P (operands[1]))
        !          1581:     output_asm_insn (\"fqtoi %1,%2\", operands);
        !          1582:   else
        !          1583:     {
        !          1584:       rtx xoperands[3];
        !          1585:       xoperands[0] = operands[2];
        !          1586:       xoperands[1] = operands[1];
        !          1587:       output_asm_insn (output_fp_move_quad (xoperands), xoperands);
        !          1588:       output_asm_insn (\"fqtoi %2,%2\", operands);
        !          1589:     }
        !          1590:   if (GET_CODE (operands[0]) == MEM)
        !          1591:     return \"st %2,%0\";
        !          1592:   else
        !          1593:     return \"st %2,[%%fp-4]\;ld [%%fp-4],%0\";
        !          1594: }"
        !          1595:   [(set_attr "type" "fp")
        !          1596:    (set_attr "length" "3")])
        !          1597: 
        !          1598: ;; Allow combiner to combine a fix_trunctfsi2 with a floatsitf2
        !          1599: ;; This eliminates 2 useless instructions.
        !          1600: ;; The first one matches if the fixed result is needed.  The second one
        !          1601: ;; matches if the fixed result is not needed.
        !          1602: 
        !          1603: (define_insn ""
        !          1604:   [(set (match_operand:TF 0 "general_operand" "=f")
        !          1605:        (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))
        !          1606:    (set (match_operand:SI 2 "general_operand" "=rm")
        !          1607:        (fix:SI (fix:TF (match_dup 1))))]
        !          1608:   ""
        !          1609:   "*
        !          1610: {
        !          1611:   if (FP_REG_P (operands[1]))
        !          1612:     output_asm_insn (\"fqtoi %1,%0\", operands);
        !          1613:   else
        !          1614:     {
        !          1615:       output_asm_insn (output_fp_move_quad (operands), operands);
        !          1616:       output_asm_insn (\"fqtoi %0,%0\", operands);
        !          1617:     }
        !          1618:   if (GET_CODE (operands[2]) == MEM)
        !          1619:     return \"st %0,%2\;fitoq %0,%0\";
        !          1620:   else
        !          1621:     return \"st %0,[%%fp-4]\;fitoq %0,%0\;ld [%%fp-4],%2\";
        !          1622: }"
        !          1623:   [(set_attr "type" "fp")
        !          1624:    (set_attr "length" "5")])
        !          1625: 
        !          1626: (define_insn ""
        !          1627:   [(set (match_operand:TF 0 "general_operand" "=f")
        !          1628:        (float:TF (fix:SI (fix:TF (match_operand:TF 1 "general_operand" "fm")))))]
        !          1629:   ""
        !          1630:   "*
        !          1631: {
        !          1632:   if (FP_REG_P (operands[1]))
        !          1633:     output_asm_insn (\"fqtoi %1,%0\", operands);
        !          1634:   else
        !          1635:     {
        !          1636:       output_asm_insn (output_fp_move_quad (operands), operands);
        !          1637:       output_asm_insn (\"fqtoi %0,%0\", operands);
        !          1638:     }
        !          1639:   return \"fitoq %0,%0\";
        !          1640: }"
        !          1641:   [(set_attr "type" "fp")
        !          1642:    (set_attr "length" "3")])
        !          1643: 
        !          1644: ;; Allow combiner to combine a fix_truncdfsi2 with a floatsidf2
        !          1645: ;; This eliminates 2 useless instructions.
        !          1646: ;; The first one matches if the fixed result is needed.  The second one
        !          1647: ;; matches if the fixed result is not needed.
        !          1648: 
        !          1649: (define_insn ""
        !          1650:   [(set (match_operand:DF 0 "general_operand" "=f")
        !          1651:        (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))
        !          1652:    (set (match_operand:SI 2 "general_operand" "=rm")
        !          1653:        (fix:SI (fix:DF (match_dup 1))))]
        !          1654:   ""
        !          1655:   "*
        !          1656: {
        !          1657:   if (FP_REG_P (operands[1]))
        !          1658:     output_asm_insn (\"fdtoi %1,%0\", operands);
        !          1659:   else
        !          1660:     {
        !          1661:       output_asm_insn (output_fp_move_double (operands), operands);
        !          1662:       output_asm_insn (\"fdtoi %0,%0\", operands);
        !          1663:     }
        !          1664:   if (GET_CODE (operands[2]) == MEM)
        !          1665:     return \"st %0,%2\;fitod %0,%0\";
        !          1666:   else
        !          1667:     return \"st %0,[%%fp-4]\;fitod %0,%0\;ld [%%fp-4],%2\";
        !          1668: }"
        !          1669:   [(set_attr "type" "fp")
        !          1670:    (set_attr "length" "5")])
        !          1671: 
        !          1672: (define_insn ""
        !          1673:   [(set (match_operand:DF 0 "general_operand" "=f")
        !          1674:        (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))]
        !          1675:   ""
        !          1676:   "*
        !          1677: {
        !          1678:   if (FP_REG_P (operands[1]))
        !          1679:     output_asm_insn (\"fdtoi %1,%0\", operands);
        !          1680:   else
        !          1681:     {
        !          1682:       output_asm_insn (output_fp_move_double (operands), operands);
        !          1683:       output_asm_insn (\"fdtoi %0,%0\", operands);
        !          1684:     }
        !          1685:   return \"fitod %0,%0\";
        !          1686: }"
        !          1687:   [(set_attr "type" "fp")
        !          1688:    (set_attr "length" "3")])
        !          1689: 
        !          1690: ;; Allow combiner to combine a fix_truncsfsi2 with a floatsisf2
        !          1691: ;; This eliminates 2 useless instructions.
        !          1692: ;; The first one matches if the fixed result is needed.  The second one
        !          1693: ;; matches if the fixed result is not needed.
        !          1694: 
        !          1695: (define_insn ""
        !          1696:   [(set (match_operand:SF 0 "general_operand" "=f")
        !          1697:        (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))
        !          1698:    (set (match_operand:SI 2 "general_operand" "=rm")
        !          1699:        (fix:SI (fix:SF (match_dup 1))))]
        !          1700:   ""
        !          1701:   "*
        !          1702: {
        !          1703:   if (FP_REG_P (operands[1]))
        !          1704:     output_asm_insn (\"fstoi %1,%0\", operands);
        !          1705:   else
        !          1706:     output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
        !          1707:   if (GET_CODE (operands[2]) == MEM)
        !          1708:     return \"st %0,%2\;fitos %0,%0\";
        !          1709:   else
        !          1710:     return \"st %0,[%%fp-4]\;fitos %0,%0\;ld [%%fp-4],%2\";
        !          1711: }"
        !          1712:   [(set_attr "type" "fp")
        !          1713:    (set_attr "length" "5")])
        !          1714: 
        !          1715: (define_insn ""
        !          1716:   [(set (match_operand:SF 0 "general_operand" "=f")
        !          1717:        (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))]
        !          1718:   ""
        !          1719:   "*
        !          1720: {
        !          1721:   if (FP_REG_P (operands[1]))
        !          1722:     output_asm_insn (\"fstoi %1,%0\", operands);
        !          1723:   else
        !          1724:     output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
        !          1725:   return \"fitos %0,%0\";
        !          1726: }"
        !          1727:   [(set_attr "type" "fp")
        !          1728:    (set_attr "length" "3")])
1.1       root     1729: 
                   1730: ;;- arithmetic instructions
                   1731: 
                   1732: (define_insn "adddi3"
                   1733:   [(set (match_operand:DI 0 "register_operand" "=r")
                   1734:        (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
                   1735:                 (match_operand:DI 2 "arith_double_operand" "rHI")))
                   1736:    (clobber (reg:SI 0))]
                   1737:   ""
                   1738:   "*
                   1739: {
                   1740:   rtx op2 = operands[2];
                   1741: 
1.1.1.2   root     1742:   /* If constant is positive, upper bits zeroed, otherwise unchanged.
                   1743:      Give the assembler a chance to pick the move instruction. */
1.1       root     1744:   if (GET_CODE (op2) == CONST_INT)
                   1745:     {
                   1746:       int sign = INTVAL (op2);
                   1747:       if (sign < 0)
                   1748:        return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
                   1749:       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
                   1750:     }
                   1751:   else if (GET_CODE (op2) == CONST_DOUBLE)
                   1752:     {
                   1753:       int sign = CONST_DOUBLE_HIGH (op2);
                   1754:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1755:                             CONST_DOUBLE_LOW (operands[1]));
                   1756:       if (sign < 0)
                   1757:         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
                   1758:       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
                   1759:     }
                   1760:   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
                   1761: }"
                   1762:   [(set_attr "length" "2")])
                   1763: 
                   1764: (define_insn "addsi3"
                   1765:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1766:        (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                   1767:                 (match_operand:SI 2 "arith_operand" "rI")))]
                   1768:   ""
                   1769:   "add %1,%2,%0")
                   1770: 
                   1771: (define_insn ""
                   1772:   [(set (reg:CC_NOOV 0)
                   1773:        (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
                   1774:                                  (match_operand:SI 1 "arith_operand" "rI"))
                   1775:                         (const_int 0)))]
                   1776:   ""
                   1777:   "addcc %0,%1,%%g0"
                   1778:   [(set_attr "type" "compare")])
                   1779: 
                   1780: (define_insn ""
                   1781:   [(set (reg:CC_NOOV 0)
                   1782:        (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                   1783:                                  (match_operand:SI 2 "arith_operand" "rI"))
                   1784:                         (const_int 0)))
                   1785:    (set (match_operand:SI 0 "register_operand" "=r")
                   1786:        (plus:SI (match_dup 1) (match_dup 2)))]
                   1787:   ""
                   1788:   "addcc %1,%2,%0")
                   1789: 
                   1790: (define_insn "subdi3"
                   1791:   [(set (match_operand:DI 0 "register_operand" "=r")
                   1792:        (minus:DI (match_operand:DI 1 "register_operand" "r")
                   1793:                  (match_operand:DI 2 "arith_double_operand" "rHI")))
                   1794:    (clobber (reg:SI 0))]
                   1795:   ""
                   1796:   "*
                   1797: {
                   1798:   rtx op2 = operands[2];
                   1799: 
1.1.1.2   root     1800:   /* If constant is positive, upper bits zeroed, otherwise unchanged.
                   1801:      Give the assembler a chance to pick the move instruction. */
1.1       root     1802:   if (GET_CODE (op2) == CONST_INT)
                   1803:     {
                   1804:       int sign = INTVAL (op2);
                   1805:       if (sign < 0)
                   1806:        return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
                   1807:       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
                   1808:     }
                   1809:   else if (GET_CODE (op2) == CONST_DOUBLE)
                   1810:     {
                   1811:       int sign = CONST_DOUBLE_HIGH (op2);
                   1812:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1813:                             CONST_DOUBLE_LOW (operands[1]));
                   1814:       if (sign < 0)
                   1815:         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
                   1816:       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
                   1817:     }
                   1818:   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
                   1819: }"
                   1820:   [(set_attr "length" "2")])
                   1821: 
                   1822: (define_insn "subsi3"
                   1823:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1824:        (minus:SI (match_operand:SI 1 "register_operand" "r")
                   1825:                  (match_operand:SI 2 "arith_operand" "rI")))]
                   1826:   ""
                   1827:   "sub %1,%2,%0")
                   1828: 
                   1829: (define_insn ""
                   1830:   [(set (reg:CC_NOOV 0)
                   1831:        (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
                   1832:                                   (match_operand:SI 1 "arith_operand" "rI"))
                   1833:                         (const_int 0)))]
                   1834:   ""
                   1835:   "subcc %0,%1,%%g0"
                   1836:   [(set_attr "type" "compare")])
                   1837: 
                   1838: (define_insn ""
                   1839:   [(set (reg:CC_NOOV 0)
                   1840:        (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
                   1841:                                   (match_operand:SI 2 "arith_operand" "rI"))
                   1842:                         (const_int 0)))
                   1843:    (set (match_operand:SI 0 "register_operand" "=r")
                   1844:        (minus:SI (match_dup 1) (match_dup 2)))]
                   1845:   ""
                   1846:   "subcc %1,%2,%0")
                   1847: 
1.1.1.3 ! root     1848: (define_insn "mulsi3"
        !          1849:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1850:        (mult:SI (match_operand:SI 1 "arith_operand" "%r")
        !          1851:                 (match_operand:SI 2 "arith_operand" "rI")))]
        !          1852:   "TARGET_V8 || TARGET_SPARCLITE"
        !          1853:   "smul %1,%2,%0")
        !          1854: 
        !          1855: ;; It is not known whether this will match.
        !          1856: 
        !          1857: (define_insn ""
        !          1858:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1859:        (mult:SI (match_operand:SI 1 "arith_operand" "%r")
        !          1860:                 (match_operand:SI 2 "arith_operand" "rI")))
        !          1861:    (set (reg:CC_NOOV 0)
        !          1862:        (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
        !          1863:                         (const_int 0)))]
        !          1864:   "TARGET_V8 || TARGET_SPARCLITE"
        !          1865:   "smulcc %1,%2,%0")
        !          1866: 
        !          1867: (define_insn "mulsidi3"
        !          1868:   [(set (match_operand:DI 0 "register_operand" "=r")
        !          1869:        (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_operand" "%r"))
        !          1870:                 (sign_extend:DI (match_operand:SI 2 "arith_operand" "rI"))))]
        !          1871:   "TARGET_V8 || TARGET_SPARCLITE"
        !          1872:   "smul %1,%2,%R0\;rd %y,%0"
        !          1873:   [(set_attr "length" "2")])
        !          1874: 
        !          1875: (define_insn "umulsidi3"
        !          1876:   [(set (match_operand:DI 0 "register_operand" "=r")
        !          1877:        (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_operand" "%r"))
        !          1878:                 (zero_extend:DI (match_operand:SI 2 "arith_operand" "rI"))))]
        !          1879:   "TARGET_V8 || TARGET_SPARCLITE"
        !          1880:   "umul %1,%2,%R0\;rd %y,%0"
        !          1881:   [(set_attr "length" "2")])
        !          1882: 
        !          1883: ;; The architecture specifies that there must be 3 instructions between
        !          1884: ;; a y register write and a use of it for correct results.
        !          1885: 
        !          1886: (define_insn "divsi3"
        !          1887:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1888:        (div:SI (match_operand:SI 1 "register_operand" "r")
        !          1889:                (match_operand:SI 2 "arith_operand" "rI")))
        !          1890:    (clobber (match_scratch:SI 3 "=&r"))]
        !          1891:   "TARGET_V8"
        !          1892:   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
        !          1893:   [(set_attr "length" "3")])
        !          1894: 
        !          1895: ;; It is not known whether this will match.
        !          1896: 
        !          1897: (define_insn ""
        !          1898:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1899:        (div:SI (match_operand:SI 1 "register_operand" "r")
        !          1900:                (match_operand:SI 2 "arith_operand" "rI")))
        !          1901:    (set (reg:CC 0)
        !          1902:        (compare:CC (div:SI (match_dup 1) (match_dup 2))
        !          1903:                    (const_int 0)))
        !          1904:    (clobber (match_scratch:SI 3 "=&r"))]
        !          1905:   "TARGET_V8"
        !          1906:   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
        !          1907:   [(set_attr "length" "3")])
        !          1908: 
        !          1909: (define_insn "udivsi3"
        !          1910:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1911:        (udiv:SI (match_operand:SI 1 "register_operand" "r")
        !          1912:                (match_operand:SI 2 "arith_operand" "rI")))]
        !          1913:   "TARGET_V8"
        !          1914:   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
        !          1915:   [(set_attr "length" "2")])
        !          1916: 
        !          1917: ;; It is not known whether this will match.
        !          1918: 
        !          1919: (define_insn ""
        !          1920:   [(set (match_operand:SI 0 "register_operand" "=r")
        !          1921:        (udiv:SI (match_operand:SI 1 "register_operand" "r")
        !          1922:                (match_operand:SI 2 "arith_operand" "rI")))
        !          1923:    (set (reg:CC 0)
        !          1924:        (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
        !          1925:                    (const_int 0)))]
        !          1926:   "TARGET_V8"
        !          1927:   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
        !          1928:   [(set_attr "length" "2")])
        !          1929: 
1.1       root     1930: ;;- and instructions
                   1931: ;; We define DImode `and` so with DImode `not` we can get
                   1932: ;; DImode `andn`.  Other combinations are possible.
                   1933: 
                   1934: (define_expand "anddi3"
                   1935:   [(set (match_operand:DI 0 "register_operand" "")
                   1936:        (and:DI (match_operand:DI 1 "arith_double_operand" "")
                   1937:                (match_operand:DI 2 "arith_double_operand" "")))]
                   1938:   ""
                   1939:   "")
                   1940: 
                   1941: (define_insn ""
                   1942:   [(set (match_operand:DI 0 "register_operand" "=r")
                   1943:        (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
                   1944:                (match_operand:DI 2 "arith_double_operand" "rHI")))]
                   1945:   ""
                   1946:   "*
                   1947: {
                   1948:   rtx op2 = operands[2];
                   1949: 
1.1.1.2   root     1950:   /* If constant is positive, upper bits zeroed, otherwise unchanged.
                   1951:      Give the assembler a chance to pick the move instruction. */
1.1       root     1952:   if (GET_CODE (op2) == CONST_INT)
                   1953:     {
                   1954:       int sign = INTVAL (op2);
                   1955:       if (sign < 0)
                   1956:        return \"mov %1,%0\;and %R1,%2,%R0\";
                   1957:       return \"mov 0,%0\;and %R1,%2,%R0\";
                   1958:     }
                   1959:   else if (GET_CODE (op2) == CONST_DOUBLE)
                   1960:     {
                   1961:       int sign = CONST_DOUBLE_HIGH (op2);
                   1962:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1963:                             CONST_DOUBLE_LOW (operands[1]));
                   1964:       if (sign < 0)
                   1965:        return \"mov %1,%0\;and %R1,%2,%R0\";
                   1966:       return \"mov 0,%0\;and %R1,%2,%R0\";
                   1967:     }
                   1968:   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
                   1969: }"
                   1970:   [(set_attr "length" "2")])
                   1971: 
                   1972: (define_insn "andsi3"
                   1973:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1974:        (and:SI (match_operand:SI 1 "arith_operand" "%r")
                   1975:                (match_operand:SI 2 "arith_operand" "rI")))]
                   1976:   ""
                   1977:   "and %1,%2,%0")
                   1978: 
                   1979: (define_insn ""
                   1980:   [(set (match_operand:DI 0 "register_operand" "=r")
                   1981:        (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
                   1982:                (match_operand:DI 2 "register_operand" "r")))]
                   1983:   ""
                   1984:   "andn %2,%1,%0\;andn %R2,%R1,%R0"
                   1985:   [(set_attr "length" "2")])
                   1986: 
                   1987: (define_insn ""
                   1988:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1989:        (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
                   1990:                (match_operand:SI 2 "register_operand" "r")))]
                   1991:   ""
                   1992:   "andn %2,%1,%0")
                   1993: 
                   1994: (define_expand "iordi3"
                   1995:   [(set (match_operand:DI 0 "register_operand" "")
                   1996:        (ior:DI (match_operand:DI 1 "arith_double_operand" "")
                   1997:                (match_operand:DI 2 "arith_double_operand" "")))]
                   1998:   ""
                   1999:   "")
                   2000: 
                   2001: (define_insn ""
                   2002:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2003:        (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
                   2004:                (match_operand:DI 2 "arith_double_operand" "rHI")))]
                   2005:   ""
                   2006:   "*
                   2007: {
                   2008:   rtx op2 = operands[2];
                   2009: 
1.1.1.2   root     2010:   /* If constant is positive, upper bits zeroed, otherwise unchanged.
                   2011:      Give the assembler a chance to pick the move instruction. */
1.1       root     2012:   if (GET_CODE (op2) == CONST_INT)
                   2013:     {
                   2014:       int sign = INTVAL (op2);
                   2015:       if (sign < 0)
                   2016:        return \"mov -1,%0\;or %R1,%2,%R0\";
                   2017:       return \"mov %1,%0\;or %R1,%2,%R0\";
                   2018:     }
                   2019:   else if (GET_CODE (op2) == CONST_DOUBLE)
                   2020:     {
                   2021:       int sign = CONST_DOUBLE_HIGH (op2);
                   2022:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   2023:                             CONST_DOUBLE_LOW (operands[1]));
                   2024:       if (sign < 0)
                   2025:        return \"mov -1,%0\;or %R1,%2,%R0\";
                   2026:       return \"mov %1,%0\;or %R1,%2,%R0\";
                   2027:     }
                   2028:   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
                   2029: }"
                   2030:   [(set_attr "length" "2")])
                   2031: 
                   2032: (define_insn "iorsi3"
                   2033:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2034:        (ior:SI (match_operand:SI 1 "arith_operand" "%r")
                   2035:                (match_operand:SI 2 "arith_operand" "rI")))]
                   2036:   ""
                   2037:   "or %1,%2,%0")
                   2038: 
                   2039: (define_insn ""
                   2040:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2041:        (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
                   2042:                (match_operand:DI 2 "register_operand" "r")))]
                   2043:   ""
                   2044:   "orn %2,%1,%0\;orn %R2,%R1,%R0"
                   2045:   [(set_attr "length" "2")])
                   2046: 
                   2047: (define_insn ""
                   2048:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2049:        (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
                   2050:                (match_operand:SI 2 "register_operand" "r")))]
                   2051:   ""
                   2052:   "orn %2,%1,%0")
                   2053: 
                   2054: (define_expand "xordi3"
                   2055:   [(set (match_operand:DI 0 "register_operand" "")
                   2056:        (xor:DI (match_operand:DI 1 "arith_double_operand" "")
                   2057:                (match_operand:DI 2 "arith_double_operand" "")))]
                   2058:   ""
                   2059:   "")
                   2060: 
                   2061: (define_insn ""
                   2062:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2063:        (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
                   2064:                (match_operand:DI 2 "arith_double_operand" "rHI")))]
                   2065:   ""
                   2066:   "*
                   2067: {
                   2068:   rtx op2 = operands[2];
                   2069: 
1.1.1.3 ! root     2070:   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1.1.1.2   root     2071:      Give the assembler a chance to pick the move instruction. */
1.1       root     2072:   if (GET_CODE (op2) == CONST_INT)
                   2073:     {
                   2074:       int sign = INTVAL (op2);
                   2075:       if (sign < 0)
                   2076:        return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
                   2077:       return \"mov %1,%0\;xor %R1,%2,%R0\";
                   2078:     }
                   2079:   else if (GET_CODE (op2) == CONST_DOUBLE)
                   2080:     {
                   2081:       int sign = CONST_DOUBLE_HIGH (op2);
                   2082:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   2083:                             CONST_DOUBLE_LOW (operands[1]));
                   2084:       if (sign < 0)
                   2085:        return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
                   2086:       return \"mov %1,%0\;xor %R1,%2,%R0\";
                   2087:     }
                   2088:   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
                   2089: }"
                   2090:   [(set_attr "length" "2")])
                   2091: 
                   2092: (define_insn "xorsi3"
                   2093:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2094:        (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
                   2095:                (match_operand:SI 2 "arith_operand" "rI")))]
                   2096:   ""
                   2097:   "xor %r1,%2,%0")
                   2098: 
                   2099: ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
                   2100: ;; Combine now canonicalizes to the rightmost expression.
                   2101: (define_insn ""
                   2102:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2103:        (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
                   2104:                        (match_operand:DI 2 "register_operand" "r"))))]
                   2105:   ""
                   2106:   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
                   2107:   [(set_attr "length" "2")])
                   2108: 
                   2109: (define_insn ""
                   2110:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2111:        (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
                   2112:                        (match_operand:SI 2 "arith_operand" "rI"))))]
                   2113:   ""
                   2114:   "xnor %r1,%2,%0")
                   2115: 
                   2116: ;; These correspond to the above in the case where we also (or only)
                   2117: ;; want to set the condition code.  
                   2118: 
                   2119: (define_insn ""
                   2120:   [(set (reg:CC 0)
                   2121:        (compare:CC
                   2122:         (match_operator:SI 2 "cc_arithop"
                   2123:                            [(match_operand:SI 0 "arith_operand" "%r")
                   2124:                             (match_operand:SI 1 "arith_operand" "rI")])
                   2125:         (const_int 0)))]
                   2126:   ""
                   2127:   "%A2cc %0,%1,%%g0"
                   2128:   [(set_attr "type" "compare")])
                   2129: 
                   2130: (define_insn ""
                   2131:   [(set (reg:CC 0)
                   2132:        (compare:CC
                   2133:         (match_operator:SI 3 "cc_arithop"
                   2134:                            [(match_operand:SI 1 "arith_operand" "%r")
                   2135:                             (match_operand:SI 2 "arith_operand" "rI")])
                   2136:         (const_int 0)))
                   2137:    (set (match_operand:SI 0 "register_operand" "=r")
                   2138:        (match_dup 3))]
                   2139:   ""
                   2140:   "%A3cc %1,%2,%0")
                   2141: 
                   2142: (define_insn ""
                   2143:   [(set (reg:CC 0)
                   2144:        (compare:CC
                   2145:         (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
                   2146:                         (match_operand:SI 1 "arith_operand" "rI")))
                   2147:         (const_int 0)))]
                   2148:   ""
                   2149:   "xnorcc %r0,%1,%%g0"
                   2150:   [(set_attr "type" "compare")])
                   2151: 
                   2152: (define_insn ""
                   2153:   [(set (reg:CC 0)
                   2154:        (compare:CC
                   2155:         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
                   2156:                         (match_operand:SI 2 "arith_operand" "rI")))
                   2157:         (const_int 0)))
                   2158:    (set (match_operand:SI 0 "register_operand" "=r")
                   2159:        (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
                   2160:   ""
                   2161:   "xnorcc %r1,%2,%0")
                   2162: 
                   2163: (define_insn ""
                   2164:   [(set (reg:CC 0)
                   2165:        (compare:CC
                   2166:         (match_operator:SI 2 "cc_arithopn"
                   2167:                            [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
                   2168:                             (match_operand:SI 1 "reg_or_0_operand" "rJ")])
                   2169:         (const_int 0)))]
                   2170:   ""
                   2171:   "%B2cc %r1,%0,%%g0"
                   2172:   [(set_attr "type" "compare")])
                   2173: 
                   2174: (define_insn ""
                   2175:   [(set (reg:CC 0)
                   2176:        (compare:CC
                   2177:         (match_operator:SI 3 "cc_arithopn"
                   2178:                            [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
                   2179:                             (match_operand:SI 2 "reg_or_0_operand" "rJ")])
                   2180:         (const_int 0)))
                   2181:    (set (match_operand:SI 0 "register_operand" "=r")
                   2182:        (match_dup 3))]
                   2183:   ""
                   2184:   "%B3cc %r2,%1,%0")
                   2185: 
                   2186: ;; We cannot use the "neg" pseudo insn because the Sun assembler
                   2187: ;; does not know how to make it work for constants.
                   2188: 
                   2189: (define_insn "negdi2"
                   2190:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2191:        (neg:DI (match_operand:DI 1 "register_operand" "r")))
                   2192:    (clobber (reg:SI 0))]
                   2193:   ""
                   2194:   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
                   2195:   [(set_attr "type" "unary")
                   2196:    (set_attr "length" "2")])
                   2197: 
                   2198: (define_insn "negsi2"
                   2199:   [(set (match_operand:SI 0 "general_operand" "=r")
                   2200:        (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
                   2201:   ""
                   2202:   "sub %%g0,%1,%0"
                   2203:   [(set_attr "type" "unary")])
                   2204: 
                   2205: (define_insn ""
                   2206:   [(set (reg:CC_NOOV 0)
                   2207:        (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
                   2208:                         (const_int 0)))]
                   2209:   ""
                   2210:   "subcc %%g0,%0,%%g0"
                   2211:   [(set_attr "type" "compare")])
                   2212: 
                   2213: (define_insn ""
                   2214:   [(set (reg:CC_NOOV 0)
                   2215:        (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
                   2216:                         (const_int 0)))
                   2217:    (set (match_operand:SI 0 "register_operand" "=r")
                   2218:        (neg:SI (match_dup 1)))]
                   2219:   ""
                   2220:   "subcc %%g0,%1,%0"
                   2221:   [(set_attr "type" "unary")])
                   2222: 
                   2223: ;; We cannot use the "not" pseudo insn because the Sun assembler
                   2224: ;; does not know how to make it work for constants.
                   2225: (define_expand "one_cmpldi2"
                   2226:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2227:        (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
                   2228:   ""
                   2229:   "")
                   2230: 
                   2231: (define_insn ""
                   2232:   [(set (match_operand:DI 0 "register_operand" "=r")
                   2233:        (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
                   2234:   ""
                   2235:   "*
                   2236: {
                   2237:   rtx op1 = operands[1];
                   2238: 
                   2239:   if (GET_CODE (op1) == CONST_INT)
                   2240:     {
                   2241:       int sign = INTVAL (op1);
                   2242:       if (sign < 0)
                   2243:        return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
                   2244:       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
                   2245:     }
                   2246:   else if (GET_CODE (op1) == CONST_DOUBLE)
                   2247:     {
                   2248:       int sign = CONST_DOUBLE_HIGH (op1);
                   2249:       operands[1] = gen_rtx (CONST_INT, VOIDmode,
                   2250:                             CONST_DOUBLE_LOW (operands[1]));
                   2251:       if (sign < 0)
                   2252:        return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
                   2253:       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
                   2254:     }
                   2255:   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
                   2256: }"
                   2257:   [(set_attr "type" "unary")
                   2258:    (set_attr "length" "2")])
                   2259: 
                   2260: (define_insn "one_cmplsi2"
                   2261:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2262:        (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
                   2263:   ""
                   2264:   "xnor %%g0,%1,%0"
                   2265:   [(set_attr "type" "unary")])
                   2266: 
                   2267: (define_insn ""
                   2268:   [(set (reg:CC 0)
                   2269:        (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
                   2270:                    (const_int 0)))]
                   2271:   ""
                   2272:   "xnorcc %%g0,%0,%%g0"
                   2273:   [(set_attr "type" "compare")])
                   2274: 
                   2275: (define_insn ""
                   2276:   [(set (reg:CC 0)
                   2277:        (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
                   2278:                    (const_int 0)))
                   2279:    (set (match_operand:SI 0 "register_operand" "=r")
                   2280:        (not:SI (match_dup 1)))]
                   2281:   ""
                   2282:   "xnorcc %%g0,%1,%0"
                   2283:   [(set_attr "type" "unary")])
                   2284: 
                   2285: ;; Floating point arithmetic instructions.
                   2286: 
1.1.1.3 ! root     2287: (define_insn "addtf3"
        !          2288:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          2289:        (plus:TF (match_operand:TF 1 "register_operand" "f")
        !          2290:                 (match_operand:TF 2 "register_operand" "f")))]
        !          2291:   ""
        !          2292:   "faddq %1,%2,%0"
        !          2293:   [(set_attr "type" "fp")])
        !          2294: 
1.1       root     2295: (define_insn "adddf3"
                   2296:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2297:        (plus:DF (match_operand:DF 1 "register_operand" "f")
                   2298:                 (match_operand:DF 2 "register_operand" "f")))]
                   2299:   ""
                   2300:   "faddd %1,%2,%0"
                   2301:   [(set_attr "type" "fp")])
                   2302: 
                   2303: (define_insn "addsf3"
                   2304:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2305:        (plus:SF (match_operand:SF 1 "register_operand" "f")
                   2306:                 (match_operand:SF 2 "register_operand" "f")))]
                   2307:   ""
                   2308:   "fadds %1,%2,%0"
                   2309:   [(set_attr "type" "fp")])
                   2310: 
1.1.1.3 ! root     2311: (define_insn "subtf3"
        !          2312:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          2313:        (minus:TF (match_operand:TF 1 "register_operand" "f")
        !          2314:                  (match_operand:TF 2 "register_operand" "f")))]
        !          2315:   ""
        !          2316:   "fsubq %1,%2,%0"
        !          2317:   [(set_attr "type" "fp")])
        !          2318: 
1.1       root     2319: (define_insn "subdf3"
                   2320:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2321:        (minus:DF (match_operand:DF 1 "register_operand" "f")
                   2322:                  (match_operand:DF 2 "register_operand" "f")))]
                   2323:   ""
                   2324:   "fsubd %1,%2,%0"
                   2325:   [(set_attr "type" "fp")])
                   2326: 
                   2327: (define_insn "subsf3"
                   2328:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2329:        (minus:SF (match_operand:SF 1 "register_operand" "f")
                   2330:                  (match_operand:SF 2 "register_operand" "f")))]
                   2331:   ""
                   2332:   "fsubs %1,%2,%0"
                   2333:   [(set_attr "type" "fp")])
                   2334: 
1.1.1.3 ! root     2335: (define_insn "multf3"
        !          2336:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          2337:        (mult:TF (match_operand:TF 1 "register_operand" "f")
        !          2338:                 (match_operand:TF 2 "register_operand" "f")))]
        !          2339:   ""
        !          2340:   "fmulq %1,%2,%0"
        !          2341:   [(set_attr "type" "fpmul")])
        !          2342: 
1.1       root     2343: (define_insn "muldf3"
                   2344:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2345:        (mult:DF (match_operand:DF 1 "register_operand" "f")
                   2346:                 (match_operand:DF 2 "register_operand" "f")))]
                   2347:   ""
                   2348:   "fmuld %1,%2,%0"
                   2349:   [(set_attr "type" "fpmul")])
                   2350: 
                   2351: (define_insn "mulsf3"
                   2352:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2353:        (mult:SF (match_operand:SF 1 "register_operand" "f")
                   2354:                 (match_operand:SF 2 "register_operand" "f")))]
                   2355:   ""
                   2356:   "fmuls %1,%2,%0"
                   2357:   [(set_attr "type" "fpmul")])
                   2358: 
1.1.1.3 ! root     2359: (define_insn "divtf3"
        !          2360:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          2361:        (div:TF (match_operand:TF 1 "register_operand" "f")
        !          2362:                (match_operand:TF 2 "register_operand" "f")))]
        !          2363:   ""
        !          2364:   "fdivq %1,%2,%0"
        !          2365:   [(set_attr "type" "fpdiv")])
        !          2366: 
1.1       root     2367: (define_insn "divdf3"
                   2368:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2369:        (div:DF (match_operand:DF 1 "register_operand" "f")
                   2370:                (match_operand:DF 2 "register_operand" "f")))]
                   2371:   ""
                   2372:   "fdivd %1,%2,%0"
                   2373:   [(set_attr "type" "fpdiv")])
                   2374: 
                   2375: (define_insn "divsf3"
                   2376:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2377:        (div:SF (match_operand:SF 1 "register_operand" "f")
                   2378:                (match_operand:SF 2 "register_operand" "f")))]
                   2379:   ""
                   2380:   "fdivs %1,%2,%0"
                   2381:   [(set_attr "type" "fpdiv")])
                   2382: 
1.1.1.3 ! root     2383: (define_insn "negtf2"
        !          2384:   [(set (match_operand:TF 0 "register_operand" "=f,f")
        !          2385:        (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
        !          2386:   ""
        !          2387:   "@
        !          2388:    fnegs %0,%0
        !          2389:    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
        !          2390:   [(set_attr "type" "fp")
        !          2391:    (set_attr "length" "1,4")])
        !          2392: 
1.1       root     2393: (define_insn "negdf2"
                   2394:   [(set (match_operand:DF 0 "register_operand" "=f,f")
                   2395:        (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
                   2396:   ""
                   2397:   "@
                   2398:    fnegs %0,%0
                   2399:    fnegs %1,%0\;fmovs %R1,%R0"
                   2400:   [(set_attr "type" "fp")
                   2401:    (set_attr "length" "1,2")])
                   2402: 
                   2403: (define_insn "negsf2"
                   2404:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2405:        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
                   2406:   ""
                   2407:   "fnegs %1,%0"
                   2408:   [(set_attr "type" "fp")])
                   2409: 
1.1.1.3 ! root     2410: (define_insn "abstf2"
        !          2411:   [(set (match_operand:TF 0 "register_operand" "=f,f")
        !          2412:        (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
        !          2413:   ""
        !          2414:   "@
        !          2415:    fabss %0,%0
        !          2416:    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
        !          2417:   [(set_attr "type" "fp")
        !          2418:    (set_attr "length" "1,4")])
        !          2419: 
1.1       root     2420: (define_insn "absdf2"
                   2421:   [(set (match_operand:DF 0 "register_operand" "=f,f")
                   2422:        (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
                   2423:   ""
                   2424:   "@
                   2425:    fabss %0,%0
                   2426:    fabss %1,%0\;fmovs %R1,%R0"
                   2427:   [(set_attr "type" "fp")
                   2428:    (set_attr "length" "1,2")])
                   2429: 
                   2430: (define_insn "abssf2"
                   2431:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2432:        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
                   2433:   ""
                   2434:   "fabss %1,%0"
                   2435:   [(set_attr "type" "fp")])
                   2436: 
1.1.1.3 ! root     2437: (define_insn "sqrttf2"
        !          2438:   [(set (match_operand:TF 0 "register_operand" "=f")
        !          2439:        (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
        !          2440:   ""
        !          2441:   "fsqrtq %1,%0"
        !          2442:   [(set_attr "type" "fpsqrt")])
        !          2443: 
1.1       root     2444: (define_insn "sqrtdf2"
                   2445:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2446:        (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
                   2447:   ""
                   2448:   "fsqrtd %1,%0"
                   2449:   [(set_attr "type" "fpsqrt")])
                   2450: 
                   2451: (define_insn "sqrtsf2"
                   2452:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2453:        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
                   2454:   ""
                   2455:   "fsqrts %1,%0"
                   2456:   [(set_attr "type" "fpsqrt")])
                   2457: 
                   2458: ;;- arithmetic shift instructions
                   2459: 
                   2460: ;; We can trivially handle shifting the constant 1 by 64 bits.
                   2461: ;; For other shifts we use the library routine.
                   2462: ;; ??? Questionable, we can do better than this can't we?
                   2463: (define_expand "ashldi3"
                   2464:   [(parallel [(set (match_operand:DI 0 "register_operand" "")
                   2465:                   (ashift:DI (match_operand:DI 1 "const_double_operand" "")
                   2466:                              (match_operand:SI 2 "register_operand" "")))
                   2467:              (clobber (reg:SI 0))])]
                   2468:   ""
                   2469:   "
                   2470: {
                   2471:   if (GET_CODE (operands[1]) == CONST_DOUBLE
                   2472:       && CONST_DOUBLE_HIGH (operands[1]) == 0
                   2473:       && CONST_DOUBLE_LOW (operands[1]) == 1)
                   2474:     operands[1] = const1_rtx;
                   2475:   else if (operands[1] != const1_rtx)
                   2476:     FAIL;
                   2477: }")
                   2478: 
                   2479: ;; ??? Questionable, we can do better than this can't we?
                   2480: (define_insn ""
                   2481:   [(set (match_operand:DI 0 "register_operand" "=&r")
                   2482:        (ashift:DI (const_int 1)
1.1.1.3 ! root     2483:                   (match_operand:SI 1 "register_operand" "r")))
1.1       root     2484:    (clobber (reg:SI 0))]
                   2485:   ""
1.1.1.3 ! root     2486:   "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
1.1       root     2487:   [(set_attr "type" "multi")
                   2488:    (set_attr "length" "5")])
                   2489: 
                   2490: (define_insn "ashlsi3"
                   2491:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2492:        (ashift:SI (match_operand:SI 1 "register_operand" "r")
                   2493:                   (match_operand:SI 2 "arith_operand" "rI")))]
                   2494:   ""
                   2495:   "sll %1,%2,%0")
                   2496: 
                   2497: (define_insn "ashrsi3"
                   2498:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2499:        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
                   2500:                     (match_operand:SI 2 "arith_operand" "rI")))]
                   2501:   ""
                   2502:   "sra %1,%2,%0")
                   2503: 
                   2504: (define_insn "lshrsi3"
                   2505:   [(set (match_operand:SI 0 "register_operand" "=r")
                   2506:        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
                   2507:                     (match_operand:SI 2 "arith_operand" "rI")))]
                   2508:   ""
                   2509:   "srl %1,%2,%0")
                   2510: 
                   2511: ;; Unconditional and other jump instructions
                   2512: ;; Note that for the Sparc, by setting the annul bit on an unconditional
                   2513: ;; branch, the following insn is never executed.  This saves us a nop,
1.1.1.2   root     2514: ;; but requires a debugger which can handle annulled branches.
1.1       root     2515: (define_insn "jump"
                   2516:   [(set (pc) (label_ref (match_operand 0 "" "")))]
                   2517:   ""
                   2518:   "b%* %l0"
                   2519:   [(set_attr "type" "branch")])
                   2520: 
                   2521: (define_expand "tablejump"
                   2522:   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
                   2523:              (use (label_ref (match_operand 1 "" "")))])]
                   2524:   ""
                   2525:   "
                   2526: {
                   2527:   /* We need to use the PC value in %o7 that was set up when the address
                   2528:      of the label was loaded into a register, so we need different RTL.  */
                   2529:   if (flag_pic)
                   2530:     {
                   2531:       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
                   2532:       DONE;
                   2533:     }
                   2534: }")
                   2535: 
                   2536: (define_insn "pic_tablejump"
                   2537:   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
                   2538:    (use (label_ref (match_operand 1 "" "")))
                   2539:    (use (reg:SI 15))]
                   2540:   ""
                   2541:   "jmp %%o7+%0%#"
                   2542:   [(set_attr "type" "branch")])
                   2543: 
                   2544: (define_insn ""
                   2545:   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
                   2546:    (use (label_ref (match_operand 1 "" "")))]
                   2547:   ""
                   2548:   "jmp %a0%#"
                   2549:   [(set_attr "type" "branch")])
                   2550: 
                   2551: (define_insn ""
                   2552:   [(set (pc) (label_ref (match_operand 0 "" "")))
                   2553:    (set (reg:SI 15) (label_ref (match_dup 0)))]
                   2554:   ""
                   2555:   "call %l0%#"
                   2556:   [(set_attr "type" "branch")])
                   2557: 
                   2558: ;; This pattern recognizes the "instruction" that appears in 
                   2559: ;; a function call that wants a structure value, 
                   2560: ;; to inform the called function if compiled with Sun CC.
                   2561: ;(define_insn ""
                   2562: ;  [(match_operand:SI 0 "immediate_operand" "")]
                   2563: ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
                   2564: ;  "unimp %0"
                   2565: ;  [(set_attr "type" "marker")])
                   2566: 
                   2567: ;;- jump to subroutine
                   2568: (define_expand "call"
                   2569:   ;; Note that this expression is not used for generating RTL.
                   2570:   ;; All the RTL is generated explicitly below.
                   2571:   [(call (match_operand:SI 0 "call_operand" "")
                   2572:         (match_operand 3 "" "i"))]
                   2573:   ;; operands[2] is next_arg_register
                   2574:   ;; operands[3] is struct_value_size_rtx.
                   2575:   ""
                   2576:   "
                   2577: {
                   2578:   rtx fn_rtx, nregs_rtx;
                   2579: 
                   2580:   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
                   2581:     {
                   2582:       /* This is really a PIC sequence.  We want to represent
                   2583:         it as a funny jump so it's delay slots can be filled. 
                   2584: 
                   2585:         ??? But if this really *is* a CALL, will not it clobber the
                   2586:         call-clobbered registers?  We lose this if it is a JUMP_INSN.
                   2587:         Why cannot we have delay slots filled if it were a CALL?  */
                   2588: 
                   2589:       if (INTVAL (operands[3]) > 0)
                   2590:        emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
                   2591:                                 gen_rtx (SET, VOIDmode, pc_rtx,
                   2592:                                          XEXP (operands[0], 0)),
                   2593:                                 operands[3],
                   2594:                                 gen_rtx (CLOBBER, VOIDmode,
                   2595:                                          gen_rtx (REG, SImode, 15)))));
                   2596:       else
                   2597:        emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
                   2598:                                 gen_rtx (SET, VOIDmode, pc_rtx,
                   2599:                                          XEXP (operands[0], 0)),
                   2600:                                 gen_rtx (CLOBBER, VOIDmode,
                   2601:                                          gen_rtx (REG, SImode, 15)))));
                   2602:       goto finish_call;
                   2603:     }
                   2604: 
                   2605:   fn_rtx = operands[0];
                   2606: 
                   2607:   /* Count the number of parameter registers being used by this call.
                   2608:      if that argument is NULL, it means we are using them all, which
                   2609:      means 6 on the sparc.  */
                   2610: #if 0
                   2611:   if (operands[2])
                   2612:     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
                   2613:   else
                   2614:     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
                   2615: #else
                   2616:   nregs_rtx = const0_rtx;
                   2617: #endif
                   2618: 
                   2619:   if (INTVAL (operands[3]) > 0)
                   2620:     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
                   2621:                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
                   2622:                             operands[3],
                   2623:                             gen_rtx (CLOBBER, VOIDmode,
                   2624:                                               gen_rtx (REG, SImode, 15)))));
                   2625:   else
                   2626:     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
                   2627:                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
                   2628:                             gen_rtx (CLOBBER, VOIDmode,
                   2629:                                               gen_rtx (REG, SImode, 15)))));
                   2630: 
                   2631:  finish_call:
                   2632: #if 0
                   2633:   /* If this call wants a structure value,
                   2634:      emit an unimp insn to let the called function know about this.  */
                   2635:   if (INTVAL (operands[3]) > 0)
                   2636:     {
                   2637:       rtx insn = emit_insn (operands[3]);
                   2638:       SCHED_GROUP_P (insn) = 1;
                   2639:     }
                   2640: #endif
                   2641: 
                   2642:   DONE;
                   2643: }")
                   2644: 
                   2645: (define_insn ""
                   2646:   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
                   2647:         (match_operand 1 "" ""))
                   2648:    (clobber (reg:SI 15))]
                   2649:   ;;- Do not use operand 1 for most machines.
                   2650:   ""
                   2651:   "*
                   2652: {
                   2653:   return \"call %a0,%1%#\";
                   2654: }"
                   2655:   [(set_attr "type" "call")])
                   2656: 
                   2657: ;; This is a call that wants a structure value.
                   2658: (define_insn ""
                   2659:   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
                   2660:         (match_operand 1 "" ""))
                   2661:    (match_operand 2 "immediate_operand" "")
                   2662:    (clobber (reg:SI 15))]
                   2663:   ;;- Do not use operand 1 for most machines.
                   2664:   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
                   2665:   "*
                   2666: {
                   2667:   return \"call %a0,%1\;nop\;unimp %2\";
                   2668: }"
                   2669:   [(set_attr "type" "call_no_delay_slot")])
                   2670: 
                   2671: (define_expand "call_value"
                   2672:   [(set (match_operand 0 "register_operand" "=rf")
                   2673:        (call (match_operand:SI 1 "" "")
                   2674:              (match_operand 4 "" "")))]
                   2675:   ;; operand 3 is next_arg_register
                   2676:   ""
                   2677:   "
                   2678: {
                   2679:   rtx fn_rtx, nregs_rtx;
                   2680:   rtvec vec;
                   2681: 
                   2682:   fn_rtx = operands[1];
                   2683: 
                   2684: #if 0
                   2685:   if (operands[3])
                   2686:     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
                   2687:   else
                   2688:     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
                   2689: #else
                   2690:   nregs_rtx = const0_rtx;
                   2691: #endif
                   2692: 
                   2693:   vec = gen_rtvec (2,
                   2694:                   gen_rtx (SET, VOIDmode, operands[0],
                   2695:                            gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
                   2696:                   gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
                   2697: 
                   2698:   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
                   2699: 
                   2700:   DONE;
                   2701: }")
                   2702: 
                   2703: (define_insn ""
                   2704:   [(set (match_operand 0 "" "=rf")
                   2705:        (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
                   2706:              (match_operand 2 "" "")))
                   2707:    (clobber (reg:SI 15))]
                   2708:   ;;- Do not use operand 2 for most machines.
                   2709:   ""
                   2710:   "*
                   2711: {
                   2712:   return \"call %a1,%2%#\";
                   2713: }"
                   2714:   [(set_attr "type" "call")])
                   2715: 
                   2716: (define_insn "return"
                   2717:   [(return)]
                   2718:   "! TARGET_EPILOGUE"
                   2719:   "* return output_return (operands);"
                   2720:   [(set_attr "type" "multi")])
                   2721: 
                   2722: (define_insn "nop"
                   2723:   [(const_int 0)]
                   2724:   ""
                   2725:   "nop")
                   2726: 
                   2727: (define_insn "indirect_jump"
                   2728:   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
                   2729:   ""
                   2730:  "jmp %a0%#"
                   2731:  [(set_attr "type" "branch")])
                   2732:  
                   2733: (define_expand "nonlocal_goto"
                   2734:   [(match_operand:SI 0 "general_operand" "")
                   2735:    (match_operand:SI 1 "general_operand" "")
                   2736:    (match_operand:SI 2 "general_operand" "")
                   2737:    (match_operand:SI 3 "" "")]
                   2738:   ""
                   2739:   "
                   2740: {
                   2741:   rtx temp;
                   2742:   /* Trap instruction to flush all the registers window.  */
                   2743:   emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
                   2744:                      gen_rtvec (1, const0_rtx), 0));
                   2745:   /* Load the fp value for the containing fn into %fp.
                   2746:      This is needed because operands[2] refers to %fp.  */
                   2747:   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
                   2748:   /* Find the containing function's current nonlocal goto handler,
                   2749:      which will do any cleanups and then jump to the label.  */
                   2750:   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
                   2751:   /* Restore %fp from stack pointer value for containing function.
                   2752:      The restore insn that follows will move this to %sp,
                   2753:      and reload the appropriate value into %fp.  */
                   2754:   emit_move_insn (frame_pointer_rtx, operands[2]);
                   2755:   /* Put in the static chain register the nonlocal label address.  */
                   2756:   emit_move_insn (static_chain_rtx, operands[3]);
                   2757:   /* USE of frame_pointer_rtx added for consistency; not clear if
                   2758:      really needed.  */
                   2759:   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
                   2760:   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
                   2761:   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
                   2762:   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
                   2763:   /* Return, restoring reg window and jumping to goto handler.  */
                   2764:   emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
                   2765:                      gen_rtvec (1, const0_rtx), 1));
                   2766:   DONE;
                   2767: }")
                   2768: 
                   2769: ;; Special trap insn to flush register windows.
                   2770: (define_insn ""
                   2771:   [(unspec_volatile [(const_int 0)] 0)]
                   2772:   ""
1.1.1.2   root     2773:   "ta 3"
                   2774:   [(set_attr "type" "misc")])
1.1       root     2775: 
                   2776: (define_insn ""
                   2777:   [(unspec_volatile [(const_int 0)] 1)]
                   2778:   ""
1.1.1.2   root     2779:   "jmp %%o0+0\;restore"
                   2780:   [(set_attr "type" "misc")
                   2781:    (set_attr "length" "2")])
1.1       root     2782: 
                   2783: ;; Split up troublesome insns for better scheduling.  */
                   2784: 
                   2785: ;; The following patterns are straightforward.  They can be applied
                   2786: ;; either before or after register allocation.
                   2787: 
                   2788: (define_split
                   2789:   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
                   2790:        (match_operand 2 "reg_or_0_operand" ""))
                   2791:    (clobber (match_operand:SI 3 "register_operand" ""))]
                   2792:   "! flag_pic"
                   2793:   [(set (match_dup 3) (high:SI (match_dup 1)))
                   2794:    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
                   2795:        (match_dup 2))]
                   2796:   "")
                   2797: 
                   2798: (define_split
                   2799:   [(set (match_operator 0 "memop"
                   2800:                        [(match_operand:SI 1 "immediate_operand" "")])
                   2801:        (match_operand 2 "general_operand" ""))
                   2802:    (clobber (match_operand:SI 3 "register_operand" ""))]
                   2803:   "flag_pic"
                   2804:   [(set (match_op_dup 0 [(match_dup 1)])
                   2805:        (match_dup 2))]
                   2806:   "
                   2807: {
                   2808:   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
                   2809:                                        operands[3], 0);
                   2810: }")
                   2811: 
                   2812: (define_split
                   2813:   [(set (match_operand 0 "register_operand" "")
                   2814:        (match_operator 1 "memop"
                   2815:                        [(match_operand:SI 2 "immediate_operand" "")]))]
                   2816:   "flag_pic"
                   2817:   [(set (match_dup 0)
                   2818:        (match_op_dup 1 [(match_dup 2)]))]
                   2819:   "
                   2820: {
                   2821:   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
                   2822:                                        operands[0], 0);
                   2823: }")
                   2824: 
                   2825: ;; Sign- and Zero-extend operations can have symbolic memory operands.
                   2826: 
                   2827: (define_split
                   2828:   [(set (match_operand 0 "register_operand" "")
                   2829:        (match_operator 1 "extend_op"
                   2830:                        [(match_operator 2 "memop"
                   2831:                                         [(match_operand:SI 3 "immediate_operand" "")])]))]
                   2832:   "flag_pic"
                   2833:   [(set (match_dup 0)
                   2834:        (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
                   2835:   "
                   2836: {
                   2837:   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
                   2838:                                        operands[0], 0);
                   2839: }")
                   2840: 
                   2841: (define_split
                   2842:   [(set (match_operand:SI 0 "register_operand" "")
                   2843:        (match_operand:SI 1 "immediate_operand" ""))]
                   2844:   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
                   2845:                  || GET_CODE (operands[1]) == CONST
                   2846:                  || GET_CODE (operands[1]) == LABEL_REF)"
                   2847:   [(set (match_dup 0) (high:SI (match_dup 1)))
                   2848:    (set (match_dup 0)
                   2849:        (lo_sum:SI (match_dup 0) (match_dup 1)))]
                   2850:   "")
                   2851: 
                   2852: ;; LABEL_REFs are not modified by `legitimize_pic_address`
                   2853: ;; so do not recurse infinitely in the PIC case.
                   2854: (define_split
                   2855:   [(set (match_operand:SI 0 "register_operand" "")
                   2856:        (match_operand:SI 1 "immediate_operand" ""))]
                   2857:   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
                   2858:                || GET_CODE (operands[1]) == CONST)"
                   2859:   [(set (match_dup 0) (match_dup 1))]
                   2860:   "
                   2861: {
                   2862:   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
                   2863: }")
                   2864: 
                   2865: ;; These split sne/seq insns.  The forms of the resulting insns are 
                   2866: ;; somewhat bogus, but they avoid extra patterns and show data dependency.
                   2867: ;; Nothing will look at these in detail after splitting has occurred.
                   2868: 
                   2869: (define_split
                   2870:   [(set (match_operand:SI 0 "register_operand" "")
                   2871:        (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
                   2872:    (clobber (reg:CC 0))]
                   2873:   ""
                   2874:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2875:                                         (const_int 0)))
                   2876:    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
                   2877:   "")
                   2878: 
                   2879: (define_split
                   2880:   [(set (match_operand:SI 0 "register_operand" "")
                   2881:        (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
                   2882:                       (const_int 0))))
                   2883:    (clobber (reg:CC 0))]
                   2884:   ""
                   2885:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2886:                                         (const_int 0)))
                   2887:    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
                   2888:   "")
                   2889: 
                   2890: (define_split
                   2891:   [(set (match_operand:SI 0 "register_operand" "")
                   2892:        (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
                   2893:    (clobber (reg:CC 0))]
                   2894:   ""
                   2895:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2896:                                         (const_int 0)))
                   2897:    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
                   2898:   "")
                   2899: 
                   2900: (define_split
                   2901:   [(set (match_operand:SI 0 "register_operand" "")
                   2902:        (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
                   2903:                       (const_int 0))))
                   2904:    (clobber (reg:CC 0))]
                   2905:   ""
                   2906:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2907:                                         (const_int 0)))
                   2908:    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
                   2909:   "")
                   2910: 
                   2911: (define_split
                   2912:   [(set (match_operand:SI 0 "register_operand" "")
                   2913:        (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
                   2914:                        (const_int 0))
                   2915:                 (match_operand:SI 2 "register_operand" "")))
                   2916:    (clobber (reg:CC 0))]
                   2917:   ""
                   2918:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2919:                                         (const_int 0)))
                   2920:    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
                   2921:                               (match_dup 2)))]
                   2922:   "")
                   2923: 
                   2924: (define_split
                   2925:   [(set (match_operand:SI 0 "register_operand" "")
                   2926:        (minus:SI (match_operand:SI 2 "register_operand" "")
                   2927:                  (ne:SI (match_operand:SI 1 "register_operand" "")
                   2928:                         (const_int 0))))
                   2929:    (clobber (reg:CC 0))]
                   2930:   ""
                   2931:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2932:                                         (const_int 0)))
                   2933:    (set (match_dup 0) (minus:SI (match_dup 2)
                   2934:                                (ltu:SI (reg:CC 0) (const_int 0))))]
                   2935:   "")
                   2936: 
                   2937: (define_split
                   2938:   [(set (match_operand:SI 0 "register_operand" "")
                   2939:        (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
                   2940:                        (const_int 0))
                   2941:                 (match_operand:SI 2 "register_operand" "")))
                   2942:    (clobber (reg:CC 0))]
                   2943:   ""
                   2944:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2945:                                         (const_int 0)))
                   2946:    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
                   2947:                               (match_dup 2)))]
                   2948:   "")
                   2949: 
                   2950: (define_split
                   2951:   [(set (match_operand:SI 0 "register_operand" "")
                   2952:        (minus:SI (match_operand:SI 2 "register_operand" "")
                   2953:                  (eq:SI (match_operand:SI 1 "register_operand" "")
                   2954:                         (const_int 0))))
                   2955:    (clobber (reg:CC 0))]
                   2956:   ""
                   2957:   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
                   2958:                                         (const_int 0)))
                   2959:    (set (match_dup 0) (minus:SI (match_dup 2)
                   2960:                                (geu:SI (reg:CC 0) (const_int 0))))]
                   2961:   "")
                   2962: 
                   2963: ;; Peepholes go at the end.
                   2964: 
1.1.1.3 ! root     2965: ;; Optimize consecutive loads or stores into ldd and std when possible.
        !          2966: ;; The conditions in which we do this are very restricted and are 
        !          2967: ;; explained in the code for {registers,memory}_ok_for_ldd functions.
        !          2968: 
        !          2969: (define_peephole
        !          2970:   [(set (match_operand:SI 0 "register_operand" "r")
        !          2971:         (match_operand:SI 1 "memory_operand" ""))
        !          2972:    (set (match_operand:SI 2 "register_operand" "r")
        !          2973:         (match_operand:SI 3 "memory_operand" ""))]
        !          2974:   "registers_ok_for_ldd (operands[0], operands[2]) 
        !          2975:    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
        !          2976:    && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
        !          2977:   "ldd %1,%0")
        !          2978: 
        !          2979: (define_peephole
        !          2980:   [(set (match_operand:SI 0 "memory_operand" "")
        !          2981:         (match_operand:SI 1 "register_operand" "r"))
        !          2982:    (set (match_operand:SI 2 "memory_operand" "")
        !          2983:         (match_operand:SI 3 "register_operand" "r"))]
        !          2984:   "registers_ok_for_ldd (operands[1], operands[3]) 
        !          2985:    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
        !          2986:    && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
        !          2987:   "std %1,%0")
        !          2988:  
        !          2989: (define_peephole
        !          2990:   [(set (match_operand:SF 0 "register_operand" "fr")
        !          2991:         (match_operand:SF 1 "memory_operand" ""))
        !          2992:    (set (match_operand:SF 2 "register_operand" "fr")
        !          2993:         (match_operand:SF 3 "memory_operand" ""))]
        !          2994:   "registers_ok_for_ldd (operands[0], operands[2]) 
        !          2995:    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
        !          2996:    && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
        !          2997:   "ldd %1,%0")
        !          2998: 
        !          2999: (define_peephole
        !          3000:   [(set (match_operand:SF 0 "memory_operand" "")
        !          3001:         (match_operand:SF 1 "register_operand" "fr"))
        !          3002:    (set (match_operand:SF 2 "memory_operand" "")
        !          3003:         (match_operand:SF 3 "register_operand" "fr"))]
        !          3004:   "registers_ok_for_ldd (operands[1], operands[3]) 
        !          3005:    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
        !          3006:    && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
        !          3007:   "std %1,%0")
        !          3008: 
        !          3009: (define_peephole
        !          3010:   [(set (match_operand:SI 0 "register_operand" "r")
        !          3011:         (match_operand:SI 1 "memory_operand" ""))
        !          3012:    (set (match_operand:SI 2 "register_operand" "r")
        !          3013:         (match_operand:SI 3 "memory_operand" ""))]
        !          3014:   "registers_ok_for_ldd (operands[2], operands[0]) 
        !          3015:    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
        !          3016:    && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
        !          3017:   "ldd %3,%2")
        !          3018: 
        !          3019: (define_peephole
        !          3020:   [(set (match_operand:SI 0 "memory_operand" "")
        !          3021:         (match_operand:SI 1 "register_operand" "r"))
        !          3022:    (set (match_operand:SI 2 "memory_operand" "")
        !          3023:         (match_operand:SI 3 "register_operand" "r"))]
        !          3024:   "registers_ok_for_ldd (operands[3], operands[1]) 
        !          3025:    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
        !          3026:    && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
        !          3027:   "std %3,%2")
        !          3028:  
        !          3029: (define_peephole
        !          3030:   [(set (match_operand:SF 0 "register_operand" "fr")
        !          3031:         (match_operand:SF 1 "memory_operand" ""))
        !          3032:    (set (match_operand:SF 2 "register_operand" "fr")
        !          3033:         (match_operand:SF 3 "memory_operand" ""))]
        !          3034:   "registers_ok_for_ldd (operands[2], operands[0]) 
        !          3035:    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
        !          3036:    && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
        !          3037:   "ldd %3,%2")
        !          3038: 
        !          3039: (define_peephole
        !          3040:   [(set (match_operand:SF 0 "memory_operand" "")
        !          3041:         (match_operand:SF 1 "register_operand" "fr"))
        !          3042:    (set (match_operand:SF 2 "memory_operand" "")
        !          3043:         (match_operand:SF 3 "register_operand" "fr"))]
        !          3044:   "registers_ok_for_ldd (operands[3], operands[1]) 
        !          3045:    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
        !          3046:    && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
        !          3047:   "std %3,%2")
        !          3048:  
1.1       root     3049: ;; Optimize the case of following a reg-reg move with a test
                   3050: ;; of reg just moved.
                   3051: 
                   3052: (define_peephole
                   3053:   [(set (match_operand:SI 0 "register_operand" "=r")
                   3054:        (match_operand:SI 1 "register_operand" "r"))
                   3055:    (set (reg:CC 0)
                   3056:        (compare:CC (match_operand:SI 2 "register_operand" "r")
                   3057:                    (const_int 0)))]
                   3058:   "rtx_equal_p (operands[2], operands[0])
                   3059:    || rtx_equal_p (operands[2], operands[1])"
1.1.1.2   root     3060:   "orcc %1,%%g0,%0")
1.1       root     3061: 
                   3062: ;; Do {sign,zero}-extended compares somewhat more efficiently.
                   3063: ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
                   3064: ;;     eventually have some impact here?
                   3065: 
                   3066: (define_peephole
                   3067:   [(set (match_operand:HI 0 "register_operand" "")
                   3068:        (match_operand:HI 1 "memory_operand" ""))
                   3069:    (set (match_operand:SI 2 "register_operand" "")
                   3070:        (sign_extend:SI (match_dup 0)))
                   3071:    (set (reg:CC 0)
                   3072:        (compare:CC (match_dup 2)
                   3073:                    (const_int 0)))]
                   3074:   ""
                   3075:   "ldsh %1,%0\;orcc %0,%%g0,%2")
                   3076: 
                   3077: (define_peephole
                   3078:   [(set (match_operand:QI 0 "register_operand" "")
                   3079:        (match_operand:QI 1 "memory_operand" ""))
                   3080:    (set (match_operand:SI 2 "register_operand" "")
                   3081:        (sign_extend:SI (match_dup 0)))
                   3082:    (set (reg:CC 0)
                   3083:        (compare:CC (match_dup 2)
                   3084:                    (const_int 0)))]
                   3085:   ""
                   3086:   "ldsb %1,%0\;orcc %0,%%g0,%2")
                   3087: 
                   3088: (define_peephole
                   3089:   [(set (match_operand:HI 0 "register_operand" "")
                   3090:        (match_operand:HI 1 "memory_operand" ""))
                   3091:    (set (match_operand:SI 2 "register_operand" "")
                   3092:        (sign_extend:SI (match_dup 0)))]
                   3093:   "dead_or_set_p (insn, operands[0])"
                   3094:   "*
                   3095: {
                   3096:   warning (\"bad peephole\");
                   3097:   if (! MEM_VOLATILE_P (operands[1]))
                   3098:     abort ();
                   3099:   return \"ldsh %1,%2\";
                   3100: }")
                   3101: 
                   3102: (define_peephole
                   3103:   [(set (match_operand:QI 0 "register_operand" "")
                   3104:        (match_operand:QI 1 "memory_operand" ""))
                   3105:    (set (match_operand:SI 2 "register_operand" "")
                   3106:        (sign_extend:SI (match_dup 0)))]
                   3107:   "dead_or_set_p (insn, operands[0])"
                   3108:   "*
                   3109: {
                   3110:   warning (\"bad peephole\");
                   3111:   if (! MEM_VOLATILE_P (operands[1]))
                   3112:     abort ();
                   3113:   return \"ldsb %1,%2\";
                   3114: }")
                   3115: 
                   3116: ;; Floating-point move peepholes
                   3117: 
                   3118: (define_peephole
                   3119:   [(set (match_operand:SI 0 "register_operand" "=r")
                   3120:        (lo_sum:SI (match_dup 0)
                   3121:                   (match_operand:SI 1 "immediate_operand" "i")))
                   3122:    (set (match_operand:DF 2 "register_operand" "=fr")
                   3123:        (mem:DF (match_dup 0)))]
                   3124:   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
                   3125:   "*
                   3126: {
                   3127:   /* Go by way of output_move_double in case the register in operand 2
                   3128:      is not properly aligned for ldd.  */
                   3129:   operands[1] = gen_rtx (MEM, DFmode,
                   3130:                         gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
                   3131:   operands[0] = operands[2];
                   3132:   return output_move_double (operands);
                   3133: }")
                   3134: 
                   3135: (define_peephole
                   3136:   [(set (match_operand:SI 0 "register_operand" "=r")
                   3137:        (lo_sum:SI (match_dup 0)
                   3138:                   (match_operand:SI 1 "immediate_operand" "i")))
                   3139:    (set (match_operand:SF 2 "register_operand" "=fr")
                   3140:        (mem:SF (match_dup 0)))]
                   3141:   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
                   3142:   "ld [%0+%%lo(%a1)],%2")
                   3143: 
                   3144: ;; Return peepholes.  First the "normal" ones
                   3145: 
                   3146: (define_insn ""
                   3147:   [(set (match_operand:SI 0 "restore_operand" "")
                   3148:        (match_operand:SI 1 "arith_operand" "rI"))
                   3149:    (return)]
                   3150:   "! TARGET_EPILOGUE"
                   3151:   "*
                   3152: {
                   3153:   if (current_function_returns_struct)
                   3154:     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
                   3155:   else
                   3156:     return \"ret\;restore %%g0,%1,%Y0\";
                   3157: }"
                   3158:   [(set_attr "type" "multi")])
                   3159: 
                   3160: (define_insn ""
                   3161:   [(set (match_operand:SI 0 "restore_operand" "")
                   3162:        (plus:SI (match_operand:SI 1 "arith_operand" "%r")
                   3163:                 (match_operand:SI 2 "arith_operand" "rI")))
                   3164:    (return)]
                   3165:   "! TARGET_EPILOGUE"
                   3166:   "*
                   3167: {
                   3168:   if (current_function_returns_struct)
                   3169:     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
                   3170:   else
                   3171:     return \"ret\;restore %r1,%2,%Y0\";
                   3172: }"
                   3173:   [(set_attr "type" "multi")])
                   3174: 
                   3175: ;; Turned off because it should never match (subtracting a constant
                   3176: ;; is turned into addition) and because it would do the wrong thing
                   3177: ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
                   3178: ;;(define_insn ""
                   3179: ;;  [(set (match_operand:SI 0 "restore_operand" "")
                   3180: ;;     (minus:SI (match_operand:SI 1 "register_operand" "r")
                   3181: ;;               (match_operand:SI 2 "small_int" "I")))
                   3182: ;;   (return)]
                   3183: ;;  "! TARGET_EPILOGUE"
                   3184: ;;  "ret\;restore %1,-(%2),%Y0"
                   3185: ;;  [(set_attr "type" "multi")])
                   3186: 
                   3187: ;; The following pattern is only generated by delayed-branch scheduling,
                   3188: ;; when the insn winds up in the epilogue.
                   3189: (define_insn ""
                   3190:   [(set (reg:SF 32)
                   3191:        (match_operand:SF 0 "register_operand" "f"))
                   3192:    (return)]
                   3193:   "! TARGET_EPILOGUE"
1.1.1.2   root     3194:   "ret\;fmovs %0,%%f0"
                   3195:   [(set_attr "type" "multi")])
1.1       root     3196: 
                   3197: ;; Now peepholes to go a call followed by a jump.
                   3198: 
                   3199: (define_peephole
                   3200:   [(parallel [(set (match_operand 0 "" "")
                   3201:                   (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
                   3202:                         (match_operand 2 "" "")))
                   3203:              (clobber (reg:SI 15))])
                   3204:    (set (pc) (label_ref (match_operand 3 "" "")))]
                   3205:   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
                   3206:   "*
                   3207: {
                   3208:   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
                   3209: }")
                   3210: 
                   3211: (define_peephole
                   3212:   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
                   3213:                    (match_operand 1 "" ""))
                   3214:              (clobber (reg:SI 15))])
                   3215:    (set (pc) (label_ref (match_operand 2 "" "")))]
                   3216:   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
                   3217:   "*
                   3218: {
                   3219:   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
                   3220: }")
                   3221: 
                   3222: (define_peephole
                   3223:   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
                   3224:                   (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
                   3225:                             (reg:SI 0)))
                   3226:              (clobber (reg:CC 0))])
                   3227:    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
                   3228:   ""
1.1.1.2   root     3229:   "subxcc %r1,0,%0")
1.1       root     3230: 
                   3231: ;;- Local variables:
                   3232: ;;- mode:emacs-lisp
                   3233: ;;- comment-start: ";;- "
                   3234: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
                   3235: ;;- eval: (modify-syntax-entry ?[ "(]")
                   3236: ;;- eval: (modify-syntax-entry ?] ")[")
                   3237: ;;- eval: (modify-syntax-entry ?{ "(}")
                   3238: ;;- eval: (modify-syntax-entry ?} "){")
                   3239: ;;- End:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.