Revision f230a1cf deps/v8/src/code-stubs.h
deps/v8/src/code-stubs.h | ||
---|---|---|
30 | 30 |
|
31 | 31 |
#include "allocation.h" |
32 | 32 |
#include "assembler.h" |
33 |
#include "globals.h" |
|
34 | 33 |
#include "codegen.h" |
34 |
#include "globals.h" |
|
35 |
#include "macro-assembler.h" |
|
35 | 36 |
|
36 | 37 |
namespace v8 { |
37 | 38 |
namespace internal { |
... | ... | |
200 | 201 |
|
201 | 202 |
virtual void PrintName(StringStream* stream); |
202 | 203 |
|
204 |
// Returns a name for logging/debugging purposes. |
|
205 |
SmartArrayPointer<const char> GetName(); |
|
206 |
|
|
203 | 207 |
protected: |
204 | 208 |
static bool CanUseFPRegisters(); |
205 | 209 |
|
206 | 210 |
// Generates the assembler code for the stub. |
207 | 211 |
virtual Handle<Code> GenerateCode(Isolate* isolate) = 0; |
208 | 212 |
|
213 |
virtual void VerifyPlatformFeatures(Isolate* isolate); |
|
209 | 214 |
|
210 | 215 |
// Returns whether the code generated for this stub needs to be allocated as |
211 | 216 |
// a fixed (non-moveable) code object. |
212 | 217 |
virtual bool NeedsImmovableCode() { return false; } |
213 | 218 |
|
214 |
// Returns a name for logging/debugging purposes. |
|
215 |
SmartArrayPointer<const char> GetName(); |
|
216 | 219 |
virtual void PrintBaseName(StringStream* stream); |
217 | 220 |
virtual void PrintState(StringStream* stream) { } |
218 | 221 |
|
... | ... | |
278 | 281 |
struct CodeStubInterfaceDescriptor { |
279 | 282 |
CodeStubInterfaceDescriptor(); |
280 | 283 |
int register_param_count_; |
281 |
const Register* stack_parameter_count_;
|
|
284 |
Register stack_parameter_count_;
|
|
282 | 285 |
// if hint_stack_parameter_count_ > 0, the code stub can optimize the |
283 | 286 |
// return sequence. Default value is -1, which means it is ignored. |
284 | 287 |
int hint_stack_parameter_count_; |
... | ... | |
287 | 290 |
Address deoptimization_handler_; |
288 | 291 |
|
289 | 292 |
int environment_length() const { |
290 |
if (stack_parameter_count_ != NULL) {
|
|
293 |
if (stack_parameter_count_.is_valid()) {
|
|
291 | 294 |
return register_param_count_ + 1; |
292 | 295 |
} |
293 | 296 |
return register_param_count_; |
... | ... | |
318 | 321 |
// defined outside of the platform directories |
319 | 322 |
#define DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index) \ |
320 | 323 |
((index) == (descriptor)->register_param_count_) \ |
321 |
? *((descriptor)->stack_parameter_count_) \
|
|
324 |
? (descriptor)->stack_parameter_count_ \
|
|
322 | 325 |
: (descriptor)->register_params_[(index)] |
323 | 326 |
|
324 | 327 |
|
... | ... | |
402 | 405 |
// Check right parameter. |
403 | 406 |
STRING_ADD_CHECK_RIGHT = 1 << 1, |
404 | 407 |
// Check both parameters. |
405 |
STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT, |
|
406 |
// Stub needs a frame before calling the runtime |
|
407 |
STRING_ADD_ERECT_FRAME = 1 << 2 |
|
408 |
STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT |
|
408 | 409 |
}; |
409 | 410 |
|
410 | 411 |
} } // namespace v8::internal |
... | ... | |
464 | 465 |
}; |
465 | 466 |
|
466 | 467 |
|
468 |
class NumberToStringStub V8_FINAL : public HydrogenCodeStub { |
|
469 |
public: |
|
470 |
NumberToStringStub() {} |
|
471 |
|
|
472 |
virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE; |
|
473 |
|
|
474 |
virtual void InitializeInterfaceDescriptor( |
|
475 |
Isolate* isolate, |
|
476 |
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; |
|
477 |
|
|
478 |
static void InstallDescriptors(Isolate* isolate); |
|
479 |
|
|
480 |
// Parameters accessed via CodeStubGraphBuilder::GetParameter() |
|
481 |
static const int kNumber = 0; |
|
482 |
|
|
483 |
private: |
|
484 |
virtual Major MajorKey() V8_OVERRIDE { return NumberToString; } |
|
485 |
virtual int NotMissMinorKey() V8_OVERRIDE { return 0; } |
|
486 |
}; |
|
487 |
|
|
488 |
|
|
467 | 489 |
class FastNewClosureStub : public HydrogenCodeStub { |
468 | 490 |
public: |
469 | 491 |
explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator) |
... | ... | |
830 | 852 |
|
831 | 853 |
class StringLengthStub: public ICStub { |
832 | 854 |
public: |
833 |
StringLengthStub(Code::Kind kind, bool support_wrapper) |
|
834 |
: ICStub(kind), support_wrapper_(support_wrapper) { } |
|
855 |
explicit StringLengthStub(Code::Kind kind) : ICStub(kind) { } |
|
835 | 856 |
virtual void Generate(MacroAssembler* masm); |
836 | 857 |
|
837 | 858 |
private: |
838 | 859 |
STATIC_ASSERT(KindBits::kSize == 4); |
839 |
class WrapperModeBits: public BitField<bool, 4, 1> {}; |
|
840 |
virtual CodeStub::Major MajorKey() { return StringLength; } |
|
841 |
virtual int MinorKey() { |
|
842 |
return KindBits::encode(kind()) | WrapperModeBits::encode(support_wrapper_); |
|
843 |
} |
|
844 |
|
|
845 |
bool support_wrapper_; |
|
860 |
virtual CodeStub::Major MajorKey() { return StringLength; } |
|
846 | 861 |
}; |
847 | 862 |
|
848 | 863 |
|
... | ... | |
892 | 907 |
|
893 | 908 |
class HandlerStub: public HICStub { |
894 | 909 |
public: |
895 |
virtual Code::Kind GetCodeKind() const { return Code::STUB; }
|
|
910 |
virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
|
|
896 | 911 |
virtual int GetStubFlags() { return kind(); } |
897 | 912 |
|
898 | 913 |
protected: |
... | ... | |
983 | 998 |
}; |
984 | 999 |
|
985 | 1000 |
|
986 |
class BinaryOpStub: public PlatformCodeStub {
|
|
1001 |
class BinaryOpStub: public HydrogenCodeStub {
|
|
987 | 1002 |
public: |
988 | 1003 |
BinaryOpStub(Token::Value op, OverwriteMode mode) |
989 |
: op_(op), |
|
990 |
mode_(mode), |
|
991 |
platform_specific_bit_(false), |
|
992 |
left_type_(BinaryOpIC::UNINITIALIZED), |
|
993 |
right_type_(BinaryOpIC::UNINITIALIZED), |
|
994 |
result_type_(BinaryOpIC::UNINITIALIZED), |
|
995 |
encoded_right_arg_(false, encode_arg_value(1)) { |
|
1004 |
: HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) { |
|
1005 |
ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN); |
|
996 | 1006 |
Initialize(); |
997 |
ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
|
998 | 1007 |
} |
999 | 1008 |
|
1000 |
BinaryOpStub( |
|
1001 |
int key, |
|
1002 |
BinaryOpIC::TypeInfo left_type, |
|
1003 |
BinaryOpIC::TypeInfo right_type, |
|
1004 |
BinaryOpIC::TypeInfo result_type, |
|
1005 |
Maybe<int32_t> fixed_right_arg) |
|
1006 |
: op_(OpBits::decode(key)), |
|
1007 |
mode_(ModeBits::decode(key)), |
|
1008 |
platform_specific_bit_(PlatformSpecificBits::decode(key)), |
|
1009 |
left_type_(left_type), |
|
1010 |
right_type_(right_type), |
|
1011 |
result_type_(result_type), |
|
1012 |
encoded_right_arg_(fixed_right_arg.has_value, |
|
1013 |
encode_arg_value(fixed_right_arg.value)) { } |
|
1009 |
explicit BinaryOpStub(Code::ExtraICState state) |
|
1010 |
: op_(decode_token(OpBits::decode(state))), |
|
1011 |
mode_(OverwriteModeField::decode(state)), |
|
1012 |
fixed_right_arg_( |
|
1013 |
Maybe<int>(HasFixedRightArgBits::decode(state), |
|
1014 |
decode_arg_value(FixedRightArgValueBits::decode(state)))), |
|
1015 |
left_state_(LeftStateField::decode(state)), |
|
1016 |
right_state_(fixed_right_arg_.has_value |
|
1017 |
? ((fixed_right_arg_.value <= Smi::kMaxValue) ? SMI : INT32) |
|
1018 |
: RightStateField::decode(state)), |
|
1019 |
result_state_(ResultStateField::decode(state)) { |
|
1020 |
// We don't deserialize the SSE2 Field, since this is only used to be able |
|
1021 |
// to include SSE2 as well as non-SSE2 versions in the snapshot. For code |
|
1022 |
// generation we always want it to reflect the current state. |
|
1023 |
ASSERT(!fixed_right_arg_.has_value || |
|
1024 |
can_encode_arg_value(fixed_right_arg_.value)); |
|
1025 |
} |
|
1026 |
|
|
1027 |
static const int FIRST_TOKEN = Token::BIT_OR; |
|
1028 |
static const int LAST_TOKEN = Token::MOD; |
|
1014 | 1029 |
|
1015 |
static void decode_types_from_minor_key(int minor_key, |
|
1016 |
BinaryOpIC::TypeInfo* left_type, |
|
1017 |
BinaryOpIC::TypeInfo* right_type, |
|
1018 |
BinaryOpIC::TypeInfo* result_type) { |
|
1019 |
*left_type = |
|
1020 |
static_cast<BinaryOpIC::TypeInfo>(LeftTypeBits::decode(minor_key)); |
|
1021 |
*right_type = |
|
1022 |
static_cast<BinaryOpIC::TypeInfo>(RightTypeBits::decode(minor_key)); |
|
1023 |
*result_type = |
|
1024 |
static_cast<BinaryOpIC::TypeInfo>(ResultTypeBits::decode(minor_key)); |
|
1030 |
static void GenerateAheadOfTime(Isolate* isolate); |
|
1031 |
virtual void InitializeInterfaceDescriptor( |
|
1032 |
Isolate* isolate, CodeStubInterfaceDescriptor* descriptor); |
|
1033 |
static void InitializeForIsolate(Isolate* isolate) { |
|
1034 |
BinaryOpStub binopStub(UNINITIALIZED); |
|
1035 |
binopStub.InitializeInterfaceDescriptor( |
|
1036 |
isolate, isolate->code_stub_interface_descriptor(CodeStub::BinaryOp)); |
|
1037 |
} |
|
1038 |
|
|
1039 |
virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; } |
|
1040 |
virtual InlineCacheState GetICState() { |
|
1041 |
if (Max(left_state_, right_state_) == NONE) { |
|
1042 |
return ::v8::internal::UNINITIALIZED; |
|
1043 |
} |
|
1044 |
if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC; |
|
1045 |
return MONOMORPHIC; |
|
1025 | 1046 |
} |
1026 | 1047 |
|
1027 |
static Token::Value decode_op_from_minor_key(int minor_key) {
|
|
1028 |
return static_cast<Token::Value>(OpBits::decode(minor_key));
|
|
1048 |
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
|
|
1049 |
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
|
|
1029 | 1050 |
} |
1030 | 1051 |
|
1031 |
static Maybe<int> decode_fixed_right_arg_from_minor_key(int minor_key) { |
|
1032 |
return Maybe<int>( |
|
1033 |
HasFixedRightArgBits::decode(minor_key), |
|
1034 |
decode_arg_value(FixedRightArgValueBits::decode(minor_key))); |
|
1052 |
virtual Code::ExtraICState GetExtraICState() { |
|
1053 |
bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI && |
|
1054 |
CpuFeatures::IsSafeForSnapshot(SSE2); |
|
1055 |
|
|
1056 |
return OpBits::encode(encode_token(op_)) |
|
1057 |
| LeftStateField::encode(left_state_) |
|
1058 |
| RightStateField::encode(fixed_right_arg_.has_value |
|
1059 |
? NONE : right_state_) |
|
1060 |
| ResultStateField::encode(result_state_) |
|
1061 |
| HasFixedRightArgBits::encode(fixed_right_arg_.has_value) |
|
1062 |
| FixedRightArgValueBits::encode(fixed_right_arg_.has_value |
|
1063 |
? encode_arg_value( |
|
1064 |
fixed_right_arg_.value) |
|
1065 |
: 0) |
|
1066 |
| SSE2Field::encode(sse_field) |
|
1067 |
| OverwriteModeField::encode(mode_); |
|
1035 | 1068 |
} |
1036 | 1069 |
|
1037 |
int fixed_right_arg_value() const { |
|
1038 |
return decode_arg_value(encoded_right_arg_.value); |
|
1070 |
bool CanReuseDoubleBox() { |
|
1071 |
return result_state_ <= NUMBER && result_state_ > SMI && |
|
1072 |
((left_state_ > SMI && left_state_ <= NUMBER && |
|
1073 |
mode_ == OVERWRITE_LEFT) || |
|
1074 |
(right_state_ > SMI && right_state_ <= NUMBER && |
|
1075 |
mode_ == OVERWRITE_RIGHT)); |
|
1039 | 1076 |
} |
1040 | 1077 |
|
1041 |
static bool can_encode_arg_value(int32_t value) {
|
|
1042 |
return value > 0 &&
|
|
1043 |
IsPowerOf2(value) &&
|
|
1044 |
FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
|
|
1078 |
bool HasSideEffects(Isolate* isolate) const {
|
|
1079 |
Handle<Type> left = GetLeftType(isolate);
|
|
1080 |
Handle<Type> right = GetRightType(isolate);
|
|
1081 |
return left->Maybe(Type::Receiver()) || right->Maybe(Type::Receiver());
|
|
1045 | 1082 |
} |
1046 | 1083 |
|
1047 |
enum SmiCodeGenerateHeapNumberResults { |
|
1048 |
ALLOW_HEAPNUMBER_RESULTS, |
|
1049 |
NO_HEAPNUMBER_RESULTS |
|
1050 |
}; |
|
1084 |
virtual Handle<Code> GenerateCode(Isolate* isolate); |
|
1051 | 1085 |
|
1052 |
private: |
|
1053 |
Token::Value op_; |
|
1054 |
OverwriteMode mode_; |
|
1055 |
bool platform_specific_bit_; // Indicates SSE3 on IA32. |
|
1086 |
Maybe<Handle<Object> > Result(Handle<Object> left, |
|
1087 |
Handle<Object> right, |
|
1088 |
Isolate* isolate); |
|
1056 | 1089 |
|
1057 |
// Operand type information determined at runtime. |
|
1058 |
BinaryOpIC::TypeInfo left_type_; |
|
1059 |
BinaryOpIC::TypeInfo right_type_; |
|
1060 |
BinaryOpIC::TypeInfo result_type_; |
|
1090 |
Token::Value operation() const { return op_; } |
|
1091 |
OverwriteMode mode() const { return mode_; } |
|
1092 |
Maybe<int> fixed_right_arg() const { return fixed_right_arg_; } |
|
1061 | 1093 |
|
1062 |
Maybe<int> encoded_right_arg_; |
|
1094 |
Handle<Type> GetLeftType(Isolate* isolate) const; |
|
1095 |
Handle<Type> GetRightType(Isolate* isolate) const; |
|
1096 |
Handle<Type> GetResultType(Isolate* isolate) const; |
|
1063 | 1097 |
|
1064 |
static int encode_arg_value(int32_t value) { |
|
1065 |
ASSERT(can_encode_arg_value(value)); |
|
1066 |
return WhichPowerOf2(value); |
|
1067 |
} |
|
1098 |
void UpdateStatus(Handle<Object> left, |
|
1099 |
Handle<Object> right, |
|
1100 |
Maybe<Handle<Object> > result); |
|
1068 | 1101 |
|
1069 |
static int32_t decode_arg_value(int value) { |
|
1070 |
return 1 << value; |
|
1102 |
void PrintState(StringStream* stream); |
|
1103 |
|
|
1104 |
private: |
|
1105 |
explicit BinaryOpStub(InitializationState state) : HydrogenCodeStub(state), |
|
1106 |
op_(Token::ADD), |
|
1107 |
mode_(NO_OVERWRITE) { |
|
1108 |
Initialize(); |
|
1071 | 1109 |
} |
1110 |
void Initialize(); |
|
1072 | 1111 |
|
1073 |
virtual void PrintName(StringStream* stream); |
|
1112 |
enum State { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; |
|
1113 |
|
|
1114 |
// We truncate the last bit of the token. |
|
1115 |
STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 5)); |
|
1116 |
class LeftStateField: public BitField<State, 0, 3> {}; |
|
1117 |
// When fixed right arg is set, we don't need to store the right state. |
|
1118 |
// Thus the two fields can overlap. |
|
1119 |
class HasFixedRightArgBits: public BitField<bool, 4, 1> {}; |
|
1120 |
class FixedRightArgValueBits: public BitField<int, 5, 4> {}; |
|
1121 |
class RightStateField: public BitField<State, 5, 3> {}; |
|
1122 |
class ResultStateField: public BitField<State, 9, 3> {}; |
|
1123 |
class SSE2Field: public BitField<bool, 12, 1> {}; |
|
1124 |
class OverwriteModeField: public BitField<OverwriteMode, 13, 2> {}; |
|
1125 |
class OpBits: public BitField<int, 15, 5> {}; |
|
1126 |
|
|
1127 |
virtual CodeStub::Major MajorKey() { return BinaryOp; } |
|
1128 |
virtual int NotMissMinorKey() { return GetExtraICState(); } |
|
1074 | 1129 |
|
1075 |
// Minor key encoding in all 25 bits FFFFFHTTTRRRLLLPOOOOOOOMM. |
|
1076 |
// Note: We actually do not need 7 bits for the operation, just 4 bits to |
|
1077 |
// encode ADD, SUB, MUL, DIV, MOD, BIT_OR, BIT_AND, BIT_XOR, SAR, SHL, SHR. |
|
1078 |
class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
|
1079 |
class OpBits: public BitField<Token::Value, 2, 7> {}; |
|
1080 |
class PlatformSpecificBits: public BitField<bool, 9, 1> {}; |
|
1081 |
class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {}; |
|
1082 |
class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {}; |
|
1083 |
class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {}; |
|
1084 |
class HasFixedRightArgBits: public BitField<bool, 19, 1> {}; |
|
1085 |
class FixedRightArgValueBits: public BitField<int, 20, 5> {}; |
|
1086 |
|
|
1087 |
Major MajorKey() { return BinaryOp; } |
|
1088 |
int MinorKey() { |
|
1089 |
return OpBits::encode(op_) |
|
1090 |
| ModeBits::encode(mode_) |
|
1091 |
| PlatformSpecificBits::encode(platform_specific_bit_) |
|
1092 |
| LeftTypeBits::encode(left_type_) |
|
1093 |
| RightTypeBits::encode(right_type_) |
|
1094 |
| ResultTypeBits::encode(result_type_) |
|
1095 |
| HasFixedRightArgBits::encode(encoded_right_arg_.has_value) |
|
1096 |
| FixedRightArgValueBits::encode(encoded_right_arg_.value); |
|
1097 |
} |
|
1130 |
static Handle<Type> StateToType(State state, |
|
1131 |
Isolate* isolate); |
|
1098 | 1132 |
|
1133 |
static void Generate(Token::Value op, |
|
1134 |
State left, |
|
1135 |
int right, |
|
1136 |
State result, |
|
1137 |
OverwriteMode mode, |
|
1138 |
Isolate* isolate); |
|
1099 | 1139 |
|
1100 |
// Platform-independent implementation. |
|
1101 |
void Generate(MacroAssembler* masm); |
|
1102 |
void GenerateCallRuntime(MacroAssembler* masm); |
|
1140 |
static void Generate(Token::Value op, |
|
1141 |
State left, |
|
1142 |
State right, |
|
1143 |
State result, |
|
1144 |
OverwriteMode mode, |
|
1145 |
Isolate* isolate); |
|
1103 | 1146 |
|
1104 |
// Platform-independent signature, platform-specific implementation. |
|
1105 |
void Initialize(); |
|
1106 |
void GenerateAddStrings(MacroAssembler* masm); |
|
1107 |
void GenerateBothStringStub(MacroAssembler* masm); |
|
1108 |
void GenerateGeneric(MacroAssembler* masm); |
|
1109 |
void GenerateGenericStub(MacroAssembler* masm); |
|
1110 |
void GenerateNumberStub(MacroAssembler* masm); |
|
1111 |
void GenerateInt32Stub(MacroAssembler* masm); |
|
1112 |
void GenerateLoadArguments(MacroAssembler* masm); |
|
1113 |
void GenerateOddballStub(MacroAssembler* masm); |
|
1114 |
void GenerateRegisterArgsPush(MacroAssembler* masm); |
|
1115 |
void GenerateReturn(MacroAssembler* masm); |
|
1116 |
void GenerateSmiStub(MacroAssembler* masm); |
|
1117 |
void GenerateStringStub(MacroAssembler* masm); |
|
1118 |
void GenerateTypeTransition(MacroAssembler* masm); |
|
1119 |
void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm); |
|
1120 |
void GenerateUninitializedStub(MacroAssembler* masm); |
|
1121 |
|
|
1122 |
// Entirely platform-specific methods are defined as static helper |
|
1123 |
// functions in the <arch>/code-stubs-<arch>.cc files. |
|
1147 |
void UpdateStatus(Handle<Object> object, |
|
1148 |
State* state); |
|
1124 | 1149 |
|
1125 |
virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; } |
|
1150 |
bool can_encode_arg_value(int32_t value) const; |
|
1151 |
int encode_arg_value(int32_t value) const; |
|
1152 |
int32_t decode_arg_value(int value) const; |
|
1153 |
int encode_token(Token::Value op) const; |
|
1154 |
Token::Value decode_token(int op) const; |
|
1126 | 1155 |
|
1127 |
virtual InlineCacheState GetICState() { |
|
1128 |
return BinaryOpIC::ToState(Max(left_type_, right_type_)); |
|
1156 |
bool has_int_result() const { |
|
1157 |
return op_ == Token::BIT_XOR || op_ == Token::BIT_AND || |
|
1158 |
op_ == Token::BIT_OR || op_ == Token::SAR || op_ == Token::SHL; |
|
1129 | 1159 |
} |
1130 | 1160 |
|
1131 |
virtual void FinishCode(Handle<Code> code) {
|
|
1132 |
code->set_stub_info(MinorKey()); |
|
1133 |
}
|
|
1161 |
const char* StateToName(State state);
|
|
1162 |
|
|
1163 |
void PrintBaseName(StringStream* stream);
|
|
1134 | 1164 |
|
1135 |
friend class CodeGenerator; |
|
1165 |
Token::Value op_; |
|
1166 |
OverwriteMode mode_; |
|
1167 |
|
|
1168 |
Maybe<int> fixed_right_arg_; |
|
1169 |
State left_state_; |
|
1170 |
State right_state_; |
|
1171 |
State result_state_; |
|
1136 | 1172 |
}; |
1137 | 1173 |
|
1138 | 1174 |
|
... | ... | |
1318 | 1354 |
virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE; |
1319 | 1355 |
static void GenerateAheadOfTime(Isolate* isolate); |
1320 | 1356 |
|
1357 |
protected: |
|
1358 |
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { |
|
1359 |
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); |
|
1360 |
}; |
|
1361 |
|
|
1321 | 1362 |
private: |
1322 | 1363 |
void GenerateCore(MacroAssembler* masm, |
1323 | 1364 |
Label* throw_normal_exception, |
... | ... | |
1705 | 1746 |
DestinationRegisterBits::encode(destination.code_) | |
1706 | 1747 |
OffsetBits::encode(offset) | |
1707 | 1748 |
IsTruncatingBits::encode(is_truncating) | |
1708 |
SkipFastPathBits::encode(skip_fastpath); |
|
1749 |
SkipFastPathBits::encode(skip_fastpath) | |
|
1750 |
SSEBits::encode(CpuFeatures::IsSafeForSnapshot(SSE2) ? |
|
1751 |
CpuFeatures::IsSafeForSnapshot(SSE3) ? 2 : 1 : 0); |
|
1709 | 1752 |
} |
1710 | 1753 |
|
1711 | 1754 |
Register source() { |
... | ... | |
1734 | 1777 |
|
1735 | 1778 |
virtual bool SometimesSetsUpAFrame() { return false; } |
1736 | 1779 |
|
1780 |
protected: |
|
1781 |
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { |
|
1782 |
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); |
|
1783 |
} |
|
1784 |
|
|
1737 | 1785 |
private: |
1738 | 1786 |
static const int kBitsPerRegisterNumber = 6; |
1739 | 1787 |
STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters); |
... | ... | |
1748 | 1796 |
public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT |
1749 | 1797 |
class SkipFastPathBits: |
1750 | 1798 |
public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT |
1799 |
class SSEBits: |
|
1800 |
public BitField<int, 2 * kBitsPerRegisterNumber + 5, 2> {}; // NOLINT |
|
1751 | 1801 |
|
1752 | 1802 |
Major MajorKey() { return DoubleToI; } |
1753 | 1803 |
int MinorKey() { return bit_field_; } |
Also available in: Unified diff