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) { ...@@ -1484,8 +1484,7 @@ void Assembler::mcrfs(CRegister cr, FPSCRBit bit) {
void Assembler::mfcr(Register dst) { emit(EXT2 | MFCR | dst.code() * B21); } void Assembler::mfcr(Register dst) { emit(EXT2 | MFCR | dst.code() * B21); }
void Assembler::mtcr(Register src) { void Assembler::mtcrf(Register src, uint8_t FXM) {
uint8_t FXM = 0xFF;
emit(MTCRF | src.code() * B21 | FXM * B12); emit(MTCRF | src.code() * B21 | FXM * B12);
} }
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
......
...@@ -922,7 +922,7 @@ class Assembler : public AssemblerBase { ...@@ -922,7 +922,7 @@ class Assembler : public AssemblerBase {
void mtxer(Register src); void mtxer(Register src);
void mcrfs(CRegister cr, FPSCRBit bit); void mcrfs(CRegister cr, FPSCRBit bit);
void mfcr(Register dst); void mfcr(Register dst);
void mtcr(Register src); void mtcrf(Register src, uint8_t FXM);
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
void mffprd(Register dst, DoubleRegister src); void mffprd(Register dst, DoubleRegister src);
void mffprwz(Register dst, DoubleRegister src); void mffprwz(Register dst, DoubleRegister src);
......
...@@ -2997,12 +2997,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -2997,12 +2997,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kPPC_V128AnyTrue: { case kPPC_V128AnyTrue: {
Simd128Register src = i.InputSimd128Register(0); Simd128Register src = i.InputSimd128Register(0);
Register dst = i.OutputRegister(); Register dst = i.OutputRegister();
constexpr uint8_t fxm = 0x2; // field mask.
constexpr int bit_number = 24; constexpr int bit_number = 24;
__ li(r0, Operand(0)); __ li(r0, Operand(0));
__ li(ip, Operand(1)); __ li(ip, Operand(1));
// Check if both lanes are 0, if so then return false. // Check if both lanes are 0, if so then return false.
__ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg); __ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg);
__ mtcr(r0); // Clear cr. __ mtcrf(r0, fxm); // Clear cr6.
__ vcmpequd(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC); __ vcmpequd(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC);
__ isel(dst, r0, ip, bit_number); __ isel(dst, r0, ip, bit_number);
break; break;
...@@ -3010,12 +3011,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -3010,12 +3011,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#define SIMD_ALL_TRUE(opcode) \ #define SIMD_ALL_TRUE(opcode) \
Simd128Register src = i.InputSimd128Register(0); \ Simd128Register src = i.InputSimd128Register(0); \
Register dst = i.OutputRegister(); \ Register dst = i.OutputRegister(); \
constexpr uint8_t fxm = 0x2; /* field mask. */ \
constexpr int bit_number = 24; \ constexpr int bit_number = 24; \
__ li(r0, Operand(0)); \ __ li(r0, Operand(0)); \
__ li(ip, Operand(1)); \ __ li(ip, Operand(1)); \
/* Check if all lanes > 0, if not then return false.*/ \ /* Check if all lanes > 0, if not then return false.*/ \
__ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg); \ __ vxor(kScratchSimd128Reg, kScratchSimd128Reg, kScratchSimd128Reg); \
__ mtcr(r0); /* Clear cr.*/ \ __ mtcrf(r0, fxm); /* Clear cr6.*/ \
__ opcode(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC); \ __ opcode(kScratchSimd128Reg, src, kScratchSimd128Reg, SetRC); \
__ isel(dst, ip, r0, bit_number); __ isel(dst, ip, r0, bit_number);
case kPPC_I64x2AllTrue: { case kPPC_I64x2AllTrue: {
......
...@@ -265,6 +265,11 @@ int Decoder::FormatOption(Instruction* instr, const char* format) { ...@@ -265,6 +265,11 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
return 6; 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 case 'U': { // UIM
int32_t value = instr->Bits(20, 16); int32_t value = instr->Bits(20, 16);
out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
...@@ -1071,7 +1076,7 @@ void Decoder::DecodeExt2(Instruction* instr) { ...@@ -1071,7 +1076,7 @@ void Decoder::DecodeExt2(Instruction* instr) {
return; return;
} }
case MTCRF: { case MTCRF: {
Format(instr, "mtcr 'rs"); Format(instr, "mtcrf 'FXM, 'rs");
return; return;
} }
#endif #endif
......
...@@ -3880,12 +3880,25 @@ void Simulator::ExecuteGeneric(Instruction* instr) { ...@@ -3880,12 +3880,25 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
return; return;
} }
case MTCRF: { case MTCRF: {
// This only simulates mtcr.
int rs = instr->RSValue(); int rs = instr->RSValue();
uint32_t rs_val = static_cast<int32_t>(get_register(rs));
uint8_t fxm = instr->Bits(19, 12); uint8_t fxm = instr->Bits(19, 12);
DCHECK_EQ(fxm, 0xFF); uint8_t bit_mask = 0x80;
USE(fxm); const int field_bit_count = 4;
condition_reg_ = static_cast<int32_t>(get_register(rs)); 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; break;
} }
// Vector instructions. // 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