Commit 9debac6d authored by Zhi An Ng's avatar Zhi An Ng Committed by Commit Bot

[arm][cleanup] Refactor decoding to follow guide

Stick more closely to the decoding guide laid out in the manual, and
also take the chance to remove some duplicate code.

Drive-by fix a clang-tidy warning for bool literal.

Bug: v8:11074
Change-Id: I91aa8db7cd3db30b250e8bfc9bb146c8bb56dcd1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2567530
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71630}
parent 5ce5f429
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "src/execution/arm/simulator-arm.h" #include "src/execution/arm/simulator-arm.h"
#include "src/base/logging.h"
#if defined(USE_SIMULATOR) #if defined(USE_SIMULATOR)
#include <stdarg.h> #include <stdarg.h>
...@@ -79,6 +81,17 @@ void Simulator::DebugAtNextPC() { ...@@ -79,6 +81,17 @@ void Simulator::DebugAtNextPC() {
ArmDebugger(this).Debug(); ArmDebugger(this).Debug();
} }
void Simulator::AdvancedSIMDElementOrStructureLoadStoreWriteback(int Rn, int Rm,
int ebytes) {
if (Rm != 15) {
if (Rm == 13) {
set_register(Rn, get_register(Rn) + ebytes);
} else {
set_register(Rn, get_register(Rn) + get_register(Rm));
}
}
}
int32_t ArmDebugger::GetRegisterValue(int regnum) { int32_t ArmDebugger::GetRegisterValue(int regnum) {
if (regnum == kPCRegister) { if (regnum == kPCRegister) {
return sim_->get_pc(); return sim_->get_pc();
...@@ -2340,7 +2353,7 @@ void Simulator::DecodeType01(Instruction* instr) { ...@@ -2340,7 +2353,7 @@ void Simulator::DecodeType01(Instruction* instr) {
int rn = instr->RnValue(); int rn = instr->RnValue();
int32_t rn_val = get_register(rn); int32_t rn_val = get_register(rn);
int32_t shifter_operand = 0; int32_t shifter_operand = 0;
bool shifter_carry_out = 0; bool shifter_carry_out = false;
if (type == 0) { if (type == 0) {
shifter_operand = GetShiftRm(instr, &shifter_carry_out); shifter_operand = GetShiftRm(instr, &shifter_carry_out);
} else { } else {
...@@ -2633,7 +2646,7 @@ void Simulator::DecodeType3(Instruction* instr) { ...@@ -2633,7 +2646,7 @@ void Simulator::DecodeType3(Instruction* instr) {
int rd = instr->RdValue(); int rd = instr->RdValue();
int rn = instr->RnValue(); int rn = instr->RnValue();
int32_t rn_val = get_register(rn); int32_t rn_val = get_register(rn);
bool shifter_carry_out = 0; bool shifter_carry_out = false;
int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
int32_t addr = 0; int32_t addr = 0;
switch (instr->PUField()) { switch (instr->PUField()) {
...@@ -5626,55 +5639,24 @@ void Simulator::DecodeMemoryHintsAndBarriers(Instruction* instr) { ...@@ -5626,55 +5639,24 @@ void Simulator::DecodeMemoryHintsAndBarriers(Instruction* instr) {
void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
Instruction* instr) { Instruction* instr) {
switch (instr->SpecialValue()) { int op0 = instr->Bit(23);
case 8: int op1 = instr->Bits(11, 10);
if (instr->Bits(21, 20) == 0) {
// vst1 if (!op0) {
int Vd = (instr->Bit(22) << 4) | instr->VdValue(); DecodeAdvancedSIMDLoadStoreMultipleStructures(instr);
int Rn = instr->VnValue(); } else if (op1 == 0b11) {
int type = instr->Bits(11, 8); DecodeAdvancedSIMDLoadSingleStructureToAllLanes(instr);
int Rm = instr->VmValue();
int32_t address = get_register(Rn);
int regs = 0;
switch (type) {
case nlt_1:
regs = 1;
break;
case nlt_2:
regs = 2;
break;
case nlt_3:
regs = 3;
break;
case nlt_4:
regs = 4;
break;
default:
UNIMPLEMENTED();
break;
}
int r = 0;
while (r < regs) {
uint32_t data[2];
get_d_register(Vd + r, data);
WriteW(address, data[0]);
WriteW(address + 4, data[1]);
address += 8;
r++;
}
if (Rm != 15) {
if (Rm == 13) {
set_register(Rn, address);
} else { } else {
set_register(Rn, get_register(Rn) + get_register(Rm)); DecodeAdvancedSIMDLoadStoreSingleStructureToOneLane(instr);
}
} }
} else if (instr->Bits(21, 20) == 2) { }
// vld1
int Vd = (instr->Bit(22) << 4) | instr->VdValue(); void Simulator::DecodeAdvancedSIMDLoadStoreMultipleStructures(
Instruction* instr) {
int Vd = instr->VFPDRegValue(kDoublePrecision);
int Rn = instr->VnValue(); int Rn = instr->VnValue();
int type = instr->Bits(11, 8);
int Rm = instr->VmValue(); int Rm = instr->VmValue();
int type = instr->Bits(11, 8);
int32_t address = get_register(Rn); int32_t address = get_register(Rn);
int regs = 0; int regs = 0;
switch (type) { switch (type) {
...@@ -5694,6 +5676,8 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( ...@@ -5694,6 +5676,8 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
UNIMPLEMENTED(); UNIMPLEMENTED();
break; break;
} }
if (instr->Bit(21)) {
// vld1
int r = 0; int r = 0;
while (r < regs) { while (r < regs) {
uint32_t data[2]; uint32_t data[2];
...@@ -5703,28 +5687,33 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( ...@@ -5703,28 +5687,33 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
address += 8; address += 8;
r++; r++;
} }
if (Rm != 15) {
if (Rm == 13) {
set_register(Rn, address);
} else { } else {
set_register(Rn, get_register(Rn) + get_register(Rm)); // vst1
} int r = 0;
while (r < regs) {
uint32_t data[2];
get_d_register(Vd + r, data);
WriteW(address, data[0]);
WriteW(address + 4, data[1]);
address += 8;
r++;
} }
} else {
UNIMPLEMENTED();
} }
break; AdvancedSIMDElementOrStructureLoadStoreWriteback(Rn, Rm, 8 * regs);
case 9: { }
void Simulator::DecodeAdvancedSIMDLoadSingleStructureToAllLanes(
Instruction* instr) {
DCHECK_NE(0, instr->Bit(21));
int N = instr->Bits(9, 8);
int Vd = instr->VFPDRegValue(kDoublePrecision); int Vd = instr->VFPDRegValue(kDoublePrecision);
int Rn = instr->VnValue(); int Rn = instr->VnValue();
int Rm = instr->VmValue(); int Rm = instr->VmValue();
int32_t address = get_register(Rn); int32_t address = get_register(Rn);
if (instr->Bits(21, 20) == 2) {
// Bits(11, 8) is the B field in A7.7 Advanced SIMD element or structure if (!N) {
// load/store instructions. See table A7-21.
if (instr->Bits(11, 8) == 0xC) {
// vld1 (single element to all lanes). // vld1 (single element to all lanes).
DCHECK_EQ(instr->Bits(11, 8), 0b1100); // Type field.
int regs = instr->Bit(5) + 1; int regs = instr->Bit(5) + 1;
int size = instr->Bits(7, 6); int size = instr->Bits(7, 6);
uint32_t q_data[2]; uint32_t q_data[2];
...@@ -5756,17 +5745,25 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( ...@@ -5756,17 +5745,25 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
for (int r = 0; r < regs; r++) { for (int r = 0; r < regs; r++) {
set_neon_register<uint32_t, kDoubleSize>(Vd + r, q_data); set_neon_register<uint32_t, kDoubleSize>(Vd + r, q_data);
} }
if (Rm != 15) { AdvancedSIMDElementOrStructureLoadStoreWriteback(Rn, Rm, 1 << size);
if (Rm == 13) {
set_register(Rn, address);
} else { } else {
set_register(Rn, get_register(Rn) + get_register(Rm)); UNIMPLEMENTED();
}
} }
} else if (instr->Bits(11, 8) == 8 || }
((instr->Bits(11, 8) & 0b1011) == 0)) {
// vld1 (single element to one lane) void Simulator::DecodeAdvancedSIMDLoadStoreSingleStructureToOneLane(
Instruction* instr) {
int L = instr->Bit(21);
int size = instr->Bits(11, 10); int size = instr->Bits(11, 10);
int N = instr->Bits(9, 8);
int Vd = instr->VFPDRegValue(kDoublePrecision);
int Rn = instr->VnValue();
int Rm = instr->VmValue();
int32_t address = get_register(Rn);
if (L && N == 0) {
// vld1 (single element to one lane)
DCHECK_NE(3, size);
uint64_t dreg; uint64_t dreg;
get_d_register(Vd, &dreg); get_d_register(Vd, &dreg);
switch (size) { switch (size) {
...@@ -5797,22 +5794,9 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( ...@@ -5797,22 +5794,9 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
} }
} }
set_d_register(Vd, &dreg); set_d_register(Vd, &dreg);
AdvancedSIMDElementOrStructureLoadStoreWriteback(Rn, Rm, 1 << size);
// write back } else if (!L && N == 0) {
if (Rm != 15) {
if (Rm == 13) {
set_register(Rn, address);
} else {
set_register(Rn, get_register(Rn) + get_register(Rm));
}
}
} else {
UNIMPLEMENTED();
}
} else if (instr->Bits(21, 20) == 0) {
// TODO(zhin): Refactor this function to follow decoding guide.
// vst1s (single element from one lane). // vst1s (single element from one lane).
int size = instr->Bits(11, 10);
DCHECK_NE(3, size); DCHECK_NE(3, size);
uint64_t dreg; uint64_t dreg;
get_d_register(Vd, &dreg); get_d_register(Vd, &dreg);
...@@ -5843,15 +5827,10 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore( ...@@ -5843,15 +5827,10 @@ void Simulator::DecodeAdvancedSIMDElementOrStructureLoadStore(
UNREACHABLE(); UNREACHABLE();
} }
} }
AdvancedSIMDElementOrStructureLoadStoreWriteback(Rn, Rm, 1 << size);
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
break;
}
default:
UNIMPLEMENTED();
}
} }
void Simulator::DecodeFloatingPointDataProcessing(Instruction* instr) { void Simulator::DecodeFloatingPointDataProcessing(Instruction* instr) {
......
...@@ -332,6 +332,10 @@ class Simulator : public SimulatorBase { ...@@ -332,6 +332,10 @@ class Simulator : public SimulatorBase {
void SoftwareInterrupt(Instruction* instr); void SoftwareInterrupt(Instruction* instr);
void DebugAtNextPC(); void DebugAtNextPC();
// Helper to write back values to register.
void AdvancedSIMDElementOrStructureLoadStoreWriteback(int Rn, int Rm,
int ebytes);
// Stop helper functions. // Stop helper functions.
inline bool isWatchedStop(uint32_t bkpt_code); inline bool isWatchedStop(uint32_t bkpt_code);
inline bool isEnabledStop(uint32_t bkpt_code); inline bool isEnabledStop(uint32_t bkpt_code);
...@@ -391,6 +395,9 @@ class Simulator : public SimulatorBase { ...@@ -391,6 +395,9 @@ class Simulator : public SimulatorBase {
void DecodeAdvancedSIMDDataProcessing(Instruction* instr); void DecodeAdvancedSIMDDataProcessing(Instruction* instr);
void DecodeMemoryHintsAndBarriers(Instruction* instr); void DecodeMemoryHintsAndBarriers(Instruction* instr);
void DecodeAdvancedSIMDElementOrStructureLoadStore(Instruction* instr); void DecodeAdvancedSIMDElementOrStructureLoadStore(Instruction* instr);
void DecodeAdvancedSIMDLoadStoreMultipleStructures(Instruction* instr);
void DecodeAdvancedSIMDLoadSingleStructureToAllLanes(Instruction* instr);
void DecodeAdvancedSIMDLoadStoreSingleStructureToOneLane(Instruction* instr);
void DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr); void DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr);
void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment