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 |