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 |