diff options
author | K. Richard Pixley <rich@cygnus> | 1991-04-04 18:19:53 +0000 |
---|---|---|
committer | K. Richard Pixley <rich@cygnus> | 1991-04-04 18:19:53 +0000 |
commit | fecd2382e77b89f12c9d630ed4e42e9a54ba6953 (patch) | |
tree | 6cddf76f492c3485605175c97c13d9a24c65306f /gas/cond.c | |
parent | b6fc45ca4c306a4f6f6bdbaf90a69d3dab62777a (diff) | |
download | gdb-fecd2382e77b89f12c9d630ed4e42e9a54ba6953.zip gdb-fecd2382e77b89f12c9d630ed4e42e9a54ba6953.tar.gz gdb-fecd2382e77b89f12c9d630ed4e42e9a54ba6953.tar.bz2 |
Initial revision
Diffstat (limited to 'gas/cond.c')
-rw-r--r-- | gas/cond.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/gas/cond.c b/gas/cond.c new file mode 100644 index 0000000..38aec6f --- /dev/null +++ b/gas/cond.c @@ -0,0 +1,128 @@ +/* cond.c - conditional assembly pseudo-ops, and .include + Copyright (C) 1990, 1991 Free Software Foundation, Inc. + +This file is part of GAS, the GNU Assembler. + +GAS is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GAS is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* static const char rcsid[] = "$Id$"; */ + +#include "as.h" + +#include "obstack.h" + +void s_ifdef(arg) +int arg; +{ +/* register char c; */ + register char *name; /* points to name of symbol */ + register struct symbol * symbolP; /* Points to symbol */ + + SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ + name = input_line_pointer; + if (!is_name_beginner(*name)) { + as_bad("invalid identifier for .ifdef"); + obstack_1grow (&cond_obstack, 0); + } else { + get_symbol_end(); + ++input_line_pointer; + symbolP = symbol_find(name); + + /* ??? Should we try to optimize such that if we hit a .endif + before a .else, we don't need to push state? */ + obstack_1grow(&cond_obstack, (symbolP != 0) ^ arg); + } +} /* s_ifdef() */ + +/* This is allocated to grow and shrink as .ifdef/.endif pairs + are scanned. When the top element is nonzero, it means + we should accept input. Otherwise, we should ignore input. */ +struct obstack cond_obstack; + +void s_if(arg) +int arg; +{ + expressionS operand; + + SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */ + expr(0, &operand); + + if (operand.X_add_symbol != NULL + || operand.X_subtract_symbol != NULL) + as_bad("non-constant expression in .if statement"); + + /* If the above error is signaled, this will dispatch + using an undefined result. No big deal. */ + obstack_1grow(&cond_obstack, (operand.X_add_number != 0) ^ arg); +} /* s_if() */ + +void s_endif(arg) +int arg; +{ + char *base = obstack_base(&cond_obstack); + char *ptr = obstack_next_free(&cond_obstack); + + if (ptr-1 == base) { + as_bad("unbalanced .endif"); + } else { + obstack_free(&cond_obstack, ptr-1); + cond_obstack.object_base = base; + } +} /* s_endif() */ + +void s_else(arg) +int arg; +{ + char *ptr = obstack_next_free(&cond_obstack); + if (ptr-1 == obstack_base(&cond_obstack)) { + as_bad(".else without matching .if"); + } else { + ptr[-1] = !ptr[-1]; + } +} /* s_else() */ + +void s_ifeqs(arg) +int arg; +{ + as_bad("ifeqs not implemented."); +} /* s_ifeqs() */ + +void s_end(arg) +int arg; +{ + ; +} /* s_end() */ + +int ignore_input() { + char *ptr = obstack_next_free (&cond_obstack); + + /* We cannot ignore certain pseudo ops. */ + if (input_line_pointer[-1] == '.') + { + if (input_line_pointer[0] == 'i' + && (!strncmp (input_line_pointer, "if", 2) + || !strncmp (input_line_pointer, "ifdef", 5) + || !strncmp (input_line_pointer, "ifndef", 6))) + return 0; + if (input_line_pointer[0] == 'e' + && (!strncmp (input_line_pointer, "else", 4) + || !strncmp (input_line_pointer, "endif", 5))) + return 0; + } + + return (ptr[-1] == 0); +} /* ignore_input() */ + +/* end of cond.c */ |