diff options
author | Doug Evans <dje@google.com> | 1998-02-19 22:51:08 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 1998-02-19 22:51:08 +0000 |
commit | 915729414dc1941450059d4629f0e345a197c5d2 (patch) | |
tree | fec4c2dce3741a326be2ad39bbaed93cbea08819 | |
parent | 63705534458c69ee02b79c6fd9a87b43e6d6bb84 (diff) | |
download | gdb-915729414dc1941450059d4629f0e345a197c5d2.zip gdb-915729414dc1941450059d4629f0e345a197c5d2.tar.gz gdb-915729414dc1941450059d4629f0e345a197c5d2.tar.bz2 |
* config/tc-dvp.c (LOCAL_LABEL_PREFIX,END_LABEL_PREFIX): New macros.
(inline_dmadata): Renamed from s_dmadata_implied.
(assemble_one_insn): Rewrite dma operand processing.
(md_apply_fix3): Handle DVP_OPERAND_DMA_NEXT.
(unique_name,setup_autocount): New functions.
-rw-r--r-- | gas/ChangeLog | 22 | ||||
-rw-r--r-- | gas/config/tc-dvp.c | 385 |
2 files changed, 216 insertions, 191 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 451455a..655840f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,25 @@ +start-sanitize-sky +Thu Feb 19 02:17:03 1998 Doug Evans <devans@charmed.cygnus.com> + + * config/tc-dvp.c (LOCAL_LABEL_PREFIX,END_LABEL_PREFIX): New macros. + (inline_dmadata): Renamed from s_dmadata_implied. + (assemble_one_insn): Rewrite dma operand processing. + (md_apply_fix3): Handle DVP_OPERAND_DMA_NEXT. + (unique_name,setup_autocount): New functions. + + * config/tc-dvp.c: Include stdarg.h/varargs.h. + (md_pseudo_table): Add .word. + (assemble_dma): Set alignment to 16 bytes. Enable code that records + fixups. + (assemble_one_insn): Handle DVP_OPERAND_DMA_{ADDR,AUTOCOUNT}. + (md_apply_fix3): Handle DVP_OPERAND_DMA_ADDR. + (parse_dma_addr_autocount): Renamed from parse_dma_ptr_autocount. + Rewrite. + (eval_expr): New function. + (create_label,create_colon_label): New function. + (s_enddmadata): Rewrite. + +end-sanitize-sky Wed Feb 18 23:39:46 1998 Richard Henderson <rth@cygnus.com> * Makefile.am (install-exec-local): Install properly when ln diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c index 0d3f193..0718731 100644 --- a/gas/config/tc-dvp.c +++ b/gas/config/tc-dvp.c @@ -38,12 +38,19 @@ /* Compute DMA operand index number of OP. */ #define DMA_OPERAND_INDEX(op) ((op) - dma_operands) +/* Our local label prefix. */ +#define LOCAL_LABEL_PREFIX ".L" +/* Label prefix for end markers used in autocounts. */ +#define END_LABEL_PREFIX ".L.end." + static long parse_float PARAMS ((char **, const char **)); static struct symbol * create_label PARAMS ((const char *, const char *)); static struct symbol * create_colon_label PARAMS ((const char *, const char *)); +static char * unique_name PARAMS ((void)); static long eval_expr PARAMS ((int, int, const char *, ...)); -static long parse_dma_ild_autocount (); static long parse_dma_addr_autocount (); +static void inline_dmadata PARAMS ((int, DVP_INSN *)); +static void setup_autocount PARAMS ((const char *, DVP_INSN *)); static void insert_operand PARAMS ((dvp_cpu, const dvp_opcode *, const dvp_operand *, int, @@ -73,6 +80,11 @@ typedef enum { } asm_state; static asm_state cur_asm_state = ASM_INIT; +/* Nonzero if inside .DmaData. */ +static int dmadata_state = 0; +/* Label of .DmaData (internally generated for inline data). */ +static const char *dmadata_name; + /* For variable length instructions, pointer to the initial frag and pointer into that frag. These only hold valid values if cur_asm_state is one of ASM_MPG, ASM_DIRECT, ASM_UNPACK. */ @@ -139,7 +151,6 @@ static subsegT prev_subseg; static segT prev_seg; static void s_dmadata PARAMS ((int)); -static void s_dmadata_implied PARAMS ((int)); static void s_enddmadata PARAMS ((int)); static void s_dmapackvif PARAMS ((int)); static void s_enddirect PARAMS ((int)); @@ -565,7 +576,7 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) start = str = *pstr; for ( ; opcode != NULL; opcode = DVP_OPCODE_NEXT_ASM (opcode)) { - int past_opcode_p, num_suffixes, num_operands; + int past_opcode_p, num_suffixes; const unsigned char *syn; /* Ensure the mnemonic part matches. */ @@ -578,11 +589,10 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) /* Scan the syntax string. If it doesn't match, try the next one. */ dvp_opcode_init_parse (); - insn_buf[ opcode->opcode_word] = opcode->value; + insn_buf[opcode->opcode_word] = opcode->value; fixup_count = 0; past_opcode_p = 0; num_suffixes = 0; - num_operands = 0; /* We don't check for (*str != '\0') here because we want to parse any trailing fake arguments in the syntax string. */ @@ -623,6 +633,15 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) if (operand->flags & DVP_OPERAND_FAKE) { long value = 0; + + if (operand->flags & DVP_OPERAND_DMA_INLINE) + { + inline_dmadata ((mods & DVP_OPERAND_AUTOCOUNT) != 0, + insn_buf); + ++syn; + continue; + } + if (operand->parse) { errmsg = NULL; @@ -690,23 +709,6 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) if (operand->flags & DVP_OPERAND_SUFFIX) as_fatal ("bad opcode table, suffix wrong"); -#if 0 /* commas are in the syntax string now */ - /* If this is not the first, there must be a comma. */ - if (num_operands > 0) - { - if (*str != ',') - break; - ++str; - } -#endif - - if (operand->flags & DVP_OPERAND_DMA_ILD) - { - s_dmadata_implied (0); - ++syn; - break; - } - /* Is there anything left to parse? We don't check for this at the top because we want to parse any trailing fake arguments in the syntax string. */ @@ -722,16 +724,8 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) if (errmsg) break; } - else if (operand->flags & DVP_OPERAND_DMA_ILD_AUTOCOUNT) - { - errmsg = 0; - value = parse_dma_ild_autocount (opcode, operand, mods, - insn_buf, &str, &errmsg); - if (errmsg) - break; - } - else if ((operand->flags & (DVP_OPERAND_DMA_ADDR | DVP_OPERAND_DMA_AUTOCOUNT)) - == (DVP_OPERAND_DMA_ADDR | DVP_OPERAND_DMA_AUTOCOUNT)) + else if ((operand->flags & DVP_OPERAND_DMA_ADDR) + && (mods & DVP_OPERAND_AUTOCOUNT)) { errmsg = 0; value = parse_dma_addr_autocount (opcode, operand, mods, @@ -791,7 +785,6 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) break; ++syn; - ++num_operands; } } @@ -1017,7 +1010,8 @@ md_apply_fix3 (fixP, valueP, seg) && operand->shift == 0); fixP->fx_r_type = BFD_RELOC_MIPS_DVP_11_PCREL; } - else if ((operand->flags & DVP_OPERAND_DMA_ADDR) != 0) + else if ((operand->flags & DVP_OPERAND_DMA_ADDR) != 0 + || (operand->flags & DVP_OPERAND_DMA_NEXT) != 0) { assert (operand->bits == 27 && operand->shift == 4); @@ -1166,6 +1160,8 @@ md_atof (type, litP, sizeP) return 0; } +/* Miscellaneous utilities. */ + /* Parse a 32 bit floating point number. The result is those 32 bits as an integer. */ @@ -1181,34 +1177,9 @@ parse_float (pstr, errmsg) *pstr = p; return (words[0] << 16) | words[1]; } - -/* Compute the auto-count value for a DMA tag with inline data. */ - -static long -parse_dma_ild_autocount (opcode, operand, mods, insn_buf, pstr, errmsg) - const dvp_opcode *opcode; - const dvp_operand *operand; - int mods; - DVP_INSN *insn_buf; - char **pstr; - const char **errmsg; -{ - char *start = *pstr; - char *end = start; - long retval; - -#if 0 - /* FIXME: unfinished */ - evaluate the operand as an expression - store the value to the count field - compute the length as _$EndDma-. -#endif - *pstr = end; - return 0; -} +/* Scan a symbol and return a pointer to one past the end. */ -/* Scan a symbol and return a pointer to one past the end. */ #define issymchar(ch) (isalnum(ch) || ch == '_') static char * scan_symbol (sym) @@ -1219,60 +1190,6 @@ scan_symbol (sym) return sym; } -/* Compute the auto-count value for a DMA tag with out-of-line data. */ - -static long -parse_dma_addr_autocount (opcode, operand, mods, insn_buf, pstr, errmsg) - const dvp_opcode *opcode; - const dvp_operand *operand; - int mods; - DVP_INSN *insn_buf; - char **pstr; - const char **errmsg; -{ - char *start = *pstr; - char *end = start; - long retval; - /* Data reference must be a .DmaData label. */ - struct symbol *label, *label2, *endlabel; - const char *name; - char *name2; - int len; - long count; - char c; - - label = label2 = 0; - if (! is_name_beginner (*start)) - { - *errmsg = "invalid .DmaData label"; - return 0; - } - - name = start; - end = scan_symbol (name); - c = *end; - *end = 0; - label = symbol_find_or_make (name); - *end = c; - - label2 = create_label ("_$", name); - /* FIXME: revisit .L. */ - endlabel = create_label (".L.end.", name); - - retval = eval_expr (dma_operand_addr, operand->word * 4, name); - count = eval_expr (dma_operand_count, (operand->word + 1) * 4, - ".L.end.%s - %s", name, name); - /* count is in quadwords */ - count /= 16; - - /* Store the count field. */ - insn_buf[3] &= 0xffff0000; - insn_buf[3] |= count & 0x0000ffff; - - *pstr = end; - return retval; -} - /* Evaluate an expression. The result is the value of the expression if it can be evaluated, or 0 if it cannot (say because some symbols haven't been defined yet) @@ -1357,6 +1274,166 @@ create_colon_label (prefix, name) free (fullname); return result; } + +/* Return a malloc'd string useful in creating unique labels. */ +/* ??? Presumably such a routine already exists somewhere + [but a first pass at finding it didn't turn up anything]. */ + +static char * +unique_name () +{ + static int counter; + char *result; + + asprintf (&result, "dvptmp%d", counter); + ++counter; + return result; +} + +/* Compute the auto-count value for a DMA tag. */ + +static void +setup_autocount (name, insn_buf) + const char *name; + DVP_INSN *insn_buf; +{ + long count; + + count = eval_expr (dma_operand_count, 12, + "(%s%s - %s) >> 4", END_LABEL_PREFIX, name, name); + /* count is in quadwords */ + count /= 16; + + /* Store the count field. */ + insn_buf[3] &= 0xffff0000; + insn_buf[3] |= count & 0x0000ffff; +} + +/* Record that inline data follows. */ + +static void +inline_dmadata (autocount_p, insn_buf) + int autocount_p; + DVP_INSN *insn_buf; +{ + if (dmadata_state != 0 ) + { + as_bad ("DmaData blocks cannot be nested."); + return; + } + + dmadata_state = 1; + + if (autocount_p) + { + dmadata_name = S_GET_NAME (create_colon_label ("", unique_name ())); + setup_autocount (dmadata_name, insn_buf); + } + else + dmadata_name = 0; +} + +/* Compute the auto-count value for a DMA tag with out-of-line data. */ + +static long +parse_dma_addr_autocount (opcode, operand, mods, insn_buf, pstr, errmsg) + const dvp_opcode *opcode; + const dvp_operand *operand; + int mods; + DVP_INSN *insn_buf; + char **pstr; + const char **errmsg; +{ + char *start = *pstr; + char *end = start; + long retval; + /* Data reference must be a .DmaData label. */ + struct symbol *label, *label2, *endlabel; + const char *name; + char c; + + label = label2 = 0; + if (! is_name_beginner (*start)) + { + *errmsg = "invalid .DmaData label"; + return 0; + } + + name = start; + end = scan_symbol (name); + c = *end; + *end = 0; + label = symbol_find_or_make (name); + *end = c; + + label2 = create_label ("_$", name); + endlabel = create_label (END_LABEL_PREFIX, name); + + retval = eval_expr (dma_operand_addr, 8, name); + + setup_autocount (name, insn_buf); + + *pstr = end; + return retval; +} + +/* Parse a DMA data spec which can be either of '*' or a quad word count. */ + +static int +parse_dma_count (pstr, errmsg) + char **pstr; + const char **errmsg; +{ + char *str = *pstr; + long count, value; + expressionS exp; + + if (*str == '*') + { + ++*pstr; + /* -1 is a special marker to caller to tell it the count is to be + computed from the data. */ + return -1; + } + + expression (&exp); + if (exp.X_op == O_illegal + || exp.X_op == O_absent) + ; + else if (exp.X_op == O_constant) + value = exp.X_add_number; + else if (exp.X_op == O_register) + as_fatal ("got O_register"); + else + { + /* We need to generate a fixup for this expression. */ + if (fixup_count >= MAX_FIXUPS ) + as_fatal ("too many fixups"); + fixups[fixup_count].exp = exp; + fixups[fixup_count].opindex = 0 /*FIXME*/; + fixups[fixup_count].offset = 0 /*FIXME*/; + ++fixup_count; + value = 0; + } + + if (isdigit( *str)) /* ????????needs to accept an expression*/ + { + char *start = str; + while (*str && *str != ',') + ++str; + if (*str != ',') + { + *errmsg = "invalid dma count"; + return 0; + } + count = atoi (start); + *pstr = str; + return (count); + } + + *errmsg = "invalid dma count"; + return 0; +} /* Return length in bytes of the variable length VIF insn currently being assembled. */ @@ -1584,23 +1661,7 @@ insert_operand_final (cpu, operand, mods, insn_buf, val, file, line) } } -static short dmadata_state = 0; -static const char *dmadata_name; - -/* Non-zero if .DmaData was implied by a real (non-pseudo) opcode. */ -static int implied_dmadata_p = 0; - -static void -s_dmadata_implied (ignore) - int ignore; -{ - if (dmadata_state != 0 ) - { - as_bad ("DmaData blocks cannot be nested."); - } - dmadata_state = 1; - dmadata_name = 0; -} +/* DVP pseudo ops. */ static void s_dmadata (ignore) @@ -1656,10 +1717,10 @@ s_enddmadata (ignore) /* Fill the data out to a multiple of 16 bytes. */ /* FIXME: Does the fill contents matter? */ frag_align (4, 0, 0); - create_colon_label (".L.end.", dmadata_name); + create_colon_label (END_LABEL_PREFIX, dmadata_name); } } - + static void s_dmapackvif (ignore) int ignore; @@ -1784,61 +1845,3 @@ s_endgif (ignore) int ignore; { } - -/* Parse a DMA data spec which can be either of '*' or a quad word count. */ - -static int -parse_dma_count (pstr, errmsg) - char **pstr; - const char **errmsg; -{ - char *str = *pstr; - long count, value; - expressionS exp; - - if (*str == '*') - { - ++*pstr; - /* -1 is a special marker to caller to tell it the count is to be - computed from the data. */ - return -1; - } - - expression (&exp); - if (exp.X_op == O_illegal - || exp.X_op == O_absent) - ; - else if (exp.X_op == O_constant) - value = exp.X_add_number; - else if (exp.X_op == O_register) - as_fatal ("got O_register"); - else - { - /* We need to generate a fixup for this expression. */ - if (fixup_count >= MAX_FIXUPS ) - as_fatal ("too many fixups"); - fixups[fixup_count].exp = exp; - fixups[fixup_count].opindex = 0 /*FIXME*/; - fixups[fixup_count].offset = 0 /*FIXME*/; - ++fixup_count; - value = 0; - } - - if (isdigit( *str)) /* ????????needs to accept an expression*/ - { - char *start = str; - while (*str && *str != ',') - ++str; - if (*str != ',') - { - *errmsg = "invalid dma count"; - return 0; - } - count = atoi (start); - *pstr = str; - return (count); - } - - *errmsg = "invalid dma count"; - return 0; -} |