aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorChris Demetriou <cgd@google.com>2003-09-30 16:17:15 +0000
committerChris Demetriou <cgd@google.com>2003-09-30 16:17:15 +0000
commit5f74bc130d437ca83b9f94507f92838aa516cb01 (patch)
tree91577658127caf0f41264b843bbd0600f9d81ea9 /gas/config
parent2e0926257dd7f472121aa9d48341d94e5b08c403 (diff)
downloadfsf-binutils-gdb-5f74bc130d437ca83b9f94507f92838aa516cb01.zip
fsf-binutils-gdb-5f74bc130d437ca83b9f94507f92838aa516cb01.tar.gz
fsf-binutils-gdb-5f74bc130d437ca83b9f94507f92838aa516cb01.tar.bz2
[ bfd/ChangeLog ]
2003-09-30 Chris Demetriou <cgd@broadcom.com> * archures.c (bfd_mach_mipsisa64r2): New define. * bfd-in2.h: Regenerate. * aoutx.h (NAME(aout,machine_type)): Handle bfd_mach_mipsisa64r2. * cpu-mips.c (I_mipsisa64r2): New enum value. (arch_info_struct): Add entry for I_mipsisa64r2. * elfxx-mips.c (_bfd_elf_mips_mach) (_bfd_mips_elf_print_private_bfd_data): Handle E_MIPS_ARCH_64R2. (mips_set_isa_flags): Add bfd_mach_mipsisa64r2 case. (mips_mach_extensions): Add entry for bfd_mach_mipsisa64r2. [ binutils/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * readelf.c (get_machine_flags): Handle E_MIPS_ARCH_64R2. [ gas/Changelog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * configure.in (mipsisa64r2, mipsisa64r2el, mipsisa64r2*): New CPUs. * configure: Regenerate. * config/tc-mips.c (imm2_expr): New variable. (md_assemble, mips16_ip): Initialize imm2_expr. (ISA_HAS_64BIT_REGS, ISA_HAS_DROR, ISA_HAS_ROR): Add ISA_MIPS64R2. (macro_build): Handle +A, +B, +C, +E, +F, +G, and +H format operands. (macro): Handle M_DEXT and M_DINS. (validate_mips_insn): Handle +E, +F, +G, +H, and +I format operands. (mips_ip): Likewise. (OPTION_MIPS64R2): New define. (md_longopts): New entry for -mips64r2 (OPTION_MIPS64R2). OPTION_ASE_BASE): Increase to compensate for OPTION_MIPS64R2. (md_parse_option): Handle OPTION_MIPS64R2. (s_mipsset): Handle setting "mips64r2" ISA. (mips_cpu_info_table): Add mips64r2. (md_show_usage): Document -mips64r2 option. * doc/as.texinfo: Docuemnt -mips64r2 option. * doc/c-mips.texi: Likewise. [ gas/testsuite/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * gas/mips/cp0-names-mips64r2.d: New file. * gas/mips/cp0sel-names-mips64r2.d: New file. * gas/mips/elf_arch_mips64r2.d: New file. * gas/mips/hwr-names-mips64r2.d: New file. * gas/mips/mips32r2-ill-fp64.l: New file. * gas/mips/mips32r2-ill-fp64.s: New file. * gas/mips/mips64r2-ill.l: New file. * gas/mips/mips64r2-ill.s: New file. * gas/mips/mips64r2.d: New file. * gas/mips/mips64r2.s: New file. * gas/mips/mips.exp: Define "mips64r2" arch, and run new tests. [ include/elf/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * mips.h (E_MIPS_ARCH_64R2): New define. [ include/opcode/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * mips.h: Document +E, +F, +G, +H, and +I operand types. Update documentation of I, +B and +C operand types. (INSN_ISA64R2, ISA_MIPS64R2, CPU_MIPS64R2): New defines. (M_DEXT, M_DINS): New enum values. [ ld/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * ldmain.c (get_emulation): Ignore "-mips64r2". [ ld/testsuite/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * ld-mips-elf/mips-elf-flags.exp: Add tests for combinations with MIPS64r2. [ opcodes/ChangeLog ] 2003-09-30 Chris Demetriou <cgd@broadcom.com> * mips-dis.c (mips_arch_choices): Add entry for "mips64r2" (print_insn_args): Add handing for +E, +F, +G, and +H. * mips-opc.c (I65): New define for MIPS64r2. (mips_builtin_opcodes): Add "dext", "dextm", "dextu", "dins", "dinsm", "dinsu", "drotl", "drotr", "drotr32", "drotrv", "dsbh", and "dshd" for MIPS64r2. Adjust "dror", "dror32", and "drorv" to be supported on MIPS64r2.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-mips.c189
1 files changed, 187 insertions, 2 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index e638883..25e5a3d 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -266,18 +266,20 @@ static int mips_32bitmode = 0;
|| (ISA) == ISA_MIPS4 \
|| (ISA) == ISA_MIPS5 \
|| (ISA) == ISA_MIPS64 \
+ || (ISA) == ISA_MIPS64R2 \
)
/* Return true if ISA supports 64-bit right rotate (dror et al.)
instructions. */
#define ISA_HAS_DROR(ISA) ( \
- 0 \
+ (ISA) == ISA_MIPS64R2 \
)
/* Return true if ISA supports 32-bit right rotate (ror et al.)
instructions. */
#define ISA_HAS_ROR(ISA) ( \
(ISA) == ISA_MIPS32R2 \
+ || (ISA) == ISA_MIPS64R2 \
)
#define HAVE_32BIT_GPRS \
@@ -1025,6 +1027,7 @@ static char *expr_end;
mips_ip. */
static expressionS imm_expr;
+static expressionS imm2_expr;
static expressionS offset_expr;
/* Relocs associated with imm_expr and offset_expr. */
@@ -1323,6 +1326,7 @@ md_assemble (char *str)
= {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
imm_expr.X_op = O_absent;
+ imm2_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
imm_reloc[0] = BFD_RELOC_UNUSED;
imm_reloc[1] = BFD_RELOC_UNUSED;
@@ -2872,6 +2876,41 @@ macro_build (char *place, int *counter, expressionS *ep, const char *name,
case ')':
continue;
+ case '+':
+ switch (*fmt++)
+ {
+ case 'A':
+ case 'E':
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_SHAMT) << OP_SH_SHAMT;
+ continue;
+
+ case 'B':
+ case 'F':
+ /* Note that in the macro case, these arguments are already
+ in MSB form. (When handling the instruction in the
+ non-macro case, these arguments are sizes from which
+ MSB values must be calculated.) */
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_INSMSB) << OP_SH_INSMSB;
+ continue;
+
+ case 'C':
+ case 'G':
+ case 'H':
+ /* Note that in the macro case, these arguments are already
+ in MSBD form. (When handling the instruction in the
+ non-macro case, these arguments are sizes from which
+ MSBD values must be calculated.) */
+ insn.insn_opcode |= (va_arg (args, int)
+ & OP_MASK_EXTMSBD) << OP_SH_EXTMSBD;
+ continue;
+
+ default:
+ internalError ();
+ }
+ continue;
+
case 't':
case 'w':
case 'E':
@@ -4437,6 +4476,104 @@ macro (struct mips_cl_insn *ip)
"s,t,p", AT, 0);
break;
+ case M_DEXT:
+ {
+ unsigned long pos;
+ unsigned long size;
+
+ if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
+ {
+ as_bad (_("Unsupported large constant"));
+ pos = size = 1;
+ }
+ else
+ {
+ pos = (unsigned long) imm_expr.X_add_number;
+ size = (unsigned long) imm2_expr.X_add_number;
+ }
+
+ if (pos > 63)
+ {
+ as_bad (_("Improper position (%lu)"), pos);
+ pos = 1;
+ }
+ if (size == 0 || size > 64
+ || (pos + size - 1) > 63)
+ {
+ as_bad (_("Improper extract size (%lu, position %lu)"),
+ size, pos);
+ size = 1;
+ }
+
+ if (size <= 32 && pos < 32)
+ {
+ s = "dext";
+ fmt = "t,r,+A,+C";
+ }
+ else if (size <= 32)
+ {
+ s = "dextu";
+ fmt = "t,r,+E,+H";
+ }
+ else
+ {
+ s = "dextm";
+ fmt = "t,r,+A,+G";
+ }
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s,
+ fmt, treg, sreg, pos, size - 1);
+ }
+ return;
+
+ case M_DINS:
+ {
+ unsigned long pos;
+ unsigned long size;
+
+ if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
+ {
+ as_bad (_("Unsupported large constant"));
+ pos = size = 1;
+ }
+ else
+ {
+ pos = (unsigned long) imm_expr.X_add_number;
+ size = (unsigned long) imm2_expr.X_add_number;
+ }
+
+ if (pos > 63)
+ {
+ as_bad (_("Improper position (%lu)"), pos);
+ pos = 1;
+ }
+ if (size == 0 || size > 64
+ || (pos + size - 1) > 63)
+ {
+ as_bad (_("Improper insert size (%lu, position %lu)"),
+ size, pos);
+ size = 1;
+ }
+
+ if (pos < 32 && (pos + size - 1) < 32)
+ {
+ s = "dins";
+ fmt = "t,r,+A,+B";
+ }
+ else if (pos >= 32)
+ {
+ s = "dinsu";
+ fmt = "t,r,+E,+F";
+ }
+ else
+ {
+ s = "dinsm";
+ fmt = "t,r,+A,+F";
+ }
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s,
+ fmt, treg, sreg, pos, pos + size - 1);
+ }
+ return;
+
case M_DDIV_3:
dbl = 1;
case M_DIV_3:
@@ -8060,6 +8197,11 @@ validate_mips_insn (const struct mips_opcode *opc)
case 'C': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
case 'D': USE_BITS (OP_MASK_RD, OP_SH_RD);
USE_BITS (OP_MASK_SEL, OP_SH_SEL); break;
+ case 'E': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
+ case 'F': USE_BITS (OP_MASK_INSMSB, OP_SH_INSMSB); break;
+ case 'G': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
+ case 'H': USE_BITS (OP_MASK_EXTMSBD, OP_SH_EXTMSBD); break;
+ case 'I': break;
default:
as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
c, opc->name, opc->args);
@@ -8319,6 +8461,12 @@ mips_ip (char *str, struct mips_cl_insn *ip)
case 'A': /* ins/ext position, becomes LSB. */
limlo = 0;
limhi = 31;
+ goto do_lsb;
+ case 'E':
+ limlo = 32;
+ limhi = 63;
+ goto do_lsb;
+do_lsb:
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
if ((unsigned long) imm_expr.X_add_number < limlo
@@ -8338,6 +8486,12 @@ mips_ip (char *str, struct mips_cl_insn *ip)
case 'B': /* ins size, becomes MSB. */
limlo = 1;
limhi = 32;
+ goto do_msb;
+ case 'F':
+ limlo = 33;
+ limhi = 64;
+ goto do_msb;
+do_msb:
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
/* Check for negative input so that small negative numbers
@@ -8364,6 +8518,16 @@ mips_ip (char *str, struct mips_cl_insn *ip)
case 'C': /* ext size, becomes MSBD. */
limlo = 1;
limhi = 32;
+ goto do_msbd;
+ case 'G':
+ limlo = 33;
+ limhi = 64;
+ goto do_msbd;
+ case 'H':
+ limlo = 33;
+ limhi = 64;
+ goto do_msbd;
+do_msbd:
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
/* Check for negative input so that small negative numbers
@@ -8391,6 +8555,15 @@ mips_ip (char *str, struct mips_cl_insn *ip)
/* +D is for disassembly only; never match. */
break;
+ case 'I':
+ /* "+I" is like "I", except that imm2_expr is used. */
+ my_getExpression (&imm2_expr, s);
+ if (imm2_expr.X_op != O_big
+ && imm2_expr.X_op != O_constant)
+ insn_error = _("absolute expression required");
+ s = expr_end;
+ continue;
+
default:
as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
*args, insn->name, insn->args);
@@ -9358,6 +9531,7 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
imm_reloc[0] = BFD_RELOC_UNUSED;
imm_reloc[1] = BFD_RELOC_UNUSED;
imm_reloc[2] = BFD_RELOC_UNUSED;
+ imm2_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
offset_reloc[0] = BFD_RELOC_UNUSED;
offset_reloc[1] = BFD_RELOC_UNUSED;
@@ -10256,9 +10430,11 @@ struct option md_longopts[] =
{"mips64", no_argument, NULL, OPTION_MIPS64},
#define OPTION_MIPS32R2 (OPTION_ARCH_BASE + 9)
{"mips32r2", no_argument, NULL, OPTION_MIPS32R2},
+#define OPTION_MIPS64R2 (OPTION_ARCH_BASE + 10)
+ {"mips64r2", no_argument, NULL, OPTION_MIPS64R2},
/* Options which specify Application Specific Extensions (ASEs). */
-#define OPTION_ASE_BASE (OPTION_ARCH_BASE + 10)
+#define OPTION_ASE_BASE (OPTION_ARCH_BASE + 11)
#define OPTION_MIPS16 (OPTION_ASE_BASE + 0)
{"mips16", no_argument, NULL, OPTION_MIPS16},
#define OPTION_NO_MIPS16 (OPTION_ASE_BASE + 1)
@@ -10463,6 +10639,10 @@ md_parse_option (int c, char *arg)
file_mips_isa = ISA_MIPS32R2;
break;
+ case OPTION_MIPS64R2:
+ file_mips_isa = ISA_MIPS64R2;
+ break;
+
case OPTION_MIPS64:
file_mips_isa = ISA_MIPS64;
break;
@@ -12020,6 +12200,8 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
mips_opts.isa = ISA_MIPS32R2;
else if (strcmp (name, "mips64") == 0)
mips_opts.isa = ISA_MIPS64;
+ else if (strcmp (name, "mips64r2") == 0)
+ mips_opts.isa = ISA_MIPS64R2;
else if (strcmp (name, "arch=default") == 0)
{
reset = 1;
@@ -12057,6 +12239,7 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
case ISA_MIPS4:
case ISA_MIPS5:
case ISA_MIPS64:
+ case ISA_MIPS64R2:
mips_opts.gp32 = 0;
mips_opts.fp32 = 0;
break;
@@ -14302,6 +14485,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
{ "mips32", 1, ISA_MIPS32, CPU_MIPS32 },
{ "mips32r2", 1, ISA_MIPS32R2, CPU_MIPS32R2 },
{ "mips64", 1, ISA_MIPS64, CPU_MIPS64 },
+ { "mips64r2", 1, ISA_MIPS64R2, CPU_MIPS64R2 },
/* MIPS I */
{ "r3000", 0, ISA_MIPS1, CPU_R3000 },
@@ -14533,6 +14717,7 @@ MIPS options:\n\
-mips32 generate MIPS32 ISA instructions\n\
-mips32r2 generate MIPS32 release 2 ISA instructions\n\
-mips64 generate MIPS64 ISA instructions\n\
+-mips64r2 generate MIPS64 release 2 ISA instructions\n\
-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
first = 1;