OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 60 matching lines...) Loading... |
71 ASSERT(initialized_); | 71 ASSERT(initialized_); |
72 return (found_by_runtime_probing_only_ & | 72 return (found_by_runtime_probing_only_ & |
73 (static_cast<uint64_t>(1) << f)) != 0; | 73 (static_cast<uint64_t>(1) << f)) != 0; |
74 } | 74 } |
75 | 75 |
76 static bool IsSafeForSnapshot(CpuFeature f) { | 76 static bool IsSafeForSnapshot(CpuFeature f) { |
77 return (IsSupported(f) && | 77 return (IsSupported(f) && |
78 (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f))); | 78 (!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f))); |
79 } | 79 } |
80 | 80 |
| 81 static unsigned cache_line_size() { return cache_line_size_; } |
| 82 |
81 private: | 83 private: |
82 #ifdef DEBUG | 84 #ifdef DEBUG |
83 static bool initialized_; | 85 static bool initialized_; |
84 #endif | 86 #endif |
85 static unsigned supported_; | 87 static unsigned supported_; |
86 static unsigned found_by_runtime_probing_only_; | 88 static unsigned found_by_runtime_probing_only_; |
| 89 static unsigned cache_line_size_; |
87 | 90 |
88 friend class ExternalReference; | 91 friend class ExternalReference; |
89 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); | 92 DISALLOW_COPY_AND_ASSIGN(CpuFeatures); |
90 }; | 93 }; |
91 | 94 |
92 | 95 |
93 // CPU Registers. | 96 // CPU Registers. |
94 // | 97 // |
95 // 1) We would prefer to use an enum, but enum values are assignment- | 98 // 1) We would prefer to use an enum, but enum values are assignment- |
96 // compatible with int, which has caused code-generation bugs. | 99 // compatible with int, which has caused code-generation bugs. |
(...skipping 197 matching lines...) Loading... |
294 *vm = code_ & 0x0F; | 297 *vm = code_ & 0x0F; |
295 } | 298 } |
296 | 299 |
297 int code_; | 300 int code_; |
298 }; | 301 }; |
299 | 302 |
300 | 303 |
301 typedef DwVfpRegister DoubleRegister; | 304 typedef DwVfpRegister DoubleRegister; |
302 | 305 |
303 | 306 |
| 307 // Quad word NEON register. |
| 308 struct QwNeonRegister { |
| 309 static const int kMaxNumRegisters = 16; |
| 310 |
| 311 static QwNeonRegister from_code(int code) { |
| 312 QwNeonRegister r = { code }; |
| 313 return r; |
| 314 } |
| 315 |
| 316 bool is_valid() const { |
| 317 return (0 <= code_) && (code_ < kMaxNumRegisters); |
| 318 } |
| 319 bool is(QwNeonRegister reg) const { return code_ == reg.code_; } |
| 320 int code() const { |
| 321 ASSERT(is_valid()); |
| 322 return code_; |
| 323 } |
| 324 void split_code(int* vm, int* m) const { |
| 325 ASSERT(is_valid()); |
| 326 *m = (code_ & 0x10) >> 4; |
| 327 *vm = code_ & 0x0F; |
| 328 } |
| 329 |
| 330 int code_; |
| 331 }; |
| 332 |
| 333 |
| 334 typedef QwNeonRegister QuadRegister; |
| 335 |
| 336 |
304 // Support for the VFP registers s0 to s31 (d0 to d15). | 337 // Support for the VFP registers s0 to s31 (d0 to d15). |
305 // Note that "s(N):s(N+1)" is the same as "d(N/2)". | 338 // Note that "s(N):s(N+1)" is the same as "d(N/2)". |
306 const SwVfpRegister s0 = { 0 }; | 339 const SwVfpRegister s0 = { 0 }; |
307 const SwVfpRegister s1 = { 1 }; | 340 const SwVfpRegister s1 = { 1 }; |
308 const SwVfpRegister s2 = { 2 }; | 341 const SwVfpRegister s2 = { 2 }; |
309 const SwVfpRegister s3 = { 3 }; | 342 const SwVfpRegister s3 = { 3 }; |
310 const SwVfpRegister s4 = { 4 }; | 343 const SwVfpRegister s4 = { 4 }; |
311 const SwVfpRegister s5 = { 5 }; | 344 const SwVfpRegister s5 = { 5 }; |
312 const SwVfpRegister s6 = { 6 }; | 345 const SwVfpRegister s6 = { 6 }; |
313 const SwVfpRegister s7 = { 7 }; | 346 const SwVfpRegister s7 = { 7 }; |
(...skipping 49 matching lines...) Loading... |
363 const DwVfpRegister d23 = { 23 }; | 396 const DwVfpRegister d23 = { 23 }; |
364 const DwVfpRegister d24 = { 24 }; | 397 const DwVfpRegister d24 = { 24 }; |
365 const DwVfpRegister d25 = { 25 }; | 398 const DwVfpRegister d25 = { 25 }; |
366 const DwVfpRegister d26 = { 26 }; | 399 const DwVfpRegister d26 = { 26 }; |
367 const DwVfpRegister d27 = { 27 }; | 400 const DwVfpRegister d27 = { 27 }; |
368 const DwVfpRegister d28 = { 28 }; | 401 const DwVfpRegister d28 = { 28 }; |
369 const DwVfpRegister d29 = { 29 }; | 402 const DwVfpRegister d29 = { 29 }; |
370 const DwVfpRegister d30 = { 30 }; | 403 const DwVfpRegister d30 = { 30 }; |
371 const DwVfpRegister d31 = { 31 }; | 404 const DwVfpRegister d31 = { 31 }; |
372 | 405 |
| 406 const QwNeonRegister q0 = { 0 }; |
| 407 const QwNeonRegister q1 = { 1 }; |
| 408 const QwNeonRegister q2 = { 2 }; |
| 409 const QwNeonRegister q3 = { 3 }; |
| 410 const QwNeonRegister q4 = { 4 }; |
| 411 const QwNeonRegister q5 = { 5 }; |
| 412 const QwNeonRegister q6 = { 6 }; |
| 413 const QwNeonRegister q7 = { 7 }; |
| 414 const QwNeonRegister q8 = { 8 }; |
| 415 const QwNeonRegister q9 = { 9 }; |
| 416 const QwNeonRegister q10 = { 10 }; |
| 417 const QwNeonRegister q11 = { 11 }; |
| 418 const QwNeonRegister q12 = { 12 }; |
| 419 const QwNeonRegister q13 = { 13 }; |
| 420 const QwNeonRegister q14 = { 14 }; |
| 421 const QwNeonRegister q15 = { 15 }; |
| 422 |
373 // Aliases for double registers. Defined using #define instead of | 423 // Aliases for double registers. Defined using #define instead of |
374 // "static const DwVfpRegister&" because Clang complains otherwise when a | 424 // "static const DwVfpRegister&" because Clang complains otherwise when a |
375 // compilation unit that includes this header doesn't use the variables. | 425 // compilation unit that includes this header doesn't use the variables. |
376 #define kFirstCalleeSavedDoubleReg d8 | 426 #define kFirstCalleeSavedDoubleReg d8 |
377 #define kLastCalleeSavedDoubleReg d15 | 427 #define kLastCalleeSavedDoubleReg d15 |
378 #define kDoubleRegZero d14 | 428 #define kDoubleRegZero d14 |
379 #define kScratchDoubleReg d15 | 429 #define kScratchDoubleReg d15 |
380 | 430 |
381 | 431 |
382 // Coprocessor register | 432 // Coprocessor register |
(...skipping 172 matching lines...) Loading... |
555 Register rn_; // base | 605 Register rn_; // base |
556 Register rm_; // register offset | 606 Register rm_; // register offset |
557 int32_t offset_; // valid if rm_ == no_reg | 607 int32_t offset_; // valid if rm_ == no_reg |
558 ShiftOp shift_op_; | 608 ShiftOp shift_op_; |
559 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg | 609 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg |
560 AddrMode am_; // bits P, U, and W | 610 AddrMode am_; // bits P, U, and W |
561 | 611 |
562 friend class Assembler; | 612 friend class Assembler; |
563 }; | 613 }; |
564 | 614 |
| 615 |
| 616 // Class NeonMemOperand represents a memory operand in load and |
| 617 // store NEON instructions |
| 618 class NeonMemOperand BASE_EMBEDDED { |
| 619 public: |
| 620 // [rn {:align}] Offset |
| 621 // [rn {:align}]! PostIndex |
| 622 explicit NeonMemOperand(Register rn, AddrMode am = Offset, int align = 0); |
| 623 |
| 624 // [rn {:align}], rm PostIndex |
| 625 explicit NeonMemOperand(Register rn, Register rm, int align = 0); |
| 626 |
| 627 Register rn() const { return rn_; } |
| 628 Register rm() const { return rm_; } |
| 629 int align() const { return align_; } |
| 630 |
| 631 private: |
| 632 Register rn_; // base |
| 633 Register rm_; // register increment |
| 634 int align_; |
| 635 }; |
| 636 |
| 637 |
| 638 // Class NeonListOperand represents a list of NEON registers |
| 639 class NeonListOperand BASE_EMBEDDED { |
| 640 public: |
| 641 explicit NeonListOperand(DoubleRegister base, int registers_count = 1); |
| 642 DoubleRegister base() const { return base_; } |
| 643 NeonListType type() const { return type_; } |
| 644 private: |
| 645 DoubleRegister base_; |
| 646 NeonListType type_; |
| 647 }; |
| 648 |
565 extern const Instr kMovLrPc; | 649 extern const Instr kMovLrPc; |
566 extern const Instr kLdrPCMask; | 650 extern const Instr kLdrPCMask; |
567 extern const Instr kLdrPCPattern; | 651 extern const Instr kLdrPCPattern; |
568 extern const Instr kBlxRegMask; | 652 extern const Instr kBlxRegMask; |
569 extern const Instr kBlxRegPattern; | 653 extern const Instr kBlxRegPattern; |
570 extern const Instr kBlxIp; | 654 extern const Instr kBlxIp; |
571 | 655 |
572 extern const Instr kMovMvnMask; | 656 extern const Instr kMovMvnMask; |
573 extern const Instr kMovMvnPattern; | 657 extern const Instr kMovMvnPattern; |
574 extern const Instr kMovMvnFlip; | 658 extern const Instr kMovMvnFlip; |
(...skipping 284 matching lines...) Loading... |
859 Condition cond = al); | 943 Condition cond = al); |
860 | 944 |
861 void sbfx(Register dst, Register src, int lsb, int width, | 945 void sbfx(Register dst, Register src, int lsb, int width, |
862 Condition cond = al); | 946 Condition cond = al); |
863 | 947 |
864 void bfc(Register dst, int lsb, int width, Condition cond = al); | 948 void bfc(Register dst, int lsb, int width, Condition cond = al); |
865 | 949 |
866 void bfi(Register dst, Register src, int lsb, int width, | 950 void bfi(Register dst, Register src, int lsb, int width, |
867 Condition cond = al); | 951 Condition cond = al); |
868 | 952 |
| 953 void pkhbt(Register dst, Register src1, const Operand& src2, |
| 954 Condition cond = al); |
| 955 |
| 956 void pkhtb(Register dst, Register src1, const Operand& src2, |
| 957 Condition cond = al); |
| 958 |
| 959 void uxtb(Register dst, const Operand& src, Condition cond = al); |
| 960 |
| 961 void uxtab(Register dst, Register src1, const Operand& src2, |
| 962 Condition cond = al); |
| 963 |
| 964 void uxtb16(Register dst, const Operand& src, Condition cond = al); |
| 965 |
869 // Status register access instructions | 966 // Status register access instructions |
870 | 967 |
871 void mrs(Register dst, SRegister s, Condition cond = al); | 968 void mrs(Register dst, SRegister s, Condition cond = al); |
872 void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al); | 969 void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al); |
873 | 970 |
874 // Load/Store instructions | 971 // Load/Store instructions |
875 void ldr(Register dst, const MemOperand& src, Condition cond = al); | 972 void ldr(Register dst, const MemOperand& src, Condition cond = al); |
876 void str(Register src, const MemOperand& dst, Condition cond = al); | 973 void str(Register src, const MemOperand& dst, Condition cond = al); |
877 void ldrb(Register dst, const MemOperand& src, Condition cond = al); | 974 void ldrb(Register dst, const MemOperand& src, Condition cond = al); |
878 void strb(Register src, const MemOperand& dst, Condition cond = al); | 975 void strb(Register src, const MemOperand& dst, Condition cond = al); |
879 void ldrh(Register dst, const MemOperand& src, Condition cond = al); | 976 void ldrh(Register dst, const MemOperand& src, Condition cond = al); |
880 void strh(Register src, const MemOperand& dst, Condition cond = al); | 977 void strh(Register src, const MemOperand& dst, Condition cond = al); |
881 void ldrsb(Register dst, const MemOperand& src, Condition cond = al); | 978 void ldrsb(Register dst, const MemOperand& src, Condition cond = al); |
882 void ldrsh(Register dst, const MemOperand& src, Condition cond = al); | 979 void ldrsh(Register dst, const MemOperand& src, Condition cond = al); |
883 void ldrd(Register dst1, | 980 void ldrd(Register dst1, |
884 Register dst2, | 981 Register dst2, |
885 const MemOperand& src, Condition cond = al); | 982 const MemOperand& src, Condition cond = al); |
886 void strd(Register src1, | 983 void strd(Register src1, |
887 Register src2, | 984 Register src2, |
888 const MemOperand& dst, Condition cond = al); | 985 const MemOperand& dst, Condition cond = al); |
889 | 986 |
| 987 // Preload instructions |
| 988 void pld(const MemOperand& address); |
| 989 |
890 // Load/Store multiple instructions | 990 // Load/Store multiple instructions |
891 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); | 991 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); |
892 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); | 992 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); |
893 | 993 |
894 // Exception-generating instructions and debugging support | 994 // Exception-generating instructions and debugging support |
895 void stop(const char* msg, | 995 void stop(const char* msg, |
896 Condition cond = al, | 996 Condition cond = al, |
897 int32_t code = kDefaultStopCode); | 997 int32_t code = kDefaultStopCode); |
898 | 998 |
899 void bkpt(uint32_t imm16); // v5 and above | 999 void bkpt(uint32_t imm16); // v5 and above |
(...skipping 190 matching lines...) Loading... |
1090 const double src2, | 1190 const double src2, |
1091 const Condition cond = al); | 1191 const Condition cond = al); |
1092 void vmrs(const Register dst, | 1192 void vmrs(const Register dst, |
1093 const Condition cond = al); | 1193 const Condition cond = al); |
1094 void vmsr(const Register dst, | 1194 void vmsr(const Register dst, |
1095 const Condition cond = al); | 1195 const Condition cond = al); |
1096 void vsqrt(const DwVfpRegister dst, | 1196 void vsqrt(const DwVfpRegister dst, |
1097 const DwVfpRegister src, | 1197 const DwVfpRegister src, |
1098 const Condition cond = al); | 1198 const Condition cond = al); |
1099 | 1199 |
| 1200 // Support for NEON. |
| 1201 // All these APIs support D0 to D31 and Q0 to Q15. |
| 1202 |
| 1203 void vld1(NeonSize size, |
| 1204 const NeonListOperand& dst, |
| 1205 const NeonMemOperand& src); |
| 1206 void vst1(NeonSize size, |
| 1207 const NeonListOperand& src, |
| 1208 const NeonMemOperand& dst); |
| 1209 void vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src); |
| 1210 |
1100 // Pseudo instructions | 1211 // Pseudo instructions |
1101 | 1212 |
1102 // Different nop operations are used by the code generator to detect certain | 1213 // Different nop operations are used by the code generator to detect certain |
1103 // states of the generated code. | 1214 // states of the generated code. |
1104 enum NopMarkerTypes { | 1215 enum NopMarkerTypes { |
1105 NON_MARKING_NOP = 0, | 1216 NON_MARKING_NOP = 0, |
1106 DEBUG_BREAK_NOP, | 1217 DEBUG_BREAK_NOP, |
1107 // IC markers. | 1218 // IC markers. |
1108 PROPERTY_ACCESS_INLINED, | 1219 PROPERTY_ACCESS_INLINED, |
1109 PROPERTY_ACCESS_INLINED_CONTEXT, | 1220 PROPERTY_ACCESS_INLINED_CONTEXT, |
(...skipping 324 matching lines...) Loading... |
1434 public: | 1545 public: |
1435 explicit EnsureSpace(Assembler* assembler) { | 1546 explicit EnsureSpace(Assembler* assembler) { |
1436 assembler->CheckBuffer(); | 1547 assembler->CheckBuffer(); |
1437 } | 1548 } |
1438 }; | 1549 }; |
1439 | 1550 |
1440 | 1551 |
1441 } } // namespace v8::internal | 1552 } } // namespace v8::internal |
1442 | 1553 |
1443 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1554 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |