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) {
}
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.
......@@ -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----------------
// Load, store, move.
......
......@@ -386,7 +386,15 @@ class Operand BASE_EMBEDDED {
// Class MemOperand represents a memory operand in load and store instructions.
class MemOperand : public Operand {
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 unit, int32_t multiplier,
OffsetAddend offset_addend = offset_zero);
int32_t offset() const { return offset_; }
bool OffsetIsInt16Encodable() const {
......@@ -711,6 +719,11 @@ class Assembler : public AssemblerBase {
void swr(Register rd, const MemOperand& rs);
//----------------Prefetch--------------------
void pref(int32_t hint, const MemOperand& rs);
//-------------Misc-instructions--------------
// Break / Trap instructions.
......
This diff is collapsed.
......@@ -124,6 +124,16 @@ const uint32_t kFCSRFlagMask =
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.
class Registers {
public:
......@@ -297,6 +307,8 @@ enum Opcode {
LWC1 = ((6 << 3) + 1) << kOpcodeShift,
LDC1 = ((6 << 3) + 5) << kOpcodeShift,
PREF = ((6 << 3) + 3) << kOpcodeShift,
SWC1 = ((7 << 3) + 1) << kOpcodeShift,
SDC1 = ((7 << 3) + 5) << kOpcodeShift,
......
......@@ -899,6 +899,9 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
case LWR:
Format(instr, "lwr 'rt, 'imm16s('rs)");
break;
case PREF:
Format(instr, "pref 'rt, 'imm16s('rs)");
break;
case SB:
Format(instr, "sb 'rt, 'imm16s('rs)");
break;
......
......@@ -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-------------
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) {
AllowDeferredHandleDereference smi_check;
if (value->IsSmi()) {
......
......@@ -601,12 +601,17 @@ class MacroAssembler: public Assembler {
#undef DEFINE_INSTRUCTION
#undef DEFINE_INSTRUCTION2
void Pref(int32_t hint, const MemOperand& rs);
// ---------------------------------------------------------------------------
// Pseudo-instructions.
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.
void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
......
......@@ -503,6 +503,12 @@ OS::MemCopyUint8Function CreateMemCopyUint8Function(
OS::MemCopyUint8Function stub);
OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
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
......@@ -517,6 +523,9 @@ void OS::PostSetUp() {
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
OS::memcopy_uint16_uint8_function =
CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper);
#elif defined(V8_HOST_ARCH_MIPS)
OS::memcopy_uint8_function =
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
#endif
init_fast_log_function();
// fast_exp is initialized lazily.
......
......@@ -365,6 +365,26 @@ class OS {
size_t 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
// Copy memory area to disjoint memory area.
static void MemCopy(void* dest, const void* src, size_t size) {
......
......@@ -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(uint16_t* dest, const uint8_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
// Copy from ASCII/16bit chars to ASCII/16bit chars.
......@@ -421,6 +424,24 @@ void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
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
......
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