Commit bc5e7fc3 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [turbofan] Implemented the TruncateFloat64ToUint64 TurboFan operator.

Port f6e689ce

Original commit message:
    The TruncateFloat64ToUint64 operator converts a float64 to an uint64 using
    round-to-zero rounding mode (truncate). If the input value is outside uint64
    range, then the result depends on the architecture.

R=ahaas@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1460093002

Cr-Commit-Position: refs/heads/master@{#32181}
parent 8ced019a
......@@ -1137,6 +1137,13 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
i.OutputRegister(), kScratchDoubleReg);
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
#if V8_TARGET_ARCH_PPC64
case kPPC_DoubleToUint64:
__ ConvertDoubleToUnsignedInt64(i.InputDoubleRegister(0),
i.OutputRegister(), kScratchDoubleReg);
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
#endif
case kPPC_DoubleToFloat32:
ASSEMBLE_FLOAT_UNOP_RC(frsp);
break;
......
......@@ -88,6 +88,7 @@ namespace compiler {
V(PPC_DoubleToInt32) \
V(PPC_DoubleToUint32) \
V(PPC_DoubleToInt64) \
V(PPC_DoubleToUint64) \
V(PPC_DoubleToFloat32) \
V(PPC_DoubleExtractLowWord32) \
V(PPC_DoubleExtractHighWord32) \
......
......@@ -933,7 +933,7 @@ void InstructionSelector::VisitTruncateFloat64ToInt64(Node* node) {
void InstructionSelector::VisitTruncateFloat64ToUint64(Node* node) {
UNIMPLEMENTED();
VisitRR(this, kPPC_DoubleToUint64, node);
}
......
......@@ -2193,6 +2193,18 @@ void Assembler::fctidz(const DoubleRegister frt, const DoubleRegister frb,
}
void Assembler::fctidu(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc) {
emit(EXT4 | FCTIDU | frt.code() * B21 | frb.code() * B11 | rc);
}
void Assembler::fctiduz(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc) {
emit(EXT4 | FCTIDUZ | frt.code() * B21 | frb.code() * B11 | rc);
}
void Assembler::fsel(const DoubleRegister frt, const DoubleRegister fra,
const DoubleRegister frc, const DoubleRegister frb,
RCBit rc) {
......
......@@ -1060,6 +1060,10 @@ class Assembler : public AssemblerBase {
RCBit rc = LeaveRC);
void fctidz(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc = LeaveRC);
void fctidu(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc = LeaveRC);
void fctiduz(const DoubleRegister frt, const DoubleRegister frb,
RCBit rc = LeaveRC);
void fsel(const DoubleRegister frt, const DoubleRegister fra,
const DoubleRegister frc, const DoubleRegister frb,
RCBit rc = LeaveRC);
......
......@@ -275,25 +275,27 @@ enum OpcodeExt4 {
FMADD = 29 << 1, // Floating Multiply-Add
// Bits 10-1
FCMPU = 0 << 1, // Floating Compare Unordered
FRSP = 12 << 1, // Floating-Point Rounding
FCTIW = 14 << 1, // Floating Convert to Integer Word X-form
FCTIWZ = 15 << 1, // Floating Convert to Integer Word with Round to Zero
FNEG = 40 << 1, // Floating Negate
MCRFS = 64 << 1, // Move to Condition Register from FPSCR
FMR = 72 << 1, // Floating Move Register
MTFSFI = 134 << 1, // Move to FPSCR Field Immediate
FABS = 264 << 1, // Floating Absolute Value
FRIN = 392 << 1, // Floating Round to Integer Nearest
FRIZ = 424 << 1, // Floating Round to Integer Toward Zero
FRIP = 456 << 1, // Floating Round to Integer Plus
FRIM = 488 << 1, // Floating Round to Integer Minus
MFFS = 583 << 1, // move from FPSCR x-form
MTFSF = 711 << 1, // move to FPSCR fields XFL-form
FCFID = 846 << 1, // Floating convert from integer doubleword
FCTID = 814 << 1, // Floating convert from integer doubleword
FCTIDZ = 815 << 1, // Floating convert from integer doubleword
FCFIDU = 974 << 1 // Floating convert from integer doubleword unsigned
FCMPU = 0 << 1, // Floating Compare Unordered
FRSP = 12 << 1, // Floating-Point Rounding
FCTIW = 14 << 1, // Floating Convert to Integer Word X-form
FCTIWZ = 15 << 1, // Floating Convert to Integer Word with Round to Zero
FNEG = 40 << 1, // Floating Negate
MCRFS = 64 << 1, // Move to Condition Register from FPSCR
FMR = 72 << 1, // Floating Move Register
MTFSFI = 134 << 1, // Move to FPSCR Field Immediate
FABS = 264 << 1, // Floating Absolute Value
FRIN = 392 << 1, // Floating Round to Integer Nearest
FRIZ = 424 << 1, // Floating Round to Integer Toward Zero
FRIP = 456 << 1, // Floating Round to Integer Plus
FRIM = 488 << 1, // Floating Round to Integer Minus
MFFS = 583 << 1, // move from FPSCR x-form
MTFSF = 711 << 1, // move to FPSCR fields XFL-form
FCTID = 814 << 1, // Floating convert to integer doubleword
FCTIDZ = 815 << 1, // ^^^ with round toward zero
FCFID = 846 << 1, // Floating convert from integer doubleword
FCTIDU = 942 << 1, // Floating convert to integer doubleword unsigned
FCTIDUZ = 943 << 1, // ^^^ with round toward zero
FCFIDU = 974 << 1 // Floating convert from integer doubleword unsigned
};
enum OpcodeExt5 {
......
......@@ -961,6 +961,14 @@ void Decoder::DecodeExt4(Instruction* instr) {
Format(instr, "fctidz 'Dt, 'Db");
break;
}
case FCTIDU: {
Format(instr, "fctidu 'Dt, 'Db");
break;
}
case FCTIDUZ: {
Format(instr, "fctiduz 'Dt, 'Db");
break;
}
case FCTIW: {
Format(instr, "fctiw'. 'Dt, 'Db");
break;
......
......@@ -715,6 +715,22 @@ void MacroAssembler::ConvertDoubleToInt64(const DoubleRegister double_input,
dst, double_dst);
}
#if V8_TARGET_ARCH_PPC64
void MacroAssembler::ConvertDoubleToUnsignedInt64(
const DoubleRegister double_input, const Register dst,
const DoubleRegister double_dst, FPRoundingMode rounding_mode) {
if (rounding_mode == kRoundToZero) {
fctiduz(double_dst, double_input);
} else {
SetRoundingMode(rounding_mode);
fctidu(double_dst, double_input);
ResetRoundingMode();
}
MovDoubleToInt64(dst, double_dst);
}
#endif
void MacroAssembler::LoadConstantPoolPointerRegisterFromCodeTargetAddress(
Register code_target_address) {
......
......@@ -403,6 +403,15 @@ class MacroAssembler : public Assembler {
const Register dst, const DoubleRegister double_dst,
FPRoundingMode rounding_mode = kRoundToZero);
#if V8_TARGET_ARCH_PPC64
// Converts the double_input to an unsigned integer. Note that, upon return,
// the contents of double_dst will also hold the fixed point representation.
void ConvertDoubleToUnsignedInt64(
const DoubleRegister double_input, const Register dst,
const DoubleRegister double_dst,
FPRoundingMode rounding_mode = kRoundToZero);
#endif
// Generates function and stub prologue code.
void StubPrologue(int prologue_offset = 0);
void Prologue(bool code_pre_aging, int prologue_offset = 0);
......
......@@ -2959,6 +2959,56 @@ void Simulator::ExecuteExt4(Instruction* instr) {
set_d_register(frt, frt_val);
return;
}
case FCTIDU: {
int frt = instr->RTValue();
int frb = instr->RBValue();
double frb_val = get_double_from_d_register(frb);
uint64_t frt_val;
uint64_t kMinLongLong = 0;
uint64_t kMaxLongLong = kMinLongLong - 1;
if (frb_val > kMaxLongLong) {
frt_val = kMaxLongLong;
} else if (frb_val < kMinLongLong) {
frt_val = kMinLongLong;
} else {
switch (fp_condition_reg_ & kFPRoundingModeMask) {
case kRoundToZero:
frt_val = (uint64_t)frb_val;
break;
case kRoundToPlusInf:
frt_val = (uint64_t)std::ceil(frb_val);
break;
case kRoundToMinusInf:
frt_val = (uint64_t)std::floor(frb_val);
break;
default:
frt_val = (uint64_t)frb_val;
UNIMPLEMENTED(); // Not used by V8.
break;
}
}
set_d_register(frt, frt_val);
return;
}
case FCTIDUZ: {
int frt = instr->RTValue();
int frb = instr->RBValue();
double frb_val = get_double_from_d_register(frb);
uint64_t frt_val;
uint64_t kMinLongLong = 0;
uint64_t kMaxLongLong = kMinLongLong - 1;
if (frb_val > kMaxLongLong) {
frt_val = kMaxLongLong;
} else if (frb_val < kMinLongLong) {
frt_val = kMinLongLong;
} else {
frt_val = (uint64_t)frb_val;
}
set_d_register(frt, frt_val);
return;
}
case FCTIW:
case FCTIWZ: {
int frt = instr->RTValue();
......
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