| Index: src/mips/assembler-mips.h
|
| diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
|
| index 2c0633f52df06ec2f78b6a9a7fe3c32f0d975062..38e9537afbac52f452c97722763646e0a3dfc509 100644
|
| --- a/src/mips/assembler-mips.h
|
| +++ b/src/mips/assembler-mips.h
|
| @@ -168,24 +168,36 @@ Register ToRegister(int num);
|
| // Coprocessor register.
|
| struct FPURegister {
|
| static const int kNumRegisters = v8::internal::kNumFPURegisters;
|
| - // f0 has been excluded from allocation. This is following ia32
|
| - // where xmm0 is excluded.
|
| - static const int kNumAllocatableRegisters = 15;
|
| +
|
| + // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
|
| + // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
|
| + // number of Double regs (64-bit regs, or FPU-reg-pairs).
|
| +
|
| + // A few double registers are reserved: one as a scratch register and one to
|
| + // hold 0.0.
|
| + // f28: 0.0
|
| + // f30: scratch register.
|
| + static const int kNumReservedRegisters = 2;
|
| + static const int kNumAllocatableRegisters = kNumRegisters / 2 -
|
| + kNumReservedRegisters;
|
| +
|
|
|
| static int ToAllocationIndex(FPURegister reg) {
|
| - ASSERT(reg.code() != 0);
|
| ASSERT(reg.code() % 2 == 0);
|
| - return (reg.code() / 2) - 1;
|
| + ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
|
| + ASSERT(reg.is_valid());
|
| + return (reg.code() / 2);
|
| }
|
|
|
| static FPURegister FromAllocationIndex(int index) {
|
| ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
| - return from_code((index + 1) * 2);
|
| + return from_code(index * 2);
|
| }
|
|
|
| static const char* AllocationIndexToString(int index) {
|
| ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
| const char* const names[] = {
|
| + "f0",
|
| "f2",
|
| "f4",
|
| "f6",
|
| @@ -198,9 +210,7 @@ struct FPURegister {
|
| "f20",
|
| "f22",
|
| "f24",
|
| - "f26",
|
| - "f28",
|
| - "f30"
|
| + "f26"
|
| };
|
| return names[index];
|
| }
|
| @@ -212,6 +222,23 @@ struct FPURegister {
|
|
|
| bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegisters ; }
|
| bool is(FPURegister creg) const { return code_ == creg.code_; }
|
| + FPURegister low() const {
|
| + // Find low reg of a Double-reg pair, which is the reg itself.
|
| + ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
|
| + FPURegister reg;
|
| + reg.code_ = code_;
|
| + ASSERT(reg.is_valid());
|
| + return reg;
|
| + }
|
| + FPURegister high() const {
|
| + // Find high reg of a Doubel-reg pair, which is reg + 1.
|
| + ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
|
| + FPURegister reg;
|
| + reg.code_ = code_ + 1;
|
| + ASSERT(reg.is_valid());
|
| + return reg;
|
| + }
|
| +
|
| int code() const {
|
| ASSERT(is_valid());
|
| return code_;
|
| @@ -228,9 +255,19 @@ struct FPURegister {
|
| int code_;
|
| };
|
|
|
| +// V8 now supports the O32 ABI, and the FPU Registers are organized as 32
|
| +// 32-bit registers, f0 through f31. When used as 'double' they are used
|
| +// in pairs, starting with the even numbered register. So a double operation
|
| +// on f0 really uses f0 and f1.
|
| +// (Modern mips hardware also supports 32 64-bit registers, via setting
|
| +// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI,
|
| +// but it is not in common use. Someday we will want to support this in v8.)
|
| +
|
| +// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
|
| typedef FPURegister DoubleRegister;
|
| +typedef FPURegister FloatRegister;
|
|
|
| -const FPURegister no_creg = { -1 };
|
| +const FPURegister no_freg = { -1 };
|
|
|
| const FPURegister f0 = { 0 }; // Return value in hard float mode.
|
| const FPURegister f1 = { 1 };
|
| @@ -265,6 +302,8 @@ const FPURegister f29 = { 29 };
|
| const FPURegister f30 = { 30 };
|
| const FPURegister f31 = { 31 };
|
|
|
| +const FPURegister kDoubleRegZero = f28;
|
| +
|
| // FPU (coprocessor 1) control registers.
|
| // Currently only FCSR (#31) is implemented.
|
| struct FPUControlRegister {
|
| @@ -331,6 +370,10 @@ class MemOperand : public Operand {
|
| explicit MemOperand(Register rn, int32_t offset = 0);
|
| int32_t offset() const { return offset_; }
|
|
|
| + bool OffsetIsInt16Encodable() const {
|
| + return is_int16(offset_);
|
| + }
|
| +
|
| private:
|
| int32_t offset_;
|
|
|
| @@ -504,6 +547,8 @@ class Assembler : public AssemblerBase {
|
| static Address target_address_at(Address pc);
|
| static void set_target_address_at(Address pc, Address target);
|
|
|
| + static void JumpLabelToJumpRegister(Address pc);
|
| +
|
| // This sets the branch destination (which gets loaded at the call address).
|
| // This is for calls and branches within generated code.
|
| inline static void set_target_at(Address instruction_payload,
|
| @@ -534,9 +579,13 @@ class Assembler : public AssemblerBase {
|
| static const int kExternalTargetSize = 0 * kInstrSize;
|
|
|
| // Number of consecutive instructions used to store 32bit constant.
|
| - // Used in RelocInfo::target_address_address() function to tell serializer
|
| - // address of the instruction that follows LUI/ORI instruction pair.
|
| - static const int kInstructionsFor32BitConstant = 2;
|
| + // Before jump-optimizations, this constant was used in
|
| + // RelocInfo::target_address_address() function to tell serializer address of
|
| + // the instruction that follows LUI/ORI instruction pair. Now, with new jump
|
| + // optimization, where jump-through-register instruction that usually
|
| + // follows LUI/ORI pair is substituted with J/JAL, this constant equals
|
| + // to 3 instructions (LUI+ORI+J/JAL/JR/JALR).
|
| + static const int kInstructionsFor32BitConstant = 3;
|
|
|
| // Distance between the instruction referring to the address of the call
|
| // target and the return address.
|
| @@ -623,6 +672,8 @@ class Assembler : public AssemblerBase {
|
| void jal(int32_t target);
|
| void jalr(Register rs, Register rd = ra);
|
| void jr(Register target);
|
| + void j_or_jr(int32_t target, Register rs);
|
| + void jal_or_jalr(int32_t target, Register rs);
|
|
|
|
|
| //-------Data-processing-instructions---------
|
| @@ -892,6 +943,10 @@ class Assembler : public AssemblerBase {
|
| static bool IsLui(Instr instr);
|
| static bool IsOri(Instr instr);
|
|
|
| + static bool IsJal(Instr instr);
|
| + static bool IsJr(Instr instr);
|
| + static bool IsJalr(Instr instr);
|
| +
|
| static bool IsNop(Instr instr, unsigned int type);
|
| static bool IsPop(Instr instr);
|
| static bool IsPush(Instr instr);
|
| @@ -976,6 +1031,8 @@ class Assembler : public AssemblerBase {
|
| return internal_trampoline_exception_;
|
| }
|
|
|
| + void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
|
| +
|
| bool is_trampoline_emitted() const {
|
| return trampoline_emitted_;
|
| }
|
|
|