Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |