diff options
author | Doug Evans <dje@google.com> | 1998-02-21 03:26:47 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 1998-02-21 03:26:47 +0000 |
commit | 498fcb9cdb2bf70b04a0d5329105a7193636a0fc (patch) | |
tree | cda3d5ce28c1079aabf02bb784952406a19734b3 | |
parent | 8151801a092be04feffab9ca3d2098d1f7397f18 (diff) | |
download | binutils-498fcb9cdb2bf70b04a0d5329105a7193636a0fc.zip binutils-498fcb9cdb2bf70b04a0d5329105a7193636a0fc.tar.gz binutils-498fcb9cdb2bf70b04a0d5329105a7193636a0fc.tar.bz2 |
(asm_state_stack): Maintain stack of parsing states.
({push,pop,set}_asm_state): New functions.
(CUR_ASM_STATE): Renamed from cur_asm_state, all uses updated.
-rw-r--r-- | gas/ChangeLog | 5 | ||||
-rw-r--r-- | gas/config/tc-dvp.c | 256 |
2 files changed, 169 insertions, 92 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 55ed25f..5a17829 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,11 +1,14 @@ start-sanitize-sky Fri Feb 20 12:43:02 1998 Doug Evans <devans@canuck.cygnus.com> - * confirg/tc-dvp.c (md_assemble): Handle ASM_DIRECT state. + * config/tc-dvp.c (md_assemble): Handle ASM_DIRECT state. (dvp_parse_done): Comment out contents. (s_enddirect,s_endmpg,s_endunpack): Call demand_empty_rest_of_line. (s_state): Handle .vu in included file. (asm_state): New state ASM_GIF. + (asm_state_stack): Maintain stack of parsing states. + ({push,pop,set}_asm_state): New functions. + (CUR_ASM_STATE): Renamed from cur_asm_state, all uses updated. (gif_{insn_type,data_name,insn_frag}): New static locals. (md_assemble): Watch for .endgif if in ASM_GIF state. (assemble_gif): Complete. diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c index 885fa6b..d23fa2d 100644 --- a/gas/config/tc-dvp.c +++ b/gas/config/tc-dvp.c @@ -74,11 +74,32 @@ const char FLT_CHARS[] = "dD"; Instructions like mpg and direct are followed by a restricted set of instructions. In the case of a '*' length argument an end marker must be provided. (e.g. mpg is followed by vu insns until a .EndMpg is - seen). */ + seen). + + Allowed state transitions: + ASM_INIT -> ASM_MPG + ASM_DIRECT -> ASM_GIF + ASM_UNPACK + ASM_VU +*/ + typedef enum { - ASM_INIT, ASM_MPG, ASM_DIRECT, ASM_UNPACK, ASM_VU, ASM_GIF + ASM_INIT, ASM_DIRECT, ASM_MPG, ASM_UNPACK, ASM_VU, ASM_GIF } asm_state; -static asm_state cur_asm_state = ASM_INIT; + +/* We need to maintain a stack of the current and previous status to handle + such things as "direct ...; gifpacked ... ; .endgif ; .enddirect". */ +#define MAX_STATE_DEPTH 2 +static asm_state asm_state_stack[MAX_STATE_DEPTH]; +/* Current state's index in the stack. */ +static int cur_state_index; +/* Macro to fetch the current state. */ +#define CUR_ASM_STATE (asm_state_stack[cur_state_index]) + +/* Functions to push/pop the state stack. */ +static void push_asm_state PARAMS ((asm_state)); +static void pop_asm_state PARAMS ((int)); +static void set_asm_state PARAMS ((asm_state)); /* Nonzero if inside .DmaData. */ static int dma_data_state = 0; @@ -94,7 +115,7 @@ static char *gif_insn_frag; /* 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. */ + CUR_ASM_STATE is one of ASM_MPG, ASM_DIRECT, ASM_UNPACK. */ static fragS *cur_varlen_frag; static char *cur_varlen_insn; /* The length value specified in the insn, or -1 if '*'. */ @@ -161,9 +182,9 @@ static void s_dmadata PARAMS ((int)); static void s_enddmadata PARAMS ((int)); static void s_dmapackvif PARAMS ((int)); static void s_enddirect PARAMS ((int)); -static void s_endgif PARAMS ((int)); static void s_endmpg PARAMS ((int)); static void s_endunpack PARAMS ((int)); +static void s_endgif PARAMS ((int)); static void s_state PARAMS ((int)); /* The target specific pseudo-ops which we support. */ @@ -174,9 +195,9 @@ const pseudo_typeS md_pseudo_table[] = { "dmapackvif", s_dmapackvif, 0 }, { "enddirect", s_enddirect, 0 }, { "enddmadata", s_enddmadata, 0 }, - { "endgif", s_endgif, 0 }, { "endmpg", s_endmpg, 0 }, { "endunpack", s_endunpack, 0 }, + { "endgif", s_endgif, 0 }, /* .vu added to simplify debugging and creation of input files */ { "vu", s_state, ASM_VU }, { NULL, NULL, 0 } @@ -200,7 +221,8 @@ md_begin () This involves computing the hash chains. */ dvp_opcode_init_tables (0); - cur_asm_state = ASM_INIT; + cur_state_index = 0; + set_asm_state (ASM_INIT); dma_pack_vif_p = 0; } @@ -253,13 +275,27 @@ md_assemble (str) str++; /* After a gif tag, no insns can appear until a .endgif is seen. */ - if (cur_asm_state == ASM_GIF) + if (CUR_ASM_STATE == ASM_GIF) { as_bad ("missing .endgif"); - cur_asm_state = ASM_INIT; + pop_asm_state (1); + } + /* Ditto for unpack. */ + if (CUR_ASM_STATE == ASM_UNPACK) + { + as_bad ("missing .endunpack"); + pop_asm_state (1); + } +#if 0 /* this doesn't work of course as gif insns may follow */ + /* Ditto for direct. */ + if (CUR_ASM_STATE == ASM_DIRECT) + { + as_bad ("missing .enddirect"); + pop_asm_state (1); } +#endif - if (cur_asm_state == ASM_INIT) + if (CUR_ASM_STATE == ASM_INIT) { if (strncasecmp (str, "dma", 3) == 0) assemble_dma (str); @@ -268,10 +304,10 @@ md_assemble (str) else assemble_vif (str); } - else if (cur_asm_state == ASM_DIRECT) + else if (CUR_ASM_STATE == ASM_DIRECT) assemble_gif (str); - else if (cur_asm_state == ASM_VU - || cur_asm_state == ASM_MPG) + else if (CUR_ASM_STATE == ASM_VU + || CUR_ASM_STATE == ASM_MPG) assemble_vu (str); else as_fatal ("unknown parse state"); @@ -445,11 +481,11 @@ assemble_vif (str) cur_varlen_insn = f; cur_varlen_value = data_len; if (opcode->flags & VIF_OPCODE_MPG) - cur_asm_state = ASM_MPG; + set_asm_state (ASM_MPG); else if (opcode->flags & VIF_OPCODE_DIRECT) - cur_asm_state = ASM_DIRECT; + set_asm_state (ASM_DIRECT); else if (opcode->flags & VIF_OPCODE_UNPACK) - cur_asm_state = ASM_UNPACK; + set_asm_state (ASM_UNPACK); } } } @@ -495,7 +531,7 @@ assemble_gif (str) gif_insn_type = GIF_IMAGE; else abort (); - cur_asm_state = ASM_GIF; + push_asm_state (ASM_GIF); } /* Subroutine of md_assemble to assemble VU instructions. */ @@ -864,7 +900,45 @@ assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf) as_bad ("bad instruction `%s'", start); return 0; } + +/* Push/pop the current parsing state. */ + +static void +push_asm_state (new_state) + asm_state new_state; +{ + ++cur_state_index; + if (cur_state_index == MAX_STATE_DEPTH) + as_fatal ("unexpected state push"); + asm_state_stack[cur_state_index] = new_state; +} + +/* TOP_OK_P is non-zero if it's ok that we're at the top of the stack. + This happens if there are errors in the assembler code. + We just reset the stack to its "init" state. */ +static void +pop_asm_state (top_ok_p) + int top_ok_p; +{ + if (cur_state_index == 0) + { + if (top_ok_p) + asm_state_stack[cur_state_index] = ASM_INIT; + else + as_fatal ("unexpected state pop"); + } + else + --cur_state_index; +} + +static void +set_asm_state (state) + asm_state state; +{ + CUR_ASM_STATE = state; +} + void md_operand (expressionP) expressionS *expressionP; @@ -895,11 +969,11 @@ dvp_parse_done () #if 0 /* ??? Doesn't work unless we keep track of the nested include file level. */ /* Check for missing .EndMpg, and supply one if necessary. */ - if (cur_asm_state == ASM_MPG) + if (CUR_ASM_STATE == ASM_MPG) s_endmpg (0); - else if (cur_asm_state == ASM_DIRECT) + else if (CUR_ASM_STATE == ASM_DIRECT) s_enddirect (0); - else if (cur_asm_state == ASM_UNPACK) + else if (CUR_ASM_STATE == ASM_UNPACK) s_endunpack (0); #endif } @@ -1749,7 +1823,7 @@ s_enddirect (ignore) { int byte_len; - if (cur_asm_state != ASM_DIRECT) + if (CUR_ASM_STATE != ASM_DIRECT) { as_bad ("`.enddirect' has no matching `direct' instruction"); return; @@ -1762,13 +1836,78 @@ s_enddirect (ignore) if (output_vif) install_vif_length (cur_varlen_insn, byte_len); - cur_asm_state = ASM_INIT; + set_asm_state (ASM_INIT); + + /* These needn't be reset, but to catch bugs they are. */ + cur_varlen_frag = NULL; + cur_varlen_insn = NULL; + cur_varlen_value = 0; + + demand_empty_rest_of_line (); +} + +static void +s_endmpg (ignore) + int ignore; +{ + int byte_len; + + if (CUR_ASM_STATE != ASM_MPG) + { + as_bad ("`.endmpg' has no matching `mpg' instruction"); + return; + } + + byte_len = cur_vif_insn_length (); + if (cur_varlen_value != -1 + && cur_varlen_value * 8 != byte_len) + as_warn ("length in `mpg' instruction does not match length of data"); + if (output_vif) + install_vif_length (cur_varlen_insn, byte_len); + + set_asm_state (ASM_INIT); + + /* These needn't be reset, but to catch bugs they are. */ + cur_varlen_frag = NULL; + cur_varlen_insn = NULL; + cur_varlen_value = 0; + + /* Update $.MpgLoc. */ + vif_set_mpgloc (vif_get_mpgloc () + byte_len); + + demand_empty_rest_of_line (); +} + +static void +s_endunpack (ignore) + int ignore; +{ + int byte_len; + + if (CUR_ASM_STATE != ASM_UNPACK) + { + as_bad ("`.endunpack' has no matching `unpack' instruction"); + return; + } + + byte_len = cur_vif_insn_length (); +#if 0 /* unpack doesn't support prespecifying a length */ + if (cur_varlen_value * 16 != bytelen) + as_warn ("length in `direct' instruction does not match length of data"); +#endif + if (output_vif) + install_vif_length (cur_varlen_insn, byte_len); + + set_asm_state (ASM_INIT); /* These needn't be reset, but to catch bugs they are. */ cur_varlen_frag = NULL; cur_varlen_insn = NULL; cur_varlen_value = 0; + /* Update $.UnpackLoc. */ + vif_set_unpackloc (vif_get_unpackloc () + byte_len); + demand_empty_rest_of_line (); } @@ -1779,12 +1918,12 @@ s_endgif (ignore) long count; int nloop = gif_nloop (); - if (cur_asm_state != ASM_GIF) + if (CUR_ASM_STATE != ASM_GIF) { as_bad (".endgif doesn't follow a gif tag"); return; } - cur_asm_state = ASM_INIT; + pop_asm_state (0); if (gif_insn_type == GIF_PACKED) count = eval_expr (0, 0, "(. - %s) >> 4", gif_data_name); @@ -1837,81 +1976,16 @@ s_endgif (ignore) } static void -s_endmpg (ignore) - int ignore; -{ - int byte_len; - - if (cur_asm_state != ASM_MPG) - { - as_bad ("`.endmpg' has no matching `mpg' instruction"); - return; - } - - byte_len = cur_vif_insn_length (); - if (cur_varlen_value != -1 - && cur_varlen_value * 8 != byte_len) - as_warn ("length in `mpg' instruction does not match length of data"); - if (output_vif) - install_vif_length (cur_varlen_insn, byte_len); - - cur_asm_state = ASM_INIT; - - /* These needn't be reset, but to catch bugs they are. */ - cur_varlen_frag = NULL; - cur_varlen_insn = NULL; - cur_varlen_value = 0; - - /* Update $.MpgLoc. */ - vif_set_mpgloc (vif_get_mpgloc () + byte_len); - - demand_empty_rest_of_line (); -} - -static void -s_endunpack (ignore) - int ignore; -{ - int byte_len; - - if (cur_asm_state != ASM_UNPACK) - { - as_bad ("`.endunpack' has no matching `unpack' instruction"); - return; - } - - byte_len = cur_vif_insn_length (); -#if 0 /* unpack doesn't support prespecifying a length */ - if (cur_varlen_value * 16 != bytelen) - as_warn ("length in `direct' instruction does not match length of data"); -#endif - if (output_vif) - install_vif_length (cur_varlen_insn, byte_len); - - cur_asm_state = ASM_INIT; - - /* These needn't be reset, but to catch bugs they are. */ - cur_varlen_frag = NULL; - cur_varlen_insn = NULL; - cur_varlen_value = 0; - - /* Update $.UnpackLoc. */ - vif_set_unpackloc (vif_get_unpackloc () + byte_len); - - demand_empty_rest_of_line (); -} - -static void s_state (state) int state; { /* If in MPG state and the user requests to change to VU state, leave the state as MPG. This happens when we see an mpg followed by a .include that has .vu. */ - if (cur_asm_state == ASM_MPG && state == ASM_VU) + if (CUR_ASM_STATE == ASM_MPG && state == ASM_VU) return; - cur_asm_state = state; + set_asm_state (state); demand_empty_rest_of_line (); } |