Commit b78b0bf9 authored by jyan's avatar jyan Committed by Commit bot

S390: [builtins] Introduce proper Float64Log1p, Float64Atan and Float64Atan2 operators.

Port 7ceed92a
Port 89d8c57b

Original commit message:

    Import base::ieee754::atan() and base::ieee754::atan2() from fdlibm and
    introduce Float64Atan and Float64Atan2 TurboFan operators based on those,
    similar to what we already did for Float64Log and Float64Log1p. Rewrite
    Math.atan() and Math.atan2() as TurboFan builtin and use the operators
    to also inline Math.atan() and Math.atan2() into optimized TurboFan functions.

    Import base::ieee754::log1p() from fdlibm and introduce a Float64Log1p
    TurboFan operator based on that, similar to what we do for Float64Log.
    Rewrite Math.log1p() as TurboFan builtin and use that operator to also
    inline Math.log1p() into optimized TurboFan functions.

    Also unify the handling of the special IEEE 754 functions somewhat in
    the TurboFan backends. At some point we can hopefully express this
    completely in the InstructionSelector (once we have an idea what to do
    with the ST(0) return issue on IA-32/X87).

    Drive-by-fix: Add some more test coverage for the log function.

R=bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com, bjaideep@ca.ibm.com
BUG=

Review-Url: https://codereview.chromium.org/2064783002
Cr-Commit-Position: refs/heads/master@{#36946}
parent 03bf4dc0
......@@ -385,6 +385,35 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
__ MovFromFloatResult(i.OutputDoubleRegister()); \
} while (0)
#define ASSEMBLE_IEEE754_UNOP(name) \
do { \
/* TODO(bmeurer): We should really get rid of this special instruction, */ \
/* and generate a CallAddress instruction instead. */ \
FrameScope scope(masm(), StackFrame::MANUAL); \
__ PrepareCallCFunction(0, 1, kScratchReg); \
__ MovToFloatParameter(i.InputDoubleRegister(0)); \
__ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
0, 1); \
/* Move the result in the double result register. */ \
__ MovFromFloatResult(i.OutputDoubleRegister()); \
DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
#define ASSEMBLE_IEEE754_BINOP(name) \
do { \
/* TODO(bmeurer): We should really get rid of this special instruction, */ \
/* and generate a CallAddress instruction instead. */ \
FrameScope scope(masm(), StackFrame::MANUAL); \
__ PrepareCallCFunction(0, 2, kScratchReg); \
__ MovToFloatParameters(i.InputDoubleRegister(0), \
i.InputDoubleRegister(1)); \
__ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
0, 2); \
/* Move the result in the double result register. */ \
__ MovFromFloatResult(i.OutputDoubleRegister()); \
DCHECK_EQ(LeaveRC, i.OutputRCBit()); \
} while (0)
#define ASSEMBLE_FLOAT_MAX(double_scratch_reg, general_scratch_reg) \
do { \
Label ge, done; \
......@@ -1219,18 +1248,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kS390_ModDouble:
ASSEMBLE_FLOAT_MODULO();
break;
case kS390_LogDouble: {
// TODO(bmeurer): We should really get rid of this special instruction,
// and generate a CallAddress instruction instead.
FrameScope scope(masm(), StackFrame::MANUAL);
__ PrepareCallCFunction(0, 1, kScratchReg);
__ MovToFloatParameter(i.InputDoubleRegister(0));
__ CallCFunction(ExternalReference::ieee754_log_function(isolate()), 0,
1);
// Move the result in the double result register.
__ MovFromFloatResult(i.OutputDoubleRegister());
case kIeee754Float64Atan:
ASSEMBLE_IEEE754_UNOP(atan);
break;
case kIeee754Float64Atan2:
ASSEMBLE_IEEE754_BINOP(atan2);
break;
case kIeee754Float64Log:
ASSEMBLE_IEEE754_UNOP(log);
break;
case kIeee754Float64Log1p:
ASSEMBLE_IEEE754_UNOP(log1p);
break;
}
case kS390_Neg:
__ LoadComplementRR(i.OutputRegister(), i.InputRegister(0));
break;
......
......@@ -61,7 +61,6 @@ namespace compiler {
V(S390_ModU32) \
V(S390_ModU64) \
V(S390_ModDouble) \
V(S390_LogDouble) \
V(S390_Neg) \
V(S390_NegDouble) \
V(S390_SqrtFloat) \
......
......@@ -62,7 +62,6 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_ModU32:
case kS390_ModU64:
case kS390_ModDouble:
case kS390_LogDouble:
case kS390_Neg:
case kS390_NegDouble:
case kS390_SqrtFloat:
......
......@@ -1191,15 +1191,23 @@ void InstructionSelector::VisitFloat64Abs(Node* node) {
VisitRR(this, kS390_AbsDouble, node);
}
void InstructionSelector::VisitFloat64Log(Node* node) {
void InstructionSelector::VisitFloat32Sqrt(Node* node) {
VisitRR(this, kS390_SqrtFloat, node);
}
void InstructionSelector::VisitFloat64Ieee754Unop(Node* node,
InstructionCode opcode) {
S390OperandGenerator g(this);
Emit(kS390_LogDouble, g.DefineAsFixed(node, d1),
g.UseFixed(node->InputAt(0), d1))
Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0))
->MarkAsCall();
}
void InstructionSelector::VisitFloat32Sqrt(Node* node) {
VisitRR(this, kS390_SqrtFloat, node);
void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
InstructionCode opcode) {
S390OperandGenerator g(this);
Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0),
g.UseFixed(node->InputAt(1), d2))
->MarkAsCall();
}
void InstructionSelector::VisitFloat64Sqrt(Node* node) {
......
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