diff options
author | Doug Evans <dje@google.com> | 1998-04-16 22:07:02 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 1998-04-16 22:07:02 +0000 |
commit | a6756468109f51ed7ea8952213cc2d9f4f39fa98 (patch) | |
tree | e52c636f897a110718bcc8a293e28d7af7842ee1 /gas | |
parent | c2e042cf7b6d131200437fc93793415a5001220c (diff) | |
download | gdb-a6756468109f51ed7ea8952213cc2d9f4f39fa98.zip gdb-a6756468109f51ed7ea8952213cc2d9f4f39fa98.tar.gz gdb-a6756468109f51ed7ea8952213cc2d9f4f39fa98.tar.bz2 |
(vif_insn_type): New function.
(md_apply_fix3): Don't validate user specified length if unpack insn
and wl > cl.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/tc-dvp.c | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c index 9474733..c785da4 100644 --- a/gas/config/tc-dvp.c +++ b/gas/config/tc-dvp.c @@ -80,7 +80,8 @@ static int insert_file PARAMS ((const char *, void (*) PARAMS ((unsigned long)), unsigned long, int)); -static int vif_length_value PARAMS ((int, int, int, int)); +static int vif_insn_type PARAMS ((char)); +static int vif_length_value PARAMS ((char, int, int, int)); static void install_vif_length PARAMS ((char *, int)); const char comment_chars[] = ";"; @@ -1767,12 +1768,16 @@ md_apply_fix3 (fixP, valueP, seg) if (cpu == DVP_VIF && (operand - vif_operands) == vif_operand_datalen_special) { + int insn_type = vif_insn_type (where[3]); value = vif_length_value (where[3], fixP->tc_fix_data.wl, fixP->tc_fix_data.cl, value); if (fixP->tc_fix_data.user_value != -1) { - if (fixP->tc_fix_data.user_value != value) + /* We can't do this for unpack insns with wl > cl. */ + if ((insn_type != VIF_OPCODE_UNPACK + || (fixP->tc_fix_data.wl <= fixP->tc_fix_data.cl)) + && fixP->tc_fix_data.user_value != value) as_warn_where (fixP->fx_file, fixP->fx_line, "specified length value doesn't match computed value"); /* Don't override the user specified value. */ @@ -2325,18 +2330,41 @@ parse_dma_addr_autocount (opcode, operand, mods, insn_buf, pstr, errmsg) return retval; } +/* Compute the type of vif insn of IBYTE. + IBYTE is the msb of the insn. + This is only used for mpg,direct,unpack insns. + The result is one of VIF_OPCODE_{DIRECT,DIRECTHL,MPG,UNPACK}. */ + +static int +vif_insn_type (ibyte) + char ibyte; +{ + switch (ibyte & 0x70) + { + case 0x50 : + return (ibyte & 1) ? VIF_OPCODE_DIRECTHL : VIF_OPCODE_DIRECT; + case 0x40 : + return VIF_OPCODE_MPG; + case 0x60 : + case 0x70 : + return VIF_OPCODE_UNPACK; + default : + as_fatal ("internal error: bad call to vif_insn_type"); + } +} + /* Return the length value to insert in a VIF instruction whose upper - byte is CMD and whose data length is BYTES. + byte is IBYTE and whose data length is BYTES. WL,CL are used for unpack insns and are the stcycl values in effect. This does not do the max -> 0 conversion. */ static int -vif_length_value (cmd, wl, cl, bytes) - int cmd; +vif_length_value (ibyte, wl, cl, bytes) + char ibyte; int wl,cl; int bytes; { - switch (cmd & 0x70) + switch (ibyte & 0x70) { case 0x50 : /* direct */ /* ??? Worry about data /= 16 cuts off? */ @@ -2346,7 +2374,7 @@ vif_length_value (cmd, wl, cl, bytes) return bytes / 8; case 0x60 : /* unpack */ case 0x70 : - return vif_unpack_len_value (cmd & 15, wl, cl, bytes); + return vif_unpack_len_value (ibyte & 15, wl, cl, bytes); default : as_fatal ("internal error: bad call to vif_length_value"); } @@ -2362,16 +2390,16 @@ install_vif_length (buf, len) char *buf; int len; { - unsigned char cmd = buf[3]; + unsigned char ibyte = buf[3]; - if ((cmd & 0x70) == 0x40) + if ((ibyte & 0x70) == 0x40) { /* mpg */ if (len > 256) as_bad ("`mpg' data length must be between 1 and 256"); buf[2] = len == 256 ? 0 : len; } - else if ((cmd & 0x70) == 0x50) + else if ((ibyte & 0x70) == 0x50) { /* direct/directhl */ if (len > 65536) @@ -2380,7 +2408,7 @@ install_vif_length (buf, len) buf[0] = len; buf[1] = len >> 8; } - else if ((cmd & 0x60) == 0x60) + else if ((ibyte & 0x60) == 0x60) { /* unpack */ /* len == -1 means wl,cl are unknown and thus we can't compute |