00001 // Copyright 2006-2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_MACRO_ASSEMBLER_ARM_H_ 00029 #define V8_MACRO_ASSEMBLER_ARM_H_ 00030 00031 #include "assembler.h" 00032 00033 namespace v8 { namespace internal { 00034 00035 00036 // Give alias names to registers 00037 extern Register cp; // JavaScript context pointer 00038 extern Register pp; // parameter pointer 00039 00040 00041 // Helper types to make boolean flag easier to read at call-site. 00042 enum InvokeFlag { 00043 CALL_FUNCTION, 00044 JUMP_FUNCTION 00045 }; 00046 00047 enum InvokeJSFlags { 00048 CALL_JS, 00049 JUMP_JS 00050 }; 00051 00052 enum ExitJSFlag { 00053 RETURN, 00054 DO_NOT_RETURN 00055 }; 00056 00057 enum CodeLocation { 00058 IN_JAVASCRIPT, 00059 IN_JS_ENTRY, 00060 IN_C_ENTRY 00061 }; 00062 00063 enum HandlerType { 00064 TRY_CATCH_HANDLER, 00065 TRY_FINALLY_HANDLER, 00066 JS_ENTRY_HANDLER 00067 }; 00068 00069 00070 // MacroAssembler implements a collection of frequently used macros. 00071 class MacroAssembler: public Assembler { 00072 public: 00073 MacroAssembler(void* buffer, int size); 00074 00075 // --------------------------------------------------------------------------- 00076 // Low-level helpers for compiler 00077 00078 // Jump, Call, and Ret pseudo instructions implementing inter-working 00079 private: 00080 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 00081 void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al); 00082 public: 00083 void Jump(Register target, Condition cond = al); 00084 void Jump(byte* target, RelocInfo::Mode rmode, Condition cond = al); 00085 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al); 00086 void Call(Register target, Condition cond = al); 00087 void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al); 00088 void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al); 00089 void Ret(); 00090 00091 00092 // Sets the remembered set bit for [address+offset], where address is the 00093 // address of the heap object 'object'. The address must be in the first 8K 00094 // of an allocated page. The 'scratch' register is used in the 00095 // implementation and all 3 registers are clobbered by the operation, as 00096 // well as the ip register. 00097 void RecordWrite(Register object, Register offset, Register scratch); 00098 00099 // --------------------------------------------------------------------------- 00100 // Activation frames 00101 00102 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } 00103 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } 00104 00105 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 00106 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 00107 00108 // Enter specific kind of exit frame; either EXIT or 00109 // EXIT_DEBUG. Expects the number of arguments in register r0 and 00110 // the builtin function to call in register r1. Exits with argc in 00111 // r4, argv in r6, and and the builtin function to call in r5. 00112 void EnterExitFrame(StackFrame::Type type); 00113 00114 // Leave the current exit frame. Expects the return value in r0. 00115 void LeaveExitFrame(StackFrame::Type type); 00116 00117 00118 // --------------------------------------------------------------------------- 00119 // JavaScript invokes 00120 00121 // Invoke the JavaScript function code by either calling or jumping. 00122 void InvokeCode(Register code, 00123 const ParameterCount& expected, 00124 const ParameterCount& actual, 00125 InvokeFlag flag); 00126 00127 void InvokeCode(Handle<Code> code, 00128 const ParameterCount& expected, 00129 const ParameterCount& actual, 00130 RelocInfo::Mode rmode, 00131 InvokeFlag flag); 00132 00133 // Invoke the JavaScript function in the given register. Changes the 00134 // current context to the context in the function before invoking. 00135 void InvokeFunction(Register function, 00136 const ParameterCount& actual, 00137 InvokeFlag flag); 00138 00139 00140 // --------------------------------------------------------------------------- 00141 // Debugger Support 00142 00143 void SaveRegistersToMemory(RegList regs); 00144 void RestoreRegistersFromMemory(RegList regs); 00145 void CopyRegistersFromMemoryToStack(Register base, RegList regs); 00146 void CopyRegistersFromStackToMemory(Register base, 00147 Register scratch, 00148 RegList regs); 00149 00150 00151 // --------------------------------------------------------------------------- 00152 // Exception handling 00153 00154 // Push a new try handler and link into try handler chain. 00155 // The return address must be passed in register lr. 00156 // On exit, r0 contains TOS (code slot). 00157 void PushTryHandler(CodeLocation try_location, HandlerType type); 00158 00159 00160 // --------------------------------------------------------------------------- 00161 // Inline caching support 00162 00163 // Generates code that verifies that the maps of objects in the 00164 // prototype chain of object hasn't changed since the code was 00165 // generated and branches to the miss label if any map has. If 00166 // necessary the function also generates code for security check 00167 // in case of global object holders. The scratch and holder 00168 // registers are always clobbered, but the object register is only 00169 // clobbered if it the same as the holder register. The function 00170 // returns a register containing the holder - either object_reg or 00171 // holder_reg. 00172 Register CheckMaps(JSObject* object, Register object_reg, 00173 JSObject* holder, Register holder_reg, 00174 Register scratch, Label* miss); 00175 00176 // Generate code for checking access rights - used for security checks 00177 // on access to global objects across environments. The holder register 00178 // is left untouched, whereas both scratch registers are clobbered. 00179 void CheckAccessGlobalProxy(Register holder_reg, 00180 Register scratch, 00181 Label* miss); 00182 00183 00184 // --------------------------------------------------------------------------- 00185 // Support functions. 00186 00187 // Generates code for reporting that an illegal operation has 00188 // occurred. 00189 void IllegalOperation(int num_arguments); 00190 00191 00192 // --------------------------------------------------------------------------- 00193 // Runtime calls 00194 00195 // Call a code stub. 00196 void CallStub(CodeStub* stub); 00197 void CallJSExitStub(CodeStub* stub); 00198 00199 // Return from a code stub after popping its arguments. 00200 void StubReturn(int argc); 00201 00202 // Call a runtime routine. 00203 // Eventually this should be used for all C calls. 00204 void CallRuntime(Runtime::Function* f, int num_arguments); 00205 00206 // Convenience function: Same as above, but takes the fid instead. 00207 void CallRuntime(Runtime::FunctionId fid, int num_arguments); 00208 00209 // Tail call of a runtime routine (jump). 00210 // Like JumpToBuiltin, but also takes care of passing the number 00211 // of parameters. 00212 void TailCallRuntime(const ExternalReference& ext, int num_arguments); 00213 00214 // Jump to the builtin routine. 00215 void JumpToBuiltin(const ExternalReference& builtin); 00216 00217 // Invoke specified builtin JavaScript function. Adds an entry to 00218 // the unresolved list if the name does not resolve. 00219 void InvokeBuiltin(Builtins::JavaScript id, InvokeJSFlags flags); 00220 00221 // Store the code object for the given builtin in the target register and 00222 // setup the function in r1. 00223 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 00224 00225 struct Unresolved { 00226 int pc; 00227 uint32_t flags; // see Bootstrapper::FixupFlags decoders/encoders. 00228 const char* name; 00229 }; 00230 List<Unresolved>* unresolved() { return &unresolved_; } 00231 00232 00233 // --------------------------------------------------------------------------- 00234 // Debugging 00235 00236 // Calls Abort(msg) if the condition cc is not satisfied. 00237 // Use --debug_code to enable. 00238 void Assert(Condition cc, const char* msg); 00239 00240 // Like Assert(), but always enabled. 00241 void Check(Condition cc, const char* msg); 00242 00243 // Print a message to stdout and abort execution. 00244 void Abort(const char* msg); 00245 00246 // Verify restrictions about code generated in stubs. 00247 void set_generating_stub(bool value) { generating_stub_ = value; } 00248 bool generating_stub() { return generating_stub_; } 00249 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 00250 bool allow_stub_calls() { return allow_stub_calls_; } 00251 00252 private: 00253 List<Unresolved> unresolved_; 00254 bool generating_stub_; 00255 bool allow_stub_calls_; 00256 00257 // Helper functions for generating invokes. 00258 void InvokePrologue(const ParameterCount& expected, 00259 const ParameterCount& actual, 00260 Handle<Code> code_constant, 00261 Register code_reg, 00262 Label* done, 00263 InvokeFlag flag); 00264 00265 // Get the code for the given builtin. Returns if able to resolve 00266 // the function in the 'resolved' flag. 00267 Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved); 00268 00269 // Activation support. 00270 void EnterFrame(StackFrame::Type type); 00271 void LeaveFrame(StackFrame::Type type); 00272 }; 00273 00274 00275 // ----------------------------------------------------------------------------- 00276 // Static helper functions. 00277 00278 // Generate a MemOperand for loading a field from an object. 00279 static inline MemOperand FieldMemOperand(Register object, int offset) { 00280 return MemOperand(object, offset - kHeapObjectTag); 00281 } 00282 00283 00284 00285 } } // namespace v8::internal 00286 00287 #endif // V8_MACRO_ASSEMBLER_ARM_H_