Commit 17766404 authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Faster memcpy.

BUG=
R=jkummerow@chromium.org, plind44@gmail.com

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

Patch from yuyin QQ <xwafish@gmail.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18274 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6afe5553
...@@ -260,6 +260,12 @@ MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) { ...@@ -260,6 +260,12 @@ MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
} }
MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
OffsetAddend offset_addend) : Operand(rm) {
offset_ = unit * multiplier + offset_addend;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Specific instructions, constants, and masks. // Specific instructions, constants, and masks.
...@@ -1623,6 +1629,15 @@ void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) { ...@@ -1623,6 +1629,15 @@ void Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
} }
void Assembler::pref(int32_t hint, const MemOperand& rs) {
ASSERT(kArchVariant != kLoongson);
ASSERT(is_uint5(hint) && is_uint16(rs.offset_));
Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
| (rs.offset_);
emit(instr);
}
//--------Coprocessor-instructions---------------- //--------Coprocessor-instructions----------------
// Load, store, move. // Load, store, move.
......
...@@ -386,7 +386,15 @@ class Operand BASE_EMBEDDED { ...@@ -386,7 +386,15 @@ class Operand BASE_EMBEDDED {
// Class MemOperand represents a memory operand in load and store instructions. // Class MemOperand represents a memory operand in load and store instructions.
class MemOperand : public Operand { class MemOperand : public Operand {
public: public:
// Immediate value attached to offset.
enum OffsetAddend {
offset_minus_one = -1,
offset_zero = 0
};
explicit MemOperand(Register rn, int32_t offset = 0); explicit MemOperand(Register rn, int32_t offset = 0);
explicit MemOperand(Register rn, int32_t unit, int32_t multiplier,
OffsetAddend offset_addend = offset_zero);
int32_t offset() const { return offset_; } int32_t offset() const { return offset_; }
bool OffsetIsInt16Encodable() const { bool OffsetIsInt16Encodable() const {
...@@ -711,6 +719,11 @@ class Assembler : public AssemblerBase { ...@@ -711,6 +719,11 @@ class Assembler : public AssemblerBase {
void swr(Register rd, const MemOperand& rs); void swr(Register rd, const MemOperand& rs);
//----------------Prefetch--------------------
void pref(int32_t hint, const MemOperand& rs);
//-------------Misc-instructions-------------- //-------------Misc-instructions--------------
// Break / Trap instructions. // Break / Trap instructions.
......
This diff is collapsed.
...@@ -124,6 +124,16 @@ const uint32_t kFCSRFlagMask = ...@@ -124,6 +124,16 @@ const uint32_t kFCSRFlagMask =
const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask; const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
// 'pref' instruction hints
const int32_t kPrefHintLoad = 0;
const int32_t kPrefHintStore = 1;
const int32_t kPrefHintLoadStreamed = 4;
const int32_t kPrefHintStoreStreamed = 5;
const int32_t kPrefHintLoadRetained = 6;
const int32_t kPrefHintStoreRetained = 7;
const int32_t kPrefHintWritebackInvalidate = 25;
const int32_t kPrefHintPrepareForStore = 30;
// Helper functions for converting between register numbers and names. // Helper functions for converting between register numbers and names.
class Registers { class Registers {
public: public:
...@@ -297,6 +307,8 @@ enum Opcode { ...@@ -297,6 +307,8 @@ enum Opcode {
LWC1 = ((6 << 3) + 1) << kOpcodeShift, LWC1 = ((6 << 3) + 1) << kOpcodeShift,
LDC1 = ((6 << 3) + 5) << kOpcodeShift, LDC1 = ((6 << 3) + 5) << kOpcodeShift,
PREF = ((6 << 3) + 3) << kOpcodeShift,
SWC1 = ((7 << 3) + 1) << kOpcodeShift, SWC1 = ((7 << 3) + 1) << kOpcodeShift,
SDC1 = ((7 << 3) + 5) << kOpcodeShift, SDC1 = ((7 << 3) + 5) << kOpcodeShift,
......
...@@ -899,6 +899,9 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { ...@@ -899,6 +899,9 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
case LWR: case LWR:
Format(instr, "lwr 'rt, 'imm16s('rs)"); Format(instr, "lwr 'rt, 'imm16s('rs)");
break; break;
case PREF:
Format(instr, "pref 'rt, 'imm16s('rs)");
break;
case SB: case SB:
Format(instr, "sb 'rt, 'imm16s('rs)"); Format(instr, "sb 'rt, 'imm16s('rs)");
break; break;
......
...@@ -789,8 +789,29 @@ void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) { ...@@ -789,8 +789,29 @@ void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) {
} }
void MacroAssembler::Pref(int32_t hint, const MemOperand& rs) {
if (kArchVariant == kLoongson) {
lw(zero_reg, rs);
} else {
pref(hint, rs);
}
}
//------------Pseudo-instructions------------- //------------Pseudo-instructions-------------
void MacroAssembler::Ulw(Register rd, const MemOperand& rs) {
lwr(rd, rs);
lwl(rd, MemOperand(rs.rm(), rs.offset() + 3));
}
void MacroAssembler::Usw(Register rd, const MemOperand& rs) {
swr(rd, rs);
swl(rd, MemOperand(rs.rm(), rs.offset() + 3));
}
void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) { void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) {
AllowDeferredHandleDereference smi_check; AllowDeferredHandleDereference smi_check;
if (value->IsSmi()) { if (value->IsSmi()) {
......
...@@ -601,12 +601,17 @@ class MacroAssembler: public Assembler { ...@@ -601,12 +601,17 @@ class MacroAssembler: public Assembler {
#undef DEFINE_INSTRUCTION #undef DEFINE_INSTRUCTION
#undef DEFINE_INSTRUCTION2 #undef DEFINE_INSTRUCTION2
void Pref(int32_t hint, const MemOperand& rs);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Pseudo-instructions. // Pseudo-instructions.
void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); } void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
void Ulw(Register rd, const MemOperand& rs);
void Usw(Register rd, const MemOperand& rs);
// Load int32 in the rd register. // Load int32 in the rd register.
void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE); void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) { inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
......
...@@ -503,6 +503,12 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function( ...@@ -503,6 +503,12 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
OS::MemCopyUint8Function stub); OS::MemCopyUint8Function stub);
OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function( OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
OS::MemCopyUint16Uint8Function stub); OS::MemCopyUint16Uint8Function stub);
#elif defined(V8_HOST_ARCH_MIPS)
OS::MemCopyUint8Function OS::memcopy_uint8_function = &OS::MemCopyUint8Wrapper;
// Defined in codegen-mips.cc.
OS::MemCopyUint8Function CreateMemCopyUint8Function(
OS::MemCopyUint8Function stub);
#endif #endif
...@@ -517,6 +523,9 @@ void OS::PostSetUp() { ...@@ -517,6 +523,9 @@ void OS::PostSetUp() {
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper); CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
OS::memcopy_uint16_uint8_function = OS::memcopy_uint16_uint8_function =
CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper); CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper);
#elif defined(V8_HOST_ARCH_MIPS)
OS::memcopy_uint8_function =
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
#endif #endif
init_fast_log_function(); init_fast_log_function();
// fast_exp is initialized lazily. // fast_exp is initialized lazily.
......
...@@ -365,6 +365,26 @@ class OS { ...@@ -365,6 +365,26 @@ class OS {
size_t size) { size_t size) {
(*memcopy_uint16_uint8_function)(dest, src, size); (*memcopy_uint16_uint8_function)(dest, src, size);
} }
#elif defined(V8_HOST_ARCH_MIPS)
typedef void (*MemCopyUint8Function)(uint8_t* dest,
const uint8_t* src,
size_t size);
static MemCopyUint8Function memcopy_uint8_function;
static void MemCopyUint8Wrapper(uint8_t* dest,
const uint8_t* src,
size_t chars) {
memcpy(dest, src, chars);
}
// For values < 16, the assembler function is slower than the inlined C code.
static const int kMinComplexMemCopy = 16;
static void MemCopy(void* dest, const void* src, size_t size) {
(*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
reinterpret_cast<const uint8_t*>(src),
size);
}
static void MemMove(void* dest, const void* src, size_t size) {
memmove(dest, src, size);
}
#else #else
// Copy memory area to disjoint memory area. // Copy memory area to disjoint memory area.
static void MemCopy(void* dest, const void* src, size_t size) { static void MemCopy(void* dest, const void* src, size_t size) {
......
...@@ -266,6 +266,9 @@ INLINE(static void CopyCharsUnsigned(sinkchar* dest, ...@@ -266,6 +266,9 @@ INLINE(static void CopyCharsUnsigned(sinkchar* dest,
INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars)); INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars)); INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars)); INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
#elif defined(V8_HOST_ARCH_MIPS)
INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
#endif #endif
// Copy from ASCII/16bit chars to ASCII/16bit chars. // Copy from ASCII/16bit chars to ASCII/16bit chars.
...@@ -421,6 +424,24 @@ void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) { ...@@ -421,6 +424,24 @@ void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
break; break;
} }
} }
#elif defined(V8_HOST_ARCH_MIPS)
void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
if (chars < OS::kMinComplexMemCopy) {
memcpy(dest, src, chars);
} else {
OS::MemCopy(dest, src, chars);
}
}
void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
if (chars < OS::kMinComplexMemCopy) {
memcpy(dest, src, chars * sizeof(*dest));
} else {
OS::MemCopy(dest, src, chars * sizeof(*dest));
}
}
#endif #endif
......
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