| 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 23 matching lines...) Expand all Loading... |
| 34 // modified significantly by Google Inc. | 34 // modified significantly by Google Inc. |
| 35 // Copyright 2010 the V8 project authors. All rights reserved. | 35 // Copyright 2010 the V8 project authors. All rights reserved. |
| 36 | 36 |
| 37 // A light-weight ARM Assembler | 37 // A light-weight ARM Assembler |
| 38 // Generates user mode instructions for the ARM architecture up to version 5 | 38 // Generates user mode instructions for the ARM architecture up to version 5 |
| 39 | 39 |
| 40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ | 40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ |
| 41 #define V8_ARM_ASSEMBLER_ARM_H_ | 41 #define V8_ARM_ASSEMBLER_ARM_H_ |
| 42 #include <stdio.h> | 42 #include <stdio.h> |
| 43 #include "assembler.h" | 43 #include "assembler.h" |
| 44 #include "constants-arm.h" |
| 44 #include "serialize.h" | 45 #include "serialize.h" |
| 45 | 46 |
| 46 namespace v8 { | 47 namespace v8 { |
| 47 namespace internal { | 48 namespace internal { |
| 48 | 49 |
| 49 // CPU Registers. | 50 // CPU Registers. |
| 50 // | 51 // |
| 51 // 1) We would prefer to use an enum, but enum values are assignment- | 52 // 1) We would prefer to use an enum, but enum values are assignment- |
| 52 // compatible with int, which has caused code-generation bugs. | 53 // compatible with int, which has caused code-generation bugs. |
| 53 // | 54 // |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 } | 161 } |
| 161 | 162 |
| 162 int code_; | 163 int code_; |
| 163 }; | 164 }; |
| 164 | 165 |
| 165 | 166 |
| 166 // Double word VFP register. | 167 // Double word VFP register. |
| 167 struct DwVfpRegister { | 168 struct DwVfpRegister { |
| 168 // d0 has been excluded from allocation. This is following ia32 | 169 // d0 has been excluded from allocation. This is following ia32 |
| 169 // where xmm0 is excluded. This should be revisited. | 170 // where xmm0 is excluded. This should be revisited. |
| 171 // Currently d0 is used as a scratch register. |
| 172 // d1 has also been excluded from allocation to be used as a scratch |
| 173 // register as well. |
| 170 static const int kNumRegisters = 16; | 174 static const int kNumRegisters = 16; |
| 171 static const int kNumAllocatableRegisters = 15; | 175 static const int kNumAllocatableRegisters = 15; |
| 172 | 176 |
| 173 static int ToAllocationIndex(DwVfpRegister reg) { | 177 static int ToAllocationIndex(DwVfpRegister reg) { |
| 174 ASSERT(reg.code() != 0); | 178 ASSERT(reg.code() != 0); |
| 175 return reg.code() - 1; | 179 return reg.code() - 1; |
| 176 } | 180 } |
| 177 | 181 |
| 178 static DwVfpRegister FromAllocationIndex(int index) { | 182 static DwVfpRegister FromAllocationIndex(int index) { |
| 179 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 183 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 const DwVfpRegister d7 = { 7 }; | 294 const DwVfpRegister d7 = { 7 }; |
| 291 const DwVfpRegister d8 = { 8 }; | 295 const DwVfpRegister d8 = { 8 }; |
| 292 const DwVfpRegister d9 = { 9 }; | 296 const DwVfpRegister d9 = { 9 }; |
| 293 const DwVfpRegister d10 = { 10 }; | 297 const DwVfpRegister d10 = { 10 }; |
| 294 const DwVfpRegister d11 = { 11 }; | 298 const DwVfpRegister d11 = { 11 }; |
| 295 const DwVfpRegister d12 = { 12 }; | 299 const DwVfpRegister d12 = { 12 }; |
| 296 const DwVfpRegister d13 = { 13 }; | 300 const DwVfpRegister d13 = { 13 }; |
| 297 const DwVfpRegister d14 = { 14 }; | 301 const DwVfpRegister d14 = { 14 }; |
| 298 const DwVfpRegister d15 = { 15 }; | 302 const DwVfpRegister d15 = { 15 }; |
| 299 | 303 |
| 300 // VFP FPSCR constants. | |
| 301 static const uint32_t kVFPExceptionMask = 0xf; | |
| 302 static const uint32_t kVFPRoundingModeMask = 3 << 22; | |
| 303 static const uint32_t kVFPFlushToZeroMask = 1 << 24; | |
| 304 static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22; | |
| 305 | 304 |
| 306 // Coprocessor register | 305 // Coprocessor register |
| 307 struct CRegister { | 306 struct CRegister { |
| 308 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 307 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
| 309 bool is(CRegister creg) const { return code_ == creg.code_; } | 308 bool is(CRegister creg) const { return code_ == creg.code_; } |
| 310 int code() const { | 309 int code() const { |
| 311 ASSERT(is_valid()); | 310 ASSERT(is_valid()); |
| 312 return code_; | 311 return code_; |
| 313 } | 312 } |
| 314 int bit() const { | 313 int bit() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 p9 = 9, | 354 p9 = 9, |
| 356 p10 = 10, | 355 p10 = 10, |
| 357 p11 = 11, | 356 p11 = 11, |
| 358 p12 = 12, | 357 p12 = 12, |
| 359 p13 = 13, | 358 p13 = 13, |
| 360 p14 = 14, | 359 p14 = 14, |
| 361 p15 = 15 | 360 p15 = 15 |
| 362 }; | 361 }; |
| 363 | 362 |
| 364 | 363 |
| 365 // Condition field in instructions. | |
| 366 enum Condition { | |
| 367 // any value < 0 is considered no_condition | |
| 368 no_condition = -1, | |
| 369 | |
| 370 eq = 0 << 28, // Z set equal. | |
| 371 ne = 1 << 28, // Z clear not equal. | |
| 372 nz = 1 << 28, // Z clear not zero. | |
| 373 cs = 2 << 28, // C set carry set. | |
| 374 hs = 2 << 28, // C set unsigned higher or same. | |
| 375 cc = 3 << 28, // C clear carry clear. | |
| 376 lo = 3 << 28, // C clear unsigned lower. | |
| 377 mi = 4 << 28, // N set negative. | |
| 378 pl = 5 << 28, // N clear positive or zero. | |
| 379 vs = 6 << 28, // V set overflow. | |
| 380 vc = 7 << 28, // V clear no overflow. | |
| 381 hi = 8 << 28, // C set, Z clear unsigned higher. | |
| 382 ls = 9 << 28, // C clear or Z set unsigned lower or same. | |
| 383 ge = 10 << 28, // N == V greater or equal. | |
| 384 lt = 11 << 28, // N != V less than. | |
| 385 gt = 12 << 28, // Z clear, N == V greater than. | |
| 386 le = 13 << 28, // Z set or N != V less then or equal | |
| 387 al = 14 << 28 // always. | |
| 388 }; | |
| 389 | |
| 390 | |
| 391 // Returns the equivalent of !cc. | |
| 392 inline Condition NegateCondition(Condition cc) { | |
| 393 ASSERT(cc != al); | |
| 394 return static_cast<Condition>(cc ^ ne); | |
| 395 } | |
| 396 | |
| 397 | |
| 398 // Corresponds to transposing the operands of a comparison. | |
| 399 inline Condition ReverseCondition(Condition cc) { | |
| 400 switch (cc) { | |
| 401 case lo: | |
| 402 return hi; | |
| 403 case hi: | |
| 404 return lo; | |
| 405 case hs: | |
| 406 return ls; | |
| 407 case ls: | |
| 408 return hs; | |
| 409 case lt: | |
| 410 return gt; | |
| 411 case gt: | |
| 412 return lt; | |
| 413 case ge: | |
| 414 return le; | |
| 415 case le: | |
| 416 return ge; | |
| 417 default: | |
| 418 return cc; | |
| 419 }; | |
| 420 } | |
| 421 | |
| 422 | |
| 423 // Branch hints are not used on the ARM. They are defined so that they can | |
| 424 // appear in shared function signatures, but will be ignored in ARM | |
| 425 // implementations. | |
| 426 enum Hint { no_hint }; | |
| 427 | |
| 428 // Hints are not used on the arm. Negating is trivial. | |
| 429 inline Hint NegateHint(Hint ignored) { return no_hint; } | |
| 430 | |
| 431 | |
| 432 // ----------------------------------------------------------------------------- | |
| 433 // Addressing modes and instruction variants | |
| 434 | |
| 435 // Shifter operand shift operation | |
| 436 enum ShiftOp { | |
| 437 LSL = 0 << 5, | |
| 438 LSR = 1 << 5, | |
| 439 ASR = 2 << 5, | |
| 440 ROR = 3 << 5, | |
| 441 RRX = -1 | |
| 442 }; | |
| 443 | |
| 444 | |
| 445 // Condition code updating mode | |
| 446 enum SBit { | |
| 447 SetCC = 1 << 20, // set condition code | |
| 448 LeaveCC = 0 << 20 // leave condition code unchanged | |
| 449 }; | |
| 450 | |
| 451 | |
| 452 // Status register selection | |
| 453 enum SRegister { | |
| 454 CPSR = 0 << 22, | |
| 455 SPSR = 1 << 22 | |
| 456 }; | |
| 457 | |
| 458 | |
| 459 // Status register fields | |
| 460 enum SRegisterField { | |
| 461 CPSR_c = CPSR | 1 << 16, | |
| 462 CPSR_x = CPSR | 1 << 17, | |
| 463 CPSR_s = CPSR | 1 << 18, | |
| 464 CPSR_f = CPSR | 1 << 19, | |
| 465 SPSR_c = SPSR | 1 << 16, | |
| 466 SPSR_x = SPSR | 1 << 17, | |
| 467 SPSR_s = SPSR | 1 << 18, | |
| 468 SPSR_f = SPSR | 1 << 19 | |
| 469 }; | |
| 470 | |
| 471 // Status register field mask (or'ed SRegisterField enum values) | |
| 472 typedef uint32_t SRegisterFieldMask; | |
| 473 | |
| 474 | |
| 475 // Memory operand addressing mode | |
| 476 enum AddrMode { | |
| 477 // bit encoding P U W | |
| 478 Offset = (8|4|0) << 21, // offset (without writeback to base) | |
| 479 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback | |
| 480 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback | |
| 481 NegOffset = (8|0|0) << 21, // negative offset (without writeback to base) | |
| 482 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback | |
| 483 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback | |
| 484 }; | |
| 485 | |
| 486 | |
| 487 // Load/store multiple addressing mode | |
| 488 enum BlockAddrMode { | |
| 489 // bit encoding P U W | |
| 490 da = (0|0|0) << 21, // decrement after | |
| 491 ia = (0|4|0) << 21, // increment after | |
| 492 db = (8|0|0) << 21, // decrement before | |
| 493 ib = (8|4|0) << 21, // increment before | |
| 494 da_w = (0|0|1) << 21, // decrement after with writeback to base | |
| 495 ia_w = (0|4|1) << 21, // increment after with writeback to base | |
| 496 db_w = (8|0|1) << 21, // decrement before with writeback to base | |
| 497 ib_w = (8|4|1) << 21 // increment before with writeback to base | |
| 498 }; | |
| 499 | |
| 500 | |
| 501 // Coprocessor load/store operand size | |
| 502 enum LFlag { | |
| 503 Long = 1 << 22, // long load/store coprocessor | |
| 504 Short = 0 << 22 // short load/store coprocessor | |
| 505 }; | |
| 506 | |
| 507 | |
| 508 // ----------------------------------------------------------------------------- | 364 // ----------------------------------------------------------------------------- |
| 509 // Machine instruction Operands | 365 // Machine instruction Operands |
| 510 | 366 |
| 511 // Class Operand represents a shifter operand in data processing instructions | 367 // Class Operand represents a shifter operand in data processing instructions |
| 512 class Operand BASE_EMBEDDED { | 368 class Operand BASE_EMBEDDED { |
| 513 public: | 369 public: |
| 514 // immediate | 370 // immediate |
| 515 INLINE(explicit Operand(int32_t immediate, | 371 INLINE(explicit Operand(int32_t immediate, |
| 516 RelocInfo::Mode rmode = RelocInfo::NONE)); | 372 RelocInfo::Mode rmode = RelocInfo::NONE)); |
| 517 INLINE(explicit Operand(const ExternalReference& f)); | 373 INLINE(explicit Operand(const ExternalReference& f)); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 #endif | 497 #endif |
| 642 }; | 498 }; |
| 643 | 499 |
| 644 private: | 500 private: |
| 645 static unsigned supported_; | 501 static unsigned supported_; |
| 646 static unsigned enabled_; | 502 static unsigned enabled_; |
| 647 static unsigned found_by_runtime_probing_; | 503 static unsigned found_by_runtime_probing_; |
| 648 }; | 504 }; |
| 649 | 505 |
| 650 | 506 |
| 651 typedef int32_t Instr; | |
| 652 | |
| 653 | |
| 654 extern const Instr kMovLrPc; | 507 extern const Instr kMovLrPc; |
| 655 extern const Instr kLdrPCMask; | 508 extern const Instr kLdrPCMask; |
| 656 extern const Instr kLdrPCPattern; | 509 extern const Instr kLdrPCPattern; |
| 657 extern const Instr kBlxRegMask; | 510 extern const Instr kBlxRegMask; |
| 658 extern const Instr kBlxRegPattern; | 511 extern const Instr kBlxRegPattern; |
| 659 | 512 |
| 660 extern const Instr kMovMvnMask; | 513 extern const Instr kMovMvnMask; |
| 661 extern const Instr kMovMvnPattern; | 514 extern const Instr kMovMvnPattern; |
| 662 extern const Instr kMovMvnFlip; | 515 extern const Instr kMovMvnFlip; |
| 663 | 516 |
| 664 extern const Instr kMovLeaveCCMask; | 517 extern const Instr kMovLeaveCCMask; |
| 665 extern const Instr kMovLeaveCCPattern; | 518 extern const Instr kMovLeaveCCPattern; |
| 666 extern const Instr kMovwMask; | 519 extern const Instr kMovwMask; |
| 667 extern const Instr kMovwPattern; | 520 extern const Instr kMovwPattern; |
| 668 extern const Instr kMovwLeaveCCFlip; | 521 extern const Instr kMovwLeaveCCFlip; |
| 669 | 522 |
| 670 extern const Instr kCmpCmnMask; | 523 extern const Instr kCmpCmnMask; |
| 671 extern const Instr kCmpCmnPattern; | 524 extern const Instr kCmpCmnPattern; |
| 672 extern const Instr kCmpCmnFlip; | 525 extern const Instr kCmpCmnFlip; |
| 673 | |
| 674 extern const Instr kALUMask; | |
| 675 extern const Instr kAddPattern; | |
| 676 extern const Instr kSubPattern; | |
| 677 extern const Instr kAndPattern; | |
| 678 extern const Instr kBicPattern; | |
| 679 extern const Instr kAddSubFlip; | 526 extern const Instr kAddSubFlip; |
| 680 extern const Instr kAndBicFlip; | 527 extern const Instr kAndBicFlip; |
| 681 | 528 |
| 529 |
| 530 |
| 682 class Assembler : public Malloced { | 531 class Assembler : public Malloced { |
| 683 public: | 532 public: |
| 684 // Create an assembler. Instructions and relocation information are emitted | 533 // Create an assembler. Instructions and relocation information are emitted |
| 685 // into a buffer, with the instructions starting from the beginning and the | 534 // into a buffer, with the instructions starting from the beginning and the |
| 686 // relocation information starting from the end of the buffer. See CodeDesc | 535 // relocation information starting from the end of the buffer. See CodeDesc |
| 687 // for a detailed comment on the layout (globals.h). | 536 // for a detailed comment on the layout (globals.h). |
| 688 // | 537 // |
| 689 // If the provided buffer is NULL, the assembler allocates and grows its own | 538 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 690 // buffer, and buffer_size determines the initial buffer size. The buffer is | 539 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| 691 // owned by the assembler and deallocated upon destruction of the assembler. | 540 // owned by the assembler and deallocated upon destruction of the assembler. |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 void tst(Register src1, Register src2, Condition cond = al) { | 722 void tst(Register src1, Register src2, Condition cond = al) { |
| 874 tst(src1, Operand(src2), cond); | 723 tst(src1, Operand(src2), cond); |
| 875 } | 724 } |
| 876 | 725 |
| 877 void teq(Register src1, const Operand& src2, Condition cond = al); | 726 void teq(Register src1, const Operand& src2, Condition cond = al); |
| 878 | 727 |
| 879 void cmp(Register src1, const Operand& src2, Condition cond = al); | 728 void cmp(Register src1, const Operand& src2, Condition cond = al); |
| 880 void cmp(Register src1, Register src2, Condition cond = al) { | 729 void cmp(Register src1, Register src2, Condition cond = al) { |
| 881 cmp(src1, Operand(src2), cond); | 730 cmp(src1, Operand(src2), cond); |
| 882 } | 731 } |
| 732 void cmp_raw_immediate(Register src1, int raw_immediate, Condition cond = al); |
| 883 | 733 |
| 884 void cmn(Register src1, const Operand& src2, Condition cond = al); | 734 void cmn(Register src1, const Operand& src2, Condition cond = al); |
| 885 | 735 |
| 886 void orr(Register dst, Register src1, const Operand& src2, | 736 void orr(Register dst, Register src1, const Operand& src2, |
| 887 SBit s = LeaveCC, Condition cond = al); | 737 SBit s = LeaveCC, Condition cond = al); |
| 888 void orr(Register dst, Register src1, Register src2, | 738 void orr(Register dst, Register src1, Register src2, |
| 889 SBit s = LeaveCC, Condition cond = al) { | 739 SBit s = LeaveCC, Condition cond = al) { |
| 890 orr(dst, src1, Operand(src2), s, cond); | 740 orr(dst, src1, Operand(src2), s, cond); |
| 891 } | 741 } |
| 892 | 742 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 const MemOperand& src, Condition cond = al); | 834 const MemOperand& src, Condition cond = al); |
| 985 void strd(Register src1, | 835 void strd(Register src1, |
| 986 Register src2, | 836 Register src2, |
| 987 const MemOperand& dst, Condition cond = al); | 837 const MemOperand& dst, Condition cond = al); |
| 988 | 838 |
| 989 // Load/Store multiple instructions | 839 // Load/Store multiple instructions |
| 990 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); | 840 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); |
| 991 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); | 841 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); |
| 992 | 842 |
| 993 // Exception-generating instructions and debugging support | 843 // Exception-generating instructions and debugging support |
| 994 static const int kDefaultStopCode = -1; | |
| 995 void stop(const char* msg, | 844 void stop(const char* msg, |
| 996 Condition cond = al, | 845 Condition cond = al, |
| 997 int32_t code = kDefaultStopCode); | 846 int32_t code = kDefaultStopCode); |
| 998 | 847 |
| 999 void bkpt(uint32_t imm16); // v5 and above | 848 void bkpt(uint32_t imm16); // v5 and above |
| 1000 void svc(uint32_t imm24, Condition cond = al); | 849 void svc(uint32_t imm24, Condition cond = al); |
| 1001 | 850 |
| 1002 // Coprocessor instructions | 851 // Coprocessor instructions |
| 1003 | 852 |
| 1004 void cdp(Coprocessor coproc, int opcode_1, | 853 void cdp(Coprocessor coproc, int opcode_1, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 void vmov(const Register dst1, | 936 void vmov(const Register dst1, |
| 1088 const Register dst2, | 937 const Register dst2, |
| 1089 const DwVfpRegister src, | 938 const DwVfpRegister src, |
| 1090 const Condition cond = al); | 939 const Condition cond = al); |
| 1091 void vmov(const SwVfpRegister dst, | 940 void vmov(const SwVfpRegister dst, |
| 1092 const Register src, | 941 const Register src, |
| 1093 const Condition cond = al); | 942 const Condition cond = al); |
| 1094 void vmov(const Register dst, | 943 void vmov(const Register dst, |
| 1095 const SwVfpRegister src, | 944 const SwVfpRegister src, |
| 1096 const Condition cond = al); | 945 const Condition cond = al); |
| 1097 enum ConversionMode { | |
| 1098 FPSCRRounding = 0, | |
| 1099 RoundToZero = 1 | |
| 1100 }; | |
| 1101 void vcvt_f64_s32(const DwVfpRegister dst, | 946 void vcvt_f64_s32(const DwVfpRegister dst, |
| 1102 const SwVfpRegister src, | 947 const SwVfpRegister src, |
| 1103 ConversionMode mode = RoundToZero, | 948 VFPConversionMode mode = kDefaultRoundToZero, |
| 1104 const Condition cond = al); | 949 const Condition cond = al); |
| 1105 void vcvt_f32_s32(const SwVfpRegister dst, | 950 void vcvt_f32_s32(const SwVfpRegister dst, |
| 1106 const SwVfpRegister src, | 951 const SwVfpRegister src, |
| 1107 ConversionMode mode = RoundToZero, | 952 VFPConversionMode mode = kDefaultRoundToZero, |
| 1108 const Condition cond = al); | 953 const Condition cond = al); |
| 1109 void vcvt_f64_u32(const DwVfpRegister dst, | 954 void vcvt_f64_u32(const DwVfpRegister dst, |
| 1110 const SwVfpRegister src, | 955 const SwVfpRegister src, |
| 1111 ConversionMode mode = RoundToZero, | 956 VFPConversionMode mode = kDefaultRoundToZero, |
| 1112 const Condition cond = al); | 957 const Condition cond = al); |
| 1113 void vcvt_s32_f64(const SwVfpRegister dst, | 958 void vcvt_s32_f64(const SwVfpRegister dst, |
| 1114 const DwVfpRegister src, | 959 const DwVfpRegister src, |
| 1115 ConversionMode mode = RoundToZero, | 960 VFPConversionMode mode = kDefaultRoundToZero, |
| 1116 const Condition cond = al); | 961 const Condition cond = al); |
| 1117 void vcvt_u32_f64(const SwVfpRegister dst, | 962 void vcvt_u32_f64(const SwVfpRegister dst, |
| 1118 const DwVfpRegister src, | 963 const DwVfpRegister src, |
| 1119 ConversionMode mode = RoundToZero, | 964 VFPConversionMode mode = kDefaultRoundToZero, |
| 1120 const Condition cond = al); | 965 const Condition cond = al); |
| 1121 void vcvt_f64_f32(const DwVfpRegister dst, | 966 void vcvt_f64_f32(const DwVfpRegister dst, |
| 1122 const SwVfpRegister src, | 967 const SwVfpRegister src, |
| 1123 ConversionMode mode = RoundToZero, | 968 VFPConversionMode mode = kDefaultRoundToZero, |
| 1124 const Condition cond = al); | 969 const Condition cond = al); |
| 1125 void vcvt_f32_f64(const SwVfpRegister dst, | 970 void vcvt_f32_f64(const SwVfpRegister dst, |
| 1126 const DwVfpRegister src, | 971 const DwVfpRegister src, |
| 1127 ConversionMode mode = RoundToZero, | 972 VFPConversionMode mode = kDefaultRoundToZero, |
| 1128 const Condition cond = al); | 973 const Condition cond = al); |
| 1129 | 974 |
| 975 void vabs(const DwVfpRegister dst, |
| 976 const DwVfpRegister src, |
| 977 const Condition cond = al); |
| 1130 void vadd(const DwVfpRegister dst, | 978 void vadd(const DwVfpRegister dst, |
| 1131 const DwVfpRegister src1, | 979 const DwVfpRegister src1, |
| 1132 const DwVfpRegister src2, | 980 const DwVfpRegister src2, |
| 1133 const Condition cond = al); | 981 const Condition cond = al); |
| 1134 void vsub(const DwVfpRegister dst, | 982 void vsub(const DwVfpRegister dst, |
| 1135 const DwVfpRegister src1, | 983 const DwVfpRegister src1, |
| 1136 const DwVfpRegister src2, | 984 const DwVfpRegister src2, |
| 1137 const Condition cond = al); | 985 const Condition cond = al); |
| 1138 void vmul(const DwVfpRegister dst, | 986 void vmul(const DwVfpRegister dst, |
| 1139 const DwVfpRegister src1, | 987 const DwVfpRegister src1, |
| 1140 const DwVfpRegister src2, | 988 const DwVfpRegister src2, |
| 1141 const Condition cond = al); | 989 const Condition cond = al); |
| 1142 void vdiv(const DwVfpRegister dst, | 990 void vdiv(const DwVfpRegister dst, |
| 1143 const DwVfpRegister src1, | 991 const DwVfpRegister src1, |
| 1144 const DwVfpRegister src2, | 992 const DwVfpRegister src2, |
| 1145 const Condition cond = al); | 993 const Condition cond = al); |
| 1146 void vcmp(const DwVfpRegister src1, | 994 void vcmp(const DwVfpRegister src1, |
| 1147 const DwVfpRegister src2, | 995 const DwVfpRegister src2, |
| 1148 const SBit s = LeaveCC, | |
| 1149 const Condition cond = al); | 996 const Condition cond = al); |
| 1150 void vcmp(const DwVfpRegister src1, | 997 void vcmp(const DwVfpRegister src1, |
| 1151 const double src2, | 998 const double src2, |
| 1152 const SBit s = LeaveCC, | |
| 1153 const Condition cond = al); | 999 const Condition cond = al); |
| 1154 void vmrs(const Register dst, | 1000 void vmrs(const Register dst, |
| 1155 const Condition cond = al); | 1001 const Condition cond = al); |
| 1156 void vmsr(const Register dst, | 1002 void vmsr(const Register dst, |
| 1157 const Condition cond = al); | 1003 const Condition cond = al); |
| 1158 void vsqrt(const DwVfpRegister dst, | 1004 void vsqrt(const DwVfpRegister dst, |
| 1159 const DwVfpRegister src, | 1005 const DwVfpRegister src, |
| 1160 const Condition cond = al); | 1006 const Condition cond = al); |
| 1161 | 1007 |
| 1162 // Pseudo instructions | 1008 // Pseudo instructions |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 // Mark address of the ExitJSFrame code. | 1071 // Mark address of the ExitJSFrame code. |
| 1226 void RecordJSReturn(); | 1072 void RecordJSReturn(); |
| 1227 | 1073 |
| 1228 // Mark address of a debug break slot. | 1074 // Mark address of a debug break slot. |
| 1229 void RecordDebugBreakSlot(); | 1075 void RecordDebugBreakSlot(); |
| 1230 | 1076 |
| 1231 // Record a comment relocation entry that can be used by a disassembler. | 1077 // Record a comment relocation entry that can be used by a disassembler. |
| 1232 // Use --code-comments to enable. | 1078 // Use --code-comments to enable. |
| 1233 void RecordComment(const char* msg); | 1079 void RecordComment(const char* msg); |
| 1234 | 1080 |
| 1235 // Writes a single byte or word of data in the code stream. Used for | 1081 // Writes a single byte or word of data in the code stream. Used |
| 1236 // inline tables, e.g., jump-tables. | 1082 // for inline tables, e.g., jump-tables. The constant pool should be |
| 1083 // emitted before any use of db and dd to ensure that constant pools |
| 1084 // are not emitted as part of the tables generated. |
| 1237 void db(uint8_t data); | 1085 void db(uint8_t data); |
| 1238 void dd(uint32_t data); | 1086 void dd(uint32_t data); |
| 1239 | 1087 |
| 1240 int pc_offset() const { return pc_ - buffer_; } | 1088 int pc_offset() const { return pc_ - buffer_; } |
| 1241 | 1089 |
| 1242 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1090 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
| 1243 | 1091 |
| 1244 bool can_peephole_optimize(int instructions) { | 1092 bool can_peephole_optimize(int instructions) { |
| 1245 if (!allow_peephole_optimization_) return false; | 1093 if (!allow_peephole_optimization_) return false; |
| 1246 if (last_bound_pos_ > pc_offset() - instructions * kInstrSize) return false; | 1094 if (last_bound_pos_ > pc_offset() - instructions * kInstrSize) return false; |
| 1247 return reloc_info_writer.last_pc() <= pc_ - instructions * kInstrSize; | 1095 return reloc_info_writer.last_pc() <= pc_ - instructions * kInstrSize; |
| 1248 } | 1096 } |
| 1249 | 1097 |
| 1250 // Read/patch instructions | 1098 // Read/patch instructions |
| 1251 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 1099 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
| 1252 static void instr_at_put(byte* pc, Instr instr) { | 1100 static void instr_at_put(byte* pc, Instr instr) { |
| 1253 *reinterpret_cast<Instr*>(pc) = instr; | 1101 *reinterpret_cast<Instr*>(pc) = instr; |
| 1254 } | 1102 } |
| 1103 static Condition GetCondition(Instr instr); |
| 1255 static bool IsBranch(Instr instr); | 1104 static bool IsBranch(Instr instr); |
| 1256 static int GetBranchOffset(Instr instr); | 1105 static int GetBranchOffset(Instr instr); |
| 1257 static bool IsLdrRegisterImmediate(Instr instr); | 1106 static bool IsLdrRegisterImmediate(Instr instr); |
| 1258 static int GetLdrRegisterImmediateOffset(Instr instr); | 1107 static int GetLdrRegisterImmediateOffset(Instr instr); |
| 1259 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); | 1108 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); |
| 1260 static bool IsStrRegisterImmediate(Instr instr); | 1109 static bool IsStrRegisterImmediate(Instr instr); |
| 1261 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); | 1110 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); |
| 1262 static bool IsAddRegisterImmediate(Instr instr); | 1111 static bool IsAddRegisterImmediate(Instr instr); |
| 1263 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); | 1112 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); |
| 1264 static Register GetRd(Instr instr); | 1113 static Register GetRd(Instr instr); |
| 1114 static Register GetRn(Instr instr); |
| 1115 static Register GetRm(Instr instr); |
| 1265 static bool IsPush(Instr instr); | 1116 static bool IsPush(Instr instr); |
| 1266 static bool IsPop(Instr instr); | 1117 static bool IsPop(Instr instr); |
| 1267 static bool IsStrRegFpOffset(Instr instr); | 1118 static bool IsStrRegFpOffset(Instr instr); |
| 1268 static bool IsLdrRegFpOffset(Instr instr); | 1119 static bool IsLdrRegFpOffset(Instr instr); |
| 1269 static bool IsStrRegFpNegOffset(Instr instr); | 1120 static bool IsStrRegFpNegOffset(Instr instr); |
| 1270 static bool IsLdrRegFpNegOffset(Instr instr); | 1121 static bool IsLdrRegFpNegOffset(Instr instr); |
| 1271 static bool IsLdrPcImmediateOffset(Instr instr); | 1122 static bool IsLdrPcImmediateOffset(Instr instr); |
| 1123 static bool IsTstImmediate(Instr instr); |
| 1124 static bool IsCmpRegister(Instr instr); |
| 1125 static bool IsCmpImmediate(Instr instr); |
| 1126 static Register GetCmpImmediateRegister(Instr instr); |
| 1127 static int GetCmpImmediateRawImmediate(Instr instr); |
| 1272 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1128 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
| 1273 | 1129 |
| 1274 // Check if is time to emit a constant pool for pending reloc info entries | 1130 // Check if is time to emit a constant pool for pending reloc info entries |
| 1275 void CheckConstPool(bool force_emit, bool require_jump); | 1131 void CheckConstPool(bool force_emit, bool require_jump); |
| 1276 | 1132 |
| 1277 protected: | 1133 protected: |
| 1278 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1134 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
| 1279 | 1135 |
| 1280 // Read/patch instructions | 1136 // Read/patch instructions |
| 1281 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 1137 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1412 public: | 1268 public: |
| 1413 explicit EnsureSpace(Assembler* assembler) { | 1269 explicit EnsureSpace(Assembler* assembler) { |
| 1414 assembler->CheckBuffer(); | 1270 assembler->CheckBuffer(); |
| 1415 } | 1271 } |
| 1416 }; | 1272 }; |
| 1417 | 1273 |
| 1418 | 1274 |
| 1419 } } // namespace v8::internal | 1275 } } // namespace v8::internal |
| 1420 | 1276 |
| 1421 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1277 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |