Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: src/compiler/ppc/code-generator-ppc.cc

Issue 1552783002: PPC: [turbofan] Add Int64(Add|Sub)WithOverflow support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/ppc/instruction-selector-ppc.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler/code-generator-impl.h" 8 #include "src/compiler/code-generator-impl.h"
9 #include "src/compiler/gap-resolver.h" 9 #include "src/compiler/gap-resolver.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 private: 194 private:
195 Register const object_; 195 Register const object_;
196 Register const offset_; 196 Register const offset_;
197 Register const value_; 197 Register const value_;
198 Register const scratch0_; 198 Register const scratch0_;
199 Register const scratch1_; 199 Register const scratch1_;
200 RecordWriteMode const mode_; 200 RecordWriteMode const mode_;
201 }; 201 };
202 202
203 203
204 Condition FlagsConditionToCondition(FlagsCondition condition) { 204 Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
205 switch (condition) { 205 switch (condition) {
206 case kEqual: 206 case kEqual:
207 return eq; 207 return eq;
208 case kNotEqual: 208 case kNotEqual:
209 return ne; 209 return ne;
210 case kSignedLessThan: 210 case kSignedLessThan:
211 case kUnsignedLessThan: 211 case kUnsignedLessThan:
212 return lt; 212 return lt;
213 case kSignedGreaterThanOrEqual: 213 case kSignedGreaterThanOrEqual:
214 case kUnsignedGreaterThanOrEqual: 214 case kUnsignedGreaterThanOrEqual:
215 return ge; 215 return ge;
216 case kSignedLessThanOrEqual: 216 case kSignedLessThanOrEqual:
217 case kUnsignedLessThanOrEqual: 217 case kUnsignedLessThanOrEqual:
218 return le; 218 return le;
219 case kSignedGreaterThan: 219 case kSignedGreaterThan:
220 case kUnsignedGreaterThan: 220 case kUnsignedGreaterThan:
221 return gt; 221 return gt;
222 case kOverflow: 222 case kOverflow:
223 // Overflow checked for add/sub only.
224 switch (op) {
223 #if V8_TARGET_ARCH_PPC64 225 #if V8_TARGET_ARCH_PPC64
224 return ne; 226 case kPPC_Add:
227 case kPPC_Sub:
228 return lt;
229 #endif
230 case kPPC_AddWithOverflow32:
231 case kPPC_SubWithOverflow32:
232 #if V8_TARGET_ARCH_PPC64
233 return ne;
225 #else 234 #else
226 return lt; 235 return lt;
227 #endif 236 #endif
237 default:
238 break;
239 }
240 break;
228 case kNotOverflow: 241 case kNotOverflow:
242 switch (op) {
229 #if V8_TARGET_ARCH_PPC64 243 #if V8_TARGET_ARCH_PPC64
230 return eq; 244 case kPPC_Add:
245 case kPPC_Sub:
246 return ge;
247 #endif
248 case kPPC_AddWithOverflow32:
249 case kPPC_SubWithOverflow32:
250 #if V8_TARGET_ARCH_PPC64
251 return eq;
231 #else 252 #else
232 return ge; 253 return ge;
233 #endif 254 #endif
255 default:
256 break;
257 }
258 break;
234 default: 259 default:
235 break; 260 break;
236 } 261 }
237 UNREACHABLE(); 262 UNREACHABLE();
238 return kNoCondition; 263 return kNoCondition;
239 } 264 }
240 265
241 } // namespace 266 } // namespace
242 267
243 #define ASSEMBLE_FLOAT_UNOP_RC(asm_instr) \ 268 #define ASSEMBLE_FLOAT_UNOP_RC(asm_instr) \
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 if (HasRegisterInput(instr, 1)) { \ 308 if (HasRegisterInput(instr, 1)) { \
284 __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \ 309 __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
285 i.InputRegister(1), i.OutputRCBit()); \ 310 i.InputRegister(1), i.OutputRCBit()); \
286 } else { \ 311 } else { \
287 __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \ 312 __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
288 i.InputInt32(1), i.OutputRCBit()); \ 313 i.InputInt32(1), i.OutputRCBit()); \
289 } \ 314 } \
290 } while (0) 315 } while (0)
291 316
292 317
293 #if V8_TARGET_ARCH_PPC64
294 #define ASSEMBLE_ADD_WITH_OVERFLOW() \
295 do { \
296 ASSEMBLE_BINOP(add, addi); \
297 __ TestIfInt32(i.OutputRegister(), r0, cr0); \
298 } while (0)
299 #else
300 #define ASSEMBLE_ADD_WITH_OVERFLOW() \ 318 #define ASSEMBLE_ADD_WITH_OVERFLOW() \
301 do { \ 319 do { \
302 if (HasRegisterInput(instr, 1)) { \ 320 if (HasRegisterInput(instr, 1)) { \
303 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 321 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
304 i.InputRegister(1), kScratchReg, r0); \ 322 i.InputRegister(1), kScratchReg, r0); \
305 } else { \ 323 } else { \
306 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 324 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
307 i.InputInt32(1), kScratchReg, r0); \ 325 i.InputInt32(1), kScratchReg, r0); \
308 } \ 326 } \
309 } while (0) 327 } while (0)
310 #endif
311 328
312 329
313 #if V8_TARGET_ARCH_PPC64
314 #define ASSEMBLE_SUB_WITH_OVERFLOW() \
315 do { \
316 ASSEMBLE_BINOP(sub, subi); \
317 __ TestIfInt32(i.OutputRegister(), r0, cr0); \
318 } while (0)
319 #else
320 #define ASSEMBLE_SUB_WITH_OVERFLOW() \ 330 #define ASSEMBLE_SUB_WITH_OVERFLOW() \
321 do { \ 331 do { \
322 if (HasRegisterInput(instr, 1)) { \ 332 if (HasRegisterInput(instr, 1)) { \
323 __ SubAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 333 __ SubAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
324 i.InputRegister(1), kScratchReg, r0); \ 334 i.InputRegister(1), kScratchReg, r0); \
325 } else { \ 335 } else { \
326 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ 336 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
327 -i.InputInt32(1), kScratchReg, r0); \ 337 -i.InputInt32(1), kScratchReg, r0); \
328 } \ 338 } \
329 } while (0) 339 } while (0)
340
341
342 #if V8_TARGET_ARCH_PPC64
343 #define ASSEMBLE_ADD_WITH_OVERFLOW32() \
344 do { \
345 ASSEMBLE_BINOP(add, addi); \
346 __ TestIfInt32(i.OutputRegister(), r0, cr0); \
347 } while (0)
348
349
350 #define ASSEMBLE_SUB_WITH_OVERFLOW32() \
351 do { \
352 ASSEMBLE_BINOP(sub, subi); \
353 __ TestIfInt32(i.OutputRegister(), r0, cr0); \
354 } while (0)
355 #else
356 #define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW
357 #define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW
330 #endif 358 #endif
331 359
332 360
333 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ 361 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \
334 do { \ 362 do { \
335 const CRegister cr = cr0; \ 363 const CRegister cr = cr0; \
336 if (HasRegisterInput(instr, 1)) { \ 364 if (HasRegisterInput(instr, 1)) { \
337 if (i.CompareLogical()) { \ 365 if (i.CompareLogical()) { \
338 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1), cr); \ 366 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1), cr); \
339 } else { \ 367 } else { \
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 case kPPC_RotLeftAndClearLeft64: 924 case kPPC_RotLeftAndClearLeft64:
897 __ rldicl(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 925 __ rldicl(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
898 63 - i.InputInt32(2), i.OutputRCBit()); 926 63 - i.InputInt32(2), i.OutputRCBit());
899 break; 927 break;
900 case kPPC_RotLeftAndClearRight64: 928 case kPPC_RotLeftAndClearRight64:
901 __ rldicr(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1), 929 __ rldicr(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
902 63 - i.InputInt32(2), i.OutputRCBit()); 930 63 - i.InputInt32(2), i.OutputRCBit());
903 break; 931 break;
904 #endif 932 #endif
905 case kPPC_Add: 933 case kPPC_Add:
906 if (HasRegisterInput(instr, 1)) { 934 #if V8_TARGET_ARCH_PPC64
907 __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 935 if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
908 LeaveOE, i.OutputRCBit()); 936 ASSEMBLE_ADD_WITH_OVERFLOW();
909 } else { 937 } else {
910 __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 938 #endif
911 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 939 if (HasRegisterInput(instr, 1)) {
940 __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
941 LeaveOE, i.OutputRCBit());
942 } else {
943 __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
944 DCHECK_EQ(LeaveRC, i.OutputRCBit());
945 }
946 #if V8_TARGET_ARCH_PPC64
912 } 947 }
948 #endif
913 break; 949 break;
914 case kPPC_AddWithOverflow32: 950 case kPPC_AddWithOverflow32:
915 ASSEMBLE_ADD_WITH_OVERFLOW(); 951 ASSEMBLE_ADD_WITH_OVERFLOW32();
916 break; 952 break;
917 case kPPC_AddDouble: 953 case kPPC_AddDouble:
918 ASSEMBLE_FLOAT_BINOP_RC(fadd); 954 ASSEMBLE_FLOAT_BINOP_RC(fadd);
919 break; 955 break;
920 case kPPC_Sub: 956 case kPPC_Sub:
921 if (HasRegisterInput(instr, 1)) { 957 #if V8_TARGET_ARCH_PPC64
922 __ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 958 if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
923 LeaveOE, i.OutputRCBit()); 959 ASSEMBLE_SUB_WITH_OVERFLOW();
924 } else { 960 } else {
925 __ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1)); 961 #endif
926 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 962 if (HasRegisterInput(instr, 1)) {
963 __ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
964 LeaveOE, i.OutputRCBit());
965 } else {
966 __ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
967 DCHECK_EQ(LeaveRC, i.OutputRCBit());
968 }
969 #if V8_TARGET_ARCH_PPC64
927 } 970 }
971 #endif
928 break; 972 break;
929 case kPPC_SubWithOverflow32: 973 case kPPC_SubWithOverflow32:
930 ASSEMBLE_SUB_WITH_OVERFLOW(); 974 ASSEMBLE_SUB_WITH_OVERFLOW32();
931 break; 975 break;
932 case kPPC_SubDouble: 976 case kPPC_SubDouble:
933 ASSEMBLE_FLOAT_BINOP_RC(fsub); 977 ASSEMBLE_FLOAT_BINOP_RC(fsub);
934 break; 978 break;
935 case kPPC_Mul32: 979 case kPPC_Mul32:
936 __ mullw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1), 980 __ mullw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
937 LeaveOE, i.OutputRCBit()); 981 LeaveOE, i.OutputRCBit());
938 break; 982 break;
939 #if V8_TARGET_ARCH_PPC64 983 #if V8_TARGET_ARCH_PPC64
940 case kPPC_Mul64: 984 case kPPC_Mul64:
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 case kPPC_ExtendSignWord32: 1165 case kPPC_ExtendSignWord32:
1122 __ extsw(i.OutputRegister(), i.InputRegister(0)); 1166 __ extsw(i.OutputRegister(), i.InputRegister(0));
1123 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1167 DCHECK_EQ(LeaveRC, i.OutputRCBit());
1124 break; 1168 break;
1125 case kPPC_Uint32ToUint64: 1169 case kPPC_Uint32ToUint64:
1126 // Zero extend 1170 // Zero extend
1127 __ clrldi(i.OutputRegister(), i.InputRegister(0), Operand(32)); 1171 __ clrldi(i.OutputRegister(), i.InputRegister(0), Operand(32));
1128 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1172 DCHECK_EQ(LeaveRC, i.OutputRCBit());
1129 break; 1173 break;
1130 case kPPC_Int64ToInt32: 1174 case kPPC_Int64ToInt32:
1131 // TODO(mbrandy): sign extend? 1175 __ extsw(i.OutputRegister(), i.InputRegister(0));
1132 __ Move(i.OutputRegister(), i.InputRegister(0));
1133 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1176 DCHECK_EQ(LeaveRC, i.OutputRCBit());
1134 break; 1177 break;
1135 case kPPC_Int64ToFloat32: 1178 case kPPC_Int64ToFloat32:
1136 __ ConvertInt64ToFloat(i.InputRegister(0), i.OutputDoubleRegister()); 1179 __ ConvertInt64ToFloat(i.InputRegister(0), i.OutputDoubleRegister());
1137 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1180 DCHECK_EQ(LeaveRC, i.OutputRCBit());
1138 break; 1181 break;
1139 case kPPC_Int64ToDouble: 1182 case kPPC_Int64ToDouble:
1140 __ ConvertInt64ToDouble(i.InputRegister(0), i.OutputDoubleRegister()); 1183 __ ConvertInt64ToDouble(i.InputRegister(0), i.OutputDoubleRegister());
1141 DCHECK_EQ(LeaveRC, i.OutputRCBit()); 1184 DCHECK_EQ(LeaveRC, i.OutputRCBit());
1142 break; 1185 break;
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 1406
1364 // Assembles branches after an instruction. 1407 // Assembles branches after an instruction.
1365 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 1408 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1366 PPCOperandConverter i(this, instr); 1409 PPCOperandConverter i(this, instr);
1367 Label* tlabel = branch->true_label; 1410 Label* tlabel = branch->true_label;
1368 Label* flabel = branch->false_label; 1411 Label* flabel = branch->false_label;
1369 ArchOpcode op = instr->arch_opcode(); 1412 ArchOpcode op = instr->arch_opcode();
1370 FlagsCondition condition = branch->condition; 1413 FlagsCondition condition = branch->condition;
1371 CRegister cr = cr0; 1414 CRegister cr = cr0;
1372 1415
1373 // Overflow checked for add/sub only. 1416 Condition cond = FlagsConditionToCondition(condition, op);
1374 DCHECK((condition != kOverflow && condition != kNotOverflow) ||
1375 (op == kPPC_AddWithOverflow32 || op == kPPC_SubWithOverflow32));
1376
1377 Condition cond = FlagsConditionToCondition(condition);
1378 if (op == kPPC_CmpDouble) { 1417 if (op == kPPC_CmpDouble) {
1379 // check for unordered if necessary 1418 // check for unordered if necessary
1380 if (cond == le) { 1419 if (cond == le) {
1381 __ bunordered(flabel, cr); 1420 __ bunordered(flabel, cr);
1382 // Unnecessary for eq/lt since only FU bit will be set. 1421 // Unnecessary for eq/lt since only FU bit will be set.
1383 } else if (cond == gt) { 1422 } else if (cond == gt) {
1384 __ bunordered(tlabel, cr); 1423 __ bunordered(tlabel, cr);
1385 // Unnecessary for ne/ge since only FU bit will be set. 1424 // Unnecessary for ne/ge since only FU bit will be set.
1386 } 1425 }
1387 } 1426 }
1388 __ b(cond, tlabel, cr); 1427 __ b(cond, tlabel, cr);
1389 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel. 1428 if (!branch->fallthru) __ b(flabel); // no fallthru to flabel.
1390 } 1429 }
1391 1430
1392 1431
1393 void CodeGenerator::AssembleArchJump(RpoNumber target) { 1432 void CodeGenerator::AssembleArchJump(RpoNumber target) {
1394 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); 1433 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
1395 } 1434 }
1396 1435
1397 1436
1398 // Assembles boolean materializations after an instruction. 1437 // Assembles boolean materializations after an instruction.
1399 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 1438 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
1400 FlagsCondition condition) { 1439 FlagsCondition condition) {
1401 PPCOperandConverter i(this, instr); 1440 PPCOperandConverter i(this, instr);
1402 Label done; 1441 Label done;
1403 ArchOpcode op = instr->arch_opcode(); 1442 ArchOpcode op = instr->arch_opcode();
1404 bool check_unordered = (op == kPPC_CmpDouble); 1443 bool check_unordered = (op == kPPC_CmpDouble);
1405 CRegister cr = cr0; 1444 CRegister cr = cr0;
1406 1445
1407 // Overflow checked for add/sub only.
1408 DCHECK((condition != kOverflow && condition != kNotOverflow) ||
1409 (op == kPPC_AddWithOverflow32 || op == kPPC_SubWithOverflow32));
1410
1411 // Materialize a full 32-bit 1 or 0 value. The result register is always the 1446 // Materialize a full 32-bit 1 or 0 value. The result register is always the
1412 // last output of the instruction. 1447 // last output of the instruction.
1413 DCHECK_NE(0u, instr->OutputCount()); 1448 DCHECK_NE(0u, instr->OutputCount());
1414 Register reg = i.OutputRegister(instr->OutputCount() - 1); 1449 Register reg = i.OutputRegister(instr->OutputCount() - 1);
1415 1450
1416 Condition cond = FlagsConditionToCondition(condition); 1451 Condition cond = FlagsConditionToCondition(condition, op);
1417 switch (cond) { 1452 switch (cond) {
1418 case eq: 1453 case eq:
1419 case lt: 1454 case lt:
1420 __ li(reg, Operand::Zero()); 1455 __ li(reg, Operand::Zero());
1421 __ li(kScratchReg, Operand(1)); 1456 __ li(kScratchReg, Operand(1));
1422 __ isel(cond, reg, kScratchReg, reg, cr); 1457 __ isel(cond, reg, kScratchReg, reg, cr);
1423 break; 1458 break;
1424 case ne: 1459 case ne:
1425 case ge: 1460 case ge:
1426 __ li(reg, Operand(1)); 1461 __ li(reg, Operand(1));
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 padding_size -= v8::internal::Assembler::kInstrSize; 1841 padding_size -= v8::internal::Assembler::kInstrSize;
1807 } 1842 }
1808 } 1843 }
1809 } 1844 }
1810 1845
1811 #undef __ 1846 #undef __
1812 1847
1813 } // namespace compiler 1848 } // namespace compiler
1814 } // namespace internal 1849 } // namespace internal
1815 } // namespace v8 1850 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/ppc/instruction-selector-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698