Index: src/x64/code-stubs-x64.h |
=================================================================== |
--- src/x64/code-stubs-x64.h (revision 0) |
+++ src/x64/code-stubs-x64.h (revision 0) |
@@ -0,0 +1,392 @@ |
+// Copyright 2010 the V8 project authors. All rights reserved. |
+// Redistribution and use in source and binary forms, with or without |
+// modification, are permitted provided that the following conditions are |
+// met: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+#ifndef V8_X64_CODE_STUBS_X64_H_ |
+#define V8_X64_CODE_STUBS_X64_H_ |
+ |
+#include "codegen-inl.h" |
+#include "ast.h" |
+#include "ic-inl.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+ |
+// Compute a transcendental math function natively, or call the |
+// TranscendentalCache runtime function. |
+class TranscendentalCacheStub: public CodeStub { |
+ public: |
+ explicit TranscendentalCacheStub(TranscendentalCache::Type type) |
+ : type_(type) {} |
+ void Generate(MacroAssembler* masm); |
+ private: |
+ TranscendentalCache::Type type_; |
+ Major MajorKey() { return TranscendentalCache; } |
+ int MinorKey() { return type_; } |
+ Runtime::FunctionId RuntimeFunction(); |
+ void GenerateOperation(MacroAssembler* masm, Label* on_nan_result); |
+}; |
+ |
+ |
+class ToBooleanStub: public CodeStub { |
+ public: |
+ ToBooleanStub() { } |
+ |
+ void Generate(MacroAssembler* masm); |
+ |
+ private: |
+ Major MajorKey() { return ToBoolean; } |
+ int MinorKey() { return 0; } |
+}; |
+ |
+ |
+// Flag that indicates how to generate code for the stub GenericBinaryOpStub. |
+enum GenericBinaryFlags { |
+ NO_GENERIC_BINARY_FLAGS = 0, |
+ NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. |
+}; |
+ |
+ |
+class GenericBinaryOpStub: public CodeStub { |
+ public: |
+ GenericBinaryOpStub(Token::Value op, |
+ OverwriteMode mode, |
+ GenericBinaryFlags flags, |
+ TypeInfo operands_type = TypeInfo::Unknown()) |
+ : op_(op), |
+ mode_(mode), |
+ flags_(flags), |
+ args_in_registers_(false), |
+ args_reversed_(false), |
+ static_operands_type_(operands_type), |
+ runtime_operands_type_(BinaryOpIC::DEFAULT), |
+ name_(NULL) { |
+ ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
+ } |
+ |
+ GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) |
+ : op_(OpBits::decode(key)), |
+ mode_(ModeBits::decode(key)), |
+ flags_(FlagBits::decode(key)), |
+ args_in_registers_(ArgsInRegistersBits::decode(key)), |
+ args_reversed_(ArgsReversedBits::decode(key)), |
+ static_operands_type_(TypeInfo::ExpandedRepresentation( |
+ StaticTypeInfoBits::decode(key))), |
+ runtime_operands_type_(type_info), |
+ name_(NULL) { |
+ } |
+ |
+ // Generate code to call the stub with the supplied arguments. This will add |
+ // code at the call site to prepare arguments either in registers or on the |
+ // stack together with the actual call. |
+ void GenerateCall(MacroAssembler* masm, Register left, Register right); |
+ void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
+ void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
+ |
+ Result GenerateCall(MacroAssembler* masm, |
+ VirtualFrame* frame, |
+ Result* left, |
+ Result* right); |
+ |
+ private: |
+ Token::Value op_; |
+ OverwriteMode mode_; |
+ GenericBinaryFlags flags_; |
+ bool args_in_registers_; // Arguments passed in registers not on the stack. |
+ bool args_reversed_; // Left and right argument are swapped. |
+ |
+ // Number type information of operands, determined by code generator. |
+ TypeInfo static_operands_type_; |
+ |
+ // Operand type information determined at runtime. |
+ BinaryOpIC::TypeInfo runtime_operands_type_; |
+ |
+ char* name_; |
+ |
+ const char* GetName(); |
+ |
+#ifdef DEBUG |
+ void Print() { |
+ PrintF("GenericBinaryOpStub %d (op %s), " |
+ "(mode %d, flags %d, registers %d, reversed %d, only_numbers %s)\n", |
+ MinorKey(), |
+ Token::String(op_), |
+ static_cast<int>(mode_), |
+ static_cast<int>(flags_), |
+ static_cast<int>(args_in_registers_), |
+ static_cast<int>(args_reversed_), |
+ static_operands_type_.ToString()); |
+ } |
+#endif |
+ |
+ // Minor key encoding in 17 bits TTNNNFRAOOOOOOOMM. |
+ class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
+ class OpBits: public BitField<Token::Value, 2, 7> {}; |
+ class ArgsInRegistersBits: public BitField<bool, 9, 1> {}; |
+ class ArgsReversedBits: public BitField<bool, 10, 1> {}; |
+ class FlagBits: public BitField<GenericBinaryFlags, 11, 1> {}; |
+ class StaticTypeInfoBits: public BitField<int, 12, 3> {}; |
+ class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 15, 2> {}; |
+ |
+ Major MajorKey() { return GenericBinaryOp; } |
+ int MinorKey() { |
+ // Encode the parameters in a unique 18 bit value. |
+ return OpBits::encode(op_) |
+ | ModeBits::encode(mode_) |
+ | FlagBits::encode(flags_) |
+ | ArgsInRegistersBits::encode(args_in_registers_) |
+ | ArgsReversedBits::encode(args_reversed_) |
+ | StaticTypeInfoBits::encode( |
+ static_operands_type_.ThreeBitRepresentation()) |
+ | RuntimeTypeInfoBits::encode(runtime_operands_type_); |
+ } |
+ |
+ void Generate(MacroAssembler* masm); |
+ void GenerateSmiCode(MacroAssembler* masm, Label* slow); |
+ void GenerateLoadArguments(MacroAssembler* masm); |
+ void GenerateReturn(MacroAssembler* masm); |
+ void GenerateRegisterArgsPush(MacroAssembler* masm); |
+ void GenerateTypeTransition(MacroAssembler* masm); |
+ |
+ bool ArgsInRegistersSupported() { |
+ return (op_ == Token::ADD) || (op_ == Token::SUB) |
+ || (op_ == Token::MUL) || (op_ == Token::DIV); |
+ } |
+ bool IsOperationCommutative() { |
+ return (op_ == Token::ADD) || (op_ == Token::MUL); |
+ } |
+ |
+ void SetArgsInRegisters() { args_in_registers_ = true; } |
+ void SetArgsReversed() { args_reversed_ = true; } |
+ bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } |
+ bool HasArgsInRegisters() { return args_in_registers_; } |
+ bool HasArgsReversed() { return args_reversed_; } |
+ |
+ bool ShouldGenerateSmiCode() { |
+ return HasSmiCodeInStub() && |
+ runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && |
+ runtime_operands_type_ != BinaryOpIC::STRINGS; |
+ } |
+ |
+ bool ShouldGenerateFPCode() { |
+ return runtime_operands_type_ != BinaryOpIC::STRINGS; |
+ } |
+ |
+ virtual int GetCodeKind() { return Code::BINARY_OP_IC; } |
+ |
+ virtual InlineCacheState GetICState() { |
+ return BinaryOpIC::ToState(runtime_operands_type_); |
+ } |
+}; |
+ |
+class StringHelper : public AllStatic { |
+ public: |
+ // Generate code for copying characters using a simple loop. This should only |
+ // be used in places where the number of characters is small and the |
+ // additional setup and checking in GenerateCopyCharactersREP adds too much |
+ // overhead. Copying of overlapping regions is not supported. |
+ static void GenerateCopyCharacters(MacroAssembler* masm, |
+ Register dest, |
+ Register src, |
+ Register count, |
+ bool ascii); |
+ |
+ // Generate code for copying characters using the rep movs instruction. |
+ // Copies rcx characters from rsi to rdi. Copying of overlapping regions is |
+ // not supported. |
+ static void GenerateCopyCharactersREP(MacroAssembler* masm, |
+ Register dest, // Must be rdi. |
+ Register src, // Must be rsi. |
+ Register count, // Must be rcx. |
+ bool ascii); |
+ |
+ |
+ // Probe the symbol table for a two character string. If the string is |
+ // not found by probing a jump to the label not_found is performed. This jump |
+ // does not guarantee that the string is not in the symbol table. If the |
+ // string is found the code falls through with the string in register rax. |
+ static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
+ Register c1, |
+ Register c2, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Register scratch4, |
+ Label* not_found); |
+ |
+ // Generate string hash. |
+ static void GenerateHashInit(MacroAssembler* masm, |
+ Register hash, |
+ Register character, |
+ Register scratch); |
+ static void GenerateHashAddCharacter(MacroAssembler* masm, |
+ Register hash, |
+ Register character, |
+ Register scratch); |
+ static void GenerateHashGetHash(MacroAssembler* masm, |
+ Register hash, |
+ Register scratch); |
+ |
+ private: |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); |
+}; |
+ |
+ |
+// Flag that indicates how to generate code for the stub StringAddStub. |
+enum StringAddFlags { |
+ NO_STRING_ADD_FLAGS = 0, |
+ NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. |
+}; |
+ |
+ |
+class StringAddStub: public CodeStub { |
+ public: |
+ explicit StringAddStub(StringAddFlags flags) { |
+ string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0); |
+ } |
+ |
+ private: |
+ Major MajorKey() { return StringAdd; } |
+ int MinorKey() { return string_check_ ? 0 : 1; } |
+ |
+ void Generate(MacroAssembler* masm); |
+ |
+ // Should the stub check whether arguments are strings? |
+ bool string_check_; |
+}; |
+ |
+ |
+class SubStringStub: public CodeStub { |
+ public: |
+ SubStringStub() {} |
+ |
+ private: |
+ Major MajorKey() { return SubString; } |
+ int MinorKey() { return 0; } |
+ |
+ void Generate(MacroAssembler* masm); |
+}; |
+ |
+ |
+class StringCompareStub: public CodeStub { |
+ public: |
+ explicit StringCompareStub() {} |
+ |
+ // Compare two flat ascii strings and returns result in rax after popping two |
+ // arguments from the stack. |
+ static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
+ Register left, |
+ Register right, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Register scratch4); |
+ |
+ private: |
+ Major MajorKey() { return StringCompare; } |
+ int MinorKey() { return 0; } |
+ |
+ void Generate(MacroAssembler* masm); |
+}; |
+ |
+ |
+class NumberToStringStub: public CodeStub { |
+ public: |
+ NumberToStringStub() { } |
+ |
+ // Generate code to do a lookup in the number string cache. If the number in |
+ // the register object is found in the cache the generated code falls through |
+ // with the result in the result register. The object and the result register |
+ // can be the same. If the number is not found in the cache the code jumps to |
+ // the label not_found with only the content of register object unchanged. |
+ static void GenerateLookupNumberStringCache(MacroAssembler* masm, |
+ Register object, |
+ Register result, |
+ Register scratch1, |
+ Register scratch2, |
+ bool object_is_smi, |
+ Label* not_found); |
+ |
+ private: |
+ static void GenerateConvertHashCodeToIndex(MacroAssembler* masm, |
+ Register hash, |
+ Register mask); |
+ |
+ Major MajorKey() { return NumberToString; } |
+ int MinorKey() { return 0; } |
+ |
+ void Generate(MacroAssembler* masm); |
+ |
+ const char* GetName() { return "NumberToStringStub"; } |
+ |
+#ifdef DEBUG |
+ void Print() { |
+ PrintF("NumberToStringStub\n"); |
+ } |
+#endif |
+}; |
+ |
+ |
+class RecordWriteStub : public CodeStub { |
+ public: |
+ RecordWriteStub(Register object, Register addr, Register scratch) |
+ : object_(object), addr_(addr), scratch_(scratch) { } |
+ |
+ void Generate(MacroAssembler* masm); |
+ |
+ private: |
+ Register object_; |
+ Register addr_; |
+ Register scratch_; |
+ |
+#ifdef DEBUG |
+ void Print() { |
+ PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n", |
+ object_.code(), addr_.code(), scratch_.code()); |
+ } |
+#endif |
+ |
+ // Minor key encoding in 12 bits. 4 bits for each of the three |
+ // registers (object, address and scratch) OOOOAAAASSSS. |
+ class ScratchBits : public BitField<uint32_t, 0, 4> {}; |
+ class AddressBits : public BitField<uint32_t, 4, 4> {}; |
+ class ObjectBits : public BitField<uint32_t, 8, 4> {}; |
+ |
+ Major MajorKey() { return RecordWrite; } |
+ |
+ int MinorKey() { |
+ // Encode the registers. |
+ return ObjectBits::encode(object_.code()) | |
+ AddressBits::encode(addr_.code()) | |
+ ScratchBits::encode(scratch_.code()); |
+ } |
+}; |
+ |
+ |
+} } // namespace v8::internal |
+ |
+#endif // V8_X64_CODE_STUBS_X64_H_ |
Property changes on: src/x64/code-stubs-x64.h |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |