(linenum→info "unix/slp.c:2238")

binutils/2.18/opcodes/frv-ibld.c

    1: /* Instruction building/extraction support for frv. -*- C -*-
    2: 
    3:    THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
    4:    - the resultant file is machine generated, cgen-ibld.in isn't
    5: 
    6:    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007
    7:    Free Software Foundation, Inc.
    8: 
    9:    This file is part of libopcodes.
   10: 
   11:    This library is free software; you can redistribute it and/or modify
   12:    it under the terms of the GNU General Public License as published by
   13:    the Free Software Foundation; either version 3, or (at your option)
   14:    any later version.
   15: 
   16:    It is distributed in the hope that it will be useful, but WITHOUT
   17:    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   18:    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   19:    License for more details.
   20: 
   21:    You should have received a copy of the GNU General Public License
   22:    along with this program; if not, write to the Free Software Foundation, Inc.,
   23:    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
   24: 
   25: /* ??? Eventually more and more of this stuff can go to cpu-independent files.
   26:    Keep that in mind.  */
   27: 
   28: #include "sysdep.h"
   29: #include <stdio.h>
   30: #include "ansidecl.h"
   31: #include "dis-asm.h"
   32: #include "bfd.h"
   33: #include "symcat.h"
   34: #include "frv-desc.h"
   35: #include "frv-opc.h"
   36: #include "opintl.h"
   37: #include "safe-ctype.h"
   38: 
   39: #undef  min
   40: #define min(a,b) ((a) < (b) ? (a) : (b))
   41: #undef  max
   42: #define max(a,b) ((a) > (b) ? (a) : (b))
   43: 
   44: /* Used by the ifield rtx function.  */
   45: #define FLD(f) (fields->f)
   46: 
   47: static const char * insert_normal
   48:   (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
   49:    unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
   50: static const char * insert_insn_normal
   51:   (CGEN_CPU_DESC, const CGEN_INSN *,
   52:    CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
   53: static int extract_normal
   54:   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
   55:    unsigned int, unsigned int, unsigned int, unsigned int,
   56:    unsigned int, unsigned int, bfd_vma, long *);
   57: static int extract_insn_normal
   58:   (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
   59:    CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
   60: #if CGEN_INT_INSN_P
   61: static void put_insn_int_value
   62:   (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
   63: #endif
   64: #if ! CGEN_INT_INSN_P
   65: static CGEN_INLINE void insert_1
   66:   (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
   67: static CGEN_INLINE int fill_cache
   68:   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
   69: static CGEN_INLINE long extract_1
   70:   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
   71: #endif
   72: ^L
   73: /* Operand insertion.  */
   74: 
   75: #if ! CGEN_INT_INSN_P
   76: 
   77: /* Subroutine of insert_normal.  */
   78: 
   79: static CGEN_INLINE void
   80: insert_1 (CGEN_CPU_DESC cd,
   81:           unsigned long value,
   82:           int start,
   83:           int length,
   84:           int word_length,
   85:           unsigned char *bufp)
   86: {
   87:   unsigned long x,mask;
   88:   int shift;
   89: 
   90:   x = cgen_get_insn_value (cd, bufp, word_length);
   91: 
   92:   /* Written this way to avoid undefined behaviour.  */
   93:   mask = (((1L << (length - 1)) - 1) << 1) | 1;
   94:   if (CGEN_INSN_LSB0_P)
   95:     shift = (start + 1) - length;
   96:   else
   97:     shift = (word_length - (start + length));
   98:   x = (x & ~(mask << shift)) | ((value & mask) << shift);
   99: 
  100:   cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
  101: }
  102: 
  103: #endif /* ! CGEN_INT_INSN_P */
  104: 
  105: /* Default insertion routine.
  106: 
  107:    ATTRS is a mask of the boolean attributes.
  108:    WORD_OFFSET is the offset in bits from the start of the insn of the value.
  109:    WORD_LENGTH is the length of the word in bits in which the value resides.
  110:    START is the starting bit number in the word, architecture origin.
  111:    LENGTH is the length of VALUE in bits.
  112:    TOTAL_LENGTH is the total length of the insn in bits.
  113: 
  114:    The result is an error message or NULL if success.  */
  115: 
  116: /* ??? This duplicates functionality with bfd's howto table and
  117:    bfd_install_relocation.  */
  118: /* ??? This doesn't handle bfd_vma's.  Create another function when
  119:    necessary.  */
  120: 
  121: static const char *
  122: insert_normal (CGEN_CPU_DESC cd,
  123:                long value,
  124:                unsigned int attrs,
  125:                unsigned int word_offset,
  126:                unsigned int start,
  127:                unsigned int length,
  128:                unsigned int word_length,
  129:                unsigned int total_length,
  130:                CGEN_INSN_BYTES_PTR buffer)
  131: {
  132:   static char errbuf[100];
  133:   /* Written this way to avoid undefined behaviour.  */
  134:   unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
  135: 
  136:   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
  137:   if (length == 0)
  138:     return NULL;
  139: 
  140:   if (word_length > 32)
  141:     abort ();
  142: 
  143:   /* For architectures with insns smaller than the base-insn-bitsize,
  144:      word_length may be too big.  */
  145:   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
  146:     {
  147:       if (word_offset == 0
  148:           && word_length > total_length)
  149:         word_length = total_length;
  150:     }
  151: 
  152:   /* Ensure VALUE will fit.  */
  153:   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
  154:     {
  155:       long minval = - (1L << (length - 1));
  156:       unsigned long maxval = mask;
  157:       
  158:       if ((value > 0 && (unsigned long) value > maxval)
  159:           || value < minval)
  160:         {
  161:           /* xgettext:c-format */
  162:           sprintf (errbuf,
  163:                    _("operand out of range (%ld not between %ld and %lu)"),
  164:                    value, minval, maxval);
  165:           return errbuf;
  166:         }
  167:     }
  168:   else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
  169:     {
  170:       unsigned long maxval = mask;
  171:       unsigned long val = (unsigned long) value;
  172: 
  173:       /* For hosts with a word size > 32 check to see if value has been sign
  174:          extended beyond 32 bits.  If so then ignore these higher sign bits
  175:          as the user is attempting to store a 32-bit signed value into an
  176:          unsigned 32-bit field which is allowed.  */
  177:       if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
  178:         val &= 0xFFFFFFFF;
  179: 
  180:       if (val > maxval)
  181:         {
  182:           /* xgettext:c-format */
  183:           sprintf (errbuf,
  184:                    _("operand out of range (0x%lx not between 0 and 0x%lx)"),
  185:                    val, maxval);
  186:           return errbuf;
  187:         }
  188:     }
  189:   else
  190:     {
  191:       if (! cgen_signed_overflow_ok_p (cd))
  192:         {
  193:           long minval = - (1L << (length - 1));
  194:           long maxval =   (1L << (length - 1)) - 1;
  195:           
  196:           if (value < minval || value > maxval)
  197:             {
  198:               sprintf
  199:                 /* xgettext:c-format */
  200:                 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
  201:                  value, minval, maxval);
  202:               return errbuf;
  203:             }
  204:         }
  205:     }
  206: 
  207: #if CGEN_INT_INSN_P
  208: 
  209:   {
  210:     int shift;
  211: 
  212:     if (CGEN_INSN_LSB0_P)
  213:       shift = (word_offset + start + 1) - length;
  214:     else
  215:       shift = total_length - (word_offset + start + length);
  216:     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
  217:   }
  218: 
  219: #else /* ! CGEN_INT_INSN_P */
  220: 
  221:   {
  222:     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
  223: 
  224:     insert_1 (cd, value, start, length, word_length, bufp);
  225:   }
  226: 
  227: #endif /* ! CGEN_INT_INSN_P */
  228: 
  229:   return NULL;
  230: }
  231: 
  232: /* Default insn builder (insert handler).
  233:    The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
  234:    that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
  235:    recorded in host byte order, otherwise BUFFER is an array of bytes
  236:    and the value is recorded in target byte order).
  237:    The result is an error message or NULL if success.  */
  238: 
  239: static const char *
  240: insert_insn_normal (CGEN_CPU_DESC cd,
  241:                     const CGEN_INSN * insn,
  242:                     CGEN_FIELDS * fields,
  243:                     CGEN_INSN_BYTES_PTR buffer,
  244:                     bfd_vma pc)
  245: {
  246:   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
  247:   unsigned long value;
  248:   const CGEN_SYNTAX_CHAR_TYPE * syn;
  249: 
  250:   CGEN_INIT_INSERT (cd);
  251:   value = CGEN_INSN_BASE_VALUE (insn);
  252: 
  253:   /* If we're recording insns as numbers (rather than a string of bytes),
  254:      target byte order handling is deferred until later.  */
  255: 
  256: #if CGEN_INT_INSN_P
  257: 
  258:   put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
  259:                       CGEN_FIELDS_BITSIZE (fields), value);
  260: 
  261: #else
  262: 
  263:   cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
  264:                                         (unsigned) CGEN_FIELDS_BITSIZE (fields)),
  265:                        value);
  266: 
  267: #endif /* ! CGEN_INT_INSN_P */
  268: 
  269:   /* ??? It would be better to scan the format's fields.
  270:      Still need to be able to insert a value based on the operand though;
  271:      e.g. storing a branch displacement that got resolved later.
  272:      Needs more thought first.  */
  273: 
  274:   for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
  275:     {
  276:       const char *errmsg;
  277: 
  278:       if (CGEN_SYNTAX_CHAR_P (* syn))
  279:         continue;
  280: 
  281:       errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
  282:                                        fields, buffer, pc);
  283:       if (errmsg)
  284:         return errmsg;
  285:     }
  286: 
  287:   return NULL;
  288: }
  289: 
  290: #if CGEN_INT_INSN_P
  291: /* Cover function to store an insn value into an integral insn.  Must go here
  292:    because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
  293: 
  294: static void
  295: put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  296:                     CGEN_INSN_BYTES_PTR buf,
  297:                     int length,
  298:                     int insn_length,
  299:                     CGEN_INSN_INT value)
  300: {
  301:   /* For architectures with insns smaller than the base-insn-bitsize,
  302:      length may be too big.  */
  303:   if (length > insn_length)
  304:     *buf = value;
  305:   else
  306:     {
  307:       int shift = insn_length - length;
  308:       /* Written this way to avoid undefined behaviour.  */
  309:       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
  310: 
  311:       *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
  312:     }
  313: }
  314: #endif
  315: ^L
  316: /* Operand extraction.  */
  317: 
  318: #if ! CGEN_INT_INSN_P
  319: 
  320: /* Subroutine of extract_normal.
  321:    Ensure sufficient bytes are cached in EX_INFO.
  322:    OFFSET is the offset in bytes from the start of the insn of the value.
  323:    BYTES is the length of the needed value.
  324:    Returns 1 for success, 0 for failure.  */
  325: 
  326: static CGEN_INLINE int
  327: fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
  328:             CGEN_EXTRACT_INFO *ex_info,
  329:             int offset,
  330:             int bytes,
  331:             bfd_vma pc)
  332: {
  333:   /* It's doubtful that the middle part has already been fetched so
  334:      we don't optimize that case.  kiss.  */
  335:   unsigned int mask;
  336:   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
  337: 
  338:   /* First do a quick check.  */
  339:   mask = (1 << bytes) - 1;
  340:   if (((ex_info->valid >> offset) & mask) == mask)
  341:     return 1;
  342: 
  343:   /* Search for the first byte we need to read.  */
  344:   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
  345:     if (! (mask & ex_info->valid))
  346:       break;
  347: 
  348:   if (bytes)
  349:     {
  350:       int status;
  351: 
  352:       pc += offset;
  353:       status = (*info->read_memory_func)
  354:         (pc, ex_info->insn_bytes + offset, bytes, info);
  355: 
  356:       if (status != 0)
  357:         {
  358:           (*info->memory_error_func) (status, pc, info);
  359:           return 0;
  360:         }
  361: 
  362:       ex_info->valid |= ((1 << bytes) - 1) << offset;
  363:     }
  364: 
  365:   return 1;
  366: }
  367: 
  368: /* Subroutine of extract_normal.  */
  369: 
  370: static CGEN_INLINE long
  371: extract_1 (CGEN_CPU_DESC cd,
  372:            CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
  373:            int start,
  374:            int length,
  375:            int word_length,
  376:            unsigned char *bufp,
  377:            bfd_vma pc ATTRIBUTE_UNUSED)
  378: {
  379:   unsigned long x;
  380:   int shift;
  381: 
  382:   x = cgen_get_insn_value (cd, bufp, word_length);
  383: 
  384:   if (CGEN_INSN_LSB0_P)
  385:     shift = (start + 1) - length;
  386:   else
  387:     shift = (word_length - (start + length));
  388:   return x >> shift;
  389: }
  390: 
  391: #endif /* ! CGEN_INT_INSN_P */
  392: 
  393: /* Default extraction routine.
  394: 
  395:    INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
  396:    or sometimes less for cases like the m32r where the base insn size is 32
  397:    but some insns are 16 bits.
  398:    ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
  399:    but for generality we take a bitmask of all of them.
  400:    WORD_OFFSET is the offset in bits from the start of the insn of the value.
  401:    WORD_LENGTH is the length of the word in bits in which the value resides.
  402:    START is the starting bit number in the word, architecture origin.
  403:    LENGTH is the length of VALUE in bits.
  404:    TOTAL_LENGTH is the total length of the insn in bits.
  405: 
  406:    Returns 1 for success, 0 for failure.  */
  407: 
  408: /* ??? The return code isn't properly used.  wip.  */
  409: 
  410: /* ??? This doesn't handle bfd_vma's.  Create another function when
  411:    necessary.  */
  412: 
  413: static int
  414: extract_normal (CGEN_CPU_DESC cd,
  415: #if ! CGEN_INT_INSN_P
  416:                 CGEN_EXTRACT_INFO *ex_info,
  417: #else
  418:                 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
  419: #endif
  420:                 CGEN_INSN_INT insn_value,
  421:                 unsigned int attrs,
  422:                 unsigned int word_offset,
  423:                 unsigned int start,
  424:                 unsigned int length,
  425:                 unsigned int word_length,
  426:                 unsigned int total_length,
  427: #if ! CGEN_INT_INSN_P
  428:                 bfd_vma pc,
  429: #else
  430:                 bfd_vma pc ATTRIBUTE_UNUSED,
  431: #endif
  432:                 long *valuep)
  433: {
  434:   long value, mask;
  435: 
  436:   /* If LENGTH is zero, this operand doesn't contribute to the value
  437:      so give it a standard value of zero.  */
  438:   if (length == 0)
  439:     {
  440:       *valuep = 0;
  441:       return 1;
  442:     }
  443: 
  444:   if (word_length > 32)
  445:     abort ();
  446: 
  447:   /* For architectures with insns smaller than the insn-base-bitsize,
  448:      word_length may be too big.  */
  449:   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
  450:     {
  451:       if (word_offset + word_length > total_length)
  452:         word_length = total_length - word_offset;
  453:     }
  454: 
  455:   /* Does the value reside in INSN_VALUE, and at the right alignment?  */
  456: 
  457:   if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
  458:     {
  459:       if (CGEN_INSN_LSB0_P)
  460:         value = insn_value >> ((word_offset + start + 1) - length);
  461:       else
  462:         value = insn_value >> (total_length - ( word_offset + start + length));
  463:     }
  464: 
  465: #if ! CGEN_INT_INSN_P
  466: 
  467:   else
  468:     {
  469:       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
  470: 
  471:       if (word_length > 32)
  472:         abort ();
  473: 
  474:       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
  475:         return 0;
  476: 
  477:       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
  478:     }
  479: 
  480: #endif /* ! CGEN_INT_INSN_P */
  481: 
  482:   /* Written this way to avoid undefined behaviour.  */
  483:   mask = (((1L << (length - 1)) - 1) << 1) | 1;
  484: 
  485:   value &= mask;
  486:   /* sign extend? */
  487:   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
  488:       && (value & (1L << (length - 1))))
  489:     value |= ~mask;
  490: 
  491:   *valuep = value;
  492: 
  493:   return 1;
  494: }
  495: 
  496: /* Default insn extractor.
  497: 
  498:    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
  499:    The extracted fields are stored in FIELDS.
  500:    EX_INFO is used to handle reading variable length insns.
  501:    Return the length of the insn in bits, or 0 if no match,
  502:    or -1 if an error occurs fetching data (memory_error_func will have
  503:    been called).  */
  504: 
  505: static int
  506: extract_insn_normal (CGEN_CPU_DESC cd,
  507:                      const CGEN_INSN *insn,
  508:                      CGEN_EXTRACT_INFO *ex_info,
  509:                      CGEN_INSN_INT insn_value,
  510:                      CGEN_FIELDS *fields,
  511:                      bfd_vma pc)
  512: {
  513:   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
  514:   const CGEN_SYNTAX_CHAR_TYPE *syn;
  515: 
  516:   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
  517: 
  518:   CGEN_INIT_EXTRACT (cd);
  519: 
  520:   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
  521:     {
  522:       int length;
  523: 
  524:       if (CGEN_SYNTAX_CHAR_P (*syn))
  525:         continue;
  526: 
  527:       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
  528:                                         ex_info, insn_value, fields, pc);
  529:       if (length <= 0)
  530:         return length;
  531:     }
  532: 
  533:   /* We recognized and successfully extracted this insn.  */
  534:   return CGEN_INSN_BITSIZE (insn);
  535: }
  536: ^L
  537: /* Machine generated code added here.  */
  538: 
  539: const char * frv_cgen_insert_operand
  540:   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
  541: 
  542: /* Main entry point for operand insertion.
  543: 
  544:    This function is basically just a big switch statement.  Earlier versions
  545:    used tables to look up the function to use, but
  546:    - if the table contains both assembler and disassembler functions then
  547:      the disassembler contains much of the assembler and vice-versa,
  548:    - there's a lot of inlining possibilities as things grow,
  549:    - using a switch statement avoids the function call overhead.
  550: 
  551:    This function could be moved into `parse_insn_normal', but keeping it
  552:    separate makes clear the interface between `parse_insn_normal' and each of
  553:    the handlers.  It's also needed by GAS to insert operands that couldn't be
  554:    resolved during parsing.  */
  555: 
  556: const char *
  557: frv_cgen_insert_operand (CGEN_CPU_DESC cd,
  558:                              int opindex,
  559:                              CGEN_FIELDS * fields,
  560:                              CGEN_INSN_BYTES_PTR buffer,
  561:                              bfd_vma pc ATTRIBUTE_UNUSED)
  562: {
  563:   const char * errmsg = NULL;
  564:   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
  565: 
  566:   switch (opindex)
  567:     {
  568:     case FRV_OPERAND_A0 :
  569:       errmsg = insert_normal (cd, fields->f_A, 0, 0, 17, 1, 32, total_length, buffer);
  570:       break;
  571:     case FRV_OPERAND_A1 :
  572:       errmsg = insert_normal (cd, fields->f_A, 0, 0, 17, 1, 32, total_length, buffer);
  573:       break;
  574:     case FRV_OPERAND_ACC40SI :
  575:       errmsg = insert_normal (c