OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 MachineRepresentation::kWord32); | 1863 MachineRepresentation::kWord32); |
1864 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | 1864 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
1865 return; | 1865 return; |
1866 } | 1866 } |
1867 case IrOpcode::kNumberImul: { | 1867 case IrOpcode::kNumberImul: { |
1868 VisitBinop(node, UseInfo::TruncatingWord32(), | 1868 VisitBinop(node, UseInfo::TruncatingWord32(), |
1869 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); | 1869 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
1870 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | 1870 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
1871 return; | 1871 return; |
1872 } | 1872 } |
1873 case IrOpcode::kNumberCeil: { | |
1874 VisitUnop(node, UseInfo::TruncatingFloat64(), | |
1875 MachineRepresentation::kFloat64); | |
1876 if (lower()) DeferReplacement(node, lowering->Float64Ceil(node)); | |
1877 return; | |
1878 } | |
1879 case IrOpcode::kNumberFloor: { | |
1880 VisitUnop(node, UseInfo::TruncatingFloat64(), | |
1881 MachineRepresentation::kFloat64); | |
1882 if (lower()) DeferReplacement(node, lowering->Float64Floor(node)); | |
1883 return; | |
1884 } | |
1885 case IrOpcode::kNumberFround: { | 1873 case IrOpcode::kNumberFround: { |
1886 VisitUnop(node, UseInfo::TruncatingFloat64(), | 1874 VisitUnop(node, UseInfo::TruncatingFloat64(), |
1887 MachineRepresentation::kFloat32); | 1875 MachineRepresentation::kFloat32); |
1888 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1876 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
1889 return; | 1877 return; |
1890 } | 1878 } |
1891 case IrOpcode::kNumberMax: { | 1879 case IrOpcode::kNumberMax: { |
1892 // TODO(turbofan): We should consider feedback types here as well. | 1880 // TODO(turbofan): We should consider feedback types here as well. |
1893 if (BothInputsAreUnsigned32(node)) { | 1881 if (BothInputsAreUnsigned32(node)) { |
1894 VisitUint32Binop(node); | 1882 VisitUint32Binop(node); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 MachineRepresentation::kFloat64); | 1934 MachineRepresentation::kFloat64); |
1947 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1935 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
1948 return; | 1936 return; |
1949 } | 1937 } |
1950 case IrOpcode::kNumberAcos: | 1938 case IrOpcode::kNumberAcos: |
1951 case IrOpcode::kNumberAcosh: | 1939 case IrOpcode::kNumberAcosh: |
1952 case IrOpcode::kNumberAsin: | 1940 case IrOpcode::kNumberAsin: |
1953 case IrOpcode::kNumberAsinh: | 1941 case IrOpcode::kNumberAsinh: |
1954 case IrOpcode::kNumberAtan: | 1942 case IrOpcode::kNumberAtan: |
1955 case IrOpcode::kNumberAtanh: | 1943 case IrOpcode::kNumberAtanh: |
| 1944 case IrOpcode::kNumberCeil: |
1956 case IrOpcode::kNumberCos: | 1945 case IrOpcode::kNumberCos: |
1957 case IrOpcode::kNumberCosh: | 1946 case IrOpcode::kNumberCosh: |
1958 case IrOpcode::kNumberExp: | 1947 case IrOpcode::kNumberExp: |
1959 case IrOpcode::kNumberExpm1: | 1948 case IrOpcode::kNumberExpm1: |
| 1949 case IrOpcode::kNumberFloor: |
1960 case IrOpcode::kNumberLog: | 1950 case IrOpcode::kNumberLog: |
1961 case IrOpcode::kNumberLog1p: | 1951 case IrOpcode::kNumberLog1p: |
1962 case IrOpcode::kNumberLog2: | 1952 case IrOpcode::kNumberLog2: |
1963 case IrOpcode::kNumberLog10: | 1953 case IrOpcode::kNumberLog10: |
1964 case IrOpcode::kNumberCbrt: | 1954 case IrOpcode::kNumberCbrt: |
1965 case IrOpcode::kNumberSin: | 1955 case IrOpcode::kNumberSin: |
1966 case IrOpcode::kNumberSinh: | 1956 case IrOpcode::kNumberSinh: |
1967 case IrOpcode::kNumberTan: | 1957 case IrOpcode::kNumberTan: |
1968 case IrOpcode::kNumberTanh: { | 1958 case IrOpcode::kNumberTanh: |
| 1959 case IrOpcode::kNumberTrunc: { |
1969 VisitUnop(node, UseInfo::TruncatingFloat64(), | 1960 VisitUnop(node, UseInfo::TruncatingFloat64(), |
1970 MachineRepresentation::kFloat64); | 1961 MachineRepresentation::kFloat64); |
1971 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1962 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
1972 return; | 1963 return; |
1973 } | 1964 } |
1974 case IrOpcode::kNumberRound: { | 1965 case IrOpcode::kNumberRound: { |
1975 VisitUnop(node, UseInfo::TruncatingFloat64(), | 1966 VisitUnop(node, UseInfo::TruncatingFloat64(), |
1976 MachineRepresentation::kFloat64); | 1967 MachineRepresentation::kFloat64); |
1977 if (lower()) DeferReplacement(node, lowering->Float64Round(node)); | 1968 if (lower()) DeferReplacement(node, lowering->Float64Round(node)); |
1978 return; | 1969 return; |
1979 } | 1970 } |
1980 case IrOpcode::kNumberSign: { | 1971 case IrOpcode::kNumberSign: { |
1981 if (InputIs(node, Type::Signed32())) { | 1972 if (InputIs(node, Type::Signed32())) { |
1982 VisitUnop(node, UseInfo::TruncatingWord32(), | 1973 VisitUnop(node, UseInfo::TruncatingWord32(), |
1983 MachineRepresentation::kWord32); | 1974 MachineRepresentation::kWord32); |
1984 if (lower()) DeferReplacement(node, lowering->Int32Sign(node)); | 1975 if (lower()) DeferReplacement(node, lowering->Int32Sign(node)); |
1985 } else { | 1976 } else { |
1986 VisitUnop(node, UseInfo::TruncatingFloat64(), | 1977 VisitUnop(node, UseInfo::TruncatingFloat64(), |
1987 MachineRepresentation::kFloat64); | 1978 MachineRepresentation::kFloat64); |
1988 if (lower()) DeferReplacement(node, lowering->Float64Sign(node)); | 1979 if (lower()) DeferReplacement(node, lowering->Float64Sign(node)); |
1989 } | 1980 } |
1990 return; | 1981 return; |
1991 } | 1982 } |
1992 case IrOpcode::kNumberSqrt: { | 1983 case IrOpcode::kNumberSqrt: { |
1993 VisitUnop(node, UseInfo::TruncatingFloat64(), | 1984 VisitUnop(node, UseInfo::TruncatingFloat64(), |
1994 MachineRepresentation::kFloat64); | 1985 MachineRepresentation::kFloat64); |
1995 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1986 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
1996 return; | 1987 return; |
1997 } | 1988 } |
1998 case IrOpcode::kNumberTrunc: { | |
1999 VisitUnop(node, UseInfo::TruncatingFloat64(), | |
2000 MachineRepresentation::kFloat64); | |
2001 if (lower()) DeferReplacement(node, lowering->Float64Trunc(node)); | |
2002 return; | |
2003 } | |
2004 case IrOpcode::kNumberToInt32: { | 1989 case IrOpcode::kNumberToInt32: { |
2005 // Just change representation if necessary. | 1990 // Just change representation if necessary. |
2006 VisitUnop(node, UseInfo::TruncatingWord32(), | 1991 VisitUnop(node, UseInfo::TruncatingWord32(), |
2007 MachineRepresentation::kWord32); | 1992 MachineRepresentation::kWord32); |
2008 if (lower()) DeferReplacement(node, node->InputAt(0)); | 1993 if (lower()) DeferReplacement(node, node->InputAt(0)); |
2009 return; | 1994 return; |
2010 } | 1995 } |
2011 case IrOpcode::kNumberToUint32: { | 1996 case IrOpcode::kNumberToUint32: { |
2012 // Just change representation if necessary. | 1997 // Just change representation if necessary. |
2013 VisitUnop(node, UseInfo::TruncatingWord32(), | 1998 VisitUnop(node, UseInfo::TruncatingWord32(), |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2920 } | 2905 } |
2921 | 2906 |
2922 | 2907 |
2923 void SimplifiedLowering::DoStoreBuffer(Node* node) { | 2908 void SimplifiedLowering::DoStoreBuffer(Node* node) { |
2924 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); | 2909 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); |
2925 MachineRepresentation const rep = | 2910 MachineRepresentation const rep = |
2926 BufferAccessOf(node->op()).machine_type().representation(); | 2911 BufferAccessOf(node->op()).machine_type().representation(); |
2927 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); | 2912 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); |
2928 } | 2913 } |
2929 | 2914 |
2930 Node* SimplifiedLowering::Float64Ceil(Node* const node) { | |
2931 Node* const one = jsgraph()->Float64Constant(1.0); | |
2932 Node* const zero = jsgraph()->Float64Constant(0.0); | |
2933 Node* const minus_zero = jsgraph()->Float64Constant(-0.0); | |
2934 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); | |
2935 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); | |
2936 Node* const input = node->InputAt(0); | |
2937 | |
2938 // Use fast hardware instruction if available. | |
2939 if (machine()->Float64RoundUp().IsSupported()) { | |
2940 return graph()->NewNode(machine()->Float64RoundUp().op(), input); | |
2941 } | |
2942 | |
2943 // General case for ceil. | |
2944 // | |
2945 // if 0.0 < input then | |
2946 // if 2^52 <= input then | |
2947 // input | |
2948 // else | |
2949 // let temp1 = (2^52 + input) - 2^52 in | |
2950 // if temp1 < input then | |
2951 // temp1 + 1 | |
2952 // else | |
2953 // temp1 | |
2954 // else | |
2955 // if input == 0 then | |
2956 // input | |
2957 // else | |
2958 // if input <= -2^52 then | |
2959 // input | |
2960 // else | |
2961 // let temp1 = -0 - input in | |
2962 // let temp2 = (2^52 + temp1) - 2^52 in | |
2963 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in | |
2964 // -0 - temp3 | |
2965 // | |
2966 // Note: We do not use the Diamond helper class here, because it really hurts | |
2967 // readability with nested diamonds. | |
2968 | |
2969 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); | |
2970 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | |
2971 graph()->start()); | |
2972 | |
2973 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | |
2974 Node* vtrue0; | |
2975 { | |
2976 Node* check1 = | |
2977 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); | |
2978 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); | |
2979 | |
2980 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
2981 Node* vtrue1 = input; | |
2982 | |
2983 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
2984 Node* vfalse1; | |
2985 { | |
2986 Node* temp1 = graph()->NewNode( | |
2987 machine()->Float64Sub(), | |
2988 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); | |
2989 vfalse1 = graph()->NewNode( | |
2990 common()->Select(MachineRepresentation::kFloat64), | |
2991 graph()->NewNode(machine()->Float64LessThan(), temp1, input), | |
2992 graph()->NewNode(machine()->Float64Add(), temp1, one), temp1); | |
2993 } | |
2994 | |
2995 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
2996 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
2997 vtrue1, vfalse1, if_true0); | |
2998 } | |
2999 | |
3000 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | |
3001 Node* vfalse0; | |
3002 { | |
3003 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); | |
3004 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3005 check1, if_false0); | |
3006 | |
3007 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
3008 Node* vtrue1 = input; | |
3009 | |
3010 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
3011 Node* vfalse1; | |
3012 { | |
3013 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), | |
3014 input, minus_two_52); | |
3015 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3016 check2, if_false1); | |
3017 | |
3018 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
3019 Node* vtrue2 = input; | |
3020 | |
3021 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
3022 Node* vfalse2; | |
3023 { | |
3024 Node* temp1 = | |
3025 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); | |
3026 Node* temp2 = graph()->NewNode( | |
3027 machine()->Float64Sub(), | |
3028 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); | |
3029 Node* temp3 = graph()->NewNode( | |
3030 common()->Select(MachineRepresentation::kFloat64), | |
3031 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2), | |
3032 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2); | |
3033 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3); | |
3034 } | |
3035 | |
3036 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
3037 vfalse1 = | |
3038 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3039 vtrue2, vfalse2, if_false1); | |
3040 } | |
3041 | |
3042 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
3043 vfalse0 = | |
3044 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3045 vtrue1, vfalse1, if_false0); | |
3046 } | |
3047 | |
3048 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
3049 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3050 vtrue0, vfalse0, merge0); | |
3051 } | |
3052 | |
3053 Node* SimplifiedLowering::Float64Floor(Node* const node) { | |
3054 Node* const one = jsgraph()->Float64Constant(1.0); | |
3055 Node* const zero = jsgraph()->Float64Constant(0.0); | |
3056 Node* const minus_one = jsgraph()->Float64Constant(-1.0); | |
3057 Node* const minus_zero = jsgraph()->Float64Constant(-0.0); | |
3058 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); | |
3059 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); | |
3060 Node* const input = node->InputAt(0); | |
3061 | |
3062 // Use fast hardware instruction if available. | |
3063 if (machine()->Float64RoundDown().IsSupported()) { | |
3064 return graph()->NewNode(machine()->Float64RoundDown().op(), input); | |
3065 } | |
3066 | |
3067 // General case for floor. | |
3068 // | |
3069 // if 0.0 < input then | |
3070 // if 2^52 <= input then | |
3071 // input | |
3072 // else | |
3073 // let temp1 = (2^52 + input) - 2^52 in | |
3074 // if input < temp1 then | |
3075 // temp1 - 1 | |
3076 // else | |
3077 // temp1 | |
3078 // else | |
3079 // if input == 0 then | |
3080 // input | |
3081 // else | |
3082 // if input <= -2^52 then | |
3083 // input | |
3084 // else | |
3085 // let temp1 = -0 - input in | |
3086 // let temp2 = (2^52 + temp1) - 2^52 in | |
3087 // if temp2 < temp1 then | |
3088 // -1 - temp2 | |
3089 // else | |
3090 // -0 - temp2 | |
3091 // | |
3092 // Note: We do not use the Diamond helper class here, because it really hurts | |
3093 // readability with nested diamonds. | |
3094 | |
3095 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); | |
3096 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | |
3097 graph()->start()); | |
3098 | |
3099 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | |
3100 Node* vtrue0; | |
3101 { | |
3102 Node* check1 = | |
3103 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); | |
3104 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); | |
3105 | |
3106 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
3107 Node* vtrue1 = input; | |
3108 | |
3109 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
3110 Node* vfalse1; | |
3111 { | |
3112 Node* temp1 = graph()->NewNode( | |
3113 machine()->Float64Sub(), | |
3114 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); | |
3115 vfalse1 = graph()->NewNode( | |
3116 common()->Select(MachineRepresentation::kFloat64), | |
3117 graph()->NewNode(machine()->Float64LessThan(), input, temp1), | |
3118 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1); | |
3119 } | |
3120 | |
3121 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
3122 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3123 vtrue1, vfalse1, if_true0); | |
3124 } | |
3125 | |
3126 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | |
3127 Node* vfalse0; | |
3128 { | |
3129 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); | |
3130 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3131 check1, if_false0); | |
3132 | |
3133 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
3134 Node* vtrue1 = input; | |
3135 | |
3136 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
3137 Node* vfalse1; | |
3138 { | |
3139 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), | |
3140 input, minus_two_52); | |
3141 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3142 check2, if_false1); | |
3143 | |
3144 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
3145 Node* vtrue2 = input; | |
3146 | |
3147 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
3148 Node* vfalse2; | |
3149 { | |
3150 Node* temp1 = | |
3151 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); | |
3152 Node* temp2 = graph()->NewNode( | |
3153 machine()->Float64Sub(), | |
3154 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); | |
3155 vfalse2 = graph()->NewNode( | |
3156 common()->Select(MachineRepresentation::kFloat64), | |
3157 graph()->NewNode(machine()->Float64LessThan(), temp2, temp1), | |
3158 graph()->NewNode(machine()->Float64Sub(), minus_one, temp2), | |
3159 graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2)); | |
3160 } | |
3161 | |
3162 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
3163 vfalse1 = | |
3164 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3165 vtrue2, vfalse2, if_false1); | |
3166 } | |
3167 | |
3168 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
3169 vfalse0 = | |
3170 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3171 vtrue1, vfalse1, if_false0); | |
3172 } | |
3173 | |
3174 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
3175 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3176 vtrue0, vfalse0, merge0); | |
3177 } | |
3178 | |
3179 Node* SimplifiedLowering::Float64Round(Node* const node) { | 2915 Node* SimplifiedLowering::Float64Round(Node* const node) { |
3180 Node* const one = jsgraph()->Float64Constant(1.0); | 2916 Node* const one = jsgraph()->Float64Constant(1.0); |
3181 Node* const one_half = jsgraph()->Float64Constant(0.5); | 2917 Node* const one_half = jsgraph()->Float64Constant(0.5); |
3182 Node* const input = node->InputAt(0); | 2918 Node* const input = node->InputAt(0); |
3183 | 2919 |
3184 // Round up towards Infinity, and adjust if the difference exceeds 0.5. | 2920 // Round up towards Infinity, and adjust if the difference exceeds 0.5. |
3185 Node* result = Float64Ceil(node); | 2921 Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(), |
| 2922 node->InputAt(0)); |
3186 return graph()->NewNode( | 2923 return graph()->NewNode( |
3187 common()->Select(MachineRepresentation::kFloat64), | 2924 common()->Select(MachineRepresentation::kFloat64), |
3188 graph()->NewNode( | 2925 graph()->NewNode( |
3189 machine()->Float64LessThanOrEqual(), | 2926 machine()->Float64LessThanOrEqual(), |
3190 graph()->NewNode(machine()->Float64Sub(), result, one_half), input), | 2927 graph()->NewNode(machine()->Float64Sub(), result, one_half), input), |
3191 result, graph()->NewNode(machine()->Float64Sub(), result, one)); | 2928 result, graph()->NewNode(machine()->Float64Sub(), result, one)); |
3192 } | 2929 } |
3193 | 2930 |
3194 Node* SimplifiedLowering::Float64Sign(Node* const node) { | 2931 Node* SimplifiedLowering::Float64Sign(Node* const node) { |
3195 Node* const minus_one = jsgraph()->Float64Constant(-1.0); | 2932 Node* const minus_one = jsgraph()->Float64Constant(-1.0); |
3196 Node* const zero = jsgraph()->Float64Constant(0.0); | 2933 Node* const zero = jsgraph()->Float64Constant(0.0); |
3197 Node* const one = jsgraph()->Float64Constant(1.0); | 2934 Node* const one = jsgraph()->Float64Constant(1.0); |
3198 | 2935 |
3199 Node* const input = node->InputAt(0); | 2936 Node* const input = node->InputAt(0); |
3200 | 2937 |
3201 return graph()->NewNode( | 2938 return graph()->NewNode( |
3202 common()->Select(MachineRepresentation::kFloat64), | 2939 common()->Select(MachineRepresentation::kFloat64), |
3203 graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one, | 2940 graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one, |
3204 graph()->NewNode( | 2941 graph()->NewNode( |
3205 common()->Select(MachineRepresentation::kFloat64), | 2942 common()->Select(MachineRepresentation::kFloat64), |
3206 graph()->NewNode(machine()->Float64LessThan(), zero, input), one, | 2943 graph()->NewNode(machine()->Float64LessThan(), zero, input), one, |
3207 zero)); | 2944 zero)); |
3208 } | 2945 } |
3209 | 2946 |
3210 Node* SimplifiedLowering::Float64Trunc(Node* const node) { | |
3211 Node* const one = jsgraph()->Float64Constant(1.0); | |
3212 Node* const zero = jsgraph()->Float64Constant(0.0); | |
3213 Node* const minus_zero = jsgraph()->Float64Constant(-0.0); | |
3214 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); | |
3215 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); | |
3216 Node* const input = node->InputAt(0); | |
3217 | |
3218 // Use fast hardware instruction if available. | |
3219 if (machine()->Float64RoundTruncate().IsSupported()) { | |
3220 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input); | |
3221 } | |
3222 | |
3223 // General case for trunc. | |
3224 // | |
3225 // if 0.0 < input then | |
3226 // if 2^52 <= input then | |
3227 // input | |
3228 // else | |
3229 // let temp1 = (2^52 + input) - 2^52 in | |
3230 // if input < temp1 then | |
3231 // temp1 - 1 | |
3232 // else | |
3233 // temp1 | |
3234 // else | |
3235 // if input == 0 then | |
3236 // input | |
3237 // else | |
3238 // if input <= -2^52 then | |
3239 // input | |
3240 // else | |
3241 // let temp1 = -0 - input in | |
3242 // let temp2 = (2^52 + temp1) - 2^52 in | |
3243 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in | |
3244 // -0 - temp3 | |
3245 // | |
3246 // Note: We do not use the Diamond helper class here, because it really hurts | |
3247 // readability with nested diamonds. | |
3248 | |
3249 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); | |
3250 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, | |
3251 graph()->start()); | |
3252 | |
3253 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | |
3254 Node* vtrue0; | |
3255 { | |
3256 Node* check1 = | |
3257 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); | |
3258 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); | |
3259 | |
3260 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
3261 Node* vtrue1 = input; | |
3262 | |
3263 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
3264 Node* vfalse1; | |
3265 { | |
3266 Node* temp1 = graph()->NewNode( | |
3267 machine()->Float64Sub(), | |
3268 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); | |
3269 vfalse1 = graph()->NewNode( | |
3270 common()->Select(MachineRepresentation::kFloat64), | |
3271 graph()->NewNode(machine()->Float64LessThan(), input, temp1), | |
3272 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1); | |
3273 } | |
3274 | |
3275 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
3276 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3277 vtrue1, vfalse1, if_true0); | |
3278 } | |
3279 | |
3280 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | |
3281 Node* vfalse0; | |
3282 { | |
3283 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); | |
3284 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3285 check1, if_false0); | |
3286 | |
3287 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
3288 Node* vtrue1 = input; | |
3289 | |
3290 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
3291 Node* vfalse1; | |
3292 { | |
3293 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), | |
3294 input, minus_two_52); | |
3295 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
3296 check2, if_false1); | |
3297 | |
3298 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
3299 Node* vtrue2 = input; | |
3300 | |
3301 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
3302 Node* vfalse2; | |
3303 { | |
3304 Node* temp1 = | |
3305 graph()->NewNode(machine()->Float64Sub(), minus_zero, input); | |
3306 Node* temp2 = graph()->NewNode( | |
3307 machine()->Float64Sub(), | |
3308 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); | |
3309 Node* temp3 = graph()->NewNode( | |
3310 common()->Select(MachineRepresentation::kFloat64), | |
3311 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2), | |
3312 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2); | |
3313 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3); | |
3314 } | |
3315 | |
3316 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
3317 vfalse1 = | |
3318 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3319 vtrue2, vfalse2, if_false1); | |
3320 } | |
3321 | |
3322 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
3323 vfalse0 = | |
3324 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3325 vtrue1, vfalse1, if_false0); | |
3326 } | |
3327 | |
3328 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
3329 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | |
3330 vtrue0, vfalse0, merge0); | |
3331 } | |
3332 | |
3333 Node* SimplifiedLowering::Int32Abs(Node* const node) { | 2947 Node* SimplifiedLowering::Int32Abs(Node* const node) { |
3334 Node* const input = node->InputAt(0); | 2948 Node* const input = node->InputAt(0); |
3335 | 2949 |
3336 // Generate case for absolute integer value. | 2950 // Generate case for absolute integer value. |
3337 // | 2951 // |
3338 // let sign = input >> 31 in | 2952 // let sign = input >> 31 in |
3339 // (input ^ sign) - sign | 2953 // (input ^ sign) - sign |
3340 | 2954 |
3341 Node* sign = graph()->NewNode(machine()->Word32Sar(), input, | 2955 Node* sign = graph()->NewNode(machine()->Word32Sar(), input, |
3342 jsgraph()->Int32Constant(31)); | 2956 jsgraph()->Int32Constant(31)); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3673 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3287 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3674 Operator::kNoProperties); | 3288 Operator::kNoProperties); |
3675 to_number_operator_.set(common()->Call(desc)); | 3289 to_number_operator_.set(common()->Call(desc)); |
3676 } | 3290 } |
3677 return to_number_operator_.get(); | 3291 return to_number_operator_.get(); |
3678 } | 3292 } |
3679 | 3293 |
3680 } // namespace compiler | 3294 } // namespace compiler |
3681 } // namespace internal | 3295 } // namespace internal |
3682 } // namespace v8 | 3296 } // namespace v8 |
OLD | NEW |