| 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 |