PPC: Fix UIM on disassembler and the simulator

A few fixes are applied in this CL:

1- Instructions which use UIM in V8 only use bits 16 to 19 inclusive.
2- get_simd_register is set to return a reference and not a copy.
3- On vector extract and insert instructions, UIM could be used
to select specific bytes as starting point which may not reflect a lane.
Vector splat uses UIM as a lane selector which remains
unchanged in this CL.

Change-Id: Ieb43afb977dac11d3ea10a2f265c2823f64457e3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3011166
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#75618}
This commit is contained in:
Milad Fa 2021-07-07 11:36:26 -04:00 committed by V8 LUCI CQ
parent d38f225375
commit 12b2a8702f
3 changed files with 33 additions and 15 deletions

View File

@ -285,7 +285,7 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
return 3;
}
case 'U': { // UIM
int32_t value = instr->Bits(20, 16);
uint8_t value = instr->Bits(19, 16);
out_buffer_pos_ +=
base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
return 3;

View File

@ -4051,7 +4051,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
break;
}
#define VSPLT(type) \
uint32_t uim = instr->Bits(20, 16); \
uint8_t uim = instr->Bits(19, 16); \
int vrt = instr->RTValue(); \
int vrb = instr->RBValue(); \
type value = get_simd_register_by_lane<type>(vrb, uim); \
@ -4094,11 +4094,11 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
break;
}
#undef VSPLTI
#define VINSERT(type, element) \
uint32_t uim = static_cast<uint32_t>(instr->Bits(20, 16)) / sizeof(type); \
int vrt = instr->RTValue(); \
int vrb = instr->RBValue(); \
set_simd_register_by_lane<type>( \
#define VINSERT(type, element) \
uint8_t uim = instr->Bits(19, 16); \
int vrt = instr->RTValue(); \
int vrb = instr->RBValue(); \
set_simd_register_bytes<type>( \
vrt, uim, get_simd_register_by_lane<type>(vrb, element));
case VINSERTD: {
VINSERT(int64_t, 0)
@ -4117,13 +4117,13 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
break;
}
#undef VINSERT
#define VEXTRACT(type, element) \
uint32_t uim = static_cast<uint32_t>(instr->Bits(20, 16)) / sizeof(type); \
int vrt = instr->RTValue(); \
int vrb = instr->RBValue(); \
type val = get_simd_register_by_lane<type>(vrb, uim); \
set_simd_register_by_lane<uint64_t>(vrt, 0, 0); \
set_simd_register_by_lane<uint64_t>(vrt, 1, 0); \
#define VEXTRACT(type, element) \
uint8_t uim = instr->Bits(19, 16); \
int vrt = instr->RTValue(); \
int vrb = instr->RBValue(); \
type val = get_simd_register_bytes<type>(vrb, uim); \
set_simd_register_by_lane<uint64_t>(vrt, 0, 0); \
set_simd_register_by_lane<uint64_t>(vrt, 1, 0); \
set_simd_register_by_lane<type>(vrt, element, val);
case VEXTRACTD: {
VEXTRACT(uint64_t, 0)

View File

@ -430,6 +430,16 @@ class Simulator : public SimulatorBase {
return (reinterpret_cast<T*>(&simd_registers_[reg]))[lane];
}
template <class T>
T get_simd_register_bytes(int reg, int byte_from) {
// Byte location is reversed in memory.
int from = kSimd128Size - 1 - (byte_from + sizeof(T) - 1);
void* src = bit_cast<uint8_t*>(&simd_registers_[reg]) + from;
T dst;
memcpy(&dst, src, sizeof(T));
return dst;
}
template <class T>
void set_simd_register_by_lane(int reg, int lane, const T& value,
bool force_ibm_lane_numbering = true) {
@ -443,7 +453,15 @@ class Simulator : public SimulatorBase {
(reinterpret_cast<T*>(&simd_registers_[reg]))[lane] = value;
}
simdr_t get_simd_register(int reg) { return simd_registers_[reg]; }
template <class T>
void set_simd_register_bytes(int reg, int byte_from, T value) {
// Byte location is reversed in memory.
int from = kSimd128Size - 1 - (byte_from + sizeof(T) - 1);
void* dst = bit_cast<uint8_t*>(&simd_registers_[reg]) + from;
memcpy(dst, &value, sizeof(T));
}
simdr_t& get_simd_register(int reg) { return simd_registers_[reg]; }
void set_simd_register(int reg, const simdr_t& value) {
simd_registers_[reg] = value;