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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6708025: ARM: Add optimization for constant RHS in DoMulI (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), 1004 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(),
1005 0, 1005 0,
1006 Safepoint::kNoDeoptimizationIndex); 1006 Safepoint::kNoDeoptimizationIndex);
1007 // Overwrite the stored value of r0 with the result of the stub. 1007 // Overwrite the stored value of r0 with the result of the stub.
1008 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); 1008 __ StoreToSafepointRegistersAndDoublesSlot(r0, r0);
1009 __ PopSafepointRegistersAndDoubles(); 1009 __ PopSafepointRegistersAndDoubles();
1010 } 1010 }
1011 1011
1012 1012
1013 void LCodeGen::DoMulI(LMulI* instr) { 1013 void LCodeGen::DoMulI(LMulI* instr) {
1014 LOperand* left_op = instr->InputAt(0);
1015 LOperand* right_op = instr->InputAt(1);
1016
1014 Register scratch = scratch0(); 1017 Register scratch = scratch0();
1015 Register left = ToRegister(instr->InputAt(0)); 1018 Register left = ToRegister(left_op);
1016 Register right = EmitLoadRegister(instr->InputAt(1), scratch);
1017 1019
1018 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && 1020 ASSERT(left_op->Equals(instr->result()));
1019 !instr->InputAt(1)->IsConstantOperand()) {
1020 __ orr(ToRegister(instr->TempAt(0)), left, right);
1021 }
1022 1021
1023 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1022 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1024 // scratch:left = left * right. 1023 bool bailout_on_minus_zero =
1025 __ smull(left, scratch, left, right); 1024 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1026 __ mov(ip, Operand(left, ASR, 31)); 1025
1027 __ cmp(ip, Operand(scratch)); 1026 if (right_op->IsConstantOperand()) {
1028 DeoptimizeIf(ne, instr->environment()); 1027 // Use optimized code for specific constants.
1028 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1029 Condition overflow_deopt_cond = kNoCondition;
1030
Karl Klose 2011/03/21 13:37:37 Consider removing the blank lines between the case
1031 switch (constant) {
1032 case -1:
1033 overflow_deopt_cond = can_overflow ? vs : kNoCondition;
1034 __ rsb(left,
1035 left,
1036 Operand(0),
1037 can_overflow ? SetCC : LeaveCC);
1038 break;
1039
1040 case 0:
1041 if (bailout_on_minus_zero) {
1042 // If left is strictly negative and the constant is null, the
1043 // result is -0. Deoptimize if required, otherwise return 0.
1044 __ cmp(left, Operand(0));
1045 DeoptimizeIf(mi, instr->environment());
1046 }
1047 __ mov(left, Operand(0));
1048 break;
1049
1050 case 1:
1051 // Do nothing.
1052 break;
1053
1054 default:
1055 // Multiplying by powers of two and powers of two plus or minus
1056 // one can be done faster with shifted operands.
1057 // For other constants we emit standard code.
1058 int32_t mask = constant >> 31;
1059 uint32_t constant_abs = (constant + mask) ^ mask;
1060
1061 if (IsPowerOf2(constant_abs)) {
1062 if (!can_overflow) {
1063 int32_t shift = WhichPowerOf2(constant_abs);
1064 __ mov(left, Operand(left, LSL, shift));
1065 if (constant < 0) __ rsb(left, left, Operand(0));
1066 } else {
1067 // scratch:left = left * constant.
1068 __ mov(ip, Operand(constant));
1069 __ smull(left, scratch, left, ip);
1070 __ cmp(scratch, Operand(left, ASR, 31));
1071 overflow_deopt_cond = ne;
1072 }
1073
1074 } else if (IsPowerOf2(constant_abs - 1)) {
1075 int32_t shift = WhichPowerOf2(constant_abs - 1);
1076 __ add(left,
1077 left,
1078 Operand(left, LSL, shift),
1079 can_overflow ? SetCC : LeaveCC);
1080 overflow_deopt_cond = can_overflow ? vs : kNoCondition;
1081 if (constant < 0) __ rsb(left, left, Operand(0));
1082
1083 } else if (IsPowerOf2(constant_abs + 1)) {
1084 int32_t shift = WhichPowerOf2(constant_abs + 1);
1085 __ rsb(left,
1086 left,
1087 Operand(left, LSL, shift),
1088 can_overflow ? SetCC : LeaveCC);
1089 overflow_deopt_cond = can_overflow ? vs : kNoCondition;
1090 if (constant < 0) __ rsb(left, left, Operand(0));
1091
1092 } else {
1093 if (!can_overflow) {
1094 __ mov(ip, Operand(constant));
1095 __ mul(left, left, ip);
1096 } else {
1097 // scratch:left = left * constant.
1098 __ mov(ip, Operand(constant));
1099 __ smull(left, scratch, left, ip);
1100 __ cmp(scratch, Operand(left, ASR, 31));
1101 overflow_deopt_cond = ne;
1102 }
1103 }
1104 break;
1105 }
1106
1107
1108 if (can_overflow && (constant != 0) && (constant != 1)) {
1109 ASSERT(overflow_deopt_cond != kNoCondition);
1110 DeoptimizeIf(overflow_deopt_cond, instr->environment());
1111 }
1112
1113 if (bailout_on_minus_zero && (constant < 0)) {
1114 // The case of a null constant was handled separately.
1115 // If constant is negative and left is null, the result should be -0.
1116 __ cmp(left, Operand(0));
1117 DeoptimizeIf(eq, instr->environment());
1118 }
1119
1029 } else { 1120 } else {
1030 __ mul(left, left, right); 1121 Register right = EmitLoadRegister(right_op, scratch);
1031 } 1122 if (bailout_on_minus_zero) {
1123 __ orr(ToRegister(instr->TempAt(0)), left, right);
1124 }
1032 1125
1033 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1126 if (can_overflow) {
1034 // Bail out if the result is supposed to be negative zero. 1127 // scratch:left = left * right.
1035 Label done; 1128 __ smull(left, scratch, left, right);
1036 __ tst(left, Operand(left)); 1129 __ cmp(scratch, Operand(left, ASR, 31));
1037 __ b(ne, &done); 1130 DeoptimizeIf(ne, instr->environment());
1038 if (instr->InputAt(1)->IsConstantOperand()) {
1039 if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
1040 DeoptimizeIf(al, instr->environment());
1041 }
1042 } else { 1131 } else {
1043 // Test the non-zero operand for negative sign. 1132 __ mul(left, left, right);
1133 }
1134
1135 if (bailout_on_minus_zero) {
1136 // Bail out if the result is supposed to be negative zero.
1137 Label done;
1138 __ cmp(left, Operand(0));
1139 __ b(ne, &done);
1044 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); 1140 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1045 DeoptimizeIf(mi, instr->environment()); 1141 DeoptimizeIf(mi, instr->environment());
1142 __ bind(&done);
1046 } 1143 }
1047 __ bind(&done);
1048 } 1144 }
1049 } 1145 }
1050 1146
1051 1147
1052 void LCodeGen::DoBitI(LBitI* instr) { 1148 void LCodeGen::DoBitI(LBitI* instr) {
1053 LOperand* left = instr->InputAt(0); 1149 LOperand* left = instr->InputAt(0);
1054 LOperand* right = instr->InputAt(1); 1150 LOperand* right = instr->InputAt(1);
1055 ASSERT(left->Equals(instr->result())); 1151 ASSERT(left->Equals(instr->result()));
1056 ASSERT(left->IsRegister()); 1152 ASSERT(left->IsRegister());
1057 Register result = ToRegister(left); 1153 Register result = ToRegister(left);
(...skipping 2899 matching lines...) Expand 10 before | Expand all | Expand 10 after
3957 ASSERT(!environment->HasBeenRegistered()); 4053 ASSERT(!environment->HasBeenRegistered());
3958 RegisterEnvironmentForDeoptimization(environment); 4054 RegisterEnvironmentForDeoptimization(environment);
3959 ASSERT(osr_pc_offset_ == -1); 4055 ASSERT(osr_pc_offset_ == -1);
3960 osr_pc_offset_ = masm()->pc_offset(); 4056 osr_pc_offset_ = masm()->pc_offset();
3961 } 4057 }
3962 4058
3963 4059
3964 #undef __ 4060 #undef __
3965 4061
3966 } } // namespace v8::internal 4062 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698