OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
6 #include <setjmp.h> | 6 #include <setjmp.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #if defined(TARGET_ARCH_ARM64) | 10 #if defined(TARGET_ARCH_ARM64) |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 // Set the oVerflow flag. | 287 // Set the oVerflow flag. |
288 void Simulator::SetVFlag(bool val) { | 288 void Simulator::SetVFlag(bool val) { |
289 v_flag_ = val; | 289 v_flag_ = val; |
290 } | 290 } |
291 | 291 |
292 | 292 |
293 void Simulator::DecodeMoveWide(Instr* instr) { | 293 void Simulator::DecodeMoveWide(Instr* instr) { |
294 UnimplementedInstruction(instr); | 294 const Register rd = instr->RdField(); |
| 295 const int hw = instr->HWField(); |
| 296 const int64_t shift = hw << 4; |
| 297 const int64_t shifted_imm = |
| 298 static_cast<uint64_t>(instr->Imm16Field()) << shift; |
| 299 |
| 300 if (instr->SFField()) { |
| 301 if (instr->Bits(29, 2) == 0) { |
| 302 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); |
| 303 set_register(rd, ~shifted_imm, instr->RdMode()); |
| 304 } else if (instr->Bits(29, 2) == 2) { |
| 305 // Format(instr, "movz'sf 'rd, 'imm16 'hw"); |
| 306 set_register(rd, shifted_imm, instr->RdMode()); |
| 307 } else if (instr->Bits(29, 2) == 3) { |
| 308 // Format(instr, "movk'sf 'rd, 'imm16 'hw"); |
| 309 const int64_t rd_val = get_register(rd, instr->RdMode()); |
| 310 const int64_t result = (rd_val & ~(0xffffL << shift)) | shifted_imm; |
| 311 set_register(rd, result, instr->RdMode()); |
| 312 } else { |
| 313 UnimplementedInstruction(instr); |
| 314 } |
| 315 } else if ((hw & 0x2) == 0) { |
| 316 if (instr->Bits(29, 2) == 0) { |
| 317 // Format(instr, "movn'sf 'rd, 'imm16 'hw"); |
| 318 set_wregister(rd, ~shifted_imm & kWRegMask, instr->RdMode()); |
| 319 } else if (instr->Bits(29, 2) == 2) { |
| 320 // Format(instr, "movz'sf 'rd, 'imm16 'hw"); |
| 321 set_wregister(rd, shifted_imm & kWRegMask, instr->RdMode()); |
| 322 } else if (instr->Bits(29, 2) == 3) { |
| 323 // Format(instr, "movk'sf 'rd, 'imm16 'hw"); |
| 324 const int32_t rd_val = get_wregister(rd, instr->RdMode()); |
| 325 const int32_t result = (rd_val & ~(0xffffL << shift)) | shifted_imm; |
| 326 set_wregister(rd, result, instr->RdMode()); |
| 327 } else { |
| 328 UnimplementedInstruction(instr); |
| 329 } |
| 330 } else { |
| 331 // Dest is 32 bits, but shift is more than 32. |
| 332 UnimplementedInstruction(instr); |
| 333 } |
295 } | 334 } |
296 | 335 |
297 | 336 |
298 void Simulator::DecodeAddSubImm(Instr* instr) { | 337 void Simulator::DecodeAddSubImm(Instr* instr) { |
299 switch (instr->Bit(30)) { | 338 bool addition = (instr->Bit(30) == 0); |
300 case 0: { | 339 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); |
301 // Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); | 340 // Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); |
302 const Register rd = instr->RdField(); | 341 const Register rd = instr->RdField(); |
303 const Register rn = instr->RnField(); | 342 const Register rn = instr->RnField(); |
304 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) | 343 const uint32_t imm = (instr->Bit(22) == 1) ? (instr->Imm12Field() << 12) |
305 : (instr->Imm12Field()); | 344 : (instr->Imm12Field()); |
306 if (instr->SFField()) { | 345 if (instr->SFField()) { |
307 // 64-bit add. | 346 // 64-bit add. |
308 const int64_t rn_val = get_register(rn, instr->RnMode()); | 347 const int64_t rn_val = get_register(rn, instr->RnMode()); |
309 const int64_t alu_out = rn_val + imm; | 348 const int64_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); |
310 set_register(rd, alu_out, instr->RdMode()); | 349 set_register(rd, alu_out, instr->RdMode()); |
311 if (instr->HasS()) { | 350 if (instr->HasS()) { |
312 SetNZFlagsX(alu_out); | 351 SetNZFlagsX(alu_out); |
313 SetCFlag(CarryFromX(rn_val, imm)); | 352 SetCFlag(CarryFromX(rn_val, imm)); |
314 SetVFlag(OverflowFromX(alu_out, rn_val, imm, true)); | 353 SetVFlag(OverflowFromX(alu_out, rn_val, imm, addition)); |
315 } | |
316 } else { | |
317 // 32-bit add. | |
318 const int32_t rn_val = get_wregister(rn, instr->RnMode()); | |
319 const int32_t alu_out = rn_val + imm; | |
320 set_wregister(rd, alu_out, instr->RdMode()); | |
321 if (instr->HasS()) { | |
322 SetNZFlagsW(alu_out); | |
323 SetCFlag(CarryFromW(rn_val, imm)); | |
324 SetVFlag(OverflowFromW(alu_out, rn_val, imm, true)); | |
325 } | |
326 } | |
327 break; | |
328 } | 354 } |
329 default: | 355 } else { |
330 UnimplementedInstruction(instr); | 356 // 32-bit add. |
331 break; | 357 const int32_t rn_val = get_wregister(rn, instr->RnMode()); |
| 358 const int32_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); |
| 359 set_wregister(rd, alu_out, instr->RdMode()); |
| 360 if (instr->HasS()) { |
| 361 SetNZFlagsW(alu_out); |
| 362 SetCFlag(CarryFromW(rn_val, imm)); |
| 363 SetVFlag(OverflowFromW(alu_out, rn_val, imm, addition)); |
| 364 } |
332 } | 365 } |
333 } | 366 } |
334 | 367 |
335 void Simulator::DecodeDPImmediate(Instr* instr) { | 368 void Simulator::DecodeDPImmediate(Instr* instr) { |
336 if (instr->IsMoveWideOp()) { | 369 if (instr->IsMoveWideOp()) { |
337 DecodeMoveWide(instr); | 370 DecodeMoveWide(instr); |
338 } else if (instr->IsAddSubImmOp()) { | 371 } else if (instr->IsAddSubImmOp()) { |
339 DecodeAddSubImm(instr); | 372 DecodeAddSubImm(instr); |
340 } else { | 373 } else { |
341 UnimplementedInstruction(instr); | 374 UnimplementedInstruction(instr); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 int64_t return_value; | 738 int64_t return_value; |
706 return_value = get_register(R0); | 739 return_value = get_register(R0); |
707 return return_value; | 740 return return_value; |
708 } | 741 } |
709 | 742 |
710 } // namespace dart | 743 } // namespace dart |
711 | 744 |
712 #endif // !defined(HOST_ARCH_ARM64) | 745 #endif // !defined(HOST_ARCH_ARM64) |
713 | 746 |
714 #endif // defined TARGET_ARCH_ARM64 | 747 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |