mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-03 23:56:39 +00:00
* config/tc-mips.c (append_insn): Don't swap branch instructions
if .set nobopt or .set volatile. (gp_reference): .lit8 and .lit4 are accessed via the GP register. (macro): Added cases M_LI_S, M_LI_SS. Fixed M_LI_D and M_LI_DD. (mips_ip): Added cases 'F', 'L', 'f', 'l' for floating point. * config/obj-ecoff.c: Renamed some variables to avoid shadow warnings.
This commit is contained in:
parent
45b1470513
commit
19ed896035
@ -1,5 +1,17 @@
|
||||
Wed Aug 18 15:30:29 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* config/tc-mips.c (append_insn): Don't swap branch instructions
|
||||
if .set nobopt or .set volatile.
|
||||
(gp_reference): .lit8 and .lit4 are accessed via the GP register.
|
||||
(macro): Added cases M_LI_S, M_LI_SS. Fixed M_LI_D and M_LI_DD.
|
||||
(mips_ip): Added cases 'F', 'L', 'f', 'l' for floating point.
|
||||
* config/obj-ecoff.c: Renamed some variables to avoid shadow
|
||||
warnings.
|
||||
|
||||
Mon Aug 16 14:16:02 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
|
||||
|
||||
* config/obj-coff.h (S_IS_COMMON): add missing backslash
|
||||
|
||||
* configure.in (z8k-*-{coff,sim}): use coffbfd for this target
|
||||
|
||||
Thu Aug 12 11:47:58 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
@ -165,7 +165,7 @@ static void macro_build_lui PARAMS ((int *counter, expressionS * ep,
|
||||
static void set_at PARAMS ((int *counter, int reg));
|
||||
static void set_at_unsigned PARAMS ((int *counter, int reg));
|
||||
static void check_absolute_expr PARAMS ((struct mips_cl_insn * ip,
|
||||
expressionS * expr));
|
||||
expressionS *));
|
||||
static void load_register PARAMS ((int *counter,
|
||||
struct mips_cl_insn * ip,
|
||||
int reg, expressionS * ep));
|
||||
@ -635,6 +635,11 @@ append_insn (ip, address_expr, reloc_type)
|
||||
|| (ip->insn_mo->pinfo & INSN_COND_BRANCH_DELAY))
|
||||
{
|
||||
if (mips_optimize < 2
|
||||
/* If we have seen .set nobopt, don't optimize. */
|
||||
|| mips_nobopt != 0
|
||||
/* If we have seen .set volatile or .set nomove, don't
|
||||
optimize. */
|
||||
|| mips_nomove != 0
|
||||
/* If we had to emit any NOP instructions, then we
|
||||
already know we can not swap. */
|
||||
|| nops != 0
|
||||
@ -878,7 +883,9 @@ gp_reference (ep)
|
||||
return 1;
|
||||
segname = segment_name (S_GET_SEGMENT (ep->X_add_symbol));
|
||||
return (strcmp (segname, ".sdata") == 0
|
||||
|| strcmp (segname, ".sbss") == 0);
|
||||
|| strcmp (segname, ".sbss") == 0
|
||||
|| strcmp (segname, ".lit8") == 0
|
||||
|| strcmp (segname, ".lit4") == 0);
|
||||
#else /* ! defined (OBJ_ECOFF) */
|
||||
/* The GP register is only used for ECOFF. */
|
||||
return 0;
|
||||
@ -1147,12 +1154,11 @@ set_at_unsigned (counter, reg)
|
||||
}
|
||||
|
||||
static void
|
||||
check_absolute_expr (ip, expr)
|
||||
check_absolute_expr (ip, ex)
|
||||
struct mips_cl_insn *ip;
|
||||
expressionS *expr;
|
||||
expressionS *ex;
|
||||
{
|
||||
|
||||
if (expr->X_op != O_constant)
|
||||
if (ex->X_op != O_constant)
|
||||
as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name);
|
||||
}
|
||||
|
||||
@ -1672,6 +1678,7 @@ macro (ip)
|
||||
s = "lwc0";
|
||||
goto ld;
|
||||
case M_LWC1_AB:
|
||||
case M_LI_SS:
|
||||
s = "lwc1";
|
||||
goto ld;
|
||||
case M_LWC2_AB:
|
||||
@ -1686,7 +1693,12 @@ macro (ip)
|
||||
case M_LWR_AB:
|
||||
s = "lwr";
|
||||
ld:
|
||||
if (breg == treg || mask == M_LWC1_AB)
|
||||
if (breg == treg
|
||||
|| mask == M_LWC0_AB
|
||||
|| mask == M_LWC1_AB
|
||||
|| mask == M_LI_SS
|
||||
|| mask == M_LWC2_AB
|
||||
|| mask == M_LWC3_AB)
|
||||
{
|
||||
tempreg = AT;
|
||||
used_at = 1;
|
||||
@ -1727,8 +1739,15 @@ macro (ip)
|
||||
tempreg = AT;
|
||||
used_at = 1;
|
||||
ld_st:
|
||||
if (mask == M_LWC1_AB || mask == M_SWC1_AB)
|
||||
if (mask == M_LWC1_AB || mask == M_SWC1_AB || mask == M_LI_SS)
|
||||
fmt = "T,o(b)";
|
||||
else if (mask == M_LWC0_AB
|
||||
|| mask == M_LWC2_AB
|
||||
|| mask == M_LWC3_AB
|
||||
|| mask == M_SWC0_AB
|
||||
|| mask == M_SWC2_AB
|
||||
|| mask == M_SWC3_AB)
|
||||
fmt = "E,o(b)";
|
||||
else
|
||||
fmt = "t,o(b)";
|
||||
if (gp_reference (&offset_expr))
|
||||
@ -1753,21 +1772,18 @@ macro (ip)
|
||||
return;
|
||||
|
||||
case M_LI:
|
||||
case M_LI_S:
|
||||
load_register (&icnt, ip, treg, &imm_expr);
|
||||
return;
|
||||
|
||||
case M_LI_D:
|
||||
/*
|
||||
0x400370 <main>: lui $at,%hi(foo)
|
||||
0x400374 <main+4>: lw $v0,%lo(foo)($at)
|
||||
0x400378 <main+8>: lw $v1,%lo(foo+4)($at)
|
||||
.data
|
||||
<foo>:
|
||||
.float 3.133435
|
||||
*/
|
||||
/* FIXME: I don't think this is used at present, because the 'F'
|
||||
format character is not supported. When this is supported,
|
||||
it should use the GP register. */
|
||||
/* lui $at,%hi(foo)
|
||||
lw $v0,%lo(foo)($at)
|
||||
lw $v1,%lo(foo+4)($at)
|
||||
.rdata
|
||||
foo:
|
||||
.double 3.133435
|
||||
*/
|
||||
macro_build_lui (&icnt, &offset_expr, AT);
|
||||
macro_build (&icnt, &offset_expr, "lw", "t,o(b)", treg, AT);
|
||||
offset_expr.X_add_number = 4;
|
||||
@ -1775,18 +1791,9 @@ macro (ip)
|
||||
break;
|
||||
|
||||
case M_LI_DD:
|
||||
/*
|
||||
0x4003a0 <main>: lwc1 $f0,-32752($gp)
|
||||
0x4003a4 <main+4>: lwc1 $f1,-32748($gp)
|
||||
0x4003a8 <main+8>: nop
|
||||
*/
|
||||
/* FIXME: This is nonsense. It isn't used anyhow. */
|
||||
sreg = (ip->insn_opcode >> 11) & 0x1f; /* Fs reg */
|
||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg, AT);
|
||||
offset_expr.X_add_number = 4;
|
||||
macro_build (&icnt, &offset_expr, "lwc1", "T,o(b)", treg + 1, AT);
|
||||
break;
|
||||
|
||||
/* Load a floating point number from the .lit8 section. */
|
||||
breg = GP;
|
||||
/* Fall through. */
|
||||
case M_L_DOB:
|
||||
/* Even on a big endian machine $fn comes before $fn+1. We have
|
||||
to adjust when loading from memory. */
|
||||
@ -2671,7 +2678,104 @@ mips_ip (str, ip)
|
||||
continue;
|
||||
|
||||
case 'F':
|
||||
as_bad ("Floating point constants only implemented for pseudo ops.");
|
||||
case 'L':
|
||||
case 'f':
|
||||
case 'l':
|
||||
{
|
||||
int f64;
|
||||
char *save_in;
|
||||
char *err;
|
||||
unsigned char temp[8];
|
||||
int length;
|
||||
segT seg;
|
||||
subsegT subseg;
|
||||
char *p;
|
||||
|
||||
/* These only appear as the last operand in an
|
||||
instruction, and every instruction that accepts
|
||||
them in any variant accepts them in all variants.
|
||||
This means we don't have to worry about backing out
|
||||
any changes if the instruction does not match.
|
||||
|
||||
The difference between them is the size of the
|
||||
floating point constant and where it goes. For 'F'
|
||||
and 'L' the constant is 64 bits; for 'f' and 'l' it
|
||||
is 32 bits. Where the constant is placed is based
|
||||
on how the MIPS assembler does things:
|
||||
F -- .rdata
|
||||
L -- .lit8
|
||||
f -- immediate value
|
||||
l -- .lit4
|
||||
*/
|
||||
|
||||
f64 = *args == 'F' || *args == 'L';
|
||||
|
||||
save_in = input_line_pointer;
|
||||
input_line_pointer = s;
|
||||
err = md_atof (f64 ? 'd' : 'f', (char *) temp, &length);
|
||||
s = input_line_pointer;
|
||||
input_line_pointer = save_in;
|
||||
if (err != NULL && *err != '\0')
|
||||
{
|
||||
as_bad ("Bad floating point constant: %s", err);
|
||||
memset (temp, '\0', sizeof temp);
|
||||
length = f64 ? 8 : 4;
|
||||
}
|
||||
|
||||
assert (length == (f64 ? 8 : 4));
|
||||
|
||||
if (*args == 'f')
|
||||
{
|
||||
imm_expr.X_op = O_constant;
|
||||
if (byte_order == LITTLE_ENDIAN)
|
||||
imm_expr.X_add_number =
|
||||
(((((((int) temp[3] << 8)
|
||||
| temp[2]) << 8)
|
||||
| temp[1]) << 8)
|
||||
| temp[0]);
|
||||
else
|
||||
imm_expr.X_add_number =
|
||||
(((((((int) temp[0] << 8)
|
||||
| temp[1]) << 8)
|
||||
| temp[2]) << 8)
|
||||
| temp[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Switch to the right section. */
|
||||
seg = now_seg;
|
||||
subseg = now_subseg;
|
||||
switch (*args)
|
||||
{
|
||||
case 'F':
|
||||
subseg_new (".rdata", (subsegT) 0);
|
||||
break;
|
||||
case 'L':
|
||||
subseg_new (".lit8", (subsegT) 0);
|
||||
break;
|
||||
case 'l':
|
||||
subseg_new (".lit4", (subsegT) 0);
|
||||
break;
|
||||
}
|
||||
if (seg == now_seg)
|
||||
as_bad ("Can't use floating point insn in this section");
|
||||
|
||||
/* Set the argument to the current address in the
|
||||
.rdata section. */
|
||||
offset_expr.X_op = O_symbol;
|
||||
offset_expr.X_add_symbol =
|
||||
symbol_new ("L0\001", now_seg,
|
||||
(valueT) frag_now_fix (), frag_now);
|
||||
offset_expr.X_add_number = 0;
|
||||
|
||||
/* Put the floating point number into the section. */
|
||||
p = frag_more (length);
|
||||
memcpy (p, temp, length);
|
||||
|
||||
/* Switch back to the original section. */
|
||||
subseg_set (seg, subseg);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case 'i': /* 16 bit unsigned immediate */
|
||||
|
Loading…
x
Reference in New Issue
Block a user