Commit 22d5ac91 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

s390x: move Double/FloatMin/Max to TurboAssembler

Change-Id: I982c0040b95a1495630034871389843e5248b221
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2572961
Commit-Queue: Junliang Yan <junyan@redhat.com>
Reviewed-by: 's avatarMilad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#71612}
parent 65d2c4b4
......@@ -34,6 +34,177 @@
namespace v8 {
namespace internal {
void TurboAssembler::DoubleMax(DoubleRegister result_reg,
DoubleRegister left_reg,
DoubleRegister right_reg) {
Label check_zero, return_left, return_right, return_nan, done;
cdbr(left_reg, right_reg);
bunordered(&return_nan, Label::kNear);
beq(&check_zero);
bge(&return_left, Label::kNear);
b(&return_right, Label::kNear);
bind(&check_zero);
lzdr(kDoubleRegZero);
cdbr(left_reg, kDoubleRegZero);
/* left == right != 0. */
bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For max we want logical-and of sign bit: (L + R) */
ldr(result_reg, left_reg);
adbr(result_reg, right_reg);
b(&done, Label::kNear);
bind(&return_nan);
/* If left or right are NaN, adbr propagates the appropriate one.*/
adbr(left_reg, right_reg);
b(&return_left, Label::kNear);
bind(&return_right);
if (right_reg != result_reg) {
ldr(result_reg, right_reg);
}
b(&done, Label::kNear);
bind(&return_left);
if (left_reg != result_reg) {
ldr(result_reg, left_reg);
}
bind(&done);
}
void TurboAssembler::DoubleMin(DoubleRegister result_reg,
DoubleRegister left_reg,
DoubleRegister right_reg) {
Label check_zero, return_left, return_right, return_nan, done;
cdbr(left_reg, right_reg);
bunordered(&return_nan, Label::kNear);
beq(&check_zero);
ble(&return_left, Label::kNear);
b(&return_right, Label::kNear);
bind(&check_zero);
lzdr(kDoubleRegZero);
cdbr(left_reg, kDoubleRegZero);
/* left == right != 0. */
bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For min we want logical-or of sign bit: -(-L + -R) */
lcdbr(left_reg, left_reg);
ldr(result_reg, left_reg);
if (left_reg == right_reg) {
adbr(result_reg, right_reg);
} else {
sdbr(result_reg, right_reg);
}
lcdbr(result_reg, result_reg);
b(&done, Label::kNear);
bind(&return_nan);
/* If left or right are NaN, adbr propagates the appropriate one.*/
adbr(left_reg, right_reg);
b(&return_left, Label::kNear);
bind(&return_right);
if (right_reg != result_reg) {
ldr(result_reg, right_reg);
}
b(&done, Label::kNear);
bind(&return_left);
if (left_reg != result_reg) {
ldr(result_reg, left_reg);
}
bind(&done);
}
void TurboAssembler::FloatMax(DoubleRegister result_reg,
DoubleRegister left_reg,
DoubleRegister right_reg) {
Label check_zero, return_left, return_right, return_nan, done;
cebr(left_reg, right_reg);
bunordered(&return_nan, Label::kNear);
beq(&check_zero);
bge(&return_left, Label::kNear);
b(&return_right, Label::kNear);
bind(&check_zero);
lzdr(kDoubleRegZero);
cebr(left_reg, kDoubleRegZero);
/* left == right != 0. */
bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For max we want logical-and of sign bit: (L + R) */
ldr(result_reg, left_reg);
aebr(result_reg, right_reg);
b(&done, Label::kNear);
bind(&return_nan);
/* If left or right are NaN, aebr propagates the appropriate one.*/
aebr(left_reg, right_reg);
b(&return_left, Label::kNear);
bind(&return_right);
if (right_reg != result_reg) {
ldr(result_reg, right_reg);
}
b(&done, Label::kNear);
bind(&return_left);
if (left_reg != result_reg) {
ldr(result_reg, left_reg);
}
bind(&done);
}
void TurboAssembler::FloatMin(DoubleRegister result_reg,
DoubleRegister left_reg,
DoubleRegister right_reg) {
Label check_zero, return_left, return_right, return_nan, done;
cebr(left_reg, right_reg);
bunordered(&return_nan, Label::kNear);
beq(&check_zero);
ble(&return_left, Label::kNear);
b(&return_right, Label::kNear);
bind(&check_zero);
lzdr(kDoubleRegZero);
cebr(left_reg, kDoubleRegZero);
/* left == right != 0. */
bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For min we want logical-or of sign bit: -(-L + -R) */
lcebr(left_reg, left_reg);
ldr(result_reg, left_reg);
if (left_reg == right_reg) {
aebr(result_reg, right_reg);
} else {
sebr(result_reg, right_reg);
}
lcebr(result_reg, result_reg);
b(&done, Label::kNear);
bind(&return_nan);
/* If left or right are NaN, aebr propagates the appropriate one.*/
aebr(left_reg, right_reg);
b(&return_left, Label::kNear);
bind(&return_right);
if (right_reg != result_reg) {
ldr(result_reg, right_reg);
}
b(&done, Label::kNear);
bind(&return_left);
if (left_reg != result_reg) {
ldr(result_reg, left_reg);
}
bind(&done);
}
int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
Register exclusion1,
Register exclusion2,
......
......@@ -130,6 +130,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
public:
using TurboAssemblerBase::TurboAssemblerBase;
void DoubleMax(DoubleRegister result_reg, DoubleRegister left_reg,
DoubleRegister right_reg);
void DoubleMin(DoubleRegister result_reg, DoubleRegister left_reg,
DoubleRegister right_reg);
void FloatMax(DoubleRegister result_reg, DoubleRegister left_reg,
DoubleRegister right_reg);
void FloatMin(DoubleRegister result_reg, DoubleRegister left_reg,
DoubleRegister right_reg);
void LoadFromConstantsTable(Register destination,
int constant_index) override;
void LoadRootRegisterOffset(Register destination, intptr_t offset) override;
......
......@@ -643,185 +643,6 @@ static inline int AssembleUnaryOp(Instruction* instr, _R _r, _M _m, _I _i) {
__ MovFromFloatResult(i.OutputDoubleRegister()); \
} while (0)
#define ASSEMBLE_DOUBLE_MAX() \
do { \
DoubleRegister left_reg = i.InputDoubleRegister(0); \
DoubleRegister right_reg = i.InputDoubleRegister(1); \
DoubleRegister result_reg = i.OutputDoubleRegister(); \
Label check_zero, return_left, return_right, return_nan, done; \
__ cdbr(left_reg, right_reg); \
__ bunordered(&return_nan, Label::kNear); \
__ beq(&check_zero); \
__ bge(&return_left, Label::kNear); \
__ b(&return_right, Label::kNear); \
\
__ bind(&check_zero); \
__ lzdr(kDoubleRegZero); \
__ cdbr(left_reg, kDoubleRegZero); \
/* left == right != 0. */ \
__ bne(&return_left, Label::kNear); \
/* At this point, both left and right are either 0 or -0. */ \
/* N.B. The following works because +0 + -0 == +0 */ \
/* For max we want logical-and of sign bit: (L + R) */ \
__ ldr(result_reg, left_reg); \
__ adbr(result_reg, right_reg); \
__ b(&done, Label::kNear); \
\
__ bind(&return_nan); \
/* If left or right are NaN, adbr propagates the appropriate one.*/ \
__ adbr(left_reg, right_reg); \
__ b(&return_left, Label::kNear); \
\
__ bind(&return_right); \
if (right_reg != result_reg) { \
__ ldr(result_reg, right_reg); \
} \
__ b(&done, Label::kNear); \
\
__ bind(&return_left); \
if (left_reg != result_reg) { \
__ ldr(result_reg, left_reg); \
} \
__ bind(&done); \
} while (0)
#define ASSEMBLE_DOUBLE_MIN() \
do { \
DoubleRegister left_reg = i.InputDoubleRegister(0); \
DoubleRegister right_reg = i.InputDoubleRegister(1); \
DoubleRegister result_reg = i.OutputDoubleRegister(); \
Label check_zero, return_left, return_right, return_nan, done; \
__ cdbr(left_reg, right_reg); \
__ bunordered(&return_nan, Label::kNear); \
__ beq(&check_zero); \
__ ble(&return_left, Label::kNear); \
__ b(&return_right, Label::kNear); \
\
__ bind(&check_zero); \
__ lzdr(kDoubleRegZero); \
__ cdbr(left_reg, kDoubleRegZero); \
/* left == right != 0. */ \
__ bne(&return_left, Label::kNear); \
/* At this point, both left and right are either 0 or -0. */ \
/* N.B. The following works because +0 + -0 == +0 */ \
/* For min we want logical-or of sign bit: -(-L + -R) */ \
__ lcdbr(left_reg, left_reg); \
__ ldr(result_reg, left_reg); \
if (left_reg == right_reg) { \
__ adbr(result_reg, right_reg); \
} else { \
__ sdbr(result_reg, right_reg); \
} \
__ lcdbr(result_reg, result_reg); \
__ b(&done, Label::kNear); \
\
__ bind(&return_nan); \
/* If left or right are NaN, adbr propagates the appropriate one.*/ \
__ adbr(left_reg, right_reg); \
__ b(&return_left, Label::kNear); \
\
__ bind(&return_right); \
if (right_reg != result_reg) { \
__ ldr(result_reg, right_reg); \
} \
__ b(&done, Label::kNear); \
\
__ bind(&return_left); \
if (left_reg != result_reg) { \
__ ldr(result_reg, left_reg); \
} \
__ bind(&done); \
} while (0)
#define ASSEMBLE_FLOAT_MAX() \
do { \
DoubleRegister left_reg = i.InputDoubleRegister(0); \
DoubleRegister right_reg = i.InputDoubleRegister(1); \
DoubleRegister result_reg = i.OutputDoubleRegister(); \
Label check_zero, return_left, return_right, return_nan, done; \
__ cebr(left_reg, right_reg); \
__ bunordered(&return_nan, Label::kNear); \
__ beq(&check_zero); \
__ bge(&return_left, Label::kNear); \
__ b(&return_right, Label::kNear); \
\
__ bind(&check_zero); \
__ lzdr(kDoubleRegZero); \
__ cebr(left_reg, kDoubleRegZero); \
/* left == right != 0. */ \
__ bne(&return_left, Label::kNear); \
/* At this point, both left and right are either 0 or -0. */ \
/* N.B. The following works because +0 + -0 == +0 */ \
/* For max we want logical-and of sign bit: (L + R) */ \
__ ldr(result_reg, left_reg); \
__ aebr(result_reg, right_reg); \
__ b(&done, Label::kNear); \
\
__ bind(&return_nan); \
/* If left or right are NaN, aebr propagates the appropriate one.*/ \
__ aebr(left_reg, right_reg); \
__ b(&return_left, Label::kNear); \
\
__ bind(&return_right); \
if (right_reg != result_reg) { \
__ ldr(result_reg, right_reg); \
} \
__ b(&done, Label::kNear); \
\
__ bind(&return_left); \
if (left_reg != result_reg) { \
__ ldr(result_reg, left_reg); \
} \
__ bind(&done); \
} while (0)
#define ASSEMBLE_FLOAT_MIN() \
do { \
DoubleRegister left_reg = i.InputDoubleRegister(0); \
DoubleRegister right_reg = i.InputDoubleRegister(1); \
DoubleRegister result_reg = i.OutputDoubleRegister(); \
Label check_zero, return_left, return_right, return_nan, done; \
__ cebr(left_reg, right_reg); \
__ bunordered(&return_nan, Label::kNear); \
__ beq(&check_zero); \
__ ble(&return_left, Label::kNear); \
__ b(&return_right, Label::kNear); \
\
__ bind(&check_zero); \
__ lzdr(kDoubleRegZero); \
__ cebr(left_reg, kDoubleRegZero); \
/* left == right != 0. */ \
__ bne(&return_left, Label::kNear); \
/* At this point, both left and right are either 0 or -0. */ \
/* N.B. The following works because +0 + -0 == +0 */ \
/* For min we want logical-or of sign bit: -(-L + -R) */ \
__ lcebr(left_reg, left_reg); \
__ ldr(result_reg, left_reg); \
if (left_reg == right_reg) { \
__ aebr(result_reg, right_reg); \
} else { \
__ sebr(result_reg, right_reg); \
} \
__ lcebr(result_reg, result_reg); \
__ b(&done, Label::kNear); \
\
__ bind(&return_nan); \
/* If left or right are NaN, aebr propagates the appropriate one.*/ \
__ aebr(left_reg, right_reg); \
__ b(&return_left, Label::kNear); \
\
__ bind(&return_right); \
if (right_reg != result_reg) { \
__ ldr(result_reg, right_reg); \
} \
__ b(&done, Label::kNear); \
\
__ bind(&return_left); \
if (left_reg != result_reg) { \
__ ldr(result_reg, left_reg); \
} \
__ bind(&done); \
} while (0)
//
// Only MRI mode for these instructions available
#define ASSEMBLE_LOAD_FLOAT(asm_instr) \
......@@ -2133,16 +1954,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ lcgr(i.OutputRegister(), i.InputRegister(0));
break;
case kS390_MaxFloat:
ASSEMBLE_FLOAT_MAX();
__ FloatMax(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
break;
case kS390_MaxDouble:
ASSEMBLE_DOUBLE_MAX();
__ DoubleMax(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
break;
case kS390_MinFloat:
ASSEMBLE_FLOAT_MIN();
__ FloatMin(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
break;
case kS390_MinDouble:
ASSEMBLE_DOUBLE_MIN();
__ DoubleMin(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
break;
case kS390_AbsDouble:
__ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
......
......@@ -88,175 +88,6 @@ inline MemOperand GetStackSlot(uint32_t offset) {
inline MemOperand GetInstanceOperand() { return GetStackSlot(kInstanceOffset); }
#define __ assm->
inline void FloatMax(LiftoffAssembler* assm, DoubleRegister result_reg,
DoubleRegister left_reg, DoubleRegister right_reg) {
Label check_nan_left, check_zero, return_left, return_right, done;
__ cebr(left_reg, right_reg);
__ bunordered(&check_nan_left, Label::kNear);
__ beq(&check_zero);
__ bge(&return_left, Label::kNear);
__ b(&return_right, Label::kNear);
__ bind(&check_zero);
__ lzer(kDoubleRegZero);
__ cebr(left_reg, kDoubleRegZero);
/* left == right != 0. */
__ bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For max we want logical-and of sign bit: (L + R) */
__ ldr(result_reg, left_reg);
__ aebr(result_reg, right_reg);
__ b(&done, Label::kNear);
__ bind(&check_nan_left);
__ cebr(left_reg, left_reg);
// left == NaN.
__ bunordered(&return_left, Label::kNear);
__ bind(&return_right);
if (right_reg != result_reg) {
__ ldr(result_reg, right_reg);
}
__ b(&done, Label::kNear);
__ bind(&return_left);
if (left_reg != result_reg) {
__ ldr(result_reg, left_reg);
}
__ bind(&done);
}
inline void FloatMin(LiftoffAssembler* assm, DoubleRegister result_reg,
DoubleRegister left_reg, DoubleRegister right_reg) {
Label check_nan_left, check_zero, return_left, return_right, done;
__ cebr(left_reg, right_reg);
__ bunordered(&check_nan_left, Label::kNear);
__ beq(&check_zero);
__ ble(&return_left, Label::kNear);
__ b(&return_right, Label::kNear);
__ bind(&check_zero);
__ lzer(kDoubleRegZero);
__ cebr(left_reg, kDoubleRegZero);
// left == right != 0.
__ bne(&return_left, Label::kNear);
// At this point, both left and right are either 0 or -0. */
// N.B. The following works because +0 + -0 == +0 */
// For min we want logical-or of sign bit: -(-L + -R) */
__ lcebr(left_reg, left_reg);
__ ldr(result_reg, left_reg);
if (left_reg == right_reg) {
__ aebr(result_reg, right_reg);
} else {
__ sebr(result_reg, right_reg);
}
__ lcebr(result_reg, result_reg);
__ b(&done, Label::kNear);
__ bind(&check_nan_left);
__ cebr(left_reg, left_reg);
/* left == NaN. */
__ bunordered(&return_left, Label::kNear);
__ bind(&return_right);
if (right_reg != result_reg) {
__ ldr(result_reg, right_reg);
}
__ b(&done, Label::kNear);
__ bind(&return_left);
if (left_reg != result_reg) {
__ ldr(result_reg, left_reg);
}
__ bind(&done);
}
inline void DoubleMax(LiftoffAssembler* assm, DoubleRegister result_reg,
DoubleRegister left_reg, DoubleRegister right_reg) {
Label check_nan_left, check_zero, return_left, return_right, done;
__ cdbr(left_reg, right_reg);
__ bunordered(&check_nan_left, Label::kNear);
__ beq(&check_zero);
__ bge(&return_left, Label::kNear);
__ b(&return_right, Label::kNear);
__ bind(&check_zero);
__ lzdr(kDoubleRegZero);
__ cdbr(left_reg, kDoubleRegZero);
/* left == right != 0. */
__ bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For max we want logical-and of sign bit: (L + R) */
__ ldr(result_reg, left_reg);
__ adbr(result_reg, right_reg);
__ b(&done, Label::kNear);
__ bind(&check_nan_left);
__ cdbr(left_reg, left_reg);
/* left == NaN. */
__ bunordered(&return_left, Label::kNear);
__ bind(&return_right);
if (right_reg != result_reg) {
__ ldr(result_reg, right_reg);
}
__ b(&done, Label::kNear);
__ bind(&return_left);
if (left_reg != result_reg) {
__ ldr(result_reg, left_reg);
}
__ bind(&done);
}
inline void DoubleMin(LiftoffAssembler* assm, DoubleRegister result_reg,
DoubleRegister left_reg, DoubleRegister right_reg) {
Label check_nan_left, check_zero, return_left, return_right, done;
__ cdbr(left_reg, right_reg);
__ bunordered(&check_nan_left, Label::kNear);
__ beq(&check_zero);
__ ble(&return_left, Label::kNear);
__ b(&return_right, Label::kNear);
__ bind(&check_zero);
__ lzdr(kDoubleRegZero);
__ cdbr(left_reg, kDoubleRegZero);
/* left == right != 0. */
__ bne(&return_left, Label::kNear);
/* At this point, both left and right are either 0 or -0. */
/* N.B. The following works because +0 + -0 == +0 */
/* For min we want logical-or of sign bit: -(-L + -R) */
__ lcdbr(left_reg, left_reg);
__ ldr(result_reg, left_reg);
if (left_reg == right_reg) {
__ adbr(result_reg, right_reg);
} else {
__ sdbr(result_reg, right_reg);
}
__ lcdbr(result_reg, result_reg);
__ b(&done, Label::kNear);
__ bind(&check_nan_left);
__ cdbr(left_reg, left_reg);
/* left == NaN. */
__ bunordered(&return_left, Label::kNear);
__ bind(&return_right);
if (right_reg != result_reg) {
__ ldr(result_reg, right_reg);
}
__ b(&done, Label::kNear);
__ bind(&return_left);
if (left_reg != result_reg) {
__ ldr(result_reg, left_reg);
}
__ bind(&done);
}
#undef __
} // namespace liftoff
......@@ -631,7 +462,7 @@ void LiftoffAssembler::emit_f64_min(DoubleRegister dst, DoubleRegister lhs,
vfmin(dst, lhs, rhs, Condition(1), Condition(8), Condition(3));
return;
}
liftoff::DoubleMin(this, dst, lhs, rhs);
DoubleMin(dst, lhs, rhs);
}
void LiftoffAssembler::emit_f32_min(DoubleRegister dst, DoubleRegister lhs,
......@@ -640,7 +471,7 @@ void LiftoffAssembler::emit_f32_min(DoubleRegister dst, DoubleRegister lhs,
vfmin(dst, lhs, rhs, Condition(1), Condition(8), Condition(2));
return;
}
liftoff::FloatMin(this, dst, lhs, rhs);
FloatMin(dst, lhs, rhs);
}
void LiftoffAssembler::emit_f64_max(DoubleRegister dst, DoubleRegister lhs,
......@@ -649,7 +480,7 @@ void LiftoffAssembler::emit_f64_max(DoubleRegister dst, DoubleRegister lhs,
vfmax(dst, lhs, rhs, Condition(1), Condition(8), Condition(3));
return;
}
liftoff::DoubleMax(this, dst, lhs, rhs);
DoubleMax(dst, lhs, rhs);
}
void LiftoffAssembler::emit_f32_max(DoubleRegister dst, DoubleRegister lhs,
......@@ -658,7 +489,7 @@ void LiftoffAssembler::emit_f32_max(DoubleRegister dst, DoubleRegister lhs,
vfmax(dst, lhs, rhs, Condition(1), Condition(8), Condition(2));
return;
}
liftoff::FloatMax(this, dst, lhs, rhs);
FloatMax(dst, lhs, rhs);
}
void LiftoffAssembler::emit_i32_divs(Register dst, Register lhs, Register rhs,
......
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