Landing for Rodolph Perfetta.

Implementing Math.floor and Math.sqrt for crankshaft.

BUG=none
TEST=none

Code review URL: http://codereview.chromium.org/6250002/

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6298 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ager@chromium.org 2011-01-13 12:21:47 +00:00
parent ba023c5405
commit 0ec74d5829
5 changed files with 50 additions and 8 deletions

View File

@ -167,8 +167,11 @@ struct SwVfpRegister {
struct DwVfpRegister { struct DwVfpRegister {
// d0 has been excluded from allocation. This is following ia32 // d0 has been excluded from allocation. This is following ia32
// where xmm0 is excluded. This should be revisited. // where xmm0 is excluded. This should be revisited.
// Currently d0 is used as a scratch register.
// d1 has also been excluded from allocation to be used as a scratch
// register as well.
static const int kNumRegisters = 16; static const int kNumRegisters = 16;
static const int kNumAllocatableRegisters = 15; static const int kNumAllocatableRegisters = 14;
static int ToAllocationIndex(DwVfpRegister reg) { static int ToAllocationIndex(DwVfpRegister reg) {
ASSERT(reg.code() != 0); ASSERT(reg.code() != 0);
@ -177,13 +180,12 @@ struct DwVfpRegister {
static DwVfpRegister FromAllocationIndex(int index) { static DwVfpRegister FromAllocationIndex(int index) {
ASSERT(index >= 0 && index < kNumAllocatableRegisters); ASSERT(index >= 0 && index < kNumAllocatableRegisters);
return from_code(index + 1); return from_code(index + 2);
} }
static const char* AllocationIndexToString(int index) { static const char* AllocationIndexToString(int index) {
ASSERT(index >= 0 && index < kNumAllocatableRegisters); ASSERT(index >= 0 && index < kNumAllocatableRegisters);
const char* const names[] = { const char* const names[] = {
"d1",
"d2", "d2",
"d3", "d3",
"d4", "d4",

View File

@ -1120,7 +1120,8 @@ LInstruction* LChunkBuilder::DoCallConstantFunction(
LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
BuiltinFunctionId op = instr->op(); BuiltinFunctionId op = instr->op();
LOperand* input = UseRegisterAtStart(instr->value()); LOperand* input = UseRegisterAtStart(instr->value());
LInstruction* result = new LUnaryMathOperation(input); LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
LInstruction* result = new LUnaryMathOperation(input, temp);
switch (op) { switch (op) {
case kMathAbs: case kMathAbs:
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));

View File

@ -621,14 +621,18 @@ class LCmpIDAndBranch: public LCmpID {
class LUnaryMathOperation: public LUnaryOperation { class LUnaryMathOperation: public LUnaryOperation {
public: public:
explicit LUnaryMathOperation(LOperand* value) explicit LUnaryMathOperation(LOperand* value, LOperand* temp)
: LUnaryOperation(value) { } : LUnaryOperation(value), temp_(temp) { }
DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation") DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
virtual void PrintDataTo(StringStream* stream) const; virtual void PrintDataTo(StringStream* stream) const;
BuiltinFunctionId op() const { return hydrogen()->op(); } BuiltinFunctionId op() const { return hydrogen()->op(); }
LOperand* temp() const { return temp_; }
private:
LOperand* temp_;
}; };

View File

@ -1980,12 +1980,44 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
Abort("DoMathFloor unimplemented."); DoubleRegister input = ToDoubleRegister(instr->input());
Register result = ToRegister(instr->result());
Register prev_fpscr = ToRegister(instr->temp());
SwVfpRegister single_scratch = single_scratch0();
Register scratch = scratch0();
// Set custom FPCSR:
// - Set rounding mode to "Round towards Minus Infinity".
// - Clear vfp cumulative exception flags.
// - Make sure Flush-to-zero mode control bit is unset.
__ vmrs(prev_fpscr);
__ bic(scratch, prev_fpscr,
Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
__ orr(scratch, scratch, Operand(kVFPRoundToMinusInfinityBits));
__ vmsr(scratch);
// Convert the argument to an integer.
__ vcvt_s32_f64(single_scratch,
input,
Assembler::FPSCRRounding,
al);
// Retrieve FPSCR and check for vfp exceptions.
__ vmrs(scratch);
// Restore FPSCR
__ vmsr(prev_fpscr);
__ tst(scratch, Operand(kVFPExceptionMask));
DeoptimizeIf(ne, instr->environment());
// Move the result back to general purpose register r0.
__ vmov(result, single_scratch);
} }
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
Abort("DoMathSqrt unimplemented."); DoubleRegister input = ToDoubleRegister(instr->input());
ASSERT(ToDoubleRegister(instr->result()).is(input));
__ vsqrt(input, input);
} }

View File

@ -107,6 +107,9 @@ class LCodeGen BASE_EMBEDDED {
MacroAssembler* masm() const { return masm_; } MacroAssembler* masm() const { return masm_; }
Register scratch0() { return r9; } Register scratch0() { return r9; }
SwVfpRegister single_scratch0() { return s0; }
SwVfpRegister single_scratch1() { return s1; }
DwVfpRegister double_scratch0() { return d1; }
int GetNextEmittedBlock(int block); int GetNextEmittedBlock(int block);
LInstruction* GetNextInstruction(); LInstruction* GetNextInstruction();