Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 | 8 |
| 9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 // ShiftRightLogical <src> | 829 // ShiftRightLogical <src> |
| 830 // | 830 // |
| 831 // Right Shifts register <src> by the count specified in the accumulator. | 831 // Right Shifts register <src> by the count specified in the accumulator. |
| 832 // Result is zero-filled. The accumulator and register <src> are converted to | 832 // Result is zero-filled. The accumulator and register <src> are converted to |
| 833 // uint32 before the operation 5 lsb bits from the accumulator are used as | 833 // uint32 before the operation 5 lsb bits from the accumulator are used as |
| 834 // count i.e. <src> << (accumulator & 0x1F). | 834 // count i.e. <src> << (accumulator & 0x1F). |
| 835 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { | 835 void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) { |
| 836 DoBinaryOp<ShiftRightLogicalStub>(assembler); | 836 DoBinaryOp<ShiftRightLogicalStub>(assembler); |
| 837 } | 837 } |
| 838 | 838 |
| 839 // AddSmi <imm> <reg> | |
| 840 // | |
| 841 // Adds an immediate value <imm> to register <reg>. For this | |
| 842 // operation <reg> is the lhs operand and <imm> is the <rhs> operand. | |
| 843 void Interpreter::DoAddSmi(InterpreterAssembler* assembler) { | |
| 844 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 845 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), | |
| 846 end(assembler); | |
| 847 | |
| 848 Node* reg_index = __ BytecodeOperandReg(1); | |
| 849 Node* left = __ LoadRegister(reg_index); | |
| 850 Node* raw_int = __ BytecodeOperandImm(0); | |
| 851 Node* right = __ SmiTag(raw_int); | |
| 852 | |
| 853 // {right} is known to be a Smi. | |
| 854 // Check if the {left} is a Smi take the fast path. | |
| 855 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); | |
| 856 __ Bind(&fastpath); | |
| 857 { | |
| 858 // Try fast Smi addition first. | |
| 859 Node* pair = __ SmiAddWithOverflow(left, right); | |
| 860 Node* overflow = __ Projection(1, pair); | |
| 861 | |
| 862 // Check if the Smi additon overflowed. | |
| 863 Label if_notoverflow(assembler); | |
| 864 __ BranchIf(overflow, &slowpath, &if_notoverflow); | |
| 865 __ Bind(&if_notoverflow); | |
| 866 { | |
| 867 var_result.Bind(__ Projection(0, pair)); | |
| 868 __ Goto(&end); | |
|
rmcilroy
2016/07/05 09:55:41
Might be worth dispatching directly here - a dispa
oth
2016/07/05 13:19:35
Yes though for interpreted Octane on desktop, the
| |
| 869 } | |
| 870 } | |
| 871 __ Bind(&slowpath); | |
| 872 { | |
| 873 Node* context = __ GetContext(); | |
| 874 Callable callable = CodeFactory::Add(__ isolate()); | |
| 875 var_result.Bind(__ CallStub(callable, context, left, right)); | |
| 876 __ Goto(&end); | |
| 877 } | |
| 878 __ Bind(&end); | |
| 879 { | |
| 880 __ SetAccumulator(var_result.value()); | |
| 881 __ Dispatch(); | |
| 882 } | |
| 883 } | |
| 884 | |
| 885 // SubSmi <imm> <reg> | |
| 886 // | |
| 887 // Subtracts an immediate value <imm> to register <reg>. For this | |
| 888 // operation <reg> is the lhs operand and <imm> is the rhs operand. | |
| 889 void Interpreter::DoSubSmi(InterpreterAssembler* assembler) { | |
| 890 Variable var_result(assembler, MachineRepresentation::kTagged); | |
| 891 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), | |
| 892 end(assembler); | |
| 893 | |
| 894 Node* reg_index = __ BytecodeOperandReg(1); | |
| 895 Node* left = __ LoadRegister(reg_index); | |
| 896 Node* raw_int = __ BytecodeOperandImm(0); | |
| 897 Node* right = __ SmiTag(raw_int); | |
| 898 | |
| 899 // {right} is known to be a Smi. | |
| 900 // Check if the {left} is a Smi take the fast path. | |
| 901 __ BranchIf(__ WordIsSmi(left), &fastpath, &slowpath); | |
| 902 __ Bind(&fastpath); | |
| 903 { | |
| 904 // Try fast Smi subtraction first. | |
| 905 Node* pair = __ SmiSubWithOverflow(left, right); | |
| 906 Node* overflow = __ Projection(1, pair); | |
| 907 | |
| 908 // Check if the Smi subtraction overflowed. | |
| 909 Label if_notoverflow(assembler); | |
| 910 __ BranchIf(overflow, &slowpath, &if_notoverflow); | |
| 911 __ Bind(&if_notoverflow); | |
| 912 { | |
| 913 var_result.Bind(__ Projection(0, pair)); | |
| 914 __ Goto(&end); | |
| 915 } | |
| 916 } | |
| 917 __ Bind(&slowpath); | |
| 918 { | |
| 919 Node* context = __ GetContext(); | |
| 920 Callable callable = CodeFactory::Subtract(__ isolate()); | |
| 921 var_result.Bind(__ CallStub(callable, context, left, right)); | |
| 922 __ Goto(&end); | |
| 923 } | |
| 924 __ Bind(&end); | |
| 925 { | |
| 926 __ SetAccumulator(var_result.value()); | |
| 927 __ Dispatch(); | |
| 928 } | |
| 929 } | |
| 930 | |
| 931 // BitwiseOr <imm> <reg> | |
| 932 // | |
| 933 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs | |
| 934 // operand and <imm> is the rhs operand. | |
| 935 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) { | |
| 936 Node* reg_index = __ BytecodeOperandReg(1); | |
| 937 Node* left = __ LoadRegister(reg_index); | |
| 938 Node* raw_int = __ BytecodeOperandImm(0); | |
| 939 Node* right = __ SmiTag(raw_int); | |
| 940 Node* context = __ GetContext(); | |
| 941 Node* lhs_value = __ TruncateTaggedToWord32(context, left); | |
| 942 Node* rhs_value = __ SmiToWord32(right); | |
| 943 Node* value = __ Word32Or(lhs_value, rhs_value); | |
| 944 Node* result = __ ChangeInt32ToTagged(value); | |
| 945 __ SetAccumulator(result); | |
| 946 __ Dispatch(); | |
| 947 } | |
| 948 | |
| 949 // BitwiseAnd <imm> <reg> | |
| 950 // | |
| 951 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs | |
| 952 // operand and <imm> is the rhs operand. | |
| 953 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) { | |
| 954 Node* reg_index = __ BytecodeOperandReg(1); | |
| 955 Node* left = __ LoadRegister(reg_index); | |
| 956 Node* raw_int = __ BytecodeOperandImm(0); | |
| 957 Node* right = __ SmiTag(raw_int); | |
| 958 Node* context = __ GetContext(); | |
| 959 Node* lhs_value = __ TruncateTaggedToWord32(context, left); | |
| 960 Node* rhs_value = __ SmiToWord32(right); | |
| 961 Node* value = __ Word32And(lhs_value, rhs_value); | |
| 962 Node* result = __ ChangeInt32ToTagged(value); | |
| 963 __ SetAccumulator(result); | |
| 964 __ Dispatch(); | |
| 965 } | |
| 966 | |
| 967 // ShiftLeftSmi <imm> <reg> | |
| 968 // | |
| 969 // Left shifts register <src> by the count specified in <imm>. | |
| 970 // Register <src> is converted to an int32 before the operation. The 5 | |
| 971 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). | |
| 972 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) { | |
| 973 Node* reg_index = __ BytecodeOperandReg(1); | |
| 974 Node* left = __ LoadRegister(reg_index); | |
| 975 Node* raw_int = __ BytecodeOperandImm(0); | |
| 976 Node* right = __ SmiTag(raw_int); | |
| 977 Node* context = __ GetContext(); | |
| 978 Node* lhs_value = __ TruncateTaggedToWord32(context, left); | |
| 979 Node* rhs_value = __ SmiToWord32(right); | |
| 980 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); | |
| 981 Node* value = __ Word32Shl(lhs_value, shift_count); | |
| 982 Node* result = __ ChangeInt32ToTagged(value); | |
| 983 __ SetAccumulator(result); | |
| 984 __ Dispatch(); | |
| 985 } | |
| 986 | |
| 987 // ShiftRightSmi <imm> <reg> | |
| 988 // | |
| 989 // Right shifts register <src> by the count specified in <imm>. | |
| 990 // Register <src> is converted to an int32 before the operation. The 5 | |
| 991 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). | |
| 992 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) { | |
| 993 Node* reg_index = __ BytecodeOperandReg(1); | |
| 994 Node* left = __ LoadRegister(reg_index); | |
| 995 Node* raw_int = __ BytecodeOperandImm(0); | |
| 996 Node* right = __ SmiTag(raw_int); | |
| 997 Node* context = __ GetContext(); | |
| 998 Node* lhs_value = __ TruncateTaggedToWord32(context, left); | |
| 999 Node* rhs_value = __ SmiToWord32(right); | |
| 1000 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); | |
| 1001 Node* value = __ Word32Sar(lhs_value, shift_count); | |
| 1002 Node* result = __ ChangeInt32ToTagged(value); | |
| 1003 __ SetAccumulator(result); | |
| 1004 __ Dispatch(); | |
| 1005 } | |
| 1006 | |
| 839 void Interpreter::DoUnaryOp(Callable callable, | 1007 void Interpreter::DoUnaryOp(Callable callable, |
| 840 InterpreterAssembler* assembler) { | 1008 InterpreterAssembler* assembler) { |
| 841 Node* target = __ HeapConstant(callable.code()); | 1009 Node* target = __ HeapConstant(callable.code()); |
| 842 Node* accumulator = __ GetAccumulator(); | 1010 Node* accumulator = __ GetAccumulator(); |
| 843 Node* context = __ GetContext(); | 1011 Node* context = __ GetContext(); |
| 844 Node* result = | 1012 Node* result = |
| 845 __ CallStub(callable.descriptor(), target, context, accumulator); | 1013 __ CallStub(callable.descriptor(), target, context, accumulator); |
| 846 __ SetAccumulator(result); | 1014 __ SetAccumulator(result); |
| 847 __ Dispatch(); | 1015 __ Dispatch(); |
| 848 } | 1016 } |
| (...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1856 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2024 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
| 1857 __ SmiTag(new_state)); | 2025 __ SmiTag(new_state)); |
| 1858 __ SetAccumulator(old_state); | 2026 __ SetAccumulator(old_state); |
| 1859 | 2027 |
| 1860 __ Dispatch(); | 2028 __ Dispatch(); |
| 1861 } | 2029 } |
| 1862 | 2030 |
| 1863 } // namespace interpreter | 2031 } // namespace interpreter |
| 1864 } // namespace internal | 2032 } // namespace internal |
| 1865 } // namespace v8 | 2033 } // namespace v8 |
| OLD | NEW |