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 |