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); |
| 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 |