X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-xgate.c;h=488ee4c39bbbb815760120885a6f360e2fb8ea0a;hb=bd920864f3dc2cad376989a642ab774aef6b2fce;hp=cbd65f21b04e1f2e17e47cbce474ac82c55d5431;hpb=9798e45d7ea5a1f702e7af18db9d3ee5a1d7b96d;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/config/tc-xgate.c b/gas/config/tc-xgate.c index cbd65f21b0..488ee4c39b 100644 --- a/gas/config/tc-xgate.c +++ b/gas/config/tc-xgate.c @@ -1,6 +1,5 @@ /* tc-xgate.c -- Assembler code for Freescale XGATE - Copyright 2010, 2011, 2012 - Free Software Foundation, Inc. + Copyright (C) 2010-2020 Free Software Foundation, Inc. Contributed by Sean Keys This file is part of GAS, the GNU Assembler. @@ -33,9 +32,12 @@ const char line_separator_chars[] = ""; const char EXP_CHARS[] = "eE"; const char FLT_CHARS[] = "dD"; -#define SIXTEENTH_BIT 0x8000 -#define N_BITS_IN_WORD 16 -#define MAX_NUM_OPERANDS 3 +/* Max opcodes per opcode handle. */ +#define MAX_OPCODES 0x05 + +#define SIXTEENTH_BIT 0x8000 +#define N_BITS_IN_WORD 16 +#define MAX_NUM_OPERANDS 3 /* #define STATE_CONDITIONAL_BRANCH (1) */ #define STATE_PC_RELATIVE (2) @@ -60,7 +62,8 @@ struct xgate_opcode_handle struct xgate_opcode *opc0[MAX_OPCODES]; }; -/* XGATE's registers all are 16-bit general purpose. They are numbered according to the specifications. */ +/* XGATE's registers all are 16-bit general purpose. + They are numbered according to the specifications. */ typedef enum register_id { REG_NONE = -1, @@ -95,43 +98,21 @@ typedef struct s_operand } s_operand; -/* LOCAL FUNCTIONS */ -static char * -xgate_parse_exp (char *, expressionS *); -static inline char * -skip_whitespace (char *); -static void -get_default_target (void); -static char * -extract_word (char *, char *, int); -static char * -xgate_new_instruction (int size); -unsigned short -xgate_apply_operand (unsigned short, unsigned short *, unsigned short, - unsigned char); -static struct xgate_opcode * -xgate_find_match (struct xgate_opcode_handle *, int, unsigned int); -static int -cmp_opcode (struct xgate_opcode *, struct xgate_opcode *); -void -xgate_print_syntax (char *); -void -xgate_print_table (void); -unsigned int -xgate_get_operands (char *, s_operand []); -static register_id -reg_name_search (char *); -op_modifiers -xgate_determine_modifiers(char **); - -void -xgate_scan_operands (struct xgate_opcode *opcode, s_operand []); +/* Forward declarations. */ +static inline char *skip_whitespace (char *); +static void get_default_target (void); +static char *extract_word (char *, char *, int); +static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *, + int, s_operand [], unsigned int); +static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *); +static void xgate_print_table (void); +static unsigned int xgate_get_operands (char *, s_operand []); +static register_id reg_name_search (char *); +static op_modifiers xgate_determine_modifiers (char **); +static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []); +static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int, + char **, s_operand); -static unsigned int -xgate_parse_operand (struct xgate_opcode *, int *, int where, char **, - s_operand); - -/* LOCAL DATA */ static struct hash_control *xgate_hash; /* Previous opcode. */ @@ -140,7 +121,7 @@ static unsigned int prev = 0; static unsigned char fixup_required = 0; /* Used to enable clipping of 16 bit operands into 8 bit constraints. */ -static unsigned char autoHiLo = 0; +static unsigned char autoHiLo = 0; static char oper_check; static char flag_print_insn_syntax = 0; @@ -210,16 +191,16 @@ struct option md_longopts[] = { NULL, no_argument, NULL, 0 } }; -size_t md_longopts_size = sizeof(md_longopts); +size_t md_longopts_size = sizeof (md_longopts); -char * +const char * md_atof (int type, char *litP, int *sizeP) { return ieee_md_atof (type, litP, sizeP, TRUE); } int -md_parse_option (int c, char *arg) +md_parse_option (int c, const char *arg) { switch (c) { @@ -231,7 +212,7 @@ md_parse_option (int c, char *arg) else if (strcasecmp (arg, "v3") == 0) current_architecture = XGATE_V3; else - as_bad (_(" architecture variant invalid")); + as_bad (_("architecture variant invalid")); break; case OPTION_PRINT_INSN_SYNTAX: @@ -294,11 +275,11 @@ get_default_target (void) if (target && target->name) { if (strcmp (target->name, "elf32-xgate") == 0) - { - current_architecture = cpuxgate; - default_cpu = "XGATE V1"; - return; - } + { + current_architecture = cpuxgate; + default_cpu = "XGATE V1"; + return; + } as_bad (_("Default target `%s' is not supported."), target->name); } @@ -310,68 +291,69 @@ md_begin (void) struct xgate_opcode *xgate_opcode_ptr = NULL; struct xgate_opcode *xgate_op_table = NULL; struct xgate_opcode_handle *op_handles = 0; - char *prev_op_name = 0; + const char *prev_op_name = 0; int handle_enum = 0; int number_of_op_handles = 0; int i, j = 0; /* Create a local copy of our opcode table including an extra line for NULL termination. */ - xgate_op_table = (struct xgate_opcode *) - xmalloc ((xgate_num_opcodes) * sizeof (struct xgate_opcode)); + xgate_op_table = XNEWVEC (struct xgate_opcode, xgate_num_opcodes); memset (xgate_op_table, 0, - sizeof(struct xgate_opcode) * (xgate_num_opcodes)); + sizeof (struct xgate_opcode) * (xgate_num_opcodes)); for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0; - i < xgate_num_opcodes; i++) + i < xgate_num_opcodes; i++) xgate_op_table[i] = xgate_opcode_ptr[i]; - qsort (xgate_op_table, xgate_num_opcodes, sizeof(struct xgate_opcode), + qsort (xgate_op_table, xgate_num_opcodes, sizeof (struct xgate_opcode), (int (*)(const void *, const void *)) cmp_opcode); /* Calculate number of handles since this will be smaller than the raw number of opcodes in the table. */ prev_op_name = ""; for (xgate_opcode_ptr = xgate_op_table, i = 0; i < xgate_num_opcodes; - xgate_opcode_ptr++, i++) + xgate_opcode_ptr++, i++) { if (strcmp (prev_op_name, xgate_opcode_ptr->name)) - number_of_op_handles++; + number_of_op_handles++; prev_op_name = xgate_opcode_ptr->name; } - op_handles = (struct xgate_opcode_handle *) - xmalloc (sizeof(struct xgate_opcode_handle) * (number_of_op_handles)); + op_handles = XNEWVEC (struct xgate_opcode_handle, number_of_op_handles); /* Insert unique opcode names into hash table, aliasing duplicates. */ xgate_hash = hash_new (); prev_op_name = ""; for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes; - i++, xgate_opcode_ptr++) + i++, xgate_opcode_ptr++) { if (!strcmp (prev_op_name, xgate_opcode_ptr->name)) - { - handle_enum++; - op_handles[j].opc0[handle_enum] = xgate_opcode_ptr; - } + { + handle_enum++; + op_handles[j].opc0[handle_enum] = xgate_opcode_ptr; + } else - { - handle_enum = 0; - if (i) - j++; - op_handles[j].name = xgate_opcode_ptr->name; - op_handles[j].opc0[0] = xgate_opcode_ptr; - hash_insert (xgate_hash, (char *) op_handles[j].name, - (char *) &(op_handles[j])); - } + { + handle_enum = 0; + if (i) + j++; + op_handles[j].name = xgate_opcode_ptr->name; + op_handles[j].opc0[0] = xgate_opcode_ptr; + hash_insert (xgate_hash, (char *) op_handles[j].name, + (char *) &(op_handles[j])); + } op_handles[j].number_of_modes = handle_enum; prev_op_name = op_handles[j].name; } - if (flag_print_opcodes == 1) - xgate_print_table (); + if (flag_print_opcodes) + { + xgate_print_table (); + exit (EXIT_SUCCESS); + } } void @@ -384,18 +366,17 @@ md_show_usage (FILE * stream) { get_default_target (); - fprintf ( - stream, + fprintf (stream, _("\ - Freescale XGATE co-processor options:\n \ - -mshort use 16-bit int ABI (default)\n \ - -mlong use 32-bit int ABI\n \ - -mshort-double use 32-bit double ABI\n \ - -mlong-double use 64-bit double ABI (default)\n\ - --mxgate specify the processor variant[default %s]\n\ - --print-insn-syntax print the syntax of instruction in case of error\n\ - --print-opcodes print the list of instructions with syntax\n\ - --generate-example generate an example of each instruction"), +Freescale XGATE co-processor options:\n\ + -mshort use 16-bit int ABI (default)\n\ + -mlong use 32-bit int ABI\n\ + -mshort-double use 32-bit double ABI\n\ + -mlong-double use 64-bit double ABI (default)\n\ + --mxgate specify the processor variant [default %s]\n\ + --print-insn-syntax print the syntax of instruction in case of error\n\ + --print-opcodes print the list of instructions with syntax\n\ + --generate-example generate an example of each instruction"), default_cpu); } @@ -412,7 +393,7 @@ xgate_mach (void) return 0; } -void +static void xgate_print_syntax (char *name) { int i; @@ -420,40 +401,40 @@ xgate_print_syntax (char *name) for (i = 0; i < xgate_num_opcodes; i++) { if (!strcmp (xgate_opcodes[i].name, name)) - { - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR)) - printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n", + { + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR)) + printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH)) - printf ("\tFormat is %s\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI)) - printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA)) - printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3)) - printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4)) - printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8)) - printf ("\tFormat is %s\tRx, <8-bit value>\n", + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH)) + printf ("\tFormat is %s\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI)) + printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA)) + printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3)) + printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4)) + printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8)) + printf ("\tFormat is %s\tRx, <8-bit value>\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16)) - printf ("\tFormat is %s\tRx, <16-bit value>\n", + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16)) + printf ("\tFormat is %s\tRx, <16-bit value>\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C)) - printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R)) - printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P)) - printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name); - if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW)) - printf ("\tFormat is %s\tRx, <16-bit value>\n", + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C)) + printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R)) + printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P)) + printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name); + if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW)) + printf ("\tFormat is %s\tRx, <16-bit value>\n", xgate_opcodes[i].name); - } + } } } -void +static void xgate_print_table (void) { int i; @@ -476,7 +457,7 @@ xgate_listing_header (void) symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { - return 0; + return NULL; } /* GAS will call this function for each section at the end of the assembly, @@ -485,8 +466,8 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED) valueT md_section_align (asection * seg, valueT addr) { - int align = bfd_get_section_alignment (stdoutput, seg); - return ((addr + (1 << align) - 1) & (-1 << align)); + int align = bfd_section_alignment (seg); + return ((addr + (1 << align) - 1) & -(1 << align)); } void @@ -498,21 +479,21 @@ md_assemble (char *input_line) /* Caller expects it to be returned as it was passed. */ char *saved_input_line = input_line; char op_name[9] = { 0 }; - unsigned int sh_format = 0; + unsigned int operandCount = 0; char *p = 0; s_operand new_operands[MAX_NUM_OPERANDS]; fixup_required = 0; oper_check = 0; /* set error flags */ - input_line = extract_word (input_line, op_name, sizeof(op_name)); + input_line = extract_word (input_line, op_name, sizeof (op_name)); /* Check to make sure we are not reading a bogus line. */ if (!op_name[0]) as_bad (_("opcode missing or not found on input line")); if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash, - op_name))) + op_name))) { as_bad (_("opcode %s not found in opcode hash table"), op_name); } @@ -520,64 +501,65 @@ md_assemble (char *input_line) { /* Parse operands so we can find the proper opcode bin. */ - sh_format = xgate_get_operands(input_line, new_operands); + operandCount = xgate_get_operands (input_line, new_operands); opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes, - sh_format); + new_operands, operandCount); if (!opcode) - { - as_bad (_("matching operands to opcode ")); - xgate_print_syntax (opcode_handle->opc0[0]->name); - } + { + as_bad (_("matching operands to opcode")); + xgate_print_syntax (opcode_handle->opc0[0]->name); + } else if (opcode->size == 2) - { + { /* Size is one word - assemble that native insn. */ - xgate_scan_operands (opcode, new_operands); - } + xgate_scan_operands (opcode, new_operands); + } else - { + { /* Insn is a simplified instruction - expand it out. */ - autoHiLo = 1; - unsigned int i; - - /* skip past our ';' separator. */ - for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0; - i--, p++) - { - if (*p == ';') - { - p++; - break; - } - } - input_line = skip_whitespace (input_line); - char *macro_inline = input_line; - - /* Loop though the macro's opcode list and apply operands to each real opcode. */ - for (i = 0; *p && i < (opcode->size / 2); i++) - { + autoHiLo = 1; + unsigned int i; + + /* skip past our ';' separator. */ + for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0; + i--, p++) + { + if (*p == ';') + { + p++; + break; + } + } + input_line = skip_whitespace (input_line); + char *macro_inline = input_line; + + /* Loop though the macro's opcode list and apply operands to + each real opcode. */ + for (i = 0; *p && i < (opcode->size / 2); i++) + { /* Loop though macro operand list. */ - input_line = macro_inline; /* Rewind. */ - p = extract_word (p, op_name, 10); + input_line = macro_inline; /* Rewind. */ + p = extract_word (p, op_name, 10); - if (!(opcode_handle = (struct xgate_opcode_handle *) + if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash, op_name))) - { - as_bad ( - _(": processing macro, real opcode handle not found in hash")); - break; - } - else - { - sh_format = xgate_get_operands(input_line, new_operands); - macro_opcode = xgate_find_match (opcode_handle, - opcode_handle->number_of_modes, sh_format); - xgate_scan_operands (macro_opcode, new_operands); - - } - } - } + { + as_bad (_(": processing macro, real opcode handle" + " not found in hash")); + break; + } + else + { + operandCount = xgate_get_operands (input_line, new_operands); + macro_opcode = xgate_find_match (opcode_handle, + opcode_handle->number_of_modes, new_operands, + operandCount); + xgate_scan_operands (macro_opcode, new_operands); + } + } + } } autoHiLo = 0; input_line = saved_input_line; @@ -592,18 +574,17 @@ md_estimate_size_before_relax (fragS *fragp, asection *seg) /* If symbol is undefined or located in a different section, select the largest supported relocation. */ relax_substateT subtype; - relax_substateT rlx_state[] = - { 0, 2 }; + relax_substateT rlx_state[] = { 0, 2 }; for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2) { if (fragp->fr_subtype == rlx_state[subtype] - && (!S_IS_DEFINED (fragp->fr_symbol) - || seg != S_GET_SEGMENT (fragp->fr_symbol))) - { - fragp->fr_subtype = rlx_state[subtype + 1]; - break; - } + && (!S_IS_DEFINED (fragp->fr_symbol) + || seg != S_GET_SEGMENT (fragp->fr_symbol))) + { + fragp->fr_subtype = rlx_state[subtype + 1]; + break; + } } if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table)) @@ -633,25 +614,21 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) { arelent * reloc; - reloc = (arelent *) xmalloc (sizeof(arelent)); - reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof(asymbol *)); + reloc = XNEW (arelent); + reloc->sym_ptr_ptr = XNEW (asymbol *); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; if (fixp->fx_r_type == 0) - { - reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); - } + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); else - { - reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); - } + reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (reloc->howto == (reloc_howto_type *) NULL) { as_bad_where (fixp->fx_file, fixp->fx_line, _ - ("Relocation %d is not supported by object file format."), - (int) fixp->fx_r_type); + ("Relocation %d is not supported by object file format."), + (int) fixp->fx_r_type); return NULL; } @@ -676,11 +653,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED) int opcode = 0; ldiv_t result; - /* If the fixup is done mark it done so no further symbol resolution will take place. */ + /* If the fixup is done mark it done so no further symbol resolution + will take place. */ if (fixP->fx_addsy == (symbolS *) NULL) - { - fixP->fx_done = 1; - } + fixP->fx_done = 1; /* We don't actually support subtracting a symbol. */ if (fixP->fx_subsy != (symbolS *) NULL) @@ -692,29 +668,37 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED) switch (fixP->fx_r_type) { - case R_XGATE_PCREL_9: + case BFD_RELOC_XGATE_PCREL_9: if (value < -512 || value > 511) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Value %ld too large for 9-bit PC-relative branch."), value); + _("Value %ld too large for 9-bit PC-relative branch."), + value); result = ldiv (value, 2); /* from bytes to words */ value = result.quot; if (result.rem) as_bad_where (fixP->fx_file, fixP->fx_line, _ - ("Value %ld not aligned by 2 for 9-bit PC-relative branch."), value); - mask = 0x1FF; /* Clip into 8-bit field FIXME I'm sure there is a more proper place for this */ + ("Value %ld not aligned by 2 for 9-bit" + " PC-relative branch."), value); + /* Clip into 8-bit field. + FIXME I'm sure there is a more proper place for this. */ + mask = 0x1FF; value &= mask; number_to_chars_bigendian (where, (opcode | value), 2); break; - case R_XGATE_PCREL_10: + case BFD_RELOC_XGATE_PCREL_10: if (value < -1024 || value > 1023) as_bad_where (fixP->fx_file, fixP->fx_line, - _("Value %ld too large for 10-bit PC-relative branch."), value); + _("Value %ld too large for 10-bit PC-relative branch."), + value); result = ldiv (value, 2); /* from bytes to words */ value = result.quot; if (result.rem) as_bad_where (fixP->fx_file, fixP->fx_line, _ - ("Value %ld not aligned by 2 for 10-bit PC-relative branch."), value); - mask = 0x3FF; /* Clip into 9-bit field FIXME I'm sure there is a more proper place for this */ + ("Value %ld not aligned by 2 for 10-bit" + " PC-relative branch."), value); + /* Clip into 9-bit field. + FIXME I'm sure there is a more proper place for this. */ + mask = 0x3FF; value &= mask; number_to_chars_bigendian (where, (opcode | value), 2); break; @@ -850,7 +834,7 @@ extract_word (char *from, char *to, int limit) { to[size++] = *op_end++; if (size + 1 >= limit) - break; + break; } to[size] = 0; return op_end; @@ -864,7 +848,7 @@ xgate_new_instruction (int size) return f; } -unsigned short +static unsigned short xgate_apply_operand (unsigned short new_mask, unsigned short *availiable_mask_bits, unsigned short mask, @@ -873,13 +857,15 @@ xgate_apply_operand (unsigned short new_mask, unsigned short n_shifts; unsigned int n_drop_bits; - /* Shift until you find an available operand bit "1" and record the number of shifts. */ + /* Shift until you find an available operand bit "1" and record + the number of shifts. */ for (n_shifts = 0; !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16; n_shifts++) *availiable_mask_bits <<= 1; - /* Shift for the number of bits your operand requires while bits are available. */ + /* Shift for the number of bits your operand requires while bits + are available. */ for (n_drop_bits = n_bits; n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT); --n_drop_bits) @@ -903,7 +889,8 @@ static char * xgate_parse_exp (char *s, expressionS * op) { input_line_pointer = s; - expression(op); + + expression (op); if (op->X_op == O_absent) as_bad (_("missing operand")); return input_line_pointer; @@ -917,8 +904,7 @@ cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2) static struct xgate_opcode * xgate_find_match (struct xgate_opcode_handle *opcode_handle, - int numberOfModes, - unsigned int sh_format) + int numberOfModes, s_operand oprs[], unsigned int operandCount) { int i; @@ -926,10 +912,88 @@ xgate_find_match (struct xgate_opcode_handle *opcode_handle, return opcode_handle->opc0[0]; for (i = 0; i <= numberOfModes; i++) - if (opcode_handle->opc0[i]->sh_format & sh_format) - return opcode_handle->opc0[i]; - - return NULL; + { + switch (operandCount) + { + case 0: + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_INH)) + return opcode_handle->opc0[i]; + break; + case 1: + if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) + { + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON)) + return opcode_handle->opc0[i]; + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON)) + return opcode_handle->opc0[i]; + } + if (oprs[0].reg == REG_NONE) + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3)) + return opcode_handle->opc0[i]; + break; + case 2: + if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) + { + if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7) + { + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA)) + return opcode_handle->opc0[i]; + } + if (oprs[1].reg == REG_CCR) + if (!strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_MON_R_C)) + return opcode_handle->opc0[i]; + if (oprs[1].reg == REG_PC) + if (!strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_MON_R_P)) + return opcode_handle->opc0[i]; + if (oprs[1].reg == REG_NONE) + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16) + || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8) + || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IMM16mADD) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IMM16mAND) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IMM16mCPC) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IMM16mSUB) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IMM16mLDW)) + return opcode_handle->opc0[i]; + } + if (oprs[0].reg == REG_CCR) + if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R)) + return opcode_handle->opc0[i]; + break; + case 3: + if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) + { + if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7) + { + if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7) + { + if (!strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IDR) + || !strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_TRI)) + return opcode_handle->opc0[i]; + } + + if (oprs[2].reg == REG_NONE) + if (!strcmp (opcode_handle->opc0[i]->constraints, + XGATE_OP_IDO5)) + return opcode_handle->opc0[i]; + } + } + break; + default: + as_bad (_("unknown operand count")); + break; + } + } + return NULL ; } /* Because we are dealing with two different core that view the system @@ -945,7 +1009,7 @@ xgate_frob_symbol (symbolS *sym) bfdsym = symbol_get_bfdsym (sym); elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); - gas_assert(elfsym); + gas_assert (elfsym); /* Mark the symbol as being *from XGATE */ elfsym->internal_elf_sym.st_target_internal = 1; @@ -953,87 +1017,46 @@ xgate_frob_symbol (symbolS *sym) return 0; } -unsigned int +static unsigned int xgate_get_operands (char *line, s_operand oprs[]) { int num_operands; /* If there are no operands, then it must be inherent. */ if (*line == 0 || *line == '\n' || *line == '\r') - return XG_INH; + return 0; for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS); - num_operands++) + num_operands++) { line = skip_whitespace (line); if (*line == '#') - line++; + line++; oprs[num_operands].mod = xgate_determine_modifiers (&line); if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE) - line = xgate_parse_exp (line, &oprs[num_operands].exp); + line = xgate_parse_exp (line, &oprs[num_operands].exp); /* skip to next operand */ while (*line != 0) - { - if (*line == ',') - { - line++; - break; - } - line++; - } + { + if (*line == ',') + { + line++; + break; + } + line++; + } } - if (num_operands > MAX_NUM_OPERANDS) return 0; - - switch (num_operands) - { - case 1: - if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) - return XG_R; - if (oprs[0].reg == REG_NONE) - return XG_I; - break; - case 2: - if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) - { - if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7) - return XG_R_R; - if (oprs[1].reg == REG_CCR) - return XG_R_C; - if (oprs[1].reg == REG_PC) - return XG_R_P; - if (oprs[1].reg == REG_NONE) - return XG_R_I; - } - if (oprs[0].reg == REG_CCR) - return XG_C_R; - break; - case 3: - if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7) - { - if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7) - { - if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7) - return XG_R_R_R; - if (oprs[2].reg >= REG_NONE) - return XG_R_R_I; - } - } - break; - default: - as_bad (_("unknown operand format")); - break; - } - - return 0; + return num_operands; } /* reg_name_search() finds the register number given its name. Returns the register number or REG_NONE on failure. */ + static register_id reg_name_search (char *name) { @@ -1062,8 +1085,8 @@ reg_name_search (char *name) /* Parse operand modifiers such as inc/dec/hi/low. */ -op_modifiers -xgate_determine_modifiers(char **line) +static op_modifiers +xgate_determine_modifiers (char **line) { char *local_line = line[0]; @@ -1078,18 +1101,18 @@ xgate_determine_modifiers(char **line) return MOD_LOAD_LOW; } if (*(local_line + 2) == '+') - return MOD_POSTINC; + return MOD_POSTINC; if (strncasecmp (local_line, "-r", 2) == 0) { *line += 1; return MOD_PREDEC; - } + } return MOD_NONE; } /* Parse instruction operands. */ -void +static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[]) { char *frag = xgate_new_instruction (opcode->size); @@ -1108,67 +1131,70 @@ xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[]) for (i = 0; (c = opcode->format[i]); i++) { if (ISDIGIT (c) || (c == 's')) - { - oper_mask <<= 1; - } + { + oper_mask <<= 1; + } else - { - oper_mask <<= 1; - oper_mask += 1; - n_operand_bits++; - } + { + oper_mask <<= 1; + oper_mask += 1; + n_operand_bits++; + } } /* Parse first operand. */ if (*op) { if (*op == '=') - { - first_operand_equals_second = 1; - ++op; - } - operand = xgate_parse_operand (opcode, &operand_bit_length, where, &op, oprs[0]); + { + first_operand_equals_second = 1; + ++op; + } + operand = xgate_parse_operand (opcode, &operand_bit_length, where, + &op, oprs[0]); ++op; bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length); - if(first_operand_equals_second) - bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length); + if (first_operand_equals_second) + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); /* Parse second operand. */ if (*op) - { - if (*op == ',') - ++op; - if (first_operand_equals_second) - { - bin = xgate_apply_operand (operand, &oper_mask, bin, - operand_bit_length); - ++op; - } - else - { - operand = xgate_parse_operand (opcode, &operand_bit_length, where, - &op, oprs[1]); - bin = xgate_apply_operand (operand, &oper_mask, bin, - operand_bit_length); - ++op; - } - } + { + if (*op == ',') + ++op; + if (first_operand_equals_second) + { + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + ++op; + } + else + { + operand = xgate_parse_operand (opcode, &operand_bit_length, where, + &op, oprs[1]); + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + ++op; + } + } /* Parse the third register. */ if (*op) - { - if (*op == ',') - ++op; - operand = xgate_parse_operand (opcode, &operand_bit_length, where, &op, - oprs[2]); - bin = xgate_apply_operand (operand, &oper_mask, bin, - operand_bit_length); - } + { + if (*op == ',') + ++op; + operand = xgate_parse_operand (opcode, &operand_bit_length, where, + &op, oprs[2]); + bin = xgate_apply_operand (operand, &oper_mask, bin, + operand_bit_length); + } } if (opcode->size == 2 && fixup_required) { bfd_putl16 (bin, frag); } - else if ((opcode->sh_format & XG_PCREL)) + else if ( !strcmp (opcode->constraints, XGATE_OP_REL9) + || !strcmp (opcode->constraints, XGATE_OP_REL10)) { /* Write our data to a frag for further processing. */ bfd_putl16 (opcode->bin_opcode, frag); @@ -1185,10 +1211,10 @@ xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[]) static unsigned int xgate_parse_operand (struct xgate_opcode *opcode, - int *bit_width, - int where, - char **op_con, - s_operand operand) + int *bit_width, + int where, + char **op_con, + s_operand operand) { char *op_constraint = *op_con; unsigned int op_mask = 0; @@ -1207,23 +1233,23 @@ xgate_parse_operand (struct xgate_opcode *opcode, *bit_width = 5; if (operand.reg == REG_NONE) - as_bad (_(": expected register name r0-r7 ") ); + as_bad (_(": expected register name r0-r7 ") ); op_mask = operand.reg; - if(operand.mod == MOD_POSTINC) - pp_fix = INCREMENT; - if(operand.mod == MOD_PREDEC) - pp_fix = DECREMENT; + if (operand.mod == MOD_POSTINC) + pp_fix = INCREMENT; + if (operand.mod == MOD_PREDEC) + pp_fix = DECREMENT; op_mask <<= 2; op_mask |= pp_fix; break; case 'r': /* Register operand. */ - if (operand.reg == REG_NONE) - as_bad (_(": expected register name r0-r7 ")); + if (operand.reg == REG_NONE) + as_bad (_(": expected register name r0-r7 ")); - *bit_width = 3; + *bit_width = 3; - op_mask = operand.reg; + op_mask = operand.reg; break; case 'i': /* Immediate value or expression expected. */ @@ -1231,99 +1257,75 @@ xgate_parse_operand (struct xgate_opcode *opcode, (*op_con)++; op_constraint++; if (ISDIGIT (*op_constraint)) - { - *bit_width = (int) *op_constraint - '0'; - } + *bit_width = (int) *op_constraint - '0'; else if (*op_constraint == 'a') - { - *bit_width = 0x0A; - } + *bit_width = 0x0A; else if (*op_constraint == 'f') - { - *bit_width = 0x0F; - } + *bit_width = 0x0F; + /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */ if (operand.exp.X_op == O_constant) - { - op_mask = operand.exp.X_add_number; - if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo) - || operand.mod == MOD_LOAD_LOW) - { - op_mask &= 0x00FF; - } - else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' - && autoHiLo) || operand.mod == MOD_LOAD_HIGH) - { - op_mask >>= 8; - } - - /* Make sure it fits. */ - for (i = *bit_width; i; i--) - { - max_size <<= 1; - max_size += 1; - } - if (op_mask > max_size) - as_bad (_(":operand value(%d) too big for constraint"), op_mask); - } + { + op_mask = operand.exp.X_add_number; + if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo) + || operand.mod == MOD_LOAD_LOW) + op_mask &= 0x00FF; + else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' + && autoHiLo) || operand.mod == MOD_LOAD_HIGH) + op_mask >>= 8; + + /* Make sure it fits. */ + for (i = *bit_width; i; i--) + { + max_size <<= 1; + max_size += 1; + } + if (op_mask > max_size) + as_bad (_(":operand value(%d) too big for constraint"), op_mask); + } else - { - /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24 - TODO fix. */ - fixup_required = 1; - if (*op_constraint == '8') - { - if (((opcode->name[strlen (opcode->name) - 1] == 'l') - && autoHiLo) || operand.mod == MOD_LOAD_LOW) - { - fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, - BFD_RELOC_XGATE_24); - } - else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' - && autoHiLo) || operand.mod == MOD_LOAD_HIGH ) - { - fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, - BFD_RELOC_XGATE_IMM8_HI); - } - else - { - as_bad (_("you must use a hi/lo directive or 16-bit macro " - "to load a 16-bit value.")); - break; - } - } - else if (*op_constraint == '5') - { - fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, - BFD_RELOC_XGATE_IMM5); - } - else if (*op_constraint == '4') - { - fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, - BFD_RELOC_XGATE_IMM4); - } - else if (*op_constraint == '3') - { - fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, - BFD_RELOC_XGATE_IMM3); - } - else - { - as_bad (_(":unknown relocation constraint size")); - } - } + { + /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24 + TODO fix. */ + fixup_required = 1; + if (*op_constraint == '8') + { + if (((opcode->name[strlen (opcode->name) - 1] == 'l') + && autoHiLo) || operand.mod == MOD_LOAD_LOW) + fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, + BFD_RELOC_XGATE_24); + else if (((opcode->name[strlen (opcode->name) - 1]) == 'h' + && autoHiLo) || operand.mod == MOD_LOAD_HIGH ) + fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, + BFD_RELOC_XGATE_IMM8_HI); + else + as_bad (_("you must use a hi/lo directive or 16-bit macro " + "to load a 16-bit value.")); + } + else if (*op_constraint == '5') + fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, + BFD_RELOC_XGATE_IMM5); + else if (*op_constraint == '4') + fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, + BFD_RELOC_XGATE_IMM4); + else if (*op_constraint == '3') + fix_new_exp (frag_now, where, 2, &operand.exp, FALSE, + BFD_RELOC_XGATE_IMM3); + else + as_bad (_(":unknown relocation constraint size")); + } break; case 'c': /* CCR register expected. */ *bit_width = 0; if (operand.reg != REG_CCR) - as_bad (_(": expected register name ccr ")); + as_bad (_(": expected register name ccr ")); break; case 'p': /* PC register expected. */ *bit_width = 0; - if (operand.reg != REG_PC) - as_bad (_(": expected register name pc ")); + if (operand.reg != REG_PC) + as_bad (_(": expected register name pc ")); break; case 'b': /* Branch expected. */ @@ -1331,22 +1333,17 @@ xgate_parse_operand (struct xgate_opcode *opcode, op_constraint++; if (operand.exp.X_op != O_register) - { - if (*op_constraint == '9') - { - fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, - R_XGATE_PCREL_9); - } - else if (*op_constraint == 'a') - { - fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, - R_XGATE_PCREL_10); - } - } + { + if (*op_constraint == '9') + fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, + BFD_RELOC_XGATE_PCREL_9); + else if (*op_constraint == 'a') + fix_new_exp (frag_now, where, 2, &operand.exp, TRUE, + BFD_RELOC_XGATE_PCREL_10); + } else - { - as_fatal (_("Operand `%x' not recognized in fixup8."), operand.exp.X_op); - } + as_fatal (_("Operand `%x' not recognized in fixup8."), + operand.exp.X_op); break; case '?': break;