Line 368... |
Line 368... |
|
|
#define ISA_SUPPORTS_MT_ASE (mips_opts.isa == ISA_MIPS32R2 \
|
#define ISA_SUPPORTS_MT_ASE (mips_opts.isa == ISA_MIPS32R2 \
|
|| mips_opts.isa == ISA_MIPS64R2)
|
|| mips_opts.isa == ISA_MIPS64R2)
|
|
|
#define ISA_SUPPORTS_MCU_ASE (mips_opts.isa == ISA_MIPS32R2 \
|
#define ISA_SUPPORTS_MCU_ASE (mips_opts.isa == ISA_MIPS32R2 \
|
|| mips_opts.isa == ISA_MIPS64R2)
|
|| mips_opts.isa == ISA_MIPS64R2 \
|
|
|| mips_opts.micromips)
|
|
|
/* The argument of the -march= flag. The architecture we are assembling. */
|
/* The argument of the -march= flag. The architecture we are assembling. */
|
static int file_mips_arch = CPU_UNKNOWN;
|
static int file_mips_arch = CPU_UNKNOWN;
|
static const char *mips_arch_string;
|
static const char *mips_arch_string;
|
|
|
Line 494... |
Line 495... |
#define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500)
|
#define CPU_HAS_DROR(CPU) ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500)
|
|
|
/* True if CPU has a ror instruction. */
|
/* True if CPU has a ror instruction. */
|
#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU)
|
#define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU)
|
|
|
|
/* True if CPU is in the Octeon family */
|
|
#define CPU_IS_OCTEON(CPU) ((CPU) == CPU_OCTEON || (CPU) == CPU_OCTEONP || (CPU) == CPU_OCTEON2)
|
|
|
/* True if CPU has seq/sne and seqi/snei instructions. */
|
/* True if CPU has seq/sne and seqi/snei instructions. */
|
#define CPU_HAS_SEQ(CPU) ((CPU) == CPU_OCTEON)
|
#define CPU_HAS_SEQ(CPU) (CPU_IS_OCTEON (CPU))
|
|
|
/* True if CPU does not implement the all the coprocessor insns. For these
|
/* True if CPU does not implement the all the coprocessor insns. For these
|
CPUs only those COP insns are accepted that are explicitly marked to be
|
CPUs only those COP insns are accepted that are explicitly marked to be
|
available on the CPU. ISA membership for COP insns is ignored. */
|
available on the CPU. ISA membership for COP insns is ignored. */
|
#define NO_ISA_COP(CPU) ((CPU) == CPU_OCTEON)
|
#define NO_ISA_COP(CPU) (CPU_IS_OCTEON (CPU))
|
|
|
/* True if mflo and mfhi can be immediately followed by instructions
|
/* True if mflo and mfhi can be immediately followed by instructions
|
which write to the HI and LO registers.
|
which write to the HI and LO registers.
|
|
|
According to MIPS specifications, MIPS ISAs I, II, and III need
|
According to MIPS specifications, MIPS ISAs I, II, and III need
|
Line 1350... |
Line 1354... |
static void s_cplocal (int);
|
static void s_cplocal (int);
|
static void s_cprestore (int);
|
static void s_cprestore (int);
|
static void s_cpreturn (int);
|
static void s_cpreturn (int);
|
static void s_dtprelword (int);
|
static void s_dtprelword (int);
|
static void s_dtpreldword (int);
|
static void s_dtpreldword (int);
|
|
static void s_tprelword (int);
|
|
static void s_tpreldword (int);
|
static void s_gpvalue (int);
|
static void s_gpvalue (int);
|
static void s_gpword (int);
|
static void s_gpword (int);
|
static void s_gpdword (int);
|
static void s_gpdword (int);
|
static void s_cpadd (int);
|
static void s_cpadd (int);
|
static void s_insn (int);
|
static void s_insn (int);
|
Line 1429... |
Line 1435... |
{"cplocal", s_cplocal, 0},
|
{"cplocal", s_cplocal, 0},
|
{"cprestore", s_cprestore, 0},
|
{"cprestore", s_cprestore, 0},
|
{"cpreturn", s_cpreturn, 0},
|
{"cpreturn", s_cpreturn, 0},
|
{"dtprelword", s_dtprelword, 0},
|
{"dtprelword", s_dtprelword, 0},
|
{"dtpreldword", s_dtpreldword, 0},
|
{"dtpreldword", s_dtpreldword, 0},
|
|
{"tprelword", s_tprelword, 0},
|
|
{"tpreldword", s_tpreldword, 0},
|
{"gpvalue", s_gpvalue, 0},
|
{"gpvalue", s_gpvalue, 0},
|
{"gpword", s_gpword, 0},
|
{"gpword", s_gpword, 0},
|
{"gpdword", s_gpdword, 0},
|
{"gpdword", s_gpdword, 0},
|
{"cpadd", s_cpadd, 0},
|
{"cpadd", s_cpadd, 0},
|
{"insn", s_insn, 0},
|
{"insn", s_insn, 0},
|
Line 2751... |
Line 2759... |
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Move all labels in insn_labels to the current insertion point. */
|
/* Move all labels in LABELS to the current insertion point. TEXT_P
|
|
says whether the labels refer to text or data. */
|
|
|
static void
|
static void
|
mips_move_labels (void)
|
mips_move_labels (struct insn_label_list *labels, bfd_boolean text_p)
|
{
|
{
|
segment_info_type *si = seg_info (now_seg);
|
|
struct insn_label_list *l;
|
struct insn_label_list *l;
|
valueT val;
|
valueT val;
|
|
|
for (l = si->label_list; l != NULL; l = l->next)
|
for (l = labels; l != NULL; l = l->next)
|
{
|
{
|
gas_assert (S_GET_SEGMENT (l->label) == now_seg);
|
gas_assert (S_GET_SEGMENT (l->label) == now_seg);
|
symbol_set_frag (l->label, frag_now);
|
symbol_set_frag (l->label, frag_now);
|
val = (valueT) frag_now_fix ();
|
val = (valueT) frag_now_fix ();
|
/* MIPS16/microMIPS text labels are stored as odd. */
|
/* MIPS16/microMIPS text labels are stored as odd. */
|
if (HAVE_CODE_COMPRESSION)
|
if (text_p && HAVE_CODE_COMPRESSION)
|
++val;
|
++val;
|
S_SET_VALUE (l->label, val);
|
S_SET_VALUE (l->label, val);
|
}
|
}
|
}
|
}
|
|
|
|
/* Move all labels in insn_labels to the current insertion point
|
|
and treat them as text labels. */
|
|
|
|
static void
|
|
mips_move_text_labels (void)
|
|
{
|
|
mips_move_labels (seg_info (now_seg)->label_list, TRUE);
|
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
s_is_linkonce (symbolS *sym, segT from_seg)
|
s_is_linkonce (symbolS *sym, segT from_seg)
|
{
|
{
|
bfd_boolean linkonce = FALSE;
|
bfd_boolean linkonce = FALSE;
|
segT symseg = S_GET_SEGMENT (sym);
|
segT symseg = S_GET_SEGMENT (sym);
|
Line 4139... |
Line 4156... |
middle of a variant frag, because the variants insert
|
middle of a variant frag, because the variants insert
|
all needed nop instructions themselves. */
|
all needed nop instructions themselves. */
|
frag_grow (40);
|
frag_grow (40);
|
}
|
}
|
|
|
mips_move_labels ();
|
mips_move_text_labels ();
|
|
|
#ifndef NO_ECOFF_DEBUGGING
|
#ifndef NO_ECOFF_DEBUGGING
|
if (ECOFF_DEBUGGING)
|
if (ECOFF_DEBUGGING)
|
ecoff_fix_loc (old_frag, old_frag_offset);
|
ecoff_fix_loc (old_frag, old_frag_offset);
|
#endif
|
#endif
|
Line 4531... |
Line 4548... |
int nops = nops_for_insn (0, history, NULL);
|
int nops = nops_for_insn (0, history, NULL);
|
if (nops > 0)
|
if (nops > 0)
|
{
|
{
|
while (nops-- > 0)
|
while (nops-- > 0)
|
add_fixed_insn (NOP_INSN);
|
add_fixed_insn (NOP_INSN);
|
mips_move_labels ();
|
mips_move_text_labels ();
|
}
|
}
|
}
|
}
|
mips_no_prev_insn ();
|
mips_no_prev_insn ();
|
}
|
}
|
|
|
Line 4575... |
Line 4592... |
|
|
/* Move on to a new frag, so that it is safe to simply
|
/* Move on to a new frag, so that it is safe to simply
|
decrease the size of prev_nop_frag. */
|
decrease the size of prev_nop_frag. */
|
frag_wane (frag_now);
|
frag_wane (frag_now);
|
frag_new (0);
|
frag_new (0);
|
mips_move_labels ();
|
mips_move_text_labels ();
|
}
|
}
|
mips_mark_labels ();
|
mips_mark_labels ();
|
mips_clear_insn_labels ();
|
mips_clear_insn_labels ();
|
}
|
}
|
mips_opts.noreorder++;
|
mips_opts.noreorder++;
|
Line 5258... |
Line 5275... |
if (MIPS_JALR_HINT_P (ep))
|
if (MIPS_JALR_HINT_P (ep))
|
{
|
{
|
frag_grow (8);
|
frag_grow (8);
|
f = frag_more (0);
|
f = frag_more (0);
|
}
|
}
|
if (!mips_opts.micromips)
|
if (mips_opts.micromips)
|
macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
|
|
else
|
|
{
|
{
|
jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
|
jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
|
if (MIPS_JALR_HINT_P (ep))
|
if (MIPS_JALR_HINT_P (ep))
|
macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
|
macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
|
else
|
else
|
macro_build (NULL, jalr, "mj", PIC_CALL_REG);
|
macro_build (NULL, jalr, "mj", PIC_CALL_REG);
|
}
|
}
|
|
else
|
|
macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
|
if (MIPS_JALR_HINT_P (ep))
|
if (MIPS_JALR_HINT_P (ep))
|
fix_new_exp (frag_now, f - frag_now->fr_literal, 4, ep, FALSE, jalr_reloc);
|
fix_new_exp (frag_now, f - frag_now->fr_literal, 4, ep, FALSE, jalr_reloc);
|
}
|
}
|
|
|
/*
|
/*
|
Line 6258... |
Line 6275... |
int dbl = 0;
|
int dbl = 0;
|
int imm = 0;
|
int imm = 0;
|
int ust = 0;
|
int ust = 0;
|
int lp = 0;
|
int lp = 0;
|
int ab = 0;
|
int ab = 0;
|
|
int off0 = 0;
|
int off;
|
int off;
|
offsetT maxnum;
|
offsetT maxnum;
|
bfd_reloc_code_real_type r;
|
bfd_reloc_code_real_type r;
|
int hold_mips_optimize;
|
int hold_mips_optimize;
|
|
|
Line 8292... |
Line 8310... |
if (breg != 0)
|
if (breg != 0)
|
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
|
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
|
tempreg, tempreg, breg);
|
tempreg, tempreg, breg);
|
breg = tempreg;
|
breg = tempreg;
|
}
|
}
|
if (!off12)
|
if (off0)
|
|
{
|
|
if (offset_expr.X_add_number == 0)
|
|
tempreg = breg;
|
|
else
|
|
macro_build (&offset_expr, ADDRESS_ADDI_INSN,
|
|
"t,r,j", tempreg, breg, BFD_RELOC_LO16);
|
|
macro_build (NULL, s, fmt, treg, tempreg);
|
|
}
|
|
else if (!off12)
|
macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_LO16, breg);
|
macro_build (&offset_expr, s, fmt, treg, BFD_RELOC_LO16, breg);
|
else
|
else
|
macro_build (NULL, s, fmt,
|
macro_build (NULL, s, fmt,
|
treg, (unsigned long) offset_expr.X_add_number, breg);
|
treg, (unsigned long) offset_expr.X_add_number, breg);
|
}
|
}
|
else if (off12)
|
else if (off12 || off0)
|
{
|
{
|
/* A 12-bit offset field is too narrow to be used for a low-part
|
/* A 12-bit or 0-bit offset field is too narrow to be used
|
relocation, so load the whole address into the auxillary
|
for a low-part relocation, so load the whole address into
|
register. In the case of "A(b)" addresses, we first load
|
the auxillary register. In the case of "A(b)" addresses,
|
absolute address "A" into the register and then add base
|
we first load absolute address "A" into the register and
|
register "b". In the case of "o(b)" addresses, we simply
|
then add base register "b". In the case of "o(b)" addresses,
|
need to add 16-bit offset "o" to base register "b", and
|
we simply need to add 16-bit offset "o" to base register "b", and
|
offset_reloc already contains the relocations associated
|
offset_reloc already contains the relocations associated
|
with "o". */
|
with "o". */
|
if (ab)
|
if (ab)
|
{
|
{
|
load_address (tempreg, &offset_expr, &used_at);
|
load_address (tempreg, &offset_expr, &used_at);
|
Line 8320... |
Line 8347... |
else
|
else
|
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
|
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
|
tempreg, breg, -1,
|
tempreg, breg, -1,
|
offset_reloc[0], offset_reloc[1], offset_reloc[2]);
|
offset_reloc[0], offset_reloc[1], offset_reloc[2]);
|
expr1.X_add_number = 0;
|
expr1.X_add_number = 0;
|
|
if (off0)
|
|
macro_build (NULL, s, fmt, treg, tempreg);
|
|
else
|
macro_build (NULL, s, fmt,
|
macro_build (NULL, s, fmt,
|
treg, (unsigned long) expr1.X_add_number, tempreg);
|
treg, (unsigned long) expr1.X_add_number, tempreg);
|
}
|
}
|
else if (mips_pic == NO_PIC)
|
else if (mips_pic == NO_PIC)
|
{
|
{
|
Line 9115... |
Line 9145... |
-1, offset_reloc[0], offset_reloc[1], offset_reloc[2],
|
-1, offset_reloc[0], offset_reloc[1], offset_reloc[2],
|
breg);
|
breg);
|
}
|
}
|
break;
|
break;
|
|
|
|
|
|
case M_SAA_AB:
|
|
ab = 1;
|
|
case M_SAA_OB:
|
|
s = "saa";
|
|
off0 = 1;
|
|
fmt = "t,(b)";
|
|
goto ld_st;
|
|
case M_SAAD_AB:
|
|
ab = 1;
|
|
case M_SAAD_OB:
|
|
s = "saad";
|
|
off0 = 1;
|
|
fmt = "t,(b)";
|
|
goto ld_st;
|
|
|
/* New code added to support COPZ instructions.
|
/* New code added to support COPZ instructions.
|
This code builds table entries out of the macros in mip_opcodes.
|
This code builds table entries out of the macros in mip_opcodes.
|
R4000 uses interlocks to handle coproc delays.
|
R4000 uses interlocks to handle coproc delays.
|
Other chips (like the R3000) require nops to be inserted for delays.
|
Other chips (like the R3000) require nops to be inserted for delays.
|
|
|
Line 9148... |
Line 9194... |
copz:
|
copz:
|
gas_assert (!mips_opts.micromips);
|
gas_assert (!mips_opts.micromips);
|
if (NO_ISA_COP (mips_opts.arch)
|
if (NO_ISA_COP (mips_opts.arch)
|
&& (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0)
|
&& (ip->insn_mo->pinfo2 & INSN2_M_FP_S) == 0)
|
{
|
{
|
as_bad (_("opcode not supported on this processor: %s"),
|
as_bad (_("Opcode not supported on this processor: %s"),
|
mips_cpu_info_from_arch (mips_opts.arch)->name);
|
mips_cpu_info_from_arch (mips_opts.arch)->name);
|
break;
|
break;
|
}
|
}
|
|
|
/* For now we just do C (same as Cz). The parameter will be
|
/* For now we just do C (same as Cz). The parameter will be
|
Line 10697... |
Line 10743... |
|
|
if (insn_error)
|
if (insn_error)
|
return;
|
return;
|
|
|
if (!ok)
|
if (!ok)
|
sprintf (buf, _("opcode not supported on this processor: %s (%s)"),
|
sprintf (buf, _("Opcode not supported on this processor: %s (%s)"),
|
mips_cpu_info_from_arch (mips_opts.arch)->name,
|
mips_cpu_info_from_arch (mips_opts.arch)->name,
|
mips_cpu_info_from_isa (mips_opts.isa)->name);
|
mips_cpu_info_from_isa (mips_opts.isa)->name);
|
else
|
else
|
sprintf (buf, _("Unrecognized %u-bit version of microMIPS opcode"),
|
sprintf (buf, _("Unrecognized %u-bit version of microMIPS opcode"),
|
8 * forced_insn_length);
|
8 * forced_insn_length);
|
Line 10962... |
Line 11008... |
as_bad (_("Invalid dsp/smartmips acc register"));
|
as_bad (_("Invalid dsp/smartmips acc register"));
|
break;
|
break;
|
|
|
case '\\': /* 3-bit bit position. */
|
case '\\': /* 3-bit bit position. */
|
{
|
{
|
unsigned long mask = (!mips_opts.micromips
|
unsigned long mask = (mips_opts.micromips
|
? OP_MASK_3BITPOS
|
? MICROMIPSOP_MASK_3BITPOS
|
: MICROMIPSOP_MASK_3BITPOS);
|
: OP_MASK_3BITPOS);
|
|
|
my_getExpression (&imm_expr, s);
|
my_getExpression (&imm_expr, s);
|
check_absolute_expr (ip, &imm_expr);
|
check_absolute_expr (ip, &imm_expr);
|
if ((unsigned long) imm_expr.X_add_number > mask)
|
if ((unsigned long) imm_expr.X_add_number > mask)
|
as_warn (_("Bit position for %s not in range 0..%lu (%lu)"),
|
as_warn (_("Bit position for %s not in range 0..%lu (%lu)"),
|
Line 13226... |
Line 13272... |
{
|
{
|
if (!insn_error)
|
if (!insn_error)
|
{
|
{
|
static char buf[100];
|
static char buf[100];
|
sprintf (buf,
|
sprintf (buf,
|
_("opcode not supported on this processor: %s (%s)"),
|
_("Opcode not supported on this processor: %s (%s)"),
|
mips_cpu_info_from_arch (mips_opts.arch)->name,
|
mips_cpu_info_from_arch (mips_opts.arch)->name,
|
mips_cpu_info_from_isa (mips_opts.isa)->name);
|
mips_cpu_info_from_isa (mips_opts.isa)->name);
|
insn_error = buf;
|
insn_error = buf;
|
}
|
}
|
return;
|
return;
|
Line 14038... |
Line 14084... |
{
|
{
|
{"%lo", BFD_RELOC_MIPS16_LO16},
|
{"%lo", BFD_RELOC_MIPS16_LO16},
|
{"%gprel", BFD_RELOC_MIPS16_GPREL},
|
{"%gprel", BFD_RELOC_MIPS16_GPREL},
|
{"%got", BFD_RELOC_MIPS16_GOT16},
|
{"%got", BFD_RELOC_MIPS16_GOT16},
|
{"%call16", BFD_RELOC_MIPS16_CALL16},
|
{"%call16", BFD_RELOC_MIPS16_CALL16},
|
{"%hi", BFD_RELOC_MIPS16_HI16_S}
|
{"%hi", BFD_RELOC_MIPS16_HI16_S},
|
|
{"%tlsgd", BFD_RELOC_MIPS16_TLS_GD},
|
|
{"%tlsldm", BFD_RELOC_MIPS16_TLS_LDM},
|
|
{"%dtprel_hi", BFD_RELOC_MIPS16_TLS_DTPREL_HI16},
|
|
{"%dtprel_lo", BFD_RELOC_MIPS16_TLS_DTPREL_LO16},
|
|
{"%tprel_hi", BFD_RELOC_MIPS16_TLS_TPREL_HI16},
|
|
{"%tprel_lo", BFD_RELOC_MIPS16_TLS_TPREL_LO16},
|
|
{"%gottprel", BFD_RELOC_MIPS16_TLS_GOTTPREL}
|
};
|
};
|
|
|
|
|
/* Return true if *STR points to a relocation operator. When returning true,
|
/* Return true if *STR points to a relocation operator. When returning true,
|
move *STR over the operator and store its relocation code in *RELOC.
|
move *STR over the operator and store its relocation code in *RELOC.
|
Line 15367... |
Line 15420... |
case BFD_RELOC_MIPS_TLS_DTPREL32:
|
case BFD_RELOC_MIPS_TLS_DTPREL32:
|
case BFD_RELOC_MIPS_TLS_DTPREL64:
|
case BFD_RELOC_MIPS_TLS_DTPREL64:
|
case BFD_RELOC_MIPS_TLS_DTPREL_HI16:
|
case BFD_RELOC_MIPS_TLS_DTPREL_HI16:
|
case BFD_RELOC_MIPS_TLS_DTPREL_LO16:
|
case BFD_RELOC_MIPS_TLS_DTPREL_LO16:
|
case BFD_RELOC_MIPS_TLS_GOTTPREL:
|
case BFD_RELOC_MIPS_TLS_GOTTPREL:
|
|
case BFD_RELOC_MIPS_TLS_TPREL32:
|
|
case BFD_RELOC_MIPS_TLS_TPREL64:
|
case BFD_RELOC_MIPS_TLS_TPREL_HI16:
|
case BFD_RELOC_MIPS_TLS_TPREL_HI16:
|
case BFD_RELOC_MIPS_TLS_TPREL_LO16:
|
case BFD_RELOC_MIPS_TLS_TPREL_LO16:
|
case BFD_RELOC_MICROMIPS_TLS_GD:
|
case BFD_RELOC_MICROMIPS_TLS_GD:
|
case BFD_RELOC_MICROMIPS_TLS_LDM:
|
case BFD_RELOC_MICROMIPS_TLS_LDM:
|
case BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16:
|
case BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16:
|
case BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16:
|
case BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16:
|
case BFD_RELOC_MICROMIPS_TLS_GOTTPREL:
|
case BFD_RELOC_MICROMIPS_TLS_GOTTPREL:
|
case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16:
|
case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16:
|
case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16:
|
case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16:
|
|
case BFD_RELOC_MIPS16_TLS_GD:
|
|
case BFD_RELOC_MIPS16_TLS_LDM:
|
|
case BFD_RELOC_MIPS16_TLS_DTPREL_HI16:
|
|
case BFD_RELOC_MIPS16_TLS_DTPREL_LO16:
|
|
case BFD_RELOC_MIPS16_TLS_GOTTPREL:
|
|
case BFD_RELOC_MIPS16_TLS_TPREL_HI16:
|
|
case BFD_RELOC_MIPS16_TLS_TPREL_LO16:
|
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
S_SET_THREAD_LOCAL (fixP->fx_addsy);
|
/* fall through */
|
/* fall through */
|
|
|
case BFD_RELOC_MIPS_JMP:
|
case BFD_RELOC_MIPS_JMP:
|
case BFD_RELOC_MIPS_SHIFT5:
|
case BFD_RELOC_MIPS_SHIFT5:
|
Line 15594... |
Line 15656... |
|
|
/* Align the current frag to a given power of two. If a particular
|
/* Align the current frag to a given power of two. If a particular
|
fill byte should be used, FILL points to an integer that contains
|
fill byte should be used, FILL points to an integer that contains
|
that byte, otherwise FILL is null.
|
that byte, otherwise FILL is null.
|
|
|
The MIPS assembler also automatically adjusts any preceding
|
This function used to have the comment:
|
label. */
|
|
|
The MIPS assembler also automatically adjusts any preceding label.
|
|
|
|
The implementation therefore applied the adjustment to a maximum of
|
|
one label. However, other label adjustments are applied to batches
|
|
of labels, and adjusting just one caused problems when new labels
|
|
were added for the sake of debugging or unwind information.
|
|
We therefore adjust all preceding labels (given as LABELS) instead. */
|
|
|
static void
|
static void
|
mips_align (int to, int *fill, symbolS *label)
|
mips_align (int to, int *fill, struct insn_label_list *labels)
|
{
|
{
|
mips_emit_delays ();
|
mips_emit_delays ();
|
mips_record_compressed_mode ();
|
mips_record_compressed_mode ();
|
if (fill == NULL && subseg_text_p (now_seg))
|
if (fill == NULL && subseg_text_p (now_seg))
|
frag_align_code (to, 0);
|
frag_align_code (to, 0);
|
else
|
else
|
frag_align (to, fill ? *fill : 0, 0);
|
frag_align (to, fill ? *fill : 0, 0);
|
record_alignment (now_seg, to);
|
record_alignment (now_seg, to);
|
if (label != NULL)
|
mips_move_labels (labels, FALSE);
|
{
|
|
gas_assert (S_GET_SEGMENT (label) == now_seg);
|
|
symbol_set_frag (label, frag_now);
|
|
S_SET_VALUE (label, (valueT) frag_now_fix ());
|
|
}
|
|
}
|
}
|
|
|
/* Align to a given power of two. .align 0 turns off the automatic
|
/* Align to a given power of two. .align 0 turns off the automatic
|
alignment used by the data creating pseudo-ops. */
|
alignment used by the data creating pseudo-ops. */
|
|
|
Line 15654... |
Line 15718... |
{
|
{
|
segment_info_type *si = seg_info (now_seg);
|
segment_info_type *si = seg_info (now_seg);
|
struct insn_label_list *l = si->label_list;
|
struct insn_label_list *l = si->label_list;
|
/* Auto alignment should be switched on by next section change. */
|
/* Auto alignment should be switched on by next section change. */
|
auto_align = 1;
|
auto_align = 1;
|
mips_align (temp, fill_ptr, l != NULL ? l->label : NULL);
|
mips_align (temp, fill_ptr, l);
|
}
|
}
|
else
|
else
|
{
|
{
|
auto_align = 0;
|
auto_align = 0;
|
}
|
}
|
Line 15824... |
Line 15888... |
static void
|
static void
|
s_cons (int log_size)
|
s_cons (int log_size)
|
{
|
{
|
segment_info_type *si = seg_info (now_seg);
|
segment_info_type *si = seg_info (now_seg);
|
struct insn_label_list *l = si->label_list;
|
struct insn_label_list *l = si->label_list;
|
symbolS *label;
|
|
|
|
label = l != NULL ? l->label : NULL;
|
|
mips_emit_delays ();
|
mips_emit_delays ();
|
if (log_size > 0 && auto_align)
|
if (log_size > 0 && auto_align)
|
mips_align (log_size, 0, label);
|
mips_align (log_size, 0, l);
|
cons (1 << log_size);
|
cons (1 << log_size);
|
mips_clear_insn_labels ();
|
mips_clear_insn_labels ();
|
}
|
}
|
|
|
static void
|
static void
|
s_float_cons (int type)
|
s_float_cons (int type)
|
{
|
{
|
segment_info_type *si = seg_info (now_seg);
|
segment_info_type *si = seg_info (now_seg);
|
struct insn_label_list *l = si->label_list;
|
struct insn_label_list *l = si->label_list;
|
symbolS *label;
|
|
|
|
label = l != NULL ? l->label : NULL;
|
|
|
|
mips_emit_delays ();
|
mips_emit_delays ();
|
|
|
if (auto_align)
|
if (auto_align)
|
{
|
{
|
if (type == 'd')
|
if (type == 'd')
|
mips_align (3, 0, label);
|
mips_align (3, 0, l);
|
else
|
else
|
mips_align (2, 0, label);
|
mips_align (2, 0, l);
|
}
|
}
|
|
|
float_cons (type);
|
float_cons (type);
|
mips_clear_insn_labels ();
|
mips_clear_insn_labels ();
|
}
|
}
|
Line 16545... |
Line 16604... |
macro_end ();
|
macro_end ();
|
|
|
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
}
|
}
|
|
|
/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
|
/* Handle a .dtprelword, .dtpreldword, .tprelword, or .tpreldword
|
a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
|
pseudo-op; DIRSTR says which. The pseudo-op generates a BYTES-size
|
use in DWARF debug information. */
|
DTP- or TP-relative relocation of type RTYPE, for use in either DWARF
|
|
debug information or MIPS16 TLS. */
|
|
|
static void
|
static void
|
s_dtprel_internal (size_t bytes)
|
s_tls_rel_directive (const size_t bytes, const char *dirstr,
|
|
bfd_reloc_code_real_type rtype)
|
{
|
{
|
expressionS ex;
|
expressionS ex;
|
char *p;
|
char *p;
|
|
|
expression (&ex);
|
expression (&ex);
|
|
|
if (ex.X_op != O_symbol)
|
if (ex.X_op != O_symbol)
|
{
|
{
|
as_bad (_("Unsupported use of %s"), (bytes == 8
|
as_bad (_("Unsupported use of %s"), dirstr);
|
? ".dtpreldword"
|
|
: ".dtprelword"));
|
|
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
}
|
}
|
|
|
p = frag_more (bytes);
|
p = frag_more (bytes);
|
md_number_to_chars (p, 0, bytes);
|
md_number_to_chars (p, 0, bytes);
|
fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
|
fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype);
|
(bytes == 8
|
|
? BFD_RELOC_MIPS_TLS_DTPREL64
|
|
: BFD_RELOC_MIPS_TLS_DTPREL32));
|
|
|
|
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
|
mips_clear_insn_labels ();
|
}
|
}
|
|
|
/* Handle .dtprelword. */
|
/* Handle .dtprelword. */
|
|
|
static void
|
static void
|
s_dtprelword (int ignore ATTRIBUTE_UNUSED)
|
s_dtprelword (int ignore ATTRIBUTE_UNUSED)
|
{
|
{
|
s_dtprel_internal (4);
|
s_tls_rel_directive (4, ".dtprelword", BFD_RELOC_MIPS_TLS_DTPREL32);
|
}
|
}
|
|
|
/* Handle .dtpreldword. */
|
/* Handle .dtpreldword. */
|
|
|
static void
|
static void
|
s_dtpreldword (int ignore ATTRIBUTE_UNUSED)
|
s_dtpreldword (int ignore ATTRIBUTE_UNUSED)
|
{
|
{
|
s_dtprel_internal (8);
|
s_tls_rel_directive (8, ".dtpreldword", BFD_RELOC_MIPS_TLS_DTPREL64);
|
|
}
|
|
|
|
/* Handle .tprelword. */
|
|
|
|
static void
|
|
s_tprelword (int ignore ATTRIBUTE_UNUSED)
|
|
{
|
|
s_tls_rel_directive (4, ".tprelword", BFD_RELOC_MIPS_TLS_TPREL32);
|
|
}
|
|
|
|
/* Handle .tpreldword. */
|
|
|
|
static void
|
|
s_tpreldword (int ignore ATTRIBUTE_UNUSED)
|
|
{
|
|
s_tls_rel_directive (8, ".tpreldword", BFD_RELOC_MIPS_TLS_TPREL64);
|
}
|
}
|
|
|
/* Handle the .gpvalue pseudo-op. This is used when generating NewABI PIC
|
/* Handle the .gpvalue pseudo-op. This is used when generating NewABI PIC
|
code. It sets the offset to use in gp_rel relocations. */
|
code. It sets the offset to use in gp_rel relocations. */
|
|
|
Line 16618... |
Line 16690... |
static void
|
static void
|
s_gpword (int ignore ATTRIBUTE_UNUSED)
|
s_gpword (int ignore ATTRIBUTE_UNUSED)
|
{
|
{
|
segment_info_type *si;
|
segment_info_type *si;
|
struct insn_label_list *l;
|
struct insn_label_list *l;
|
symbolS *label;
|
|
expressionS ex;
|
expressionS ex;
|
char *p;
|
char *p;
|
|
|
/* When not generating PIC code, this is treated as .word. */
|
/* When not generating PIC code, this is treated as .word. */
|
if (mips_pic != SVR4_PIC)
|
if (mips_pic != SVR4_PIC)
|
Line 16631... |
Line 16702... |
return;
|
return;
|
}
|
}
|
|
|
si = seg_info (now_seg);
|
si = seg_info (now_seg);
|
l = si->label_list;
|
l = si->label_list;
|
label = l != NULL ? l->label : NULL;
|
|
mips_emit_delays ();
|
mips_emit_delays ();
|
if (auto_align)
|
if (auto_align)
|
mips_align (2, 0, label);
|
mips_align (2, 0, l);
|
|
|
expression (&ex);
|
expression (&ex);
|
mips_clear_insn_labels ();
|
mips_clear_insn_labels ();
|
|
|
if (ex.X_op != O_symbol || ex.X_add_number != 0)
|
if (ex.X_op != O_symbol || ex.X_add_number != 0)
|
Line 16658... |
Line 16728... |
static void
|
static void
|
s_gpdword (int ignore ATTRIBUTE_UNUSED)
|
s_gpdword (int ignore ATTRIBUTE_UNUSED)
|
{
|
{
|
segment_info_type *si;
|
segment_info_type *si;
|
struct insn_label_list *l;
|
struct insn_label_list *l;
|
symbolS *label;
|
|
expressionS ex;
|
expressionS ex;
|
char *p;
|
char *p;
|
|
|
/* When not generating PIC code, this is treated as .dword. */
|
/* When not generating PIC code, this is treated as .dword. */
|
if (mips_pic != SVR4_PIC)
|
if (mips_pic != SVR4_PIC)
|
Line 16671... |
Line 16740... |
return;
|
return;
|
}
|
}
|
|
|
si = seg_info (now_seg);
|
si = seg_info (now_seg);
|
l = si->label_list;
|
l = si->label_list;
|
label = l != NULL ? l->label : NULL;
|
|
mips_emit_delays ();
|
mips_emit_delays ();
|
if (auto_align)
|
if (auto_align)
|
mips_align (3, 0, label);
|
mips_align (3, 0, l);
|
|
|
expression (&ex);
|
expression (&ex);
|
mips_clear_insn_labels ();
|
mips_clear_insn_labels ();
|
|
|
if (ex.X_op != O_symbol || ex.X_add_number != 0)
|
if (ex.X_op != O_symbol || ex.X_add_number != 0)
|
Line 18961... |
Line 19029... |
{ "4ksd", MIPS_CPU_ASE_SMARTMIPS, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "4ksd", MIPS_CPU_ASE_SMARTMIPS, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m4k", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m4k", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m4kp", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m4kp", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m14k", MIPS_CPU_ASE_MCU, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m14k", MIPS_CPU_ASE_MCU, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m14kc", MIPS_CPU_ASE_MCU, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "m14kc", MIPS_CPU_ASE_MCU, ISA_MIPS32R2, CPU_MIPS32R2 },
|
|
{ "m14ke", MIPS_CPU_ASE_DSP | MIPS_CPU_ASE_DSPR2 | MIPS_CPU_ASE_MCU,
|
|
ISA_MIPS32R2, CPU_MIPS32R2 },
|
|
{ "m14kec", MIPS_CPU_ASE_DSP | MIPS_CPU_ASE_DSPR2 | MIPS_CPU_ASE_MCU,
|
|
ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kc", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kc", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf2_1", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf2_1", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf1_1", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
{ "24kf1_1", 0, ISA_MIPS32R2, CPU_MIPS32R2 },
|
/* Deprecated forms of the above. */
|
/* Deprecated forms of the above. */
|
Line 19035... |
Line 19107... |
|
|
/* MIPS 64 Release 2 */
|
/* MIPS 64 Release 2 */
|
|
|
/* Cavium Networks Octeon CPU core */
|
/* Cavium Networks Octeon CPU core */
|
{ "octeon", 0, ISA_MIPS64R2, CPU_OCTEON },
|
{ "octeon", 0, ISA_MIPS64R2, CPU_OCTEON },
|
|
{ "octeon+", 0, ISA_MIPS64R2, CPU_OCTEONP },
|
|
{ "octeon2", 0, ISA_MIPS64R2, CPU_OCTEON2 },
|
|
|
/* RMI Xlr */
|
/* RMI Xlr */
|
{ "xlr", 0, ISA_MIPS64, CPU_XLR },
|
{ "xlr", 0, ISA_MIPS64, CPU_XLR },
|
|
|
/* End marker */
|
/* End marker */
|