* config/tc-mips.c (mips_align): Take new argument, label, and use

it instead of global insn_label.
	(s_align, s_cons, s_float_cons, s_gpword): Save insn_label before
	call to mips_emit_delay and pass it to mips_align.
This commit is contained in:
Ian Lance Taylor
1994-03-16 22:16:02 +00:00
parent f8715549af
commit 23dc1ae33d
2 changed files with 44 additions and 23 deletions

View File

@ -1,3 +1,15 @@
Wed Mar 16 17:11:37 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* config/tc-mips.c (mips_align): Take new argument, label, and use
it instead of global insn_label.
(s_align, s_cons, s_float_cons, s_gpword): Save insn_label before
call to mips_emit_delay and pass it to mips_align.
Wed Mar 16 11:54:12 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
* config/tc-hppa.c (pa_reg): Use pa_parse_number so that we can
use pre-defined registers as arguments.
Mon Mar 14 14:29:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com) Mon Mar 14 14:29:45 1994 Ken Raeburn (raeburn@cujo.cygnus.com)
* write.c (write_object_file): Check both S_IS_LOCAL and * write.c (write_object_file): Check both S_IS_LOCAL and

View File

@ -228,7 +228,7 @@ static int prev_prev_insn_unreordered;
Every macro that refers to a symbol can occur in (at least) two Every macro that refers to a symbol can occur in (at least) two
forms, one with GP relative addressing and one without. For forms, one with GP relative addressing and one without. For
example, loading a global variable into a register generally uses example, loading a global variable into a register generally uses
an macroinstruction like this: a macro instruction like this:
lw $4,i lw $4,i
If i can be addressed off the GP register (this is true if it is in If i can be addressed off the GP register (this is true if it is in
the .sbss or .sdata section, or if it is known to be smaller than the .sbss or .sdata section, or if it is known to be smaller than
@ -246,12 +246,12 @@ static int prev_prev_insn_unreordered;
until after we see the instruction that uses it. Therefore, we until after we see the instruction that uses it. Therefore, we
want to be able to choose the final instruction sequence only at want to be able to choose the final instruction sequence only at
the end of the assembly. This is similar to the way other the end of the assembly. This is similar to the way other
platforms choose the form of a PC relative instruction only at the platforms choose the size of a PC relative instruction only at the
end of assembly. end of assembly.
When generating position independent code we do not use GP When generating position independent code we do not use GP
addressing in the same way, but the issue still arises as external addressing in quite the same way, but the issue still arises as
symbols and local symbols must be handled differently. external symbols and local symbols must be handled differently.
We handle these issues by actually generating both possible We handle these issues by actually generating both possible
instruction sequences. The longer one is put in a frag_var with instruction sequences. The longer one is put in a frag_var with
@ -268,13 +268,13 @@ static int prev_prev_insn_unreordered;
noat is in effect). All these numbers are reasonably small. noat is in effect). All these numbers are reasonably small.
Generating two instruction sequences must be handled carefully to Generating two instruction sequences must be handled carefully to
ensure that delay slots are handled correctly. Fortunately, the ensure that delay slots are handled correctly. Fortunately, there
issue only arises in a restricted number of cases. When the second are a limited number of cases. When the second instruction
instruction sequence is generated, append_insn is directed to sequence is generated, append_insn is directed to maintain the
maintain the existing delay slot information, so it continues to existing delay slot information, so it continues to apply to any
apply to any code after the second instruction sequence. This code after the second instruction sequence. This means that the
means that the second instruction sequence must not impose any second instruction sequence must not impose any requirements not
requirements not required by the first instruction sequence. required by the first instruction sequence.
These variant frags are then handled in functions called by the These variant frags are then handled in functions called by the
machine independent code. md_estimate_size_before_relax returns machine independent code. md_estimate_size_before_relax returns
@ -331,7 +331,7 @@ static void mips_ip PARAMS ((char *str, struct mips_cl_insn * ip));
static int my_getSmallExpression PARAMS ((expressionS * ep, char *str)); static int my_getSmallExpression PARAMS ((expressionS * ep, char *str));
static void my_getExpression PARAMS ((expressionS * ep, char *str)); static void my_getExpression PARAMS ((expressionS * ep, char *str));
static symbolS *get_symbol PARAMS ((void)); static symbolS *get_symbol PARAMS ((void));
static void mips_align PARAMS ((int to, int fill)); static void mips_align PARAMS ((int to, int fill, symbolS *label));
static void s_align PARAMS ((int)); static void s_align PARAMS ((int));
static void s_stringer PARAMS ((int)); static void s_stringer PARAMS ((int));
static void s_change_sec PARAMS ((int)); static void s_change_sec PARAMS ((int));
@ -5021,19 +5021,19 @@ get_symbol ()
also automatically adjusts any preceding label. */ also automatically adjusts any preceding label. */
static void static void
mips_align (to, fill) mips_align (to, fill, label)
int to; int to;
int fill; int fill;
symbolS *label;
{ {
mips_emit_delays (); mips_emit_delays ();
frag_align (to, fill); frag_align (to, fill);
record_alignment (now_seg, to); record_alignment (now_seg, to);
if (insn_label != NULL) if (label != NULL)
{ {
assert (S_GET_SEGMENT (insn_label) == now_seg); assert (S_GET_SEGMENT (label) == now_seg);
insn_label->sy_frag = frag_now; label->sy_frag = frag_now;
S_SET_VALUE (insn_label, (valueT) frag_now_fix ()); S_SET_VALUE (label, (valueT) frag_now_fix ());
insn_label = NULL;
} }
} }
@ -5078,7 +5078,7 @@ s_align (x)
if (temp) if (temp)
{ {
auto_align = 1; auto_align = 1;
mips_align (temp, (int) temp_fill); mips_align (temp, (int) temp_fill, insn_label);
} }
else else
{ {
@ -5169,9 +5169,12 @@ static void
s_cons (log_size) s_cons (log_size)
int log_size; int log_size;
{ {
symbolS *label;
label = insn_label;
mips_emit_delays (); mips_emit_delays ();
if (log_size > 0 && auto_align) if (log_size > 0 && auto_align)
mips_align (log_size, 0); mips_align (log_size, 0, label);
insn_label = NULL; insn_label = NULL;
cons (1 << log_size); cons (1 << log_size);
} }
@ -5205,13 +5208,17 @@ static void
s_float_cons (type) s_float_cons (type)
int type; int type;
{ {
symbolS *label;
label = insn_label;
mips_emit_delays (); mips_emit_delays ();
if (auto_align) if (auto_align)
if (type == 'd') if (type == 'd')
mips_align (3, 0); mips_align (3, 0, label);
else else
mips_align (2, 0); mips_align (2, 0, label);
insn_label = NULL; insn_label = NULL;
@ -5440,6 +5447,7 @@ static void
s_gpword (ignore) s_gpword (ignore)
int ignore; int ignore;
{ {
symbolS *label;
expressionS ex; expressionS ex;
char *p; char *p;
@ -5450,9 +5458,10 @@ s_gpword (ignore)
return; return;
} }
label = insn_label;
mips_emit_delays (); mips_emit_delays ();
if (auto_align) if (auto_align)
mips_align (2, 0); mips_align (2, 0, label);
insn_label = NULL; insn_label = NULL;
expression (&ex); expression (&ex);