aboutsummaryrefslogtreecommitdiff
path: root/gas/cgen.c
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>1998-01-12 21:12:52 +0000
committerDoug Evans <dje@google.com>1998-01-12 21:12:52 +0000
commit1002d8ed0b06cebde9e23c04ca1d2475854f2b93 (patch)
tree35cf547e659dd5d76c9272e37b5b4c78b9fbb1e4 /gas/cgen.c
parentb5e9e5625f38a485a0e1fb0796c342ed35b813f1 (diff)
downloadgdb-1002d8ed0b06cebde9e23c04ca1d2475854f2b93.zip
gdb-1002d8ed0b06cebde9e23c04ca1d2475854f2b93.tar.gz
gdb-1002d8ed0b06cebde9e23c04ca1d2475854f2b93.tar.bz2
* cgen.c: #include setjmp.h. Clean up pass over `struct foo' usage.
(expr_jmp_buf): New static local. (cgen_parse_operand): Allow use of longjmp in parsing to handle errors. (cgen_md_operand): New function. * tc-m32r.c: Clean up pass over `struct foo' usage. (md_estimate_size_before_relax): Use CGEN_INSN_MNEMONIC.
Diffstat (limited to 'gas/cgen.c')
-rw-r--r--gas/cgen.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/gas/cgen.c b/gas/cgen.c
index 3ed8d99..0e5c33c 100644
--- a/gas/cgen.c
+++ b/gas/cgen.c
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#include <setjmp.h>
#include "ansidecl.h"
#include "bfd.h"
#include "cgen-opc.h"
@@ -103,9 +104,9 @@ fixS *
cgen_record_fixup (frag, where, insn, length, operand, opinfo, symbol, offset)
fragS *frag;
int where;
- const struct cgen_insn *insn;
+ const CGEN_INSN *insn;
int length;
- const struct cgen_operand *operand;
+ const CGEN_OPERAND *operand;
int opinfo;
symbolS *symbol;
offsetT offset;
@@ -141,9 +142,9 @@ fixS *
cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
fragS *frag;
int where;
- const struct cgen_insn *insn;
+ const CGEN_INSN *insn;
int length;
- const struct cgen_operand *operand;
+ const CGEN_OPERAND *operand;
int opinfo;
expressionS *exp;
{
@@ -161,6 +162,9 @@ cgen_record_fixup_exp (frag, where, insn, length, operand, opinfo, exp)
return fixP;
}
+/* Used for communication between the next two procedures. */
+static jmp_buf expr_jmp_buf;
+
/* Callback for cgen interface. Parse the expression at *STRP.
The result is an error message or NULL for success (in which case
*STRP is advanced past the parsed text).
@@ -181,7 +185,14 @@ cgen_parse_operand (want, strP, opindex, opinfo, resultP, valueP)
enum cgen_parse_operand_result *resultP;
bfd_vma *valueP;
{
- char *hold;
+#ifdef __STDC__
+ /* These is volatile to survive the setjmp. */
+ char * volatile hold;
+ enum cgen_parse_operand_result * volatile resultP_1;
+#else
+ static char *hold;
+ static enum cgen_parse_operand_result *resultP_1;
+#endif
const char *errmsg = NULL;
expressionS exp;
@@ -191,9 +202,21 @@ cgen_parse_operand (want, strP, opindex, opinfo, resultP, valueP)
return NULL;
}
+ resultP_1 = resultP;
hold = input_line_pointer;
input_line_pointer = (char *) *strP;
+
+ /* We rely on md_operand to longjmp back to us.
+ This is done via cgen_md_operand. */
+ if (setjmp (expr_jmp_buf) != 0)
+ {
+ input_line_pointer = (char *) hold;
+ *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
+ return "illegal operand";
+ }
+
expression (&exp);
+
*strP = input_line_pointer;
input_line_pointer = hold;
@@ -227,13 +250,25 @@ cgen_parse_operand (want, strP, opindex, opinfo, resultP, valueP)
return errmsg;
}
+/* md_operand handler to catch unrecognized expressions and halt the
+ parsing process so the next entry can be tried.
+
+ ??? This could be done differently by adding code to `expression'. */
+
+void
+cgen_md_operand (expressionP)
+ expressionS *expressionP;
+{
+ longjmp (expr_jmp_buf, 1);
+}
+
/* Finish assembling instruction INSN.
BUF contains what we've built up so far.
LENGTH is the size of the insn in bits. */
void
cgen_asm_finish_insn (insn, buf, length)
- const struct cgen_insn *insn;
+ const CGEN_INSN *insn;
cgen_insn_t *buf;
unsigned int length;
{
@@ -303,12 +338,9 @@ cgen_asm_finish_insn (insn, buf, length)
f);
/* Record the operand number with the fragment so md_convert_frag
can use cgen_md_record_fixup to record the appropriate reloc. */
- /* FIXME: fr_targ.cgen is used pending deciding whether to
- allow a target to add members to fragS. For more info
- see the comment above fr_targ in as.h. */
- old_frag->fr_targ.cgen.insn = insn;
- old_frag->fr_targ.cgen.opindex = fixups[relax_operand].opindex;
- old_frag->fr_targ.cgen.opinfo = fixups[relax_operand].opinfo;
+ old_frag->fr_cgen.insn = insn;
+ old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
+ old_frag->fr_cgen.opinfo = fixups[relax_operand].opinfo;
}
else
f = frag_more (byte_len);
@@ -418,11 +450,11 @@ cgen_md_apply_fix3 (fixP, valueP, seg)
if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
{
int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
- const struct cgen_operand *operand = & CGEN_SYM (operand_table) [opindex];
+ const CGEN_OPERAND *operand = & CGEN_SYM (operand_table) [opindex];
const char *errmsg;
bfd_reloc_code_real_type reloc_type;
- struct cgen_fields fields;
- const struct cgen_insn *insn = (struct cgen_insn *) fixP->tc_fix_data.insn;
+ CGEN_FIELDS fields;
+ const CGEN_INSN *insn = (CGEN_INSN *) fixP->tc_fix_data.insn;
/* If the reloc has been fully resolved finish the operand here. */
/* FIXME: This duplicates the capabilities of code in BFD. */
@@ -506,7 +538,7 @@ cgen_tc_gen_reloc (section, fixP)
{
arelent *reloc;
- reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+ reloc = (arelent *) bfd_alloc (stdoutput, sizeof (arelent));
reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
if (reloc->howto == (reloc_howto_type *) NULL)