[VM Bigint] Fix arm64 intrinsic for _estimateQuotientDigit (loop missing jump back).

Add regression test.
Fix arm64 disassembler (was printing "unknow" instructions).
Make decoding stricter in arm64 simulator.
This fix addresses https://github.com/a14n/dart-rational/issues/19

Change-Id: I1b2ccb4bd560b588d0c4860c904cc398fba9014f
Reviewed-on: https://dart-review.googlesource.com/56740
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
This commit is contained in:
Régis Crelier 2018-05-26 01:19:03 +00:00 committed by commit-bot@chromium.org
parent 57d256377c
commit 4d271519a1
5 changed files with 18 additions and 9 deletions

View file

@ -614,9 +614,7 @@ int ARM64Decoder::FormatOption(Instr* instr, const char* format) {
} else if (format[1] == 'f') {
ASSERT(STRING_STARTS_WITH(format, "sf"));
if (instr->SFField() == 1) {
// TODO(zra): If we don't use the w form much, we can omit printing
// this x.
Print("x");
// 64-bit width is most commonly used, no need to print "x".
} else {
Print("w");
}
@ -1142,13 +1140,13 @@ void ARM64Decoder::DecodeMiscDP3Source(Instr* instr) {
int32_t mask = B31 | B30 | B29 | B23 | B22 | B21 | B15 | MiscDP3SourceMask;
int32_t bits = instr->InstructionBits() & mask;
if (bits == MADD) {
if (bits == MADD || bits == MADDW) {
if (zero_operand) {
Format(instr, "mul'sf 'rd, 'rn, 'rm");
} else {
Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra");
}
} else if (bits == MSUB) {
} else if (bits == MSUB || bits == MSUBW) {
if (zero_operand) {
Format(instr, "mneg'sf 'rd, 'rn, 'rm");
} else {

View file

@ -1175,6 +1175,9 @@ void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
// --qh
__ sub(R6, R6, Operand(1));
// Continue while loop.
__ b(&qh_adj_loop);
__ Bind(&qh_ok);
// R0 = qd = qh << 32
__ orr(R0, ZR, Operand(R6, LSL, 32));
@ -1227,6 +1230,9 @@ void Intrinsifier::Bigint_estQuotientDigit(Assembler* assembler) {
// --ql
__ sub(R6, R6, Operand(1));
// Continue while loop.
__ b(&ql_adj_loop);
__ Bind(&ql_ok);
// qd |= ql;
__ orr(R0, R0, Operand(R6));

View file

@ -522,8 +522,10 @@ enum MiscDP2SourceOp {
enum MiscDP3SourceOp {
MiscDP3SourceMask = 0x1f000000,
MiscDP3SourceFixed = DPRegisterFixed | B28 | B24,
MADD = MiscDP3SourceFixed,
MSUB = MiscDP3SourceFixed | B15,
MADDW = MiscDP3SourceFixed,
MADD = MiscDP3SourceFixed | B31,
MSUBW = MiscDP3SourceFixed | B15,
MSUB = MiscDP3SourceFixed | B31 | B15,
SMULH = MiscDP3SourceFixed | B31 | B22,
UMULH = MiscDP3SourceFixed | B31 | B23 | B22,
SMADDL = MiscDP3SourceFixed | B31 | B21,

View file

@ -2552,7 +2552,7 @@ void Simulator::DecodeMiscDP3Source(Instr* instr) {
const int32_t alu_out = ra_val - (rn_val * rm_val);
set_wregister(rd, alu_out, R31IsZR);
}
} else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) &&
} else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 2) &&
(instr->Bit(15) == 0)) {
ASSERT(ra == R31); // Should-Be-One
// Format(instr, "smulh 'rd, 'rn, 'rm");
@ -2568,7 +2568,7 @@ void Simulator::DecodeMiscDP3Source(Instr* instr) {
const int64_t alu_out = static_cast<int64_t>(res >> 64);
#endif // HOST_OS_WINDOWS
set_register(instr, rd, alu_out, R31IsZR);
} else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 6) &&
} else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 6) &&
(instr->Bit(15) == 0)) {
ASSERT(ra == R31); // Should-Be-One
// Format(instr, "umulh 'rd, 'rn, 'rm");

View file

@ -363,6 +363,9 @@ testBigintTruncDiv() {
a = BigInt.parse("12345678901234567890");
b = BigInt.parse("10000000000000000");
Expect.equals(new BigInt.from(1234), a ~/ b);
a = BigInt.parse("9173112362840293939050000000000000000");
b = BigInt.parse("50000000000000000");
Expect.equals(BigInt.parse("183462247256805878781"), a ~/ b);
}
testBigintDiv() {