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

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.
122 UNIMPLEMENTED();
123 return 0;
124 }
125
126
127 uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
128 if ((addr & 1) == 0) {
129 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
130 return *ptr;
131 }
132 // TODO(zra) unaligned access. Trap into debugger.
133 UNIMPLEMENTED();
134 return 0;
135 }
136
137
138 int Simulator::ReadW(uword addr, Instr* instr) {
139 if ((addr & 3) == 0) {
140 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
141 return *ptr;
142 }
143 // TODO(zra) unaligned access. Trap into debugger.
144 UNIMPLEMENTED();
145 return 0;
146 }
147
148
149 void Simulator::WriteB(uword addr, uint8_t value) {
150 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
151 *ptr = value;
152 }
153
154
155 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
156 if ((addr & 1) == 0) {
157 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
158 *ptr = value;
159 return;
160 }
161 // TODO(zra) unaligned access. Trap into debugger.
162 UNIMPLEMENTED();
163 }
164
165
166 void Simulator::WriteW(uword addr, int value, Instr* instr) {
167 if ((addr & 3) == 0) {
168 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
169 *ptr = value;
170 return;
171 }
172 // TODO(zra) unaligned access. Trap into debugger.
173 UNIMPLEMENTED();
174 }
175
176
104 bool Simulator::OverflowFrom(int32_t alu_out, 177 bool Simulator::OverflowFrom(int32_t alu_out,
105 int32_t left, int32_t right, bool addition) { 178 int32_t left, int32_t right, bool addition) {
106 bool overflow; 179 bool overflow;
107 if (addition) { 180 if (addition) {
108 // Operands have the same sign. 181 // Operands have the same sign.
109 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0)) 182 overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
110 // And operands and result have different sign. 183 // And operands and result have different sign.
111 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 184 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
112 } else { 185 } else {
113 // Operands have different signs. 186 // Operands have different signs.
114 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) 187 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
115 // And first operand and result have different signs. 188 // And first operand and result have different signs.
116 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 189 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
117 } 190 }
118 return overflow; 191 return overflow;
119 } 192 }
120 193
121 194
122 void Simulator::DecodeSpecial(Instr* instr) { 195 void Simulator::DecodeSpecial(Instr* instr) {
196 ASSERT(instr->OpcodeField() == SPECIAL);
123 switch (instr->FunctionField()) { 197 switch (instr->FunctionField()) {
124 case ADDU: { 198 case ADDU: {
125 ASSERT(instr->SaField() == 0); 199 ASSERT(instr->SaField() == 0);
126 // Format(instr, "addu 'rd, 'rs, 'rt"); 200 // Format(instr, "addu 'rd, 'rs, 'rt");
127 int32_t rs_val = get_register(instr->RsField()); 201 int32_t rs_val = get_register(instr->RsField());
128 int32_t rt_val = get_register(instr->RtField()); 202 int32_t rt_val = get_register(instr->RtField());
129 set_register(instr->RdField(), rs_val + rt_val); 203 set_register(instr->RdField(), rs_val + rt_val);
130 break; 204 break;
131 } 205 }
132 case AND: { 206 case AND: {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 default: { 296 default: {
223 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits()); 297 OS::PrintErr("DecodeSpecial: 0x%x\n", instr->InstructionBits());
224 UNREACHABLE(); 298 UNREACHABLE();
225 break; 299 break;
226 } 300 }
227 } 301 }
228 } 302 }
229 303
230 304
231 void Simulator::DecodeSpecial2(Instr* instr) { 305 void Simulator::DecodeSpecial2(Instr* instr) {
306 ASSERT(instr->OpcodeField() == SPECIAL2);
232 switch (instr->FunctionField()) { 307 switch (instr->FunctionField()) {
233 case CLO: { 308 case CLO: {
234 ASSERT(instr->SaField() == 0); 309 ASSERT(instr->SaField() == 0);
235 ASSERT(instr->RtField() == instr->RdField()); 310 ASSERT(instr->RtField() == instr->RdField());
236 // Format(instr, "clo 'rd, 'rs"); 311 // Format(instr, "clo 'rd, 'rs");
237 int32_t rs_val = get_register(instr->RsField()); 312 int32_t rs_val = get_register(instr->RsField());
238 int32_t bitcount = 0; 313 int32_t bitcount = 0;
239 while (rs_val < 0) { 314 while (rs_val < 0) {
240 bitcount++; 315 bitcount++;
241 rs_val <<= 1; 316 rs_val <<= 1;
(...skipping 20 matching lines...) Expand all
262 } 337 }
263 default: { 338 default: {
264 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits()); 339 OS::PrintErr("DecodeSpecial2: 0x%x\n", instr->InstructionBits());
265 UNREACHABLE(); 340 UNREACHABLE();
266 break; 341 break;
267 } 342 }
268 } 343 }
269 } 344 }
270 345
271 346
347 void Simulator::DecodeSpecial3(Instr* instr) {
348 ASSERT(instr->OpcodeField() == SPECIAL3);
349 switch (instr->FunctionField()) {
350 default: {
351 OS::PrintErr("DecodeSpecial3: 0x%x\n", instr->InstructionBits());
352 UNREACHABLE();
353 break;
354 }
355 }
356 }
357
358
272 void Simulator::InstructionDecode(Instr* instr) { 359 void Simulator::InstructionDecode(Instr* instr) {
273 switch (instr->OpcodeField()) { 360 switch (instr->OpcodeField()) {
274 case SPECIAL: { 361 case SPECIAL: {
275 DecodeSpecial(instr); 362 DecodeSpecial(instr);
276 break; 363 break;
277 } 364 }
278 case SPECIAL2: { 365 case SPECIAL2: {
279 DecodeSpecial2(instr); 366 DecodeSpecial2(instr);
280 break; 367 break;
281 } 368 }
282 case ADDI: { 369 case SPECIAL3: {
283 // Format(instr, "addi 'rt, 'rs, 'immu"); 370 DecodeSpecial3(instr);
371 break;
372 }
373 case ADDIU: {
374 // Format(instr, "addiu 'rt, 'rs, 'imms");
284 int32_t rs_val = get_register(instr->RsField()); 375 int32_t rs_val = get_register(instr->RsField());
285 int32_t imm_val = instr->SImmField(); 376 int32_t imm_val = instr->SImmField();
286 int32_t res = rs_val + imm_val; 377 int32_t res = rs_val + imm_val;
287 // Rt is not set on overflow.
288 if (!OverflowFrom(res, rs_val, imm_val, true)) {
289 set_register(instr->RtField(), res);
290 }
291 break;
292 }
293 case ADDIU: {
294 // Format(instr, "addiu 'rt, 'rs, 'immu");
295 int32_t rs_val = get_register(instr->RsField());
296 int32_t imm_val = instr->SImmField();
297 int32_t res = rs_val + imm_val;
298 // Rt is set even on overflow. 378 // Rt is set even on overflow.
299 set_register(instr->RtField(), res); 379 set_register(instr->RtField(), res);
300 break; 380 break;
301 } 381 }
302 case ANDI: { 382 case ANDI: {
303 // Format(instr, "andi 'rt, 'rs, 'immu"); 383 // Format(instr, "andi 'rt, 'rs, 'immu");
304 int32_t rs_val = get_register(instr->RsField()); 384 int32_t rs_val = get_register(instr->RsField());
305 set_register(instr->RtField(), rs_val & instr->UImmField()); 385 set_register(instr->RtField(), rs_val & instr->UImmField());
306 break; 386 break;
307 } 387 }
388 case LB: {
389 // Format(instr, "lb 'rt, 'imms('rs)");
390 int32_t base_val = get_register(instr->RsField());
391 int32_t imm_val = instr->SImmField();
392 uword addr = base_val + imm_val;
393 if (Simulator::IsIllegalAddress(addr)) {
394 // TODO(zra) trap into debugger.
395 UNIMPLEMENTED();
396 } else {
397 int32_t res = ReadB(addr);
398 set_register(instr->RtField(), res);
399 }
400 break;
401 }
402 case LBU: {
403 // Format(instr, "lbu 'rt, 'imms('rs)");
404 int32_t base_val = get_register(instr->RsField());
405 int32_t imm_val = instr->SImmField();
406 uword addr = base_val + imm_val;
407 if (Simulator::IsIllegalAddress(addr)) {
408 // TODO(zra) trap into debugger.
409 UNIMPLEMENTED();
410 } else {
411 int32_t res = ReadBU(addr);
412 set_register(instr->RtField(), res);
413 }
414 break;
415 }
416 case LH: {
417 // Format(instr, "lh 'rt, 'imms('rs)");
418 int32_t base_val = get_register(instr->RsField());
419 int32_t imm_val = instr->SImmField();
420 uword addr = base_val + imm_val;
421 if (Simulator::IsIllegalAddress(addr)) {
422 // TODO(zra) trap into debugger.
423 UNIMPLEMENTED();
424 } else {
425 int32_t res = ReadH(addr, instr);
426 set_register(instr->RtField(), res);
427 }
428 break;
429 }
430 case LHU: {
431 // Format(instr, "lhu 'rt, 'imms('rs)");
432 int32_t base_val = get_register(instr->RsField());
433 int32_t imm_val = instr->SImmField();
434 uword addr = base_val + imm_val;
435 if (Simulator::IsIllegalAddress(addr)) {
436 // TODO(zra) trap into debugger.
437 UNIMPLEMENTED();
438 } else {
439 int32_t res = ReadHU(addr, instr);
440 set_register(instr->RtField(), res);
441 }
442 break;
443 }
308 case LUI: { 444 case LUI: {
309 ASSERT(instr->RsField() == 0); 445 ASSERT(instr->RsField() == 0);
310 set_register(instr->RtField(), instr->UImmField() << 16); 446 set_register(instr->RtField(), instr->UImmField() << 16);
311 break; 447 break;
312 } 448 }
449 case LW: {
450 // Format(instr, "lw 'rt, 'imms('rs)");
451 int32_t base_val = get_register(instr->RsField());
452 int32_t imm_val = instr->SImmField();
453 uword addr = base_val + imm_val;
454 if (Simulator::IsIllegalAddress(addr)) {
455 // TODO(zra) trap into debugger.
456 UNIMPLEMENTED();
457 } else {
458 int32_t res = ReadW(addr, instr);
459 set_register(instr->RtField(), res);
460 }
461 break;
462 }
313 case ORI: { 463 case ORI: {
314 // Format(instr, "ori 'rt, 'rs, 'immu"); 464 // Format(instr, "ori 'rt, 'rs, 'immu");
315 int32_t rs_val = get_register(instr->RsField()); 465 int32_t rs_val = get_register(instr->RsField());
316 set_register(instr->RtField(), rs_val | instr->UImmField()); 466 set_register(instr->RtField(), rs_val | instr->UImmField());
317 break; 467 break;
318 } 468 }
469 case SB: {
470 // Format(instr, "sb 'rt, 'imms('rs)");
471 int32_t rt_val = get_register(instr->RtField());
472 int32_t base_val = get_register(instr->RsField());
473 int32_t imm_val = instr->SImmField();
474 uword addr = base_val + imm_val;
475 if (Simulator::IsIllegalAddress(addr)) {
476 // TODO(zra) trap into debugger.
477 UNIMPLEMENTED();
478 } else {
479 WriteB(addr, rt_val & 0xff);
480 }
481 break;
482 }
483 case SH: {
484 // Format(instr, "sh 'rt, 'imms('rs)");
485 int32_t rt_val = get_register(instr->RtField());
486 int32_t base_val = get_register(instr->RsField());
487 int32_t imm_val = instr->SImmField();
488 uword addr = base_val + imm_val;
489 if (Simulator::IsIllegalAddress(addr)) {
490 // TODO(zra) trap into debugger.
491 UNIMPLEMENTED();
492 } else {
493 WriteH(addr, rt_val & 0xffff, instr);
494 }
495 break;
496 }
497 case SW: {
498 // Format(instr, "sw 'rt, 'imms('rs)");
499 int32_t rt_val = get_register(instr->RtField());
500 int32_t base_val = get_register(instr->RsField());
501 int32_t imm_val = instr->SImmField();
502 uword addr = base_val + imm_val;
503 if (Simulator::IsIllegalAddress(addr)) {
504 // TODO(zra) trap into debugger.
505 UNIMPLEMENTED();
506 } else {
507 WriteW(addr, rt_val, instr);
508 }
509 break;
510 }
319 default: { 511 default: {
320 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits()); 512 OS::PrintErr("Undecoded instruction: 0x%x\n", instr->InstructionBits());
321 UNREACHABLE(); 513 UNREACHABLE();
322 break; 514 break;
323 } 515 }
324 } 516 }
325 pc_ += Instr::kInstrSize; 517 pc_ += Instr::kInstrSize;
326 } 518 }
327 519
328 520
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Restore the SP register and return R1:R0. 635 // Restore the SP register and return R1:R0.
444 set_register(SP, sp_before_call); 636 set_register(SP, sp_before_call);
445 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); 637 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1));
446 } 638 }
447 639
448 } // namespace dart 640 } // namespace dart
449 641
450 #endif // !defined(HOST_ARCH_MIPS) 642 #endif // !defined(HOST_ARCH_MIPS)
451 643
452 #endif // defined TARGET_ARCH_MIPS 644 #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