Annotation of gcc/config/i386.md, revision 1.1.1.1

1.1       root        1: ;; GCC machine description for Intel 80386.
                      2: ;; Copyright (C) 1988 Free Software Foundation, Inc.
                      3: ;; Mostly by William Schelter.
                      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: ;;- instruction definitions
                     23: 
                     24: ;;- @@The original PO technology requires these to be ordered by speed,
                     25: ;;- @@    so that assigner will pick the fastest.
                     26: 
                     27: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
                     28: 
                     29: ;;- When naming insn's (operand 0 of define_insn) be careful about using
                     30: ;;- names from other targets machine descriptions.
                     31: 
                     32: ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
                     33: ;;- updates for most instructions.
                     34: 
                     35: ;;- Operand classes for the register allocator:
                     36: ;;- 'a' for eax
                     37: ;;- 'd' for edx
                     38: ;;- 'c' for ecx
                     39: ;;- 'b' for ebx
                     40: ;;- 'f' for anything in FLOAT_REGS
                     41: ;;- 'r' any (non-floating-point) register
                     42: ;;- 'q' regs that allow byte operations (A, B, C and D)
                     43: ;;- 'A' A and D registers
                     44: 
                     45: ;; the special asm out single letter directives following a '%' are:
                     46: ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of operands[1]
                     47: ;; 's' output a '*'
                     48: ;; 'w' If the operand is a REG, it uses the mode size to determine the
                     49: ;;      printing of the reg
                     50: 
                     51: 
                     52: 
                     53: ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM".
                     54: ;; But restricting MEM here would mean that gcc could not remove a redundant
                     55: ;; test in cases like "incl MEM / je TARGET".
                     56: ;;
                     57: ;; We don't want to allow a constant operand for test insns because
                     58: ;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
                     59: ;; be folded while optimizing anyway.
                     60: 
                     61: (define_insn "tstsi"
                     62:   [(set (cc0)
                     63:        (match_operand:SI 0 "nonimmediate_operand" "rm"))]
                     64:   ""
                     65:   "*
                     66: {
                     67:   if (REG_P (operands[0]))
                     68:     return AS2 (test%L0,%0,%0);
                     69: 
                     70:   operands[1] = const0_rtx;
                     71:   return AS2 (cmp%L0,%1,%0);
                     72: }")
                     73: 
                     74: (define_insn "tsthi"
                     75:   [(set (cc0)
                     76:        (match_operand:HI 0 "nonimmediate_operand" "rm"))]
                     77:   ""
                     78:   "*
                     79: {
                     80:   if (REG_P (operands[0]))
                     81:     return AS2 (test%W0,%0,%0);
                     82: 
                     83:   operands[1] = const0_rtx;
                     84:   return AS2 (cmp%W0,%1,%0);
                     85: }")
                     86: 
                     87: (define_insn "tstqi"
                     88:   [(set (cc0)
                     89:        (match_operand:QI 0 "nonimmediate_operand" "qm"))]
                     90:   ""
                     91:   "*
                     92: {
                     93:   if (REG_P (operands[0]))
                     94:     return AS2 (test%B0,%0,%0);
                     95: 
                     96:   operands[1] = const0_rtx;
                     97:   return AS2 (cmp%B0,%1,%0);
                     98: }")
                     99: 
                    100: (define_insn "tstsf"
                    101:   [(set (cc0)
                    102:        (match_operand:SF 0 "register_operand" "f"))
                    103:    (clobber (match_scratch:HI 1 "=a"))]
                    104:   "TARGET_80387"
                    105:   "*
                    106: {
                    107:   if (! STACK_TOP_P (operands[0]))
                    108:     abort ();
                    109: 
                    110:   output_asm_insn (\"ftst\", operands);
                    111:   cc_status.flags |= CC_IN_80387;
                    112: 
                    113:   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
                    114:     output_asm_insn (AS1 (fstp,%y0), operands);
                    115: 
                    116:   output_asm_insn (AS1 (fnsts%W1,%1), operands);
                    117: 
                    118:   return \"sahf\";
                    119: }")
                    120: 
                    121: (define_insn "tstdf"
                    122:   [(set (cc0)
                    123:        (match_operand:DF 0 "register_operand" "f"))
                    124:    (clobber (match_scratch:HI 1 "=a"))]
                    125:   "TARGET_80387"
                    126:   "*
                    127: {
                    128:   if (! STACK_TOP_P (operands[0]))
                    129:     abort ();
                    130: 
                    131:   output_asm_insn (\"ftst\", operands);
                    132:   cc_status.flags |= CC_IN_80387;
                    133: 
                    134:   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
                    135:     output_asm_insn (AS1 (fstp,%y0), operands);
                    136: 
                    137:   output_asm_insn (AS1 (fnsts%W1,%1), operands);
                    138: 
                    139:   return \"sahf\";
                    140: }")
                    141: 
                    142: ;;- compare instructions
                    143: 
                    144: (define_insn "cmpsi"
                    145:   [(set (cc0)
                    146:        (compare (match_operand:SI 0 "nonimmediate_operand" "mr,ri")
                    147:                 (match_operand:SI 1 "general_operand" "ri,mr")))]
                    148:   ""
                    149:   "*
                    150: {
                    151:   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
                    152:     {
                    153:       cc_status.flags |= CC_REVERSED;
                    154:       return AS2 (cmp%L0,%0,%1);
                    155:     }
                    156:   return AS2 (cmp%L0,%1,%0);
                    157: }")
                    158: 
                    159: (define_insn "cmphi"
                    160:   [(set (cc0)
                    161:        (compare (match_operand:HI 0 "nonimmediate_operand" "mr,ri")
                    162:                 (match_operand:HI 1 "general_operand" "ri,mr")))]
                    163:   ""
                    164:   "*
                    165: {
                    166:   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
                    167:     {
                    168:       cc_status.flags |= CC_REVERSED;
                    169:       return AS2 (cmp%W0,%0,%1);
                    170:     }
                    171:   return AS2 (cmp%W0,%1,%0);
                    172: }")
                    173: 
                    174: (define_insn "cmpqi"
                    175:   [(set (cc0)
                    176:        (compare (match_operand:QI 0 "nonimmediate_operand" "qn,mq")
                    177:                 (match_operand:QI 1 "general_operand" "qm,nq")))]
                    178:   ""
                    179:   "*
                    180: {
                    181:   if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
                    182:     {
                    183:       cc_status.flags |= CC_REVERSED;
                    184:       return AS2 (cmp%B0,%0,%1);
                    185:     }
                    186:   return AS2 (cmp%B0,%1,%0);
                    187: }")
                    188: 
                    189: ;; These implement float point compares.  For each of DFmode and
                    190: ;; SFmode, there is the normal insn, and an insn where the second operand
                    191: ;; is converted to the desired mode.
                    192: 
                    193: (define_expand "cmpdf"
                    194:   [(parallel [(set (cc0)
                    195:                   (compare (match_operand:DF 0 "nonimmediate_operand" "")
                    196:                            (match_operand:DF 1 "nonimmediate_operand" "")))
                    197:              (clobber (match_scratch:HI 2 ""))])]
                    198:   "TARGET_80387"
                    199:   "")
                    200: 
                    201: (define_expand "cmpsf"
                    202:   [(parallel [(set (cc0)
                    203:                   (compare (match_operand:SF 0 "nonimmediate_operand" "")
                    204:                            (match_operand:SF 1 "nonimmediate_operand" "")))
                    205:              (clobber (match_scratch:HI 2 ""))])]
                    206:   "TARGET_80387"
                    207:   "")
                    208: 
                    209: ;; The `ble' and `blt' patterns can reverse a compare, so we must allow
                    210: ;; an immediate operand as operand 0 in the recognizers below.
                    211: 
                    212: (define_insn ""
                    213:   [(set (cc0)
                    214:        (compare (match_operand:DF 0 "general_operand" "f")
                    215:                 (match_operand:DF 1 "general_operand" "fm")))
                    216:    (clobber (match_scratch:HI 2 "=a"))]
                    217:   "TARGET_80387"
                    218:   "* return (char *) output_float_compare (insn, operands);")
                    219: 
                    220: (define_insn ""
                    221:   [(set (cc0)
                    222:        (compare (match_operand:DF 0 "general_operand" "f,f")
                    223:                 (float:DF (match_operand:SI 1 "general_operand" "m,!*r"))))
                    224:    (clobber (match_scratch:HI 2 "=a,a"))]
                    225:   "TARGET_80387"
                    226:   "* return (char *) output_float_compare (insn, operands);")
                    227: 
                    228: (define_insn ""
                    229:   [(set (cc0)
                    230:        (compare (match_operand:DF 0 "general_operand" "f,f")
                    231:                 (float_extend:DF
                    232:                  (match_operand:SF 1 "general_operand" "fm,!*r"))))
                    233:    (clobber (match_scratch:HI 2 "=a,a"))]
                    234:   "TARGET_80387"
                    235:   "* return (char *) output_float_compare (insn, operands);")
                    236: 
                    237: (define_insn ""
                    238:   [(set (cc0)
                    239:        (compare (match_operand:SF 0 "general_operand" "f")
                    240:                 (match_operand:SF 1 "general_operand" "fm")))
                    241:    (clobber (match_scratch:HI 2 "=a"))]
                    242:   "TARGET_80387"
                    243:   "* return (char *) output_float_compare (insn, operands);")
                    244: 
                    245: (define_insn ""
                    246:   [(set (cc0)
                    247:        (compare (match_operand:SF 0 "general_operand" "f,f")
                    248:                 (float:SF (match_operand:SI 1 "general_operand" "m,!*r"))))
                    249:    (clobber (match_scratch:HI 2 "=a,a"))]
                    250:   "TARGET_80387"
                    251:   "* return (char *) output_float_compare (insn, operands);")
                    252: 
                    253: ;; logical compare
                    254: 
                    255: ;; ??? What if we are testing one byte of an offsettable memory reference?
                    256: (define_insn ""
                    257:   [(set (cc0)
                    258:        (and:SI (match_operand:SI 0 "general_operand" "%rm")
                    259:                (match_operand:SI 1 "general_operand" "ri")))]
                    260:   ""
                    261:   "*
                    262: {
                    263:   /* For small integers, we may actually use testb. */
                    264:   if (GET_CODE (operands[1]) == CONST_INT
                    265:       && (INTVAL (operands[1]) & ~0xffff) == 0
                    266:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                    267:     {
                    268:       /* We may set the sign bit spuriously.  */
                    269:       cc_status.flags |= CC_NOT_NEGATIVE;
                    270: 
                    271:       if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[1]) & ~0xff) == 0)
                    272:         return AS2 (test%B0,%1,%b0);
                    273: 
                    274:       if (QI_REG_P (operands[0]) && (INTVAL (operands[1]) & ~0xff00) == 0)
                    275:         {
                    276:          operands[1] = gen_rtx (CONST_INT, VOIDmode,
                    277:                                 INTVAL (operands[1]) >> 8);
                    278:          return AS2 (test%B0,%1,%h0);
                    279:        }
                    280:     }
                    281: 
                    282:   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
                    283:     return AS2 (test%L0,%1,%0);
                    284: 
                    285:   return AS2 (test%L1,%0,%1);
                    286: }")
                    287: 
                    288: (define_insn ""
                    289:   [(set (cc0)
                    290:        (and:HI (match_operand:HI 0 "general_operand" "%rm")
                    291:                (match_operand:HI 1 "general_operand" "ri")))]
                    292:   ""
                    293:   "*
                    294: {
                    295:   if (GET_CODE (operands[1]) == CONST_INT
                    296:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                    297:     {
                    298:       /* Can we ignore the upper byte? */
                    299:       if (! NON_QI_REG_P (operands[0])
                    300:          && (INTVAL (operands[1]) & 0xff00) == 0)
                    301:        {
                    302:          if (INTVAL (operands[1]) & 0xffff0000)
                    303:            operands[1] = gen_rtx (CONST_INT, VOIDmode,
                    304:                                   INTVAL (operands[1]) & 0xff);
                    305: 
                    306:          /* We may set the sign bit spuriously.  */
                    307:          cc_status.flags |= CC_NOT_NEGATIVE;
                    308:          return AS2 (test%B0,%1,%b0);
                    309:        }
                    310: 
                    311:       /* Can we ignore the lower byte? */
                    312:       /* ??? what about offsettable memory references? */
                    313:       if (QI_REG_P (operands[0]) && (INTVAL (operands[1]) & 0xff) == 0)
                    314:         {
                    315:          operands[1] = gen_rtx (CONST_INT, VOIDmode,
                    316:                                 (INTVAL (operands[1]) >> 8) & 0xff);
                    317:          return AS2 (test%B0,%1,%h0);
                    318:        }
                    319:     }
                    320: 
                    321:   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
                    322:     return AS2 (test%W0,%1,%0);
                    323: 
                    324:   return AS2 (test%W1,%0,%1);
                    325: }")
                    326: 
                    327: (define_insn ""
                    328:   [(set (cc0)
                    329:        (and:QI (match_operand:QI 0 "general_operand" "%qm")
                    330:                (match_operand:QI 1 "general_operand" "qi")))]
                    331:   ""
                    332:   "*
                    333: {
                    334:   if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM)
                    335:     return AS2 (test%B0,%1,%0);
                    336: 
                    337:   return AS2 (test%B1,%0,%1);
                    338: }")
                    339: 
                    340: ;; move instructions.
                    341: ;; There is one for each machine mode,
                    342: ;; and each is preceded by a corresponding push-insn pattern
                    343: ;; (since pushes are not general_operands on the 386).
                    344: 
                    345: (define_insn ""
                    346:   [(set (match_operand:SI 0 "push_operand" "=<")
                    347:        (match_operand:SI 1 "general_operand" "g"))]
                    348:   "! TARGET_486"
                    349:   "push%L0 %1")
                    350: 
                    351: ;; On a 486, it is faster to move MEM to a REG and then push, rather than
                    352: ;; push MEM directly.
                    353: 
                    354: (define_insn ""
                    355:   [(set (match_operand:SI 0 "push_operand" "=<")
                    356:        (match_operand:SI 1 "general_operand" "ri"))]
                    357:   "TARGET_486"
                    358:   "push%L0 %1")
                    359: 
                    360: ;; General case of fullword move.
                    361: 
                    362: ;; If generating PIC code and operands[1] is a symbolic CONST, emit a
                    363: ;; move to get the address of the symbolic object from the GOT.
                    364: 
                    365: (define_expand "movsi"
                    366:   [(set (match_operand:SI 0 "general_operand" "")
                    367:        (match_operand:SI 1 "general_operand" ""))]
                    368:   ""
                    369:   "
                    370: {
                    371:   extern int flag_pic;
                    372: 
                    373:   if (flag_pic && SYMBOLIC_CONST (operands[1]))
                    374:     emit_pic_move (operands, SImode);
                    375: }")
                    376: 
                    377: ;; On i486, incl reg is faster than movl $1,reg.
                    378: 
                    379: (define_insn ""
                    380:   [(set (match_operand:SI 0 "general_operand" "=g,r")
                    381:        (match_operand:SI 1 "general_operand" "ri,m"))]
                    382:   ""
                    383:   "*
                    384: {
                    385:   rtx link;
                    386:   if (operands[1] == const0_rtx && REG_P (operands[0]))
                    387:     return AS2 (xor%L0,%0,%0);
                    388: 
                    389:   if (operands[1] == const1_rtx
                    390:       && (link = find_reg_note (insn, REG_WAS_0, 0))
                    391:       /* Make sure the insn that stored the 0 is still present.  */
                    392:       && ! XEXP (link, 0)->volatil
                    393:       && GET_CODE (XEXP (link, 0)) != NOTE
                    394:       /* Make sure cross jumping didn't happen here.  */
                    395:       && no_labels_between_p (XEXP (link, 0), insn))
                    396:     /* Fastest way to change a 0 to a 1.  */
                    397:     return AS1 (inc%L0,%0);
                    398: 
                    399:   return AS2 (mov%L0,%1,%0);
                    400: }")
                    401: 
                    402: (define_insn ""
                    403:   [(set (match_operand:HI 0 "push_operand" "=<")
                    404:        (match_operand:HI 1 "general_operand" "g"))]
                    405:   ""
                    406:   "push%W0 %1")
                    407: 
                    408: ;; On i486, an incl and movl are both faster than incw and movw.
                    409: 
                    410: (define_insn "movhi"
                    411:   [(set (match_operand:HI 0 "general_operand" "=g,r")
                    412:        (match_operand:HI 1 "general_operand" "ri,m"))]
                    413:   ""
                    414:   "*
                    415: {
                    416:   rtx link;
                    417:   if (REG_P (operands[0]) && operands[1] == const0_rtx)
                    418:     return AS2 (xor%L0,%k0,%k0);
                    419: 
                    420:   if (REG_P (operands[0]) && operands[1] == const1_rtx 
                    421:       && (link = find_reg_note (insn, REG_WAS_0, 0))
                    422:       /* Make sure the insn that stored the 0 is still present.  */
                    423:       && ! XEXP (link, 0)->volatil
                    424:       && GET_CODE (XEXP (link, 0)) != NOTE
                    425:       /* Make sure cross jumping didn't happen here.  */
                    426:       && no_labels_between_p (XEXP (link, 0), insn))
                    427:     /* Fastest way to change a 0 to a 1.  */
                    428:     return AS1 (inc%L0,%k0);
                    429: 
                    430:   if (REG_P (operands[0]))
                    431:     {
                    432:       if (REG_P (operands[1]))
                    433:        return AS2 (mov%L0,%k1,%k0);
                    434:       else if (CONSTANT_P (operands[1]))
                    435:        return AS2 (mov%L0,%1,%k0);
                    436:     }
                    437: 
                    438:   return AS2 (mov%W0,%1,%0);
                    439: }")
                    440: 
                    441: (define_insn "movstricthi"
                    442:   [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
                    443:        (match_operand:HI 1 "general_operand" "ri,m"))]
                    444:   ""
                    445:   "*
                    446: {
                    447:   rtx link;
                    448:   if (operands[1] == const0_rtx && REG_P (operands[0]))
                    449:     return AS2 (xor%W0,%0,%0);
                    450: 
                    451:   if (operands[1] == const1_rtx
                    452:       && (link = find_reg_note (insn, REG_WAS_0, 0))
                    453:       /* Make sure the insn that stored the 0 is still present.  */
                    454:       && ! XEXP (link, 0)->volatil
                    455:       && GET_CODE (XEXP (link, 0)) != NOTE
                    456:       /* Make sure cross jumping didn't happen here.  */
                    457:       && no_labels_between_p (XEXP (link, 0), insn))
                    458:     /* Fastest way to change a 0 to a 1.  */
                    459:     return AS1 (inc%W0,%0);
                    460: 
                    461:   return AS2 (mov%W0,%1,%0);
                    462: }")
                    463: 
                    464: ;; emit_push_insn when it calls move_by_pieces
                    465: ;; requires an insn to "push a byte".
                    466: ;; But actually we use pushw, which has the effect of rounding
                    467: ;; the amount pushed up to a halfword.
                    468: (define_insn ""
                    469:   [(set (match_operand:QI 0 "push_operand" "=<")
                    470:        (match_operand:QI 1 "general_operand" "q"))]
                    471:   ""
                    472:   "*
                    473: {
                    474:   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
                    475:   return AS1 (push%W0,%1);
                    476: }")
                    477: 
                    478: ;; On i486, incb reg is faster than movb $1,reg.
                    479: 
                    480: ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
                    481: ;; or writes %ah, %bh, %ch, %dh.
                    482: 
                    483: (define_insn "movqi"
                    484:   [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
                    485:        (match_operand:QI 1 "general_operand" "*g,q,qn"))]
                    486:   ""
                    487:   "*
                    488: {
                    489:   rtx link;
                    490:   if (operands[1] == const0_rtx && REG_P (operands[0]))
                    491:     return AS2 (xor%B0,%0,%0);
                    492: 
                    493:   if (operands[1] == const1_rtx
                    494:       && (link = find_reg_note (insn, REG_WAS_0, 0))
                    495:       /* Make sure the insn that stored the 0 is still present.  */
                    496:       && ! XEXP (link, 0)->volatil
                    497:       && GET_CODE (XEXP (link, 0)) != NOTE
                    498:       /* Make sure cross jumping didn't happen here.  */
                    499:       && no_labels_between_p (XEXP (link, 0), insn))
                    500:     /* Fastest way to change a 0 to a 1.  */
                    501:     return AS1 (inc%B0,%0);
                    502: 
                    503:   /* If mov%B0 isn't allowed for one of these regs, use mov%L0.  */
                    504:   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
                    505:     return (AS2 (mov%L0,%k1,%k0));
                    506: 
                    507:   return (AS2 (mov%B0,%1,%0));
                    508: }")
                    509: 
                    510: ;; If it becomes necessary to support movstrictqi into %esi or %edi,
                    511: ;; use the insn sequence:
                    512: ;;
                    513: ;;     shrdl $8,srcreg,dstreg
                    514: ;;     rorl $24,dstreg
                    515: ;;
                    516: ;; If operands[1] is a constant, then an andl/orl sequence would be
                    517: ;; faster.
                    518: 
                    519: (define_insn "movstrictqi"
                    520:   [(set (strict_low_part (match_operand:QI 0 "general_operand" "+q,qm"))
                    521:        (match_operand:QI 1 "general_operand" "*g,qn"))]
                    522:   ""
                    523:   "*
                    524: {
                    525:   rtx link;
                    526:   if (operands[1] == const0_rtx && REG_P (operands[0]))
                    527:     return AS2 (xor%B0,%0,%0);
                    528: 
                    529:   if (operands[1] == const1_rtx
                    530:       && (link = find_reg_note (insn, REG_WAS_0, 0))
                    531:       /* Make sure the insn that stored the 0 is still present.  */
                    532:       && ! XEXP (link, 0)->volatil
                    533:       && GET_CODE (XEXP (link, 0)) != NOTE
                    534:       /* Make sure cross jumping didn't happen here.  */
                    535:       && no_labels_between_p (XEXP (link, 0), insn))
                    536:     /* Fastest way to change a 0 to a 1.  */
                    537:     return AS1 (inc%B0,%0);
                    538: 
                    539:   /* If mov%B0 isn't allowed for one of these regs, use mov%W0.  */
                    540:   if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1]))
                    541:     {
                    542:       abort ();
                    543:       return (AS2 (mov%L0,%k1,%k0));
                    544:     }
                    545: 
                    546:   return AS2 (mov%B0,%1,%0);
                    547: }")
                    548: 
                    549: (define_insn ""
                    550:   [(set (match_operand:SF 0 "push_operand" "=<,<")
                    551:        (match_operand:SF 1 "general_operand" "gF,f"))]
                    552:   ""
                    553:   "*
                    554: {
                    555:   if (STACK_REG_P (operands[1]))
                    556:     {
                    557:       rtx xops[3];
                    558: 
                    559:       if (! STACK_TOP_P (operands[1]))
                    560:         abort ();
                    561: 
                    562:       xops[0] = AT_SP (SFmode);
                    563:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 4);
                    564:       xops[2] = stack_pointer_rtx;
                    565: 
                    566:       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
                    567: 
                    568:       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
                    569:         output_asm_insn (AS1 (fstp%S0,%0), xops);
                    570:       else
                    571:         output_asm_insn (AS1 (fst%S0,%0), xops);
                    572:       RET;
                    573:     }
                    574:   return AS1 (push%L1,%1);
                    575: }")
                    576: 
                    577: (define_insn "movsf"
                    578:   [(set (match_operand:SF 0 "general_operand" "=f,fm,!*rf,!*rm")
                    579:        (match_operand:SF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
                    580:   ""
                    581:   "*
                    582: {
                    583:   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
                    584: 
                    585:   /* First handle a `pop' insn or a `fld %st(0)' */
                    586: 
                    587:   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
                    588:     {
                    589:       if (stack_top_dies)
                    590:        return AS1 (fstp,%y0);
                    591:       else
                    592:         return AS1 (fld,%y0);
                    593:     }
                    594: 
                    595:   /* Handle a transfer between the 387 and a 386 register */
                    596: 
                    597:   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
                    598:     {
                    599:       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
                    600:       RET;
                    601:     }
                    602: 
                    603:   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
                    604:     {
                    605:       output_to_reg (operands[0], stack_top_dies);
                    606:       RET;
                    607:     }
                    608: 
                    609:   /* Handle other kinds of writes from the 387 */
                    610: 
                    611:   if (STACK_TOP_P (operands[1]))
                    612:     {
                    613:       if (stack_top_dies)
                    614:        return AS1 (fstp%z0,%y0);
                    615:       else
                    616:         return AS1 (fst%z0,%y0);
                    617:     }
                    618: 
                    619:   /* Handle other kinds of reads to the 387 */
                    620: 
                    621:   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
                    622:     return (char *) output_move_const_single (operands);
                    623: 
                    624:   if (STACK_TOP_P (operands[0]))
                    625:     return AS1 (fld%z1,%y1);
                    626: 
                    627:   /* Handle all SFmode moves not involving the 387 */
                    628: 
                    629:   return (char *) singlemove_string (operands);
                    630: }")
                    631: 
                    632: ;;should change to handle the memory operands[1] without doing df push..
                    633: (define_insn ""
                    634:   [(set (match_operand:DF 0 "push_operand" "=<,<")
                    635:        (match_operand:DF 1 "general_operand" "gF,f"))]
                    636:   ""
                    637:   "*
                    638: {
                    639:   if (STACK_REG_P (operands[1]))
                    640:     {
                    641:       rtx xops[3];
                    642: 
                    643:       xops[0] = AT_SP (SFmode);
                    644:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 8);
                    645:       xops[2] = stack_pointer_rtx;
                    646: 
                    647:       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
                    648: 
                    649:       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
                    650:         output_asm_insn (AS1 (fstp%Q0,%0), xops);
                    651:       else
                    652:         output_asm_insn (AS1 (fst%Q0,%0), xops);
                    653: 
                    654:       RET;
                    655:     }
                    656:   else
                    657:     return (char *) output_move_double (operands);
                    658: }")
                    659: 
                    660: (define_insn "swapdf"
                    661:   [(set (match_operand:DF 0 "register_operand" "f")
                    662:        (match_operand:DF 1 "register_operand" "f"))
                    663:    (set (match_dup 1)
                    664:        (match_dup 0))]
                    665:   ""
                    666:   "*
                    667: {
                    668:   if (STACK_TOP_P (operands[0]))
                    669:     return AS1 (fxch,%1);
                    670:   else
                    671:     return AS1 (fxch,%0);
                    672: }")
                    673: 
                    674: (define_insn "movdf"
                    675:   [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
                    676:        (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
                    677:   ""
                    678:   "*
                    679: {
                    680:   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
                    681: 
                    682:   /* First handle a `pop' insn or a `fld %st(0)' */
                    683: 
                    684:   if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]))
                    685:     {
                    686:       if (stack_top_dies)
                    687:        return AS1 (fstp,%y0);
                    688:       else
                    689:         return AS1 (fld,%y0);
                    690:     }
                    691: 
                    692:   /* Handle a transfer between the 387 and a 386 register */
                    693: 
                    694:   if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1]))
                    695:     {
                    696:       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
                    697:       RET;
                    698:     }
                    699: 
                    700:   if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0]))
                    701:     {
                    702:       output_to_reg (operands[0], stack_top_dies);
                    703:       RET;
                    704:     }
                    705: 
                    706:   /* Handle other kinds of writes from the 387 */
                    707: 
                    708:   if (STACK_TOP_P (operands[1]))
                    709:     {
                    710:       if (stack_top_dies)
                    711:        return AS1 (fstp%z0,%y0);
                    712:       else
                    713:         return AS1 (fst%z0,%y0);
                    714:     }
                    715: 
                    716:   /* Handle other kinds of reads to the 387 */
                    717: 
                    718:   if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
                    719:     return (char *) output_move_const_single (operands);
                    720: 
                    721:   if (STACK_TOP_P (operands[0]))
                    722:     return AS1 (fld%z1,%y1);
                    723: 
                    724:   /* Handle all DFmode moves not involving the 387 */
                    725: 
                    726:   return (char *) output_move_double (operands);
                    727: }")
                    728: 
                    729: (define_insn ""
                    730:   [(set (match_operand:DI 0 "push_operand" "=<")
                    731:        (match_operand:DI 1 "general_operand" "roiF"))]
                    732:   ""
                    733:   "*
                    734: {
                    735:   return (char *) output_move_double (operands);
                    736: }")
                    737: 
                    738: (define_insn "movdi"
                    739:   [(set (match_operand:DI 0 "general_operand" "=&r,rm")
                    740:        (match_operand:DI 1 "general_operand" "m,riF"))]
                    741:   ""
                    742:   "*
                    743: {
                    744:   return (char *) output_move_double (operands);
                    745: }")
                    746: 
                    747: ;;- conversion instructions
                    748: ;;- NONE
                    749: 
                    750: ;;- truncation instructions
                    751: 
                    752: (define_insn "truncsiqi2"
                    753:   [(set (match_operand:QI 0 "general_operand" "=q,qm")
                    754:        (truncate:QI
                    755:         (match_operand:SI 1 "general_operand" "qim,qn")))]
                    756:   ""
                    757:   "*
                    758: {
                    759:   if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
                    760:     return AS2 (mov%L0,%1,%k0);
                    761: 
                    762:   return AS2 (mov%B0,%b1,%0);
                    763: }")
                    764: 
                    765: (define_insn "trunchiqi2"
                    766:   [(set (match_operand:QI 0 "general_operand" "=q,qm")
                    767:        (truncate:QI
                    768:         (match_operand:HI 1 "general_operand" "qim,qn")))]
                    769:   ""
                    770:   "*
                    771: {
                    772:   if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
                    773:     return AS2 (mov%L0,%1,%k0);
                    774: 
                    775:   return AS2 (mov%B0,%b1,%0);
                    776: }")
                    777: 
                    778: (define_insn "truncsihi2"
                    779:   [(set (match_operand:HI 0 "general_operand" "=r,rm")
                    780:        (truncate:HI
                    781:         (match_operand:SI 1 "general_operand" "rim,rn")))]
                    782:   ""
                    783:   "*
                    784: {
                    785:   if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT)
                    786:     return AS2 (mov%L0,%1,%k0);
                    787: 
                    788:   return AS2 (mov%W0,%w1,%0);
                    789: }")
                    790: 
                    791: ;;- zero extension instructions
                    792: ;; See comments by `andsi' for when andl is faster than movzx.
                    793: 
                    794: (define_insn "zero_extendhisi2"
                    795:   [(set (match_operand:SI 0 "general_operand" "=r")
                    796:        (zero_extend:SI
                    797:         (match_operand:HI 1 "nonimmediate_operand" "rm")))]
                    798:   ""
                    799:   "*
                    800: {
                    801:   if ((TARGET_486 || REGNO (operands[0]) == 0)
                    802:       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
                    803:     {
                    804:       rtx xops[2];
                    805:       xops[0] = operands[0];
                    806:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff);
                    807:       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
                    808:       RET;
                    809:     }
                    810: 
                    811: #ifdef INTEL_SYNTAX
                    812:   return AS2 (movzx,%1,%0);
                    813: #else
                    814:   return AS2 (movz%W0%L0,%1,%0);
                    815: #endif
                    816: }")
                    817: 
                    818: (define_insn "zero_extendqihi2"
                    819:   [(set (match_operand:HI 0 "general_operand" "=r")
                    820:        (zero_extend:HI
                    821:         (match_operand:QI 1 "nonimmediate_operand" "qm")))]
                    822:   ""
                    823:   "*
                    824: {
                    825:   if ((TARGET_486 || REGNO (operands[0]) == 0)
                    826:       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
                    827:     {
                    828:       rtx xops[2];
                    829:       xops[0] = operands[0];
                    830:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
                    831:       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
                    832:       RET;
                    833:     }
                    834: 
                    835: #ifdef INTEL_SYNTAX
                    836:   return AS2 (movzx,%1,%0);
                    837: #else
                    838:   return AS2 (movz%B0%W0,%1,%0);
                    839: #endif
                    840: }")
                    841: 
                    842: (define_insn "zero_extendqisi2"
                    843:   [(set (match_operand:SI 0 "general_operand" "=r")
                    844:        (zero_extend:SI
                    845:         (match_operand:QI 1 "nonimmediate_operand" "qm")))]
                    846:   ""
                    847:   "*
                    848: {
                    849:   if ((TARGET_486 || REGNO (operands[0]) == 0)
                    850:       && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
                    851:     {
                    852:       rtx xops[2];
                    853:       xops[0] = operands[0];
                    854:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
                    855:       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
                    856:       RET;
                    857:     }
                    858: 
                    859: #ifdef INTEL_SYNTAX
                    860:   return AS2 (movzx,%1,%0);
                    861: #else
                    862:   return AS2 (movz%B0%L0,%1,%0);
                    863: #endif
                    864: }")
                    865: 
                    866: ;;- sign extension instructions
                    867: 
                    868: /*
                    869: (define_insn "extendsidi2"
                    870:   [(set (match_operand:DI 0 "general_operand" "=a")
                    871:        (sign_extend:DI
                    872:         (match_operand:SI 1 "nonimmediate_operand" "a")))]
                    873:   ""
                    874:   "clq")
                    875: */
                    876: 
                    877: ;; Note that the i386 programmers' manual says that the opcodes
                    878: ;; are named movsx..., but the assembler on Unix does not accept that.
                    879: ;; We use what the Unix assembler expects.
                    880: 
                    881: (define_insn "extendhisi2"
                    882:   [(set (match_operand:SI 0 "general_operand" "=r")
                    883:        (sign_extend:SI
                    884:         (match_operand:HI 1 "nonimmediate_operand" "rm")))]
                    885:   ""
                    886:   "*
                    887: {
                    888:   if (REGNO (operands[0]) == 0
                    889:       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
                    890: #ifdef INTEL_SYNTAX
                    891:     return \"cwde\";
                    892: #else
                    893:     return \"cwtl\";
                    894: #endif
                    895: 
                    896: #ifdef INTEL_SYNTAX
                    897:   return AS2 (movsx,%1,%0);
                    898: #else
                    899:   return AS2 (movs%W0%L0,%1,%0);
                    900: #endif
                    901: }")
                    902: 
                    903: (define_insn "extendqihi2"
                    904:   [(set (match_operand:HI 0 "general_operand" "=r")
                    905:        (sign_extend:HI
                    906:         (match_operand:QI 1 "nonimmediate_operand" "qm")))]
                    907:   ""
                    908:   "*
                    909: {
                    910:   if (REGNO (operands[0]) == 0
                    911:       && REG_P (operands[1]) && REGNO (operands[1]) == 0)
                    912:     return \"cbtw\";
                    913: 
                    914: #ifdef INTEL_SYNTAX
                    915:   return AS2 (movsx,%1,%0);
                    916: #else
                    917:   return AS2 (movs%B0%W0,%1,%0);
                    918: #endif
                    919: }")
                    920: 
                    921: (define_insn "extendqisi2"
                    922:   [(set (match_operand:SI 0 "general_operand" "=r")
                    923:        (sign_extend:SI
                    924:         (match_operand:QI 1 "nonimmediate_operand" "qm")))]
                    925:   ""
                    926:   "*
                    927: {
                    928: #ifdef INTEL_SYNTAX
                    929:   return AS2 (movsx,%1,%0);
                    930: #else
                    931:   return AS2 (movs%B0%L0,%1,%0);
                    932: #endif
                    933: }")
                    934: 
                    935: ;; Conversions between float and double.
                    936: 
                    937: (define_insn "extendsfdf2"
                    938:   [(set (match_operand:DF 0 "general_operand" "=fm,f,f,!*r")
                    939:        (float_extend:DF
                    940:         (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))]
                    941:   "TARGET_80387"
                    942:   "*
                    943: {
                    944:   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
                    945: 
                    946:   if (NON_STACK_REG_P (operands[1]))
                    947:     {
                    948:       output_op_from_reg (operands[1], AS1 (fld%z0,%y1));
                    949:       RET;
                    950:     }
                    951: 
                    952:   if (NON_STACK_REG_P (operands[0]))
                    953:     {
                    954:       output_to_reg (operands[0], stack_top_dies);
                    955:       RET;
                    956:     }
                    957: 
                    958:   if (STACK_TOP_P (operands[0]))
                    959:     return AS1 (fld%z1,%y1);
                    960: 
                    961:   if (GET_CODE (operands[0]) == MEM)
                    962:     {
                    963:       if (stack_top_dies)
                    964:        return AS1 (fstp%z0,%y0);
                    965:       else
                    966:         return AS1 (fst%z0,%y0);
                    967:     }
                    968: 
                    969:   abort ();
                    970: }")
                    971: 
                    972: ;; This cannot output into an f-reg because there is no way to be sure
                    973: ;; of truncating in that case.  Otherwise this is just like a simple move
                    974: ;; insn.
                    975: 
                    976: (define_insn "truncdfsf2"
                    977:   [(set (match_operand:SF 0 "general_operand" "=m,!*r")
                    978:        (float_truncate:SF
                    979:         (match_operand:DF 1 "register_operand" "f,f")))]
                    980:   "TARGET_80387"
                    981:   "*
                    982: {
                    983:   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
                    984: 
                    985:   if (NON_STACK_REG_P (operands[0]))
                    986:     {
                    987:       output_to_reg (operands[0], stack_top_dies);
                    988:       RET;
                    989:     }
                    990:   else if (GET_CODE (operands[0]) == MEM)
                    991:     {
                    992:       if (stack_top_dies)
                    993:        return AS1 (fstp%z0,%0);
                    994:       else
                    995:         return AS1 (fst%z0,%0);
                    996:     }
                    997:   else
                    998:     abort ();
                    999: }")
                   1000: 
                   1001: ;; The 387 requires that the stack top dies after converting to DImode.
                   1002: 
                   1003: ;; Represent an unsigned conversion from SImode to MODE_FLOAT by first
                   1004: ;; doing a signed conversion to DImode, and then taking just the low
                   1005: ;; part.
                   1006: 
                   1007: (define_expand "fixuns_truncdfsi2"
                   1008:   [(parallel [(set (match_dup 3)
                   1009:                   (fix:DI
                   1010:                    (fix:DF (match_operand:DF 1 "register_operand" ""))))
                   1011:              (clobber (match_scratch:HI 2 ""))
                   1012:              (clobber (match_dup 1))])
                   1013:    (set (match_operand:SI 0 "general_operand" "")
                   1014:        (match_dup 4))]
                   1015:   "TARGET_80387"
                   1016:   "
                   1017: {
                   1018:   operands[3] = gen_reg_rtx (DImode);
                   1019:   operands[4] = gen_lowpart (SImode, operands[3]);
                   1020: }")
                   1021: 
                   1022: (define_expand "fixuns_truncsfsi2"
                   1023:   [(parallel [(set (match_dup 3)
                   1024:                   (fix:DI
                   1025:                    (fix:SF (match_operand:SF 1 "register_operand" ""))))
                   1026:              (clobber (match_scratch:HI 2 ""))
                   1027:              (clobber (match_dup 1))])
                   1028:    (set (match_operand:SI 0 "general_operand" "")
                   1029:        (match_dup 4))]
                   1030:   "TARGET_80387"
                   1031:   "
                   1032: {
                   1033:   operands[3] = gen_reg_rtx (DImode);
                   1034:   operands[4] = gen_lowpart (SImode, operands[3]);
                   1035: }")
                   1036: 
                   1037: ;; Signed conversion to DImode.
                   1038: 
                   1039: (define_expand "fix_truncdfdi2"
                   1040:   [(parallel [(set (match_operand:DI 0 "general_operand" "")
                   1041:                   (fix:DI
                   1042:                    (fix:DF (match_operand:DF 1 "register_operand" ""))))
                   1043:              (clobber (match_scratch:HI 2 ""))
                   1044:              (clobber (match_dup 1))])]
                   1045:   "TARGET_80387"
                   1046:   "
                   1047: {
                   1048:   operands[1] = copy_to_mode_reg (DFmode, operands[1]);
                   1049: }")
                   1050: 
                   1051: (define_expand "fix_truncsfdi2"
                   1052:   [(parallel [(set (match_operand:DI 0 "general_operand" "")
                   1053:                   (fix:DI
                   1054:                    (fix:SF (match_operand:SF 1 "register_operand" ""))))
                   1055:              (clobber (match_scratch:HI 2 ""))
                   1056:              (clobber (match_dup 1))])]
                   1057:   "TARGET_80387"
                   1058:   "
                   1059: {
                   1060:   operands[1] = copy_to_mode_reg (SFmode, operands[1]);
                   1061: }")
                   1062: 
                   1063: ;; These match a signed convertion of either DFmode or SFmode to DImode.
                   1064: 
                   1065: (define_insn ""
                   1066:   [(set (match_operand:DI 0 "general_operand" "=m,!*r")
                   1067:        (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
                   1068:    (clobber (match_scratch:HI 2 "=&r,&r"))
                   1069:    (clobber (match_dup 1))]
                   1070:   "TARGET_80387"
                   1071:   "* return (char *) output_fix_trunc (insn, operands);")
                   1072: 
                   1073: (define_insn ""
                   1074:   [(set (match_operand:DI 0 "general_operand" "=m,!*r")
                   1075:        (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
                   1076:    (clobber (match_scratch:HI 2 "=&r,&r"))
                   1077:    (clobber (match_dup 1))]
                   1078:   "TARGET_80387"
                   1079:   "* return (char *) output_fix_trunc (insn, operands);")
                   1080: 
                   1081: ;; Signed MODE_FLOAT conversion to SImode.
                   1082: 
                   1083: (define_expand "fix_truncdfsi2"
                   1084:   [(parallel [(set (match_operand:SI 0 "general_operand" "")
                   1085:                   (fix:SI
                   1086:                    (fix:DF (match_operand:DF 1 "register_operand" ""))))
                   1087:              (clobber (match_scratch:HI 2 ""))])]
                   1088:   "TARGET_80387"
                   1089:   "")
                   1090: 
                   1091: (define_expand "fix_truncsfsi2"
                   1092:   [(parallel [(set (match_operand:SI 0 "general_operand" "")
                   1093:                   (fix:SI
                   1094:                    (fix:SF (match_operand:SF 1 "register_operand" ""))))
                   1095:              (clobber (match_scratch:HI 2 ""))])]
                   1096:   "TARGET_80387"
                   1097:   "")
                   1098: 
                   1099: (define_insn ""
                   1100:   [(set (match_operand:SI 0 "general_operand" "=m,!*r")
                   1101:        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
                   1102:    (clobber (match_scratch:HI 2 "=&r,&r"))]
                   1103:   "TARGET_80387"
                   1104:   "* return (char *) output_fix_trunc (insn, operands);")
                   1105: 
                   1106: (define_insn ""
                   1107:   [(set (match_operand:SI 0 "general_operand" "=m,!*r")
                   1108:        (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
                   1109:    (clobber (match_scratch:HI 2 "=&r,&r"))]
                   1110:   "TARGET_80387"
                   1111:   "* return (char *) output_fix_trunc (insn, operands);")
                   1112: 
                   1113: ;; Conversion between fixed point and floating point.
                   1114: ;; The actual pattern that matches these is at the end of this file.
                   1115: 
                   1116: ;; ??? Possibly repsent floatunssidf2 here in gcc2.
                   1117: 
                   1118: (define_expand "floatsisf2"
                   1119:   [(set (match_operand:SF 0 "register_operand" "")
                   1120:        (float:SF (match_operand:SI 1 "general_operand" "")))]
                   1121:   "TARGET_80387"
                   1122:   "")
                   1123: 
                   1124: (define_expand "floatdisf2"
                   1125:   [(set (match_operand:SF 0 "register_operand" "")
                   1126:        (float:SF (match_operand:DI 1 "general_operand" "")))]
                   1127:   "TARGET_80387"
                   1128:   "")
                   1129: 
                   1130: (define_expand "floatsidf2"
                   1131:   [(set (match_operand:DF 0 "register_operand" "")
                   1132:        (float:DF (match_operand:SI 1 "general_operand" "")))]
                   1133:   "TARGET_80387"
                   1134:   "")
                   1135: 
                   1136: (define_expand "floatdidf2"
                   1137:   [(set (match_operand:DF 0 "register_operand" "")
                   1138:        (float:DF (match_operand:DI 1 "general_operand" "")))]
                   1139:   "TARGET_80387"
                   1140:   "")
                   1141: 
                   1142: ;; This will convert from SImode or DImode to MODE_FLOAT.
                   1143: 
                   1144: (define_insn ""
                   1145:   [(set (match_operand 0 "register_operand" "=f,f")
                   1146:        (match_operator 2 "float_op"
                   1147:                        [(match_operand:DI 1 "general_operand" "m,!*r")]))]
                   1148:   "TARGET_80387 && GET_MODE (operands[0]) == GET_MODE (operands[2])
                   1149:    && GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT"
                   1150:   "*
                   1151: {
                   1152:   if (NON_STACK_REG_P (operands[1]))
                   1153:     {
                   1154:       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
                   1155:       RET;
                   1156:     }
                   1157:   else if (GET_CODE (operands[1]) == MEM)
                   1158:     return AS1 (fild%z1,%1);
                   1159:   else
                   1160:     abort ();
                   1161: }")
                   1162: 
                   1163: (define_insn ""
                   1164:   [(set (match_operand 0 "register_operand" "=f,f")
                   1165:        (match_operator 2 "float_op"
                   1166:                        [(match_operand:SI 1 "general_operand" "m,!*r")]))]
                   1167:   "TARGET_80387 && GET_MODE (operands[0]) == GET_MODE (operands[2])
                   1168:    && GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT"
                   1169:   "*
                   1170: {
                   1171:   if (NON_STACK_REG_P (operands[1]))
                   1172:     {
                   1173:       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
                   1174:       RET;
                   1175:     }
                   1176:   else if (GET_CODE (operands[1]) == MEM)
                   1177:     return AS1 (fild%z1,%1);
                   1178:   else
                   1179:     abort ();
                   1180: }")
                   1181: 
                   1182: ;;- add instructions
                   1183: 
                   1184: (define_insn "adddi3"
                   1185:   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
                   1186:        (plus:DI (match_operand:DI 1 "general_operand" "%0,0")
                   1187:                 (match_operand:DI 2 "general_operand" "o,riF")))]
                   1188:   ""
                   1189:   "*
                   1190: {
                   1191:   rtx low[3], high[3];
                   1192: 
                   1193:   CC_STATUS_INIT;
                   1194: 
                   1195:   split_di (operands, 3, low, high);
                   1196: 
                   1197:   output_asm_insn (AS2 (add%L0,%2,%0), low);
                   1198:   output_asm_insn (AS2 (adc%L0,%2,%0), high);
                   1199:   RET;
                   1200: }")
                   1201: 
                   1202: ;; On a 486, it is faster to do movl/addl than to do a single leal if
                   1203: ;; operands[1] and operands[2] are both registers.
                   1204: 
                   1205: (define_insn "addsi3"
                   1206:   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
                   1207:        (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
                   1208:                 (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
                   1209:   ""
                   1210:   "*
                   1211: {
                   1212:   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
                   1213:     {
                   1214:       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
                   1215:        return AS2 (add%L0,%1,%0);
                   1216: 
                   1217:       if (! TARGET_486 || ! REG_P (operands[2]))
                   1218:         {
                   1219:          CC_STATUS_INIT;
                   1220:          operands[1] = SET_SRC (PATTERN (insn));
                   1221:          return AS2 (lea%L0,%a1,%0);
                   1222:        }
                   1223: 
                   1224:       output_asm_insn (AS2 (mov%L0,%1,%0), operands);
                   1225:     }
                   1226: 
                   1227:   if (operands[2] == const1_rtx)
                   1228:     return AS1 (inc%L0,%0);
                   1229: 
                   1230:   if (operands[2] == constm1_rtx)
                   1231:     return AS1 (dec%L0,%0);
                   1232: 
                   1233:   return AS2 (add%L0,%2,%0);
                   1234: }")
                   1235: 
                   1236: ;; ??? `lea' here, for three operand add?  If leaw is used, only %bx,
                   1237: ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be
                   1238: ;; able to handle the operand.  But leal always works?
                   1239: 
                   1240: (define_insn "addhi3"
                   1241:   [(set (match_operand:HI 0 "general_operand" "=rm,r")
                   1242:        (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
                   1243:                 (match_operand:HI 2 "general_operand" "ri,rm")))]
                   1244:   ""
                   1245:   "*
                   1246: {
                   1247:   if (operands[2] == const1_rtx)
                   1248:     return AS1 (inc%W0,%0);
                   1249: 
                   1250:   if (operands[2] == constm1_rtx)
                   1251:     return AS1 (dec%W0,%0);
                   1252: 
                   1253:   return AS2 (add%W0,%2,%0);
                   1254: }")
                   1255: 
                   1256: (define_insn "addqi3"
                   1257:   [(set (match_operand:QI 0 "general_operand" "=qm,q")
                   1258:        (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
                   1259:                 (match_operand:QI 2 "general_operand" "qn,qmn")))]
                   1260:   ""
                   1261:   "*
                   1262: {
                   1263:   if (operands[2] == const1_rtx)
                   1264:     return AS1 (inc%B0,%0);
                   1265: 
                   1266:   if (operands[2] == constm1_rtx)
                   1267:     return AS1 (dec%B0,%0);
                   1268: 
                   1269:   return AS2 (add%B0,%2,%0);
                   1270: }")
                   1271: 
                   1272: ;Lennart Augustsson <[email protected]>
                   1273: ;says this pattern just makes slower code:
                   1274: ;      pushl   %ebp
                   1275: ;      addl    $-80,(%esp)
                   1276: ;instead of
                   1277: ;      leal    -80(%ebp),%eax
                   1278: ;      pushl   %eax
                   1279: ;
                   1280: ;(define_insn ""
                   1281: ;  [(set (match_operand:SI 0 "push_operand" "=<")
                   1282: ;      (plus:SI (match_operand:SI 1 "general_operand" "%r")
                   1283: ;               (match_operand:SI 2 "general_operand" "ri")))]
                   1284: ;  ""
                   1285: ;  "*
                   1286: ;{
                   1287: ;  rtx xops[4];
                   1288: ;  xops[0] = operands[0];
                   1289: ;  xops[1] = operands[1];
                   1290: ;  xops[2] = operands[2];
                   1291: ;  xops[3] = gen_rtx (MEM, SImode, stack_pointer_rtx);
                   1292: ;  output_asm_insn (\"push%z1 %1\", xops);
                   1293: ;  output_asm_insn (AS2 (add%z3,%2,%3), xops);
                   1294: ;  RET;
                   1295: ;}")
                   1296: 
                   1297: ;; addsi3 is faster, so put this after.
                   1298: 
                   1299: (define_insn ""
                   1300:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1301:         (match_operand:QI 1 "address_operand" "p"))]
                   1302:   ""
                   1303:   "*
                   1304: {
                   1305:   CC_STATUS_INIT;
                   1306:   /* Adding a constant to a register is faster with an add.  */
                   1307:   /* ??? can this ever happen? */
                   1308:   if (GET_CODE (operands[1]) == PLUS
                   1309:       && GET_CODE (XEXP (operands[1], 1)) == CONST_INT
                   1310:       && rtx_equal_p (operands[0], XEXP (operands[1], 0)))
                   1311:     {
                   1312:       operands[1] = XEXP (operands[1], 1);
                   1313: 
                   1314:       if (operands[1] == const1_rtx)
                   1315:         return AS1 (inc%L0,%0);
                   1316: 
                   1317:       if (operands[1] == constm1_rtx)
                   1318:         return AS1 (dec%L0,%0);
                   1319: 
                   1320:       return AS2 (add%L0,%1,%0);
                   1321:     }
                   1322:   return AS2 (lea%L0,%a1,%0);
                   1323: }")
                   1324: 
                   1325: ;; The patterns that match these are at the end of this file.
                   1326: 
                   1327: (define_expand "adddf3"
                   1328:   [(set (match_operand:DF 0 "register_operand" "")
                   1329:        (plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
                   1330:                 (match_operand:DF 2 "nonimmediate_operand" "")))]
                   1331:   "TARGET_80387"
                   1332:   "")
                   1333: 
                   1334: (define_expand "addsf3"
                   1335:   [(set (match_operand:SF 0 "register_operand" "")
                   1336:        (plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
                   1337:                 (match_operand:SF 2 "nonimmediate_operand" "")))]
                   1338:   "TARGET_80387"
                   1339:   "")
                   1340: 
                   1341: ;;- subtract instructions
                   1342: 
                   1343: (define_insn "subdi3"
                   1344:   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
                   1345:        (minus:DI (match_operand:DI 1 "general_operand" "0,0")
                   1346:                  (match_operand:DI 2 "general_operand" "o,riF")))]
                   1347:   ""
                   1348:   "*
                   1349: {
                   1350:   rtx low[3], high[3];
                   1351: 
                   1352:   CC_STATUS_INIT;
                   1353: 
                   1354:   split_di (operands, 3, low, high);
                   1355: 
                   1356:   output_asm_insn (AS2 (sub%L0,%2,%0), low);
                   1357:   output_asm_insn (AS2 (sbb%L0,%2,%0), high);
                   1358:   RET;
                   1359: }")
                   1360: 
                   1361: (define_insn "subsi3"
                   1362:   [(set (match_operand:SI 0 "general_operand" "=rm,r")
                   1363:        (minus:SI (match_operand:SI 1 "general_operand" "0,0")
                   1364:                  (match_operand:SI 2 "general_operand" "ri,rm")))]
                   1365:   ""
                   1366:   "* return AS2 (sub%L0,%2,%0);")
                   1367: 
                   1368: (define_insn "subhi3"
                   1369:   [(set (match_operand:HI 0 "general_operand" "=rm,r")
                   1370:        (minus:HI (match_operand:HI 1 "general_operand" "0,0")
                   1371:                  (match_operand:HI 2 "general_operand" "ri,rm")))]
                   1372:   ""
                   1373:   "* return AS2 (sub%W0,%2,%0);")
                   1374: 
                   1375: (define_insn "subqi3"
                   1376:   [(set (match_operand:QI 0 "general_operand" "=qm,q")
                   1377:        (minus:QI (match_operand:QI 1 "general_operand" "0,0")
                   1378:                  (match_operand:QI 2 "general_operand" "qn,qmn")))]
                   1379:   ""
                   1380:   "* return AS2 (sub%B0,%2,%0);")
                   1381: 
                   1382: ;; The patterns that match these are at the end of this file.
                   1383: 
                   1384: (define_expand "subdf3"
                   1385:   [(set (match_operand:DF 0 "register_operand" "")
                   1386:        (minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
                   1387:                  (match_operand:DF 2 "nonimmediate_operand" "")))]
                   1388:   "TARGET_80387"
                   1389:   "")
                   1390: 
                   1391: (define_expand "subsf3"
                   1392:   [(set (match_operand:SF 0 "register_operand" "")
                   1393:        (minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
                   1394:                  (match_operand:SF 2 "nonimmediate_operand" "")))]
                   1395:   "TARGET_80387"
                   1396:   "")
                   1397: 
                   1398: ;;- multiply instructions
                   1399: 
                   1400: ;(define_insn "mulqi3"
                   1401: ;  [(set (match_operand:QI 0 "general_operand" "=a")
                   1402: ;      (mult:QI (match_operand:QI 1 "general_operand" "%0")
                   1403: ;               (match_operand:QI 2 "general_operand" "qm")))]
                   1404: ;  ""
                   1405: ;  "imul%B0 %2,%0")
                   1406: 
                   1407: (define_insn ""
                   1408:   [(set (match_operand:HI 0 "general_operand" "=r")
                   1409:        (mult:SI (match_operand:HI 1 "general_operand" "%0")
                   1410:                 (match_operand:HI 2 "general_operand" "r")))]
                   1411:   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
                   1412:   "* return AS2 (imul%W0,%2,%0);")
                   1413: 
                   1414: (define_insn "mulhi3"
                   1415:   [(set (match_operand:HI 0 "general_operand" "=r,r")
                   1416:        (mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
                   1417:                 (match_operand:HI 2 "general_operand" "g,i")))]
                   1418:   ""
                   1419:   "*
                   1420: {
                   1421:   if (GET_CODE (operands[1]) == REG
                   1422:       && REGNO (operands[1]) == REGNO (operands[0])
                   1423:       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
                   1424:     /* Assembler has weird restrictions.  */
                   1425:     return AS2 (imul%W0,%2,%0);
                   1426:   return AS3 (imul%W0,%2,%1,%0);
                   1427: }")
                   1428: 
                   1429: (define_insn ""
                   1430:   [(set (match_operand:SI 0 "general_operand" "=r")
                   1431:        (mult:SI (match_operand:SI 1 "general_operand" "%0")
                   1432:                 (match_operand:SI 2 "general_operand" "r")))]
                   1433:   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
                   1434:   "* return AS2 (imul%L0,%2,%0);")
                   1435: 
                   1436: (define_insn "mulsi3"
                   1437:   [(set (match_operand:SI 0 "general_operand" "=r,r")
                   1438:        (mult:SI (match_operand:SI 1 "general_operand" "%0,rm")
                   1439:                 (match_operand:SI 2 "general_operand" "g,i")))]
                   1440:   ""
                   1441:   "*
                   1442: {
                   1443:   if (GET_CODE (operands[1]) == REG
                   1444:       && REGNO (operands[1]) == REGNO (operands[0])
                   1445:       && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG))
                   1446:     /* Assembler has weird restrictions.  */
                   1447:     return AS2 (imul%L0,%2,%0);
                   1448:   return AS3 (imul%L0,%2,%1,%0);
                   1449: }")
                   1450: 
                   1451: (define_insn "mulqihi3_1"
                   1452:   [(set (match_operand:HI 0 "general_operand" "=a")
                   1453:        (mult:SI (zero_extend:HI
                   1454:                  (match_operand:QI 1 "nonimmediate_operand" "%0"))
                   1455:                 (zero_extend:HI
                   1456:                  (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
                   1457:   ""
                   1458:   "mul%B0 %2")
                   1459: 
                   1460: ;; The patterns that match these are at the end of this file.
                   1461: 
                   1462: (define_expand "muldf3"
                   1463:   [(set (match_operand:DF 0 "register_operand" "")
                   1464:        (mult:DF (match_operand:DF 1 "nonimmediate_operand" "")
                   1465:                 (match_operand:DF 2 "nonimmediate_operand" "")))]
                   1466:   "TARGET_80387"
                   1467:   "")
                   1468: 
                   1469: (define_expand "mulsf3"
                   1470:   [(set (match_operand:SF 0 "register_operand" "")
                   1471:        (mult:SF (match_operand:SF 1 "nonimmediate_operand" "")
                   1472:                 (match_operand:SF 2 "nonimmediate_operand" "")))]
                   1473:   "TARGET_80387"
                   1474:   "")
                   1475: 
                   1476: ;;- divide instructions
                   1477: 
                   1478: (define_insn "divqi3"
                   1479:   [(set (match_operand:QI 0 "general_operand" "=a")
                   1480:        (div:QI (match_operand:HI 1 "general_operand" "0")
                   1481:                (match_operand:QI 2 "general_operand" "qm")))]
                   1482:   ""
                   1483:   "idiv%B0 %2")
                   1484: 
                   1485: (define_insn "udivqi3"
                   1486:   [(set (match_operand:QI 0 "general_operand" "=a")
                   1487:        (udiv:QI (match_operand:HI 1 "general_operand" "0")
                   1488:                 (match_operand:QI 2 "general_operand" "qm")))]
                   1489:   ""
                   1490:   "div%B0 %2")
                   1491: 
                   1492: ;; The patterns that match these are at the end of this file.
                   1493: 
                   1494: (define_expand "divdf3"
                   1495:   [(set (match_operand:DF 0 "register_operand" "")
                   1496:        (div:DF (match_operand:DF 1 "nonimmediate_operand" "")
                   1497:                (match_operand:DF 2 "nonimmediate_operand" "")))]
                   1498:   "TARGET_80387"
                   1499:   "")
                   1500: 
                   1501: (define_expand "divsf3"
                   1502:   [(set (match_operand:SF 0 "register_operand" "")
                   1503:        (div:SF (match_operand:SF 1 "nonimmediate_operand" "")
                   1504:                (match_operand:SF 2 "nonimmediate_operand" "")))]
                   1505:   "TARGET_80387"
                   1506:   "")
                   1507: 
                   1508: ;; Remainder instructions.
                   1509: 
                   1510: (define_insn "divmodsi4"
                   1511:   [(set (match_operand:SI 0 "register_operand" "=a")
                   1512:        (div:SI (match_operand:SI 1 "register_operand" "0")
                   1513:                (match_operand:SI 2 "general_operand" "rm")))
                   1514:    (set (match_operand:SI 3 "register_operand" "=&d")
                   1515:        (mod:SI (match_dup 1) (match_dup 2)))]
                   1516:   ""
                   1517:   "*
                   1518: {
                   1519: #ifdef INTEL_SYNTAX
                   1520:   output_asm_insn (\"cdq\", operands);
                   1521: #else
                   1522:   output_asm_insn (\"cltd\", operands);
                   1523: #endif
                   1524:   return AS1 (idiv%L0,%2);
                   1525: }")
                   1526: 
                   1527: (define_insn "divmodhi4"
                   1528:   [(set (match_operand:HI 0 "register_operand" "=a")
                   1529:        (div:HI (match_operand:HI 1 "register_operand" "0")
                   1530:                (match_operand:HI 2 "general_operand" "rm")))
                   1531:    (set (match_operand:HI 3 "register_operand" "=&d")
                   1532:        (mod:HI (match_dup 1) (match_dup 2)))]
                   1533:   ""
                   1534:   "cwtd\;idiv%W0 %2")
                   1535: 
                   1536: ;; ??? Can we make gcc zero extend operand[0]?
                   1537: (define_insn "udivmodsi4"
                   1538:   [(set (match_operand:SI 0 "register_operand" "=a")
                   1539:        (udiv:SI (match_operand:SI 1 "register_operand" "0")
                   1540:                 (match_operand:SI 2 "general_operand" "rm")))
                   1541:    (set (match_operand:SI 3 "register_operand" "=&d")
                   1542:        (umod:SI (match_dup 1) (match_dup 2)))]
                   1543:   ""
                   1544:   "*
                   1545: {
                   1546:   output_asm_insn (AS2 (xor%L3,%3,%3), operands);
                   1547:   return AS1 (div%L0,%2);
                   1548: }")
                   1549: 
                   1550: ;; ??? Can we make gcc zero extend operand[0]?
                   1551: (define_insn "udivmodhi4"
                   1552:   [(set (match_operand:HI 0 "register_operand" "=a")
                   1553:        (udiv:HI (match_operand:HI 1 "register_operand" "0")
                   1554:                 (match_operand:HI 2 "general_operand" "rm")))
                   1555:    (set (match_operand:HI 3 "register_operand" "=&d")
                   1556:        (umod:HI (match_dup 1) (match_dup 2)))]
                   1557:   ""
                   1558:   "*
                   1559: {
                   1560:   output_asm_insn (AS2 (xor%W0,%3,%3), operands);
                   1561:   return AS1 (div%W0,%2);
                   1562: }")
                   1563: 
                   1564: /*
                   1565: ;;this should be a valid double division which we may want to add
                   1566: 
                   1567: (define_insn ""
                   1568:   [(set (match_operand:SI 0 "register_operand" "=a")
                   1569:        (udiv:DI (match_operand:DI 1 "register_operand" "a")
                   1570:                 (match_operand:SI 2 "general_operand" "rm")))
                   1571:    (set (match_operand:SI 3 "register_operand" "=d")
                   1572:        (umod:SI (match_dup 1) (match_dup 2)))]
                   1573:   ""
                   1574:   "div%L0 %2,%0")
                   1575: */
                   1576: 
                   1577: ;;- and instructions
                   1578: 
                   1579: ;; On i386,
                   1580: ;;                     movzbl %bl,%ebx
                   1581: ;; is faster than
                   1582: ;;                     andl $255,%ebx
                   1583: ;;
                   1584: ;; but if the reg is %eax, then the "andl" is faster.
                   1585: ;;
                   1586: ;; On i486, the "andl" is always faster than the "movzbl".
                   1587: ;;
                   1588: ;; On both i386 and i486, a three operand AND is as fast with movzbl or
                   1589: ;; movzwl as with andl, if operands[0] != operands[1].
                   1590: 
                   1591: ;; The `r' in `rm' for operand 3 looks redundant, but it causes
                   1592: ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
                   1593: 
                   1594: ;; ??? What if we only change one byte of an offsettable memory reference?
                   1595: (define_insn "andsi3"
                   1596:   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
                   1597:        (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
                   1598:                (match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
                   1599:   ""
                   1600:   "*
                   1601: {
                   1602:   if (GET_CODE (operands[2]) == CONST_INT
                   1603:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1604:     {
                   1605:       if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
                   1606:          && (! REG_P (operands[1])
                   1607:              || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
                   1608:          && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
                   1609:        {
                   1610:          /* ??? tege: Should forget CC_STATUS only if we clobber a
                   1611:             remembered operand.  Fix that later.  */
                   1612:          CC_STATUS_INIT;
                   1613: #ifdef INTEL_SYNTAX
                   1614:          return AS2 (movzx,%w1,%0);
                   1615: #else
                   1616:          return AS2 (movz%W0%L0,%w1,%0);
                   1617: #endif
                   1618:        }
                   1619: 
                   1620:       if (INTVAL (operands[2]) == 0xff && REG_P (operands[0])
                   1621:          && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
                   1622:          && (! REG_P (operands[1])
                   1623:              || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
                   1624:          && (! TARGET_486 || ! rtx_equal_p (operands[0], operands[1])))
                   1625:        {
                   1626:          /* ??? tege: Should forget CC_STATUS only if we clobber a
                   1627:             remembered operand.  Fix that later.  */
                   1628:          CC_STATUS_INIT;
                   1629: #ifdef INTEL_SYNTAX
                   1630:          return AS2 (movzx,%b1,%0);
                   1631: #else
                   1632:          return AS2 (movz%B0%L0,%b1,%0);
                   1633: #endif
                   1634:        }
                   1635: 
                   1636:       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff) == 0)
                   1637:        {
                   1638:          CC_STATUS_INIT;
                   1639: 
                   1640:          if (INTVAL (operands[2]) == 0xffffff00)
                   1641:            {
                   1642:              operands[2] = const0_rtx;
                   1643:              return AS2 (mov%B0,%2,%b0);
                   1644:            }
                   1645: 
                   1646:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1647:                                 INTVAL (operands[2]) & 0xff);
                   1648:          return AS2 (and%B0,%2,%b0);
                   1649:        }
                   1650: 
                   1651:       if (QI_REG_P (operands[0]) && ~(INTVAL (operands[2]) | 0xff00) == 0)
                   1652:        {
                   1653:          CC_STATUS_INIT;
                   1654: 
                   1655:          if (INTVAL (operands[2]) == 0xffff00ff)
                   1656:            {
                   1657:              operands[2] = const0_rtx;
                   1658:              return AS2 (mov%B0,%2,%h0);
                   1659:            }
                   1660: 
                   1661:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1662:                                 INTVAL (operands[2]) >> 8);
                   1663:          return AS2 (and%B0,%2,%h0);
                   1664:        }
                   1665: 
                   1666:       if (GET_CODE (operands[0]) == MEM && INTVAL (operands[2]) == 0xffff0000)
                   1667:         {
                   1668:          operands[2] = const0_rtx;
                   1669:          return AS2 (mov%W0,%2,%w0);
                   1670:        }
                   1671:     }
                   1672: 
                   1673:   return AS2 (and%L0,%2,%0);
                   1674: }")
                   1675: 
                   1676: (define_insn "andhi3"
                   1677:   [(set (match_operand:HI 0 "general_operand" "=rm,r")
                   1678:        (and:HI (match_operand:HI 1 "general_operand" "%0,0")
                   1679:                (match_operand:HI 2 "general_operand" "ri,rm")))]
                   1680:   ""
                   1681:   "*
                   1682: {
                   1683:   if (GET_CODE (operands[2]) == CONST_INT
                   1684:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1685:     {
                   1686:       /* Can we ignore the upper byte? */
                   1687:       if (! NON_QI_REG_P (operands[0])
                   1688:          && (INTVAL (operands[2]) & 0xff00) == 0xff00)
                   1689:        {
                   1690:          CC_STATUS_INIT;
                   1691: 
                   1692:          if ((INTVAL (operands[2]) & 0xff) == 0)
                   1693:            {
                   1694:              operands[2] = const0_rtx;
                   1695:              return AS2 (mov%B0,%2,%b0);
                   1696:            }
                   1697: 
                   1698:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1699:                                 INTVAL (operands[2]) & 0xff);
                   1700:          return AS2 (and%B0,%2,%b0);
                   1701:        }
                   1702: 
                   1703:       /* Can we ignore the lower byte? */
                   1704:       /* ??? what about offsettable memory references? */
                   1705:       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff)
                   1706:        {
                   1707:          CC_STATUS_INIT;
                   1708: 
                   1709:          if ((INTVAL (operands[2]) & 0xff00) == 0)
                   1710:            {
                   1711:              operands[2] = const0_rtx;
                   1712:              return AS2 (mov%B0,%2,%h0);
                   1713:            }
                   1714: 
                   1715:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1716:                                 (INTVAL (operands[2]) >> 8) & 0xff);
                   1717:          return AS2 (and%B0,%2,%h0);
                   1718:        }
                   1719:     }
                   1720: 
                   1721:   return AS2 (and%W0,%2,%0);
                   1722: }")
                   1723: 
                   1724: (define_insn "andqi3"
                   1725:   [(set (match_operand:QI 0 "general_operand" "=qm,q")
                   1726:        (and:QI (match_operand:QI 1 "general_operand" "%0,0")
                   1727:                (match_operand:QI 2 "general_operand" "qn,qmn")))]
                   1728:   ""
                   1729:   "* return AS2 (and%B0,%2,%0);")
                   1730: 
                   1731: /* I am nervous about these two.. add them later..
                   1732: ;I presume this means that we have something in say op0= eax which is small
                   1733: ;and we want to and it with memory so we can do this by just an
                   1734: ;andb m,%al  and have success.
                   1735: (define_insn ""
                   1736:   [(set (match_operand:SI 0 "general_operand" "=r")
                   1737:        (and:SI (zero_extend:SI
                   1738:                 (match_operand:HI 1 "nonimmediate_operand" "rm"))
                   1739:                (match_operand:SI 2 "general_operand" "0")))]
                   1740:   "GET_CODE (operands[2]) == CONST_INT
                   1741:    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))"
                   1742:   "and%W0 %1,%0")
                   1743: 
                   1744: (define_insn ""
                   1745:   [(set (match_operand:SI 0 "general_operand" "=q")
                   1746:        (and:SI
                   1747:         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))
                   1748:                (match_operand:SI 2 "general_operand" "0")))]
                   1749:   "GET_CODE (operands[2]) == CONST_INT
                   1750:    && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))"
                   1751:   "and%L0 %1,%0")
                   1752: 
                   1753: */
                   1754: 
                   1755: ;;- Bit set (inclusive or) instructions
                   1756: 
                   1757: ;; ??? What if we only change one byte of an offsettable memory reference?
                   1758: (define_insn "iorsi3"
                   1759:   [(set (match_operand:SI 0 "general_operand" "=rm,r")
                   1760:        (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
                   1761:                (match_operand:SI 2 "general_operand" "ri,rm")))]
                   1762:   ""
                   1763:   "*
                   1764: {
                   1765:   if (GET_CODE (operands[2]) == CONST_INT
                   1766:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1767:     {
                   1768:       if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff) == 0)
                   1769:        {
                   1770:          CC_STATUS_INIT;
                   1771: 
                   1772:          if (INTVAL (operands[2]) == 0xff)
                   1773:            return AS2 (mov%B0,%2,%b0);
                   1774: 
                   1775:          return AS2 (or%B0,%2,%b0);
                   1776:        }
                   1777: 
                   1778:       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
                   1779:        {
                   1780:          CC_STATUS_INIT;
                   1781:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1782:                                 INTVAL (operands[2]) >> 8);
                   1783: 
                   1784:          if (INTVAL (operands[2]) == 0xff)
                   1785:            return AS2 (mov%B0,%2,%h0);
                   1786: 
                   1787:          return AS2 (or%B0,%2,%h0);
                   1788:        }
                   1789:     }
                   1790: 
                   1791:   return AS2 (or%L0,%2,%0);
                   1792: }")
                   1793: 
                   1794: (define_insn "iorhi3"
                   1795:   [(set (match_operand:HI 0 "general_operand" "=rm,r")
                   1796:        (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
                   1797:                (match_operand:HI 2 "general_operand" "ri,rm")))]
                   1798:   ""
                   1799:   "*
                   1800: {
                   1801:   if (GET_CODE (operands[2]) == CONST_INT
                   1802:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1803:     {
                   1804:       /* Can we ignore the upper byte? */
                   1805:       if (! NON_QI_REG_P (operands[0])
                   1806:          && (INTVAL (operands[2]) & 0xff00) == 0)
                   1807:        {
                   1808:          CC_STATUS_INIT;
                   1809:          if (INTVAL (operands[2]) & 0xffff0000)
                   1810:            operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1811:                                   INTVAL (operands[2]) & 0xffff);
                   1812: 
                   1813:          if (INTVAL (operands[2]) == 0xff)
                   1814:            return AS2 (mov%B0,%2,%b0);
                   1815: 
                   1816:          return AS2 (or%B0,%2,%b0);
                   1817:        }
                   1818: 
                   1819:       /* Can we ignore the lower byte? */
                   1820:       /* ??? what about offsettable memory references? */
                   1821:       if (QI_REG_P (operands[0])
                   1822:          && (INTVAL (operands[2]) & 0xff) == 0)
                   1823:        {
                   1824:          CC_STATUS_INIT;
                   1825:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1826:                                 (INTVAL (operands[2]) >> 8) & 0xff);
                   1827: 
                   1828:          if (INTVAL (operands[2]) == 0xff)
                   1829:            return AS2 (mov%B0,%2,%h0);
                   1830: 
                   1831:          return AS2 (or%B0,%2,%h0);
                   1832:        }
                   1833:     }
                   1834: 
                   1835:   return AS2 (or%W0,%2,%0);
                   1836: }")
                   1837: 
                   1838: (define_insn "iorqi3"
                   1839:   [(set (match_operand:QI 0 "general_operand" "=qm,q")
                   1840:        (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
                   1841:                (match_operand:QI 2 "general_operand" "qn,qmn")))]
                   1842:   ""
                   1843:   "* return AS2 (or%B0,%2,%0);")
                   1844: 
                   1845: ;;- xor instructions
                   1846: 
                   1847: ;; ??? What if we only change one byte of an offsettable memory reference?
                   1848: (define_insn "xorsi3"
                   1849:   [(set (match_operand:SI 0 "general_operand" "=rm,r")
                   1850:        (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
                   1851:                (match_operand:SI 2 "general_operand" "ri,rm")))]
                   1852:   ""
                   1853:   "*
                   1854: {
                   1855:   if (GET_CODE (operands[2]) == CONST_INT
                   1856:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1857:     {
                   1858:       if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff) == 0)
                   1859:        {
                   1860:          CC_STATUS_INIT;
                   1861: 
                   1862:          if (INTVAL (operands[2]) == 0xff)
                   1863:            return AS1 (not%B0,%0);
                   1864: 
                   1865:          return AS2 (xor%B0,%2,%b0);
                   1866:        }
                   1867: 
                   1868:       if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & ~0xff00) == 0)
                   1869:        {
                   1870:          CC_STATUS_INIT;
                   1871:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1872:                                 INTVAL (operands[2]) >> 8);
                   1873: 
                   1874:          if (INTVAL (operands[2]) == 0xff)
                   1875:            return AS1 (not%B0,%h0);
                   1876: 
                   1877:          return AS2 (xor%B0,%2,%h0);
                   1878:        }
                   1879:     }
                   1880: 
                   1881:   return AS2 (xor%L0,%2,%0);
                   1882: }")
                   1883: 
                   1884: (define_insn "xorhi3"
                   1885:   [(set (match_operand:HI 0 "general_operand" "=rm,r")
                   1886:        (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
                   1887:                (match_operand:HI 2 "general_operand" "ri,rm")))]
                   1888:   ""
                   1889:   "*
                   1890: {
                   1891:   if (GET_CODE (operands[2]) == CONST_INT
                   1892:       && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
                   1893:     {
                   1894:       /* Can we ignore the upper byte? */
                   1895:       if (! NON_QI_REG_P (operands[0])
                   1896:          && (INTVAL (operands[2]) & 0xff00) == 0)
                   1897:        {
                   1898:          CC_STATUS_INIT;
                   1899:          if (INTVAL (operands[2]) & 0xffff0000)
                   1900:            operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1901:                                   INTVAL (operands[2]) & 0xffff);
                   1902: 
                   1903:          if (INTVAL (operands[2]) == 0xff)
                   1904:            return AS1 (not%B0,%0);
                   1905: 
                   1906:          return AS2 (xor%B0,%2,%b0);
                   1907:        }
                   1908: 
                   1909:       /* Can we ignore the lower byte? */
                   1910:       /* ??? what about offsettable memory references? */
                   1911:       if (QI_REG_P (operands[0])
                   1912:          && (INTVAL (operands[2]) & 0xff) == 0)
                   1913:        {
                   1914:          CC_STATUS_INIT;
                   1915:          operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   1916:                                 (INTVAL (operands[2]) >> 8) & 0xff);
                   1917: 
                   1918:          if (INTVAL (operands[2]) == 0xff)
                   1919:            return AS1 (not%B0,%h0);
                   1920: 
                   1921:          return AS2 (xor%B0,%2,%h0);
                   1922:        }
                   1923:     }
                   1924: 
                   1925:   return AS2 (xor%W0,%2,%0);
                   1926: }")
                   1927: 
                   1928: (define_insn "xorqi3"
                   1929:   [(set (match_operand:QI 0 "general_operand" "=qm,q")
                   1930:        (xor:QI (match_operand:QI 1 "general_operand" "%0,0")
                   1931:                (match_operand:QI 2 "general_operand" "qn,qm")))]
                   1932:   ""
                   1933:   "* return AS2 (xor%B0,%2,%0);")
                   1934: 
                   1935: ;;- negation instructions
                   1936: 
                   1937: (define_insn "negdi2"
                   1938:   [(set (match_operand:DI 0 "general_operand" "=&ro")
                   1939:        (neg:DI (match_operand:DI 1 "general_operand" "0")))]
                   1940:   ""
                   1941:   "*
                   1942: {
                   1943:   rtx xops[2], low[1], high[1];
                   1944: 
                   1945:   CC_STATUS_INIT;
                   1946: 
                   1947:   split_di (operands, 1, low, high);
                   1948:   xops[0] = const0_rtx;
                   1949:   xops[1] = high[0];
                   1950: 
                   1951:   output_asm_insn (AS1 (neg%L0,%0), low);
                   1952:   output_asm_insn (AS2 (adc%L1,%0,%1), xops);
                   1953:   output_asm_insn (AS1 (neg%L0,%0), high);
                   1954:   RET;
                   1955: }")
                   1956: 
                   1957: (define_insn "negsi2"
                   1958:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   1959:        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
                   1960:   ""
                   1961:   "neg%L0 %0")
                   1962: 
                   1963: (define_insn "neghi2"
                   1964:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   1965:        (neg:HI (match_operand:HI 1 "general_operand" "0")))]
                   1966:   ""
                   1967:   "neg%W0 %0")
                   1968: 
                   1969: (define_insn "negqi2"
                   1970:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   1971:        (neg:QI (match_operand:QI 1 "general_operand" "0")))]
                   1972:   ""
                   1973:   "neg%B0 %0")
                   1974: 
                   1975: (define_insn "negsf2"
                   1976:   [(set (match_operand:SF 0 "register_operand" "=f")
                   1977:        (neg:SF (match_operand:SF 1 "general_operand" "0")))]
                   1978:   "TARGET_80387"
                   1979:   "fchs")
                   1980: 
                   1981: (define_insn "negdf2"
                   1982:   [(set (match_operand:DF 0 "register_operand" "=f")
                   1983:        (neg:DF (match_operand:DF 1 "general_operand" "0")))]
                   1984:   "TARGET_80387"
                   1985:   "fchs")
                   1986: 
                   1987: (define_insn ""
                   1988:   [(set (match_operand:DF 0 "register_operand" "=f")
                   1989:        (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
                   1990:   "TARGET_80387"
                   1991:   "fchs")
                   1992: 
                   1993: ;; Absolute value instructions
                   1994: 
                   1995: (define_insn "abssf2"
                   1996:   [(set (match_operand:SF 0 "register_operand" "=f")
                   1997:        (abs:SF (match_operand:SF 1 "general_operand" "0")))]
                   1998:   "TARGET_80387"
                   1999:   "fabs")
                   2000: 
                   2001: (define_insn "absdf2"
                   2002:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2003:        (abs:DF (match_operand:DF 1 "general_operand" "0")))]
                   2004:   "TARGET_80387"
                   2005:   "fabs")
                   2006: 
                   2007: (define_insn ""
                   2008:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2009:        (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
                   2010:   "TARGET_80387"
                   2011:   "fabs")
                   2012: 
                   2013: (define_insn "sqrtsf2"
                   2014:   [(set (match_operand:SF 0 "register_operand" "=f")
                   2015:        (sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
                   2016:   "TARGET_80387"
                   2017:   "fsqrt")
                   2018: 
                   2019: (define_insn "sqrtdf2"
                   2020:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2021:        (sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
                   2022:   "TARGET_80387"
                   2023:   "fsqrt")
                   2024: 
                   2025: (define_insn ""
                   2026:   [(set (match_operand:DF 0 "register_operand" "=f")
                   2027:        (sqrt:DF (float_extend:DF
                   2028:                  (match_operand:SF 1 "general_operand" "0"))))]
                   2029:   "TARGET_80387"
                   2030:   "fsqrt")
                   2031: 
                   2032: ;;- one complement instructions
                   2033: 
                   2034: (define_insn "one_cmplsi2"
                   2035:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   2036:        (not:SI (match_operand:SI 1 "general_operand" "0")))]
                   2037:   ""
                   2038:   "not%L0 %0")
                   2039: 
                   2040: (define_insn "one_cmplhi2"
                   2041:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2042:        (not:HI (match_operand:HI 1 "general_operand" "0")))]
                   2043:   ""
                   2044:   "not%W0 %0")
                   2045: 
                   2046: (define_insn "one_cmplqi2"
                   2047:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2048:        (not:QI (match_operand:QI 1 "general_operand" "0")))]
                   2049:   ""
                   2050:   "not%B0 %0")
                   2051: 
                   2052: ;;- arithmetic shift instructions
                   2053: 
                   2054: ;; DImode shifts are implemented using the i386 "shift double" opcode,
                   2055: ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
                   2056: ;; is variable, then the count is in %cl and the "imm" operand is dropped
                   2057: ;; from the assembler input.
                   2058: 
                   2059: ;; This instruction shifts the target reg/mem as usual, but instead of
                   2060: ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
                   2061: ;; is a left shift double, bits are taken from the high order bits of
                   2062: ;; reg, else if the insn is a shift right double, bits are taken from the
                   2063: ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
                   2064: ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
                   2065: 
                   2066: ;; Since sh[lr]d does not change the `reg' operand, that is done
                   2067: ;; separately, making all shifts emit pairs of shift double and normal
                   2068: ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
                   2069: ;; support a 63 bit shift, each shift where the count is in a reg expands
                   2070: ;; to three pairs.  If the overall shift is by N bits, then the first two
                   2071: ;; pairs shift by N / 2 and the last pair by N & 1.
                   2072: 
                   2073: ;; If the shift count is a constant, we need never emit more than one
                   2074: ;; shift pair, instead using moves and sign extension for counts greater
                   2075: ;; than 31.
                   2076: 
                   2077: (define_insn "ashldi3"
                   2078:   [(set (match_operand:DI 0 "general_operand" "=&r")
                   2079:        (ashift:DI (match_operand:DI 1 "general_operand" "0")
                   2080:                   (match_operand:QI 2 "general_operand" "cJ")))
                   2081:    (clobber (match_dup 2))]
                   2082:   ""
                   2083:   "*
                   2084: {
                   2085:   rtx xops[4], low[1], high[1];
                   2086: 
                   2087:   CC_STATUS_INIT;
                   2088: 
                   2089:   split_di (operands, 1, low, high);
                   2090:   xops[0] = operands[2];
                   2091:   xops[1] = const1_rtx;
                   2092:   xops[2] = low[0];
                   2093:   xops[3] = high[0];
                   2094: 
                   2095:   if (REG_P (xops[0])) /* If shift count in %cl */
                   2096:     {
                   2097:       output_asm_insn (AS2 (ror%B0,%1,%0), xops);      /* shift count / 2 */
                   2098: 
                   2099:       output_asm_insn (AS2 (shld%L3,%2,%3), xops);
                   2100:       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
                   2101:       output_asm_insn (AS2 (shld%L3,%2,%3), xops);
                   2102:       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
                   2103: 
                   2104:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 7);      /* shift count & 1 */
                   2105: 
                   2106:       output_asm_insn (AS2 (shr%B0,%1,%0), xops);
                   2107: 
                   2108:       output_asm_insn (AS2 (shld%L3,%2,%3), xops);
                   2109:       output_asm_insn (AS2 (sal%L2,%0,%2), xops);
                   2110:     }
                   2111:   else if (GET_CODE (xops[0]) == CONST_INT)
                   2112:     {
                   2113:       if (INTVAL (xops[0]) > 31)
                   2114:        {
                   2115:          output_asm_insn (AS2 (mov%L3,%2,%3), xops);   /* Fast shift by 32 */
                   2116:          output_asm_insn (AS2 (xor%L2,%2,%2), xops);
                   2117: 
                   2118:          if (INTVAL (xops[0]) > 32)
                   2119:            {
                   2120:              xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32);
                   2121: 
                   2122:              output_asm_insn (AS2 (sal%3,%0,%3), xops); /* Remaining shift */
                   2123:            }
                   2124:        }
                   2125:       else
                   2126:         {
                   2127:          output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops);
                   2128:          output_asm_insn (AS2 (sal%L2,%0,%2), xops);
                   2129:        }
                   2130:     }
                   2131:   RET;
                   2132: }")
                   2133: 
                   2134: ;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg"
                   2135: ;; On i486, movl/sall appears slightly faster than leal, but the leal
                   2136: ;; is smaller - use leal for now unless the shift count is 1.
                   2137: 
                   2138: (define_insn "ashlsi3"
                   2139:   [(set (match_operand:SI 0 "general_operand" "=r,rm")
                   2140:        (ashift:SI (match_operand:SI 1 "general_operand" "r,0")
                   2141:                   (match_operand:SI 2 "general_operand" "M,cI")))]
                   2142:   ""
                   2143:   "*
                   2144: {
                   2145:   if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
                   2146:     {
                   2147:       if (TARGET_486 && INTVAL (operands[2]) == 1)
                   2148:        {
                   2149:          output_asm_insn (AS2 (mov%L0,%1,%0), operands);
                   2150:          return AS2 (add%L0,%1,%0);
                   2151:        }
                   2152:       else
                   2153:         {
                   2154:           CC_STATUS_INIT;
                   2155:           operands[1] = gen_rtx (MULT, SImode, operands[1],
                   2156:                                 gen_rtx (CONST_INT, VOIDmode,
                   2157:                                          1 << INTVAL (operands[2])));
                   2158:          return AS2 (lea%L0,%a1,%0);
                   2159:        }
                   2160:     }
                   2161: 
                   2162:   if (REG_P (operands[2]))
                   2163:     return AS2 (sal%L0,%b2,%0);
                   2164: 
                   2165:   if (REG_P (operands[0]) && operands[2] == const1_rtx)
                   2166:     return AS2 (add%L0,%0,%0);
                   2167: 
                   2168:   return AS2 (sal%L0,%2,%0);
                   2169: }")
                   2170: 
                   2171: (define_insn "ashlhi3"
                   2172:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2173:        (ashift:HI (match_operand:HI 1 "general_operand" "0")
                   2174:                   (match_operand:HI 2 "general_operand" "cI")))]
                   2175:   ""
                   2176:   "*
                   2177: {
                   2178:   if (REG_P (operands[2]))
                   2179:     return AS2 (sal%W0,%b2,%0);
                   2180: 
                   2181:   if (REG_P (operands[0]) && operands[2] == const1_rtx)
                   2182:     return AS2 (add%W0,%0,%0);
                   2183: 
                   2184:   return AS2 (sal%W0,%2,%0);
                   2185: }")
                   2186: 
                   2187: (define_insn "ashlqi3"
                   2188:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2189:        (ashift:QI (match_operand:QI 1 "general_operand" "0")
                   2190:                   (match_operand:QI 2 "general_operand" "cI")))]
                   2191:   ""
                   2192:   "*
                   2193: {
                   2194:   if (REG_P (operands[2]))
                   2195:     return AS2 (sal%B0,%b2,%0);
                   2196: 
                   2197:   if (REG_P (operands[0]) && operands[2] == const1_rtx)
                   2198:     return AS2 (add%B0,%0,%0);
                   2199: 
                   2200:   return AS2 (sal%B0,%2,%0);
                   2201: }")
                   2202: 
                   2203: ;; See comment above `ashldi3' about how this works.
                   2204: 
                   2205: (define_insn "ashrdi3"
                   2206:   [(set (match_operand:DI 0 "general_operand" "=&r")
                   2207:        (ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
                   2208:                     (match_operand:QI 2 "general_operand" "cJ")))
                   2209:    (clobber (match_dup 2))]
                   2210:   ""
                   2211:   "*
                   2212: {
                   2213:   rtx xops[5], low[1], high[1];
                   2214: 
                   2215:   CC_STATUS_INIT;
                   2216: 
                   2217:   split_di (operands, 1, low, high);
                   2218:   xops[0] = operands[2];
                   2219:   xops[1] = const1_rtx;
                   2220:   xops[2] = low[0];
                   2221:   xops[3] = high[0];
                   2222: 
                   2223:   if (REG_P (xops[0])) /* If shift count in %cl */
                   2224:     {
                   2225:       output_asm_insn (AS2 (ror%B0,%1,%0), xops);      /* shift count / 2 */
                   2226: 
                   2227:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2228:       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
                   2229:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2230:       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
                   2231: 
                   2232:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 7);      /* shift count & 1 */
                   2233: 
                   2234:       output_asm_insn (AS2 (shr%B0,%1,%0), xops);
                   2235: 
                   2236:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2237:       output_asm_insn (AS2 (sar%L3,%0,%3), xops);
                   2238:     }
                   2239:   else if (GET_CODE (xops[0]) == CONST_INT)
                   2240:     {
                   2241:       if (INTVAL (xops[0]) > 31)
                   2242:        {
                   2243:          xops[1] = gen_rtx (CONST_INT, VOIDmode, 31);
                   2244:          output_asm_insn (AS2 (mov%L2,%3,%2), xops);
                   2245:          output_asm_insn (AS2 (sar%L3,%1,%3), xops);   /* shift by 32 */
                   2246: 
                   2247:          if (INTVAL (xops[0]) > 32)
                   2248:            {
                   2249:              xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32);
                   2250: 
                   2251:              output_asm_insn (AS2 (sar%2,%0,%2), xops); /* Remaining shift */
                   2252:            }
                   2253:        }
                   2254:       else
                   2255:         {
                   2256:          output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
                   2257:          output_asm_insn (AS2 (sar%L3,%0,%3), xops);
                   2258:         }
                   2259:     }
                   2260:   RET;
                   2261: }")
                   2262: 
                   2263: (define_insn "ashrsi3"
                   2264:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   2265:        (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
                   2266:                     (match_operand:SI 2 "general_operand" "cI")))]
                   2267:   ""
                   2268:   "*
                   2269: {
                   2270:   if (REG_P (operands[2]))
                   2271:     return AS2 (sar%L0,%b2,%0);
                   2272:   else
                   2273:     return AS2 (sar%L0,%2,%0);
                   2274: }")
                   2275: 
                   2276: (define_insn "ashrhi3"
                   2277:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2278:        (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
                   2279:                     (match_operand:HI 2 "general_operand" "cI")))]
                   2280:   ""
                   2281:   "*
                   2282: {
                   2283:   if (REG_P (operands[2]))
                   2284:     return AS2 (sar%W0,%b2,%0);
                   2285:   else
                   2286:     return AS2 (sar%W0,%2,%0);
                   2287: }")
                   2288: 
                   2289: (define_insn "ashrqi3"
                   2290:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2291:        (ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
                   2292:                     (match_operand:QI 2 "general_operand" "cI")))]
                   2293:   ""
                   2294:   "*
                   2295: {
                   2296:   if (REG_P (operands[2]))
                   2297:     return AS2 (sar%B0,%b2,%0);
                   2298:   else
                   2299:     return AS2 (sar%B0,%2,%0);
                   2300: }")
                   2301: 
                   2302: ;;- logical shift instructions
                   2303: 
                   2304: ;; See comment above `ashldi3' about how this works.
                   2305: 
                   2306: (define_insn "lshrdi3"
                   2307:   [(set (match_operand:DI 0 "general_operand" "=&r")
                   2308:        (lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
                   2309:                     (match_operand:QI 2 "general_operand" "cJ")))
                   2310:    (clobber (match_dup 2))]
                   2311:   ""
                   2312:   "*
                   2313: {
                   2314:   rtx xops[5], low[1], high[1];
                   2315: 
                   2316:   CC_STATUS_INIT;
                   2317: 
                   2318:   split_di (operands, 1, low, high);
                   2319:   xops[0] = operands[2];
                   2320:   xops[1] = const1_rtx;
                   2321:   xops[2] = low[0];
                   2322:   xops[3] = high[0];
                   2323: 
                   2324:   if (REG_P (xops[0])) /* If shift count in %cl */
                   2325:     {
                   2326:       output_asm_insn (AS2 (ror%B0,%1,%0), xops);      /* shift count / 2 */
                   2327: 
                   2328:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2329:       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
                   2330:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2331:       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
                   2332: 
                   2333:       xops[1] = gen_rtx (CONST_INT, VOIDmode, 7);      /* shift count & 1 */
                   2334: 
                   2335:       output_asm_insn (AS2 (shr%B0,%1,%0), xops);
                   2336: 
                   2337:       output_asm_insn (AS2 (shrd%L2,%3,%2), xops);
                   2338:       output_asm_insn (AS2 (shr%L3,%0,%3), xops);
                   2339:     }
                   2340:   else if (GET_CODE (xops[0]) == CONST_INT)
                   2341:     {
                   2342:       if (INTVAL (xops[0]) > 31)
                   2343:        {
                   2344:          output_asm_insn (AS2 (mov%L2,%3,%2), xops);   /* Fast shift by 32 */
                   2345:          output_asm_insn (AS2 (xor%L3,%3,%3), xops);
                   2346: 
                   2347:          if (INTVAL (xops[0]) > 32)
                   2348:            {
                   2349:              xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (xops[0]) - 32);
                   2350: 
                   2351:              output_asm_insn (AS2 (shr%2,%0,%2), xops); /* Remaining shift */
                   2352:            }
                   2353:        }
                   2354:       else
                   2355:         {
                   2356:          output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops);
                   2357:          output_asm_insn (AS2 (shr%L3,%0,%3), xops);
                   2358:         }
                   2359:     }
                   2360:   RET;
                   2361: }")
                   2362: 
                   2363: (define_insn "lshrsi3"
                   2364:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   2365:        (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
                   2366:                     (match_operand:SI 2 "general_operand" "cI")))]
                   2367:   ""
                   2368:   "*
                   2369: {
                   2370:   if (REG_P (operands[2]))
                   2371:     return AS2 (shr%L0,%b2,%0);
                   2372:   else
                   2373:     return AS2 (shr%L0,%2,%1);
                   2374: }")
                   2375: 
                   2376: (define_insn "lshrhi3"
                   2377:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2378:        (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
                   2379:                     (match_operand:HI 2 "general_operand" "cI")))]
                   2380:   ""
                   2381:   "*
                   2382: {
                   2383:   if (REG_P (operands[2]))
                   2384:     return AS2 (shr%W0,%b2,%0);
                   2385:   else
                   2386:     return AS2 (shr%W0,%2,%0);
                   2387: }")
                   2388: 
                   2389: (define_insn "lshrqi3"
                   2390:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2391:        (lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
                   2392:                     (match_operand:QI 2 "general_operand" "cI")))]
                   2393:   ""
                   2394:   "*
                   2395: {
                   2396:   if (REG_P (operands[2]))
                   2397:     return AS2 (shr%B0,%b2,%0);
                   2398:   else
                   2399:     return AS2 (shr%B0,%2,%0);
                   2400: }")
                   2401: 
                   2402: ;;- rotate instructions
                   2403: 
                   2404: (define_insn "rotlsi3"
                   2405:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   2406:        (rotate:SI (match_operand:SI 1 "general_operand" "0")
                   2407:                   (match_operand:SI 2 "general_operand" "cI")))]
                   2408:   ""
                   2409:   "*
                   2410: {
                   2411:   if (REG_P (operands[2]))
                   2412:     return AS2 (rol%L0,%b2,%0);
                   2413:   else
                   2414:     return AS2 (rol%L0,%2,%0);
                   2415: }")
                   2416: 
                   2417: (define_insn "rotlhi3"
                   2418:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2419:        (rotate:HI (match_operand:HI 1 "general_operand" "0")
                   2420:                   (match_operand:HI 2 "general_operand" "cI")))]
                   2421:   ""
                   2422:   "*
                   2423: {
                   2424:   if (REG_P (operands[2]))
                   2425:     return AS2 (rol%W0,%b2,%0);
                   2426:   else
                   2427:     return AS2 (rol%W0,%2,%0);
                   2428: }")
                   2429: 
                   2430: (define_insn "rotlqi3"
                   2431:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2432:        (rotate:QI (match_operand:QI 1 "general_operand" "0")
                   2433:                   (match_operand:QI 2 "general_operand" "cI")))]
                   2434:   ""
                   2435:   "*
                   2436: {
                   2437:   if (REG_P (operands[2]))
                   2438:     return AS2 (rol%B0,%b2,%0);
                   2439:   else
                   2440:     return AS2 (rol%B0,%2,%0);
                   2441: }")
                   2442: 
                   2443: (define_insn "rotrsi3"
                   2444:   [(set (match_operand:SI 0 "general_operand" "=rm")
                   2445:        (rotatert:SI (match_operand:SI 1 "general_operand" "0")
                   2446:                     (match_operand:SI 2 "general_operand" "cI")))]
                   2447:   ""
                   2448:   "*
                   2449: {
                   2450:   if (REG_P (operands[2]))
                   2451:     return AS2 (ror%L0,%b2,%0);
                   2452:   else
                   2453:     return AS2 (ror%L0,%2,%0);
                   2454: }")
                   2455: 
                   2456: (define_insn "rotrhi3"
                   2457:   [(set (match_operand:HI 0 "general_operand" "=rm")
                   2458:        (rotatert:HI (match_operand:HI 1 "general_operand" "0")
                   2459:                     (match_operand:HI 2 "general_operand" "cI")))]
                   2460:   ""
                   2461:   "*
                   2462: {
                   2463:   if (REG_P (operands[2]))
                   2464:     return AS2 (ror%W0,%b2,%0);
                   2465:   else
                   2466:     return AS2 (ror%W0,%2,%0);
                   2467: }")
                   2468: 
                   2469: (define_insn "rotrqi3"
                   2470:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2471:        (rotatert:QI (match_operand:QI 1 "general_operand" "0")
                   2472:                     (match_operand:QI 2 "general_operand" "cI")))]
                   2473:   ""
                   2474:   "*
                   2475: {
                   2476:   if (REG_P (operands[2]))
                   2477:     return AS2 (ror%B0,%b2,%0);
                   2478:   else
                   2479:     return AS2 (ror%B0,%2,%0);
                   2480: }")
                   2481: 
                   2482: /*
                   2483: ;; This usually looses.  But try a define_expand to recognize a few case
                   2484: ;; we can do efficiently, such as accessing the "high" QImode registers,
                   2485: ;; %ah, %bh, %ch, %dh.
                   2486: (define_insn "insv"
                   2487:   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r")
                   2488:                         (match_operand:SI 1 "general_operand" "i")
                   2489:                         (match_operand:SI 2 "general_operand" "i"))
                   2490:        (match_operand:SI 3 "general_operand" "ri"))]
                   2491:   ""
                   2492:   "*
                   2493: {
                   2494:   if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode))
                   2495:     abort ();
                   2496:   if (GET_CODE (operands[3]) == CONST_INT)
                   2497:     {
                   2498:       unsigned int mask = (1 << INTVAL (operands[1])) - 1; 
                   2499:       operands[1] = gen_rtx (CONST_INT, VOIDmode,
                   2500:                                        ~(mask << INTVAL (operands[2])));
                   2501:       output_asm_insn (AS2 (and%L0,%1,%0), operands);
                   2502:       operands[3] = gen_rtx (CONST_INT, VOIDmode,
                   2503:                             INTVAL (operands[3]) << INTVAL (operands[2]));
                   2504:       output_asm_insn (AS2 (or%L0,%3,%0), operands);
                   2505:     }
                   2506:   else
                   2507:     {
                   2508:       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
                   2509:       if (INTVAL (operands[2]))
                   2510:        output_asm_insn (AS2 (ror%L0,%2,%0), operands);
                   2511:       output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands);
                   2512:       operands[2] = gen_rtx (CONST_INT, VOIDmode,
                   2513:                             BITS_PER_WORD
                   2514:                             - INTVAL (operands[1]) - INTVAL (operands[2]));
                   2515:       if (INTVAL (operands[2]))
                   2516:        output_asm_insn (AS2 (ror%L0,%2,%0), operands);
                   2517:     }
                   2518:   RET;
                   2519: }")
                   2520: */
                   2521: /*
                   2522: ;; ??? There are problems with the mode of operand[3].  The point of this
                   2523: ;; is to represent an HImode move to a "high byte" register.
                   2524: 
                   2525: (define_expand "insv"
                   2526:   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
                   2527:                         (match_operand:SI 1 "immediate_operand" "")
                   2528:                         (match_operand:SI 2 "immediate_operand" ""))
                   2529:        (match_operand:QI 3 "general_operand" "ri"))]
                   2530:   ""
                   2531:   "
                   2532: {
                   2533:   if (GET_CODE (operands[1]) != CONST_INT
                   2534:       || GET_CODE (operands[2]) != CONST_INT)
                   2535:     FAIL;
                   2536: 
                   2537:   if (! (INTVAL (operands[1]) == 8
                   2538:         && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0))
                   2539:       && ! INTVAL (operands[1]) == 1)
                   2540:     FAIL;
                   2541: }")
                   2542: 
                   2543: ;; ??? Are these constraints right?
                   2544: (define_insn ""
                   2545:   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+&qo")
                   2546:                         (const_int 8)
                   2547:                         (const_int 8))
                   2548:        (match_operand:QI 1 "general_operand" "qn"))]
                   2549:   ""
                   2550:   "*
                   2551: {
                   2552:   if (REG_P (operands[0]))
                   2553:     return AS2 (mov%B0,%1,%h0);
                   2554: 
                   2555:   operands[0] = adj_offsettable_operand (operands[0], 1);
                   2556:   return AS2 (mov%B0,%1,%0);
                   2557: }")
                   2558: */
                   2559: 
                   2560: ;; On i386, the register count for a bit operation is *not* truncated,
                   2561: ;; so SHIFT_COUNT_TRUNCATED must not be defined.
                   2562: 
                   2563: ;; On i486, the shift & or/and code is faster than bts or btr.  If
                   2564: ;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code.
                   2565: 
                   2566: ;; On i386, bts is a little faster if operands[0] is a reg, and a
                   2567: ;; little slower if operands[0] is a MEM, than the shift & or/and code.
                   2568: ;; Use bts & btr, since they reload better.
                   2569: 
                   2570: ;; General bit set and clear.
                   2571: (define_insn ""
                   2572:   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm")
                   2573:                         (const_int 1)
                   2574:                         (match_operand:SI 2 "nonimmediate_operand" "r"))
                   2575:        (match_operand:SI 3 "immediate_operand" "i"))]
                   2576:   "! TARGET_486"
                   2577:   "*
                   2578: {
                   2579:   CC_STATUS_INIT;
                   2580: 
                   2581:   if (INTVAL (operands[3]) == 1)
                   2582:     return AS2 (bts%L0,%2,%0);
                   2583:   else
                   2584:     return AS2 (btr%L0,%2,%0);
                   2585: }")
                   2586: 
                   2587: ;; Bit complement.  See comments on previous pattern.
                   2588: ;; ??? Is this really worthwhile?
                   2589: (define_insn ""
                   2590:   [(set (match_operand:SI 0 "general_operand" "+rm")
                   2591:        (xor:SI (ashift:SI (const_int 1)
                   2592:                           (match_operand:SI 1 "general_operand" "r"))
                   2593:                (match_dup 0)))]
                   2594:   "! TARGET_486"
                   2595:   "*
                   2596: {
                   2597:   CC_STATUS_INIT;
                   2598: 
                   2599:   return AS2 (btc%L0,%1,%0);
                   2600: }")
                   2601: 
                   2602: /* ??? This works, but that SUBREG looks dangerous.
                   2603: (define_insn ""
                   2604:   [(set (match_operand:HI 0 "general_operand" "+rm")
                   2605:        (xor:HI (subreg:HI
                   2606:                 (ashift:SI (const_int 1)
                   2607:                            (sign_extend:SI
                   2608:                             (match_operand:HI 1 "nonimmediate_operand" "r"))) 0)
                   2609:                (match_dup 0)))]
                   2610:   "! TARGET_486"
                   2611:   "*
                   2612: {
                   2613:   CC_STATUS_INIT;
                   2614: 
                   2615:   return AS2 (btc%W0,%1,%0);
                   2616: }")
                   2617: */
                   2618: 
                   2619: ;; Recognizers for bit-test instructions.
                   2620: 
                   2621: ;; The bt opcode allows a MEM in operands[0].  But on both i386 and
                   2622: ;; i486, it is faster to copy a MEM to REG and then use bt, than to use
                   2623: ;; bt on the MEM directly.
                   2624: 
                   2625: (define_insn ""
                   2626:   [(set (cc0) (zero_extract (match_operand:QI 0 "register_operand" "q")
                   2627:                            (const_int 1)
                   2628:                            (match_operand:SI 1 "general_operand" "ri")))]
                   2629:   ""
                   2630:   "*
                   2631: {
                   2632:   if (GET_CODE (operands[1]) == CONST_INT)
                   2633:     {
                   2634:       operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1]));
                   2635:       output_asm_insn (AS2 (test%B0,%1,%0), operands);
                   2636:     }
                   2637:   else
                   2638:     {
                   2639:       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
                   2640:       cc_status.flags |= CC_Z_IN_NOT_C;
                   2641:       output_asm_insn (AS2 (bt%L0,%1,%0), operands);
                   2642:     }
                   2643:   RET;
                   2644: }")
                   2645: 
                   2646: (define_insn ""
                   2647:   [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
                   2648:                            (const_int 1)
                   2649:                            (match_operand:SI 1 "general_operand" "ri")))
                   2650:    (clobber (match_scratch:SI 2 "=&r"))]
                   2651:   ""
                   2652:   "*
                   2653: {
                   2654:   /* Copy memory to scratch register; pretend it was there to start with.  */
                   2655:   if (GET_CODE (operands[0]) == MEM)
                   2656:     {
                   2657:       output_asm_insn (AS2 (mov%L2,%0,%2), operands);
                   2658:       operands[0] = operands[2];
                   2659:     }
                   2660:   if (GET_CODE (operands[1]) == CONST_INT)
                   2661:     {
                   2662:       operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1]));
                   2663:       output_asm_insn (AS2 (test%L0,%1,%0), operands);
                   2664:     }
                   2665:   else
                   2666:     {
                   2667:       operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
                   2668:       cc_status.flags |= CC_Z_IN_NOT_C;
                   2669:       output_asm_insn (AS2 (bt%L0,%1,%0), operands);
                   2670:     }
                   2671:   RET;
                   2672: }")
                   2673: 
                   2674: (define_insn ""
                   2675:   [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "r")
                   2676:                            (const_int 1)
                   2677:                            (match_operand:SI 1 "general_operand" "ri")))]
                   2678:   ""
                   2679:   "*
                   2680: {
                   2681:   if (GET_CODE (operands[1]) == CONST_INT)
                   2682:     {
                   2683:       operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1]));
                   2684:       output_asm_insn (AS2 (test%W0,%1,%0), operands);
                   2685:     }
                   2686:   else
                   2687:     {
                   2688:       cc_status.flags |= CC_Z_IN_NOT_C;
                   2689:       output_asm_insn (AS2 (bt%W0,%1,%0), operands);
                   2690:     }
                   2691:   RET;
                   2692: }")
                   2693: 
                   2694: (define_insn ""
                   2695:   [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "r")
                   2696:                            (const_int 1)
                   2697:                            (match_operand:SI 1 "general_operand" "ri")))]
                   2698:   ""
                   2699:   "*
                   2700: {
                   2701:   if (GET_CODE (operands[1]) == CONST_INT)
                   2702:     {
                   2703:       operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1]));
                   2704:       output_asm_insn (AS2 (test%L0,%1,%0), operands);
                   2705:     }
                   2706:   else
                   2707:     {
                   2708:       cc_status.flags |= CC_Z_IN_NOT_C;
                   2709:       output_asm_insn (AS2 (bt%L0,%1,%0), operands);
                   2710:     }
                   2711:   RET;
                   2712: }")
                   2713: 
                   2714: ;; Store-flag instructions.
                   2715: 
                   2716: (define_insn "seq"
                   2717:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2718:        (eq:QI (cc0) (const_int 0)))]
                   2719:   ""
                   2720:   "*
                   2721: {
                   2722:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2723:     return AS1 (setnb,%0);
                   2724:   else
                   2725:     return AS1 (sete,%0);
                   2726: }
                   2727: ")
                   2728: 
                   2729: (define_insn "sne"
                   2730:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2731:        (ne:QI (cc0) (const_int 0)))]
                   2732:   ""
                   2733:   "*
                   2734: {
                   2735:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2736:     return AS1 (setb,%0);
                   2737:   else
                   2738:     return AS1 (setne,%0);
                   2739: }
                   2740: ")
                   2741: 
                   2742: (define_insn "sgt"
                   2743:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2744:        (gt:QI (cc0) (const_int 0)))]
                   2745:   ""
                   2746:   "* OUTPUT_JUMP (\"setg %0\", \"seta %0\", 0); ")
                   2747: 
                   2748: (define_insn "sgtu"
                   2749:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2750:        (gtu:QI (cc0) (const_int 0)))]
                   2751:   ""
                   2752:   "* return \"seta %0\"; ")
                   2753: 
                   2754: (define_insn "slt"
                   2755:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2756:        (lt:QI (cc0) (const_int 0)))]
                   2757:   ""
                   2758:   "* OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); ")
                   2759: 
                   2760: (define_insn "sltu"
                   2761:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2762:        (ltu:QI (cc0) (const_int 0)))]
                   2763:   ""
                   2764:   "* return \"setb %0\"; ")
                   2765: 
                   2766: (define_insn "sge"
                   2767:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2768:        (ge:QI (cc0) (const_int 0)))]
                   2769:   ""
                   2770:   "* OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); ")
                   2771: 
                   2772: (define_insn "sgeu"
                   2773:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2774:        (geu:QI (cc0) (const_int 0)))]
                   2775:   ""
                   2776:   "* return \"setae %0\"; ")
                   2777: 
                   2778: (define_insn "sle"
                   2779:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2780:        (le:QI (cc0) (const_int 0)))]
                   2781:   ""
                   2782:   "* OUTPUT_JUMP (\"setle %0\", \"setbe %0\", 0); ")
                   2783: 
                   2784: (define_insn "sleu"
                   2785:   [(set (match_operand:QI 0 "general_operand" "=qm")
                   2786:        (leu:QI (cc0) (const_int 0)))]
                   2787:   ""
                   2788:   "* return \"setbe %0\"; ")
                   2789: 
                   2790: ;; Basic conditional jump instructions.
                   2791: ;; We ignore the overflow flag for signed branch instructions.
                   2792: 
                   2793: (define_insn "beq"
                   2794:   [(set (pc)
                   2795:        (if_then_else (eq (cc0)
                   2796:                          (const_int 0))
                   2797:                      (label_ref (match_operand 0 "" ""))
                   2798:                      (pc)))]
                   2799:   ""
                   2800:   "*
                   2801: {
                   2802:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2803:     return \"jnc %l0\";
                   2804:   else
                   2805:     return \"je %l0\";
                   2806: }")
                   2807: 
                   2808: (define_insn "bne"
                   2809:   [(set (pc)
                   2810:        (if_then_else (ne (cc0)
                   2811:                          (const_int 0))
                   2812:                      (label_ref (match_operand 0 "" ""))
                   2813:                      (pc)))]
                   2814:   ""
                   2815:   "*
                   2816: {
                   2817:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2818:     return \"jc %l0\";
                   2819:   else
                   2820:     return \"jne %l0\";
                   2821: }")
                   2822: 
                   2823: (define_insn "bgt"
                   2824:   [(set (pc)
                   2825:        (if_then_else (gt (cc0)
                   2826:                          (const_int 0))
                   2827:                      (label_ref (match_operand 0 "" ""))
                   2828:                      (pc)))]
                   2829:   ""
                   2830:   "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
                   2831: 
                   2832: (define_insn "bgtu"
                   2833:   [(set (pc)
                   2834:        (if_then_else (gtu (cc0)
                   2835:                           (const_int 0))
                   2836:                      (label_ref (match_operand 0 "" ""))
                   2837:                      (pc)))]
                   2838:   ""
                   2839:   "ja %l0")
                   2840: 
                   2841: ;; There is no jump insn to check for `<' on IEEE floats.
                   2842: ;; Page 17-80 in the 80387 manual says jb, but that's wrong;
                   2843: ;; jb checks for `not >='.  So swap the operands and do `>'.
                   2844: (define_expand "blt"
                   2845:   [(set (pc)
                   2846:        (if_then_else (lt (cc0)
                   2847:                          (const_int 0))
                   2848:                      (label_ref (match_operand 0 "" ""))
                   2849:                      (pc)))]
                   2850:   ""
                   2851:   "
                   2852: {
                   2853:   rtx prev = get_last_insn_anywhere ();
                   2854:   rtx body = PATTERN (prev);
                   2855:   rtx comp;
                   2856:   if (GET_CODE (body) == SET)
                   2857:     comp = SET_SRC (body);
                   2858:   else
                   2859:     comp = SET_SRC (XVECEXP (body, 0, 0));
                   2860: 
                   2861:   if (GET_CODE (comp) == COMPARE
                   2862:       ? GET_MODE_CLASS (GET_MODE (XEXP (comp, 0))) == MODE_FLOAT
                   2863:       : GET_MODE_CLASS (GET_MODE (comp)) == MODE_FLOAT)
                   2864:     {
                   2865:       reverse_comparison (prev);
                   2866:       emit_insn (gen_bgt (operands[0]));
                   2867:       DONE;
                   2868:     }
                   2869: }")
                   2870: 
                   2871: (define_insn ""
                   2872:   [(set (pc)
                   2873:        (if_then_else (lt (cc0)
                   2874:                          (const_int 0))
                   2875:                      (label_ref (match_operand 0 "" ""))
                   2876:                      (pc)))]
                   2877:   ""
                   2878:   "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
                   2879: 
                   2880: (define_insn "bltu"
                   2881:   [(set (pc)
                   2882:        (if_then_else (ltu (cc0)
                   2883:                           (const_int 0))
                   2884:                      (label_ref (match_operand 0 "" ""))
                   2885:                      (pc)))]
                   2886:   ""
                   2887:   "jb %l0")
                   2888: 
                   2889: (define_insn "bge"
                   2890:   [(set (pc)
                   2891:        (if_then_else (ge (cc0)
                   2892:                          (const_int 0))
                   2893:                      (label_ref (match_operand 0 "" ""))
                   2894:                      (pc)))]
                   2895:   ""
                   2896:   "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")")
                   2897: 
                   2898: (define_insn "bgeu"
                   2899:   [(set (pc)
                   2900:        (if_then_else (geu (cc0)
                   2901:                           (const_int 0))
                   2902:                      (label_ref (match_operand 0 "" ""))
                   2903:                      (pc)))]
                   2904:   ""
                   2905:   "jae %l0")
                   2906: 
                   2907: ;; See comment on `blt', above.
                   2908: (define_expand "ble"
                   2909:   [(set (pc)
                   2910:        (if_then_else (le (cc0)
                   2911:                          (const_int 0))
                   2912:                      (label_ref (match_operand 0 "" ""))
                   2913:                      (pc)))]
                   2914:   ""
                   2915:   "
                   2916: {
                   2917:   rtx prev = get_last_insn_anywhere ();
                   2918:   rtx body = PATTERN (prev);
                   2919:   rtx comp;
                   2920:   if (GET_CODE (body) == SET)
                   2921:     comp = SET_SRC (body);
                   2922:   else
                   2923:     comp = SET_SRC (XVECEXP (body, 0, 0));
                   2924: 
                   2925:   if (GET_CODE (comp) == COMPARE
                   2926:       ? GET_MODE_CLASS (GET_MODE (XEXP (comp, 0))) == MODE_FLOAT
                   2927:       : GET_MODE_CLASS (GET_MODE (comp)) == MODE_FLOAT)
                   2928:     {
                   2929:       reverse_comparison (prev);
                   2930:       emit_insn (gen_bge (operands[0]));
                   2931:       DONE;
                   2932:     }
                   2933: }")
                   2934: 
                   2935: (define_insn ""
                   2936:   [(set (pc)
                   2937:        (if_then_else (le (cc0)
                   2938:                          (const_int 0))
                   2939:                      (label_ref (match_operand 0 "" ""))
                   2940:                      (pc)))]
                   2941:   ""
                   2942:   "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
                   2943: 
                   2944: (define_insn "bleu"
                   2945:   [(set (pc)
                   2946:        (if_then_else (leu (cc0)
                   2947:                           (const_int 0))
                   2948:                      (label_ref (match_operand 0 "" ""))
                   2949:                      (pc)))]
                   2950:   ""
                   2951:   "jbe %l0")
                   2952: 
                   2953: ;; Negated conditional jump instructions.
                   2954: 
                   2955: (define_insn ""
                   2956:   [(set (pc)
                   2957:        (if_then_else (eq (cc0)
                   2958:                          (const_int 0))
                   2959:                      (pc)
                   2960:                      (label_ref (match_operand 0 "" ""))))]
                   2961:   ""
                   2962:   "*
                   2963: {
                   2964:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2965:     return \"jc %l0\";
                   2966:   else
                   2967:     return \"jne %l0\";
                   2968: }")
                   2969: 
                   2970: (define_insn ""
                   2971:   [(set (pc)
                   2972:        (if_then_else (ne (cc0)
                   2973:                          (const_int 0))
                   2974:                      (pc)
                   2975:                      (label_ref (match_operand 0 "" ""))))]
                   2976:   ""
                   2977:   "*
                   2978: {
                   2979:   if (cc_prev_status.flags & CC_Z_IN_NOT_C)
                   2980:     return \"jnc %l0\";
                   2981:   else
                   2982:     return \"je %l0\";
                   2983: }")
                   2984: 
                   2985: (define_insn ""
                   2986:   [(set (pc)
                   2987:        (if_then_else (gt (cc0)
                   2988:                          (const_int 0))
                   2989:                      (pc)
                   2990:                      (label_ref (match_operand 0 "" ""))))]
                   2991:   ""
                   2992:   "*OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", 0) ")
                   2993: 
                   2994: (define_insn ""
                   2995:   [(set (pc)
                   2996:        (if_then_else (gtu (cc0)
                   2997:                           (const_int 0))
                   2998:                      (pc)
                   2999:                      (label_ref (match_operand 0 "" ""))))]
                   3000:   ""
                   3001:   "jbe %l0")
                   3002: 
                   3003: (define_insn ""
                   3004:   [(set (pc)
                   3005:        (if_then_else (lt (cc0)
                   3006:                          (const_int 0))
                   3007:                      (pc)
                   3008:                      (label_ref (match_operand 0 "" ""))))]
                   3009:   ""
                   3010:   "*OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\")
                   3011: ")
                   3012: 
                   3013: (define_insn ""
                   3014:   [(set (pc)
                   3015:        (if_then_else (ltu (cc0)
                   3016:                           (const_int 0))
                   3017:                      (pc)
                   3018:                      (label_ref (match_operand 0 "" ""))))]
                   3019:   ""
                   3020:   "jae %l0")
                   3021: 
                   3022: (define_insn ""
                   3023:   [(set (pc)
                   3024:        (if_then_else (ge (cc0)
                   3025:                          (const_int 0))
                   3026:                      (pc)
                   3027:                      (label_ref (match_operand 0 "" ""))))]
                   3028:   ""
                   3029:   "*OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\")")
                   3030: 
                   3031: (define_insn ""
                   3032:   [(set (pc)
                   3033:        (if_then_else (geu (cc0)
                   3034:                           (const_int 0))
                   3035:                      (pc)
                   3036:                      (label_ref (match_operand 0 "" ""))))]
                   3037:   ""
                   3038:   "jb %l0")
                   3039: 
                   3040: (define_insn ""
                   3041:   [(set (pc)
                   3042:        (if_then_else (le (cc0)
                   3043:                          (const_int 0))
                   3044:                      (pc)
                   3045:                      (label_ref (match_operand 0 "" ""))))]
                   3046:   ""
                   3047:   "*OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", 0)")
                   3048: 
                   3049: (define_insn ""
                   3050:   [(set (pc)
                   3051:        (if_then_else (leu (cc0)
                   3052:                           (const_int 0))
                   3053:                      (pc)
                   3054:                      (label_ref (match_operand 0 "" ""))))]
                   3055:   ""
                   3056:   "ja %l0")
                   3057: 
                   3058: ;; Unconditional and other jump instructions
                   3059: 
                   3060: (define_insn "jump"
                   3061:   [(set (pc)
                   3062:        (label_ref (match_operand 0 "" "")))]
                   3063:   ""
                   3064:   "jmp %l0")
                   3065: 
                   3066: (define_insn "indirect_jump"
                   3067:   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
                   3068:   ""
                   3069:   "*
                   3070: {
                   3071:   CC_STATUS_INIT;
                   3072: 
                   3073:   return AS1 (jmp,%*%0);
                   3074: }")
                   3075: 
                   3076: ;; Implement switch statements when generating PIC code.  Switches are
                   3077: ;; implemented by `tablejump' when not using -fpic.
                   3078: 
                   3079: ;; Emit code here to do the range checking and make the index zero based.
                   3080: 
                   3081: (define_expand "casesi"
                   3082:   [(parallel
                   3083:     [(set (pc)
                   3084:          (if_then_else (leu (minus:SI
                   3085:                              (match_operand:SI 0 "general_operand" "")
                   3086:                              (match_operand:SI 1 "const_int_operand" ""))
                   3087:                             (match_operand:SI 2 "const_int_operand" ""))
                   3088:                        (plus:SI (mem:SI (plus:SI (pc)
                   3089:                                                  (minus:SI (match_dup 0)
                   3090:                                                            (match_dup 1))))
                   3091:                                 (label_ref (match_operand 3 "" "")))
                   3092:                        (pc)))
                   3093:      (use (label_ref (match_operand 4 "" "")))
                   3094:      (clobber (match_scratch:SI 5 ""))])]
                   3095:   "flag_pic"
                   3096:   "
                   3097: {
                   3098:   rtx reg = gen_reg_rtx (SImode);
                   3099: 
                   3100:   current_function_uses_pic_offset_table = 1;
                   3101: 
                   3102:   emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
                   3103:   emit_insn (gen_cmpsi (reg, operands[2]));
                   3104:   emit_jump_insn (gen_bgtu (operands[4]));
                   3105:   operands[0] = reg;
                   3106:   operands[1] = CONST0_RTX (SImode);
                   3107: }")
                   3108: 
                   3109: ;; Implement a casesi insn.
                   3110: 
                   3111: ;; Each entry in the "addr_diff_vec" looks like this as the result of the
                   3112: ;; two rules below:
                   3113: ;; 
                   3114: ;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
                   3115: ;; 
                   3116: ;; 1. An expression involving an external reference may only use the
                   3117: ;;    addition operator, and only with an assembly-time constant.
                   3118: ;;    The example above satisfies this because ".-.L2" is a constant.
                   3119: ;; 
                   3120: ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
                   3121: ;;    given the value of "GOT - .", where GOT is the actual address of
                   3122: ;;    the Global Offset Table.  Therefore, the .long above actually
                   3123: ;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
                   3124: ;;    expression "GOT - .L2" by itself would generate an error from as(1).
                   3125: ;; 
                   3126: ;; The pattern below emits code that looks like this:
                   3127: ;; 
                   3128: ;;     movl %ebx,reg
                   3129: ;;     subl TABLE@GOTOFF(%ebx,index,4),reg
                   3130: ;;     jmp reg
                   3131: ;; 
                   3132: ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
                   3133: ;; the addr_diff_vec is known to be part of this module.
                   3134: ;; 
                   3135: ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
                   3136: ;; evaluates to just ".L2".
                   3137: 
                   3138: (define_insn ""
                   3139:   [(set (pc)
                   3140:        (if_then_else (leu (minus:SI
                   3141:                            (match_operand:SI 0 "general_operand" "r")
                   3142:                            (match_operand:SI 1 "const_int_operand" "i"))
                   3143:                           (match_operand:SI 2 "const_int_operand" "i"))
                   3144:                      (plus:SI (mem:SI (plus:SI (pc)
                   3145:                                                (minus:SI (match_dup 0)
                   3146:                                                          (match_dup 1))))
                   3147:                               (label_ref (match_operand 3 "" "")))
                   3148:                      (pc)))
                   3149:    (use (label_ref (match_operand 4 "" "")))
                   3150:    (clobber (match_scratch:SI 5 "=&r"))]
                   3151:   ""
                   3152:   "*
                   3153: {
                   3154:   rtx xops[4];
                   3155: 
                   3156:   xops[0] = pic_offset_table_rtx;
                   3157:   xops[1] = operands[5];
                   3158:   xops[2] = operands[3];
                   3159:   xops[3] = operands[0];
                   3160: 
                   3161:   output_asm_insn (AS2 (mov%L1,%0,%1), xops);
                   3162:   output_asm_insn (\"sub%L1 %l2@GOTOFF(%0,%3,4),%1\", xops);
                   3163:   output_asm_insn (AS1 (jmp,%*%1), xops);
                   3164:   ASM_OUTPUT_ALIGN_CODE (asm_out_file);
                   3165:   RET;
                   3166: }")
                   3167: 
                   3168: (define_insn "tablejump"
                   3169:   [(set (pc) (match_operand:SI 0 "general_operand" "rm"))
                   3170:    (use (label_ref (match_operand 1 "" "")))]
                   3171:   ""
                   3172:   "*
                   3173: {
                   3174:   CC_STATUS_INIT;
                   3175: 
                   3176:   return AS1 (jmp,%*%0);
                   3177: }")
                   3178: 
                   3179: ;; Call insns.
                   3180: 
                   3181: ;; If generating PIC code, the predicate indirect_operand will fail
                   3182: ;; for operands[0] containing symbolic references on all of the named
                   3183: ;; call* patterns.  Each named pattern is followed by an unnamed pattern
                   3184: ;; that matches any call to a symbolic CONST (ie, a symbol_ref).  The
                   3185: ;; unnamed patterns are only used while generating PIC code, because
                   3186: ;; otherwise the named patterns match.
                   3187: 
                   3188: ;; Call subroutine returning no value.
                   3189: 
                   3190: (define_expand "call_pop"
                   3191:   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
                   3192:                    (match_operand:SI 1 "general_operand" ""))
                   3193:              (set (reg:SI 7)
                   3194:                   (plus:SI (reg:SI 7)
                   3195:                            (match_operand:SI 3 "immediate_operand" "")))])]
                   3196:   ""
                   3197:   "
                   3198: {
                   3199:   if (flag_pic)
                   3200:     current_function_uses_pic_offset_table = 1;
                   3201: }")
                   3202: 
                   3203: (define_insn ""
                   3204:   [(call (match_operand:QI 0 "indirect_operand" "m")
                   3205:         (match_operand:SI 1 "general_operand" "g"))
                   3206:    (set (reg:SI 7) (plus:SI (reg:SI 7)
                   3207:                            (match_operand:SI 3 "immediate_operand" "i")))]
                   3208:   ""
                   3209:   "*
                   3210: {
                   3211:   if (GET_CODE (operands[0]) == MEM
                   3212:       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
                   3213:     {
                   3214:       operands[0] = XEXP (operands[0], 0);
                   3215:       return AS1 (call,%*%0);
                   3216:     }
                   3217:   else
                   3218:     return AS1 (call,%P0);
                   3219: }")
                   3220: 
                   3221: (define_insn ""
                   3222:   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
                   3223:         (match_operand:SI 1 "general_operand" "g"))
                   3224:    (set (reg:SI 7) (plus:SI (reg:SI 7)
                   3225:                            (match_operand:SI 3 "immediate_operand" "i")))]
                   3226:   ""
                   3227:   "call %P0")
                   3228: 
                   3229: (define_expand "call"
                   3230:   [(call (match_operand:QI 0 "indirect_operand" "")
                   3231:         (match_operand:SI 1 "general_operand" ""))]
                   3232:   ;; Operand 1 not used on the i386.
                   3233:   ""
                   3234:   "
                   3235: {
                   3236:   if (flag_pic)
                   3237:     current_function_uses_pic_offset_table = 1;
                   3238: }")
                   3239: 
                   3240: (define_insn ""
                   3241:   [(call (match_operand:QI 0 "indirect_operand" "m")
                   3242:         (match_operand:SI 1 "general_operand" "g"))]
                   3243:   ;; Operand 1 not used on the i386.
                   3244:   ""
                   3245:   "*
                   3246: {
                   3247:   if (GET_CODE (operands[0]) == MEM
                   3248:       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
                   3249:     {
                   3250:       operands[0] = XEXP (operands[0], 0);
                   3251:       return AS1 (call,%*%0);
                   3252:     }
                   3253:   else
                   3254:     return AS1 (call,%P0);
                   3255: }")
                   3256: 
                   3257: (define_insn ""
                   3258:   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
                   3259:         (match_operand:SI 1 "general_operand" "g"))]
                   3260:   ;; Operand 1 not used on the i386.
                   3261:   ""
                   3262:   "call %P0")
                   3263: 
                   3264: ;; Call subroutine, returning value in operand 0
                   3265: ;; (which must be a hard register).
                   3266: 
                   3267: (define_expand "call_value_pop"
                   3268:   [(parallel [(set (match_operand 0 "" "")
                   3269:                   (call (match_operand:QI 1 "indirect_operand" "")
                   3270:                         (match_operand:SI 2 "general_operand" "")))
                   3271:              (set (reg:SI 7)
                   3272:                   (plus:SI (reg:SI 7)
                   3273:                            (match_operand:SI 4 "immediate_operand" "")))])]
                   3274:   ""
                   3275:   "
                   3276: {
                   3277:   if (flag_pic)
                   3278:     current_function_uses_pic_offset_table = 1;
                   3279: }")
                   3280: 
                   3281: (define_insn ""
                   3282:   [(set (match_operand 0 "" "=rf")
                   3283:        (call (match_operand:QI 1 "indirect_operand" "m")
                   3284:              (match_operand:SI 2 "general_operand" "g")))
                   3285:    (set (reg:SI 7) (plus:SI (reg:SI 7)
                   3286:                            (match_operand:SI 4 "immediate_operand" "i")))]
                   3287:   ""
                   3288:   "*
                   3289: {
                   3290:   if (GET_CODE (operands[1]) == MEM
                   3291:       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
                   3292:     {
                   3293:       operands[1] = XEXP (operands[1], 0);
                   3294:       output_asm_insn (AS1 (call,%*%1), operands);
                   3295:     }
                   3296:   else
                   3297:     output_asm_insn (AS1 (call,%P1), operands);
                   3298: 
                   3299:   RET;
                   3300: }")
                   3301: 
                   3302: (define_insn ""
                   3303:   [(set (match_operand 0 "" "=rf")
                   3304:        (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
                   3305:              (match_operand:SI 2 "general_operand" "g")))
                   3306:    (set (reg:SI 7) (plus:SI (reg:SI 7)
                   3307:                            (match_operand:SI 4 "immediate_operand" "i")))]
                   3308:   ""
                   3309:   "call %P1")
                   3310: 
                   3311: (define_expand "call_value"
                   3312:   [(set (match_operand 0 "" "")
                   3313:        (call (match_operand:QI 1 "indirect_operand" "")
                   3314:              (match_operand:SI 2 "general_operand" "")))]
                   3315:   ;; Operand 2 not used on the i386.
                   3316:   ""
                   3317:   "
                   3318: {
                   3319:   if (flag_pic)
                   3320:     current_function_uses_pic_offset_table = 1;
                   3321: }")
                   3322: 
                   3323: (define_insn ""
                   3324:   [(set (match_operand 0 "" "=rf")
                   3325:        (call (match_operand:QI 1 "indirect_operand" "m")
                   3326:              (match_operand:SI 2 "general_operand" "g")))]
                   3327:   ;; Operand 2 not used on the i386.
                   3328:   ""
                   3329:   "*
                   3330: {
                   3331:   if (GET_CODE (operands[1]) == MEM
                   3332:       && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
                   3333:     {
                   3334:       operands[1] = XEXP (operands[1], 0);
                   3335:       output_asm_insn (AS1 (call,%*%1), operands);
                   3336:     }
                   3337:   else
                   3338:     output_asm_insn (AS1 (call,%P1), operands);
                   3339: 
                   3340:   RET;
                   3341: }")
                   3342: 
                   3343: (define_insn ""
                   3344:   [(set (match_operand 0 "" "=rf")
                   3345:        (call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
                   3346:              (match_operand:SI 2 "general_operand" "g")))]
                   3347:   ;; Operand 2 not used on the i386.
                   3348:   ""
                   3349:   "call %P1")
                   3350: 
                   3351: ;; Insn emitted into the body of a function to return from a function.
                   3352: ;; This is only done if the function's epilogue is known to be simple.
                   3353: ;; See comments for simple_386_epilogue in i386.c.
                   3354: 
                   3355: (define_insn "return"
                   3356:   [(return)]
                   3357:   "simple_386_epilogue ()"
                   3358:   "*
                   3359: {
                   3360:   function_epilogue (asm_out_file, get_frame_size ());
                   3361:   RET;
                   3362: }")
                   3363: 
                   3364: (define_insn "nop"
                   3365:   [(const_int 0)]
                   3366:   ""
                   3367:   "nop")
                   3368: 
                   3369: (define_expand "movstrsi"
                   3370:   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
                   3371:                   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
                   3372:              (use (match_operand:SI 2 "immediate_operand" ""))
                   3373:              (use (match_operand:SI 3 "immediate_operand" ""))
                   3374:              (set (match_operand:SI 4 "register_operand" "")
                   3375:                   (const_int 0))
                   3376:              (set (match_dup 0)
                   3377:                   (plus:SI (match_dup 0)
                   3378:                            (match_dup 2)))
                   3379:              (set (match_dup 1)
                   3380:                   (plus:SI (match_dup 1)
                   3381:                            (match_dup 2)))])]
                   3382:   ""
                   3383:   "
                   3384: {
                   3385:   if (GET_CODE (operands[2]) != CONST_INT)
                   3386:     FAIL;
                   3387:   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
                   3388:   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
                   3389:   operands[4] = gen_reg_rtx (SImode);
                   3390: }")
                   3391: 
                   3392: (define_insn ""
                   3393:   [(set (mem:BLK (match_operand:SI 0 "register_operand" "D"))
                   3394:        (mem:BLK (match_operand:SI 1 "register_operand" "S")))
                   3395:    (use (match_operand:SI 2 "immediate_operand" "n"))
                   3396:    (use (match_operand:SI 3 "immediate_operand" "i"))
                   3397:    (set (match_operand:SI 4 "register_operand" "c")
                   3398:        (const_int 0))
                   3399:    (set (match_operand:SI 5 "register_operand" "=0")
                   3400:        (plus:SI (match_dup 0)
                   3401:                 (match_dup 2)))
                   3402:    (set (match_operand:SI 7 "register_operand" "=1")
                   3403:        (plus:SI (match_dup 1)
                   3404:                 (match_dup 2)))]
                   3405:   ""
                   3406:   "*
                   3407: {
                   3408:   rtx xops[2];
                   3409: 
                   3410:   if (GET_CODE (operands[2]) == CONST_INT)
                   3411:     {
                   3412:       if (INTVAL (operands[2]) & ~0x03)
                   3413:        {
                   3414:          xops[0] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) >> 2);
                   3415:          xops[1] = gen_rtx (REG, SImode, 2);
                   3416: 
                   3417:          output_asm_insn (AS2 (mov%L1,%0,%1), xops);
                   3418: #ifdef INTEL_SYNTAX
                   3419:          output_asm_insn (\"rep movsd\", xops);
                   3420: #else
                   3421:          output_asm_insn (\"rep\;movs%L1\", xops);
                   3422: #endif
                   3423:        }
                   3424:       if (INTVAL (operands[2]) & 0x02)
                   3425:        output_asm_insn (\"movsw\", operands);
                   3426:       if (INTVAL (operands[2]) & 0x01)
                   3427:        output_asm_insn (\"movsb\", operands);
                   3428:     }
                   3429:   else
                   3430:     abort ();
                   3431:   RET;
                   3432: }")
                   3433: 
                   3434: (define_expand "cmpstrsi"
                   3435:   [(parallel [(set (match_operand:QI 0 "general_operand" "")
                   3436:                   (compare
                   3437:                    (mem:BLK (match_operand:BLK 1 "general_operand" ""))
                   3438:                    (mem:BLK (match_operand:BLK 2 "general_operand" ""))))
                   3439:              (use (match_operand:SI 3 "general_operand" ""))
                   3440:              (use (match_operand:SI 4 "immediate_operand" ""))
                   3441:              (clobber (match_dup 1))
                   3442:              (clobber (match_dup 2))
                   3443:              (clobber (match_dup 3))])]
                   3444:   ""
                   3445:   "
                   3446: {
                   3447:   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
                   3448:   operands[2] = copy_to_mode_reg (SImode, XEXP (operands[2], 0));
                   3449:   operands[3] = copy_to_mode_reg (SImode, operands[3]);
                   3450: }")
                   3451: 
                   3452: (define_insn ""
                   3453:   [(set (match_operand:QI 0 "general_operand" "=q")
                   3454:        (compare (mem:BLK (match_operand:SI 1 "general_operand" "D"))
                   3455:                 (mem:BLK (match_operand:SI 2 "general_operand" "S"))))
                   3456:    (use (match_operand:SI 3 "general_operand" "c"))
                   3457:    (use (match_operand:SI 4 "immediate_operand" "i"))
                   3458:    (clobber (match_dup 1))
                   3459:    (clobber (match_dup 2))
                   3460:    (clobber (match_dup 3))]
                   3461:   ""
                   3462:   "*
                   3463: {
                   3464:   rtx xops[3];
                   3465: 
                   3466:   output_asm_insn (\"repz\;cmps%B2\", operands);
                   3467: 
                   3468:   xops[0] = operands[0];
                   3469:   xops[1] = gen_rtx (MEM, QImode,
                   3470:                     gen_rtx (PLUS, SImode, operands[1], constm1_rtx));
                   3471:   xops[2] = gen_rtx (MEM, QImode,
                   3472:                     gen_rtx (PLUS, SImode, operands[2], constm1_rtx));
                   3473: 
                   3474:   output_asm_insn (AS2 (mov%B0,%1,%b0), xops);
                   3475:   output_asm_insn (AS2 (sub%B0,%2,%b0), xops);
                   3476:   RET;
                   3477: }")
                   3478: 
                   3479: (define_insn ""
                   3480:   [(set (cc0)
                   3481:        (compare (mem:BLK (match_operand:SI 0 "general_operand" "D"))
                   3482:                 (mem:BLK (match_operand:SI 1 "general_operand" "S"))))
                   3483:    (use (match_operand:SI 2 "general_operand" "c"))
                   3484:    (use (match_operand:SI 3 "immediate_operand" "i"))
                   3485:    (clobber (match_dup 0))
                   3486:    (clobber (match_dup 1))
                   3487:    (clobber (match_dup 2))]
                   3488:   ""
                   3489:   "repz\;cmps%B2")
                   3490: 
                   3491: (define_expand "ffssi2"
                   3492:   [(set (match_dup 2)
                   3493:        (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
                   3494:                 (const_int -1)))
                   3495:    (set (match_operand:SI 0 "general_operand" "")
                   3496:        (plus:SI (match_dup 2) (const_int 1)))]
                   3497:   ""
                   3498:   "operands[2] = gen_reg_rtx (SImode);")
                   3499: 
                   3500: (define_insn ""
                   3501:   [(set (match_operand:SI 0 "general_operand" "=&r")
                   3502:        (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm"))
                   3503:                 (const_int -1)))]
                   3504:   ""
                   3505:   "*
                   3506: {
                   3507:   rtx xops[2];
                   3508: 
                   3509:   xops[0] = operands[0];
                   3510:   xops[1] = constm1_rtx;
                   3511:   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
                   3512:   return AS2 (bsf%L0,%1,%0);
                   3513: }")
                   3514: 
                   3515: (define_expand "ffshi2"
                   3516:   [(set (match_dup 2)
                   3517:        (plus:HI (ffs:HI (match_operand:HI 1 "general_operand" ""))
                   3518:                 (const_int -1)))
                   3519:    (set (match_operand:HI 0 "general_operand" "")
                   3520:        (plus:HI (match_dup 2) (const_int 1)))]
                   3521:   ""
                   3522:   "operands[2] = gen_reg_rtx (HImode);")
                   3523: 
                   3524: (define_insn ""
                   3525:   [(set (match_operand:HI 0 "general_operand" "=&r")
                   3526:        (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm"))
                   3527:                 (const_int -1)))]
                   3528:   ""
                   3529:   "*
                   3530: {
                   3531:   rtx xops[2];
                   3532: 
                   3533:   xops[0] = operands[0];
                   3534:   xops[1] = constm1_rtx;
                   3535:   output_asm_insn (AS2 (mov%W0,%1,%0), xops);
                   3536:   return AS2 (bsf%W0,%1,%0);
                   3537: }")
                   3538: 
                   3539: ;; These patterns match the binary 387 instructions for addM3, subM3,
                   3540: ;; mulM3 and divM3.  There are three patterns for each of DFmode and
                   3541: ;; SFmode.  The first is the normal insn, the second the same insn but
                   3542: ;; with one operand a conversion, and the third the same insn but with
                   3543: ;; the other operand a conversion.  The conversion may be SFmode or
                   3544: ;; SImode if the target mode DFmode, but only SImode if the target mode
                   3545: ;; is SFmode.
                   3546: 
                   3547: (define_insn ""
                   3548:   [(set (match_operand:DF 0 "register_operand" "=f,f")
                   3549:        (match_operator:DF 3 "binary_387_op"
                   3550:                        [(match_operand:DF 1 "general_operand" "0,fm")
                   3551:                         (match_operand:DF 2 "general_operand" "fm,0")]))]
                   3552:   "TARGET_80387"
                   3553:   "* return (char *) output_387_binary_op (insn, operands);")
                   3554: 
                   3555: (define_insn ""
                   3556:   [(set (match_operand:DF 0 "register_operand" "=f,f")
                   3557:        (match_operator:DF 3 "binary_387_op"
                   3558:           [(float:DF (match_operand:SI 1 "general_operand" "m,!*r"))
                   3559:            (match_operand:DF 2 "general_operand" "0,0")]))]
                   3560:   "TARGET_80387"
                   3561:   "* return (char *) output_387_binary_op (insn, operands);")
                   3562: 
                   3563: (define_insn ""
                   3564:   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
                   3565:        (match_operator:DF 3 "binary_387_op"
                   3566:           [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,!*r,0"))
                   3567:            (match_operand:DF 2 "general_operand" "0,0,f")]))]
                   3568:   "TARGET_80387"
                   3569:   "* return (char *) output_387_binary_op (insn, operands);")
                   3570: 
                   3571: (define_insn ""
                   3572:   [(set (match_operand:DF 0 "register_operand" "=f,f")
                   3573:        (match_operator:DF 3 "binary_387_op"
                   3574:          [(match_operand:DF 1 "general_operand" "0,0")
                   3575:           (float:DF (match_operand:SI 2 "general_operand" "m,!*r"))]))]
                   3576:   "TARGET_80387"
                   3577:   "* return (char *) output_387_binary_op (insn, operands);")
                   3578: 
                   3579: (define_insn ""
                   3580:   [(set (match_operand:DF 0 "register_operand" "=f,f,f")
                   3581:        (match_operator:DF 3 "binary_387_op"
                   3582:          [(match_operand:DF 1 "general_operand" "0,0,f")
                   3583:           (float_extend:DF
                   3584:            (match_operand:SF 2 "general_operand" "fm,!*r,0"))]))]
                   3585:   "TARGET_80387"
                   3586:   "* return (char *) output_387_binary_op (insn, operands);")
                   3587: 
                   3588: (define_insn ""
                   3589:   [(set (match_operand:SF 0 "register_operand" "=f,f")
                   3590:        (match_operator:SF 3 "binary_387_op"
                   3591:                        [(match_operand:SF 1 "general_operand" "0,fm")
                   3592:                         (match_operand:SF 2 "general_operand" "fm,0")]))]
                   3593:   "TARGET_80387"
                   3594:   "* return (char *) output_387_binary_op (insn, operands);")
                   3595: 
                   3596: (define_insn ""
                   3597:   [(set (match_operand:SF 0 "register_operand" "=f,f")
                   3598:        (match_operator:SF 3 "binary_387_op"
                   3599:          [(float:SF (match_operand:SI 1 "general_operand" "m,!*r"))
                   3600:           (match_operand:SF 2 "general_operand" "0,0")]))]
                   3601:   "TARGET_80387"
                   3602:   "* return (char *) output_387_binary_op (insn, operands);")
                   3603: 
                   3604: (define_insn ""
                   3605:   [(set (match_operand:SF 0 "register_operand" "=f,f")
                   3606:        (match_operator:SF 3 "binary_387_op"
                   3607:          [(match_operand:SF 1 "general_operand" "0,0")
                   3608:           (float:SF (match_operand:SI 2 "general_operand" "m,!*r"))]))]
                   3609:   "TARGET_80387"
                   3610:   "* return (char *) output_387_binary_op (insn, operands);")
                   3611: 
                   3612: ;;- Local variables:
                   3613: ;;- mode:emacs-lisp
                   3614: ;;- comment-start: ";;- "
                   3615: ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
                   3616: ;;- eval: (modify-syntax-entry ?[ "(]")
                   3617: ;;- eval: (modify-syntax-entry ?] ")[")
                   3618: ;;- eval: (modify-syntax-entry ?{ "(}")
                   3619: ;;- eval: (modify-syntax-entry ?} "){")
                   3620: ;;- End:

unix.superglobalmegacorp.com

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