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

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

Issue 1869001: Add inlined code for (constant SHL smi), ported from ia32 to x64. (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 | src/x64/codegen-x64.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 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 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 deferred = new DeferredInlineSmiAdd(operand->reg(), 2034 deferred = new DeferredInlineSmiAdd(operand->reg(),
2035 operand->type_info(), 2035 operand->type_info(),
2036 smi_value, 2036 smi_value,
2037 overwrite_mode); 2037 overwrite_mode);
2038 } 2038 }
2039 __ add(Operand(operand->reg()), Immediate(value)); 2039 __ add(Operand(operand->reg()), Immediate(value));
2040 deferred->Branch(overflow); 2040 deferred->Branch(overflow);
2041 if (!operand->type_info().IsSmi()) { 2041 if (!operand->type_info().IsSmi()) {
2042 __ test(operand->reg(), Immediate(kSmiTagMask)); 2042 __ test(operand->reg(), Immediate(kSmiTagMask));
2043 deferred->Branch(not_zero); 2043 deferred->Branch(not_zero);
2044 } else { 2044 } else if (FLAG_debug_code) {
2045 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2045 __ AbortIfNotSmi(operand->reg());
2046 } 2046 }
2047 deferred->BindExit(); 2047 deferred->BindExit();
2048 answer = *operand; 2048 answer = *operand;
2049 break; 2049 break;
2050 } 2050 }
2051 2051
2052 case Token::SUB: { 2052 case Token::SUB: {
2053 DeferredCode* deferred = NULL; 2053 DeferredCode* deferred = NULL;
2054 if (reversed) { 2054 if (reversed) {
2055 // The reversed case is only hit when the right operand is not a 2055 // The reversed case is only hit when the right operand is not a
(...skipping 17 matching lines...) Expand all
2073 deferred = new DeferredInlineSmiSub(operand->reg(), 2073 deferred = new DeferredInlineSmiSub(operand->reg(),
2074 operand->type_info(), 2074 operand->type_info(),
2075 smi_value, 2075 smi_value,
2076 overwrite_mode); 2076 overwrite_mode);
2077 __ sub(Operand(operand->reg()), Immediate(value)); 2077 __ sub(Operand(operand->reg()), Immediate(value));
2078 } 2078 }
2079 deferred->Branch(overflow); 2079 deferred->Branch(overflow);
2080 if (!operand->type_info().IsSmi()) { 2080 if (!operand->type_info().IsSmi()) {
2081 __ test(answer.reg(), Immediate(kSmiTagMask)); 2081 __ test(answer.reg(), Immediate(kSmiTagMask));
2082 deferred->Branch(not_zero); 2082 deferred->Branch(not_zero);
2083 } else { 2083 } else if (FLAG_debug_code) {
2084 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2084 __ AbortIfNotSmi(operand->reg());
2085 } 2085 }
2086 deferred->BindExit(); 2086 deferred->BindExit();
2087 operand->Unuse(); 2087 operand->Unuse();
2088 break; 2088 break;
2089 } 2089 }
2090 2090
2091 case Token::SAR: 2091 case Token::SAR:
2092 if (reversed) { 2092 if (reversed) {
2093 Result constant_operand(value); 2093 Result constant_operand(value);
2094 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand, 2094 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
(...skipping 13 matching lines...) Expand all
2108 smi_value, 2108 smi_value,
2109 overwrite_mode); 2109 overwrite_mode);
2110 __ test(operand->reg(), Immediate(kSmiTagMask)); 2110 __ test(operand->reg(), Immediate(kSmiTagMask));
2111 deferred->Branch(not_zero); 2111 deferred->Branch(not_zero);
2112 if (shift_value > 0) { 2112 if (shift_value > 0) {
2113 __ sar(operand->reg(), shift_value); 2113 __ sar(operand->reg(), shift_value);
2114 __ and_(operand->reg(), ~kSmiTagMask); 2114 __ and_(operand->reg(), ~kSmiTagMask);
2115 } 2115 }
2116 deferred->BindExit(); 2116 deferred->BindExit();
2117 } else { 2117 } else {
2118 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2118 if (FLAG_debug_code) {
2119 __ AbortIfNotSmi(operand->reg());
2120 }
2119 if (shift_value > 0) { 2121 if (shift_value > 0) {
2120 __ sar(operand->reg(), shift_value); 2122 __ sar(operand->reg(), shift_value);
2121 __ and_(operand->reg(), ~kSmiTagMask); 2123 __ and_(operand->reg(), ~kSmiTagMask);
2122 } 2124 }
2123 } 2125 }
2124 answer = *operand; 2126 answer = *operand;
2125 } 2127 }
2126 break; 2128 break;
2127 2129
2128 case Token::SHR: 2130 case Token::SHR:
(...skipping 11 matching lines...) Expand all
2140 DeferredInlineSmiOperation* deferred = 2142 DeferredInlineSmiOperation* deferred =
2141 new DeferredInlineSmiOperation(op, 2143 new DeferredInlineSmiOperation(op,
2142 answer.reg(), 2144 answer.reg(),
2143 operand->reg(), 2145 operand->reg(),
2144 operand->type_info(), 2146 operand->type_info(),
2145 smi_value, 2147 smi_value,
2146 overwrite_mode); 2148 overwrite_mode);
2147 if (!operand->type_info().IsSmi()) { 2149 if (!operand->type_info().IsSmi()) {
2148 __ test(operand->reg(), Immediate(kSmiTagMask)); 2150 __ test(operand->reg(), Immediate(kSmiTagMask));
2149 deferred->Branch(not_zero); 2151 deferred->Branch(not_zero);
2150 } else { 2152 } else if (FLAG_debug_code) {
2151 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2153 __ AbortIfNotSmi(operand->reg());
2152 } 2154 }
2153 __ mov(answer.reg(), operand->reg()); 2155 __ mov(answer.reg(), operand->reg());
2154 __ SmiUntag(answer.reg()); 2156 __ SmiUntag(answer.reg());
2155 __ shr(answer.reg(), shift_value); 2157 __ shr(answer.reg(), shift_value);
2156 // A negative Smi shifted right two is in the positive Smi range. 2158 // A negative Smi shifted right two is in the positive Smi range.
2157 if (shift_value < 2) { 2159 if (shift_value < 2) {
2158 __ test(answer.reg(), Immediate(0xc0000000)); 2160 __ test(answer.reg(), Immediate(0xc0000000));
2159 deferred->Branch(not_zero); 2161 deferred->Branch(not_zero);
2160 } 2162 }
2161 operand->Unuse(); 2163 operand->Unuse();
2162 __ SmiTag(answer.reg()); 2164 __ SmiTag(answer.reg());
2163 deferred->BindExit(); 2165 deferred->BindExit();
2164 } 2166 }
2165 break; 2167 break;
2166 2168
2167 case Token::SHL: 2169 case Token::SHL:
2168 if (reversed) { 2170 if (reversed) {
2171 // Move operand into ecx and also into a second register.
2172 // If operand is already in a register, take advantage of that.
2173 // This lets us modify ecx, but still bail out to deferred code.
2169 Result right; 2174 Result right;
2170 Result right_copy_in_ecx; 2175 Result right_copy_in_ecx;
2171 2176 TypeInfo right_type_info = operand->type_info();
2172 // Make sure to get a copy of the right operand into ecx. This
2173 // allows us to modify it without having to restore it in the
2174 // deferred code.
2175 operand->ToRegister(); 2177 operand->ToRegister();
2176 if (operand->reg().is(ecx)) { 2178 if (operand->reg().is(ecx)) {
2177 right = allocator()->Allocate(); 2179 right = allocator()->Allocate();
2178 __ mov(right.reg(), ecx); 2180 __ mov(right.reg(), ecx);
2179 frame_->Spill(ecx); 2181 frame_->Spill(ecx);
2180 right_copy_in_ecx = *operand; 2182 right_copy_in_ecx = *operand;
2181 } else { 2183 } else {
2182 right_copy_in_ecx = allocator()->Allocate(ecx); 2184 right_copy_in_ecx = allocator()->Allocate(ecx);
2183 __ mov(ecx, operand->reg()); 2185 __ mov(ecx, operand->reg());
2184 right = *operand; 2186 right = *operand;
2185 } 2187 }
2186 operand->Unuse(); 2188 operand->Unuse();
2187 2189
2188 answer = allocator()->Allocate(); 2190 answer = allocator()->Allocate();
2189 DeferredInlineSmiOperationReversed* deferred = 2191 DeferredInlineSmiOperationReversed* deferred =
2190 new DeferredInlineSmiOperationReversed(op, 2192 new DeferredInlineSmiOperationReversed(op,
2191 answer.reg(), 2193 answer.reg(),
2192 smi_value, 2194 smi_value,
2193 right.reg(), 2195 right.reg(),
2194 right.type_info(), 2196 right_type_info,
2195 overwrite_mode); 2197 overwrite_mode);
2196 __ mov(answer.reg(), Immediate(int_value)); 2198 __ mov(answer.reg(), Immediate(int_value));
2197 __ sar(ecx, kSmiTagSize); 2199 __ sar(ecx, kSmiTagSize);
2198 if (!right.type_info().IsSmi()) { 2200 if (!right.type_info().IsSmi()) {
2199 deferred->Branch(carry); 2201 deferred->Branch(carry);
2200 } else { 2202 } else if (FLAG_debug_code) {
2201 if (FLAG_debug_code) __ AbortIfNotSmi(right.reg()); 2203 __ AbortIfNotSmi(right.reg());
2202 } 2204 }
2203 __ shl_cl(answer.reg()); 2205 __ shl_cl(answer.reg());
2204 __ cmp(answer.reg(), 0xc0000000); 2206 __ cmp(answer.reg(), 0xc0000000);
2205 deferred->Branch(sign); 2207 deferred->Branch(sign);
2206 __ SmiTag(answer.reg()); 2208 __ SmiTag(answer.reg());
2207 2209
2208 deferred->BindExit(); 2210 deferred->BindExit();
2209 } else { 2211 } else {
2210 // Only the least significant 5 bits of the shift value are used. 2212 // Only the least significant 5 bits of the shift value are used.
2211 // In the slow case, this masking is done inside the runtime call. 2213 // In the slow case, this masking is done inside the runtime call.
(...skipping 20 matching lines...) Expand all
2232 DeferredInlineSmiOperation* deferred = 2234 DeferredInlineSmiOperation* deferred =
2233 new DeferredInlineSmiOperation(op, 2235 new DeferredInlineSmiOperation(op,
2234 answer.reg(), 2236 answer.reg(),
2235 operand->reg(), 2237 operand->reg(),
2236 operand->type_info(), 2238 operand->type_info(),
2237 smi_value, 2239 smi_value,
2238 overwrite_mode); 2240 overwrite_mode);
2239 if (!operand->type_info().IsSmi()) { 2241 if (!operand->type_info().IsSmi()) {
2240 __ test(operand->reg(), Immediate(kSmiTagMask)); 2242 __ test(operand->reg(), Immediate(kSmiTagMask));
2241 deferred->Branch(not_zero); 2243 deferred->Branch(not_zero);
2242 } else { 2244 } else if (FLAG_debug_code) {
2243 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2245 __ AbortIfNotSmi(operand->reg());
2244 } 2246 }
2245 __ mov(answer.reg(), operand->reg()); 2247 __ mov(answer.reg(), operand->reg());
2246 ASSERT(kSmiTag == 0); // adjust code if not the case 2248 ASSERT(kSmiTag == 0); // adjust code if not the case
2247 // We do no shifts, only the Smi conversion, if shift_value is 1. 2249 // We do no shifts, only the Smi conversion, if shift_value is 1.
2248 if (shift_value > 1) { 2250 if (shift_value > 1) {
2249 __ shl(answer.reg(), shift_value - 1); 2251 __ shl(answer.reg(), shift_value - 1);
2250 } 2252 }
2251 // Convert int result to Smi, checking that it is in int range. 2253 // Convert int result to Smi, checking that it is in int range.
2252 ASSERT(kSmiTagSize == 1); // adjust code if not the case 2254 ASSERT(kSmiTagSize == 1); // adjust code if not the case
2253 __ add(answer.reg(), Operand(answer.reg())); 2255 __ add(answer.reg(), Operand(answer.reg()));
(...skipping 22 matching lines...) Expand all
2276 deferred = new DeferredInlineSmiOperation(op, 2278 deferred = new DeferredInlineSmiOperation(op,
2277 operand->reg(), 2279 operand->reg(),
2278 operand->reg(), 2280 operand->reg(),
2279 operand->type_info(), 2281 operand->type_info(),
2280 smi_value, 2282 smi_value,
2281 overwrite_mode); 2283 overwrite_mode);
2282 } 2284 }
2283 if (!operand->type_info().IsSmi()) { 2285 if (!operand->type_info().IsSmi()) {
2284 __ test(operand->reg(), Immediate(kSmiTagMask)); 2286 __ test(operand->reg(), Immediate(kSmiTagMask));
2285 deferred->Branch(not_zero); 2287 deferred->Branch(not_zero);
2286 } else { 2288 } else if (FLAG_debug_code) {
2287 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2289 __ AbortIfNotSmi(operand->reg());
2288 } 2290 }
2289 if (op == Token::BIT_AND) { 2291 if (op == Token::BIT_AND) {
2290 __ and_(Operand(operand->reg()), Immediate(value)); 2292 __ and_(Operand(operand->reg()), Immediate(value));
2291 } else if (op == Token::BIT_XOR) { 2293 } else if (op == Token::BIT_XOR) {
2292 if (int_value != 0) { 2294 if (int_value != 0) {
2293 __ xor_(Operand(operand->reg()), Immediate(value)); 2295 __ xor_(Operand(operand->reg()), Immediate(value));
2294 } 2296 }
2295 } else { 2297 } else {
2296 ASSERT(op == Token::BIT_OR); 2298 ASSERT(op == Token::BIT_OR);
2297 if (int_value != 0) { 2299 if (int_value != 0) {
(...skipping 10748 matching lines...) Expand 10 before | Expand all | Expand 10 after
13046 13048
13047 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 13049 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
13048 // tagged as a small integer. 13050 // tagged as a small integer.
13049 __ bind(&runtime); 13051 __ bind(&runtime);
13050 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13052 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13051 } 13053 }
13052 13054
13053 #undef __ 13055 #undef __
13054 13056
13055 } } // namespace v8::internal 13057 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698