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

1.1.1.2   root        1: ;; GCC machine description for Hitachi H8/300
1.1.1.3 ! root        2: ;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
1.1.1.2   root        3: 
                      4: ;;   Contributed by Steve Chamberlain ([email protected]),
                      5: ;;   Jim Wilson ([email protected]), and Doug Evans ([email protected]).
1.1       root        6: 
                      7: ;; This file is part of GNU CC.
                      8: 
                      9: ;; GNU CC is free software; you can redistribute it and/or modify
                     10: ;; it under the terms of the GNU General Public License as published by
                     11: ;; the Free Software Foundation; either version 2, or (at your option)
                     12: ;; any later version.
                     13: 
                     14: ;; GNU CC is distributed in the hope that it will be useful,
                     15: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17: ;; GNU General Public License for more details.
                     18: 
                     19: ;; You should have received a copy of the GNU General Public License
                     20: ;; along with GNU CC; see the file COPYING.  If not, write to
1.1.1.3 ! root       21: ;; the Free Software Foundation, 59 Temple Place - Suite 330,
        !            22: ;; Boston, MA 02111-1307, USA.
1.1       root       23: 
                     24: 
                     25: ;; The original PO technology requires these to be ordered by speed,
                     26: ;; so that assigner will pick the fastest.
                     27: 
                     28: ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
                     29: 
1.1.1.2   root       30: (define_attr "cpu" "h8300,h8300h"
                     31:   (const (symbol_ref "cpu_type")))
                     32: 
                     33: ;; ??? If we can remove the operand type on all the insns, do it.
                     34: ;; ??? Otherwise, try to have the operand type on all the insns.
                     35: 
1.1       root       36: (define_attr "type" "branch,return,call,arith,move,float,multi"
                     37:   (const_string "arith"))
                     38: 
                     39: ;; The size of instructions in bytes.
                     40: 
                     41: (define_attr "length" "" 
                     42:   (cond [(eq_attr "type" "branch")
                     43:         (if_then_else (and (ge (minus (pc) (match_dup 0))
1.1.1.2   root       44:                                (const_int -120))
1.1       root       45:                            (le (minus (pc) (match_dup 0))
1.1.1.2   root       46:                                (const_int 120)))
1.1       root       47:                       (const_int 2)
1.1.1.2   root       48:                       (if_then_else (and (eq_attr "cpu" "h8300h")
                     49:                                          (and (ge (minus (pc) (match_dup 0))
                     50:                                                   (const_int -32000))
                     51:                                               (le (minus (pc) (match_dup 0))
                     52:                                                   (const_int 32000))))
                     53:                                     (const_int 4)
                     54:                                     (const_int 6)))
1.1       root       55:         (eq_attr "type" "move")        (const_int 4)
                     56:         (eq_attr "type" "return")      (const_int 2)
                     57:         (eq_attr "type" "float")       (const_int 12)
                     58:         (eq_attr "type" "call")        (const_int 4)]
                     59:        (const_int 200)))
                     60: 
1.1.1.2   root       61: (define_attr "cc" "none,clobber,none_0hit,set,compare,whoops,cbit" 
1.1       root       62:   (const_string "whoops"))
1.1.1.2   root       63: 
1.1       root       64: ;; ----------------------------------------------------------------------
1.1.1.2   root       65: ;; MOVE INSTRUCTIONS
1.1       root       66: ;; ----------------------------------------------------------------------
                     67: 
1.1.1.2   root       68: ;; movqi
1.1       root       69: 
1.1.1.2   root       70: (define_insn "movqi_push"
                     71:   [(set (match_operand:QI 0 "push_operand" "=<")
                     72:        (match_operand:QI 1 "register_operand" "r"))]
1.1       root       73:   ""
1.1.1.2   root       74:   "*
                     75: {
                     76:   if (TARGET_H8300)
                     77:     return \"push.w    %T1\";
                     78:   else
                     79:     return \"push.l    %S1\";
                     80: }"
1.1       root       81:   [(set_attr "type" "move")
1.1.1.2   root       82:    (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
1.1       root       83:    (set_attr "cc" "set")])
                     84: 
1.1.1.2   root       85: (define_insn "movqi_internal"
                     86:   [(set (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<,r")
                     87:        (match_operand:QI 1 "general_operand_src" "I,r>,io,r,r,c"))]
                     88:   "register_operand (operands[0],QImode) || register_operand (operands[1], QImode)"
                     89:   "@
                     90:    sub.b       %X0,%X0
                     91:    mov.b       %X1,%X0
                     92:    mov.b       %X1,%X0
                     93:    mov.b       %X1,%X0
                     94:    mov.b       %X1,%X0
                     95:    xor         %X0,%X0\;bst    #0,%X0"
                     96:   [(set_attr "type" "move")
                     97:    (set_attr_alternative "length"
                     98:      [(const_int 2) (const_int 2)
                     99:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    100:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    101:       (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))
                    102:       (const_int 4)])
                    103:    (set_attr "cc" "set,set,set,set,set,none")])
                    104: 
                    105: (define_expand "movqi"
                    106:   [(set (match_operand:QI 0 "general_operand_dst" "")
                    107:        (match_operand:QI 1 "general_operand_src" ""))]
                    108:   ""
                    109:   "
                    110: {
                    111:   /* One of the ops has to be in a register */
                    112:   if (!register_operand(operand0, QImode)
                    113:       && !register_operand(operand1, QImode))
                    114:     {
                    115:       operands[1] = copy_to_mode_reg(QImode, operand1);
                    116:     }
                    117: }")
                    118: 
                    119: (define_insn "movstrictqi"
                    120:   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<"))
                    121:                         (match_operand:QI 1 "general_operand_src" "I,r,io,r,r"))]
1.1       root      122:   ""
                    123:   "@
1.1.1.2   root      124:    sub.b       %X0,%X0
                    125:    mov.b       %X1,%X0
                    126:    mov.b       %X1,%X0
                    127:    mov.b       %X1,%X0
                    128:    mov.b       %X1,%X0"
1.1       root      129:   [(set_attr "type" "move")
1.1.1.2   root      130:    (set_attr_alternative "length"
                    131:      [(const_int 2) (const_int 2)
                    132:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    133:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    134:       (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
                    135:    (set_attr "cc" "set")])
                    136:    
                    137: ;; movhi
                    138: 
                    139: (define_insn "movhi_push"
                    140:   [(set (match_operand:HI 0 "push_operand" "=<")
                    141:        (match_operand:HI 1 "register_operand" "ra"))]
                    142:   ""
                    143:   "*
                    144: {
                    145:   if (TARGET_H8300)
                    146:     return \"push.w    %T1\";
                    147:   else
                    148:     return \"push.l    %S1\";
                    149: }"
                    150:   [(set_attr "type" "move")
                    151:    (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
1.1       root      152:    (set_attr "cc" "set")])
                    153: 
1.1.1.2   root      154: (define_insn "movhi_internal"
1.1       root      155:   [(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,ra,o,<")
1.1.1.2   root      156:        (match_operand:HI 1 "general_operand_src" "I,ra>,ion,ra,ra"))]
1.1       root      157:   ""
                    158:   "@
                    159:    sub.w       %T0,%T0
                    160:    mov.w       %T1,%T0
                    161:    mov.w       %T1,%T0
                    162:    mov.w       %T1,%T0
                    163:    mov.w       %T1,%T0"
                    164:   [(set_attr "type" "move")
1.1.1.2   root      165:    (set_attr_alternative "length"
                    166:      [(const_int 2) (const_int 2)
                    167:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    168:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    169:       (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
1.1       root      170:    (set_attr "cc" "set")])
                    171: 
                    172: (define_expand "movhi"
                    173:   [(set (match_operand:HI 0 "general_operand_dst" "")
                    174:        (match_operand:HI 1 "general_operand_src" ""))]
                    175:   ""
                    176:   "
                    177: {
1.1.1.2   root      178:   /* One of the ops has to be in a register */
                    179:   if (!register_operand(operand1, HImode)
                    180:       && !register_operand(operand0, HImode))
                    181:     {
                    182:       operands[1] = copy_to_mode_reg(HImode, operand1);
                    183:     }
1.1       root      184: }")
                    185: 
1.1.1.2   root      186: (define_insn "movstricthi"
                    187:   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r,o,<"))
                    188:                         (match_operand:HI 1 "general_operand_src" "I,r,io,r,r"))]
1.1       root      189:   ""
                    190:   "@
1.1.1.2   root      191:    sub.w       %T0,%T0
                    192:    mov.w       %T1,%T0
                    193:    mov.w       %T1,%T0
                    194:    mov.w       %T1,%T0
                    195:    mov.w       %T1,%T0"
1.1       root      196:   [(set_attr "type" "move")
1.1.1.2   root      197:    (set_attr_alternative "length"
                    198:      [(const_int 2) (const_int 2)
                    199:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    200:       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
                    201:       (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))])
1.1       root      202:    (set_attr "cc" "set")])
                    203: 
1.1.1.2   root      204: ;; movsi
1.1       root      205: 
1.1.1.2   root      206: (define_expand "movsi"
                    207:   [(set (match_operand:SI 0 "general_operand_dst" "")
                    208:        (match_operand:SI 1 "general_operand_src" ""))]
1.1       root      209:   ""
                    210:   "
                    211: {
1.1.1.2   root      212:   if (TARGET_H8300)
                    213:     {
                    214:       if (do_movsi (operands))
                    215:        DONE;
                    216:     }
                    217:   else /* TARGET_H8300H */
                    218:     {
                    219:       /* One of the ops has to be in a register.  */
                    220:       if (!register_operand (operand1, SImode)
                    221:          && !register_operand (operand0, SImode))
                    222:        {
                    223:          operands[1] = copy_to_mode_reg (SImode, operand1);
                    224:        }
                    225:     }
1.1       root      226: }")
                    227: 
1.1.1.2   root      228: (define_expand "movsf"
                    229:   [(set (match_operand:SF 0 "general_operand_dst" "")
                    230:        (match_operand:SF 1 "general_operand_src" ""))]
1.1       root      231:   ""
1.1.1.2   root      232:   "
                    233: {
                    234:   if (TARGET_H8300)
                    235:     {
                    236:       if (do_movsi (operands))
                    237:        DONE;
                    238:     }
                    239:   else /* TARGET_H8300H */
                    240:     {
                    241:       /* One of the ops has to be in a register.  */
                    242:       if (!register_operand (operand1, SFmode)
                    243:          && !register_operand (operand0, SFmode))
                    244:        {
                    245:          operands[1] = copy_to_mode_reg (SFmode, operand1);
                    246:        }
                    247:     }
                    248: }")
                    249: 
                    250: (define_insn "movsi_h8300"
                    251:   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
                    252:        (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))]
                    253:   "TARGET_H8300
                    254:    && (register_operand (operands[0], SImode)
                    255:        || register_operand (operands[1], SImode))"
1.1       root      256:   "*
                    257: {
                    258:   int rn = -1;
                    259:   switch (which_alternative)
                    260:     {
                    261:     case 0:
                    262:       return \"sub.w   %e0,%e0\;sub.w  %f0,%f0\";
                    263:     case 1:
1.1.1.2   root      264:       if (REGNO(operands[0]) < REGNO(operands[1]))
                    265:        return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
                    266:       else 
                    267:        return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
1.1       root      268:     case 2:
                    269:       /* Make sure we don't trample the register we index with.  */
                    270:     
1.1.1.2   root      271:       if (GET_CODE(operands[1]) == MEM) 
1.1       root      272:        {
1.1.1.2   root      273:          rtx inside = XEXP (operands[1],0);
                    274:          if  (REG_P (inside)) 
                    275:            {
                    276:              rn = REGNO(inside);
                    277:            }
1.1       root      278:          else if (GET_CODE (inside) == PLUS) 
                    279:            {
1.1.1.2   root      280:              rtx lhs = XEXP (inside,0);
                    281:              rtx rhs = XEXP (inside,1);
                    282:              if (REG_P (lhs)) rn = REGNO (lhs);
                    283:              if (REG_P (rhs)) rn = REGNO (rhs);
1.1       root      284:            }
                    285:        }
1.1.1.2   root      286:       if (rn == REGNO (operands[0]))   
                    287:        {
                    288:          /* Move the second word first.  */
                    289:          return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
                    290:        }
1.1       root      291:       else 
1.1.1.2   root      292:        {
                    293:          return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
                    294:        }
1.1       root      295:     
                    296:     case 3:
                    297:       return \"mov.w   %e1,%e0\;mov.w  %f1,%f0\";
                    298:     case 4:
                    299:       return \"mov.w   %f1,%T0\;mov.w  %e1,%T0\";
1.1.1.2   root      300:     case 5:
                    301:       return \"mov.w   %T1,%e0\;mov.w  %T1,%f0\";
1.1       root      302:     }
                    303: }"
                    304:   [(set_attr "type" "move")
1.1.1.2   root      305:    (set_attr "length" "4,4,8,8,4,4")
1.1       root      306:    (set_attr "cc" "clobber")])
                    307: 
1.1.1.2   root      308: (define_insn "movsf_h8300"
                    309:   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
                    310:        (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))]
                    311:   "TARGET_H8300
                    312:    && (register_operand (operands[0], SFmode)
                    313:        || register_operand (operands[1], SFmode))"
1.1       root      314:   "*
                    315: {
1.1.1.2   root      316:   /* Copy of the movsi stuff */
1.1       root      317:   int rn = -1;
                    318:   switch (which_alternative)
                    319:     {
                    320:     case 0:
                    321:       return \"sub.w   %e0,%e0\;sub.w  %f0,%f0\";
                    322:     case 1:
1.1.1.2   root      323:       if (REGNO(operands[0]) < REGNO(operands[1]))
                    324:        return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
                    325:       else 
                    326:        return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
1.1       root      327:     case 2:
                    328:       /* Make sure we don't trample the register we index with.  */
                    329:     
                    330:       if (GET_CODE (operands[1]) == MEM) 
                    331:        {
1.1.1.2   root      332:          rtx inside = XEXP (operands[1],0);
1.1       root      333:          if (REG_P (inside))
1.1.1.2   root      334:            {
                    335:              rn = REGNO (inside);
                    336:            }
1.1       root      337:          else if (GET_CODE (inside) == PLUS) 
                    338:            {
1.1.1.2   root      339:              rtx lhs = XEXP (inside,0);
                    340:              rtx rhs = XEXP (inside,1);
                    341:              if (REG_P (lhs)) rn = REGNO (lhs);
                    342:              if (REG_P (rhs)) rn = REGNO (rhs);
1.1       root      343:            }
                    344:        }
                    345:       if (rn == REGNO (operands[0]))
1.1.1.2   root      346:        {
                    347:          /* move the second word first */
                    348:          return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
                    349:        }
1.1       root      350:       else 
1.1.1.2   root      351:        {
                    352:          return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
                    353:        }
1.1       root      354:     
                    355:     case 3:
                    356:       return \"mov.w   %e1,%e0\;mov.w  %f1,%f0\";
                    357:     case 4:
                    358:       return \"mov.w   %f1,%T0\;mov.w  %e1,%T0\";
1.1.1.2   root      359:     case 5:
                    360:       return \"mov.w   %T1,%e0\;mov.w  %T1,%f0\";
                    361: 
                    362:     }
1.1       root      363: }"
                    364:   [(set_attr "type" "move")
1.1.1.2   root      365:    (set_attr "length" "4,4,8,8,4,4")
1.1       root      366:    (set_attr "cc" "clobber")])
                    367: 
1.1.1.2   root      368: (define_insn "movsi_h8300h"
                    369:   [(set (match_operand:SI 0 "general_operand_dst" "=ra,ra,ra,o,<,ra")
                    370:        (match_operand:SI 1 "general_operand_src" "I,ra,ion,ra,ra,>"))]
                    371:   "TARGET_H8300H
                    372:    && (register_operand (operands[0], SImode)
                    373:        || register_operand (operands[1], SImode))"
                    374:   "@
                    375:    sub.l       %S0,%S0
                    376:    mov.l       %S1,%S0
                    377:    mov.l       %S1,%S0
                    378:    mov.l       %S1,%S0
                    379:    mov.l       %S1,%S0
                    380:    mov.l       %S1,%S0"
1.1       root      381:   [(set_attr "type" "move")
1.1.1.2   root      382:    (set_attr "length" "2,2,8,8,4,4")
                    383:    (set_attr "cc" "set")])
1.1       root      384: 
1.1.1.2   root      385: (define_insn "movsf_h8300h"
1.1.1.3 ! root      386:   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
        !           387:        (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))]
1.1.1.2   root      388:   "TARGET_H8300H
                    389:    && (register_operand (operands[0], SFmode)
                    390:        || register_operand (operands[1], SFmode))"
                    391:   "@
                    392:    sub.l       %S0,%S0
                    393:    mov.l       %S1,%S0
                    394:    mov.l       %S1,%S0
                    395:    mov.l       %S1,%S0
1.1.1.3 ! root      396:    mov.l       %S1,%S0
1.1.1.2   root      397:    mov.l       %S1,%S0"
                    398:   [(set_attr "type" "move")
1.1.1.3 ! root      399:    (set_attr "length" "2,2,8,8,4,4")
1.1.1.2   root      400:    (set_attr "cc" "set")])
1.1       root      401: 
                    402: ;; ----------------------------------------------------------------------
1.1.1.2   root      403: ;; TEST INSTRUCTIONS
1.1       root      404: ;; ----------------------------------------------------------------------
                    405: 
                    406: (define_insn "tstqi"
1.1.1.2   root      407:   [(set (cc0) (match_operand:QI 0 "register_operand" "ra"))]
1.1       root      408:   ""
1.1.1.2   root      409:   "*
                    410: {
                    411:   /* ??? I don't think this is right.  --Jim */
                    412:   if (cc_prev_status.flags & CC_DONE_CBIT)
                    413:     return \"btst      #0,%X0\";
                    414:   else
                    415:     return \"cmp.b     #0,%X0\";
                    416: }"
1.1       root      417:   [(set_attr "type" "arith")
1.1.1.2   root      418:    (set_attr "length" "4")
1.1       root      419:    (set_attr "cc" "set")])
                    420: 
                    421: (define_insn "tsthi"
1.1.1.2   root      422:   [(set (cc0) (match_operand:HI 0 "general_operand" "ra"))]
                    423:   ""
                    424:   "*
                    425: {
                    426:   /* ??? I don't think this is right.  --Jim */
                    427:   if (cc_prev_status.flags & CC_DONE_CBIT)
                    428:     return \"btst      #0,%0l\";
                    429:   else
                    430:     return \"mov.w     %T0,%T0\";
                    431: }"
                    432:   [(set_attr "type" "arith")
                    433:    (set_attr "length" "4")
                    434:    (set_attr "cc" "set")])
                    435: 
                    436: (define_insn "tstsi"
                    437:   [(set (cc0) (match_operand:SI 0 "general_operand" "ra"))]
                    438:   "TARGET_H8300H"
                    439:   "*
                    440: {
                    441:   /* ??? I don't think this is right.  --Jim */
                    442:   if (cc_prev_status.flags & CC_DONE_CBIT)
                    443:     return \"btst      #0,%0l\";
                    444:   else
                    445:     return \"mov.l     %S0,%S0\";
                    446: }"
                    447:   [(set_attr "type" "arith")
                    448:    (set_attr "length" "4")
                    449:    (set_attr "cc" "set")])
                    450: 
                    451: (define_insn "cmpqi"
1.1       root      452:   [(set (cc0)
1.1.1.2   root      453:        (compare:QI (match_operand:QI 0 "register_operand" "ra")
                    454:                    (match_operand:QI 1 "nonmemory_operand" "rai")))]
1.1       root      455:   ""
1.1.1.2   root      456:   "cmp.b       %X1,%X0"
1.1       root      457:   [(set_attr "type" "arith")
                    458:    (set_attr "length" "2")
1.1.1.2   root      459:    (set_attr "cc" "compare")])
                    460: 
                    461: ;; ??? 300h can have an immediate operand here.
1.1       root      462: 
                    463: (define_insn "cmphi"
                    464:   [(set (cc0)
                    465:        (compare:HI (match_operand:HI 0 "register_operand" "ra")
                    466:                    (match_operand:HI 1 "register_operand" "ra")))]
                    467:   ""
                    468:   "cmp.w       %T1,%T0"
                    469:   [(set_attr "type" "arith")
                    470:    (set_attr "length" "2")
                    471:    (set_attr "cc" "compare")])
                    472: 
1.1.1.2   root      473: ;; ??? 300h can have an immediate operand here.
                    474: 
                    475: (define_insn "cmpsi"
1.1       root      476:   [(set (cc0)
1.1.1.2   root      477:        (compare:SI (match_operand:SI 0 "register_operand" "ra")
                    478:                    (match_operand:SI 1 "register_operand" "ra")))]
                    479:   "TARGET_H8300H"
                    480:   "cmp.l       %S1,%S0"
1.1       root      481:   [(set_attr "type" "arith")
                    482:    (set_attr "length" "2")
                    483:    (set_attr "cc" "compare")])
1.1.1.2   root      484: 
1.1       root      485: ;; ----------------------------------------------------------------------
1.1.1.2   root      486: ;; ADD INSTRUCTIONS
1.1       root      487: ;; ----------------------------------------------------------------------
                    488: 
1.1.1.2   root      489: (define_insn "addqi3"
                    490:   [(set (match_operand:QI 0 "register_operand" "=r")
                    491:        (plus:QI (match_operand:QI 1 "register_operand" "%0")
                    492:                 (match_operand:QI 2 "nonmemory_operand" "ri")))]
                    493:   ""
                    494:   "add.b       %X2,%X0"
                    495:   [(set_attr "type" "arith")
                    496:    (set_attr "length" "2")
                    497:    (set_attr "cc" "set")])
                    498: 
                    499: ;; ??? adds operates on the 32bit register.  We can use it because we don't
                    500: ;; use the e0-7 registers.
                    501: ;; ??? 4 can be handled in one insn on the 300h.
                    502: 
                    503: (define_insn "addhi3_internal"
1.1       root      504:   [(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,ra,r,ra")
                    505:        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
                    506:                 (match_operand:HI 2 "nonmemory_operand" "K,M,L,N,n,ra")))]
                    507:   ""
                    508:   "@
1.1.1.2   root      509:    adds        %T2,%A0
                    510:    adds        #2,%A0\;adds    %C2,%A0
                    511:    subs        %M2,%A0
                    512:    subs        #2,%A0\;subs    %M2,%A0
1.1       root      513:    add.b       %s2,%s0\;addx   %t2,%t0 
                    514:    add.w       %T2,%T0"
1.1.1.2   root      515:   [(set_attr "type" "arith,multi,arith,multi,multi,arith")
1.1       root      516:    (set_attr "length" "2,4,2,4,4,2")
                    517:    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set")])
                    518: 
1.1.1.2   root      519: ;; ??? Why is this here?
1.1       root      520: (define_expand "addhi3"
                    521:   [(set (match_operand:HI 0 "register_operand" "")
                    522:        (plus:HI (match_operand:HI 1 "register_operand" "")
                    523:                 (match_operand:HI 2 "nonmemory_operand" "")))]
                    524:   ""
1.1.1.2   root      525:   "")
1.1       root      526: 
1.1.1.2   root      527: (define_expand "addsi3"
                    528:   [(set (match_operand:SI 0 "register_operand" "")
                    529:        (plus:SI (match_operand:SI 1 "register_operand" "")
                    530:                 (match_operand:SI 2 "nonmemory_operand" "")))]
1.1       root      531:   ""
1.1.1.2   root      532:   "")
1.1       root      533: 
1.1.1.2   root      534: (define_insn "addsi_h8300"
                    535:   [(set (match_operand:SI 0 "register_operand" "=r,r,&r")
                    536:        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
                    537:                 (match_operand:SI 2 "nonmemory_operand" "n,r,r")))]
                    538:   "TARGET_H8300"
1.1       root      539:   "@
1.1.1.2   root      540:    add %w2,%w0\;addx   %x2,%x0\;addx   %y2,%y0\;addx   %z2,%z0
                    541:    add.w       %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0
                    542:    mov %f1,%f0\;mov    %e1,%e0\;add.w  %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0"
                    543:   [(set_attr "type" "arith")
                    544:    (set_attr "length" "8,6,20")
1.1       root      545:    (set_attr "cc" "clobber")])
                    546: 
1.1.1.2   root      547: ;; ??? 4 can be handled in one insn on the 300h.
                    548: ;; ??? Should the 'n' constraint be 'i' here?
                    549: ;; ??? We don't handle (reg + symbol_ref) which the 300h can handle.
                    550: 
                    551: (define_insn "addsi_h8300h"
                    552:   [(set (match_operand:SI 0 "register_operand" "=ra,ra,ra,ra,r,ra")
                    553:        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
                    554:                 (match_operand:SI 2 "nonmemory_operand" "K,M,L,N,n,ra")))]
                    555:   "TARGET_H8300H"
                    556:   "@
                    557:    adds        %S2,%S0
                    558:    adds        #2,%S0\;adds    %C2,%S0
                    559:    subs        %M2,%S0
                    560:    subs        #2,%S0\;subs    %M2,%S0
                    561:    add.l       %S2,%S0
                    562:    add.l       %S2,%S0"
                    563:   [(set_attr "type" "multi,multi,multi,multi,arith,arith")
                    564:    (set_attr "length" "2,4,2,4,6,2")
                    565:    (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,clobber")])
                    566: 
                    567: ;; ----------------------------------------------------------------------
                    568: ;; SUBTRACT INSTRUCTIONS
                    569: ;; ----------------------------------------------------------------------
                    570: 
                    571: (define_insn "subqi3"
                    572:   [(set (match_operand:QI 0 "register_operand" "=r,r")
                    573:        (minus:QI (match_operand:QI 1 "register_operand" "0,0")
                    574:                  (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1.1       root      575:   ""
                    576:   "@
1.1.1.2   root      577:    sub.b       %X2,%X0
                    578:    add.b       %G2,%X0"
1.1       root      579:   [(set_attr "type" "arith")
1.1.1.2   root      580:    (set_attr "length" "2")
                    581:    (set_attr "cc" "set")])
1.1       root      582: 
1.1.1.2   root      583: ;; ??? subs operates on the 32bit register.  We can use it because we don't
                    584: ;; use the e0-7 registers.
                    585: ;; ??? 4 can be handled in one insn on the 300h.
                    586: ;; ??? The fourth alternative can use sub.w on the 300h.
                    587: ;; ??? Should the 'n' constraint be an 'i' here?
1.1       root      588: 
1.1.1.2   root      589: (define_insn "subhi3_internal"
1.1       root      590:   [(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,r")
                    591:        (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
                    592:                  (match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))]
                    593:   ""
                    594:   "@
                    595:    subs        %T2,%T0
1.1.1.2   root      596:    subs        #2,%T0\;subs    %M2,%T0
1.1       root      597:    sub.w       %T2,%T0
                    598:    add.b       %E2,%s0\;addx   %F2,%t0 ; -%0"
                    599:   [(set_attr "type" "multi")
                    600:    (set_attr "length" "2,4,2,4")
                    601:    (set_attr "cc" "none_0hit,none_0hit,set,clobber")])
                    602: 
1.1.1.2   root      603: ;; ??? Why is this here?
1.1       root      604: (define_expand "subhi3"
                    605:   [(set (match_operand:HI 0 "register_operand" "")
                    606:        (minus:HI (match_operand:HI 1 "register_operand" "")
                    607:                  (match_operand:HI 2 "nonmemory_operand" "")))]
                    608:   ""
1.1.1.2   root      609:   "")
1.1       root      610: 
1.1.1.2   root      611: (define_expand "subsi3"
                    612:   [(set (match_operand:SI 0 "register_operand" "")
                    613:        (minus:SI (match_operand:SI 1 "register_operand" "")
                    614:                  (match_operand:SI 2 "nonmemory_operand" "")))]
1.1       root      615:   ""
1.1.1.2   root      616:   "")
                    617: 
                    618: (define_insn "subsi3_h8300"
                    619:   [(set (match_operand:SI 0 "register_operand" "=r")
                    620:        (minus:SI (match_operand:SI 1 "register_operand" "0")
                    621:                  (match_operand:SI 2 "register_operand" "r")))]
                    622:   "TARGET_H8300"
1.1       root      623:   "sub.w       %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
                    624:   [(set_attr "type" "arith")
                    625:    (set_attr "length" "6")
                    626:    (set_attr "cc" "clobber")])
                    627: 
1.1.1.2   root      628: ;; ??? 4 can be handled in one insn on the 300h.
                    629: 
                    630: (define_insn "subsi3_h8300h"
                    631:   [(set (match_operand:SI 0 "register_operand" "=ra,ra,ra,r")
                    632:        (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
                    633:                  (match_operand:SI 2 "nonmemory_operand" "K,M,ra,n")))]
                    634:   "TARGET_H8300H"
                    635:   "@
                    636:    subs        %T2,%T0
                    637:    subs        #2,%T0\;subs    %E2,%T0
                    638:    sub.l       %S2,%S0
                    639:    sub.l       %S2,%S0"
                    640:   [(set_attr "type" "multi")
                    641:    (set_attr "length" "2,4,2,6")
                    642:    (set_attr "cc" "none_0hit,none_0hit,set,set")])
1.1       root      643: 
                    644: ;; ----------------------------------------------------------------------
1.1.1.2   root      645: ;; MULTIPLY INSTRUCTIONS
1.1       root      646: ;; ----------------------------------------------------------------------
                    647: 
1.1.1.2   root      648: ;; Note that the h8/300 can only handle umulqihi3.
                    649: 
                    650: (define_insn "mulqihi3"
                    651:   [(set (match_operand:HI 0 "register_operand" "=r")
                    652:        (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%0"))
                    653:                 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
                    654:   "TARGET_H8300H"
                    655:   "mulxs.b     %X2,%T0"
                    656:   [(set_attr "type" "multi")
                    657:    (set_attr "length" "4")
                    658:    (set_attr "cc" "set")])
                    659: 
                    660: (define_insn "mulhisi3"
                    661:   [(set (match_operand:SI 0 "register_operand" "=r")
                    662:        (mult:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "%0"))
                    663:                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
                    664:   "TARGET_H8300H"
                    665:   "mulxs.w     %T2,%S0"
                    666:   [(set_attr "type" "multi")
                    667:    (set_attr "length" "4")
                    668:    (set_attr "cc" "set")])
                    669: 
1.1       root      670: (define_insn "umulqihi3"
                    671:   [(set (match_operand:HI 0 "register_operand" "=r")
1.1.1.2   root      672:        (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%0"))
                    673:                 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1.1       root      674:   ""
                    675:   "mulxu       %X2,%T0"
                    676:   [(set_attr "type" "multi")
                    677:    (set_attr "length" "2")
                    678:    (set_attr "cc" "none_0hit")])
                    679: 
1.1.1.2   root      680: (define_insn "umulhisi3"
                    681:   [(set (match_operand:SI 0 "register_operand" "=r")
                    682:        (mult:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "%0"))
                    683:                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
                    684:   "TARGET_H8300H"
                    685:   "mulxu.w     %T2,%S0"
                    686:   [(set_attr "type" "multi")
                    687:    (set_attr "length" "2")
                    688:    (set_attr "cc" "none_0hit")])
                    689: 
1.1       root      690: ;; ----------------------------------------------------------------------
1.1.1.2   root      691: ;; DIVIDE INSTRUCTIONS
1.1       root      692: ;; ----------------------------------------------------------------------
                    693: 
                    694: (define_insn "udivqi3"
                    695:   [(set (match_operand:QI 0 "register_operand" "=r")
                    696:        (udiv:QI (match_operand:HI 1 "general_operand" "0")
                    697:                 (match_operand:QI 2 "register_operand" "r")))]
                    698:   ""
                    699:   "divxu       %X2,%T0"
                    700:   [(set_attr "type" "multi")
                    701:    (set_attr "length" "2")
                    702:    (set_attr "cc" "clobber")])
                    703: 
1.1.1.2   root      704: ;; ??? Will divxu always work here?
                    705: 
1.1       root      706: (define_insn "divqi3"
                    707:   [(set (match_operand:QI 0 "register_operand" "=r")
                    708:        (div:QI (match_operand:HI 1 "general_operand" "0")
                    709:                (match_operand:QI 2 "register_operand" "r")))]
                    710:   ""
                    711:   "divxu       %X2,%T0"
                    712:   [(set_attr "type" "multi")
                    713:    (set_attr "length" "2")
                    714:    (set_attr "cc" "clobber")])
1.1.1.2   root      715: 
                    716: (define_insn "udivhi3"
                    717:   [(set (match_operand:HI 0 "register_operand" "=r")
                    718:        (udiv:HI (match_operand:SI 1 "general_operand" "0")
                    719:                 (match_operand:HI 2 "register_operand" "r")))]
                    720:   "TARGET_H8300H"
                    721:   "divxu.w     %T2,%S0"
                    722:   [(set_attr "type" "multi")
                    723:    (set_attr "length" "2")
                    724:    (set_attr "cc" "clobber")])
                    725: 
                    726: (define_insn "divhi3"
                    727:   [(set (match_operand:HI 0 "register_operand" "=r")
                    728:        (div:HI (match_operand:SI 1 "general_operand" "0")
                    729:                (match_operand:HI 2 "register_operand" "r")))]
                    730:   "TARGET_H8300H"
                    731:   "divxs.w     %T2,%S0"
                    732:   [(set_attr "type" "multi")
                    733:    (set_attr "length" "4")
                    734:    (set_attr "cc" "clobber")])
                    735: 
1.1       root      736: ;; ----------------------------------------------------------------------
1.1.1.2   root      737: ;; MOD INSTRUCTIONS
1.1       root      738: ;; ----------------------------------------------------------------------
                    739: 
1.1.1.2   root      740: (define_insn "umodqi3"
                    741:   [(set (match_operand:QI 0 "register_operand" "=r")
                    742:        (umod:QI (match_operand:HI 1 "general_operand" "0")
                    743:                 (match_operand:QI 2 "register_operand" "r")))]
1.1       root      744:   ""
1.1.1.2   root      745:   "divxu       %X2,%T0\;mov %t0,%s0"
                    746:   [(set_attr "type" "multi")
                    747:    (set_attr "length" "4")
                    748:    (set_attr "cc" "clobber")])
                    749: 
                    750: (define_insn "modqi3"
                    751:   [(set (match_operand:QI 0 "register_operand" "=r")
                    752:        (mod:QI (match_operand:HI 1 "general_operand" "0")
                    753:                (match_operand:QI 2 "register_operand" "r")))]
                    754:   "TARGET_H8300H"
                    755:   "divxs.b     %X2,%T0\;mov %t0,%s0"
                    756:   [(set_attr "type" "multi")
                    757:    (set_attr "length" "6")
                    758:    (set_attr "cc" "clobber")])
                    759: 
                    760: (define_insn "umodhi3"
                    761:   [(set (match_operand:HI 0 "register_operand" "=r")
                    762:        (umod:HI (match_operand:SI 1 "general_operand" "0")
                    763:                 (match_operand:HI 2 "register_operand" "r")))]
                    764:   "TARGET_H8300H"
                    765:   "divxu.w     %T2,%S0\;mov %e0,%f0"
                    766:   [(set_attr "type" "multi")
                    767:    (set_attr "length" "4")
                    768:    (set_attr "cc" "clobber")])
                    769: 
                    770: (define_insn "modhi3"
                    771:   [(set (match_operand:HI 0 "register_operand" "=r")
                    772:        (mod:HI (match_operand:SI 1 "general_operand" "0")
                    773:                (match_operand:HI 2 "register_operand" "r")))]
                    774:   "TARGET_H8300H"
                    775:   "divxs.w     %T2,%S0\;mov %e0,%f0"
                    776:   [(set_attr "type" "multi")
                    777:    (set_attr "length" "6")
                    778:    (set_attr "cc" "clobber")])
                    779: 
                    780: ;; ----------------------------------------------------------------------
                    781: ;; AND INSTRUCTIONS
                    782: ;; ----------------------------------------------------------------------
                    783: 
                    784: (define_insn "andqi3_internal"
                    785:   [(set (match_operand:QI 0 "bit_operand" "=r,U")
                    786:        (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    787:                (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
                    788:   "register_operand (operands[0], QImode) || o_operand (operands[2], QImode)"
                    789:   "@
                    790:    and %X2,%X0
                    791:    bclr        %W2,%X0"
1.1       root      792:   [(set_attr "type" "arith")
1.1.1.2   root      793:    (set_attr "length" "2,4")
                    794:    (set_attr "cc" "set,none_0hit")])
                    795: 
                    796: (define_expand "andqi3"
                    797:   [(set (match_operand:QI 0 "bit_operand" "=r,U")
                    798:        (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    799:                (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
                    800:   ""
                    801:   "
                    802: {
                    803:   if (fix_bit_operand (operands, 'O', AND))
                    804:     DONE;
                    805: }")
                    806: 
                    807: ;; ??? Should have a bclr case here also.
1.1       root      808: 
                    809: (define_insn "andhi3"
                    810:   [(set (match_operand:HI 0 "register_operand" "=r")
                    811:        (and:HI (match_operand:HI 1 "register_operand" "%0")
1.1.1.2   root      812:                (match_operand:HI 2 "nonmemory_operand" "rn")))]
1.1       root      813:   ""
1.1.1.2   root      814:   "*
                    815: {
                    816:   if (GET_CODE (operands[2]) == CONST_INT)
                    817:     {
                    818:       int i = INTVAL (operands[2]);
                    819:       if ((i & 0x00ff) != 0x00ff) 
                    820:        output_asm_insn (\"and  %s2,%s0\", operands);
                    821:       if ((i & 0xff00) != 0xff00) 
                    822:        output_asm_insn (\"and  %t2,%t0\", operands);
                    823:       return \"\";
                    824:     }
                    825:   return \"and %s2,%s0\;and    %t2,%t0;\";
                    826: }"
1.1       root      827:   [(set_attr "type" "multi")
                    828:    (set_attr "length" "4")
                    829:    (set_attr "cc" "clobber")])
1.1.1.2   root      830: 
                    831: ;; ??? There is an iorsi3 for TARGET_H8300.  Should we have andsi3?
                    832: 
                    833: (define_insn "andsi3"
                    834:   [(set (match_operand:SI 0 "register_operand" "=r,r")
                    835:        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
                    836:                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
                    837:   "TARGET_H8300H"
                    838:   "@
                    839:    and %S2,%S0
                    840:    and %S2,%S0"
                    841:   [(set_attr "type" "arith")
                    842:    (set_attr "length" "4,6")
                    843:    (set_attr "cc" "clobber")])
                    844: 
1.1       root      845: ;; ----------------------------------------------------------------------
1.1.1.2   root      846: ;; OR INSTRUCTIONS
1.1       root      847: ;; ----------------------------------------------------------------------
                    848: 
1.1.1.2   root      849: (define_insn "iorqi3_internal"
                    850:   [(set (match_operand:QI 0 "bit_operand" "=U,r")
                    851:        (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    852:                (match_operand:QI 2 "nonmemory_operand" "P,rn")))]
                    853:   "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
1.1       root      854:   "@
1.1.1.2   root      855:    bset        %V2,%X0
                    856:    or  %X2,%X0"
1.1       root      857:   [(set_attr "type" "arith")
1.1.1.2   root      858:    (set_attr "length" "4,2")
                    859:    (set_attr "cc" "none_0hit,set")])
                    860: 
                    861: (define_expand "iorqi3"
                    862:   [(set (match_operand:QI 0 "bit_operand" "=r,U")
                    863:        (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    864:                (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
                    865:   ""
                    866:   "
                    867: {
                    868:   if (fix_bit_operand (operands, 'P', IOR))
                    869:     DONE;
                    870: }")
                    871: 
                    872: ;; ??? Should have a bset case here also.
1.1       root      873: 
                    874: (define_insn "iorhi3"
                    875:   [(set (match_operand:HI 0 "general_operand" "=r,r")
                    876:        (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1.1.1.2   root      877:                (match_operand:HI 2 "general_operand" "J,rn")))]
1.1       root      878:   ""
1.1.1.2   root      879:   "*
                    880: {
                    881:   if (TARGET_H8300)
                    882:     {
                    883:       if (GET_CODE (operands[2]) == CONST_INT)
                    884:        {
                    885:          int i = INTVAL (operands[2]);
                    886:          if ((i & 0x00ff) != 0) 
                    887:            output_asm_insn (\"or       %s2,%s0\", operands);
                    888:          if ((i & 0xff00) != 0) 
                    889:            output_asm_insn (\"or       %t2,%t0\", operands);
                    890:          return \"\";
                    891:        }
                    892:       return \"or      %s2,%s0\;or     %t2,%t0; %2 or2\";
                    893:     }
                    894:   else
                    895:     {
                    896:       return \"or      %S2,%S0\";
                    897:     }
                    898: }"
1.1       root      899:   [(set_attr "type" "multi")
                    900:    (set_attr "length" "2,4")
                    901:    (set_attr "cc" "clobber,clobber")])
1.1.1.2   root      902: 
                    903: (define_insn "iorsi3"
                    904:   [(set (match_operand:SI 0 "register_operand" "=r")
                    905:        (ior:SI (match_operand:SI 1 "register_operand" "%0")
                    906:                (match_operand:SI 2 "nonmemory_operand" "ri")))]
                    907:   ""
                    908:   "*
                    909: {
                    910:   if (TARGET_H8300)
                    911:     {
                    912:       if (GET_CODE (operands[2]) == CONST_INT)
                    913:        {
                    914:          int i = INTVAL (operands[2]);
                    915:          if ((i & 0x000000ff) != 0) 
                    916:            output_asm_insn (\"or       %w2,%w0\", operands);
                    917:          if ((i & 0x0000ff00) != 0) 
                    918:            output_asm_insn (\"or       %x2,%x0\", operands);
                    919:          if ((i & 0x00ff0000) != 0) 
                    920:            output_asm_insn (\"or       %y2,%y0\", operands);
                    921:          if ((i & 0xff000000) != 0) 
                    922:            output_asm_insn (\"or       %z2,%z0\", operands);
                    923:          return \"\";
                    924:        }
                    925:       return \"or      %w2,%w0\;or     %x2,%x0\;or     %y2,%y0\;or     %z2,%z0\;\";
                    926:     }
                    927:   else
                    928:     {
                    929:       return \"or      %S2,%S0\";
                    930:     }
                    931: }"
                    932:   [(set_attr "type" "multi")
                    933:    (set_attr "length" "8")
                    934:    (set_attr "cc" "clobber")])
                    935: 
1.1       root      936: ;; ----------------------------------------------------------------------
1.1.1.2   root      937: ;; XOR INSTRUCTIONS
1.1       root      938: ;; ----------------------------------------------------------------------
                    939: 
1.1.1.2   root      940: (define_insn "xorqi3_internal"
                    941:   [(set (match_operand:QI 0 "bit_operand" "=r,U")
                    942:        (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    943:                (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
                    944:   "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
                    945:   "@
                    946:    xor %X2,%X0
                    947:    bnot        %V2,%X0"
1.1       root      948:   [(set_attr "type" "arith")
1.1.1.2   root      949:    (set_attr "length" "2,4")
                    950:    (set_attr "cc" "set,none_0hit")])
                    951: 
                    952: (define_expand "xorqi3"
                    953:   [(set (match_operand:QI 0 "bit_operand" "=r,U")
                    954:        (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
                    955:                (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
                    956:   ""
                    957:   "
                    958: {
                    959:   if (fix_bit_operand (operands, 'O', XOR))
                    960:     DONE;
                    961: }")
1.1       root      962: 
                    963: (define_insn "xorhi3"
1.1.1.2   root      964:   [(set (match_operand:HI 0 "register_operand" "=r")
1.1       root      965:        (xor:HI (match_operand:HI 1 "general_operand" "%0")
1.1.1.2   root      966:                (match_operand:HI 2 "nonmemory_operand" "rn")))]
1.1       root      967:   ""
1.1.1.2   root      968:   "*
                    969: {
                    970:   if (TARGET_H8300)
                    971:     return \"xor       %s2,%s0\;xor    %t2,%t0\";
                    972:   else
                    973:     return \"xor       %S2,%S0\";
                    974: }"
1.1       root      975:   [(set_attr "type" "multi")
                    976:    (set_attr "length" "4")
                    977:    (set_attr "cc" "clobber")])
1.1.1.2   root      978: 
                    979: ;; ??? There is an iorsi3 for TARGET_H8300.  Should we have xorsi3?
                    980: 
                    981: (define_insn "xorsi3"
                    982:   [(set (match_operand:SI 0 "register_operand" "=r,r")
                    983:        (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
                    984:                (match_operand:SI 2 "nonmemory_operand" "r,i")))]
                    985:   "TARGET_H8300H"
                    986:   "@
                    987:    xor %S2,%S0
                    988:    xor %S2,%S0"
                    989:   [(set_attr "type" "arith")
                    990:    (set_attr "length" "4,6")
                    991:    (set_attr "cc" "clobber")])
                    992: 
1.1       root      993: ;; ----------------------------------------------------------------------
1.1.1.2   root      994: ;; NEGATION INSTRUCTIONS
1.1       root      995: ;; ----------------------------------------------------------------------
                    996: 
                    997: (define_insn "negqi2"
                    998:   [(set (match_operand:QI 0 "register_operand" "=r")
                    999:        (neg:QI (match_operand:QI 1 "general_operand" "0")))]
                   1000:   ""
                   1001:   "neg %X0"
                   1002:   [(set_attr "type" "arith")
                   1003:    (set_attr "length" "2")
1.1.1.2   root     1004:    (set_attr "cc" "clobber")])
1.1       root     1005: 
                   1006: (define_expand "neghi2"
1.1.1.2   root     1007:   [(set (match_operand:HI 0 "register_operand" "=r")
                   1008:        (neg:HI (match_operand:HI 1 "general_operand" "0")))]
                   1009:   ""
                   1010:   "
                   1011: {
                   1012:   if (TARGET_H8300)
                   1013:     {
                   1014:       emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
                   1015:       DONE;
                   1016:     }
                   1017: }")
                   1018: 
                   1019: (define_expand "neghi2_h8300"
1.1       root     1020:   [(set (match_dup 2)
                   1021:        (not:HI (match_operand:HI 1 "register_operand" "r")))
                   1022:    (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
                   1023:    (set (match_operand:HI 0 "register_operand" "=r")
                   1024:        (match_dup 2))]
                   1025:   ""
1.1.1.2   root     1026:   "{ operands[2] = gen_reg_rtx (HImode); }")
                   1027: 
                   1028: (define_insn "neghi2_h8300h"
                   1029:   [(set (match_operand:HI 0 "register_operand" "=r")
                   1030:        (neg:HI (match_operand:HI 1 "general_operand" "0")))]
                   1031:   "TARGET_H8300H"
                   1032:   "neg %T0"
                   1033:   [(set_attr "type" "arith")
                   1034:    (set_attr "length" "2")
                   1035:    (set_attr "cc" "clobber")])
1.1       root     1036: 
                   1037: (define_expand "negsi2"
1.1.1.2   root     1038:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1039:        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
                   1040:   ""
                   1041:   "
                   1042: {
                   1043:   if (TARGET_H8300)
                   1044:     {
                   1045:       emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
                   1046:       DONE;
                   1047:     }
                   1048: }")
                   1049: 
                   1050: (define_expand "negsi2_h8300"
1.1       root     1051:   [(set (match_dup 2)
                   1052:        (not:SI (match_operand:SI 1 "register_operand" "r")))
                   1053:    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
                   1054:    (set (match_operand:SI 0 "register_operand" "=r")
                   1055:        (match_dup 2))]
                   1056:   ""
1.1.1.2   root     1057:   "{ operands[2] = gen_reg_rtx(SImode); }")
                   1058: 
                   1059: (define_insn "negsi2_h8300h"
                   1060:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1061:        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
                   1062:   "TARGET_H8300H"
                   1063:   "neg %S0"
                   1064:   [(set_attr "type" "arith")
                   1065:    (set_attr "length" "2")
                   1066:    (set_attr "cc" "clobber")])
                   1067: 
1.1       root     1068: ;; ----------------------------------------------------------------------
1.1.1.2   root     1069: ;; NOT INSTRUCTIONS
1.1       root     1070: ;; ----------------------------------------------------------------------
                   1071: 
                   1072: (define_insn "one_cmplqi2"
                   1073:   [(set (match_operand:QI 0 "register_operand" "=r")
                   1074:        (not:QI (match_operand:QI 1 "general_operand" "0")))]
                   1075:   ""
                   1076:   "not %X0"
                   1077:   [(set_attr "type" "arith")
                   1078:    (set_attr "length" "2")
                   1079:    (set_attr "cc" "set")])
                   1080: 
                   1081: (define_insn "one_cmplhi2"
                   1082:   [(set (match_operand:HI 0 "register_operand" "=r")
                   1083:        (not:HI (match_operand:HI 1 "general_operand" "0")))]
                   1084:   ""
1.1.1.2   root     1085:   "*
                   1086: {
                   1087:   if (TARGET_H8300)
                   1088:     return \"not       %s0\;not        %t0\";
                   1089:   else
                   1090:     return \"not       %T0\";
                   1091: }"
1.1       root     1092:   [(set_attr "type" "arith")
                   1093:    (set_attr "length" "4")
                   1094:    (set_attr "cc" "clobber")])
                   1095: 
                   1096: (define_insn "one_cmplsi2"
                   1097:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1098:        (not:SI (match_operand:SI 1 "general_operand" "0")))]
                   1099:   ""
1.1.1.2   root     1100:   "*
                   1101: {
                   1102:   if (TARGET_H8300)
                   1103:     return \"not       %w0\;not        %x0\;not        %y0\;not        %z0\";
                   1104:   else
                   1105:     return \"not       %S0\";
                   1106: }"
1.1       root     1107:   [(set_attr "type" "arith")
1.1.1.2   root     1108: ;; ??? length is wrong for 300h
1.1       root     1109:    (set_attr "length" "8")
                   1110:    (set_attr "cc" "clobber")])
1.1.1.2   root     1111: 
1.1       root     1112: ;; ----------------------------------------------------------------------
1.1.1.2   root     1113: ;; JUMP INSTRUCTIONS
1.1       root     1114: ;; ----------------------------------------------------------------------
                   1115: 
1.1.1.2   root     1116: ;; Conditional jump instructions
                   1117: 
1.1       root     1118: (define_expand "ble"
                   1119:   [(set (pc)
                   1120:        (if_then_else (le (cc0)
                   1121:                          (const_int 0))
                   1122:                      (label_ref (match_operand 0 "" ""))
                   1123:                      (pc)))]
                   1124:   ""
                   1125:   "")
                   1126: 
                   1127: (define_expand "bleu"
                   1128:   [(set (pc)
                   1129:        (if_then_else (leu (cc0)
                   1130:                           (const_int 0))
                   1131:                      (label_ref (match_operand 0 "" ""))
                   1132:                      (pc)))]
                   1133:   ""
                   1134:   "")
                   1135: 
                   1136: (define_expand "bge"
                   1137:   [(set (pc)
                   1138:        (if_then_else (ge (cc0)
                   1139:                          (const_int 0))
                   1140:                      (label_ref (match_operand 0 "" ""))
                   1141:                      (pc)))]
                   1142:   ""
                   1143:   "")
                   1144: 
                   1145: (define_expand "bgeu"
                   1146:   [(set (pc)
                   1147:        (if_then_else (geu (cc0)
                   1148:                           (const_int 0))
                   1149:                      (label_ref (match_operand 0 "" ""))
                   1150:                      (pc)))]
                   1151:   ""
                   1152:   "")
                   1153: 
                   1154: (define_expand "blt"
                   1155:   [(set (pc)
                   1156:        (if_then_else (lt (cc0)
                   1157:                          (const_int 0))
                   1158:                      (label_ref (match_operand 0 "" ""))
                   1159:                      (pc)))]
                   1160:   ""
                   1161:   "")
                   1162: 
                   1163: (define_expand "bltu"
                   1164:   [(set (pc)
                   1165:        (if_then_else (ltu (cc0)
                   1166:                           (const_int 0))
                   1167:                      (label_ref (match_operand 0 "" ""))
                   1168:                      (pc)))]
                   1169:   ""
                   1170:   "")
                   1171: 
                   1172: (define_expand "bgt"
                   1173:   [(set (pc)
                   1174:        (if_then_else (gt (cc0)
                   1175:                          (const_int 0))
                   1176:                      (label_ref (match_operand 0 "" ""))
                   1177:                      (pc)))]
                   1178:   ""
                   1179:   "")
                   1180: 
                   1181: (define_expand "bgtu"
                   1182:   [(set (pc)
                   1183:        (if_then_else (gtu (cc0)
                   1184:                           (const_int 0))
                   1185:                      (label_ref (match_operand 0 "" ""))
                   1186:                      (pc)))]
                   1187:   ""
                   1188:   "")
                   1189: 
                   1190: (define_expand "beq"
                   1191:   [(set (pc)
                   1192:        (if_then_else (eq (cc0)
                   1193:                          (const_int 0))
                   1194:                      (label_ref (match_operand 0 "" ""))
                   1195:                      (pc)))]
                   1196:   ""
                   1197:   "")
                   1198: 
                   1199: (define_expand "bne"
                   1200:   [(set (pc)
                   1201:        (if_then_else (ne (cc0)
                   1202:                          (const_int 0))
                   1203:                      (label_ref (match_operand 0 "" ""))
                   1204:                      (pc)))]
                   1205:   ""
                   1206:   "")
                   1207: 
1.1.1.2   root     1208: (define_insn "branch_true"
1.1       root     1209:   [(set (pc)
1.1.1.2   root     1210:        (if_then_else (match_operator 1 "comparison_operator"
                   1211:                                      [(cc0) (const_int 0)])
                   1212:                      (label_ref (match_operand 0 "" ""))
                   1213:                      (pc)))]
1.1       root     1214:   ""
                   1215:   "*
                   1216: {
                   1217:   if (get_attr_length (insn) == 2) 
1.1.1.2   root     1218:     return \"b%j1      %l0\";
                   1219:   else if (get_attr_length (insn) == 4) 
                   1220:     return \"b%j1      %l0:16\";
1.1       root     1221:   else
1.1.1.2   root     1222:     return \"b%k1      %L0\;jmp        @%l0\;%L0:\";
1.1       root     1223: }" 
1.1.1.2   root     1224:  [(set_attr "type" "branch")
1.1       root     1225:    (set_attr "cc" "none")])
                   1226: 
1.1.1.2   root     1227: (define_insn "branch_false"
1.1       root     1228:   [(set (pc)
1.1.1.2   root     1229:        (if_then_else (match_operator 1 "comparison_operator"
                   1230:                                      [(cc0) (const_int 0)])
                   1231:                      (pc)
                   1232:                      (label_ref (match_operand 0 "" ""))))]
1.1       root     1233:   ""
1.1.1.2   root     1234: ;; ??? We don't take advantage of 16 bit relative jumps in the 300h.
1.1       root     1235:   "*
                   1236: {
                   1237:   if (get_attr_length (insn) == 2) 
1.1.1.2   root     1238:     return \"b%k1      %l0\";
                   1239:   else if (get_attr_length (insn) == 4) 
                   1240:     return \"b%k1      %l0:16\";
1.1       root     1241:   else
1.1.1.2   root     1242:     return \"b%j1      %L0\;jmp        @%l0\;%L0:\";
1.1       root     1243: }"
                   1244:   [(set_attr "type" "branch")
                   1245:    (set_attr "cc" "none")])
1.1.1.2   root     1246: 
                   1247: ;; Unconditional and other jump instructions.
1.1       root     1248: 
                   1249: (define_insn "jump"
                   1250:   [(set (pc)
                   1251:        (label_ref (match_operand 0 "" "")))]
                   1252:   ""
                   1253:   "*
                   1254: {
1.1.1.2   root     1255:   if (get_attr_length (insn) == 2)
                   1256:     return \"bra       %l0\";
                   1257:   else if (get_attr_length (insn) == 4)
                   1258:     return \"bra       %l0:16\";
1.1       root     1259:   else
1.1.1.2   root     1260:     return \"jmp       @%l0\";
1.1       root     1261: }"
                   1262:   [(set_attr "type" "branch")
                   1263:    (set_attr "cc" "none")])
                   1264: 
1.1.1.2   root     1265: ;; This is a define expand, because pointers may be either 16 or 32 bits.
                   1266: 
                   1267: (define_expand "tablejump"
                   1268:   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
                   1269:              (use (label_ref (match_operand 1 "" "")))])]
                   1270:   ""
                   1271:   "")
                   1272: 
                   1273: (define_insn "tablejump_h8300"
1.1.1.3 ! root     1274:   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1.1       root     1275:    (use (label_ref (match_operand 1 "" "")))]
1.1.1.2   root     1276:   "TARGET_H8300"
1.1       root     1277:   "jmp @%0"
                   1278:   [(set_attr "type" "branch")
                   1279:    (set_attr "cc" "none")
                   1280:    (set_attr "length" "2")])
                   1281: 
1.1.1.2   root     1282: (define_insn "tablejump_h8300h"
1.1.1.3 ! root     1283:   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1.1.1.2   root     1284:    (use (label_ref (match_operand 1 "" "")))]
                   1285:   "TARGET_H8300H"
                   1286:   "jmp @%0"
                   1287:   [(set_attr "type" "branch")
                   1288:    (set_attr "cc" "none")
                   1289:    (set_attr "length" "2")])
1.1       root     1290: 
1.1.1.2   root     1291: ;; This is a define expand, because pointers may be either 16 or 32 bits.
                   1292: 
                   1293: ;(define_insn "indirect_jump"
                   1294: ;  [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
                   1295: ;  ""
                   1296: ;  "jmp        @%0"
                   1297: ;  [(set_attr "type" "branch")
                   1298: ;   (set_attr "cc" "none")
                   1299: ;   (set_attr "length" "2")])
                   1300: 
                   1301: (define_expand "indirect_jump"
                   1302:   [(set (pc) (match_operand 0 "jump_address_operand" "Vr"))]
1.1       root     1303:   ""
1.1.1.2   root     1304:   "")
                   1305: 
                   1306: (define_insn "indirect_jump_h8300"
                   1307:   [(set (pc) (match_operand:HI 0 "jump_address_operand" "V,r"))]
                   1308:   "TARGET_H8300"
                   1309:   "@
                   1310:    jmp @%0
                   1311:    jmp @%0"
                   1312:   [(set_attr "type" "branch")
                   1313:    (set_attr "cc" "none")
                   1314:    (set_attr "length" "2")])
                   1315: 
                   1316: (define_insn "indirect_jump_h8300h"
                   1317:   [(set (pc) (match_operand:SI 0 "jump_address_operand" "V,r"))]
                   1318:   "TARGET_H8300H"
                   1319:   "@
                   1320:    jmp @%0
                   1321:    jmp @%0"
                   1322:   [(set_attr "type" "branch")
                   1323:    (set_attr "cc" "none")
                   1324:    (set_attr "length" "2")])
                   1325: 
                   1326: ;; Call subroutine with no return value.
                   1327: 
                   1328: ;; ??? Even though we use HImode here, this works for the 300h.
                   1329: 
                   1330: (define_insn "call"
                   1331:   [(call (match_operand:QI 0 "call_insn_operand" "or")
                   1332:         (match_operand:HI 1 "general_operand" "g"))]
                   1333:   ""
                   1334:   "jsr %0"
1.1       root     1335:   [(set_attr "type" "call")
                   1336:    (set_attr "cc" "clobber")
                   1337:    (set_attr "length" "4")])
                   1338: 
                   1339: ;; Call subroutine, returning value in operand 0
                   1340: ;; (which must be a hard register).
                   1341: 
1.1.1.2   root     1342: ;; ??? Even though we use HImode here, this works on the 300h.
                   1343: 
1.1       root     1344: (define_insn "call_value"
                   1345:   [(set (match_operand 0 "" "=r")
1.1.1.2   root     1346:        (call (match_operand:QI 1 "call_insn_operand" "or")
1.1       root     1347:              (match_operand:HI 2 "general_operand" "g")))]
                   1348:   ""
                   1349:   "jsr %1"
                   1350:   [(set_attr "type" "call")
                   1351:    (set_attr "cc" "clobber")
                   1352:    (set_attr "length" "4")])
                   1353: 
                   1354: (define_insn "nop"
                   1355:   [(const_int 0)]
                   1356:   ""
                   1357:   "nop"
                   1358:   [(set_attr "type" "multi")
                   1359:    (set_attr "cc" "none")
                   1360:    (set_attr "length" "2")])
                   1361: 
1.1.1.2   root     1362: ;; ----------------------------------------------------------------------
                   1363: ;; EXTEND INSTRUCTIONS
                   1364: ;; ----------------------------------------------------------------------
1.1       root     1365: 
1.1.1.2   root     1366: (define_insn "zero_extendqihi2"
                   1367:   [(set (match_operand:HI 0 "register_operand" "=r,r")
                   1368:        (zero_extend:HI (match_operand:QI 1 "general_operand" "0,g")))]
1.1       root     1369:   ""
1.1.1.2   root     1370:   "*
                   1371: {
                   1372:   if (which_alternative==0)
                   1373:     return \"mov.b     #0,%t0\";
1.1       root     1374: 
1.1.1.2   root     1375:   if (TARGET_H8300)
                   1376:     return \"mov.b     %X1,%s0\;mov.b  #0,%t0\";
                   1377:   else
                   1378:     {
                   1379:       /* ??? See how often this gets optimized.  */
                   1380:       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
                   1381:        return \"extu.w %T0\";
                   1382:       else
                   1383:        return \"mov.b  %X1,%s0\;extu.w %T0\";
                   1384:     }
                   1385: }"
                   1386:   [(set_attr "type" "multi")
                   1387: ;; ??? This length is wrong for one case.
                   1388:    (set_attr "length" "4")
                   1389:    (set_attr "cc" "clobber")])
1.1       root     1390: 
1.1.1.2   root     1391: (define_insn "zero_extendhisi2"
                   1392:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1393:        (zero_extend:SI (match_operand:HI 1 "general_operand" "g")))]
                   1394:   "TARGET_H8300H"
                   1395:   "*
1.1       root     1396: {
1.1.1.2   root     1397:   /* ??? See how often this gets optimized.  */
                   1398:   if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
                   1399:     return \"extu.l    %S0\";
1.1       root     1400:   else
1.1.1.2   root     1401:     return \"mov.w     %T1,%T0\;extu.l %S0\";
                   1402: }"
                   1403:   [(set_attr "type" "multi")
                   1404: ;; ??? This length is wrong for one case.
                   1405:    (set_attr "length" "4")
                   1406:    (set_attr "cc" "clobber")])
1.1       root     1407: 
1.1.1.2   root     1408: (define_insn "extendqihi2"
                   1409:   [(set (match_operand:HI 0 "register_operand" "=r")
                   1410:        (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))]
1.1       root     1411:   ""
1.1.1.2   root     1412:   "*
1.1       root     1413: {
1.1.1.2   root     1414:   if (TARGET_H8300)
                   1415:     {
                   1416:       /* ??? See how often this gets optimized.  */
                   1417:       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
                   1418:        return \"bld    #7,%s0\;subx    %t0,%t0\";
                   1419:       else
                   1420:        return \"mov.b  %X1,%s0\;bld    #7,%s0\;subx    %t0,%t0\";
                   1421:     }
1.1       root     1422:   else
1.1.1.2   root     1423:     {
                   1424:       /* ??? See how often this gets optimized.  */
                   1425:       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
                   1426:        return \"exts.w %T0\";
                   1427:       else
                   1428:        return \"mov.b  %X1,%s0\;exts.w %T0\";
                   1429:     }
                   1430: }"
                   1431:   [(set_attr "type" "multi")
                   1432: ;; ??? Length is wrong in some cases.
                   1433:    (set_attr "length" "6")
                   1434:    (set_attr "cc" "clobber")])
1.1       root     1435: 
1.1.1.2   root     1436: (define_expand "extendhisi2"
                   1437:   [(set (match_operand:SI 0 "register_operand" "")
                   1438:        (sign_extend:SI (match_operand:HI 1 "general_operand" "")))]
1.1       root     1439:   ""
                   1440:   "
                   1441: {
1.1.1.2   root     1442:   if (TARGET_H8300)
                   1443:     emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1]));
1.1       root     1444:   else
1.1.1.2   root     1445:     emit_insn (gen_extendhisi2_h8300h (operands[0], operands[1]));
                   1446:   DONE;
1.1       root     1447: }")
                   1448: 
1.1.1.2   root     1449: (define_expand "extendhisi2_h8300"
                   1450:   [(set (reg:HI 1) (match_operand:HI 1 "general_operand" ""))
                   1451:    (set (reg:SI 0) (sign_extend:SI (reg:HI 1)))
                   1452:    (set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))]
                   1453:   "TARGET_H8300"
                   1454:   "")
1.1       root     1455: 
1.1.1.2   root     1456: (define_expand "extendhisi2_h8300h"
                   1457:   [(set (match_operand:SI 0 "register_operand" "")
                   1458:        (sign_extend:SI (match_operand:HI 1 "general_operand" "")))]
                   1459:   "TARGET_H8300H"
                   1460:   "")
1.1       root     1461: 
1.1.1.2   root     1462: (define_insn "extendhisi2_h8300_internal"
                   1463:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1464:        (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
                   1465:   "TARGET_H8300"
                   1466:   "mov.w       %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
                   1467:   [(set_attr "length" "10")
1.1       root     1468:    (set_attr "cc" "clobber")])
                   1469: 
1.1.1.2   root     1470: (define_insn "extendhisi2_h8300h_internal"
                   1471:   [(set (match_operand:SI 0 "register_operand" "=r")
                   1472:        (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
                   1473:   "TARGET_H8300H"
                   1474:   "*
1.1       root     1475: {
1.1.1.2   root     1476:   /* ??? See how often this gets optimized.  */
                   1477:   if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
                   1478:     return \"exts.l    %S0\";
1.1       root     1479:   else
1.1.1.2   root     1480:     return \"mov.w     %T1,%T0\;exts.l %S0\";
                   1481: }"
                   1482:   [(set_attr "length" "10")
                   1483:    (set_attr "cc" "clobber")])
1.1       root     1484: 
1.1.1.2   root     1485: ;; ----------------------------------------------------------------------
                   1486: ;; SHIFTS
                   1487: ;; ----------------------------------------------------------------------
                   1488: ;;
                   1489: ;; We make some attempt to provide real efficient shifting.  One example is
                   1490: ;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
                   1491: ;; reg and moving 0 into the former reg.
                   1492: ;;
                   1493: ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
                   1494: ;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
                   1495: ;; give the optimizer more cracks at the code.  However, we wish to do things
                   1496: ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
                   1497: ;; There is rtl to handle this (rotate + and), but the h8/300 doesn't handle
                   1498: ;; 16 bit rotates.  Also, if we emit complicated rtl, combine may not be able
                   1499: ;; to detect cases it can optimize.
                   1500: ;;
                   1501: ;; For these and other fuzzy reasons, I've decided to go the less pretty but
                   1502: ;; easier "do it at insn emit time" route.
                   1503: 
                   1504: ;; QI BIT SHIFTS
                   1505: 
                   1506: (define_expand "ashlqi3"
                   1507:   [(set (match_operand:QI 0 "register_operand" "")
                   1508:        (ashift:QI (match_operand:QI 1 "register_operand" "")
                   1509:                   (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1510:   ""
1.1.1.2   root     1511:   "if (expand_a_shift (QImode, ASHIFT, operands)) DONE;else FAIL;")
1.1       root     1512: 
1.1.1.2   root     1513: (define_expand "ashrqi3"
                   1514:   [(set (match_operand:QI 0 "register_operand" "")
                   1515:        (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
                   1516:                     (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1517:   ""
1.1.1.2   root     1518:   "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1519: 
1.1.1.2   root     1520: (define_expand "lshrqi3"
                   1521:   [(set (match_operand:QI 0 "register_operand" "")
                   1522:        (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
                   1523:                     (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1524:   ""
1.1.1.2   root     1525:   "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1526: 
1.1.1.2   root     1527: ;; WARNING: The constraints on the scratch register say one is not needed
                   1528: ;; for constant shifts of 1,2,3,4.  Emit_a_shift() must know this.
                   1529: 
                   1530: (define_insn "shiftbyn_QI"
                   1531:   [(set (match_operand:QI 0 "register_operand" "=r,r")
                   1532:        (match_operator:QI 3 "nshift_operator" 
                   1533:                        [ (match_operand:QI 1 "register_operand" "0,0")
                   1534:                          (match_operand:QI 2 "nonmemory_operand" "IKM,rn")]))
                   1535:    (clobber (match_scratch:QI 4 "=X,&r"))]
1.1       root     1536:   ""
1.1.1.2   root     1537:   "* return emit_a_shift (insn, operands);"
                   1538:   [(set_attr "type" "arith")
                   1539:    (set_attr "length" "20")
                   1540: ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
                   1541: ;; However, for cases that loop or are done in pieces, cc does not contain
                   1542: ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1.1       root     1543:    (set_attr "cc" "clobber")])
                   1544: 
1.1.1.2   root     1545: ;; HI BIT SHIFTS
1.1       root     1546: 
1.1.1.2   root     1547: (define_expand "ashlhi3"
                   1548:   [(set (match_operand:HI 0 "register_operand" "")
                   1549:        (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
                   1550:                   (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1551:   ""
1.1.1.2   root     1552:   "if (expand_a_shift (HImode, ASHIFT, operands)) DONE;else FAIL;")
                   1553: 
                   1554: (define_expand "lshrhi3"
                   1555:   [(set (match_operand:HI 0 "register_operand" "")
                   1556:        (lshiftrt:HI (match_operand:HI 1 "general_operand_src" "")
                   1557:                     (match_operand:QI 2 "nonmemory_operand" "")))]
                   1558:   ""
                   1559:   "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1560: 
                   1561: (define_expand "ashrhi3"
                   1562:   [(set (match_operand:HI 0 "register_operand" "")
1.1.1.2   root     1563:        (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
                   1564:                     (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1565:   ""
1.1.1.2   root     1566:   "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1567: 
1.1.1.2   root     1568: ;; WARNING: The constraints on the scratch register say one is not needed
                   1569: ;; for constant shifts of 1,2,3,4.  Emit_a_shift() must know this.
1.1       root     1570: 
1.1.1.2   root     1571: (define_insn "shiftbyn_HI"
                   1572:   [(set (match_operand:HI 0 "register_operand" "=r,r")
                   1573:        (match_operator:HI 3 "nshift_operator" 
                   1574:                        [ (match_operand:HI 1 "register_operand" "0,0")
                   1575:                          (match_operand:QI 2 "nonmemory_operand" "IKM,rn")]))
                   1576:    (clobber (match_scratch:QI 4 "=X,&r"))]
1.1       root     1577:   ""
1.1.1.2   root     1578:   "* return emit_a_shift (insn, operands);"
                   1579:   [(set_attr "type" "arith")
                   1580:    (set_attr "length" "20")
                   1581: ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
                   1582: ;; However, for cases that loop or are done in pieces, cc does not contain
                   1583: ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1.1       root     1584:    (set_attr "cc" "clobber")])
                   1585: 
1.1.1.2   root     1586: ;;  SI BIT SHIFTS
                   1587: 
1.1       root     1588: (define_expand "ashlsi3"
                   1589:   [(set (match_operand:SI 0 "register_operand" "")
                   1590:        (ashift:SI
                   1591:         (match_operand:SI 1 "general_operand_src" "")
1.1.1.2   root     1592:         (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1593:   ""
1.1.1.2   root     1594:   "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;")
1.1       root     1595: 
                   1596: (define_expand "lshrsi3"
                   1597:   [(set (match_operand:SI 0 "register_operand" "")
                   1598:        (lshiftrt:SI
                   1599:         (match_operand:SI 1 "general_operand_src" "")
1.1.1.2   root     1600:         (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1601:   ""
1.1.1.2   root     1602:   "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1603: 
                   1604: (define_expand "ashrsi3"
                   1605:   [(set (match_operand:SI 0 "register_operand" "")
                   1606:        (ashiftrt:SI
                   1607:         (match_operand:SI 1 "general_operand_src" "")
1.1.1.2   root     1608:         (match_operand:QI 2 "nonmemory_operand" "")))]
1.1       root     1609:   ""
1.1.1.2   root     1610:   "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;")
1.1       root     1611: 
1.1.1.2   root     1612: ;; WARNING: The constraints on the scratch register say one is not needed
                   1613: ;; for constant shifts of 1,2.  Emit_a_shift() must know this.
1.1       root     1614: 
1.1.1.2   root     1615: (define_insn "shiftbyn_SI"
                   1616:   [(set (match_operand:SI 0 "register_operand" "=r,r")
                   1617:        (match_operator:SI 3 "nshift_operator" 
                   1618:                        [ (match_operand:SI 1 "register_operand" "0,0")
                   1619:                          (match_operand:QI 2 "nonmemory_operand" "IK,rn")]))
                   1620:    (clobber (match_scratch:QI 4 "=X,&r"))]
1.1       root     1621:   ""
1.1.1.2   root     1622:   "* return emit_a_shift (insn, operands);"
                   1623:   [(set_attr "type" "arith")
                   1624:    (set_attr "length" "20")
                   1625: ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
                   1626: ;; However, for cases that loop or are done in pieces, cc does not contain
                   1627: ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1.1       root     1628:    (set_attr "cc" "clobber")])
                   1629: 
1.1.1.2   root     1630: ;; -----------------------------------------------------------------
                   1631: ;; BIT FIELDS
                   1632: ;; -----------------------------------------------------------------
                   1633: ;; The H8/300 has given 1/8th of its opcode space to bitfield
1.1.1.3 ! root     1634: ;; instructions so let's use them as well as we can
1.1       root     1635: 
1.1.1.2   root     1636: ;; BCC and BCS patterns.
                   1637: 
                   1638: (define_insn "bcs_qiqi"
                   1639:   [(set (pc)
                   1640:        (if_then_else 
                   1641:         (match_operator 1 "eq_operator"
                   1642:                         [(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur")
                   1643:                                           (const_int 1)
                   1644:                                           (match_operand:HI 3 "immediate_operand" "i"))
                   1645:                          (const_int 0)])
                   1646:         (label_ref (match_operand 0 "" ""))
                   1647:         (pc)))]
1.1       root     1648:   ""
1.1.1.2   root     1649:   "*
                   1650: {
                   1651:   output_asm_insn(\"bld        %Z3,%Y2\", operands);
                   1652:   if (get_attr_length (insn) == 2) 
                   1653:     return \"b%d1      %l0\";
                   1654:   else if (get_attr_length (insn) == 4) 
                   1655:     return \"b%d1      %l0:16\";
                   1656:   else
                   1657:     return \"b%g1      %L0\;jmp        @%l0\;%L0:\";
                   1658: }" 
                   1659:   [(set_attr "type" "branch")
1.1       root     1660:    (set_attr "cc" "clobber")])
                   1661: 
1.1.1.2   root     1662: (define_insn "bcs_hihi"
                   1663:   [(set (pc)
                   1664:        (if_then_else 
                   1665:         (match_operator 1 "eq_operator"
                   1666:                         [(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur")
                   1667:                                           (const_int 1)
                   1668:                                           (match_operand:HI 3 "immediate_operand" "i"))
                   1669:                          (const_int 0)])
                   1670:         (label_ref (match_operand 0 "" ""))
                   1671:         (pc)))]
1.1       root     1672:   ""
1.1.1.2   root     1673:   "*
                   1674: {
                   1675:   output_asm_insn(\"bld        %Z3,%Y2\", operands);
                   1676:   if (get_attr_length (insn) == 2) 
                   1677:     return \"%d1       %l0\";
                   1678:   else if (get_attr_length (insn) == 4) 
                   1679:     return \"%d1       %l0:16\";
                   1680:   else
                   1681:     return \"%g1       %L0\;jmp        @%l0\;%L0:\";
                   1682: }" 
                   1683:   [(set_attr "type" "branch")
1.1       root     1684:    (set_attr "cc" "clobber")])
                   1685: 
1.1.1.2   root     1686: (define_insn "bcs_hiqi"
                   1687:   [(set (pc)
                   1688:        (if_then_else 
                   1689:         (match_operator 1 "eq_operator"
                   1690:                         [(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur")
                   1691:                                           (const_int 1)
                   1692:                                           (match_operand:HI 3 "immediate_operand" "i"))
                   1693:                          (const_int 0)])
                   1694:         (label_ref (match_operand 0 "" ""))
                   1695:         (pc)))]
1.1       root     1696:   ""
1.1.1.2   root     1697:   "*
                   1698: {
                   1699:   output_asm_insn(\"bld        %Z3,%Y2\", operands);
                   1700:   if (get_attr_length (insn) == 2) 
                   1701:     return \"%d1       %l0\";
                   1702:   else if (get_attr_length (insn) == 4) 
                   1703:     return \"%d1       %l0:16\";
                   1704:   else
                   1705:     return \"%g1       %L0\;jmp        @%l0\;%L0:\";
                   1706: }" 
                   1707:   [(set_attr "type" "branch")
                   1708:    (set_attr "cc" "clobber")])
1.1       root     1709: 
1.1.1.2   root     1710: ;; BLD and BST patterns
                   1711: 
                   1712: (define_insn "extract_1"
                   1713:   [(set (match_operand:HI 0 "register_operand" "=&r")
                   1714:        (zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
                   1715:                         (const_int 1)
                   1716:                         (match_operand:HI 2 "immediate_operand" "i")))]
1.1       root     1717:   ""
1.1.1.2   root     1718:   "sub.w       %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0")
1.1       root     1719: 
1.1.1.2   root     1720: (define_insn "extract_1_hi"
                   1721:   [(set (match_operand:HI 0 "register_operand" "=&r")
                   1722:        (zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
                   1723:                         (const_int 1)
                   1724:                         (match_operand:HI 2 "immediate_operand" "i")))]
1.1       root     1725:   ""
1.1.1.2   root     1726:   "sub.w       %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0")
1.1       root     1727: 
1.1.1.2   root     1728: (define_insn "insert_1"
                   1729:   [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur")
                   1730:                         (const_int 1)
                   1731:                         (match_operand:HI 1 "immediate_operand" "i"))
                   1732:        (zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur")
                   1733:                         (const_int 1)
                   1734:                         (const_int 0)))]
1.1       root     1735:   ""
1.1.1.2   root     1736:   "bld #0,%X2\;bst     %Z1,%Y0 ; i1")
                   1737: 
                   1738: ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
                   1739: ;; in combine.c, but there is no problem with writing it this way so we do.
                   1740: (define_insn "extract_insert_1"
                   1741:   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur")
                   1742:                         (const_int 1)
                   1743:                         (match_operand:HI 1 "immediate_operand" "i"))
                   1744:        (lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur")
                   1745:                     (match_operand:HI 3 "immediate_operand" "i")))]
                   1746:  ""
                   1747:  "bld  %Z3,%Y2\;bst    %Z1,%Y0; ei1")
                   1748: 
                   1749: ;; BAND, BOR, and BXOR patterns
                   1750: 
                   1751: (define_insn "bitlogical_1"
                   1752:   [(set (match_operand:HI 0 "bit_operand" "=Ur")
                   1753:        (match_operator:HI 4 "bit_operator"
                   1754:           [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
                   1755:                             (const_int 1)
                   1756:                             (match_operand:HI 2 "immediate_operand" "i"))
                   1757:            (match_operand:HI 3 "bit_operand" "0")]))]
                   1758:   ""
                   1759:   "bld %Z2,%Y1\;%b4    #0,%X0\;bst     #0,%X0; bl1")
                   1760: 
                   1761: (define_insn "bitlogical_1_hi"
                   1762:   [(set (match_operand:HI 0 "bit_operand" "=Ur")
                   1763:        (match_operator:HI 4 "bit_operator"
                   1764:           [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
                   1765:                             (const_int 1)
                   1766:                             (match_operand:HI 2 "immediate_operand" "i"))
                   1767:            (match_operand:HI 3 "bit_operand" "0")]))]
                   1768:   ""
                   1769:   "bld %Z2,%Y1\;%b4    #0,%X0\;bst     #0,%X0; bl2")
                   1770: 
                   1771: (define_insn "bitlogical_2"
                   1772:   [(set (match_operand:HI 0 "bit_operand" "=Ur")
                   1773:        (match_operator:HI 5 "bit_operator"
                   1774:           [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
                   1775:                             (const_int 1)
                   1776:                             (match_operand:HI 2 "immediate_operand" "i"))
                   1777:            (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur")
                   1778:                             (const_int 1)
                   1779:                             (match_operand:HI 4 "immediate_operand" "i"))]))]
                   1780:   ""
                   1781:   "bld %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%X0; bl3")
                   1782: 
                   1783: (define_insn "bitlogical_2_hi"
                   1784:   [(set (match_operand:HI 0 "bit_operand" "=Ur")
                   1785:        (match_operator:HI 5 "bit_operator"
                   1786:           [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
                   1787:                             (const_int 1)
                   1788:                             (match_operand:HI 2 "immediate_operand" "i"))
                   1789:            (zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur")
                   1790:                             (const_int 1)
                   1791:                             (match_operand:HI 4 "immediate_operand" "i"))]))]
                   1792:   ""
                   1793:   "bld %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%X0; bl3")
                   1794: 
                   1795: ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
                   1796: ;; in combine.c, but there is no problem with writing it this way so we do.
                   1797: (define_insn "bitlogical_3"
                   1798:   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur")
                   1799:                         (const_int 1)
                   1800:                         (match_operand:HI 1 "immediate_operand" "i"))
                   1801:        (match_operator:QI 6 "bit_operator"
                   1802:           [(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur")
                   1803:                         (match_operand:HI 3 "immediate_operand" "i"))
                   1804:            (lshiftrt:QI (match_operand:QI 4 "bit_operand" "Ur")
                   1805:                         (match_operand:HI 5 "immediate_operand" "i"))]))]
                   1806:   ""
                   1807:   "bld %Z3,%Y2\;%b6    %Z5,%Y4\;bst    %Z1,%Y0; bl5")
                   1808:                                                     
                   1809: ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
                   1810: ;; in combine.c, but there is no problem with writing it this way so we do.
                   1811: (define_insn "bitnot_1"
                   1812:   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur")
                   1813:                         (const_int 1)
                   1814:                         (match_operand:HI 1 "immediate_operand" "i"))
                   1815:        (lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0")
                   1816:                             (match_operand:HI 3 "immediate_operand" "i"))
                   1817:                     (match_operand:HI 4 "immediate_operand" "1")))]
                   1818:   "GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
                   1819:    && exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])"
                   1820:   "bnot        %Z1,%Y0")
                   1821: 
                   1822: ;; ??? Implement BIAND, BIOR, BIXOR
                   1823: 
                   1824: ;; ??? Implement BILD, BIST
                   1825: 
                   1826: ;; ??? Apparently general_operand for the 1st and 2nd operands is useful,
                   1827: ;; but I don't know why.  --Jim
                   1828: 
                   1829: (define_expand "insv"
                   1830:   [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur")
                   1831:                         (match_operand:HI 1 "general_operand" "g")
                   1832:                         (match_operand:HI 2 "general_operand" "g"))
                   1833:        (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur")
                   1834:                         (const_int 1)
                   1835:                         (const_int 0)))]
                   1836: ;; ??? This should have word mode which is SImode for the h8/300h.
                   1837:   "TARGET_H8300"
                   1838:   "
1.1       root     1839: {
1.1.1.2   root     1840:   if (INTVAL (operands[1]) != 1)
                   1841:     FAIL;
                   1842: 
                   1843:   /* ??? HACK ???
                   1844:      This INSV pattern is wrong.  It should use HImode for operand 3.
                   1845:      Also, the zero_extract around operand 3 is superfluous and should be
                   1846:      deleted.  Fixing this is more work than we care to do for the moment,
                   1847:      because it means most of the above patterns would need to be rewritten,
                   1848:      and we also need more combine.c patches to make this work.
                   1849: 
                   1850:      So, for now, we work around this bug by simply not accepting any bitfield
                   1851:      inserts that have a position greater than fits in QImode.  */
                   1852: 
                   1853:   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 8)
                   1854:     FAIL;
                   1855: 
1.1.1.3 ! root     1856:   /* The bit_operand predicate accepts any memory during RTL generation, but
1.1.1.2   root     1857:      only 'U' memory afterwards, so if this is a MEM operand, we must force
                   1858:      it to be valid for 'U' by reloading the address.  */
                   1859: 
                   1860:   if (GET_CODE (operands[0]) == MEM && ! EXTRA_CONSTRAINT (operands[0], 'U'))
                   1861:     {
                   1862:       rtx mem;
                   1863:       mem = gen_rtx (MEM, GET_MODE (operands[0]),
                   1864:                     copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
                   1865:       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
                   1866:       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
                   1867:       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
                   1868:       operands[0] = mem;
                   1869:     }
                   1870: 
                   1871:   /* Likewise for operands[3].  */
                   1872: 
                   1873:   if (GET_CODE (operands[3]) == MEM && ! EXTRA_CONSTRAINT (operands[3], 'U'))
                   1874:     {
                   1875:       rtx mem;
                   1876:       mem = gen_rtx (MEM, GET_MODE (operands[3]),
                   1877:                     copy_to_mode_reg (Pmode, XEXP (operands[3], 0)));
                   1878:       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[3]);
                   1879:       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[3]);
                   1880:       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
                   1881:       operands[3] = mem;
                   1882:     }
                   1883: }")
                   1884: 
                   1885: ;; ??? Apparently general_operand for the 2nd and 3rd operands is useful,
                   1886: ;; but I don't know why.  --Jim
                   1887: 
                   1888: (define_expand "extzv"
                   1889:   [(set (match_operand:HI 0 "register_operand" "") 
                   1890:        (zero_extract:HI (match_operand:QI 1 "bit_operand" "")
                   1891:                         (match_operand:HI 2 "general_operand" "g")
                   1892:                         (match_operand:HI 3 "general_operand" "g")))]
                   1893: ;; ??? This should have word mode which is SImode for the h8/300h.
                   1894:   "TARGET_H8300"
                   1895:   "
                   1896: {
                   1897:   if (INTVAL (operands[2]) != 1)
                   1898:     FAIL;
                   1899: 
1.1.1.3 ! root     1900:   /* The bit_operand predicate accepts any memory during RTL generation, but
1.1.1.2   root     1901:      only 'U' memory afterwards, so if this is a MEM operand, we must force
                   1902:      it to be valid for 'U' by reloading the address.  */
                   1903: 
                   1904:   if (GET_CODE (operands[1]) == MEM && ! EXTRA_CONSTRAINT (operands[1], 'U'))
                   1905:     {
                   1906:       rtx mem;
                   1907:       mem = gen_rtx (MEM, GET_MODE (operands[1]),
                   1908:                     copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
                   1909:       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
                   1910:       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
                   1911:       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
                   1912:       operands[1] = mem;
                   1913:     }
                   1914: }")
                   1915: 
                   1916: ;; -----------------------------------------------------------------
                   1917: ;; STACK POINTER MANIPULATIONS
                   1918: ;; -----------------------------------------------------------------
                   1919: 
                   1920: ;; This pattern is needed because there is no way on the H8/300
                   1921: ;; to add a 16 bit immediate value to the stack pointer in one 
                   1922: ;; instruction, which could leave an invalid instruction if interrupted
                   1923: ;; half way through.  Here we add to the stack pointer from a
                   1924: ;; register.
                   1925: 
                   1926: (define_insn "stack_pointer_manip"
                   1927:   [(set (match_operand:HI 0 "register_operand" "=&ra")
                   1928:        (plus:HI (match_operand:HI 1 "general_operand_src" "g")
                   1929:                 (match_operand:HI 2 "register_operand" "ra")))]
                   1930:   "TARGET_H8300"
                   1931:   "mov.w       %T1,%T0\;add.w  %T2,%T0"
                   1932:   [(set_attr "type" "arith")
1.1       root     1933:    (set_attr "length" "6")
1.1.1.2   root     1934:    (set_attr "cc" "set")])
1.1       root     1935: 
                   1936: 
1.1.1.2   root     1937: ;; -------------------------------------------
                   1938: ;; BLK moves
                   1939: ;; -------------------------------------------
                   1940: 
                   1941: (define_expand "movstrhi"
                   1942:   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
                   1943:                   (mem:BLK (match_operand:BLK 1 "general_operand" "")))
                   1944:             (use (match_operand:HI 2 "general_operand" ""))
                   1945:             (use (match_operand:HI 3 "immediate_operand" ""))
                   1946:             (clobber (match_dup 3))
                   1947:   ])]
1.1       root     1948:   ""
1.1.1.2   root     1949:   "
                   1950: {
                   1951:        rtx src_ptr = copy_to_mode_reg (Pmode, XEXP(operands[1], 0));
                   1952:        rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP(operands[0], 0));
                   1953:        
                   1954:         int max = GET_CODE (operands[2]) == CONST_INT
                   1955:          ? MIN (INTVAL (operands[2]), INTVAL (operands[3])) : 1;
                   1956:        enum machine_mode mode = max >= 2 ? HImode : QImode;
                   1957:        rtx tmpreg = gen_reg_rtx (mode);
                   1958:        rtx increment = mode == QImode ? const1_rtx : const2_rtx;
                   1959:        rtx length = operands[2];
                   1960:        rtx label = gen_label_rtx ();
                   1961:        rtx end_src_ptr = gen_reg_rtx (Pmode);
                   1962: 
                   1963: /*     emit_move_insn (length, gen_rtx(MINUS, HImode, length, increment));*/
                   1964:        FAIL;
                   1965:        if (Pmode == HImode)
                   1966:          emit_insn (gen_addhi3 (end_src_ptr, src_ptr, length));
                   1967:        else
                   1968:          emit_insn (gen_addsi3 (end_src_ptr, src_ptr, length));
                   1969: 
                   1970:        emit_label (label);
                   1971:        emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr));
                   1972:        emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg);
                   1973:        emit_insn (gen_rtx (SET, VOIDmode, src_ptr,
                   1974:                            gen_rtx (PLUS, Pmode, src_ptr, increment)));
                   1975:        emit_insn (gen_rtx (SET, VOIDmode, dst_ptr,
                   1976:                            gen_rtx (PLUS, Pmode, dst_ptr, increment)));
                   1977: 
                   1978:        emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
                   1979:                            gen_rtx (COMPARE, Pmode, src_ptr, end_src_ptr)));
                   1980:        emit_jump_insn (gen_bne (label));
1.1       root     1981: 
1.1.1.2   root     1982:        DONE;   
                   1983: }")
1.1       root     1984: 
1.1.1.2   root     1985: ;; ----------------------------------------------
                   1986: ;; Peepholes go at the end.
                   1987: ;; ----------------------------------------------
                   1988: 
                   1989: ;; Notice when two byte moves in a row could be a word move.
                   1990: 
                   1991: (define_peephole
                   1992:   [(set (match_operand:QI 0 "register_operand" "=r")
                   1993:        (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
                   1994:                         (match_operand:HI 2 "immediate_operand" "n"))))
                   1995:    (set (match_operand:QI 3 "register_operand" "=r")
                   1996:        (mem:QI (plus:HI (match_dup 1)
                   1997:                         (match_operand:HI 4 "immediate_operand" "n"))))]
                   1998:   "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
                   1999:   "mov.w       @(%u4,%T1),%T0"
                   2000:   [(set_attr "length" "6")
1.1       root     2001:    (set_attr "cc" "set")])
                   2002: 
1.1.1.2   root     2003: (define_peephole
                   2004:   [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
                   2005:                         (match_operand:HI 2 "immediate_operand" "n")))
                   2006:        (match_operand:QI 0 "register_operand" "r"))
                   2007:    (set (mem:QI (plus:HI (match_dup 1)
                   2008:                         (match_operand:HI 4 "immediate_operand" "n")))
                   2009:        (match_operand:QI 3 "register_operand" "r"))]
                   2010:   "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
                   2011:   "mov.w       %T0,@(%u4,%T1)"
                   2012:   [(set_attr "length" "6")
                   2013:    (set_attr "cc" "set")])
                   2014: 
                   2015: ;; Notice a move which could be post incremented.
                   2016: 
1.1       root     2017: (define_peephole 
1.1.1.2   root     2018:   [(set (match_operand:QI 0 "register_operand" "")
                   2019:        (mem:QI (match_operand:HI 1 "register_operand" "")))
                   2020:    (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
                   2021:   "REGNO(operands[1]) != REGNO(operands[0])"
                   2022:   "mov.b       @%T1+,%X0"
1.1       root     2023:   [(set_attr "length" "2")
                   2024:    (set_attr "cc" "set")])
                   2025: 
                   2026: (define_peephole 
                   2027:   [(set (match_operand:HI 0 "register_operand" "")
                   2028:        (mem:HI (match_operand:HI 1 "register_operand" "")))
                   2029:    (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))]
1.1.1.2   root     2030:   "REGNO(operands[1]) != REGNO(operands[0])"
1.1       root     2031:   "mov.w       @%T1+,%T0"
                   2032:   [(set_attr "length" "2")
                   2033:    (set_attr "cc" "set")])
                   2034: 
1.1.1.2   root     2035: ;; Notice a move which could be predecremented.
                   2036: 
1.1       root     2037: (define_peephole 
1.1.1.2   root     2038:   [(set (match_operand:HI 1 "register_operand" "")
                   2039:        (plus:HI (match_dup 1) (const_int -1)))
                   2040:    (set (mem:QI (match_dup 1))
                   2041:                (match_operand:QI 0 "register_operand" ""))]
                   2042:   "REGNO(operands[1]) != REGNO(operands[0])"
                   2043:   "mov.b       %X0,@-%T1"
1.1       root     2044:   [(set_attr "length" "2")
                   2045:    (set_attr "cc" "set")])
                   2046: 
1.1.1.2   root     2047: (define_peephole 
                   2048:   [(set (match_operand:HI 1 "register_operand" "")
                   2049:        (plus:HI (match_dup 1) (const_int -1)))
                   2050:    (set (mem:HI (match_dup 1))
                   2051:                (match_operand:HI 0 "register_operand" ""))]
                   2052:   "REGNO(operands[1]) != REGNO(operands[0])"
                   2053:   "mov.w       %T0,@-%T1"
                   2054:   [(set_attr "length" "2")
1.1       root     2055:    (set_attr "cc" "set")])
                   2056: 
1.1.1.2   root     2057: ;(define_insn ""
                   2058: ;  [(set (match_operand:HI 0 "register_operand" "=r")
                   2059: ;      (MEM:HI (match_operand:HI 1 "register_operand" "r")))
                   2060: ;   (set (match_operand:HI 3 "register_operand" "=r")
                   2061: ;      (zero_extract:HI (match_dup 0)
                   2062: ;                       (const_int 1)
                   2063: ;                       (match_operand:HI 2 "general_operand" "g")))
                   2064: ;   (set (MEM:HI (match_dup 1) (match_dup 3)))]
                   2065: ;  ""
                   2066: ;  "bld        #0,%3l\;bst     %Z2,%0%Y1"
                   2067: ;  [(set_attr "type" "multi")
                   2068: ;   (set_attr "length" "4")
                   2069: ;   (set_attr "cc" "clobber")])
                   2070: 
                   2071: (define_insn "fancybset1"
                   2072:   [(set (match_operand:QI 0 "bit_operand" "=Ur")
                   2073:        (ior:QI (subreg:QI 
                   2074:                 (ashift:HI (const_int 1)
                   2075:                            (subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0)
                   2076:                (match_dup 0)))]
                   2077:   ""
                   2078:   "bset        %X1,%X0")       
                   2079: 
                   2080: (define_insn "fancybset"
                   2081:   [(set (match_operand:QI 0 "bit_operand" "=Ur")
                   2082:        (ior:QI (subreg:QI 
                   2083:                 (ashift:HI (const_int 1)
                   2084:                            (match_operand:HI 1 "nonmemory_operand" "ri") ) 0)
                   2085:                (match_operand:QI 2 "general_operand" "Ur")))]
                   2086:   ""
                   2087:   "mov.b       %X2,%X0\;bset   %X1,%X0")       
                   2088: 
                   2089: 
                   2090: (define_insn "fancybclr4"
                   2091:   [(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
                   2092:        (and:QI 
                   2093:         (subreg:QI 
                   2094:          (rotate:HI (const_int -2)
                   2095:                     (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0)
                   2096:         (match_operand:QI 1 "general_operand" "0,Ur")))
                   2097:    (clobber (match_scratch:HI 3 "=X,&r"))]
                   2098:   ""
                   2099:   "@
                   2100:    bclr        %X2,%X0; l1
                   2101:    mov.b       %X1,%X3\;mov.b  %3,%0\;bclr     %X2,%X0; l3")
                   2102: 
                   2103: (define_insn "fancybclr5"
                   2104:   [(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
                   2105:        (and:QI 
                   2106:         (subreg:QI 
                   2107:          (rotate:HI (const_int -2)
                   2108:                     (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0)
                   2109:         (match_operand:QI 1 "general_operand" "0,Ur")))
                   2110:    (clobber (match_scratch:HI 3 "=X,&r"))]
                   2111:   ""
                   2112:   "@
                   2113:    bclr        %X2,%X0; l1
                   2114:    mov.b       %X1,%X3\;mov.b  %3,%0\;bclr     %X2,%X0;l2")
                   2115: 
                   2116: (define_insn "fancybclr2"
                   2117:   [(set (match_operand:QI 0 "general_operand" "=U,r")
                   2118:        (and:QI 
                   2119:         (subreg:QI 
                   2120:          (rotate:HI (const_int -2)
                   2121:                     (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0)
                   2122:         (match_operand:QI 1 "general_operand" "0,0")))]
                   2123:   ""
                   2124:   "bclr        %X2,%X0")
                   2125: 
                   2126: (define_insn "fancybclr3"
                   2127:   [(set (match_operand:QI 0 "general_operand" "=U,r")
                   2128:        (and:QI 
                   2129:         (subreg:QI 
                   2130:          (rotate:HI (const_int -2)
                   2131:                     (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0)
                   2132:         (match_operand:QI 1 "general_operand" "0,0")))]
                   2133:   ""
                   2134:   "bclr        %X2,%X0")
                   2135: 
                   2136: (define_insn "fancybclr"
                   2137:   [(set (match_operand:QI 0 "general_operand" "=r")
                   2138:        (and:QI (not:QI (match_operand:QI 1 "general_operand" "0"))
                   2139:                (match_operand:QI 2 "general_operand" "r")))]
                   2140:   ""
                   2141:   "not %X0\;and        %X2,%X0")
                   2142: 
                   2143: (define_insn "fancybsetp3"
                   2144:   [(set (match_operand:QI 0 "bit_operand" "=Ur")
                   2145:        (ior:QI (subreg:QI (ashift:HI (const_int 1)
                   2146:                                      (match_operand:QI 1 "register_operand" "r")) 0)
                   2147:                (match_operand:QI 2 "bit_operand" "0")))]
                   2148:   ""
                   2149:   "bset        %X1,%X0")
                   2150: 
                   2151: (define_insn "fancybsetp2"
                   2152:   [(set (match_operand:QI 0 "general_operand" "=r,U")
                   2153:        (ior:QI (subreg:QI (ashift:HI (const_int 1)
                   2154:                                      (match_operand:QI 1 "register_operand" "r,r")) 0)
                   2155:                (match_operand:QI 2 "general_operand" "U,r")))]
                   2156:   ""
                   2157:   "mov.b       %X2,%X0\;bset   %X1,%X0")
                   2158:        
                   2159: (define_insn "fancybnot"
                   2160:   [(set (match_operand:QI 0 "bit_operand" "=Ur")
                   2161:        (xor:QI (subreg:QI (ashift:HI (const_int 1)
                   2162:                                      (match_operand:QI 1 "register_operand" "r")) 0)
                   2163:                (match_operand:QI 2 "bit_operand" "0")))]
                   2164: 
                   2165:   ""
                   2166:   "bnot        %X1,%X0")
                   2167: 
                   2168: (define_insn "fancy_btst"
                   2169:   [(set (pc)
1.1.1.3 ! root     2170:        (if_then_else (eq (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur"))
1.1.1.2   root     2171:                                           (const_int 1)
1.1.1.3 ! root     2172:                                           (match_operand:HI 2 "nonmemory_operand" "rn"))
1.1.1.2   root     2173:                          (const_int 0))
1.1.1.3 ! root     2174:                      (label_ref (match_operand 0 "" ""))
1.1.1.2   root     2175:                      (pc)))]
                   2176:   ""
                   2177:   "*
                   2178: {
                   2179:   if (get_attr_length (insn) == 2)
1.1.1.3 ! root     2180:     return \"btst      %X2,%X1\;beq    %l0\";
1.1.1.2   root     2181:   else if (get_attr_length (insn) == 4)
1.1.1.3 ! root     2182:     return \"btst      %X2,%X1\;beq    %l0:16\";
1.1.1.2   root     2183:   else
1.1.1.3 ! root     2184:     return \"btst      %X2,%X1\;bne    %L1\;jmp        @%l0\;%L1:\";
1.1.1.2   root     2185: }"
                   2186:   [(set_attr "type" "branch")
                   2187:    (set_attr "cc" "clobber")])
                   2188: 
                   2189: (define_insn "fancy_btst1"
                   2190:   [(set (pc)
1.1.1.3 ! root     2191:        (if_then_else (ne (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur"))
1.1.1.2   root     2192:                                           (const_int 1)
1.1.1.3 ! root     2193:                                           (match_operand:HI 2 "nonmemory_operand" "rn"))
1.1.1.2   root     2194:                          (const_int 0))
1.1.1.3 ! root     2195:                      (label_ref (match_operand 0 "" ""))
1.1.1.2   root     2196:                      (pc)))]
                   2197:   ""
                   2198:   "*
                   2199: {
                   2200:   if (get_attr_length (insn) == 2)
1.1.1.3 ! root     2201:     return \"btst      %X2,%X1\;bne    %l0\";
1.1.1.2   root     2202:   else if (get_attr_length (insn) == 4)
1.1.1.3 ! root     2203:     return \"btst      %X2,%X1\;bne    %l0:16\";
1.1.1.2   root     2204:   else
1.1.1.3 ! root     2205:     return \"btst      %X2,%X1\;beq    %L1\;jmp        @%l0\;%L1:\";
1.1.1.2   root     2206: }"
                   2207:   [(set_attr "type" "branch")
                   2208:    (set_attr "cc" "clobber")])
                   2209: 
                   2210: (define_insn "pxor"
                   2211:   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=r,U")
                   2212:                         (const_int 1)
                   2213:                         (match_operand 1 "immediate_operand" "n,n"))
                   2214:        (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U"))
                   2215:                        (const_int 1)))]
                   2216:   ""
                   2217:   "bld #0,%X2\;bist    %1,%0"
                   2218:   [(set_attr "type" "arith")
                   2219:    (set_attr "length" "4")
                   2220:    (set_attr "cc" "clobber")])

unix.superglobalmegacorp.com

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