From fa3671a34faa25c579b8c0a3d6626a7945eff2d7 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Mon, 16 Mar 1998 18:22:18 +0000 Subject: [PATCH] * config/tc-dvp.c (md_pseudo_table): Make .quad 16 bytes. --- gas/ChangeLog | 6 ++ gas/config/tc-dvp.c | 197 ++++++++++++++++++++++++++++++-------------- 2 files changed, 141 insertions(+), 62 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index d0791095396..2e4d7eb2ee6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +start-sanitize-sky +Mon Mar 16 10:19:44 1998 Doug Evans + + * config/tc-dvp.c (md_pseudo_table): Make .quad 16 bytes. + +end-sanitize-sky Fri Mar 13 16:31:38 1998 Tom Tromey * depend.c (quote_string_for_make): New function. diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c index 017f72c3997..357a0be475a 100644 --- a/gas/config/tc-dvp.c +++ b/gas/config/tc-dvp.c @@ -51,6 +51,9 @@ static long parse_float PARAMS ((char **, const char **)); static symbolS * create_label PARAMS ((const char *, const char *)); static symbolS * create_colon_label PARAMS ((int, const char *, const char *)); static char * unique_name PARAMS ((const char *)); +static int compute_nloop PARAMS ((gif_type, int, int)); +static void check_nloop PARAMS ((gif_type, int, int, int, + char *, unsigned int)); static long eval_expr PARAMS ((int, int, const char *, ...)); static long parse_dma_addr_autocount (); static void inline_dma_data PARAMS ((int, DVP_INSN *)); @@ -125,8 +128,10 @@ static const char *dma_data_name; static gif_type gif_insn_type; /* Name of label of current gif insn's data. */ static const char *gif_data_name; -/* Pointer to current gif insn in fragment. */ -static char *gif_insn_frag; +/* Pointer to frag of current gif insn. */ +static fragS *gif_insn_frag; +/* Pointer to current gif insn in gif_insn_frag. */ +static char *gif_insn_frag_loc; /* For variable length instructions, pointer to the initial frag and pointer into that frag. These only hold valid values if @@ -210,6 +215,7 @@ static void s_state PARAMS ((int)); const pseudo_typeS md_pseudo_table[] = { { "word", cons, 4 }, + { "quad", cons, 16 }, { "dmadata", s_dmadata, 0 }, { "dmapackvif", s_dmapackvif, 0 }, { "enddirect", s_enddirect, 0 }, @@ -612,7 +618,8 @@ assemble_gif (str) record_mach (DVP_GIF, 1); - gif_insn_frag = f = frag_more (16); + gif_insn_frag_loc = f = frag_more (16); + gif_insn_frag = frag_now; for (i = 0; i < 4; ++i) md_number_to_chars (f + i * 4, insn_buf[i], 4); @@ -1278,6 +1285,27 @@ md_apply_fix3 (fixP, valueP, seg) decode_fixup_reloc_type ((int) fixP->fx_r_type, & cpu, & operand); + /* For the gif nloop operand, if it was specified by the user ensure + it matches the value we computed. */ + if (cpu == DVP_GIF + && (operand - gif_operands) == gif_operand_nloop) + { + value = compute_nloop (fixP->tc_fix_data.type, + fixP->tc_fix_data.nregs, + value); + if (fixP->tc_fix_data.user_nloop != -1) + { + check_nloop (fixP->tc_fix_data.type, + fixP->tc_fix_data.nregs, + fixP->tc_fix_data.user_nloop, + value, + fixP->fx_file, fixP->fx_line); + /* Don't override the user specified value. */ + fixP->fx_done = 1; + return 1; + } + } + /* Fetch the instruction, insert the fully resolved operand value, and stuff the instruction back again. The fixup is recorded at the appropriate word so pass DVP_MOD_THIS_WORD so any offset @@ -1331,7 +1359,7 @@ md_apply_fix3 (fixP, valueP, seg) md_number_to_chars (where, value, 4); break; default: - abort (); + as_fatal ("unexpected fixup"); } } @@ -1598,6 +1626,52 @@ unique_name (prefix) ++counter; return result; } + +/* Compute a value for nloop. */ + +static int +compute_nloop (type, nregs, bytes) + gif_type type; + int nregs, bytes; +{ + int computed_nloop; + + switch (type) + { + case GIF_PACKED : + /* We can't compute a value if no regs were specified and there is a + non-zero amount of data. Just set to something useful, a warning + will be issued later. */ + if (nregs == 0) + nregs = 1; + computed_nloop = (bytes >> 4) / nregs; + break; + case GIF_REGLIST : + if (nregs == 0) + nregs = 1; + computed_nloop = (bytes >> 3) / nregs; + break; + case GIF_IMAGE : + computed_nloop = bytes >> 4; + break; + } + + return computed_nloop; +} + +/* Issue a warning if the user specified nloop value doesn't match the + computed value. */ + +static void +check_nloop (type, nregs, user_nloop, computed_nloop, file, line) + gif_type type; + int nregs,user_nloop,computed_nloop; + char *file; + unsigned int line; +{ + if (user_nloop != computed_nloop) + as_warn_where (file, line, "nloop value does not match amount of data"); +} /* Compute the auto-count value for a DMA tag. INLINE_P is non-zero if the dma data is inline. */ @@ -2183,10 +2257,14 @@ static void s_endgif (ignore) int ignore; { - long count; + int bytes; int specified_nloop = gif_nloop (); int computed_nloop; int nregs = gif_nregs (); + char *file; + unsigned int line; + + as_where (&file, &line); if (CUR_ASM_STATE != ASM_GIF) { @@ -2195,77 +2273,72 @@ s_endgif (ignore) } pop_asm_state (0); - /* The -16 is because the `gif_data_name' label is emitted at the start - of the gif tag. */ - count = eval_expr (0, 0, ". - %s - 16", gif_data_name); - - if (count < 0 - || fixup_count != 0) + /* Fill out to proper boundary. + ??? This may cause eval_expr to always queue a fixup. So be it. */ + switch (gif_insn_type) { - as_warn ("bad data count"); - return; + case GIF_PACKED : frag_align (4, 0, 0); break; + case GIF_REGLIST : frag_align (3, 0, 0); break; + case GIF_IMAGE : frag_align (4, 0, 0); break; } - /* Compute a value for nloop. - Also check whether we're left on a double/quadword boundary. */ - switch (gif_insn_type) + /* The -16 is because the `gif_data_name' label is emitted at the start + of the gif tag. If we're in a different frag from the one we started + with, this can't be computed until much later. To cope we queue a fixup + and deal with it then. + ??? The other way to handle this is by having expr() compute "syma - symb" + when they're in different fragments but the difference is constant. + Not sure how much of a slowdown that will introduce though. */ + fixup_count = 0; + bytes = eval_expr (gif_operand_nloop, 0, ". - %s - 16", gif_data_name); + + /* Compute a value for nloop if we can. */ + + if (fixup_count == 0) { - case GIF_PACKED : - if (count % 16 != 0) - as_warn ("data doesn't fill last quadword"); - if (nregs == 0) - { - if (count != 0) - as_warn ("non-zero amount of data, but no registers specified"); - computed_nloop = 0; - } - else - computed_nloop = (count >> 4) / nregs; - break; - case GIF_REGLIST : - if (count % 8 != 0) - as_warn ("data doesn't fill last doubleword"); - /* Fill out to quadword if odd number of doublewords. */ - if (nregs == 0) - { - if (count != 0) - as_warn ("non-zero amount of data, but no registers specified"); - computed_nloop = 0; - } - else - computed_nloop = (count >> 3) / nregs; - break; - case GIF_IMAGE : - if (count % 16 != 0) - as_warn ("data doesn't fill last quadword"); - computed_nloop = count >> 4; - break; - } + computed_nloop = compute_nloop (gif_insn_type, nregs, bytes); - /* FIXME: How should be handle the case where count is not a proper - multiple of 8/16? We could just always emit a .align 16 or some - such. */ + /* If the user specified nloop, verify it. */ + if (specified_nloop != -1) + check_nloop (gif_insn_type, nregs, specified_nloop, computed_nloop, + file, line); + } - /* Validate nloop if specified. Otherwise write the computed value into + /* If computation of nloop can't be done yet, queue a fixup and do it later. + Otherwise validate nloop if specified or write the computed value into the insn. */ - if (specified_nloop != -1) + + if (fixup_count != 0) { - if (computed_nloop != specified_nloop) - { - as_warn ("nloop value does not match size of data"); - return; - } + /* FIXME: It might eventually be possible to combine all the various + copies of this bit of code. */ + int op_type, reloc_type, offset; + const dvp_operand *operand; + fixS *fix; + + op_type = fixups[0].opindex; + offset = fixups[0].offset; + reloc_type = encode_fixup_reloc_type (DVP_GIF, op_type); + operand = &gif_operands[op_type]; + fix = fix_new_exp (gif_insn_frag, + gif_insn_frag_loc + offset - gif_insn_frag->fr_literal, + 4, &fixups[0].exp, 0, + (bfd_reloc_code_real_type) reloc_type); + /* Record user specified value so we can test it when we compute the + actual value. */ + fix->tc_fix_data.type = gif_insn_type; + fix->tc_fix_data.nregs = nregs; + fix->tc_fix_data.user_nloop = specified_nloop; } + else if (specified_nloop != -1) + ; /* nothing to do */ else { - DVP_INSN insn = bfd_getl32 (gif_insn_frag); - char *file; - unsigned int line; - as_where (&file, &line); + DVP_INSN insn = bfd_getl32 (gif_insn_frag_loc); insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop], DVP_MOD_THIS_WORD, &insn, (offsetT) computed_nloop, file, line); - bfd_putl32 ((bfd_vma) insn, gif_insn_frag); + bfd_putl32 ((bfd_vma) insn, gif_insn_frag_loc); } gif_data_name = NULL; -- 2.30.2