Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #if defined(V8_TARGET_ARCH_MIPS) | 30 #if defined(V8_TARGET_ARCH_MIPS) |
| 31 | 31 |
| 32 #include "codegen.h" | 32 #include "codegen.h" |
| 33 #include "macro-assembler.h" | |
| 33 | 34 |
| 34 namespace v8 { | 35 namespace v8 { |
| 35 namespace internal { | 36 namespace internal { |
| 36 | 37 |
| 38 #define __ ACCESS_MASM(masm) | |
| 39 | |
| 37 // ------------------------------------------------------------------------- | 40 // ------------------------------------------------------------------------- |
| 38 // Platform-specific RuntimeCallHelper functions. | 41 // Platform-specific RuntimeCallHelper functions. |
| 39 | 42 |
| 40 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { | 43 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { |
| 41 masm->EnterFrame(StackFrame::INTERNAL); | 44 masm->EnterFrame(StackFrame::INTERNAL); |
| 42 ASSERT(!masm->has_frame()); | 45 ASSERT(!masm->has_frame()); |
| 43 masm->set_has_frame(true); | 46 masm->set_has_frame(true); |
| 44 } | 47 } |
| 45 | 48 |
| 46 | 49 |
| 47 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { | 50 void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { |
| 48 masm->LeaveFrame(StackFrame::INTERNAL); | 51 masm->LeaveFrame(StackFrame::INTERNAL); |
| 49 ASSERT(masm->has_frame()); | 52 ASSERT(masm->has_frame()); |
| 50 masm->set_has_frame(false); | 53 masm->set_has_frame(false); |
| 51 } | 54 } |
| 52 | 55 |
| 56 // ------------------------------------------------------------------------- | |
| 57 // Code generators | |
| 58 | |
| 59 void ElementsTransitionGenerator::GenerateSmiOnlyToObject( | |
| 60 MacroAssembler* masm) { | |
| 61 // ----------- S t a t e ------------- | |
| 62 // -- a0 : value | |
| 63 // -- a1 : key | |
| 64 // -- a2 : receiver | |
| 65 // -- ra : return address | |
| 66 // -- a3 : target map, scratch for subsequent call | |
| 67 // -- t0 : scratch (elements) | |
| 68 // ----------------------------------- | |
| 69 // Set transitioned map. | |
| 70 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | |
| 71 __ RecordWriteField(a2, | |
| 72 HeapObject::kMapOffset, | |
| 73 a3, | |
| 74 t5, | |
| 75 kRAHasNotBeenSaved, | |
| 76 kDontSaveFPRegs, | |
| 77 EMIT_REMEMBERED_SET, | |
| 78 OMIT_SMI_CHECK); | |
| 79 __ mov(v0, a0); | |
|
Yang
2011/10/21 07:43:34
Why is a0 moved to v0?
KeyedStoreStubCompiler::Gen
Paul Lind
2011/10/21 16:39:49
Yep, you are correct, it is not needed here. Remov
| |
| 80 } | |
| 81 | |
| 82 | |
| 83 void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( | |
| 84 MacroAssembler* masm, Label* fail) { | |
| 85 // ----------- S t a t e ------------- | |
| 86 // -- a0 : value | |
| 87 // -- a1 : key | |
| 88 // -- a2 : receiver | |
| 89 // -- ra : return address | |
| 90 // -- a3 : target map, scratch for subsequent call | |
| 91 // -- t0 : scratch (elements) | |
| 92 // ----------------------------------- | |
| 93 Label loop, entry, convert_hole, gc_required; | |
| 94 bool fpu_supported = CpuFeatures::IsSupported(FPU); | |
| 95 __ push(ra); | |
| 96 | |
| 97 Register scratch = t6; | |
| 98 | |
| 99 __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); | |
| 100 __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); | |
| 101 // t0: source FixedArray | |
| 102 // t1: number of elements (smi-tagged) | |
| 103 | |
| 104 // Allocate new FixedDoubleArray. | |
| 105 __ sll(scratch, t1, 2); | |
| 106 __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize); | |
| 107 __ AllocateInNewSpace(scratch, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS); | |
| 108 // t2: destination FixedDoubleArray, not tagged as heap object | |
| 109 __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex); | |
| 110 __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); | |
| 111 // Set destination FixedDoubleArray's length. | |
| 112 __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); | |
| 113 // Update receiver's map. | |
| 114 | |
| 115 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | |
| 116 __ RecordWriteField(a2, | |
| 117 HeapObject::kMapOffset, | |
| 118 a3, | |
| 119 t5, | |
| 120 kRAHasBeenSaved, | |
| 121 kDontSaveFPRegs, | |
| 122 EMIT_REMEMBERED_SET, | |
| 123 OMIT_SMI_CHECK); | |
| 124 // Replace receiver's backing store with newly created FixedDoubleArray. | |
| 125 __ Addu(a3, t2, Operand(kHeapObjectTag)); | |
| 126 __ sw(a3, FieldMemOperand(a2, JSObject::kElementsOffset)); | |
| 127 __ RecordWriteField(a2, | |
| 128 JSObject::kElementsOffset, | |
| 129 a3, | |
| 130 t5, | |
| 131 kRAHasBeenSaved, | |
| 132 kDontSaveFPRegs, | |
| 133 EMIT_REMEMBERED_SET, | |
| 134 OMIT_SMI_CHECK); | |
| 135 | |
| 136 | |
| 137 // Prepare for conversion loop. | |
| 138 __ Addu(a3, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
| 139 __ Addu(t3, t2, Operand(FixedDoubleArray::kHeaderSize)); | |
| 140 __ sll(t2, t1, 2); | |
| 141 __ Addu(t2, t2, t3); | |
| 142 __ li(t0, Operand(kHoleNanLower32)); | |
| 143 __ li(t1, Operand(kHoleNanUpper32)); | |
| 144 // t0: kHoleNanLower32 | |
| 145 // t1: kHoleNanUpper32 | |
| 146 // t2: end of destination FixedDoubleArray, not tagged | |
| 147 // t3: begin of FixedDoubleArray element fields, not tagged | |
| 148 | |
| 149 if (!fpu_supported) __ Push(a1, a0); | |
| 150 | |
| 151 __ Branch(&entry); | |
| 152 | |
| 153 // Call into runtime if GC is required. | |
| 154 __ bind(&gc_required); | |
| 155 __ pop(ra); | |
| 156 __ Branch(fail); | |
| 157 | |
| 158 // Convert and copy elements. | |
| 159 __ bind(&loop); | |
| 160 __ lw(t5, MemOperand(a3)); | |
| 161 __ Addu(a3, a3, kIntSize); | |
| 162 // t5: current element | |
| 163 __ JumpIfNotSmi(t5, &convert_hole); | |
| 164 | |
| 165 // Normal smi, convert to double and store. | |
| 166 __ SmiUntag(t5); | |
| 167 if (fpu_supported) { | |
| 168 CpuFeatures::Scope scope(FPU); | |
| 169 __ mtc1(t5, f0); | |
| 170 __ cvt_d_w(f0, f0); | |
| 171 __ sdc1(f0, MemOperand(t3)); | |
| 172 __ Addu(t3, t3, kDoubleSize); | |
| 173 } else { | |
| 174 FloatingPointHelper::ConvertIntToDouble(masm, | |
| 175 t5, | |
| 176 FloatingPointHelper::kCoreRegisters, | |
| 177 f0, | |
| 178 a0, | |
| 179 a1, | |
| 180 t7, | |
| 181 f0); | |
| 182 __ sw(a0, MemOperand(t3)); // mantissa | |
| 183 __ sw(a1, MemOperand(t3, kIntSize)); // exponent | |
| 184 __ Addu(t3, t3, kDoubleSize); | |
| 185 } | |
| 186 __ Branch(&entry); | |
| 187 | |
| 188 // Hole found, store the-hole NaN. | |
| 189 __ bind(&convert_hole); | |
| 190 __ sw(t0, MemOperand(t3)); // mantissa | |
| 191 __ sw(t1, MemOperand(t3, kIntSize)); // exponent | |
| 192 __ Addu(t3, t3, kDoubleSize); | |
| 193 | |
| 194 __ bind(&entry); | |
| 195 __ Branch(&loop, lt, t3, Operand(t2)); | |
| 196 | |
| 197 if (!fpu_supported) __ Pop(a1, a0); | |
| 198 __ pop(ra); | |
| 199 | |
| 200 __ mov(v0, a0); | |
|
Yang
2011/10/21 07:43:34
Ditto.
Paul Lind
2011/10/21 16:39:49
Removed.
| |
| 201 } | |
| 202 | |
| 203 | |
| 204 void ElementsTransitionGenerator::GenerateDoubleToObject( | |
| 205 MacroAssembler* masm, Label* fail) { | |
| 206 // ----------- S t a t e ------------- | |
| 207 // -- a0 : value | |
| 208 // -- a1 : key | |
| 209 // -- a2 : receiver | |
| 210 // -- ra : return address | |
| 211 // -- a3 : target map, scratch for subsequent call | |
| 212 // -- t0 : scratch (elements) | |
| 213 // ----------------------------------- | |
| 214 Label entry, loop, convert_hole, gc_required; | |
| 215 __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); | |
| 216 | |
| 217 __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); | |
| 218 __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); | |
| 219 // t0: source FixedArray | |
| 220 // t1: number of elements (smi-tagged) | |
| 221 | |
| 222 // Allocate new FixedArray. | |
| 223 __ sll(a0, t1, 1); | |
| 224 __ Addu(a0, a0, FixedDoubleArray::kHeaderSize); | |
| 225 __ AllocateInNewSpace(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS); | |
| 226 // t2: destination FixedArray, not tagged as heap object | |
| 227 __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex); | |
| 228 __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); | |
| 229 // Set destination FixedDoubleArray's length. | |
| 230 __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); | |
| 231 | |
| 232 // Prepare for conversion loop. | |
| 233 __ Addu(t0, t0, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); | |
| 234 __ Addu(a3, t2, Operand(FixedArray::kHeaderSize)); | |
| 235 __ Addu(t2, t2, Operand(kHeapObjectTag)); | |
| 236 __ sll(t1, t1, 1); | |
| 237 __ Addu(t1, a3, t1); | |
| 238 __ LoadRoot(t3, Heap::kTheHoleValueRootIndex); | |
| 239 __ LoadRoot(t5, Heap::kHeapNumberMapRootIndex); | |
| 240 // Using offsetted addresses. | |
| 241 // a3: begin of destination FixedArray element fields, not tagged | |
| 242 // t0: begin of source FixedDoubleArray element fields, not tagged, +4 | |
| 243 // t1: end of destination FixedArray, not tagged | |
| 244 // t2: destination FixedArray | |
| 245 // t3: the-hole pointer | |
| 246 // t5: heap number map | |
| 247 __ Branch(&entry); | |
| 248 | |
| 249 // Call into runtime if GC is required. | |
| 250 __ bind(&gc_required); | |
| 251 __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); | |
| 252 | |
| 253 __ Branch(fail); | |
| 254 | |
| 255 __ bind(&loop); | |
| 256 __ lw(a1, MemOperand(t0)); | |
| 257 __ Addu(t0, t0, kDoubleSize); | |
| 258 // a1: current element's upper 32 bit | |
| 259 // t0: address of next element's upper 32 bit | |
| 260 __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32)); | |
| 261 | |
| 262 // Non-hole double, copy value into a heap number. | |
| 263 __ AllocateHeapNumber(a2, a0, t6, t5, &gc_required); | |
| 264 // a2: new heap number | |
| 265 __ lw(a0, MemOperand(t0, -12)); | |
| 266 __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset)); | |
| 267 __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset)); | |
| 268 __ mov(a0, a3); | |
| 269 __ sw(a2, MemOperand(a3)); | |
| 270 __ Addu(a3, a3, kIntSize); | |
| 271 __ RecordWrite(t2, | |
| 272 a0, | |
| 273 a2, | |
| 274 kRAHasBeenSaved, | |
| 275 kDontSaveFPRegs, | |
| 276 EMIT_REMEMBERED_SET, | |
| 277 OMIT_SMI_CHECK); | |
| 278 __ Branch(&entry); | |
| 279 | |
| 280 // Replace the-hole NaN with the-hole pointer. | |
| 281 __ bind(&convert_hole); | |
| 282 __ sw(t3, MemOperand(a3)); | |
| 283 __ Addu(a3, a3, kIntSize); | |
| 284 | |
| 285 __ bind(&entry); | |
| 286 __ Branch(&loop, lt, a3, Operand(t1)); | |
| 287 | |
| 288 __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit()); | |
| 289 // Update receiver's map. | |
| 290 __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | |
| 291 __ RecordWriteField(a2, | |
| 292 HeapObject::kMapOffset, | |
| 293 a3, | |
| 294 t5, | |
| 295 kRAHasBeenSaved, | |
| 296 kDontSaveFPRegs, | |
| 297 EMIT_REMEMBERED_SET, | |
| 298 OMIT_SMI_CHECK); | |
| 299 // Replace receiver's backing store with newly created and filled FixedArray. | |
| 300 __ sw(t2, FieldMemOperand(a2, JSObject::kElementsOffset)); | |
| 301 __ RecordWriteField(a2, | |
| 302 JSObject::kElementsOffset, | |
| 303 t2, | |
| 304 t5, | |
| 305 kRAHasBeenSaved, | |
| 306 kDontSaveFPRegs, | |
| 307 EMIT_REMEMBERED_SET, | |
| 308 OMIT_SMI_CHECK); | |
| 309 __ pop(ra); | |
| 310 | |
| 311 __ mov(v0, a0); | |
|
Yang
2011/10/21 07:43:34
Ditto.
Paul Lind
2011/10/21 16:39:49
Removed.
| |
| 312 } | |
| 313 | |
| 314 #undef __ | |
| 53 | 315 |
| 54 } } // namespace v8::internal | 316 } } // namespace v8::internal |
| 55 | 317 |
| 56 #endif // V8_TARGET_ARCH_MIPS | 318 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |