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

Side by Side Diff: runtime/vm/assembler_mips.h

Issue 12634030: Adds branch instructions and labels to the MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 prologue_offset_(-1), 140 prologue_offset_(-1),
141 delay_slot_available_(false), 141 delay_slot_available_(false),
142 in_delay_slot_(false), 142 in_delay_slot_(false),
143 comments_() { } 143 comments_() { }
144 ~Assembler() { } 144 ~Assembler() { }
145 145
146 void PopRegister(Register r) { 146 void PopRegister(Register r) {
147 UNIMPLEMENTED(); 147 UNIMPLEMENTED();
148 } 148 }
149 149
150 void Bind(Label* label) { 150 void Bind(Label* label);
151 UNIMPLEMENTED();
152 }
153 151
154 // Misc. functionality 152 // Misc. functionality
155 int CodeSize() const { return buffer_.Size(); } 153 int CodeSize() const { return buffer_.Size(); }
156 int prologue_offset() const { return -1; } 154 int prologue_offset() const { return -1; }
157 const ZoneGrowableArray<int>& GetPointerOffsets() const { 155 const ZoneGrowableArray<int>& GetPointerOffsets() const {
158 return buffer_.pointer_offsets(); 156 return buffer_.pointer_offsets();
159 } 157 }
160 const GrowableObjectArray& object_pool() const { return object_pool_; } 158 const GrowableObjectArray& object_pool() const { return object_pool_; }
161 void FinalizeInstructions(const MemoryRegion& region) { 159 void FinalizeInstructions(const MemoryRegion& region) {
162 buffer_.FinalizeInstructions(region); 160 buffer_.FinalizeInstructions(region);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 void and_(Register rd, Register rs, Register rt) { 236 void and_(Register rd, Register rs, Register rt) {
239 EmitRType(SPECIAL, rs, rt, rd, 0, AND); 237 EmitRType(SPECIAL, rs, rt, rd, 0, AND);
240 } 238 }
241 239
242 void andi(Register rt, Register rs, const Immediate& imm) { 240 void andi(Register rt, Register rs, const Immediate& imm) {
243 ASSERT(Utils::IsUint(16, imm.value())); 241 ASSERT(Utils::IsUint(16, imm.value()));
244 uint16_t imm_value = static_cast<uint16_t>(imm.value()); 242 uint16_t imm_value = static_cast<uint16_t>(imm.value());
245 EmitIType(ANDI, rs, rt, imm_value); 243 EmitIType(ANDI, rs, rt, imm_value);
246 } 244 }
247 245
246 // Unconditional branch.
247 void b(Label* l) {
248 beq(R0, R0, l);
249 }
250
251 // Branch if equal.
252 void beq(Register rs, Register rt, Label* l) {
253 ASSERT(!in_delay_slot_);
254 EmitBranch(BEQ, rs, rt, l);
255 EmitBranchDelayNop();
256 }
257
258 // Branch if equal, likely taken.
259 // Delay slot executed only when branch taken.
260 void beql(Register rs, Register rt, Label* l) {
261 ASSERT(!in_delay_slot_);
262 EmitBranch(BEQL, rs, rt, l);
263 EmitBranchDelayNop();
264 }
265
266 // Branch if rs >= 0.
267 void bgez(Register rs, Label* l) {
268 ASSERT(!in_delay_slot_);
269 EmitRegImmBranch(BGEZ, rs, l);
270 EmitBranchDelayNop();
271 }
272
273 // Branch if rs >= 0, likely taken.
274 // Delay slot executed only when branch taken.
275 void bgezl(Register rs, Label* l) {
276 ASSERT(!in_delay_slot_);
277 EmitRegImmBranch(BGEZL, rs, l);
278 EmitBranchDelayNop();
279 }
280
281 // Branch if rs > 0.
282 void bgtz(Register rs, Label* l) {
283 ASSERT(!in_delay_slot_);
284 EmitBranch(BGTZ, rs, R0, l);
285 EmitBranchDelayNop();
286 }
287
288 // Branch if rs > 0, likely taken.
289 // Delay slot executed only when branch taken.
290 void bgtzl(Register rs, Label* l) {
291 ASSERT(!in_delay_slot_);
292 EmitBranch(BGTZL, rs, R0, l);
293 EmitBranchDelayNop();
294 }
295
296 // Branch if rs <= 0.
297 void blez(Register rs, Label* l) {
298 ASSERT(!in_delay_slot_);
299 EmitBranch(BLEZ, rs, R0, l);
300 EmitBranchDelayNop();
301 }
302
303 // Branch if rs <= 0, likely taken.
304 // Delay slot executed only when branch taken.
305 void blezl(Register rs, Label* l) {
306 ASSERT(!in_delay_slot_);
307 EmitBranch(BLEZL, rs, R0, l);
308 EmitBranchDelayNop();
309 }
310
311 // Branch if rs < 0.
312 void bltz(Register rs, Label* l) {
313 ASSERT(!in_delay_slot_);
314 EmitRegImmBranch(BLTZ, rs, l);
315 EmitBranchDelayNop();
316 }
317
318 // Branch if rs < 0, likely taken.
319 // Delay slot executed only when branch taken.
320 void bltzl(Register rs, Label* l) {
321 ASSERT(!in_delay_slot_);
322 EmitRegImmBranch(BLTZL, rs, l);
323 EmitBranchDelayNop();
324 }
325
326 // Branch if not equal.
327 void bne(Register rs, Register rt, Label* l) {
328 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
329 EmitBranch(BNE, rs, rt, l);
330 EmitBranchDelayNop();
331 }
332
333 // Branch if not equal, likely taken.
334 // Delay slot executed only when branch taken.
335 void bnel(Register rs, Register rt, Label* l) {
336 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
337 EmitBranch(BNEL, rs, rt, l);
338 EmitBranchDelayNop();
339 }
340
248 void break_(int32_t code) { 341 void break_(int32_t code) {
249 ASSERT(Utils::IsUint(20, code)); 342 ASSERT(Utils::IsUint(20, code));
250 Emit(SPECIAL << kOpcodeShift | 343 Emit(SPECIAL << kOpcodeShift |
251 code << kBreakCodeShift | 344 code << kBreakCodeShift |
252 BREAK << kFunctionShift); 345 BREAK << kFunctionShift);
253 } 346 }
254 347
255 void clo(Register rd, Register rs) { 348 void clo(Register rd, Register rs) {
256 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO); 349 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO);
257 } 350 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 } 401 }
309 402
310 void mfhi(Register rd) { 403 void mfhi(Register rd) {
311 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); 404 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
312 } 405 }
313 406
314 void mflo(Register rd) { 407 void mflo(Register rd) {
315 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); 408 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO);
316 } 409 }
317 410
411 void mov(Register rd, Register rs) {
412 or_(rd, rs, ZR);
413 }
414
318 void movn(Register rd, Register rs, Register rt) { 415 void movn(Register rd, Register rs, Register rt) {
319 EmitRType(SPECIAL, rs, rt, rd, 0, MOVN); 416 EmitRType(SPECIAL, rs, rt, rd, 0, MOVN);
320 } 417 }
321 418
322 void movz(Register rd, Register rs, Register rt) { 419 void movz(Register rd, Register rs, Register rt) {
323 EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ); 420 EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ);
324 } 421 }
325 422
326 void mult(Register rs, Register rt) { 423 void mult(Register rs, Register rt) {
327 EmitRType(SPECIAL, rs, rt, R0, 0, MULT); 424 EmitRType(SPECIAL, rs, rt, R0, 0, MULT);
328 } 425 }
329 426
330 void multu(Register rs, Register rt) { 427 void multu(Register rs, Register rt) {
331 EmitRType(SPECIAL, rs, rt, R0, 0, MULTU); 428 EmitRType(SPECIAL, rs, rt, R0, 0, MULTU);
332 } 429 }
333 430
431 void nop() {
432 Emit(Instr::kNopInstruction);
433 }
434
334 void nor(Register rd, Register rs, Register rt) { 435 void nor(Register rd, Register rs, Register rt) {
335 EmitRType(SPECIAL, rs, rt, rd, 0, NOR); 436 EmitRType(SPECIAL, rs, rt, rd, 0, NOR);
336 } 437 }
337 438
338 void or_(Register rd, Register rs, Register rt) { 439 void or_(Register rd, Register rs, Register rt) {
339 EmitRType(SPECIAL, rs, rt, rd, 0, OR); 440 EmitRType(SPECIAL, rs, rt, rd, 0, OR);
340 } 441 }
341 442
342 void ori(Register rt, Register rs, const Immediate& imm) { 443 void ori(Register rt, Register rs, const Immediate& imm) {
343 ASSERT(Utils::IsUint(16, imm.value())); 444 ASSERT(Utils::IsUint(16, imm.value()));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 // Macros in alphabetical order. 505 // Macros in alphabetical order.
405 void LoadImmediate(Register rd, int32_t value) { 506 void LoadImmediate(Register rd, int32_t value) {
406 if (Utils::IsInt(16, value)) { 507 if (Utils::IsInt(16, value)) {
407 addiu(rd, ZR, Immediate(value)); 508 addiu(rd, ZR, Immediate(value));
408 } else { 509 } else {
409 lui(rd, Immediate((value >> 16) & 0xffff)); 510 lui(rd, Immediate((value >> 16) & 0xffff));
410 ori(rd, rd, Immediate(value & 0xffff)); 511 ori(rd, rd, Immediate(value & 0xffff));
411 } 512 }
412 } 513 }
413 514
414 void Move(Register rd, Register rs) {
415 or_(rd, rs, ZR);
416 }
417
418 private: 515 private:
419 AssemblerBuffer buffer_; 516 AssemblerBuffer buffer_;
420 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. 517 GrowableObjectArray& object_pool_; // Objects and patchable jump targets.
421 int prologue_offset_; 518 int prologue_offset_;
422 519
423 bool delay_slot_available_; 520 bool delay_slot_available_;
424 bool in_delay_slot_; 521 bool in_delay_slot_;
425 522
426 class CodeComment : public ZoneAllocated { 523 class CodeComment : public ZoneAllocated {
427 public: 524 public:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 SpecialFunction func) { 586 SpecialFunction func) {
490 ASSERT(Utils::IsUint(5, sa)); 587 ASSERT(Utils::IsUint(5, sa));
491 Emit(opcode << kOpcodeShift | 588 Emit(opcode << kOpcodeShift |
492 rs << kRsShift | 589 rs << kRsShift |
493 rt << kRtShift | 590 rt << kRtShift |
494 rd << kRdShift | 591 rd << kRdShift |
495 sa << kSaShift | 592 sa << kSaShift |
496 func << kFunctionShift); 593 func << kFunctionShift);
497 } 594 }
498 595
596 void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
597 if (label->IsBound()) {
598 // Reletive destination from an instruction after the branch.
599 int32_t dest = label->Position() - (buffer_.Size() + Instr::kInstrSize);
600 uint16_t dest_off = EncodeBranchOffset(dest, 0);
601 EmitIType(b, rs, rt, dest_off);
602 } else {
603 int position = buffer_.Size();
604 EmitIType(b, rs, rt, label->position_);
605 label->LinkTo(position);
606 }
607 }
608
609 void EmitRegImmBranch(RtRegImm b, Register rs, Label* label) {
610 if (label->IsBound()) {
611 // Reletive destination from an instruction after the branch.
612 int32_t dest = label->Position() - (buffer_.Size() + Instr::kInstrSize);
613 uint16_t dest_off = EncodeBranchOffset(dest, 0);
614 EmitRegImmType(REGIMM, rs, b, dest_off);
615 } else {
616 int position = buffer_.Size();
617 EmitRegImmType(REGIMM, rs, b, label->position_);
618 label->LinkTo(position);
619 }
620 }
621
622 static int32_t EncodeBranchOffset(int32_t offset, int32_t instr);
623 static int DecodeBranchOffset(int32_t instr);
624
499 void EmitBranchDelayNop() { 625 void EmitBranchDelayNop() {
500 Emit(Instr::kNopInstruction); // Branch delay NOP. 626 Emit(Instr::kNopInstruction); // Branch delay NOP.
501 delay_slot_available_ = true; 627 delay_slot_available_ = true;
502 } 628 }
503 629
504 DISALLOW_ALLOCATION(); 630 DISALLOW_ALLOCATION();
505 DISALLOW_COPY_AND_ASSIGN(Assembler); 631 DISALLOW_COPY_AND_ASSIGN(Assembler);
506 }; 632 };
507 633
508 } // namespace dart 634 } // namespace dart
509 635
510 #endif // VM_ASSEMBLER_MIPS_H_ 636 #endif // VM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698