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

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

Issue 2054007: ARM: Optimize shifts by constant integers, especially... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 1139
1140 case Token::SHL: 1140 case Token::SHL:
1141 case Token::SHR: 1141 case Token::SHR:
1142 case Token::SAR: { 1142 case Token::SAR: {
1143 ASSERT(!reversed); 1143 ASSERT(!reversed);
1144 Register scratch = VirtualFrame::scratch0(); 1144 Register scratch = VirtualFrame::scratch0();
1145 Register scratch2 = VirtualFrame::scratch1(); 1145 Register scratch2 = VirtualFrame::scratch1();
1146 int shift_value = int_value & 0x1f; // least significant 5 bits 1146 int shift_value = int_value & 0x1f; // least significant 5 bits
1147 DeferredCode* deferred = 1147 DeferredCode* deferred =
1148 new DeferredInlineSmiOperation(op, shift_value, false, mode, tos); 1148 new DeferredInlineSmiOperation(op, shift_value, false, mode, tos);
1149 __ tst(tos, Operand(kSmiTagMask)); 1149 uint32_t problematic_mask = kSmiTagMask;
1150 deferred->Branch(ne); 1150 // For unsigned shift by zero all negative smis are problematic.
1151 __ mov(scratch, Operand(tos, ASR, kSmiTagSize)); // remove tags 1151 if (shift_value == 0 && op == Token::SHR) problematic_mask |= 0x80000000;
1152 __ tst(tos, Operand(problematic_mask));
1153 deferred->Branch(ne); // Go slow for problematic input.
1152 switch (op) { 1154 switch (op) {
1153 case Token::SHL: { 1155 case Token::SHL: {
1154 if (shift_value != 0) { 1156 if (shift_value != 0) {
1155 __ mov(scratch, Operand(scratch, LSL, shift_value)); 1157 int adjusted_shift = shift_value - kSmiTagSize;
1158 ASSERT(adjusted_shift >= 0);
1159 if (adjusted_shift != 0) {
1160 __ mov(scratch, Operand(tos, LSL, adjusted_shift));
1161 // Check that the *signed* result fits in a smi.
1162 __ add(scratch2, scratch, Operand(0x40000000), SetCC);
1163 deferred->Branch(mi);
1164 __ mov(tos, Operand(scratch, LSL, kSmiTagSize));
1165 } else {
1166 // Check that the *signed* result fits in a smi.
1167 __ add(scratch2, tos, Operand(0x40000000), SetCC);
1168 deferred->Branch(mi);
1169 __ mov(tos, Operand(tos, LSL, kSmiTagSize));
1170 }
1156 } 1171 }
1157 // check that the *signed* result fits in a smi
1158 __ add(scratch2, scratch, Operand(0x40000000), SetCC);
1159 deferred->Branch(mi);
1160 break; 1172 break;
1161 } 1173 }
1162 case Token::SHR: { 1174 case Token::SHR: {
1163 // LSR by immediate 0 means shifting 32 bits.
1164 if (shift_value != 0) { 1175 if (shift_value != 0) {
1176 __ mov(scratch, Operand(tos, ASR, kSmiTagSize)); // Remove tag.
1177 // LSR by immediate 0 means shifting 32 bits.
1165 __ mov(scratch, Operand(scratch, LSR, shift_value)); 1178 __ mov(scratch, Operand(scratch, LSR, shift_value));
1179 if (shift_value < 2) {
Søren Thygesen Gjesse 2010/05/11 07:57:11 With the test above this is shift_value == 1.
1180 // check that the *unsigned* result fits in a smi
1181 // neither of the two high-order bits can be set:
1182 // - 0x80000000: high bit would be lost when smi tagging
1183 // - 0x40000000: this number would convert to negative when
1184 // smi tagging these two cases can only happen with shifts
1185 // by 0 or 1 when handed a valid smi
1186 __ tst(scratch, Operand(0xc0000000));
1187 deferred->Branch(ne);
1188 }
1189 __ mov(tos, Operand(scratch, LSL, kSmiTagSize));
1166 } 1190 }
1167 // check that the *unsigned* result fits in a smi
1168 // neither of the two high-order bits can be set:
1169 // - 0x80000000: high bit would be lost when smi tagging
1170 // - 0x40000000: this number would convert to negative when
1171 // smi tagging these two cases can only happen with shifts
1172 // by 0 or 1 when handed a valid smi
1173 __ tst(scratch, Operand(0xc0000000));
1174 deferred->Branch(ne);
1175 break; 1191 break;
1176 } 1192 }
1177 case Token::SAR: { 1193 case Token::SAR: {
1194 // In the ARM instructions set, ASR by immediate 0 means shifting 32
1195 // bits.
1178 if (shift_value != 0) { 1196 if (shift_value != 0) {
1179 // ASR by immediate 0 means shifting 32 bits. 1197 // Do the shift and the tag removal in one operation. If the shift
1180 __ mov(scratch, Operand(scratch, ASR, shift_value)); 1198 // is 31 bits (the highest possible value) then we emit the
1199 // instruction as a shift by 0 which means shift arithmetically by
1200 // 32.
1201 __ mov(tos, Operand(tos, ASR, (kSmiTagSize + shift_value) & 0x1f));
1202 // Put tag back.
1203 __ mov(tos, Operand(tos, LSL, kSmiTagSize));
1181 } 1204 }
1182 break; 1205 break;
1183 } 1206 }
1184 default: UNREACHABLE(); 1207 default: UNREACHABLE();
1185 } 1208 }
1186 __ mov(tos, Operand(scratch, LSL, kSmiTagSize));
1187 deferred->BindExit(); 1209 deferred->BindExit();
1188 frame_->EmitPush(tos); 1210 frame_->EmitPush(tos);
1189 break; 1211 break;
1190 } 1212 }
1191 1213
1192 case Token::MOD: { 1214 case Token::MOD: {
1193 ASSERT(!reversed); 1215 ASSERT(!reversed);
1194 ASSERT(int_value >= 2); 1216 ASSERT(int_value >= 2);
1195 ASSERT(IsPowerOf2(int_value)); 1217 ASSERT(IsPowerOf2(int_value));
1196 DeferredCode* deferred = 1218 DeferredCode* deferred =
(...skipping 8804 matching lines...) Expand 10 before | Expand all | Expand 10 after
10001 10023
10002 // Just jump to runtime to add the two strings. 10024 // Just jump to runtime to add the two strings.
10003 __ bind(&string_add_runtime); 10025 __ bind(&string_add_runtime);
10004 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 10026 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
10005 } 10027 }
10006 10028
10007 10029
10008 #undef __ 10030 #undef __
10009 10031
10010 } } // namespace v8::internal 10032 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698