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

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

Issue 14672037: Implements FPU compare and branching for MIPS simulator, assembler, disassembler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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_test.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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 ASSERT(EvenFPURegister(ft)); 236 ASSERT(EvenFPURegister(ft));
237 EmitFpuRType(COP1, FMT_D, ft, fs, fd, COP1_ADD); 237 EmitFpuRType(COP1, FMT_D, ft, fs, fd, COP1_ADD);
238 } 238 }
239 239
240 void addiu(Register rt, Register rs, const Immediate& imm) { 240 void addiu(Register rt, Register rs, const Immediate& imm) {
241 ASSERT(Utils::IsInt(kImmBits, imm.value())); 241 ASSERT(Utils::IsInt(kImmBits, imm.value()));
242 const uint16_t imm_value = static_cast<uint16_t>(imm.value()); 242 const uint16_t imm_value = static_cast<uint16_t>(imm.value());
243 EmitIType(ADDIU, rs, rt, imm_value); 243 EmitIType(ADDIU, rs, rt, imm_value);
244 } 244 }
245 245
246 void adds(FRegister fd, FRegister fs, FRegister ft) {
247 EmitFpuRType(COP1, FMT_S, ft, fs, fd, COP1_ADD);
248 }
249
250 void addu(Register rd, Register rs, Register rt) { 246 void addu(Register rd, Register rs, Register rt) {
251 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); 247 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
252 } 248 }
253 249
254 void and_(Register rd, Register rs, Register rt) { 250 void and_(Register rd, Register rs, Register rt) {
255 EmitRType(SPECIAL, rs, rt, rd, 0, AND); 251 EmitRType(SPECIAL, rs, rt, rd, 0, AND);
256 } 252 }
257 253
258 void andi(Register rt, Register rs, const Immediate& imm) { 254 void andi(Register rt, Register rs, const Immediate& imm) {
259 ASSERT(Utils::IsUint(kImmBits, imm.value())); 255 ASSERT(Utils::IsUint(kImmBits, imm.value()));
260 const uint16_t imm_value = static_cast<uint16_t>(imm.value()); 256 const uint16_t imm_value = static_cast<uint16_t>(imm.value());
261 EmitIType(ANDI, rs, rt, imm_value); 257 EmitIType(ANDI, rs, rt, imm_value);
262 } 258 }
263 259
264 // Unconditional branch. 260 // Unconditional branch.
265 void b(Label* l) { 261 void b(Label* l) {
266 beq(R0, R0, l); 262 beq(R0, R0, l);
267 } 263 }
268 264
269 void bal(Label *l) { 265 void bal(Label *l) {
270 ASSERT(!in_delay_slot_); 266 ASSERT(!in_delay_slot_);
271 EmitRegImmBranch(BGEZAL, R0, l); 267 EmitRegImmBranch(BGEZAL, R0, l);
272 EmitBranchDelayNop(); 268 EmitBranchDelayNop();
273 } 269 }
274 270
271 // Branch on floating point false.
272 void bc1f(Label* l) {
273 EmitFpuBranch(false, l);
274 EmitBranchDelayNop();
275 }
276
277 // Branch on floating point true.
278 void bc1t(Label* l) {
279 EmitFpuBranch(true, l);
280 EmitBranchDelayNop();
281 }
282
275 // Branch if equal. 283 // Branch if equal.
276 void beq(Register rs, Register rt, Label* l) { 284 void beq(Register rs, Register rt, Label* l) {
277 ASSERT(!in_delay_slot_); 285 ASSERT(!in_delay_slot_);
278 EmitBranch(BEQ, rs, rt, l); 286 EmitBranch(BEQ, rs, rt, l);
279 EmitBranchDelayNop(); 287 EmitBranchDelayNop();
280 } 288 }
281 289
282 // Branch if equal, likely taken. 290 // Branch if equal, likely taken.
283 // Delay slot executed only when branch taken. 291 // Delay slot executed only when branch taken.
284 void beql(Register rs, Register rt, Label* l) { 292 void beql(Register rs, Register rt, Label* l) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 EmitBranchDelayNop(); 370 EmitBranchDelayNop();
363 } 371 }
364 372
365 void break_(int32_t code) { 373 void break_(int32_t code) {
366 ASSERT(Utils::IsUint(20, code)); 374 ASSERT(Utils::IsUint(20, code));
367 Emit(SPECIAL << kOpcodeShift | 375 Emit(SPECIAL << kOpcodeShift |
368 code << kBreakCodeShift | 376 code << kBreakCodeShift |
369 BREAK << kFunctionShift); 377 BREAK << kFunctionShift);
370 } 378 }
371 379
380 // FPU compare, always false.
381 void cfd(FRegister fs, FRegister ft) {
382 ASSERT(EvenFPURegister(fs));
383 ASSERT(EvenFPURegister(ft));
384 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_F);
385 }
386
387 // FPU compare, true if unordered, i.e. one is NaN.
388 void cund(FRegister fs, FRegister ft) {
389 ASSERT(EvenFPURegister(fs));
390 ASSERT(EvenFPURegister(ft));
391 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_UN);
392 }
393
394 // FPU compare, true if equal.
395 void ceqd(FRegister fs, FRegister ft) {
396 ASSERT(EvenFPURegister(fs));
397 ASSERT(EvenFPURegister(ft));
398 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_EQ);
399 }
400
401 // FPU compare, true if unordered or equal.
402 void cueqd(FRegister fs, FRegister ft) {
403 ASSERT(EvenFPURegister(fs));
404 ASSERT(EvenFPURegister(ft));
405 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_UEQ);
406 }
407
408 // FPU compare, true if less than.
409 void coltd(FRegister fs, FRegister ft) {
410 ASSERT(EvenFPURegister(fs));
411 ASSERT(EvenFPURegister(ft));
412 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_OLT);
413 }
414
415 // FPU compare, true if unordered or less than.
416 void cultd(FRegister fs, FRegister ft) {
417 ASSERT(EvenFPURegister(fs));
418 ASSERT(EvenFPURegister(ft));
419 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_ULT);
420 }
421
422 // FPU compare, true if less or equal.
423 void coled(FRegister fs, FRegister ft) {
424 ASSERT(EvenFPURegister(fs));
425 ASSERT(EvenFPURegister(ft));
426 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_OLE);
427 }
428
429 // FPU compare, true if unordered or less or equal.
430 void culed(FRegister fs, FRegister ft) {
431 ASSERT(EvenFPURegister(fs));
432 ASSERT(EvenFPURegister(ft));
433 EmitFpuRType(COP1, FMT_D, ft, fs, F0, COP1_C_ULE);
434 }
435
372 void clo(Register rd, Register rs) { 436 void clo(Register rd, Register rs) {
373 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO); 437 EmitRType(SPECIAL2, rs, rd, rd, 0, CLO);
374 } 438 }
375 439
376 void clz(Register rd, Register rs) { 440 void clz(Register rd, Register rs) {
377 EmitRType(SPECIAL2, rs, rd, rd, 0, CLZ); 441 EmitRType(SPECIAL2, rs, rd, rd, 0, CLZ);
378 } 442 }
379 443
380 void div(Register rs, Register rt) { 444 void div(Register rs, Register rt) {
381 EmitRType(SPECIAL, rs, rt, R0, 0, DIV); 445 EmitRType(SPECIAL, rs, rt, R0, 0, DIV);
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 const uint16_t dest_off = EncodeBranchOffset(dest, 0); 1051 const uint16_t dest_off = EncodeBranchOffset(dest, 0);
988 EmitRegImmType(REGIMM, rs, b, dest_off); 1052 EmitRegImmType(REGIMM, rs, b, dest_off);
989 } else { 1053 } else {
990 const int position = buffer_.Size(); 1054 const int position = buffer_.Size();
991 const uint16_t dest_off = EncodeBranchOffset(label->position_, 0); 1055 const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
992 EmitRegImmType(REGIMM, rs, b, dest_off); 1056 EmitRegImmType(REGIMM, rs, b, dest_off);
993 label->LinkTo(position); 1057 label->LinkTo(position);
994 } 1058 }
995 } 1059 }
996 1060
1061 void EmitFpuBranch(bool kind, Label *label) {
1062 const int32_t b16 = kind ? (1 << 16) : 0; // Bit 16 set for branch on true.
1063 if (label->IsBound()) {
1064 // Relative destination from an instruction after the branch.
1065 const int32_t dest =
1066 label->Position() - (buffer_.Size() + Instr::kInstrSize);
1067 const uint16_t dest_off = EncodeBranchOffset(dest, 0);
1068 Emit(COP1 << kOpcodeShift |
1069 COP1_BC << kCop1SubShift |
1070 b16 |
1071 dest_off);
1072 } else {
1073 const int position = buffer_.Size();
1074 const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
1075 Emit(COP1 << kOpcodeShift |
1076 COP1_BC << kCop1SubShift |
1077 b16 |
1078 dest_off);
1079 label->LinkTo(position);
1080 }
1081 }
1082
997 static int32_t EncodeBranchOffset(int32_t offset, int32_t instr); 1083 static int32_t EncodeBranchOffset(int32_t offset, int32_t instr);
998 static int DecodeBranchOffset(int32_t instr); 1084 static int DecodeBranchOffset(int32_t instr);
999 1085
1000 void EmitBranchDelayNop() { 1086 void EmitBranchDelayNop() {
1001 Emit(Instr::kNopInstruction); // Branch delay NOP. 1087 Emit(Instr::kNopInstruction); // Branch delay NOP.
1002 delay_slot_available_ = true; 1088 delay_slot_available_ = true;
1003 } 1089 }
1004 1090
1005 void StoreIntoObjectFilter(Register object, Register value, Label* no_update); 1091 void StoreIntoObjectFilter(Register object, Register value, Label* no_update);
1006 1092
1007 // Shorter filtering sequence that assumes that value is not a smi. 1093 // Shorter filtering sequence that assumes that value is not a smi.
1008 void StoreIntoObjectFilterNoSmi(Register object, 1094 void StoreIntoObjectFilterNoSmi(Register object,
1009 Register value, 1095 Register value,
1010 Label* no_update); 1096 Label* no_update);
1011 1097
1012 DISALLOW_ALLOCATION(); 1098 DISALLOW_ALLOCATION();
1013 DISALLOW_COPY_AND_ASSIGN(Assembler); 1099 DISALLOW_COPY_AND_ASSIGN(Assembler);
1014 }; 1100 };
1015 1101
1016 } // namespace dart 1102 } // namespace dart
1017 1103
1018 #endif // VM_ASSEMBLER_MIPS_H_ 1104 #endif // VM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698