| Index: src/mips64/simulator-mips64.cc
|
| diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
|
| index 5903e529beba08c02d62d77d74c48e70e98a60e9..c64314c74aaea7819004d132e76d190d30e19f38 100644
|
| --- a/src/mips64/simulator-mips64.cc
|
| +++ b/src/mips64/simulator-mips64.cc
|
| @@ -1743,7 +1743,7 @@ int32_t Simulator::ReadW(int64_t addr, Instruction* instr) {
|
| addr, reinterpret_cast<intptr_t>(instr));
|
| DieOrDebug();
|
| }
|
| - if ((addr & 0x3) == 0) {
|
| + if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
|
| int32_t* ptr = reinterpret_cast<int32_t*>(addr);
|
| TraceMemRd(addr, static_cast<int64_t>(*ptr));
|
| return *ptr;
|
| @@ -1763,7 +1763,7 @@ uint32_t Simulator::ReadWU(int64_t addr, Instruction* instr) {
|
| addr, reinterpret_cast<intptr_t>(instr));
|
| DieOrDebug();
|
| }
|
| - if ((addr & 0x3) == 0) {
|
| + if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
|
| uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
|
| TraceMemRd(addr, static_cast<int64_t>(*ptr));
|
| return *ptr;
|
| @@ -1783,7 +1783,7 @@ void Simulator::WriteW(int64_t addr, int32_t value, Instruction* instr) {
|
| addr, reinterpret_cast<intptr_t>(instr));
|
| DieOrDebug();
|
| }
|
| - if ((addr & 0x3) == 0) {
|
| + if ((addr & 0x3) == 0 || kArchVariant == kMips64r6) {
|
| TraceMemWr(addr, value, WORD);
|
| int* ptr = reinterpret_cast<int*>(addr);
|
| *ptr = value;
|
| @@ -1803,7 +1803,7 @@ int64_t Simulator::Read2W(int64_t addr, Instruction* instr) {
|
| addr, reinterpret_cast<intptr_t>(instr));
|
| DieOrDebug();
|
| }
|
| - if ((addr & kPointerAlignmentMask) == 0) {
|
| + if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) {
|
| int64_t* ptr = reinterpret_cast<int64_t*>(addr);
|
| TraceMemRd(addr, *ptr);
|
| return *ptr;
|
| @@ -1823,7 +1823,7 @@ void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) {
|
| addr, reinterpret_cast<intptr_t>(instr));
|
| DieOrDebug();
|
| }
|
| - if ((addr & kPointerAlignmentMask) == 0) {
|
| + if ((addr & kPointerAlignmentMask) == 0 || kArchVariant == kMips64r6) {
|
| TraceMemWr(addr, value, DWORD);
|
| int64_t* ptr = reinterpret_cast<int64_t*>(addr);
|
| *ptr = value;
|
| @@ -1836,7 +1836,7 @@ void Simulator::Write2W(int64_t addr, int64_t value, Instruction* instr) {
|
|
|
|
|
| double Simulator::ReadD(int64_t addr, Instruction* instr) {
|
| - if ((addr & kDoubleAlignmentMask) == 0) {
|
| + if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) {
|
| double* ptr = reinterpret_cast<double*>(addr);
|
| return *ptr;
|
| }
|
| @@ -1848,7 +1848,7 @@ double Simulator::ReadD(int64_t addr, Instruction* instr) {
|
|
|
|
|
| void Simulator::WriteD(int64_t addr, double value, Instruction* instr) {
|
| - if ((addr & kDoubleAlignmentMask) == 0) {
|
| + if ((addr & kDoubleAlignmentMask) == 0 || kArchVariant == kMips64r6) {
|
| double* ptr = reinterpret_cast<double*>(addr);
|
| *ptr = value;
|
| return;
|
| @@ -1861,7 +1861,7 @@ void Simulator::WriteD(int64_t addr, double value, Instruction* instr) {
|
|
|
|
|
| uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) {
|
| - if ((addr & 1) == 0) {
|
| + if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
|
| uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
|
| TraceMemRd(addr, static_cast<int64_t>(*ptr));
|
| return *ptr;
|
| @@ -1875,7 +1875,7 @@ uint16_t Simulator::ReadHU(int64_t addr, Instruction* instr) {
|
|
|
|
|
| int16_t Simulator::ReadH(int64_t addr, Instruction* instr) {
|
| - if ((addr & 1) == 0) {
|
| + if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
|
| int16_t* ptr = reinterpret_cast<int16_t*>(addr);
|
| TraceMemRd(addr, static_cast<int64_t>(*ptr));
|
| return *ptr;
|
| @@ -1889,7 +1889,7 @@ int16_t Simulator::ReadH(int64_t addr, Instruction* instr) {
|
|
|
|
|
| void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) {
|
| - if ((addr & 1) == 0) {
|
| + if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
|
| TraceMemWr(addr, value, HALF);
|
| uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
|
| *ptr = value;
|
| @@ -1903,7 +1903,7 @@ void Simulator::WriteH(int64_t addr, uint16_t value, Instruction* instr) {
|
|
|
|
|
| void Simulator::WriteH(int64_t addr, int16_t value, Instruction* instr) {
|
| - if ((addr & 1) == 0) {
|
| + if ((addr & 1) == 0 || kArchVariant == kMips64r6) {
|
| TraceMemWr(addr, value, HALF);
|
| int16_t* ptr = reinterpret_cast<int16_t*>(addr);
|
| *ptr = value;
|
| @@ -4164,6 +4164,8 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
|
| int64_t addr = 0x0;
|
| // Alignment for 32-bit integers used in LWL, LWR, etc.
|
| const int kInt32AlignmentMask = sizeof(uint32_t) - 1;
|
| + // Alignment for 64-bit integers used in LDL, LDR, etc.
|
| + const int kInt64AlignmentMask = sizeof(uint64_t) - 1;
|
|
|
| // Branch instructions common part.
|
| auto BranchAndLinkHelper = [this, instr, &next_pc,
|
| @@ -4465,10 +4467,10 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
|
| uint8_t byte_shift = kInt32AlignmentMask - al_offset;
|
| uint32_t mask = (1 << byte_shift * 8) - 1;
|
| addr = rs + se_imm16 - al_offset;
|
| - alu_out = ReadW(addr, instr);
|
| - alu_out <<= byte_shift * 8;
|
| - alu_out |= rt & mask;
|
| - set_register(rt_reg, alu_out);
|
| + int32_t val = ReadW(addr, instr);
|
| + val <<= byte_shift * 8;
|
| + val |= rt & mask;
|
| + set_register(rt_reg, static_cast<int64_t>(val));
|
| break;
|
| }
|
| case LW:
|
| @@ -4498,6 +4500,30 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
|
| set_register(rt_reg, alu_out);
|
| break;
|
| }
|
| + case LDL: {
|
| + // al_offset is offset of the effective address within an aligned word.
|
| + uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
|
| + uint8_t byte_shift = kInt64AlignmentMask - al_offset;
|
| + uint64_t mask = (1UL << byte_shift * 8) - 1;
|
| + addr = rs + se_imm16 - al_offset;
|
| + alu_out = Read2W(addr, instr);
|
| + alu_out <<= byte_shift * 8;
|
| + alu_out |= rt & mask;
|
| + set_register(rt_reg, alu_out);
|
| + break;
|
| + }
|
| + case LDR: {
|
| + // al_offset is offset of the effective address within an aligned word.
|
| + uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
|
| + uint8_t byte_shift = kInt64AlignmentMask - al_offset;
|
| + uint64_t mask = al_offset ? (~0UL << (byte_shift + 1) * 8) : 0UL;
|
| + addr = rs + se_imm16 - al_offset;
|
| + alu_out = Read2W(addr, instr);
|
| + alu_out = alu_out >> al_offset * 8;
|
| + alu_out |= rt & mask;
|
| + set_register(rt_reg, alu_out);
|
| + break;
|
| + }
|
| case SB:
|
| WriteB(rs + se_imm16, static_cast<int8_t>(rt));
|
| break;
|
| @@ -4529,6 +4555,25 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
|
| WriteW(addr, static_cast<int32_t>(mem_value), instr);
|
| break;
|
| }
|
| + case SDL: {
|
| + uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
|
| + uint8_t byte_shift = kInt64AlignmentMask - al_offset;
|
| + uint64_t mask = byte_shift ? (~0UL << (al_offset + 1) * 8) : 0;
|
| + addr = rs + se_imm16 - al_offset;
|
| + uint64_t mem_value = Read2W(addr, instr) & mask;
|
| + mem_value |= rt >> byte_shift * 8;
|
| + Write2W(addr, mem_value, instr);
|
| + break;
|
| + }
|
| + case SDR: {
|
| + uint8_t al_offset = (rs + se_imm16) & kInt64AlignmentMask;
|
| + uint64_t mask = (1UL << al_offset * 8) - 1;
|
| + addr = rs + se_imm16 - al_offset;
|
| + uint64_t mem_value = Read2W(addr, instr);
|
| + mem_value = (rt << al_offset * 8) | (mem_value & mask);
|
| + Write2W(addr, mem_value, instr);
|
| + break;
|
| + }
|
| case LWC1:
|
| set_fpu_register(ft_reg, kFPUInvalidResult); // Trash upper 32 bits.
|
| set_fpu_register_word(ft_reg, ReadW(rs + se_imm16, instr));
|
|
|