[BACK]Return to aarch64-opc.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / opcodes

Annotation of src/external/gpl3/binutils.old/dist/opcodes/aarch64-opc.h, Revision 1.1.1.3

1.1       christos    1: /* aarch64-opc.h -- Header file for aarch64-opc.c and aarch64-opc-2.c.
1.1.1.3 ! christos    2:    Copyright (C) 2012-2016 Free Software Foundation, Inc.
1.1       christos    3:    Contributed by ARM Ltd.
                      4:
                      5:    This file is part of the GNU opcodes library.
                      6:
                      7:    This library is free software; you can redistribute it and/or modify
                      8:    it under the terms of the GNU General Public License as published by
                      9:    the Free Software Foundation; either version 3, or (at your option)
                     10:    any later version.
                     11:
                     12:    It is distributed in the hope that it will be useful, but WITHOUT
                     13:    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
                     15:    License for more details.
                     16:
                     17:    You should have received a copy of the GNU General Public License
                     18:    along with this program; see the file COPYING3. If not,
                     19:    see <http://www.gnu.org/licenses/>.  */
                     20:
                     21: #ifndef OPCODES_AARCH64_OPC_H
                     22: #define OPCODES_AARCH64_OPC_H
                     23:
                     24: #include <string.h>
                     25: #include "opcode/aarch64.h"
                     26:
                     27: /* Instruction fields.
                     28:    Keep synced with fields.  */
                     29: enum aarch64_field_kind
                     30: {
                     31:   FLD_NIL,
                     32:   FLD_cond2,
                     33:   FLD_nzcv,
                     34:   FLD_defgh,
                     35:   FLD_abc,
                     36:   FLD_imm19,
                     37:   FLD_immhi,
                     38:   FLD_immlo,
                     39:   FLD_size,
                     40:   FLD_vldst_size,
                     41:   FLD_op,
                     42:   FLD_Q,
                     43:   FLD_Rt,
                     44:   FLD_Rd,
                     45:   FLD_Rn,
                     46:   FLD_Rt2,
                     47:   FLD_Ra,
                     48:   FLD_op2,
                     49:   FLD_CRm,
                     50:   FLD_CRn,
                     51:   FLD_op1,
                     52:   FLD_op0,
                     53:   FLD_imm3,
                     54:   FLD_cond,
                     55:   FLD_opcode,
                     56:   FLD_cmode,
                     57:   FLD_asisdlso_opcode,
                     58:   FLD_len,
                     59:   FLD_Rm,
                     60:   FLD_Rs,
                     61:   FLD_option,
                     62:   FLD_S,
                     63:   FLD_hw,
                     64:   FLD_opc,
                     65:   FLD_opc1,
                     66:   FLD_shift,
                     67:   FLD_type,
                     68:   FLD_ldst_size,
                     69:   FLD_imm6,
                     70:   FLD_imm4,
                     71:   FLD_imm5,
                     72:   FLD_imm7,
                     73:   FLD_imm8,
                     74:   FLD_imm9,
                     75:   FLD_imm12,
                     76:   FLD_imm14,
                     77:   FLD_imm16,
                     78:   FLD_imm26,
                     79:   FLD_imms,
                     80:   FLD_immr,
                     81:   FLD_immb,
                     82:   FLD_immh,
                     83:   FLD_N,
                     84:   FLD_index,
                     85:   FLD_index2,
                     86:   FLD_sf,
1.1.1.2   christos   87:   FLD_lse_sz,
1.1       christos   88:   FLD_H,
                     89:   FLD_L,
                     90:   FLD_M,
                     91:   FLD_b5,
                     92:   FLD_b40,
                     93:   FLD_scale,
                     94: };
                     95:
                     96: /* Field description.  */
                     97: struct aarch64_field
                     98: {
                     99:   int lsb;
                    100:   int width;
                    101: };
                    102:
                    103: typedef struct aarch64_field aarch64_field;
                    104:
                    105: extern const aarch64_field fields[];
                    106: 
                    107: /* Operand description.  */
                    108:
                    109: struct aarch64_operand
                    110: {
                    111:   enum aarch64_operand_class op_class;
                    112:
                    113:   /* Name of the operand code; used mainly for the purpose of internal
                    114:      debugging.  */
                    115:   const char *name;
                    116:
                    117:   unsigned int flags;
                    118:
                    119:   /* The associated instruction bit-fields; no operand has more than 4
                    120:      bit-fields */
                    121:   enum aarch64_field_kind fields[4];
                    122:
                    123:   /* Brief description */
                    124:   const char *desc;
                    125: };
                    126:
                    127: typedef struct aarch64_operand aarch64_operand;
                    128:
                    129: extern const aarch64_operand aarch64_operands[];
                    130:
                    131: /* Operand flags.  */
                    132:
                    133: #define OPD_F_HAS_INSERTER     0x00000001
                    134: #define OPD_F_HAS_EXTRACTOR    0x00000002
                    135: #define OPD_F_SEXT             0x00000004      /* Require sign-extension.  */
                    136: #define OPD_F_SHIFT_BY_2       0x00000008      /* Need to left shift the field
                    137:                                                   value by 2 to get the value
                    138:                                                   of an immediate operand.  */
                    139: #define OPD_F_MAYBE_SP         0x00000010      /* May potentially be SP.  */
                    140:
                    141: static inline bfd_boolean
                    142: operand_has_inserter (const aarch64_operand *operand)
                    143: {
                    144:   return (operand->flags & OPD_F_HAS_INSERTER) ? TRUE : FALSE;
                    145: }
                    146:
                    147: static inline bfd_boolean
                    148: operand_has_extractor (const aarch64_operand *operand)
                    149: {
                    150:   return (operand->flags & OPD_F_HAS_EXTRACTOR) ? TRUE : FALSE;
                    151: }
                    152:
                    153: static inline bfd_boolean
                    154: operand_need_sign_extension (const aarch64_operand *operand)
                    155: {
                    156:   return (operand->flags & OPD_F_SEXT) ? TRUE : FALSE;
                    157: }
                    158:
                    159: static inline bfd_boolean
                    160: operand_need_shift_by_two (const aarch64_operand *operand)
                    161: {
                    162:   return (operand->flags & OPD_F_SHIFT_BY_2) ? TRUE : FALSE;
                    163: }
                    164:
                    165: static inline bfd_boolean
                    166: operand_maybe_stack_pointer (const aarch64_operand *operand)
                    167: {
                    168:   return (operand->flags & OPD_F_MAYBE_SP) ? TRUE : FALSE;
                    169: }
                    170:
                    171: /* Return the total width of the operand *OPERAND.  */
                    172: static inline unsigned
                    173: get_operand_fields_width (const aarch64_operand *operand)
                    174: {
                    175:   int i = 0;
                    176:   unsigned width = 0;
                    177:   while (operand->fields[i] != FLD_NIL)
                    178:     width += fields[operand->fields[i++]].width;
                    179:   assert (width > 0 && width < 32);
                    180:   return width;
                    181: }
                    182:
                    183: static inline const aarch64_operand *
                    184: get_operand_from_code (enum aarch64_opnd code)
                    185: {
                    186:   return aarch64_operands + code;
                    187: }
                    188: 
                    189: /* Operand qualifier and operand constraint checking.  */
                    190:
                    191: int aarch64_match_operands_constraint (aarch64_inst *,
                    192:                                       aarch64_operand_error *);
                    193:
                    194: /* Operand qualifier related functions.  */
                    195: const char* aarch64_get_qualifier_name (aarch64_opnd_qualifier_t);
                    196: unsigned char aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t);
                    197: aarch64_insn aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t);
                    198: int aarch64_find_best_match (const aarch64_inst *,
                    199:                             const aarch64_opnd_qualifier_seq_t *,
                    200:                             int, aarch64_opnd_qualifier_t *);
                    201:
                    202: static inline void
                    203: reset_operand_qualifier (aarch64_inst *inst, int idx)
                    204: {
                    205:   assert (idx >=0 && idx < aarch64_num_of_operands (inst->opcode));
                    206:   inst->operands[idx].qualifier = AARCH64_OPND_QLF_NIL;
                    207: }
                    208: 
                    209: /* Inline functions operating on instruction bit-field(s).  */
                    210:
                    211: /* Generate a mask that has WIDTH number of consecutive 1s.  */
                    212:
                    213: static inline aarch64_insn
                    214: gen_mask (int width)
                    215: {
1.1.1.2   christos  216:   return ((aarch64_insn) 1 << width) - 1;
1.1       christos  217: }
                    218:
                    219: /* LSB_REL is the relative location of the lsb in the sub field, starting from 0.  */
                    220: static inline int
                    221: gen_sub_field (enum aarch64_field_kind kind, int lsb_rel, int width, aarch64_field *ret)
                    222: {
                    223:   const aarch64_field *field = &fields[kind];
                    224:   if (lsb_rel < 0 || width <= 0 || lsb_rel + width > field->width)
                    225:     return 0;
                    226:   ret->lsb = field->lsb + lsb_rel;
                    227:   ret->width = width;
                    228:   return 1;
                    229: }
                    230:
                    231: /* Insert VALUE into FIELD of CODE.  MASK can be zero or the base mask
                    232:    of the opcode.  */
                    233:
                    234: static inline void
                    235: insert_field_2 (const aarch64_field *field, aarch64_insn *code,
                    236:                aarch64_insn value, aarch64_insn mask)
                    237: {
                    238:   assert (field->width < 32 && field->width >= 1 && field->lsb >= 0
                    239:          && field->lsb + field->width <= 32);
                    240:   value &= gen_mask (field->width);
                    241:   value <<= field->lsb;
                    242:   /* In some opcodes, field can be part of the base opcode, e.g. the size
                    243:      field in FADD.  The following helps avoid corrupt the base opcode.  */
                    244:   value &= ~mask;
                    245:   *code |= value;
                    246: }
                    247:
                    248: /* Extract FIELD of CODE and return the value.  MASK can be zero or the base
                    249:    mask of the opcode.  */
                    250:
                    251: static inline aarch64_insn
                    252: extract_field_2 (const aarch64_field *field, aarch64_insn code,
                    253:                 aarch64_insn mask)
                    254: {
                    255:   aarch64_insn value;
                    256:   /* Clear any bit that is a part of the base opcode.  */
                    257:   code &= ~mask;
                    258:   value = (code >> field->lsb) & gen_mask (field->width);
                    259:   return value;
                    260: }
                    261:
                    262: /* Insert VALUE into field KIND of CODE.  MASK can be zero or the base mask
                    263:    of the opcode.  */
                    264:
                    265: static inline void
                    266: insert_field (enum aarch64_field_kind kind, aarch64_insn *code,
                    267:              aarch64_insn value, aarch64_insn mask)
                    268: {
                    269:   insert_field_2 (&fields[kind], code, value, mask);
                    270: }
                    271:
                    272: /* Extract field KIND of CODE and return the value.  MASK can be zero or the
                    273:    base mask of the opcode.  */
                    274:
                    275: static inline aarch64_insn
                    276: extract_field (enum aarch64_field_kind kind, aarch64_insn code,
                    277:               aarch64_insn mask)
                    278: {
                    279:   return extract_field_2 (&fields[kind], code, mask);
                    280: }
                    281: 
                    282: /* Inline functions selecting operand to do the encoding/decoding for a
                    283:    certain instruction bit-field.  */
                    284:
                    285: /* Select the operand to do the encoding/decoding of the 'sf' field.
                    286:    The heuristic-based rule is that the result operand is respected more.  */
                    287:
                    288: static inline int
                    289: select_operand_for_sf_field_coding (const aarch64_opcode *opcode)
                    290: {
                    291:   int idx = -1;
                    292:   if (aarch64_get_operand_class (opcode->operands[0])
                    293:       == AARCH64_OPND_CLASS_INT_REG)
                    294:     /* normal case.  */
                    295:     idx = 0;
                    296:   else if (aarch64_get_operand_class (opcode->operands[1])
                    297:           == AARCH64_OPND_CLASS_INT_REG)
                    298:     /* e.g. float2fix.  */
                    299:     idx = 1;
                    300:   else
                    301:     { assert (0); abort (); }
                    302:   return idx;
                    303: }
                    304:
                    305: /* Select the operand to do the encoding/decoding of the 'type' field in
                    306:    the floating-point instructions.
                    307:    The heuristic-based rule is that the source operand is respected more.  */
                    308:
                    309: static inline int
                    310: select_operand_for_fptype_field_coding (const aarch64_opcode *opcode)
                    311: {
                    312:   int idx;
                    313:   if (aarch64_get_operand_class (opcode->operands[1])
                    314:       == AARCH64_OPND_CLASS_FP_REG)
                    315:     /* normal case.  */
                    316:     idx = 1;
                    317:   else if (aarch64_get_operand_class (opcode->operands[0])
                    318:           == AARCH64_OPND_CLASS_FP_REG)
                    319:     /* e.g. float2fix.  */
                    320:     idx = 0;
                    321:   else
                    322:     { assert (0); abort (); }
                    323:   return idx;
                    324: }
                    325:
                    326: /* Select the operand to do the encoding/decoding of the 'size' field in
                    327:    the AdvSIMD scalar instructions.
                    328:    The heuristic-based rule is that the destination operand is respected
                    329:    more.  */
                    330:
                    331: static inline int
                    332: select_operand_for_scalar_size_field_coding (const aarch64_opcode *opcode)
                    333: {
                    334:   int src_size = 0, dst_size = 0;
                    335:   if (aarch64_get_operand_class (opcode->operands[0])
                    336:       == AARCH64_OPND_CLASS_SISD_REG)
                    337:     dst_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][0]);
                    338:   if (aarch64_get_operand_class (opcode->operands[1])
                    339:       == AARCH64_OPND_CLASS_SISD_REG)
                    340:     src_size = aarch64_get_qualifier_esize (opcode->qualifiers_list[0][1]);
                    341:   if (src_size == dst_size && src_size == 0)
                    342:     { assert (0); abort (); }
                    343:   /* When the result is not a sisd register or it is a long operantion.  */
                    344:   if (dst_size == 0 || dst_size == src_size << 1)
                    345:     return 1;
                    346:   else
                    347:     return 0;
                    348: }
                    349:
                    350: /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
                    351:    the AdvSIMD instructions.  */
                    352:
                    353: int aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *);
                    354: 
                    355: /* Miscellaneous.  */
                    356:
                    357: aarch64_insn aarch64_get_operand_modifier_value (enum aarch64_modifier_kind);
                    358: enum aarch64_modifier_kind
                    359: aarch64_get_operand_modifier_from_value (aarch64_insn, bfd_boolean);
                    360:
                    361:
                    362: bfd_boolean aarch64_wide_constant_p (int64_t, int, unsigned int *);
                    363: bfd_boolean aarch64_logical_immediate_p (uint64_t, int, aarch64_insn *);
                    364: int aarch64_shrink_expanded_imm8 (uint64_t);
                    365:
                    366: /* Copy the content of INST->OPERANDS[SRC] to INST->OPERANDS[DST].  */
                    367: static inline void
                    368: copy_operand_info (aarch64_inst *inst, int dst, int src)
                    369: {
                    370:   assert (dst >= 0 && src >= 0 && dst < AARCH64_MAX_OPND_NUM
                    371:          && src < AARCH64_MAX_OPND_NUM);
                    372:   memcpy (&inst->operands[dst], &inst->operands[src],
                    373:          sizeof (aarch64_opnd_info));
                    374:   inst->operands[dst].idx = dst;
                    375: }
                    376:
                    377: /* A primitive log caculator.  */
                    378:
                    379: static inline unsigned int
                    380: get_logsz (unsigned int size)
                    381: {
                    382:   const unsigned char ls[16] =
                    383:     {0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4};
                    384:   if (size > 16)
                    385:     {
                    386:       assert (0);
                    387:       return -1;
                    388:     }
                    389:   assert (ls[size - 1] != (unsigned char)-1);
                    390:   return ls[size - 1];
                    391: }
                    392:
                    393: #endif /* OPCODES_AARCH64_OPC_H */

CVSweb <webmaster@jp.NetBSD.org>