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

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

Issue 371923006: Add mips64 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 5 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/mips64/codegen-mips64.h ('k') | src/mips64/constants-mips64.h » ('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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
11 #include "src/mips/simulator-mips.h" 11 #include "src/mips64/simulator-mips64.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 #define __ masm. 17 #define __ masm.
18 18
19 19
20 #if defined(USE_SIMULATOR) 20 #if defined(USE_SIMULATOR)
21 byte* fast_exp_mips_machine_code = NULL; 21 byte* fast_exp_mips_machine_code = NULL;
(...skipping 12 matching lines...) Expand all
34 if (buffer == NULL) return &std::exp; 34 if (buffer == NULL) return &std::exp;
35 ExternalReference::InitializeMathExpData(); 35 ExternalReference::InitializeMathExpData();
36 36
37 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 37 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
38 38
39 { 39 {
40 DoubleRegister input = f12; 40 DoubleRegister input = f12;
41 DoubleRegister result = f0; 41 DoubleRegister result = f0;
42 DoubleRegister double_scratch1 = f4; 42 DoubleRegister double_scratch1 = f4;
43 DoubleRegister double_scratch2 = f6; 43 DoubleRegister double_scratch2 = f6;
44 Register temp1 = t0; 44 Register temp1 = a4;
45 Register temp2 = t1; 45 Register temp2 = a5;
46 Register temp3 = t2; 46 Register temp3 = a6;
47 47
48 __ MovFromFloatParameter(input); 48 if (!IsMipsSoftFloatABI) {
49 // Input value is in f12 anyway, nothing to do.
50 } else {
51 __ Move(input, a0, a1);
52 }
49 __ Push(temp3, temp2, temp1); 53 __ Push(temp3, temp2, temp1);
50 MathExpGenerator::EmitMathExp( 54 MathExpGenerator::EmitMathExp(
51 &masm, input, result, double_scratch1, double_scratch2, 55 &masm, input, result, double_scratch1, double_scratch2,
52 temp1, temp2, temp3); 56 temp1, temp2, temp3);
53 __ Pop(temp3, temp2, temp1); 57 __ Pop(temp3, temp2, temp1);
54 __ MovToFloatResult(result); 58 if (!IsMipsSoftFloatABI) {
59 // Result is already in f0, nothing to do.
60 } else {
61 __ Move(v0, v1, result);
62 }
55 __ Ret(); 63 __ Ret();
56 } 64 }
57 65
58 CodeDesc desc; 66 CodeDesc desc;
59 masm.GetCode(&desc); 67 masm.GetCode(&desc);
60 ASSERT(!RelocInfo::RequiresRelocation(desc)); 68 ASSERT(!RelocInfo::RequiresRelocation(desc));
61 69
62 CpuFeatures::FlushICache(buffer, actual_size); 70 CpuFeatures::FlushICache(buffer, actual_size);
63 base::OS::ProtectCode(buffer, actual_size); 71 base::OS::ProtectCode(buffer, actual_size);
64 72
65 #if !defined(USE_SIMULATOR) 73 #if !defined(USE_SIMULATOR)
66 return FUNCTION_CAST<UnaryMathFunction>(buffer); 74 return FUNCTION_CAST<UnaryMathFunction>(buffer);
67 #else 75 #else
68 fast_exp_mips_machine_code = buffer; 76 fast_exp_mips_machine_code = buffer;
69 return &fast_exp_simulator; 77 return &fast_exp_simulator;
70 #endif 78 #endif
71 } 79 }
72 80
73 81
74 #if defined(V8_HOST_ARCH_MIPS) 82 #if defined(V8_HOST_ARCH_MIPS)
75 MemCopyUint8Function CreateMemCopyUint8Function(MemCopyUint8Function stub) { 83 MemCopyUint8Function CreateMemCopyUint8Function(MemCopyUint8Function stub) {
76 #if defined(USE_SIMULATOR) 84 #if defined(USE_SIMULATOR)
77 return stub; 85 return stub;
78 #else 86 #else
87
79 size_t actual_size; 88 size_t actual_size;
80 byte* buffer = 89 byte* buffer =
81 static_cast<byte*>(base::OS::Allocate(3 * KB, &actual_size, true)); 90 static_cast<byte*>(base::OS::Allocate(3 * KB, &actual_size, true));
82 if (buffer == NULL) return stub; 91 if (buffer == NULL) return stub;
83 92
84 // This code assumes that cache lines are 32 bytes and if the cache line is 93 // This code assumes that cache lines are 32 bytes and if the cache line is
85 // larger it will not work correctly. 94 // larger it will not work correctly.
86 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 95 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
87 96
88 { 97 {
(...skipping 17 matching lines...) Expand all
106 uint32_t pref_limit = (5 * pref_chunk) + max_pref_size; 115 uint32_t pref_limit = (5 * pref_chunk) + max_pref_size;
107 int32_t pref_hint_load = kPrefHintLoadStreamed; 116 int32_t pref_hint_load = kPrefHintLoadStreamed;
108 int32_t pref_hint_store = kPrefHintPrepareForStore; 117 int32_t pref_hint_store = kPrefHintPrepareForStore;
109 uint32_t loadstore_chunk = 4; 118 uint32_t loadstore_chunk = 4;
110 119
111 // The initial prefetches may fetch bytes that are before the buffer being 120 // The initial prefetches may fetch bytes that are before the buffer being
112 // copied. Start copies with an offset of 4 so avoid this situation when 121 // copied. Start copies with an offset of 4 so avoid this situation when
113 // using kPrefHintPrepareForStore. 122 // using kPrefHintPrepareForStore.
114 ASSERT(pref_hint_store != kPrefHintPrepareForStore || 123 ASSERT(pref_hint_store != kPrefHintPrepareForStore ||
115 pref_chunk * 4 >= max_pref_size); 124 pref_chunk * 4 >= max_pref_size);
116
117 // If the size is less than 8, go to lastb. Regardless of size, 125 // If the size is less than 8, go to lastb. Regardless of size,
118 // copy dst pointer to v0 for the retuen value. 126 // copy dst pointer to v0 for the retuen value.
119 __ slti(t2, a2, 2 * loadstore_chunk); 127 __ slti(a6, a2, 2 * loadstore_chunk);
120 __ bne(t2, zero_reg, &lastb); 128 __ bne(a6, zero_reg, &lastb);
121 __ mov(v0, a0); // In delay slot. 129 __ mov(v0, a0); // In delay slot.
122 130
123 // If src and dst have different alignments, go to unaligned, if they 131 // If src and dst have different alignments, go to unaligned, if they
124 // have the same alignment (but are not actually aligned) do a partial 132 // have the same alignment (but are not actually aligned) do a partial
125 // load/store to make them aligned. If they are both already aligned 133 // load/store to make them aligned. If they are both already aligned
126 // we can start copying at aligned. 134 // we can start copying at aligned.
127 __ xor_(t8, a1, a0); 135 __ xor_(t8, a1, a0);
128 __ andi(t8, t8, loadstore_chunk - 1); // t8 is a0/a1 word-displacement. 136 __ andi(t8, t8, loadstore_chunk - 1); // t8 is a0/a1 word-displacement.
129 __ bne(t8, zero_reg, &unaligned); 137 __ bne(t8, zero_reg, &unaligned);
130 __ subu(a3, zero_reg, a0); // In delay slot. 138 __ subu(a3, zero_reg, a0); // In delay slot.
131 139
132 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1. 140 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
133 __ beq(a3, zero_reg, &aligned); // Already aligned. 141 __ beq(a3, zero_reg, &aligned); // Already aligned.
134 __ subu(a2, a2, a3); // In delay slot. a2 is the remining bytes count. 142 __ subu(a2, a2, a3); // In delay slot. a2 is the remining bytes count.
135 143
136 if (kArchEndian == kLittle) { 144 __ lwr(t8, MemOperand(a1));
137 __ lwr(t8, MemOperand(a1)); 145 __ addu(a1, a1, a3);
138 __ addu(a1, a1, a3); 146 __ swr(t8, MemOperand(a0));
139 __ swr(t8, MemOperand(a0)); 147 __ addu(a0, a0, a3);
140 __ addu(a0, a0, a3); 148
141 } else {
142 __ lwl(t8, MemOperand(a1));
143 __ addu(a1, a1, a3);
144 __ swl(t8, MemOperand(a0));
145 __ addu(a0, a0, a3);
146 }
147 // Now dst/src are both aligned to (word) aligned addresses. Set a2 to 149 // Now dst/src are both aligned to (word) aligned addresses. Set a2 to
148 // count how many bytes we have to copy after all the 64 byte chunks are 150 // count how many bytes we have to copy after all the 64 byte chunks are
149 // copied and a3 to the dst pointer after all the 64 byte chunks have been 151 // copied and a3 to the dst pointer after all the 64 byte chunks have been
150 // copied. We will loop, incrementing a0 and a1 until a0 equals a3. 152 // copied. We will loop, incrementing a0 and a1 until a0 equals a3.
151 __ bind(&aligned); 153 __ bind(&aligned);
152 __ andi(t8, a2, 0x3f); 154 __ andi(t8, a2, 0x3f);
153 __ beq(a2, t8, &chkw); // Less than 64? 155 __ beq(a2, t8, &chkw); // Less than 64?
154 __ subu(a3, a2, t8); // In delay slot. 156 __ subu(a3, a2, t8); // In delay slot.
155 __ addu(a3, a0, a3); // Now a3 is the final dst after loop. 157 __ addu(a3, a0, a3); // Now a3 is the final dst after loop.
156 158
157 // When in the loop we prefetch with kPrefHintPrepareForStore hint, 159 // When in the loop we prefetch with kPrefHintPrepareForStore hint,
158 // in this case the a0+x should be past the "t0-32" address. This means: 160 // in this case the a0+x should be past the "a4-32" address. This means:
159 // for x=128 the last "safe" a0 address is "t0-160". Alternatively, for 161 // for x=128 the last "safe" a0 address is "a4-160". Alternatively, for
160 // x=64 the last "safe" a0 address is "t0-96". In the current version we 162 // x=64 the last "safe" a0 address is "a4-96". In the current version we
161 // will use "pref hint, 128(a0)", so "t0-160" is the limit. 163 // will use "pref hint, 128(a0)", so "a4-160" is the limit.
162 if (pref_hint_store == kPrefHintPrepareForStore) { 164 if (pref_hint_store == kPrefHintPrepareForStore) {
163 __ addu(t0, a0, a2); // t0 is the "past the end" address. 165 __ addu(a4, a0, a2); // a4 is the "past the end" address.
164 __ Subu(t9, t0, pref_limit); // t9 is the "last safe pref" address. 166 __ Subu(t9, a4, pref_limit); // t9 is the "last safe pref" address.
165 } 167 }
166 168
167 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk)); 169 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
168 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk)); 170 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
169 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk)); 171 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
170 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk)); 172 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
171 173
172 if (pref_hint_store != kPrefHintPrepareForStore) { 174 if (pref_hint_store != kPrefHintPrepareForStore) {
173 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk)); 175 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
174 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk)); 176 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
175 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk)); 177 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
176 } 178 }
177 __ bind(&loop16w); 179 __ bind(&loop16w);
178 __ lw(t0, MemOperand(a1)); 180 __ lw(a4, MemOperand(a1));
179 181
180 if (pref_hint_store == kPrefHintPrepareForStore) { 182 if (pref_hint_store == kPrefHintPrepareForStore) {
181 __ sltu(v1, t9, a0); // If a0 > t9, don't use next prefetch. 183 __ sltu(v1, t9, a0); // If a0 > t9, don't use next prefetch.
182 __ Branch(USE_DELAY_SLOT, &skip_pref, gt, v1, Operand(zero_reg)); 184 __ Branch(USE_DELAY_SLOT, &skip_pref, gt, v1, Operand(zero_reg));
183 } 185 }
184 __ lw(t1, MemOperand(a1, 1, loadstore_chunk)); // Maybe in delay slot. 186 __ lw(a5, MemOperand(a1, 1, loadstore_chunk)); // Maybe in delay slot.
185 187
186 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk)); 188 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
187 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk)); 189 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
188 190
189 __ bind(&skip_pref); 191 __ bind(&skip_pref);
190 __ lw(t2, MemOperand(a1, 2, loadstore_chunk)); 192 __ lw(a6, MemOperand(a1, 2, loadstore_chunk));
191 __ lw(t3, MemOperand(a1, 3, loadstore_chunk)); 193 __ lw(a7, MemOperand(a1, 3, loadstore_chunk));
192 __ lw(t4, MemOperand(a1, 4, loadstore_chunk)); 194 __ lw(t0, MemOperand(a1, 4, loadstore_chunk));
193 __ lw(t5, MemOperand(a1, 5, loadstore_chunk)); 195 __ lw(t1, MemOperand(a1, 5, loadstore_chunk));
194 __ lw(t6, MemOperand(a1, 6, loadstore_chunk)); 196 __ lw(t2, MemOperand(a1, 6, loadstore_chunk));
195 __ lw(t7, MemOperand(a1, 7, loadstore_chunk)); 197 __ lw(t3, MemOperand(a1, 7, loadstore_chunk));
196 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk)); 198 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
197 199
198 __ sw(t0, MemOperand(a0)); 200 __ sw(a4, MemOperand(a0));
199 __ sw(t1, MemOperand(a0, 1, loadstore_chunk)); 201 __ sw(a5, MemOperand(a0, 1, loadstore_chunk));
200 __ sw(t2, MemOperand(a0, 2, loadstore_chunk)); 202 __ sw(a6, MemOperand(a0, 2, loadstore_chunk));
201 __ sw(t3, MemOperand(a0, 3, loadstore_chunk)); 203 __ sw(a7, MemOperand(a0, 3, loadstore_chunk));
202 __ sw(t4, MemOperand(a0, 4, loadstore_chunk)); 204 __ sw(t0, MemOperand(a0, 4, loadstore_chunk));
203 __ sw(t5, MemOperand(a0, 5, loadstore_chunk)); 205 __ sw(t1, MemOperand(a0, 5, loadstore_chunk));
204 __ sw(t6, MemOperand(a0, 6, loadstore_chunk)); 206 __ sw(t2, MemOperand(a0, 6, loadstore_chunk));
205 __ sw(t7, MemOperand(a0, 7, loadstore_chunk)); 207 __ sw(t3, MemOperand(a0, 7, loadstore_chunk));
206 208
207 __ lw(t0, MemOperand(a1, 8, loadstore_chunk)); 209 __ lw(a4, MemOperand(a1, 8, loadstore_chunk));
208 __ lw(t1, MemOperand(a1, 9, loadstore_chunk)); 210 __ lw(a5, MemOperand(a1, 9, loadstore_chunk));
209 __ lw(t2, MemOperand(a1, 10, loadstore_chunk)); 211 __ lw(a6, MemOperand(a1, 10, loadstore_chunk));
210 __ lw(t3, MemOperand(a1, 11, loadstore_chunk)); 212 __ lw(a7, MemOperand(a1, 11, loadstore_chunk));
211 __ lw(t4, MemOperand(a1, 12, loadstore_chunk)); 213 __ lw(t0, MemOperand(a1, 12, loadstore_chunk));
212 __ lw(t5, MemOperand(a1, 13, loadstore_chunk)); 214 __ lw(t1, MemOperand(a1, 13, loadstore_chunk));
213 __ lw(t6, MemOperand(a1, 14, loadstore_chunk)); 215 __ lw(t2, MemOperand(a1, 14, loadstore_chunk));
214 __ lw(t7, MemOperand(a1, 15, loadstore_chunk)); 216 __ lw(t3, MemOperand(a1, 15, loadstore_chunk));
215 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk)); 217 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
216 218
217 __ sw(t0, MemOperand(a0, 8, loadstore_chunk)); 219 __ sw(a4, MemOperand(a0, 8, loadstore_chunk));
218 __ sw(t1, MemOperand(a0, 9, loadstore_chunk)); 220 __ sw(a5, MemOperand(a0, 9, loadstore_chunk));
219 __ sw(t2, MemOperand(a0, 10, loadstore_chunk)); 221 __ sw(a6, MemOperand(a0, 10, loadstore_chunk));
220 __ sw(t3, MemOperand(a0, 11, loadstore_chunk)); 222 __ sw(a7, MemOperand(a0, 11, loadstore_chunk));
221 __ sw(t4, MemOperand(a0, 12, loadstore_chunk)); 223 __ sw(t0, MemOperand(a0, 12, loadstore_chunk));
222 __ sw(t5, MemOperand(a0, 13, loadstore_chunk)); 224 __ sw(t1, MemOperand(a0, 13, loadstore_chunk));
223 __ sw(t6, MemOperand(a0, 14, loadstore_chunk)); 225 __ sw(t2, MemOperand(a0, 14, loadstore_chunk));
224 __ sw(t7, MemOperand(a0, 15, loadstore_chunk)); 226 __ sw(t3, MemOperand(a0, 15, loadstore_chunk));
225 __ addiu(a0, a0, 16 * loadstore_chunk); 227 __ addiu(a0, a0, 16 * loadstore_chunk);
226 __ bne(a0, a3, &loop16w); 228 __ bne(a0, a3, &loop16w);
227 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot. 229 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
228 __ mov(a2, t8); 230 __ mov(a2, t8);
229 231
230 // Here we have src and dest word-aligned but less than 64-bytes to go. 232 // Here we have src and dest word-aligned but less than 64-bytes to go.
231 // Check for a 32 bytes chunk and copy if there is one. Otherwise jump 233 // Check for a 32 bytes chunk and copy if there is one. Otherwise jump
232 // down to chk1w to handle the tail end of the copy. 234 // down to chk1w to handle the tail end of the copy.
233 __ bind(&chkw); 235 __ bind(&chkw);
234 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk)); 236 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
235 __ andi(t8, a2, 0x1f); 237 __ andi(t8, a2, 0x1f);
236 __ beq(a2, t8, &chk1w); // Less than 32? 238 __ beq(a2, t8, &chk1w); // Less than 32?
237 __ nop(); // In delay slot. 239 __ nop(); // In delay slot.
238 __ lw(t0, MemOperand(a1)); 240 __ lw(a4, MemOperand(a1));
239 __ lw(t1, MemOperand(a1, 1, loadstore_chunk)); 241 __ lw(a5, MemOperand(a1, 1, loadstore_chunk));
240 __ lw(t2, MemOperand(a1, 2, loadstore_chunk)); 242 __ lw(a6, MemOperand(a1, 2, loadstore_chunk));
241 __ lw(t3, MemOperand(a1, 3, loadstore_chunk)); 243 __ lw(a7, MemOperand(a1, 3, loadstore_chunk));
242 __ lw(t4, MemOperand(a1, 4, loadstore_chunk)); 244 __ lw(t0, MemOperand(a1, 4, loadstore_chunk));
243 __ lw(t5, MemOperand(a1, 5, loadstore_chunk)); 245 __ lw(t1, MemOperand(a1, 5, loadstore_chunk));
244 __ lw(t6, MemOperand(a1, 6, loadstore_chunk)); 246 __ lw(t2, MemOperand(a1, 6, loadstore_chunk));
245 __ lw(t7, MemOperand(a1, 7, loadstore_chunk)); 247 __ lw(t3, MemOperand(a1, 7, loadstore_chunk));
246 __ addiu(a1, a1, 8 * loadstore_chunk); 248 __ addiu(a1, a1, 8 * loadstore_chunk);
247 __ sw(t0, MemOperand(a0)); 249 __ sw(a4, MemOperand(a0));
248 __ sw(t1, MemOperand(a0, 1, loadstore_chunk)); 250 __ sw(a5, MemOperand(a0, 1, loadstore_chunk));
249 __ sw(t2, MemOperand(a0, 2, loadstore_chunk)); 251 __ sw(a6, MemOperand(a0, 2, loadstore_chunk));
250 __ sw(t3, MemOperand(a0, 3, loadstore_chunk)); 252 __ sw(a7, MemOperand(a0, 3, loadstore_chunk));
251 __ sw(t4, MemOperand(a0, 4, loadstore_chunk)); 253 __ sw(t0, MemOperand(a0, 4, loadstore_chunk));
252 __ sw(t5, MemOperand(a0, 5, loadstore_chunk)); 254 __ sw(t1, MemOperand(a0, 5, loadstore_chunk));
253 __ sw(t6, MemOperand(a0, 6, loadstore_chunk)); 255 __ sw(t2, MemOperand(a0, 6, loadstore_chunk));
254 __ sw(t7, MemOperand(a0, 7, loadstore_chunk)); 256 __ sw(t3, MemOperand(a0, 7, loadstore_chunk));
255 __ addiu(a0, a0, 8 * loadstore_chunk); 257 __ addiu(a0, a0, 8 * loadstore_chunk);
256 258
257 // Here we have less than 32 bytes to copy. Set up for a loop to copy 259 // Here we have less than 32 bytes to copy. Set up for a loop to copy
258 // one word at a time. Set a2 to count how many bytes we have to copy 260 // one word at a time. Set a2 to count how many bytes we have to copy
259 // after all the word chunks are copied and a3 to the dst pointer after 261 // after all the word chunks are copied and a3 to the dst pointer after
260 // all the word chunks have been copied. We will loop, incrementing a0 262 // all the word chunks have been copied. We will loop, incrementing a0
261 // and a1 untill a0 equals a3. 263 // and a1 untill a0 equals a3.
262 __ bind(&chk1w); 264 __ bind(&chk1w);
263 __ andi(a2, t8, loadstore_chunk - 1); 265 __ andi(a2, t8, loadstore_chunk - 1);
264 __ beq(a2, t8, &lastb); 266 __ beq(a2, t8, &lastb);
265 __ subu(a3, t8, a2); // In delay slot. 267 __ subu(a3, t8, a2); // In delay slot.
266 __ addu(a3, a0, a3); 268 __ addu(a3, a0, a3);
267 269
268 __ bind(&wordCopy_loop); 270 __ bind(&wordCopy_loop);
269 __ lw(t3, MemOperand(a1)); 271 __ lw(a7, MemOperand(a1));
270 __ addiu(a0, a0, loadstore_chunk); 272 __ addiu(a0, a0, loadstore_chunk);
271 __ addiu(a1, a1, loadstore_chunk); 273 __ addiu(a1, a1, loadstore_chunk);
272 __ bne(a0, a3, &wordCopy_loop); 274 __ bne(a0, a3, &wordCopy_loop);
273 __ sw(t3, MemOperand(a0, -1, loadstore_chunk)); // In delay slot. 275 __ sw(a7, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
274 276
275 __ bind(&lastb); 277 __ bind(&lastb);
276 __ Branch(&leave, le, a2, Operand(zero_reg)); 278 __ Branch(&leave, le, a2, Operand(zero_reg));
277 __ addu(a3, a0, a2); 279 __ addu(a3, a0, a2);
278 280
279 __ bind(&lastbloop); 281 __ bind(&lastbloop);
280 __ lb(v1, MemOperand(a1)); 282 __ lb(v1, MemOperand(a1));
281 __ addiu(a0, a0, 1); 283 __ addiu(a0, a0, 1);
282 __ addiu(a1, a1, 1); 284 __ addiu(a1, a1, 1);
283 __ bne(a0, a3, &lastbloop); 285 __ bne(a0, a3, &lastbloop);
284 __ sb(v1, MemOperand(a0, -1)); // In delay slot. 286 __ sb(v1, MemOperand(a0, -1)); // In delay slot.
285 287
286 __ bind(&leave); 288 __ bind(&leave);
287 __ jr(ra); 289 __ jr(ra);
288 __ nop(); 290 __ nop();
289 291
290 // Unaligned case. Only the dst gets aligned so we need to do partial 292 // Unaligned case. Only the dst gets aligned so we need to do partial
291 // loads of the source followed by normal stores to the dst (once we 293 // loads of the source followed by normal stores to the dst (once we
292 // have aligned the destination). 294 // have aligned the destination).
293 __ bind(&unaligned); 295 __ bind(&unaligned);
294 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1. 296 __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
295 __ beq(a3, zero_reg, &ua_chk16w); 297 __ beq(a3, zero_reg, &ua_chk16w);
296 __ subu(a2, a2, a3); // In delay slot. 298 __ subu(a2, a2, a3); // In delay slot.
297 299
298 if (kArchEndian == kLittle) { 300 __ lwr(v1, MemOperand(a1));
299 __ lwr(v1, MemOperand(a1)); 301 __ lwl(v1,
300 __ lwl(v1, 302 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
301 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one)); 303 __ addu(a1, a1, a3);
302 __ addu(a1, a1, a3); 304 __ swr(v1, MemOperand(a0));
303 __ swr(v1, MemOperand(a0)); 305 __ addu(a0, a0, a3);
304 __ addu(a0, a0, a3);
305 } else {
306 __ lwl(v1, MemOperand(a1));
307 __ lwr(v1,
308 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
309 __ addu(a1, a1, a3);
310 __ swl(v1, MemOperand(a0));
311 __ addu(a0, a0, a3);
312 }
313 306
314 // Now the dst (but not the source) is aligned. Set a2 to count how many 307 // Now the dst (but not the source) is aligned. Set a2 to count how many
315 // bytes we have to copy after all the 64 byte chunks are copied and a3 to 308 // bytes we have to copy after all the 64 byte chunks are copied and a3 to
316 // the dst pointer after all the 64 byte chunks have been copied. We will 309 // the dst pointer after all the 64 byte chunks have been copied. We will
317 // loop, incrementing a0 and a1 until a0 equals a3. 310 // loop, incrementing a0 and a1 until a0 equals a3.
318 __ bind(&ua_chk16w); 311 __ bind(&ua_chk16w);
319 __ andi(t8, a2, 0x3f); 312 __ andi(t8, a2, 0x3f);
320 __ beq(a2, t8, &ua_chkw); 313 __ beq(a2, t8, &ua_chkw);
321 __ subu(a3, a2, t8); // In delay slot. 314 __ subu(a3, a2, t8); // In delay slot.
322 __ addu(a3, a0, a3); 315 __ addu(a3, a0, a3);
323 316
324 if (pref_hint_store == kPrefHintPrepareForStore) { 317 if (pref_hint_store == kPrefHintPrepareForStore) {
325 __ addu(t0, a0, a2); 318 __ addu(a4, a0, a2);
326 __ Subu(t9, t0, pref_limit); 319 __ Subu(t9, a4, pref_limit);
327 } 320 }
328 321
329 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk)); 322 __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
330 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk)); 323 __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
331 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk)); 324 __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
332 325
333 if (pref_hint_store != kPrefHintPrepareForStore) { 326 if (pref_hint_store != kPrefHintPrepareForStore) {
334 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk)); 327 __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
335 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk)); 328 __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
336 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk)); 329 __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
337 } 330 }
338 331
339 __ bind(&ua_loop16w); 332 __ bind(&ua_loop16w);
340 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk)); 333 __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
341 if (kArchEndian == kLittle) { 334 __ lwr(a4, MemOperand(a1));
342 __ lwr(t0, MemOperand(a1)); 335 __ lwr(a5, MemOperand(a1, 1, loadstore_chunk));
343 __ lwr(t1, MemOperand(a1, 1, loadstore_chunk)); 336 __ lwr(a6, MemOperand(a1, 2, loadstore_chunk));
344 __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
345 337
346 if (pref_hint_store == kPrefHintPrepareForStore) { 338 if (pref_hint_store == kPrefHintPrepareForStore) {
347 __ sltu(v1, t9, a0); 339 __ sltu(v1, t9, a0);
348 __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg)); 340 __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
349 } 341 }
350 __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot. 342 __ lwr(a7, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
351 343
352 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk)); 344 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
353 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk)); 345 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
354 346
355 __ bind(&ua_skip_pref); 347 __ bind(&ua_skip_pref);
356 __ lwr(t4, MemOperand(a1, 4, loadstore_chunk)); 348 __ lwr(t0, MemOperand(a1, 4, loadstore_chunk));
357 __ lwr(t5, MemOperand(a1, 5, loadstore_chunk)); 349 __ lwr(t1, MemOperand(a1, 5, loadstore_chunk));
358 __ lwr(t6, MemOperand(a1, 6, loadstore_chunk)); 350 __ lwr(t2, MemOperand(a1, 6, loadstore_chunk));
359 __ lwr(t7, MemOperand(a1, 7, loadstore_chunk)); 351 __ lwr(t3, MemOperand(a1, 7, loadstore_chunk));
360 __ lwl(t0, 352 __ lwl(a4,
361 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one)); 353 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
362 __ lwl(t1, 354 __ lwl(a5,
363 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one)); 355 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
364 __ lwl(t2, 356 __ lwl(a6,
365 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one)); 357 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
366 __ lwl(t3, 358 __ lwl(a7,
367 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one)); 359 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
368 __ lwl(t4, 360 __ lwl(t0,
369 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one)); 361 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
370 __ lwl(t5, 362 __ lwl(t1,
371 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one)); 363 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
372 __ lwl(t6, 364 __ lwl(t2,
373 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one)); 365 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
374 __ lwl(t7, 366 __ lwl(t3,
375 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one)); 367 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
376 } else {
377 __ lwl(t0, MemOperand(a1));
378 __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
379 __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
380
381 if (pref_hint_store == kPrefHintPrepareForStore) {
382 __ sltu(v1, t9, a0);
383 __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
384 }
385 __ lwl(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
386
387 __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
388 __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
389
390 __ bind(&ua_skip_pref);
391 __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
392 __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
393 __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
394 __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
395 __ lwr(t0,
396 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
397 __ lwr(t1,
398 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
399 __ lwr(t2,
400 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
401 __ lwr(t3,
402 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
403 __ lwr(t4,
404 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
405 __ lwr(t5,
406 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
407 __ lwr(t6,
408 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
409 __ lwr(t7,
410 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
411 }
412 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk)); 368 __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
413 __ sw(t0, MemOperand(a0)); 369 __ sw(a4, MemOperand(a0));
414 __ sw(t1, MemOperand(a0, 1, loadstore_chunk)); 370 __ sw(a5, MemOperand(a0, 1, loadstore_chunk));
415 __ sw(t2, MemOperand(a0, 2, loadstore_chunk)); 371 __ sw(a6, MemOperand(a0, 2, loadstore_chunk));
416 __ sw(t3, MemOperand(a0, 3, loadstore_chunk)); 372 __ sw(a7, MemOperand(a0, 3, loadstore_chunk));
417 __ sw(t4, MemOperand(a0, 4, loadstore_chunk)); 373 __ sw(t0, MemOperand(a0, 4, loadstore_chunk));
418 __ sw(t5, MemOperand(a0, 5, loadstore_chunk)); 374 __ sw(t1, MemOperand(a0, 5, loadstore_chunk));
419 __ sw(t6, MemOperand(a0, 6, loadstore_chunk)); 375 __ sw(t2, MemOperand(a0, 6, loadstore_chunk));
420 __ sw(t7, MemOperand(a0, 7, loadstore_chunk)); 376 __ sw(t3, MemOperand(a0, 7, loadstore_chunk));
421 if (kArchEndian == kLittle) { 377 __ lwr(a4, MemOperand(a1, 8, loadstore_chunk));
422 __ lwr(t0, MemOperand(a1, 8, loadstore_chunk)); 378 __ lwr(a5, MemOperand(a1, 9, loadstore_chunk));
423 __ lwr(t1, MemOperand(a1, 9, loadstore_chunk)); 379 __ lwr(a6, MemOperand(a1, 10, loadstore_chunk));
424 __ lwr(t2, MemOperand(a1, 10, loadstore_chunk)); 380 __ lwr(a7, MemOperand(a1, 11, loadstore_chunk));
425 __ lwr(t3, MemOperand(a1, 11, loadstore_chunk)); 381 __ lwr(t0, MemOperand(a1, 12, loadstore_chunk));
426 __ lwr(t4, MemOperand(a1, 12, loadstore_chunk)); 382 __ lwr(t1, MemOperand(a1, 13, loadstore_chunk));
427 __ lwr(t5, MemOperand(a1, 13, loadstore_chunk)); 383 __ lwr(t2, MemOperand(a1, 14, loadstore_chunk));
428 __ lwr(t6, MemOperand(a1, 14, loadstore_chunk)); 384 __ lwr(t3, MemOperand(a1, 15, loadstore_chunk));
429 __ lwr(t7, MemOperand(a1, 15, loadstore_chunk)); 385 __ lwl(a4,
430 __ lwl(t0, 386 MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
431 MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one)); 387 __ lwl(a5,
432 __ lwl(t1, 388 MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
433 MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one)); 389 __ lwl(a6,
434 __ lwl(t2, 390 MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
435 MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one)); 391 __ lwl(a7,
436 __ lwl(t3, 392 MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
437 MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one)); 393 __ lwl(t0,
438 __ lwl(t4, 394 MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
439 MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one)); 395 __ lwl(t1,
440 __ lwl(t5, 396 MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
441 MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one)); 397 __ lwl(t2,
442 __ lwl(t6, 398 MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
443 MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one)); 399 __ lwl(t3,
444 __ lwl(t7, 400 MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
445 MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
446 } else {
447 __ lwl(t0, MemOperand(a1, 8, loadstore_chunk));
448 __ lwl(t1, MemOperand(a1, 9, loadstore_chunk));
449 __ lwl(t2, MemOperand(a1, 10, loadstore_chunk));
450 __ lwl(t3, MemOperand(a1, 11, loadstore_chunk));
451 __ lwl(t4, MemOperand(a1, 12, loadstore_chunk));
452 __ lwl(t5, MemOperand(a1, 13, loadstore_chunk));
453 __ lwl(t6, MemOperand(a1, 14, loadstore_chunk));
454 __ lwl(t7, MemOperand(a1, 15, loadstore_chunk));
455 __ lwr(t0,
456 MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
457 __ lwr(t1,
458 MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
459 __ lwr(t2,
460 MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
461 __ lwr(t3,
462 MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
463 __ lwr(t4,
464 MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
465 __ lwr(t5,
466 MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
467 __ lwr(t6,
468 MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
469 __ lwr(t7,
470 MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
471 }
472 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk)); 401 __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
473 __ sw(t0, MemOperand(a0, 8, loadstore_chunk)); 402 __ sw(a4, MemOperand(a0, 8, loadstore_chunk));
474 __ sw(t1, MemOperand(a0, 9, loadstore_chunk)); 403 __ sw(a5, MemOperand(a0, 9, loadstore_chunk));
475 __ sw(t2, MemOperand(a0, 10, loadstore_chunk)); 404 __ sw(a6, MemOperand(a0, 10, loadstore_chunk));
476 __ sw(t3, MemOperand(a0, 11, loadstore_chunk)); 405 __ sw(a7, MemOperand(a0, 11, loadstore_chunk));
477 __ sw(t4, MemOperand(a0, 12, loadstore_chunk)); 406 __ sw(t0, MemOperand(a0, 12, loadstore_chunk));
478 __ sw(t5, MemOperand(a0, 13, loadstore_chunk)); 407 __ sw(t1, MemOperand(a0, 13, loadstore_chunk));
479 __ sw(t6, MemOperand(a0, 14, loadstore_chunk)); 408 __ sw(t2, MemOperand(a0, 14, loadstore_chunk));
480 __ sw(t7, MemOperand(a0, 15, loadstore_chunk)); 409 __ sw(t3, MemOperand(a0, 15, loadstore_chunk));
481 __ addiu(a0, a0, 16 * loadstore_chunk); 410 __ addiu(a0, a0, 16 * loadstore_chunk);
482 __ bne(a0, a3, &ua_loop16w); 411 __ bne(a0, a3, &ua_loop16w);
483 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot. 412 __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
484 __ mov(a2, t8); 413 __ mov(a2, t8);
485 414
486 // Here less than 64-bytes. Check for 415 // Here less than 64-bytes. Check for
487 // a 32 byte chunk and copy if there is one. Otherwise jump down to 416 // a 32 byte chunk and copy if there is one. Otherwise jump down to
488 // ua_chk1w to handle the tail end of the copy. 417 // ua_chk1w to handle the tail end of the copy.
489 __ bind(&ua_chkw); 418 __ bind(&ua_chkw);
490 __ Pref(pref_hint_load, MemOperand(a1)); 419 __ Pref(pref_hint_load, MemOperand(a1));
491 __ andi(t8, a2, 0x1f); 420 __ andi(t8, a2, 0x1f);
492 421
493 __ beq(a2, t8, &ua_chk1w); 422 __ beq(a2, t8, &ua_chk1w);
494 __ nop(); // In delay slot. 423 __ nop(); // In delay slot.
495 if (kArchEndian == kLittle) { 424 __ lwr(a4, MemOperand(a1));
496 __ lwr(t0, MemOperand(a1)); 425 __ lwr(a5, MemOperand(a1, 1, loadstore_chunk));
497 __ lwr(t1, MemOperand(a1, 1, loadstore_chunk)); 426 __ lwr(a6, MemOperand(a1, 2, loadstore_chunk));
498 __ lwr(t2, MemOperand(a1, 2, loadstore_chunk)); 427 __ lwr(a7, MemOperand(a1, 3, loadstore_chunk));
499 __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); 428 __ lwr(t0, MemOperand(a1, 4, loadstore_chunk));
500 __ lwr(t4, MemOperand(a1, 4, loadstore_chunk)); 429 __ lwr(t1, MemOperand(a1, 5, loadstore_chunk));
501 __ lwr(t5, MemOperand(a1, 5, loadstore_chunk)); 430 __ lwr(t2, MemOperand(a1, 6, loadstore_chunk));
502 __ lwr(t6, MemOperand(a1, 6, loadstore_chunk)); 431 __ lwr(t3, MemOperand(a1, 7, loadstore_chunk));
503 __ lwr(t7, MemOperand(a1, 7, loadstore_chunk)); 432 __ lwl(a4,
504 __ lwl(t0, 433 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
505 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one)); 434 __ lwl(a5,
506 __ lwl(t1, 435 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
507 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one)); 436 __ lwl(a6,
508 __ lwl(t2, 437 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
509 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one)); 438 __ lwl(a7,
510 __ lwl(t3, 439 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
511 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one)); 440 __ lwl(t0,
512 __ lwl(t4, 441 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
513 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one)); 442 __ lwl(t1,
514 __ lwl(t5, 443 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
515 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one)); 444 __ lwl(t2,
516 __ lwl(t6, 445 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
517 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one)); 446 __ lwl(t3,
518 __ lwl(t7, 447 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
519 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
520 } else {
521 __ lwl(t0, MemOperand(a1));
522 __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
523 __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
524 __ lwl(t3, MemOperand(a1, 3, loadstore_chunk));
525 __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
526 __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
527 __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
528 __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
529 __ lwr(t0,
530 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
531 __ lwr(t1,
532 MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
533 __ lwr(t2,
534 MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
535 __ lwr(t3,
536 MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
537 __ lwr(t4,
538 MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
539 __ lwr(t5,
540 MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
541 __ lwr(t6,
542 MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
543 __ lwr(t7,
544 MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
545 }
546 __ addiu(a1, a1, 8 * loadstore_chunk); 448 __ addiu(a1, a1, 8 * loadstore_chunk);
547 __ sw(t0, MemOperand(a0)); 449 __ sw(a4, MemOperand(a0));
548 __ sw(t1, MemOperand(a0, 1, loadstore_chunk)); 450 __ sw(a5, MemOperand(a0, 1, loadstore_chunk));
549 __ sw(t2, MemOperand(a0, 2, loadstore_chunk)); 451 __ sw(a6, MemOperand(a0, 2, loadstore_chunk));
550 __ sw(t3, MemOperand(a0, 3, loadstore_chunk)); 452 __ sw(a7, MemOperand(a0, 3, loadstore_chunk));
551 __ sw(t4, MemOperand(a0, 4, loadstore_chunk)); 453 __ sw(t0, MemOperand(a0, 4, loadstore_chunk));
552 __ sw(t5, MemOperand(a0, 5, loadstore_chunk)); 454 __ sw(t1, MemOperand(a0, 5, loadstore_chunk));
553 __ sw(t6, MemOperand(a0, 6, loadstore_chunk)); 455 __ sw(t2, MemOperand(a0, 6, loadstore_chunk));
554 __ sw(t7, MemOperand(a0, 7, loadstore_chunk)); 456 __ sw(t3, MemOperand(a0, 7, loadstore_chunk));
555 __ addiu(a0, a0, 8 * loadstore_chunk); 457 __ addiu(a0, a0, 8 * loadstore_chunk);
556 458
557 // Less than 32 bytes to copy. Set up for a loop to 459 // Less than 32 bytes to copy. Set up for a loop to
558 // copy one word at a time. 460 // copy one word at a time.
559 __ bind(&ua_chk1w); 461 __ bind(&ua_chk1w);
560 __ andi(a2, t8, loadstore_chunk - 1); 462 __ andi(a2, t8, loadstore_chunk - 1);
561 __ beq(a2, t8, &ua_smallCopy); 463 __ beq(a2, t8, &ua_smallCopy);
562 __ subu(a3, t8, a2); // In delay slot. 464 __ subu(a3, t8, a2); // In delay slot.
563 __ addu(a3, a0, a3); 465 __ addu(a3, a0, a3);
564 466
565 __ bind(&ua_wordCopy_loop); 467 __ bind(&ua_wordCopy_loop);
566 if (kArchEndian == kLittle) { 468 __ lwr(v1, MemOperand(a1));
567 __ lwr(v1, MemOperand(a1)); 469 __ lwl(v1,
568 __ lwl(v1, 470 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
569 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
570 } else {
571 __ lwl(v1, MemOperand(a1));
572 __ lwr(v1,
573 MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
574 }
575 __ addiu(a0, a0, loadstore_chunk); 471 __ addiu(a0, a0, loadstore_chunk);
576 __ addiu(a1, a1, loadstore_chunk); 472 __ addiu(a1, a1, loadstore_chunk);
577 __ bne(a0, a3, &ua_wordCopy_loop); 473 __ bne(a0, a3, &ua_wordCopy_loop);
578 __ sw(v1, MemOperand(a0, -1, loadstore_chunk)); // In delay slot. 474 __ sw(v1, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
579 475
580 // Copy the last 8 bytes. 476 // Copy the last 8 bytes.
581 __ bind(&ua_smallCopy); 477 __ bind(&ua_smallCopy);
582 __ beq(a2, zero_reg, &leave); 478 __ beq(a2, zero_reg, &leave);
583 __ addu(a3, a0, a2); // In delay slot. 479 __ addu(a3, a0, a2); // In delay slot.
584 480
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 552
657 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 553 void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
658 MacroAssembler* masm, AllocationSiteMode mode, 554 MacroAssembler* masm, AllocationSiteMode mode,
659 Label* allocation_memento_found) { 555 Label* allocation_memento_found) {
660 // ----------- S t a t e ------------- 556 // ----------- S t a t e -------------
661 // -- a0 : value 557 // -- a0 : value
662 // -- a1 : key 558 // -- a1 : key
663 // -- a2 : receiver 559 // -- a2 : receiver
664 // -- ra : return address 560 // -- ra : return address
665 // -- a3 : target map, scratch for subsequent call 561 // -- a3 : target map, scratch for subsequent call
666 // -- t0 : scratch (elements) 562 // -- a4 : scratch (elements)
667 // ----------------------------------- 563 // -----------------------------------
668 if (mode == TRACK_ALLOCATION_SITE) { 564 if (mode == TRACK_ALLOCATION_SITE) {
669 ASSERT(allocation_memento_found != NULL); 565 ASSERT(allocation_memento_found != NULL);
670 __ JumpIfJSArrayHasAllocationMemento(a2, t0, allocation_memento_found); 566 __ JumpIfJSArrayHasAllocationMemento(a2, a4, allocation_memento_found);
671 } 567 }
672 568
673 // Set transitioned map. 569 // Set transitioned map.
674 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 570 __ sd(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
675 __ RecordWriteField(a2, 571 __ RecordWriteField(a2,
676 HeapObject::kMapOffset, 572 HeapObject::kMapOffset,
677 a3, 573 a3,
678 t5, 574 t1,
679 kRAHasNotBeenSaved, 575 kRAHasNotBeenSaved,
680 kDontSaveFPRegs, 576 kDontSaveFPRegs,
681 EMIT_REMEMBERED_SET, 577 EMIT_REMEMBERED_SET,
682 OMIT_SMI_CHECK); 578 OMIT_SMI_CHECK);
683 } 579 }
684 580
685 581
686 void ElementsTransitionGenerator::GenerateSmiToDouble( 582 void ElementsTransitionGenerator::GenerateSmiToDouble(
687 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { 583 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
688 // ----------- S t a t e ------------- 584 // ----------- S t a t e -------------
689 // -- a0 : value 585 // -- a0 : value
690 // -- a1 : key 586 // -- a1 : key
691 // -- a2 : receiver 587 // -- a2 : receiver
692 // -- ra : return address 588 // -- ra : return address
693 // -- a3 : target map, scratch for subsequent call 589 // -- a3 : target map, scratch for subsequent call
694 // -- t0 : scratch (elements) 590 // -- a4 : scratch (elements)
695 // ----------------------------------- 591 // -----------------------------------
696 Label loop, entry, convert_hole, gc_required, only_change_map, done; 592 Label loop, entry, convert_hole, gc_required, only_change_map, done;
697 593
698 Register scratch = t6; 594 Register scratch = t2;
699
700 if (mode == TRACK_ALLOCATION_SITE) { 595 if (mode == TRACK_ALLOCATION_SITE) {
701 __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail); 596 __ JumpIfJSArrayHasAllocationMemento(a2, a4, fail);
702 } 597 }
703 598
704 // Check for empty arrays, which only require a map transition and no changes 599 // Check for empty arrays, which only require a map transition and no changes
705 // to the backing store. 600 // to the backing store.
706 __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); 601 __ ld(a4, FieldMemOperand(a2, JSObject::kElementsOffset));
707 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); 602 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
708 __ Branch(&only_change_map, eq, at, Operand(t0)); 603 __ Branch(&only_change_map, eq, at, Operand(a4));
709 604
710 __ push(ra); 605 __ push(ra);
711 __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); 606 __ ld(a5, FieldMemOperand(a4, FixedArray::kLengthOffset));
712 // t0: source FixedArray 607 // a4: source FixedArray
713 // t1: number of elements (smi-tagged) 608 // a5: number of elements (smi-tagged)
714 609
715 // Allocate new FixedDoubleArray. 610 // Allocate new FixedDoubleArray.
716 __ sll(scratch, t1, 2); 611 __ SmiScale(scratch, a5, kDoubleSizeLog2);
717 __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize); 612 __ Daddu(scratch, scratch, FixedDoubleArray::kHeaderSize);
718 __ Allocate(scratch, t2, t3, t5, &gc_required, DOUBLE_ALIGNMENT); 613 __ Allocate(scratch, a6, a7, t1, &gc_required, DOUBLE_ALIGNMENT);
719 // t2: destination FixedDoubleArray, not tagged as heap object 614 // a6: destination FixedDoubleArray, not tagged as heap object
720 615
721 // Set destination FixedDoubleArray's length and map. 616 // Set destination FixedDoubleArray's length and map.
722 __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex); 617 __ LoadRoot(t1, Heap::kFixedDoubleArrayMapRootIndex);
723 __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); 618 __ sd(a5, MemOperand(a6, FixedDoubleArray::kLengthOffset));
724 __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); 619 __ sd(t1, MemOperand(a6, HeapObject::kMapOffset));
725 // Update receiver's map. 620 // Update receiver's map.
726 621
727 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 622 __ sd(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
728 __ RecordWriteField(a2, 623 __ RecordWriteField(a2,
729 HeapObject::kMapOffset, 624 HeapObject::kMapOffset,
730 a3, 625 a3,
731 t5, 626 t1,
732 kRAHasBeenSaved, 627 kRAHasBeenSaved,
733 kDontSaveFPRegs, 628 kDontSaveFPRegs,
734 OMIT_REMEMBERED_SET, 629 OMIT_REMEMBERED_SET,
735 OMIT_SMI_CHECK); 630 OMIT_SMI_CHECK);
736 // Replace receiver's backing store with newly created FixedDoubleArray. 631 // Replace receiver's backing store with newly created FixedDoubleArray.
737 __ Addu(a3, t2, Operand(kHeapObjectTag)); 632 __ Daddu(a3, a6, Operand(kHeapObjectTag));
738 __ sw(a3, FieldMemOperand(a2, JSObject::kElementsOffset)); 633 __ sd(a3, FieldMemOperand(a2, JSObject::kElementsOffset));
739 __ RecordWriteField(a2, 634 __ RecordWriteField(a2,
740 JSObject::kElementsOffset, 635 JSObject::kElementsOffset,
741 a3, 636 a3,
742 t5, 637 t1,
743 kRAHasBeenSaved, 638 kRAHasBeenSaved,
744 kDontSaveFPRegs, 639 kDontSaveFPRegs,
745 EMIT_REMEMBERED_SET, 640 EMIT_REMEMBERED_SET,
746 OMIT_SMI_CHECK); 641 OMIT_SMI_CHECK);
747 642
748 643
749 // Prepare for conversion loop. 644 // Prepare for conversion loop.
750 __ Addu(a3, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 645 __ Daddu(a3, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
751 __ Addu(t3, t2, Operand(FixedDoubleArray::kHeaderSize)); 646 __ Daddu(a7, a6, Operand(FixedDoubleArray::kHeaderSize));
752 __ sll(t2, t1, 2); 647 __ SmiScale(a6, a5, kDoubleSizeLog2);
753 __ Addu(t2, t2, t3); 648 __ Daddu(a6, a6, a7);
754 __ li(t0, Operand(kHoleNanLower32)); 649 __ li(a4, Operand(kHoleNanLower32));
755 __ li(t1, Operand(kHoleNanUpper32)); 650 __ li(a5, Operand(kHoleNanUpper32));
756 // t0: kHoleNanLower32 651 // a4: kHoleNanLower32
757 // t1: kHoleNanUpper32 652 // a5: kHoleNanUpper32
758 // t2: end of destination FixedDoubleArray, not tagged 653 // a6: end of destination FixedDoubleArray, not tagged
759 // t3: begin of FixedDoubleArray element fields, not tagged 654 // a7: begin of FixedDoubleArray element fields, not tagged
760 655
761 __ Branch(&entry); 656 __ Branch(&entry);
762 657
763 __ bind(&only_change_map); 658 __ bind(&only_change_map);
764 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 659 __ sd(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
765 __ RecordWriteField(a2, 660 __ RecordWriteField(a2,
766 HeapObject::kMapOffset, 661 HeapObject::kMapOffset,
767 a3, 662 a3,
768 t5, 663 t1,
769 kRAHasNotBeenSaved, 664 kRAHasNotBeenSaved,
770 kDontSaveFPRegs, 665 kDontSaveFPRegs,
771 OMIT_REMEMBERED_SET, 666 OMIT_REMEMBERED_SET,
772 OMIT_SMI_CHECK); 667 OMIT_SMI_CHECK);
773 __ Branch(&done); 668 __ Branch(&done);
774 669
775 // Call into runtime if GC is required. 670 // Call into runtime if GC is required.
776 __ bind(&gc_required); 671 __ bind(&gc_required);
777 __ pop(ra); 672 __ pop(ra);
778 __ Branch(fail); 673 __ Branch(fail);
779 674
780 // Convert and copy elements. 675 // Convert and copy elements.
781 __ bind(&loop); 676 __ bind(&loop);
782 __ lw(t5, MemOperand(a3)); 677 __ ld(t1, MemOperand(a3));
783 __ Addu(a3, a3, kIntSize); 678 __ Daddu(a3, a3, kIntSize);
784 // t5: current element 679 // t1: current element
785 __ UntagAndJumpIfNotSmi(t5, t5, &convert_hole); 680 __ JumpIfNotSmi(t1, &convert_hole);
681 __ SmiUntag(t1);
786 682
787 // Normal smi, convert to double and store. 683 // Normal smi, convert to double and store.
788 __ mtc1(t5, f0); 684 __ mtc1(t1, f0);
789 __ cvt_d_w(f0, f0); 685 __ cvt_d_w(f0, f0);
790 __ sdc1(f0, MemOperand(t3)); 686 __ sdc1(f0, MemOperand(a7));
791 __ Addu(t3, t3, kDoubleSize); 687 __ Daddu(a7, a7, kDoubleSize);
792 688
793 __ Branch(&entry); 689 __ Branch(&entry);
794 690
795 // Hole found, store the-hole NaN. 691 // Hole found, store the-hole NaN.
796 __ bind(&convert_hole); 692 __ bind(&convert_hole);
797 if (FLAG_debug_code) { 693 if (FLAG_debug_code) {
798 // Restore a "smi-untagged" heap object. 694 // Restore a "smi-untagged" heap object.
799 __ SmiTag(t5); 695 __ Or(t1, t1, Operand(1));
800 __ Or(t5, t5, Operand(1));
801 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 696 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
802 __ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t5)); 697 __ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t1));
803 } 698 }
804 __ sw(t0, MemOperand(t3, Register::kMantissaOffset)); // mantissa 699 __ sw(a4, MemOperand(a7)); // mantissa
805 __ sw(t1, MemOperand(t3, Register::kExponentOffset)); // exponent 700 __ sw(a5, MemOperand(a7, kIntSize)); // exponent
806 __ Addu(t3, t3, kDoubleSize); 701 __ Daddu(a7, a7, kDoubleSize);
807 702
808 __ bind(&entry); 703 __ bind(&entry);
809 __ Branch(&loop, lt, t3, Operand(t2)); 704 __ Branch(&loop, lt, a7, Operand(a6));
810 705
811 __ pop(ra); 706 __ pop(ra);
812 __ bind(&done); 707 __ bind(&done);
813 } 708 }
814 709
815 710
816 void ElementsTransitionGenerator::GenerateDoubleToObject( 711 void ElementsTransitionGenerator::GenerateDoubleToObject(
817 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { 712 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
818 // ----------- S t a t e ------------- 713 // ----------- S t a t e -------------
819 // -- a0 : value 714 // -- a0 : value
820 // -- a1 : key 715 // -- a1 : key
821 // -- a2 : receiver 716 // -- a2 : receiver
822 // -- ra : return address 717 // -- ra : return address
823 // -- a3 : target map, scratch for subsequent call 718 // -- a3 : target map, scratch for subsequent call
824 // -- t0 : scratch (elements) 719 // -- a4 : scratch (elements)
825 // ----------------------------------- 720 // -----------------------------------
826 Label entry, loop, convert_hole, gc_required, only_change_map; 721 Label entry, loop, convert_hole, gc_required, only_change_map;
827
828 if (mode == TRACK_ALLOCATION_SITE) { 722 if (mode == TRACK_ALLOCATION_SITE) {
829 __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail); 723 __ JumpIfJSArrayHasAllocationMemento(a2, a4, fail);
830 } 724 }
831 725
832 // Check for empty arrays, which only require a map transition and no changes 726 // Check for empty arrays, which only require a map transition and no changes
833 // to the backing store. 727 // to the backing store.
834 __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); 728 __ ld(a4, FieldMemOperand(a2, JSObject::kElementsOffset));
835 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); 729 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
836 __ Branch(&only_change_map, eq, at, Operand(t0)); 730 __ Branch(&only_change_map, eq, at, Operand(a4));
837 731
838 __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); 732 __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
839 733
840 __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); 734 __ ld(a5, FieldMemOperand(a4, FixedArray::kLengthOffset));
841 // t0: source FixedArray 735 // a4: source FixedArray
842 // t1: number of elements (smi-tagged) 736 // a5: number of elements (smi-tagged)
843 737
844 // Allocate new FixedArray. 738 // Allocate new FixedArray.
845 __ sll(a0, t1, 1); 739 __ SmiScale(a0, a5, kPointerSizeLog2);
846 __ Addu(a0, a0, FixedDoubleArray::kHeaderSize); 740 __ Daddu(a0, a0, FixedDoubleArray::kHeaderSize);
847 __ Allocate(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS); 741 __ Allocate(a0, a6, a7, t1, &gc_required, NO_ALLOCATION_FLAGS);
848 // t2: destination FixedArray, not tagged as heap object 742 // a6: destination FixedArray, not tagged as heap object
849 // Set destination FixedDoubleArray's length and map. 743 // Set destination FixedDoubleArray's length and map.
850 __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex); 744 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
851 __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); 745 __ sd(a5, MemOperand(a6, FixedDoubleArray::kLengthOffset));
852 __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); 746 __ sd(t1, MemOperand(a6, HeapObject::kMapOffset));
853 747
854 // Prepare for conversion loop. 748 // Prepare for conversion loop.
855 __ Addu(t0, t0, Operand( 749 __ Daddu(a4, a4, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
856 FixedDoubleArray::kHeaderSize - kHeapObjectTag 750 __ Daddu(a3, a6, Operand(FixedArray::kHeaderSize));
857 + Register::kExponentOffset)); 751 __ Daddu(a6, a6, Operand(kHeapObjectTag));
858 __ Addu(a3, t2, Operand(FixedArray::kHeaderSize)); 752 __ SmiScale(a5, a5, kPointerSizeLog2);
859 __ Addu(t2, t2, Operand(kHeapObjectTag)); 753 __ Daddu(a5, a3, a5);
860 __ sll(t1, t1, 1); 754 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex);
861 __ Addu(t1, a3, t1); 755 __ LoadRoot(t1, Heap::kHeapNumberMapRootIndex);
862 __ LoadRoot(t3, Heap::kTheHoleValueRootIndex);
863 __ LoadRoot(t5, Heap::kHeapNumberMapRootIndex);
864 // Using offsetted addresses. 756 // Using offsetted addresses.
865 // a3: begin of destination FixedArray element fields, not tagged 757 // a3: begin of destination FixedArray element fields, not tagged
866 // t0: begin of source FixedDoubleArray element fields, not tagged, 758 // a4: begin of source FixedDoubleArray element fields, not tagged, +4
867 // points to the exponent 759 // a5: end of destination FixedArray, not tagged
868 // t1: end of destination FixedArray, not tagged 760 // a6: destination FixedArray
869 // t2: destination FixedArray 761 // a7: the-hole pointer
870 // t3: the-hole pointer 762 // t1: heap number map
871 // t5: heap number map
872 __ Branch(&entry); 763 __ Branch(&entry);
873 764
874 // Call into runtime if GC is required. 765 // Call into runtime if GC is required.
875 __ bind(&gc_required); 766 __ bind(&gc_required);
876 __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); 767 __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
877 768
878 __ Branch(fail); 769 __ Branch(fail);
879 770
880 __ bind(&loop); 771 __ bind(&loop);
881 __ lw(a1, MemOperand(t0)); 772 __ lw(a1, MemOperand(a4));
882 __ Addu(t0, t0, kDoubleSize); 773 __ Daddu(a4, a4, kDoubleSize);
883 // a1: current element's upper 32 bit 774 // a1: current element's upper 32 bit
884 // t0: address of next element's upper 32 bit 775 // a4: address of next element's upper 32 bit
885 __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32)); 776 __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32));
886 777
887 // Non-hole double, copy value into a heap number. 778 // Non-hole double, copy value into a heap number.
888 __ AllocateHeapNumber(a2, a0, t6, t5, &gc_required); 779 __ AllocateHeapNumber(a2, a0, t2, t1, &gc_required);
889 // a2: new heap number 780 // a2: new heap number
890 // Load mantissa of current element, t0 point to exponent of next element. 781 __ lw(a0, MemOperand(a4, -12));
891 __ lw(a0, MemOperand(t0, (Register::kMantissaOffset
892 - Register::kExponentOffset - kDoubleSize)));
893 __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset)); 782 __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset));
894 __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset)); 783 __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset));
895 __ mov(a0, a3); 784 __ mov(a0, a3);
896 __ sw(a2, MemOperand(a3)); 785 __ sd(a2, MemOperand(a3));
897 __ Addu(a3, a3, kIntSize); 786 __ Daddu(a3, a3, kPointerSize);
898 __ RecordWrite(t2, 787 __ RecordWrite(a6,
899 a0, 788 a0,
900 a2, 789 a2,
901 kRAHasBeenSaved, 790 kRAHasBeenSaved,
902 kDontSaveFPRegs, 791 kDontSaveFPRegs,
903 EMIT_REMEMBERED_SET, 792 EMIT_REMEMBERED_SET,
904 OMIT_SMI_CHECK); 793 OMIT_SMI_CHECK);
905 __ Branch(&entry); 794 __ Branch(&entry);
906 795
907 // Replace the-hole NaN with the-hole pointer. 796 // Replace the-hole NaN with the-hole pointer.
908 __ bind(&convert_hole); 797 __ bind(&convert_hole);
909 __ sw(t3, MemOperand(a3)); 798 __ sd(a7, MemOperand(a3));
910 __ Addu(a3, a3, kIntSize); 799 __ Daddu(a3, a3, kPointerSize);
911 800
912 __ bind(&entry); 801 __ bind(&entry);
913 __ Branch(&loop, lt, a3, Operand(t1)); 802 __ Branch(&loop, lt, a3, Operand(a5));
914 803
915 __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit()); 804 __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit());
916 // Replace receiver's backing store with newly created and filled FixedArray. 805 // Replace receiver's backing store with newly created and filled FixedArray.
917 __ sw(t2, FieldMemOperand(a2, JSObject::kElementsOffset)); 806 __ sd(a6, FieldMemOperand(a2, JSObject::kElementsOffset));
918 __ RecordWriteField(a2, 807 __ RecordWriteField(a2,
919 JSObject::kElementsOffset, 808 JSObject::kElementsOffset,
920 t2, 809 a6,
921 t5, 810 t1,
922 kRAHasBeenSaved, 811 kRAHasBeenSaved,
923 kDontSaveFPRegs, 812 kDontSaveFPRegs,
924 EMIT_REMEMBERED_SET, 813 EMIT_REMEMBERED_SET,
925 OMIT_SMI_CHECK); 814 OMIT_SMI_CHECK);
926 __ pop(ra); 815 __ pop(ra);
927 816
928 __ bind(&only_change_map); 817 __ bind(&only_change_map);
929 // Update receiver's map. 818 // Update receiver's map.
930 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 819 __ sd(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
931 __ RecordWriteField(a2, 820 __ RecordWriteField(a2,
932 HeapObject::kMapOffset, 821 HeapObject::kMapOffset,
933 a3, 822 a3,
934 t5, 823 t1,
935 kRAHasNotBeenSaved, 824 kRAHasNotBeenSaved,
936 kDontSaveFPRegs, 825 kDontSaveFPRegs,
937 OMIT_REMEMBERED_SET, 826 OMIT_REMEMBERED_SET,
938 OMIT_SMI_CHECK); 827 OMIT_SMI_CHECK);
939 } 828 }
940 829
941 830
942 void StringCharLoadGenerator::Generate(MacroAssembler* masm, 831 void StringCharLoadGenerator::Generate(MacroAssembler* masm,
943 Register string, 832 Register string,
944 Register index, 833 Register index,
945 Register result, 834 Register result,
946 Label* call_runtime) { 835 Label* call_runtime) {
947 // Fetch the instance type of the receiver into result register. 836 // Fetch the instance type of the receiver into result register.
948 __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); 837 __ ld(result, FieldMemOperand(string, HeapObject::kMapOffset));
949 __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); 838 __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
950 839
951 // We need special handling for indirect strings. 840 // We need special handling for indirect strings.
952 Label check_sequential; 841 Label check_sequential;
953 __ And(at, result, Operand(kIsIndirectStringMask)); 842 __ And(at, result, Operand(kIsIndirectStringMask));
954 __ Branch(&check_sequential, eq, at, Operand(zero_reg)); 843 __ Branch(&check_sequential, eq, at, Operand(zero_reg));
955 844
956 // Dispatch on the indirect string shape: slice or cons. 845 // Dispatch on the indirect string shape: slice or cons.
957 Label cons_string; 846 Label cons_string;
958 __ And(at, result, Operand(kSlicedNotConsMask)); 847 __ And(at, result, Operand(kSlicedNotConsMask));
959 __ Branch(&cons_string, eq, at, Operand(zero_reg)); 848 __ Branch(&cons_string, eq, at, Operand(zero_reg));
960 849
961 // Handle slices. 850 // Handle slices.
962 Label indirect_string_loaded; 851 Label indirect_string_loaded;
963 __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); 852 __ ld(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
964 __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset)); 853 __ ld(string, FieldMemOperand(string, SlicedString::kParentOffset));
965 __ sra(at, result, kSmiTagSize); 854 __ dsra32(at, result, 0);
966 __ Addu(index, index, at); 855 __ Daddu(index, index, at);
967 __ jmp(&indirect_string_loaded); 856 __ jmp(&indirect_string_loaded);
968 857
969 // Handle cons strings. 858 // Handle cons strings.
970 // Check whether the right hand side is the empty string (i.e. if 859 // Check whether the right hand side is the empty string (i.e. if
971 // this is really a flat string in a cons string). If that is not 860 // this is really a flat string in a cons string). If that is not
972 // the case we would rather go to the runtime system now to flatten 861 // the case we would rather go to the runtime system now to flatten
973 // the string. 862 // the string.
974 __ bind(&cons_string); 863 __ bind(&cons_string);
975 __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset)); 864 __ ld(result, FieldMemOperand(string, ConsString::kSecondOffset));
976 __ LoadRoot(at, Heap::kempty_stringRootIndex); 865 __ LoadRoot(at, Heap::kempty_stringRootIndex);
977 __ Branch(call_runtime, ne, result, Operand(at)); 866 __ Branch(call_runtime, ne, result, Operand(at));
978 // Get the first of the two strings and load its instance type. 867 // Get the first of the two strings and load its instance type.
979 __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset)); 868 __ ld(string, FieldMemOperand(string, ConsString::kFirstOffset));
980 869
981 __ bind(&indirect_string_loaded); 870 __ bind(&indirect_string_loaded);
982 __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); 871 __ ld(result, FieldMemOperand(string, HeapObject::kMapOffset));
983 __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); 872 __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
984 873
985 // Distinguish sequential and external strings. Only these two string 874 // Distinguish sequential and external strings. Only these two string
986 // representations can reach here (slices and flat cons strings have been 875 // representations can reach here (slices and flat cons strings have been
987 // reduced to the underlying sequential or external string). 876 // reduced to the underlying sequential or external string).
988 Label external_string, check_encoding; 877 Label external_string, check_encoding;
989 __ bind(&check_sequential); 878 __ bind(&check_sequential);
990 STATIC_ASSERT(kSeqStringTag == 0); 879 STATIC_ASSERT(kSeqStringTag == 0);
991 __ And(at, result, Operand(kStringRepresentationMask)); 880 __ And(at, result, Operand(kStringRepresentationMask));
992 __ Branch(&external_string, ne, at, Operand(zero_reg)); 881 __ Branch(&external_string, ne, at, Operand(zero_reg));
993 882
994 // Prepare sequential strings 883 // Prepare sequential strings
995 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 884 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
996 __ Addu(string, 885 __ Daddu(string,
997 string, 886 string,
998 SeqTwoByteString::kHeaderSize - kHeapObjectTag); 887 SeqTwoByteString::kHeaderSize - kHeapObjectTag);
999 __ jmp(&check_encoding); 888 __ jmp(&check_encoding);
1000 889
1001 // Handle external strings. 890 // Handle external strings.
1002 __ bind(&external_string); 891 __ bind(&external_string);
1003 if (FLAG_debug_code) { 892 if (FLAG_debug_code) {
1004 // Assert that we do not have a cons or slice (indirect strings) here. 893 // Assert that we do not have a cons or slice (indirect strings) here.
1005 // Sequential strings have already been ruled out. 894 // Sequential strings have already been ruled out.
1006 __ And(at, result, Operand(kIsIndirectStringMask)); 895 __ And(at, result, Operand(kIsIndirectStringMask));
1007 __ Assert(eq, kExternalStringExpectedButNotFound, 896 __ Assert(eq, kExternalStringExpectedButNotFound,
1008 at, Operand(zero_reg)); 897 at, Operand(zero_reg));
1009 } 898 }
1010 // Rule out short external strings. 899 // Rule out short external strings.
1011 STATIC_ASSERT(kShortExternalStringTag != 0); 900 STATIC_ASSERT(kShortExternalStringTag != 0);
1012 __ And(at, result, Operand(kShortExternalStringMask)); 901 __ And(at, result, Operand(kShortExternalStringMask));
1013 __ Branch(call_runtime, ne, at, Operand(zero_reg)); 902 __ Branch(call_runtime, ne, at, Operand(zero_reg));
1014 __ lw(string, FieldMemOperand(string, ExternalString::kResourceDataOffset)); 903 __ ld(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
1015 904
1016 Label ascii, done; 905 Label ascii, done;
1017 __ bind(&check_encoding); 906 __ bind(&check_encoding);
1018 STATIC_ASSERT(kTwoByteStringTag == 0); 907 STATIC_ASSERT(kTwoByteStringTag == 0);
1019 __ And(at, result, Operand(kStringEncodingMask)); 908 __ And(at, result, Operand(kStringEncodingMask));
1020 __ Branch(&ascii, ne, at, Operand(zero_reg)); 909 __ Branch(&ascii, ne, at, Operand(zero_reg));
1021 // Two-byte string. 910 // Two-byte string.
1022 __ sll(at, index, 1); 911 __ dsll(at, index, 1);
1023 __ Addu(at, string, at); 912 __ Daddu(at, string, at);
1024 __ lhu(result, MemOperand(at)); 913 __ lhu(result, MemOperand(at));
1025 __ jmp(&done); 914 __ jmp(&done);
1026 __ bind(&ascii); 915 __ bind(&ascii);
1027 // Ascii string. 916 // Ascii string.
1028 __ Addu(at, string, index); 917 __ Daddu(at, string, index);
1029 __ lbu(result, MemOperand(at)); 918 __ lbu(result, MemOperand(at));
1030 __ bind(&done); 919 __ bind(&done);
1031 } 920 }
1032 921
1033 922
1034 static MemOperand ExpConstant(int index, Register base) { 923 static MemOperand ExpConstant(int index, Register base) {
1035 return MemOperand(base, index * kDoubleSize); 924 return MemOperand(base, index * kDoubleSize);
1036 } 925 }
1037 926
1038 927
(...skipping 10 matching lines...) Expand all
1049 ASSERT(!input.is(double_scratch2)); 938 ASSERT(!input.is(double_scratch2));
1050 ASSERT(!result.is(double_scratch1)); 939 ASSERT(!result.is(double_scratch1));
1051 ASSERT(!result.is(double_scratch2)); 940 ASSERT(!result.is(double_scratch2));
1052 ASSERT(!double_scratch1.is(double_scratch2)); 941 ASSERT(!double_scratch1.is(double_scratch2));
1053 ASSERT(!temp1.is(temp2)); 942 ASSERT(!temp1.is(temp2));
1054 ASSERT(!temp1.is(temp3)); 943 ASSERT(!temp1.is(temp3));
1055 ASSERT(!temp2.is(temp3)); 944 ASSERT(!temp2.is(temp3));
1056 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL); 945 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
1057 946
1058 Label zero, infinity, done; 947 Label zero, infinity, done;
1059
1060 __ li(temp3, Operand(ExternalReference::math_exp_constants(0))); 948 __ li(temp3, Operand(ExternalReference::math_exp_constants(0)));
1061 949
1062 __ ldc1(double_scratch1, ExpConstant(0, temp3)); 950 __ ldc1(double_scratch1, ExpConstant(0, temp3));
1063 __ BranchF(&zero, NULL, ge, double_scratch1, input); 951 __ BranchF(&zero, NULL, ge, double_scratch1, input);
1064 952
1065 __ ldc1(double_scratch2, ExpConstant(1, temp3)); 953 __ ldc1(double_scratch2, ExpConstant(1, temp3));
1066 __ BranchF(&infinity, NULL, ge, input, double_scratch2); 954 __ BranchF(&infinity, NULL, ge, input, double_scratch2);
1067 955
1068 __ ldc1(double_scratch1, ExpConstant(3, temp3)); 956 __ ldc1(double_scratch1, ExpConstant(3, temp3));
1069 __ ldc1(result, ExpConstant(4, temp3)); 957 __ ldc1(result, ExpConstant(4, temp3));
1070 __ mul_d(double_scratch1, double_scratch1, input); 958 __ mul_d(double_scratch1, double_scratch1, input);
1071 __ add_d(double_scratch1, double_scratch1, result); 959 __ add_d(double_scratch1, double_scratch1, result);
1072 __ FmoveLow(temp2, double_scratch1); 960 __ FmoveLow(temp2, double_scratch1);
1073 __ sub_d(double_scratch1, double_scratch1, result); 961 __ sub_d(double_scratch1, double_scratch1, result);
1074 __ ldc1(result, ExpConstant(6, temp3)); 962 __ ldc1(result, ExpConstant(6, temp3));
1075 __ ldc1(double_scratch2, ExpConstant(5, temp3)); 963 __ ldc1(double_scratch2, ExpConstant(5, temp3));
1076 __ mul_d(double_scratch1, double_scratch1, double_scratch2); 964 __ mul_d(double_scratch1, double_scratch1, double_scratch2);
1077 __ sub_d(double_scratch1, double_scratch1, input); 965 __ sub_d(double_scratch1, double_scratch1, input);
1078 __ sub_d(result, result, double_scratch1); 966 __ sub_d(result, result, double_scratch1);
1079 __ mul_d(double_scratch2, double_scratch1, double_scratch1); 967 __ mul_d(double_scratch2, double_scratch1, double_scratch1);
1080 __ mul_d(result, result, double_scratch2); 968 __ mul_d(result, result, double_scratch2);
1081 __ ldc1(double_scratch2, ExpConstant(7, temp3)); 969 __ ldc1(double_scratch2, ExpConstant(7, temp3));
1082 __ mul_d(result, result, double_scratch2); 970 __ mul_d(result, result, double_scratch2);
1083 __ sub_d(result, result, double_scratch1); 971 __ sub_d(result, result, double_scratch1);
1084 // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1. 972 // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
1085 ASSERT(*reinterpret_cast<double*> 973 ASSERT(*reinterpret_cast<double*>
1086 (ExternalReference::math_exp_constants(8).address()) == 1); 974 (ExternalReference::math_exp_constants(8).address()) == 1);
1087 __ Move(double_scratch2, 1); 975 __ Move(double_scratch2, 1);
1088 __ add_d(result, result, double_scratch2); 976 __ add_d(result, result, double_scratch2);
1089 __ srl(temp1, temp2, 11); 977 __ dsrl(temp1, temp2, 11);
1090 __ Ext(temp2, temp2, 0, 11); 978 __ Ext(temp2, temp2, 0, 11);
1091 __ Addu(temp1, temp1, Operand(0x3ff)); 979 __ Daddu(temp1, temp1, Operand(0x3ff));
1092 980
1093 // Must not call ExpConstant() after overwriting temp3! 981 // Must not call ExpConstant() after overwriting temp3!
1094 __ li(temp3, Operand(ExternalReference::math_exp_log_table())); 982 __ li(temp3, Operand(ExternalReference::math_exp_log_table()));
1095 __ sll(at, temp2, 3); 983 __ dsll(at, temp2, 3);
1096 __ Addu(temp3, temp3, Operand(at)); 984 __ Daddu(temp3, temp3, Operand(at));
1097 __ lw(temp2, MemOperand(temp3, Register::kMantissaOffset)); 985 __ lwu(temp2, MemOperand(temp3, 0));
1098 __ lw(temp3, MemOperand(temp3, Register::kExponentOffset)); 986 __ lwu(temp3, MemOperand(temp3, kIntSize));
1099 // The first word is loaded is the lower number register. 987 // The first word is loaded is the lower number register.
1100 if (temp2.code() < temp3.code()) { 988 if (temp2.code() < temp3.code()) {
1101 __ sll(at, temp1, 20); 989 __ dsll(at, temp1, 20);
1102 __ Or(temp1, temp3, at); 990 __ Or(temp1, temp3, at);
1103 __ Move(double_scratch1, temp2, temp1); 991 __ Move(double_scratch1, temp2, temp1);
1104 } else { 992 } else {
1105 __ sll(at, temp1, 20); 993 __ dsll(at, temp1, 20);
1106 __ Or(temp1, temp2, at); 994 __ Or(temp1, temp2, at);
1107 __ Move(double_scratch1, temp3, temp1); 995 __ Move(double_scratch1, temp3, temp1);
1108 } 996 }
1109 __ mul_d(result, result, double_scratch1); 997 __ mul_d(result, result, double_scratch1);
1110 __ BranchShort(&done); 998 __ BranchShort(&done);
1111 999
1112 __ bind(&zero); 1000 __ bind(&zero);
1113 __ Move(result, kDoubleRegZero); 1001 __ Move(result, kDoubleRegZero);
1114 __ BranchShort(&done); 1002 __ BranchShort(&done);
1115 1003
(...skipping 15 matching lines...) Expand all
1131 // to avoid overloading the stack in stress conditions. 1019 // to avoid overloading the stack in stress conditions.
1132 // DONT_FLUSH is used because the CodeAgingHelper is initialized early in 1020 // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
1133 // the process, before MIPS simulator ICache is setup. 1021 // the process, before MIPS simulator ICache is setup.
1134 SmartPointer<CodePatcher> patcher( 1022 SmartPointer<CodePatcher> patcher(
1135 new CodePatcher(young_sequence_.start(), 1023 new CodePatcher(young_sequence_.start(),
1136 young_sequence_.length() / Assembler::kInstrSize, 1024 young_sequence_.length() / Assembler::kInstrSize,
1137 CodePatcher::DONT_FLUSH)); 1025 CodePatcher::DONT_FLUSH));
1138 PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length()); 1026 PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
1139 patcher->masm()->Push(ra, fp, cp, a1); 1027 patcher->masm()->Push(ra, fp, cp, a1);
1140 patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP); 1028 patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
1141 patcher->masm()->Addu( 1029 patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
1030 patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
1031 patcher->masm()->Daddu(
1142 fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); 1032 fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
1143 } 1033 }
1144 1034
1145 1035
1146 #ifdef DEBUG 1036 #ifdef DEBUG
1147 bool CodeAgingHelper::IsOld(byte* candidate) const { 1037 bool CodeAgingHelper::IsOld(byte* candidate) const {
1148 return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction; 1038 return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction;
1149 } 1039 }
1150 #endif 1040 #endif
1151 1041
(...skipping 29 matching lines...) Expand all
1181 CpuFeatures::FlushICache(sequence, young_length); 1071 CpuFeatures::FlushICache(sequence, young_length);
1182 } else { 1072 } else {
1183 Code* stub = GetCodeAgeStub(isolate, age, parity); 1073 Code* stub = GetCodeAgeStub(isolate, age, parity);
1184 CodePatcher patcher(sequence, young_length / Assembler::kInstrSize); 1074 CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
1185 // Mark this code sequence for FindPlatformCodeAgeSequence(). 1075 // Mark this code sequence for FindPlatformCodeAgeSequence().
1186 patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP); 1076 patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP);
1187 // Load the stub address to t9 and call it, 1077 // Load the stub address to t9 and call it,
1188 // GetCodeAgeAndParity() extracts the stub address from this instruction. 1078 // GetCodeAgeAndParity() extracts the stub address from this instruction.
1189 patcher.masm()->li( 1079 patcher.masm()->li(
1190 t9, 1080 t9,
1191 Operand(reinterpret_cast<uint32_t>(stub->instruction_start())), 1081 Operand(reinterpret_cast<uint64_t>(stub->instruction_start())),
1192 CONSTANT_SIZE); 1082 ADDRESS_LOAD);
1193 patcher.masm()->nop(); // Prevent jalr to jal optimization. 1083 patcher.masm()->nop(); // Prevent jalr to jal optimization.
1194 patcher.masm()->jalr(t9, a0); 1084 patcher.masm()->jalr(t9, a0);
1195 patcher.masm()->nop(); // Branch delay slot nop. 1085 patcher.masm()->nop(); // Branch delay slot nop.
1196 patcher.masm()->nop(); // Pad the empty space. 1086 patcher.masm()->nop(); // Pad the empty space.
1197 } 1087 }
1198 } 1088 }
1199 1089
1200 1090
1201 #undef __ 1091 #undef __
1202 1092
1203 } } // namespace v8::internal 1093 } } // namespace v8::internal
1204 1094
1205 #endif // V8_TARGET_ARCH_MIPS 1095 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/codegen-mips64.h ('k') | src/mips64/constants-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698