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

1.1       root        1: /* Subroutines for insn-output.c 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:    Contributed by Steve Chamberlain ([email protected]),
                      4:    Jim Wilson ([email protected]), and Doug Evans ([email protected]).
1.1       root        5: 
                      6: This file is part of GNU CC.
                      7: 
                      8: GNU CC is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU General Public License as published by
                     10: the Free Software Foundation; either version 2, or (at your option)
                     11: any later version.
                     12: 
                     13: GNU CC is distributed in the hope that it will be useful,
                     14: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: GNU General Public License for more details.
                     17: 
                     18: You should have received a copy of the GNU General Public License
                     19: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.3 ! root       20: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            21: Boston, MA 02111-1307, USA.  */
1.1       root       22: 
                     23: #include <stdio.h>
                     24: #include "config.h"
                     25: #include "rtl.h"
                     26: #include "regs.h"
                     27: #include "hard-reg-set.h"
                     28: #include "real.h"
                     29: #include "insn-config.h"
                     30: #include "conditions.h"
                     31: #include "insn-flags.h"
                     32: #include "output.h"
                     33: #include "insn-attr.h"
                     34: #include "flags.h"
                     35: #include "recog.h"
                     36: #include "expr.h"
                     37: #include "tree.h"
                     38: 
                     39: /* Forward declarations.  */
                     40: void print_operand_address ();
                     41: char *index ();
                     42: 
1.1.1.2   root       43: /* CPU_TYPE, says what cpu we're compiling for.  */
                     44: int cpu_type;
                     45: 
1.1       root       46: /* True if a #pragma interrupt has been seen for the current function.  */
                     47: int pragma_interrupt;
                     48: 
                     49: /* True if a #pragma saveall has been seen for the current function.  */
                     50: int pragma_saveall;
                     51: 
1.1.1.2   root       52: static char *names_big[] =
                     53: {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7"};
                     54: 
                     55: static char *names_extended[] =
                     56: {"er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"};
                     57: 
                     58: static char *names_upper_extended[] =
                     59: {"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"};
                     60: 
                     61: /* Points to one of the above.  */
                     62: /* ??? The above could be put in an array indexed by CPU_TYPE.  */
                     63: char **h8_reg_names;
                     64: 
                     65: /* Various operations needed by the following, indexed by CPU_TYPE.  */
                     66: /* ??? The h8/300 assembler doesn't understand pop.w (yet).  */
                     67: 
                     68: static char *h8_push_ops[2] =
                     69: {"push", "push.l"};
                     70: static char *h8_pop_ops[2] =
                     71: {"pop", "pop.l"};
                     72: static char *h8_mov_ops[2] =
                     73: {"mov.w", "mov.l"};
                     74: 
                     75: char *h8_push_op, *h8_pop_op, *h8_mov_op;
                     76: 
                     77: /* Initialize various cpu specific globals at start up.  */
                     78: 
                     79: void
                     80: h8300_init_once ()
                     81: {
                     82:   if (TARGET_H8300)
                     83:     {
                     84:       cpu_type = (int) CPU_H8300;
                     85:       h8_reg_names = names_big;
                     86:     }
                     87:   else
                     88:     {
                     89:       cpu_type = (int) CPU_H8300H;
                     90:       h8_reg_names = names_extended;
                     91:     }
                     92:   h8_push_op = h8_push_ops[cpu_type];
                     93:   h8_pop_op = h8_pop_ops[cpu_type];
                     94:   h8_mov_op = h8_mov_ops[cpu_type];
                     95: }
1.1       root       96: 
                     97: char *
                     98: byte_reg (x, b)
                     99:      rtx x;
                    100:      int b;
                    101: {
1.1.1.2   root      102:   static char *names_small[] =
                    103:   {"r0l", "r0h", "r1l", "r1h", "r2l", "r2h", "r3l", "r3h",
                    104:    "r4l", "r4h", "r5l", "r5h", "r6l", "r6h", "r7lBAD", "r7hBAD"};
1.1       root      105: 
                    106:   return names_small[REGNO (x) * 2 + b];
                    107: }
                    108: 
                    109: /* REGNO must be saved/restored across calls if this macro is true.  */
1.1.1.2   root      110: 
                    111: #define WORD_REG_USED(regno)                                   \
                    112:   (regno < 7 &&                                                        \
                    113:    (pragma_interrupt                                           \
                    114:     || pragma_saveall                                          \
                    115:     || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])        \
                    116:     || (regs_ever_live[regno] & !call_used_regs[regno])))
1.1       root      117: 
                    118: /* Output assembly language to FILE for the operation OP with operand size
1.1.1.2   root      119:    SIZE to adjust the stack pointer.  */
                    120: /* ??? FPED is currently unused.  */
                    121: 
1.1       root      122: static void
                    123: dosize (file, op, size, fped)
                    124:      FILE *file;
                    125:      char *op;
                    126:      unsigned int size;
                    127:      int fped;
                    128: {
                    129:   switch (size)
                    130:     {
                    131:     case 4:
1.1.1.2   root      132:       /* ??? TARGET_H8300H can do this in one insn.  */
1.1       root      133:     case 3:
                    134:       fprintf (file, "\t%ss\t#%d,sp\n", op, 2);
                    135:       size -= 2;
                    136:       /* Fall through...  */
                    137:     case 2:
                    138:     case 1:
                    139:       fprintf (file, "\t%ss\t#%d,sp\n", op, size);
                    140:       size = 0;
                    141:       break;
                    142:     case 0:
                    143:       break;
                    144:     default:
1.1.1.2   root      145:       if (TARGET_H8300)
                    146:        fprintf (file, "\tmov.w\t#%d,r3\n\t%s.w\tr3,sp\n", size, op);
                    147:       else
                    148:        fprintf (file, "\t%s\t#%d,sp\n", op, size);
1.1       root      149:       size = 0;
                    150:       break;
                    151:     }
                    152: }
                    153: 
                    154: /* Output assembly language code for the function prologue.  */
1.1.1.2   root      155: static int push_order[FIRST_PSEUDO_REGISTER] =
                    156: {6, 5, 4, 3, 2, 1, 0, -1, -1};
                    157: static int pop_order[FIRST_PSEUDO_REGISTER] =
                    158: {0, 1, 2, 3, 4, 5, 6, -1, -1};
1.1       root      159: 
                    160: /* This is what the stack looks like after the prolog of 
                    161:    a function with a frame has been set up:
                    162: 
1.1.1.2   root      163:    <args>
                    164:    PC
                    165:    FP                  <- fp
                    166:    <locals>
                    167:    <saved registers>   <- sp
1.1       root      168: 
                    169:    This is what the stack looks like after the prolog of
                    170:    a function which doesn't have a frame:
                    171: 
1.1.1.2   root      172:    <args>
                    173:    PC
                    174:    <locals>
                    175:    <saved registers>           <- sp
1.1       root      176: */
                    177: 
1.1.1.2   root      178: int current_function_anonymous_args;
                    179: 
                    180: /* Extra arguments to pop, in words (IE: 2 bytes for 300, 4 for 300h */
                    181: static int extra_pop;
                    182: 
1.1       root      183: void
                    184: function_prologue (file, size)
                    185:      FILE *file;
                    186:      int size;
                    187: {
                    188:   register int mask = 0;
1.1.1.2   root      189:   int fsize = (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
1.1       root      190:   int idx;
1.1.1.2   root      191:   extra_pop = 0;
                    192: 
                    193:   if (current_function_anonymous_args && TARGET_QUICKCALL)
                    194:     {
                    195:       /* Push regs as if done by caller, and move around return address.  */
                    196: 
                    197:       switch (current_function_args_info.nbytes / UNITS_PER_WORD)
                    198:        {
                    199:        case 0:
                    200:          /* get ret addr */
                    201:          fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
                    202:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
                    203:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[1]);
                    204:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[0]);
                    205:          /* push it again */
                    206:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
                    207:          extra_pop = 3;
                    208:          break;
                    209:        case 1:
                    210:          /* get ret addr */
                    211:          fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
                    212:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
                    213:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[1]);
                    214:          /* push it again */
                    215:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
                    216:          extra_pop = 2;
                    217:          break;
                    218:        case 2:
                    219:          /* get ret addr */
                    220:          fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
                    221:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[2]);
                    222:          /* push it again */
                    223:          fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[3]);
                    224:          extra_pop = 1;
                    225:          break;
                    226:        default:
                    227:          fprintf (file, "; varargs\n");
                    228:          break;
                    229:        }
                    230:     }
1.1       root      231: 
                    232:   if (frame_pointer_needed)
                    233:     {
1.1.1.2   root      234:       /* Push fp */
                    235:       fprintf (file, "\t%s\t%s\n", h8_push_op,
                    236:               h8_reg_names[FRAME_POINTER_REGNUM]);
                    237:       fprintf (file, "\t%s\t%s,%s\n", h8_mov_op,
                    238:               h8_reg_names[STACK_POINTER_REGNUM],
                    239:               h8_reg_names[FRAME_POINTER_REGNUM]);
1.1       root      240: 
1.1.1.2   root      241:       /* leave room for locals */
1.1       root      242:       dosize (file, "sub", fsize, 1);
                    243: 
1.1.1.2   root      244:       /* Push the rest of the registers */
                    245:       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
1.1       root      246:        {
                    247:          int regno = push_order[idx];
                    248: 
1.1.1.2   root      249:          if (regno >= 0 && WORD_REG_USED (regno) && regno != FRAME_POINTER_REGNUM)
                    250:            fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]);
1.1       root      251:        }
                    252:     }
                    253:   else
                    254:     {
                    255:       dosize (file, "sub", fsize, 0);
                    256:       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
                    257:        {
                    258:          int regno = push_order[idx];
                    259: 
1.1.1.2   root      260:          if (regno >= 0 && WORD_REG_USED (regno))
                    261:            fprintf (file, "\t%s\t%s\n", h8_push_op, h8_reg_names[regno]);
1.1       root      262:        }
                    263:     }
                    264: }
                    265: 
                    266: /* Output assembly language code for the function epilogue.  */
                    267: 
                    268: void
                    269: function_epilogue (file, size)
                    270:      FILE *file;
                    271:      int size;
                    272: {
                    273:   register int regno;
                    274:   register int mask = 0;
1.1.1.2   root      275:   int fsize = (size + STACK_BOUNDARY / 8 - 1) & -STACK_BOUNDARY / 8;
1.1       root      276:   int nregs;
                    277:   int offset;
                    278:   int idx;
                    279:   rtx insn = get_last_insn ();
                    280: 
                    281:   /* If the last insn was a BARRIER, we don't have to write any code.  */
                    282:   if (GET_CODE (insn) == NOTE)
                    283:     insn = prev_nonnote_insn (insn);
                    284:   if (insn && GET_CODE (insn) == BARRIER)
                    285:     return;
                    286: 
                    287:   nregs = 0;
                    288: 
                    289:   if (frame_pointer_needed)
                    290:     {
1.1.1.2   root      291:       /* Pop saved registers */
1.1       root      292:       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
                    293:        {
                    294:          regno = pop_order[idx];
1.1.1.2   root      295:          if (regno >= 0 && regno != FRAME_POINTER_REGNUM && WORD_REG_USED (regno))
                    296:            fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]);
1.1       root      297:        }
1.1.1.2   root      298:       /* deallocate locals */
1.1       root      299:       dosize (file, "add", fsize, 1);
1.1.1.2   root      300:       /* pop frame pointer */
                    301:       fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[FRAME_POINTER_REGNUM]);
1.1       root      302:     }
                    303:   else
                    304:     {
1.1.1.2   root      305:       /* pop saved registers */
1.1       root      306:       for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
                    307:        {
                    308:          regno = pop_order[idx];
1.1.1.2   root      309:          if (regno >= 0 && WORD_REG_USED (regno))
                    310:            fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[regno]);
1.1       root      311:        }
1.1.1.2   root      312:       /* deallocate locals */
1.1       root      313:       dosize (file, "add", fsize, 0);
                    314:     }
1.1.1.2   root      315: 
                    316:   if (extra_pop)
                    317:     {
                    318:       fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[3]);
                    319:       while (extra_pop)
                    320:        {
                    321:          fprintf (file, "\t%s\t%s\n", h8_pop_op, h8_reg_names[2]);
                    322:          extra_pop--;
                    323:        }
                    324:       fprintf (file, "\tjmp    @%s\n", h8_reg_names[3]);
                    325:     }
1.1       root      326:   else
1.1.1.2   root      327:     {
                    328:       if (pragma_interrupt)
                    329:        fprintf (file, "\trte\n");
                    330:       else
                    331:        fprintf (file, "\trts\n");
                    332:     }
1.1       root      333: 
                    334:   pragma_interrupt = 0;
                    335:   pragma_saveall = 0;
1.1.1.2   root      336: 
                    337:   current_function_anonymous_args = 0;
                    338: }
                    339: 
                    340: /* Output assembly code for the start of the file.  */
                    341: 
                    342: asm_file_start (file)
                    343:      FILE *file;
                    344: {
                    345:   fprintf (file, ";\tGCC For the Hitachi H8/300\n");
                    346:   fprintf (file, ";\tBy Hitachi America Ltd and Cygnus Support\n");
                    347:   fprintf (file, ";\trelease F-1\n");
                    348:   if (optimize)
                    349:     fprintf (file, "; -O%d\n", optimize);
                    350:   if (TARGET_H8300H)
                    351:     fprintf (file, "\n\t.h8300h\n");
                    352:   else
                    353:     fprintf (file, "\n\n");
                    354:   output_file_directive (file, main_input_filename);
                    355: }
                    356: 
                    357: /* Output assembly language code for the end of file.  */
                    358: 
                    359: void
                    360: asm_file_end (file)
                    361:      FILE *file;
                    362: {
                    363:   fprintf (file, "\t.end\n");
1.1       root      364: }
                    365: 
1.1.1.2   root      366: /* Return true if VALUE is a valid constant for constraint 'P'.
                    367:    IE: VALUE is a power of two <= 2**15.  */
1.1       root      368: 
                    369: int
1.1.1.2   root      370: small_power_of_two (value)
                    371:      int value;
1.1       root      372: {
                    373:   switch (value)
                    374:     {
                    375:     case 1:
                    376:     case 2:
                    377:     case 4:
                    378:     case 8:
                    379:     case 16:
                    380:     case 32:
                    381:     case 64:
                    382:     case 128:
                    383:     case 256:
                    384:     case 512:
                    385:     case 1024:
                    386:     case 2048:
                    387:     case 4096:
                    388:     case 8192:
                    389:     case 16384:
                    390:     case 32768:
                    391:       return 1;
                    392:     }
                    393:   return 0;
                    394: }
                    395: 
1.1.1.2   root      396: /* Return true if VALUE is a valid constant for constraint 'O', which
                    397:    means that the constant would be ok to use as a bit for a bclr
                    398:    instruction.  */
                    399: 
                    400: int
                    401: ok_for_bclr (value)
                    402:      int value;
                    403: {
                    404:   return small_power_of_two ((~value) & 0xff);
                    405: }
                    406: 
1.1       root      407: /* Return true is OP is a valid source operand for an integer move
                    408:    instruction.  */
1.1.1.2   root      409: 
1.1       root      410: int
                    411: general_operand_src (op, mode)
                    412:      rtx op;
                    413:      enum machine_mode mode;
                    414: {
1.1.1.2   root      415:   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
                    416:     return 1;
1.1       root      417:   return general_operand (op, mode);
                    418: }
                    419: 
                    420: /* Return true if OP is a valid destination operand for an integer move
                    421:    instruction.  */
1.1.1.2   root      422: 
1.1       root      423: int
                    424: general_operand_dst (op, mode)
                    425:      rtx op;
                    426:      enum machine_mode mode;
                    427: {
1.1.1.2   root      428:   if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == PRE_DEC)
                    429:     return 1;
1.1       root      430:   return general_operand (op, mode);
                    431: }
1.1.1.2   root      432: 
                    433: /* Return true if OP is a const valid for a bit clear instruction.  */
                    434: 
                    435: int
                    436: o_operand (operand, mode)
                    437:      rtx operand;
                    438:      enum machine_mode mode;
                    439: {
                    440:   return (GET_CODE (operand) == CONST_INT
                    441:          && CONST_OK_FOR_O (INTVAL (operand)));
                    442: }
                    443: 
                    444: /* Return true if OP is a const valid for a bit set or bit xor instruction.  */
                    445: 
                    446: int
                    447: p_operand (operand, mode)
                    448:      rtx operand;
                    449:      enum machine_mode mode;
                    450: {
                    451:   return (GET_CODE (operand) == CONST_INT
                    452:          && CONST_OK_FOR_P (INTVAL (operand)));
                    453: }
                    454: 
                    455: /* Return true if OP is a valid call operand.  */
                    456: 
                    457: int
                    458: call_insn_operand (op, mode)
                    459:      rtx op;
                    460:      enum machine_mode mode;
                    461: {
                    462:   if (GET_CODE (op) == MEM)
                    463:     {
                    464:       rtx inside = XEXP (op, 0);
                    465:       if (register_operand (inside, Pmode))
                    466:        return 1;
                    467:       if (CONSTANT_ADDRESS_P (inside))
                    468:        return 1;
                    469:     }
                    470:   return 0;
                    471: }
                    472: 
                    473: /* Return true if OP is a valid jump operand.  */
                    474: 
                    475: int
                    476: jump_address_operand (op, mode)
                    477:      rtx op;
                    478:      enum machine_mode mode;
                    479: {
                    480:   if (GET_CODE (op) == REG)
                    481:     return mode == Pmode;
                    482: 
                    483:   if (GET_CODE (op) == MEM)
                    484:     {
                    485:       rtx inside = XEXP (op, 0);
                    486:       if (register_operand (inside, Pmode))
                    487:        return 1;
                    488:       if (CONSTANT_ADDRESS_P (inside))
                    489:        return 1;
                    490:     }
                    491:   return 0;
                    492: }
                    493: 
                    494: /* Recognize valid operands for bitfield instructions.  */
                    495: 
                    496: extern int rtx_equal_function_value_matters;
                    497: 
                    498: int
                    499: bit_operand (op, mode)
                    500:      rtx op;
                    501:      enum machine_mode mode;
                    502: {
                    503:   /* We can except any general operand, expept that MEM operands must
                    504:      be limited to those that use addresses valid for the 'U' constraint.  */
                    505:   if (!general_operand (op, mode))
                    506:     return 0;
                    507: 
                    508:   /* Accept any mem during RTL generation.  Otherwise, the code that does
                    509:      insv and extzv will think that we can not handle memory.  However,
                    510:      to avoid reload problems, we only accept 'U' MEM operands after RTL
                    511:      generation.  This means that any named pattern which uses this predicate
                    512:      must force its operands to match 'U' before emitting RTL.  */
                    513: 
                    514:   if (GET_CODE (op) == REG)
                    515:     return 1;
                    516:   if (GET_CODE (op) == SUBREG)
                    517:     return 1;
                    518:   if (!rtx_equal_function_value_matters)
                    519:     {
                    520:       /* We're building rtl */
                    521:       return GET_CODE (op) == MEM;
                    522:     }
                    523:   else
                    524:     {
                    525:       return (GET_CODE (op) == MEM
                    526:              && EXTRA_CONSTRAINT (op, 'U'));
                    527:     }
                    528: }
                    529: 
                    530: /* Recognize valid operators for bit test.  */
                    531: 
                    532: int
                    533: eq_operator (x, mode)
                    534:      rtx x;
                    535:      enum machine_mode mode;
                    536: {
                    537:   return (GET_CODE (x) == EQ || GET_CODE (x) == NE);
                    538: }
                    539: 
1.1       root      540: /* Handle machine specific pragmas for compatibility with existing
1.1.1.2   root      541:    compilers for the H8/300.
1.1       root      542: 
                    543:    pragma saveall generates prolog/epilog code which saves and
                    544:    restores all the registers on function entry.
1.1.1.2   root      545: 
1.1       root      546:    pragma interrupt saves and restores all registers, and exits with
                    547:    an rte instruction rather than an rts.  A pointer to a function
                    548:    with this attribute may be safely used in an interrupt vector.  */
1.1.1.2   root      549: 
1.1       root      550: int
                    551: handle_pragma (file)
                    552:      FILE *file;
                    553: {
                    554:   int c;
                    555:   char pbuf[20];
1.1.1.2   root      556:   int psize = 0;
1.1       root      557: 
                    558:   c = getc (file);
                    559:   while (c == ' ' || c == '\t')
                    560:     c = getc (file);
                    561: 
                    562:   if (c == '\n' || c == EOF)
                    563:     return c;
                    564: 
1.1.1.2   root      565:   /* The only pragmas we understand are interrupt and saveall.  */
                    566:   while (psize < sizeof (pbuf) - 1
                    567:         && isalpha (c))
1.1       root      568:     {
1.1.1.2   root      569:       pbuf[psize++] = c;
1.1       root      570:       c = getc (file);
                    571:     }
                    572:   pbuf[psize] = 0;
                    573: 
                    574:   if (strcmp (pbuf, "interrupt") == 0)
                    575:     pragma_interrupt = 1;
                    576: 
                    577:   if (strcmp (pbuf, "saveall") == 0)
                    578:     pragma_saveall = 1;
                    579: 
1.1.1.3 ! root      580:   /* ??? This is deprecated.  Delete for gcc 2.8.  */
1.1.1.2   root      581:   if (strcmp (pbuf, "section") == 0)
                    582:     {
1.1.1.3 ! root      583:       static int printed_p = 0;
        !           584:       if (!printed_p)
        !           585:        {
        !           586:          warning ("#pragma section is deprecated, use section attributes");
        !           587:          printed_p = 1;
        !           588:        }
1.1.1.2   root      589:       while (c && !isalpha (c))
                    590:        c = getc (file);
                    591:       psize = 0;
                    592:       while (psize < sizeof (pbuf) - 1
                    593:             && isalpha (c) || isdigit (c) || c == '_')
                    594:        {
                    595:          pbuf[psize++] = c;
                    596:          c = getc (file);
                    597:        }
                    598:       pbuf[psize] = 0;
1.1.1.3 ! root      599:       named_section (NULL_TREE, pbuf);
1.1.1.2   root      600:     }
                    601:   ungetc (c, file);
1.1       root      602:   return c;
                    603: }
                    604: 
                    605: /* If the next arg with MODE and TYPE is to be passed in a register, return
                    606:    the rtx to represent where it is passed.  CUM represents the state after
                    607:    the last argument.  NAMED is not used.  */
                    608: 
1.1.1.2   root      609: static char *hand_list[] =
                    610: {
                    611:   "__main",
                    612:   "__cmpsi2",
                    613:   "__divhi3",
                    614:   "__modhi3",
                    615:   "__udivhi3",
                    616:   "__umodhi3",
                    617:   "__divsi3",
                    618:   "__modsi3",
                    619:   "__udivsi3",
                    620:   "__umodsi3",
                    621:   "__mulhi3",
                    622:   "__mulsi3",
                    623:   "__reg_memcpy",
                    624:   "__reg_memset",
                    625:   "__ucmpsi2",
                    626:   0,
                    627: };
                    628: 
                    629: /* Return an RTX to represent where a value with mode MODE will be returned
                    630:    from a function.  If the result is 0, the argument is pushed.  */
                    631: 
1.1       root      632: rtx
                    633: function_arg (cum, mode, type, named)
                    634:      CUMULATIVE_ARGS *cum;
                    635:      enum machine_mode mode;
                    636:      tree type;
                    637:      int named;
                    638: {
                    639:   rtx result = 0;
1.1.1.2   root      640:   char *fname;
                    641:   int regpass = 0;
                    642: 
                    643:   /* Pass 3 regs worth of data in regs when user asked on the command line.  */
                    644:   if (TARGET_QUICKCALL)
                    645:     regpass = 3;
                    646: 
                    647:   /* If calling hand written assembler, use 4 regs of args.  */
                    648: 
                    649:   if (cum->libcall)
                    650:     {
                    651:       char **p;
                    652: 
                    653:       fname = XSTR (cum->libcall, 0);
                    654: 
                    655:       /* See if this libcall is one of the hand coded ones.  */
1.1       root      656: 
1.1.1.2   root      657:       for (p = hand_list; *p && strcmp (*p, fname) != 0; p++)
                    658:        ;
1.1       root      659: 
1.1.1.2   root      660:       if (*p)
                    661:        regpass = 4;
                    662:     }
                    663: 
                    664:   if (regpass)
                    665:     {
                    666:       int size;
                    667: 
                    668:       if (mode == BLKmode)
                    669:        size = int_size_in_bytes (type);
                    670:       else
                    671:        size = GET_MODE_SIZE (mode);
                    672: 
                    673:       if (size + cum->nbytes > regpass * UNITS_PER_WORD)
                    674:        {
                    675:          result = 0;
                    676:        }
                    677:       else
                    678:        {
                    679:          switch (cum->nbytes / UNITS_PER_WORD)
                    680:            {
                    681:            case 0:
                    682:              result = gen_rtx (REG, mode, 0);
                    683:              break;
                    684:            case 1:
                    685:              result = gen_rtx (REG, mode, 1);
                    686:              break;
                    687:            case 2:
                    688:              result = gen_rtx (REG, mode, 2);
                    689:              break;
                    690:            case 3:
                    691:              result = gen_rtx (REG, mode, 3);
                    692:              break;
                    693:            default:
                    694:              result = 0;
                    695:            }
                    696:        }
                    697:     }
1.1       root      698: 
1.1.1.2   root      699:   return result;
                    700: }
                    701: 
                    702: /* Return the cost of the rtx R with code CODE.  */
1.1       root      703: 
1.1.1.2   root      704: int
                    705: const_costs (r, c)
                    706:      rtx r;
                    707:      enum rtx_code c;
                    708: {
                    709:   switch (c)
1.1       root      710:     {
1.1.1.2   root      711:     case CONST_INT:
                    712:       switch (INTVAL (r))
1.1       root      713:        {
                    714:        case 0:
1.1.1.2   root      715:        case 1:
1.1       root      716:        case 2:
1.1.1.2   root      717:        case -1:
                    718:        case -2:
1.1       root      719:          return 0;
1.1.1.2   root      720:        default:
                    721:          return 1;
1.1       root      722:        }
1.1.1.2   root      723: 
                    724:     case CONST:
                    725:     case LABEL_REF:
                    726:     case SYMBOL_REF:
                    727:       return 3;
                    728: 
                    729:     case CONST_DOUBLE:
                    730:       return 20;
                    731: 
                    732:     default:
                    733:       return 4;
1.1       root      734:     }
                    735: }
1.1.1.2   root      736: 
1.1       root      737: /* Documentation for the machine specific operand escapes:
                    738: 
1.1.1.2   root      739:    'A' print rn in h8/300 mode, erN in H8/300H mode
1.1       root      740:    'C' print (operand - 2).
1.1.1.2   root      741:    'E' like s but negative.
                    742:    'F' like t but negative.
                    743:    'G' constant just the negative
1.1       root      744:    'L' fake label, changed after used twice.
                    745:    'M' turn a 'M' constant into its negative mod 2.
1.1.1.2   root      746:    'P' if operand is incing/decing sp, print .w, otherwise .b.
                    747:    'S' print operand as a long word
1.1       root      748:    'T' print operand as a word
1.1.1.2   root      749:    'U' if operand is incing/decing sp, print l, otherwise nothing.
                    750:    'V' find the set bit, and print its number.
                    751:    'W' find the clear bit, and print its number.
                    752:    'X' print operand as a byte
1.1       root      753:    'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8.
1.1.1.2   root      754:    'Z' print int & 7.
                    755:    'b' print the bit opcode
                    756:    'c' print the ibit opcode
                    757:    'd' bcc if EQ, bcs if NE
                    758:    'e' first word of 32 bit value - if reg, then least reg. if mem
                    759:        then least. if const then most sig word
                    760:    'f' second word of 32 bit value - if reg, then biggest reg. if mem
                    761:        then +2. if const then least sig word
                    762:    'g' bcs if EQ, bcc if NE
1.1       root      763:    'j' print operand as condition code.
                    764:    'k' print operand as reverse condition code.
1.1.1.2   root      765:    's' print as low byte of 16 bit value
                    766:    't' print as high byte of 16 bit value
                    767:    'w' print as low byte of 32 bit value
                    768:    'x' print as 2nd byte of 32 bit value
                    769:    'y' print as 3rd byte of 32 bit value
                    770:    'z' print as msb of 32 bit value
                    771: */
1.1       root      772: 
                    773: /* Return assembly language string which identifies a comparison type.  */
                    774: 
1.1.1.2   root      775: static char *
1.1       root      776: cond_string (code)
                    777:      enum rtx_code code;
                    778: {
                    779:   switch (code)
                    780:     {
                    781:     case NE:
1.1.1.2   root      782:       if (cc_prev_status.flags & CC_DONE_CBIT)
                    783:        return "cs";
1.1       root      784:       return "ne";
                    785:     case EQ:
1.1.1.2   root      786:       if (cc_prev_status.flags & CC_DONE_CBIT)
                    787:        return "cc";
1.1       root      788:       return "eq";
                    789:     case GE:
                    790:       return "ge";
                    791:     case GT:
                    792:       return "gt";
                    793:     case LE:
                    794:       return "le";
                    795:     case LT:
                    796:       return "lt";
                    797:     case GEU:
                    798:       return "hs";
                    799:     case GTU:
                    800:       return "hi";
                    801:     case LEU:
                    802:       return "ls";
                    803:     case LTU:
                    804:       return "lo";
                    805:     default:
                    806:       abort ();
                    807:     }
                    808: }
                    809: 
                    810: /* Print operand X using operand code CODE to assembly language output file
                    811:    FILE.  */
                    812: 
                    813: void
                    814: print_operand (file, x, code)
                    815:      FILE *file;
                    816:      rtx x;
                    817:      int code;
                    818: {
                    819:   /* This is used to general unique labels for the 'L' code.  */
                    820:   static int lab = 1000;
                    821: 
                    822:   /* This is used for communication between the 'P' and 'U' codes.  */
                    823:   static char *last_p;
                    824: 
                    825:   /* This is used for communication between the 'Z' and 'Y' codes.  */
1.1.1.2   root      826:   /* ??? 'V' and 'W' use it too.  */
1.1       root      827:   static int bitint;
                    828: 
                    829:   switch (code)
                    830:     {
1.1.1.2   root      831:     case 'A':
1.1       root      832:       if (GET_CODE (x) == REG)
1.1.1.2   root      833:        fprintf (file, "%s", h8_reg_names[REGNO (x)]);
1.1       root      834:       else
                    835:        goto def;
                    836:       break;
1.1.1.2   root      837:     case 'C':
                    838:       fprintf (file, "#%d", INTVAL (x) - 2);
                    839:       break;
                    840:     case 'E':
                    841:       switch (GET_CODE (x))
                    842:        {
                    843:        case REG:
                    844:          fprintf (file, "%sl", names_big[REGNO (x)]);
                    845:          break;
                    846:        case CONST_INT:
                    847:          fprintf (file, "#%d", (-INTVAL (x)) & 0xff);
                    848:          break;
                    849:        default:
                    850:          abort ();
                    851:        }
                    852:       break;
                    853:     case 'F':
                    854:       switch (GET_CODE (x))
                    855:        {
                    856:        case REG:
                    857:          fprintf (file, "%sh", names_big[REGNO (x)]);
                    858:          break;
                    859:        case CONST_INT:
                    860:          fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8);
                    861:          break;
                    862:        default:
                    863:          abort ();
                    864:        }
                    865:       break;
1.1       root      866:     case 'G':
                    867:       if (GET_CODE (x) != CONST_INT)
                    868:        abort ();
                    869:       fprintf (file, "#%d", 0xff & (-INTVAL (x)));
                    870:       break;
1.1.1.2   root      871:     case 'L':
                    872:       /* 'L' must always be used twice in a single pattern.  It generates
1.1.1.3 ! root      873:         the same label twice, and then will generate a unique label the
1.1.1.2   root      874:         next time it is used.  */
                    875:       asm_fprintf (file, "tl%d", (lab++) / 2);
1.1       root      876:       break;
1.1.1.2   root      877:     case 'M':
                    878:       /* For 3/-3 and 4/-4, the other 2 is handled separately.  */
                    879:       switch (INTVAL (x))
                    880:        {
                    881:        case 2:
                    882:        case 4:
                    883:        case -2:
                    884:        case -4:
                    885:          fprintf (file, "#2");
                    886:          break;
                    887:        case 1:
                    888:        case 3:
                    889:        case -1:
                    890:        case -3:
                    891:          fprintf (file, "#1");
                    892:          break;
                    893:        default:
                    894:          abort ();
                    895:        }
1.1       root      896:       break;
1.1.1.2   root      897:     case 'P':
                    898:       if (REGNO (XEXP (XEXP (x, 0), 0)) == STACK_POINTER_REGNUM)
                    899:        {
                    900:          last_p = "";
                    901:          fprintf (file, ".w");
                    902:        }
1.1       root      903:       else
1.1.1.2   root      904:        {
                    905:          last_p = "l";
                    906:          fprintf (file, ".b");
                    907:        }
1.1       root      908:       break;
1.1.1.2   root      909:     case 'S':
                    910:       if (GET_CODE (x) == REG)
                    911:        fprintf (file, "%s", names_extended[REGNO (x)]);
1.1       root      912:       else
1.1.1.2   root      913:        goto def;
1.1       root      914:       break;
1.1.1.2   root      915:     case 'T':
                    916:       if (GET_CODE (x) == REG)
                    917:        fprintf (file, "%s", names_big[REGNO (x)]);
1.1       root      918:       else
1.1.1.2   root      919:        goto def;
1.1       root      920:       break;
1.1.1.2   root      921:     case 'U':
                    922:       fprintf (file, "%s%s", names_big[REGNO (x)], last_p);
1.1       root      923:       break;
1.1.1.2   root      924:     case 'V':
                    925:       bitint = exact_log2 (INTVAL (x));
                    926:       if (bitint == -1)
1.1       root      927:        abort ();
                    928:       fprintf (file, "#%d", bitint & 7);
                    929:       break;
1.1.1.2   root      930:     case 'W':
1.1       root      931:       bitint = exact_log2 ((~INTVAL (x)) & 0xff);
                    932:       if (bitint == -1)
                    933:        abort ();
                    934:       fprintf (file, "#%d", bitint & 7);
                    935:       break;
1.1.1.2   root      936:     case 'X':
                    937:       if (GET_CODE (x) == REG)
                    938:        fprintf (file, "%s", byte_reg (x, 0));
                    939:       else
                    940:        goto def;
                    941:       break;
                    942:     case 'Y':
1.1       root      943:       if (bitint == -1)
                    944:        abort ();
1.1.1.2   root      945:       if (GET_CODE (x) == REG)
                    946:        fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l');
                    947:       else
                    948:        print_operand (file, x, 0);
                    949:       bitint = -1;
                    950:       break;
                    951:     case 'Z':
                    952:       bitint = INTVAL (x);
1.1       root      953:       fprintf (file, "#%d", bitint & 7);
                    954:       break;
1.1.1.2   root      955:     case 'b':
                    956:       switch (GET_CODE (x))
1.1       root      957:        {
1.1.1.2   root      958:        case IOR:
                    959:          fprintf (file, "bor");
                    960:          break;
                    961:        case XOR:
                    962:          fprintf (file, "bxor");
                    963:          break;
                    964:        case AND:
                    965:          fprintf (file, "band");
                    966:          break;
1.1       root      967:        }
1.1.1.2   root      968:       break;
                    969:     case 'c':
                    970:       switch (GET_CODE (x))
1.1       root      971:        {
1.1.1.2   root      972:        case IOR:
                    973:          fprintf (file, "bior");
                    974:          break;
                    975:        case XOR:
                    976:          fprintf (file, "bixor");
                    977:          break;
                    978:        case AND:
                    979:          fprintf (file, "biand");
                    980:          break;
1.1       root      981:        }
                    982:       break;
1.1.1.2   root      983:     case 'd':
                    984:       switch (GET_CODE (x))
1.1       root      985:        {
1.1.1.2   root      986:        case EQ:
                    987:          fprintf (file, "bcc");
1.1       root      988:          break;
1.1.1.2   root      989:        case NE:
                    990:          fprintf (file, "bcs");
1.1       root      991:          break;
                    992:        default:
                    993:          abort ();
                    994:        }
                    995:       break;
                    996:     case 'e':
                    997:       switch (GET_CODE (x))
                    998:        {
                    999:        case REG:
1.1.1.2   root     1000:          if (TARGET_H8300)
                   1001:            fprintf (file, "%s", names_big[REGNO (x)]);
                   1002:          else
                   1003:            fprintf (file, "%s", names_upper_extended[REGNO (x)]);
1.1       root     1004:          break;
                   1005:        case MEM:
                   1006:          x = adj_offsettable_operand (x, 0);
                   1007:          print_operand (file, x, 0);
                   1008:          break;
                   1009:        case CONST_INT:
                   1010:          fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff));
                   1011:          break;
                   1012:        default:
                   1013:          abort ();
                   1014:          break;
                   1015:        }
                   1016:       break;
                   1017:     case 'f':
                   1018:       switch (GET_CODE (x))
                   1019:        {
                   1020:        case REG:
1.1.1.2   root     1021:          if (TARGET_H8300)
                   1022:            fprintf (file, "%s", names_big[REGNO (x) + 1]);
                   1023:          else
                   1024:            fprintf (file, "%s", names_big[REGNO (x)]);
1.1       root     1025:          break;
                   1026:        case MEM:
                   1027:          x = adj_offsettable_operand (x, 2);
                   1028:          print_operand (file, x, 0);
                   1029:          break;
                   1030:        case CONST_INT:
                   1031:          fprintf (file, "#%d", INTVAL (x) & 0xffff);
                   1032:          break;
                   1033:        default:
                   1034:          abort ();
                   1035:        }
                   1036:       break;
1.1.1.2   root     1037:     case 'g':
1.1       root     1038:       switch (GET_CODE (x))
                   1039:        {
1.1.1.2   root     1040:        case NE:
                   1041:          fprintf (file, "bcc");
1.1       root     1042:          break;
1.1.1.2   root     1043:        case EQ:
                   1044:          fprintf (file, "bcs");
1.1       root     1045:          break;
                   1046:        default:
                   1047:          abort ();
                   1048:        }
                   1049:       break;
                   1050:     case 'j':
                   1051:       asm_fprintf (file, cond_string (GET_CODE (x)));
                   1052:       break;
                   1053:     case 'k':
                   1054:       asm_fprintf (file, cond_string (reverse_condition (GET_CODE (x))));
                   1055:       break;
1.1.1.2   root     1056:     case 's':
                   1057:       if (GET_CODE (x) == CONST_INT)
                   1058:        fprintf (file, "#%d", (INTVAL (x)) & 0xff);
                   1059:       else
                   1060:        fprintf (file, "%s", byte_reg (x, 0));
                   1061:       break;
                   1062:     case 't':
                   1063:       if (GET_CODE (x) == CONST_INT)
                   1064:        fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
                   1065:       else
                   1066:        fprintf (file, "%s", byte_reg (x, 1));
                   1067:       break;
                   1068:     case 'u':
                   1069:       if (GET_CODE (x) != CONST_INT)
                   1070:        abort ();
                   1071:       fprintf (file, "%d", INTVAL (x));
                   1072:       break;
                   1073:     case 'w':
                   1074:       if (GET_CODE (x) == CONST_INT)
                   1075:        fprintf (file, "#%d", INTVAL (x) & 0xff);
                   1076:       else
                   1077:        fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 2 : 0));
                   1078:       break;
                   1079:     case 'x':
                   1080:       if (GET_CODE (x) == CONST_INT)
                   1081:        fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff);
                   1082:       else
                   1083:        fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 3 : 1));
                   1084:       break;
                   1085:     case 'y':
                   1086:       if (GET_CODE (x) == CONST_INT)
                   1087:        fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff);
                   1088:       else
                   1089:        fprintf (file, "%s", byte_reg (x, 0));
                   1090:       break;
                   1091:     case 'z':
                   1092:       if (GET_CODE (x) == CONST_INT)
                   1093:        fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff);
                   1094:       else
                   1095:        fprintf (file, "%s", byte_reg (x, 1));
                   1096:       break;
                   1097: 
1.1       root     1098:     default:
1.1.1.2   root     1099:     def:
1.1       root     1100:       switch (GET_CODE (x))
                   1101:        {
                   1102:        case REG:
1.1.1.2   root     1103:          switch (GET_MODE (x))
                   1104:            {
                   1105:            case QImode:
                   1106: #if 0                          /* Is it asm ("mov.b %0,r2l", ...) */
                   1107:              fprintf (file, "%s", byte_reg (x, 0));
                   1108: #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
                   1109:              fprintf (file, "%s", names_big[REGNO (x)]);
                   1110: #endif
                   1111:              break;
                   1112:            case HImode:
                   1113:              fprintf (file, "%s", names_big[REGNO (x)]);
                   1114:              break;
                   1115:            case SImode:
                   1116:            case SFmode:
                   1117:              fprintf (file, "%s", names_extended[REGNO (x)]);
                   1118:              break;
                   1119:            default:
                   1120:              abort ();
                   1121:            }
1.1       root     1122:          break;
                   1123: 
                   1124:        case MEM:
                   1125:          fprintf (file, "@");
                   1126:          output_address (XEXP (x, 0));
                   1127:          break;
                   1128: 
                   1129:        case CONST_INT:
                   1130:        case SYMBOL_REF:
                   1131:        case CONST:
                   1132:        case LABEL_REF:
                   1133:          fprintf (file, "#");
                   1134:          print_operand_address (file, x);
                   1135:          break;
                   1136:        }
                   1137:     }
                   1138: }
                   1139: 
                   1140: /* Output assembly language output for the address ADDR to FILE.  */
                   1141: 
                   1142: void
                   1143: print_operand_address (file, addr)
                   1144:      FILE *file;
                   1145:      rtx addr;
                   1146: {
                   1147:   switch (GET_CODE (addr))
                   1148:     {
                   1149:     case REG:
1.1.1.2   root     1150:       fprintf (file, "%s", h8_reg_names[REGNO (addr)]);
1.1       root     1151:       break;
                   1152: 
                   1153:     case PRE_DEC:
1.1.1.2   root     1154:       fprintf (file, "-%s", h8_reg_names[REGNO (XEXP (addr, 0))]);
1.1       root     1155:       break;
                   1156: 
                   1157:     case POST_INC:
1.1.1.2   root     1158:       fprintf (file, "%s+", h8_reg_names[REGNO (XEXP (addr, 0))]);
1.1       root     1159:       break;
                   1160: 
                   1161:     case PLUS:
                   1162:       fprintf (file, "(");
                   1163:       if (GET_CODE (XEXP (addr, 0)) == REG)
                   1164:        {
                   1165:          /* reg,foo */
                   1166:          print_operand_address (file, XEXP (addr, 1));
                   1167:          fprintf (file, ",");
                   1168:          print_operand_address (file, XEXP (addr, 0));
                   1169:        }
                   1170:       else
                   1171:        {
                   1172:          /* foo+k */
                   1173:          print_operand_address (file, XEXP (addr, 0));
                   1174:          fprintf (file, "+");
                   1175:          print_operand_address (file, XEXP (addr, 1));
                   1176:        }
                   1177:       fprintf (file, ")");
                   1178:       break;
                   1179: 
                   1180:     case CONST_INT:
1.1.1.2   root     1181:       {
                   1182:        /* Since the h8/300 only has 16 bit pointers, negative values are also
                   1183:           those >= 32768.  This happens for example with pointer minus a
                   1184:           constant.  We don't want to turn (char *p - 2) into
                   1185:           (char *p + 65534) because loop unrolling can build upon this
                   1186:           (IE: char *p + 131068).  */
                   1187:        int n = INTVAL (addr);
                   1188:        if (TARGET_H8300)
                   1189:          n = (int) (short) n;
                   1190:        if (n < 0)
                   1191:          /* ??? Why the special case for -ve values? */
                   1192:          fprintf (file, "-%d", -n);
                   1193:        else
                   1194:          fprintf (file, "%d", n);
                   1195:        break;
                   1196:       }
1.1       root     1197: 
                   1198:     default:
                   1199:       output_addr_const (file, addr);
                   1200:       break;
                   1201:     }
                   1202: }
                   1203: 
                   1204: /* Output all insn addresses and their sizes into the assembly language
                   1205:    output file.  This is helpful for debugging whether the length attributes
                   1206:    in the md file are correct.  This is not meant to be a user selectable
                   1207:    option.  */
                   1208: 
                   1209: void
                   1210: final_prescan_insn (insn, operand, num_operands)
                   1211:      rtx insn, *operand;
                   1212:      int num_operands;
                   1213: {
                   1214:   /* This holds the last insn address.  */
                   1215:   static int last_insn_address = 0;
                   1216: 
                   1217:   int uid = INSN_UID (insn);
                   1218: 
1.1.1.2   root     1219:   if (TARGET_RTL_DUMP)
                   1220:     {
                   1221:       fprintf (asm_out_file, "\n****************");
                   1222:       print_rtl (asm_out_file, PATTERN (insn));
                   1223:       fprintf (asm_out_file, "\n");
                   1224:     }
                   1225: 
1.1       root     1226:   if (TARGET_ADDRESSES)
                   1227:     {
1.1.1.2   root     1228:       fprintf (asm_out_file, "; 0x%x %d\n", insn_addresses[uid],
1.1       root     1229:               insn_addresses[uid] - last_insn_address);
                   1230:       last_insn_address = insn_addresses[uid];
                   1231:     }
                   1232: }
                   1233: 
1.1.1.2   root     1234: /* Prepare for an SI sized move.  */
                   1235: 
                   1236: int
                   1237: do_movsi (operands)
                   1238:      rtx operands[];
                   1239: {
                   1240:   rtx src = operands[1];
                   1241:   rtx dst = operands[0];
                   1242:   if (!reload_in_progress && !reload_completed)
                   1243:     {
                   1244:       if (!register_operand (dst, GET_MODE (dst)))
                   1245:        {
                   1246:          rtx tmp = gen_reg_rtx (GET_MODE (dst));
                   1247:          emit_move_insn (tmp, src);
                   1248:          operands[1] = tmp;
                   1249:        }
                   1250:     }
                   1251:   return 0;
                   1252: }
                   1253: 
                   1254: /* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
                   1255:    Define the offset between two registers, one to be eliminated, and the other
                   1256:    its replacement, at the start of a routine.  */
                   1257: 
                   1258: int
                   1259: initial_offset (from, to)
1.1       root     1260: {
1.1.1.2   root     1261:   int offset = 0;
1.1       root     1262: 
1.1.1.2   root     1263:   if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
                   1264:     offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;
                   1265:   else
1.1       root     1266:     {
1.1.1.2   root     1267:       int regno;
                   1268: 
                   1269:       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                   1270:        if ((regs_ever_live[regno]
                   1271:             && (!call_used_regs[regno] || regno == FRAME_POINTER_REGNUM)))
                   1272:          offset += UNITS_PER_WORD;
                   1273: 
                   1274:       /* See the comments for get_frame_size.  We need to round it up to
                   1275:         STACK_BOUNDARY.  */
                   1276: 
                   1277:       offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)
                   1278:                 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));
                   1279: 
                   1280:       if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
                   1281:        offset += UNITS_PER_WORD;       /* Skip saved PC */
1.1       root     1282:     }
1.1.1.2   root     1283:   return offset;
                   1284: }
1.1       root     1285: 
1.1.1.2   root     1286: /* Update the condition code from the insn.  */
                   1287: 
                   1288: int
                   1289: notice_update_cc (body, insn)
                   1290:      rtx body;
                   1291:      rtx insn;
                   1292: {
                   1293:   switch (get_attr_cc (insn))
                   1294:     {
                   1295:     case CC_NONE:
                   1296:       /* Insn does not affect the CC at all */
                   1297:       break;
                   1298: 
                   1299:     case CC_NONE_0HIT:
                   1300:       /* Insn does not change the CC, but the 0't operand has been changed.  */
                   1301: 
                   1302:       if (cc_status.value1 != 0
                   1303:          && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
                   1304:        cc_status.value1 = 0;
                   1305: 
                   1306:       if (cc_status.value2 != 0
                   1307:          && reg_overlap_mentioned_p (recog_operand[0], cc_status.value2))
                   1308:        cc_status.value2 = 0;
                   1309: 
                   1310:       break;
                   1311: 
                   1312:     case CC_SET:
                   1313:       /* Insn sets CC to recog_operand[0], but overflow is impossible.  */
                   1314:       CC_STATUS_INIT;
                   1315:       cc_status.flags |= CC_NO_OVERFLOW;
                   1316:       cc_status.value1 = recog_operand[0];
                   1317:       break;
                   1318: 
                   1319:     case CC_COMPARE:
                   1320:       /* The insn is a compare instruction */
                   1321:       CC_STATUS_INIT;
                   1322:       cc_status.value1 = SET_SRC (body);
                   1323:       break;
                   1324: 
                   1325:     case CC_CBIT:
                   1326:       CC_STATUS_INIT;
                   1327:       cc_status.flags |= CC_DONE_CBIT;
                   1328:       cc_status.value1 = 0;
                   1329:       break;
                   1330: 
                   1331:     case CC_WHOOPS:
                   1332:     case CC_CLOBBER:
                   1333:       /* Insn clobbers CC. */
                   1334:       CC_STATUS_INIT;
                   1335:       break;
                   1336:     }
1.1       root     1337: }
                   1338: 
1.1.1.2   root     1339: /* Recognize valid operators for bit instructions */
                   1340: 
1.1       root     1341: int
1.1.1.2   root     1342: bit_operator (x, mode)
                   1343:      rtx x;
                   1344:      enum machine_mode mode;
                   1345: {
                   1346:   enum rtx_code code = GET_CODE (x);
                   1347: 
                   1348:   return (code == XOR
                   1349:          || code == AND
                   1350:          || code == IOR);
                   1351: }
                   1352: 
                   1353: /* Shifts.
                   1354: 
                   1355:    We devote a fair bit of code to getting efficient shifts since we can only
                   1356:    shift one bit at a time.  See the .md file for more comments.
                   1357: 
                   1358:    Here are some thoughts on what the absolutely positively best code is.
                   1359:    "Best" here means some rational trade-off between code size and speed,
                   1360:    where speed is more preferred but not at the expense of generating 20 insns.
                   1361: 
                   1362:    H8/300 QImode shifts
                   1363:    1-4   - do them inline
                   1364:    5-6   - ASHIFT | LSHIFTRT: rotate, mask off other bits
                   1365:            ASHIFTRT: loop
                   1366:    7     - ASHIFT | LSHIFTRT: rotate, mask off other bits
                   1367:            ASHIFTRT: shll, subx (propagate carry bit to all bits)
                   1368: 
                   1369:    H8/300 HImode shifts
                   1370:    1-4   - do them inline
                   1371:    5-6   - loop
                   1372:    7     - shift other way once, move byte into place, move carry bit into place
                   1373:    8     - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)
                   1374:    9     - inline shift 1-4, move byte, set other byte
                   1375:    13-14 - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0
                   1376:          - ASHIFTRT: loop
                   1377:    15    - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0
                   1378:          - ASHIFTRT: shll, subx, set other byte
                   1379: 
                   1380:    H8/300 SImode shifts
                   1381:    1-2   - do them inline
                   1382:    3-6   - loop
                   1383:    7     - shift other way once, move bytes into place,
                   1384:            move carry into place (possibly with sign extension)
                   1385:    8     - move bytes into place, zero or sign extend other
                   1386:    9-14  - loop
                   1387:    15    - shift other way once, move word into place, move carry into place
                   1388:    16    - move word, zero or sign extend other
                   1389:    17-23 - loop
                   1390:    24    - move bytes into place, zero or sign extend other
                   1391:    25-27 - loop
                   1392:    28-30 - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,
                   1393:                               zero others
                   1394:            ASHIFTRT: loop
                   1395:    31    - ASHIFT | LSHIFTRT: rotate top byte, mask, byte byte into place,
                   1396:                               zero others
                   1397:            ASHIFTRT: shll top byte, subx, copy to other bytes
                   1398: 
                   1399:    H8/300H QImode shifts
                   1400:    - same as H8/300
                   1401: 
                   1402:    H8/300H HImode shifts
                   1403:    - same as H8/300
                   1404: 
                   1405:    H8/300H SImode shifts
                   1406:    (These are complicated by the fact that we don't have byte level access to
                   1407:    the top word.)
                   1408:    A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)
                   1409:    1-4   - do them inline
                   1410:    5-14  - loop
                   1411:    15    - shift other way once, move word into place, move carry into place
                   1412:            (with sign extension for ASHIFTRT)
                   1413:    16    - move word into place, zero or sign extend other
                   1414:    17-23 - loop
                   1415:    24    - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,
                   1416:                    move word 0 to word 1, zero word 0
                   1417:            LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
                   1418:                      zero word 1, zero byte 1
                   1419:            ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,
                   1420:                      sign extend byte 0, sign extend word 0
                   1421:    25-27 - either loop, or
                   1422:            do 24 bit shift, inline rest
                   1423:    28-30 - ASHIFT: rotate 4/3/2, mask
                   1424:            LSHIFTRT: rotate 4/3/2, mask
                   1425:            ASHIFTRT: loop
                   1426:    31    - shll, subx byte 0, sign extend byte 0, sign extend word 0
                   1427: 
                   1428:    Don't Panic!!!
                   1429: 
                   1430:    All of these haven't been implemented.  I've just documented them and
                   1431:    provided hooks so they can be.
                   1432: */
                   1433: 
                   1434: int
                   1435: nshift_operator (x, mode)
                   1436:      rtx x;
                   1437:      enum machine_mode mode;
                   1438: {
                   1439:   switch (GET_CODE (x))
                   1440:     {
                   1441:     case ASHIFTRT:
                   1442:     case LSHIFTRT:
                   1443:     case ASHIFT:
                   1444:       return 1;
                   1445: 
                   1446:     default:
                   1447:       return 0;
                   1448:     }
                   1449: }
                   1450: 
                   1451: /* Called from the .md file to emit code to do shifts.
                   1452:    Returns a boolean indicating success
                   1453:    (currently this is always TRUE).  */
                   1454: 
                   1455: int
                   1456: expand_a_shift (mode, code, operands)
                   1457:      enum machine_mode mode;
1.1       root     1458:      int code;
                   1459:      rtx operands[];
                   1460: {
                   1461:   extern int rtx_equal_function_value_matters;
                   1462: 
                   1463:   emit_move_insn (operands[0], operands[1]);
                   1464: 
1.1.1.2   root     1465:   /* need a loop to get all the bits we want  - we generate the
                   1466:      code at emit time, but need to allocate a scratch reg now  */
1.1       root     1467: 
1.1.1.2   root     1468:   emit_insn (gen_rtx
                   1469:             (PARALLEL, VOIDmode,
                   1470:              gen_rtvec (2,
                   1471:                         gen_rtx (SET, VOIDmode, operands[0],
                   1472:                                  gen_rtx (code, mode, operands[0], operands[2])),
                   1473:                         gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));
                   1474: 
                   1475:   return 1;
                   1476: }
1.1       root     1477: 
1.1.1.2   root     1478: /* Shift algorithm determination.
1.1       root     1479: 
1.1.1.2   root     1480:    There are various ways of doing a shift:
                   1481:    SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
                   1482:                  shifts as we need.
                   1483:    SHIFT_ROT_AND: If the amount is large but close to either end, rotate the
                   1484:                   necessary bits into position and then set the rest to zero.
                   1485:    SHIFT_SPECIAL: Hand crafted assembler.
                   1486:    SHIFT_LOOP:    If the above methods fail, just loop.  */
                   1487: 
                   1488: enum shift_alg
                   1489: {
                   1490:   SHIFT_INLINE,
                   1491:   SHIFT_ROT_AND,
                   1492:   SHIFT_SPECIAL,
                   1493:   SHIFT_LOOP,
                   1494:   SHIFT_MAX
                   1495: };
                   1496: 
                   1497: /* Symbols of the various shifts which can be used as indices.  */
                   1498: 
                   1499: enum shift_type
                   1500:   {
                   1501:     SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
                   1502:   };
                   1503: 
                   1504: /* Symbols of the various modes which can be used as indices.  */
                   1505: 
                   1506: enum shift_mode
                   1507:   {
                   1508:     QIshift, HIshift, SIshift
                   1509:   };
                   1510: 
                   1511: /* For single bit shift insns, record assembler and whether the condition code
                   1512:    is valid afterwards.  */
                   1513: 
                   1514: struct shift_insn
                   1515: {
                   1516:   char *assembler;
                   1517:   int cc_valid;
                   1518: };
                   1519: 
                   1520: /* Assembler instruction shift table.
                   1521: 
                   1522:    These tables are used to look up the basic shifts.
                   1523:    They are indexed by cpu, shift_type, and mode.
                   1524: */
                   1525: 
                   1526: static const struct shift_insn shift_one[2][3][3] =
                   1527: {
                   1528: /* H8/300 */
                   1529:   {
                   1530: /* SHIFT_ASHIFT */
                   1531:     {
                   1532:       { "shal %X0", 1 },
                   1533:       { "add.w %T0,%T0\t; shal.w", 1 },
                   1534:       { "add.w %f0,%f0\t; shal.l\n\taddx %y0,%y0\n\taddx %z0,%z0\t; end shal.l", 0 }
                   1535:     },
                   1536: /* SHIFT_LSHIFTRT */
                   1537:     {
                   1538:       { "shlr %X0", 1 },
                   1539:       { "shlr %t0\t; shlr.w\n\trotxr %s0\t; end shlr.w", 0 },
                   1540:       { "shlr %z0\t; shlr.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shlr.l", 0 }
                   1541:     },
                   1542: /* SHIFT_ASHIFTRT */
                   1543:     {
                   1544:       { "shar %X0", 1 },
                   1545:       { "shar %t0\t; shar.w\n\trotxr %s0\t; end shar.w", 0 },
                   1546:       { "shar %z0\t; shar.l\n\trotxr %y0\n\trotxr %x0\n\trotxr %w0\t; end shar.l", 0 }
1.1       root     1547:     }
1.1.1.2   root     1548:   },
                   1549: /* H8/300H */
                   1550:   {
                   1551: /* SHIFT_ASHIFT */
                   1552:     {
                   1553:       { "shal.b %X0", 1 },
                   1554:       { "shal.w %T0", 1 },
                   1555:       { "shal.l %S0", 1 }
                   1556:     },
                   1557: /* SHIFT_LSHIFTRT */
1.1       root     1558:     {
1.1.1.2   root     1559:       { "shlr.b %X0", 1 },
                   1560:       { "shlr.w %T0", 1 },
                   1561:       { "shlr.l %S0", 1 }
                   1562:     },
                   1563: /* SHIFT_ASHIFTRT */
                   1564:     {
                   1565:       { "shar.b %X0", 1 },
                   1566:       { "shar.w %T0", 1 },
                   1567:       { "shar.l %S0", 1 }
                   1568:     }
                   1569:   }
                   1570: };
1.1       root     1571: 
1.1.1.2   root     1572: /* Rotates are organized by which shift they'll be used in implementing.
                   1573:    There's no need to record whether the cc is valid afterwards because
                   1574:    it is the AND insn that will decide this.  */
1.1       root     1575: 
1.1.1.2   root     1576: static const char *const rotate_one[2][3][3] =
                   1577: {
                   1578: /* H8/300 */
                   1579:   {
                   1580: /* SHIFT_ASHIFT */
                   1581:     {
                   1582:       "rotr %X0",
                   1583:       "shlr %t0\t; rotr.w\n\trotxr %s0\n\tbst #7,%t0\t; end rotr.w",
                   1584:       0
                   1585:     },
                   1586: /* SHIFT_LSHIFTRT */
                   1587:     {
                   1588:       "rotl %X0",
                   1589:       "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
                   1590:       0
                   1591:     },
                   1592: /* SHIFT_ASHIFTRT */
                   1593:     {
                   1594:       "rotl %X0",
                   1595:       "shll %s0\t; rotl.w\n\trotxl %t0\n\tbst #0,%s0\t; end rotl.w",
                   1596:       0
                   1597:     }
                   1598:   },
                   1599: /* H8/300H */
                   1600:   {
                   1601: /* SHIFT_ASHIFT */
                   1602:     {
                   1603:       "rotr.b %X0",
                   1604:       "rotr.w %T0",
                   1605:       "rotr.l %S0"
                   1606:     },
                   1607: /* SHIFT_LSHIFTRT */
                   1608:     {
                   1609:       "rotl.b %X0",
                   1610:       "rotl.w %T0",
                   1611:       "rotl.l %S0"
                   1612:     },
                   1613: /* SHIFT_ASHIFTRT */
                   1614:     {
                   1615:       "rotl.b %X0",
                   1616:       "rotl.w %T0",
                   1617:       "rotl.l %S0"
                   1618:     }
                   1619:   }
                   1620: };
                   1621: 
                   1622: /* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
                   1623:    algorithm for doing the shift.  The assembler code is stored in ASSEMBLER.
                   1624:    We don't achieve maximum efficiency in all cases, but the hooks are here
                   1625:    to do so.
                   1626: 
                   1627:    For now we just use lots of switch statements.  Since we don't even come
                   1628:    close to supporting all the cases, this is simplest.  If this function ever
                   1629:    gets too big, perhaps resort to a more table based lookup.  Of course,
                   1630:    at this point you may just wish to do it all in rtl.
                   1631: 
                   1632:    WARNING: The constraints on insns shiftbyn_QI/HI/SI assume shifts of
                   1633:    1,2,3,4 will be inlined (1,2 for SI).  */
                   1634: 
                   1635: static enum shift_alg
                   1636: get_shift_alg (cpu, shift_type, mode, count, assembler_p, cc_valid_p)
                   1637:      enum attr_cpu cpu;
                   1638:      enum shift_type shift_type;
                   1639:      enum machine_mode mode;
                   1640:      int count;
                   1641:      const char **assembler_p;
                   1642:      int *cc_valid_p;
                   1643: {
                   1644:   /* The default is to loop.  */
                   1645:   enum shift_alg alg = SHIFT_LOOP;
                   1646:   enum shift_mode shift_mode;
                   1647: 
                   1648:   /* We don't handle negative shifts or shifts greater than the word size,
                   1649:      they should have been handled already.  */
                   1650: 
                   1651:   if (count < 0 || count > GET_MODE_BITSIZE (mode))
                   1652:     abort ();
                   1653: 
                   1654:   switch (mode)
                   1655:     {
                   1656:     case QImode:
                   1657:       shift_mode = QIshift;
                   1658:       break;
                   1659:     case HImode:
                   1660:       shift_mode = HIshift;
                   1661:       break;
                   1662:     case SImode:
                   1663:       shift_mode = SIshift;
                   1664:       break;
                   1665:     default:
                   1666:       abort ();
                   1667:     }
                   1668: 
                   1669:   /* Assume either SHIFT_LOOP or SHIFT_INLINE.
                   1670:      It is up to the caller to know that looping clobbers cc.  */
                   1671:   *assembler_p = shift_one[cpu][shift_type][shift_mode].assembler;
                   1672:   *cc_valid_p = shift_one[cpu][shift_type][shift_mode].cc_valid;
                   1673: 
                   1674:   /* Now look for cases we want to optimize.  */
                   1675: 
                   1676:   switch (shift_mode)
                   1677:     {
                   1678:     case QIshift:
                   1679:       if (count <= 4)
                   1680:        return SHIFT_INLINE;
                   1681:       else if (count <= 6)
                   1682:        {
                   1683:          if (shift_type == SHIFT_ASHIFTRT)
                   1684:            {
                   1685:              return SHIFT_LOOP;
                   1686:            }
                   1687:          else
                   1688:            {
                   1689:              *assembler_p = rotate_one[cpu][shift_type][shift_mode];
                   1690:              *cc_valid_p = 0;
                   1691:              return SHIFT_ROT_AND;
                   1692:            }
                   1693:        }
                   1694:       else if (count == 7)
                   1695:        {
                   1696:          if (shift_type == SHIFT_ASHIFTRT)
                   1697:            {
                   1698:              *assembler_p = "shll %X0\t; shar.b(7)\n\tsubx %X0,%X0\t; end shar.b(7)";
                   1699:              *cc_valid_p = 0;
                   1700:              return SHIFT_SPECIAL;
                   1701:            }
                   1702:          else
                   1703:            {
                   1704:              *assembler_p = rotate_one[cpu][shift_type][shift_mode];
                   1705:              *cc_valid_p = 0;
                   1706:              return SHIFT_ROT_AND;
                   1707:            }
                   1708:        }
                   1709:       break;
                   1710:     case HIshift:
                   1711:       if (count <= 4)
                   1712:        return SHIFT_INLINE;
                   1713:       else if (count == 8)
                   1714:        {
                   1715:          switch (shift_type)
                   1716:            {
                   1717:            case SHIFT_ASHIFT:
                   1718:              *assembler_p = "mov.b %s0,%t0\t; shal.w(8)\n\tsub.b %s0,%s0\t; end shal.w(8)";
                   1719:              *cc_valid_p = 0;
                   1720:              return SHIFT_SPECIAL;
                   1721:            case SHIFT_LSHIFTRT:
                   1722:              *assembler_p = "mov.b %t0,%s0\t; shlr.w(8)\n\tsub.b %t0,%t0\t; end shlr.w(8)";
                   1723:              *cc_valid_p = 0;
                   1724:              return SHIFT_SPECIAL;
                   1725:            case SHIFT_ASHIFTRT:
                   1726:              if (cpu == CPU_H8300)
                   1727:                *assembler_p = "mov.b %t0,%s0\t; shar.w(8)\n\tshll %t0\n\tsubx %t0,%t0\t; end shar.w(8)";
                   1728:              else
                   1729:                *assembler_p = "mov.b %t0,%s0\t; shar.w(8)\n\texts.w %T0\t; end shar.w(8)";
                   1730:              *cc_valid_p = 0;
                   1731:              return SHIFT_SPECIAL;
                   1732:            }
                   1733:          abort ();
1.1       root     1734:        }
1.1.1.2   root     1735:       else if (count == 15)
1.1       root     1736:        {
1.1.1.2   root     1737:          if (shift_type == SHIFT_ASHIFTRT)
                   1738:            {
                   1739:              *assembler_p = "shll %t0,%t0\t; shar.w(15)\n\tsubx %t0,%t0\n\tmov.b %t0,%s0\t; end shar.w(15)";
                   1740:              *cc_valid_p = 0;
                   1741:              return SHIFT_SPECIAL;
                   1742:            }
                   1743:          else
                   1744:            {
                   1745:              *assembler_p = rotate_one[cpu][shift_type][shift_mode];
                   1746:              *cc_valid_p = 0;
                   1747:              return SHIFT_ROT_AND;
                   1748:            }
                   1749:        }
                   1750:       break;
                   1751:     case SIshift:
                   1752:       if (count <= (cpu == CPU_H8300 ? 2 : 4))
                   1753:        return SHIFT_INLINE;
                   1754:       else if (count == 8)
                   1755:        {
                   1756:          if (cpu == CPU_H8300)
                   1757:            {
                   1758:              switch (shift_type)
                   1759:                {
                   1760:                case SHIFT_ASHIFT:
                   1761:                  *assembler_p = "mov.b %y0,%z0\t; shal.l(8)\n\tmov.b %x0,%y0\n\tmov.b %w0,%x0\n\tsub.b %w0,%w0\t; end shal.l(8)";
                   1762:                  *cc_valid_p = 0;
                   1763:                  return SHIFT_SPECIAL;
                   1764:                case SHIFT_LSHIFTRT:
                   1765:                  *assembler_p = "mov.b %x0,%w0\t; shlr.l(8)\n\tmov.b %y0,%x0\n\tmov.b %z0,%y0\n\tsub.b %z0,%z0\t; end shlr.l(8)";
                   1766:                  *cc_valid_p = 0;
                   1767:                  return SHIFT_SPECIAL;
                   1768:                case SHIFT_ASHIFTRT:
                   1769:                  *assembler_p = "mov.b %x0,%w0\t; shar.l(8)\n\tmov.b %y0,%x0\n\tmov.b %z0,%y0\n\tshll %z0\n\tsubx %z0,%z0; end shar.l(8)";
                   1770:                  *cc_valid_p = 0;
                   1771:                  return SHIFT_SPECIAL;
                   1772:                }
                   1773:            }
                   1774:          else                  /* CPU_H8300H */
                   1775:            /* We don't have byte level access to the high word so this isn't
                   1776:               easy to do.  For now, just loop.  */
                   1777:            ;
                   1778:        }
                   1779:       else if (count == 16)
                   1780:        {
                   1781:          switch (shift_type)
                   1782:            {
                   1783:            case SHIFT_ASHIFT:
                   1784:              *assembler_p = "mov.w %f0,%e0\t; shal.l(16)\n\tsub.w %f0,%f0\t; end shal.l(16)";
                   1785:              *cc_valid_p = 0;
                   1786:              return SHIFT_SPECIAL;
                   1787:            case SHIFT_LSHIFTRT:
                   1788:              *assembler_p = "mov.w %e0,%f0\t; shlr.l(16)\n\tsub.w %e0,%e0\t; end shlr.l(16)";
                   1789:              *cc_valid_p = 0;
                   1790:              return SHIFT_SPECIAL;
                   1791:            case SHIFT_ASHIFTRT:
                   1792:              if (cpu == CPU_H8300)
                   1793:                *assembler_p = "mov.w %e0,%f0\t; shar.l(16)\n\tshll %z0\n\tsubx %z0,%z0\n\tmov.b %z0,%y0\t; end shar.l(16)";
                   1794:              else
                   1795:                *assembler_p = "mov.w %e0,%f0\t; shar.l(16)\n\texts.l %S0\t; end shar.l(16)";
                   1796:              *cc_valid_p = 0;
                   1797:              return SHIFT_SPECIAL;
                   1798:            }
                   1799:        }
                   1800:       else if (count >= 28 && count <= 30)
                   1801:        {
                   1802:          if (shift_type == SHIFT_ASHIFTRT)
                   1803:            {
                   1804:              return SHIFT_LOOP;
                   1805:            }
                   1806:          else
                   1807:            {
                   1808:              if (cpu == CPU_H8300)
                   1809:                return SHIFT_LOOP;
                   1810:              else
                   1811:                {
                   1812:                  *assembler_p = rotate_one[cpu][shift_type][shift_mode];
                   1813:                  *cc_valid_p = 0;
                   1814:                  return SHIFT_ROT_AND;
                   1815:                }
                   1816:            }
                   1817:        }
                   1818:       else if (count == 31)
                   1819:        {
                   1820:          if (shift_type == SHIFT_ASHIFTRT)
                   1821:            {
                   1822:              if (cpu == CPU_H8300)
                   1823:                *assembler_p = "shll %z0\t; shar.l(31)\n\tsubx %w0,%w0\n\tmov.b %w0,%x0\n\tmov.w %f0,%e0\t; end shar.l(31)";
                   1824:              else
                   1825:                *assembler_p = "shll %e0\t; shar.l(31)\n\tsubx %w0,%w0\n\tmov.b %w0,%x0\n\tmov.w %f0,%e0\t; end shar.l(31)";
                   1826:              *cc_valid_p = 0;
                   1827:              return SHIFT_SPECIAL;
                   1828:            }
                   1829:          else
                   1830:            {
                   1831:              if (cpu == CPU_H8300)
                   1832:                {
                   1833:                  if (shift_type == SHIFT_ASHIFT)
                   1834:                    *assembler_p = "sub.w %e0,%e0\t; shal.l(31)\n\tshlr %w0\n\tmov.w %e0,%f0\n\trotxr %z0\t; end shal.l(31)";
                   1835:                  else
                   1836:                    *assembler_p = "sub.w %f0,%f0\t; shlr.l(31)\n\tshll %z0\n\tmov.w %f0,%e0\n\trotxl %w0\t; end shlr.l(31)";
                   1837:                  *cc_valid_p = 0;
                   1838:                  return SHIFT_SPECIAL;
                   1839:                }
                   1840:              else
                   1841:                {
                   1842:                  *assembler_p = rotate_one[cpu][shift_type][shift_mode];
                   1843:                  *cc_valid_p = 0;
                   1844:                  return SHIFT_ROT_AND;
                   1845:                }
                   1846:            }
1.1       root     1847:        }
1.1.1.2   root     1848:       break;
                   1849:     default:
                   1850:       abort ();
1.1       root     1851:     }
1.1.1.2   root     1852: 
                   1853:   return alg;
1.1       root     1854: }
                   1855: 
1.1.1.2   root     1856: /* Emit the assembler code for doing shifts.  */
                   1857: 
                   1858: char *
                   1859: emit_a_shift (insn, operands)
                   1860:      rtx insn;
                   1861:      rtx *operands;
1.1       root     1862: {
1.1.1.2   root     1863:   static int loopend_lab;
                   1864:   char *assembler;
                   1865:   int cc_valid;
                   1866:   rtx inside = PATTERN (insn);
                   1867:   rtx shift = operands[3];
                   1868:   enum machine_mode mode = GET_MODE (shift);
                   1869:   enum rtx_code code = GET_CODE (shift);
                   1870:   enum shift_type shift_type;
                   1871:   enum shift_mode shift_mode;
                   1872: 
                   1873:   loopend_lab++;
1.1       root     1874: 
1.1.1.2   root     1875:   switch (mode)
1.1       root     1876:     {
1.1.1.2   root     1877:     case QImode:
                   1878:       shift_mode = QIshift;
                   1879:       break;
                   1880:     case HImode:
                   1881:       shift_mode = HIshift;
                   1882:       break;
                   1883:     case SImode:
                   1884:       shift_mode = SIshift;
                   1885:       break;
                   1886:     default:
                   1887:       abort ();
                   1888:     }
1.1       root     1889: 
1.1.1.2   root     1890:   switch (code)
                   1891:     {
                   1892:     case ASHIFTRT:
                   1893:       shift_type = SHIFT_ASHIFTRT;
                   1894:       break;
                   1895:     case LSHIFTRT:
                   1896:       shift_type = SHIFT_LSHIFTRT;
                   1897:       break;
                   1898:     case ASHIFT:
                   1899:       shift_type = SHIFT_ASHIFT;
                   1900:       break;
                   1901:     default:
                   1902:       abort ();
                   1903:     }
                   1904: 
                   1905:   if (GET_CODE (operands[2]) != CONST_INT)
                   1906:     {
                   1907:       /* Indexing by reg, so have to loop and test at top */
                   1908:       output_asm_insn ("mov.b  %X2,%X4", operands);
                   1909:       fprintf (asm_out_file, "\tble    .Lle%d\n", loopend_lab);
                   1910: 
                   1911:       /* Get the assembler code to do one shift.  */
                   1912:       get_shift_alg (cpu_type, shift_type, mode, 1, &assembler, &cc_valid);
                   1913:     }
                   1914:   else
                   1915:     {
                   1916:       int n = INTVAL (operands[2]);
                   1917:       enum shift_alg alg;
                   1918: 
                   1919:       /* If the count is negative, make it 0.  */
                   1920:       if (n < 0)
                   1921:        n = 0;
                   1922:       /* If the count is too big, truncate it.
                   1923:          ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
                   1924:         do the intuitive thing.  */
                   1925:       else if (n > GET_MODE_BITSIZE (mode))
                   1926:        n = GET_MODE_BITSIZE (mode);
                   1927: 
                   1928:       alg = get_shift_alg (cpu_type, shift_type, mode, n, &assembler, &cc_valid);
                   1929: 
                   1930:       switch (alg)
                   1931:        {
                   1932:        case SHIFT_INLINE:
                   1933:          while (--n >= 0)
                   1934:            output_asm_insn (assembler, operands);
                   1935:          if (cc_valid)
                   1936:            cc_status.value1 = operands[0];
                   1937:          return "";
                   1938:        case SHIFT_ROT_AND:
                   1939:          {
                   1940:            int m = GET_MODE_BITSIZE (mode) - n;
                   1941:            int mask = (shift_type == SHIFT_ASHIFT
                   1942:                        ? ((1 << GET_MODE_BITSIZE (mode) - n) - 1) << n
                   1943:                        : (1 << GET_MODE_BITSIZE (mode) - n) - 1);
                   1944:            char insn_buf[200];
                   1945:            /* Not all possibilities of rotate are supported.  They shouldn't
                   1946:               be generated, but let's watch for 'em.  */
                   1947:            if (assembler == 0)
                   1948:              abort ();
                   1949:            while (--m >= 0)
                   1950:              output_asm_insn (assembler, operands);
                   1951:            if (TARGET_H8300)
                   1952:              {
                   1953:                switch (mode)
                   1954:                  {
                   1955:                  case QImode:
                   1956:                    sprintf (insn_buf, "and #%d,%%X0\t; end shift %d via rotate+and",
                   1957:                             mask, n);
                   1958:                    cc_status.value1 = operands[0];
                   1959:                    break;
                   1960:                  case HImode:
                   1961:                    sprintf (insn_buf, "and #%d,%%s0\n\tand #%d,%%t0\t; end shift %d via rotate+and",
                   1962:                             mask & 255, mask >> 8, n);
                   1963:                    break;
                   1964:                  case SImode:
                   1965:                    abort ();
                   1966:                  }
                   1967:              }
                   1968:            else
                   1969:              {
                   1970:                sprintf (insn_buf, "and.%c #%d,%%%c0",
                   1971:                         "bwl"[shift_mode], mask,
                   1972:                         mode == QImode ? 'X' : mode == HImode ? 'T' : 'S');
                   1973:                cc_status.value1 = operands[0];
                   1974:              }
                   1975:            output_asm_insn (insn_buf, operands);
                   1976:            return "";
                   1977:          }
                   1978:        case SHIFT_SPECIAL:
                   1979:          output_asm_insn (assembler, operands);
                   1980:          return "";
1.1       root     1981:        }
1.1.1.2   root     1982: 
                   1983:       /* Need a loop, move limit to tmp reg */
                   1984:       fprintf (asm_out_file, "\tmov.b  #%d,%sl\n", n, names_big[REGNO (operands[4])]);
1.1       root     1985:     }
1.1.1.2   root     1986: 
                   1987:   fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
                   1988:   output_asm_insn (assembler, operands);
                   1989:   output_asm_insn ("add        #0xff,%X4", operands);
                   1990:   fprintf (asm_out_file, "\tbne        .Llt%d\n", loopend_lab);
                   1991:   fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);
                   1992: 
                   1993:   return "";
1.1       root     1994: }
1.1.1.2   root     1995: 
                   1996: /* Fix the operands of a gen_xxx so that it could become a bit
                   1997:   operating insn.  */
1.1       root     1998: 
                   1999: int
1.1.1.2   root     2000: fix_bit_operand (operands, what, type)
                   2001:      rtx *operands;
                   2002:      char what;
                   2003:      enum rtx_code type;
1.1       root     2004: {
1.1.1.3 ! root     2005:   /* The bit_operand predicate accepts any memory during RTL generation, but
1.1.1.2   root     2006:      only 'U' memory afterwards, so if this is a MEM operand, we must force
                   2007:      it to be valid for 'U' by reloading the address.  */
1.1       root     2008: 
1.1.1.2   root     2009:   if (GET_CODE (operands[2]) == CONST_INT)
1.1       root     2010:     {
1.1.1.2   root     2011:       if (CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), what))
                   2012:        {
                   2013:          /* Ok to have a memory dest.  */
                   2014:          if (GET_CODE (operands[0]) == MEM && !EXTRA_CONSTRAINT (operands[0], 'U'))
                   2015:            {
                   2016:              rtx mem;
                   2017:              mem = gen_rtx (MEM, GET_MODE (operands[0]),
                   2018:                           copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
                   2019:              RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
                   2020:              MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
                   2021:              MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
                   2022:              operands[0] = mem;
                   2023:            }
                   2024: 
                   2025:          if (GET_CODE (operands[1]) == MEM && !EXTRA_CONSTRAINT (operands[1], 'U'))
                   2026:            {
                   2027:              rtx mem;
                   2028:              mem = gen_rtx (MEM, GET_MODE (operands[1]),
                   2029:                           copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
                   2030:              RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
                   2031:              MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
                   2032:              MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
                   2033:              operands[1] = mem;
                   2034:            }
                   2035:          return 0;
                   2036:        }
                   2037:     }
1.1       root     2038: 
1.1.1.2   root     2039:   /* Dest and src op must be register.  */
1.1       root     2040: 
1.1.1.2   root     2041:   operands[1] = force_reg (QImode, operands[1]);
                   2042:   {
                   2043:     rtx res = gen_reg_rtx (QImode);
                   2044:     emit_insn (gen_rtx (SET, VOIDmode, res, gen_rtx (type, QImode, operands[1], operands[2])));
                   2045:     emit_insn (gen_rtx (SET, VOIDmode, operands[0], res));
                   2046:   }
                   2047:   return 1;
1.1       root     2048: }

unix.superglobalmegacorp.com

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