diff options
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-dvp.c | 122 |
2 files changed, 94 insertions, 33 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 8d0e882..95406ad 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -5,6 +5,11 @@ Fri Mar 6 11:36:37 1998 Doug Evans <devans@canuck.cygnus.com> insufficient data present. Fix insertion of computed nloop value. (install_vif_length): Second pass at unpack len calcs. (s_endunpack): Round data up to word boundary. + (insert_mpg_marker): New function. + (insert_file): New args insert_marker, size. All callers updated. + (assemble_vif): Rewrite varlen insn handling. + (assemble_vu): Call insert_mpg_marker when 256th insn reached. + (s_enddirect,s_endunpack): Rename arg to internal_p. end-sanitize-sky start-sanitize-vr4320 diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c index c924bc4..017f72c 100644 --- a/gas/config/tc-dvp.c +++ b/gas/config/tc-dvp.c @@ -35,6 +35,8 @@ #include <varargs.h> #endif +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + /* Compute DMA operand index number of OP. */ #define DMA_OPERAND_INDEX(op) ((op) - dma_operands) @@ -61,7 +63,8 @@ static void insert_operand_final PARAMS ((dvp_cpu, const dvp_operand *, int, DVP_INSN *, offsetT, char *, unsigned int)); -static int insert_file PARAMS ((const char *)); +static void insert_mpg_marker PARAMS ((void)); +static int insert_file PARAMS ((const char *, void (*) (), int)); static int cur_vif_insn_length PARAMS ((void)); static void install_vif_length PARAMS ((char *, int)); @@ -514,29 +517,46 @@ assemble_vif (str) file = NULL; data_len = 0; vif_get_var_data (&file, &data_len); + + cur_varlen_frag = frag_now; + cur_varlen_insn = f; + cur_varlen_value = data_len; + if (file) { int byte_len; - /* Emit a label to set the mach type for the data we're - inserting. */ + /* Indicate length must be computed. */ + cur_varlen_value = -1; + + /* The handling for each of mpg,direct,unpack is basically the same: + - emit a label to set the mach type for the data we're inserting + - switch to the new assembler state + - insert the file + - call the `end' handler */ + if (opcode->flags & VIF_OPCODE_MPG) - record_mach (DVP_VUUP, 1); + { + record_mach (DVP_VUUP, 1); + set_asm_state (ASM_MPG); + byte_len = insert_file (file, insert_mpg_marker, 256 * 8); + s_endmpg (1); + } else if (opcode->flags & VIF_OPCODE_DIRECT) - record_mach (DVP_GIF, 1); + { + record_mach (DVP_GIF, 1); + set_asm_state (ASM_DIRECT); + byte_len = insert_file (file, NULL, 0); + s_enddirect (1); + } else if (opcode->flags & VIF_OPCODE_UNPACK) - ; /* nothing to do */ - else - as_fatal ("unknown cpu type for variable length vif insn"); - - byte_len = insert_file (file); - if (output_vif) - install_vif_length (f, byte_len); - if (opcode->flags & VIF_OPCODE_MPG) { - /* Update $.MpgLoc. */ - vif_set_mpgloc (vif_get_mpgloc () + byte_len); + set_asm_state (ASM_UNPACK); + byte_len = insert_file (file, NULL, 0); + s_endunpack (1); } + else + as_fatal ("unknown cpu type for variable length vif insn"); } else { @@ -544,9 +564,7 @@ assemble_vif (str) the data. */ if (data_len == 0 || data_len < -2) as_bad ("invalid data length"); - cur_varlen_frag = frag_now; - cur_varlen_insn = f; - cur_varlen_value = data_len; + if (opcode->flags & VIF_OPCODE_MPG) { set_asm_state (ASM_MPG); @@ -623,10 +641,7 @@ assemble_vu (str) /* Handle automatic mpg insertion if enabled. */ if (CUR_ASM_STATE == ASM_MPG && vu_count == 256) - { - s_endmpg (1); - md_assemble ("mpg *,*"); - } + insert_mpg_marker (); /* Do an implicit alignment to a 8 byte boundary. */ frag_align (3, 0, 0); @@ -1762,18 +1777,34 @@ install_vif_length (buf, len) as_fatal ("bad call to install_vif_length"); } +/* Finish off the current set of mpg insns, and start a new set. */ + +static void +insert_mpg_marker () +{ + s_endmpg (1); + md_assemble ("mpg *,*"); + /* Record the cpu type in case we're in the middle of reading binary + data. */ + record_mach (DVP_VUUP, 0); +} + /* Insert a file into the output. - -I is used to specify where to find the file. + The -I arg passed to GAS is used to specify where to find the file. + INSERT_MARKER if non-NULL is called every SIZE bytes. This is used + by the mpg insn to insert mpg's every 256 insns. The result is the number of bytes inserted. If an error occurs an error message is printed and zero is returned. */ static int -insert_file (file) +insert_file (file, insert_marker, size) const char *file; + void (*insert_marker) (); + int size; { FILE *f; char buf[256]; - int i, n, total; + int i, n, total, left_before_marker; char *path; path = xmalloc (strlen (file) + include_dir_maxlen + 5 /*slop*/); @@ -1796,19 +1827,36 @@ insert_file (file) } total = 0; + left_before_marker = 0; do { - n = fread (buf, 1, sizeof (buf), f); + int bytes; + if (insert_marker) + bytes = MIN (size - left_before_marker, sizeof (buf)); + else + bytes = sizeof (buf); + n = fread (buf, 1, bytes, f); if (n > 0) { char *fr = frag_more (n); memcpy (fr, buf, n); total += n; + if (insert_marker) + { + left_before_marker += n; + if (left_before_marker > size) + as_fatal ("file insertion sanity checky failed"); + if (left_before_marker == size) + { + (*insert_marker) (); + left_before_marker = 0; + } + } } } while (n > 0); fclose (f); /* We assume the file is smaller than 2^31 bytes. - Ok, we shouldn't make any assumptions. Later. */ + Ok, we shouldn't make any assumptions. */ return total; } @@ -2017,9 +2065,12 @@ s_dmapackvif (ignore) demand_empty_rest_of_line (); } +/* INTERNAL_P is non-zero if invoked internally by this file rather than + by the user. In this case we don't touch the input stream. */ + static void -s_enddirect (ignore) - int ignore; +s_enddirect (internal_p) + int internal_p; { int byte_len; @@ -2043,7 +2094,8 @@ s_enddirect (ignore) cur_varlen_insn = NULL; cur_varlen_value = 0; - demand_empty_rest_of_line (); + if (! internal_p) + demand_empty_rest_of_line (); } /* INTERNAL_P is non-zero if invoked internally by this file rather than @@ -2085,9 +2137,12 @@ s_endmpg (internal_p) demand_empty_rest_of_line (); } +/* INTERNAL_P is non-zero if invoked internally by this file rather than + by the user. In this case we don't touch the input stream. */ + static void -s_endunpack (ignore) - int ignore; +s_endunpack (internal_p) + int internal_p; { int byte_len; @@ -2120,7 +2175,8 @@ s_endunpack (ignore) /* Update $.UnpackLoc. */ vif_set_unpackloc (vif_get_unpackloc () + byte_len); - demand_empty_rest_of_line (); + if (! internal_p) + demand_empty_rest_of_line (); } static void |