diff options
Diffstat (limited to 'gas/read.c')
-rw-r--r-- | gas/read.c | 285 |
1 files changed, 157 insertions, 128 deletions
@@ -159,17 +159,9 @@ char is_end_of_line[256] = static char *buffer; /* 1st char of each buffer of lines is here. */ static char *buffer_limit; /*->1 + last char in buffer. */ -#ifdef TARGET_BYTES_BIG_ENDIAN -/* Hack to deal with tc-*.h defining TARGET_BYTES_BIG_ENDIAN to empty - instead of to 0 or 1. */ -#if 5 - TARGET_BYTES_BIG_ENDIAN - 5 == 10 -#undef TARGET_BYTES_BIG_ENDIAN -#define TARGET_BYTES_BIG_ENDIAN 1 -#endif +/* TARGET_BYTES_BIG_ENDIAN is required to be defined to either 0 or 1 in the + tc-<CPU>.h file. See the "Porting GAS" section of the internals manual. */ int target_big_endian = TARGET_BYTES_BIG_ENDIAN; -#else -int target_big_endian /* = 0 */; -#endif static char *old_buffer; /* JF a hack */ static char *old_input; @@ -208,7 +200,8 @@ symbolS *mri_common_symbol; static int mri_pending_align; static int scrub_from_string PARAMS ((char **)); -static void do_align PARAMS ((int, char *, int)); +static void do_align PARAMS ((int, char *, int, int)); +static void s_align PARAMS ((int, int)); static int hex_float PARAMS ((int, char *)); static void do_org PARAMS ((segT, expressionS *, int)); char *demand_copy_string PARAMS ((int *lenP)); @@ -534,6 +527,7 @@ read_a_source_file (name) char c; int mri_line_macro; + LISTING_NEWLINE (); HANDLE_CONDITIONAL_ASSEMBLY (); c = get_symbol_end (); @@ -554,7 +548,8 @@ read_a_source_file (name) && (rest[3] == ' ' || rest[3] == '\t')) { input_line_pointer = rest + 3; - equals (line_start); + equals (line_start, + strncasecmp (rest, "SET", 3) == 0); continue; } if (strncasecmp (rest, "MACRO", 5) == 0 @@ -640,7 +635,7 @@ read_a_source_file (name) && (rest[3] == ' ' || rest[3] == '\t')) { input_line_pointer = rest + 3; - equals (s); + equals (s, 1); continue; } } @@ -660,7 +655,7 @@ read_a_source_file (name) #endif )) { - equals (s); + equals (s, 1); demand_empty_rest_of_line (); } else @@ -728,7 +723,7 @@ read_a_source_file (name) || pop->poc_handler == s_globl || pop->poc_handler == s_ignore))) { - do_align (1, (char *) NULL, 0); + do_align (1, (char *) NULL, 0, 0); mri_pending_align = 0; if (line_label != NULL) { @@ -823,7 +818,7 @@ read_a_source_file (name) if (mri_pending_align) { - do_align (1, (char *) NULL, 0); + do_align (1, (char *) NULL, 0, 0); mri_pending_align = 0; if (line_label != NULL) { @@ -1092,40 +1087,43 @@ s_abort (ignore) as_fatal (".abort detected. Abandoning ship."); } -/* Guts of .align directive. */ +/* Guts of .align directive. N is the power of two to which to align. + FILL may be NULL, or it may point to the bytes of the fill pattern. + LEN is the length of whatever FILL points to, if anything. MAX is + the maximum number of characters to skip when doing the alignment, + or 0 if there is no maximum. */ + static void -do_align (n, fill, len) +do_align (n, fill, len, max) int n; char *fill; int len; + int max; { + char default_fill; + #ifdef md_do_align - md_do_align (n, fill, len, just_record_alignment); + md_do_align (n, fill, len, max, just_record_alignment); #endif - if (!fill) - { - /* @@ Fix this right for BFD! */ - static char zero; - static char nop_opcode = NOP_OPCODE; + if (fill == NULL) + { + /* FIXME: Fix this right for BFD! */ if (now_seg != data_section && now_seg != bss_section) - { - fill = &nop_opcode; - } + default_fill = NOP_OPCODE; else - { - fill = &zero; - } + default_fill = 0; + fill = &default_fill; len = 1; } /* Only make a frag if we HAVE to. . . */ - if (n && !need_pass_2) + if (n != 0 && !need_pass_2) { if (len <= 1) - frag_align (n, *fill); + frag_align (n, *fill, max); else - frag_align_pattern (n, fill, len); + frag_align_pattern (n, fill, len, max); } #ifdef md_do_align @@ -1135,17 +1133,22 @@ do_align (n, fill, len) record_alignment (now_seg, n); } -/* For machines where ".align 4" means align to a 4 byte boundary. */ -void -s_align_bytes (arg) +/* Handle the .align pseudo-op. A positive ARG is a default alignment + (in bytes). A negative ARG is the negative of the length of the + fill pattern. BYTES_P is non-zero if the alignment value should be + interpreted as the byte boundary, rather than the power of 2. */ + +static void +s_align (arg, bytes_p) int arg; + int bytes_p; { - register unsigned int temp; - char temp_fill; - unsigned int i = 0; - unsigned long max_alignment = 1 << 15; + register unsigned int align; char *stop = NULL; char stopc; + offsetT fill = 0; + int max; + int fill_p; if (flag_mri) stop = mri_comment_field (&stopc); @@ -1153,122 +1156,94 @@ s_align_bytes (arg) if (is_end_of_line[(unsigned char) *input_line_pointer]) { if (arg < 0) - temp = 0; + align = 0; else - temp = arg; /* Default value from pseudo-op table */ + align = arg; /* Default value from pseudo-op table */ } else - temp = get_absolute_expression (); - - if (temp > max_alignment) { - as_bad ("Alignment too large: %d. assumed.", temp = max_alignment); + align = get_absolute_expression (); + SKIP_WHITESPACE (); } - /* For the sparc, `.align (1<<n)' actually means `.align n' so we - have to convert it. */ - if (temp != 0) + if (bytes_p) { - for (i = 0; (temp & 1) == 0; temp >>= 1, ++i) - ; + /* Convert to a power of 2. */ + if (align != 0) + { + unsigned int i; + + for (i = 0; (align & 1) == 0; align >>= 1, ++i) + ; + if (align != 1) + as_bad ("Alignment not a power of 2"); + align = i; + } } - if (temp != 1) - as_bad ("Alignment not a power of 2"); - temp = i; - if (*input_line_pointer == ',') + if (align > 15) { - offsetT fillval; - int len; + align = 15; + as_bad ("Alignment too large: %u assumed", align); + } - input_line_pointer++; - fillval = get_absolute_expression (); - if (arg >= 0) - len = 1; + if (*input_line_pointer != ',') + { + fill_p = 0; + max = 0; + } + else + { + ++input_line_pointer; + if (*input_line_pointer == ',') + fill_p = 0; else - len = - arg; - if (len <= 1) { - temp_fill = fillval; - do_align (temp, &temp_fill, len); + fill = get_absolute_expression (); + SKIP_WHITESPACE (); + fill_p = 1; } + + if (*input_line_pointer != ',') + max = 0; else { - char ab[16]; - - if (len > sizeof ab) - abort (); - md_number_to_chars (ab, fillval, len); - do_align (temp, ab, len); + ++input_line_pointer; + max = get_absolute_expression (); } } - else + + if (! fill_p) { if (arg < 0) as_warn ("expected fill pattern missing"); - do_align (temp, (char *) NULL, 0); + do_align (align, (char *) NULL, 0, max); } - - if (flag_mri) - mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); -} - -/* For machines where ".align 4" means align to 2**4 boundary. */ -void -s_align_ptwo (arg) - int arg; -{ - register int temp; - char temp_fill; - long max_alignment = 15; - char *stop = NULL; - char stopc; - - if (flag_mri) - stop = mri_comment_field (&stopc); - - temp = get_absolute_expression (); - if (temp > max_alignment) - as_bad ("Alignment too large: %d. assumed.", temp = max_alignment); - else if (temp < 0) - { - as_bad ("Alignment negative. 0 assumed."); - temp = 0; - } - if (*input_line_pointer == ',') + else { - offsetT fillval; - int len; + int fill_len; - input_line_pointer++; - fillval = get_absolute_expression (); if (arg >= 0) - len = 1; + fill_len = 1; else - len = - arg; - if (len <= 1) + fill_len = - arg; + if (fill_len <= 1) { - temp_fill = fillval; - do_align (temp, &temp_fill, len); + char fill_char; + + fill_char = fill; + do_align (align, &fill_char, fill_len, max); } else { char ab[16]; - if (len > sizeof ab) + if (fill_len > sizeof ab) abort (); - md_number_to_chars (ab, fillval, len); - do_align (temp, ab, len); + md_number_to_chars (ab, fill, fill_len); + do_align (align, ab, fill_len, max); } } - else - { - if (arg < 0) - as_warn ("expected fill pattern missing"); - do_align (temp, (char *) NULL, 0); - } if (flag_mri) mri_comment_end (stop, stopc); @@ -1276,6 +1251,26 @@ s_align_ptwo (arg) demand_empty_rest_of_line (); } +/* Handle the .align pseudo-op on machines where ".align 4" means + align to a 4 byte boundary. */ + +void +s_align_bytes (arg) + int arg; +{ + s_align (arg, 1); +} + +/* Handle the .align pseud-op on machines where ".align 4" means align + to a 2**4 boundary. */ + +void +s_align_ptwo (arg) + int arg; +{ + s_align (arg, 0); +} + void s_comm (ignore) int ignore; @@ -1957,7 +1952,7 @@ s_lcomm (needs_align) subseg_set (bss_seg, 1); if (align) - frag_align (align, 0); + frag_align (align, 0, 0); /* detach from old frag */ if (S_GET_SEGMENT (symbolP) == bss_seg) symbolP->sy_frag->fr_symbol = NULL; @@ -2060,6 +2055,8 @@ static int get_line_sb (line) sb *line; { + char quote1, quote2, inquote; + if (input_line_pointer[-1] == '\n') bump_line_counters (); @@ -2070,10 +2067,36 @@ get_line_sb (line) return 0; } - while (! is_end_of_line[(unsigned char) *input_line_pointer]) - sb_add_char (line, *input_line_pointer++); - while (input_line_pointer < buffer_limit - && is_end_of_line[(unsigned char) *input_line_pointer]) + /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this + code needs to be changed. */ + if (! flag_m68k_mri) + quote1 = '"'; + else + quote1 = '\0'; + + quote2 = '\0'; + if (flag_m68k_mri) + quote2 = '\''; +#ifdef LEX_IS_STRINGQUOTE + quote2 = '\''; +#endif + + inquote = '\0'; + while (! is_end_of_line[(unsigned char) *input_line_pointer] + || (inquote != '\0' && *input_line_pointer != '\n')) + { + if (inquote == *input_line_pointer) + inquote = '\0'; + else if (inquote == '\0') + { + if (*input_line_pointer == quote1) + inquote = quote1; + else if (*input_line_pointer == quote2) + inquote = quote2; + } + sb_add_char (line, *input_line_pointer++); + } + while (input_line_pointer < buffer_limit && *input_line_pointer == '\n') { if (input_line_pointer[-1] == '\n') bump_line_counters (); @@ -2606,7 +2629,7 @@ s_space (mult) } else { - do_align (1, (char *) NULL, 0); + do_align (1, (char *) NULL, 0, 0); if (line_label != NULL) { line_label->sy_frag = frag_now; @@ -4173,8 +4196,9 @@ is_it_end_of_statement () } /* is_it_end_of_statement() */ void -equals (sym_name) +equals (sym_name, reassign) char *sym_name; + int reassign; { register symbolS *symbolP; /* symbol we are working with */ char *stop; @@ -4203,6 +4227,11 @@ equals (sym_name) else { symbolP = symbol_find_or_make (sym_name); + /* Permit register names to be redefined. */ + if (! reassign + && S_IS_DEFINED (symbolP) + && S_GET_SEGMENT (symbolP) != reg_section) + as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP)); pseudo_set (symbolP); } |