1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 
6 #ifndef V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
7 #define V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
8 
9 #include "src/macro-assembler.h"
10 #include "src/mips64/assembler-mips64-inl.h"
11 #include "src/mips64/assembler-mips64.h"
12 #include "src/mips64/macro-assembler-mips64.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 #ifndef V8_INTERPRETED_REGEXP
18 class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
19  public:
20   RegExpMacroAssemblerMIPS(Mode mode, int registers_to_save, Zone* zone);
21   virtual ~RegExpMacroAssemblerMIPS();
22   virtual int stack_limit_slack();
23   virtual void AdvanceCurrentPosition(int by);
24   virtual void AdvanceRegister(int reg, int by);
25   virtual void Backtrack();
26   virtual void Bind(Label* label);
27   virtual void CheckAtStart(Label* on_at_start);
28   virtual void CheckCharacter(uint32_t c, Label* on_equal);
29   virtual void CheckCharacterAfterAnd(uint32_t c,
30                                       uint32_t mask,
31                                       Label* on_equal);
32   virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
33   virtual void CheckCharacterLT(uc16 limit, Label* on_less);
34   // A "greedy loop" is a loop that is both greedy and with a simple
35   // body. It has a particularly simple implementation.
36   virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
37   virtual void CheckNotAtStart(Label* on_not_at_start);
38   virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
39   virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
40                                                Label* on_no_match);
41   virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
42   virtual void CheckNotCharacterAfterAnd(uint32_t c,
43                                          uint32_t mask,
44                                          Label* on_not_equal);
45   virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
46                                               uc16 minus,
47                                               uc16 mask,
48                                               Label* on_not_equal);
49   virtual void CheckCharacterInRange(uc16 from,
50                                      uc16 to,
51                                      Label* on_in_range);
52   virtual void CheckCharacterNotInRange(uc16 from,
53                                         uc16 to,
54                                         Label* on_not_in_range);
55   virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
56 
57   // Checks whether the given offset from the current position is before
58   // the end of the string.
59   virtual void CheckPosition(int cp_offset, Label* on_outside_input);
60   virtual bool CheckSpecialCharacterClass(uc16 type,
61                                           Label* on_no_match);
62   virtual void Fail();
63   virtual Handle<HeapObject> GetCode(Handle<String> source);
64   virtual void GoTo(Label* label);
65   virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
66   virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
67   virtual void IfRegisterEqPos(int reg, Label* if_eq);
68   virtual IrregexpImplementation Implementation();
69   virtual void LoadCurrentCharacter(int cp_offset,
70                                     Label* on_end_of_input,
71                                     bool check_bounds = true,
72                                     int characters = 1);
73   virtual void PopCurrentPosition();
74   virtual void PopRegister(int register_index);
75   virtual void PushBacktrack(Label* label);
76   virtual void PushCurrentPosition();
77   virtual void PushRegister(int register_index,
78                             StackCheckFlag check_stack_limit);
79   virtual void ReadCurrentPositionFromRegister(int reg);
80   virtual void ReadStackPointerFromRegister(int reg);
81   virtual void SetCurrentPositionFromEnd(int by);
82   virtual void SetRegister(int register_index, int to);
83   virtual bool Succeed();
84   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
85   virtual void ClearRegisters(int reg_from, int reg_to);
86   virtual void WriteStackPointerToRegister(int reg);
87   virtual bool CanReadUnaligned();
88 
89   // Called from RegExp if the stack-guard is triggered.
90   // If the code object is relocated, the return address is fixed before
91   // returning.
92   static int CheckStackGuardState(Address* return_address,
93                                   Code* re_code,
94                                   Address re_frame);
95 
96   void print_regexp_frame_constants();
97 
98  private:
99 #if defined(MIPS_ABI_N64)
100   // Offsets from frame_pointer() of function parameters and stored registers.
101   static const int kFramePointer = 0;
102 
103   // Above the frame pointer - Stored registers and stack passed parameters.
104   // Registers s0 to s7, fp, and ra.
105   static const int kStoredRegisters = kFramePointer;
106   // Return address (stored from link register, read into pc on return).
107 
108 // TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp.
109 
110   static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
111   static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
112   // Stack frame header.
113   static const int kStackFrameHeader = kSecondaryReturnAddress;
114   // Stack parameters placed by caller.
115   static const int kIsolate = kStackFrameHeader + kPointerSize;
116 
117   // Below the frame pointer.
118   // Register parameters stored by setup code.
119   static const int kDirectCall = kFramePointer - kPointerSize;
120   static const int kStackHighEnd = kDirectCall - kPointerSize;
121   static const int kNumOutputRegisters = kStackHighEnd - kPointerSize;
122   static const int kRegisterOutput = kNumOutputRegisters - kPointerSize;
123   static const int kInputEnd = kRegisterOutput - kPointerSize;
124   static const int kInputStart = kInputEnd - kPointerSize;
125   static const int kStartIndex = kInputStart - kPointerSize;
126   static const int kInputString = kStartIndex - kPointerSize;
127   // When adding local variables remember to push space for them in
128   // the frame in GetCode.
129   static const int kSuccessfulCaptures = kInputString - kPointerSize;
130   static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
131   // First register address. Following registers are below it on the stack.
132   static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
133 
134 #elif defined(MIPS_ABI_O32)
135   // Offsets from frame_pointer() of function parameters and stored registers.
136   static const int kFramePointer = 0;
137 
138   // Above the frame pointer - Stored registers and stack passed parameters.
139   // Registers s0 to s7, fp, and ra.
140   static const int kStoredRegisters = kFramePointer;
141   // Return address (stored from link register, read into pc on return).
142   static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
143   static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
144   // Stack frame header.
145   static const int kStackFrameHeader = kReturnAddress + kPointerSize;
146   // Stack parameters placed by caller.
147   static const int kRegisterOutput =
148       kStackFrameHeader + 4 * kPointerSize + kPointerSize;
149   static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
150   static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
151   static const int kDirectCall = kStackHighEnd + kPointerSize;
152   static const int kIsolate = kDirectCall + kPointerSize;
153 
154   // Below the frame pointer.
155   // Register parameters stored by setup code.
156   static const int kInputEnd = kFramePointer - kPointerSize;
157   static const int kInputStart = kInputEnd - kPointerSize;
158   static const int kStartIndex = kInputStart - kPointerSize;
159   static const int kInputString = kStartIndex - kPointerSize;
160   // When adding local variables remember to push space for them in
161   // the frame in GetCode.
162   static const int kSuccessfulCaptures = kInputString - kPointerSize;
163   static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
164   // First register address. Following registers are below it on the stack.
165   static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
166 
167 #else
168 # error "undefined MIPS ABI"
169 #endif
170 
171   // Initial size of code buffer.
172   static const size_t kRegExpCodeSize = 1024;
173 
174   // Load a number of characters at the given offset from the
175   // current position, into the current-character register.
176   void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
177 
178   // Check whether preemption has been requested.
179   void CheckPreemption();
180 
181   // Check whether we are exceeding the stack limit on the backtrack stack.
182   void CheckStackLimit();
183 
184 
185   // Generate a call to CheckStackGuardState.
186   void CallCheckStackGuardState(Register scratch);
187 
188   // The ebp-relative location of a regexp register.
189   MemOperand register_location(int register_index);
190 
191   // Register holding the current input position as negative offset from
192   // the end of the string.
current_input_offset()193   inline Register current_input_offset() { return a6; }
194 
195   // The register containing the current character after LoadCurrentCharacter.
current_character()196   inline Register current_character() { return a7; }
197 
198   // Register holding address of the end of the input string.
end_of_input_address()199   inline Register end_of_input_address() { return t2; }
200 
201   // Register holding the frame address. Local variables, parameters and
202   // regexp registers are addressed relative to this.
frame_pointer()203   inline Register frame_pointer() { return fp; }
204 
205   // The register containing the backtrack stack top. Provides a meaningful
206   // name to the register.
backtrack_stackpointer()207   inline Register backtrack_stackpointer() { return t0; }
208 
209   // Register holding pointer to the current code object.
code_pointer()210   inline Register code_pointer() { return a5; }
211 
212   // Byte size of chars in the string to match (decided by the Mode argument).
char_size()213   inline int char_size() { return static_cast<int>(mode_); }
214 
215   // Equivalent to a conditional branch to the label, unless the label
216   // is NULL, in which case it is a conditional Backtrack.
217   void BranchOrBacktrack(Label* to,
218                          Condition condition,
219                          Register rs,
220                          const Operand& rt);
221 
222   // Call and return internally in the generated code in a way that
223   // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
224   inline void SafeCall(Label* to,
225                        Condition cond,
226                        Register rs,
227                        const Operand& rt);
228   inline void SafeReturn();
229   inline void SafeCallTarget(Label* name);
230 
231   // Pushes the value of a register on the backtrack stack. Decrements the
232   // stack pointer by a word size and stores the register's value there.
233   inline void Push(Register source);
234 
235   // Pops a value from the backtrack stack. Reads the word at the stack pointer
236   // and increments it by a word size.
237   inline void Pop(Register target);
238 
isolate()239   Isolate* isolate() const { return masm_->isolate(); }
240 
241   MacroAssembler* masm_;
242 
243   // Which mode to generate code for (Latin1 or UC16).
244   Mode mode_;
245 
246   // One greater than maximal register index actually used.
247   int num_registers_;
248 
249   // Number of registers to output at the end (the saved registers
250   // are always 0..num_saved_registers_-1).
251   int num_saved_registers_;
252 
253   // Labels used internally.
254   Label entry_label_;
255   Label start_label_;
256   Label success_label_;
257   Label backtrack_label_;
258   Label exit_label_;
259   Label check_preempt_label_;
260   Label stack_overflow_label_;
261   Label internal_failure_label_;
262 };
263 
264 #endif  // V8_INTERPRETED_REGEXP
265 
266 
267 }}  // namespace v8::internal
268 
269 #endif  // V8_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
270