aboutsummaryrefslogtreecommitdiff
path: root/gas/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/read.c')
-rw-r--r--gas/read.c285
1 files changed, 157 insertions, 128 deletions
diff --git a/gas/read.c b/gas/read.c
index 990de7c..bb6e6d2 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -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);
}