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

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

Issue 2696343002: s390: optimize for compares (Closed)
Patch Set: add todo Created 3 years, 10 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/s390/instruction-codes-s390.h » ('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 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/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compilation-info.h" 7 #include "src/compilation-info.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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 #if V8_TARGET_ARCH_S390X && !V8_TARGET_LITTLE_ENDIAN 124 #if V8_TARGET_ARCH_S390X && !V8_TARGET_LITTLE_ENDIAN
125 // We want to read the 32-bits directly from memory 125 // We want to read the 32-bits directly from memory
126 MemOperand mem = InputStackSlot(index); 126 MemOperand mem = InputStackSlot(index);
127 return MemOperand(mem.rb(), mem.rx(), mem.offset() + 4); 127 return MemOperand(mem.rb(), mem.rx(), mem.offset() + 4);
128 #else 128 #else
129 return InputStackSlot(index); 129 return InputStackSlot(index);
130 #endif 130 #endif
131 } 131 }
132 }; 132 };
133 133
134 static inline bool HasRegisterOutput(Instruction* instr, int index = 0) {
135 return instr->OutputCount() > 0 && instr->OutputAt(index)->IsRegister();
136 }
137
134 static inline bool HasRegisterInput(Instruction* instr, int index) { 138 static inline bool HasRegisterInput(Instruction* instr, int index) {
135 return instr->InputAt(index)->IsRegister(); 139 return instr->InputAt(index)->IsRegister();
136 } 140 }
137 141
142 static inline bool HasFPRegisterInput(Instruction* instr, int index) {
143 return instr->InputAt(index)->IsFPRegister();
144 }
145
138 static inline bool HasImmediateInput(Instruction* instr, size_t index) { 146 static inline bool HasImmediateInput(Instruction* instr, size_t index) {
139 return instr->InputAt(index)->IsImmediate(); 147 return instr->InputAt(index)->IsImmediate();
140 } 148 }
141 149
142 static inline bool HasStackSlotInput(Instruction* instr, size_t index) { 150 static inline bool HasStackSlotInput(Instruction* instr, size_t index) {
143 return instr->InputAt(index)->IsStackSlot(); 151 return instr->InputAt(index)->IsStackSlot();
144 } 152 }
145 153
154 static inline bool HasFPStackSlotInput(Instruction* instr, size_t index) {
155 return instr->InputAt(index)->IsFPStackSlot();
156 }
157
146 namespace { 158 namespace {
147 159
148 class OutOfLineLoadNAN32 final : public OutOfLineCode { 160 class OutOfLineLoadNAN32 final : public OutOfLineCode {
149 public: 161 public:
150 OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result) 162 OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result)
151 : OutOfLineCode(gen), result_(result) {} 163 : OutOfLineCode(gen), result_(result) {}
152 164
153 void Generate() final { 165 void Generate() final {
154 __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(), 166 __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(),
155 kScratchReg); 167 kScratchReg);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 RecordWriteMode const mode_; 265 RecordWriteMode const mode_;
254 bool must_save_lr_; 266 bool must_save_lr_;
255 }; 267 };
256 268
257 Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { 269 Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
258 switch (condition) { 270 switch (condition) {
259 case kEqual: 271 case kEqual:
260 return eq; 272 return eq;
261 case kNotEqual: 273 case kNotEqual:
262 return ne; 274 return ne;
275 case kUnsignedLessThan:
276 // unsigned number never less than 0
277 if (op == kS390_LoadAndTestWord32 || op == kS390_LoadAndTestWord64)
278 return CC_NOP;
279 // fall through
263 case kSignedLessThan: 280 case kSignedLessThan:
264 case kUnsignedLessThan:
265 return lt; 281 return lt;
282 case kUnsignedGreaterThanOrEqual:
283 // unsigned number always greater than or equal 0
284 if (op == kS390_LoadAndTestWord32 || op == kS390_LoadAndTestWord64)
285 return CC_ALWAYS;
286 // fall through
266 case kSignedGreaterThanOrEqual: 287 case kSignedGreaterThanOrEqual:
267 case kUnsignedGreaterThanOrEqual:
268 return ge; 288 return ge;
289 case kUnsignedLessThanOrEqual:
290 // unsigned number never less than 0
291 if (op == kS390_LoadAndTestWord32 || op == kS390_LoadAndTestWord64)
292 return CC_EQ;
293 // fall through
269 case kSignedLessThanOrEqual: 294 case kSignedLessThanOrEqual:
270 case kUnsignedLessThanOrEqual:
271 return le; 295 return le;
296 case kUnsignedGreaterThan:
297 // unsigned number always greater than or equal 0
298 if (op == kS390_LoadAndTestWord32 || op == kS390_LoadAndTestWord64)
299 return ne;
300 // fall through
272 case kSignedGreaterThan: 301 case kSignedGreaterThan:
273 case kUnsignedGreaterThan:
274 return gt; 302 return gt;
275 case kOverflow: 303 case kOverflow:
276 // Overflow checked for AddP/SubP only. 304 // Overflow checked for AddP/SubP only.
277 switch (op) { 305 switch (op) {
278 case kS390_Add32: 306 case kS390_Add32:
279 case kS390_Add64: 307 case kS390_Add64:
280 case kS390_Sub32: 308 case kS390_Sub32:
281 case kS390_Sub64: 309 case kS390_Sub64:
282 return overflow; 310 return overflow;
283 default: 311 default:
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ 517 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \
490 i.InputRegister(1)); \ 518 i.InputRegister(1)); \
491 } else if (HasImmediateInput(instr, 1)) { \ 519 } else if (HasImmediateInput(instr, 1)) { \
492 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ 520 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \
493 i.InputImmediate(1)); \ 521 i.InputImmediate(1)); \
494 } else { \ 522 } else { \
495 UNIMPLEMENTED(); \ 523 UNIMPLEMENTED(); \
496 } \ 524 } \
497 } while (0) 525 } while (0)
498 526
499 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ 527 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \
500 do { \ 528 do { \
501 if (HasRegisterInput(instr, 1)) { \ 529 AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
502 if (i.CompareLogical()) { \ 530 if (mode != kMode_None) { \
503 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \ 531 size_t first_index = 1; \
504 } else { \ 532 MemOperand operand = i.MemoryOperand(&mode, &first_index); \
505 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \ 533 if (i.CompareLogical()) { \
506 } \ 534 __ cmpl_instr(i.InputRegister(0), operand); \
507 } else { \ 535 } else { \
508 if (i.CompareLogical()) { \ 536 __ cmp_instr(i.InputRegister(0), operand); \
509 __ cmpl_instr(i.InputRegister(0), i.InputImmediate(1)); \ 537 } \
510 } else { \ 538 } else if (HasRegisterInput(instr, 1)) { \
511 __ cmp_instr(i.InputRegister(0), i.InputImmediate(1)); \ 539 if (i.CompareLogical()) { \
512 } \ 540 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \
513 } \ 541 } else { \
542 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \
543 } \
544 } else if (HasImmediateInput(instr, 1)) { \
545 if (i.CompareLogical()) { \
546 __ cmpl_instr(i.InputRegister(0), i.InputImmediate(1)); \
547 } else { \
548 __ cmp_instr(i.InputRegister(0), i.InputImmediate(1)); \
549 } \
550 } else { \
551 DCHECK(HasStackSlotInput(instr, 1)); \
552 if (i.CompareLogical()) { \
553 __ cmpl_instr(i.InputRegister(0), i.InputStackSlot(1)); \
554 } else { \
555 __ cmp_instr(i.InputRegister(0), i.InputStackSlot(1)); \
556 } \
557 } \
514 } while (0) 558 } while (0)
515 559
516 #define ASSEMBLE_FLOAT_COMPARE(cmp_instr) \ 560 #define ASSEMBLE_COMPARE32(cmp_instr, cmpl_instr) \
517 do { \ 561 do { \
518 __ cmp_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ 562 AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
563 if (mode != kMode_None) { \
564 size_t first_index = 1; \
565 MemOperand operand = i.MemoryOperand(&mode, &first_index); \
566 if (i.CompareLogical()) { \
567 __ cmpl_instr(i.InputRegister(0), operand); \
568 } else { \
569 __ cmp_instr(i.InputRegister(0), operand); \
570 } \
571 } else if (HasRegisterInput(instr, 1)) { \
572 if (i.CompareLogical()) { \
573 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \
574 } else { \
575 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \
576 } \
577 } else if (HasImmediateInput(instr, 1)) { \
578 if (i.CompareLogical()) { \
579 __ cmpl_instr(i.InputRegister(0), i.InputImmediate(1)); \
580 } else { \
581 __ cmp_instr(i.InputRegister(0), i.InputImmediate(1)); \
582 } \
583 } else { \
584 DCHECK(HasStackSlotInput(instr, 1)); \
585 if (i.CompareLogical()) { \
586 __ cmpl_instr(i.InputRegister(0), i.InputStackSlot32(1)); \
587 } else { \
588 __ cmp_instr(i.InputRegister(0), i.InputStackSlot32(1)); \
589 } \
590 } \
591 } while (0)
592
593 #define ASSEMBLE_FLOAT_COMPARE(cmp_rr_instr, cmp_rm_instr, load_instr) \
594 do { \
595 AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
596 if (mode != kMode_None) { \
597 size_t first_index = 1; \
598 MemOperand operand = i.MemoryOperand(&mode, &first_index); \
599 __ cmp_rm_instr(i.InputDoubleRegister(0), operand); \
600 } else if (HasFPRegisterInput(instr, 1)) { \
601 __ cmp_rr_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
602 } else { \
603 DCHECK(HasFPStackSlotInput(instr, 1)); \
604 MemOperand operand = i.InputStackSlot(1); \
605 if (operand.offset() >= 0) { \
606 __ cmp_rm_instr(i.InputDoubleRegister(0), operand); \
607 } else { \
608 __ load_instr(kScratchDoubleReg, operand); \
609 __ cmp_rr_instr(i.InputDoubleRegister(0), kScratchDoubleReg); \
610 } \
611 } \
519 } while (0) 612 } while (0)
520 613
521 // Divide instruction dr will implicity use register pair 614 // Divide instruction dr will implicity use register pair
522 // r0 & r1 below. 615 // r0 & r1 below.
523 // R0:R1 = R1 / divisor - R0 remainder 616 // R0:R1 = R1 / divisor - R0 remainder
524 // Copy remainder to output reg 617 // Copy remainder to output reg
525 #define ASSEMBLE_MODULO(div_instr, shift_instr) \ 618 #define ASSEMBLE_MODULO(div_instr, shift_instr) \
526 do { \ 619 do { \
527 __ LoadRR(r0, i.InputRegister(0)); \ 620 __ LoadRR(r0, i.InputRegister(0)); \
528 __ shift_instr(r0, Operand(32)); \ 621 __ shift_instr(r0, Operand(32)); \
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 __ ldr(result_reg, right_reg); \ 833 __ ldr(result_reg, right_reg); \
741 } \ 834 } \
742 __ b(&done, Label::kNear); \ 835 __ b(&done, Label::kNear); \
743 \ 836 \
744 __ bind(&return_left); \ 837 __ bind(&return_left); \
745 if (!left_reg.is(result_reg)) { \ 838 if (!left_reg.is(result_reg)) { \
746 __ ldr(result_reg, left_reg); \ 839 __ ldr(result_reg, left_reg); \
747 } \ 840 } \
748 __ bind(&done); \ 841 __ bind(&done); \
749 } while (0) 842 } while (0)
843 //
750 // Only MRI mode for these instructions available 844 // Only MRI mode for these instructions available
751 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \ 845 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \
752 do { \ 846 do { \
753 DoubleRegister result = i.OutputDoubleRegister(); \ 847 DoubleRegister result = i.OutputDoubleRegister(); \
754 AddressingMode mode = kMode_None; \ 848 AddressingMode mode = kMode_None; \
755 MemOperand operand = i.MemoryOperand(&mode); \ 849 MemOperand operand = i.MemoryOperand(&mode); \
756 __ asm_instr(result, operand); \ 850 __ asm_instr(result, operand); \
757 } while (0) 851 } while (0)
758 852
759 #define ASSEMBLE_LOAD_INTEGER(asm_instr) \ 853 #define ASSEMBLE_LOAD_INTEGER(asm_instr) \
760 do { \ 854 do { \
761 Register result = i.OutputRegister(); \ 855 Register result = i.OutputRegister(); \
762 AddressingMode mode = kMode_None; \ 856 AddressingMode mode = kMode_None; \
763 MemOperand operand = i.MemoryOperand(&mode); \ 857 MemOperand operand = i.MemoryOperand(&mode); \
764 __ asm_instr(result, operand); \ 858 __ asm_instr(result, operand); \
765 } while (0) 859 } while (0)
766 860
861 #define ASSEMBLE_LOADANDTEST64(asm_instr_rr, asm_instr_rm) \
862 { \
863 AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
864 Register dst = HasRegisterOutput(instr) ? i.OutputRegister() : r0; \
865 if (mode != kMode_None) { \
866 size_t first_index = 0; \
867 MemOperand operand = i.MemoryOperand(&mode, &first_index); \
868 __ asm_instr_rm(dst, operand); \
869 } else if (HasRegisterInput(instr, 0)) { \
870 __ asm_instr_rr(dst, i.InputRegister(0)); \
871 } else { \
872 DCHECK(HasStackSlotInput(instr, 0)); \
873 __ asm_instr_rm(dst, i.InputStackSlot(0)); \
874 } \
875 }
876
877 #define ASSEMBLE_LOADANDTEST32(asm_instr_rr, asm_instr_rm) \
878 { \
879 AddressingMode mode = AddressingModeField::decode(instr->opcode()); \
880 Register dst = HasRegisterOutput(instr) ? i.OutputRegister() : r0; \
881 if (mode != kMode_None) { \
882 size_t first_index = 0; \
883 MemOperand operand = i.MemoryOperand(&mode, &first_index); \
884 __ asm_instr_rm(dst, operand); \
885 } else if (HasRegisterInput(instr, 0)) { \
886 __ asm_instr_rr(dst, i.InputRegister(0)); \
887 } else { \
888 DCHECK(HasStackSlotInput(instr, 0)); \
889 __ asm_instr_rm(dst, i.InputStackSlot32(0)); \
890 } \
891 }
892
767 #define ASSEMBLE_STORE_FLOAT32() \ 893 #define ASSEMBLE_STORE_FLOAT32() \
768 do { \ 894 do { \
769 size_t index = 0; \ 895 size_t index = 0; \
770 AddressingMode mode = kMode_None; \ 896 AddressingMode mode = kMode_None; \
771 MemOperand operand = i.MemoryOperand(&mode, &index); \ 897 MemOperand operand = i.MemoryOperand(&mode, &index); \
772 DoubleRegister value = i.InputDoubleRegister(index); \ 898 DoubleRegister value = i.InputDoubleRegister(index); \
773 __ StoreFloat32(value, operand); \ 899 __ StoreFloat32(value, operand); \
774 } while (0) 900 } while (0)
775 901
776 #define ASSEMBLE_STORE_DOUBLE() \ 902 #define ASSEMBLE_STORE_DOUBLE() \
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 #endif 1897 #endif
1772 case kS390_Popcnt32: 1898 case kS390_Popcnt32:
1773 __ Popcnt32(i.OutputRegister(), i.InputRegister(0)); 1899 __ Popcnt32(i.OutputRegister(), i.InputRegister(0));
1774 break; 1900 break;
1775 #if V8_TARGET_ARCH_S390X 1901 #if V8_TARGET_ARCH_S390X
1776 case kS390_Popcnt64: 1902 case kS390_Popcnt64:
1777 __ Popcnt64(i.OutputRegister(), i.InputRegister(0)); 1903 __ Popcnt64(i.OutputRegister(), i.InputRegister(0));
1778 break; 1904 break;
1779 #endif 1905 #endif
1780 case kS390_Cmp32: 1906 case kS390_Cmp32:
1781 ASSEMBLE_COMPARE(Cmp32, CmpLogical32); 1907 ASSEMBLE_COMPARE32(Cmp32, CmpLogical32);
1782 break; 1908 break;
1783 #if V8_TARGET_ARCH_S390X 1909 #if V8_TARGET_ARCH_S390X
1784 case kS390_Cmp64: 1910 case kS390_Cmp64:
1785 ASSEMBLE_COMPARE(CmpP, CmpLogicalP); 1911 ASSEMBLE_COMPARE(CmpP, CmpLogicalP);
1786 break; 1912 break;
1787 #endif 1913 #endif
1788 case kS390_CmpFloat: 1914 case kS390_CmpFloat:
1789 __ cebr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1915 ASSEMBLE_FLOAT_COMPARE(cebr, ceb, ley);
1916 // __ cebr(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1790 break; 1917 break;
1791 case kS390_CmpDouble: 1918 case kS390_CmpDouble:
1792 __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1919 ASSEMBLE_FLOAT_COMPARE(cdbr, cdb, ldy);
1920 // __ cdbr(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1793 break; 1921 break;
1794 case kS390_Tst32: 1922 case kS390_Tst32:
1795 if (HasRegisterInput(instr, 1)) { 1923 if (HasRegisterInput(instr, 1)) {
1796 __ lr(r0, i.InputRegister(0)); 1924 __ And(r0, i.InputRegister(0), i.InputRegister(1));
1797 __ nr(r0, i.InputRegister(1));
1798 } else { 1925 } else {
1799 Operand opnd = i.InputImmediate(1); 1926 Operand opnd = i.InputImmediate(1);
1800 if (is_uint16(opnd.immediate())) { 1927 if (is_uint16(opnd.immediate())) {
1801 __ tmll(i.InputRegister(0), opnd); 1928 __ tmll(i.InputRegister(0), opnd);
1802 } else { 1929 } else {
1803 __ lr(r0, i.InputRegister(0)); 1930 __ lr(r0, i.InputRegister(0));
1804 __ nilf(r0, opnd); 1931 __ nilf(r0, opnd);
1805 } 1932 }
1806 } 1933 }
1807 break; 1934 break;
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 __ lrvr(i.OutputRegister(), i.InputRegister(0)); 2229 __ lrvr(i.OutputRegister(), i.InputRegister(0));
2103 break; 2230 break;
2104 case kS390_LoadReverse64RR: 2231 case kS390_LoadReverse64RR:
2105 __ lrvgr(i.OutputRegister(), i.InputRegister(0)); 2232 __ lrvgr(i.OutputRegister(), i.InputRegister(0));
2106 break; 2233 break;
2107 #if V8_TARGET_ARCH_S390X 2234 #if V8_TARGET_ARCH_S390X
2108 case kS390_LoadWord64: 2235 case kS390_LoadWord64:
2109 ASSEMBLE_LOAD_INTEGER(lg); 2236 ASSEMBLE_LOAD_INTEGER(lg);
2110 break; 2237 break;
2111 #endif 2238 #endif
2239 case kS390_LoadAndTestWord32: {
2240 ASSEMBLE_LOADANDTEST32(ltr, lt_z);
2241 break;
2242 }
2243 case kS390_LoadAndTestWord64: {
2244 ASSEMBLE_LOADANDTEST64(ltgr, ltg);
2245 break;
2246 }
2112 case kS390_LoadFloat32: 2247 case kS390_LoadFloat32:
2113 ASSEMBLE_LOAD_FLOAT(LoadFloat32); 2248 ASSEMBLE_LOAD_FLOAT(LoadFloat32);
2114 break; 2249 break;
2115 case kS390_LoadDouble: 2250 case kS390_LoadDouble:
2116 ASSEMBLE_LOAD_FLOAT(LoadDouble); 2251 ASSEMBLE_LOAD_FLOAT(LoadDouble);
2117 break; 2252 break;
2118 case kS390_StoreWord8: 2253 case kS390_StoreWord8:
2119 ASSEMBLE_STORE_INTEGER(StoreByte); 2254 ASSEMBLE_STORE_INTEGER(StoreByte);
2120 break; 2255 break;
2121 case kS390_StoreWord16: 2256 case kS390_StoreWord16:
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
2757 padding_size -= 2; 2892 padding_size -= 2;
2758 } 2893 }
2759 } 2894 }
2760 } 2895 }
2761 2896
2762 #undef __ 2897 #undef __
2763 2898
2764 } // namespace compiler 2899 } // namespace compiler
2765 } // namespace internal 2900 } // namespace internal
2766 } // namespace v8 2901 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/s390/instruction-codes-s390.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698