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

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: Comments addressed. Created 5 years, 3 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
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/compiler/osr.h" 9 #include "src/compiler/osr.h"
10 #include "src/mips/macro-assembler-mips.h" 10 #include "src/mips/macro-assembler-mips.h"
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 return false; 968 return false;
969 } 969 }
970 970
971 971
972 // Assembles branches after an instruction. 972 // Assembles branches after an instruction.
973 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 973 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
974 MipsOperandConverter i(this, instr); 974 MipsOperandConverter i(this, instr);
975 Label* tlabel = branch->true_label; 975 Label* tlabel = branch->true_label;
976 Label* flabel = branch->false_label; 976 Label* flabel = branch->false_label;
977 Condition cc = kNoCondition; 977 Condition cc = kNoCondition;
978
979 // MIPS does not have condition code flags, so compare and branch are 978 // MIPS does not have condition code flags, so compare and branch are
980 // implemented differently than on the other arch's. The compare operations 979 // implemented differently than on the other arch's. The compare operations
981 // emit mips psuedo-instructions, which are handled here by branch 980 // emit mips psuedo-instructions, which are handled here by branch
982 // instructions that do the actual comparison. Essential that the input 981 // instructions that do the actual comparison. Essential that the input
983 // registers to compare pseudo-op are not modified before this branch op, as 982 // registers to compare pseudo-op are not modified before this branch op, as
984 // they are tested here. 983 // they are tested here.
985 984
986 if (instr->arch_opcode() == kMips64Tst) { 985 if (instr->arch_opcode() == kMips64Tst) {
987 cc = FlagsConditionToConditionTst(branch->condition); 986 cc = FlagsConditionToConditionTst(branch->condition);
988 __ And(at, i.InputRegister(0), i.InputOperand(1)); 987 __ And(at, i.InputRegister(0), i.InputOperand(1));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 FlagsCondition condition) { 1026 FlagsCondition condition) {
1028 MipsOperandConverter i(this, instr); 1027 MipsOperandConverter i(this, instr);
1029 Label done; 1028 Label done;
1030 1029
1031 // Materialize a full 32-bit 1 or 0 value. The result register is always the 1030 // Materialize a full 32-bit 1 or 0 value. The result register is always the
1032 // last output of the instruction. 1031 // last output of the instruction.
1033 Label false_value; 1032 Label false_value;
1034 DCHECK_NE(0u, instr->OutputCount()); 1033 DCHECK_NE(0u, instr->OutputCount());
1035 Register result = i.OutputRegister(instr->OutputCount() - 1); 1034 Register result = i.OutputRegister(instr->OutputCount() - 1);
1036 Condition cc = kNoCondition; 1035 Condition cc = kNoCondition;
1037
1038 // MIPS does not have condition code flags, so compare and branch are 1036 // MIPS does not have condition code flags, so compare and branch are
1039 // implemented differently than on the other arch's. The compare operations 1037 // implemented differently than on the other arch's. The compare operations
1040 // emit mips pseudo-instructions, which are checked and handled here. 1038 // emit mips pseudo-instructions, which are checked and handled here.
1041 1039
1042 // For materializations, we use delay slot to set the result true, and
1043 // in the false case, where we fall through the branch, we reset the result
1044 // false.
1045
1046 if (instr->arch_opcode() == kMips64Tst) { 1040 if (instr->arch_opcode() == kMips64Tst) {
1047 cc = FlagsConditionToConditionTst(condition); 1041 cc = FlagsConditionToConditionTst(condition);
1048 __ And(at, i.InputRegister(0), i.InputOperand(1)); 1042 __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
1049 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg)); 1043 __ xori(result, zero_reg, 1); // Create 1 for true.
1050 __ li(result, Operand(1)); // In delay slot. 1044 if (kArchVariant == kMips64r6) {
1045 if (cc == eq) {
1046 __ seleqz(result, result, kScratchReg);
1047 } else {
1048 __ selnez(result, result, kScratchReg);
1049 }
1050 } else {
1051 if (cc == eq) {
1052 __ Movn(result, zero_reg, kScratchReg);
1053 } else {
1054 __ Movz(result, zero_reg, kScratchReg);
1055 }
1056 }
1057 return;
1051 } else if (instr->arch_opcode() == kMips64Dadd || 1058 } else if (instr->arch_opcode() == kMips64Dadd ||
1052 instr->arch_opcode() == kMips64Dsub) { 1059 instr->arch_opcode() == kMips64Dsub) {
1053 cc = FlagsConditionToConditionOvf(condition); 1060 cc = FlagsConditionToConditionOvf(condition);
1054 __ dsra32(kScratchReg, i.OutputRegister(), 0); 1061 // Check for overflow creates 1 or 0 for result.
1055 __ sra(at, i.OutputRegister(), 31); 1062 __ dsrl32(kScratchReg, i.OutputRegister(), 31);
1056 __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg)); 1063 __ srl(at, i.OutputRegister(), 31);
1057 __ li(result, Operand(1)); // In delay slot. 1064 __ xor_(result, kScratchReg, at);
1065 if (cc == eq) // Toggle result for not overflow.
1066 __ xori(result, result, 1);
1067 return;
1058 } else if (instr->arch_opcode() == kMips64Cmp) { 1068 } else if (instr->arch_opcode() == kMips64Cmp) {
1059 Register left = i.InputRegister(0);
1060 Operand right = i.InputOperand(1);
1061 cc = FlagsConditionToConditionCmp(condition); 1069 cc = FlagsConditionToConditionCmp(condition);
1062 __ Branch(USE_DELAY_SLOT, &done, cc, left, right); 1070 switch (cc) {
1063 __ li(result, Operand(1)); // In delay slot. 1071 case eq:
1072 case ne: {
1073 Register left = i.InputRegister(0);
1074 Operand right = i.InputOperand(1);
1075 __ Dsubu(kScratchReg, left, right);
1076 __ xori(result, zero_reg, 1);
1077 if (kArchVariant == kMips64r6) {
1078 if (cc == eq) {
1079 __ seleqz(result, result, kScratchReg);
1080 } else {
1081 __ selnez(result, result, kScratchReg);
1082 }
1083 } else {
1084 if (cc == eq) {
1085 __ Movn(result, zero_reg, kScratchReg);
1086 } else {
1087 __ Movz(result, zero_reg, kScratchReg);
1088 }
1089 }
1090 } break;
1091 case lt:
1092 case ge: {
1093 Register left = i.InputRegister(0);
1094 Operand right = i.InputOperand(1);
1095 __ Slt(result, left, right);
1096 if (cc == ge) {
1097 __ xori(result, result, 1);
1098 }
1099 } break;
1100 case gt:
1101 case le: {
1102 Register left = i.InputRegister(1);
1103 Operand right = i.InputOperand(0);
1104 __ Slt(result, left, right);
1105 if (cc == le) {
1106 __ xori(result, result, 1);
1107 }
1108 } break;
1109 case lo:
1110 case hs: {
1111 Register left = i.InputRegister(0);
1112 Operand right = i.InputOperand(1);
1113 __ Sltu(result, left, right);
1114 if (cc == hs) {
1115 __ xori(result, result, 1);
1116 }
1117 } break;
1118 case hi:
1119 case ls: {
1120 Register left = i.InputRegister(1);
1121 Operand right = i.InputOperand(0);
1122 __ Sltu(result, left, right);
1123 if (cc == ls) {
1124 __ xori(result, result, 1);
1125 }
1126 } break;
1127 default:
1128 UNREACHABLE();
1129 }
1130 return;
1064 } else if (instr->arch_opcode() == kMips64CmpD || 1131 } else if (instr->arch_opcode() == kMips64CmpD ||
1065 instr->arch_opcode() == kMips64CmpS) { 1132 instr->arch_opcode() == kMips64CmpS) {
1066 FPURegister left = i.InputDoubleRegister(0); 1133 FPURegister left = i.InputDoubleRegister(0);
1067 FPURegister right = i.InputDoubleRegister(1); 1134 FPURegister right = i.InputDoubleRegister(1);
1068
1069 bool predicate; 1135 bool predicate;
1070 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition); 1136 FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
1071 if (kArchVariant != kMips64r6) { 1137 if (kArchVariant != kMips64r6) {
1072 __ li(result, Operand(1)); 1138 __ li(result, Operand(1));
1073 if (instr->arch_opcode() == kMips64CmpD) { 1139 if (instr->arch_opcode() == kMips64CmpD) {
1074 __ c(cc, D, left, right); 1140 __ c(cc, D, left, right);
1075 } else { 1141 } else {
1076 DCHECK(instr->arch_opcode() == kMips64CmpS); 1142 DCHECK(instr->arch_opcode() == kMips64CmpS);
1077 __ c(cc, S, left, right); 1143 __ c(cc, S, left, right);
1078 } 1144 }
(...skipping 14 matching lines...) Expand all
1093 if (!predicate) // Toggle result for not equal. 1159 if (!predicate) // Toggle result for not equal.
1094 __ xori(result, result, 1); 1160 __ xori(result, result, 1);
1095 } 1161 }
1096 return; 1162 return;
1097 } else { 1163 } else {
1098 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n", 1164 PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
1099 instr->arch_opcode()); 1165 instr->arch_opcode());
1100 TRACE_UNIMPL(); 1166 TRACE_UNIMPL();
1101 UNIMPLEMENTED(); 1167 UNIMPLEMENTED();
1102 } 1168 }
1103 // Fallthru case is the false materialization.
1104 __ bind(&false_value);
1105 __ li(result, Operand(static_cast<int64_t>(0)));
1106 __ bind(&done);
1107 } 1169 }
1108 1170
1109 1171
1110 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 1172 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
1111 MipsOperandConverter i(this, instr); 1173 MipsOperandConverter i(this, instr);
1112 Register input = i.InputRegister(0); 1174 Register input = i.InputRegister(0);
1113 for (size_t index = 2; index < instr->InputCount(); index += 2) { 1175 for (size_t index = 2; index < instr->InputCount(); index += 2) {
1114 __ li(at, Operand(i.InputInt32(index + 0))); 1176 __ li(at, Operand(i.InputInt32(index + 0)));
1115 __ beq(input, at, GetLabel(i.InputRpo(index + 1))); 1177 __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
1116 } 1178 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 padding_size -= v8::internal::Assembler::kInstrSize; 1515 padding_size -= v8::internal::Assembler::kInstrSize;
1454 } 1516 }
1455 } 1517 }
1456 } 1518 }
1457 1519
1458 #undef __ 1520 #undef __
1459 1521
1460 } // namespace compiler 1522 } // namespace compiler
1461 } // namespace internal 1523 } // namespace internal
1462 } // namespace v8 1524 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips/instruction-selector-mips.cc ('k') | src/compiler/mips64/instruction-selector-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698