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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 214493002: Introduce rolp, rorp, rclp, rcrp, shlp, shrp and sarp for x64 port (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 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 | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 // The assert checks that the constants for the maximum number of digits 570 // The assert checks that the constants for the maximum number of digits
571 // for an array index cached in the hash field and the number of bits 571 // for an array index cached in the hash field and the number of bits
572 // reserved for it does not conflict. 572 // reserved for it does not conflict.
573 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 573 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
574 (1 << String::kArrayIndexValueBits)); 574 (1 << String::kArrayIndexValueBits));
575 // We want the smi-tagged index in key. Even if we subsequently go to 575 // We want the smi-tagged index in key. Even if we subsequently go to
576 // the slow case, converting the key to a smi is always valid. 576 // the slow case, converting the key to a smi is always valid.
577 // key: string key 577 // key: string key
578 // hash: key's hash field, including its array index value. 578 // hash: key's hash field, including its array index value.
579 andp(hash, Immediate(String::kArrayIndexValueMask)); 579 andp(hash, Immediate(String::kArrayIndexValueMask));
580 shr(hash, Immediate(String::kHashShift)); 580 shrp(hash, Immediate(String::kHashShift));
581 // Here we actually clobber the key which will be used if calling into 581 // Here we actually clobber the key which will be used if calling into
582 // runtime later. However as the new key is the numeric value of a string key 582 // runtime later. However as the new key is the numeric value of a string key
583 // there is no difference in using either key. 583 // there is no difference in using either key.
584 Integer32ToSmi(index, hash); 584 Integer32ToSmi(index, hash);
585 } 585 }
586 586
587 587
588 void MacroAssembler::CallRuntime(const Runtime::Function* f, 588 void MacroAssembler::CallRuntime(const Runtime::Function* f,
589 int num_arguments, 589 int num_arguments,
590 SaveFPRegsMode save_doubles) { 590 SaveFPRegsMode save_doubles) {
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 negp(dst); 1089 negp(dst);
1090 } 1090 }
1091 } 1091 }
1092 1092
1093 1093
1094 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { 1094 void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
1095 STATIC_ASSERT(kSmiTag == 0); 1095 STATIC_ASSERT(kSmiTag == 0);
1096 if (!dst.is(src)) { 1096 if (!dst.is(src)) {
1097 movl(dst, src); 1097 movl(dst, src);
1098 } 1098 }
1099 shl(dst, Immediate(kSmiShift)); 1099 shlp(dst, Immediate(kSmiShift));
1100 } 1100 }
1101 1101
1102 1102
1103 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 1103 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
1104 if (emit_debug_code()) { 1104 if (emit_debug_code()) {
1105 testb(dst, Immediate(0x01)); 1105 testb(dst, Immediate(0x01));
1106 Label ok; 1106 Label ok;
1107 j(zero, &ok, Label::kNear); 1107 j(zero, &ok, Label::kNear);
1108 Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 1108 Abort(kInteger32ToSmiFieldWritingToNonSmiLocation);
1109 bind(&ok); 1109 bind(&ok);
1110 } 1110 }
1111 ASSERT(kSmiShift % kBitsPerByte == 0); 1111 ASSERT(kSmiShift % kBitsPerByte == 0);
1112 movl(Operand(dst, kSmiShift / kBitsPerByte), src); 1112 movl(Operand(dst, kSmiShift / kBitsPerByte), src);
1113 } 1113 }
1114 1114
1115 1115
1116 void MacroAssembler::Integer64PlusConstantToSmi(Register dst, 1116 void MacroAssembler::Integer64PlusConstantToSmi(Register dst,
1117 Register src, 1117 Register src,
1118 int constant) { 1118 int constant) {
1119 if (dst.is(src)) { 1119 if (dst.is(src)) {
1120 addl(dst, Immediate(constant)); 1120 addl(dst, Immediate(constant));
1121 } else { 1121 } else {
1122 leal(dst, Operand(src, constant)); 1122 leal(dst, Operand(src, constant));
1123 } 1123 }
1124 shl(dst, Immediate(kSmiShift)); 1124 shlp(dst, Immediate(kSmiShift));
1125 } 1125 }
1126 1126
1127 1127
1128 void MacroAssembler::SmiToInteger32(Register dst, Register src) { 1128 void MacroAssembler::SmiToInteger32(Register dst, Register src) {
1129 STATIC_ASSERT(kSmiTag == 0); 1129 STATIC_ASSERT(kSmiTag == 0);
1130 if (!dst.is(src)) { 1130 if (!dst.is(src)) {
1131 movp(dst, src); 1131 movp(dst, src);
1132 } 1132 }
1133 shr(dst, Immediate(kSmiShift)); 1133 shrq(dst, Immediate(kSmiShift));
1134 } 1134 }
1135 1135
1136 1136
1137 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 1137 void MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
1138 movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 1138 movl(dst, Operand(src, kSmiShift / kBitsPerByte));
1139 } 1139 }
1140 1140
1141 1141
1142 void MacroAssembler::SmiToInteger64(Register dst, Register src) { 1142 void MacroAssembler::SmiToInteger64(Register dst, Register src) {
1143 STATIC_ASSERT(kSmiTag == 0); 1143 STATIC_ASSERT(kSmiTag == 0);
1144 if (!dst.is(src)) { 1144 if (!dst.is(src)) {
1145 movp(dst, src); 1145 movp(dst, src);
1146 } 1146 }
1147 sar(dst, Immediate(kSmiShift)); 1147 sarq(dst, Immediate(kSmiShift));
1148 } 1148 }
1149 1149
1150 1150
1151 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 1151 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
1152 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 1152 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
1153 } 1153 }
1154 1154
1155 1155
1156 void MacroAssembler::SmiTest(Register src) { 1156 void MacroAssembler::SmiTest(Register src) {
1157 AssertSmi(src); 1157 AssertSmi(src);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1222 ASSERT(power >= 0); 1222 ASSERT(power >= 0);
1223 ASSERT(power < 64); 1223 ASSERT(power < 64);
1224 if (power == 0) { 1224 if (power == 0) {
1225 SmiToInteger64(dst, src); 1225 SmiToInteger64(dst, src);
1226 return; 1226 return;
1227 } 1227 }
1228 if (!dst.is(src)) { 1228 if (!dst.is(src)) {
1229 movp(dst, src); 1229 movp(dst, src);
1230 } 1230 }
1231 if (power < kSmiShift) { 1231 if (power < kSmiShift) {
1232 sar(dst, Immediate(kSmiShift - power)); 1232 sarp(dst, Immediate(kSmiShift - power));
1233 } else if (power > kSmiShift) { 1233 } else if (power > kSmiShift) {
1234 shl(dst, Immediate(power - kSmiShift)); 1234 shlp(dst, Immediate(power - kSmiShift));
1235 } 1235 }
1236 } 1236 }
1237 1237
1238 1238
1239 void MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 1239 void MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst,
1240 Register src, 1240 Register src,
1241 int power) { 1241 int power) {
1242 ASSERT((0 <= power) && (power < 32)); 1242 ASSERT((0 <= power) && (power < 32));
1243 if (dst.is(src)) { 1243 if (dst.is(src)) {
1244 shr(dst, Immediate(power + kSmiShift)); 1244 shrp(dst, Immediate(power + kSmiShift));
1245 } else { 1245 } else {
1246 UNIMPLEMENTED(); // Not used. 1246 UNIMPLEMENTED(); // Not used.
1247 } 1247 }
1248 } 1248 }
1249 1249
1250 1250
1251 void MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 1251 void MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2,
1252 Label* on_not_smis, 1252 Label* on_not_smis,
1253 Label::Distance near_jump) { 1253 Label::Distance near_jump) {
1254 if (dst.is(src1) || dst.is(src2)) { 1254 if (dst.is(src1) || dst.is(src2)) {
(...skipping 22 matching lines...) Expand all
1277 STATIC_ASSERT(kSmiTag == 0); 1277 STATIC_ASSERT(kSmiTag == 0);
1278 testb(src, Immediate(kSmiTagMask)); 1278 testb(src, Immediate(kSmiTagMask));
1279 return zero; 1279 return zero;
1280 } 1280 }
1281 1281
1282 1282
1283 Condition MacroAssembler::CheckNonNegativeSmi(Register src) { 1283 Condition MacroAssembler::CheckNonNegativeSmi(Register src) {
1284 STATIC_ASSERT(kSmiTag == 0); 1284 STATIC_ASSERT(kSmiTag == 0);
1285 // Test that both bits of the mask 0x8000000000000001 are zero. 1285 // Test that both bits of the mask 0x8000000000000001 are zero.
1286 movp(kScratchRegister, src); 1286 movp(kScratchRegister, src);
1287 rol(kScratchRegister, Immediate(1)); 1287 rolp(kScratchRegister, Immediate(1));
1288 testb(kScratchRegister, Immediate(3)); 1288 testb(kScratchRegister, Immediate(3));
1289 return zero; 1289 return zero;
1290 } 1290 }
1291 1291
1292 1292
1293 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { 1293 Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
1294 if (first.is(second)) { 1294 if (first.is(second)) {
1295 return CheckSmi(first); 1295 return CheckSmi(first);
1296 } 1296 }
1297 STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 1297 STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
1298 leal(kScratchRegister, Operand(first, second, times_1, 0)); 1298 leal(kScratchRegister, Operand(first, second, times_1, 0));
1299 testb(kScratchRegister, Immediate(0x03)); 1299 testb(kScratchRegister, Immediate(0x03));
1300 return zero; 1300 return zero;
1301 } 1301 }
1302 1302
1303 1303
1304 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1304 Condition MacroAssembler::CheckBothNonNegativeSmi(Register first,
1305 Register second) { 1305 Register second) {
1306 if (first.is(second)) { 1306 if (first.is(second)) {
1307 return CheckNonNegativeSmi(first); 1307 return CheckNonNegativeSmi(first);
1308 } 1308 }
1309 movp(kScratchRegister, first); 1309 movp(kScratchRegister, first);
1310 orp(kScratchRegister, second); 1310 orp(kScratchRegister, second);
1311 rol(kScratchRegister, Immediate(1)); 1311 rolp(kScratchRegister, Immediate(1));
1312 testl(kScratchRegister, Immediate(3)); 1312 testl(kScratchRegister, Immediate(3));
1313 return zero; 1313 return zero;
1314 } 1314 }
1315 1315
1316 1316
1317 Condition MacroAssembler::CheckEitherSmi(Register first, 1317 Condition MacroAssembler::CheckEitherSmi(Register first,
1318 Register second, 1318 Register second,
1319 Register scratch) { 1319 Register scratch) {
1320 if (first.is(second)) { 1320 if (first.is(second)) {
1321 return CheckSmi(first); 1321 return CheckSmi(first);
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 } 2027 }
2028 } 2028 }
2029 2029
2030 2030
2031 void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 2031 void MacroAssembler::SmiShiftArithmeticRightConstant(Register dst,
2032 Register src, 2032 Register src,
2033 int shift_value) { 2033 int shift_value) {
2034 ASSERT(is_uint5(shift_value)); 2034 ASSERT(is_uint5(shift_value));
2035 if (shift_value > 0) { 2035 if (shift_value > 0) {
2036 if (dst.is(src)) { 2036 if (dst.is(src)) {
2037 sar(dst, Immediate(shift_value + kSmiShift)); 2037 sarp(dst, Immediate(shift_value + kSmiShift));
2038 shl(dst, Immediate(kSmiShift)); 2038 shlp(dst, Immediate(kSmiShift));
2039 } else { 2039 } else {
2040 UNIMPLEMENTED(); // Not used. 2040 UNIMPLEMENTED(); // Not used.
2041 } 2041 }
2042 } 2042 }
2043 } 2043 }
2044 2044
2045 2045
2046 void MacroAssembler::SmiShiftLeftConstant(Register dst, 2046 void MacroAssembler::SmiShiftLeftConstant(Register dst,
2047 Register src, 2047 Register src,
2048 int shift_value) { 2048 int shift_value) {
2049 if (!dst.is(src)) { 2049 if (!dst.is(src)) {
2050 movp(dst, src); 2050 movp(dst, src);
2051 } 2051 }
2052 if (shift_value > 0) { 2052 if (shift_value > 0) {
2053 shl(dst, Immediate(shift_value)); 2053 shlp(dst, Immediate(shift_value));
2054 } 2054 }
2055 } 2055 }
2056 2056
2057 2057
2058 void MacroAssembler::SmiShiftLogicalRightConstant( 2058 void MacroAssembler::SmiShiftLogicalRightConstant(
2059 Register dst, Register src, int shift_value, 2059 Register dst, Register src, int shift_value,
2060 Label* on_not_smi_result, Label::Distance near_jump) { 2060 Label* on_not_smi_result, Label::Distance near_jump) {
2061 // Logic right shift interprets its result as an *unsigned* number. 2061 // Logic right shift interprets its result as an *unsigned* number.
2062 if (dst.is(src)) { 2062 if (dst.is(src)) {
2063 UNIMPLEMENTED(); // Not used. 2063 UNIMPLEMENTED(); // Not used.
2064 } else { 2064 } else {
2065 movp(dst, src); 2065 movp(dst, src);
2066 if (shift_value == 0) { 2066 if (shift_value == 0) {
2067 testp(dst, dst); 2067 testp(dst, dst);
2068 j(negative, on_not_smi_result, near_jump); 2068 j(negative, on_not_smi_result, near_jump);
2069 } 2069 }
2070 shr(dst, Immediate(shift_value + kSmiShift)); 2070 shrq(dst, Immediate(shift_value + kSmiShift));
2071 shl(dst, Immediate(kSmiShift)); 2071 shlq(dst, Immediate(kSmiShift));
2072 } 2072 }
2073 } 2073 }
2074 2074
2075 2075
2076 void MacroAssembler::SmiShiftLeft(Register dst, 2076 void MacroAssembler::SmiShiftLeft(Register dst,
2077 Register src1, 2077 Register src1,
2078 Register src2) { 2078 Register src2) {
2079 ASSERT(!dst.is(rcx)); 2079 ASSERT(!dst.is(rcx));
2080 // Untag shift amount. 2080 // Untag shift amount.
2081 if (!dst.is(src1)) { 2081 if (!dst.is(src1)) {
2082 movq(dst, src1); 2082 movq(dst, src1);
2083 } 2083 }
2084 SmiToInteger32(rcx, src2); 2084 SmiToInteger32(rcx, src2);
2085 // Shift amount specified by lower 5 bits, not six as the shl opcode. 2085 // Shift amount specified by lower 5 bits, not six as the shl opcode.
2086 andq(rcx, Immediate(0x1f)); 2086 andq(rcx, Immediate(0x1f));
2087 shl_cl(dst); 2087 shlq_cl(dst);
2088 } 2088 }
2089 2089
2090 2090
2091 void MacroAssembler::SmiShiftLogicalRight(Register dst, 2091 void MacroAssembler::SmiShiftLogicalRight(Register dst,
2092 Register src1, 2092 Register src1,
2093 Register src2, 2093 Register src2,
2094 Label* on_not_smi_result, 2094 Label* on_not_smi_result,
2095 Label::Distance near_jump) { 2095 Label::Distance near_jump) {
2096 ASSERT(!dst.is(kScratchRegister)); 2096 ASSERT(!dst.is(kScratchRegister));
2097 ASSERT(!src1.is(kScratchRegister)); 2097 ASSERT(!src1.is(kScratchRegister));
2098 ASSERT(!src2.is(kScratchRegister)); 2098 ASSERT(!src2.is(kScratchRegister));
2099 ASSERT(!dst.is(rcx)); 2099 ASSERT(!dst.is(rcx));
2100 // dst and src1 can be the same, because the one case that bails out 2100 // dst and src1 can be the same, because the one case that bails out
2101 // is a shift by 0, which leaves dst, and therefore src1, unchanged. 2101 // is a shift by 0, which leaves dst, and therefore src1, unchanged.
2102 if (src1.is(rcx) || src2.is(rcx)) { 2102 if (src1.is(rcx) || src2.is(rcx)) {
2103 movq(kScratchRegister, rcx); 2103 movq(kScratchRegister, rcx);
2104 } 2104 }
2105 if (!dst.is(src1)) { 2105 if (!dst.is(src1)) {
2106 movq(dst, src1); 2106 movq(dst, src1);
2107 } 2107 }
2108 SmiToInteger32(rcx, src2); 2108 SmiToInteger32(rcx, src2);
2109 orl(rcx, Immediate(kSmiShift)); 2109 orl(rcx, Immediate(kSmiShift));
2110 shr_cl(dst); // Shift is rcx modulo 0x1f + 32. 2110 shrq_cl(dst); // Shift is rcx modulo 0x1f + 32.
2111 shl(dst, Immediate(kSmiShift)); 2111 shlq(dst, Immediate(kSmiShift));
2112 testq(dst, dst); 2112 testq(dst, dst);
2113 if (src1.is(rcx) || src2.is(rcx)) { 2113 if (src1.is(rcx) || src2.is(rcx)) {
2114 Label positive_result; 2114 Label positive_result;
2115 j(positive, &positive_result, Label::kNear); 2115 j(positive, &positive_result, Label::kNear);
2116 if (src1.is(rcx)) { 2116 if (src1.is(rcx)) {
2117 movq(src1, kScratchRegister); 2117 movq(src1, kScratchRegister);
2118 } else { 2118 } else {
2119 movq(src2, kScratchRegister); 2119 movq(src2, kScratchRegister);
2120 } 2120 }
2121 jmp(on_not_smi_result, near_jump); 2121 jmp(on_not_smi_result, near_jump);
(...skipping 15 matching lines...) Expand all
2137 if (src1.is(rcx)) { 2137 if (src1.is(rcx)) {
2138 movp(kScratchRegister, src1); 2138 movp(kScratchRegister, src1);
2139 } else if (src2.is(rcx)) { 2139 } else if (src2.is(rcx)) {
2140 movp(kScratchRegister, src2); 2140 movp(kScratchRegister, src2);
2141 } 2141 }
2142 if (!dst.is(src1)) { 2142 if (!dst.is(src1)) {
2143 movp(dst, src1); 2143 movp(dst, src1);
2144 } 2144 }
2145 SmiToInteger32(rcx, src2); 2145 SmiToInteger32(rcx, src2);
2146 orl(rcx, Immediate(kSmiShift)); 2146 orl(rcx, Immediate(kSmiShift));
2147 sar_cl(dst); // Shift 32 + original rcx & 0x1f. 2147 sarp_cl(dst); // Shift 32 + original rcx & 0x1f.
2148 shl(dst, Immediate(kSmiShift)); 2148 shlp(dst, Immediate(kSmiShift));
2149 if (src1.is(rcx)) { 2149 if (src1.is(rcx)) {
2150 movp(src1, kScratchRegister); 2150 movp(src1, kScratchRegister);
2151 } else if (src2.is(rcx)) { 2151 } else if (src2.is(rcx)) {
2152 movp(src2, kScratchRegister); 2152 movp(src2, kScratchRegister);
2153 } 2153 }
2154 } 2154 }
2155 2155
2156 2156
2157 void MacroAssembler::SelectNonSmi(Register dst, 2157 void MacroAssembler::SelectNonSmi(Register dst,
2158 Register src1, 2158 Register src1,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 SmiIndex MacroAssembler::SmiToIndex(Register dst, 2194 SmiIndex MacroAssembler::SmiToIndex(Register dst,
2195 Register src, 2195 Register src,
2196 int shift) { 2196 int shift) {
2197 ASSERT(is_uint6(shift)); 2197 ASSERT(is_uint6(shift));
2198 // There is a possible optimization if shift is in the range 60-63, but that 2198 // There is a possible optimization if shift is in the range 60-63, but that
2199 // will (and must) never happen. 2199 // will (and must) never happen.
2200 if (!dst.is(src)) { 2200 if (!dst.is(src)) {
2201 movq(dst, src); 2201 movq(dst, src);
2202 } 2202 }
2203 if (shift < kSmiShift) { 2203 if (shift < kSmiShift) {
2204 sar(dst, Immediate(kSmiShift - shift)); 2204 sarq(dst, Immediate(kSmiShift - shift));
2205 } else { 2205 } else {
2206 shl(dst, Immediate(shift - kSmiShift)); 2206 shlq(dst, Immediate(shift - kSmiShift));
2207 } 2207 }
2208 return SmiIndex(dst, times_1); 2208 return SmiIndex(dst, times_1);
2209 } 2209 }
2210 2210
2211 SmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 2211 SmiIndex MacroAssembler::SmiToNegativeIndex(Register dst,
2212 Register src, 2212 Register src,
2213 int shift) { 2213 int shift) {
2214 // Register src holds a positive smi. 2214 // Register src holds a positive smi.
2215 ASSERT(is_uint6(shift)); 2215 ASSERT(is_uint6(shift));
2216 if (!dst.is(src)) { 2216 if (!dst.is(src)) {
2217 movq(dst, src); 2217 movq(dst, src);
2218 } 2218 }
2219 negq(dst); 2219 negq(dst);
2220 if (shift < kSmiShift) { 2220 if (shift < kSmiShift) {
2221 sar(dst, Immediate(kSmiShift - shift)); 2221 sarq(dst, Immediate(kSmiShift - shift));
2222 } else { 2222 } else {
2223 shl(dst, Immediate(shift - kSmiShift)); 2223 shlq(dst, Immediate(shift - kSmiShift));
2224 } 2224 }
2225 return SmiIndex(dst, times_1); 2225 return SmiIndex(dst, times_1);
2226 } 2226 }
2227 2227
2228 2228
2229 void MacroAssembler::AddSmiField(Register dst, const Operand& src) { 2229 void MacroAssembler::AddSmiField(Register dst, const Operand& src) {
2230 ASSERT_EQ(0, kSmiShift % kBitsPerByte); 2230 ASSERT_EQ(0, kSmiShift % kBitsPerByte);
2231 addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 2231 addl(dst, Operand(src, kSmiShift / kBitsPerByte));
2232 } 2232 }
2233 2233
2234 2234
2235 void MacroAssembler::Push(Smi* source) { 2235 void MacroAssembler::Push(Smi* source) {
2236 intptr_t smi = reinterpret_cast<intptr_t>(source); 2236 intptr_t smi = reinterpret_cast<intptr_t>(source);
2237 if (is_int32(smi)) { 2237 if (is_int32(smi)) {
2238 Push(Immediate(static_cast<int32_t>(smi))); 2238 Push(Immediate(static_cast<int32_t>(smi)));
2239 } else { 2239 } else {
2240 Register constant = GetSmiConstant(source); 2240 Register constant = GetSmiConstant(source);
2241 Push(constant); 2241 Push(constant);
2242 } 2242 }
2243 } 2243 }
2244 2244
2245 2245
2246 void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) { 2246 void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) {
2247 movp(scratch, src); 2247 movp(scratch, src);
2248 // High bits. 2248 // High bits.
2249 shr(src, Immediate(64 - kSmiShift)); 2249 shrp(src, Immediate(64 - kSmiShift));
2250 shl(src, Immediate(kSmiShift)); 2250 shlp(src, Immediate(kSmiShift));
2251 Push(src); 2251 Push(src);
2252 // Low bits. 2252 // Low bits.
2253 shl(scratch, Immediate(kSmiShift)); 2253 shlp(scratch, Immediate(kSmiShift));
2254 Push(scratch); 2254 Push(scratch);
2255 } 2255 }
2256 2256
2257 2257
2258 void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) { 2258 void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) {
2259 Pop(scratch); 2259 Pop(scratch);
2260 // Low bits. 2260 // Low bits.
2261 shr(scratch, Immediate(kSmiShift)); 2261 shrp(scratch, Immediate(kSmiShift));
2262 Pop(dst); 2262 Pop(dst);
2263 shr(dst, Immediate(kSmiShift)); 2263 shrp(dst, Immediate(kSmiShift));
2264 // High bits. 2264 // High bits.
2265 shl(dst, Immediate(64 - kSmiShift)); 2265 shlp(dst, Immediate(64 - kSmiShift));
2266 orp(dst, scratch); 2266 orp(dst, scratch);
2267 } 2267 }
2268 2268
2269 2269
2270 void MacroAssembler::Test(const Operand& src, Smi* source) { 2270 void MacroAssembler::Test(const Operand& src, Smi* source) {
2271 testl(Operand(src, kIntSize), Immediate(source->value())); 2271 testl(Operand(src, kIntSize), Immediate(source->value()));
2272 } 2272 }
2273 2273
2274 2274
2275 // ---------------------------------------------------------------------------- 2275 // ----------------------------------------------------------------------------
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 DONT_DO_SMI_CHECK); 2308 DONT_DO_SMI_CHECK);
2309 2309
2310 STATIC_ASSERT(8 == kDoubleSize); 2310 STATIC_ASSERT(8 == kDoubleSize);
2311 movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2311 movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4));
2312 xorp(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2312 xorp(scratch, FieldOperand(object, HeapNumber::kValueOffset));
2313 andp(scratch, mask); 2313 andp(scratch, mask);
2314 // Each entry in string cache consists of two pointer sized fields, 2314 // Each entry in string cache consists of two pointer sized fields,
2315 // but times_twice_pointer_size (multiplication by 16) scale factor 2315 // but times_twice_pointer_size (multiplication by 16) scale factor
2316 // is not supported by addrmode on x64 platform. 2316 // is not supported by addrmode on x64 platform.
2317 // So we have to premultiply entry index before lookup. 2317 // So we have to premultiply entry index before lookup.
2318 shl(scratch, Immediate(kPointerSizeLog2 + 1)); 2318 shlp(scratch, Immediate(kPointerSizeLog2 + 1));
2319 2319
2320 Register index = scratch; 2320 Register index = scratch;
2321 Register probe = mask; 2321 Register probe = mask;
2322 movp(probe, 2322 movp(probe,
2323 FieldOperand(number_string_cache, 2323 FieldOperand(number_string_cache,
2324 index, 2324 index,
2325 times_1, 2325 times_1,
2326 FixedArray::kHeaderSize)); 2326 FixedArray::kHeaderSize));
2327 JumpIfSmi(probe, not_found); 2327 JumpIfSmi(probe, not_found);
2328 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 2328 movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset));
2329 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); 2329 ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset));
2330 j(parity_even, not_found); // Bail out if NaN is involved. 2330 j(parity_even, not_found); // Bail out if NaN is involved.
2331 j(not_equal, not_found); // The cache did not contain this value. 2331 j(not_equal, not_found); // The cache did not contain this value.
2332 jmp(&load_result_from_cache); 2332 jmp(&load_result_from_cache);
2333 2333
2334 bind(&is_smi); 2334 bind(&is_smi);
2335 SmiToInteger32(scratch, object); 2335 SmiToInteger32(scratch, object);
2336 andp(scratch, mask); 2336 andp(scratch, mask);
2337 // Each entry in string cache consists of two pointer sized fields, 2337 // Each entry in string cache consists of two pointer sized fields,
2338 // but times_twice_pointer_size (multiplication by 16) scale factor 2338 // but times_twice_pointer_size (multiplication by 16) scale factor
2339 // is not supported by addrmode on x64 platform. 2339 // is not supported by addrmode on x64 platform.
2340 // So we have to premultiply entry index before lookup. 2340 // So we have to premultiply entry index before lookup.
2341 shl(scratch, Immediate(kPointerSizeLog2 + 1)); 2341 shlp(scratch, Immediate(kPointerSizeLog2 + 1));
2342 2342
2343 // Check if the entry is the smi we are looking for. 2343 // Check if the entry is the smi we are looking for.
2344 cmpp(object, 2344 cmpp(object,
2345 FieldOperand(number_string_cache, 2345 FieldOperand(number_string_cache,
2346 index, 2346 index,
2347 times_1, 2347 times_1,
2348 FixedArray::kHeaderSize)); 2348 FixedArray::kHeaderSize));
2349 j(not_equal, not_found); 2349 j(not_equal, not_found);
2350 2350
2351 // Get the result from the cache. 2351 // Get the result from the cache.
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2886 Pop(ExternalOperand(handler_address)); 2886 Pop(ExternalOperand(handler_address));
2887 addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 2887 addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
2888 } 2888 }
2889 2889
2890 2890
2891 void MacroAssembler::JumpToHandlerEntry() { 2891 void MacroAssembler::JumpToHandlerEntry() {
2892 // Compute the handler entry address and jump to it. The handler table is 2892 // Compute the handler entry address and jump to it. The handler table is
2893 // a fixed array of (smi-tagged) code offsets. 2893 // a fixed array of (smi-tagged) code offsets.
2894 // rax = exception, rdi = code object, rdx = state. 2894 // rax = exception, rdi = code object, rdx = state.
2895 movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset)); 2895 movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
2896 shr(rdx, Immediate(StackHandler::kKindWidth)); 2896 shrp(rdx, Immediate(StackHandler::kKindWidth));
2897 movp(rdx, 2897 movp(rdx,
2898 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); 2898 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
2899 SmiToInteger64(rdx, rdx); 2899 SmiToInteger64(rdx, rdx);
2900 leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize)); 2900 leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize));
2901 jmp(rdi); 2901 jmp(rdi);
2902 } 2902 }
2903 2903
2904 2904
2905 void MacroAssembler::Throw(Register value) { 2905 void MacroAssembler::Throw(Register value) {
2906 // Adjust this code if not the case. 2906 // Adjust this code if not the case.
(...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after
4875 shrl(rcx, Immediate(shift)); 4875 shrl(rcx, Immediate(shift));
4876 andp(rcx, 4876 andp(rcx,
4877 Immediate((Page::kPageAlignmentMask >> shift) & 4877 Immediate((Page::kPageAlignmentMask >> shift) &
4878 ~(Bitmap::kBytesPerCell - 1))); 4878 ~(Bitmap::kBytesPerCell - 1)));
4879 4879
4880 addp(bitmap_reg, rcx); 4880 addp(bitmap_reg, rcx);
4881 movp(rcx, addr_reg); 4881 movp(rcx, addr_reg);
4882 shrl(rcx, Immediate(kPointerSizeLog2)); 4882 shrl(rcx, Immediate(kPointerSizeLog2));
4883 andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 4883 andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
4884 movl(mask_reg, Immediate(1)); 4884 movl(mask_reg, Immediate(1));
4885 shl_cl(mask_reg); 4885 shlp_cl(mask_reg);
4886 } 4886 }
4887 4887
4888 4888
4889 void MacroAssembler::EnsureNotWhite( 4889 void MacroAssembler::EnsureNotWhite(
4890 Register value, 4890 Register value,
4891 Register bitmap_scratch, 4891 Register bitmap_scratch,
4892 Register mask_scratch, 4892 Register mask_scratch,
4893 Label* value_is_white_and_not_data, 4893 Label* value_is_white_and_not_data,
4894 Label::Distance distance) { 4894 Label::Distance distance) {
4895 ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 4895 ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4959 jmp(&is_data_object, Label::kNear); 4959 jmp(&is_data_object, Label::kNear);
4960 4960
4961 bind(&not_external); 4961 bind(&not_external);
4962 // Sequential string, either ASCII or UC16. 4962 // Sequential string, either ASCII or UC16.
4963 ASSERT(kOneByteStringTag == 0x04); 4963 ASSERT(kOneByteStringTag == 0x04);
4964 andp(length, Immediate(kStringEncodingMask)); 4964 andp(length, Immediate(kStringEncodingMask));
4965 xorp(length, Immediate(kStringEncodingMask)); 4965 xorp(length, Immediate(kStringEncodingMask));
4966 addp(length, Immediate(0x04)); 4966 addp(length, Immediate(0x04));
4967 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. 4967 // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
4968 imulp(length, FieldOperand(value, String::kLengthOffset)); 4968 imulp(length, FieldOperand(value, String::kLengthOffset));
4969 shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); 4969 shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
4970 addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 4970 addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
4971 andp(length, Immediate(~kObjectAlignmentMask)); 4971 andp(length, Immediate(~kObjectAlignmentMask));
4972 4972
4973 bind(&is_data_object); 4973 bind(&is_data_object);
4974 // Value is a data object, and it is white. Mark it black. Since we know 4974 // Value is a data object, and it is white. Mark it black. Since we know
4975 // that the object is white we can make it black by flipping one bit. 4975 // that the object is white we can make it black by flipping one bit.
4976 orp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4976 orp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
4977 4977
4978 andp(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4978 andp(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
4979 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4979 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5058 Register current = scratch0; 5058 Register current = scratch0;
5059 Label loop_again; 5059 Label loop_again;
5060 5060
5061 movp(current, object); 5061 movp(current, object);
5062 5062
5063 // Loop based on the map going up the prototype chain. 5063 // Loop based on the map going up the prototype chain.
5064 bind(&loop_again); 5064 bind(&loop_again);
5065 movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5065 movp(current, FieldOperand(current, HeapObject::kMapOffset));
5066 movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5066 movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
5067 andp(scratch1, Immediate(Map::kElementsKindMask)); 5067 andp(scratch1, Immediate(Map::kElementsKindMask));
5068 shr(scratch1, Immediate(Map::kElementsKindShift)); 5068 shrp(scratch1, Immediate(Map::kElementsKindShift));
5069 cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5069 cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
5070 j(equal, found); 5070 j(equal, found);
5071 movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5071 movp(current, FieldOperand(current, Map::kPrototypeOffset));
5072 CompareRoot(current, Heap::kNullValueRootIndex); 5072 CompareRoot(current, Heap::kNullValueRootIndex);
5073 j(not_equal, &loop_again); 5073 j(not_equal, &loop_again);
5074 } 5074 }
5075 5075
5076 5076
5077 void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5077 void MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) {
5078 ASSERT(!dividend.is(rax)); 5078 ASSERT(!dividend.is(rax));
5079 ASSERT(!dividend.is(rdx)); 5079 ASSERT(!dividend.is(rdx));
5080 MultiplierAndShift ms(divisor); 5080 MultiplierAndShift ms(divisor);
5081 movl(rax, Immediate(ms.multiplier())); 5081 movl(rax, Immediate(ms.multiplier()));
5082 imull(dividend); 5082 imull(dividend);
5083 if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend); 5083 if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend);
5084 if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend); 5084 if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend);
5085 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); 5085 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift()));
5086 movl(rax, dividend); 5086 movl(rax, dividend);
5087 shrl(rax, Immediate(31)); 5087 shrl(rax, Immediate(31));
5088 addl(rdx, rax); 5088 addl(rdx, rax);
5089 } 5089 }
5090 5090
5091 5091
5092 } } // namespace v8::internal 5092 } } // namespace v8::internal
5093 5093
5094 #endif // V8_TARGET_ARCH_X64 5094 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698