Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/runtime_entry.h" | 9 #include "vm/runtime_entry.h" |
| 10 #include "vm/simulator.h" | 10 #include "vm/simulator.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 } | 162 } |
| 163 | 163 |
| 164 | 164 |
| 165 void Assembler::CompareObject(Register rd, Register rn, const Object& object) { | 165 void Assembler::CompareObject(Register rd, Register rn, const Object& object) { |
| 166 ASSERT(rn != TMP1); | 166 ASSERT(rn != TMP1); |
| 167 LoadObject(TMP1, object); | 167 LoadObject(TMP1, object); |
| 168 subu(rd, rn, TMP1); | 168 subu(rd, rn, TMP1); |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 void Assembler::BranchOnCondition(Register rd, Label* l, Condition c) { | |
| 173 switch (c) { | |
| 174 case EQ: | |
| 175 beq(rd, ZR, l); | |
| 176 break; | |
| 177 case NE: | |
| 178 bne(rd, ZR, l); | |
| 179 break; | |
| 180 default: | |
| 181 UNIMPLEMENTED(); | |
| 182 break; | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 | |
| 172 void Assembler::LoadClassId(Register result, Register object) { | 187 void Assembler::LoadClassId(Register result, Register object) { |
| 173 ASSERT(RawObject::kClassIdTagBit == 16); | 188 ASSERT(RawObject::kClassIdTagBit == 16); |
| 174 ASSERT(RawObject::kClassIdTagSize == 16); | 189 ASSERT(RawObject::kClassIdTagSize == 16); |
| 175 const intptr_t class_id_offset = Object::tags_offset() + | 190 const intptr_t class_id_offset = Object::tags_offset() + |
| 176 RawObject::kClassIdTagBit / kBitsPerByte; | 191 RawObject::kClassIdTagBit / kBitsPerByte; |
| 177 lhu(result, FieldAddress(object, class_id_offset)); | 192 lhu(result, FieldAddress(object, class_id_offset)); |
| 178 } | 193 } |
| 179 | 194 |
| 180 | 195 |
| 181 void Assembler::LoadClassById(Register result, Register class_id) { | 196 void Assembler::LoadClassById(Register result, Register class_id) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 197 lw(result, FieldAddress(CTX, Context::isolate_offset())); | 212 lw(result, FieldAddress(CTX, Context::isolate_offset())); |
| 198 const intptr_t table_offset_in_isolate = | 213 const intptr_t table_offset_in_isolate = |
| 199 Isolate::class_table_offset() + ClassTable::table_offset(); | 214 Isolate::class_table_offset() + ClassTable::table_offset(); |
| 200 lw(result, Address(result, table_offset_in_isolate)); | 215 lw(result, Address(result, table_offset_in_isolate)); |
| 201 sll(TMP1, TMP1, 2); | 216 sll(TMP1, TMP1, 2); |
| 202 addu(result, result, TMP1); | 217 addu(result, result, TMP1); |
| 203 lw(result, Address(result)); | 218 lw(result, Address(result)); |
| 204 } | 219 } |
| 205 | 220 |
| 206 | 221 |
| 207 void Assembler::EnterStubFrame() { | 222 void Assembler::EnterStubFrame(bool uses_pp) { |
| 208 addiu(SP, SP, Immediate(-3 * kWordSize)); | 223 if (uses_pp) { |
| 209 sw(ZR, Address(SP, 2 * kWordSize)); // PC marker is 0 in stubs. | 224 addiu(SP, SP, Immediate(-4 * kWordSize)); |
| 210 sw(RA, Address(SP, 1 * kWordSize)); | 225 sw(ZR, Address(SP, 3 * kWordSize)); // PC marker is 0 in stubs. |
| 211 sw(FP, Address(SP, 0 * kWordSize)); | 226 sw(RA, Address(SP, 2 * kWordSize)); |
| 212 mov(FP, SP); | 227 sw(PP, Address(SP, 1 * kWordSize)); |
| 228 sw(FP, Address(SP, 0 * kWordSize)); | |
| 229 mov(FP, SP); | |
| 230 // Setup pool pointer for this stub. | |
| 231 Label next; | |
| 232 bal(&next); | |
| 233 delay_slot()->mov(T0, RA); | |
| 234 | |
| 235 const intptr_t object_pool_pc_dist = | |
| 236 Instructions::HeaderSize() - Instructions::object_pool_offset() + | |
| 237 CodeSize(); | |
| 238 | |
| 239 Bind(&next); | |
| 240 lw(PP, Address(T0, -object_pool_pc_dist)); | |
| 241 } else { | |
| 242 addiu(SP, SP, Immediate(-3 * kWordSize)); | |
| 243 sw(ZR, Address(SP, 2 * kWordSize)); // PC marker is 0 in stubs. | |
| 244 sw(RA, Address(SP, 1 * kWordSize)); | |
| 245 sw(FP, Address(SP, 0 * kWordSize)); | |
| 246 mov(FP, SP); | |
| 247 } | |
| 213 } | 248 } |
| 214 | 249 |
| 215 | 250 |
| 216 void Assembler::LeaveStubFrame() { | 251 void Assembler::LeaveStubFrame(bool uses_pp) { |
| 217 mov(SP, FP); | 252 if (uses_pp) { |
| 218 lw(RA, Address(SP, 1 * kWordSize)); | 253 mov(SP, FP); |
|
regis
2013/04/10 20:53:00
You can factorize this mov.
zra
2013/04/10 21:59:05
Done.
| |
| 219 lw(FP, Address(SP, 0 * kWordSize)); | 254 lw(RA, Address(SP, 2 * kWordSize)); |
| 220 addiu(SP, SP, Immediate(3 * kWordSize)); | 255 lw(PP, Address(SP, 1 * kWordSize)); |
| 256 lw(FP, Address(SP, 0 * kWordSize)); | |
| 257 addiu(SP, SP, Immediate(4 * kWordSize)); | |
| 258 } else { | |
| 259 mov(SP, FP); | |
| 260 lw(RA, Address(SP, 1 * kWordSize)); | |
| 261 lw(FP, Address(SP, 0 * kWordSize)); | |
| 262 addiu(SP, SP, Immediate(3 * kWordSize)); | |
| 263 } | |
| 221 } | 264 } |
| 222 | 265 |
| 223 | 266 |
| 224 void Assembler::CallRuntime(const RuntimeEntry& entry) { | 267 void Assembler::CallRuntime(const RuntimeEntry& entry) { |
| 225 entry.Call(this); | 268 entry.Call(this); |
| 226 } | 269 } |
| 227 | 270 |
| 228 | 271 |
| 229 void Assembler::EnterDartFrame(intptr_t frame_size) { | 272 void Assembler::EnterDartFrame(intptr_t frame_size) { |
| 230 const intptr_t offset = CodeSize(); | 273 const intptr_t offset = CodeSize(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 243 | 286 |
| 244 // Calculate the offset of the pool pointer from the PC. | 287 // Calculate the offset of the pool pointer from the PC. |
| 245 const intptr_t object_pool_pc_dist = | 288 const intptr_t object_pool_pc_dist = |
| 246 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 289 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 247 CodeSize(); | 290 CodeSize(); |
| 248 | 291 |
| 249 // This sw instruction is the return address for the bal, so T0 holds | 292 // This sw instruction is the return address for the bal, so T0 holds |
| 250 // the PC at this sw instruction. | 293 // the PC at this sw instruction. |
| 251 Bind(&next); | 294 Bind(&next); |
| 252 | 295 |
| 253 if (offset != 0) { | |
| 254 // Adjust PC for any intrinsic code that could have been generated | |
| 255 // before a frame is created. | |
| 256 addiu(T0, T0, Immediate(-offset)); | |
| 257 } | |
| 258 | |
| 259 // Save PC in frame for fast identification of corresponding code. | 296 // Save PC in frame for fast identification of corresponding code. |
| 260 sw(T0, Address(SP, 3 * kWordSize)); | 297 sw(T0, Address(SP, 3 * kWordSize)); |
|
regis
2013/04/10 20:53:00
You could save this store if offset != 0:
if (off
zra
2013/04/10 21:59:05
Done.
| |
| 261 | 298 |
| 299 if (offset != 0) { | |
| 300 // Adjust saved PC for any intrinsic code that could have been generated | |
| 301 // before a frame is created. | |
| 302 AddImmediate(T1, T0, -offset); | |
| 303 sw(T1, Address(SP, 3 * kWordSize)); | |
| 304 } | |
| 305 | |
| 262 // Set FP to the saved previous FP. | 306 // Set FP to the saved previous FP. |
| 263 addiu(FP, SP, Immediate(kWordSize)); | 307 addiu(FP, SP, Immediate(kWordSize)); |
| 264 | 308 |
| 265 // Load the pool pointer. | 309 // Load the pool pointer. |
| 266 lw(PP, Address(T0, -object_pool_pc_dist)); | 310 lw(PP, Address(T0, -object_pool_pc_dist)); |
| 267 | 311 |
| 268 // Reserve space for locals. | 312 // Reserve space for locals. |
| 269 addiu(SP, SP, Immediate(-frame_size)); | 313 AddImmediate(SP, -frame_size); |
| 270 } | 314 } |
| 271 | 315 |
| 272 | 316 |
| 273 void Assembler::LeaveDartFrame() { | 317 void Assembler::LeaveDartFrame() { |
| 274 addiu(SP, FP, Immediate(-kWordSize)); | 318 addiu(SP, FP, Immediate(-kWordSize)); |
| 275 | 319 |
| 276 lw(RA, Address(SP, 2 * kWordSize)); | 320 lw(RA, Address(SP, 2 * kWordSize)); |
| 277 lw(FP, Address(SP, 1 * kWordSize)); | 321 lw(FP, Address(SP, 1 * kWordSize)); |
| 278 lw(PP, Address(SP, 0 * kWordSize)); | 322 lw(PP, Address(SP, 0 * kWordSize)); |
| 279 | 323 |
| 280 // Adjust SP for PC pushed in EnterDartFrame. | 324 // Adjust SP for PC pushed in EnterDartFrame. |
| 281 addiu(SP, SP, Immediate(4 * kWordSize)); | 325 addiu(SP, SP, Immediate(4 * kWordSize)); |
| 282 } | 326 } |
| 283 | 327 |
| 284 | 328 |
| 285 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 329 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 286 // Reserve space for arguments and align frame before entering | 330 // Reserve space for arguments and align frame before entering |
| 287 // the C++ world. | 331 // the C++ world. |
| 288 addiu(SP, SP, Immediate(-frame_space)); | 332 AddImmediate(SP, -frame_space); |
| 289 if (OS::ActivationFrameAlignment() > 0) { | 333 if (OS::ActivationFrameAlignment() > 0) { |
| 290 LoadImmediate(TMP1, ~(OS::ActivationFrameAlignment() - 1)); | 334 LoadImmediate(TMP1, ~(OS::ActivationFrameAlignment() - 1)); |
| 291 and_(SP, SP, TMP1); | 335 and_(SP, SP, TMP1); |
| 292 } | 336 } |
| 293 } | 337 } |
| 294 | 338 |
| 295 | 339 |
| 296 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { | 340 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { |
| 297 if (object_pool_.IsNull()) { | 341 if (object_pool_.IsNull()) { |
| 298 // The object pool cannot be used in the vm isolate. | 342 // The object pool cannot be used in the vm isolate. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 318 b(&stop); | 362 b(&stop); |
| 319 Emit(reinterpret_cast<int32_t>(message)); | 363 Emit(reinterpret_cast<int32_t>(message)); |
| 320 Bind(&stop); | 364 Bind(&stop); |
| 321 break_(Instr::kStopMessageCode); | 365 break_(Instr::kStopMessageCode); |
| 322 } | 366 } |
| 323 | 367 |
| 324 } // namespace dart | 368 } // namespace dart |
| 325 | 369 |
| 326 #endif // defined TARGET_ARCH_MIPS | 370 #endif // defined TARGET_ARCH_MIPS |
| 327 | 371 |
| OLD | NEW |