1 // Copyright 2013, ARM Limited 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, 8 // this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above copyright notice, 10 // this list of conditions and the following disclaimer in the documentation 11 // and/or other materials provided with the distribution. 12 // * Neither the name of ARM Limited nor the names of its contributors may be 13 // used to endorse or promote products derived from this software without 14 // specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #ifdef USE_SIMULATOR 28 29 #include <string.h> 30 #include <cmath> 31 #include "a64/simulator-a64.h" 32 33 namespace vixl { 34 35 const Instruction* Simulator::kEndOfSimAddress = NULL; 36 37 void SimSystemRegister::SetBits(int msb, int lsb, uint32_t bits) { 38 int width = msb - lsb + 1; 39 VIXL_ASSERT(is_uintn(width, bits) || is_intn(width, bits)); 40 41 bits <<= lsb; 42 uint32_t mask = ((1 << width) - 1) << lsb; 43 VIXL_ASSERT((mask & write_ignore_mask_) == 0); 44 45 value_ = (value_ & ~mask) | (bits & mask); 46 } 47 48 49 SimSystemRegister SimSystemRegister::DefaultValueFor(SystemRegister id) { 50 switch (id) { 51 case NZCV: 52 return SimSystemRegister(0x00000000, NZCVWriteIgnoreMask); 53 case FPCR: 54 return SimSystemRegister(0x00000000, FPCRWriteIgnoreMask); 55 default: 56 VIXL_UNREACHABLE(); 57 return SimSystemRegister(); 58 } 59 } 60 61 62 Simulator::Simulator(Decoder* decoder, FILE* stream) { 63 // Ensure that shift operations act as the simulator expects. 64 VIXL_ASSERT((static_cast<int32_t>(-1) >> 1) == -1); 65 VIXL_ASSERT((static_cast<uint32_t>(-1) >> 1) == 0x7FFFFFFF); 66 67 // Set up the decoder. 68 decoder_ = decoder; 69 decoder_->AppendVisitor(this); 70 71 ResetState(); 72 73 // Allocate and set up the simulator stack. 74 stack_ = new byte[stack_size_]; 75 stack_limit_ = stack_ + stack_protection_size_; 76 // Configure the starting stack pointer. 77 // - Find the top of the stack. 78 byte * tos = stack_ + stack_size_; 79 // - There's a protection region at both ends of the stack. 80 tos -= stack_protection_size_; 81 // - The stack pointer must be 16-byte aligned. 82 tos = AlignDown(tos, 16); 83 set_sp(tos); 84 85 stream_ = stream; 86 print_disasm_ = new PrintDisassembler(stream_); 87 set_coloured_trace(false); 88 disasm_trace_ = false; 89 90 // Set the sample period to 10, as the VIXL examples and tests are short. 91 instrumentation_ = new Instrument("vixl_stats.csv", 10); 92 } 93 94 95 void Simulator::ResetState() { 96 // Reset the system registers. 97 nzcv_ = SimSystemRegister::DefaultValueFor(NZCV); 98 fpcr_ = SimSystemRegister::DefaultValueFor(FPCR); 99 100 // Reset registers to 0. 101 pc_ = NULL; 102 pc_modified_ = false; 103 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 104 set_xreg(i, 0xbadbeef); 105 } 106 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 107 // Set FP registers to a value that is NaN in both 32-bit and 64-bit FP. 108 set_dreg(i, kFP64SignallingNaN); 109 } 110 // Returning to address 0 exits the Simulator. 111 set_lr(kEndOfSimAddress); 112 } 113 114 115 Simulator::~Simulator() { 116 delete [] stack_; 117 // The decoder may outlive the simulator. 118 decoder_->RemoveVisitor(print_disasm_); 119 delete print_disasm_; 120 121 decoder_->RemoveVisitor(instrumentation_); 122 delete instrumentation_; 123 } 124 125 126 void Simulator::Run() { 127 pc_modified_ = false; 128 while (pc_ != kEndOfSimAddress) { 129 ExecuteInstruction(); 130 } 131 } 132 133 134 void Simulator::RunFrom(Instruction* first) { 135 set_pc(first); 136 Run(); 137 } 138 139 140 const char* Simulator::xreg_names[] = { 141 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", 142 "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", 143 "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", 144 "x24", "x25", "x26", "x27", "x28", "x29", "lr", "xzr", "sp"}; 145 146 147 const char* Simulator::wreg_names[] = { 148 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", 149 "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", 150 "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", 151 "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wzr", "wsp"}; 152 153 const char* Simulator::sreg_names[] = { 154 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 155 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", 156 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", 157 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31"}; 158 159 const char* Simulator::dreg_names[] = { 160 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 161 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", 162 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", 163 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; 164 165 const char* Simulator::vreg_names[] = { 166 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", 167 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", 168 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", 169 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"}; 170 171 172 173 const char* Simulator::WRegNameForCode(unsigned code, Reg31Mode mode) { 174 VIXL_ASSERT(code < kNumberOfRegisters); 175 // If the code represents the stack pointer, index the name after zr. 176 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 177 code = kZeroRegCode + 1; 178 } 179 return wreg_names[code]; 180 } 181 182 183 const char* Simulator::XRegNameForCode(unsigned code, Reg31Mode mode) { 184 VIXL_ASSERT(code < kNumberOfRegisters); 185 // If the code represents the stack pointer, index the name after zr. 186 if ((code == kZeroRegCode) && (mode == Reg31IsStackPointer)) { 187 code = kZeroRegCode + 1; 188 } 189 return xreg_names[code]; 190 } 191 192 193 const char* Simulator::SRegNameForCode(unsigned code) { 194 VIXL_ASSERT(code < kNumberOfFPRegisters); 195 return sreg_names[code]; 196 } 197 198 199 const char* Simulator::DRegNameForCode(unsigned code) { 200 VIXL_ASSERT(code < kNumberOfFPRegisters); 201 return dreg_names[code]; 202 } 203 204 205 const char* Simulator::VRegNameForCode(unsigned code) { 206 VIXL_ASSERT(code < kNumberOfFPRegisters); 207 return vreg_names[code]; 208 } 209 210 211 #define COLOUR(colour_code) "\033[" colour_code "m" 212 #define BOLD(colour_code) "1;" colour_code 213 #define NORMAL "" 214 #define GREY "30" 215 #define GREEN "32" 216 #define ORANGE "33" 217 #define BLUE "34" 218 #define PURPLE "35" 219 #define INDIGO "36" 220 #define WHITE "37" 221 void Simulator::set_coloured_trace(bool value) { 222 coloured_trace_ = value; 223 224 clr_normal = value ? COLOUR(NORMAL) : ""; 225 clr_flag_name = value ? COLOUR(BOLD(GREY)) : ""; 226 clr_flag_value = value ? COLOUR(BOLD(WHITE)) : ""; 227 clr_reg_name = value ? COLOUR(BOLD(BLUE)) : ""; 228 clr_reg_value = value ? COLOUR(BOLD(INDIGO)) : ""; 229 clr_fpreg_name = value ? COLOUR(BOLD(ORANGE)) : ""; 230 clr_fpreg_value = value ? COLOUR(BOLD(PURPLE)) : ""; 231 clr_memory_value = value ? COLOUR(BOLD(GREEN)) : ""; 232 clr_memory_address = value ? COLOUR(GREEN) : ""; 233 clr_debug_number = value ? COLOUR(BOLD(ORANGE)) : ""; 234 clr_debug_message = value ? COLOUR(ORANGE) : ""; 235 clr_printf = value ? COLOUR(GREEN) : ""; 236 } 237 238 239 // Helpers --------------------------------------------------------------------- 240 int64_t Simulator::AddWithCarry(unsigned reg_size, 241 bool set_flags, 242 int64_t src1, 243 int64_t src2, 244 int64_t carry_in) { 245 VIXL_ASSERT((carry_in == 0) || (carry_in == 1)); 246 VIXL_ASSERT((reg_size == kXRegSize) || (reg_size == kWRegSize)); 247 248 uint64_t u1, u2; 249 int64_t result; 250 int64_t signed_sum = src1 + src2 + carry_in; 251 252 uint32_t N, Z, C, V; 253 254 if (reg_size == kWRegSize) { 255 u1 = static_cast<uint64_t>(src1) & kWRegMask; 256 u2 = static_cast<uint64_t>(src2) & kWRegMask; 257 258 result = signed_sum & kWRegMask; 259 // Compute the C flag by comparing the sum to the max unsigned integer. 260 C = ((kWMaxUInt - u1) < (u2 + carry_in)) || 261 ((kWMaxUInt - u1 - carry_in) < u2); 262 // Overflow iff the sign bit is the same for the two inputs and different 263 // for the result. 264 int64_t s_src1 = src1 << (kXRegSize - kWRegSize); 265 int64_t s_src2 = src2 << (kXRegSize - kWRegSize); 266 int64_t s_result = result << (kXRegSize - kWRegSize); 267 V = ((s_src1 ^ s_src2) >= 0) && ((s_src1 ^ s_result) < 0); 268 269 } else { 270 u1 = static_cast<uint64_t>(src1); 271 u2 = static_cast<uint64_t>(src2); 272 273 result = signed_sum; 274 // Compute the C flag by comparing the sum to the max unsigned integer. 275 C = ((kXMaxUInt - u1) < (u2 + carry_in)) || 276 ((kXMaxUInt - u1 - carry_in) < u2); 277 // Overflow iff the sign bit is the same for the two inputs and different 278 // for the result. 279 V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0); 280 } 281 282 N = CalcNFlag(result, reg_size); 283 Z = CalcZFlag(result); 284 285 if (set_flags) { 286 nzcv().SetN(N); 287 nzcv().SetZ(Z); 288 nzcv().SetC(C); 289 nzcv().SetV(V); 290 } 291 return result; 292 } 293 294 295 int64_t Simulator::ShiftOperand(unsigned reg_size, 296 int64_t value, 297 Shift shift_type, 298 unsigned amount) { 299 if (amount == 0) { 300 return value; 301 } 302 int64_t mask = reg_size == kXRegSize ? kXRegMask : kWRegMask; 303 switch (shift_type) { 304 case LSL: 305 return (value << amount) & mask; 306 case LSR: 307 return static_cast<uint64_t>(value) >> amount; 308 case ASR: { 309 // Shift used to restore the sign. 310 unsigned s_shift = kXRegSize - reg_size; 311 // Value with its sign restored. 312 int64_t s_value = (value << s_shift) >> s_shift; 313 return (s_value >> amount) & mask; 314 } 315 case ROR: { 316 if (reg_size == kWRegSize) { 317 value &= kWRegMask; 318 } 319 return (static_cast<uint64_t>(value) >> amount) | 320 ((value & ((INT64_C(1) << amount) - 1)) << 321 (reg_size - amount)); 322 } 323 default: 324 VIXL_UNIMPLEMENTED(); 325 return 0; 326 } 327 } 328 329 330 int64_t Simulator::ExtendValue(unsigned reg_size, 331 int64_t value, 332 Extend extend_type, 333 unsigned left_shift) { 334 switch (extend_type) { 335 case UXTB: 336 value &= kByteMask; 337 break; 338 case UXTH: 339 value &= kHalfWordMask; 340 break; 341 case UXTW: 342 value &= kWordMask; 343 break; 344 case SXTB: 345 value = (value << 56) >> 56; 346 break; 347 case SXTH: 348 value = (value << 48) >> 48; 349 break; 350 case SXTW: 351 value = (value << 32) >> 32; 352 break; 353 case UXTX: 354 case SXTX: 355 break; 356 default: 357 VIXL_UNREACHABLE(); 358 } 359 int64_t mask = (reg_size == kXRegSize) ? kXRegMask : kWRegMask; 360 return (value << left_shift) & mask; 361 } 362 363 364 template<> double Simulator::FPDefaultNaN<double>() const { 365 return kFP64DefaultNaN; 366 } 367 368 369 template<> float Simulator::FPDefaultNaN<float>() const { 370 return kFP32DefaultNaN; 371 } 372 373 374 void Simulator::FPCompare(double val0, double val1) { 375 AssertSupportedFPCR(); 376 377 // TODO: This assumes that the C++ implementation handles comparisons in the 378 // way that we expect (as per AssertSupportedFPCR()). 379 if ((std::isnan(val0) != 0) || (std::isnan(val1) != 0)) { 380 nzcv().SetRawValue(FPUnorderedFlag); 381 } else if (val0 < val1) { 382 nzcv().SetRawValue(FPLessThanFlag); 383 } else if (val0 > val1) { 384 nzcv().SetRawValue(FPGreaterThanFlag); 385 } else if (val0 == val1) { 386 nzcv().SetRawValue(FPEqualFlag); 387 } else { 388 VIXL_UNREACHABLE(); 389 } 390 } 391 392 393 void Simulator::PrintSystemRegisters(bool print_all) { 394 static bool first_run = true; 395 396 static SimSystemRegister last_nzcv; 397 if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) { 398 fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n", 399 clr_flag_name, 400 clr_flag_value, 401 N(), Z(), C(), V(), 402 clr_normal); 403 } 404 last_nzcv = nzcv(); 405 406 static SimSystemRegister last_fpcr; 407 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) { 408 static const char * rmode[] = { 409 "0b00 (Round to Nearest)", 410 "0b01 (Round towards Plus Infinity)", 411 "0b10 (Round towards Minus Infinity)", 412 "0b11 (Round towards Zero)" 413 }; 414 VIXL_ASSERT(fpcr().RMode() <= (sizeof(rmode) / sizeof(rmode[0]))); 415 fprintf(stream_, "# %sFPCR: %sAHP:%d DN:%d FZ:%d RMode:%s%s\n", 416 clr_flag_name, 417 clr_flag_value, 418 fpcr().AHP(), fpcr().DN(), fpcr().FZ(), rmode[fpcr().RMode()], 419 clr_normal); 420 } 421 last_fpcr = fpcr(); 422 423 first_run = false; 424 } 425 426 427 void Simulator::PrintRegisters(bool print_all_regs) { 428 static bool first_run = true; 429 static int64_t last_regs[kNumberOfRegisters]; 430 431 for (unsigned i = 0; i < kNumberOfRegisters; i++) { 432 if (print_all_regs || first_run || 433 (last_regs[i] != xreg(i, Reg31IsStackPointer))) { 434 fprintf(stream_, 435 "# %s%4s:%s 0x%016" PRIx64 "%s\n", 436 clr_reg_name, 437 XRegNameForCode(i, Reg31IsStackPointer), 438 clr_reg_value, 439 xreg(i, Reg31IsStackPointer), 440 clr_normal); 441 } 442 // Cache the new register value so the next run can detect any changes. 443 last_regs[i] = xreg(i, Reg31IsStackPointer); 444 } 445 first_run = false; 446 } 447 448 449 void Simulator::PrintFPRegisters(bool print_all_regs) { 450 static bool first_run = true; 451 static uint64_t last_regs[kNumberOfFPRegisters]; 452 453 // Print as many rows of registers as necessary, keeping each individual 454 // register in the same column each time (to make it easy to visually scan 455 // for changes). 456 for (unsigned i = 0; i < kNumberOfFPRegisters; i++) { 457 if (print_all_regs || first_run || (last_regs[i] != dreg_bits(i))) { 458 fprintf(stream_, 459 "# %s%4s:%s 0x%016" PRIx64 "%s (%s%s:%s %g%s %s:%s %g%s)\n", 460 clr_fpreg_name, 461 VRegNameForCode(i), 462 clr_fpreg_value, 463 dreg_bits(i), 464 clr_normal, 465 clr_fpreg_name, 466 DRegNameForCode(i), 467 clr_fpreg_value, 468 dreg(i), 469 clr_fpreg_name, 470 SRegNameForCode(i), 471 clr_fpreg_value, 472 sreg(i), 473 clr_normal); 474 } 475 // Cache the new register value so the next run can detect any changes. 476 last_regs[i] = dreg_bits(i); 477 } 478 first_run = false; 479 } 480 481 482 void Simulator::PrintProcessorState() { 483 PrintSystemRegisters(); 484 PrintRegisters(); 485 PrintFPRegisters(); 486 } 487 488 489 // Visitors--------------------------------------------------------------------- 490 491 void Simulator::VisitUnimplemented(Instruction* instr) { 492 printf("Unimplemented instruction at 0x%p: 0x%08" PRIx32 "\n", 493 reinterpret_cast<void*>(instr), instr->InstructionBits()); 494 VIXL_UNIMPLEMENTED(); 495 } 496 497 498 void Simulator::VisitUnallocated(Instruction* instr) { 499 printf("Unallocated instruction at 0x%p: 0x%08" PRIx32 "\n", 500 reinterpret_cast<void*>(instr), instr->InstructionBits()); 501 VIXL_UNIMPLEMENTED(); 502 } 503 504 505 void Simulator::VisitPCRelAddressing(Instruction* instr) { 506 switch (instr->Mask(PCRelAddressingMask)) { 507 case ADR: 508 set_reg(kXRegSize, 509 instr->Rd(), 510 reinterpret_cast<int64_t>(instr->ImmPCOffsetTarget())); 511 break; 512 case ADRP: // Not implemented in the assembler. 513 VIXL_UNIMPLEMENTED(); 514 break; 515 default: 516 VIXL_UNREACHABLE(); 517 } 518 } 519 520 521 void Simulator::VisitUnconditionalBranch(Instruction* instr) { 522 switch (instr->Mask(UnconditionalBranchMask)) { 523 case BL: 524 set_lr(instr->NextInstruction()); 525 // Fall through. 526 case B: 527 set_pc(instr->ImmPCOffsetTarget()); 528 break; 529 default: VIXL_UNREACHABLE(); 530 } 531 } 532 533 534 void Simulator::VisitConditionalBranch(Instruction* instr) { 535 VIXL_ASSERT(instr->Mask(ConditionalBranchMask) == B_cond); 536 if (ConditionPassed(static_cast<Condition>(instr->ConditionBranch()))) { 537 set_pc(instr->ImmPCOffsetTarget()); 538 } 539 } 540 541 542 void Simulator::VisitUnconditionalBranchToRegister(Instruction* instr) { 543 Instruction* target = Instruction::Cast(xreg(instr->Rn())); 544 545 switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 546 case BLR: 547 set_lr(instr->NextInstruction()); 548 // Fall through. 549 case BR: 550 case RET: set_pc(target); break; 551 default: VIXL_UNREACHABLE(); 552 } 553 } 554 555 556 void Simulator::VisitTestBranch(Instruction* instr) { 557 unsigned bit_pos = (instr->ImmTestBranchBit5() << 5) | 558 instr->ImmTestBranchBit40(); 559 bool bit_zero = ((xreg(instr->Rt()) >> bit_pos) & 1) == 0; 560 bool take_branch = false; 561 switch (instr->Mask(TestBranchMask)) { 562 case TBZ: take_branch = bit_zero; break; 563 case TBNZ: take_branch = !bit_zero; break; 564 default: VIXL_UNIMPLEMENTED(); 565 } 566 if (take_branch) { 567 set_pc(instr->ImmPCOffsetTarget()); 568 } 569 } 570 571 572 void Simulator::VisitCompareBranch(Instruction* instr) { 573 unsigned rt = instr->Rt(); 574 bool take_branch = false; 575 switch (instr->Mask(CompareBranchMask)) { 576 case CBZ_w: take_branch = (wreg(rt) == 0); break; 577 case CBZ_x: take_branch = (xreg(rt) == 0); break; 578 case CBNZ_w: take_branch = (wreg(rt) != 0); break; 579 case CBNZ_x: take_branch = (xreg(rt) != 0); break; 580 default: VIXL_UNIMPLEMENTED(); 581 } 582 if (take_branch) { 583 set_pc(instr->ImmPCOffsetTarget()); 584 } 585 } 586 587 588 void Simulator::AddSubHelper(Instruction* instr, int64_t op2) { 589 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 590 bool set_flags = instr->FlagsUpdate(); 591 int64_t new_val = 0; 592 Instr operation = instr->Mask(AddSubOpMask); 593 594 switch (operation) { 595 case ADD: 596 case ADDS: { 597 new_val = AddWithCarry(reg_size, 598 set_flags, 599 reg(reg_size, instr->Rn(), instr->RnMode()), 600 op2); 601 break; 602 } 603 case SUB: 604 case SUBS: { 605 new_val = AddWithCarry(reg_size, 606 set_flags, 607 reg(reg_size, instr->Rn(), instr->RnMode()), 608 ~op2, 609 1); 610 break; 611 } 612 default: VIXL_UNREACHABLE(); 613 } 614 615 set_reg(reg_size, instr->Rd(), new_val, instr->RdMode()); 616 } 617 618 619 void Simulator::VisitAddSubShifted(Instruction* instr) { 620 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 621 int64_t op2 = ShiftOperand(reg_size, 622 reg(reg_size, instr->Rm()), 623 static_cast<Shift>(instr->ShiftDP()), 624 instr->ImmDPShift()); 625 AddSubHelper(instr, op2); 626 } 627 628 629 void Simulator::VisitAddSubImmediate(Instruction* instr) { 630 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); 631 AddSubHelper(instr, op2); 632 } 633 634 635 void Simulator::VisitAddSubExtended(Instruction* instr) { 636 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 637 int64_t op2 = ExtendValue(reg_size, 638 reg(reg_size, instr->Rm()), 639 static_cast<Extend>(instr->ExtendMode()), 640 instr->ImmExtendShift()); 641 AddSubHelper(instr, op2); 642 } 643 644 645 void Simulator::VisitAddSubWithCarry(Instruction* instr) { 646 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 647 int64_t op2 = reg(reg_size, instr->Rm()); 648 int64_t new_val; 649 650 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { 651 op2 = ~op2; 652 } 653 654 new_val = AddWithCarry(reg_size, 655 instr->FlagsUpdate(), 656 reg(reg_size, instr->Rn()), 657 op2, 658 C()); 659 660 set_reg(reg_size, instr->Rd(), new_val); 661 } 662 663 664 void Simulator::VisitLogicalShifted(Instruction* instr) { 665 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 666 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); 667 unsigned shift_amount = instr->ImmDPShift(); 668 int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type, 669 shift_amount); 670 if (instr->Mask(NOT) == NOT) { 671 op2 = ~op2; 672 } 673 LogicalHelper(instr, op2); 674 } 675 676 677 void Simulator::VisitLogicalImmediate(Instruction* instr) { 678 LogicalHelper(instr, instr->ImmLogical()); 679 } 680 681 682 void Simulator::LogicalHelper(Instruction* instr, int64_t op2) { 683 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 684 int64_t op1 = reg(reg_size, instr->Rn()); 685 int64_t result = 0; 686 bool update_flags = false; 687 688 // Switch on the logical operation, stripping out the NOT bit, as it has a 689 // different meaning for logical immediate instructions. 690 switch (instr->Mask(LogicalOpMask & ~NOT)) { 691 case ANDS: update_flags = true; // Fall through. 692 case AND: result = op1 & op2; break; 693 case ORR: result = op1 | op2; break; 694 case EOR: result = op1 ^ op2; break; 695 default: 696 VIXL_UNIMPLEMENTED(); 697 } 698 699 if (update_flags) { 700 nzcv().SetN(CalcNFlag(result, reg_size)); 701 nzcv().SetZ(CalcZFlag(result)); 702 nzcv().SetC(0); 703 nzcv().SetV(0); 704 } 705 706 set_reg(reg_size, instr->Rd(), result, instr->RdMode()); 707 } 708 709 710 void Simulator::VisitConditionalCompareRegister(Instruction* instr) { 711 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 712 ConditionalCompareHelper(instr, reg(reg_size, instr->Rm())); 713 } 714 715 716 void Simulator::VisitConditionalCompareImmediate(Instruction* instr) { 717 ConditionalCompareHelper(instr, instr->ImmCondCmp()); 718 } 719 720 721 void Simulator::ConditionalCompareHelper(Instruction* instr, int64_t op2) { 722 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 723 int64_t op1 = reg(reg_size, instr->Rn()); 724 725 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 726 // If the condition passes, set the status flags to the result of comparing 727 // the operands. 728 if (instr->Mask(ConditionalCompareMask) == CCMP) { 729 AddWithCarry(reg_size, true, op1, ~op2, 1); 730 } else { 731 VIXL_ASSERT(instr->Mask(ConditionalCompareMask) == CCMN); 732 AddWithCarry(reg_size, true, op1, op2, 0); 733 } 734 } else { 735 // If the condition fails, set the status flags to the nzcv immediate. 736 nzcv().SetFlags(instr->Nzcv()); 737 } 738 } 739 740 741 void Simulator::VisitLoadStoreUnsignedOffset(Instruction* instr) { 742 int offset = instr->ImmLSUnsigned() << instr->SizeLS(); 743 LoadStoreHelper(instr, offset, Offset); 744 } 745 746 747 void Simulator::VisitLoadStoreUnscaledOffset(Instruction* instr) { 748 LoadStoreHelper(instr, instr->ImmLS(), Offset); 749 } 750 751 752 void Simulator::VisitLoadStorePreIndex(Instruction* instr) { 753 LoadStoreHelper(instr, instr->ImmLS(), PreIndex); 754 } 755 756 757 void Simulator::VisitLoadStorePostIndex(Instruction* instr) { 758 LoadStoreHelper(instr, instr->ImmLS(), PostIndex); 759 } 760 761 762 void Simulator::VisitLoadStoreRegisterOffset(Instruction* instr) { 763 Extend ext = static_cast<Extend>(instr->ExtendMode()); 764 VIXL_ASSERT((ext == UXTW) || (ext == UXTX) || (ext == SXTW) || (ext == SXTX)); 765 unsigned shift_amount = instr->ImmShiftLS() * instr->SizeLS(); 766 767 int64_t offset = ExtendValue(kXRegSize, xreg(instr->Rm()), ext, 768 shift_amount); 769 LoadStoreHelper(instr, offset, Offset); 770 } 771 772 773 void Simulator::LoadStoreHelper(Instruction* instr, 774 int64_t offset, 775 AddrMode addrmode) { 776 unsigned srcdst = instr->Rt(); 777 uint8_t* address = AddressModeHelper(instr->Rn(), offset, addrmode); 778 int num_bytes = 1 << instr->SizeLS(); 779 780 LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask)); 781 switch (op) { 782 case LDRB_w: 783 case LDRH_w: 784 case LDR_w: 785 case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break; 786 case STRB_w: 787 case STRH_w: 788 case STR_w: 789 case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break; 790 case LDRSB_w: { 791 set_wreg(srcdst, ExtendValue(kWRegSize, MemoryRead8(address), SXTB)); 792 break; 793 } 794 case LDRSB_x: { 795 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead8(address), SXTB)); 796 break; 797 } 798 case LDRSH_w: { 799 set_wreg(srcdst, ExtendValue(kWRegSize, MemoryRead16(address), SXTH)); 800 break; 801 } 802 case LDRSH_x: { 803 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead16(address), SXTH)); 804 break; 805 } 806 case LDRSW_x: { 807 set_xreg(srcdst, ExtendValue(kXRegSize, MemoryRead32(address), SXTW)); 808 break; 809 } 810 case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break; 811 case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break; 812 case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break; 813 case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break; 814 default: VIXL_UNIMPLEMENTED(); 815 } 816 } 817 818 819 void Simulator::VisitLoadStorePairOffset(Instruction* instr) { 820 LoadStorePairHelper(instr, Offset); 821 } 822 823 824 void Simulator::VisitLoadStorePairPreIndex(Instruction* instr) { 825 LoadStorePairHelper(instr, PreIndex); 826 } 827 828 829 void Simulator::VisitLoadStorePairPostIndex(Instruction* instr) { 830 LoadStorePairHelper(instr, PostIndex); 831 } 832 833 834 void Simulator::VisitLoadStorePairNonTemporal(Instruction* instr) { 835 LoadStorePairHelper(instr, Offset); 836 } 837 838 839 void Simulator::LoadStorePairHelper(Instruction* instr, 840 AddrMode addrmode) { 841 unsigned rt = instr->Rt(); 842 unsigned rt2 = instr->Rt2(); 843 int offset = instr->ImmLSPair() << instr->SizeLSPair(); 844 uint8_t* address = AddressModeHelper(instr->Rn(), offset, addrmode); 845 846 LoadStorePairOp op = 847 static_cast<LoadStorePairOp>(instr->Mask(LoadStorePairMask)); 848 849 // 'rt' and 'rt2' can only be aliased for stores. 850 VIXL_ASSERT(((op & LoadStorePairLBit) == 0) || (rt != rt2)); 851 852 switch (op) { 853 case LDP_w: { 854 set_wreg(rt, MemoryRead32(address)); 855 set_wreg(rt2, MemoryRead32(address + kWRegSizeInBytes)); 856 break; 857 } 858 case LDP_s: { 859 set_sreg(rt, MemoryReadFP32(address)); 860 set_sreg(rt2, MemoryReadFP32(address + kSRegSizeInBytes)); 861 break; 862 } 863 case LDP_x: { 864 set_xreg(rt, MemoryRead64(address)); 865 set_xreg(rt2, MemoryRead64(address + kXRegSizeInBytes)); 866 break; 867 } 868 case LDP_d: { 869 set_dreg(rt, MemoryReadFP64(address)); 870 set_dreg(rt2, MemoryReadFP64(address + kDRegSizeInBytes)); 871 break; 872 } 873 case LDPSW_x: { 874 set_xreg(rt, ExtendValue(kXRegSize, MemoryRead32(address), SXTW)); 875 set_xreg(rt2, ExtendValue(kXRegSize, 876 MemoryRead32(address + kWRegSizeInBytes), SXTW)); 877 break; 878 } 879 case STP_w: { 880 MemoryWrite32(address, wreg(rt)); 881 MemoryWrite32(address + kWRegSizeInBytes, wreg(rt2)); 882 break; 883 } 884 case STP_s: { 885 MemoryWriteFP32(address, sreg(rt)); 886 MemoryWriteFP32(address + kSRegSizeInBytes, sreg(rt2)); 887 break; 888 } 889 case STP_x: { 890 MemoryWrite64(address, xreg(rt)); 891 MemoryWrite64(address + kXRegSizeInBytes, xreg(rt2)); 892 break; 893 } 894 case STP_d: { 895 MemoryWriteFP64(address, dreg(rt)); 896 MemoryWriteFP64(address + kDRegSizeInBytes, dreg(rt2)); 897 break; 898 } 899 default: VIXL_UNREACHABLE(); 900 } 901 } 902 903 904 void Simulator::VisitLoadLiteral(Instruction* instr) { 905 uint8_t* address = instr->LiteralAddress(); 906 unsigned rt = instr->Rt(); 907 908 switch (instr->Mask(LoadLiteralMask)) { 909 case LDR_w_lit: set_wreg(rt, MemoryRead32(address)); break; 910 case LDR_x_lit: set_xreg(rt, MemoryRead64(address)); break; 911 case LDR_s_lit: set_sreg(rt, MemoryReadFP32(address)); break; 912 case LDR_d_lit: set_dreg(rt, MemoryReadFP64(address)); break; 913 default: VIXL_UNREACHABLE(); 914 } 915 } 916 917 918 uint8_t* Simulator::AddressModeHelper(unsigned addr_reg, 919 int64_t offset, 920 AddrMode addrmode) { 921 uint64_t address = xreg(addr_reg, Reg31IsStackPointer); 922 923 if ((addr_reg == 31) && ((address % 16) != 0)) { 924 // When the base register is SP the stack pointer is required to be 925 // quadword aligned prior to the address calculation and write-backs. 926 // Misalignment will cause a stack alignment fault. 927 VIXL_ALIGNMENT_EXCEPTION(); 928 } 929 930 if ((addrmode == PreIndex) || (addrmode == PostIndex)) { 931 VIXL_ASSERT(offset != 0); 932 set_xreg(addr_reg, address + offset, Reg31IsStackPointer); 933 } 934 935 if ((addrmode == Offset) || (addrmode == PreIndex)) { 936 address += offset; 937 } 938 939 // Verify that the calculated address is available to the host. 940 VIXL_ASSERT(address == static_cast<uintptr_t>(address)); 941 942 return reinterpret_cast<uint8_t*>(address); 943 } 944 945 946 uint64_t Simulator::MemoryRead(const uint8_t* address, unsigned num_bytes) { 947 VIXL_ASSERT(address != NULL); 948 VIXL_ASSERT((num_bytes > 0) && (num_bytes <= sizeof(uint64_t))); 949 uint64_t read = 0; 950 memcpy(&read, address, num_bytes); 951 return read; 952 } 953 954 955 uint8_t Simulator::MemoryRead8(uint8_t* address) { 956 return MemoryRead(address, sizeof(uint8_t)); 957 } 958 959 960 uint16_t Simulator::MemoryRead16(uint8_t* address) { 961 return MemoryRead(address, sizeof(uint16_t)); 962 } 963 964 965 uint32_t Simulator::MemoryRead32(uint8_t* address) { 966 return MemoryRead(address, sizeof(uint32_t)); 967 } 968 969 970 float Simulator::MemoryReadFP32(uint8_t* address) { 971 return rawbits_to_float(MemoryRead32(address)); 972 } 973 974 975 uint64_t Simulator::MemoryRead64(uint8_t* address) { 976 return MemoryRead(address, sizeof(uint64_t)); 977 } 978 979 980 double Simulator::MemoryReadFP64(uint8_t* address) { 981 return rawbits_to_double(MemoryRead64(address)); 982 } 983 984 985 void Simulator::MemoryWrite(uint8_t* address, 986 uint64_t value, 987 unsigned num_bytes) { 988 VIXL_ASSERT(address != NULL); 989 VIXL_ASSERT((num_bytes > 0) && (num_bytes <= sizeof(uint64_t))); 990 memcpy(address, &value, num_bytes); 991 } 992 993 994 void Simulator::MemoryWrite32(uint8_t* address, uint32_t value) { 995 MemoryWrite(address, value, sizeof(uint32_t)); 996 } 997 998 999 void Simulator::MemoryWriteFP32(uint8_t* address, float value) { 1000 MemoryWrite32(address, float_to_rawbits(value)); 1001 } 1002 1003 1004 void Simulator::MemoryWrite64(uint8_t* address, uint64_t value) { 1005 MemoryWrite(address, value, sizeof(uint64_t)); 1006 } 1007 1008 1009 void Simulator::MemoryWriteFP64(uint8_t* address, double value) { 1010 MemoryWrite64(address, double_to_rawbits(value)); 1011 } 1012 1013 1014 void Simulator::VisitMoveWideImmediate(Instruction* instr) { 1015 MoveWideImmediateOp mov_op = 1016 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); 1017 int64_t new_xn_val = 0; 1018 1019 bool is_64_bits = instr->SixtyFourBits() != 0; 1020 // Shift is limited for W operations. 1021 VIXL_ASSERT(is_64_bits || (instr->ShiftMoveWide() < 2)); 1022 1023 // Get the shifted immediate. 1024 int64_t shift = instr->ShiftMoveWide() * 16; 1025 int64_t shifted_imm16 = instr->ImmMoveWide() << shift; 1026 1027 // Compute the new value. 1028 switch (mov_op) { 1029 case MOVN_w: 1030 case MOVN_x: { 1031 new_xn_val = ~shifted_imm16; 1032 if (!is_64_bits) new_xn_val &= kWRegMask; 1033 break; 1034 } 1035 case MOVK_w: 1036 case MOVK_x: { 1037 unsigned reg_code = instr->Rd(); 1038 int64_t prev_xn_val = is_64_bits ? xreg(reg_code) 1039 : wreg(reg_code); 1040 new_xn_val = 1041 (prev_xn_val & ~(INT64_C(0xffff) << shift)) | shifted_imm16; 1042 break; 1043 } 1044 case MOVZ_w: 1045 case MOVZ_x: { 1046 new_xn_val = shifted_imm16; 1047 break; 1048 } 1049 default: 1050 VIXL_UNREACHABLE(); 1051 } 1052 1053 // Update the destination register. 1054 set_xreg(instr->Rd(), new_xn_val); 1055 } 1056 1057 1058 void Simulator::VisitConditionalSelect(Instruction* instr) { 1059 uint64_t new_val = xreg(instr->Rn()); 1060 1061 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { 1062 new_val = xreg(instr->Rm()); 1063 switch (instr->Mask(ConditionalSelectMask)) { 1064 case CSEL_w: 1065 case CSEL_x: break; 1066 case CSINC_w: 1067 case CSINC_x: new_val++; break; 1068 case CSINV_w: 1069 case CSINV_x: new_val = ~new_val; break; 1070 case CSNEG_w: 1071 case CSNEG_x: new_val = -new_val; break; 1072 default: VIXL_UNIMPLEMENTED(); 1073 } 1074 } 1075 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 1076 set_reg(reg_size, instr->Rd(), new_val); 1077 } 1078 1079 1080 void Simulator::VisitDataProcessing1Source(Instruction* instr) { 1081 unsigned dst = instr->Rd(); 1082 unsigned src = instr->Rn(); 1083 1084 switch (instr->Mask(DataProcessing1SourceMask)) { 1085 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSize)); break; 1086 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSize)); break; 1087 case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; 1088 case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; 1089 case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; 1090 case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; 1091 case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; 1092 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSize)); break; 1093 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSize)); break; 1094 case CLS_w: { 1095 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSize)); 1096 break; 1097 } 1098 case CLS_x: { 1099 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSize)); 1100 break; 1101 } 1102 default: VIXL_UNIMPLEMENTED(); 1103 } 1104 } 1105 1106 1107 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { 1108 VIXL_ASSERT((num_bits == kWRegSize) || (num_bits == kXRegSize)); 1109 uint64_t result = 0; 1110 for (unsigned i = 0; i < num_bits; i++) { 1111 result = (result << 1) | (value & 1); 1112 value >>= 1; 1113 } 1114 return result; 1115 } 1116 1117 1118 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { 1119 // Split the 64-bit value into an 8-bit array, where b[0] is the least 1120 // significant byte, and b[7] is the most significant. 1121 uint8_t bytes[8]; 1122 uint64_t mask = UINT64_C(0xff00000000000000); 1123 for (int i = 7; i >= 0; i--) { 1124 bytes[i] = (value & mask) >> (i * 8); 1125 mask >>= 8; 1126 } 1127 1128 // Permutation tables for REV instructions. 1129 // permute_table[Reverse16] is used by REV16_x, REV16_w 1130 // permute_table[Reverse32] is used by REV32_x, REV_w 1131 // permute_table[Reverse64] is used by REV_x 1132 VIXL_STATIC_ASSERT((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2)); 1133 static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1}, 1134 {4, 5, 6, 7, 0, 1, 2, 3}, 1135 {0, 1, 2, 3, 4, 5, 6, 7} }; 1136 uint64_t result = 0; 1137 for (int i = 0; i < 8; i++) { 1138 result <<= 8; 1139 result |= bytes[permute_table[mode][i]]; 1140 } 1141 return result; 1142 } 1143 1144 1145 void Simulator::VisitDataProcessing2Source(Instruction* instr) { 1146 Shift shift_op = NO_SHIFT; 1147 int64_t result = 0; 1148 switch (instr->Mask(DataProcessing2SourceMask)) { 1149 case SDIV_w: { 1150 int32_t rn = wreg(instr->Rn()); 1151 int32_t rm = wreg(instr->Rm()); 1152 if ((rn == kWMinInt) && (rm == -1)) { 1153 result = kWMinInt; 1154 } else if (rm == 0) { 1155 // Division by zero can be trapped, but not on A-class processors. 1156 result = 0; 1157 } else { 1158 result = rn / rm; 1159 } 1160 break; 1161 } 1162 case SDIV_x: { 1163 int64_t rn = xreg(instr->Rn()); 1164 int64_t rm = xreg(instr->Rm()); 1165 if ((rn == kXMinInt) && (rm == -1)) { 1166 result = kXMinInt; 1167 } else if (rm == 0) { 1168 // Division by zero can be trapped, but not on A-class processors. 1169 result = 0; 1170 } else { 1171 result = rn / rm; 1172 } 1173 break; 1174 } 1175 case UDIV_w: { 1176 uint32_t rn = static_cast<uint32_t>(wreg(instr->Rn())); 1177 uint32_t rm = static_cast<uint32_t>(wreg(instr->Rm())); 1178 if (rm == 0) { 1179 // Division by zero can be trapped, but not on A-class processors. 1180 result = 0; 1181 } else { 1182 result = rn / rm; 1183 } 1184 break; 1185 } 1186 case UDIV_x: { 1187 uint64_t rn = static_cast<uint64_t>(xreg(instr->Rn())); 1188 uint64_t rm = static_cast<uint64_t>(xreg(instr->Rm())); 1189 if (rm == 0) { 1190 // Division by zero can be trapped, but not on A-class processors. 1191 result = 0; 1192 } else { 1193 result = rn / rm; 1194 } 1195 break; 1196 } 1197 case LSLV_w: 1198 case LSLV_x: shift_op = LSL; break; 1199 case LSRV_w: 1200 case LSRV_x: shift_op = LSR; break; 1201 case ASRV_w: 1202 case ASRV_x: shift_op = ASR; break; 1203 case RORV_w: 1204 case RORV_x: shift_op = ROR; break; 1205 default: VIXL_UNIMPLEMENTED(); 1206 } 1207 1208 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 1209 if (shift_op != NO_SHIFT) { 1210 // Shift distance encoded in the least-significant five/six bits of the 1211 // register. 1212 int mask = (instr->SixtyFourBits() != 0) ? 0x3f : 0x1f; 1213 unsigned shift = wreg(instr->Rm()) & mask; 1214 result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op, 1215 shift); 1216 } 1217 set_reg(reg_size, instr->Rd(), result); 1218 } 1219 1220 1221 // The algorithm used is adapted from the one described in section 8.2 of 1222 // Hacker's Delight, by Henry S. Warren, Jr. 1223 // It assumes that a right shift on a signed integer is an arithmetic shift. 1224 static int64_t MultiplyHighSigned(int64_t u, int64_t v) { 1225 uint64_t u0, v0, w0; 1226 int64_t u1, v1, w1, w2, t; 1227 1228 u0 = u & 0xffffffff; 1229 u1 = u >> 32; 1230 v0 = v & 0xffffffff; 1231 v1 = v >> 32; 1232 1233 w0 = u0 * v0; 1234 t = u1 * v0 + (w0 >> 32); 1235 w1 = t & 0xffffffff; 1236 w2 = t >> 32; 1237 w1 = u0 * v1 + w1; 1238 1239 return u1 * v1 + w2 + (w1 >> 32); 1240 } 1241 1242 1243 void Simulator::VisitDataProcessing3Source(Instruction* instr) { 1244 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 1245 1246 int64_t result = 0; 1247 // Extract and sign- or zero-extend 32-bit arguments for widening operations. 1248 uint64_t rn_u32 = reg<uint32_t>(instr->Rn()); 1249 uint64_t rm_u32 = reg<uint32_t>(instr->Rm()); 1250 int64_t rn_s32 = reg<int32_t>(instr->Rn()); 1251 int64_t rm_s32 = reg<int32_t>(instr->Rm()); 1252 switch (instr->Mask(DataProcessing3SourceMask)) { 1253 case MADD_w: 1254 case MADD_x: 1255 result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm())); 1256 break; 1257 case MSUB_w: 1258 case MSUB_x: 1259 result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm())); 1260 break; 1261 case SMADDL_x: result = xreg(instr->Ra()) + (rn_s32 * rm_s32); break; 1262 case SMSUBL_x: result = xreg(instr->Ra()) - (rn_s32 * rm_s32); break; 1263 case UMADDL_x: result = xreg(instr->Ra()) + (rn_u32 * rm_u32); break; 1264 case UMSUBL_x: result = xreg(instr->Ra()) - (rn_u32 * rm_u32); break; 1265 case SMULH_x: 1266 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); 1267 break; 1268 default: VIXL_UNIMPLEMENTED(); 1269 } 1270 set_reg(reg_size, instr->Rd(), result); 1271 } 1272 1273 1274 void Simulator::VisitBitfield(Instruction* instr) { 1275 unsigned reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; 1276 int64_t reg_mask = instr->SixtyFourBits() ? kXRegMask : kWRegMask; 1277 int64_t R = instr->ImmR(); 1278 int64_t S = instr->ImmS(); 1279 int64_t diff = S - R; 1280 int64_t mask; 1281 if (diff >= 0) { 1282 mask = (diff < (reg_size - 1)) ? (INT64_C(1) << (diff + 1)) - 1 1283 : reg_mask; 1284 } else { 1285 mask = (INT64_C(1) << (S + 1)) - 1; 1286 mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R)); 1287 diff += reg_size; 1288 } 1289 1290 // inzero indicates if the extracted bitfield is inserted into the 1291 // destination register value or in zero. 1292 // If extend is true, extend the sign of the extracted bitfield. 1293 bool inzero = false; 1294 bool extend = false; 1295 switch (instr->Mask(BitfieldMask)) { 1296 case BFM_x: 1297 case BFM_w: 1298 break; 1299 case SBFM_x: 1300 case SBFM_w: 1301 inzero = true; 1302 extend = true; 1303 break; 1304 case UBFM_x: 1305 case UBFM_w: 1306 inzero = true; 1307 break; 1308 default: 1309 VIXL_UNIMPLEMENTED(); 1310 } 1311 1312 int64_t dst = inzero ? 0 : reg(reg_size, instr->Rd()); 1313 int64_t src = reg(reg_size, instr->Rn()); 1314 // Rotate source bitfield into place. 1315 int64_t result = (static_cast<uint64_t>(src) >> R) | (src << (reg_size - R)); 1316 // Determine the sign extension. 1317 int64_t topbits = ((INT64_C(1) << (reg_size - diff - 1)) - 1) << (diff + 1); 1318 int64_t signbits = extend && ((src >> S) & 1) ? topbits : 0; 1319 1320 // Merge sign extension, dest/zero and bitfield. 1321 result = signbits | (result & mask) | (dst & ~mask); 1322 1323 set_reg(reg_size, instr->Rd(), result); 1324 } 1325 1326 1327 void Simulator::VisitExtract(Instruction* instr) { 1328 unsigned lsb = instr->ImmS(); 1329 unsigned reg_size = (instr->SixtyFourBits() != 0) ? kXRegSize 1330 : kWRegSize; 1331 set_reg(reg_size, 1332 instr->Rd(), 1333 (static_cast<uint64_t>(reg(reg_size, instr->Rm())) >> lsb) | 1334 (reg(reg_size, instr->Rn()) << (reg_size - lsb))); 1335 } 1336 1337 1338 void Simulator::VisitFPImmediate(Instruction* instr) { 1339 AssertSupportedFPCR(); 1340 1341 unsigned dest = instr->Rd(); 1342 switch (instr->Mask(FPImmediateMask)) { 1343 case FMOV_s_imm: set_sreg(dest, instr->ImmFP32()); break; 1344 case FMOV_d_imm: set_dreg(dest, instr->ImmFP64()); break; 1345 default: VIXL_UNREACHABLE(); 1346 } 1347 } 1348 1349 1350 void Simulator::VisitFPIntegerConvert(Instruction* instr) { 1351 AssertSupportedFPCR(); 1352 1353 unsigned dst = instr->Rd(); 1354 unsigned src = instr->Rn(); 1355 1356 FPRounding round = RMode(); 1357 1358 switch (instr->Mask(FPIntegerConvertMask)) { 1359 case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break; 1360 case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break; 1361 case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break; 1362 case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break; 1363 case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break; 1364 case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break; 1365 case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break; 1366 case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break; 1367 case FCVTMS_ws: 1368 set_wreg(dst, FPToInt32(sreg(src), FPNegativeInfinity)); 1369 break; 1370 case FCVTMS_xs: 1371 set_xreg(dst, FPToInt64(sreg(src), FPNegativeInfinity)); 1372 break; 1373 case FCVTMS_wd: 1374 set_wreg(dst, FPToInt32(dreg(src), FPNegativeInfinity)); 1375 break; 1376 case FCVTMS_xd: 1377 set_xreg(dst, FPToInt64(dreg(src), FPNegativeInfinity)); 1378 break; 1379 case FCVTMU_ws: 1380 set_wreg(dst, FPToUInt32(sreg(src), FPNegativeInfinity)); 1381 break; 1382 case FCVTMU_xs: 1383 set_xreg(dst, FPToUInt64(sreg(src), FPNegativeInfinity)); 1384 break; 1385 case FCVTMU_wd: 1386 set_wreg(dst, FPToUInt32(dreg(src), FPNegativeInfinity)); 1387 break; 1388 case FCVTMU_xd: 1389 set_xreg(dst, FPToUInt64(dreg(src), FPNegativeInfinity)); 1390 break; 1391 case FCVTNS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieEven)); break; 1392 case FCVTNS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieEven)); break; 1393 case FCVTNS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieEven)); break; 1394 case FCVTNS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieEven)); break; 1395 case FCVTNU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieEven)); break; 1396 case FCVTNU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieEven)); break; 1397 case FCVTNU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieEven)); break; 1398 case FCVTNU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieEven)); break; 1399 case FCVTZS_ws: set_wreg(dst, FPToInt32(sreg(src), FPZero)); break; 1400 case FCVTZS_xs: set_xreg(dst, FPToInt64(sreg(src), FPZero)); break; 1401 case FCVTZS_wd: set_wreg(dst, FPToInt32(dreg(src), FPZero)); break; 1402 case FCVTZS_xd: set_xreg(dst, FPToInt64(dreg(src), FPZero)); break; 1403 case FCVTZU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPZero)); break; 1404 case FCVTZU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPZero)); break; 1405 case FCVTZU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPZero)); break; 1406 case FCVTZU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPZero)); break; 1407 case FMOV_ws: set_wreg(dst, sreg_bits(src)); break; 1408 case FMOV_xd: set_xreg(dst, dreg_bits(src)); break; 1409 case FMOV_sw: set_sreg_bits(dst, wreg(src)); break; 1410 case FMOV_dx: set_dreg_bits(dst, xreg(src)); break; 1411 1412 // A 32-bit input can be handled in the same way as a 64-bit input, since 1413 // the sign- or zero-extension will not affect the conversion. 1414 case SCVTF_dx: set_dreg(dst, FixedToDouble(xreg(src), 0, round)); break; 1415 case SCVTF_dw: set_dreg(dst, FixedToDouble(wreg(src), 0, round)); break; 1416 case UCVTF_dx: set_dreg(dst, UFixedToDouble(xreg(src), 0, round)); break; 1417 case UCVTF_dw: { 1418 set_dreg(dst, UFixedToDouble(static_cast<uint32_t>(wreg(src)), 0, round)); 1419 break; 1420 } 1421 case SCVTF_sx: set_sreg(dst, FixedToFloat(xreg(src), 0, round)); break; 1422 case SCVTF_sw: set_sreg(dst, FixedToFloat(wreg(src), 0, round)); break; 1423 case UCVTF_sx: set_sreg(dst, UFixedToFloat(xreg(src), 0, round)); break; 1424 case UCVTF_sw: { 1425 set_sreg(dst, UFixedToFloat(static_cast<uint32_t>(wreg(src)), 0, round)); 1426 break; 1427 } 1428 1429 default: VIXL_UNREACHABLE(); 1430 } 1431 } 1432 1433 1434 void Simulator::VisitFPFixedPointConvert(Instruction* instr) { 1435 AssertSupportedFPCR(); 1436 1437 unsigned dst = instr->Rd(); 1438 unsigned src = instr->Rn(); 1439 int fbits = 64 - instr->FPScale(); 1440 1441 FPRounding round = RMode(); 1442 1443 switch (instr->Mask(FPFixedPointConvertMask)) { 1444 // A 32-bit input can be handled in the same way as a 64-bit input, since 1445 // the sign- or zero-extension will not affect the conversion. 1446 case SCVTF_dx_fixed: 1447 set_dreg(dst, FixedToDouble(xreg(src), fbits, round)); 1448 break; 1449 case SCVTF_dw_fixed: 1450 set_dreg(dst, FixedToDouble(wreg(src), fbits, round)); 1451 break; 1452 case UCVTF_dx_fixed: 1453 set_dreg(dst, UFixedToDouble(xreg(src), fbits, round)); 1454 break; 1455 case UCVTF_dw_fixed: { 1456 set_dreg(dst, 1457 UFixedToDouble(static_cast<uint32_t>(wreg(src)), fbits, round)); 1458 break; 1459 } 1460 case SCVTF_sx_fixed: 1461 set_sreg(dst, FixedToFloat(xreg(src), fbits, round)); 1462 break; 1463 case SCVTF_sw_fixed: 1464 set_sreg(dst, FixedToFloat(wreg(src), fbits, round)); 1465 break; 1466 case UCVTF_sx_fixed: 1467 set_sreg(dst, UFixedToFloat(xreg(src), fbits, round)); 1468 break; 1469 case UCVTF_sw_fixed: { 1470 set_sreg(dst, 1471 UFixedToFloat(static_cast<uint32_t>(wreg(src)), fbits, round)); 1472 break; 1473 } 1474 default: VIXL_UNREACHABLE(); 1475 } 1476 } 1477 1478 1479 int32_t Simulator::FPToInt32(double value, FPRounding rmode) { 1480 value = FPRoundInt(value, rmode); 1481 if (value >= kWMaxInt) { 1482 return kWMaxInt; 1483 } else if (value < kWMinInt) { 1484 return kWMinInt; 1485 } 1486 return std::isnan(value) ? 0 : static_cast<int32_t>(value); 1487 } 1488 1489 1490 int64_t Simulator::FPToInt64(double value, FPRounding rmode) { 1491 value = FPRoundInt(value, rmode); 1492 if (value >= kXMaxInt) { 1493 return kXMaxInt; 1494 } else if (value < kXMinInt) { 1495 return kXMinInt; 1496 } 1497 return std::isnan(value) ? 0 : static_cast<int64_t>(value); 1498 } 1499 1500 1501 uint32_t Simulator::FPToUInt32(double value, FPRounding rmode) { 1502 value = FPRoundInt(value, rmode); 1503 if (value >= kWMaxUInt) { 1504 return kWMaxUInt; 1505 } else if (value < 0.0) { 1506 return 0; 1507 } 1508 return std::isnan(value) ? 0 : static_cast<uint32_t>(value); 1509 } 1510 1511 1512 uint64_t Simulator::FPToUInt64(double value, FPRounding rmode) { 1513 value = FPRoundInt(value, rmode); 1514 if (value >= kXMaxUInt) { 1515 return kXMaxUInt; 1516 } else if (value < 0.0) { 1517 return 0; 1518 } 1519 return std::isnan(value) ? 0 : static_cast<uint64_t>(value); 1520 } 1521 1522 1523 void Simulator::VisitFPCompare(Instruction* instr) { 1524 AssertSupportedFPCR(); 1525 1526 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSize : kSRegSize; 1527 double fn_val = fpreg(reg_size, instr->Rn()); 1528 1529 switch (instr->Mask(FPCompareMask)) { 1530 case FCMP_s: 1531 case FCMP_d: FPCompare(fn_val, fpreg(reg_size, instr->Rm())); break; 1532 case FCMP_s_zero: 1533 case FCMP_d_zero: FPCompare(fn_val, 0.0); break; 1534 default: VIXL_UNIMPLEMENTED(); 1535 } 1536 } 1537 1538 1539 void Simulator::VisitFPConditionalCompare(Instruction* instr) { 1540 AssertSupportedFPCR(); 1541 1542 switch (instr->Mask(FPConditionalCompareMask)) { 1543 case FCCMP_s: 1544 case FCCMP_d: { 1545 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 1546 // If the condition passes, set the status flags to the result of 1547 // comparing the operands. 1548 unsigned reg_size = (instr->Mask(FP64) == FP64) ? kDRegSize : kSRegSize; 1549 FPCompare(fpreg(reg_size, instr->Rn()), fpreg(reg_size, instr->Rm())); 1550 } else { 1551 // If the condition fails, set the status flags to the nzcv immediate. 1552 nzcv().SetFlags(instr->Nzcv()); 1553 } 1554 break; 1555 } 1556 default: VIXL_UNIMPLEMENTED(); 1557 } 1558 } 1559 1560 1561 void Simulator::VisitFPConditionalSelect(Instruction* instr) { 1562 AssertSupportedFPCR(); 1563 1564 Instr selected; 1565 if (ConditionPassed(static_cast<Condition>(instr->Condition()))) { 1566 selected = instr->Rn(); 1567 } else { 1568 selected = instr->Rm(); 1569 } 1570 1571 switch (instr->Mask(FPConditionalSelectMask)) { 1572 case FCSEL_s: set_sreg(instr->Rd(), sreg(selected)); break; 1573 case FCSEL_d: set_dreg(instr->Rd(), dreg(selected)); break; 1574 default: VIXL_UNIMPLEMENTED(); 1575 } 1576 } 1577 1578 1579 void Simulator::VisitFPDataProcessing1Source(Instruction* instr) { 1580 AssertSupportedFPCR(); 1581 1582 unsigned fd = instr->Rd(); 1583 unsigned fn = instr->Rn(); 1584 1585 switch (instr->Mask(FPDataProcessing1SourceMask)) { 1586 case FMOV_s: set_sreg(fd, sreg(fn)); break; 1587 case FMOV_d: set_dreg(fd, dreg(fn)); break; 1588 case FABS_s: set_sreg(fd, fabsf(sreg(fn))); break; 1589 case FABS_d: set_dreg(fd, fabs(dreg(fn))); break; 1590 case FNEG_s: set_sreg(fd, -sreg(fn)); break; 1591 case FNEG_d: set_dreg(fd, -dreg(fn)); break; 1592 case FSQRT_s: set_sreg(fd, FPSqrt(sreg(fn))); break; 1593 case FSQRT_d: set_dreg(fd, FPSqrt(dreg(fn))); break; 1594 case FRINTA_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieAway)); break; 1595 case FRINTA_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieAway)); break; 1596 case FRINTM_s: 1597 set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break; 1598 case FRINTM_d: 1599 set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break; 1600 case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break; 1601 case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break; 1602 case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break; 1603 case FRINTZ_d: set_dreg(fd, FPRoundInt(dreg(fn), FPZero)); break; 1604 case FCVT_ds: set_dreg(fd, FPToDouble(sreg(fn))); break; 1605 case FCVT_sd: set_sreg(fd, FPToFloat(dreg(fn), FPTieEven)); break; 1606 default: VIXL_UNIMPLEMENTED(); 1607 } 1608 } 1609 1610 1611 // Assemble the specified IEEE-754 components into the target type and apply 1612 // appropriate rounding. 1613 // sign: 0 = positive, 1 = negative 1614 // exponent: Unbiased IEEE-754 exponent. 1615 // mantissa: The mantissa of the input. The top bit (which is not encoded for 1616 // normal IEEE-754 values) must not be omitted. This bit has the 1617 // value 'pow(2, exponent)'. 1618 // 1619 // The input value is assumed to be a normalized value. That is, the input may 1620 // not be infinity or NaN. If the source value is subnormal, it must be 1621 // normalized before calling this function such that the highest set bit in the 1622 // mantissa has the value 'pow(2, exponent)'. 1623 // 1624 // Callers should use FPRoundToFloat or FPRoundToDouble directly, rather than 1625 // calling a templated FPRound. 1626 template <class T, int ebits, int mbits> 1627 static T FPRound(int64_t sign, int64_t exponent, uint64_t mantissa, 1628 FPRounding round_mode) { 1629 VIXL_ASSERT((sign == 0) || (sign == 1)); 1630 1631 // Only the FPTieEven rounding mode is implemented. 1632 VIXL_ASSERT(round_mode == FPTieEven); 1633 USE(round_mode); 1634 1635 // Rounding can promote subnormals to normals, and normals to infinities. For 1636 // example, a double with exponent 127 (FLT_MAX_EXP) would appear to be 1637 // encodable as a float, but rounding based on the low-order mantissa bits 1638 // could make it overflow. With ties-to-even rounding, this value would become 1639 // an infinity. 1640 1641 // ---- Rounding Method ---- 1642 // 1643 // The exponent is irrelevant in the rounding operation, so we treat the 1644 // lowest-order bit that will fit into the result ('onebit') as having 1645 // the value '1'. Similarly, the highest-order bit that won't fit into 1646 // the result ('halfbit') has the value '0.5'. The 'point' sits between 1647 // 'onebit' and 'halfbit': 1648 // 1649 // These bits fit into the result. 1650 // |---------------------| 1651 // mantissa = 0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 1652 // || 1653 // / | 1654 // / halfbit 1655 // onebit 1656 // 1657 // For subnormal outputs, the range of representable bits is smaller and 1658 // the position of onebit and halfbit depends on the exponent of the 1659 // input, but the method is otherwise similar. 1660 // 1661 // onebit(frac) 1662 // | 1663 // | halfbit(frac) halfbit(adjusted) 1664 // | / / 1665 // | | | 1666 // 0b00.0 (exact) -> 0b00.0 (exact) -> 0b00 1667 // 0b00.0... -> 0b00.0... -> 0b00 1668 // 0b00.1 (exact) -> 0b00.0111..111 -> 0b00 1669 // 0b00.1... -> 0b00.1... -> 0b01 1670 // 0b01.0 (exact) -> 0b01.0 (exact) -> 0b01 1671 // 0b01.0... -> 0b01.0... -> 0b01 1672 // 0b01.1 (exact) -> 0b01.1 (exact) -> 0b10 1673 // 0b01.1... -> 0b01.1... -> 0b10 1674 // 0b10.0 (exact) -> 0b10.0 (exact) -> 0b10 1675 // 0b10.0... -> 0b10.0... -> 0b10 1676 // 0b10.1 (exact) -> 0b10.0111..111 -> 0b10 1677 // 0b10.1... -> 0b10.1... -> 0b11 1678 // 0b11.0 (exact) -> 0b11.0 (exact) -> 0b11 1679 // ... / | / | 1680 // / | / | 1681 // / | 1682 // adjusted = frac - (halfbit(mantissa) & ~onebit(frac)); / | 1683 // 1684 // mantissa = (mantissa >> shift) + halfbit(adjusted); 1685 1686 static const int mantissa_offset = 0; 1687 static const int exponent_offset = mantissa_offset + mbits; 1688 static const int sign_offset = exponent_offset + ebits; 1689 VIXL_ASSERT(sign_offset == (sizeof(T) * 8 - 1)); 1690 1691 // Bail out early for zero inputs. 1692 if (mantissa == 0) { 1693 return sign << sign_offset; 1694 } 1695 1696 // If all bits in the exponent are set, the value is infinite or NaN. 1697 // This is true for all binary IEEE-754 formats. 1698 static const int infinite_exponent = (1 << ebits) - 1; 1699 static const int max_normal_exponent = infinite_exponent - 1; 1700 1701 // Apply the exponent bias to encode it for the result. Doing this early makes 1702 // it easy to detect values that will be infinite or subnormal. 1703 exponent += max_normal_exponent >> 1; 1704 1705 if (exponent > max_normal_exponent) { 1706 // Overflow: The input is too large for the result type to represent. The 1707 // FPTieEven rounding mode handles overflows using infinities. 1708 exponent = infinite_exponent; 1709 mantissa = 0; 1710 return (sign << sign_offset) | 1711 (exponent << exponent_offset) | 1712 (mantissa << mantissa_offset); 1713 } 1714 1715 // Calculate the shift required to move the top mantissa bit to the proper 1716 // place in the destination type. 1717 const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64); 1718 int shift = highest_significant_bit - mbits; 1719 1720 if (exponent <= 0) { 1721 // The output will be subnormal (before rounding). 1722 1723 // For subnormal outputs, the shift must be adjusted by the exponent. The +1 1724 // is necessary because the exponent of a subnormal value (encoded as 0) is 1725 // the same as the exponent of the smallest normal value (encoded as 1). 1726 shift += -exponent + 1; 1727 1728 // Handle inputs that would produce a zero output. 1729 // 1730 // Shifts higher than highest_significant_bit+1 will always produce a zero 1731 // result. A shift of exactly highest_significant_bit+1 might produce a 1732 // non-zero result after rounding. 1733 if (shift > (highest_significant_bit + 1)) { 1734 // The result will always be +/-0.0. 1735 return sign << sign_offset; 1736 } 1737 1738 // Properly encode the exponent for a subnormal output. 1739 exponent = 0; 1740 } else { 1741 // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 1742 // normal values. 1743 mantissa &= ~(UINT64_C(1) << highest_significant_bit); 1744 } 1745 1746 if (shift > 0) { 1747 // We have to shift the mantissa to the right. Some precision is lost, so we 1748 // need to apply rounding. 1749 uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; 1750 uint64_t halfbit_mantissa = (mantissa >> (shift-1)) & 1; 1751 uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa); 1752 T halfbit_adjusted = (adjusted >> (shift-1)) & 1; 1753 1754 T result = (sign << sign_offset) | 1755 (exponent << exponent_offset) | 1756 ((mantissa >> shift) << mantissa_offset); 1757 1758 // A very large mantissa can overflow during rounding. If this happens, the 1759 // exponent should be incremented and the mantissa set to 1.0 (encoded as 1760 // 0). Applying halfbit_adjusted after assembling the float has the nice 1761 // side-effect that this case is handled for free. 1762 // 1763 // This also handles cases where a very large finite value overflows to 1764 // infinity, or where a very large subnormal value overflows to become 1765 // normal. 1766 return result + halfbit_adjusted; 1767 } else { 1768 // We have to shift the mantissa to the left (or not at all). The input 1769 // mantissa is exactly representable in the output mantissa, so apply no 1770 // rounding correction. 1771 return (sign << sign_offset) | 1772 (exponent << exponent_offset) | 1773 ((mantissa << -shift) << mantissa_offset); 1774 } 1775 } 1776 1777 1778 // See FPRound for a description of this function. 1779 static inline double FPRoundToDouble(int64_t sign, int64_t exponent, 1780 uint64_t mantissa, FPRounding round_mode) { 1781 int64_t bits = 1782 FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign, 1783 exponent, 1784 mantissa, 1785 round_mode); 1786 return rawbits_to_double(bits); 1787 } 1788 1789 1790 // See FPRound for a description of this function. 1791 static inline float FPRoundToFloat(int64_t sign, int64_t exponent, 1792 uint64_t mantissa, FPRounding round_mode) { 1793 int32_t bits = 1794 FPRound<int32_t, kFloatExponentBits, kFloatMantissaBits>(sign, 1795 exponent, 1796 mantissa, 1797 round_mode); 1798 return rawbits_to_float(bits); 1799 } 1800 1801 1802 double Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) { 1803 if (src >= 0) { 1804 return UFixedToDouble(src, fbits, round); 1805 } else { 1806 // This works for all negative values, including INT64_MIN. 1807 return -UFixedToDouble(-src, fbits, round); 1808 } 1809 } 1810 1811 1812 double Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) { 1813 // An input of 0 is a special case because the result is effectively 1814 // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit. 1815 if (src == 0) { 1816 return 0.0; 1817 } 1818 1819 // Calculate the exponent. The highest significant bit will have the value 1820 // 2^exponent. 1821 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64); 1822 const int64_t exponent = highest_significant_bit - fbits; 1823 1824 return FPRoundToDouble(0, exponent, src, round); 1825 } 1826 1827 1828 float Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) { 1829 if (src >= 0) { 1830 return UFixedToFloat(src, fbits, round); 1831 } else { 1832 // This works for all negative values, including INT64_MIN. 1833 return -UFixedToFloat(-src, fbits, round); 1834 } 1835 } 1836 1837 1838 float Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) { 1839 // An input of 0 is a special case because the result is effectively 1840 // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit. 1841 if (src == 0) { 1842 return 0.0f; 1843 } 1844 1845 // Calculate the exponent. The highest significant bit will have the value 1846 // 2^exponent. 1847 const int highest_significant_bit = 63 - CountLeadingZeros(src, 64); 1848 const int32_t exponent = highest_significant_bit - fbits; 1849 1850 return FPRoundToFloat(0, exponent, src, round); 1851 } 1852 1853 1854 double Simulator::FPRoundInt(double value, FPRounding round_mode) { 1855 if ((value == 0.0) || (value == kFP64PositiveInfinity) || 1856 (value == kFP64NegativeInfinity)) { 1857 return value; 1858 } else if (std::isnan(value)) { 1859 return FPProcessNaN(value); 1860 } 1861 1862 double int_result = floor(value); 1863 double error = value - int_result; 1864 switch (round_mode) { 1865 case FPTieAway: { 1866 // Take care of correctly handling the range ]-0.5, -0.0], which must 1867 // yield -0.0. 1868 if ((-0.5 < value) && (value < 0.0)) { 1869 int_result = -0.0; 1870 1871 } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) { 1872 // If the error is greater than 0.5, or is equal to 0.5 and the integer 1873 // result is positive, round up. 1874 int_result++; 1875 } 1876 break; 1877 } 1878 case FPTieEven: { 1879 // Take care of correctly handling the range [-0.5, -0.0], which must 1880 // yield -0.0. 1881 if ((-0.5 <= value) && (value < 0.0)) { 1882 int_result = -0.0; 1883 1884 // If the error is greater than 0.5, or is equal to 0.5 and the integer 1885 // result is odd, round up. 1886 } else if ((error > 0.5) || 1887 ((error == 0.5) && (fmod(int_result, 2) != 0))) { 1888 int_result++; 1889 } 1890 break; 1891 } 1892 case FPZero: { 1893 // If value>0 then we take floor(value) 1894 // otherwise, ceil(value). 1895 if (value < 0) { 1896 int_result = ceil(value); 1897 } 1898 break; 1899 } 1900 case FPNegativeInfinity: { 1901 // We always use floor(value). 1902 break; 1903 } 1904 default: VIXL_UNIMPLEMENTED(); 1905 } 1906 return int_result; 1907 } 1908 1909 1910 double Simulator::FPToDouble(float value) { 1911 switch (std::fpclassify(value)) { 1912 case FP_NAN: { 1913 if (DN()) return kFP64DefaultNaN; 1914 1915 // Convert NaNs as the processor would: 1916 // - The sign is propagated. 1917 // - The payload (mantissa) is transferred entirely, except that the top 1918 // bit is forced to '1', making the result a quiet NaN. The unused 1919 // (low-order) payload bits are set to 0. 1920 uint32_t raw = float_to_rawbits(value); 1921 1922 uint64_t sign = raw >> 31; 1923 uint64_t exponent = (1 << 11) - 1; 1924 uint64_t payload = unsigned_bitextract_64(21, 0, raw); 1925 payload <<= (52 - 23); // The unused low-order bits should be 0. 1926 payload |= (UINT64_C(1) << 51); // Force a quiet NaN. 1927 1928 return rawbits_to_double((sign << 63) | (exponent << 52) | payload); 1929 } 1930 1931 case FP_ZERO: 1932 case FP_NORMAL: 1933 case FP_SUBNORMAL: 1934 case FP_INFINITE: { 1935 // All other inputs are preserved in a standard cast, because every value 1936 // representable using an IEEE-754 float is also representable using an 1937 // IEEE-754 double. 1938 return static_cast<double>(value); 1939 } 1940 } 1941 1942 VIXL_UNREACHABLE(); 1943 return static_cast<double>(value); 1944 } 1945 1946 1947 float Simulator::FPToFloat(double value, FPRounding round_mode) { 1948 // Only the FPTieEven rounding mode is implemented. 1949 VIXL_ASSERT(round_mode == FPTieEven); 1950 USE(round_mode); 1951 1952 switch (std::fpclassify(value)) { 1953 case FP_NAN: { 1954 if (DN()) return kFP32DefaultNaN; 1955 1956 // Convert NaNs as the processor would: 1957 // - The sign is propagated. 1958 // - The payload (mantissa) is transferred as much as possible, except 1959 // that the top bit is forced to '1', making the result a quiet NaN. 1960 uint64_t raw = double_to_rawbits(value); 1961 1962 uint32_t sign = raw >> 63; 1963 uint32_t exponent = (1 << 8) - 1; 1964 uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); 1965 payload |= (1 << 22); // Force a quiet NaN. 1966 1967 return rawbits_to_float((sign << 31) | (exponent << 23) | payload); 1968 } 1969 1970 case FP_ZERO: 1971 case FP_INFINITE: { 1972 // In a C++ cast, any value representable in the target type will be 1973 // unchanged. This is always the case for +/-0.0 and infinities. 1974 return static_cast<float>(value); 1975 } 1976 1977 case FP_NORMAL: 1978 case FP_SUBNORMAL: { 1979 // Convert double-to-float as the processor would, assuming that FPCR.FZ 1980 // (flush-to-zero) is not set. 1981 uint64_t raw = double_to_rawbits(value); 1982 // Extract the IEEE-754 double components. 1983 uint32_t sign = raw >> 63; 1984 // Extract the exponent and remove the IEEE-754 encoding bias. 1985 int32_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023; 1986 // Extract the mantissa and add the implicit '1' bit. 1987 uint64_t mantissa = unsigned_bitextract_64(51, 0, raw); 1988 if (std::fpclassify(value) == FP_NORMAL) { 1989 mantissa |= (UINT64_C(1) << 52); 1990 } 1991 return FPRoundToFloat(sign, exponent, mantissa, round_mode); 1992 } 1993 } 1994 1995 VIXL_UNREACHABLE(); 1996 return value; 1997 } 1998 1999 2000 void Simulator::VisitFPDataProcessing2Source(Instruction* instr) { 2001 AssertSupportedFPCR(); 2002 2003 unsigned fd = instr->Rd(); 2004 unsigned fn = instr->Rn(); 2005 unsigned fm = instr->Rm(); 2006 2007 // Fmaxnm and Fminnm have special NaN handling. 2008 switch (instr->Mask(FPDataProcessing2SourceMask)) { 2009 case FMAXNM_s: set_sreg(fd, FPMaxNM(sreg(fn), sreg(fm))); return; 2010 case FMAXNM_d: set_dreg(fd, FPMaxNM(dreg(fn), dreg(fm))); return; 2011 case FMINNM_s: set_sreg(fd, FPMinNM(sreg(fn), sreg(fm))); return; 2012 case FMINNM_d: set_dreg(fd, FPMinNM(dreg(fn), dreg(fm))); return; 2013 default: 2014 break; // Fall through. 2015 } 2016 2017 if (FPProcessNaNs(instr)) return; 2018 2019 switch (instr->Mask(FPDataProcessing2SourceMask)) { 2020 case FADD_s: set_sreg(fd, FPAdd(sreg(fn), sreg(fm))); break; 2021 case FADD_d: set_dreg(fd, FPAdd(dreg(fn), dreg(fm))); break; 2022 case FSUB_s: set_sreg(fd, FPSub(sreg(fn), sreg(fm))); break; 2023 case FSUB_d: set_dreg(fd, FPSub(dreg(fn), dreg(fm))); break; 2024 case FMUL_s: set_sreg(fd, FPMul(sreg(fn), sreg(fm))); break; 2025 case FMUL_d: set_dreg(fd, FPMul(dreg(fn), dreg(fm))); break; 2026 case FDIV_s: set_sreg(fd, FPDiv(sreg(fn), sreg(fm))); break; 2027 case FDIV_d: set_dreg(fd, FPDiv(dreg(fn), dreg(fm))); break; 2028 case FMAX_s: set_sreg(fd, FPMax(sreg(fn), sreg(fm))); break; 2029 case FMAX_d: set_dreg(fd, FPMax(dreg(fn), dreg(fm))); break; 2030 case FMIN_s: set_sreg(fd, FPMin(sreg(fn), sreg(fm))); break; 2031 case FMIN_d: set_dreg(fd, FPMin(dreg(fn), dreg(fm))); break; 2032 case FMAXNM_s: 2033 case FMAXNM_d: 2034 case FMINNM_s: 2035 case FMINNM_d: 2036 // These were handled before the standard FPProcessNaNs() stage. 2037 VIXL_UNREACHABLE(); 2038 default: VIXL_UNIMPLEMENTED(); 2039 } 2040 } 2041 2042 2043 void Simulator::VisitFPDataProcessing3Source(Instruction* instr) { 2044 AssertSupportedFPCR(); 2045 2046 unsigned fd = instr->Rd(); 2047 unsigned fn = instr->Rn(); 2048 unsigned fm = instr->Rm(); 2049 unsigned fa = instr->Ra(); 2050 2051 switch (instr->Mask(FPDataProcessing3SourceMask)) { 2052 // fd = fa +/- (fn * fm) 2053 case FMADD_s: set_sreg(fd, FPMulAdd(sreg(fa), sreg(fn), sreg(fm))); break; 2054 case FMSUB_s: set_sreg(fd, FPMulAdd(sreg(fa), -sreg(fn), sreg(fm))); break; 2055 case FMADD_d: set_dreg(fd, FPMulAdd(dreg(fa), dreg(fn), dreg(fm))); break; 2056 case FMSUB_d: set_dreg(fd, FPMulAdd(dreg(fa), -dreg(fn), dreg(fm))); break; 2057 // Negated variants of the above. 2058 case FNMADD_s: 2059 set_sreg(fd, FPMulAdd(-sreg(fa), -sreg(fn), sreg(fm))); 2060 break; 2061 case FNMSUB_s: 2062 set_sreg(fd, FPMulAdd(-sreg(fa), sreg(fn), sreg(fm))); 2063 break; 2064 case FNMADD_d: 2065 set_dreg(fd, FPMulAdd(-dreg(fa), -dreg(fn), dreg(fm))); 2066 break; 2067 case FNMSUB_d: 2068 set_dreg(fd, FPMulAdd(-dreg(fa), dreg(fn), dreg(fm))); 2069 break; 2070 default: VIXL_UNIMPLEMENTED(); 2071 } 2072 } 2073 2074 2075 template <typename T> 2076 T Simulator::FPAdd(T op1, T op2) { 2077 // NaNs should be handled elsewhere. 2078 VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2079 2080 if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) { 2081 // inf + -inf returns the default NaN. 2082 FPProcessException(); 2083 return FPDefaultNaN<T>(); 2084 } else { 2085 // Other cases should be handled by standard arithmetic. 2086 return op1 + op2; 2087 } 2088 } 2089 2090 2091 template <typename T> 2092 T Simulator::FPDiv(T op1, T op2) { 2093 // NaNs should be handled elsewhere. 2094 VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2095 2096 if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) { 2097 // inf / inf and 0.0 / 0.0 return the default NaN. 2098 FPProcessException(); 2099 return FPDefaultNaN<T>(); 2100 } else { 2101 if (op2 == 0.0) FPProcessException(); 2102 2103 // Other cases should be handled by standard arithmetic. 2104 return op1 / op2; 2105 } 2106 } 2107 2108 2109 template <typename T> 2110 T Simulator::FPMax(T a, T b) { 2111 // NaNs should be handled elsewhere. 2112 VIXL_ASSERT(!std::isnan(a) && !std::isnan(b)); 2113 2114 if ((a == 0.0) && (b == 0.0) && 2115 (copysign(1.0, a) != copysign(1.0, b))) { 2116 // a and b are zero, and the sign differs: return +0.0. 2117 return 0.0; 2118 } else { 2119 return (a > b) ? a : b; 2120 } 2121 } 2122 2123 2124 template <typename T> 2125 T Simulator::FPMaxNM(T a, T b) { 2126 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 2127 a = kFP64NegativeInfinity; 2128 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 2129 b = kFP64NegativeInfinity; 2130 } 2131 2132 T result = FPProcessNaNs(a, b); 2133 return std::isnan(result) ? result : FPMax(a, b); 2134 } 2135 2136 2137 template <typename T> 2138 T Simulator::FPMin(T a, T b) { 2139 // NaNs should be handled elsewhere. 2140 VIXL_ASSERT(!std::isnan(a) && !std::isnan(b)); 2141 2142 if ((a == 0.0) && (b == 0.0) && 2143 (copysign(1.0, a) != copysign(1.0, b))) { 2144 // a and b are zero, and the sign differs: return -0.0. 2145 return -0.0; 2146 } else { 2147 return (a < b) ? a : b; 2148 } 2149 } 2150 2151 2152 template <typename T> 2153 T Simulator::FPMinNM(T a, T b) { 2154 if (IsQuietNaN(a) && !IsQuietNaN(b)) { 2155 a = kFP64PositiveInfinity; 2156 } else if (!IsQuietNaN(a) && IsQuietNaN(b)) { 2157 b = kFP64PositiveInfinity; 2158 } 2159 2160 T result = FPProcessNaNs(a, b); 2161 return std::isnan(result) ? result : FPMin(a, b); 2162 } 2163 2164 2165 template <typename T> 2166 T Simulator::FPMul(T op1, T op2) { 2167 // NaNs should be handled elsewhere. 2168 VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2169 2170 if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) { 2171 // inf * 0.0 returns the default NaN. 2172 FPProcessException(); 2173 return FPDefaultNaN<T>(); 2174 } else { 2175 // Other cases should be handled by standard arithmetic. 2176 return op1 * op2; 2177 } 2178 } 2179 2180 2181 template<typename T> 2182 T Simulator::FPMulAdd(T a, T op1, T op2) { 2183 T result = FPProcessNaNs3(a, op1, op2); 2184 2185 T sign_a = copysign(1.0, a); 2186 T sign_prod = copysign(1.0, op1) * copysign(1.0, op2); 2187 bool isinf_prod = std::isinf(op1) || std::isinf(op2); 2188 bool operation_generates_nan = 2189 (std::isinf(op1) && (op2 == 0.0)) || // inf * 0.0 2190 (std::isinf(op2) && (op1 == 0.0)) || // 0.0 * inf 2191 (std::isinf(a) && isinf_prod && (sign_a != sign_prod)); // inf - inf 2192 2193 if (std::isnan(result)) { 2194 // Generated NaNs override quiet NaNs propagated from a. 2195 if (operation_generates_nan && IsQuietNaN(a)) { 2196 FPProcessException(); 2197 return FPDefaultNaN<T>(); 2198 } else { 2199 return result; 2200 } 2201 } 2202 2203 // If the operation would produce a NaN, return the default NaN. 2204 if (operation_generates_nan) { 2205 FPProcessException(); 2206 return FPDefaultNaN<T>(); 2207 } 2208 2209 // Work around broken fma implementations for exact zero results: The sign of 2210 // exact 0.0 results is positive unless both a and op1 * op2 are negative. 2211 if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) { 2212 return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0; 2213 } 2214 2215 result = FusedMultiplyAdd(op1, op2, a); 2216 VIXL_ASSERT(!std::isnan(result)); 2217 2218 // Work around broken fma implementations for rounded zero results: If a is 2219 // 0.0, the sign of the result is the sign of op1 * op2 before rounding. 2220 if ((a == 0.0) && (result == 0.0)) { 2221 return copysign(0.0, sign_prod); 2222 } 2223 2224 return result; 2225 } 2226 2227 2228 template <typename T> 2229 T Simulator::FPSub(T op1, T op2) { 2230 // NaNs should be handled elsewhere. 2231 VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2)); 2232 2233 if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) { 2234 // inf - inf returns the default NaN. 2235 FPProcessException(); 2236 return FPDefaultNaN<T>(); 2237 } else { 2238 // Other cases should be handled by standard arithmetic. 2239 return op1 - op2; 2240 } 2241 } 2242 2243 2244 template <typename T> 2245 T Simulator::FPSqrt(T op) { 2246 if (std::isnan(op)) { 2247 return FPProcessNaN(op); 2248 } else if (op < 0.0) { 2249 FPProcessException(); 2250 return FPDefaultNaN<T>(); 2251 } else { 2252 return sqrt(op); 2253 } 2254 } 2255 2256 2257 template <typename T> 2258 T Simulator::FPProcessNaN(T op) { 2259 VIXL_ASSERT(std::isnan(op)); 2260 if (IsSignallingNaN(op)) { 2261 FPProcessException(); 2262 } 2263 return DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); 2264 } 2265 2266 2267 template <typename T> 2268 T Simulator::FPProcessNaNs(T op1, T op2) { 2269 if (IsSignallingNaN(op1)) { 2270 return FPProcessNaN(op1); 2271 } else if (IsSignallingNaN(op2)) { 2272 return FPProcessNaN(op2); 2273 } else if (std::isnan(op1)) { 2274 VIXL_ASSERT(IsQuietNaN(op1)); 2275 return FPProcessNaN(op1); 2276 } else if (std::isnan(op2)) { 2277 VIXL_ASSERT(IsQuietNaN(op2)); 2278 return FPProcessNaN(op2); 2279 } else { 2280 return 0.0; 2281 } 2282 } 2283 2284 2285 template <typename T> 2286 T Simulator::FPProcessNaNs3(T op1, T op2, T op3) { 2287 if (IsSignallingNaN(op1)) { 2288 return FPProcessNaN(op1); 2289 } else if (IsSignallingNaN(op2)) { 2290 return FPProcessNaN(op2); 2291 } else if (IsSignallingNaN(op3)) { 2292 return FPProcessNaN(op3); 2293 } else if (std::isnan(op1)) { 2294 VIXL_ASSERT(IsQuietNaN(op1)); 2295 return FPProcessNaN(op1); 2296 } else if (std::isnan(op2)) { 2297 VIXL_ASSERT(IsQuietNaN(op2)); 2298 return FPProcessNaN(op2); 2299 } else if (std::isnan(op3)) { 2300 VIXL_ASSERT(IsQuietNaN(op3)); 2301 return FPProcessNaN(op3); 2302 } else { 2303 return 0.0; 2304 } 2305 } 2306 2307 2308 bool Simulator::FPProcessNaNs(Instruction* instr) { 2309 unsigned fd = instr->Rd(); 2310 unsigned fn = instr->Rn(); 2311 unsigned fm = instr->Rm(); 2312 bool done = false; 2313 2314 if (instr->Mask(FP64) == FP64) { 2315 double result = FPProcessNaNs(dreg(fn), dreg(fm)); 2316 if (std::isnan(result)) { 2317 set_dreg(fd, result); 2318 done = true; 2319 } 2320 } else { 2321 float result = FPProcessNaNs(sreg(fn), sreg(fm)); 2322 if (std::isnan(result)) { 2323 set_sreg(fd, result); 2324 done = true; 2325 } 2326 } 2327 2328 return done; 2329 } 2330 2331 2332 void Simulator::VisitSystem(Instruction* instr) { 2333 // Some system instructions hijack their Op and Cp fields to represent a 2334 // range of immediates instead of indicating a different instruction. This 2335 // makes the decoding tricky. 2336 if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) { 2337 switch (instr->Mask(SystemSysRegMask)) { 2338 case MRS: { 2339 switch (instr->ImmSystemRegister()) { 2340 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; 2341 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; 2342 default: VIXL_UNIMPLEMENTED(); 2343 } 2344 break; 2345 } 2346 case MSR: { 2347 switch (instr->ImmSystemRegister()) { 2348 case NZCV: nzcv().SetRawValue(xreg(instr->Rt())); break; 2349 case FPCR: fpcr().SetRawValue(xreg(instr->Rt())); break; 2350 default: VIXL_UNIMPLEMENTED(); 2351 } 2352 break; 2353 } 2354 } 2355 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 2356 VIXL_ASSERT(instr->Mask(SystemHintMask) == HINT); 2357 switch (instr->ImmHint()) { 2358 case NOP: break; 2359 default: VIXL_UNIMPLEMENTED(); 2360 } 2361 } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { 2362 __sync_synchronize(); 2363 } else { 2364 VIXL_UNIMPLEMENTED(); 2365 } 2366 } 2367 2368 2369 void Simulator::VisitException(Instruction* instr) { 2370 switch (instr->Mask(ExceptionMask)) { 2371 case BRK: HostBreakpoint(); break; 2372 case HLT: 2373 // The Printf pseudo instruction is so useful, we include it in the 2374 // default simulator. 2375 if (instr->ImmException() == kPrintfOpcode) { 2376 DoPrintf(instr); 2377 } else { 2378 HostBreakpoint(); 2379 } 2380 break; 2381 default: 2382 VIXL_UNIMPLEMENTED(); 2383 } 2384 } 2385 2386 2387 void Simulator::DoPrintf(Instruction* instr) { 2388 VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) && 2389 (instr->ImmException() == kPrintfOpcode)); 2390 2391 // Read the arguments encoded inline in the instruction stream. 2392 uint32_t arg_count; 2393 uint32_t arg_pattern_list; 2394 VIXL_STATIC_ASSERT(sizeof(*instr) == 1); 2395 memcpy(&arg_count, 2396 instr + kPrintfArgCountOffset, 2397 sizeof(arg_count)); 2398 memcpy(&arg_pattern_list, 2399 instr + kPrintfArgPatternListOffset, 2400 sizeof(arg_pattern_list)); 2401 2402 VIXL_ASSERT(arg_count <= kPrintfMaxArgCount); 2403 VIXL_ASSERT((arg_pattern_list >> (kPrintfArgPatternBits * arg_count)) == 0); 2404 2405 // We need to call the host printf function with a set of arguments defined by 2406 // arg_pattern_list. Because we don't know the types and sizes of the 2407 // arguments, this is very difficult to do in a robust and portable way. To 2408 // work around the problem, we pick apart the format string, and print one 2409 // format placeholder at a time. 2410 2411 // Allocate space for the format string. We take a copy, so we can modify it. 2412 // Leave enough space for one extra character per expected argument (plus the 2413 // '\0' termination). 2414 const char * format_base = reg<const char *>(0); 2415 VIXL_ASSERT(format_base != NULL); 2416 size_t length = strlen(format_base) + 1; 2417 char * const format = new char[length + arg_count]; 2418 2419 // A list of chunks, each with exactly one format placeholder. 2420 const char * chunks[kPrintfMaxArgCount]; 2421 2422 // Copy the format string and search for format placeholders. 2423 uint32_t placeholder_count = 0; 2424 char * format_scratch = format; 2425 for (size_t i = 0; i < length; i++) { 2426 if (format_base[i] != '%') { 2427 *format_scratch++ = format_base[i]; 2428 } else { 2429 if (format_base[i + 1] == '%') { 2430 // Ignore explicit "%%" sequences. 2431 *format_scratch++ = format_base[i]; 2432 i++; 2433 // Chunks after the first are passed as format strings to printf, so we 2434 // need to escape '%' characters in those chunks. 2435 if (placeholder_count > 0) *format_scratch++ = format_base[i]; 2436 } else { 2437 VIXL_CHECK(placeholder_count < arg_count); 2438 // Insert '\0' before placeholders, and store their locations. 2439 *format_scratch++ = '\0'; 2440 chunks[placeholder_count++] = format_scratch; 2441 *format_scratch++ = format_base[i]; 2442 } 2443 } 2444 } 2445 VIXL_CHECK(placeholder_count == arg_count); 2446 2447 // Finally, call printf with each chunk, passing the appropriate register 2448 // argument. Normally, printf returns the number of bytes transmitted, so we 2449 // can emulate a single printf call by adding the result from each chunk. If 2450 // any call returns a negative (error) value, though, just return that value. 2451 2452 printf("%s", clr_printf); 2453 2454 // Because '\0' is inserted before each placeholder, the first string in 2455 // 'format' contains no format placeholders and should be printed literally. 2456 int result = printf("%s", format); 2457 int pcs_r = 1; // Start at x1. x0 holds the format string. 2458 int pcs_f = 0; // Start at d0. 2459 if (result >= 0) { 2460 for (uint32_t i = 0; i < placeholder_count; i++) { 2461 int part_result = -1; 2462 2463 uint32_t arg_pattern = arg_pattern_list >> (i * kPrintfArgPatternBits); 2464 arg_pattern &= (1 << kPrintfArgPatternBits) - 1; 2465 switch (arg_pattern) { 2466 case kPrintfArgW: part_result = printf(chunks[i], wreg(pcs_r++)); break; 2467 case kPrintfArgX: part_result = printf(chunks[i], xreg(pcs_r++)); break; 2468 case kPrintfArgD: part_result = printf(chunks[i], dreg(pcs_f++)); break; 2469 default: VIXL_UNREACHABLE(); 2470 } 2471 2472 if (part_result < 0) { 2473 // Handle error values. 2474 result = part_result; 2475 break; 2476 } 2477 2478 result += part_result; 2479 } 2480 } 2481 2482 printf("%s", clr_normal); 2483 2484 // Printf returns its result in x0 (just like the C library's printf). 2485 set_xreg(0, result); 2486 2487 // The printf parameters are inlined in the code, so skip them. 2488 set_pc(instr->InstructionAtOffset(kPrintfLength)); 2489 2490 // Set LR as if we'd just called a native printf function. 2491 set_lr(pc()); 2492 2493 delete[] format; 2494 } 2495 2496 } // namespace vixl 2497 2498 #endif // USE_SIMULATOR 2499