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

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

Issue 1294933003: MIPS:[turbofan] Improve boolean materialization compares. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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/mips64/instruction-selector-mips64.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 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/mips/macro-assembler-mips.h" 9 #include "src/mips/macro-assembler-mips.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 }; 193 };
194 194
195 195
196 class OutOfLineCeil final : public OutOfLineRound { 196 class OutOfLineCeil final : public OutOfLineRound {
197 public: 197 public:
198 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result) 198 OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
199 : OutOfLineRound(gen, result) {} 199 : OutOfLineRound(gen, result) {}
200 }; 200 };
201 201
202 202
203 Condition FlagsConditionToConditionCmp(FlagsCondition condition) { 203 Condition FlagsConditionToConditionCmp(bool& predicate,
204 FlagsCondition condition) {
204 switch (condition) { 205 switch (condition) {
205 case kEqual: 206 case kEqual:
207 predicate = true;
206 return eq; 208 return eq;
207 case kNotEqual: 209 case kNotEqual:
210 predicate = false;
208 return ne; 211 return ne;
209 case kSignedLessThan: 212 case kSignedLessThan:
213 predicate = true;
210 return lt; 214 return lt;
211 case kSignedGreaterThanOrEqual: 215 case kSignedGreaterThanOrEqual:
216 predicate = false;
212 return ge; 217 return ge;
213 case kSignedLessThanOrEqual: 218 case kSignedLessThanOrEqual:
219 predicate = false;
214 return le; 220 return le;
215 case kSignedGreaterThan: 221 case kSignedGreaterThan:
222 predicate = true;
216 return gt; 223 return gt;
217 case kUnsignedLessThan: 224 case kUnsignedLessThan:
225 predicate = true;
218 return lo; 226 return lo;
219 case kUnsignedGreaterThanOrEqual: 227 case kUnsignedGreaterThanOrEqual:
228 predicate = false;
220 return hs; 229 return hs;
221 case kUnsignedLessThanOrEqual: 230 case kUnsignedLessThanOrEqual:
231 predicate = false;
222 return ls; 232 return ls;
223 case kUnsignedGreaterThan: 233 case kUnsignedGreaterThan:
234 predicate = true;
224 return hi; 235 return hi;
225 case kUnorderedEqual: 236 case kUnorderedEqual:
226 case kUnorderedNotEqual: 237 case kUnorderedNotEqual:
227 break; 238 break;
228 default: 239 default:
229 break; 240 break;
230 } 241 }
231 UNREACHABLE(); 242 UNREACHABLE();
232 return kNoCondition; 243 return kNoCondition;
233 } 244 }
234 245
235 246
236 Condition FlagsConditionToConditionTst(FlagsCondition condition) { 247 Condition FlagsConditionToConditionTst(bool& predicate,
248 FlagsCondition condition) {
237 switch (condition) { 249 switch (condition) {
238 case kNotEqual: 250 case kNotEqual:
251 predicate = false;
239 return ne; 252 return ne;
240 case kEqual: 253 case kEqual:
254 predicate = true;
241 return eq; 255 return eq;
242 default: 256 default:
243 break; 257 break;
244 } 258 }
245 UNREACHABLE(); 259 UNREACHABLE();
246 return kNoCondition; 260 return kNoCondition;
247 } 261 }
248 262
249 263
250 Condition FlagsConditionToConditionOvf(FlagsCondition condition) { 264 Condition FlagsConditionToConditionOvf(bool& predicate,
265 FlagsCondition condition) {
251 switch (condition) { 266 switch (condition) {
252 case kOverflow: 267 case kOverflow:
268 predicate = true;
253 return ne; 269 return ne;
254 case kNotOverflow: 270 case kNotOverflow:
271 predicate = false;
255 return eq; 272 return eq;
256 default: 273 default:
257 break; 274 break;
258 } 275 }
259 UNREACHABLE(); 276 UNREACHABLE();
260 return kNoCondition; 277 return kNoCondition;
261 } 278 }
262 279
263 280
264 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate, 281 FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 return false; 975 return false;
959 } 976 }
960 977
961 978
962 // Assembles branches after an instruction. 979 // Assembles branches after an instruction.
963 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 980 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
964 MipsOperandConverter i(this, instr); 981 MipsOperandConverter i(this, instr);
965 Label* tlabel = branch->true_label; 982 Label* tlabel = branch->true_label;
966 Label* flabel = branch->false_label; 983 Label* flabel = branch->false_label;
967 Condition cc = kNoCondition; 984 Condition cc = kNoCondition;
968 985 bool predicate;
969 // MIPS does not have condition code flags, so compare and branch are 986 // MIPS does not have condition code flags, so compare and branch are
970 // implemented differently than on the other arch's. The compare operations 987 // implemented differently than on the other arch's. The compare operations
971 // emit mips psuedo-instructions, which are handled here by branch 988 // emit mips psuedo-instructions, which are handled here by branch
972 // instructions that do the actual comparison. Essential that the input 989 // instructions that do the actual comparison. Essential that the input
973 // registers to compare pseudo-op are not modified before this branch op, as 990 // registers to compare pseudo-op are not modified before this branch op, as
974 // they are tested here. 991 // they are tested here.
975 992
976 if (instr->arch_opcode() == kMips64Tst) { 993 if (instr->arch_opcode() == kMips64Tst) {
977 cc = FlagsConditionToConditionTst(branch->condition); 994 cc = FlagsConditionToConditionTst(predicate, branch->condition);
978 __ And(at, i.InputRegister(0), i.InputOperand(1)); 995 __ And(at, i.InputRegister(0), i.InputOperand(1));
979 __ Branch(tlabel, cc, at, Operand(zero_reg)); 996 __ Branch(tlabel, cc, at, Operand(zero_reg));
980 } else if (instr->arch_opcode() == kMips64Dadd || 997 } else if (instr->arch_opcode() == kMips64Dadd ||
981 instr->arch_opcode() == kMips64Dsub) { 998 instr->arch_opcode() == kMips64Dsub) {
982 cc = FlagsConditionToConditionOvf(branch->condition); 999 cc = FlagsConditionToConditionOvf(predicate, branch->condition);
983 __ dsra32(kScratchReg, i.OutputRegister(), 0); 1000 __ dsra32(kScratchReg, i.OutputRegister(), 0);
984 __ sra(at, i.OutputRegister(), 31); 1001 __ sra(at, i.OutputRegister(), 31);
985 __ Branch(tlabel, cc, at, Operand(kScratchReg)); 1002 __ Branch(tlabel, cc, at, Operand(kScratchReg));
986 } else if (instr->arch_opcode() == kMips64Cmp) { 1003 } else if (instr->arch_opcode() == kMips64Cmp) {
987 cc = FlagsConditionToConditionCmp(branch->condition); 1004 cc = FlagsConditionToConditionCmp(predicate, branch->condition);
988 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 1005 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
989 } else if (instr->arch_opcode() == kMips64CmpS) { 1006 } else if (instr->arch_opcode() == kMips64CmpS) {
990 if (!convertCondition(branch->condition, cc)) { 1007 if (!convertCondition(branch->condition, cc)) {
991 UNSUPPORTED_COND(kMips64CmpS, branch->condition); 1008 UNSUPPORTED_COND(kMips64CmpS, branch->condition);
992 } 1009 }
993 __ BranchF32(tlabel, NULL, cc, i.InputSingleRegister(0), 1010 __ BranchF32(tlabel, NULL, cc, i.InputSingleRegister(0),
994 i.InputSingleRegister(1)); 1011 i.InputSingleRegister(1));
995 } else if (instr->arch_opcode() == kMips64CmpD) { 1012 } else if (instr->arch_opcode() == kMips64CmpD) {
996 if (!convertCondition(branch->condition, cc)) { 1013 if (!convertCondition(branch->condition, cc)) {
997 UNSUPPORTED_COND(kMips64CmpD, branch->condition); 1014 UNSUPPORTED_COND(kMips64CmpD, branch->condition);
(...skipping 19 matching lines...) Expand all
1017 FlagsCondition condition) { 1034 FlagsCondition condition) {
1018 MipsOperandConverter i(this, instr); 1035 MipsOperandConverter i(this, instr);
1019 Label done; 1036 Label done;
1020 1037
1021 // Materialize a full 32-bit 1 or 0 value. The result register is always the 1038 // Materialize a full 32-bit 1 or 0 value. The result register is always the
1022 // last output of the instruction. 1039 // last output of the instruction.
1023 Label false_value; 1040 Label false_value;
1024 DCHECK_NE(0u, instr->OutputCount()); 1041 DCHECK_NE(0u, instr->OutputCount());
1025 Register result = i.OutputRegister(instr->OutputCount() - 1); 1042 Register result = i.OutputRegister(instr->OutputCount() - 1);
1026 Condition cc = kNoCondition; 1043 Condition cc = kNoCondition;
1027 1044 bool predicate;
1028 // MIPS does not have condition code flags, so compare and branch are 1045 // MIPS does not have condition code flags, so compare and branch are
1029 // implemented differently than on the other arch's. The compare operations 1046 // implemented differently than on the other arch's. The compare operations
1030 // emit mips pseudo-instructions, which are checked and handled here. 1047 // emit mips pseudo-instructions, which are checked and handled here.
1031 1048
1032 // For materializations, we use delay slot to set the result true, and 1049 // For materializations, we use delay slot to set the result true, and
1033 // in the false case, where we fall through the branch, we reset the result 1050 // in the false case, where we fall through the branch, we reset the result
1034 // false. 1051 // false.
paul.l... 2015/08/15 00:22:31 With your change, the above comment should be dele
1035 1052
1036 if (instr->arch_opcode() == kMips64Tst) { 1053 if (instr->arch_opcode() == kMips64Tst) {
1037 cc = FlagsConditionToConditionTst(condition); 1054 cc = FlagsConditionToConditionTst(predicate, condition);
1038 __ And(at, i.InputRegister(0), i.InputOperand(1)); 1055 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
1039 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); 1056 __ xori(kScratchReg2, zero_reg, 1);
1040 __ li(result, Operand(1)); // In delay slot. 1057 if (predicate) {
1058 __ Movn(result, zero_reg, kScratchReg);
1059 __ Movz(result, kScratchReg2, kScratchReg);
paul.l... 2015/08/15 00:22:31 I'm not sure this is a good idea anymore, due to t
1060 } else {
1061 __ Movz(result, zero_reg, kScratchReg);
1062 __ Movn(result, kScratchReg2, kScratchReg);
1063 }
1064 return;
1041 } else if (instr->arch_opcode() == kMips64Dadd || 1065 } else if (instr->arch_opcode() == kMips64Dadd ||
1042 instr->arch_opcode() == kMips64Dsub) { 1066 instr->arch_opcode() == kMips64Dsub) {
1043 cc = FlagsConditionToConditionOvf(condition); 1067 FlagsConditionToConditionOvf(predicate, condition);
1044 __ dsra32(kScratchReg, i.OutputRegister(), 0); 1068 __ dsrl32(kScratchReg, i.OutputRegister(), 31);
1045 __ sra(at, i.OutputRegister(), 31); 1069 __ srl(at, i.OutputRegister(), 31);
1046 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg)); 1070 __ xor_(result, kScratchReg, at);
1047 __ li(result, Operand(1)); // In delay slot. 1071 if (!predicate) __ xori(result, result, 1);
paul.l... 2015/08/15 00:22:31 OK, it must be too late on Friday night, but I am
1072 return;
1048 } else if (instr->arch_opcode() == kMips64Cmp) { 1073 } else if (instr->arch_opcode() == kMips64Cmp) {
1049 Register left = i.InputRegister(0); 1074 cc = FlagsConditionToConditionCmp(predicate, condition);
1050 Operand right = i.InputOperand(1); 1075 switch (cc) {
1051 cc = FlagsConditionToConditionCmp(condition); 1076 case eq:
1052 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); 1077 case ne: {
1053 __ li(result, Operand(1)); // In delay slot. 1078 Register left = i.InputRegister(0);
1079 Operand right = i.InputOperand(1);
1080 __ Dsubu(kScratchReg, left, right);
1081 __ xori(kScratchReg2, zero_reg, 1);
1082 if (predicate) {
1083 __ Movn(result, zero_reg, kScratchReg);
1084 __ Movz(result, kScratchReg2, kScratchReg);
1085 } else {
1086 __ Movz(result, zero_reg, kScratchReg);
1087 __ Movn(result, kScratchReg2, kScratchReg);
1088 }
1089 } break;
1090 case lt:
1091 case ge: {
1092 Register left = i.InputRegister(0);
1093 Operand right = i.InputOperand(1);
1094 __ Slt(result, left, right);
1095 if (!predicate) {
1096 __ xori(result, result, 1);
1097 }
1098 } break;
1099 case gt:
1100 case le: {
1101 Register left = i.InputRegister(1);
1102 Operand right = i.InputOperand(0);
1103 __ Slt(result, left, right);
1104 if (!predicate) {
1105 __ xori(result, result, 1);
1106 }
1107 } break;
1108 case lo:
1109 case hs: {
1110 Register left = i.InputRegister(0);
1111 Operand right = i.InputOperand(1);
1112 __ Sltu(result, left, right);
1113 if (!predicate) {
1114 __ xori(result, result, 1);
1115 }
1116 } break;
1117 case hi:
1118 case ls: {
1119 Register left = i.InputRegister(1);
1120 Operand right = i.InputOperand(0);
1121 __ Sltu(result, left, right);
1122 if (!predicate) {
1123 __ xori(result, result, 1);
1124 }
1125 } break;
1126 default:
1127 UNREACHABLE();
1128 }
1129 return;
1054 } else if (instr->arch_opcode() == kMips64CmpD || 1130 } else if (instr->arch_opcode() == kMips64CmpD ||
1055 instr->arch_opcode() == kMips64CmpS) { 1131 instr->arch_opcode() == kMips64CmpS) {
1056 FPURegister left = i.InputDoubleRegister(0); 1132 FPURegister left = i.InputDoubleRegister(0);
1057 FPURegister right = i.InputDoubleRegister(1); 1133 FPURegister right = i.InputDoubleRegister(1);
1058 1134
1059 bool predicate;
1060 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition); 1135 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
1061 if (kArchVariant != kMips64r6) { 1136 if (kArchVariant != kMips64r6) {
1062 __ li(result, Operand(1)); 1137 __ li(result, Operand(1));
1063 if (instr->arch_opcode() == kMips64CmpD) { 1138 if (instr->arch_opcode() == kMips64CmpD) {
1064 __ c(cc, D, left, right); 1139 __ c(cc, D, left, right);
1065 } else { 1140 } else {
1066 DCHECK(instr->arch_opcode() == kMips64CmpS); 1141 DCHECK(instr->arch_opcode() == kMips64CmpS);
1067 __ c(cc, S, left, right); 1142 __ c(cc, S, left, right);
1068 } 1143 }
1069 if (predicate) { 1144 if (predicate) {
(...skipping 13 matching lines...) Expand all
1083 if (!predicate) // Toggle result for not equal. 1158 if (!predicate) // Toggle result for not equal.
1084 __ xori(result, result, 1); 1159 __ xori(result, result, 1);
1085 } 1160 }
1086 return; 1161 return;
1087 } else { 1162 } else {
1088 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", 1163 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
1089 instr->arch_opcode()); 1164 instr->arch_opcode());
1090 TRACE_UNIMPL(); 1165 TRACE_UNIMPL();
1091 UNIMPLEMENTED(); 1166 UNIMPLEMENTED();
1092 } 1167 }
1093 // Fallthru case is the false materialization.
1094 __ bind(&false_value);
1095 __ li(result, Operand(static_cast<int64_t>(0)));
1096 __ bind(&done);
1097 } 1168 }
1098 1169
1099 1170
1100 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 1171 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
1101 MipsOperandConverter i(this, instr); 1172 MipsOperandConverter i(this, instr);
1102 Register input = i.InputRegister(0); 1173 Register input = i.InputRegister(0);
1103 for (size_t index = 2; index < instr->InputCount(); index += 2) { 1174 for (size_t index = 2; index < instr->InputCount(); index += 2) {
1104 __ li(at, Operand(i.InputInt32(index + 0))); 1175 __ li(at, Operand(i.InputInt32(index + 0)));
1105 __ beq(input, at, GetLabel(i.InputRpo(index + 1))); 1176 __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
1106 } 1177 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 } 1514 }
1444 } 1515 }
1445 } 1516 }
1446 } 1517 }
1447 1518
1448 #undef __ 1519 #undef __
1449 1520
1450 } // namespace compiler 1521 } // namespace compiler
1451 } // namespace internal 1522 } // namespace internal
1452 } // namespace v8 1523 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/mips64/instruction-selector-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698