Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: src/arm/assembler-thumb2.h

Issue 651029: Forking disassembler and simulator for Thumb2 support; (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm-inl.h ('k') | src/arm/assembler-thumb2.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
39 39
40 #ifndef V8_ARM_ASSEMBLER_THUMB2_H_ 40 #ifndef V8_ARM_ASSEMBLER_THUMB2_H_
41 #define V8_ARM_ASSEMBLER_THUMB2_H_ 41 #define V8_ARM_ASSEMBLER_THUMB2_H_
42 #include <stdio.h> 42 #include <stdio.h>
43 #include "assembler.h" 43 #include "assembler.h"
44 #include "serialize.h" 44 #include "serialize.h"
45 45
46 namespace v8 { 46 namespace v8 {
47 namespace internal { 47 namespace internal {
48 48
49 // The beginning of this file contains some enum declarations that are
50 // redundant with declarations in constants-arm.h, but in a different namespace
51 // Please keep the order and values consistent, so we can merge the files
52 // later easily.
53
54 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
55 // as defined in section A3.4
56 enum Opcode {
57 no_operand = -1,
58 AND = 0, // Logical AND
59 EOR = 1, // Logical Exclusive OR
60 SUB = 2, // Subtract
61 RSB = 3, // Reverse Subtract
62 ADD = 4, // Add
63 ADC = 5, // Add with Carry
64 SBC = 6, // Subtract with Carry
65 RSC = 7, // Reverse Subtract with Carry
66 TST = 8, // Test
67 TEQ = 9, // Test Equivalence
68 CMP = 10, // Compare
69 CMN = 11, // Compare Negated
70 ORR = 12, // Logical (inclusive) OR
71 MOV = 13, // Move
72 BIC = 14, // Bit Clear
73 MVN = 15, // Move Not
74 max_operand = 16
75 };
76
77 enum BitPositions {
78 B0 = 1 << 0,
79 B1 = 1 << 1,
80 B2 = 1 << 2,
81 B3 = 1 << 3,
82 B4 = 1 << 4,
83 B5 = 1 << 5,
84 B6 = 1 << 6,
85 B7 = 1 << 7,
86 B8 = 1 << 8,
87 B9 = 1 << 9,
88 B10 = 1 << 10,
89 B11 = 1 << 11,
90 B12 = 1 << 12,
91 B13 = 1 << 13,
92 B14 = 1 << 14,
93 B15 = 1 << 15,
94 B16 = 1 << 16,
95 B18 = 1 << 18,
96 B19 = 1 << 19,
97 B20 = 1 << 20,
98 B21 = 1 << 21,
99 B22 = 1 << 22,
100 B23 = 1 << 23,
101 B24 = 1 << 24,
102 B25 = 1 << 25,
103 B26 = 1 << 26,
104 B27 = 1 << 27
105 };
106
49 // CPU Registers. 107 // CPU Registers.
50 // 108 //
51 // 1) We would prefer to use an enum, but enum values are assignment- 109 // 1) We would prefer to use an enum, but enum values are assignment-
52 // compatible with int, which has caused code-generation bugs. 110 // compatible with int, which has caused code-generation bugs.
53 // 111 //
54 // 2) We would prefer to use a class instead of a struct but we don't like 112 // 2) We would prefer to use a class instead of a struct but we don't like
55 // the register initialization to depend on the particular initialization 113 // the register initialization to depend on the particular initialization
56 // order (which appears to be different on OS X, Linux, and Windows for the 114 // order (which appears to be different on OS X, Linux, and Windows for the
57 // installed versions of C++ we tried). Using a struct permits C-style 115 // installed versions of C++ we tried). Using a struct permits C-style
58 // "initialization". Also, the Register objects cannot be const as this 116 // "initialization". Also, the Register objects cannot be const as this
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 367
310 // Hints are not used on the arm. Negating is trivial. 368 // Hints are not used on the arm. Negating is trivial.
311 inline Hint NegateHint(Hint ignored) { return no_hint; } 369 inline Hint NegateHint(Hint ignored) { return no_hint; }
312 370
313 371
314 // ----------------------------------------------------------------------------- 372 // -----------------------------------------------------------------------------
315 // Addressing modes and instruction variants 373 // Addressing modes and instruction variants
316 374
317 // Shifter operand shift operation 375 // Shifter operand shift operation
318 enum ShiftOp { 376 enum ShiftOp {
319 LSL = 0 << 5, 377 LSL = 0,
320 LSR = 1 << 5, 378 LSR = 1,
321 ASR = 2 << 5, 379 ASR = 2,
322 ROR = 3 << 5, 380 ROR = 3,
323 RRX = -1 381 RRX = -1
324 }; 382 };
325 383
326 384
327 // Condition code updating mode 385 // Condition code updating mode
328 enum SBit { 386 enum SBit {
329 SetCC = 1 << 20, // set condition code 387 SetCC = 1 << 20, // set condition code
330 LeaveCC = 0 << 20 // leave condition code unchanged 388 LeaveCC = 0 << 20 // leave condition code unchanged
331 }; 389 };
332 390
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 explicit Scope(CpuFeature f) {} 555 explicit Scope(CpuFeature f) {}
498 #endif 556 #endif
499 }; 557 };
500 558
501 private: 559 private:
502 static unsigned supported_; 560 static unsigned supported_;
503 static unsigned enabled_; 561 static unsigned enabled_;
504 static unsigned found_by_runtime_probing_; 562 static unsigned found_by_runtime_probing_;
505 }; 563 };
506 564
565 typedef int32_t InstrArm;
566 typedef int16_t InstrThumb;
507 567
508 typedef int32_t Instr; 568 // Hack to keep the code patcher happy for now.
569 typedef InstrArm Instr;
509 570
510 571
511 extern const Instr kMovLrPc; 572 extern const InstrArm kMovLrPc;
512 extern const Instr kLdrPCPattern; 573 extern const InstrArm kLdrPCPattern;
513 574
514 575
515 class Assembler : public Malloced { 576 class Assembler : public Malloced {
516 public: 577 public:
517 // Create an assembler. Instructions and relocation information are emitted 578 // Create an assembler. Instructions and relocation information are emitted
518 // into a buffer, with the instructions starting from the beginning and the 579 // into a buffer, with the instructions starting from the beginning and the
519 // relocation information starting from the end of the buffer. See CodeDesc 580 // relocation information starting from the end of the buffer. See CodeDesc
520 // for a detailed comment on the layout (globals.h). 581 // for a detailed comment on the layout (globals.h).
521 // 582 //
522 // If the provided buffer is NULL, the assembler allocates and grows its own 583 // If the provided buffer is NULL, the assembler allocates and grows its own
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 set_target_at(constant_pool_entry, target); 641 set_target_at(constant_pool_entry, target);
581 } 642 }
582 643
583 // Here we are patching the address in the constant pool, not the actual call 644 // Here we are patching the address in the constant pool, not the actual call
584 // instruction. The address in the constant pool is the same size as a 645 // instruction. The address in the constant pool is the same size as a
585 // pointer. 646 // pointer.
586 static const int kCallTargetSize = kPointerSize; 647 static const int kCallTargetSize = kPointerSize;
587 static const int kExternalTargetSize = kPointerSize; 648 static const int kExternalTargetSize = kPointerSize;
588 649
589 // Size of an instruction. 650 // Size of an instruction.
651 static const int kInstrArmSize = sizeof(InstrArm);
652 static const int kInstrThumbSize = sizeof(InstrThumb);
653 // Keep the code generator happy for now.
590 static const int kInstrSize = sizeof(Instr); 654 static const int kInstrSize = sizeof(Instr);
591 655
592 // Distance between the instruction referring to the address of the call 656 // Distance between the instruction referring to the address of the call
593 // target (ldr pc, [target addr in const pool]) and the return address 657 // target (ldr pc, [target addr in const pool]) and the return address
594 static const int kCallTargetAddressOffset = kInstrSize; 658 static const int kCallTargetAddressOffset = kInstrArmSize;
595 659
596 // Distance between start of patched return sequence and the emitted address 660 // Distance between start of patched return sequence and the emitted address
597 // to jump to. 661 // to jump to.
598 static const int kPatchReturnSequenceAddressOffset = kInstrSize; 662 static const int kPatchReturnSequenceAddressOffset = kInstrArmSize;
599 663
600 // Difference between address of current opcode and value read from pc 664 // Difference between address of current opcode and value read from pc
601 // register. 665 // register.
602 static const int kPcLoadDelta = 8; 666 static const int kPcLoadDelta = 8;
603 667
604 static const int kJSReturnSequenceLength = 4; 668 static const int kJSReturnSequenceLength = 4;
605 669
606 // --------------------------------------------------------------------------- 670 // ---------------------------------------------------------------------------
607 // Code generation 671 // Code generation
608 672
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 930
867 // Load effective address of memory operand x into register dst 931 // Load effective address of memory operand x into register dst
868 void lea(Register dst, const MemOperand& x, 932 void lea(Register dst, const MemOperand& x,
869 SBit s = LeaveCC, Condition cond = al); 933 SBit s = LeaveCC, Condition cond = al);
870 934
871 // Jump unconditionally to given label. 935 // Jump unconditionally to given label.
872 void jmp(Label* L) { b(L, al); } 936 void jmp(Label* L) { b(L, al); }
873 937
874 // Check the code size generated from label to here. 938 // Check the code size generated from label to here.
875 int InstructionsGeneratedSince(Label* l) { 939 int InstructionsGeneratedSince(Label* l) {
876 return (pc_offset() - l->pos()) / kInstrSize; 940 return (pc_offset() - l->pos()) / kInstrArmSize;
877 } 941 }
878 942
879 // Check whether an immediate fits an addressing mode 1 instruction. 943 // Check whether an immediate fits an addressing mode 1 instruction.
880 bool ImmediateFitsAddrMode1Instruction(int32_t imm32); 944 bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
881 945
882 // Postpone the generation of the constant pool for the specified number of 946 // Postpone the generation of the constant pool for the specified number of
883 // instructions. 947 // instructions.
884 void BlockConstPoolFor(int instructions); 948 void BlockConstPoolFor(int instructions);
885 949
886 // Debugging 950 // Debugging
(...skipping 10 matching lines...) Expand all
897 void WriteRecordedPositions(); 961 void WriteRecordedPositions();
898 962
899 int pc_offset() const { return pc_ - buffer_; } 963 int pc_offset() const { return pc_ - buffer_; }
900 int current_position() const { return current_position_; } 964 int current_position() const { return current_position_; }
901 int current_statement_position() const { return current_position_; } 965 int current_statement_position() const { return current_position_; }
902 966
903 protected: 967 protected:
904 int buffer_space() const { return reloc_info_writer.pos() - pc_; } 968 int buffer_space() const { return reloc_info_writer.pos() - pc_; }
905 969
906 // Read/patch instructions 970 // Read/patch instructions
907 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 971 static InstrArm instr_arm_at(byte* pc) {
908 void instr_at_put(byte* pc, Instr instr) { 972 return *reinterpret_cast<InstrArm*>(pc);
909 *reinterpret_cast<Instr*>(pc) = instr;
910 } 973 }
911 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 974
912 void instr_at_put(int pos, Instr instr) { 975 void instr_arm_at_put(byte* pc, InstrArm instr) {
913 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 976 *reinterpret_cast<InstrArm*>(pc) = instr;
977 }
978
979 InstrArm instr_arm_at(int pos) {
980 return *reinterpret_cast<InstrArm*>(buffer_ + pos);
981 }
982
983 void instr_arm_at_put(int pos, InstrArm instr) {
984 *reinterpret_cast<InstrArm*>(buffer_ + pos) = instr;
914 } 985 }
915 986
916 // Decode branch instruction at pos and return branch target pos 987 // Decode branch instruction at pos and return branch target pos
917 int target_at(int pos); 988 int target_at(int pos);
918 989
919 // Patch branch instruction at pos to branch to given branch target pos 990 // Patch branch instruction at pos to branch to given branch target pos
920 void target_at_put(int pos, int target_pos); 991 void target_at_put(int pos, int target_pos);
921 992
922 // Check if is time to emit a constant pool for pending reloc info entries 993 // Check if is time to emit a constant pool for pending reloc info entries
923 void CheckConstPool(bool force_emit, bool require_jump); 994 void CheckConstPool(bool force_emit, bool require_jump);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 // location it is accessed from. In this case, we emit a jump over the emitted 1027 // location it is accessed from. In this case, we emit a jump over the emitted
957 // constant pool. 1028 // constant pool.
958 // Constants in the pool may be addresses of functions that gets relocated; 1029 // Constants in the pool may be addresses of functions that gets relocated;
959 // if so, a relocation info entry is associated to the constant pool entry. 1030 // if so, a relocation info entry is associated to the constant pool entry.
960 1031
961 // Repeated checking whether the constant pool should be emitted is rather 1032 // Repeated checking whether the constant pool should be emitted is rather
962 // expensive. By default we only check again once a number of instructions 1033 // expensive. By default we only check again once a number of instructions
963 // has been generated. That also means that the sizing of the buffers is not 1034 // has been generated. That also means that the sizing of the buffers is not
964 // an exact science, and that we rely on some slop to not overrun buffers. 1035 // an exact science, and that we rely on some slop to not overrun buffers.
965 static const int kCheckConstIntervalInst = 32; 1036 static const int kCheckConstIntervalInst = 32;
966 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; 1037 static const int kCheckConstInterval =
1038 kCheckConstIntervalInst * kInstrArmSize;
967 1039
968 1040
969 // Pools are emitted after function return and in dead code at (more or less) 1041 // Pools are emitted after function return and in dead code at (more or less)
970 // regular intervals of kDistBetweenPools bytes 1042 // regular intervals of kDistBetweenPools bytes
971 static const int kDistBetweenPools = 1*KB; 1043 static const int kDistBetweenPools = 1*KB;
972 1044
973 // Constants in pools are accessed via pc relative addressing, which can 1045 // Constants in pools are accessed via pc relative addressing, which can
974 // reach +/-4KB thereby defining a maximum distance between the instruction 1046 // reach +/-4KB thereby defining a maximum distance between the instruction
975 // and the accessed constant. We satisfy this constraint by limiting the 1047 // and the accessed constant. We satisfy this constraint by limiting the
976 // distance between pools. 1048 // distance between pools.
977 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval; 1049 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval;
978 1050
979 // Emission of the constant pool may be blocked in some code sequences 1051 // Emission of the constant pool may be blocked in some code sequences
980 int no_const_pool_before_; // block emission before this pc offset 1052 int no_const_pool_before_; // block emission before this pc offset
981 1053
982 // Keep track of the last emitted pool to guarantee a maximal distance 1054 // Keep track of the last emitted pool to guarantee a maximal distance
983 int last_const_pool_end_; // pc offset following the last constant pool 1055 int last_const_pool_end_; // pc offset following the last constant pool
984 1056
985 // Relocation info generation 1057 // Relocation info generation
986 // Each relocation is encoded as a variable size value 1058 // Each relocation is encoded as a variable size value
987 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1059 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
988 RelocInfoWriter reloc_info_writer; 1060 RelocInfoWriter reloc_info_writer;
989 // Relocation info records are also used during code generation as temporary 1061 // Relocation info records are also used during code generation as temporary
990 // containers for constants and code target addresses until they are emitted 1062 // containers for constants and code target addresses until they are emitted
991 // to the constant pool. These pending relocation info records are temporarily 1063 // to the constant pool. These pending relocation info records are temporarily
992 // stored in a separate buffer until a constant pool is emitted. 1064 // stored in a separate buffer until a constant pool is emitted.
993 // If every instruction in a long sequence is accessing the pool, we need one 1065 // If every instruction in a long sequence is accessing the pool, we need one
994 // pending relocation entry per instruction. 1066 // pending relocation entry per instruction.
995 static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize; 1067 static const int kMaxNumPRInfo = kMaxDistBetweenPools / kInstrArmSize;
996 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info 1068 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info
997 int num_prinfo_; // number of pending reloc info entries in the buffer 1069 int num_prinfo_; // number of pending reloc info entries in the buffer
998 1070
999 // The bound position, before this we cannot do instruction elimination. 1071 // The bound position, before this we cannot do instruction elimination.
1000 int last_bound_pos_; 1072 int last_bound_pos_;
1001 1073
1002 // source position information 1074 // source position information
1003 int current_position_; 1075 int current_position_;
1004 int current_statement_position_; 1076 int current_statement_position_;
1005 int written_position_; 1077 int written_position_;
1006 int written_statement_position_; 1078 int written_statement_position_;
1079 bool thumb_mode_;
1080
1007 1081
1008 // Code emission 1082 // Code emission
1009 inline void CheckBuffer(); 1083 inline void CheckBuffer();
1084 inline void EnsureThumbMode();
1085 inline void EnsureArmMode();
1010 void GrowBuffer(); 1086 void GrowBuffer();
1011 inline void emit(Instr x); 1087 inline void emit_thumb(InstrThumb x);
1088 inline void emit_arm(InstrArm x);
1089 inline void emit_int32(int32_t x);
1012 1090
1013 // Instruction generation 1091 // ARM Instruction generation
1014 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); 1092 void addrmod1(InstrArm instr, Register rn, Register rd, const Operand& x);
1015 void addrmod2(Instr instr, Register rd, const MemOperand& x); 1093 void addrmod2(InstrArm instr, Register rd, const MemOperand& x);
1016 void addrmod3(Instr instr, Register rd, const MemOperand& x); 1094 void addrmod3(InstrArm instr, Register rd, const MemOperand& x);
1017 void addrmod4(Instr instr, Register rn, RegList rl); 1095 void addrmod4(InstrArm instr, Register rn, RegList rl);
1018 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); 1096 void addrmod5(InstrArm instr, CRegister crd, const MemOperand& x);
1097
1098 // Thumb2 Instruction generation
1099 void DataProcessing(Condition cond, Opcode op, SBit s,
1100 Register rn, Register rd, const Operand& x);
1101 void DataProcessingReg(Opcode op, SBit s, Register rn, Register rd,
1102 Register rm, ShiftOp shiftOp, int shiftBy);
1103 void DataProcessingImm(Opcode op, SBit s, Register rn, Register rd, int imm);
1019 1104
1020 // Labels 1105 // Labels
1021 void print(Label* L); 1106 void print(Label* L);
1022 void bind_to(Label* L, int pos); 1107 void bind_to(Label* L, int pos);
1023 void link_to(Label* L, Label* appendix); 1108 void link_to(Label* L, Label* appendix);
1024 void next(Label* L); 1109 void next(Label* L);
1025 1110
1026 // Record reloc info for current pc_ 1111 // Record reloc info for current pc_
1027 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1112 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1028 1113
1029 friend class RegExpMacroAssemblerARM; 1114 friend class RegExpMacroAssemblerARM;
1030 friend class RelocInfo; 1115 friend class RelocInfo;
1031 friend class CodePatcher; 1116 friend class CodePatcher;
1032 }; 1117 };
1033 1118
1034 } } // namespace v8::internal 1119 } } // namespace v8::internal
1035 1120
1036 #endif // V8_ARM_ASSEMBLER_THUMB2_H_ 1121 #endif // V8_ARM_ASSEMBLER_THUMB2_H_
OLDNEW
« no previous file with comments | « src/arm/assembler-arm-inl.h ('k') | src/arm/assembler-thumb2.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698