aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-09-06 15:51:09 +0000
committerIan Lance Taylor <ian@airs.com>1994-09-06 15:51:09 +0000
commit8c63448afe0c72becfeecda4557db3ff57c0b446 (patch)
tree89bb1c4ec8f2a3c11b7ae066b51e15e231879505 /gas
parent942a4965b7805e370845b55b128e071cdb35e46a (diff)
downloadgdb-8c63448afe0c72becfeecda4557db3ff57c0b446.zip
gdb-8c63448afe0c72becfeecda4557db3ff57c0b446.tar.gz
gdb-8c63448afe0c72becfeecda4557db3ff57c0b446.tar.bz2
* config/tc-mips.c (mips_cpu): New static variable.
(insns_since_cache_access): New static variable. (md_begin): Set mips_cpu as well as mips_isa. (append_insn): If mips_cpu is 4600, require four nop instructions between an instruction which accesses the cache and certain CACHE instructions. Keep track of the number of instructions seen since an instruction which accesses the cache. (md_parse_option): Set mips_cpu as well as mips_isa. PR 5433.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/config/tc-mips.c131
2 files changed, 123 insertions, 21 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index ff0c2b9..92faf89 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,10 +1,21 @@
+Tue Sep 6 11:42:38 1994 Ian Lance Taylor (ian@sanguine.cygnus.com)
+
+ * config/tc-mips.c (mips_cpu): New static variable.
+ (insns_since_cache_access): New static variable.
+ (md_begin): Set mips_cpu as well as mips_isa.
+ (append_insn): If mips_cpu is 4600, require four nop instructions
+ between an instruction which accesses the cache and certain CACHE
+ instructions. Keep track of the number of instructions seen since
+ an instruction which accesses the cache.
+ (md_parse_option): Set mips_cpu as well as mips_isa.
+
Mon Sep 5 07:09:00 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com)
* doc/Makefile.in (VPATH): Define using @srcdir@.
(prefix, program_transform_name, exec_prefix): Use autoconf style
@-substitutions.
-Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
+Sun Sep 04 17:58:10 1994 Richard Earnshaw (rwe@pegasus.esprit.ec.org)
* config/ho-riscix.h, config/tc-arm.c, config/tc-arm.h: New files
* configure.in: Recognize the arm.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 7363901..e607557 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -114,6 +114,9 @@ static int mips_isa = -1;
/* MIPS ISA we are using for this output file. */
static int file_mips_isa;
+/* The CPU type as a number: 2000, 3000, 4000, 4400, etc. */
+static int mips_cpu;
+
/* MIPS PIC level. */
enum mips_pic_level
@@ -249,6 +252,12 @@ static int prev_insn_unreordered;
/* Non-zero if the previous previous instruction was in a .set
noreorder. */
static int prev_prev_insn_unreordered;
+
+/* The number of instructions since the last instruction which
+ accesses the data cache. The instruction itself counts as 1, so 0
+ means no information. This is used to work around a bug on the
+ r4600 (ORION) chip. */
+static int insns_since_cache_access;
/* Since the MIPS does not have multiple forms of PC relative
instructions, we do not have to do relaxing as is done on other
@@ -500,17 +509,55 @@ md_begin ()
if (mips_isa == -1)
{
- if (strcmp (TARGET_CPU, "mips") == 0)
- mips_isa = 1;
- else if (strcmp (TARGET_CPU, "r6000") == 0
- || strcmp (TARGET_CPU, "mips2") == 0)
- mips_isa = 2;
- else if (strcmp (TARGET_CPU, "mips64") == 0
- || strcmp (TARGET_CPU, "r4000") == 0
- || strcmp (TARGET_CPU, "mips3") == 0)
- mips_isa = 3;
+ const char *cpu;
+ char *a = NULL;
+
+ cpu = TARGET_CPU;
+ if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0)
+ {
+ a = xmalloc (sizeof TARGET_CPU);
+ strcpy (a, TARGET_CPU);
+ a[(sizeof TARGET_CPU) - 3] = '\0';
+ cpu = a;
+ }
+
+ if (strcmp (cpu, "mips") == 0)
+ {
+ mips_isa = 1;
+ mips_cpu = 3000;
+ }
+ else if (strcmp (cpu, "r6000") == 0
+ || strcmp (cpu, "mips2") == 0)
+ {
+ mips_isa = 2;
+ mips_cpu = 6000;
+ }
+ else if (strcmp (cpu, "mips64") == 0
+ || strcmp (cpu, "r4000") == 0
+ || strcmp (cpu, "mips3") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4000;
+ }
+ else if (strcmp (cpu, "r4400") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4400;
+ }
+ else if (strcmp (cpu, "mips64orion") == 0
+ || strcmp (cpu, "r4600") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4600;
+ }
else
- mips_isa = 1;
+ {
+ mips_isa = 1;
+ mips_cpu = 3000;
+ }
+
+ if (a != NULL)
+ free (a);
}
if (mips_isa < 2 && mips_trap)
@@ -866,6 +913,18 @@ append_insn (place, ip, address_expr, reloc_type)
&& (pinfo & INSN_WRITE_HI))))
++nops;
+ /* The r4600 (ORION) chip has a bug: at least four instructions
+ are required between an instruction which accesses memory and
+ a certain set of CACHE instructions. Handle that now. */
+ if (mips_cpu == 4600
+ && insns_since_cache_access != 0
+ && 5 - insns_since_cache_access > nops
+ && ((ip->insn_opcode & 0xffff0000) == 0xbc0d0000
+ || (ip->insn_opcode & 0xffff0000) == 0xbc110000
+ || (ip->insn_opcode & 0xfc1f0000) == 0xbc150000
+ || (ip->insn_opcode & 0xffff0000) == 0xbc190000))
+ nops = 5 - insns_since_cache_access;
+
/* If we are being given a nop instruction, don't bother with
one of the nops we would otherwise output. This will only
happen when a nop instruction is used with mips_optimize set
@@ -876,8 +935,9 @@ append_insn (place, ip, address_expr, reloc_type)
/* Now emit the right number of NOP instructions. */
if (nops > 0)
{
- emit_nop ();
- if (nops > 1)
+ int i;
+
+ for (i = 0; i < nops; i++)
emit_nop ();
if (listing)
listing_prev_line ();
@@ -1168,6 +1228,11 @@ append_insn (place, ip, address_expr, reloc_type)
prev_insn_where = f - frag_now->fr_literal;
prev_insn_fixp = fixp;
prev_insn_valid = 1;
+ if ((pinfo & INSN_LOAD_MEMORY_DELAY) != 0
+ || (pinfo & INSN_STORE_MEMORY) != 0)
+ insns_since_cache_access = 1;
+ else if (insns_since_cache_access != 0)
+ ++insns_since_cache_access;
}
/* We just output an insn, so the next one doesn't have a label. */
@@ -4999,14 +5064,17 @@ md_parse_option (c, arg)
case OPTION_MIPS1:
mips_isa = 1;
+ mips_cpu = 3000;
break;
case OPTION_MIPS2:
mips_isa = 2;
+ mips_cpu = 6000;
break;
case OPTION_MIPS3:
mips_isa = 3;
+ mips_cpu = 4000;
break;
case OPTION_MCPU:
@@ -5030,35 +5098,58 @@ md_parse_option (c, arg)
if (strcmp (p, "2000") == 0
|| strcmp (p, "2k") == 0
|| strcmp (p, "2K") == 0)
- mips_isa = 1;
+ {
+ mips_isa = 1;
+ mips_cpu = 2000;
+ }
break;
case '3':
if (strcmp (p, "3000") == 0
|| strcmp (p, "3k") == 0
|| strcmp (p, "3K") == 0)
- mips_isa = 1;
+ {
+ mips_isa = 1;
+ mips_cpu = 3000;
+ }
break;
case '4':
if (strcmp (p, "4000") == 0
|| strcmp (p, "4k") == 0
- || strcmp (p, "4K") == 0
- || strcmp (p, "4400") == 0
- || strcmp (p, "4600") == 0)
- mips_isa = 3;
+ || strcmp (p, "4K") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4000;
+ }
+ else if (strcmp (p, "4400") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4400;
+ }
+ else if (strcmp (p, "4600") == 0)
+ {
+ mips_isa = 3;
+ mips_cpu = 4600;
+ }
break;
case '6':
if (strcmp (p, "6000") == 0
|| strcmp (p, "6k") == 0
|| strcmp (p, "6K") == 0)
- mips_isa = 2;
+ {
+ mips_isa = 2;
+ mips_cpu = 6000;
+ }
break;
case 'o':
if (strcmp (p, "orion") == 0)
- mips_isa = 3;
+ {
+ mips_isa = 3;
+ mips_cpu = 4600;
+ }
break;
}