| Index: src/arm/assembler-arm.h
|
| diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
|
| index 3000860ba43fd75b98c980ae0198e381fbf9af94..81051bb0547f446910326fb2d02fee8d8e4ecc7c 100644
|
| --- a/src/arm/assembler-arm.h
|
| +++ b/src/arm/assembler-arm.h
|
| @@ -78,12 +78,15 @@ class CpuFeatures : public AllStatic {
|
| (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
|
| }
|
|
|
| + static unsigned cache_line_size() { return cache_line_size_; }
|
| +
|
| private:
|
| #ifdef DEBUG
|
| static bool initialized_;
|
| #endif
|
| static unsigned supported_;
|
| static unsigned found_by_runtime_probing_only_;
|
| + static unsigned cache_line_size_;
|
|
|
| friend class ExternalReference;
|
| DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
|
| @@ -301,6 +304,36 @@ struct DwVfpRegister {
|
| typedef DwVfpRegister DoubleRegister;
|
|
|
|
|
| +// Quad word NEON register.
|
| +struct QwNeonRegister {
|
| + static const int kMaxNumRegisters = 16;
|
| +
|
| + static QwNeonRegister from_code(int code) {
|
| + QwNeonRegister r = { code };
|
| + return r;
|
| + }
|
| +
|
| + bool is_valid() const {
|
| + return (0 <= code_) && (code_ < kMaxNumRegisters);
|
| + }
|
| + bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
|
| + int code() const {
|
| + ASSERT(is_valid());
|
| + return code_;
|
| + }
|
| + void split_code(int* vm, int* m) const {
|
| + ASSERT(is_valid());
|
| + *m = (code_ & 0x10) >> 4;
|
| + *vm = code_ & 0x0F;
|
| + }
|
| +
|
| + int code_;
|
| +};
|
| +
|
| +
|
| +typedef QwNeonRegister QuadRegister;
|
| +
|
| +
|
| // Support for the VFP registers s0 to s31 (d0 to d15).
|
| // Note that "s(N):s(N+1)" is the same as "d(N/2)".
|
| const SwVfpRegister s0 = { 0 };
|
| @@ -370,6 +403,23 @@ const DwVfpRegister d29 = { 29 };
|
| const DwVfpRegister d30 = { 30 };
|
| const DwVfpRegister d31 = { 31 };
|
|
|
| +const QwNeonRegister q0 = { 0 };
|
| +const QwNeonRegister q1 = { 1 };
|
| +const QwNeonRegister q2 = { 2 };
|
| +const QwNeonRegister q3 = { 3 };
|
| +const QwNeonRegister q4 = { 4 };
|
| +const QwNeonRegister q5 = { 5 };
|
| +const QwNeonRegister q6 = { 6 };
|
| +const QwNeonRegister q7 = { 7 };
|
| +const QwNeonRegister q8 = { 8 };
|
| +const QwNeonRegister q9 = { 9 };
|
| +const QwNeonRegister q10 = { 10 };
|
| +const QwNeonRegister q11 = { 11 };
|
| +const QwNeonRegister q12 = { 12 };
|
| +const QwNeonRegister q13 = { 13 };
|
| +const QwNeonRegister q14 = { 14 };
|
| +const QwNeonRegister q15 = { 15 };
|
| +
|
| // Aliases for double registers. Defined using #define instead of
|
| // "static const DwVfpRegister&" because Clang complains otherwise when a
|
| // compilation unit that includes this header doesn't use the variables.
|
| @@ -562,6 +612,40 @@ class MemOperand BASE_EMBEDDED {
|
| friend class Assembler;
|
| };
|
|
|
| +
|
| +// Class NeonMemOperand represents a memory operand in load and
|
| +// store NEON instructions
|
| +class NeonMemOperand BASE_EMBEDDED {
|
| + public:
|
| + // [rn {:align}] Offset
|
| + // [rn {:align}]! PostIndex
|
| + explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0);
|
| +
|
| + // [rn {:align}], rm PostIndex
|
| + explicit NeonMemOperand(Register rn, Register rm, int align = 0);
|
| +
|
| + Register rn() const { return rn_; }
|
| + Register rm() const { return rm_; }
|
| + int align() const { return align_; }
|
| +
|
| + private:
|
| + Register rn_; // base
|
| + Register rm_; // register increment
|
| + int align_;
|
| +};
|
| +
|
| +
|
| +// Class NeonListOperand represents a list of NEON registers
|
| +class NeonListOperand BASE_EMBEDDED {
|
| + public:
|
| + explicit NeonListOperand(DoubleRegister base, int registers_count = 1);
|
| + DoubleRegister base() const { return base_; }
|
| + NeonListType type() const { return type_; }
|
| + private:
|
| + DoubleRegister base_;
|
| + NeonListType type_;
|
| +};
|
| +
|
| extern const Instr kMovLrPc;
|
| extern const Instr kLdrPCMask;
|
| extern const Instr kLdrPCPattern;
|
| @@ -866,6 +950,19 @@ class Assembler : public AssemblerBase {
|
| void bfi(Register dst, Register src, int lsb, int width,
|
| Condition cond = al);
|
|
|
| + void pkhbt(Register dst, Register src1, const Operand& src2,
|
| + Condition cond = al);
|
| +
|
| + void pkhtb(Register dst, Register src1, const Operand& src2,
|
| + Condition cond = al);
|
| +
|
| + void uxtb(Register dst, const Operand& src, Condition cond = al);
|
| +
|
| + void uxtab(Register dst, Register src1, const Operand& src2,
|
| + Condition cond = al);
|
| +
|
| + void uxtb16(Register dst, const Operand& src, Condition cond = al);
|
| +
|
| // Status register access instructions
|
|
|
| void mrs(Register dst, SRegister s, Condition cond = al);
|
| @@ -887,6 +984,9 @@ class Assembler : public AssemblerBase {
|
| Register src2,
|
| const MemOperand& dst, Condition cond = al);
|
|
|
| + // Preload instructions
|
| + void pld(const MemOperand& address);
|
| +
|
| // Load/Store multiple instructions
|
| void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);
|
| void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
|
| @@ -1097,6 +1197,17 @@ class Assembler : public AssemblerBase {
|
| const DwVfpRegister src,
|
| const Condition cond = al);
|
|
|
| + // Support for NEON.
|
| + // All these APIs support D0 to D31 and Q0 to Q15.
|
| +
|
| + void vld1(NeonSize size,
|
| + const NeonListOperand& dst,
|
| + const NeonMemOperand& src);
|
| + void vst1(NeonSize size,
|
| + const NeonListOperand& src,
|
| + const NeonMemOperand& dst);
|
| + void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src);
|
| +
|
| // Pseudo instructions
|
|
|
| // Different nop operations are used by the code generator to detect certain
|
|
|