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

Side by Side Diff: runtime/vm/simulator_mips.cc

Issue 12519007: Adds MIPS instructions to 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
« runtime/vm/disassembler_mips.cc ('K') | « runtime/vm/simulator_mips.h ('k') | no next file » | 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 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 // Only build the simulator if not compiling for real MIPS hardware. 8 // Only build the simulator if not compiling for real MIPS hardware.
9 #if !defined(HOST_ARCH_MIPS) 9 #if !defined(HOST_ARCH_MIPS)
10 10
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer); 94 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
95 } 95 }
96 96
97 97
98 void Simulator::Format(Instr* instr, const char* format) { 98 void Simulator::Format(Instr* instr, const char* format) {
99 OS::PrintErr("Simulator - unknown instruction: %s\n", format); 99 OS::PrintErr("Simulator - unknown instruction: %s\n", format);
100 UNIMPLEMENTED(); 100 UNIMPLEMENTED();
101 } 101 }
102 102
103 103
104 int8_t Simulator::ReadB(uword addr) {
105 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
106 return *ptr;
107 }
108
109
110 uint8_t Simulator::ReadBU(uword addr) {
111 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
112 return *ptr;
113 }
114
115
116 int16_t Simulator::ReadH(uword addr, Instr* instr) {
117 if ((addr & 1) == 0) {
118 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
119 return *ptr;
120 }
121 // TODO(zra) unaligned access. Trap into debugger.
Ivan Posva 2013/03/11 17:29:04 Please use UNIMPLEMENTED() until it is. ditto bel
zra 2013/03/11 18:36:06 Done.
122 return 0;
123 }
124
125
126 uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
127 if ((addr & 1) == 0) {
128 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
129 return *ptr;
130 }
131 // TODO(zra) unaligned access. Trap into debugger.
132 return 0;
133 }
134
135
136 int Simulator::ReadW(uword addr, Instr* instr) {
137 if ((addr & 3) == 0) {
138 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
139 return *ptr;
140 }
141 // TODO(zra) unaligned access. Trap into debugger.
142 return 0;
143 }
144
145
146 void Simulator::WriteB(uword addr, uint8_t value) {
147 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
148 *ptr = value;
149 }
150
151
152 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
153 if ((addr & 1) == 0) {
154 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
155 *ptr = value;
156 }
157 // TODO(zra) unaligned access. Trap into debugger.
158 }
159
160
161 void Simulator::WriteW(uword addr, int value, Instr* instr) {
162 if ((addr & 3) == 0) {
163 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
164 *ptr = value;
165 return;
166 }
167 // TODO(zra) unaligned access. Trap into debugger.
168 }
169
170
104 bool Simulator::OverflowFrom(int32_t alu_out, 171 bool Simulator::OverflowFrom(int32_t alu_out,
105 int32_t left, int32_t right, bool addition) { 172 int32_t left, int32_t right, bool addition) {
106 bool overflow; 173 bool overflow;
107 if (addition) { 174 if (addition) {
108 // Operands have the same sign. 175 // Operands have the same sign.
109 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) 176 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
110 // And operands and result have different sign. 177 // And operands and result have different sign.
111 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 178 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
112 } else { 179 } else {
113 // Operands have different signs. 180 // Operands have different signs.
114 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) 181 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
115 // And first operand and result have different signs. 182 // And first operand and result have different signs.
116 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 183 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
117 } 184 }
118 return overflow; 185 return overflow;
119 } 186 }
120 187
121 188
122 void Simulator::DecodeSpecial(Instr* instr) { 189 void Simulator::DecodeSpecial(Instr* instr) {
190 ASSERT(instr->OpcodeField() == SPECIAL);
123 switch (instr->FunctionField()) { 191 switch (instr->FunctionField()) {
124 case ADDU: { 192 case ADDU: {
125 ASSERT(instr->SaField() == 0); 193 ASSERT(instr->SaField() == 0);
126 // Format(instr, "addu 'rd, 'rs, 'rt"); 194 // Format(instr, "addu 'rd, 'rs, 'rt");
127 int32_t rs_val = get_register(instr->RsField()); 195 int32_t rs_val = get_register(instr->RsField());
128 int32_t rt_val = get_register(instr->RtField()); 196 int32_t rt_val = get_register(instr->RtField());
129 set_register(instr->RdField(), rs_val + rt_val); 197 set_register(instr->RdField(), rs_val + rt_val);
130 break; 198 break;
131 } 199 }
132 case AND: { 200 case AND: {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 default: { 290 default: {
223 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); 291 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits());
224 UNREACHABLE(); 292 UNREACHABLE();
225 break; 293 break;
226 } 294 }
227 } 295 }
228 } 296 }
229 297
230 298
231 void Simulator::DecodeSpecial2(Instr* instr) { 299 void Simulator::DecodeSpecial2(Instr* instr) {
300 ASSERT(instr->OpcodeField() == SPECIAL2);
232 switch (instr->FunctionField()) { 301 switch (instr->FunctionField()) {
233 case CLO: { 302 case CLO: {
234 ASSERT(instr->SaField() == 0); 303 ASSERT(instr->SaField() == 0);
235 ASSERT(instr->RtField() == instr->RdField()); 304 ASSERT(instr->RtField() == instr->RdField());
236 // Format(instr, "clo 'rd, 'rs"); 305 // Format(instr, "clo 'rd, 'rs");
237 int32_t rs_val = get_register(instr->RsField()); 306 int32_t rs_val = get_register(instr->RsField());
238 int32_t bitcount = 0; 307 int32_t bitcount = 0;
239 while (rs_val < 0) { 308 while (rs_val < 0) {
240 bitcount++; 309 bitcount++;
241 rs_val <<= 1; 310 rs_val <<= 1;
(...skipping 20 matching lines...) Expand all
262 } 331 }
263 default: { 332 default: {
264 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); 333 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits());
265 UNREACHABLE(); 334 UNREACHABLE();
266 break; 335 break;
267 } 336 }
268 } 337 }
269 } 338 }
270 339
271 340
341 void Simulator::DecodeSpecial3(Instr* instr) {
342 ASSERT(instr->OpcodeField() == SPECIAL3);
343 switch (instr->FunctionField()) {
344 case EXT: {
345 int32_t rs_val = get_register(instr->RsField());
346 int32_t pos = instr->SaField();
347 int32_t size = instr->Bits(11, 5) + 1;
Ivan Posva 2013/03/11 17:29:04 What are Bits(11,5)? In the assembler you did cast
348 ASSERT((0 < pos + size) && (pos + size <=32));
regis 2013/03/11 17:31:11 Use Utils::IsUint. See my other comments.
349
350 int32_t mask = ((1 << size) - 1) << (pos - 1);
regis 2013/03/11 17:31:11 It should be pos, instead of pos - 1.
351 set_register(instr->RtField(), (rs_val & mask) >> (pos - 1));
352 break;
353 }
354 case INS: {
355 int32_t rs_val = get_register(instr->RsField());
356 int32_t rt_val = get_register(instr->RtField());
357 int32_t pos = instr->SaField();
358 int32_t size = instr->Bits(11, 5) - pos + 1;
Ivan Posva 2013/03/11 17:29:04 ditto.
359 ASSERT((0 < pos + size) && (pos + size <=32));
regis 2013/03/11 17:31:11 Use Utils::IsUint.
360
361 int32_t rs_mask = ((1 << size) - 1);
regis 2013/03/11 17:31:11 Outer () not needed.
362 int32_t rt_mask = rs_mask << (pos - 1);
regis 2013/03/11 17:31:11 pos, not pos - 1.
363 int32_t rt_tmp = rt_val & ~rt_mask;
364 set_register(instr->RtField(),
365 rt_tmp | ((rs_val & rs_mask) << (pos - 1)));
regis 2013/03/11 17:31:11 pos, not pos - 1.
366 break;
367 }
368 default: {
369 OS::PrintErr("DecodeSpecial3: 0x%x\n", instr->InstructionBits());
370 UNREACHABLE();
371 break;
372 }
373 }
374 }
375
376
272 void Simulator::InstructionDecode(Instr* instr) { 377 void Simulator::InstructionDecode(Instr* instr) {
273 switch (instr->OpcodeField()) { 378 switch (instr->OpcodeField()) {
274 case SPECIAL: { 379 case SPECIAL: {
275 DecodeSpecial(instr); 380 DecodeSpecial(instr);
276 break; 381 break;
277 } 382 }
278 case SPECIAL2: { 383 case SPECIAL2: {
279 DecodeSpecial2(instr); 384 DecodeSpecial2(instr);
280 break; 385 break;
281 } 386 }
387 case SPECIAL3: {
388 DecodeSpecial3(instr);
389 break;
390 }
282 case ADDI: { 391 case ADDI: {
283 // Format(instr, "addi 'rt, 'rs, 'immu"); 392 // Format(instr, "addi 'rt, 'rs, 'imms");
284 int32_t rs_val = get_register(instr->RsField()); 393 int32_t rs_val = get_register(instr->RsField());
285 int32_t imm_val = instr->SImmField(); 394 int32_t imm_val = instr->SImmField();
286 int32_t res = rs_val + imm_val; 395 int32_t res = rs_val + imm_val;
287 // Rt is not set on overflow. 396 // Rt is not set on overflow.
288 if (!OverflowFrom(res, rs_val, imm_val, true)) { 397 if (!OverflowFrom(res, rs_val, imm_val, true)) {
289 set_register(instr->RtField(), res); 398 set_register(instr->RtField(), res);
290 } 399 }
400 // TODO(zra): trap into debugger on overflow.
Ivan Posva 2013/03/11 17:29:04 Personally I would remove this instruction entirel
zra 2013/03/11 18:36:06 Done.
291 break; 401 break;
292 } 402 }
293 case ADDIU: { 403 case ADDIU: {
294 // Format(instr, "addiu 'rt, 'rs, 'immu"); 404 // Format(instr, "addiu 'rt, 'rs, 'imms");
295 int32_t rs_val = get_register(instr->RsField()); 405 int32_t rs_val = get_register(instr->RsField());
296 int32_t imm_val = instr->SImmField(); 406 int32_t imm_val = instr->SImmField();
297 int32_t res = rs_val + imm_val; 407 int32_t res = rs_val + imm_val;
298 // Rt is set even on overflow. 408 // Rt is set even on overflow.
299 set_register(instr->RtField(), res); 409 set_register(instr->RtField(), res);
300 break; 410 break;
301 } 411 }
302 case ANDI: { 412 case ANDI: {
303 // Format(instr, "andi 'rt, 'rs, 'immu"); 413 // Format(instr, "andi 'rt, 'rs, 'immu");
304 int32_t rs_val = get_register(instr->RsField()); 414 int32_t rs_val = get_register(instr->RsField());
305 set_register(instr->RtField(), rs_val & instr->UImmField()); 415 set_register(instr->RtField(), rs_val & instr->UImmField());
306 break; 416 break;
307 } 417 }
418 case LB: {
419 // Format(instr, "lb 'rt, 'imms('rs)");
420 int32_t base_val = get_register(instr->RsField());
421 int32_t imm_val = instr->SImmField();
422 uword addr = base_val + imm_val;
423 if (Simulator::IsIllegalAddress(addr)) {
424 // TODO(zra) trap into debugger.
Ivan Posva 2013/03/11 17:29:04 UNIMPLEMENTED() here and other places.
zra 2013/03/11 18:36:06 Done.
425 } else {
426 int32_t res = ReadB(addr);
427 set_register(instr->RtField(), res);
428 }
429 break;
430 }
431 case LBU: {
432 // Format(instr, "lbu 'rt, 'imms('rs)");
433 int32_t base_val = get_register(instr->RsField());
434 int32_t imm_val = instr->SImmField();
435 uword addr = base_val + imm_val;
436 if (Simulator::IsIllegalAddress(addr)) {
437 // TODO(zra) trap into debugger.
438 } else {
439 int32_t res = ReadBU(addr);
440 set_register(instr->RtField(), res);
441 }
442 break;
443 }
444 case LH: {
445 // Format(instr, "lh 'rt, 'imms('rs)");
446 int32_t base_val = get_register(instr->RsField());
447 int32_t imm_val = instr->SImmField();
448 uword addr = base_val + imm_val;
449 if (Simulator::IsIllegalAddress(addr)) {
450 // TODO(zra) trap into debugger.
451 } else {
452 int32_t res = ReadH(addr, instr);
453 set_register(instr->RtField(), res);
454 }
455 break;
456 }
457 case LHU: {
458 // Format(instr, "lhu 'rt, 'imms('rs)");
459 int32_t base_val = get_register(instr->RsField());
460 int32_t imm_val = instr->SImmField();
461 uword addr = base_val + imm_val;
462 if (Simulator::IsIllegalAddress(addr)) {
463 // TODO(zra) trap into debugger.
464 } else {
465 int32_t res = ReadHU(addr, instr);
466 set_register(instr->RtField(), res);
467 }
468 break;
469 }
308 case LUI: { 470 case LUI: {
309 ASSERT(instr->RsField() == 0); 471 ASSERT(instr->RsField() == 0);
310 set_register(instr->RtField(), instr->UImmField() << 16); 472 set_register(instr->RtField(), instr->UImmField() << 16);
311 break; 473 break;
312 } 474 }
475 case LW: {
476 // Format(instr, "lw 'rt, 'imms('rs)");
477 int32_t base_val = get_register(instr->RsField());
478 int32_t imm_val = instr->SImmField();
479 uword addr = base_val + imm_val;
480 if (Simulator::IsIllegalAddress(addr)) {
481 // TODO(zra) trap into debugger.
482 } else {
483 int32_t res = ReadW(addr, instr);
484 set_register(instr->RtField(), res);
485 }
486 break;
487 }
313 case ORI: { 488 case ORI: {
314 // Format(instr, "ori 'rt, 'rs, 'immu"); 489 // Format(instr, "ori 'rt, 'rs, 'immu");
315 int32_t rs_val = get_register(instr->RsField()); 490 int32_t rs_val = get_register(instr->RsField());
316 set_register(instr->RtField(), rs_val | instr->UImmField()); 491 set_register(instr->RtField(), rs_val | instr->UImmField());
317 break; 492 break;
318 } 493 }
494 case SB: {
495 // Format(instr, "sb 'rt, 'imms('rs)");
496 int32_t rt_val = get_register(instr->RtField());
497 int32_t base_val = get_register(instr->RsField());
498 int32_t imm_val = instr->SImmField();
499 uword addr = base_val + imm_val;
500 if (Simulator::IsIllegalAddress(addr)) {
501 // TODO(zra) trap into debugger.
502 } else {
503 WriteB(addr, rt_val & 0xff);
504 }
505 break;
506 }
507 case SH: {
508 // Format(instr, "sh 'rt, 'imms('rs)");
509 int32_t rt_val = get_register(instr->RtField());
510 int32_t base_val = get_register(instr->RsField());
511 int32_t imm_val = instr->SImmField();
512 uword addr = base_val + imm_val;
513 if (Simulator::IsIllegalAddress(addr)) {
514 // TODO(zra) trap into debugger.
515 } else {
516 WriteH(addr, rt_val & 0xffff, instr);
517 }
518 break;
519 }
520 case SW: {
521 // Format(instr, "sw 'rt, 'imms('rs)");
522 int32_t rt_val = get_register(instr->RtField());
523 int32_t base_val = get_register(instr->RsField());
524 int32_t imm_val = instr->SImmField();
525 uword addr = base_val + imm_val;
526 if (Simulator::IsIllegalAddress(addr)) {
527 // TODO(zra) trap into debugger.
528 } else {
529 WriteW(addr, rt_val, instr);
530 }
531 break;
532 }
319 default: { 533 default: {
320 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits()); 534 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits());
321 UNREACHABLE(); 535 UNREACHABLE();
322 break; 536 break;
323 } 537 }
324 } 538 }
325 pc_ += Instr::kInstrSize; 539 pc_ += Instr::kInstrSize;
326 } 540 }
327 541
328 542
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Restore the SP register and return R1:R0. 657 // Restore the SP register and return R1:R0.
444 set_register(SP, sp_before_call); 658 set_register(SP, sp_before_call);
445 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); 659 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
446 } 660 }
447 661
448 } // namespace dart 662 } // namespace dart
449 663
450 #endif // !defined(HOST_ARCH_MIPS) 664 #endif // !defined(HOST_ARCH_MIPS)
451 665
452 #endif // defined TARGET_ARCH_MIPS 666 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« runtime/vm/disassembler_mips.cc ('K') | « runtime/vm/simulator_mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698