28 #ifndef V8_ARM_LITHIUM_ARM_H_
29 #define V8_ARM_LITHIUM_ARM_H_
43 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \
44 V(ControlInstruction) \
46 LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
49 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
50 V(AccessArgumentsAt) \
54 V(ArgumentsElements) \
63 V(CallConstantFunction) \
73 V(CheckInstanceType) \
76 V(CheckPrototypeMaps) \
81 V(ClassOfTestAndBranch) \
82 V(CmpConstantEqAndBranch) \
84 V(CmpObjectEqAndBranch) \
98 V(FixedArrayBaseLength) \
100 V(GetCachedArrayIndex) \
104 V(HasCachedArrayIndexAndBranch) \
105 V(HasInstanceTypeAndBranch) \
108 V(InstanceOfKnownGlobal) \
110 V(Integer32ToDouble) \
112 V(IsConstructCallAndBranch) \
114 V(IsObjectAndBranch) \
115 V(IsStringAndBranch) \
117 V(IsUndetectableAndBranch) \
118 V(StringCompareAndBranch) \
124 V(LoadExternalArrayPointer) \
125 V(LoadFunctionPrototype) \
127 V(LoadGlobalGeneric) \
128 V(LoadKeyedFastDoubleElement) \
129 V(LoadKeyedFastElement) \
130 V(LoadKeyedGeneric) \
131 V(LoadKeyedSpecializedArrayElement) \
133 V(LoadNamedFieldPolymorphic) \
134 V(LoadNamedGeneric) \
154 V(StoreContextSlot) \
156 V(StoreGlobalGeneric) \
157 V(StoreKeyedFastDoubleElement) \
158 V(StoreKeyedFastElement) \
159 V(StoreKeyedGeneric) \
160 V(StoreKeyedSpecializedArrayElement) \
162 V(StoreNamedGeneric) \
164 V(StringCharCodeAt) \
165 V(StringCharFromCode) \
171 V(ToFastProperties) \
172 V(TransitionElementsKind) \
174 V(TypeofIsAndBranch) \
175 V(UnaryMathOperation) \
181 V(LoadFieldByIndex) \
187 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
188 virtual Opcode opcode() const { return LInstruction::k##type; } \
189 virtual void CompileToNative(LCodeGen* generator); \
190 virtual const char* Mnemonic() const { return mnemonic; } \
191 static L##type* cast(LInstruction* instr) { \
192 ASSERT(instr->Is##type()); \
193 return reinterpret_cast<L##type*>(instr); \
197 #define DECLARE_HYDROGEN_ACCESSOR(type) \
198 H##type* hydrogen() const { \
199 return H##type::cast(hydrogen_value()); \
206 : environment_(
NULL),
207 hydrogen_value_(
NULL),
212 virtual const char*
Mnemonic()
const = 0;
219 #define DECLARE_OPCODE(type) k##type,
222 #undef DECLARE_OPCODE
228 #define DECLARE_PREDICATE(type) \
229 bool Is##type() const { return opcode() == k##type; }
231 #undef DECLARE_PREDICATE
235 virtual bool IsGap()
const {
return false; }
283 template<
int R,
int I,
int T>
316 virtual bool IsGap()
const {
return true; }
320 return reinterpret_cast<LGap*
>(instr);
337 if (parallel_moves_[pos] ==
NULL) {
340 return parallel_moves_[pos];
344 return parallel_moves_[pos];
388 int gap_instructions_size_;
401 :
LGap(block), replacement_(
NULL) { }
432 return hydrogen()->transcendental_type();
443 template<
int I,
int T>
587 class
LMulI: public LTemplateInstruction<1, 2, 1> {
612 return hydrogen()->GetInputRepresentation().IsDouble();
642 "cmp-object-eq-and-branch")
654 "cmp-constant-eq-and-branch")
724 "is-undetectable-and-branch")
739 "string-compare-and-branch")
742 Token::
Value op()
const {
return hydrogen()->token(); }
755 "has-instance-type-and-branch")
780 "has-cached-array-index-and-branch")
795 "class-of-test-and-branch")
802 class
LCmpT: public LTemplateInstruction<1, 2, 0> {
835 "instance-of-known-global")
840 return lazy_deopt_env_;
843 lazy_deopt_env_ = env;
865 class LBitI:
public LTemplateInstruction<1, 2, 0> {
879 class
LShiftI: public LTemplateInstruction<1, 2, 0> {
882 : op_(op), can_deopt_(can_deopt) {
899 class
LSubI: public LTemplateInstruction<1, 2, 0> {
916 int32_t value()
const {
return hydrogen()->Integer32Value(); }
925 double value()
const {
return hydrogen()->DoubleValue(); }
938 class LBranch:
public LControlInstruction<1, 0> {
965 return hydrogen()->FirstSuccessor()->block_id();
968 return hydrogen()->SecondSuccessor()->block_id();
991 "fixed-array-base-length")
1028 Smi* index()
const {
return index_; }
1047 int index()
const {
return index_; }
1054 class LThrow:
public LTemplateInstruction<0, 1, 0> {
1074 class LAddI:
public LTemplateInstruction<1, 2, 0> {
1086 class
LPower: public LTemplateInstruction<1, 2, 0> {
1098 class
LRandom: public LTemplateInstruction<1, 1, 0> {
1121 virtual const char*
Mnemonic()
const;
1138 virtual const char*
Mnemonic()
const;
1147 class LReturn:
public LTemplateInstruction<0, 1, 0> {
1225 "load-external-array-pointer")
1253 "load-keyed-fast-double-element")
1265 inputs_[0] = external_pointer;
1270 "load-keyed-specialized-array-element")
1276 return hydrogen()->elements_kind();
1394 class LDrop:
public LTemplateInstruction<0, 0, 0> {
1396 explicit LDrop(
int count) : count_(count) { }
1471 int arity()
const {
return hydrogen()->argument_count() - 1; }
1488 int arity()
const {
return hydrogen()->argument_count() - 1; }
1504 int arity()
const {
return hydrogen()->argument_count() - 1; }
1517 int arity()
const {
return hydrogen()->argument_count() - 1; }
1531 int arity()
const {
return hydrogen()->argument_count() - 1; }
1543 int arity()
const {
return hydrogen()->argument_count() - 1; }
1555 int arity()
const {
return hydrogen()->argument_count() - 1; }
1570 int arity()
const {
return hydrogen()->argument_count() - 1; }
1580 int arity()
const {
return hydrogen()->argument_count(); }
1628 bool truncating() {
return hydrogen()->CanTruncateToInt32(); }
1648 bool truncating() {
return hydrogen()->CanTruncateToInt32(); }
1652 class LSmiTag:
public LTemplateInstruction<1, 1, 0> {
1676 : needs_check_(needs_check) {
1682 bool needs_check()
const {
return needs_check_; }
1707 int offset() {
return hydrogen()->offset(); }
1740 "store-keyed-fast-element")
1763 "store-keyed-fast-double-element")
1801 inputs_[0] = external_pointer;
1807 "store-keyed-specialized-array-element")
1814 return hydrogen()->elements_kind();
1826 temps_[0] = new_map_temp;
1831 "transition-elements-kind")
2069 class
LTypeof: public LTemplateInstruction<1, 1, 0> {
2101 "is-construct-call-and-branch")
2125 LOperand** SpilledRegisterArray() {
return register_spills_; }
2128 void MarkSpilledRegister(
int allocation_index,
LOperand* spill_operand);
2129 void MarkSpilledDoubleRegister(
int allocation_index,
2147 Label* done_label() {
return &done_label_; }
2154 class LIn:
public LTemplateInstruction<1, 2, 0> {
2224 class LChunkBuilder;
2234 int GetNextSpillIndex(
bool is_double);
2235 LOperand* GetNextSpillSlot(
bool is_double);
2237 int ParameterAt(
int index);
2238 int GetParameterStackSlot(
int index)
const;
2240 CompilationInfo*
info()
const {
return info_; }
2244 LGap* GetGapAt(
int index)
const;
2245 bool IsGapAt(
int index)
const;
2246 int NearestGapPos(
int index)
const;
2247 void MarkEmptyBlocks();
2250 HBasicBlock* block = graph_->blocks()->at(block_id);
2255 LLabel* cur = GetLabel(block_id);
2262 LLabel* label = GetLabel(block_id);
2264 return label->
label();
2268 return &inlined_closures_;
2272 inlined_closures_.Add(closure, zone());
2278 int spill_slot_count_;
2279 CompilationInfo* info_;
2293 zone_(graph->zone()),
2295 current_instruction_(
NULL),
2296 current_block_(
NULL),
2299 allocator_(allocator),
2300 position_(RelocInfo::kNoPosition),
2301 instruction_pending_deoptimization_environment_(
NULL),
2302 pending_deoptimization_ast_id_(
AstNode::kNoNumber) { }
2308 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2312 static bool HasMagicNumberForDivisor(
int32_t divisor);
2313 static HValue* SimplifiedDividendForMathFloorOfDiv(HValue* val);
2314 static HValue* SimplifiedDivisorForMathFloorOfDiv(HValue* val);
2324 LChunk* chunk()
const {
return chunk_; }
2325 CompilationInfo* info()
const {
return info_; }
2326 HGraph* graph()
const {
return graph_; }
2327 Zone* zone()
const {
return zone_; }
2329 bool is_unused()
const {
return status_ == UNUSED; }
2330 bool is_building()
const {
return status_ == BUILDING; }
2331 bool is_done()
const {
return status_ ==
DONE; }
2332 bool is_aborted()
const {
return status_ == ABORTED; }
2334 void Abort(
const char* format, ...);
2337 LUnallocated* ToUnallocated(Register reg);
2342 MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2370 MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2383 template<
int I,
int T>
2384 LInstruction* Define(LTemplateInstruction<1, I, T>* instr,
2386 template<
int I,
int T>
2387 LInstruction* DefineAsRegister(LTemplateInstruction<1, I, T>* instr);
2388 template<
int I,
int T>
2389 LInstruction* DefineAsSpilled(LTemplateInstruction<1, I, T>* instr,
2391 template<
int I,
int T>
2392 LInstruction* DefineSameAsFirst(LTemplateInstruction<1, I, T>* instr);
2393 template<
int I,
int T>
2394 LInstruction* DefineFixed(LTemplateInstruction<1, I, T>* instr,
2396 template<
int I,
int T>
2397 LInstruction* DefineFixedDouble(LTemplateInstruction<1, I, T>* instr,
2402 enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2409 HInstruction* hinstr,
2410 CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2412 LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env,
2413 int* argument_index_accumulator);
2415 void VisitInstruction(HInstruction* current);
2417 void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2420 HArithmeticBinaryOperation* instr);
2422 HArithmeticBinaryOperation* instr);
2425 CompilationInfo* info_;
2426 HGraph*
const graph_;
2429 HInstruction* current_instruction_;
2430 HBasicBlock* current_block_;
2431 HBasicBlock* next_block_;
2432 int argument_count_;
2433 LAllocator* allocator_;
2435 LInstruction* instruction_pending_deoptimization_environment_;
2436 int pending_deoptimization_ast_id_;
2441 #undef DECLARE_HYDROGEN_ACCESSOR
2442 #undef DECLARE_CONCRETE_INSTRUCTION
2446 #endif // V8_ARM_LITHIUM_ARM_H_
LCmpT(LOperand *left, LOperand *right)
LStringCharCodeAt(LOperand *string, LOperand *index)
LDateField(LOperand *date, LOperand *temp, Smi *index)
LArgumentsLength(LOperand *elements)
LLoadContextSlot(LOperand *context)
LGlobalReceiver(LOperand *global_object)
static LGap * cast(LInstruction *instr)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
Handle< Map > transitioned_map()
LLoadFieldByIndex(LOperand *object, LOperand *index)
Handle< Object > name() const
uint32_t additional_index() const
LGetCachedArrayIndex(LOperand *value)
LCallKeyed(LOperand *key)
void set_pointer_map(LPointerMap *p)
bool IsMarkedAsCall() const
Handle< Object > name() const
virtual LOperand * InputAt(int i)=0
LStoreKeyedGeneric(LOperand *obj, LOperand *key, LOperand *val)
LClassOfTestAndBranch(LOperand *value, LOperand *temp)
#define DECLARE_OPCODE(type)
LClampDToUint8(LOperand *value, LOperand *temp)
void set_environment(LEnvironment *env)
void set_result(LOperand *operand)
int false_block_id() const
virtual void PrintOutputOperandTo(StringStream *stream)
EmbeddedContainer< LOperand *, T > temps_
uint32_t additional_index() const
LWrapReceiver(LOperand *receiver, LOperand *function)
LParallelMove * GetOrCreateParallelMove(InnerPosition pos, Zone *zone)
LNumberTagI(LOperand *value)
LInstructionGap(HBasicBlock *block)
LLoadGlobalGeneric(LOperand *global_object)
Handle< JSFunction > target() const
LCheckSmi(LOperand *value)
LLoadFunctionPrototype(LOperand *function)
LStringLength(LOperand *string)
LIsObjectAndBranch(LOperand *value, LOperand *temp)
Handle< Object > name() const
LUnaryMathOperation(LOperand *value, LOperand *temp)
uint32_t additional_index() const
LStoreNamedField(LOperand *obj, LOperand *val, LOperand *temp)
LLabel(HBasicBlock *block)
LJSArrayLength(LOperand *value)
int true_block_id() const
Handle< String > name() const
LChunkBuilder(CompilationInfo *info, HGraph *graph, LAllocator *allocator)
LMathFloorOfDiv(LOperand *left, LOperand *right, LOperand *temp=NULL)
LOuterContext(LOperand *context)
static const int kNumAllocatableRegisters
Handle< Object > name() const
#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)
Handle< Map > transition() const
LEnvironment * environment() const
LStoreContextSlot(LOperand *context, LOperand *value)
virtual HBasicBlock * SuccessorAt(int i)=0
LCheckNonSmi(LOperand *value)
#define ASSERT(condition)
LBoundsCheck(LOperand *index, LOperand *length)
LClampTToUint8(LOperand *value, LOperand *temp)
virtual const char * Mnemonic() const =0
LFixedArrayBaseLength(LOperand *value)
LCheckPrototypeMaps(LOperand *temp1, LOperand *temp2)
LAllocateObject(LOperand *temp1, LOperand *temp2)
LCheckInstanceType(LOperand *value)
virtual void PrintDataTo(StringStream *stream)
int gap_instructions_size()
uint32_t additional_index() const
LInvokeFunction(LOperand *function)
#define DECLARE_HYDROGEN_ACCESSOR(type)
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
LHasInstanceTypeAndBranch(LOperand *value)
StrictModeFlag strict_mode_flag()
LTransitionElementsKind(LOperand *object, LOperand *new_map_temp, LOperand *temp_reg)
LNumberUntagD(LOperand *value)
LForInPrepareMap(LOperand *object)
void set_hydrogen_value(HValue *value)
LLoadNamedField(LOperand *object)
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
LPower(LOperand *left, LOperand *right)
virtual bool HasResult() const =0
Handle< JSObject > holder() const
DwVfpRegister DoubleRegister
virtual Opcode opcode() const =0
Handle< Object > name() const
Handle< Map > map() const
LGlobalObject(LOperand *context)
EmbeddedContainer< LOperand *, R > results_
ElementsKind elements_kind() const
LLabel * replacement() const
LDeleteProperty(LOperand *obj, LOperand *key)
virtual LOperand * TempAt(int i)=0
Handle< JSFunction > known_function()
LAddI(LOperand *left, LOperand *right)
bool is_loop_header() const
LCmpObjectEqAndBranch(LOperand *left, LOperand *right)
LOperand ** SpilledDoubleRegisterArray()
LNumberTagD(LOperand *value, LOperand *temp1, LOperand *temp2)
int spill_slot_count() const
LOperand * InputAt(int i)
LElementsKind(LOperand *value)
virtual Opcode opcode() const
HBasicBlock * SuccessorAt(int i)
LStoreKeyedFastElement(LOperand *obj, LOperand *key, LOperand *val)
LIsStringAndBranch(LOperand *value, LOperand *temp)
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastDoubleElement,"load-keyed-fast-double-element") LOperand *elements()
LStoreNamedGeneric(LOperand *obj, LOperand *val)
LLoadKeyedFastElement(LOperand *elements, LOperand *key)
bool HasEnvironment() const
virtual bool HasResult() const
LBitI(LOperand *left, LOperand *right)
virtual int TempCount()=0
LLoadExternalArrayPointer(LOperand *object)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
virtual bool IsControl() const
LTypeofIsAndBranch(LOperand *value)
virtual LOperand * result()=0
LDoubleToI(LOperand *value, LOperand *temp1, LOperand *temp2)
LStoreGlobalGeneric(LOperand *global_object, LOperand *value)
virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment *env)
virtual bool IsControl() const
LStringCharFromCode(LOperand *char_code)
HBasicBlock * block() const
LSubI(LOperand *left, LOperand *right)
TranscendentalCache::Type transcendental_type()
LMulI(LOperand *left, LOperand *right, LOperand *temp)
virtual void PrintTo(StringStream *stream)
LDivI(LOperand *left, LOperand *right)
virtual void PrintDataTo(StringStream *stream)
LStoreKeyedFastDoubleElement(LOperand *elements, LOperand *key, LOperand *val)
#define T(name, string, precedence)
LToFastProperties(LOperand *value)
LInstanceOf(LOperand *left, LOperand *right)
LStoreKeyedSpecializedArrayElement(LOperand *external_pointer, LOperand *key, LOperand *val)
LCmpMapAndBranch(LOperand *value, LOperand *temp)
virtual int SuccessorCount()=0
LRandom(LOperand *global_object)
LForInCacheArray(LOperand *map)
virtual bool IsControl() const
LPointerMap * pointer_map() const
LShiftI(Token::Value op, LOperand *left, LOperand *right, bool can_deopt)
Label * GetAssemblyLabel(int block_id) const
int first_instruction_index() const
ElementsKind elements_kind() const
EmbeddedContainer< LOperand *, I > inputs_
LLabel * GetLabel(int block_id) const
virtual bool IsGap() const
LHasCachedArrayIndexAndBranch(LOperand *value)
LCheckFunction(LOperand *value)
const ZoneList< Handle< JSFunction > > * inlined_closures() const
LAccessArgumentsAt(LOperand *arguments, LOperand *length, LOperand *index)
LArithmeticT(Token::Value op, LOperand *left, LOperand *right)
virtual void PrintDataTo(StringStream *stream)
CompilationInfo * info() const
void set_gap_instructions_size(int gap_instructions_size)
LLoadElements(LOperand *object)
LCmpConstantEqAndBranch(LOperand *left)
virtual void CompileToNative(LCodeGen *generator)=0
#define DECLARE_PREDICATE(type)
virtual bool IsGap() const
static const int kNumAllocatableRegisters
LStringAdd(LOperand *left, LOperand *right)
LLoadNamedFieldPolymorphic(LOperand *object)
LCheckMaps(LOperand *value)
LModI(LOperand *left, LOperand *right, LOperand *temp1, LOperand *temp2, LOperand *temp3)
bool IsLoopHeader() const
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
LLoadKeyedFastDoubleElement(LOperand *elements, LOperand *key)
LArithmeticD(Token::Value op, LOperand *left, LOperand *right)
uint32_t additional_index() const
const ZoneList< LPointerMap * > * pointer_maps() const
virtual void PrintDataTo(StringStream *stream)
Handle< String > name() const
StrictModeFlag strict_mode_flag()
LEnvironment * GetDeferredLazyDeoptimizationEnvironment()
STATIC_ASSERT(R==0||R==1)
void set_replacement(LLabel *label)
StrictModeFlag strict_mode_flag()
LCmpIDAndBranch(LOperand *left, LOperand *right)
LParallelMove * GetParallelMove(InnerPosition pos)
virtual Opcode opcode() const
LInstanceOfKnownGlobal(LOperand *value, LOperand *temp)
bool HasPointerMap() const
LCheckMapValue(LOperand *value, LOperand *map)
LIsSmiAndBranch(LOperand *value)
uint32_t additional_index() const
LInteger32ToDouble(LOperand *value)
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,"load-keyed-specialized-array-element") LOperand *external_pointer()
int LookupDestination(int block_id) const
LCallNew(LOperand *constructor)
LClampIToUint8(LOperand *value)
virtual int InputCount()=0
bool NeedsCanonicalization()
LIn(LOperand *key, LOperand *object)
LIsConstructCallAndBranch(LOperand *temp)
static HValue * cast(HValue *value)
LLoadNamedGeneric(LOperand *object)
LTaggedToI(LOperand *value, LOperand *temp1, LOperand *temp2, LOperand *temp3)
DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,"instance-of-known-global") Handle< JSFunction > function() const
HValue * hydrogen_value() const
LPushArgument(LOperand *value)
LStringCompareAndBranch(LOperand *left, LOperand *right)
bool HasReplacement() const
LSetDateField(LOperand *date, LOperand *value, LOperand *temp, int index)
LValueOf(LOperand *value, LOperand *temp)
LBitNotI(LOperand *value)
LApplyArguments(LOperand *function, LOperand *receiver, LOperand *length, LOperand *elements)
LModI(LOperand *left, LOperand *right)
Handle< Map > original_map()
LCallFunction(LOperand *function)
LIsNilAndBranch(LOperand *value)
LLoadKeyedGeneric(LOperand *obj, LOperand *key)
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,"store-keyed-specialized-array-element") LOperand *external_pointer()
LStoreGlobalCell(LOperand *value, LOperand *temp)
LIsUndetectableAndBranch(LOperand *value, LOperand *temp)
const ZoneList< LInstruction * > * instructions() const
LSmiUntag(LOperand *value, bool needs_check)
LLoadKeyedSpecializedArrayElement(LOperand *external_pointer, LOperand *key)
virtual void PrintDataTo(StringStream *stream)
void AddInlinedClosure(Handle< JSFunction > closure)