Commit 3225b326 authored by jyan's avatar jyan Committed by Commit bot

s390: improve floating point and integer convertion

R=joransiu@ca.ibm.com, bjaideep@ca.ibm.com, michael_dawson@ca.ibm.com

Review-Url: https://codereview.chromium.org/2761953002
Cr-Commit-Position: refs/heads/master@{#43998}
parent fee0961f
This diff is collapsed.
...@@ -330,6 +330,8 @@ ArchOpcode SelectLoadOpcode(Node* node) { ...@@ -330,6 +330,8 @@ ArchOpcode SelectLoadOpcode(Node* node) {
/* Word32 unary op */ \ /* Word32 unary op */ \
V(Word32Clz) \ V(Word32Clz) \
V(Word32Popcnt) \ V(Word32Popcnt) \
V(Float64ExtractLowWord32) \
V(Float64ExtractHighWord32) \
/* Word32 bin op */ \ /* Word32 bin op */ \
V(Int32Add) \ V(Int32Add) \
V(Int32Sub) \ V(Int32Sub) \
...@@ -1379,13 +1381,44 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, ...@@ -1379,13 +1381,44 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector,
} }
#endif #endif
static inline bool TryMatchDoubleConstructFromInsert(
InstructionSelector* selector, Node* node) {
S390OperandGenerator g(selector);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
Node* lo32 = NULL;
Node* hi32 = NULL;
if (node->opcode() == IrOpcode::kFloat64InsertLowWord32) {
lo32 = right;
} else if (node->opcode() == IrOpcode::kFloat64InsertHighWord32) {
hi32 = right;
} else {
return false; // doesn't match
}
if (left->opcode() == IrOpcode::kFloat64InsertLowWord32) {
lo32 = left->InputAt(1);
} else if (left->opcode() == IrOpcode::kFloat64InsertHighWord32) {
hi32 = left->InputAt(1);
} else {
return false; // doesn't match
}
if (!lo32 || !hi32) return false; // doesn't match
selector->Emit(kS390_DoubleConstruct, g.DefineAsRegister(node),
g.UseRegister(hi32), g.UseRegister(lo32));
return true;
}
#define null ([]() { return false; }) #define null ([]() { return false; })
// TODO(john.yan): place kAllowRM where available // TODO(john.yan): place kAllowRM where available
#define FLOAT_UNARY_OP_LIST_32(V) \ #define FLOAT_UNARY_OP_LIST_32(V) \
V(Float32, ChangeFloat32ToFloat64, kS390_Float32ToDouble, \ V(Float32, ChangeFloat32ToFloat64, kS390_Float32ToDouble, \
OperandMode::kAllowRM, null) \ OperandMode::kAllowRM, null) \
V(Float32, BitcastFloat32ToInt32, kS390_BitcastFloat32ToInt32, \ V(Float32, BitcastFloat32ToInt32, kS390_BitcastFloat32ToInt32, \
OperandMode::kNone, null) \ OperandMode::kAllowRM, null) \
V(Float64, TruncateFloat64ToFloat32, kS390_DoubleToFloat32, \ V(Float64, TruncateFloat64ToFloat32, kS390_DoubleToFloat32, \
OperandMode::kNone, null) \ OperandMode::kNone, null) \
V(Float64, TruncateFloat64ToWord32, kArchTruncateDoubleToI, \ V(Float64, TruncateFloat64ToWord32, kArchTruncateDoubleToI, \
...@@ -1419,7 +1452,12 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, ...@@ -1419,7 +1452,12 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector,
V(Float64, Float64RoundTiesAway, kS390_RoundDouble, OperandMode::kNone, \ V(Float64, Float64RoundTiesAway, kS390_RoundDouble, OperandMode::kNone, \
null) \ null) \
V(Float32, Float32Neg, kS390_NegFloat, OperandMode::kNone, null) \ V(Float32, Float32Neg, kS390_NegFloat, OperandMode::kNone, null) \
V(Float64, Float64Neg, kS390_NegDouble, OperandMode::kNone, null) V(Float64, Float64Neg, kS390_NegDouble, OperandMode::kNone, null) \
/* TODO(john.yan): can use kAllowRM */ \
V(Word32, Float64ExtractLowWord32, kS390_DoubleExtractLowWord32, \
OperandMode::kNone, null) \
V(Word32, Float64ExtractHighWord32, kS390_DoubleExtractHighWord32, \
OperandMode::kNone, null)
#define FLOAT_BIN_OP_LIST(V) \ #define FLOAT_BIN_OP_LIST(V) \
V(Float32, Float32Add, kS390_AddFloat, OperandMode::kAllowRM, null) \ V(Float32, Float32Add, kS390_AddFloat, OperandMode::kAllowRM, null) \
...@@ -1511,7 +1549,13 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector, ...@@ -1511,7 +1549,13 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector,
V(Word32, Word32Shl, kS390_ShiftLeft32, Shift32OperandMode, null) \ V(Word32, Word32Shl, kS390_ShiftLeft32, Shift32OperandMode, null) \
V(Word32, Word32Shr, kS390_ShiftRight32, Shift32OperandMode, null) \ V(Word32, Word32Shr, kS390_ShiftRight32, Shift32OperandMode, null) \
V(Word32, Word32Sar, kS390_ShiftRightArith32, Shift32OperandMode, \ V(Word32, Word32Sar, kS390_ShiftRightArith32, Shift32OperandMode, \
[&]() { return TryMatchSignExtInt16OrInt8FromWord32Sar(this, node); }) [&]() { return TryMatchSignExtInt16OrInt8FromWord32Sar(this, node); }) \
V(Word32, Float64InsertLowWord32, kS390_DoubleInsertLowWord32, \
OperandMode::kAllowRRR, \
[&]() -> bool { return TryMatchDoubleConstructFromInsert(this, node); }) \
V(Word32, Float64InsertHighWord32, kS390_DoubleInsertHighWord32, \
OperandMode::kAllowRRR, \
[&]() -> bool { return TryMatchDoubleConstructFromInsert(this, node); })
#define WORD64_UNARY_OP_LIST(V) \ #define WORD64_UNARY_OP_LIST(V) \
V(Word64, Word64Popcnt, kS390_Popcnt64, OperandMode::kNone, null) \ V(Word64, Word64Popcnt, kS390_Popcnt64, OperandMode::kNone, null) \
...@@ -2300,48 +2344,6 @@ bool InstructionSelector::IsTailCallAddressImmediate() { return false; } ...@@ -2300,48 +2344,6 @@ bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
S390OperandGenerator g(this);
Emit(kS390_DoubleExtractLowWord32, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)));
}
void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
S390OperandGenerator g(this);
Emit(kS390_DoubleExtractHighWord32, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)));
}
void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
S390OperandGenerator g(this);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 &&
CanCover(node, left)) {
left = left->InputAt(1);
Emit(kS390_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left),
g.UseRegister(right));
return;
}
Emit(kS390_DoubleInsertLowWord32, g.DefineSameAsFirst(node),
g.UseRegister(left), g.UseRegister(right));
}
void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
S390OperandGenerator g(this);
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 &&
CanCover(node, left)) {
left = left->InputAt(1);
Emit(kS390_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right),
g.UseRegister(left));
return;
}
Emit(kS390_DoubleInsertHighWord32, g.DefineSameAsFirst(node),
g.UseRegister(left), g.UseRegister(right));
}
void InstructionSelector::VisitAtomicLoad(Node* node) { void InstructionSelector::VisitAtomicLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op()); LoadRepresentation load_rep = LoadRepresentationOf(node->op());
S390OperandGenerator g(this); S390OperandGenerator g(this);
......
...@@ -1359,7 +1359,7 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1359,7 +1359,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
} else { } else {
__ LoadComplementRR(result, left); __ LoadComplementRR(result, left);
__ TestIfInt32(result, r0); __ TestIfInt32(result);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow);
} }
#endif #endif
...@@ -1444,7 +1444,7 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1444,7 +1444,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
__ LoadRR(result, left); __ LoadRR(result, left);
__ msgr(result, right); __ msgr(result, right);
} }
__ TestIfInt32(result, r0); __ TestIfInt32(result);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow);
if (instr->hydrogen()->representation().IsSmi()) { if (instr->hydrogen()->representation().IsSmi()) {
__ SmiTag(result); __ SmiTag(result);
...@@ -1452,16 +1452,15 @@ void LCodeGen::DoMulI(LMulI* instr) { ...@@ -1452,16 +1452,15 @@ void LCodeGen::DoMulI(LMulI* instr) {
#else #else
// r0:scratch = scratch * right // r0:scratch = scratch * right
if (instr->hydrogen()->representation().IsSmi()) { if (instr->hydrogen()->representation().IsSmi()) {
__ SmiUntag(scratch, left); __ SmiUntag(result, left);
__ mr_z(r0, right); __ lgfr(result, result);
__ LoadRR(result, scratch); __ msgfr(result, right);
} else { } else {
// r0:scratch = scratch * right // r0:scratch = scratch * right
__ LoadRR(scratch, left); __ lgfr(result, left);
__ mr_z(r0, right); __ msgfr(result, right);
__ LoadRR(result, scratch);
} }
__ TestIfInt32(r0, result, scratch); __ TestIfInt32(result);
DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow); DeoptimizeIf(ne, instr, DeoptimizeReason::kOverflow);
#endif #endif
} }
...@@ -4426,16 +4425,16 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { ...@@ -4426,16 +4425,16 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
if (input->IsStackSlot()) { if (input->IsStackSlot()) {
Register scratch = scratch0(); Register scratch = scratch0();
__ LoadP(scratch, ToMemOperand(input)); __ LoadP(scratch, ToMemOperand(input));
__ ConvertIntToDouble(scratch, ToDoubleRegister(output)); __ ConvertIntToDouble(ToDoubleRegister(output), scratch);
} else { } else {
__ ConvertIntToDouble(ToRegister(input), ToDoubleRegister(output)); __ ConvertIntToDouble(ToDoubleRegister(output), ToRegister(input));
} }
} }
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
LOperand* input = instr->value(); LOperand* input = instr->value();
LOperand* output = instr->result(); LOperand* output = instr->result();
__ ConvertUnsignedIntToDouble(ToRegister(input), ToDoubleRegister(output)); __ ConvertUnsignedIntToDouble(ToDoubleRegister(output), ToRegister(input));
} }
void LCodeGen::DoNumberTagI(LNumberTagI* instr) { void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
...@@ -4511,9 +4510,9 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, LOperand* value, ...@@ -4511,9 +4510,9 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, LOperand* value,
__ SmiUntag(src, dst); __ SmiUntag(src, dst);
__ xilf(src, Operand(HeapNumber::kSignMask)); __ xilf(src, Operand(HeapNumber::kSignMask));
} }
__ ConvertIntToDouble(src, dbl_scratch); __ ConvertIntToDouble(dbl_scratch, src);
} else { } else {
__ ConvertUnsignedIntToDouble(src, dbl_scratch); __ ConvertUnsignedIntToDouble(dbl_scratch, src);
} }
if (FLAG_inline_new) { if (FLAG_inline_new) {
...@@ -4678,7 +4677,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, ...@@ -4678,7 +4677,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
// Smi to double register conversion // Smi to double register conversion
__ bind(&load_smi); __ bind(&load_smi);
// scratch: untagged value of input_reg // scratch: untagged value of input_reg
__ ConvertIntToDouble(scratch, result_reg); __ ConvertIntToDouble(result_reg, scratch);
__ bind(&done); __ bind(&done);
} }
......
...@@ -1596,7 +1596,9 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, ...@@ -1596,7 +1596,9 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ mr_z(scratch1, ip); // R4:R5 = R5 * ip __ mr_z(scratch1, ip); // R4:R5 = R5 * ip
// Check for overflowing the smi range - no overflow if higher 33 bits // Check for overflowing the smi range - no overflow if higher 33 bits
// of the result are identical. // of the result are identical.
__ TestIfInt32(scratch1, scratch2, ip); __ lr(ip, scratch2); // 32 bit load
__ sra(ip, Operand(31));
__ cr_z(ip, scratch1); // 32 bit compare
__ bne(&stub_call); __ bne(&stub_call);
#endif #endif
// Go slow on zero result to handle -0. // Go slow on zero result to handle -0.
......
...@@ -1949,10 +1949,8 @@ void Assembler::clgebr(Condition m3, Condition m4, Register r1, ...@@ -1949,10 +1949,8 @@ void Assembler::clgebr(Condition m3, Condition m4, Register r1,
// Convert to Fixed Logical (32<-F64) // Convert to Fixed Logical (32<-F64)
void Assembler::clfdbr(Condition m3, Condition m4, Register r1, void Assembler::clfdbr(Condition m3, Condition m4, Register r1,
DoubleRegister r2) { DoubleRegister r2) {
DCHECK_EQ(m3, Condition(0));
DCHECK_EQ(m4, Condition(0)); DCHECK_EQ(m4, Condition(0));
rrfe_form(CLFDBR, Condition(0), Condition(0), r1, rrfe_form(CLFDBR, m3, Condition(0), r1, Register::from_code(r2.code()));
Register::from_code(r2.code()));
} }
// Convert to Fixed Logical (32<-F32) // Convert to Fixed Logical (32<-F32)
......
...@@ -87,18 +87,10 @@ void DoubleToIStub::Generate(MacroAssembler* masm) { ...@@ -87,18 +87,10 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ LoadDouble(double_scratch, MemOperand(input_reg, double_offset)); __ LoadDouble(double_scratch, MemOperand(input_reg, double_offset));
// Do fast-path convert from double to int. // Do fast-path convert from double to int.
__ ConvertDoubleToInt64(double_scratch, __ ConvertDoubleToInt64(result_reg, double_scratch);
#if !V8_TARGET_ARCH_S390X
scratch,
#endif
result_reg, d0);
// Test for overflow // Test for overflow
#if V8_TARGET_ARCH_S390X __ TestIfInt32(result_reg);
__ TestIfInt32(result_reg, r0);
#else
__ TestIfInt32(scratch, result_reg, r0);
#endif
__ beq(&fastpath_done, Label::kNear); __ beq(&fastpath_done, Label::kNear);
} }
...@@ -746,7 +738,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -746,7 +738,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
} }
__ ldr(double_scratch, double_base); // Back up base. __ ldr(double_scratch, double_base); // Back up base.
__ LoadImmP(scratch2, Operand(1)); __ LoadImmP(scratch2, Operand(1));
__ ConvertIntToDouble(scratch2, double_result); __ ConvertIntToDouble(double_result, scratch2);
// Get absolute value of exponent. // Get absolute value of exponent.
Label positive_exponent; Label positive_exponent;
...@@ -775,7 +767,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -775,7 +767,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// get 1/double_result: // get 1/double_result:
__ ldr(double_scratch, double_result); __ ldr(double_scratch, double_result);
__ LoadImmP(scratch2, Operand(1)); __ LoadImmP(scratch2, Operand(1));
__ ConvertIntToDouble(scratch2, double_result); __ ConvertIntToDouble(double_result, scratch2);
__ ddbr(double_result, double_scratch); __ ddbr(double_result, double_scratch);
// Test whether result is zero. Bail out to check for subnormal result. // Test whether result is zero. Bail out to check for subnormal result.
...@@ -785,7 +777,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -785,7 +777,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ bne(&done, Label::kNear); __ bne(&done, Label::kNear);
// double_exponent may not containe the exponent value if the input was a // double_exponent may not containe the exponent value if the input was a
// smi. We set it with exponent value before bailing out. // smi. We set it with exponent value before bailing out.
__ ConvertIntToDouble(exponent, double_exponent); __ ConvertIntToDouble(double_exponent, exponent);
// Returning or bailing out. // Returning or bailing out.
__ push(r14); __ push(r14);
......
This diff is collapsed.
...@@ -735,26 +735,24 @@ class MacroAssembler : public Assembler { ...@@ -735,26 +735,24 @@ class MacroAssembler : public Assembler {
// Converts the integer (untagged smi) in |src| to a double, storing // Converts the integer (untagged smi) in |src| to a double, storing
// the result to |dst| // the result to |dst|
void ConvertIntToDouble(Register src, DoubleRegister dst); void ConvertIntToDouble(DoubleRegister dst, Register src);
// Converts the unsigned integer (untagged smi) in |src| to // Converts the unsigned integer (untagged smi) in |src| to
// a double, storing the result to |dst| // a double, storing the result to |dst|
void ConvertUnsignedIntToDouble(Register src, DoubleRegister dst); void ConvertUnsignedIntToDouble(DoubleRegister dst, Register src);
// Converts the integer (untagged smi) in |src| to // Converts the integer (untagged smi) in |src| to
// a float, storing the result in |dst| // a float, storing the result in |dst|
void ConvertIntToFloat(Register src, DoubleRegister dst); void ConvertIntToFloat(DoubleRegister dst, Register src);
// Converts the unsigned integer (untagged smi) in |src| to // Converts the unsigned integer (untagged smi) in |src| to
// a float, storing the result in |dst| // a float, storing the result in |dst|
void ConvertUnsignedIntToFloat(Register src, DoubleRegister dst); void ConvertUnsignedIntToFloat(DoubleRegister dst, Register src);
#if V8_TARGET_ARCH_S390X void ConvertInt64ToFloat(DoubleRegister double_dst, Register src);
void ConvertInt64ToFloat(Register src, DoubleRegister double_dst); void ConvertInt64ToDouble(DoubleRegister double_dst, Register src);
void ConvertInt64ToDouble(Register src, DoubleRegister double_dst); void ConvertUnsignedInt64ToFloat(DoubleRegister double_dst, Register src);
void ConvertUnsignedInt64ToFloat(Register src, DoubleRegister double_dst); void ConvertUnsignedInt64ToDouble(DoubleRegister double_dst, Register src);
void ConvertUnsignedInt64ToDouble(Register src, DoubleRegister double_dst);
#endif
void MovIntToFloat(DoubleRegister dst, Register src); void MovIntToFloat(DoubleRegister dst, Register src);
void MovFloatToInt(Register dst, DoubleRegister src); void MovFloatToInt(Register dst, DoubleRegister src);
...@@ -762,43 +760,36 @@ class MacroAssembler : public Assembler { ...@@ -762,43 +760,36 @@ class MacroAssembler : public Assembler {
void MovInt64ToDouble(DoubleRegister dst, Register src); void MovInt64ToDouble(DoubleRegister dst, Register src);
// Converts the double_input to an integer. Note that, upon return, // Converts the double_input to an integer. Note that, upon return,
// the contents of double_dst will also hold the fixed point representation. // the contents of double_dst will also hold the fixed point representation.
void ConvertFloat32ToInt64(const DoubleRegister double_input, void ConvertFloat32ToInt64(const Register dst,
#if !V8_TARGET_ARCH_S390X const DoubleRegister double_input,
const Register dst_hi,
#endif
const Register dst,
const DoubleRegister double_dst,
FPRoundingMode rounding_mode = kRoundToZero); FPRoundingMode rounding_mode = kRoundToZero);
// Converts the double_input to an integer. Note that, upon return, // Converts the double_input to an integer. Note that, upon return,
// the contents of double_dst will also hold the fixed point representation. // the contents of double_dst will also hold the fixed point representation.
void ConvertDoubleToInt64(const DoubleRegister double_input, void ConvertDoubleToInt64(const Register dst,
#if !V8_TARGET_ARCH_S390X const DoubleRegister double_input,
const Register dst_hi, FPRoundingMode rounding_mode = kRoundToZero);
#endif void ConvertDoubleToInt32(const Register dst,
const Register dst, const DoubleRegister double_dst, const DoubleRegister double_input,
FPRoundingMode rounding_mode = kRoundToZero); FPRoundingMode rounding_mode = kRoundToZero);
void ConvertFloat32ToInt32(const DoubleRegister double_input, void ConvertFloat32ToInt32(const Register result,
const Register dst, const DoubleRegister double_input,
const DoubleRegister double_dst,
FPRoundingMode rounding_mode); FPRoundingMode rounding_mode);
void ConvertFloat32ToUnsignedInt32( void ConvertFloat32ToUnsignedInt32(
const DoubleRegister double_input, const Register dst, const Register result, const DoubleRegister double_input,
const DoubleRegister double_dst,
FPRoundingMode rounding_mode = kRoundToZero); FPRoundingMode rounding_mode = kRoundToZero);
#if V8_TARGET_ARCH_S390X
// Converts the double_input to an unsigned integer. Note that, upon return, // Converts the double_input to an unsigned integer. Note that, upon return,
// the contents of double_dst will also hold the fixed point representation. // the contents of double_dst will also hold the fixed point representation.
void ConvertDoubleToUnsignedInt64( void ConvertDoubleToUnsignedInt64(
const DoubleRegister double_input, const Register dst, const Register dst, const DoubleRegister double_input,
const DoubleRegister double_dst, FPRoundingMode rounding_mode = kRoundToZero);
void ConvertDoubleToUnsignedInt32(
const Register dst, const DoubleRegister double_input,
FPRoundingMode rounding_mode = kRoundToZero); FPRoundingMode rounding_mode = kRoundToZero);
void ConvertFloat32ToUnsignedInt64( void ConvertFloat32ToUnsignedInt64(
const DoubleRegister double_input, const Register dst, const Register result, const DoubleRegister double_input,
const DoubleRegister double_dst,
FPRoundingMode rounding_mode = kRoundToZero); FPRoundingMode rounding_mode = kRoundToZero);
#endif
#if !V8_TARGET_ARCH_S390X #if !V8_TARGET_ARCH_S390X
void ShiftLeftPair(Register dst_low, Register dst_high, Register src_low, void ShiftLeftPair(Register dst_low, Register dst_high, Register src_low,
...@@ -1625,20 +1616,10 @@ class MacroAssembler : public Assembler { ...@@ -1625,20 +1616,10 @@ class MacroAssembler : public Assembler {
void AssertNotSmi(Register object); void AssertNotSmi(Register object);
void AssertSmi(Register object); void AssertSmi(Register object);
#if V8_TARGET_ARCH_S390X inline void TestIfInt32(Register value) {
inline void TestIfInt32(Register value, Register scratch) {
// High bits must be identical to fit into an 32-bit integer // High bits must be identical to fit into an 32-bit integer
lgfr(scratch, value); cgfr(value, value);
CmpP(scratch, value);
} }
#else
inline void TestIfInt32(Register hi_word, Register lo_word,
Register scratch) {
// High bits must be identical to fit into an 32-bit integer
ShiftRightArith(scratch, lo_word, Operand(31));
CmpP(scratch, hi_word);
}
#endif
#if V8_TARGET_ARCH_S390X #if V8_TARGET_ARCH_S390X
// Ensure it is permissable to read/write int value directly from // Ensure it is permissable to read/write int value directly from
......
...@@ -6265,10 +6265,21 @@ EVALUATE(CLFEBR) { ...@@ -6265,10 +6265,21 @@ EVALUATE(CLFEBR) {
EVALUATE(CLFDBR) { EVALUATE(CLFDBR) {
DCHECK_OPCODE(CLFDBR); DCHECK_OPCODE(CLFDBR);
DECODE_RRE_INSTRUCTION(r1, r2); DECODE_RRE_INSTRUCTION(r1, r2);
double r2_val = get_double_from_d_register(r2); double a = get_double_from_d_register(r2);
uint32_t r1_val = static_cast<uint32_t>(r2_val); double n = std::round(a);
uint32_t r1_val = static_cast<uint32_t>(n);
set_low_register(r1, r1_val); set_low_register(r1, r1_val);
SetS390ConvertConditionCode<double>(r2_val, r1_val, UINT32_MAX); if (std::isfinite(a) && a < 0.0) {
DCHECK(n <= 0.0 && std::isfinite(n));
condition_reg_ = (n < 0.0) ? 0x1 : 0x4;
} else if (a == 0.0) {
condition_reg_ = 0x8;
} else if (std::isfinite(a) && a > 0.0) {
DCHECK(n >= 0.0 && std::isfinite(n));
condition_reg_ = (n <= static_cast<double>(UINT32_MAX)) ? 0x2 : 0x1;
} else {
condition_reg_ = 0x1;
}
return length; return length;
} }
......
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