diff options
-rw-r--r-- | gas/expr.c | 51 | ||||
-rw-r--r-- | gas/read.c | 106 |
2 files changed, 103 insertions, 54 deletions
@@ -31,6 +31,8 @@ #include "obstack.h" +static void floating_constant PARAMS ((expressionS * expressionP)); +static void integer_constant PARAMS ((int radix, expressionS * expressionP)); static void clean_up_expression PARAMS ((expressionS * expressionP)); static symbolS *make_expr_symbol PARAMS ((expressionS * expressionP)); @@ -49,11 +51,8 @@ make_expr_symbol (expressionP) /* FIXME: This should be something which decode_local_label_name will handle. */ -#ifdef DOT_LABEL_PREFIX - fake = ".L0\001"; -#else - fake = "L0\001"; -#endif + fake = FAKE_LABEL_NAME; + /* Putting constant symbols in absolute_section rather than expr_section is convenient for the old a.out code, for which S_GET_SEGMENT does not always retrieve the value put in by @@ -89,7 +88,7 @@ FLONUM_TYPE generic_floating_point_number = /* If nonzero, we've been asked to assemble nan, +inf or -inf */ int generic_floating_point_magic; -void +static void floating_constant (expressionP) expressionS *expressionP; { @@ -118,7 +117,7 @@ floating_constant (expressionP) expressionP->X_add_number = -1; } -void +static void integer_constant (radix, expressionP) int radix; expressionS *expressionP; @@ -230,10 +229,8 @@ integer_constant (radix, expressionP) } /* again, c is char after number, */ /* input_line_pointer->after c. */ - know (sizeof (int) * 8 == 32); know (LITTLENUM_NUMBER_OF_BITS == 16); - /* hence the constant "2" in the next line. */ - if (leader < generic_bignum + 2) + if (leader < generic_bignum + sizeof (valueT) / 2) { /* will fit into 32 bits. */ number = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) @@ -331,15 +328,15 @@ integer_constant (radix, expressionP) then this is a fresh instantiation of that number, so create it. */ - if (dollar_label_defined (number)) + if (dollar_label_defined ((long) number)) { - name = dollar_label_name (number, 0); + name = dollar_label_name ((long) number, 0); symbolP = symbol_find (name); know (symbolP != NULL); } else { - name = dollar_label_name (number, 1); + name = dollar_label_name ((long) number, 1); symbolP = symbol_find_or_make (name); } @@ -371,7 +368,7 @@ integer_constant (radix, expressionP) expressionP->X_add_number = number; input_line_pointer--; /*->char following number. */ } -} /* integer_constant() */ +} /* @@ -394,6 +391,14 @@ operand (expressionP) char *name; /* points to name of symbol */ segT segment; + /* All integers are regarded as unsigned unless they are negated. + This is because the only thing which cares whether a number is + unsigned is the code in emit_expr which extends constants into + bignums. It should only sign extend negative numbers, so that + something like ``.quad 0x80000000'' is not sign extended even + though it appears negative if valueT is 32 bits. */ + expressionP->X_unsigned = 1; + /* digits, assume it is a bignum. */ SKIP_WHITESPACE (); /* leading whitespace is part of operand. */ @@ -562,6 +567,7 @@ operand (expressionP) expressionP->X_add_number = - expressionP->X_add_number; /* Notice: '-' may overflow: no warning is given. This is compatible with other people's assemblers. Sigh. */ + expressionP->X_unsigned = 0; } else expressionP->X_add_number = ~ expressionP->X_add_number; @@ -589,11 +595,7 @@ operand (expressionP) /* JF: '.' is pseudo symbol with value of current location in current segment. */ -#ifdef DOT_LABEL_PREFIX - fake = ".L0\001"; -#else - fake = "L0\001"; -#endif + fake = FAKE_LABEL_NAME; symbolP = symbol_new (fake, now_seg, (valueT) frag_now_fix (), @@ -852,8 +854,8 @@ expr (rank, resultP) as_warn ("missing operand; zero assumed"); right.X_op = O_constant; right.X_add_number = 0; - resultP->X_add_symbol = NULL; - resultP->X_op_symbol = NULL; + right.X_add_symbol = NULL; + right.X_op_symbol = NULL; } know (*input_line_pointer != ' '); @@ -866,7 +868,11 @@ expr (rank, resultP) else if (! SEG_NORMAL (retval)) retval = rightseg; else if (SEG_NORMAL (rightseg) - && retval != rightseg) + && retval != rightseg +#ifdef DIFF_EXPR_OK + && op_left != O_subtract +#endif + ) as_bad ("operation combines symbols in different segments"); c_right = *input_line_pointer; @@ -968,6 +974,7 @@ expr (rank, resultP) resultP->X_op_symbol = make_expr_symbol (&right); resultP->X_op = op_left; resultP->X_add_number = 0; + resultP->X_unsigned = 1; } op_left = op_right; @@ -50,6 +50,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "aout/stab_gnu.h" +/* Allow backends to override the names used for the stab sections. */ +#ifndef STAB_SECTION_NAME +#define STAB_SECTION_NAME ".stab" +#endif + +#ifndef STAB_STRING_SECTION_NAME +#define STAB_STRING_SECTION_NAME ".stabstr" +#endif + #ifndef TC_START_LABEL #define TC_START_LABEL(x,y) (x==':') #endif @@ -449,6 +458,19 @@ read_a_source_file (name) pop = NULL; +#define IGNORE_OPCODE_CASE +#ifdef IGNORE_OPCODE_CASE + { + char *s2 = s; + while (*s2) + { + if (isupper (*s2)) + *s2 = tolower (*s2); + s2++; + } + } +#endif + #ifdef NO_PSEUDO_DOT /* The m88k uses pseudo-ops without a period. */ pop = (pseudo_typeS *) hash_find (po_hash, s); @@ -484,9 +506,7 @@ read_a_source_file (name) A well shaped space is sometimes all that separates keyword from operands. */ if (c == ' ' || c == '\t') - { - input_line_pointer++; - } /* Skip seperator after keyword. */ + input_line_pointer++; /* * Input_line is restored. * Input_line_pointer->1st non-blank char @@ -498,9 +518,7 @@ read_a_source_file (name) break; } else - { - (*pop->poc_handler) (pop->poc_val); - } /* if we have one */ + (*pop->poc_handler) (pop->poc_val); } else #endif @@ -524,23 +542,22 @@ read_a_source_file (name) *input_line_pointer++ = c; - /* We resume loop AFTER the end-of-line from this instruction */ + /* We resume loop AFTER the end-of-line from + this instruction. */ } /* if (*s=='.') */ - } /* if c==':' */ continue; } /* if (is_name_beginner(c) */ + /* Empty statement? */ if (is_end_of_line[(unsigned char) c]) - { - continue; - } /* empty statement */ - + continue; #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB) if (isdigit (c)) - { /* local label ("4:") */ + { + /* local label ("4:") */ char *backup = input_line_pointer; HANDLE_CONDITIONAL_ASSEMBLY (); @@ -2274,8 +2291,9 @@ next_char_of_string () case '9': { long number; + int i; - for (number = 0; isdigit (c); c = *input_line_pointer++) + for (i = 0, number = 0; isdigit (c) && i < 3; c = *input_line_pointer++, i++) { number = number * 8 + c - '0'; } @@ -2284,6 +2302,28 @@ next_char_of_string () --input_line_pointer; break; + case 'x': + case 'X': + { + long number; + + number = 0; + c = *input_line_pointer++; + while (isxdigit (c)) + { + if (isdigit (c)) + number = number * 16 + c - '0'; + else if (isupper (c)) + number = number * 16 + c - 'A' + 10; + else + number = number * 16 + c - 'a' + 10; + c = *input_line_pointer++; + } + c = number & 0xff; + --input_line_pointer; + } + break; + case '\n': /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */ as_warn ("Unterminated string: Newline inserted."); @@ -2598,9 +2638,9 @@ s_ignore (arg) #ifdef SEPARATE_STAB_SECTIONS unsigned int -get_stab_string_offset (string, secname) +get_stab_string_offset (string, stabstr_secname) const char *string; - const char *secname; + const char *stabstr_secname; { unsigned int length; unsigned int retval; @@ -2620,9 +2660,8 @@ get_stab_string_offset (string, secname) save_subseg = now_subseg; /* Create the stab string section. */ - newsecname = xmalloc ((unsigned long) (strlen (secname) + 4)); - strcpy (newsecname, secname); - strcat (newsecname, "str"); + newsecname = xmalloc ((unsigned long) (strlen (stabstr_secname) + 1)); + strcpy (newsecname, stabstr_secname); seg = subseg_new (newsecname, 0); @@ -2659,9 +2698,10 @@ get_stab_string_offset (string, secname) kinds of stab sections. */ static void -s_stab_generic (what, secname) +s_stab_generic (what, stab_secname, stabstr_secname) int what; - char *secname; + char *stab_secname; + char *stabstr_secname; { long longint; char *string; @@ -2742,7 +2782,7 @@ s_stab_generic (what, secname) dot = frag_now_fix (); - seg = subseg_new (secname, 0); + seg = subseg_new (stab_secname, 0); if (! seg_info (seg)->hadone) { @@ -2755,7 +2795,7 @@ s_stab_generic (what, secname) seg_info (seg)->hadone = 1; } - stroff = get_stab_string_offset (string, secname); + stroff = get_stab_string_offset (string, stabstr_secname); /* At least for now, stabs in a special stab section are always output as 12 byte blocks of information. */ @@ -2778,11 +2818,7 @@ s_stab_generic (what, secname) expressionS exp; /* Arrange for a value representing the current location. */ -#ifdef DOT_LABEL_PREFIX - fake = ".L0\001"; -#else - fake = "L0\001"; -#endif + fake = FAKE_LABEL_NAME; symbol = symbol_new (fake, saved_seg, dot, saved_frag); exp.X_op = O_symbol; @@ -2854,7 +2890,7 @@ void s_stab (what) int what; { - s_stab_generic (what, ".stab"); + s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME); } /* "Extended stabs", used in Solaris only now. */ @@ -2864,9 +2900,9 @@ s_xstab (what) int what; { int length; - char *secname; + char *stab_secname, *stabstr_secname; - secname = demand_copy_C_string (&length); + stab_secname = demand_copy_C_string (&length); SKIP_WHITESPACE (); if (*input_line_pointer == ',') input_line_pointer++; @@ -2876,7 +2912,13 @@ s_xstab (what) ignore_rest_of_line (); return; } - s_stab_generic (what, secname); + + /* To get the name of the stab string section, simply .str to + the stab section name. */ + stabstr_secname = alloca (strlen (stab_secname) + 4); + strcpy (stabstr_secname, stab_secname); + strcat (stabstr_secname, "str"); + s_stab_generic (what, stab_secname, stabstr_secname); } #ifdef S_SET_DESC |