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

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') | runtime/vm/assembler_mips.cc » ('J')
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 // Branch if equal.
247 void beq(Register rs, Register rt, Label* l) {
248 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
regis 2013/03/22 19:51:16 Either remove this comment or add it consistently
zra 2013/03/22 20:16:01 Done.
249 EmitBranch(BEQ, rs, rt, l);
250 EmitBranchDelayNop();
251 }
252
253 // Branch if equal, likely taken.
254 // Delay slot executed only when branch taken.
255 void beql(Register rs, Register rt, Label* l) {
256 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
257 EmitBranch(BEQL, rs, rt, l);
258 EmitBranchDelayNop();
259 }
260
261 // Brach if rs >= 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
262 void bgez(Register rs, Label* l) {
263 ASSERT(!in_delay_slot_);
264 EmitRegImmBranch(BGEZ, rs, l);
265 EmitBranchDelayNop();
266 }
267
268 // Branch if rs >= 0, likely taken.
269 // Delay slot executed only when branch taken.
270 void bgezl(Register rs, Label* l) {
271 ASSERT(!in_delay_slot_);
272 EmitRegImmBranch(BGEZL, rs, l);
273 EmitBranchDelayNop();
274 }
275
276 // Brach if rs > 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
277 void bgtz(Register rs, Label* l) {
278 ASSERT(!in_delay_slot_);
279 EmitBranch(BGTZ, rs, R0, l);
280 EmitBranchDelayNop();
281 }
282
283 // Branch if rs > 0, likely taken.
284 // Delay slot executed only when branch taken.
285 void bgtzl(Register rs, Label* l) {
286 ASSERT(!in_delay_slot_);
287 EmitBranch(BGTZL, rs, R0, l);
288 EmitBranchDelayNop();
289 }
290
291 // Brach if rs <= 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
292 void blez(Register rs, Label* l) {
293 ASSERT(!in_delay_slot_);
294 EmitBranch(BLEZ, rs, R0, l);
295 EmitBranchDelayNop();
296 }
297
298 // Branch if rs <= 0, likely taken.
299 // Delay slot executed only when branch taken.
300 void blezl(Register rs, Label* l) {
301 ASSERT(!in_delay_slot_);
302 EmitBranch(BLEZL, rs, R0, l);
303 EmitBranchDelayNop();
304 }
305
306 // Brach if rs < 0.
regis 2013/03/22 19:51:16 Branch
zra 2013/03/22 20:16:01 Done.
307 void bltz(Register rs, Label* l) {
308 ASSERT(!in_delay_slot_);
309 EmitRegImmBranch(BLTZ, rs, l);
310 EmitBranchDelayNop();
311 }
312
313 // Branch if rs < 0, likely taken.
314 // Delay slot executed only when branch taken.
315 void bltzl(Register rs, Label* l) {
316 ASSERT(!in_delay_slot_);
317 EmitRegImmBranch(BLTZL, rs, l);
318 EmitBranchDelayNop();
319 }
320
321 // Branch if not equal.
322 void bne(Register rs, Register rt, Label* l) {
323 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
324 EmitBranch(BNE, rs, rt, l);
325 EmitBranchDelayNop();
326 }
327
328 // Branch if not equal, likely taken.
329 // Delay slot executed only when branch taken.
330 void bnel(Register rs, Register rt, Label* l) {
331 ASSERT(!in_delay_slot_); // Jump within a delay slot is not supported.
332 EmitBranch(BNEL, rs, rt, l);
333 EmitBranchDelayNop();
334 }
335
248 void break_(int32_t code) { 336 void break_(int32_t code) {
249 ASSERT(Utils::IsUint(20, code)); 337 ASSERT(Utils::IsUint(20, code));
250 Emit(SPECIAL << kOpcodeShift | 338 Emit(SPECIAL << kOpcodeShift |
251 code << kBreakCodeShift | 339 code << kBreakCodeShift |
252 BREAK << kFunctionShift); 340 BREAK << kFunctionShift);
253 } 341 }
254 342
255 void clo(Register rd, Register rs) { 343 void clo(Register rd, Register rs) {
256 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO); 344 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO);
257 } 345 }
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 483
396 void sw(Register rt, const Address& addr) { 484 void sw(Register rt, const Address& addr) {
397 EmitLoadStore(SW, rt, addr); 485 EmitLoadStore(SW, rt, addr);
398 } 486 }
399 487
400 void xor_(Register rd, Register rs, Register rt) { 488 void xor_(Register rd, Register rs, Register rt) {
401 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); 489 EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
402 } 490 }
403 491
404 // Macros in alphabetical order. 492 // Macros in alphabetical order.
493
494 // Unconditional branch.
495 void B(Label* l) {
regis 2013/03/22 19:51:16 I would use a lower case 'b', since the MIPS assem
zra 2013/03/22 20:16:01 That makes sense. I've made it lowercase and moved
496 beq(R0, R0, l);
497 }
498
405 void LoadImmediate(Register rd, int32_t value) { 499 void LoadImmediate(Register rd, int32_t value) {
406 if (Utils::IsInt(16, value)) { 500 if (Utils::IsInt(16, value)) {
407 addiu(rd, ZR, Immediate(value)); 501 addiu(rd, ZR, Immediate(value));
408 } else { 502 } else {
409 lui(rd, Immediate((value >> 16) & 0xffff)); 503 lui(rd, Immediate((value >> 16) & 0xffff));
410 ori(rd, rd, Immediate(value & 0xffff)); 504 ori(rd, rd, Immediate(value & 0xffff));
411 } 505 }
412 } 506 }
413 507
414 void Move(Register rd, Register rs) { 508 void Move(Register rd, Register rs) {
regis 2013/03/22 19:51:16 This one is debatable, but this is also a pseudo i
zra 2013/03/22 20:16:01 I've made it mov, and moved it up, too, since mov
415 or_(rd, rs, ZR); 509 or_(rd, rs, ZR);
416 } 510 }
417 511
512 void Nop() {
regis 2013/03/22 19:51:16 nop?
zra 2013/03/22 20:16:01 Same as with mov.
513 Emit(Instr::kNopInstruction);
514 }
515
418 private: 516 private:
419 AssemblerBuffer buffer_; 517 AssemblerBuffer buffer_;
420 GrowableObjectArray& object_pool_; // Objects and patchable jump targets. 518 GrowableObjectArray& object_pool_; // Objects and patchable jump targets.
421 int prologue_offset_; 519 int prologue_offset_;
422 520
423 bool delay_slot_available_; 521 bool delay_slot_available_;
424 bool in_delay_slot_; 522 bool in_delay_slot_;
425 523
426 class CodeComment : public ZoneAllocated { 524 class CodeComment : public ZoneAllocated {
427 public: 525 public:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 SpecialFunction func) { 587 SpecialFunction func) {
490 ASSERT(Utils::IsUint(5, sa)); 588 ASSERT(Utils::IsUint(5, sa));
491 Emit(opcode << kOpcodeShift | 589 Emit(opcode << kOpcodeShift |
492 rs << kRsShift | 590 rs << kRsShift |
493 rt << kRtShift | 591 rt << kRtShift |
494 rd << kRdShift | 592 rd << kRdShift |
495 sa << kSaShift | 593 sa << kSaShift |
496 func << kFunctionShift); 594 func << kFunctionShift);
497 } 595 }
498 596
597 void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
598 if (label->IsBound()) {
599 uint16_t dest = EncodeBranchOffset(label->Position() - buffer_.Size(), 0);
600 EmitIType(b, rs, rt, dest);
601 } else {
602 int position = buffer_.Size();
603 EmitIType(b, rs, rt, label->position_);
604 label->LinkTo(position);
605 }
606 }
607
608 void EmitRegImmBranch(RtRegImm b, Register rs, Label* label) {
609 if (label->IsBound()) {
610 uint16_t dest = EncodeBranchOffset(label->Position() - buffer_.Size(), 0);
611 EmitRegImmType(REGIMM, rs, b, dest);
612 } else {
613 int position = buffer_.Size();
614 EmitRegImmType(REGIMM, rs, b, label->position_);
615 label->LinkTo(position);
616 }
617 }
618
619 static int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
regis 2013/03/22 19:51:16 inst -> instr
zra 2013/03/22 20:16:01 Done.
620 static int DecodeBranchOffset(int32_t inst);
regis 2013/03/22 19:51:16 inst -> instr
zra 2013/03/22 20:16:01 Done.
621
499 void EmitBranchDelayNop() { 622 void EmitBranchDelayNop() {
500 Emit(Instr::kNopInstruction); // Branch delay NOP. 623 Emit(Instr::kNopInstruction); // Branch delay NOP.
501 delay_slot_available_ = true; 624 delay_slot_available_ = true;
502 } 625 }
503 626
504 DISALLOW_ALLOCATION(); 627 DISALLOW_ALLOCATION();
505 DISALLOW_COPY_AND_ASSIGN(Assembler); 628 DISALLOW_COPY_AND_ASSIGN(Assembler);
506 }; 629 };
507 630
508 } // namespace dart 631 } // namespace dart
509 632
510 #endif // VM_ASSEMBLER_MIPS_H_ 633 #endif // VM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | runtime/vm/assembler_mips.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698