mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 22:11:19 +00:00
[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:
parent
57d256377c
commit
4d271519a1
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue