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

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

unix.superglobalmegacorp.com

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