mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-26 05:20:30 +00:00
Fix multiplication, ldxc1, and floating point conversion. See ChangeLog.
This commit is contained in:
parent
c12f5c678e
commit
458e1f58e6
@ -1,13 +1,16 @@
|
|||||||
Thu Sep 19 15:34:17 1996 Ian Lance Taylor <ian@cygnus.com>
|
Thu Sep 19 15:34:17 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* gencode.c (MIPS_DECODE): Set UNSIGNED for multu instruction.
|
||||||
|
(process_instructions): Correct handling of nor instruction.
|
||||||
|
Correct shift count for 32 bit shift instructions. Correct sign
|
||||||
|
extension for arithmetic shifts to not shift the number of bits in
|
||||||
|
the type. Fix 64 bit multiply high word calculation. Fix 32 bit
|
||||||
|
unsigned multiply. Fix ldxc1 and friends to use coprocessor 1.
|
||||||
|
Fix madd.
|
||||||
* interp.c (CHECKHILO): Don't set HIACCESS, LOACCESS, or HLPC.
|
* interp.c (CHECKHILO): Don't set HIACCESS, LOACCESS, or HLPC.
|
||||||
It's OK to have a mult follow a mult. What's not OK is to have a
|
It's OK to have a mult follow a mult. What's not OK is to have a
|
||||||
mult follow an mfhi.
|
mult follow an mfhi.
|
||||||
|
(Convert): Comment out incorrect rounding code.
|
||||||
* gencode.c (process_instructions): Correct handling of nor
|
|
||||||
instruction. Correct shift count for 32 bit shift instructions.
|
|
||||||
Correct sign extension for arithmetic shifts to not shift the
|
|
||||||
number of bits in the type.
|
|
||||||
|
|
||||||
Mon Sep 16 11:38:16 1996 James G. Smith <jsmith@cygnus.co.uk>
|
Mon Sep 16 11:38:16 1996 James G. Smith <jsmith@cygnus.co.uk>
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ struct instruction MIPS_DECODE[] = {
|
|||||||
{"MSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X, FPSUB, (FP | MULTIPLY | SINGLE)},
|
{"MSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X, FPSUB, (FP | MULTIPLY | SINGLE)},
|
||||||
{"MUL", 1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1, FPMUL, (FP | HI | LO)},
|
{"MUL", 1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1, FPMUL, (FP | HI | LO)},
|
||||||
{"MULT", 1,"000000sssssggggg0000000000011000",SPECIAL,MUL, (WORD | WORD32 | HI | LO)},
|
{"MULT", 1,"000000sssssggggg0000000000011000",SPECIAL,MUL, (WORD | WORD32 | HI | LO)},
|
||||||
{"MULTU", 1,"000000sssssggggg0000000000011001",SPECIAL,MUL, (WORD | WORD32 | HI | LO)},
|
{"MULTU", 1,"000000sssssggggg0000000000011001",SPECIAL,MUL, (WORD | WORD32 | UNSIGNED | HI | LO)},
|
||||||
{"MxC1", 1,"01000100x00kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | WORD)},
|
{"MxC1", 1,"01000100x00kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | WORD)},
|
||||||
{"NEG", 1,"01000110mmm00000vvvvvrrrrr000111",COP1, FPNEG, (FP)},
|
{"NEG", 1,"01000110mmm00000vvvvvrrrrr000111",COP1, FPNEG, (FP)},
|
||||||
{"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X, FPADD, (FP | NOT | MULTIPLY | DOUBLE)},
|
{"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X, FPADD, (FP | NOT | MULTIPLY | DOUBLE)},
|
||||||
@ -1056,20 +1056,34 @@ process_instructions(doarch,features)
|
|||||||
printf(" {\n");
|
printf(" {\n");
|
||||||
if (GETDATASIZE() == DOUBLEWORD) {
|
if (GETDATASIZE() == DOUBLEWORD) {
|
||||||
printf(" uword64 mid;\n");
|
printf(" uword64 mid;\n");
|
||||||
|
printf(" uword64 midhi;\n");
|
||||||
printf(" uword64 temp;\n");
|
printf(" uword64 temp;\n");
|
||||||
|
if ((MIPS_DECODE[loop].flags & UNSIGNED) == 0)
|
||||||
|
{
|
||||||
|
printf(" int sign = 0;\n");
|
||||||
|
printf(" if (op1 < 0) { op1 = - op1; ++sign; }\n");
|
||||||
|
printf(" if (op2 < 0) { op2 = - op2; ++sign; }\n");
|
||||||
|
}
|
||||||
printf(" LO = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n");
|
printf(" LO = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n");
|
||||||
printf(" HI = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n");
|
printf(" HI = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n");
|
||||||
printf(" mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
|
printf(" mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
|
||||||
printf(" temp = (LO + SET64HI(WORD64LO(mid)));\n");
|
printf(" midhi = SET64HI(WORD64LO(mid));\n");
|
||||||
printf(" if ((temp == mid) ? (LO != 0) : (temp < mid))\n");
|
printf(" temp = (LO + midhi);\n");
|
||||||
|
printf(" if ((temp == midhi) ? (LO != 0) : (temp < midhi))\n");
|
||||||
printf(" HI += 1;\n");
|
printf(" HI += 1;\n");
|
||||||
printf(" HI += WORD64HI(mid);\n");
|
printf(" HI += WORD64HI(mid);\n");
|
||||||
printf(" mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
|
printf(" mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
|
||||||
printf(" LO = (temp + SET64HI(WORD64LO(mid)));\n");
|
printf(" midhi = SET64HI(WORD64LO(mid));\n");
|
||||||
printf(" if ((LO == mid) ? (temp != 0) : (LO < mid))\n");
|
printf(" LO = (temp + midhi);\n");
|
||||||
|
printf(" if ((LO == midhi) ? (temp != 0) : (LO < midhi))\n");
|
||||||
printf(" HI += 1;\n");
|
printf(" HI += 1;\n");
|
||||||
printf(" HI += WORD64HI(mid);\n");
|
printf(" HI += WORD64HI(mid);\n");
|
||||||
|
if ((MIPS_DECODE[loop].flags & UNSIGNED) == 0)
|
||||||
|
printf(" if (sign & 1) { LO = - LO; HI = (LO == 0 ? 0 : -1) - HI; }\n");
|
||||||
} else {
|
} else {
|
||||||
|
if (MIPS_DECODE[loop].flags & UNSIGNED)
|
||||||
|
printf(" uword64 temp = ((uword64)(op1 & 0xffffffff) * (uword64)(op2 & 0xffffffff));\n");
|
||||||
|
else
|
||||||
printf(" uword64 temp = (op1 * op2);\n");
|
printf(" uword64 temp = (op1 * op2);\n");
|
||||||
printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
|
printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
|
||||||
printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
|
printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
|
||||||
@ -1585,7 +1599,10 @@ process_instructions(doarch,features)
|
|||||||
implementation will be needed to ascertain the
|
implementation will be needed to ascertain the
|
||||||
correct operation. */
|
correct operation. */
|
||||||
if (MIPS_DECODE[loop].flags & COPROC)
|
if (MIPS_DECODE[loop].flags & COPROC)
|
||||||
printf(" COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)");
|
printf(" COP_LW(%s,destreg,(unsigned int)",
|
||||||
|
((MIPS_DECODE[loop].flags & REG)
|
||||||
|
? "1"
|
||||||
|
: "((instruction >> 26) & 0x3)"));
|
||||||
else
|
else
|
||||||
printf(" GPR[destreg] = (");
|
printf(" GPR[destreg] = (");
|
||||||
|
|
||||||
@ -1597,7 +1614,10 @@ process_instructions(doarch,features)
|
|||||||
printf(");\n");
|
printf(");\n");
|
||||||
} else {
|
} else {
|
||||||
if (MIPS_DECODE[loop].flags & COPROC)
|
if (MIPS_DECODE[loop].flags & COPROC)
|
||||||
printf(" COP_LD(((instruction >> 26) & 0x3),destreg,memval);;\n");
|
printf(" COP_LD(%s,destreg,memval);;\n",
|
||||||
|
((MIPS_DECODE[loop].flags & REG)
|
||||||
|
? "1"
|
||||||
|
: "((instruction >> 26) & 0x3)"));
|
||||||
else
|
else
|
||||||
printf(" GPR[destreg] = memval;\n");
|
printf(" GPR[destreg] = memval;\n");
|
||||||
}
|
}
|
||||||
@ -1628,12 +1648,21 @@ process_instructions(doarch,features)
|
|||||||
printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
|
printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
|
||||||
printf(" byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
|
printf(" byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
|
||||||
if (MIPS_DECODE[loop].flags & COPROC)
|
if (MIPS_DECODE[loop].flags & COPROC)
|
||||||
printf(" memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),%s)) << (8 * byte));\n",((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
|
printf(" memval = (((uword64)COP_SW(%s,%s)) << (8 * byte));\n",
|
||||||
|
((MIPS_DECODE[loop].flags & REG)
|
||||||
|
? "1"
|
||||||
|
: "((instruction >> 26) & 0x3)"),
|
||||||
|
((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
|
||||||
else
|
else
|
||||||
printf(" memval = (op2 << (8 * byte));\n");
|
printf(" memval = (op2 << (8 * byte));\n");
|
||||||
} else { /* !proc64 SC and SW, plus proc64 SD and SCD */
|
} else { /* !proc64 SC and SW, plus proc64 SD and SCD */
|
||||||
if (MIPS_DECODE[loop].flags & COPROC)
|
if (MIPS_DECODE[loop].flags & COPROC)
|
||||||
printf(" memval = (uword64)COP_S%c(((instruction >> 26) & 0x3),%s);\n",((datalen == 8) ? 'D' : 'W'),((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
|
printf(" memval = (uword64)COP_S%c(%s,%s);\n",
|
||||||
|
((datalen == 8) ? 'D' : 'W'),
|
||||||
|
((MIPS_DECODE[loop].flags & REG)
|
||||||
|
? "1"
|
||||||
|
: "((instruction >> 26) & 0x3)"),
|
||||||
|
((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
|
||||||
else
|
else
|
||||||
printf(" memval = op2;\n");
|
printf(" memval = op2;\n");
|
||||||
}
|
}
|
||||||
@ -1989,7 +2018,12 @@ process_instructions(doarch,features)
|
|||||||
fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZE());
|
fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZE());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf(" StoreFPR(destreg,%s,%s(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((MIPS_DECODE[loop].flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
|
if (MIPS_DECODE[loop].flags & NOT)
|
||||||
|
printf (" StoreFPR(destreg,%s,Negate(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
|
||||||
|
type, type, type, type, type, type, type);
|
||||||
|
else
|
||||||
|
printf (" StoreFPR(destreg,%s,Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
|
||||||
|
type, type, type, type, type, type);
|
||||||
} else {
|
} else {
|
||||||
printf(" if ((format != fmt_single) && (format != fmt_double))\n");
|
printf(" if ((format != fmt_single) && (format != fmt_double))\n");
|
||||||
printf(" SignalException(ReservedInstruction,instruction);\n");
|
printf(" SignalException(ReservedInstruction,instruction);\n");
|
||||||
|
@ -3364,6 +3364,11 @@ Convert(rm,op,from,to)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* FIXME: This code is incorrect. The rounding mode does not
|
||||||
|
round to integral values; it rounds to the nearest
|
||||||
|
representable value in the format. */
|
||||||
|
|
||||||
switch (rm) {
|
switch (rm) {
|
||||||
case FP_RM_NEAREST:
|
case FP_RM_NEAREST:
|
||||||
/* Round result to nearest representable value. When two
|
/* Round result to nearest representable value. When two
|
||||||
@ -3398,6 +3403,8 @@ Convert(rm,op,from,to)
|
|||||||
tmp = (float)floor((double)tmp);
|
tmp = (float)floor((double)tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
result = (uword64)*(unsigned int *)&tmp;
|
result = (uword64)*(unsigned int *)&tmp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3425,6 +3432,11 @@ Convert(rm,op,from,to)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* FIXME: This code is incorrect. The rounding mode does not
|
||||||
|
round to integral values; it rounds to the nearest
|
||||||
|
representable value in the format. */
|
||||||
|
|
||||||
switch (rm) {
|
switch (rm) {
|
||||||
case FP_RM_NEAREST:
|
case FP_RM_NEAREST:
|
||||||
#ifdef HAVE_ANINT
|
#ifdef HAVE_ANINT
|
||||||
@ -3450,6 +3462,8 @@ Convert(rm,op,from,to)
|
|||||||
tmp = floor(*(double *)&tmp);
|
tmp = floor(*(double *)&tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
result = *(uword64 *)&tmp;
|
result = *(uword64 *)&tmp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user