| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 Move(expr->context(), rax); | 1131 Move(expr->context(), rax); |
| 1132 | 1132 |
| 1133 break; | 1133 break; |
| 1134 } | 1134 } |
| 1135 default: | 1135 default: |
| 1136 UNREACHABLE(); | 1136 UNREACHABLE(); |
| 1137 } | 1137 } |
| 1138 } | 1138 } |
| 1139 | 1139 |
| 1140 | 1140 |
| 1141 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 1142 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
| 1143 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
| 1144 Visit(expr->left()); |
| 1145 Visit(expr->right()); |
| 1146 |
| 1147 // Convert current context to test context: Pre-test code. |
| 1148 Label push_true; |
| 1149 Label push_false; |
| 1150 Label done; |
| 1151 Label* saved_true = true_label_; |
| 1152 Label* saved_false = false_label_; |
| 1153 switch (expr->context()) { |
| 1154 case Expression::kUninitialized: |
| 1155 UNREACHABLE(); |
| 1156 break; |
| 1157 |
| 1158 case Expression::kValue: |
| 1159 true_label_ = &push_true; |
| 1160 false_label_ = &push_false; |
| 1161 break; |
| 1162 |
| 1163 case Expression::kEffect: |
| 1164 true_label_ = &done; |
| 1165 false_label_ = &done; |
| 1166 break; |
| 1167 |
| 1168 case Expression::kTest: |
| 1169 break; |
| 1170 |
| 1171 case Expression::kValueTest: |
| 1172 true_label_ = &push_true; |
| 1173 break; |
| 1174 |
| 1175 case Expression::kTestValue: |
| 1176 false_label_ = &push_false; |
| 1177 break; |
| 1178 } |
| 1179 // Convert current context to test context: End pre-test code. |
| 1180 |
| 1181 switch (expr->op()) { |
| 1182 case Token::IN: { |
| 1183 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 1184 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
| 1185 __ j(equal, true_label_); |
| 1186 __ jmp(false_label_); |
| 1187 break; |
| 1188 } |
| 1189 |
| 1190 case Token::INSTANCEOF: { |
| 1191 InstanceofStub stub; |
| 1192 __ CallStub(&stub); |
| 1193 __ testq(rax, rax); |
| 1194 __ j(zero, true_label_); // The stub returns 0 for true. |
| 1195 __ jmp(false_label_); |
| 1196 break; |
| 1197 } |
| 1198 |
| 1199 default: { |
| 1200 Condition cc = no_condition; |
| 1201 bool strict = false; |
| 1202 switch (expr->op()) { |
| 1203 case Token::EQ_STRICT: |
| 1204 strict = true; |
| 1205 // Fall through |
| 1206 case Token::EQ: |
| 1207 cc = equal; |
| 1208 __ pop(rax); |
| 1209 __ pop(rdx); |
| 1210 break; |
| 1211 case Token::LT: |
| 1212 cc = less; |
| 1213 __ pop(rax); |
| 1214 __ pop(rdx); |
| 1215 break; |
| 1216 case Token::GT: |
| 1217 // Reverse left and right sizes to obtain ECMA-262 conversion order. |
| 1218 cc = less; |
| 1219 __ pop(rdx); |
| 1220 __ pop(rax); |
| 1221 break; |
| 1222 case Token::LTE: |
| 1223 // Reverse left and right sizes to obtain ECMA-262 conversion order. |
| 1224 cc = greater_equal; |
| 1225 __ pop(rdx); |
| 1226 __ pop(rax); |
| 1227 break; |
| 1228 case Token::GTE: |
| 1229 cc = greater_equal; |
| 1230 __ pop(rax); |
| 1231 __ pop(rdx); |
| 1232 break; |
| 1233 case Token::IN: |
| 1234 case Token::INSTANCEOF: |
| 1235 default: |
| 1236 UNREACHABLE(); |
| 1237 } |
| 1238 |
| 1239 // The comparison stub expects the smi vs. smi case to be handled |
| 1240 // before it is called. |
| 1241 Label slow_case; |
| 1242 __ JumpIfNotBothSmi(rax, rdx, &slow_case); |
| 1243 __ SmiCompare(rdx, rax); |
| 1244 __ j(cc, true_label_); |
| 1245 __ jmp(false_label_); |
| 1246 |
| 1247 __ bind(&slow_case); |
| 1248 CompareStub stub(cc, strict); |
| 1249 __ CallStub(&stub); |
| 1250 __ testq(rax, rax); |
| 1251 __ j(cc, true_label_); |
| 1252 __ jmp(false_label_); |
| 1253 } |
| 1254 } |
| 1255 |
| 1256 // Convert current context to test context: Post-test code. |
| 1257 switch (expr->context()) { |
| 1258 case Expression::kUninitialized: |
| 1259 UNREACHABLE(); |
| 1260 break; |
| 1261 |
| 1262 case Expression::kValue: |
| 1263 __ bind(&push_true); |
| 1264 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1265 __ jmp(&done); |
| 1266 __ bind(&push_false); |
| 1267 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1268 __ bind(&done); |
| 1269 break; |
| 1270 |
| 1271 case Expression::kEffect: |
| 1272 __ bind(&done); |
| 1273 break; |
| 1274 |
| 1275 case Expression::kTest: |
| 1276 break; |
| 1277 |
| 1278 case Expression::kValueTest: |
| 1279 __ bind(&push_true); |
| 1280 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1281 __ jmp(saved_true); |
| 1282 break; |
| 1283 |
| 1284 case Expression::kTestValue: |
| 1285 __ bind(&push_false); |
| 1286 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1287 __ jmp(saved_false); |
| 1288 break; |
| 1289 } |
| 1290 true_label_ = saved_true; |
| 1291 false_label_ = saved_false; |
| 1292 // Convert current context to test context: End post-test code. |
| 1293 } |
| 1294 |
| 1295 |
| 1296 #undef __ |
| 1297 |
| 1298 |
| 1141 } } // namespace v8::internal | 1299 } } // namespace v8::internal |
| OLD | NEW |