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;
......
......@@ -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