diff options
author | Andrew Cagney <cagney@redhat.com> | 1998-06-04 08:46:56 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1998-06-04 08:46:56 +0000 |
commit | 0e797366efd0c7aad9acddcaeac4a55a0fd8bfb7 (patch) | |
tree | 8945a1273971d382d39bf28c5ae23beeeb13dad9 /sim/mips/mips.igen | |
parent | 05f6bf9cea4c1f294a40af5ad55abe2970cf6640 (diff) | |
download | gdb-0e797366efd0c7aad9acddcaeac4a55a0fd8bfb7.zip gdb-0e797366efd0c7aad9acddcaeac4a55a0fd8bfb7.tar.gz gdb-0e797366efd0c7aad9acddcaeac4a55a0fd8bfb7.tar.bz2 |
The r5900 doesn't have HI/LO DIV/MUL register problems. Hobble
checks on hi/lo usage but retain functions so that they can be used
for HI/LO stall counting code.
Diffstat (limited to 'sim/mips/mips.igen')
-rw-r--r-- | sim/mips/mips.igen | 145 |
1 files changed, 118 insertions, 27 deletions
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen index df89140..48c6216 100644 --- a/sim/mips/mips.igen +++ b/sim/mips/mips.igen @@ -132,9 +132,6 @@ // start-sanitize-vr5400 *vr5400: // end-sanitize-vr5400 -// start-sanitize-r5900 -*r5900: -// end-sanitize-r5900 { signed64 time = sim_events_time (SD); int ok = check_mf_cycles (SD_, history, time, "MT"); @@ -148,6 +145,9 @@ // start-sanitize-tx19 *tx19: // end-sanitize-tx19 +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 { signed64 time = sim_events_time (SD); history->mt.timestamp = time; @@ -155,7 +155,20 @@ return 1; } + :function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer +*mipsI,mipsII,mipsIII,mipsIV: +*vr5000: +// start-sanitize-vr4320 +*vr4320: +// end-sanitize-vr4320 +// start-sanitize-vr5400 +*vr5400: +// end-sanitize-vr5400 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 { signed64 time = sim_events_time (SD); int ok = 1; @@ -177,6 +190,24 @@ return ok; } +// start-sanitize-r5900 +// The r5900 mfhi et.al insns _can_ be exectuted immediatly after a div +:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer +// end-sanitize-r5900 +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +// start-sanitize-r5900 +{ + /* FIXME: could record the fact that a stall occured if we want */ + signed64 time = sim_events_time (SD); + history->mf.timestamp = time; + history->mf.cia = CIA; + return 1; +} +// end-sanitize-r5900 + + :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo *mipsI,mipsII,mipsIII,mipsIV: *vr5000: @@ -186,9 +217,6 @@ // start-sanitize-vr5400 *vr5400: // end-sanitize-vr5400 -// start-sanitize-r5900 -*r5900: -// end-sanitize-r5900 { signed64 time = sim_events_time (SD); int ok = (check_mf_cycles (SD_, hi, time, "OP") @@ -200,7 +228,6 @@ return ok; } - // The r3900 mult and multu insns _can_ be exectuted immediatly after // a mf{hi,lo} :function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo @@ -208,7 +235,11 @@ // start-sanitize-tx19 *tx19: // end-sanitize-tx19 +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 { + /* FIXME: could record the fact that a stall occured if we want */ signed64 time = sim_events_time (SD); hi->op.timestamp = time; lo->op.timestamp = time; @@ -217,6 +248,7 @@ return 1; } + :function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo *mipsI,mipsII,mipsIII,mipsIV: *vr5000: @@ -230,9 +262,6 @@ // start-sanitize-tx19 *tx19: // end-sanitize-tx19 -// start-sanitize-r5900 -*r5900: -// end-sanitize-r5900 { signed64 time = sim_events_time (SD); int ok = (check_mf_cycles (SD_, hi, time, "OP") @@ -245,6 +274,27 @@ } +// start-sanitize-r5900 +// The r5900 div et.al insns _can_ be exectuted immediatly after +// a mf{hi,lo} +:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo +// end-sanitize-r5900 +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +// start-sanitize-r5900 +{ + /* FIXME: could record the fact that a stall occured if we want */ + signed64 time = sim_events_time (SD); + hi->op.timestamp = time; + lo->op.timestamp = time; + hi->op.cia = CIA; + lo->op.cia = CIA; + return 1; +} +// end-sanitize-r5900 + + // // Mips Architecture: @@ -2074,33 +2124,53 @@ address_word reverseendian = (ReverseEndian ? -1 : 0); address_word bigendiancpu = (BigEndianCPU ? -1 : 0); unsigned int byte; + unsigned int word; address_word paddr; int uncached; unsigned64 memval; address_word vaddr; + int nr_lhs_bits; + int nr_rhs_bits; + unsigned_word lhs_mask; + unsigned_word temp; vaddr = base + offset; AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) paddr = paddr & ~access; - byte = ((vaddr & mask) ^ (bigendiancpu & mask)); - LoadMemory (&memval, NULL, uncached, byte & access, paddr, vaddr, isDATA, isREAL); - /* printf ("ll: 0x%08lx %d@0x%08lx 0x%08lx\n", - (long) vaddr, byte, (long) paddr, (long) memval); */ - if ((byte & ~access) == 0) + + /* compute where within the word/mem we are */ + byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */ + word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */ + nr_lhs_bits = 8 * byte + 8; + nr_rhs_bits = 8 * access - 8 * byte; + /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */ + + /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n", + (long) ((unsigned64) vaddr >> 32), (long) vaddr, + (long) ((unsigned64) paddr >> 32), (long) paddr, + word, byte, nr_lhs_bits, nr_rhs_bits); */ + + LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL); + if (word == 0) { - int bits = 8 * (access - byte); - unsigned_word screen = LSMASK (bits - 1, 0); - rt &= screen; - rt |= ((memval << bits) & ~screen); + /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */ + temp = (memval << nr_rhs_bits); } else { - unsigned_word screen = LSMASK (8 * (access - (byte & access)) - 1, 0); - rt &= screen; - rt |= ((memval >> (8 * (mask - byte))) & ~screen); + /* GPR{31..32-NR_LHS_BITS = memval{32+NR_LHS_BITS..32} */ + temp = (memval >> nr_lhs_bits); } + lhs_mask = LSMASK (nr_lhs_bits + nr_rhs_bits - 1, nr_rhs_bits); + rt = (rt & ~lhs_mask) | (temp & lhs_mask); + + /* fprintf (stderr, "l[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx & 0x%08lx%08lx -> 0x%08lx%08lx\n", + (long) ((unsigned64) memval >> 32), (long) memval, + (long) ((unsigned64) temp >> 32), (long) temp, + (long) ((unsigned64) lhs_mask >> 32), (long) lhs_mask, + (long) (rt >> 32), (long) rt); */ return rt; } @@ -3212,22 +3282,43 @@ address_word reverseendian = (ReverseEndian ? -1 : 0); address_word bigendiancpu = (BigEndianCPU ? -1 : 0); unsigned int byte; + unsigned int word; address_word paddr; int uncached; unsigned64 memval; address_word vaddr; + int nr_lhs_bits; + int nr_rhs_bits; vaddr = base + offset; AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL); paddr = (paddr ^ (reverseendian & mask)); if (BigEndianMem == 0) paddr = paddr & ~access; - byte = ((vaddr & mask) ^ (bigendiancpu & mask)); - if ((byte & ~access) == 0) - memval = (rt >> (8 * (access - byte))); + + /* compute where within the word/mem we are */ + byte = ((vaddr ^ bigendiancpu) & access); /* 0..access */ + word = ((vaddr ^ bigendiancpu) & (mask & ~access)) / (access + 1); /* 0..1 */ + nr_lhs_bits = 8 * byte + 8; + nr_rhs_bits = 8 * access - 8 * byte; + /* nr_lhs_bits + nr_rhs_bits == 8 * (accesss + 1) */ + /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx 0x%08lx%08lx %d:%d %d+%d\n", + (long) ((unsigned64) vaddr >> 32), (long) vaddr, + (long) ((unsigned64) paddr >> 32), (long) paddr, + word, byte, nr_lhs_bits, nr_rhs_bits); */ + + if (word == 0) + { + memval = (rt >> nr_rhs_bits); + } else - memval = (rt << (8 * (mask - byte))); - StoreMemory (uncached, byte & access, memval, 0, paddr, vaddr, isREAL); + { + memval = (rt << nr_lhs_bits); + } + /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n", + (long) ((unsigned64) rt >> 32), (long) rt, + (long) ((unsigned64) memval >> 32), (long) memval); */ + StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL); } |