| 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 #ifndef VM_ASSEMBLER_MIPS_H_ | 5 #ifndef VM_ASSEMBLER_MIPS_H_ |
| 6 #define VM_ASSEMBLER_MIPS_H_ | 6 #define VM_ASSEMBLER_MIPS_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_mips.h directly; use assembler.h instead. | 9 #error Do not include assembler_mips.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 Assembler* delay_slot() { | 217 Assembler* delay_slot() { |
| 218 ASSERT(delay_slot_available_); | 218 ASSERT(delay_slot_available_); |
| 219 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == | 219 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == |
| 220 Instr::kNopInstruction); | 220 Instr::kNopInstruction); |
| 221 buffer_.Remit<int32_t>(); | 221 buffer_.Remit<int32_t>(); |
| 222 delay_slot_available_ = false; | 222 delay_slot_available_ = false; |
| 223 in_delay_slot_ = true; | 223 in_delay_slot_ = true; |
| 224 return this; | 224 return this; |
| 225 } | 225 } |
| 226 | 226 |
| 227 // CPU instructions. | 227 // CPU instructions in alphabetical order. |
| 228 void addiu(Register rt, Register rs, const Immediate& imm) { | 228 void addiu(Register rt, Register rs, const Immediate& imm) { |
| 229 ASSERT(Utils::IsInt(16, imm.value())); | 229 ASSERT(Utils::IsInt(16, imm.value())); |
| 230 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 230 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 231 EmitIType(ADDIU, rs, rt, imm_value); | 231 EmitIType(ADDIU, rs, rt, imm_value); |
| 232 } | 232 } |
| 233 | 233 |
| 234 void addu(Register rd, Register rs, Register rt) { | 234 void addu(Register rd, Register rs, Register rt) { |
| 235 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); | 235 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); |
| 236 } | 236 } |
| 237 | 237 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 261 } | 261 } |
| 262 | 262 |
| 263 void div(Register rs, Register rt) { | 263 void div(Register rs, Register rt) { |
| 264 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); | 264 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); |
| 265 } | 265 } |
| 266 | 266 |
| 267 void divu(Register rs, Register rt) { | 267 void divu(Register rs, Register rt) { |
| 268 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); | 268 EmitRType(SPECIAL, rs, rt, R0, 0, DIVU); |
| 269 } | 269 } |
| 270 | 270 |
| 271 void jalr(Register rs, Register rd = RA) { |
| 272 ASSERT(rs != rd); |
| 273 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. |
| 274 EmitRType(SPECIAL, rs, R0, rd, 0, JALR); |
| 275 EmitBranchDelayNop(); |
| 276 } |
| 277 |
| 278 void jr(Register rs) { |
| 279 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. |
| 280 EmitRType(SPECIAL, rs, R0, R0, 0, JR); |
| 281 EmitBranchDelayNop(); |
| 282 } |
| 271 | 283 |
| 272 void lb(Register rt, const Address& addr) { | 284 void lb(Register rt, const Address& addr) { |
| 273 EmitLoadStore(LB, rt, addr); | 285 EmitLoadStore(LB, rt, addr); |
| 274 } | 286 } |
| 275 | 287 |
| 276 void lbu(Register rt, const Address& addr) { | 288 void lbu(Register rt, const Address& addr) { |
| 277 EmitLoadStore(LBU, rt, addr); | 289 EmitLoadStore(LBU, rt, addr); |
| 278 } | 290 } |
| 279 | 291 |
| 280 void lh(Register rt, const Address& addr) { | 292 void lh(Register rt, const Address& addr) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 296 } | 308 } |
| 297 | 309 |
| 298 void mfhi(Register rd) { | 310 void mfhi(Register rd) { |
| 299 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); | 311 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); |
| 300 } | 312 } |
| 301 | 313 |
| 302 void mflo(Register rd) { | 314 void mflo(Register rd) { |
| 303 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); | 315 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); |
| 304 } | 316 } |
| 305 | 317 |
| 318 void movn(Register rd, Register rs, Register rt) { |
| 319 EmitRType(SPECIAL, rs, rt, rd, 0, MOVN); |
| 320 } |
| 321 |
| 322 void movz(Register rd, Register rs, Register rt) { |
| 323 EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ); |
| 324 } |
| 325 |
| 326 void mult(Register rs, Register rt) { |
| 327 EmitRType(SPECIAL, rs, rt, R0, 0, MULT); |
| 328 } |
| 329 |
| 330 void multu(Register rs, Register rt) { |
| 331 EmitRType(SPECIAL, rs, rt, R0, 0, MULTU); |
| 332 } |
| 333 |
| 334 void nor(Register rd, Register rs, Register rt) { |
| 335 EmitRType(SPECIAL, rs, rt, rd, 0, NOR); |
| 336 } |
| 337 |
| 338 void or_(Register rd, Register rs, Register rt) { |
| 339 EmitRType(SPECIAL, rs, rt, rd, 0, OR); |
| 340 } |
| 341 |
| 306 void ori(Register rt, Register rs, const Immediate& imm) { | 342 void ori(Register rt, Register rs, const Immediate& imm) { |
| 307 ASSERT(Utils::IsUint(16, imm.value())); | 343 ASSERT(Utils::IsUint(16, imm.value())); |
| 308 uint16_t imm_value = static_cast<uint16_t>(imm.value()); | 344 uint16_t imm_value = static_cast<uint16_t>(imm.value()); |
| 309 EmitIType(ORI, rs, rt, imm_value); | 345 EmitIType(ORI, rs, rt, imm_value); |
| 310 } | 346 } |
| 311 | 347 |
| 312 void jr(Register rs) { | |
| 313 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported. | |
| 314 EmitRType(SPECIAL, rs, R0, R0, 0, JR); | |
| 315 Emit(Instr::kNopInstruction); // Branch delay NOP. | |
| 316 delay_slot_available_ = true; | |
| 317 } | |
| 318 | |
| 319 void sb(Register rt, const Address& addr) { | 348 void sb(Register rt, const Address& addr) { |
| 320 EmitLoadStore(SB, rt, addr); | 349 EmitLoadStore(SB, rt, addr); |
| 321 } | 350 } |
| 322 | 351 |
| 323 void sh(Register rt, const Address& addr) { | 352 void sh(Register rt, const Address& addr) { |
| 324 EmitLoadStore(SH, rt, addr); | 353 EmitLoadStore(SH, rt, addr); |
| 325 } | 354 } |
| 326 | 355 |
| 356 void sll(Register rd, Register rt, int sa) { |
| 357 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); |
| 358 } |
| 359 |
| 360 void sllv(Register rd, Register rt, Register rs) { |
| 361 EmitRType(SPECIAL, rs, rt, rd, 0, SLLV); |
| 362 } |
| 363 |
| 364 void slt(Register rd, Register rs, Register rt) { |
| 365 EmitRType(SPECIAL, rs, rt, rd, 0, SLT); |
| 366 } |
| 367 |
| 368 void sltu(Register rd, Register rs, Register rt) { |
| 369 EmitRType(SPECIAL, rs, rt, rd, 0, SLTU); |
| 370 } |
| 371 |
| 372 void sra(Register rd, Register rt, int sa) { |
| 373 EmitRType(SPECIAL, R0, rt, rd, sa, SRA); |
| 374 } |
| 375 |
| 376 void srav(Register rd, Register rt, Register rs) { |
| 377 EmitRType(SPECIAL, rs, rt, rd, 0, SRAV); |
| 378 } |
| 379 |
| 380 void srl(Register rd, Register rt, int sa) { |
| 381 EmitRType(SPECIAL, R0, rt, rd, sa, SRL); |
| 382 } |
| 383 |
| 384 void srlv(Register rd, Register rt, Register rs) { |
| 385 EmitRType(SPECIAL, rs, rt, rd, 0, SRLV); |
| 386 } |
| 387 |
| 388 void sub(Register rd, Register rs, Register rt) { |
| 389 EmitRType(SPECIAL, rs, rt, rd, 0, SUB); |
| 390 } |
| 391 |
| 392 void subu(Register rd, Register rs, Register rt) { |
| 393 EmitRType(SPECIAL, rs, rt, rd, 0, SUBU); |
| 394 } |
| 395 |
| 327 void sw(Register rt, const Address& addr) { | 396 void sw(Register rt, const Address& addr) { |
| 328 EmitLoadStore(SW, rt, addr); | 397 EmitLoadStore(SW, rt, addr); |
| 329 } | 398 } |
| 330 | 399 |
| 331 void sll(Register rd, Register rt, int sa) { | 400 void xor_(Register rd, Register rs, Register rt) { |
| 332 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); | 401 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); |
| 333 } | 402 } |
| 334 | 403 |
| 335 // Macros. | 404 // Macros in alphabetical order. |
| 336 void LoadImmediate(Register rd, int32_t value) { | 405 void LoadImmediate(Register rd, int32_t value) { |
| 337 lui(rd, Immediate((value >> 16) & 0xffff)); | 406 if (Utils::IsInt(16, value)) { |
| 338 ori(rd, rd, Immediate(value & 0xffff)); | 407 addiu(rd, ZR, Immediate(value)); |
| 408 } else { |
| 409 lui(rd, Immediate((value >> 16) & 0xffff)); |
| 410 ori(rd, rd, Immediate(value & 0xffff)); |
| 411 } |
| 412 } |
| 413 |
| 414 void Move(Register rd, Register rs) { |
| 415 or_(rd, rs, ZR); |
| 339 } | 416 } |
| 340 | 417 |
| 341 private: | 418 private: |
| 342 AssemblerBuffer buffer_; | 419 AssemblerBuffer buffer_; |
| 343 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. | 420 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. |
| 344 int prologue_offset_; | 421 int prologue_offset_; |
| 345 | 422 |
| 346 bool delay_slot_available_; | 423 bool delay_slot_available_; |
| 347 bool in_delay_slot_; | 424 bool in_delay_slot_; |
| 348 | 425 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 SpecialFunction func) { | 489 SpecialFunction func) { |
| 413 ASSERT(Utils::IsUint(5, sa)); | 490 ASSERT(Utils::IsUint(5, sa)); |
| 414 Emit(opcode << kOpcodeShift | | 491 Emit(opcode << kOpcodeShift | |
| 415 rs << kRsShift | | 492 rs << kRsShift | |
| 416 rt << kRtShift | | 493 rt << kRtShift | |
| 417 rd << kRdShift | | 494 rd << kRdShift | |
| 418 sa << kSaShift | | 495 sa << kSaShift | |
| 419 func << kFunctionShift); | 496 func << kFunctionShift); |
| 420 } | 497 } |
| 421 | 498 |
| 499 void EmitBranchDelayNop() { |
| 500 Emit(Instr::kNopInstruction); // Branch delay NOP. |
| 501 delay_slot_available_ = true; |
| 502 } |
| 503 |
| 422 DISALLOW_ALLOCATION(); | 504 DISALLOW_ALLOCATION(); |
| 423 DISALLOW_COPY_AND_ASSIGN(Assembler); | 505 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 424 }; | 506 }; |
| 425 | 507 |
| 426 } // namespace dart | 508 } // namespace dart |
| 427 | 509 |
| 428 #endif // VM_ASSEMBLER_MIPS_H_ | 510 #endif // VM_ASSEMBLER_MIPS_H_ |
| OLD | NEW |