Index: src/mips64/assembler-mips64.h |
diff --git a/src/mips/assembler-mips.h b/src/mips64/assembler-mips64.h |
similarity index 92% |
copy from src/mips/assembler-mips.h |
copy to src/mips64/assembler-mips64.h |
index 2ba3ef7166f2f9023adb77c5d128dd12a51768bc..395ab77d8ace9116fb290d140da7a67d6ab468eb 100644 |
--- a/src/mips/assembler-mips.h |
+++ b/src/mips64/assembler-mips64.h |
@@ -37,9 +37,8 @@ |
#define V8_MIPS_ASSEMBLER_MIPS_H_ |
#include <stdio.h> |
- |
#include "src/assembler.h" |
-#include "src/mips/constants-mips.h" |
+#include "src/mips64/constants-mips64.h" |
#include "src/serialize.h" |
namespace v8 { |
@@ -74,19 +73,9 @@ namespace internal { |
struct Register { |
static const int kNumRegisters = v8::internal::kNumRegisters; |
static const int kMaxNumAllocatableRegisters = 14; // v0 through t6 and cp. |
- static const int kSizeInBytes = 4; |
+ static const int kSizeInBytes = 8; |
static const int kCpRegister = 23; // cp (s7) is the 23rd register. |
-#if defined(V8_TARGET_LITTLE_ENDIAN) |
- static const int kMantissaOffset = 0; |
- static const int kExponentOffset = 4; |
-#elif defined(V8_TARGET_BIG_ENDIAN) |
- static const int kMantissaOffset = 4; |
- static const int kExponentOffset = 0; |
-#else |
-#error Unknown endianness |
-#endif |
- |
inline static int NumAllocatableRegisters(); |
static int ToAllocationIndex(Register reg) { |
@@ -113,13 +102,13 @@ struct Register { |
"a1", |
"a2", |
"a3", |
+ "a4", |
+ "a5", |
+ "a6", |
+ "a7", |
"t0", |
"t1", |
"t2", |
- "t3", |
- "t4", |
- "t5", |
- "t6", |
"s7", |
}; |
return names[index]; |
@@ -162,16 +151,16 @@ REGISTER(a0, 4); |
REGISTER(a1, 5); |
REGISTER(a2, 6); |
REGISTER(a3, 7); |
-// t0 - t9: Can be used without reservation, act as temporary registers and are |
-// allowed to be destroyed by subroutines. |
-REGISTER(t0, 8); |
-REGISTER(t1, 9); |
-REGISTER(t2, 10); |
-REGISTER(t3, 11); |
-REGISTER(t4, 12); |
-REGISTER(t5, 13); |
-REGISTER(t6, 14); |
-REGISTER(t7, 15); |
+// a4 - a7 t0 - t3: Can be used without reservation, act as temporary registers |
+// and are allowed to be destroyed by subroutines. |
+REGISTER(a4, 8); |
+REGISTER(a5, 9); |
+REGISTER(a6, 10); |
+REGISTER(a7, 11); |
+REGISTER(t0, 12); |
+REGISTER(t1, 13); |
+REGISTER(t2, 14); |
+REGISTER(t3, 15); |
// s0 - s7: Subroutine register variables. Subroutines that write to these |
// registers must restore their values before exiting so that the caller can |
// expect the values to be preserved. |
@@ -238,6 +227,7 @@ struct FPURegister { |
bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; } |
bool is(FPURegister creg) const { return code_ == creg.code_; } |
FPURegister low() const { |
+ // TODO(plind): Create ASSERT for FR=0 mode. This usage suspect for FR=1. |
// 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; |
@@ -246,6 +236,7 @@ struct FPURegister { |
return reg; |
} |
FPURegister high() const { |
+ // TODO(plind): Create ASSERT for FR=0 mode. This usage illegal in FR=1. |
// Find high reg of a Doubel-reg pair, which is reg + 1. |
ASSERT(code_ % 2 == 0); // Specified Double reg must be even. |
FPURegister reg; |
@@ -275,7 +266,7 @@ struct FPURegister { |
// 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, |
+// (privileged) 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. |
@@ -356,13 +347,14 @@ const FPUControlRegister FCSR = { kFCSRRegister }; |
// ----------------------------------------------------------------------------- |
// Machine instruction Operands. |
- |
+const int kSmiShift = kSmiTagSize + kSmiShiftSize; |
+const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; |
// Class Operand represents a shifter operand in data processing instructions. |
class Operand BASE_EMBEDDED { |
public: |
// Immediate. |
- INLINE(explicit Operand(int32_t immediate, |
- RelocInfo::Mode rmode = RelocInfo::NONE32)); |
+ INLINE(explicit Operand(int64_t immediate, |
+ RelocInfo::Mode rmode = RelocInfo::NONE64)); |
INLINE(explicit Operand(const ExternalReference& f)); |
INLINE(explicit Operand(const char* s)); |
INLINE(explicit Operand(Object** opp)); |
@@ -376,16 +368,16 @@ class Operand BASE_EMBEDDED { |
// Return true if this is a register operand. |
INLINE(bool is_reg() const); |
- inline int32_t immediate() const { |
+ inline int64_t immediate() const { |
ASSERT(!is_reg()); |
- return imm32_; |
+ return imm64_; |
} |
Register rm() const { return rm_; } |
private: |
Register rm_; |
- int32_t imm32_; // Valid if rm_ == no_reg. |
+ int64_t imm64_; // Valid if rm_ == no_reg. |
RelocInfo::Mode rmode_; |
friend class Assembler; |
@@ -403,8 +395,8 @@ class MemOperand : public Operand { |
offset_zero = 0 |
}; |
- explicit MemOperand(Register rn, int32_t offset = 0); |
- explicit MemOperand(Register rn, int32_t unit, int32_t multiplier, |
+ explicit MemOperand(Register rn, int64_t offset = 0); |
+ explicit MemOperand(Register rn, int64_t unit, int64_t multiplier, |
OffsetAddend offset_addend = offset_zero); |
int32_t offset() const { return offset_; } |
@@ -470,7 +462,7 @@ class Assembler : public AssemblerBase { |
ASSERT((o & 3) == 0); // Assert the offset is aligned. |
return o >> 2; |
} |
- uint32_t jump_address(Label* L); |
+ uint64_t jump_address(Label* L); |
// Puts a labels target address at the given position. |
// The high 8 bits are set to zero. |
@@ -521,7 +513,7 @@ class Assembler : public AssemblerBase { |
inline static void deserialization_set_special_target_at( |
Address instruction_payload, Code* code, Address target) { |
set_target_address_at( |
- instruction_payload - kInstructionsFor32BitConstant * kInstrSize, |
+ instruction_payload - kInstructionsFor64BitConstant * kInstrSize, |
code, |
target); |
} |
@@ -540,7 +532,7 @@ class Assembler : public AssemblerBase { |
// a target is resolved and written. |
static const int kSpecialTargetSize = 0; |
- // Number of consecutive instructions used to store 32bit constant. |
+ // Number of consecutive instructions used to store 32bit/64bit constant. |
// 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 |
@@ -548,10 +540,11 @@ class Assembler : public AssemblerBase { |
// 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; |
+ static const int kInstructionsFor64BitConstant = 5; |
// Distance between the instruction referring to the address of the call |
// target and the return address. |
- static const int kCallTargetAddressOffset = 4 * kInstrSize; |
+ static const int kCallTargetAddressOffset = 6 * kInstrSize; |
// Distance between start of patched return sequence and the emitted address |
// to jump to. |
@@ -565,12 +558,12 @@ class Assembler : public AssemblerBase { |
// register. |
static const int kPcLoadDelta = 4; |
- static const int kPatchDebugBreakSlotReturnOffset = 4 * kInstrSize; |
+ static const int kPatchDebugBreakSlotReturnOffset = 6 * kInstrSize; |
// Number of instructions used for the JS return sequence. The constant is |
// used by the debugger to patch the JS return sequence. |
static const int kJSReturnSequenceInstructions = 7; |
- static const int kDebugBreakSlotInstructions = 4; |
+ static const int kDebugBreakSlotInstructions = 6; |
static const int kDebugBreakSlotLength = |
kDebugBreakSlotInstructions * kInstrSize; |
@@ -638,12 +631,12 @@ class Assembler : public AssemblerBase { |
// instead of using the Label* version. |
// Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. |
- void j(int32_t target); |
- void jal(int32_t target); |
+ void j(int64_t target); |
+ void jal(int64_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); |
+ void j_or_jr(int64_t target, Register rs); |
+ void jal_or_jalr(int64_t target, Register rs); |
// -------Data-processing-instructions--------- |
@@ -656,8 +649,15 @@ class Assembler : public AssemblerBase { |
void div(Register rs, Register rt); |
void divu(Register rs, Register rt); |
void mul(Register rd, Register rs, Register rt); |
+ void daddu(Register rd, Register rs, Register rt); |
+ void dsubu(Register rd, Register rs, Register rt); |
+ void dmult(Register rs, Register rt); |
+ void dmultu(Register rs, Register rt); |
+ void ddiv(Register rs, Register rt); |
+ void ddivu(Register rs, Register rt); |
void addiu(Register rd, Register rs, int32_t j); |
+ void daddiu(Register rd, Register rs, int32_t j); |
// Logical. |
void and_(Register rd, Register rs, Register rt); |
@@ -682,6 +682,17 @@ class Assembler : public AssemblerBase { |
void srav(Register rt, Register rd, Register rs); |
void rotr(Register rd, Register rt, uint16_t sa); |
void rotrv(Register rd, Register rt, Register rs); |
+ void dsll(Register rd, Register rt, uint16_t sa); |
+ void dsllv(Register rd, Register rt, Register rs); |
+ void dsrl(Register rd, Register rt, uint16_t sa); |
+ void dsrlv(Register rd, Register rt, Register rs); |
+ void drotr(Register rd, Register rt, uint16_t sa); |
+ void drotrv(Register rd, Register rt, Register rs); |
+ void dsra(Register rt, Register rd, uint16_t sa); |
+ void dsrav(Register rd, Register rt, Register rs); |
+ void dsll32(Register rt, Register rd, uint16_t sa); |
+ void dsrl32(Register rt, Register rd, uint16_t sa); |
+ void dsra32(Register rt, Register rd, uint16_t sa); |
// ------------Memory-instructions------------- |
@@ -691,6 +702,7 @@ class Assembler : public AssemblerBase { |
void lh(Register rd, const MemOperand& rs); |
void lhu(Register rd, const MemOperand& rs); |
void lw(Register rd, const MemOperand& rs); |
+ void lwu(Register rd, const MemOperand& rs); |
void lwl(Register rd, const MemOperand& rs); |
void lwr(Register rd, const MemOperand& rs); |
void sb(Register rd, const MemOperand& rs); |
@@ -698,6 +710,12 @@ class Assembler : public AssemblerBase { |
void sw(Register rd, const MemOperand& rs); |
void swl(Register rd, const MemOperand& rs); |
void swr(Register rd, const MemOperand& rs); |
+ void ldl(Register rd, const MemOperand& rs); |
+ void ldr(Register rd, const MemOperand& rs); |
+ void sdl(Register rd, const MemOperand& rs); |
+ void sdr(Register rd, const MemOperand& rs); |
+ void ld(Register rd, const MemOperand& rs); |
+ void sd(Register rd, const MemOperand& rs); |
// ----------------Prefetch-------------------- |
@@ -748,7 +766,12 @@ class Assembler : public AssemblerBase { |
void sdc1(FPURegister fs, const MemOperand& dst); |
void mtc1(Register rt, FPURegister fs); |
+ void mthc1(Register rt, FPURegister fs); |
+ void dmtc1(Register rt, FPURegister fs); |
+ |
void mfc1(Register rt, FPURegister fs); |
+ void mfhc1(Register rt, FPURegister fs); |
+ void dmfc1(Register rt, FPURegister fs); |
void ctc1(Register rt, FPUControlRegister fs); |
void cfc1(Register rt, FPUControlRegister fs); |
@@ -977,13 +1000,13 @@ class Assembler : public AssemblerBase { |
// the relocation info. |
TypeFeedbackId recorded_ast_id_; |
- int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } |
+ int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; } |
// Decode branch instruction at pos and return branch target pos. |
- int target_at(int32_t pos); |
+ int64_t target_at(int64_t pos); |
// Patch branch instruction at pos to branch to given branch target pos. |
- void target_at_put(int32_t pos, int32_t target_pos); |
+ void target_at_put(int64_t pos, int64_t target_pos); |
// Say if we need to relocate with this mode. |
bool MustUseReg(RelocInfo::Mode rmode); |
@@ -1077,6 +1100,7 @@ class Assembler : public AssemblerBase { |
inline void CheckBuffer(); |
void GrowBuffer(); |
inline void emit(Instr x); |
+ inline void emit(uint64_t x); |
inline void CheckTrampolinePoolQuick(); |
// Instruction generation. |
@@ -1213,7 +1237,7 @@ class Assembler : public AssemblerBase { |
// branch instruction generation, where we use jump instructions rather |
// than regular branch instructions. |
bool trampoline_emitted_; |
- static const int kTrampolineSlotsSize = 4 * kInstrSize; |
+ static const int kTrampolineSlotsSize = 6 * kInstrSize; |
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; |
static const int kInvalidSlotPos = -1; |