PPC [simd]: Implement vperm, splat imm and load reverse on Sim

Also fixed the disassembler to include 10th bit of instruction.

Change-Id: Idc6659a8a9d6a291b68537bae533a32970a4441d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2757567
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Reviewed-by: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/master@{#73382}
This commit is contained in:
Milad Fa 2021-03-12 13:44:32 -05:00 committed by Commit Bot
parent 052db704e0
commit 544185dbef
2 changed files with 45 additions and 1 deletions

View File

@ -790,7 +790,7 @@ void Decoder::DecodeExt2(Instruction* instr) {
}
// ?? are all of these xo_form?
switch (EXT2 | (instr->BitField(9, 1))) {
switch (EXT2 | (instr->BitField(10, 1))) {
case CMP: {
#if V8_TARGET_ARCH_PPC64
if (instr->Bit(21)) {
@ -1056,6 +1056,10 @@ void Decoder::DecodeExt2(Instruction* instr) {
Format(instr, "mtvsrwz 'Xt, 'ra");
return;
}
case LDBRX: {
Format(instr, "ldbrx 'rt, 'ra, 'rb");
return;
}
#endif
}

View File

@ -2924,6 +2924,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
}
break;
}
case LDBRX: {
int rt = instr->RTValue();
int ra = instr->RAValue();
int rb = instr->RBValue();
intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
intptr_t rb_val = get_register(rb);
intptr_t result = __builtin_bswap64(ReadDW(ra_val + rb_val));
set_register(rt, result);
break;
}
case STDX:
case STDUX: {
int rs = instr->RSValue();
@ -3911,6 +3921,14 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
VSPLT(int8_t)
break;
}
case XXSPLTIB: {
int8_t imm8 = instr->Bits(18, 11);
int t = instr->RTValue();
FOR_EACH_LANE(i, int8_t) {
set_simd_register_by_lane<int8_t>(t, i, imm8);
}
break;
}
#undef VSPLT
#define VINSERT(type, element) \
uint32_t uim = static_cast<uint32_t>(instr->Bits(20, 16)) / sizeof(type); \
@ -4463,6 +4481,28 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
}
break;
}
case VPERM: {
int vrt = instr->RTValue();
int vra = instr->RAValue();
int vrb = instr->RBValue();
int vrc = instr->RCValue();
int8_t temp[kSimd128Size] = {0};
FOR_EACH_LANE(i, int8_t) {
int8_t lane_num = get_simd_register_by_lane<int8_t>(vrc, i);
// Get the five least significant bits.
lane_num = (lane_num << 3) >> 3;
int reg = vra;
if (lane_num >= kSimd128Size) {
lane_num = lane_num - kSimd128Size;
reg = vrb;
}
temp[i] = get_simd_register_by_lane<int8_t>(reg, lane_num);
}
FOR_EACH_LANE(i, int8_t) {
set_simd_register_by_lane<int8_t>(vrt, i, temp[i]);
}
break;
}
#undef FOR_EACH_LANE
#undef DECODE_VX_INSTRUCTION
default: {