Commit 3dcb0d77 authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

PPC: only clear cr field 6 under simd AnyTrue and AllTrue

From PPC ABI:

>The condition code register fields CR0, CR1, CR5, CR6,
 and CR7 are volatile. The condition code register fields
 CR2, CR3, and CR4 are nonvolatile.

We can safely clear Cr field 6 without the need to save its
content first. Clearing the entire CR register will cause
crashes if it's not restored properly.

Change-Id: I854f5631294f56f542b1a6f4e23dd7dbcf000d7d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2810802Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#73837}
parent 0d5f6a49
......@@ -1484,8 +1484,7 @@ void Assembler::mcrfs(CRegister cr, FPSCRBit bit) {
void Assembler::mfcr(Register dst) { emit(EXT2 | MFCR | dst.code() * B21); }
void Assembler::mtcr(Register src) {
uint8_t FXM = 0xFF;
void Assembler::mtcrf(Register src, uint8_t FXM) {
emit(MTCRF | src.code() * B21 | FXM * B12);
}
#if V8_TARGET_ARCH_PPC64
......
......@@ -922,7 +922,7 @@ class Assembler : public AssemblerBase {
void mtxer(Register src);
void mcrfs(CRegister cr, FPSCRBit bit);
void mfcr(Register dst);
void mtcr(Register src);
void mtcrf(Register src, uint8_t FXM);
#if V8_TARGET_ARCH_PPC64
void mffprd(Register dst, DoubleRegister src);
void mffprwz(Register dst, DoubleRegister src);
......
......@@ -2997,12 +2997,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kPPC_V128AnyTrue: {
Simd128Register src = i.InputSimd128Register(0);
Register dst = i.OutputRegister();
constexpr uint8_t fxm = 0x2; // field mask.
constexpr int bit_number = 24;
__ li(r0, Operand(0));
__ li(ip, Operand(1));
// Check if both lanes are 0, if so then return false.
__ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg);
__ mtcr(r0); // Clear cr.
__ mtcrf(r0, fxm); // Clear cr6.
__ vcmpequd(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC);
__ isel(dst, r0, ip, bit_number);
break;
......@@ -3010,12 +3011,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#define SIMD_ALL_TRUE(opcode) \
Simd128Register src = i.InputSimd128Register(0); \
Register dst = i.OutputRegister(); \
constexpr uint8_t fxm = 0x2; /* field mask. */ \
constexpr int bit_number = 24; \
__ li(r0, Operand(0)); \
__ li(ip, Operand(1)); \
/* Check if all lanes > 0, if not then return false.*/ \
__ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg); \
__ mtcr(r0); /* Clear cr.*/ \
__ mtcrf(r0, fxm); /* Clear cr6.*/ \
__ opcode(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC); \
__ isel(dst, ip, r0, bit_number);
case kPPC_I64x2AllTrue: {
......
......@@ -265,6 +265,11 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
return 6;
}
case 'F': { // FXM
uint8_t value = instr->Bits(19, 12);
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
return 3;
}
case 'U': { // UIM
int32_t value = instr->Bits(20, 16);
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
......@@ -1071,7 +1076,7 @@ void Decoder::DecodeExt2(Instruction* instr) {
return;
}
case MTCRF: {
Format(instr, "mtcr 'rs");
Format(instr, "mtcrf 'FXM, 'rs");
return;
}
#endif
......
......@@ -3880,12 +3880,25 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
return;
}
case MTCRF: {
// This only simulates mtcr.
int rs = instr->RSValue();
uint32_t rs_val = static_cast<int32_t>(get_register(rs));
uint8_t fxm = instr->Bits(19, 12);
DCHECK_EQ(fxm, 0xFF);
USE(fxm);
condition_reg_ = static_cast<int32_t>(get_register(rs));
uint8_t bit_mask = 0x80;
const int field_bit_count = 4;
const int max_field_index = 7;
uint32_t result = 0;
for (int i = 0; i <= max_field_index; i++) {
result <<= field_bit_count;
uint32_t source = condition_reg_;
if ((bit_mask & fxm) != 0) {
// take it from rs.
source = rs_val;
}
result |= ((source << i * field_bit_count) >> i * field_bit_count) >>
(max_field_index - i) * field_bit_count;
bit_mask >>= 1;
}
condition_reg_ = result;
break;
}
// Vector instructions.
......
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