EmulateInstructionARM.cpp revision 360784
1187692Snwhitehorn//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===// 2187692Snwhitehorn// 3187692Snwhitehorn// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4187692Snwhitehorn// See https://llvm.org/LICENSE.txt for license information. 5187692Snwhitehorn// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6187692Snwhitehorn// 7187692Snwhitehorn//===----------------------------------------------------------------------===// 8187692Snwhitehorn 9187692Snwhitehorn#include <stdlib.h> 10187692Snwhitehorn 11187692Snwhitehorn#include "EmulateInstructionARM.h" 12187692Snwhitehorn#include "EmulationStateARM.h" 13187692Snwhitehorn#include "lldb/Core/Address.h" 14187692Snwhitehorn#include "lldb/Core/PluginManager.h" 15187692Snwhitehorn#include "lldb/Host/PosixApi.h" 16187692Snwhitehorn#include "lldb/Interpreter/OptionValueArray.h" 17187692Snwhitehorn#include "lldb/Interpreter/OptionValueDictionary.h" 18187692Snwhitehorn#include "lldb/Symbol/UnwindPlan.h" 19187692Snwhitehorn#include "lldb/Utility/ArchSpec.h" 20187692Snwhitehorn#include "lldb/Utility/ConstString.h" 21187692Snwhitehorn#include "lldb/Utility/Stream.h" 22187692Snwhitehorn 23187692Snwhitehorn#include "Plugins/Process/Utility/ARMDefines.h" 24187692Snwhitehorn#include "Plugins/Process/Utility/ARMUtils.h" 25187692Snwhitehorn#include "Utility/ARM_DWARF_Registers.h" 26187692Snwhitehorn 27187692Snwhitehorn#include "llvm/ADT/STLExtras.h" 28187692Snwhitehorn#include "llvm/Support/MathExtras.h" 29187692Snwhitehorn 30187692Snwhitehornusing namespace lldb; 31187692Snwhitehornusing namespace lldb_private; 32187692Snwhitehorn 33187692Snwhitehorn// Convenient macro definitions. 34187692Snwhitehorn#define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS) 35187692Snwhitehorn#define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS) 36187692Snwhitehorn 37187692Snwhitehorn#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC) 38187692Snwhitehorn 39187692Snwhitehorn// 40187692Snwhitehorn// ITSession implementation 41187692Snwhitehorn// 42187692Snwhitehorn 43187692Snwhitehornstatic bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { 44187692Snwhitehorn ::memset(®_info, 0, sizeof(RegisterInfo)); 45187692Snwhitehorn ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); 46187692Snwhitehorn 47187692Snwhitehorn if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { 48187692Snwhitehorn reg_info.byte_size = 16; 49187692Snwhitehorn reg_info.format = eFormatVectorOfUInt8; 50187692Snwhitehorn reg_info.encoding = eEncodingVector; 51187692Snwhitehorn } 52187692Snwhitehorn 53187692Snwhitehorn if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31) { 54187692Snwhitehorn reg_info.byte_size = 8; 55187692Snwhitehorn reg_info.format = eFormatFloat; 56187692Snwhitehorn reg_info.encoding = eEncodingIEEE754; 57187692Snwhitehorn } else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31) { 58187692Snwhitehorn reg_info.byte_size = 4; 59187692Snwhitehorn reg_info.format = eFormatFloat; 60187692Snwhitehorn reg_info.encoding = eEncodingIEEE754; 61187692Snwhitehorn } else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7) { 62187692Snwhitehorn reg_info.byte_size = 12; 63187692Snwhitehorn reg_info.format = eFormatFloat; 64187692Snwhitehorn reg_info.encoding = eEncodingIEEE754; 65187692Snwhitehorn } else { 66187692Snwhitehorn reg_info.byte_size = 4; 67187692Snwhitehorn reg_info.format = eFormatHex; 68187692Snwhitehorn reg_info.encoding = eEncodingUint; 69187692Snwhitehorn } 70187692Snwhitehorn 71187692Snwhitehorn reg_info.kinds[eRegisterKindDWARF] = reg_num; 72187692Snwhitehorn 73187692Snwhitehorn switch (reg_num) { 74187692Snwhitehorn case dwarf_r0: 75187692Snwhitehorn reg_info.name = "r0"; 76187692Snwhitehorn break; 77187692Snwhitehorn case dwarf_r1: 78193640Sariff reg_info.name = "r1"; 79193640Sariff break; 80193640Sariff case dwarf_r2: 81193640Sariff reg_info.name = "r2"; 82193640Sariff break; 83187692Snwhitehorn case dwarf_r3: 84193640Sariff reg_info.name = "r3"; 85187692Snwhitehorn break; 86187692Snwhitehorn case dwarf_r4: 87187692Snwhitehorn reg_info.name = "r4"; 88187692Snwhitehorn break; 89187692Snwhitehorn case dwarf_r5: 90187692Snwhitehorn reg_info.name = "r5"; 91187692Snwhitehorn break; 92187692Snwhitehorn case dwarf_r6: 93187692Snwhitehorn reg_info.name = "r6"; 94187692Snwhitehorn break; 95187692Snwhitehorn case dwarf_r7: 96187692Snwhitehorn reg_info.name = "r7"; 97187692Snwhitehorn reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; 98187692Snwhitehorn break; 99193694Sariff case dwarf_r8: 100187692Snwhitehorn reg_info.name = "r8"; 101187692Snwhitehorn break; 102187692Snwhitehorn case dwarf_r9: 103193640Sariff reg_info.name = "r9"; 104187692Snwhitehorn break; 105187692Snwhitehorn case dwarf_r10: 106187692Snwhitehorn reg_info.name = "r10"; 107187692Snwhitehorn break; 108187692Snwhitehorn case dwarf_r11: 109187692Snwhitehorn reg_info.name = "r11"; 110187692Snwhitehorn break; 111187692Snwhitehorn case dwarf_r12: 112187692Snwhitehorn reg_info.name = "r12"; 113187692Snwhitehorn break; 114187692Snwhitehorn case dwarf_sp: 115187692Snwhitehorn reg_info.name = "sp"; 116187692Snwhitehorn reg_info.alt_name = "r13"; 117187692Snwhitehorn reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; 118187692Snwhitehorn break; 119187692Snwhitehorn case dwarf_lr: 120187692Snwhitehorn reg_info.name = "lr"; 121187692Snwhitehorn reg_info.alt_name = "r14"; 122187692Snwhitehorn reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; 123187692Snwhitehorn break; 124187692Snwhitehorn case dwarf_pc: 125187692Snwhitehorn reg_info.name = "pc"; 126187692Snwhitehorn reg_info.alt_name = "r15"; 127187692Snwhitehorn reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; 128187692Snwhitehorn break; 129187692Snwhitehorn case dwarf_cpsr: 130193640Sariff reg_info.name = "cpsr"; 131187692Snwhitehorn reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; 132187692Snwhitehorn break; 133187692Snwhitehorn 134187692Snwhitehorn case dwarf_s0: 135187692Snwhitehorn reg_info.name = "s0"; 136187692Snwhitehorn break; 137187692Snwhitehorn case dwarf_s1: 138187692Snwhitehorn reg_info.name = "s1"; 139187692Snwhitehorn break; 140187692Snwhitehorn case dwarf_s2: 141187692Snwhitehorn reg_info.name = "s2"; 142187692Snwhitehorn break; 143187692Snwhitehorn case dwarf_s3: 144187692Snwhitehorn reg_info.name = "s3"; 145187692Snwhitehorn break; 146187692Snwhitehorn case dwarf_s4: 147187692Snwhitehorn reg_info.name = "s4"; 148187692Snwhitehorn break; 149187692Snwhitehorn case dwarf_s5: 150187692Snwhitehorn reg_info.name = "s5"; 151187692Snwhitehorn break; 152187692Snwhitehorn case dwarf_s6: 153187692Snwhitehorn reg_info.name = "s6"; 154187692Snwhitehorn break; 155187692Snwhitehorn case dwarf_s7: 156187692Snwhitehorn reg_info.name = "s7"; 157187692Snwhitehorn break; 158187692Snwhitehorn case dwarf_s8: 159187692Snwhitehorn reg_info.name = "s8"; 160187692Snwhitehorn break; 161187692Snwhitehorn case dwarf_s9: 162187692Snwhitehorn reg_info.name = "s9"; 163187692Snwhitehorn break; 164187692Snwhitehorn case dwarf_s10: 165187692Snwhitehorn reg_info.name = "s10"; 166187692Snwhitehorn break; 167187692Snwhitehorn case dwarf_s11: 168187692Snwhitehorn reg_info.name = "s11"; 169187692Snwhitehorn break; 170187692Snwhitehorn case dwarf_s12: 171187692Snwhitehorn reg_info.name = "s12"; 172187692Snwhitehorn break; 173187692Snwhitehorn case dwarf_s13: 174187692Snwhitehorn reg_info.name = "s13"; 175187692Snwhitehorn break; 176187692Snwhitehorn case dwarf_s14: 177187692Snwhitehorn reg_info.name = "s14"; 178187692Snwhitehorn break; 179187692Snwhitehorn case dwarf_s15: 180187692Snwhitehorn reg_info.name = "s15"; 181187692Snwhitehorn break; 182187692Snwhitehorn case dwarf_s16: 183187692Snwhitehorn reg_info.name = "s16"; 184187692Snwhitehorn break; 185187692Snwhitehorn case dwarf_s17: 186187692Snwhitehorn reg_info.name = "s17"; 187187692Snwhitehorn break; 188187692Snwhitehorn case dwarf_s18: 189187692Snwhitehorn reg_info.name = "s18"; 190187692Snwhitehorn break; 191187692Snwhitehorn case dwarf_s19: 192187692Snwhitehorn reg_info.name = "s19"; 193187692Snwhitehorn break; 194187692Snwhitehorn case dwarf_s20: 195187692Snwhitehorn reg_info.name = "s20"; 196187692Snwhitehorn break; 197187692Snwhitehorn case dwarf_s21: 198187692Snwhitehorn reg_info.name = "s21"; 199187692Snwhitehorn break; 200187692Snwhitehorn case dwarf_s22: 201187692Snwhitehorn reg_info.name = "s22"; 202187692Snwhitehorn break; 203187692Snwhitehorn case dwarf_s23: 204187692Snwhitehorn reg_info.name = "s23"; 205187692Snwhitehorn break; 206187692Snwhitehorn case dwarf_s24: 207187692Snwhitehorn reg_info.name = "s24"; 208187692Snwhitehorn break; 209187692Snwhitehorn case dwarf_s25: 210187692Snwhitehorn reg_info.name = "s25"; 211187692Snwhitehorn break; 212187692Snwhitehorn case dwarf_s26: 213187692Snwhitehorn reg_info.name = "s26"; 214187692Snwhitehorn break; 215187692Snwhitehorn case dwarf_s27: 216187692Snwhitehorn reg_info.name = "s27"; 217187692Snwhitehorn break; 218187692Snwhitehorn case dwarf_s28: 219187692Snwhitehorn reg_info.name = "s28"; 220187692Snwhitehorn break; 221187692Snwhitehorn case dwarf_s29: 222187692Snwhitehorn reg_info.name = "s29"; 223187692Snwhitehorn break; 224187692Snwhitehorn case dwarf_s30: 225187692Snwhitehorn reg_info.name = "s30"; 226187692Snwhitehorn break; 227187692Snwhitehorn case dwarf_s31: 228187692Snwhitehorn reg_info.name = "s31"; 229187692Snwhitehorn break; 230187692Snwhitehorn 231187692Snwhitehorn // FPA Registers 0-7 232187692Snwhitehorn case dwarf_f0: 233187692Snwhitehorn reg_info.name = "f0"; 234187692Snwhitehorn break; 235187692Snwhitehorn case dwarf_f1: 236187692Snwhitehorn reg_info.name = "f1"; 237187692Snwhitehorn break; 238187692Snwhitehorn case dwarf_f2: 239187692Snwhitehorn reg_info.name = "f2"; 240187692Snwhitehorn break; 241187692Snwhitehorn case dwarf_f3: 242187692Snwhitehorn reg_info.name = "f3"; 243187692Snwhitehorn break; 244187692Snwhitehorn case dwarf_f4: 245187692Snwhitehorn reg_info.name = "f4"; 246187692Snwhitehorn break; 247187692Snwhitehorn case dwarf_f5: 248187692Snwhitehorn reg_info.name = "f5"; 249187692Snwhitehorn break; 250187692Snwhitehorn case dwarf_f6: 251187692Snwhitehorn reg_info.name = "f6"; 252187692Snwhitehorn break; 253187692Snwhitehorn case dwarf_f7: 254187692Snwhitehorn reg_info.name = "f7"; 255187692Snwhitehorn break; 256187692Snwhitehorn 257187692Snwhitehorn // Intel wireless MMX general purpose registers 0 - 7 XScale accumulator 258187692Snwhitehorn // register 0 - 7 (they do overlap with wCGR0 - wCGR7) 259187692Snwhitehorn case dwarf_wCGR0: 260187692Snwhitehorn reg_info.name = "wCGR0/ACC0"; 261187692Snwhitehorn break; 262187692Snwhitehorn case dwarf_wCGR1: 263187692Snwhitehorn reg_info.name = "wCGR1/ACC1"; 264187692Snwhitehorn break; 265187692Snwhitehorn case dwarf_wCGR2: 266187692Snwhitehorn reg_info.name = "wCGR2/ACC2"; 267187692Snwhitehorn break; 268187692Snwhitehorn case dwarf_wCGR3: 269187692Snwhitehorn reg_info.name = "wCGR3/ACC3"; 270187692Snwhitehorn break; 271187692Snwhitehorn case dwarf_wCGR4: 272187692Snwhitehorn reg_info.name = "wCGR4/ACC4"; 273187692Snwhitehorn break; 274187692Snwhitehorn case dwarf_wCGR5: 275187692Snwhitehorn reg_info.name = "wCGR5/ACC5"; 276187692Snwhitehorn break; 277187692Snwhitehorn case dwarf_wCGR6: 278187692Snwhitehorn reg_info.name = "wCGR6/ACC6"; 279187692Snwhitehorn break; 280187692Snwhitehorn case dwarf_wCGR7: 281187692Snwhitehorn reg_info.name = "wCGR7/ACC7"; 282187692Snwhitehorn break; 283187692Snwhitehorn 284187692Snwhitehorn // Intel wireless MMX data registers 0 - 15 285187692Snwhitehorn case dwarf_wR0: 286187692Snwhitehorn reg_info.name = "wR0"; 287187692Snwhitehorn break; 288187692Snwhitehorn case dwarf_wR1: 289187692Snwhitehorn reg_info.name = "wR1"; 290187692Snwhitehorn break; 291187692Snwhitehorn case dwarf_wR2: 292187692Snwhitehorn reg_info.name = "wR2"; 293187692Snwhitehorn break; 294187692Snwhitehorn case dwarf_wR3: 295187692Snwhitehorn reg_info.name = "wR3"; 296187692Snwhitehorn break; 297187692Snwhitehorn case dwarf_wR4: 298187692Snwhitehorn reg_info.name = "wR4"; 299187692Snwhitehorn break; 300187692Snwhitehorn case dwarf_wR5: 301187692Snwhitehorn reg_info.name = "wR5"; 302187692Snwhitehorn break; 303187692Snwhitehorn case dwarf_wR6: 304187692Snwhitehorn reg_info.name = "wR6"; 305187692Snwhitehorn break; 306187692Snwhitehorn case dwarf_wR7: 307187692Snwhitehorn reg_info.name = "wR7"; 308187692Snwhitehorn break; 309187692Snwhitehorn case dwarf_wR8: 310187692Snwhitehorn reg_info.name = "wR8"; 311187692Snwhitehorn break; 312187692Snwhitehorn case dwarf_wR9: 313187692Snwhitehorn reg_info.name = "wR9"; 314187692Snwhitehorn break; 315187692Snwhitehorn case dwarf_wR10: 316187692Snwhitehorn reg_info.name = "wR10"; 317187692Snwhitehorn break; 318187692Snwhitehorn case dwarf_wR11: 319187692Snwhitehorn reg_info.name = "wR11"; 320187692Snwhitehorn break; 321187692Snwhitehorn case dwarf_wR12: 322187692Snwhitehorn reg_info.name = "wR12"; 323187692Snwhitehorn break; 324187692Snwhitehorn case dwarf_wR13: 325187692Snwhitehorn reg_info.name = "wR13"; 326187692Snwhitehorn break; 327187692Snwhitehorn case dwarf_wR14: 328187692Snwhitehorn reg_info.name = "wR14"; 329187692Snwhitehorn break; 330187692Snwhitehorn case dwarf_wR15: 331187692Snwhitehorn reg_info.name = "wR15"; 332187692Snwhitehorn break; 333187692Snwhitehorn 334187692Snwhitehorn case dwarf_spsr: 335187692Snwhitehorn reg_info.name = "spsr"; 336187692Snwhitehorn break; 337187692Snwhitehorn case dwarf_spsr_fiq: 338187692Snwhitehorn reg_info.name = "spsr_fiq"; 339187692Snwhitehorn break; 340187692Snwhitehorn case dwarf_spsr_irq: 341187692Snwhitehorn reg_info.name = "spsr_irq"; 342187692Snwhitehorn break; 343187692Snwhitehorn case dwarf_spsr_abt: 344187692Snwhitehorn reg_info.name = "spsr_abt"; 345187692Snwhitehorn break; 346187692Snwhitehorn case dwarf_spsr_und: 347187692Snwhitehorn reg_info.name = "spsr_und"; 348187692Snwhitehorn break; 349187692Snwhitehorn case dwarf_spsr_svc: 350187692Snwhitehorn reg_info.name = "spsr_svc"; 351187692Snwhitehorn break; 352187692Snwhitehorn 353187692Snwhitehorn case dwarf_r8_usr: 354187692Snwhitehorn reg_info.name = "r8_usr"; 355187692Snwhitehorn break; 356187692Snwhitehorn case dwarf_r9_usr: 357187692Snwhitehorn reg_info.name = "r9_usr"; 358187692Snwhitehorn break; 359187692Snwhitehorn case dwarf_r10_usr: 360187692Snwhitehorn reg_info.name = "r10_usr"; 361187692Snwhitehorn break; 362187692Snwhitehorn case dwarf_r11_usr: 363187692Snwhitehorn reg_info.name = "r11_usr"; 364187692Snwhitehorn break; 365187692Snwhitehorn case dwarf_r12_usr: 366187692Snwhitehorn reg_info.name = "r12_usr"; 367187692Snwhitehorn break; 368187692Snwhitehorn case dwarf_r13_usr: 369187692Snwhitehorn reg_info.name = "r13_usr"; 370187692Snwhitehorn break; 371187692Snwhitehorn case dwarf_r14_usr: 372193694Sariff reg_info.name = "r14_usr"; 373187692Snwhitehorn break; 374187692Snwhitehorn case dwarf_r8_fiq: 375193694Sariff reg_info.name = "r8_fiq"; 376187692Snwhitehorn break; 377187692Snwhitehorn case dwarf_r9_fiq: 378187692Snwhitehorn reg_info.name = "r9_fiq"; 379187692Snwhitehorn break; 380187692Snwhitehorn case dwarf_r10_fiq: 381187692Snwhitehorn reg_info.name = "r10_fiq"; 382187692Snwhitehorn break; 383187692Snwhitehorn case dwarf_r11_fiq: 384187692Snwhitehorn reg_info.name = "r11_fiq"; 385187692Snwhitehorn break; 386187692Snwhitehorn case dwarf_r12_fiq: 387187692Snwhitehorn reg_info.name = "r12_fiq"; 388188259Snwhitehorn break; 389188259Snwhitehorn case dwarf_r13_fiq: 390188259Snwhitehorn reg_info.name = "r13_fiq"; 391188259Snwhitehorn break; 392187692Snwhitehorn case dwarf_r14_fiq: 393187692Snwhitehorn reg_info.name = "r14_fiq"; 394188259Snwhitehorn break; 395188259Snwhitehorn case dwarf_r13_irq: 396187692Snwhitehorn reg_info.name = "r13_irq"; 397187692Snwhitehorn break; 398187692Snwhitehorn case dwarf_r14_irq: 399188259Snwhitehorn reg_info.name = "r14_irq"; 400188259Snwhitehorn break; 401188259Snwhitehorn case dwarf_r13_abt: 402188259Snwhitehorn reg_info.name = "r13_abt"; 403188259Snwhitehorn break; 404188259Snwhitehorn case dwarf_r14_abt: 405188259Snwhitehorn reg_info.name = "r14_abt"; 406188259Snwhitehorn break; 407188259Snwhitehorn case dwarf_r13_und: 408188259Snwhitehorn reg_info.name = "r13_und"; 409188259Snwhitehorn break; 410188259Snwhitehorn case dwarf_r14_und: 411188259Snwhitehorn reg_info.name = "r14_und"; 412188259Snwhitehorn break; 413188259Snwhitehorn case dwarf_r13_svc: 414188259Snwhitehorn reg_info.name = "r13_svc"; 415188259Snwhitehorn break; 416188259Snwhitehorn case dwarf_r14_svc: 417188259Snwhitehorn reg_info.name = "r14_svc"; 418188259Snwhitehorn break; 419188259Snwhitehorn 420188259Snwhitehorn // Intel wireless MMX control register in co-processor 0 - 7 421188259Snwhitehorn case dwarf_wC0: 422188259Snwhitehorn reg_info.name = "wC0"; 423188259Snwhitehorn break; 424188259Snwhitehorn case dwarf_wC1: 425188259Snwhitehorn reg_info.name = "wC1"; 426188259Snwhitehorn break; 427188259Snwhitehorn case dwarf_wC2: 428187692Snwhitehorn reg_info.name = "wC2"; 429187692Snwhitehorn break; 430187692Snwhitehorn case dwarf_wC3: 431187692Snwhitehorn reg_info.name = "wC3"; 432187692Snwhitehorn break; 433193640Sariff case dwarf_wC4: 434187692Snwhitehorn reg_info.name = "wC4"; 435187692Snwhitehorn break; 436187692Snwhitehorn case dwarf_wC5: 437187692Snwhitehorn reg_info.name = "wC5"; 438187692Snwhitehorn break; 439 case dwarf_wC6: 440 reg_info.name = "wC6"; 441 break; 442 case dwarf_wC7: 443 reg_info.name = "wC7"; 444 break; 445 446 // VFP-v3/Neon 447 case dwarf_d0: 448 reg_info.name = "d0"; 449 break; 450 case dwarf_d1: 451 reg_info.name = "d1"; 452 break; 453 case dwarf_d2: 454 reg_info.name = "d2"; 455 break; 456 case dwarf_d3: 457 reg_info.name = "d3"; 458 break; 459 case dwarf_d4: 460 reg_info.name = "d4"; 461 break; 462 case dwarf_d5: 463 reg_info.name = "d5"; 464 break; 465 case dwarf_d6: 466 reg_info.name = "d6"; 467 break; 468 case dwarf_d7: 469 reg_info.name = "d7"; 470 break; 471 case dwarf_d8: 472 reg_info.name = "d8"; 473 break; 474 case dwarf_d9: 475 reg_info.name = "d9"; 476 break; 477 case dwarf_d10: 478 reg_info.name = "d10"; 479 break; 480 case dwarf_d11: 481 reg_info.name = "d11"; 482 break; 483 case dwarf_d12: 484 reg_info.name = "d12"; 485 break; 486 case dwarf_d13: 487 reg_info.name = "d13"; 488 break; 489 case dwarf_d14: 490 reg_info.name = "d14"; 491 break; 492 case dwarf_d15: 493 reg_info.name = "d15"; 494 break; 495 case dwarf_d16: 496 reg_info.name = "d16"; 497 break; 498 case dwarf_d17: 499 reg_info.name = "d17"; 500 break; 501 case dwarf_d18: 502 reg_info.name = "d18"; 503 break; 504 case dwarf_d19: 505 reg_info.name = "d19"; 506 break; 507 case dwarf_d20: 508 reg_info.name = "d20"; 509 break; 510 case dwarf_d21: 511 reg_info.name = "d21"; 512 break; 513 case dwarf_d22: 514 reg_info.name = "d22"; 515 break; 516 case dwarf_d23: 517 reg_info.name = "d23"; 518 break; 519 case dwarf_d24: 520 reg_info.name = "d24"; 521 break; 522 case dwarf_d25: 523 reg_info.name = "d25"; 524 break; 525 case dwarf_d26: 526 reg_info.name = "d26"; 527 break; 528 case dwarf_d27: 529 reg_info.name = "d27"; 530 break; 531 case dwarf_d28: 532 reg_info.name = "d28"; 533 break; 534 case dwarf_d29: 535 reg_info.name = "d29"; 536 break; 537 case dwarf_d30: 538 reg_info.name = "d30"; 539 break; 540 case dwarf_d31: 541 reg_info.name = "d31"; 542 break; 543 544 // NEON 128-bit vector registers (overlays the d registers) 545 case dwarf_q0: 546 reg_info.name = "q0"; 547 break; 548 case dwarf_q1: 549 reg_info.name = "q1"; 550 break; 551 case dwarf_q2: 552 reg_info.name = "q2"; 553 break; 554 case dwarf_q3: 555 reg_info.name = "q3"; 556 break; 557 case dwarf_q4: 558 reg_info.name = "q4"; 559 break; 560 case dwarf_q5: 561 reg_info.name = "q5"; 562 break; 563 case dwarf_q6: 564 reg_info.name = "q6"; 565 break; 566 case dwarf_q7: 567 reg_info.name = "q7"; 568 break; 569 case dwarf_q8: 570 reg_info.name = "q8"; 571 break; 572 case dwarf_q9: 573 reg_info.name = "q9"; 574 break; 575 case dwarf_q10: 576 reg_info.name = "q10"; 577 break; 578 case dwarf_q11: 579 reg_info.name = "q11"; 580 break; 581 case dwarf_q12: 582 reg_info.name = "q12"; 583 break; 584 case dwarf_q13: 585 reg_info.name = "q13"; 586 break; 587 case dwarf_q14: 588 reg_info.name = "q14"; 589 break; 590 case dwarf_q15: 591 reg_info.name = "q15"; 592 break; 593 594 default: 595 return false; 596 } 597 return true; 598} 599 600// A8.6.50 601// Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. 602static uint32_t CountITSize(uint32_t ITMask) { 603 // First count the trailing zeros of the IT mask. 604 uint32_t TZ = llvm::countTrailingZeros(ITMask); 605 if (TZ > 3) { 606#ifdef LLDB_CONFIGURATION_DEBUG 607 printf("Encoding error: IT Mask '0000'\n"); 608#endif 609 return 0; 610 } 611 return (4 - TZ); 612} 613 614// Init ITState. Note that at least one bit is always 1 in mask. 615bool ITSession::InitIT(uint32_t bits7_0) { 616 ITCounter = CountITSize(Bits32(bits7_0, 3, 0)); 617 if (ITCounter == 0) 618 return false; 619 620 // A8.6.50 IT 621 unsigned short FirstCond = Bits32(bits7_0, 7, 4); 622 if (FirstCond == 0xF) { 623#ifdef LLDB_CONFIGURATION_DEBUG 624 printf("Encoding error: IT FirstCond '1111'\n"); 625#endif 626 return false; 627 } 628 if (FirstCond == 0xE && ITCounter != 1) { 629#ifdef LLDB_CONFIGURATION_DEBUG 630 printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n"); 631#endif 632 return false; 633 } 634 635 ITState = bits7_0; 636 return true; 637} 638 639// Update ITState if necessary. 640void ITSession::ITAdvance() { 641 // assert(ITCounter); 642 --ITCounter; 643 if (ITCounter == 0) 644 ITState = 0; 645 else { 646 unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1; 647 SetBits32(ITState, 4, 0, NewITState4_0); 648 } 649} 650 651// Return true if we're inside an IT Block. 652bool ITSession::InITBlock() { return ITCounter != 0; } 653 654// Return true if we're the last instruction inside an IT Block. 655bool ITSession::LastInITBlock() { return ITCounter == 1; } 656 657// Get condition bits for the current thumb instruction. 658uint32_t ITSession::GetCond() { 659 if (InITBlock()) 660 return Bits32(ITState, 7, 4); 661 else 662 return COND_AL; 663} 664 665// ARM constants used during decoding 666#define REG_RD 0 667#define LDM_REGLIST 1 668#define SP_REG 13 669#define LR_REG 14 670#define PC_REG 15 671#define PC_REGLIST_BIT 0x8000 672 673#define ARMv4 (1u << 0) 674#define ARMv4T (1u << 1) 675#define ARMv5T (1u << 2) 676#define ARMv5TE (1u << 3) 677#define ARMv5TEJ (1u << 4) 678#define ARMv6 (1u << 5) 679#define ARMv6K (1u << 6) 680#define ARMv6T2 (1u << 7) 681#define ARMv7 (1u << 8) 682#define ARMv7S (1u << 9) 683#define ARMv8 (1u << 10) 684#define ARMvAll (0xffffffffu) 685 686#define ARMV4T_ABOVE \ 687 (ARMv4T | ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | \ 688 ARMv7S | ARMv8) 689#define ARMV5_ABOVE \ 690 (ARMv5T | ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | \ 691 ARMv8) 692#define ARMV5TE_ABOVE \ 693 (ARMv5TE | ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 694#define ARMV5J_ABOVE \ 695 (ARMv5TEJ | ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 696#define ARMV6_ABOVE (ARMv6 | ARMv6K | ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 697#define ARMV6T2_ABOVE (ARMv6T2 | ARMv7 | ARMv7S | ARMv8) 698#define ARMV7_ABOVE (ARMv7 | ARMv7S | ARMv8) 699 700#define No_VFP 0 701#define VFPv1 (1u << 1) 702#define VFPv2 (1u << 2) 703#define VFPv3 (1u << 3) 704#define AdvancedSIMD (1u << 4) 705 706#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD) 707#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD) 708#define VFPv2v3 (VFPv2 | VFPv3) 709 710// 711// EmulateInstructionARM implementation 712// 713 714void EmulateInstructionARM::Initialize() { 715 PluginManager::RegisterPlugin(GetPluginNameStatic(), 716 GetPluginDescriptionStatic(), CreateInstance); 717} 718 719void EmulateInstructionARM::Terminate() { 720 PluginManager::UnregisterPlugin(CreateInstance); 721} 722 723ConstString EmulateInstructionARM::GetPluginNameStatic() { 724 static ConstString g_name("arm"); 725 return g_name; 726} 727 728const char *EmulateInstructionARM::GetPluginDescriptionStatic() { 729 return "Emulate instructions for the ARM architecture."; 730} 731 732EmulateInstruction * 733EmulateInstructionARM::CreateInstance(const ArchSpec &arch, 734 InstructionType inst_type) { 735 if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic( 736 inst_type)) { 737 if (arch.GetTriple().getArch() == llvm::Triple::arm) { 738 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 739 new EmulateInstructionARM(arch)); 740 741 if (emulate_insn_up) 742 return emulate_insn_up.release(); 743 } else if (arch.GetTriple().getArch() == llvm::Triple::thumb) { 744 std::unique_ptr<EmulateInstructionARM> emulate_insn_up( 745 new EmulateInstructionARM(arch)); 746 747 if (emulate_insn_up) 748 return emulate_insn_up.release(); 749 } 750 } 751 752 return nullptr; 753} 754 755bool EmulateInstructionARM::SetTargetTriple(const ArchSpec &arch) { 756 if (arch.GetTriple().getArch() == llvm::Triple::arm) 757 return true; 758 else if (arch.GetTriple().getArch() == llvm::Triple::thumb) 759 return true; 760 761 return false; 762} 763 764// Write "bits (32) UNKNOWN" to memory address "address". Helper function for 765// many ARM instructions. 766bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { 767 EmulateInstruction::Context context; 768 context.type = EmulateInstruction::eContextWriteMemoryRandomBits; 769 context.SetNoArgs(); 770 771 uint32_t random_data = rand(); 772 const uint32_t addr_byte_size = GetAddressByteSize(); 773 774 return MemAWrite(context, address, random_data, addr_byte_size); 775} 776 777// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM 778// instructions. 779bool EmulateInstructionARM::WriteBits32Unknown(int n) { 780 EmulateInstruction::Context context; 781 context.type = EmulateInstruction::eContextWriteRegisterRandomBits; 782 context.SetNoArgs(); 783 784 bool success; 785 uint32_t data = 786 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 787 788 if (!success) 789 return false; 790 791 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, data)) 792 return false; 793 794 return true; 795} 796 797bool EmulateInstructionARM::GetRegisterInfo(lldb::RegisterKind reg_kind, 798 uint32_t reg_num, 799 RegisterInfo ®_info) { 800 if (reg_kind == eRegisterKindGeneric) { 801 switch (reg_num) { 802 case LLDB_REGNUM_GENERIC_PC: 803 reg_kind = eRegisterKindDWARF; 804 reg_num = dwarf_pc; 805 break; 806 case LLDB_REGNUM_GENERIC_SP: 807 reg_kind = eRegisterKindDWARF; 808 reg_num = dwarf_sp; 809 break; 810 case LLDB_REGNUM_GENERIC_FP: 811 reg_kind = eRegisterKindDWARF; 812 reg_num = dwarf_r7; 813 break; 814 case LLDB_REGNUM_GENERIC_RA: 815 reg_kind = eRegisterKindDWARF; 816 reg_num = dwarf_lr; 817 break; 818 case LLDB_REGNUM_GENERIC_FLAGS: 819 reg_kind = eRegisterKindDWARF; 820 reg_num = dwarf_cpsr; 821 break; 822 default: 823 return false; 824 } 825 } 826 827 if (reg_kind == eRegisterKindDWARF) 828 return GetARMDWARFRegisterInfo(reg_num, reg_info); 829 return false; 830} 831 832uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { 833 if (m_arch.GetTriple().isAndroid()) 834 return LLDB_INVALID_REGNUM; // Don't use frame pointer on android 835 bool is_apple = false; 836 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 837 is_apple = true; 838 switch (m_arch.GetTriple().getOS()) { 839 case llvm::Triple::Darwin: 840 case llvm::Triple::MacOSX: 841 case llvm::Triple::IOS: 842 case llvm::Triple::TvOS: 843 case llvm::Triple::WatchOS: 844 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: 845 is_apple = true; 846 break; 847 default: 848 break; 849 } 850 851 /* On Apple iOS et al, the frame pointer register is always r7. 852 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 853 * Windows on ARM, which is in thumb mode, uses r11 though. 854 */ 855 856 uint32_t fp_regnum = 11; 857 858 if (is_apple) 859 fp_regnum = 7; 860 861 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 862 fp_regnum = 7; 863 864 return fp_regnum; 865} 866 867uint32_t EmulateInstructionARM::GetFramePointerDWARFRegisterNumber() const { 868 bool is_apple = false; 869 if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple) 870 is_apple = true; 871 switch (m_arch.GetTriple().getOS()) { 872 case llvm::Triple::Darwin: 873 case llvm::Triple::MacOSX: 874 case llvm::Triple::IOS: 875 is_apple = true; 876 break; 877 default: 878 break; 879 } 880 881 /* On Apple iOS et al, the frame pointer register is always r7. 882 * Typically on other ARM systems, thumb code uses r7; arm code uses r11. 883 * Windows on ARM, which is in thumb mode, uses r11 though. 884 */ 885 886 uint32_t fp_regnum = dwarf_r11; 887 888 if (is_apple) 889 fp_regnum = dwarf_r7; 890 891 if (m_opcode_mode == eModeThumb && !m_arch.GetTriple().isOSWindows()) 892 fp_regnum = dwarf_r7; 893 894 return fp_regnum; 895} 896 897// Push Multiple Registers stores multiple registers to the stack, storing to 898// consecutive memory locations ending just below the address in SP, and 899// updates 900// SP to point to the start of the stored data. 901bool EmulateInstructionARM::EmulatePUSH(const uint32_t opcode, 902 const ARMEncoding encoding) { 903#if 0 904 // ARM pseudo code... 905 if (ConditionPassed()) 906 { 907 EncodingSpecificOperations(); 908 NullCheckIfThumbEE(13); 909 address = SP - 4*BitCount(registers); 910 911 for (i = 0 to 14) 912 { 913 if (registers<i> == '1') 914 { 915 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1 916 MemA[address,4] = bits(32) UNKNOWN; 917 else 918 MemA[address,4] = R[i]; 919 address = address + 4; 920 } 921 } 922 923 if (registers<15> == '1') // Only possible for encoding A1 or A2 924 MemA[address,4] = PCStoreValue(); 925 926 SP = SP - 4*BitCount(registers); 927 } 928#endif 929 930 bool success = false; 931 if (ConditionPassed(opcode)) { 932 const uint32_t addr_byte_size = GetAddressByteSize(); 933 const addr_t sp = ReadCoreReg(SP_REG, &success); 934 if (!success) 935 return false; 936 uint32_t registers = 0; 937 uint32_t Rt; // the source register 938 switch (encoding) { 939 case eEncodingT1: 940 registers = Bits32(opcode, 7, 0); 941 // The M bit represents LR. 942 if (Bit32(opcode, 8)) 943 registers |= (1u << 14); 944 // if BitCount(registers) < 1 then UNPREDICTABLE; 945 if (BitCount(registers) < 1) 946 return false; 947 break; 948 case eEncodingT2: 949 // Ignore bits 15 & 13. 950 registers = Bits32(opcode, 15, 0) & ~0xa000; 951 // if BitCount(registers) < 2 then UNPREDICTABLE; 952 if (BitCount(registers) < 2) 953 return false; 954 break; 955 case eEncodingT3: 956 Rt = Bits32(opcode, 15, 12); 957 // if BadReg(t) then UNPREDICTABLE; 958 if (BadReg(Rt)) 959 return false; 960 registers = (1u << Rt); 961 break; 962 case eEncodingA1: 963 registers = Bits32(opcode, 15, 0); 964 // Instead of return false, let's handle the following case as well, 965 // which amounts to pushing one reg onto the full descending stacks. 966 // if BitCount(register_list) < 2 then SEE STMDB / STMFD; 967 break; 968 case eEncodingA2: 969 Rt = Bits32(opcode, 15, 12); 970 // if t == 13 then UNPREDICTABLE; 971 if (Rt == dwarf_sp) 972 return false; 973 registers = (1u << Rt); 974 break; 975 default: 976 return false; 977 } 978 addr_t sp_offset = addr_byte_size * BitCount(registers); 979 addr_t addr = sp - sp_offset; 980 uint32_t i; 981 982 EmulateInstruction::Context context; 983 context.type = EmulateInstruction::eContextPushRegisterOnStack; 984 RegisterInfo reg_info; 985 RegisterInfo sp_reg; 986 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 987 for (i = 0; i < 15; ++i) { 988 if (BitIsSet(registers, i)) { 989 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, reg_info); 990 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 991 uint32_t reg_value = ReadCoreReg(i, &success); 992 if (!success) 993 return false; 994 if (!MemAWrite(context, addr, reg_value, addr_byte_size)) 995 return false; 996 addr += addr_byte_size; 997 } 998 } 999 1000 if (BitIsSet(registers, 15)) { 1001 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, reg_info); 1002 context.SetRegisterToRegisterPlusOffset(reg_info, sp_reg, addr - sp); 1003 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1004 if (!success) 1005 return false; 1006 if (!MemAWrite(context, addr, pc, addr_byte_size)) 1007 return false; 1008 } 1009 1010 context.type = EmulateInstruction::eContextAdjustStackPointer; 1011 context.SetImmediateSigned(-sp_offset); 1012 1013 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1014 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 1015 return false; 1016 } 1017 return true; 1018} 1019 1020// Pop Multiple Registers loads multiple registers from the stack, loading from 1021// consecutive memory locations staring at the address in SP, and updates 1022// SP to point just above the loaded data. 1023bool EmulateInstructionARM::EmulatePOP(const uint32_t opcode, 1024 const ARMEncoding encoding) { 1025#if 0 1026 // ARM pseudo code... 1027 if (ConditionPassed()) 1028 { 1029 EncodingSpecificOperations(); NullCheckIfThumbEE(13); 1030 address = SP; 1031 for i = 0 to 14 1032 if registers<i> == '1' then 1033 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4; 1034 if registers<15> == '1' then 1035 if UnalignedAllowed then 1036 LoadWritePC(MemU[address,4]); 1037 else 1038 LoadWritePC(MemA[address,4]); 1039 if registers<13> == '0' then SP = SP + 4*BitCount(registers); 1040 if registers<13> == '1' then SP = bits(32) UNKNOWN; 1041 } 1042#endif 1043 1044 bool success = false; 1045 1046 if (ConditionPassed(opcode)) { 1047 const uint32_t addr_byte_size = GetAddressByteSize(); 1048 const addr_t sp = ReadCoreReg(SP_REG, &success); 1049 if (!success) 1050 return false; 1051 uint32_t registers = 0; 1052 uint32_t Rt; // the destination register 1053 switch (encoding) { 1054 case eEncodingT1: 1055 registers = Bits32(opcode, 7, 0); 1056 // The P bit represents PC. 1057 if (Bit32(opcode, 8)) 1058 registers |= (1u << 15); 1059 // if BitCount(registers) < 1 then UNPREDICTABLE; 1060 if (BitCount(registers) < 1) 1061 return false; 1062 break; 1063 case eEncodingT2: 1064 // Ignore bit 13. 1065 registers = Bits32(opcode, 15, 0) & ~0x2000; 1066 // if BitCount(registers) < 2 || (P == '1' && M == '1') then 1067 // UNPREDICTABLE; 1068 if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14))) 1069 return false; 1070 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 1071 // UNPREDICTABLE; 1072 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 1073 return false; 1074 break; 1075 case eEncodingT3: 1076 Rt = Bits32(opcode, 15, 12); 1077 // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then 1078 // UNPREDICTABLE; 1079 if (Rt == 13) 1080 return false; 1081 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1082 return false; 1083 registers = (1u << Rt); 1084 break; 1085 case eEncodingA1: 1086 registers = Bits32(opcode, 15, 0); 1087 // Instead of return false, let's handle the following case as well, 1088 // which amounts to popping one reg from the full descending stacks. 1089 // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; 1090 1091 // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; 1092 if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7) 1093 return false; 1094 break; 1095 case eEncodingA2: 1096 Rt = Bits32(opcode, 15, 12); 1097 // if t == 13 then UNPREDICTABLE; 1098 if (Rt == dwarf_sp) 1099 return false; 1100 registers = (1u << Rt); 1101 break; 1102 default: 1103 return false; 1104 } 1105 addr_t sp_offset = addr_byte_size * BitCount(registers); 1106 addr_t addr = sp; 1107 uint32_t i, data; 1108 1109 EmulateInstruction::Context context; 1110 context.type = EmulateInstruction::eContextPopRegisterOffStack; 1111 1112 RegisterInfo sp_reg; 1113 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1114 1115 for (i = 0; i < 15; ++i) { 1116 if (BitIsSet(registers, i)) { 1117 context.SetAddress(addr); 1118 data = MemARead(context, addr, 4, 0, &success); 1119 if (!success) 1120 return false; 1121 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 1122 data)) 1123 return false; 1124 addr += addr_byte_size; 1125 } 1126 } 1127 1128 if (BitIsSet(registers, 15)) { 1129 context.SetRegisterPlusOffset(sp_reg, addr - sp); 1130 data = MemARead(context, addr, 4, 0, &success); 1131 if (!success) 1132 return false; 1133 // In ARMv5T and above, this is an interworking branch. 1134 if (!LoadWritePC(context, data)) 1135 return false; 1136 // addr += addr_byte_size; 1137 } 1138 1139 context.type = EmulateInstruction::eContextAdjustStackPointer; 1140 context.SetImmediateSigned(sp_offset); 1141 1142 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1143 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 1144 return false; 1145 } 1146 return true; 1147} 1148 1149// Set r7 or ip to point to saved value residing within the stack. 1150// ADD (SP plus immediate) 1151bool EmulateInstructionARM::EmulateADDRdSPImm(const uint32_t opcode, 1152 const ARMEncoding encoding) { 1153#if 0 1154 // ARM pseudo code... 1155 if (ConditionPassed()) 1156 { 1157 EncodingSpecificOperations(); 1158 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1159 if d == 15 then 1160 ALUWritePC(result); // setflags is always FALSE here 1161 else 1162 R[d] = result; 1163 if setflags then 1164 APSR.N = result<31>; 1165 APSR.Z = IsZeroBit(result); 1166 APSR.C = carry; 1167 APSR.V = overflow; 1168 } 1169#endif 1170 1171 bool success = false; 1172 1173 if (ConditionPassed(opcode)) { 1174 const addr_t sp = ReadCoreReg(SP_REG, &success); 1175 if (!success) 1176 return false; 1177 uint32_t Rd; // the destination register 1178 uint32_t imm32; 1179 switch (encoding) { 1180 case eEncodingT1: 1181 Rd = 7; 1182 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32) 1183 break; 1184 case eEncodingA1: 1185 Rd = Bits32(opcode, 15, 12); 1186 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 1187 break; 1188 default: 1189 return false; 1190 } 1191 addr_t sp_offset = imm32; 1192 addr_t addr = sp + sp_offset; // a pointer to the stack area 1193 1194 EmulateInstruction::Context context; 1195 if (Rd == GetFramePointerRegisterNumber()) 1196 context.type = eContextSetFramePointer; 1197 else 1198 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1199 RegisterInfo sp_reg; 1200 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1201 context.SetRegisterPlusOffset(sp_reg, sp_offset); 1202 1203 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, 1204 addr)) 1205 return false; 1206 } 1207 return true; 1208} 1209 1210// Set r7 or ip to the current stack pointer. 1211// MOV (register) 1212bool EmulateInstructionARM::EmulateMOVRdSP(const uint32_t opcode, 1213 const ARMEncoding encoding) { 1214#if 0 1215 // ARM pseudo code... 1216 if (ConditionPassed()) 1217 { 1218 EncodingSpecificOperations(); 1219 result = R[m]; 1220 if d == 15 then 1221 ALUWritePC(result); // setflags is always FALSE here 1222 else 1223 R[d] = result; 1224 if setflags then 1225 APSR.N = result<31>; 1226 APSR.Z = IsZeroBit(result); 1227 // APSR.C unchanged 1228 // APSR.V unchanged 1229 } 1230#endif 1231 1232 bool success = false; 1233 1234 if (ConditionPassed(opcode)) { 1235 const addr_t sp = ReadCoreReg(SP_REG, &success); 1236 if (!success) 1237 return false; 1238 uint32_t Rd; // the destination register 1239 switch (encoding) { 1240 case eEncodingT1: 1241 Rd = 7; 1242 break; 1243 case eEncodingA1: 1244 Rd = 12; 1245 break; 1246 default: 1247 return false; 1248 } 1249 1250 EmulateInstruction::Context context; 1251 if (Rd == GetFramePointerRegisterNumber()) 1252 context.type = EmulateInstruction::eContextSetFramePointer; 1253 else 1254 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1255 RegisterInfo sp_reg; 1256 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1257 context.SetRegisterPlusOffset(sp_reg, 0); 1258 1259 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rd, sp)) 1260 return false; 1261 } 1262 return true; 1263} 1264 1265// Move from high register (r8-r15) to low register (r0-r7). 1266// MOV (register) 1267bool EmulateInstructionARM::EmulateMOVLowHigh(const uint32_t opcode, 1268 const ARMEncoding encoding) { 1269 return EmulateMOVRdRm(opcode, encoding); 1270} 1271 1272// Move from register to register. 1273// MOV (register) 1274bool EmulateInstructionARM::EmulateMOVRdRm(const uint32_t opcode, 1275 const ARMEncoding encoding) { 1276#if 0 1277 // ARM pseudo code... 1278 if (ConditionPassed()) 1279 { 1280 EncodingSpecificOperations(); 1281 result = R[m]; 1282 if d == 15 then 1283 ALUWritePC(result); // setflags is always FALSE here 1284 else 1285 R[d] = result; 1286 if setflags then 1287 APSR.N = result<31>; 1288 APSR.Z = IsZeroBit(result); 1289 // APSR.C unchanged 1290 // APSR.V unchanged 1291 } 1292#endif 1293 1294 bool success = false; 1295 1296 if (ConditionPassed(opcode)) { 1297 uint32_t Rm; // the source register 1298 uint32_t Rd; // the destination register 1299 bool setflags; 1300 switch (encoding) { 1301 case eEncodingT1: 1302 Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 1303 Rm = Bits32(opcode, 6, 3); 1304 setflags = false; 1305 if (Rd == 15 && InITBlock() && !LastInITBlock()) 1306 return false; 1307 break; 1308 case eEncodingT2: 1309 Rd = Bits32(opcode, 2, 0); 1310 Rm = Bits32(opcode, 5, 3); 1311 setflags = true; 1312 if (InITBlock()) 1313 return false; 1314 break; 1315 case eEncodingT3: 1316 Rd = Bits32(opcode, 11, 8); 1317 Rm = Bits32(opcode, 3, 0); 1318 setflags = BitIsSet(opcode, 20); 1319 // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1320 if (setflags && (BadReg(Rd) || BadReg(Rm))) 1321 return false; 1322 // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then 1323 // UNPREDICTABLE; 1324 if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13))) 1325 return false; 1326 break; 1327 case eEncodingA1: 1328 Rd = Bits32(opcode, 15, 12); 1329 Rm = Bits32(opcode, 3, 0); 1330 setflags = BitIsSet(opcode, 20); 1331 1332 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1333 // instructions; 1334 if (Rd == 15 && setflags) 1335 return EmulateSUBSPcLrEtc(opcode, encoding); 1336 break; 1337 default: 1338 return false; 1339 } 1340 uint32_t result = ReadCoreReg(Rm, &success); 1341 if (!success) 1342 return false; 1343 1344 // The context specifies that Rm is to be moved into Rd. 1345 EmulateInstruction::Context context; 1346 if (Rd == 13) 1347 context.type = EmulateInstruction::eContextAdjustStackPointer; 1348 else if (Rd == GetFramePointerRegisterNumber() && Rm == 13) 1349 context.type = EmulateInstruction::eContextSetFramePointer; 1350 else 1351 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1352 RegisterInfo dwarf_reg; 1353 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 1354 context.SetRegisterPlusOffset(dwarf_reg, 0); 1355 1356 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags)) 1357 return false; 1358 } 1359 return true; 1360} 1361 1362// Move (immediate) writes an immediate value to the destination register. It 1363// can optionally update the condition flags based on the value. 1364// MOV (immediate) 1365bool EmulateInstructionARM::EmulateMOVRdImm(const uint32_t opcode, 1366 const ARMEncoding encoding) { 1367#if 0 1368 // ARM pseudo code... 1369 if (ConditionPassed()) 1370 { 1371 EncodingSpecificOperations(); 1372 result = imm32; 1373 if d == 15 then // Can only occur for ARM encoding 1374 ALUWritePC(result); // setflags is always FALSE here 1375 else 1376 R[d] = result; 1377 if setflags then 1378 APSR.N = result<31>; 1379 APSR.Z = IsZeroBit(result); 1380 APSR.C = carry; 1381 // APSR.V unchanged 1382 } 1383#endif 1384 1385 if (ConditionPassed(opcode)) { 1386 uint32_t Rd; // the destination register 1387 uint32_t imm32; // the immediate value to be written to Rd 1388 uint32_t carry = 1389 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C. 1390 // for setflags == false, this value is a don't care initialized to 1391 // 0 to silence the static analyzer 1392 bool setflags; 1393 switch (encoding) { 1394 case eEncodingT1: 1395 Rd = Bits32(opcode, 10, 8); 1396 setflags = !InITBlock(); 1397 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 1398 carry = APSR_C; 1399 1400 break; 1401 1402 case eEncodingT2: 1403 Rd = Bits32(opcode, 11, 8); 1404 setflags = BitIsSet(opcode, 20); 1405 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1406 if (BadReg(Rd)) 1407 return false; 1408 1409 break; 1410 1411 case eEncodingT3: { 1412 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 1413 // 32); 1414 Rd = Bits32(opcode, 11, 8); 1415 setflags = false; 1416 uint32_t imm4 = Bits32(opcode, 19, 16); 1417 uint32_t imm3 = Bits32(opcode, 14, 12); 1418 uint32_t i = Bit32(opcode, 26); 1419 uint32_t imm8 = Bits32(opcode, 7, 0); 1420 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; 1421 1422 // if BadReg(d) then UNPREDICTABLE; 1423 if (BadReg(Rd)) 1424 return false; 1425 } break; 1426 1427 case eEncodingA1: 1428 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = 1429 // ARMExpandImm_C(imm12, APSR.C); 1430 Rd = Bits32(opcode, 15, 12); 1431 setflags = BitIsSet(opcode, 20); 1432 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1433 1434 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1435 // instructions; 1436 if ((Rd == 15) && setflags) 1437 return EmulateSUBSPcLrEtc(opcode, encoding); 1438 1439 break; 1440 1441 case eEncodingA2: { 1442 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32); 1443 Rd = Bits32(opcode, 15, 12); 1444 setflags = false; 1445 uint32_t imm4 = Bits32(opcode, 19, 16); 1446 uint32_t imm12 = Bits32(opcode, 11, 0); 1447 imm32 = (imm4 << 12) | imm12; 1448 1449 // if d == 15 then UNPREDICTABLE; 1450 if (Rd == 15) 1451 return false; 1452 } break; 1453 1454 default: 1455 return false; 1456 } 1457 uint32_t result = imm32; 1458 1459 // The context specifies that an immediate is to be moved into Rd. 1460 EmulateInstruction::Context context; 1461 context.type = EmulateInstruction::eContextImmediate; 1462 context.SetNoArgs(); 1463 1464 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1465 return false; 1466 } 1467 return true; 1468} 1469 1470// MUL multiplies two register values. The least significant 32 bits of the 1471// result are written to the destination 1472// register. These 32 bits do not depend on whether the source register values 1473// are considered to be signed values or unsigned values. 1474// 1475// Optionally, it can update the condition flags based on the result. In the 1476// Thumb instruction set, this option is limited to only a few forms of the 1477// instruction. 1478bool EmulateInstructionARM::EmulateMUL(const uint32_t opcode, 1479 const ARMEncoding encoding) { 1480#if 0 1481 if ConditionPassed() then 1482 EncodingSpecificOperations(); 1483 operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results 1484 operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results 1485 result = operand1 * operand2; 1486 R[d] = result<31:0>; 1487 if setflags then 1488 APSR.N = result<31>; 1489 APSR.Z = IsZeroBit(result); 1490 if ArchVersion() == 4 then 1491 APSR.C = bit UNKNOWN; 1492 // else APSR.C unchanged 1493 // APSR.V always unchanged 1494#endif 1495 1496 if (ConditionPassed(opcode)) { 1497 uint32_t d; 1498 uint32_t n; 1499 uint32_t m; 1500 bool setflags; 1501 1502 // EncodingSpecificOperations(); 1503 switch (encoding) { 1504 case eEncodingT1: 1505 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock(); 1506 d = Bits32(opcode, 2, 0); 1507 n = Bits32(opcode, 5, 3); 1508 m = Bits32(opcode, 2, 0); 1509 setflags = !InITBlock(); 1510 1511 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1512 if ((ArchVersion() < ARMv6) && (d == n)) 1513 return false; 1514 1515 break; 1516 1517 case eEncodingT2: 1518 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE; 1519 d = Bits32(opcode, 11, 8); 1520 n = Bits32(opcode, 19, 16); 1521 m = Bits32(opcode, 3, 0); 1522 setflags = false; 1523 1524 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE; 1525 if (BadReg(d) || BadReg(n) || BadReg(m)) 1526 return false; 1527 1528 break; 1529 1530 case eEncodingA1: 1531 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 1532 d = Bits32(opcode, 19, 16); 1533 n = Bits32(opcode, 3, 0); 1534 m = Bits32(opcode, 11, 8); 1535 setflags = BitIsSet(opcode, 20); 1536 1537 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; 1538 if ((d == 15) || (n == 15) || (m == 15)) 1539 return false; 1540 1541 // if ArchVersion() < 6 && d == n then UNPREDICTABLE; 1542 if ((ArchVersion() < ARMv6) && (d == n)) 1543 return false; 1544 1545 break; 1546 1547 default: 1548 return false; 1549 } 1550 1551 bool success = false; 1552 1553 // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final 1554 // results 1555 uint64_t operand1 = 1556 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 1557 if (!success) 1558 return false; 1559 1560 // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final 1561 // results 1562 uint64_t operand2 = 1563 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 1564 if (!success) 1565 return false; 1566 1567 // result = operand1 * operand2; 1568 uint64_t result = operand1 * operand2; 1569 1570 // R[d] = result<31:0>; 1571 RegisterInfo op1_reg; 1572 RegisterInfo op2_reg; 1573 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, op1_reg); 1574 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, op2_reg); 1575 1576 EmulateInstruction::Context context; 1577 context.type = eContextArithmetic; 1578 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 1579 1580 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 1581 (0x0000ffff & result))) 1582 return false; 1583 1584 // if setflags then 1585 if (setflags) { 1586 // APSR.N = result<31>; 1587 // APSR.Z = IsZeroBit(result); 1588 m_new_inst_cpsr = m_opcode_cpsr; 1589 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, 31)); 1590 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 1591 if (m_new_inst_cpsr != m_opcode_cpsr) { 1592 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1593 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 1594 return false; 1595 } 1596 1597 // if ArchVersion() == 4 then 1598 // APSR.C = bit UNKNOWN; 1599 } 1600 } 1601 return true; 1602} 1603 1604// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to 1605// the destination register. It can optionally update the condition flags based 1606// on the value. 1607bool EmulateInstructionARM::EmulateMVNImm(const uint32_t opcode, 1608 const ARMEncoding encoding) { 1609#if 0 1610 // ARM pseudo code... 1611 if (ConditionPassed()) 1612 { 1613 EncodingSpecificOperations(); 1614 result = NOT(imm32); 1615 if d == 15 then // Can only occur for ARM encoding 1616 ALUWritePC(result); // setflags is always FALSE here 1617 else 1618 R[d] = result; 1619 if setflags then 1620 APSR.N = result<31>; 1621 APSR.Z = IsZeroBit(result); 1622 APSR.C = carry; 1623 // APSR.V unchanged 1624 } 1625#endif 1626 1627 if (ConditionPassed(opcode)) { 1628 uint32_t Rd; // the destination register 1629 uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C 1630 uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C 1631 bool setflags; 1632 switch (encoding) { 1633 case eEncodingT1: 1634 Rd = Bits32(opcode, 11, 8); 1635 setflags = BitIsSet(opcode, 20); 1636 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); 1637 break; 1638 case eEncodingA1: 1639 Rd = Bits32(opcode, 15, 12); 1640 setflags = BitIsSet(opcode, 20); 1641 imm32 = ARMExpandImm_C(opcode, APSR_C, carry); 1642 1643 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 1644 // instructions; 1645 if (Rd == 15 && setflags) 1646 return EmulateSUBSPcLrEtc(opcode, encoding); 1647 break; 1648 default: 1649 return false; 1650 } 1651 uint32_t result = ~imm32; 1652 1653 // The context specifies that an immediate is to be moved into Rd. 1654 EmulateInstruction::Context context; 1655 context.type = EmulateInstruction::eContextImmediate; 1656 context.SetNoArgs(); 1657 1658 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1659 return false; 1660 } 1661 return true; 1662} 1663 1664// Bitwise NOT (register) writes the bitwise inverse of a register value to the 1665// destination register. It can optionally update the condition flags based on 1666// the result. 1667bool EmulateInstructionARM::EmulateMVNReg(const uint32_t opcode, 1668 const ARMEncoding encoding) { 1669#if 0 1670 // ARM pseudo code... 1671 if (ConditionPassed()) 1672 { 1673 EncodingSpecificOperations(); 1674 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 1675 result = NOT(shifted); 1676 if d == 15 then // Can only occur for ARM encoding 1677 ALUWritePC(result); // setflags is always FALSE here 1678 else 1679 R[d] = result; 1680 if setflags then 1681 APSR.N = result<31>; 1682 APSR.Z = IsZeroBit(result); 1683 APSR.C = carry; 1684 // APSR.V unchanged 1685 } 1686#endif 1687 1688 if (ConditionPassed(opcode)) { 1689 uint32_t Rm; // the source register 1690 uint32_t Rd; // the destination register 1691 ARM_ShifterType shift_t; 1692 uint32_t shift_n; // the shift applied to the value read from Rm 1693 bool setflags; 1694 uint32_t carry; // the carry bit after the shift operation 1695 switch (encoding) { 1696 case eEncodingT1: 1697 Rd = Bits32(opcode, 2, 0); 1698 Rm = Bits32(opcode, 5, 3); 1699 setflags = !InITBlock(); 1700 shift_t = SRType_LSL; 1701 shift_n = 0; 1702 if (InITBlock()) 1703 return false; 1704 break; 1705 case eEncodingT2: 1706 Rd = Bits32(opcode, 11, 8); 1707 Rm = Bits32(opcode, 3, 0); 1708 setflags = BitIsSet(opcode, 20); 1709 shift_n = DecodeImmShiftThumb(opcode, shift_t); 1710 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 1711 if (BadReg(Rd) || BadReg(Rm)) 1712 return false; 1713 break; 1714 case eEncodingA1: 1715 Rd = Bits32(opcode, 15, 12); 1716 Rm = Bits32(opcode, 3, 0); 1717 setflags = BitIsSet(opcode, 20); 1718 shift_n = DecodeImmShiftARM(opcode, shift_t); 1719 break; 1720 default: 1721 return false; 1722 } 1723 bool success = false; 1724 uint32_t value = ReadCoreReg(Rm, &success); 1725 if (!success) 1726 return false; 1727 1728 uint32_t shifted = 1729 Shift_C(value, shift_t, shift_n, APSR_C, carry, &success); 1730 if (!success) 1731 return false; 1732 uint32_t result = ~shifted; 1733 1734 // The context specifies that an immediate is to be moved into Rd. 1735 EmulateInstruction::Context context; 1736 context.type = EmulateInstruction::eContextImmediate; 1737 context.SetNoArgs(); 1738 1739 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 1740 return false; 1741 } 1742 return true; 1743} 1744 1745// PC relative immediate load into register, possibly followed by ADD (SP plus 1746// register). 1747// LDR (literal) 1748bool EmulateInstructionARM::EmulateLDRRtPCRelative(const uint32_t opcode, 1749 const ARMEncoding encoding) { 1750#if 0 1751 // ARM pseudo code... 1752 if (ConditionPassed()) 1753 { 1754 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 1755 base = Align(PC,4); 1756 address = if add then (base + imm32) else (base - imm32); 1757 data = MemU[address,4]; 1758 if t == 15 then 1759 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 1760 elsif UnalignedSupport() || address<1:0> = '00' then 1761 R[t] = data; 1762 else // Can only apply before ARMv7 1763 if CurrentInstrSet() == InstrSet_ARM then 1764 R[t] = ROR(data, 8*UInt(address<1:0>)); 1765 else 1766 R[t] = bits(32) UNKNOWN; 1767 } 1768#endif 1769 1770 if (ConditionPassed(opcode)) { 1771 bool success = false; 1772 const uint32_t pc = ReadCoreReg(PC_REG, &success); 1773 if (!success) 1774 return false; 1775 1776 // PC relative immediate load context 1777 EmulateInstruction::Context context; 1778 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1779 RegisterInfo pc_reg; 1780 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 1781 context.SetRegisterPlusOffset(pc_reg, 0); 1782 1783 uint32_t Rt; // the destination register 1784 uint32_t imm32; // immediate offset from the PC 1785 bool add; // +imm32 or -imm32? 1786 addr_t base; // the base address 1787 addr_t address; // the PC relative address 1788 uint32_t data; // the literal data value from the PC relative load 1789 switch (encoding) { 1790 case eEncodingT1: 1791 Rt = Bits32(opcode, 10, 8); 1792 imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32); 1793 add = true; 1794 break; 1795 case eEncodingT2: 1796 Rt = Bits32(opcode, 15, 12); 1797 imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32); 1798 add = BitIsSet(opcode, 23); 1799 if (Rt == 15 && InITBlock() && !LastInITBlock()) 1800 return false; 1801 break; 1802 default: 1803 return false; 1804 } 1805 1806 base = Align(pc, 4); 1807 if (add) 1808 address = base + imm32; 1809 else 1810 address = base - imm32; 1811 1812 context.SetRegisterPlusOffset(pc_reg, address - base); 1813 data = MemURead(context, address, 4, 0, &success); 1814 if (!success) 1815 return false; 1816 1817 if (Rt == 15) { 1818 if (Bits32(address, 1, 0) == 0) { 1819 // In ARMv5T and above, this is an interworking branch. 1820 if (!LoadWritePC(context, data)) 1821 return false; 1822 } else 1823 return false; 1824 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 1825 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 1826 data)) 1827 return false; 1828 } else // We don't handle ARM for now. 1829 return false; 1830 } 1831 return true; 1832} 1833 1834// An add operation to adjust the SP. 1835// ADD (SP plus immediate) 1836bool EmulateInstructionARM::EmulateADDSPImm(const uint32_t opcode, 1837 const ARMEncoding encoding) { 1838#if 0 1839 // ARM pseudo code... 1840 if (ConditionPassed()) 1841 { 1842 EncodingSpecificOperations(); 1843 (result, carry, overflow) = AddWithCarry(SP, imm32, '0'); 1844 if d == 15 then // Can only occur for ARM encoding 1845 ALUWritePC(result); // setflags is always FALSE here 1846 else 1847 R[d] = result; 1848 if setflags then 1849 APSR.N = result<31>; 1850 APSR.Z = IsZeroBit(result); 1851 APSR.C = carry; 1852 APSR.V = overflow; 1853 } 1854#endif 1855 1856 bool success = false; 1857 1858 if (ConditionPassed(opcode)) { 1859 const addr_t sp = ReadCoreReg(SP_REG, &success); 1860 if (!success) 1861 return false; 1862 uint32_t imm32; // the immediate operand 1863 uint32_t d; 1864 bool setflags; 1865 switch (encoding) { 1866 case eEncodingT1: 1867 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32); 1868 d = Bits32(opcode, 10, 8); 1869 imm32 = (Bits32(opcode, 7, 0) << 2); 1870 setflags = false; 1871 break; 1872 1873 case eEncodingT2: 1874 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32); 1875 d = 13; 1876 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 1877 setflags = false; 1878 break; 1879 1880 case eEncodingT3: 1881 // d = UInt(Rd); setflags = (S == "1"); imm32 = 1882 // ThumbExpandImm(i:imm3:imm8); 1883 d = Bits32(opcode, 11, 8); 1884 imm32 = ThumbExpandImm(opcode); 1885 setflags = Bit32(opcode, 20); 1886 1887 // if Rd == "1111" && S == "1" then SEE CMN (immediate); 1888 if (d == 15 && setflags == 1) 1889 return false; // CMN (immediate) not yet supported 1890 1891 // if d == 15 && S == "0" then UNPREDICTABLE; 1892 if (d == 15 && setflags == 0) 1893 return false; 1894 break; 1895 1896 case eEncodingT4: { 1897 // if Rn == '1111' then SEE ADR; 1898 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32); 1899 d = Bits32(opcode, 11, 8); 1900 setflags = false; 1901 uint32_t i = Bit32(opcode, 26); 1902 uint32_t imm3 = Bits32(opcode, 14, 12); 1903 uint32_t imm8 = Bits32(opcode, 7, 0); 1904 imm32 = (i << 11) | (imm3 << 8) | imm8; 1905 1906 // if d == 15 then UNPREDICTABLE; 1907 if (d == 15) 1908 return false; 1909 } break; 1910 1911 default: 1912 return false; 1913 } 1914 // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 1915 AddWithCarryResult res = AddWithCarry(sp, imm32, 0); 1916 1917 EmulateInstruction::Context context; 1918 if (d == 13) 1919 context.type = EmulateInstruction::eContextAdjustStackPointer; 1920 else 1921 context.type = EmulateInstruction::eContextRegisterPlusOffset; 1922 1923 RegisterInfo sp_reg; 1924 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1925 context.SetRegisterPlusOffset(sp_reg, res.result - sp); 1926 1927 if (d == 15) { 1928 if (!ALUWritePC(context, res.result)) 1929 return false; 1930 } else { 1931 // R[d] = result; 1932 // if setflags then 1933 // APSR.N = result<31>; 1934 // APSR.Z = IsZeroBit(result); 1935 // APSR.C = carry; 1936 // APSR.V = overflow; 1937 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 1938 res.carry_out, res.overflow)) 1939 return false; 1940 } 1941 } 1942 return true; 1943} 1944 1945// An add operation to adjust the SP. 1946// ADD (SP plus register) 1947bool EmulateInstructionARM::EmulateADDSPRm(const uint32_t opcode, 1948 const ARMEncoding encoding) { 1949#if 0 1950 // ARM pseudo code... 1951 if (ConditionPassed()) 1952 { 1953 EncodingSpecificOperations(); 1954 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 1955 (result, carry, overflow) = AddWithCarry(SP, shifted, '0'); 1956 if d == 15 then 1957 ALUWritePC(result); // setflags is always FALSE here 1958 else 1959 R[d] = result; 1960 if setflags then 1961 APSR.N = result<31>; 1962 APSR.Z = IsZeroBit(result); 1963 APSR.C = carry; 1964 APSR.V = overflow; 1965 } 1966#endif 1967 1968 bool success = false; 1969 1970 if (ConditionPassed(opcode)) { 1971 const addr_t sp = ReadCoreReg(SP_REG, &success); 1972 if (!success) 1973 return false; 1974 uint32_t Rm; // the second operand 1975 switch (encoding) { 1976 case eEncodingT2: 1977 Rm = Bits32(opcode, 6, 3); 1978 break; 1979 default: 1980 return false; 1981 } 1982 int32_t reg_value = ReadCoreReg(Rm, &success); 1983 if (!success) 1984 return false; 1985 1986 addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value 1987 1988 EmulateInstruction::Context context; 1989 context.type = eContextArithmetic; 1990 RegisterInfo sp_reg; 1991 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 1992 1993 RegisterInfo other_reg; 1994 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, other_reg); 1995 context.SetRegisterRegisterOperands(sp_reg, other_reg); 1996 1997 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 1998 LLDB_REGNUM_GENERIC_SP, addr)) 1999 return false; 2000 } 2001 return true; 2002} 2003 2004// Branch with Link and Exchange Instruction Sets (immediate) calls a 2005// subroutine at a PC-relative address, and changes instruction set from ARM to 2006// Thumb, or from Thumb to ARM. 2007// BLX (immediate) 2008bool EmulateInstructionARM::EmulateBLXImmediate(const uint32_t opcode, 2009 const ARMEncoding encoding) { 2010#if 0 2011 // ARM pseudo code... 2012 if (ConditionPassed()) 2013 { 2014 EncodingSpecificOperations(); 2015 if CurrentInstrSet() == InstrSet_ARM then 2016 LR = PC - 4; 2017 else 2018 LR = PC<31:1> : '1'; 2019 if targetInstrSet == InstrSet_ARM then 2020 targetAddress = Align(PC,4) + imm32; 2021 else 2022 targetAddress = PC + imm32; 2023 SelectInstrSet(targetInstrSet); 2024 BranchWritePC(targetAddress); 2025 } 2026#endif 2027 2028 bool success = true; 2029 2030 if (ConditionPassed(opcode)) { 2031 EmulateInstruction::Context context; 2032 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2033 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2034 if (!success) 2035 return false; 2036 addr_t lr; // next instruction address 2037 addr_t target; // target address 2038 int32_t imm32; // PC-relative offset 2039 switch (encoding) { 2040 case eEncodingT1: { 2041 lr = pc | 1u; // return address 2042 uint32_t S = Bit32(opcode, 26); 2043 uint32_t imm10 = Bits32(opcode, 25, 16); 2044 uint32_t J1 = Bit32(opcode, 13); 2045 uint32_t J2 = Bit32(opcode, 11); 2046 uint32_t imm11 = Bits32(opcode, 10, 0); 2047 uint32_t I1 = !(J1 ^ S); 2048 uint32_t I2 = !(J2 ^ S); 2049 uint32_t imm25 = 2050 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2051 imm32 = llvm::SignExtend32<25>(imm25); 2052 target = pc + imm32; 2053 SelectInstrSet(eModeThumb); 2054 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2055 if (InITBlock() && !LastInITBlock()) 2056 return false; 2057 break; 2058 } 2059 case eEncodingT2: { 2060 lr = pc | 1u; // return address 2061 uint32_t S = Bit32(opcode, 26); 2062 uint32_t imm10H = Bits32(opcode, 25, 16); 2063 uint32_t J1 = Bit32(opcode, 13); 2064 uint32_t J2 = Bit32(opcode, 11); 2065 uint32_t imm10L = Bits32(opcode, 10, 1); 2066 uint32_t I1 = !(J1 ^ S); 2067 uint32_t I2 = !(J2 ^ S); 2068 uint32_t imm25 = 2069 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2); 2070 imm32 = llvm::SignExtend32<25>(imm25); 2071 target = Align(pc, 4) + imm32; 2072 SelectInstrSet(eModeARM); 2073 context.SetISAAndImmediateSigned(eModeARM, 4 + imm32); 2074 if (InITBlock() && !LastInITBlock()) 2075 return false; 2076 break; 2077 } 2078 case eEncodingA1: 2079 lr = pc - 4; // return address 2080 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2081 target = Align(pc, 4) + imm32; 2082 SelectInstrSet(eModeARM); 2083 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2084 break; 2085 case eEncodingA2: 2086 lr = pc - 4; // return address 2087 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | 2088 Bits32(opcode, 24, 24) << 1); 2089 target = pc + imm32; 2090 SelectInstrSet(eModeThumb); 2091 context.SetISAAndImmediateSigned(eModeThumb, 8 + imm32); 2092 break; 2093 default: 2094 return false; 2095 } 2096 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2097 LLDB_REGNUM_GENERIC_RA, lr)) 2098 return false; 2099 if (!BranchWritePC(context, target)) 2100 return false; 2101 if (m_opcode_cpsr != m_new_inst_cpsr) 2102 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2103 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 2104 return false; 2105 } 2106 return true; 2107} 2108 2109// Branch with Link and Exchange (register) calls a subroutine at an address 2110// and instruction set specified by a register. 2111// BLX (register) 2112bool EmulateInstructionARM::EmulateBLXRm(const uint32_t opcode, 2113 const ARMEncoding encoding) { 2114#if 0 2115 // ARM pseudo code... 2116 if (ConditionPassed()) 2117 { 2118 EncodingSpecificOperations(); 2119 target = R[m]; 2120 if CurrentInstrSet() == InstrSet_ARM then 2121 next_instr_addr = PC - 4; 2122 LR = next_instr_addr; 2123 else 2124 next_instr_addr = PC - 2; 2125 LR = next_instr_addr<31:1> : '1'; 2126 BXWritePC(target); 2127 } 2128#endif 2129 2130 bool success = false; 2131 2132 if (ConditionPassed(opcode)) { 2133 EmulateInstruction::Context context; 2134 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2135 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2136 addr_t lr; // next instruction address 2137 if (!success) 2138 return false; 2139 uint32_t Rm; // the register with the target address 2140 switch (encoding) { 2141 case eEncodingT1: 2142 lr = (pc - 2) | 1u; // return address 2143 Rm = Bits32(opcode, 6, 3); 2144 // if m == 15 then UNPREDICTABLE; 2145 if (Rm == 15) 2146 return false; 2147 if (InITBlock() && !LastInITBlock()) 2148 return false; 2149 break; 2150 case eEncodingA1: 2151 lr = pc - 4; // return address 2152 Rm = Bits32(opcode, 3, 0); 2153 // if m == 15 then UNPREDICTABLE; 2154 if (Rm == 15) 2155 return false; 2156 break; 2157 default: 2158 return false; 2159 } 2160 addr_t target = ReadCoreReg(Rm, &success); 2161 if (!success) 2162 return false; 2163 RegisterInfo dwarf_reg; 2164 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2165 context.SetRegister(dwarf_reg); 2166 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2167 LLDB_REGNUM_GENERIC_RA, lr)) 2168 return false; 2169 if (!BXWritePC(context, target)) 2170 return false; 2171 } 2172 return true; 2173} 2174 2175// Branch and Exchange causes a branch to an address and instruction set 2176// specified by a register. 2177bool EmulateInstructionARM::EmulateBXRm(const uint32_t opcode, 2178 const ARMEncoding encoding) { 2179#if 0 2180 // ARM pseudo code... 2181 if (ConditionPassed()) 2182 { 2183 EncodingSpecificOperations(); 2184 BXWritePC(R[m]); 2185 } 2186#endif 2187 2188 if (ConditionPassed(opcode)) { 2189 EmulateInstruction::Context context; 2190 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2191 uint32_t Rm; // the register with the target address 2192 switch (encoding) { 2193 case eEncodingT1: 2194 Rm = Bits32(opcode, 6, 3); 2195 if (InITBlock() && !LastInITBlock()) 2196 return false; 2197 break; 2198 case eEncodingA1: 2199 Rm = Bits32(opcode, 3, 0); 2200 break; 2201 default: 2202 return false; 2203 } 2204 bool success = false; 2205 addr_t target = ReadCoreReg(Rm, &success); 2206 if (!success) 2207 return false; 2208 2209 RegisterInfo dwarf_reg; 2210 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2211 context.SetRegister(dwarf_reg); 2212 if (!BXWritePC(context, target)) 2213 return false; 2214 } 2215 return true; 2216} 2217 2218// Branch and Exchange Jazelle attempts to change to Jazelle state. If the 2219// attempt fails, it branches to an address and instruction set specified by a 2220// register as though it were a BX instruction. 2221// 2222// TODO: Emulate Jazelle architecture? 2223// We currently assume that switching to Jazelle state fails, thus 2224// treating BXJ as a BX operation. 2225bool EmulateInstructionARM::EmulateBXJRm(const uint32_t opcode, 2226 const ARMEncoding encoding) { 2227#if 0 2228 // ARM pseudo code... 2229 if (ConditionPassed()) 2230 { 2231 EncodingSpecificOperations(); 2232 if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then 2233 BXWritePC(R[m]); 2234 else 2235 if JazelleAcceptsExecution() then 2236 SwitchToJazelleExecution(); 2237 else 2238 SUBARCHITECTURE_DEFINED handler call; 2239 } 2240#endif 2241 2242 if (ConditionPassed(opcode)) { 2243 EmulateInstruction::Context context; 2244 context.type = EmulateInstruction::eContextAbsoluteBranchRegister; 2245 uint32_t Rm; // the register with the target address 2246 switch (encoding) { 2247 case eEncodingT1: 2248 Rm = Bits32(opcode, 19, 16); 2249 if (BadReg(Rm)) 2250 return false; 2251 if (InITBlock() && !LastInITBlock()) 2252 return false; 2253 break; 2254 case eEncodingA1: 2255 Rm = Bits32(opcode, 3, 0); 2256 if (Rm == 15) 2257 return false; 2258 break; 2259 default: 2260 return false; 2261 } 2262 bool success = false; 2263 addr_t target = ReadCoreReg(Rm, &success); 2264 if (!success) 2265 return false; 2266 2267 RegisterInfo dwarf_reg; 2268 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg); 2269 context.SetRegister(dwarf_reg); 2270 if (!BXWritePC(context, target)) 2271 return false; 2272 } 2273 return true; 2274} 2275 2276// Set r7 to point to some ip offset. 2277// SUB (immediate) 2278bool EmulateInstructionARM::EmulateSUBR7IPImm(const uint32_t opcode, 2279 const ARMEncoding encoding) { 2280#if 0 2281 // ARM pseudo code... 2282 if (ConditionPassed()) 2283 { 2284 EncodingSpecificOperations(); 2285 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2286 if d == 15 then // Can only occur for ARM encoding 2287 ALUWritePC(result); // setflags is always FALSE here 2288 else 2289 R[d] = result; 2290 if setflags then 2291 APSR.N = result<31>; 2292 APSR.Z = IsZeroBit(result); 2293 APSR.C = carry; 2294 APSR.V = overflow; 2295 } 2296#endif 2297 2298 if (ConditionPassed(opcode)) { 2299 bool success = false; 2300 const addr_t ip = ReadCoreReg(12, &success); 2301 if (!success) 2302 return false; 2303 uint32_t imm32; 2304 switch (encoding) { 2305 case eEncodingA1: 2306 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2307 break; 2308 default: 2309 return false; 2310 } 2311 addr_t ip_offset = imm32; 2312 addr_t addr = ip - ip_offset; // the adjusted ip value 2313 2314 EmulateInstruction::Context context; 2315 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2316 RegisterInfo dwarf_reg; 2317 GetRegisterInfo(eRegisterKindDWARF, dwarf_r12, dwarf_reg); 2318 context.SetRegisterPlusOffset(dwarf_reg, -ip_offset); 2319 2320 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r7, addr)) 2321 return false; 2322 } 2323 return true; 2324} 2325 2326// Set ip to point to some stack offset. 2327// SUB (SP minus immediate) 2328bool EmulateInstructionARM::EmulateSUBIPSPImm(const uint32_t opcode, 2329 const ARMEncoding encoding) { 2330#if 0 2331 // ARM pseudo code... 2332 if (ConditionPassed()) 2333 { 2334 EncodingSpecificOperations(); 2335 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2336 if d == 15 then // Can only occur for ARM encoding 2337 ALUWritePC(result); // setflags is always FALSE here 2338 else 2339 R[d] = result; 2340 if setflags then 2341 APSR.N = result<31>; 2342 APSR.Z = IsZeroBit(result); 2343 APSR.C = carry; 2344 APSR.V = overflow; 2345 } 2346#endif 2347 2348 if (ConditionPassed(opcode)) { 2349 bool success = false; 2350 const addr_t sp = ReadCoreReg(SP_REG, &success); 2351 if (!success) 2352 return false; 2353 uint32_t imm32; 2354 switch (encoding) { 2355 case eEncodingA1: 2356 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2357 break; 2358 default: 2359 return false; 2360 } 2361 addr_t sp_offset = imm32; 2362 addr_t addr = sp - sp_offset; // the adjusted stack pointer value 2363 2364 EmulateInstruction::Context context; 2365 context.type = EmulateInstruction::eContextRegisterPlusOffset; 2366 RegisterInfo dwarf_reg; 2367 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg); 2368 context.SetRegisterPlusOffset(dwarf_reg, -sp_offset); 2369 2370 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r12, addr)) 2371 return false; 2372 } 2373 return true; 2374} 2375 2376// This instruction subtracts an immediate value from the SP value, and writes 2377// the result to the destination register. 2378// 2379// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local 2380// storage. 2381bool EmulateInstructionARM::EmulateSUBSPImm(const uint32_t opcode, 2382 const ARMEncoding encoding) { 2383#if 0 2384 // ARM pseudo code... 2385 if (ConditionPassed()) 2386 { 2387 EncodingSpecificOperations(); 2388 (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1'); 2389 if d == 15 then // Can only occur for ARM encoding 2390 ALUWritePC(result); // setflags is always FALSE here 2391 else 2392 R[d] = result; 2393 if setflags then 2394 APSR.N = result<31>; 2395 APSR.Z = IsZeroBit(result); 2396 APSR.C = carry; 2397 APSR.V = overflow; 2398 } 2399#endif 2400 2401 bool success = false; 2402 if (ConditionPassed(opcode)) { 2403 const addr_t sp = ReadCoreReg(SP_REG, &success); 2404 if (!success) 2405 return false; 2406 2407 uint32_t Rd; 2408 bool setflags; 2409 uint32_t imm32; 2410 switch (encoding) { 2411 case eEncodingT1: 2412 Rd = 13; 2413 setflags = false; 2414 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32) 2415 break; 2416 case eEncodingT2: 2417 Rd = Bits32(opcode, 11, 8); 2418 setflags = BitIsSet(opcode, 20); 2419 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 2420 if (Rd == 15 && setflags) 2421 return EmulateCMPImm(opcode, eEncodingT2); 2422 if (Rd == 15 && !setflags) 2423 return false; 2424 break; 2425 case eEncodingT3: 2426 Rd = Bits32(opcode, 11, 8); 2427 setflags = false; 2428 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 2429 if (Rd == 15) 2430 return false; 2431 break; 2432 case eEncodingA1: 2433 Rd = Bits32(opcode, 15, 12); 2434 setflags = BitIsSet(opcode, 20); 2435 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 2436 2437 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 2438 // instructions; 2439 if (Rd == 15 && setflags) 2440 return EmulateSUBSPcLrEtc(opcode, encoding); 2441 break; 2442 default: 2443 return false; 2444 } 2445 AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1); 2446 2447 EmulateInstruction::Context context; 2448 if (Rd == 13) { 2449 uint64_t imm64 = imm32; // Need to expand it to 64 bits before attempting 2450 // to negate it, or the wrong 2451 // value gets passed down to context.SetImmediateSigned. 2452 context.type = EmulateInstruction::eContextAdjustStackPointer; 2453 context.SetImmediateSigned(-imm64); // the stack pointer offset 2454 } else { 2455 context.type = EmulateInstruction::eContextImmediate; 2456 context.SetNoArgs(); 2457 } 2458 2459 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 2460 res.carry_out, res.overflow)) 2461 return false; 2462 } 2463 return true; 2464} 2465 2466// A store operation to the stack that also updates the SP. 2467bool EmulateInstructionARM::EmulateSTRRtSP(const uint32_t opcode, 2468 const ARMEncoding encoding) { 2469#if 0 2470 // ARM pseudo code... 2471 if (ConditionPassed()) 2472 { 2473 EncodingSpecificOperations(); 2474 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 2475 address = if index then offset_addr else R[n]; 2476 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 2477 if wback then R[n] = offset_addr; 2478 } 2479#endif 2480 2481 bool success = false; 2482 if (ConditionPassed(opcode)) { 2483 const uint32_t addr_byte_size = GetAddressByteSize(); 2484 const addr_t sp = ReadCoreReg(SP_REG, &success); 2485 if (!success) 2486 return false; 2487 uint32_t Rt; // the source register 2488 uint32_t imm12; 2489 uint32_t 2490 Rn; // This function assumes Rn is the SP, but we should verify that. 2491 2492 bool index; 2493 bool add; 2494 bool wback; 2495 switch (encoding) { 2496 case eEncodingA1: 2497 Rt = Bits32(opcode, 15, 12); 2498 imm12 = Bits32(opcode, 11, 0); 2499 Rn = Bits32(opcode, 19, 16); 2500 2501 if (Rn != 13) // 13 is the SP reg on ARM. Verify that Rn == SP. 2502 return false; 2503 2504 index = BitIsSet(opcode, 24); 2505 add = BitIsSet(opcode, 23); 2506 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 2507 2508 if (wback && ((Rn == 15) || (Rn == Rt))) 2509 return false; 2510 break; 2511 default: 2512 return false; 2513 } 2514 addr_t offset_addr; 2515 if (add) 2516 offset_addr = sp + imm12; 2517 else 2518 offset_addr = sp - imm12; 2519 2520 addr_t addr; 2521 if (index) 2522 addr = offset_addr; 2523 else 2524 addr = sp; 2525 2526 EmulateInstruction::Context context; 2527 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2528 RegisterInfo sp_reg; 2529 RegisterInfo dwarf_reg; 2530 2531 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2532 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg); 2533 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2534 if (Rt != 15) { 2535 uint32_t reg_value = ReadCoreReg(Rt, &success); 2536 if (!success) 2537 return false; 2538 if (!MemUWrite(context, addr, reg_value, addr_byte_size)) 2539 return false; 2540 } else { 2541 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2542 if (!success) 2543 return false; 2544 if (!MemUWrite(context, addr, pc, addr_byte_size)) 2545 return false; 2546 } 2547 2548 if (wback) { 2549 context.type = EmulateInstruction::eContextAdjustStackPointer; 2550 context.SetImmediateSigned(addr - sp); 2551 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2552 LLDB_REGNUM_GENERIC_SP, offset_addr)) 2553 return false; 2554 } 2555 } 2556 return true; 2557} 2558 2559// Vector Push stores multiple extension registers to the stack. It also 2560// updates SP to point to the start of the stored data. 2561bool EmulateInstructionARM::EmulateVPUSH(const uint32_t opcode, 2562 const ARMEncoding encoding) { 2563#if 0 2564 // ARM pseudo code... 2565 if (ConditionPassed()) 2566 { 2567 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2568 address = SP - imm32; 2569 SP = SP - imm32; 2570 if single_regs then 2571 for r = 0 to regs-1 2572 MemA[address,4] = S[d+r]; address = address+4; 2573 else 2574 for r = 0 to regs-1 2575 // Store as two word-aligned words in the correct order for 2576 // current endianness. 2577 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 2578 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 2579 address = address+8; 2580 } 2581#endif 2582 2583 bool success = false; 2584 if (ConditionPassed(opcode)) { 2585 const uint32_t addr_byte_size = GetAddressByteSize(); 2586 const addr_t sp = ReadCoreReg(SP_REG, &success); 2587 if (!success) 2588 return false; 2589 bool single_regs; 2590 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2591 uint32_t imm32; // stack offset 2592 uint32_t regs; // number of registers 2593 switch (encoding) { 2594 case eEncodingT1: 2595 case eEncodingA1: 2596 single_regs = false; 2597 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2598 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2599 // If UInt(imm8) is odd, see "FSTMX". 2600 regs = Bits32(opcode, 7, 0) / 2; 2601 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2602 if (regs == 0 || regs > 16 || (d + regs) > 32) 2603 return false; 2604 break; 2605 case eEncodingT2: 2606 case eEncodingA2: 2607 single_regs = true; 2608 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2609 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2610 regs = Bits32(opcode, 7, 0); 2611 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2612 if (regs == 0 || regs > 16 || (d + regs) > 32) 2613 return false; 2614 break; 2615 default: 2616 return false; 2617 } 2618 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2619 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2620 addr_t sp_offset = imm32; 2621 addr_t addr = sp - sp_offset; 2622 uint32_t i; 2623 2624 EmulateInstruction::Context context; 2625 context.type = EmulateInstruction::eContextPushRegisterOnStack; 2626 2627 RegisterInfo dwarf_reg; 2628 RegisterInfo sp_reg; 2629 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2630 for (i = 0; i < regs; ++i) { 2631 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2632 context.SetRegisterToRegisterPlusOffset(dwarf_reg, sp_reg, addr - sp); 2633 // uint64_t to accommodate 64-bit registers. 2634 uint64_t reg_value = ReadRegisterUnsigned(&dwarf_reg, 0, &success); 2635 if (!success) 2636 return false; 2637 if (!MemAWrite(context, addr, reg_value, reg_byte_size)) 2638 return false; 2639 addr += reg_byte_size; 2640 } 2641 2642 context.type = EmulateInstruction::eContextAdjustStackPointer; 2643 context.SetImmediateSigned(-sp_offset); 2644 2645 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2646 LLDB_REGNUM_GENERIC_SP, sp - sp_offset)) 2647 return false; 2648 } 2649 return true; 2650} 2651 2652// Vector Pop loads multiple extension registers from the stack. It also 2653// updates SP to point just above the loaded data. 2654bool EmulateInstructionARM::EmulateVPOP(const uint32_t opcode, 2655 const ARMEncoding encoding) { 2656#if 0 2657 // ARM pseudo code... 2658 if (ConditionPassed()) 2659 { 2660 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13); 2661 address = SP; 2662 SP = SP + imm32; 2663 if single_regs then 2664 for r = 0 to regs-1 2665 S[d+r] = MemA[address,4]; address = address+4; 2666 else 2667 for r = 0 to regs-1 2668 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 2669 // Combine the word-aligned words in the correct order for 2670 // current endianness. 2671 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 2672 } 2673#endif 2674 2675 bool success = false; 2676 if (ConditionPassed(opcode)) { 2677 const uint32_t addr_byte_size = GetAddressByteSize(); 2678 const addr_t sp = ReadCoreReg(SP_REG, &success); 2679 if (!success) 2680 return false; 2681 bool single_regs; 2682 uint32_t d; // UInt(D:Vd) or UInt(Vd:D) starting register 2683 uint32_t imm32; // stack offset 2684 uint32_t regs; // number of registers 2685 switch (encoding) { 2686 case eEncodingT1: 2687 case eEncodingA1: 2688 single_regs = false; 2689 d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12); 2690 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2691 // If UInt(imm8) is odd, see "FLDMX". 2692 regs = Bits32(opcode, 7, 0) / 2; 2693 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2694 if (regs == 0 || regs > 16 || (d + regs) > 32) 2695 return false; 2696 break; 2697 case eEncodingT2: 2698 case eEncodingA2: 2699 single_regs = true; 2700 d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22); 2701 imm32 = Bits32(opcode, 7, 0) * addr_byte_size; 2702 regs = Bits32(opcode, 7, 0); 2703 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 2704 if (regs == 0 || regs > 16 || (d + regs) > 32) 2705 return false; 2706 break; 2707 default: 2708 return false; 2709 } 2710 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 2711 uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2; 2712 addr_t sp_offset = imm32; 2713 addr_t addr = sp; 2714 uint32_t i; 2715 uint64_t data; // uint64_t to accommodate 64-bit registers. 2716 2717 EmulateInstruction::Context context; 2718 context.type = EmulateInstruction::eContextPopRegisterOffStack; 2719 2720 RegisterInfo dwarf_reg; 2721 RegisterInfo sp_reg; 2722 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 2723 for (i = 0; i < regs; ++i) { 2724 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + i, dwarf_reg); 2725 context.SetAddress(addr); 2726 data = MemARead(context, addr, reg_byte_size, 0, &success); 2727 if (!success) 2728 return false; 2729 if (!WriteRegisterUnsigned(context, &dwarf_reg, data)) 2730 return false; 2731 addr += reg_byte_size; 2732 } 2733 2734 context.type = EmulateInstruction::eContextAdjustStackPointer; 2735 context.SetImmediateSigned(sp_offset); 2736 2737 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2738 LLDB_REGNUM_GENERIC_SP, sp + sp_offset)) 2739 return false; 2740 } 2741 return true; 2742} 2743 2744// SVC (previously SWI) 2745bool EmulateInstructionARM::EmulateSVC(const uint32_t opcode, 2746 const ARMEncoding encoding) { 2747#if 0 2748 // ARM pseudo code... 2749 if (ConditionPassed()) 2750 { 2751 EncodingSpecificOperations(); 2752 CallSupervisor(); 2753 } 2754#endif 2755 2756 bool success = false; 2757 2758 if (ConditionPassed(opcode)) { 2759 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2760 addr_t lr; // next instruction address 2761 if (!success) 2762 return false; 2763 uint32_t imm32; // the immediate constant 2764 uint32_t mode; // ARM or Thumb mode 2765 switch (encoding) { 2766 case eEncodingT1: 2767 lr = (pc + 2) | 1u; // return address 2768 imm32 = Bits32(opcode, 7, 0); 2769 mode = eModeThumb; 2770 break; 2771 case eEncodingA1: 2772 lr = pc + 4; // return address 2773 imm32 = Bits32(opcode, 23, 0); 2774 mode = eModeARM; 2775 break; 2776 default: 2777 return false; 2778 } 2779 2780 EmulateInstruction::Context context; 2781 context.type = EmulateInstruction::eContextSupervisorCall; 2782 context.SetISAAndImmediate(mode, imm32); 2783 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 2784 LLDB_REGNUM_GENERIC_RA, lr)) 2785 return false; 2786 } 2787 return true; 2788} 2789 2790// If Then makes up to four following instructions (the IT block) conditional. 2791bool EmulateInstructionARM::EmulateIT(const uint32_t opcode, 2792 const ARMEncoding encoding) { 2793#if 0 2794 // ARM pseudo code... 2795 EncodingSpecificOperations(); 2796 ITSTATE.IT<7:0> = firstcond:mask; 2797#endif 2798 2799 m_it_session.InitIT(Bits32(opcode, 7, 0)); 2800 return true; 2801} 2802 2803bool EmulateInstructionARM::EmulateNop(const uint32_t opcode, 2804 const ARMEncoding encoding) { 2805 // NOP, nothing to do... 2806 return true; 2807} 2808 2809// Branch causes a branch to a target address. 2810bool EmulateInstructionARM::EmulateB(const uint32_t opcode, 2811 const ARMEncoding encoding) { 2812#if 0 2813 // ARM pseudo code... 2814 if (ConditionPassed()) 2815 { 2816 EncodingSpecificOperations(); 2817 BranchWritePC(PC + imm32); 2818 } 2819#endif 2820 2821 bool success = false; 2822 2823 if (ConditionPassed(opcode)) { 2824 EmulateInstruction::Context context; 2825 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2826 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2827 if (!success) 2828 return false; 2829 addr_t target; // target address 2830 int32_t imm32; // PC-relative offset 2831 switch (encoding) { 2832 case eEncodingT1: 2833 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2834 imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1); 2835 target = pc + imm32; 2836 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2837 break; 2838 case eEncodingT2: 2839 imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1); 2840 target = pc + imm32; 2841 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2842 break; 2843 case eEncodingT3: 2844 // The 'cond' field is handled in EmulateInstructionARM::CurrentCond(). 2845 { 2846 if (Bits32(opcode, 25, 23) == 7) 2847 return false; // See Branches and miscellaneous control on page 2848 // A6-235. 2849 2850 uint32_t S = Bit32(opcode, 26); 2851 uint32_t imm6 = Bits32(opcode, 21, 16); 2852 uint32_t J1 = Bit32(opcode, 13); 2853 uint32_t J2 = Bit32(opcode, 11); 2854 uint32_t imm11 = Bits32(opcode, 10, 0); 2855 uint32_t imm21 = 2856 (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); 2857 imm32 = llvm::SignExtend32<21>(imm21); 2858 target = pc + imm32; 2859 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2860 break; 2861 } 2862 case eEncodingT4: { 2863 uint32_t S = Bit32(opcode, 26); 2864 uint32_t imm10 = Bits32(opcode, 25, 16); 2865 uint32_t J1 = Bit32(opcode, 13); 2866 uint32_t J2 = Bit32(opcode, 11); 2867 uint32_t imm11 = Bits32(opcode, 10, 0); 2868 uint32_t I1 = !(J1 ^ S); 2869 uint32_t I2 = !(J2 ^ S); 2870 uint32_t imm25 = 2871 (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1); 2872 imm32 = llvm::SignExtend32<25>(imm25); 2873 target = pc + imm32; 2874 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2875 break; 2876 } 2877 case eEncodingA1: 2878 imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2); 2879 target = pc + imm32; 2880 context.SetISAAndImmediateSigned(eModeARM, 8 + imm32); 2881 break; 2882 default: 2883 return false; 2884 } 2885 if (!BranchWritePC(context, target)) 2886 return false; 2887 } 2888 return true; 2889} 2890 2891// Compare and Branch on Nonzero and Compare and Branch on Zero compare the 2892// value in a register with zero and conditionally branch forward a constant 2893// value. They do not affect the condition flags. CBNZ, CBZ 2894bool EmulateInstructionARM::EmulateCB(const uint32_t opcode, 2895 const ARMEncoding encoding) { 2896#if 0 2897 // ARM pseudo code... 2898 EncodingSpecificOperations(); 2899 if nonzero ^ IsZero(R[n]) then 2900 BranchWritePC(PC + imm32); 2901#endif 2902 2903 bool success = false; 2904 2905 // Read the register value from the operand register Rn. 2906 uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success); 2907 if (!success) 2908 return false; 2909 2910 EmulateInstruction::Context context; 2911 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 2912 const uint32_t pc = ReadCoreReg(PC_REG, &success); 2913 if (!success) 2914 return false; 2915 2916 addr_t target; // target address 2917 uint32_t imm32; // PC-relative offset to branch forward 2918 bool nonzero; 2919 switch (encoding) { 2920 case eEncodingT1: 2921 imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1; 2922 nonzero = BitIsSet(opcode, 11); 2923 target = pc + imm32; 2924 context.SetISAAndImmediateSigned(eModeThumb, 4 + imm32); 2925 break; 2926 default: 2927 return false; 2928 } 2929 if (m_ignore_conditions || (nonzero ^ (reg_val == 0))) 2930 if (!BranchWritePC(context, target)) 2931 return false; 2932 2933 return true; 2934} 2935 2936// Table Branch Byte causes a PC-relative forward branch using a table of 2937// single byte offsets. 2938// A base register provides a pointer to the table, and a second register 2939// supplies an index into the table. 2940// The branch length is twice the value of the byte returned from the table. 2941// 2942// Table Branch Halfword causes a PC-relative forward branch using a table of 2943// single halfword offsets. 2944// A base register provides a pointer to the table, and a second register 2945// supplies an index into the table. 2946// The branch length is twice the value of the halfword returned from the 2947// table. TBB, TBH 2948bool EmulateInstructionARM::EmulateTB(const uint32_t opcode, 2949 const ARMEncoding encoding) { 2950#if 0 2951 // ARM pseudo code... 2952 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 2953 if is_tbh then 2954 halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]); 2955 else 2956 halfwords = UInt(MemU[R[n]+R[m], 1]); 2957 BranchWritePC(PC + 2*halfwords); 2958#endif 2959 2960 bool success = false; 2961 2962 if (ConditionPassed(opcode)) { 2963 uint32_t Rn; // the base register which contains the address of the table of 2964 // branch lengths 2965 uint32_t Rm; // the index register which contains an integer pointing to a 2966 // byte/halfword in the table 2967 bool is_tbh; // true if table branch halfword 2968 switch (encoding) { 2969 case eEncodingT1: 2970 Rn = Bits32(opcode, 19, 16); 2971 Rm = Bits32(opcode, 3, 0); 2972 is_tbh = BitIsSet(opcode, 4); 2973 if (Rn == 13 || BadReg(Rm)) 2974 return false; 2975 if (InITBlock() && !LastInITBlock()) 2976 return false; 2977 break; 2978 default: 2979 return false; 2980 } 2981 2982 // Read the address of the table from the operand register Rn. The PC can 2983 // be used, in which case the table immediately follows this instruction. 2984 uint32_t base = ReadCoreReg(Rn, &success); 2985 if (!success) 2986 return false; 2987 2988 // the table index 2989 uint32_t index = ReadCoreReg(Rm, &success); 2990 if (!success) 2991 return false; 2992 2993 // the offsetted table address 2994 addr_t addr = base + (is_tbh ? index * 2 : index); 2995 2996 // PC-relative offset to branch forward 2997 EmulateInstruction::Context context; 2998 context.type = EmulateInstruction::eContextTableBranchReadMemory; 2999 uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2; 3000 if (!success) 3001 return false; 3002 3003 const uint32_t pc = ReadCoreReg(PC_REG, &success); 3004 if (!success) 3005 return false; 3006 3007 // target address 3008 addr_t target = pc + offset; 3009 context.type = EmulateInstruction::eContextRelativeBranchImmediate; 3010 context.SetISAAndImmediateSigned(eModeThumb, 4 + offset); 3011 3012 if (!BranchWritePC(context, target)) 3013 return false; 3014 } 3015 3016 return true; 3017} 3018 3019// This instruction adds an immediate value to a register value, and writes the 3020// result to the destination register. It can optionally update the condition 3021// flags based on the result. 3022bool EmulateInstructionARM::EmulateADDImmThumb(const uint32_t opcode, 3023 const ARMEncoding encoding) { 3024#if 0 3025 if ConditionPassed() then 3026 EncodingSpecificOperations(); 3027 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3028 R[d] = result; 3029 if setflags then 3030 APSR.N = result<31>; 3031 APSR.Z = IsZeroBit(result); 3032 APSR.C = carry; 3033 APSR.V = overflow; 3034#endif 3035 3036 bool success = false; 3037 3038 if (ConditionPassed(opcode)) { 3039 uint32_t d; 3040 uint32_t n; 3041 bool setflags; 3042 uint32_t imm32; 3043 uint32_t carry_out; 3044 3045 // EncodingSpecificOperations(); 3046 switch (encoding) { 3047 case eEncodingT1: 3048 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = 3049 // ZeroExtend(imm3, 32); 3050 d = Bits32(opcode, 2, 0); 3051 n = Bits32(opcode, 5, 3); 3052 setflags = !InITBlock(); 3053 imm32 = Bits32(opcode, 8, 6); 3054 3055 break; 3056 3057 case eEncodingT2: 3058 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = 3059 // ZeroExtend(imm8, 32); 3060 d = Bits32(opcode, 10, 8); 3061 n = Bits32(opcode, 10, 8); 3062 setflags = !InITBlock(); 3063 imm32 = Bits32(opcode, 7, 0); 3064 3065 break; 3066 3067 case eEncodingT3: 3068 // if Rd == '1111' && S == '1' then SEE CMN (immediate); 3069 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = 3070 // ThumbExpandImm(i:imm3:imm8); 3071 d = Bits32(opcode, 11, 8); 3072 n = Bits32(opcode, 19, 16); 3073 setflags = BitIsSet(opcode, 20); 3074 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry_out); 3075 3076 // if Rn == '1101' then SEE ADD (SP plus immediate); 3077 if (n == 13) 3078 return EmulateADDSPImm(opcode, eEncodingT3); 3079 3080 // if BadReg(d) || n == 15 then UNPREDICTABLE; 3081 if (BadReg(d) || (n == 15)) 3082 return false; 3083 3084 break; 3085 3086 case eEncodingT4: { 3087 // if Rn == '1111' then SEE ADR; 3088 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = 3089 // ZeroExtend(i:imm3:imm8, 32); 3090 d = Bits32(opcode, 11, 8); 3091 n = Bits32(opcode, 19, 16); 3092 setflags = false; 3093 uint32_t i = Bit32(opcode, 26); 3094 uint32_t imm3 = Bits32(opcode, 14, 12); 3095 uint32_t imm8 = Bits32(opcode, 7, 0); 3096 imm32 = (i << 11) | (imm3 << 8) | imm8; 3097 3098 // if Rn == '1101' then SEE ADD (SP plus immediate); 3099 if (n == 13) 3100 return EmulateADDSPImm(opcode, eEncodingT4); 3101 3102 // if BadReg(d) then UNPREDICTABLE; 3103 if (BadReg(d)) 3104 return false; 3105 3106 break; 3107 } 3108 3109 default: 3110 return false; 3111 } 3112 3113 uint64_t Rn = 3114 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3115 if (!success) 3116 return false; 3117 3118 //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3119 AddWithCarryResult res = AddWithCarry(Rn, imm32, 0); 3120 3121 RegisterInfo reg_n; 3122 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 3123 3124 EmulateInstruction::Context context; 3125 context.type = eContextArithmetic; 3126 context.SetRegisterPlusOffset(reg_n, imm32); 3127 3128 // R[d] = result; 3129 // if setflags then 3130 // APSR.N = result<31>; 3131 // APSR.Z = IsZeroBit(result); 3132 // APSR.C = carry; 3133 // APSR.V = overflow; 3134 if (!WriteCoreRegOptionalFlags(context, res.result, d, setflags, 3135 res.carry_out, res.overflow)) 3136 return false; 3137 } 3138 return true; 3139} 3140 3141// This instruction adds an immediate value to a register value, and writes the 3142// result to the destination register. It can optionally update the condition 3143// flags based on the result. 3144bool EmulateInstructionARM::EmulateADDImmARM(const uint32_t opcode, 3145 const ARMEncoding encoding) { 3146#if 0 3147 // ARM pseudo code... 3148 if ConditionPassed() then 3149 EncodingSpecificOperations(); 3150 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3151 if d == 15 then 3152 ALUWritePC(result); // setflags is always FALSE here 3153 else 3154 R[d] = result; 3155 if setflags then 3156 APSR.N = result<31>; 3157 APSR.Z = IsZeroBit(result); 3158 APSR.C = carry; 3159 APSR.V = overflow; 3160#endif 3161 3162 bool success = false; 3163 3164 if (ConditionPassed(opcode)) { 3165 uint32_t Rd, Rn; 3166 uint32_t 3167 imm32; // the immediate value to be added to the value obtained from Rn 3168 bool setflags; 3169 switch (encoding) { 3170 case eEncodingA1: 3171 Rd = Bits32(opcode, 15, 12); 3172 Rn = Bits32(opcode, 19, 16); 3173 setflags = BitIsSet(opcode, 20); 3174 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3175 break; 3176 default: 3177 return false; 3178 } 3179 3180 // Read the first operand. 3181 uint32_t val1 = ReadCoreReg(Rn, &success); 3182 if (!success) 3183 return false; 3184 3185 AddWithCarryResult res = AddWithCarry(val1, imm32, 0); 3186 3187 EmulateInstruction::Context context; 3188 if (Rd == 13) 3189 context.type = EmulateInstruction::eContextAdjustStackPointer; 3190 else if (Rd == GetFramePointerRegisterNumber()) 3191 context.type = EmulateInstruction::eContextSetFramePointer; 3192 else 3193 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3194 3195 RegisterInfo dwarf_reg; 3196 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 3197 context.SetRegisterPlusOffset(dwarf_reg, imm32); 3198 3199 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3200 res.carry_out, res.overflow)) 3201 return false; 3202 } 3203 return true; 3204} 3205 3206// This instruction adds a register value and an optionally-shifted register 3207// value, and writes the result to the destination register. It can optionally 3208// update the condition flags based on the result. 3209bool EmulateInstructionARM::EmulateADDReg(const uint32_t opcode, 3210 const ARMEncoding encoding) { 3211#if 0 3212 // ARM pseudo code... 3213 if ConditionPassed() then 3214 EncodingSpecificOperations(); 3215 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3216 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3217 if d == 15 then 3218 ALUWritePC(result); // setflags is always FALSE here 3219 else 3220 R[d] = result; 3221 if setflags then 3222 APSR.N = result<31>; 3223 APSR.Z = IsZeroBit(result); 3224 APSR.C = carry; 3225 APSR.V = overflow; 3226#endif 3227 3228 bool success = false; 3229 3230 if (ConditionPassed(opcode)) { 3231 uint32_t Rd, Rn, Rm; 3232 ARM_ShifterType shift_t; 3233 uint32_t shift_n; // the shift applied to the value read from Rm 3234 bool setflags; 3235 switch (encoding) { 3236 case eEncodingT1: 3237 Rd = Bits32(opcode, 2, 0); 3238 Rn = Bits32(opcode, 5, 3); 3239 Rm = Bits32(opcode, 8, 6); 3240 setflags = !InITBlock(); 3241 shift_t = SRType_LSL; 3242 shift_n = 0; 3243 break; 3244 case eEncodingT2: 3245 Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3246 Rm = Bits32(opcode, 6, 3); 3247 setflags = false; 3248 shift_t = SRType_LSL; 3249 shift_n = 0; 3250 if (Rn == 15 && Rm == 15) 3251 return false; 3252 if (Rd == 15 && InITBlock() && !LastInITBlock()) 3253 return false; 3254 break; 3255 case eEncodingA1: 3256 Rd = Bits32(opcode, 15, 12); 3257 Rn = Bits32(opcode, 19, 16); 3258 Rm = Bits32(opcode, 3, 0); 3259 setflags = BitIsSet(opcode, 20); 3260 shift_n = DecodeImmShiftARM(opcode, shift_t); 3261 break; 3262 default: 3263 return false; 3264 } 3265 3266 // Read the first operand. 3267 uint32_t val1 = ReadCoreReg(Rn, &success); 3268 if (!success) 3269 return false; 3270 3271 // Read the second operand. 3272 uint32_t val2 = ReadCoreReg(Rm, &success); 3273 if (!success) 3274 return false; 3275 3276 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3277 if (!success) 3278 return false; 3279 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3280 3281 EmulateInstruction::Context context; 3282 context.type = eContextArithmetic; 3283 RegisterInfo op1_reg; 3284 RegisterInfo op2_reg; 3285 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg); 3286 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg); 3287 context.SetRegisterRegisterOperands(op1_reg, op2_reg); 3288 3289 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 3290 res.carry_out, res.overflow)) 3291 return false; 3292 } 3293 return true; 3294} 3295 3296// Compare Negative (immediate) adds a register value and an immediate value. 3297// It updates the condition flags based on the result, and discards the result. 3298bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, 3299 const ARMEncoding encoding) { 3300#if 0 3301 // ARM pseudo code... 3302 if ConditionPassed() then 3303 EncodingSpecificOperations(); 3304 (result, carry, overflow) = AddWithCarry(R[n], imm32, '0'); 3305 APSR.N = result<31>; 3306 APSR.Z = IsZeroBit(result); 3307 APSR.C = carry; 3308 APSR.V = overflow; 3309#endif 3310 3311 bool success = false; 3312 3313 uint32_t Rn; // the first operand 3314 uint32_t imm32; // the immediate value to be compared with 3315 switch (encoding) { 3316 case eEncodingT1: 3317 Rn = Bits32(opcode, 19, 16); 3318 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3319 if (Rn == 15) 3320 return false; 3321 break; 3322 case eEncodingA1: 3323 Rn = Bits32(opcode, 19, 16); 3324 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3325 break; 3326 default: 3327 return false; 3328 } 3329 // Read the register value from the operand register Rn. 3330 uint32_t reg_val = ReadCoreReg(Rn, &success); 3331 if (!success) 3332 return false; 3333 3334 AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0); 3335 3336 EmulateInstruction::Context context; 3337 context.type = EmulateInstruction::eContextImmediate; 3338 context.SetNoArgs(); 3339 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3340} 3341 3342// Compare Negative (register) adds a register value and an optionally-shifted 3343// register value. It updates the condition flags based on the result, and 3344// discards the result. 3345bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, 3346 const ARMEncoding encoding) { 3347#if 0 3348 // ARM pseudo code... 3349 if ConditionPassed() then 3350 EncodingSpecificOperations(); 3351 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3352 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 3353 APSR.N = result<31>; 3354 APSR.Z = IsZeroBit(result); 3355 APSR.C = carry; 3356 APSR.V = overflow; 3357#endif 3358 3359 bool success = false; 3360 3361 uint32_t Rn; // the first operand 3362 uint32_t Rm; // the second operand 3363 ARM_ShifterType shift_t; 3364 uint32_t shift_n; // the shift applied to the value read from Rm 3365 switch (encoding) { 3366 case eEncodingT1: 3367 Rn = Bits32(opcode, 2, 0); 3368 Rm = Bits32(opcode, 5, 3); 3369 shift_t = SRType_LSL; 3370 shift_n = 0; 3371 break; 3372 case eEncodingT2: 3373 Rn = Bits32(opcode, 19, 16); 3374 Rm = Bits32(opcode, 3, 0); 3375 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3376 // if n == 15 || BadReg(m) then UNPREDICTABLE; 3377 if (Rn == 15 || BadReg(Rm)) 3378 return false; 3379 break; 3380 case eEncodingA1: 3381 Rn = Bits32(opcode, 19, 16); 3382 Rm = Bits32(opcode, 3, 0); 3383 shift_n = DecodeImmShiftARM(opcode, shift_t); 3384 break; 3385 default: 3386 return false; 3387 } 3388 // Read the register value from register Rn. 3389 uint32_t val1 = ReadCoreReg(Rn, &success); 3390 if (!success) 3391 return false; 3392 3393 // Read the register value from register Rm. 3394 uint32_t val2 = ReadCoreReg(Rm, &success); 3395 if (!success) 3396 return false; 3397 3398 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3399 if (!success) 3400 return false; 3401 AddWithCarryResult res = AddWithCarry(val1, shifted, 0); 3402 3403 EmulateInstruction::Context context; 3404 context.type = EmulateInstruction::eContextImmediate; 3405 context.SetNoArgs(); 3406 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3407} 3408 3409// Compare (immediate) subtracts an immediate value from a register value. It 3410// updates the condition flags based on the result, and discards the result. 3411bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, 3412 const ARMEncoding encoding) { 3413#if 0 3414 // ARM pseudo code... 3415 if ConditionPassed() then 3416 EncodingSpecificOperations(); 3417 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 3418 APSR.N = result<31>; 3419 APSR.Z = IsZeroBit(result); 3420 APSR.C = carry; 3421 APSR.V = overflow; 3422#endif 3423 3424 bool success = false; 3425 3426 uint32_t Rn; // the first operand 3427 uint32_t imm32; // the immediate value to be compared with 3428 switch (encoding) { 3429 case eEncodingT1: 3430 Rn = Bits32(opcode, 10, 8); 3431 imm32 = Bits32(opcode, 7, 0); 3432 break; 3433 case eEncodingT2: 3434 Rn = Bits32(opcode, 19, 16); 3435 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 3436 if (Rn == 15) 3437 return false; 3438 break; 3439 case eEncodingA1: 3440 Rn = Bits32(opcode, 19, 16); 3441 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 3442 break; 3443 default: 3444 return false; 3445 } 3446 // Read the register value from the operand register Rn. 3447 uint32_t reg_val = ReadCoreReg(Rn, &success); 3448 if (!success) 3449 return false; 3450 3451 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 3452 3453 EmulateInstruction::Context context; 3454 context.type = EmulateInstruction::eContextImmediate; 3455 context.SetNoArgs(); 3456 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3457} 3458 3459// Compare (register) subtracts an optionally-shifted register value from a 3460// register value. It updates the condition flags based on the result, and 3461// discards the result. 3462bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, 3463 const ARMEncoding encoding) { 3464#if 0 3465 // ARM pseudo code... 3466 if ConditionPassed() then 3467 EncodingSpecificOperations(); 3468 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 3469 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 3470 APSR.N = result<31>; 3471 APSR.Z = IsZeroBit(result); 3472 APSR.C = carry; 3473 APSR.V = overflow; 3474#endif 3475 3476 bool success = false; 3477 3478 uint32_t Rn; // the first operand 3479 uint32_t Rm; // the second operand 3480 ARM_ShifterType shift_t; 3481 uint32_t shift_n; // the shift applied to the value read from Rm 3482 switch (encoding) { 3483 case eEncodingT1: 3484 Rn = Bits32(opcode, 2, 0); 3485 Rm = Bits32(opcode, 5, 3); 3486 shift_t = SRType_LSL; 3487 shift_n = 0; 3488 break; 3489 case eEncodingT2: 3490 Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0); 3491 Rm = Bits32(opcode, 6, 3); 3492 shift_t = SRType_LSL; 3493 shift_n = 0; 3494 if (Rn < 8 && Rm < 8) 3495 return false; 3496 if (Rn == 15 || Rm == 15) 3497 return false; 3498 break; 3499 case eEncodingT3: 3500 Rn = Bits32(opcode, 19, 16); 3501 Rm = Bits32(opcode, 3, 0); 3502 shift_n = DecodeImmShiftThumb(opcode, shift_t); 3503 if (Rn == 15 || BadReg(Rm)) 3504 return false; 3505 break; 3506 case eEncodingA1: 3507 Rn = Bits32(opcode, 19, 16); 3508 Rm = Bits32(opcode, 3, 0); 3509 shift_n = DecodeImmShiftARM(opcode, shift_t); 3510 break; 3511 default: 3512 return false; 3513 } 3514 // Read the register value from register Rn. 3515 uint32_t val1 = ReadCoreReg(Rn, &success); 3516 if (!success) 3517 return false; 3518 3519 // Read the register value from register Rm. 3520 uint32_t val2 = ReadCoreReg(Rm, &success); 3521 if (!success) 3522 return false; 3523 3524 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 3525 if (!success) 3526 return false; 3527 AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1); 3528 3529 EmulateInstruction::Context context; 3530 context.type = EmulateInstruction::eContextImmediate; 3531 context.SetNoArgs(); 3532 return WriteFlags(context, res.result, res.carry_out, res.overflow); 3533} 3534 3535// Arithmetic Shift Right (immediate) shifts a register value right by an 3536// immediate number of bits, shifting in copies of its sign bit, and writes the 3537// result to the destination register. It can optionally update the condition 3538// flags based on the result. 3539bool EmulateInstructionARM::EmulateASRImm(const uint32_t opcode, 3540 const ARMEncoding encoding) { 3541#if 0 3542 // ARM pseudo code... 3543 if ConditionPassed() then 3544 EncodingSpecificOperations(); 3545 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3546 if d == 15 then // Can only occur for ARM encoding 3547 ALUWritePC(result); // setflags is always FALSE here 3548 else 3549 R[d] = result; 3550 if setflags then 3551 APSR.N = result<31>; 3552 APSR.Z = IsZeroBit(result); 3553 APSR.C = carry; 3554 // APSR.V unchanged 3555#endif 3556 3557 return EmulateShiftImm(opcode, encoding, SRType_ASR); 3558} 3559 3560// Arithmetic Shift Right (register) shifts a register value right by a 3561// variable number of bits, shifting in copies of its sign bit, and writes the 3562// result to the destination register. The variable number of bits is read from 3563// the bottom byte of a register. It can optionally update the condition flags 3564// based on the result. 3565bool EmulateInstructionARM::EmulateASRReg(const uint32_t opcode, 3566 const ARMEncoding encoding) { 3567#if 0 3568 // ARM pseudo code... 3569 if ConditionPassed() then 3570 EncodingSpecificOperations(); 3571 shift_n = UInt(R[m]<7:0>); 3572 (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C); 3573 R[d] = result; 3574 if setflags then 3575 APSR.N = result<31>; 3576 APSR.Z = IsZeroBit(result); 3577 APSR.C = carry; 3578 // APSR.V unchanged 3579#endif 3580 3581 return EmulateShiftReg(opcode, encoding, SRType_ASR); 3582} 3583 3584// Logical Shift Left (immediate) shifts a register value left by an immediate 3585// number of bits, shifting in zeros, and writes the result to the destination 3586// register. It can optionally update the condition flags based on the result. 3587bool EmulateInstructionARM::EmulateLSLImm(const uint32_t opcode, 3588 const ARMEncoding encoding) { 3589#if 0 3590 // ARM pseudo code... 3591 if ConditionPassed() then 3592 EncodingSpecificOperations(); 3593 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3594 if d == 15 then // Can only occur for ARM encoding 3595 ALUWritePC(result); // setflags is always FALSE here 3596 else 3597 R[d] = result; 3598 if setflags then 3599 APSR.N = result<31>; 3600 APSR.Z = IsZeroBit(result); 3601 APSR.C = carry; 3602 // APSR.V unchanged 3603#endif 3604 3605 return EmulateShiftImm(opcode, encoding, SRType_LSL); 3606} 3607 3608// Logical Shift Left (register) shifts a register value left by a variable 3609// number of bits, shifting in zeros, and writes the result to the destination 3610// register. The variable number of bits is read from the bottom byte of a 3611// register. It can optionally update the condition flags based on the result. 3612bool EmulateInstructionARM::EmulateLSLReg(const uint32_t opcode, 3613 const ARMEncoding encoding) { 3614#if 0 3615 // ARM pseudo code... 3616 if ConditionPassed() then 3617 EncodingSpecificOperations(); 3618 shift_n = UInt(R[m]<7:0>); 3619 (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C); 3620 R[d] = result; 3621 if setflags then 3622 APSR.N = result<31>; 3623 APSR.Z = IsZeroBit(result); 3624 APSR.C = carry; 3625 // APSR.V unchanged 3626#endif 3627 3628 return EmulateShiftReg(opcode, encoding, SRType_LSL); 3629} 3630 3631// Logical Shift Right (immediate) shifts a register value right by an 3632// immediate number of bits, shifting in zeros, and writes the result to the 3633// destination register. It can optionally update the condition flags based on 3634// the result. 3635bool EmulateInstructionARM::EmulateLSRImm(const uint32_t opcode, 3636 const ARMEncoding encoding) { 3637#if 0 3638 // ARM pseudo code... 3639 if ConditionPassed() then 3640 EncodingSpecificOperations(); 3641 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3642 if d == 15 then // Can only occur for ARM encoding 3643 ALUWritePC(result); // setflags is always FALSE here 3644 else 3645 R[d] = result; 3646 if setflags then 3647 APSR.N = result<31>; 3648 APSR.Z = IsZeroBit(result); 3649 APSR.C = carry; 3650 // APSR.V unchanged 3651#endif 3652 3653 return EmulateShiftImm(opcode, encoding, SRType_LSR); 3654} 3655 3656// Logical Shift Right (register) shifts a register value right by a variable 3657// number of bits, shifting in zeros, and writes the result to the destination 3658// register. The variable number of bits is read from the bottom byte of a 3659// register. It can optionally update the condition flags based on the result. 3660bool EmulateInstructionARM::EmulateLSRReg(const uint32_t opcode, 3661 const ARMEncoding encoding) { 3662#if 0 3663 // ARM pseudo code... 3664 if ConditionPassed() then 3665 EncodingSpecificOperations(); 3666 shift_n = UInt(R[m]<7:0>); 3667 (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C); 3668 R[d] = result; 3669 if setflags then 3670 APSR.N = result<31>; 3671 APSR.Z = IsZeroBit(result); 3672 APSR.C = carry; 3673 // APSR.V unchanged 3674#endif 3675 3676 return EmulateShiftReg(opcode, encoding, SRType_LSR); 3677} 3678 3679// Rotate Right (immediate) provides the value of the contents of a register 3680// rotated by a constant value. The bits that are rotated off the right end are 3681// inserted into the vacated bit positions on the left. It can optionally 3682// update the condition flags based on the result. 3683bool EmulateInstructionARM::EmulateRORImm(const uint32_t opcode, 3684 const ARMEncoding encoding) { 3685#if 0 3686 // ARM pseudo code... 3687 if ConditionPassed() then 3688 EncodingSpecificOperations(); 3689 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3690 if d == 15 then // Can only occur for ARM encoding 3691 ALUWritePC(result); // setflags is always FALSE here 3692 else 3693 R[d] = result; 3694 if setflags then 3695 APSR.N = result<31>; 3696 APSR.Z = IsZeroBit(result); 3697 APSR.C = carry; 3698 // APSR.V unchanged 3699#endif 3700 3701 return EmulateShiftImm(opcode, encoding, SRType_ROR); 3702} 3703 3704// Rotate Right (register) provides the value of the contents of a register 3705// rotated by a variable number of bits. The bits that are rotated off the 3706// right end are inserted into the vacated bit positions on the left. The 3707// variable number of bits is read from the bottom byte of a register. It can 3708// optionally update the condition flags based on the result. 3709bool EmulateInstructionARM::EmulateRORReg(const uint32_t opcode, 3710 const ARMEncoding encoding) { 3711#if 0 3712 // ARM pseudo code... 3713 if ConditionPassed() then 3714 EncodingSpecificOperations(); 3715 shift_n = UInt(R[m]<7:0>); 3716 (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C); 3717 R[d] = result; 3718 if setflags then 3719 APSR.N = result<31>; 3720 APSR.Z = IsZeroBit(result); 3721 APSR.C = carry; 3722 // APSR.V unchanged 3723#endif 3724 3725 return EmulateShiftReg(opcode, encoding, SRType_ROR); 3726} 3727 3728// Rotate Right with Extend provides the value of the contents of a register 3729// shifted right by one place, with the carry flag shifted into bit [31]. 3730// 3731// RRX can optionally update the condition flags based on the result. 3732// In that case, bit [0] is shifted into the carry flag. 3733bool EmulateInstructionARM::EmulateRRX(const uint32_t opcode, 3734 const ARMEncoding encoding) { 3735#if 0 3736 // ARM pseudo code... 3737 if ConditionPassed() then 3738 EncodingSpecificOperations(); 3739 (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C); 3740 if d == 15 then // Can only occur for ARM encoding 3741 ALUWritePC(result); // setflags is always FALSE here 3742 else 3743 R[d] = result; 3744 if setflags then 3745 APSR.N = result<31>; 3746 APSR.Z = IsZeroBit(result); 3747 APSR.C = carry; 3748 // APSR.V unchanged 3749#endif 3750 3751 return EmulateShiftImm(opcode, encoding, SRType_RRX); 3752} 3753 3754bool EmulateInstructionARM::EmulateShiftImm(const uint32_t opcode, 3755 const ARMEncoding encoding, 3756 ARM_ShifterType shift_type) { 3757 // assert(shift_type == SRType_ASR 3758 // || shift_type == SRType_LSL 3759 // || shift_type == SRType_LSR 3760 // || shift_type == SRType_ROR 3761 // || shift_type == SRType_RRX); 3762 3763 bool success = false; 3764 3765 if (ConditionPassed(opcode)) { 3766 uint32_t Rd; // the destination register 3767 uint32_t Rm; // the first operand register 3768 uint32_t imm5; // encoding for the shift amount 3769 uint32_t carry; // the carry bit after the shift operation 3770 bool setflags; 3771 3772 // Special case handling! 3773 // A8.6.139 ROR (immediate) -- Encoding T1 3774 ARMEncoding use_encoding = encoding; 3775 if (shift_type == SRType_ROR && use_encoding == eEncodingT1) { 3776 // Morph the T1 encoding from the ARM Architecture Manual into T2 3777 // encoding to have the same decoding of bit fields as the other Thumb2 3778 // shift operations. 3779 use_encoding = eEncodingT2; 3780 } 3781 3782 switch (use_encoding) { 3783 case eEncodingT1: 3784 // Due to the above special case handling! 3785 if (shift_type == SRType_ROR) 3786 return false; 3787 3788 Rd = Bits32(opcode, 2, 0); 3789 Rm = Bits32(opcode, 5, 3); 3790 setflags = !InITBlock(); 3791 imm5 = Bits32(opcode, 10, 6); 3792 break; 3793 case eEncodingT2: 3794 // A8.6.141 RRX 3795 // There's no imm form of RRX instructions. 3796 if (shift_type == SRType_RRX) 3797 return false; 3798 3799 Rd = Bits32(opcode, 11, 8); 3800 Rm = Bits32(opcode, 3, 0); 3801 setflags = BitIsSet(opcode, 20); 3802 imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6); 3803 if (BadReg(Rd) || BadReg(Rm)) 3804 return false; 3805 break; 3806 case eEncodingA1: 3807 Rd = Bits32(opcode, 15, 12); 3808 Rm = Bits32(opcode, 3, 0); 3809 setflags = BitIsSet(opcode, 20); 3810 imm5 = Bits32(opcode, 11, 7); 3811 break; 3812 default: 3813 return false; 3814 } 3815 3816 // A8.6.139 ROR (immediate) 3817 if (shift_type == SRType_ROR && imm5 == 0) 3818 shift_type = SRType_RRX; 3819 3820 // Get the first operand. 3821 uint32_t value = ReadCoreReg(Rm, &success); 3822 if (!success) 3823 return false; 3824 3825 // Decode the shift amount if not RRX. 3826 uint32_t amt = 3827 (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5)); 3828 3829 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3830 if (!success) 3831 return false; 3832 3833 // The context specifies that an immediate is to be moved into Rd. 3834 EmulateInstruction::Context context; 3835 context.type = EmulateInstruction::eContextImmediate; 3836 context.SetNoArgs(); 3837 3838 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3839 return false; 3840 } 3841 return true; 3842} 3843 3844bool EmulateInstructionARM::EmulateShiftReg(const uint32_t opcode, 3845 const ARMEncoding encoding, 3846 ARM_ShifterType shift_type) { 3847 // assert(shift_type == SRType_ASR 3848 // || shift_type == SRType_LSL 3849 // || shift_type == SRType_LSR 3850 // || shift_type == SRType_ROR); 3851 3852 bool success = false; 3853 3854 if (ConditionPassed(opcode)) { 3855 uint32_t Rd; // the destination register 3856 uint32_t Rn; // the first operand register 3857 uint32_t 3858 Rm; // the register whose bottom byte contains the amount to shift by 3859 uint32_t carry; // the carry bit after the shift operation 3860 bool setflags; 3861 switch (encoding) { 3862 case eEncodingT1: 3863 Rd = Bits32(opcode, 2, 0); 3864 Rn = Rd; 3865 Rm = Bits32(opcode, 5, 3); 3866 setflags = !InITBlock(); 3867 break; 3868 case eEncodingT2: 3869 Rd = Bits32(opcode, 11, 8); 3870 Rn = Bits32(opcode, 19, 16); 3871 Rm = Bits32(opcode, 3, 0); 3872 setflags = BitIsSet(opcode, 20); 3873 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 3874 return false; 3875 break; 3876 case eEncodingA1: 3877 Rd = Bits32(opcode, 15, 12); 3878 Rn = Bits32(opcode, 3, 0); 3879 Rm = Bits32(opcode, 11, 8); 3880 setflags = BitIsSet(opcode, 20); 3881 if (Rd == 15 || Rn == 15 || Rm == 15) 3882 return false; 3883 break; 3884 default: 3885 return false; 3886 } 3887 3888 // Get the first operand. 3889 uint32_t value = ReadCoreReg(Rn, &success); 3890 if (!success) 3891 return false; 3892 // Get the Rm register content. 3893 uint32_t val = ReadCoreReg(Rm, &success); 3894 if (!success) 3895 return false; 3896 3897 // Get the shift amount. 3898 uint32_t amt = Bits32(val, 7, 0); 3899 3900 uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success); 3901 if (!success) 3902 return false; 3903 3904 // The context specifies that an immediate is to be moved into Rd. 3905 EmulateInstruction::Context context; 3906 context.type = EmulateInstruction::eContextImmediate; 3907 context.SetNoArgs(); 3908 3909 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 3910 return false; 3911 } 3912 return true; 3913} 3914 3915// LDM loads multiple registers from consecutive memory locations, using an 3916// address from a base register. Optionally the address just above the highest 3917// of those locations can be written back to the base register. 3918bool EmulateInstructionARM::EmulateLDM(const uint32_t opcode, 3919 const ARMEncoding encoding) { 3920#if 0 3921 // ARM pseudo code... 3922 if ConditionPassed() 3923 EncodingSpecificOperations(); NullCheckIfThumbEE (n); 3924 address = R[n]; 3925 3926 for i = 0 to 14 3927 if registers<i> == '1' then 3928 R[i] = MemA[address, 4]; address = address + 4; 3929 if registers<15> == '1' then 3930 LoadWritePC (MemA[address, 4]); 3931 3932 if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers); 3933 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 3934 3935#endif 3936 3937 bool success = false; 3938 if (ConditionPassed(opcode)) { 3939 uint32_t n; 3940 uint32_t registers = 0; 3941 bool wback; 3942 const uint32_t addr_byte_size = GetAddressByteSize(); 3943 switch (encoding) { 3944 case eEncodingT1: 3945 // n = UInt(Rn); registers = '00000000':register_list; wback = 3946 // (registers<n> == '0'); 3947 n = Bits32(opcode, 10, 8); 3948 registers = Bits32(opcode, 7, 0); 3949 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 3950 wback = BitIsClear(registers, n); 3951 // if BitCount(registers) < 1 then UNPREDICTABLE; 3952 if (BitCount(registers) < 1) 3953 return false; 3954 break; 3955 case eEncodingT2: 3956 // if W == '1' && Rn == '1101' then SEE POP; 3957 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 3958 n = Bits32(opcode, 19, 16); 3959 registers = Bits32(opcode, 15, 0); 3960 registers = registers & 0xdfff; // Make sure bit 13 is zero. 3961 wback = BitIsSet(opcode, 21); 3962 3963 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 3964 // UNPREDICTABLE; 3965 if ((n == 15) || (BitCount(registers) < 2) || 3966 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 3967 return false; 3968 3969 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 3970 // UNPREDICTABLE; 3971 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 3972 return false; 3973 3974 // if wback && registers<n> == '1' then UNPREDICTABLE; 3975 if (wback && BitIsSet(registers, n)) 3976 return false; 3977 break; 3978 3979 case eEncodingA1: 3980 n = Bits32(opcode, 19, 16); 3981 registers = Bits32(opcode, 15, 0); 3982 wback = BitIsSet(opcode, 21); 3983 if ((n == 15) || (BitCount(registers) < 1)) 3984 return false; 3985 break; 3986 default: 3987 return false; 3988 } 3989 3990 int32_t offset = 0; 3991 const addr_t base_address = 3992 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 3993 if (!success) 3994 return false; 3995 3996 EmulateInstruction::Context context; 3997 context.type = EmulateInstruction::eContextRegisterPlusOffset; 3998 RegisterInfo dwarf_reg; 3999 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4000 context.SetRegisterPlusOffset(dwarf_reg, offset); 4001 4002 for (int i = 0; i < 14; ++i) { 4003 if (BitIsSet(registers, i)) { 4004 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4005 context.SetRegisterPlusOffset(dwarf_reg, offset); 4006 if (wback && (n == 13)) // Pop Instruction 4007 { 4008 context.type = EmulateInstruction::eContextPopRegisterOffStack; 4009 context.SetAddress(base_address + offset); 4010 } 4011 4012 // R[i] = MemA [address, 4]; address = address + 4; 4013 uint32_t data = MemARead(context, base_address + offset, addr_byte_size, 4014 0, &success); 4015 if (!success) 4016 return false; 4017 4018 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4019 data)) 4020 return false; 4021 4022 offset += addr_byte_size; 4023 } 4024 } 4025 4026 if (BitIsSet(registers, 15)) { 4027 // LoadWritePC (MemA [address, 4]); 4028 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4029 context.SetRegisterPlusOffset(dwarf_reg, offset); 4030 uint32_t data = 4031 MemARead(context, base_address + offset, addr_byte_size, 0, &success); 4032 if (!success) 4033 return false; 4034 // In ARMv5T and above, this is an interworking branch. 4035 if (!LoadWritePC(context, data)) 4036 return false; 4037 } 4038 4039 if (wback && BitIsClear(registers, n)) { 4040 // R[n] = R[n] + 4 * BitCount (registers) 4041 int32_t offset = addr_byte_size * BitCount(registers); 4042 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4043 context.SetRegisterPlusOffset(dwarf_reg, offset); 4044 4045 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4046 base_address + offset)) 4047 return false; 4048 } 4049 if (wback && BitIsSet(registers, n)) 4050 // R[n] bits(32) UNKNOWN; 4051 return WriteBits32Unknown(n); 4052 } 4053 return true; 4054} 4055 4056// LDMDA loads multiple registers from consecutive memory locations using an 4057// address from a base register. 4058// The consecutive memory locations end at this address and the address just 4059// below the lowest of those locations can optionally be written back to the 4060// base register. 4061bool EmulateInstructionARM::EmulateLDMDA(const uint32_t opcode, 4062 const ARMEncoding encoding) { 4063#if 0 4064 // ARM pseudo code... 4065 if ConditionPassed() then 4066 EncodingSpecificOperations(); 4067 address = R[n] - 4*BitCount(registers) + 4; 4068 4069 for i = 0 to 14 4070 if registers<i> == '1' then 4071 R[i] = MemA[address,4]; address = address + 4; 4072 4073 if registers<15> == '1' then 4074 LoadWritePC(MemA[address,4]); 4075 4076 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4077 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4078#endif 4079 4080 bool success = false; 4081 4082 if (ConditionPassed(opcode)) { 4083 uint32_t n; 4084 uint32_t registers = 0; 4085 bool wback; 4086 const uint32_t addr_byte_size = GetAddressByteSize(); 4087 4088 // EncodingSpecificOperations(); 4089 switch (encoding) { 4090 case eEncodingA1: 4091 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4092 n = Bits32(opcode, 19, 16); 4093 registers = Bits32(opcode, 15, 0); 4094 wback = BitIsSet(opcode, 21); 4095 4096 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4097 if ((n == 15) || (BitCount(registers) < 1)) 4098 return false; 4099 4100 break; 4101 4102 default: 4103 return false; 4104 } 4105 // address = R[n] - 4*BitCount(registers) + 4; 4106 4107 int32_t offset = 0; 4108 addr_t Rn = ReadCoreReg(n, &success); 4109 4110 if (!success) 4111 return false; 4112 4113 addr_t address = 4114 Rn - (addr_byte_size * BitCount(registers)) + addr_byte_size; 4115 4116 EmulateInstruction::Context context; 4117 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4118 RegisterInfo dwarf_reg; 4119 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4120 context.SetRegisterPlusOffset(dwarf_reg, offset); 4121 4122 // for i = 0 to 14 4123 for (int i = 0; i < 14; ++i) { 4124 // if registers<i> == '1' then 4125 if (BitIsSet(registers, i)) { 4126 // R[i] = MemA[address,4]; address = address + 4; 4127 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4128 uint32_t data = 4129 MemARead(context, address + offset, addr_byte_size, 0, &success); 4130 if (!success) 4131 return false; 4132 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4133 data)) 4134 return false; 4135 offset += addr_byte_size; 4136 } 4137 } 4138 4139 // if registers<15> == '1' then 4140 // LoadWritePC(MemA[address,4]); 4141 if (BitIsSet(registers, 15)) { 4142 context.SetRegisterPlusOffset(dwarf_reg, offset); 4143 uint32_t data = 4144 MemARead(context, address + offset, addr_byte_size, 0, &success); 4145 if (!success) 4146 return false; 4147 // In ARMv5T and above, this is an interworking branch. 4148 if (!LoadWritePC(context, data)) 4149 return false; 4150 } 4151 4152 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4153 if (wback && BitIsClear(registers, n)) { 4154 if (!success) 4155 return false; 4156 4157 offset = (addr_byte_size * BitCount(registers)) * -1; 4158 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4159 context.SetImmediateSigned(offset); 4160 addr_t addr = Rn + offset; 4161 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4162 addr)) 4163 return false; 4164 } 4165 4166 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4167 if (wback && BitIsSet(registers, n)) 4168 return WriteBits32Unknown(n); 4169 } 4170 return true; 4171} 4172 4173// LDMDB loads multiple registers from consecutive memory locations using an 4174// address from a base register. The 4175// consecutive memory locations end just below this address, and the address of 4176// the lowest of those locations can be optionally written back to the base 4177// register. 4178bool EmulateInstructionARM::EmulateLDMDB(const uint32_t opcode, 4179 const ARMEncoding encoding) { 4180#if 0 4181 // ARM pseudo code... 4182 if ConditionPassed() then 4183 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4184 address = R[n] - 4*BitCount(registers); 4185 4186 for i = 0 to 14 4187 if registers<i> == '1' then 4188 R[i] = MemA[address,4]; address = address + 4; 4189 if registers<15> == '1' then 4190 LoadWritePC(MemA[address,4]); 4191 4192 if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4193 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1 4194#endif 4195 4196 bool success = false; 4197 4198 if (ConditionPassed(opcode)) { 4199 uint32_t n; 4200 uint32_t registers = 0; 4201 bool wback; 4202 const uint32_t addr_byte_size = GetAddressByteSize(); 4203 switch (encoding) { 4204 case eEncodingT1: 4205 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1'); 4206 n = Bits32(opcode, 19, 16); 4207 registers = Bits32(opcode, 15, 0); 4208 registers = registers & 0xdfff; // Make sure bit 13 is a zero. 4209 wback = BitIsSet(opcode, 21); 4210 4211 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then 4212 // UNPREDICTABLE; 4213 if ((n == 15) || (BitCount(registers) < 2) || 4214 (BitIsSet(opcode, 14) && BitIsSet(opcode, 15))) 4215 return false; 4216 4217 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then 4218 // UNPREDICTABLE; 4219 if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock()) 4220 return false; 4221 4222 // if wback && registers<n> == '1' then UNPREDICTABLE; 4223 if (wback && BitIsSet(registers, n)) 4224 return false; 4225 4226 break; 4227 4228 case eEncodingA1: 4229 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4230 n = Bits32(opcode, 19, 16); 4231 registers = Bits32(opcode, 15, 0); 4232 wback = BitIsSet(opcode, 21); 4233 4234 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4235 if ((n == 15) || (BitCount(registers) < 1)) 4236 return false; 4237 4238 break; 4239 4240 default: 4241 return false; 4242 } 4243 4244 // address = R[n] - 4*BitCount(registers); 4245 4246 int32_t offset = 0; 4247 addr_t Rn = 4248 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4249 4250 if (!success) 4251 return false; 4252 4253 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4254 EmulateInstruction::Context context; 4255 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4256 RegisterInfo dwarf_reg; 4257 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4258 context.SetRegisterPlusOffset(dwarf_reg, Rn - address); 4259 4260 for (int i = 0; i < 14; ++i) { 4261 if (BitIsSet(registers, i)) { 4262 // R[i] = MemA[address,4]; address = address + 4; 4263 context.SetRegisterPlusOffset(dwarf_reg, Rn - (address + offset)); 4264 uint32_t data = 4265 MemARead(context, address + offset, addr_byte_size, 0, &success); 4266 if (!success) 4267 return false; 4268 4269 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4270 data)) 4271 return false; 4272 4273 offset += addr_byte_size; 4274 } 4275 } 4276 4277 // if registers<15> == '1' then 4278 // LoadWritePC(MemA[address,4]); 4279 if (BitIsSet(registers, 15)) { 4280 context.SetRegisterPlusOffset(dwarf_reg, offset); 4281 uint32_t data = 4282 MemARead(context, address + offset, addr_byte_size, 0, &success); 4283 if (!success) 4284 return false; 4285 // In ARMv5T and above, this is an interworking branch. 4286 if (!LoadWritePC(context, data)) 4287 return false; 4288 } 4289 4290 // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers); 4291 if (wback && BitIsClear(registers, n)) { 4292 if (!success) 4293 return false; 4294 4295 offset = (addr_byte_size * BitCount(registers)) * -1; 4296 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4297 context.SetImmediateSigned(offset); 4298 addr_t addr = Rn + offset; 4299 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4300 addr)) 4301 return false; 4302 } 4303 4304 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4305 // possible for encoding A1 4306 if (wback && BitIsSet(registers, n)) 4307 return WriteBits32Unknown(n); 4308 } 4309 return true; 4310} 4311 4312// LDMIB loads multiple registers from consecutive memory locations using an 4313// address from a base register. The 4314// consecutive memory locations start just above this address, and thea ddress 4315// of the last of those locations can optinoally be written back to the base 4316// register. 4317bool EmulateInstructionARM::EmulateLDMIB(const uint32_t opcode, 4318 const ARMEncoding encoding) { 4319#if 0 4320 if ConditionPassed() then 4321 EncodingSpecificOperations(); 4322 address = R[n] + 4; 4323 4324 for i = 0 to 14 4325 if registers<i> == '1' then 4326 R[i] = MemA[address,4]; address = address + 4; 4327 if registers<15> == '1' then 4328 LoadWritePC(MemA[address,4]); 4329 4330 if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4331 if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; 4332#endif 4333 4334 bool success = false; 4335 4336 if (ConditionPassed(opcode)) { 4337 uint32_t n; 4338 uint32_t registers = 0; 4339 bool wback; 4340 const uint32_t addr_byte_size = GetAddressByteSize(); 4341 switch (encoding) { 4342 case eEncodingA1: 4343 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4344 n = Bits32(opcode, 19, 16); 4345 registers = Bits32(opcode, 15, 0); 4346 wback = BitIsSet(opcode, 21); 4347 4348 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4349 if ((n == 15) || (BitCount(registers) < 1)) 4350 return false; 4351 4352 break; 4353 default: 4354 return false; 4355 } 4356 // address = R[n] + 4; 4357 4358 int32_t offset = 0; 4359 addr_t Rn = 4360 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4361 4362 if (!success) 4363 return false; 4364 4365 addr_t address = Rn + addr_byte_size; 4366 4367 EmulateInstruction::Context context; 4368 context.type = EmulateInstruction::eContextRegisterPlusOffset; 4369 RegisterInfo dwarf_reg; 4370 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg); 4371 context.SetRegisterPlusOffset(dwarf_reg, offset); 4372 4373 for (int i = 0; i < 14; ++i) { 4374 if (BitIsSet(registers, i)) { 4375 // R[i] = MemA[address,4]; address = address + 4; 4376 4377 context.SetRegisterPlusOffset(dwarf_reg, offset + addr_byte_size); 4378 uint32_t data = 4379 MemARead(context, address + offset, addr_byte_size, 0, &success); 4380 if (!success) 4381 return false; 4382 4383 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, 4384 data)) 4385 return false; 4386 4387 offset += addr_byte_size; 4388 } 4389 } 4390 4391 // if registers<15> == '1' then 4392 // LoadWritePC(MemA[address,4]); 4393 if (BitIsSet(registers, 15)) { 4394 context.SetRegisterPlusOffset(dwarf_reg, offset); 4395 uint32_t data = 4396 MemARead(context, address + offset, addr_byte_size, 0, &success); 4397 if (!success) 4398 return false; 4399 // In ARMv5T and above, this is an interworking branch. 4400 if (!LoadWritePC(context, data)) 4401 return false; 4402 } 4403 4404 // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers); 4405 if (wback && BitIsClear(registers, n)) { 4406 if (!success) 4407 return false; 4408 4409 offset = addr_byte_size * BitCount(registers); 4410 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4411 context.SetImmediateSigned(offset); 4412 addr_t addr = Rn + offset; 4413 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4414 addr)) 4415 return false; 4416 } 4417 4418 // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only 4419 // possible for encoding A1 4420 if (wback && BitIsSet(registers, n)) 4421 return WriteBits32Unknown(n); 4422 } 4423 return true; 4424} 4425 4426// Load Register (immediate) calculates an address from a base register value 4427// and an immediate offset, loads a word from memory, and writes to a register. 4428// LDR (immediate, Thumb) 4429bool EmulateInstructionARM::EmulateLDRRtRnImm(const uint32_t opcode, 4430 const ARMEncoding encoding) { 4431#if 0 4432 // ARM pseudo code... 4433 if (ConditionPassed()) 4434 { 4435 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 4436 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 4437 address = if index then offset_addr else R[n]; 4438 data = MemU[address,4]; 4439 if wback then R[n] = offset_addr; 4440 if t == 15 then 4441 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 4442 elsif UnalignedSupport() || address<1:0> = '00' then 4443 R[t] = data; 4444 else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7 4445 } 4446#endif 4447 4448 bool success = false; 4449 4450 if (ConditionPassed(opcode)) { 4451 uint32_t Rt; // the destination register 4452 uint32_t Rn; // the base register 4453 uint32_t imm32; // the immediate offset used to form the address 4454 addr_t offset_addr; // the offset address 4455 addr_t address; // the calculated address 4456 uint32_t data; // the literal data value from memory load 4457 bool add, index, wback; 4458 switch (encoding) { 4459 case eEncodingT1: 4460 Rt = Bits32(opcode, 2, 0); 4461 Rn = Bits32(opcode, 5, 3); 4462 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32); 4463 // index = TRUE; add = TRUE; wback = FALSE 4464 add = true; 4465 index = true; 4466 wback = false; 4467 4468 break; 4469 4470 case eEncodingT2: 4471 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 4472 Rt = Bits32(opcode, 10, 8); 4473 Rn = 13; 4474 imm32 = Bits32(opcode, 7, 0) << 2; 4475 4476 // index = TRUE; add = TRUE; wback = FALSE; 4477 index = true; 4478 add = true; 4479 wback = false; 4480 4481 break; 4482 4483 case eEncodingT3: 4484 // if Rn == '1111' then SEE LDR (literal); 4485 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 4486 Rt = Bits32(opcode, 15, 12); 4487 Rn = Bits32(opcode, 19, 16); 4488 imm32 = Bits32(opcode, 11, 0); 4489 4490 // index = TRUE; add = TRUE; wback = FALSE; 4491 index = true; 4492 add = true; 4493 wback = false; 4494 4495 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 4496 if ((Rt == 15) && InITBlock() && !LastInITBlock()) 4497 return false; 4498 4499 break; 4500 4501 case eEncodingT4: 4502 // if Rn == '1111' then SEE LDR (literal); 4503 // if P == '1' && U == '1' && W == '0' then SEE LDRT; 4504 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == 4505 // '00000100' then SEE POP; 4506 // if P == '0' && W == '0' then UNDEFINED; 4507 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 4508 return false; 4509 4510 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 4511 Rt = Bits32(opcode, 15, 12); 4512 Rn = Bits32(opcode, 19, 16); 4513 imm32 = Bits32(opcode, 7, 0); 4514 4515 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 4516 index = BitIsSet(opcode, 10); 4517 add = BitIsSet(opcode, 9); 4518 wback = BitIsSet(opcode, 8); 4519 4520 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) 4521 // then UNPREDICTABLE; 4522 if ((wback && (Rn == Rt)) || 4523 ((Rt == 15) && InITBlock() && !LastInITBlock())) 4524 return false; 4525 4526 break; 4527 4528 default: 4529 return false; 4530 } 4531 uint32_t base = ReadCoreReg(Rn, &success); 4532 if (!success) 4533 return false; 4534 if (add) 4535 offset_addr = base + imm32; 4536 else 4537 offset_addr = base - imm32; 4538 4539 address = (index ? offset_addr : base); 4540 4541 RegisterInfo base_reg; 4542 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + Rn, base_reg); 4543 if (wback) { 4544 EmulateInstruction::Context ctx; 4545 if (Rn == 13) { 4546 ctx.type = eContextAdjustStackPointer; 4547 ctx.SetImmediateSigned((int32_t)(offset_addr - base)); 4548 } else if (Rn == GetFramePointerRegisterNumber()) { 4549 ctx.type = eContextSetFramePointer; 4550 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4551 } else { 4552 ctx.type = EmulateInstruction::eContextAdjustBaseRegister; 4553 ctx.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4554 } 4555 4556 if (!WriteRegisterUnsigned(ctx, eRegisterKindDWARF, dwarf_r0 + Rn, 4557 offset_addr)) 4558 return false; 4559 } 4560 4561 // Prepare to write to the Rt register. 4562 EmulateInstruction::Context context; 4563 context.type = EmulateInstruction::eContextRegisterLoad; 4564 context.SetRegisterPlusOffset(base_reg, (int32_t)(offset_addr - base)); 4565 4566 // Read memory from the address. 4567 data = MemURead(context, address, 4, 0, &success); 4568 if (!success) 4569 return false; 4570 4571 if (Rt == 15) { 4572 if (Bits32(address, 1, 0) == 0) { 4573 if (!LoadWritePC(context, data)) 4574 return false; 4575 } else 4576 return false; 4577 } else if (UnalignedSupport() || Bits32(address, 1, 0) == 0) { 4578 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + Rt, 4579 data)) 4580 return false; 4581 } else 4582 WriteBits32Unknown(Rt); 4583 } 4584 return true; 4585} 4586 4587// STM (Store Multiple Increment After) stores multiple registers to consecutive 4588// memory locations using an address 4589// from a base register. The consecutive memory locations start at this 4590// address, and the address just above the last of those locations can 4591// optionally be written back to the base register. 4592bool EmulateInstructionARM::EmulateSTM(const uint32_t opcode, 4593 const ARMEncoding encoding) { 4594#if 0 4595 if ConditionPassed() then 4596 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4597 address = R[n]; 4598 4599 for i = 0 to 14 4600 if registers<i> == '1' then 4601 if i == n && wback && i != LowestSetBit(registers) then 4602 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1 4603 else 4604 MemA[address,4] = R[i]; 4605 address = address + 4; 4606 4607 if registers<15> == '1' then // Only possible for encoding A1 4608 MemA[address,4] = PCStoreValue(); 4609 if wback then R[n] = R[n] + 4*BitCount(registers); 4610#endif 4611 4612 bool success = false; 4613 4614 if (ConditionPassed(opcode)) { 4615 uint32_t n; 4616 uint32_t registers = 0; 4617 bool wback; 4618 const uint32_t addr_byte_size = GetAddressByteSize(); 4619 4620 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4621 switch (encoding) { 4622 case eEncodingT1: 4623 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE; 4624 n = Bits32(opcode, 10, 8); 4625 registers = Bits32(opcode, 7, 0); 4626 registers = registers & 0x00ff; // Make sure the top 8 bits are zeros. 4627 wback = true; 4628 4629 // if BitCount(registers) < 1 then UNPREDICTABLE; 4630 if (BitCount(registers) < 1) 4631 return false; 4632 4633 break; 4634 4635 case eEncodingT2: 4636 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4637 n = Bits32(opcode, 19, 16); 4638 registers = Bits32(opcode, 15, 0); 4639 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4640 wback = BitIsSet(opcode, 21); 4641 4642 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4643 if ((n == 15) || (BitCount(registers) < 2)) 4644 return false; 4645 4646 // if wback && registers<n> == '1' then UNPREDICTABLE; 4647 if (wback && BitIsSet(registers, n)) 4648 return false; 4649 4650 break; 4651 4652 case eEncodingA1: 4653 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4654 n = Bits32(opcode, 19, 16); 4655 registers = Bits32(opcode, 15, 0); 4656 wback = BitIsSet(opcode, 21); 4657 4658 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4659 if ((n == 15) || (BitCount(registers) < 1)) 4660 return false; 4661 4662 break; 4663 4664 default: 4665 return false; 4666 } 4667 4668 // address = R[n]; 4669 int32_t offset = 0; 4670 const addr_t address = 4671 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4672 if (!success) 4673 return false; 4674 4675 EmulateInstruction::Context context; 4676 context.type = EmulateInstruction::eContextRegisterStore; 4677 RegisterInfo base_reg; 4678 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4679 4680 // for i = 0 to 14 4681 uint32_t lowest_set_bit = 14; 4682 for (uint32_t i = 0; i < 14; ++i) { 4683 // if registers<i> == '1' then 4684 if (BitIsSet(registers, i)) { 4685 if (i < lowest_set_bit) 4686 lowest_set_bit = i; 4687 // if i == n && wback && i != LowestSetBit(registers) then 4688 if ((i == n) && wback && (i != lowest_set_bit)) 4689 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings 4690 // T1 and A1 4691 WriteBits32UnknownToMemory(address + offset); 4692 else { 4693 // MemA[address,4] = R[i]; 4694 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4695 0, &success); 4696 if (!success) 4697 return false; 4698 4699 RegisterInfo data_reg; 4700 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4701 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 4702 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4703 return false; 4704 } 4705 4706 // address = address + 4; 4707 offset += addr_byte_size; 4708 } 4709 } 4710 4711 // if registers<15> == '1' then // Only possible for encoding A1 4712 // MemA[address,4] = PCStoreValue(); 4713 if (BitIsSet(registers, 15)) { 4714 RegisterInfo pc_reg; 4715 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4716 context.SetRegisterPlusOffset(pc_reg, 8); 4717 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4718 if (!success) 4719 return false; 4720 4721 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4722 return false; 4723 } 4724 4725 // if wback then R[n] = R[n] + 4*BitCount(registers); 4726 if (wback) { 4727 offset = addr_byte_size * BitCount(registers); 4728 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4729 context.SetImmediateSigned(offset); 4730 addr_t data = address + offset; 4731 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4732 data)) 4733 return false; 4734 } 4735 } 4736 return true; 4737} 4738 4739// STMDA (Store Multiple Decrement After) stores multiple registers to 4740// consecutive memory locations using an address from a base register. The 4741// consecutive memory locations end at this address, and the address just below 4742// the lowest of those locations can optionally be written back to the base 4743// register. 4744bool EmulateInstructionARM::EmulateSTMDA(const uint32_t opcode, 4745 const ARMEncoding encoding) { 4746#if 0 4747 if ConditionPassed() then 4748 EncodingSpecificOperations(); 4749 address = R[n] - 4*BitCount(registers) + 4; 4750 4751 for i = 0 to 14 4752 if registers<i> == '1' then 4753 if i == n && wback && i != LowestSetBit(registers) then 4754 MemA[address,4] = bits(32) UNKNOWN; 4755 else 4756 MemA[address,4] = R[i]; 4757 address = address + 4; 4758 4759 if registers<15> == '1' then 4760 MemA[address,4] = PCStoreValue(); 4761 4762 if wback then R[n] = R[n] - 4*BitCount(registers); 4763#endif 4764 4765 bool success = false; 4766 4767 if (ConditionPassed(opcode)) { 4768 uint32_t n; 4769 uint32_t registers = 0; 4770 bool wback; 4771 const uint32_t addr_byte_size = GetAddressByteSize(); 4772 4773 // EncodingSpecificOperations(); 4774 switch (encoding) { 4775 case eEncodingA1: 4776 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4777 n = Bits32(opcode, 19, 16); 4778 registers = Bits32(opcode, 15, 0); 4779 wback = BitIsSet(opcode, 21); 4780 4781 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4782 if ((n == 15) || (BitCount(registers) < 1)) 4783 return false; 4784 break; 4785 default: 4786 return false; 4787 } 4788 4789 // address = R[n] - 4*BitCount(registers) + 4; 4790 int32_t offset = 0; 4791 addr_t Rn = ReadCoreReg(n, &success); 4792 if (!success) 4793 return false; 4794 4795 addr_t address = Rn - (addr_byte_size * BitCount(registers)) + 4; 4796 4797 EmulateInstruction::Context context; 4798 context.type = EmulateInstruction::eContextRegisterStore; 4799 RegisterInfo base_reg; 4800 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4801 4802 // for i = 0 to 14 4803 uint32_t lowest_bit_set = 14; 4804 for (uint32_t i = 0; i < 14; ++i) { 4805 // if registers<i> == '1' then 4806 if (BitIsSet(registers, i)) { 4807 if (i < lowest_bit_set) 4808 lowest_bit_set = i; 4809 // if i == n && wback && i != LowestSetBit(registers) then 4810 if ((i == n) && wback && (i != lowest_bit_set)) 4811 // MemA[address,4] = bits(32) UNKNOWN; 4812 WriteBits32UnknownToMemory(address + offset); 4813 else { 4814 // MemA[address,4] = R[i]; 4815 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4816 0, &success); 4817 if (!success) 4818 return false; 4819 4820 RegisterInfo data_reg; 4821 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4822 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4823 Rn - (address + offset)); 4824 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4825 return false; 4826 } 4827 4828 // address = address + 4; 4829 offset += addr_byte_size; 4830 } 4831 } 4832 4833 // if registers<15> == '1' then 4834 // MemA[address,4] = PCStoreValue(); 4835 if (BitIsSet(registers, 15)) { 4836 RegisterInfo pc_reg; 4837 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4838 context.SetRegisterPlusOffset(pc_reg, 8); 4839 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4840 if (!success) 4841 return false; 4842 4843 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4844 return false; 4845 } 4846 4847 // if wback then R[n] = R[n] - 4*BitCount(registers); 4848 if (wback) { 4849 offset = (addr_byte_size * BitCount(registers)) * -1; 4850 context.type = EmulateInstruction::eContextAdjustBaseRegister; 4851 context.SetImmediateSigned(offset); 4852 addr_t data = Rn + offset; 4853 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 4854 data)) 4855 return false; 4856 } 4857 } 4858 return true; 4859} 4860 4861// STMDB (Store Multiple Decrement Before) stores multiple registers to 4862// consecutive memory locations using an address from a base register. The 4863// consecutive memory locations end just below this address, and the address of 4864// the first of those locations can optionally be written back to the base 4865// register. 4866bool EmulateInstructionARM::EmulateSTMDB(const uint32_t opcode, 4867 const ARMEncoding encoding) { 4868#if 0 4869 if ConditionPassed() then 4870 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4871 address = R[n] - 4*BitCount(registers); 4872 4873 for i = 0 to 14 4874 if registers<i> == '1' then 4875 if i == n && wback && i != LowestSetBit(registers) then 4876 MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1 4877 else 4878 MemA[address,4] = R[i]; 4879 address = address + 4; 4880 4881 if registers<15> == '1' then // Only possible for encoding A1 4882 MemA[address,4] = PCStoreValue(); 4883 4884 if wback then R[n] = R[n] - 4*BitCount(registers); 4885#endif 4886 4887 bool success = false; 4888 4889 if (ConditionPassed(opcode)) { 4890 uint32_t n; 4891 uint32_t registers = 0; 4892 bool wback; 4893 const uint32_t addr_byte_size = GetAddressByteSize(); 4894 4895 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 4896 switch (encoding) { 4897 case eEncodingT1: 4898 // if W == '1' && Rn == '1101' then SEE PUSH; 4899 if ((BitIsSet(opcode, 21)) && (Bits32(opcode, 19, 16) == 13)) { 4900 // See PUSH 4901 } 4902 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1'); 4903 n = Bits32(opcode, 19, 16); 4904 registers = Bits32(opcode, 15, 0); 4905 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros. 4906 wback = BitIsSet(opcode, 21); 4907 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE; 4908 if ((n == 15) || BitCount(registers) < 2) 4909 return false; 4910 // if wback && registers<n> == '1' then UNPREDICTABLE; 4911 if (wback && BitIsSet(registers, n)) 4912 return false; 4913 break; 4914 4915 case eEncodingA1: 4916 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE 4917 // PUSH; 4918 if (BitIsSet(opcode, 21) && (Bits32(opcode, 19, 16) == 13) && 4919 BitCount(Bits32(opcode, 15, 0)) >= 2) { 4920 // See Push 4921 } 4922 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 4923 n = Bits32(opcode, 19, 16); 4924 registers = Bits32(opcode, 15, 0); 4925 wback = BitIsSet(opcode, 21); 4926 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 4927 if ((n == 15) || BitCount(registers) < 1) 4928 return false; 4929 break; 4930 4931 default: 4932 return false; 4933 } 4934 4935 // address = R[n] - 4*BitCount(registers); 4936 4937 int32_t offset = 0; 4938 addr_t Rn = 4939 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 4940 if (!success) 4941 return false; 4942 4943 addr_t address = Rn - (addr_byte_size * BitCount(registers)); 4944 4945 EmulateInstruction::Context context; 4946 context.type = EmulateInstruction::eContextRegisterStore; 4947 RegisterInfo base_reg; 4948 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 4949 4950 // for i = 0 to 14 4951 uint32_t lowest_set_bit = 14; 4952 for (uint32_t i = 0; i < 14; ++i) { 4953 // if registers<i> == '1' then 4954 if (BitIsSet(registers, i)) { 4955 if (i < lowest_set_bit) 4956 lowest_set_bit = i; 4957 // if i == n && wback && i != LowestSetBit(registers) then 4958 if ((i == n) && wback && (i != lowest_set_bit)) 4959 // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding 4960 // A1 4961 WriteBits32UnknownToMemory(address + offset); 4962 else { 4963 // MemA[address,4] = R[i]; 4964 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 4965 0, &success); 4966 if (!success) 4967 return false; 4968 4969 RegisterInfo data_reg; 4970 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 4971 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 4972 Rn - (address + offset)); 4973 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 4974 return false; 4975 } 4976 4977 // address = address + 4; 4978 offset += addr_byte_size; 4979 } 4980 } 4981 4982 // if registers<15> == '1' then // Only possible for encoding A1 4983 // MemA[address,4] = PCStoreValue(); 4984 if (BitIsSet(registers, 15)) { 4985 RegisterInfo pc_reg; 4986 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 4987 context.SetRegisterPlusOffset(pc_reg, 8); 4988 const uint32_t pc = ReadCoreReg(PC_REG, &success); 4989 if (!success) 4990 return false; 4991 4992 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 4993 return false; 4994 } 4995 4996 // if wback then R[n] = R[n] - 4*BitCount(registers); 4997 if (wback) { 4998 offset = (addr_byte_size * BitCount(registers)) * -1; 4999 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5000 context.SetImmediateSigned(offset); 5001 addr_t data = Rn + offset; 5002 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5003 data)) 5004 return false; 5005 } 5006 } 5007 return true; 5008} 5009 5010// STMIB (Store Multiple Increment Before) stores multiple registers to 5011// consecutive memory locations using an address from a base register. The 5012// consecutive memory locations start just above this address, and the address 5013// of the last of those locations can optionally be written back to the base 5014// register. 5015bool EmulateInstructionARM::EmulateSTMIB(const uint32_t opcode, 5016 const ARMEncoding encoding) { 5017#if 0 5018 if ConditionPassed() then 5019 EncodingSpecificOperations(); 5020 address = R[n] + 4; 5021 5022 for i = 0 to 14 5023 if registers<i> == '1' then 5024 if i == n && wback && i != LowestSetBit(registers) then 5025 MemA[address,4] = bits(32) UNKNOWN; 5026 else 5027 MemA[address,4] = R[i]; 5028 address = address + 4; 5029 5030 if registers<15> == '1' then 5031 MemA[address,4] = PCStoreValue(); 5032 5033 if wback then R[n] = R[n] + 4*BitCount(registers); 5034#endif 5035 5036 bool success = false; 5037 5038 if (ConditionPassed(opcode)) { 5039 uint32_t n; 5040 uint32_t registers = 0; 5041 bool wback; 5042 const uint32_t addr_byte_size = GetAddressByteSize(); 5043 5044 // EncodingSpecificOperations(); 5045 switch (encoding) { 5046 case eEncodingA1: 5047 // n = UInt(Rn); registers = register_list; wback = (W == '1'); 5048 n = Bits32(opcode, 19, 16); 5049 registers = Bits32(opcode, 15, 0); 5050 wback = BitIsSet(opcode, 21); 5051 5052 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE; 5053 if ((n == 15) && (BitCount(registers) < 1)) 5054 return false; 5055 break; 5056 default: 5057 return false; 5058 } 5059 // address = R[n] + 4; 5060 5061 int32_t offset = 0; 5062 addr_t Rn = ReadCoreReg(n, &success); 5063 if (!success) 5064 return false; 5065 5066 addr_t address = Rn + addr_byte_size; 5067 5068 EmulateInstruction::Context context; 5069 context.type = EmulateInstruction::eContextRegisterStore; 5070 RegisterInfo base_reg; 5071 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5072 5073 uint32_t lowest_set_bit = 14; 5074 // for i = 0 to 14 5075 for (uint32_t i = 0; i < 14; ++i) { 5076 // if registers<i> == '1' then 5077 if (BitIsSet(registers, i)) { 5078 if (i < lowest_set_bit) 5079 lowest_set_bit = i; 5080 // if i == n && wback && i != LowestSetBit(registers) then 5081 if ((i == n) && wback && (i != lowest_set_bit)) 5082 // MemA[address,4] = bits(32) UNKNOWN; 5083 WriteBits32UnknownToMemory(address + offset); 5084 // else 5085 else { 5086 // MemA[address,4] = R[i]; 5087 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + i, 5088 0, &success); 5089 if (!success) 5090 return false; 5091 5092 RegisterInfo data_reg; 5093 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + i, data_reg); 5094 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5095 offset + addr_byte_size); 5096 if (!MemAWrite(context, address + offset, data, addr_byte_size)) 5097 return false; 5098 } 5099 5100 // address = address + 4; 5101 offset += addr_byte_size; 5102 } 5103 } 5104 5105 // if registers<15> == '1' then 5106 // MemA[address,4] = PCStoreValue(); 5107 if (BitIsSet(registers, 15)) { 5108 RegisterInfo pc_reg; 5109 GetRegisterInfo(eRegisterKindDWARF, dwarf_pc, pc_reg); 5110 context.SetRegisterPlusOffset(pc_reg, 8); 5111 const uint32_t pc = ReadCoreReg(PC_REG, &success); 5112 if (!success) 5113 return false; 5114 5115 if (!MemAWrite(context, address + offset, pc, addr_byte_size)) 5116 return false; 5117 } 5118 5119 // if wback then R[n] = R[n] + 4*BitCount(registers); 5120 if (wback) { 5121 offset = addr_byte_size * BitCount(registers); 5122 context.type = EmulateInstruction::eContextAdjustBaseRegister; 5123 context.SetImmediateSigned(offset); 5124 addr_t data = Rn + offset; 5125 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5126 data)) 5127 return false; 5128 } 5129 } 5130 return true; 5131} 5132 5133// STR (store immediate) calculates an address from a base register value and an 5134// immediate offset, and stores a word 5135// from a register to memory. It can use offset, post-indexed, or pre-indexed 5136// addressing. 5137bool EmulateInstructionARM::EmulateSTRThumb(const uint32_t opcode, 5138 const ARMEncoding encoding) { 5139#if 0 5140 if ConditionPassed() then 5141 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5142 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5143 address = if index then offset_addr else R[n]; 5144 if UnalignedSupport() || address<1:0> == '00' then 5145 MemU[address,4] = R[t]; 5146 else // Can only occur before ARMv7 5147 MemU[address,4] = bits(32) UNKNOWN; 5148 if wback then R[n] = offset_addr; 5149#endif 5150 5151 bool success = false; 5152 5153 if (ConditionPassed(opcode)) { 5154 const uint32_t addr_byte_size = GetAddressByteSize(); 5155 5156 uint32_t t; 5157 uint32_t n; 5158 uint32_t imm32; 5159 bool index; 5160 bool add; 5161 bool wback; 5162 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5163 switch (encoding) { 5164 case eEncodingT1: 5165 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32); 5166 t = Bits32(opcode, 2, 0); 5167 n = Bits32(opcode, 5, 3); 5168 imm32 = Bits32(opcode, 10, 6) << 2; 5169 5170 // index = TRUE; add = TRUE; wback = FALSE; 5171 index = true; 5172 add = false; 5173 wback = false; 5174 break; 5175 5176 case eEncodingT2: 5177 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32); 5178 t = Bits32(opcode, 10, 8); 5179 n = 13; 5180 imm32 = Bits32(opcode, 7, 0) << 2; 5181 5182 // index = TRUE; add = TRUE; wback = FALSE; 5183 index = true; 5184 add = true; 5185 wback = false; 5186 break; 5187 5188 case eEncodingT3: 5189 // if Rn == '1111' then UNDEFINED; 5190 if (Bits32(opcode, 19, 16) == 15) 5191 return false; 5192 5193 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5194 t = Bits32(opcode, 15, 12); 5195 n = Bits32(opcode, 19, 16); 5196 imm32 = Bits32(opcode, 11, 0); 5197 5198 // index = TRUE; add = TRUE; wback = FALSE; 5199 index = true; 5200 add = true; 5201 wback = false; 5202 5203 // if t == 15 then UNPREDICTABLE; 5204 if (t == 15) 5205 return false; 5206 break; 5207 5208 case eEncodingT4: 5209 // if P == '1' && U == '1' && W == '0' then SEE STRT; 5210 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == 5211 // '00000100' then SEE PUSH; 5212 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5213 if ((Bits32(opcode, 19, 16) == 15) || 5214 (BitIsClear(opcode, 10) && BitIsClear(opcode, 8))) 5215 return false; 5216 5217 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5218 t = Bits32(opcode, 15, 12); 5219 n = Bits32(opcode, 19, 16); 5220 imm32 = Bits32(opcode, 7, 0); 5221 5222 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5223 index = BitIsSet(opcode, 10); 5224 add = BitIsSet(opcode, 9); 5225 wback = BitIsSet(opcode, 8); 5226 5227 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 5228 if ((t == 15) || (wback && (n == t))) 5229 return false; 5230 break; 5231 5232 default: 5233 return false; 5234 } 5235 5236 addr_t offset_addr; 5237 addr_t address; 5238 5239 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5240 uint32_t base_address = ReadCoreReg(n, &success); 5241 if (!success) 5242 return false; 5243 5244 if (add) 5245 offset_addr = base_address + imm32; 5246 else 5247 offset_addr = base_address - imm32; 5248 5249 // address = if index then offset_addr else R[n]; 5250 if (index) 5251 address = offset_addr; 5252 else 5253 address = base_address; 5254 5255 EmulateInstruction::Context context; 5256 if (n == 13) 5257 context.type = eContextPushRegisterOnStack; 5258 else 5259 context.type = eContextRegisterStore; 5260 5261 RegisterInfo base_reg; 5262 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5263 5264 // if UnalignedSupport() || address<1:0> == '00' then 5265 if (UnalignedSupport() || 5266 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 5267 // MemU[address,4] = R[t]; 5268 uint32_t data = 5269 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5270 if (!success) 5271 return false; 5272 5273 RegisterInfo data_reg; 5274 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5275 int32_t offset = address - base_address; 5276 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, offset); 5277 if (!MemUWrite(context, address, data, addr_byte_size)) 5278 return false; 5279 } else { 5280 // MemU[address,4] = bits(32) UNKNOWN; 5281 WriteBits32UnknownToMemory(address); 5282 } 5283 5284 // if wback then R[n] = offset_addr; 5285 if (wback) { 5286 if (n == 13) 5287 context.type = eContextAdjustStackPointer; 5288 else 5289 context.type = eContextAdjustBaseRegister; 5290 context.SetAddress(offset_addr); 5291 5292 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5293 offset_addr)) 5294 return false; 5295 } 5296 } 5297 return true; 5298} 5299 5300// STR (Store Register) calculates an address from a base register value and an 5301// offset register value, stores a 5302// word from a register to memory. The offset register value can optionally 5303// be shifted. 5304bool EmulateInstructionARM::EmulateSTRRegister(const uint32_t opcode, 5305 const ARMEncoding encoding) { 5306#if 0 5307 if ConditionPassed() then 5308 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5309 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5310 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5311 address = if index then offset_addr else R[n]; 5312 if t == 15 then // Only possible for encoding A1 5313 data = PCStoreValue(); 5314 else 5315 data = R[t]; 5316 if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then 5317 MemU[address,4] = data; 5318 else // Can only occur before ARMv7 5319 MemU[address,4] = bits(32) UNKNOWN; 5320 if wback then R[n] = offset_addr; 5321#endif 5322 5323 bool success = false; 5324 5325 if (ConditionPassed(opcode)) { 5326 const uint32_t addr_byte_size = GetAddressByteSize(); 5327 5328 uint32_t t; 5329 uint32_t n; 5330 uint32_t m; 5331 ARM_ShifterType shift_t; 5332 uint32_t shift_n; 5333 bool index; 5334 bool add; 5335 bool wback; 5336 5337 // EncodingSpecificOperations (); NullCheckIfThumbEE(n); 5338 switch (encoding) { 5339 case eEncodingT1: 5340 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5341 // in ThumbEE"; 5342 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5343 t = Bits32(opcode, 2, 0); 5344 n = Bits32(opcode, 5, 3); 5345 m = Bits32(opcode, 8, 6); 5346 5347 // index = TRUE; add = TRUE; wback = FALSE; 5348 index = true; 5349 add = true; 5350 wback = false; 5351 5352 // (shift_t, shift_n) = (SRType_LSL, 0); 5353 shift_t = SRType_LSL; 5354 shift_n = 0; 5355 break; 5356 5357 case eEncodingT2: 5358 // if Rn == '1111' then UNDEFINED; 5359 if (Bits32(opcode, 19, 16) == 15) 5360 return false; 5361 5362 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5363 t = Bits32(opcode, 15, 12); 5364 n = Bits32(opcode, 19, 16); 5365 m = Bits32(opcode, 3, 0); 5366 5367 // index = TRUE; add = TRUE; wback = FALSE; 5368 index = true; 5369 add = true; 5370 wback = false; 5371 5372 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5373 shift_t = SRType_LSL; 5374 shift_n = Bits32(opcode, 5, 4); 5375 5376 // if t == 15 || BadReg(m) then UNPREDICTABLE; 5377 if ((t == 15) || (BadReg(m))) 5378 return false; 5379 break; 5380 5381 case eEncodingA1: { 5382 // if P == '0' && W == '1' then SEE STRT; 5383 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5384 t = Bits32(opcode, 15, 12); 5385 n = Bits32(opcode, 19, 16); 5386 m = Bits32(opcode, 3, 0); 5387 5388 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5389 // (W == '1'); 5390 index = BitIsSet(opcode, 24); 5391 add = BitIsSet(opcode, 23); 5392 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5393 5394 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 5395 uint32_t typ = Bits32(opcode, 6, 5); 5396 uint32_t imm5 = Bits32(opcode, 11, 7); 5397 shift_n = DecodeImmShift(typ, imm5, shift_t); 5398 5399 // if m == 15 then UNPREDICTABLE; 5400 if (m == 15) 5401 return false; 5402 5403 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5404 if (wback && ((n == 15) || (n == t))) 5405 return false; 5406 5407 break; 5408 } 5409 default: 5410 return false; 5411 } 5412 5413 addr_t offset_addr; 5414 addr_t address; 5415 int32_t offset = 0; 5416 5417 addr_t base_address = 5418 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5419 if (!success) 5420 return false; 5421 5422 uint32_t Rm_data = 5423 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 5424 if (!success) 5425 return false; 5426 5427 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5428 offset = Shift(Rm_data, shift_t, shift_n, APSR_C, &success); 5429 if (!success) 5430 return false; 5431 5432 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5433 if (add) 5434 offset_addr = base_address + offset; 5435 else 5436 offset_addr = base_address - offset; 5437 5438 // address = if index then offset_addr else R[n]; 5439 if (index) 5440 address = offset_addr; 5441 else 5442 address = base_address; 5443 5444 uint32_t data; 5445 // if t == 15 then // Only possible for encoding A1 5446 if (t == 15) 5447 // data = PCStoreValue(); 5448 data = ReadCoreReg(PC_REG, &success); 5449 else 5450 // data = R[t]; 5451 data = 5452 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5453 5454 if (!success) 5455 return false; 5456 5457 EmulateInstruction::Context context; 5458 context.type = eContextRegisterStore; 5459 5460 // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == 5461 // InstrSet_ARM then 5462 if (UnalignedSupport() || 5463 (BitIsClear(address, 1) && BitIsClear(address, 0)) || 5464 CurrentInstrSet() == eModeARM) { 5465 // MemU[address,4] = data; 5466 5467 RegisterInfo base_reg; 5468 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5469 5470 RegisterInfo data_reg; 5471 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5472 5473 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5474 address - base_address); 5475 if (!MemUWrite(context, address, data, addr_byte_size)) 5476 return false; 5477 5478 } else 5479 // MemU[address,4] = bits(32) UNKNOWN; 5480 WriteBits32UnknownToMemory(address); 5481 5482 // if wback then R[n] = offset_addr; 5483 if (wback) { 5484 context.type = eContextRegisterLoad; 5485 context.SetAddress(offset_addr); 5486 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5487 offset_addr)) 5488 return false; 5489 } 5490 } 5491 return true; 5492} 5493 5494bool EmulateInstructionARM::EmulateSTRBThumb(const uint32_t opcode, 5495 const ARMEncoding encoding) { 5496#if 0 5497 if ConditionPassed() then 5498 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5499 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5500 address = if index then offset_addr else R[n]; 5501 MemU[address,1] = R[t]<7:0>; 5502 if wback then R[n] = offset_addr; 5503#endif 5504 5505 bool success = false; 5506 5507 if (ConditionPassed(opcode)) { 5508 uint32_t t; 5509 uint32_t n; 5510 uint32_t imm32; 5511 bool index; 5512 bool add; 5513 bool wback; 5514 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5515 switch (encoding) { 5516 case eEncodingT1: 5517 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 5518 t = Bits32(opcode, 2, 0); 5519 n = Bits32(opcode, 5, 3); 5520 imm32 = Bits32(opcode, 10, 6); 5521 5522 // index = TRUE; add = TRUE; wback = FALSE; 5523 index = true; 5524 add = true; 5525 wback = false; 5526 break; 5527 5528 case eEncodingT2: 5529 // if Rn == '1111' then UNDEFINED; 5530 if (Bits32(opcode, 19, 16) == 15) 5531 return false; 5532 5533 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 5534 t = Bits32(opcode, 15, 12); 5535 n = Bits32(opcode, 19, 16); 5536 imm32 = Bits32(opcode, 11, 0); 5537 5538 // index = TRUE; add = TRUE; wback = FALSE; 5539 index = true; 5540 add = true; 5541 wback = false; 5542 5543 // if BadReg(t) then UNPREDICTABLE; 5544 if (BadReg(t)) 5545 return false; 5546 break; 5547 5548 case eEncodingT3: 5549 // if P == '1' && U == '1' && W == '0' then SEE STRBT; 5550 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; 5551 if (Bits32(opcode, 19, 16) == 15) 5552 return false; 5553 5554 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 5555 t = Bits32(opcode, 15, 12); 5556 n = Bits32(opcode, 19, 16); 5557 imm32 = Bits32(opcode, 7, 0); 5558 5559 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 5560 index = BitIsSet(opcode, 10); 5561 add = BitIsSet(opcode, 9); 5562 wback = BitIsSet(opcode, 8); 5563 5564 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE 5565 if ((BadReg(t)) || (wback && (n == t))) 5566 return false; 5567 break; 5568 5569 default: 5570 return false; 5571 } 5572 5573 addr_t offset_addr; 5574 addr_t address; 5575 addr_t base_address = 5576 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 5577 if (!success) 5578 return false; 5579 5580 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 5581 if (add) 5582 offset_addr = base_address + imm32; 5583 else 5584 offset_addr = base_address - imm32; 5585 5586 // address = if index then offset_addr else R[n]; 5587 if (index) 5588 address = offset_addr; 5589 else 5590 address = base_address; 5591 5592 // MemU[address,1] = R[t]<7:0> 5593 RegisterInfo base_reg; 5594 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5595 5596 RegisterInfo data_reg; 5597 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5598 5599 EmulateInstruction::Context context; 5600 context.type = eContextRegisterStore; 5601 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 5602 address - base_address); 5603 5604 uint32_t data = 5605 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 5606 if (!success) 5607 return false; 5608 5609 data = Bits32(data, 7, 0); 5610 5611 if (!MemUWrite(context, address, data, 1)) 5612 return false; 5613 5614 // if wback then R[n] = offset_addr; 5615 if (wback) { 5616 context.type = eContextRegisterLoad; 5617 context.SetAddress(offset_addr); 5618 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5619 offset_addr)) 5620 return false; 5621 } 5622 } 5623 5624 return true; 5625} 5626 5627// STRH (register) calculates an address from a base register value and an 5628// offset register value, and stores a 5629// halfword from a register to memory. The offset register value can be 5630// shifted left by 0, 1, 2, or 3 bits. 5631bool EmulateInstructionARM::EmulateSTRHRegister(const uint32_t opcode, 5632 const ARMEncoding encoding) { 5633#if 0 5634 if ConditionPassed() then 5635 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5636 offset = Shift(R[m], shift_t, shift_n, APSR.C); 5637 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5638 address = if index then offset_addr else R[n]; 5639 if UnalignedSupport() || address<0> == '0' then 5640 MemU[address,2] = R[t]<15:0>; 5641 else // Can only occur before ARMv7 5642 MemU[address,2] = bits(16) UNKNOWN; 5643 if wback then R[n] = offset_addr; 5644#endif 5645 5646 bool success = false; 5647 5648 if (ConditionPassed(opcode)) { 5649 uint32_t t; 5650 uint32_t n; 5651 uint32_t m; 5652 bool index; 5653 bool add; 5654 bool wback; 5655 ARM_ShifterType shift_t; 5656 uint32_t shift_n; 5657 5658 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 5659 switch (encoding) { 5660 case eEncodingT1: 5661 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 5662 // in ThumbEE"; 5663 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5664 t = Bits32(opcode, 2, 0); 5665 n = Bits32(opcode, 5, 3); 5666 m = Bits32(opcode, 8, 6); 5667 5668 // index = TRUE; add = TRUE; wback = FALSE; 5669 index = true; 5670 add = true; 5671 wback = false; 5672 5673 // (shift_t, shift_n) = (SRType_LSL, 0); 5674 shift_t = SRType_LSL; 5675 shift_n = 0; 5676 5677 break; 5678 5679 case eEncodingT2: 5680 // if Rn == '1111' then UNDEFINED; 5681 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5682 t = Bits32(opcode, 15, 12); 5683 n = Bits32(opcode, 19, 16); 5684 m = Bits32(opcode, 3, 0); 5685 if (n == 15) 5686 return false; 5687 5688 // index = TRUE; add = TRUE; wback = FALSE; 5689 index = true; 5690 add = true; 5691 wback = false; 5692 5693 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 5694 shift_t = SRType_LSL; 5695 shift_n = Bits32(opcode, 5, 4); 5696 5697 // if BadReg(t) || BadReg(m) then UNPREDICTABLE; 5698 if (BadReg(t) || BadReg(m)) 5699 return false; 5700 5701 break; 5702 5703 case eEncodingA1: 5704 // if P == '0' && W == '1' then SEE STRHT; 5705 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 5706 t = Bits32(opcode, 15, 12); 5707 n = Bits32(opcode, 19, 16); 5708 m = Bits32(opcode, 3, 0); 5709 5710 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 5711 // (W == '1'); 5712 index = BitIsSet(opcode, 24); 5713 add = BitIsSet(opcode, 23); 5714 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 5715 5716 // (shift_t, shift_n) = (SRType_LSL, 0); 5717 shift_t = SRType_LSL; 5718 shift_n = 0; 5719 5720 // if t == 15 || m == 15 then UNPREDICTABLE; 5721 if ((t == 15) || (m == 15)) 5722 return false; 5723 5724 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 5725 if (wback && ((n == 15) || (n == t))) 5726 return false; 5727 5728 break; 5729 5730 default: 5731 return false; 5732 } 5733 5734 uint32_t Rm = ReadCoreReg(m, &success); 5735 if (!success) 5736 return false; 5737 5738 uint32_t Rn = ReadCoreReg(n, &success); 5739 if (!success) 5740 return false; 5741 5742 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 5743 uint32_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 5744 if (!success) 5745 return false; 5746 5747 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 5748 addr_t offset_addr; 5749 if (add) 5750 offset_addr = Rn + offset; 5751 else 5752 offset_addr = Rn - offset; 5753 5754 // address = if index then offset_addr else R[n]; 5755 addr_t address; 5756 if (index) 5757 address = offset_addr; 5758 else 5759 address = Rn; 5760 5761 EmulateInstruction::Context context; 5762 context.type = eContextRegisterStore; 5763 RegisterInfo base_reg; 5764 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5765 RegisterInfo offset_reg; 5766 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5767 5768 // if UnalignedSupport() || address<0> == '0' then 5769 if (UnalignedSupport() || BitIsClear(address, 0)) { 5770 // MemU[address,2] = R[t]<15:0>; 5771 uint32_t Rt = ReadCoreReg(t, &success); 5772 if (!success) 5773 return false; 5774 5775 EmulateInstruction::Context context; 5776 context.type = eContextRegisterStore; 5777 RegisterInfo base_reg; 5778 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 5779 RegisterInfo offset_reg; 5780 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 5781 RegisterInfo data_reg; 5782 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 5783 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 5784 data_reg); 5785 5786 if (!MemUWrite(context, address, Bits32(Rt, 15, 0), 2)) 5787 return false; 5788 } else // Can only occur before ARMv7 5789 { 5790 // MemU[address,2] = bits(16) UNKNOWN; 5791 } 5792 5793 // if wback then R[n] = offset_addr; 5794 if (wback) { 5795 context.type = eContextAdjustBaseRegister; 5796 context.SetAddress(offset_addr); 5797 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 5798 offset_addr)) 5799 return false; 5800 } 5801 } 5802 5803 return true; 5804} 5805 5806// Add with Carry (immediate) adds an immediate value and the carry flag value 5807// to a register value, and writes the result to the destination register. It 5808// can optionally update the condition flags based on the result. 5809bool EmulateInstructionARM::EmulateADCImm(const uint32_t opcode, 5810 const ARMEncoding encoding) { 5811#if 0 5812 // ARM pseudo code... 5813 if ConditionPassed() then 5814 EncodingSpecificOperations(); 5815 (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C); 5816 if d == 15 then // Can only occur for ARM encoding 5817 ALUWritePC(result); // setflags is always FALSE here 5818 else 5819 R[d] = result; 5820 if setflags then 5821 APSR.N = result<31>; 5822 APSR.Z = IsZeroBit(result); 5823 APSR.C = carry; 5824 APSR.V = overflow; 5825#endif 5826 5827 bool success = false; 5828 5829 if (ConditionPassed(opcode)) { 5830 uint32_t Rd, Rn; 5831 uint32_t 5832 imm32; // the immediate value to be added to the value obtained from Rn 5833 bool setflags; 5834 switch (encoding) { 5835 case eEncodingT1: 5836 Rd = Bits32(opcode, 11, 8); 5837 Rn = Bits32(opcode, 19, 16); 5838 setflags = BitIsSet(opcode, 20); 5839 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 5840 if (BadReg(Rd) || BadReg(Rn)) 5841 return false; 5842 break; 5843 case eEncodingA1: 5844 Rd = Bits32(opcode, 15, 12); 5845 Rn = Bits32(opcode, 19, 16); 5846 setflags = BitIsSet(opcode, 20); 5847 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 5848 5849 if (Rd == 15 && setflags) 5850 return EmulateSUBSPcLrEtc(opcode, encoding); 5851 break; 5852 default: 5853 return false; 5854 } 5855 5856 // Read the first operand. 5857 int32_t val1 = ReadCoreReg(Rn, &success); 5858 if (!success) 5859 return false; 5860 5861 AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C); 5862 5863 EmulateInstruction::Context context; 5864 context.type = EmulateInstruction::eContextImmediate; 5865 context.SetNoArgs(); 5866 5867 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5868 res.carry_out, res.overflow)) 5869 return false; 5870 } 5871 return true; 5872} 5873 5874// Add with Carry (register) adds a register value, the carry flag value, and 5875// an optionally-shifted register value, and writes the result to the 5876// destination register. It can optionally update the condition flags based on 5877// the result. 5878bool EmulateInstructionARM::EmulateADCReg(const uint32_t opcode, 5879 const ARMEncoding encoding) { 5880#if 0 5881 // ARM pseudo code... 5882 if ConditionPassed() then 5883 EncodingSpecificOperations(); 5884 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 5885 (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C); 5886 if d == 15 then // Can only occur for ARM encoding 5887 ALUWritePC(result); // setflags is always FALSE here 5888 else 5889 R[d] = result; 5890 if setflags then 5891 APSR.N = result<31>; 5892 APSR.Z = IsZeroBit(result); 5893 APSR.C = carry; 5894 APSR.V = overflow; 5895#endif 5896 5897 bool success = false; 5898 5899 if (ConditionPassed(opcode)) { 5900 uint32_t Rd, Rn, Rm; 5901 ARM_ShifterType shift_t; 5902 uint32_t shift_n; // the shift applied to the value read from Rm 5903 bool setflags; 5904 switch (encoding) { 5905 case eEncodingT1: 5906 Rd = Rn = Bits32(opcode, 2, 0); 5907 Rm = Bits32(opcode, 5, 3); 5908 setflags = !InITBlock(); 5909 shift_t = SRType_LSL; 5910 shift_n = 0; 5911 break; 5912 case eEncodingT2: 5913 Rd = Bits32(opcode, 11, 8); 5914 Rn = Bits32(opcode, 19, 16); 5915 Rm = Bits32(opcode, 3, 0); 5916 setflags = BitIsSet(opcode, 20); 5917 shift_n = DecodeImmShiftThumb(opcode, shift_t); 5918 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 5919 return false; 5920 break; 5921 case eEncodingA1: 5922 Rd = Bits32(opcode, 15, 12); 5923 Rn = Bits32(opcode, 19, 16); 5924 Rm = Bits32(opcode, 3, 0); 5925 setflags = BitIsSet(opcode, 20); 5926 shift_n = DecodeImmShiftARM(opcode, shift_t); 5927 5928 if (Rd == 15 && setflags) 5929 return EmulateSUBSPcLrEtc(opcode, encoding); 5930 break; 5931 default: 5932 return false; 5933 } 5934 5935 // Read the first operand. 5936 int32_t val1 = ReadCoreReg(Rn, &success); 5937 if (!success) 5938 return false; 5939 5940 // Read the second operand. 5941 int32_t val2 = ReadCoreReg(Rm, &success); 5942 if (!success) 5943 return false; 5944 5945 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 5946 if (!success) 5947 return false; 5948 AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C); 5949 5950 EmulateInstruction::Context context; 5951 context.type = EmulateInstruction::eContextImmediate; 5952 context.SetNoArgs(); 5953 5954 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 5955 res.carry_out, res.overflow)) 5956 return false; 5957 } 5958 return true; 5959} 5960 5961// This instruction adds an immediate value to the PC value to form a PC- 5962// relative address, and writes the result to the destination register. 5963bool EmulateInstructionARM::EmulateADR(const uint32_t opcode, 5964 const ARMEncoding encoding) { 5965#if 0 5966 // ARM pseudo code... 5967 if ConditionPassed() then 5968 EncodingSpecificOperations(); 5969 result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32); 5970 if d == 15 then // Can only occur for ARM encodings 5971 ALUWritePC(result); 5972 else 5973 R[d] = result; 5974#endif 5975 5976 bool success = false; 5977 5978 if (ConditionPassed(opcode)) { 5979 uint32_t Rd; 5980 uint32_t imm32; // the immediate value to be added/subtracted to/from the PC 5981 bool add; 5982 switch (encoding) { 5983 case eEncodingT1: 5984 Rd = Bits32(opcode, 10, 8); 5985 imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32) 5986 add = true; 5987 break; 5988 case eEncodingT2: 5989 case eEncodingT3: 5990 Rd = Bits32(opcode, 11, 8); 5991 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 5992 add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB 5993 if (BadReg(Rd)) 5994 return false; 5995 break; 5996 case eEncodingA1: 5997 case eEncodingA2: 5998 Rd = Bits32(opcode, 15, 12); 5999 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 6000 add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB 6001 break; 6002 default: 6003 return false; 6004 } 6005 6006 // Read the PC value. 6007 uint32_t pc = ReadCoreReg(PC_REG, &success); 6008 if (!success) 6009 return false; 6010 6011 uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32); 6012 6013 EmulateInstruction::Context context; 6014 context.type = EmulateInstruction::eContextImmediate; 6015 context.SetNoArgs(); 6016 6017 if (!WriteCoreReg(context, result, Rd)) 6018 return false; 6019 } 6020 return true; 6021} 6022 6023// This instruction performs a bitwise AND of a register value and an immediate 6024// value, and writes the result to the destination register. It can optionally 6025// update the condition flags based on the result. 6026bool EmulateInstructionARM::EmulateANDImm(const uint32_t opcode, 6027 const ARMEncoding encoding) { 6028#if 0 6029 // ARM pseudo code... 6030 if ConditionPassed() then 6031 EncodingSpecificOperations(); 6032 result = R[n] AND imm32; 6033 if d == 15 then // Can only occur for ARM encoding 6034 ALUWritePC(result); // setflags is always FALSE here 6035 else 6036 R[d] = result; 6037 if setflags then 6038 APSR.N = result<31>; 6039 APSR.Z = IsZeroBit(result); 6040 APSR.C = carry; 6041 // APSR.V unchanged 6042#endif 6043 6044 bool success = false; 6045 6046 if (ConditionPassed(opcode)) { 6047 uint32_t Rd, Rn; 6048 uint32_t 6049 imm32; // the immediate value to be ANDed to the value obtained from Rn 6050 bool setflags; 6051 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6052 switch (encoding) { 6053 case eEncodingT1: 6054 Rd = Bits32(opcode, 11, 8); 6055 Rn = Bits32(opcode, 19, 16); 6056 setflags = BitIsSet(opcode, 20); 6057 imm32 = ThumbExpandImm_C( 6058 opcode, APSR_C, 6059 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6060 // if Rd == '1111' && S == '1' then SEE TST (immediate); 6061 if (Rd == 15 && setflags) 6062 return EmulateTSTImm(opcode, eEncodingT1); 6063 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 6064 return false; 6065 break; 6066 case eEncodingA1: 6067 Rd = Bits32(opcode, 15, 12); 6068 Rn = Bits32(opcode, 19, 16); 6069 setflags = BitIsSet(opcode, 20); 6070 imm32 = 6071 ARMExpandImm_C(opcode, APSR_C, 6072 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6073 6074 if (Rd == 15 && setflags) 6075 return EmulateSUBSPcLrEtc(opcode, encoding); 6076 break; 6077 default: 6078 return false; 6079 } 6080 6081 // Read the first operand. 6082 uint32_t val1 = ReadCoreReg(Rn, &success); 6083 if (!success) 6084 return false; 6085 6086 uint32_t result = val1 & imm32; 6087 6088 EmulateInstruction::Context context; 6089 context.type = EmulateInstruction::eContextImmediate; 6090 context.SetNoArgs(); 6091 6092 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6093 return false; 6094 } 6095 return true; 6096} 6097 6098// This instruction performs a bitwise AND of a register value and an 6099// optionally-shifted register value, and writes the result to the destination 6100// register. It can optionally update the condition flags based on the result. 6101bool EmulateInstructionARM::EmulateANDReg(const uint32_t opcode, 6102 const ARMEncoding encoding) { 6103#if 0 6104 // ARM pseudo code... 6105 if ConditionPassed() then 6106 EncodingSpecificOperations(); 6107 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6108 result = R[n] AND shifted; 6109 if d == 15 then // Can only occur for ARM encoding 6110 ALUWritePC(result); // setflags is always FALSE here 6111 else 6112 R[d] = result; 6113 if setflags then 6114 APSR.N = result<31>; 6115 APSR.Z = IsZeroBit(result); 6116 APSR.C = carry; 6117 // APSR.V unchanged 6118#endif 6119 6120 bool success = false; 6121 6122 if (ConditionPassed(opcode)) { 6123 uint32_t Rd, Rn, Rm; 6124 ARM_ShifterType shift_t; 6125 uint32_t shift_n; // the shift applied to the value read from Rm 6126 bool setflags; 6127 uint32_t carry; 6128 switch (encoding) { 6129 case eEncodingT1: 6130 Rd = Rn = Bits32(opcode, 2, 0); 6131 Rm = Bits32(opcode, 5, 3); 6132 setflags = !InITBlock(); 6133 shift_t = SRType_LSL; 6134 shift_n = 0; 6135 break; 6136 case eEncodingT2: 6137 Rd = Bits32(opcode, 11, 8); 6138 Rn = Bits32(opcode, 19, 16); 6139 Rm = Bits32(opcode, 3, 0); 6140 setflags = BitIsSet(opcode, 20); 6141 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6142 // if Rd == '1111' && S == '1' then SEE TST (register); 6143 if (Rd == 15 && setflags) 6144 return EmulateTSTReg(opcode, eEncodingT2); 6145 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 6146 return false; 6147 break; 6148 case eEncodingA1: 6149 Rd = Bits32(opcode, 15, 12); 6150 Rn = Bits32(opcode, 19, 16); 6151 Rm = Bits32(opcode, 3, 0); 6152 setflags = BitIsSet(opcode, 20); 6153 shift_n = DecodeImmShiftARM(opcode, shift_t); 6154 6155 if (Rd == 15 && setflags) 6156 return EmulateSUBSPcLrEtc(opcode, encoding); 6157 break; 6158 default: 6159 return false; 6160 } 6161 6162 // Read the first operand. 6163 uint32_t val1 = ReadCoreReg(Rn, &success); 6164 if (!success) 6165 return false; 6166 6167 // Read the second operand. 6168 uint32_t val2 = ReadCoreReg(Rm, &success); 6169 if (!success) 6170 return false; 6171 6172 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6173 if (!success) 6174 return false; 6175 uint32_t result = val1 & shifted; 6176 6177 EmulateInstruction::Context context; 6178 context.type = EmulateInstruction::eContextImmediate; 6179 context.SetNoArgs(); 6180 6181 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6182 return false; 6183 } 6184 return true; 6185} 6186 6187// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and 6188// the complement of an immediate value, and writes the result to the 6189// destination register. It can optionally update the condition flags based on 6190// the result. 6191bool EmulateInstructionARM::EmulateBICImm(const uint32_t opcode, 6192 const ARMEncoding encoding) { 6193#if 0 6194 // ARM pseudo code... 6195 if ConditionPassed() then 6196 EncodingSpecificOperations(); 6197 result = R[n] AND NOT(imm32); 6198 if d == 15 then // Can only occur for ARM encoding 6199 ALUWritePC(result); // setflags is always FALSE here 6200 else 6201 R[d] = result; 6202 if setflags then 6203 APSR.N = result<31>; 6204 APSR.Z = IsZeroBit(result); 6205 APSR.C = carry; 6206 // APSR.V unchanged 6207#endif 6208 6209 bool success = false; 6210 6211 if (ConditionPassed(opcode)) { 6212 uint32_t Rd, Rn; 6213 uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to 6214 // the value obtained from Rn 6215 bool setflags; 6216 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 6217 switch (encoding) { 6218 case eEncodingT1: 6219 Rd = Bits32(opcode, 11, 8); 6220 Rn = Bits32(opcode, 19, 16); 6221 setflags = BitIsSet(opcode, 20); 6222 imm32 = ThumbExpandImm_C( 6223 opcode, APSR_C, 6224 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 6225 if (BadReg(Rd) || BadReg(Rn)) 6226 return false; 6227 break; 6228 case eEncodingA1: 6229 Rd = Bits32(opcode, 15, 12); 6230 Rn = Bits32(opcode, 19, 16); 6231 setflags = BitIsSet(opcode, 20); 6232 imm32 = 6233 ARMExpandImm_C(opcode, APSR_C, 6234 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 6235 6236 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6237 // instructions; 6238 if (Rd == 15 && setflags) 6239 return EmulateSUBSPcLrEtc(opcode, encoding); 6240 break; 6241 default: 6242 return false; 6243 } 6244 6245 // Read the first operand. 6246 uint32_t val1 = ReadCoreReg(Rn, &success); 6247 if (!success) 6248 return false; 6249 6250 uint32_t result = val1 & ~imm32; 6251 6252 EmulateInstruction::Context context; 6253 context.type = EmulateInstruction::eContextImmediate; 6254 context.SetNoArgs(); 6255 6256 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6257 return false; 6258 } 6259 return true; 6260} 6261 6262// Bitwise Bit Clear (register) performs a bitwise AND of a register value and 6263// the complement of an optionally-shifted register value, and writes the 6264// result to the destination register. It can optionally update the condition 6265// flags based on the result. 6266bool EmulateInstructionARM::EmulateBICReg(const uint32_t opcode, 6267 const ARMEncoding encoding) { 6268#if 0 6269 // ARM pseudo code... 6270 if ConditionPassed() then 6271 EncodingSpecificOperations(); 6272 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 6273 result = R[n] AND NOT(shifted); 6274 if d == 15 then // Can only occur for ARM encoding 6275 ALUWritePC(result); // setflags is always FALSE here 6276 else 6277 R[d] = result; 6278 if setflags then 6279 APSR.N = result<31>; 6280 APSR.Z = IsZeroBit(result); 6281 APSR.C = carry; 6282 // APSR.V unchanged 6283#endif 6284 6285 bool success = false; 6286 6287 if (ConditionPassed(opcode)) { 6288 uint32_t Rd, Rn, Rm; 6289 ARM_ShifterType shift_t; 6290 uint32_t shift_n; // the shift applied to the value read from Rm 6291 bool setflags; 6292 uint32_t carry; 6293 switch (encoding) { 6294 case eEncodingT1: 6295 Rd = Rn = Bits32(opcode, 2, 0); 6296 Rm = Bits32(opcode, 5, 3); 6297 setflags = !InITBlock(); 6298 shift_t = SRType_LSL; 6299 shift_n = 0; 6300 break; 6301 case eEncodingT2: 6302 Rd = Bits32(opcode, 11, 8); 6303 Rn = Bits32(opcode, 19, 16); 6304 Rm = Bits32(opcode, 3, 0); 6305 setflags = BitIsSet(opcode, 20); 6306 shift_n = DecodeImmShiftThumb(opcode, shift_t); 6307 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 6308 return false; 6309 break; 6310 case eEncodingA1: 6311 Rd = Bits32(opcode, 15, 12); 6312 Rn = Bits32(opcode, 19, 16); 6313 Rm = Bits32(opcode, 3, 0); 6314 setflags = BitIsSet(opcode, 20); 6315 shift_n = DecodeImmShiftARM(opcode, shift_t); 6316 6317 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 6318 // instructions; 6319 if (Rd == 15 && setflags) 6320 return EmulateSUBSPcLrEtc(opcode, encoding); 6321 break; 6322 default: 6323 return false; 6324 } 6325 6326 // Read the first operand. 6327 uint32_t val1 = ReadCoreReg(Rn, &success); 6328 if (!success) 6329 return false; 6330 6331 // Read the second operand. 6332 uint32_t val2 = ReadCoreReg(Rm, &success); 6333 if (!success) 6334 return false; 6335 6336 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 6337 if (!success) 6338 return false; 6339 uint32_t result = val1 & ~shifted; 6340 6341 EmulateInstruction::Context context; 6342 context.type = EmulateInstruction::eContextImmediate; 6343 context.SetNoArgs(); 6344 6345 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 6346 return false; 6347 } 6348 return true; 6349} 6350 6351// LDR (immediate, ARM) calculates an address from a base register value and an 6352// immediate offset, loads a word 6353// from memory, and writes it to a register. It can use offset, post-indexed, 6354// or pre-indexed addressing. 6355bool EmulateInstructionARM::EmulateLDRImmediateARM(const uint32_t opcode, 6356 const ARMEncoding encoding) { 6357#if 0 6358 if ConditionPassed() then 6359 EncodingSpecificOperations(); 6360 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6361 address = if index then offset_addr else R[n]; 6362 data = MemU[address,4]; 6363 if wback then R[n] = offset_addr; 6364 if t == 15 then 6365 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6366 elsif UnalignedSupport() || address<1:0> = '00' then 6367 R[t] = data; 6368 else // Can only apply before ARMv7 6369 R[t] = ROR(data, 8*UInt(address<1:0>)); 6370#endif 6371 6372 bool success = false; 6373 6374 if (ConditionPassed(opcode)) { 6375 const uint32_t addr_byte_size = GetAddressByteSize(); 6376 6377 uint32_t t; 6378 uint32_t n; 6379 uint32_t imm32; 6380 bool index; 6381 bool add; 6382 bool wback; 6383 6384 switch (encoding) { 6385 case eEncodingA1: 6386 // if Rn == '1111' then SEE LDR (literal); 6387 // if P == '0' && W == '1' then SEE LDRT; 6388 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == 6389 // '000000000100' then SEE POP; 6390 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6391 t = Bits32(opcode, 15, 12); 6392 n = Bits32(opcode, 19, 16); 6393 imm32 = Bits32(opcode, 11, 0); 6394 6395 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6396 // (W == '1'); 6397 index = BitIsSet(opcode, 24); 6398 add = BitIsSet(opcode, 23); 6399 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6400 6401 // if wback && n == t then UNPREDICTABLE; 6402 if (wback && (n == t)) 6403 return false; 6404 6405 break; 6406 6407 default: 6408 return false; 6409 } 6410 6411 addr_t address; 6412 addr_t offset_addr; 6413 addr_t base_address = ReadCoreReg(n, &success); 6414 if (!success) 6415 return false; 6416 6417 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6418 if (add) 6419 offset_addr = base_address + imm32; 6420 else 6421 offset_addr = base_address - imm32; 6422 6423 // address = if index then offset_addr else R[n]; 6424 if (index) 6425 address = offset_addr; 6426 else 6427 address = base_address; 6428 6429 // data = MemU[address,4]; 6430 6431 RegisterInfo base_reg; 6432 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6433 6434 EmulateInstruction::Context context; 6435 context.type = eContextRegisterLoad; 6436 context.SetRegisterPlusOffset(base_reg, address - base_address); 6437 6438 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6439 if (!success) 6440 return false; 6441 6442 // if wback then R[n] = offset_addr; 6443 if (wback) { 6444 context.type = eContextAdjustBaseRegister; 6445 context.SetAddress(offset_addr); 6446 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6447 offset_addr)) 6448 return false; 6449 } 6450 6451 // if t == 15 then 6452 if (t == 15) { 6453 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6454 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6455 // LoadWritePC (data); 6456 context.type = eContextRegisterLoad; 6457 context.SetRegisterPlusOffset(base_reg, address - base_address); 6458 LoadWritePC(context, data); 6459 } else 6460 return false; 6461 } 6462 // elsif UnalignedSupport() || address<1:0> = '00' then 6463 else if (UnalignedSupport() || 6464 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6465 // R[t] = data; 6466 context.type = eContextRegisterLoad; 6467 context.SetRegisterPlusOffset(base_reg, address - base_address); 6468 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6469 data)) 6470 return false; 6471 } 6472 // else // Can only apply before ARMv7 6473 else { 6474 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6475 data = ROR(data, Bits32(address, 1, 0), &success); 6476 if (!success) 6477 return false; 6478 context.type = eContextRegisterLoad; 6479 context.SetImmediate(data); 6480 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6481 data)) 6482 return false; 6483 } 6484 } 6485 return true; 6486} 6487 6488// LDR (register) calculates an address from a base register value and an offset 6489// register value, loads a word 6490// from memory, and writes it to a register. The offset register value can 6491// optionally be shifted. 6492bool EmulateInstructionARM::EmulateLDRRegister(const uint32_t opcode, 6493 const ARMEncoding encoding) { 6494#if 0 6495 if ConditionPassed() then 6496 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6497 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6498 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6499 address = if index then offset_addr else R[n]; 6500 data = MemU[address,4]; 6501 if wback then R[n] = offset_addr; 6502 if t == 15 then 6503 if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6504 elsif UnalignedSupport() || address<1:0> = '00' then 6505 R[t] = data; 6506 else // Can only apply before ARMv7 6507 if CurrentInstrSet() == InstrSet_ARM then 6508 R[t] = ROR(data, 8*UInt(address<1:0>)); 6509 else 6510 R[t] = bits(32) UNKNOWN; 6511#endif 6512 6513 bool success = false; 6514 6515 if (ConditionPassed(opcode)) { 6516 const uint32_t addr_byte_size = GetAddressByteSize(); 6517 6518 uint32_t t; 6519 uint32_t n; 6520 uint32_t m; 6521 bool index; 6522 bool add; 6523 bool wback; 6524 ARM_ShifterType shift_t; 6525 uint32_t shift_n; 6526 6527 switch (encoding) { 6528 case eEncodingT1: 6529 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 6530 // in ThumbEE"; 6531 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6532 t = Bits32(opcode, 2, 0); 6533 n = Bits32(opcode, 5, 3); 6534 m = Bits32(opcode, 8, 6); 6535 6536 // index = TRUE; add = TRUE; wback = FALSE; 6537 index = true; 6538 add = true; 6539 wback = false; 6540 6541 // (shift_t, shift_n) = (SRType_LSL, 0); 6542 shift_t = SRType_LSL; 6543 shift_n = 0; 6544 6545 break; 6546 6547 case eEncodingT2: 6548 // if Rn == '1111' then SEE LDR (literal); 6549 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6550 t = Bits32(opcode, 15, 12); 6551 n = Bits32(opcode, 19, 16); 6552 m = Bits32(opcode, 3, 0); 6553 6554 // index = TRUE; add = TRUE; wback = FALSE; 6555 index = true; 6556 add = true; 6557 wback = false; 6558 6559 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6560 shift_t = SRType_LSL; 6561 shift_n = Bits32(opcode, 5, 4); 6562 6563 // if BadReg(m) then UNPREDICTABLE; 6564 if (BadReg(m)) 6565 return false; 6566 6567 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; 6568 if ((t == 15) && InITBlock() && !LastInITBlock()) 6569 return false; 6570 6571 break; 6572 6573 case eEncodingA1: { 6574 // if P == '0' && W == '1' then SEE LDRT; 6575 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6576 t = Bits32(opcode, 15, 12); 6577 n = Bits32(opcode, 19, 16); 6578 m = Bits32(opcode, 3, 0); 6579 6580 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 6581 // (W == '1'); 6582 index = BitIsSet(opcode, 24); 6583 add = BitIsSet(opcode, 23); 6584 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 6585 6586 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 6587 uint32_t type = Bits32(opcode, 6, 5); 6588 uint32_t imm5 = Bits32(opcode, 11, 7); 6589 shift_n = DecodeImmShift(type, imm5, shift_t); 6590 6591 // if m == 15 then UNPREDICTABLE; 6592 if (m == 15) 6593 return false; 6594 6595 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 6596 if (wback && ((n == 15) || (n == t))) 6597 return false; 6598 } break; 6599 6600 default: 6601 return false; 6602 } 6603 6604 uint32_t Rm = 6605 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 6606 if (!success) 6607 return false; 6608 6609 uint32_t Rn = 6610 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6611 if (!success) 6612 return false; 6613 6614 addr_t offset_addr; 6615 addr_t address; 6616 6617 // offset = Shift(R[m], shift_t, shift_n, APSR.C); -- Note "The APSR is 6618 // an application level alias for the CPSR". 6619 addr_t offset = 6620 Shift(Rm, shift_t, shift_n, Bit32(m_opcode_cpsr, APSR_C), &success); 6621 if (!success) 6622 return false; 6623 6624 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6625 if (add) 6626 offset_addr = Rn + offset; 6627 else 6628 offset_addr = Rn - offset; 6629 6630 // address = if index then offset_addr else R[n]; 6631 if (index) 6632 address = offset_addr; 6633 else 6634 address = Rn; 6635 6636 // data = MemU[address,4]; 6637 RegisterInfo base_reg; 6638 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6639 6640 EmulateInstruction::Context context; 6641 context.type = eContextRegisterLoad; 6642 context.SetRegisterPlusOffset(base_reg, address - Rn); 6643 6644 uint64_t data = MemURead(context, address, addr_byte_size, 0, &success); 6645 if (!success) 6646 return false; 6647 6648 // if wback then R[n] = offset_addr; 6649 if (wback) { 6650 context.type = eContextAdjustBaseRegister; 6651 context.SetAddress(offset_addr); 6652 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6653 offset_addr)) 6654 return false; 6655 } 6656 6657 // if t == 15 then 6658 if (t == 15) { 6659 // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE; 6660 if (BitIsClear(address, 1) && BitIsClear(address, 0)) { 6661 context.type = eContextRegisterLoad; 6662 context.SetRegisterPlusOffset(base_reg, address - Rn); 6663 LoadWritePC(context, data); 6664 } else 6665 return false; 6666 } 6667 // elsif UnalignedSupport() || address<1:0> = '00' then 6668 else if (UnalignedSupport() || 6669 (BitIsClear(address, 1) && BitIsClear(address, 0))) { 6670 // R[t] = data; 6671 context.type = eContextRegisterLoad; 6672 context.SetRegisterPlusOffset(base_reg, address - Rn); 6673 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6674 data)) 6675 return false; 6676 } else // Can only apply before ARMv7 6677 { 6678 // if CurrentInstrSet() == InstrSet_ARM then 6679 if (CurrentInstrSet() == eModeARM) { 6680 // R[t] = ROR(data, 8*UInt(address<1:0>)); 6681 data = ROR(data, Bits32(address, 1, 0), &success); 6682 if (!success) 6683 return false; 6684 context.type = eContextRegisterLoad; 6685 context.SetImmediate(data); 6686 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 6687 data)) 6688 return false; 6689 } else { 6690 // R[t] = bits(32) UNKNOWN; 6691 WriteBits32Unknown(t); 6692 } 6693 } 6694 } 6695 return true; 6696} 6697 6698// LDRB (immediate, Thumb) 6699bool EmulateInstructionARM::EmulateLDRBImmediate(const uint32_t opcode, 6700 const ARMEncoding encoding) { 6701#if 0 6702 if ConditionPassed() then 6703 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6704 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6705 address = if index then offset_addr else R[n]; 6706 R[t] = ZeroExtend(MemU[address,1], 32); 6707 if wback then R[n] = offset_addr; 6708#endif 6709 6710 bool success = false; 6711 6712 if (ConditionPassed(opcode)) { 6713 uint32_t t; 6714 uint32_t n; 6715 uint32_t imm32; 6716 bool index; 6717 bool add; 6718 bool wback; 6719 6720 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6721 switch (encoding) { 6722 case eEncodingT1: 6723 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32); 6724 t = Bits32(opcode, 2, 0); 6725 n = Bits32(opcode, 5, 3); 6726 imm32 = Bits32(opcode, 10, 6); 6727 6728 // index = TRUE; add = TRUE; wback = FALSE; 6729 index = true; 6730 add = true; 6731 wback = false; 6732 6733 break; 6734 6735 case eEncodingT2: 6736 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 6737 t = Bits32(opcode, 15, 12); 6738 n = Bits32(opcode, 19, 16); 6739 imm32 = Bits32(opcode, 11, 0); 6740 6741 // index = TRUE; add = TRUE; wback = FALSE; 6742 index = true; 6743 add = true; 6744 wback = false; 6745 6746 // if Rt == '1111' then SEE PLD; 6747 if (t == 15) 6748 return false; // PLD is not implemented yet 6749 6750 // if Rn == '1111' then SEE LDRB (literal); 6751 if (n == 15) 6752 return EmulateLDRBLiteral(opcode, eEncodingT1); 6753 6754 // if t == 13 then UNPREDICTABLE; 6755 if (t == 13) 6756 return false; 6757 6758 break; 6759 6760 case eEncodingT3: 6761 // if P == '1' && U == '1' && W == '0' then SEE LDRBT; 6762 // if P == '0' && W == '0' then UNDEFINED; 6763 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 6764 return false; 6765 6766 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 6767 t = Bits32(opcode, 15, 12); 6768 n = Bits32(opcode, 19, 16); 6769 imm32 = Bits32(opcode, 7, 0); 6770 6771 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 6772 index = BitIsSet(opcode, 10); 6773 add = BitIsSet(opcode, 9); 6774 wback = BitIsSet(opcode, 8); 6775 6776 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD; 6777 if (t == 15) 6778 return false; // PLD is not implemented yet 6779 6780 // if Rn == '1111' then SEE LDRB (literal); 6781 if (n == 15) 6782 return EmulateLDRBLiteral(opcode, eEncodingT1); 6783 6784 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 6785 if (BadReg(t) || (wback && (n == t))) 6786 return false; 6787 6788 break; 6789 6790 default: 6791 return false; 6792 } 6793 6794 uint32_t Rn = 6795 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 6796 if (!success) 6797 return false; 6798 6799 addr_t address; 6800 addr_t offset_addr; 6801 6802 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 6803 if (add) 6804 offset_addr = Rn + imm32; 6805 else 6806 offset_addr = Rn - imm32; 6807 6808 // address = if index then offset_addr else R[n]; 6809 if (index) 6810 address = offset_addr; 6811 else 6812 address = Rn; 6813 6814 // R[t] = ZeroExtend(MemU[address,1], 32); 6815 RegisterInfo base_reg; 6816 RegisterInfo data_reg; 6817 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 6818 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 6819 6820 EmulateInstruction::Context context; 6821 context.type = eContextRegisterLoad; 6822 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 6823 6824 uint64_t data = MemURead(context, address, 1, 0, &success); 6825 if (!success) 6826 return false; 6827 6828 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6829 return false; 6830 6831 // if wback then R[n] = offset_addr; 6832 if (wback) { 6833 context.type = eContextAdjustBaseRegister; 6834 context.SetAddress(offset_addr); 6835 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 6836 offset_addr)) 6837 return false; 6838 } 6839 } 6840 return true; 6841} 6842 6843// LDRB (literal) calculates an address from the PC value and an immediate 6844// offset, loads a byte from memory, 6845// zero-extends it to form a 32-bit word and writes it to a register. 6846bool EmulateInstructionARM::EmulateLDRBLiteral(const uint32_t opcode, 6847 const ARMEncoding encoding) { 6848#if 0 6849 if ConditionPassed() then 6850 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 6851 base = Align(PC,4); 6852 address = if add then (base + imm32) else (base - imm32); 6853 R[t] = ZeroExtend(MemU[address,1], 32); 6854#endif 6855 6856 bool success = false; 6857 6858 if (ConditionPassed(opcode)) { 6859 uint32_t t; 6860 uint32_t imm32; 6861 bool add; 6862 switch (encoding) { 6863 case eEncodingT1: 6864 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6865 t = Bits32(opcode, 15, 12); 6866 imm32 = Bits32(opcode, 11, 0); 6867 add = BitIsSet(opcode, 23); 6868 6869 // if Rt == '1111' then SEE PLD; 6870 if (t == 15) 6871 return false; // PLD is not implemented yet 6872 6873 // if t == 13 then UNPREDICTABLE; 6874 if (t == 13) 6875 return false; 6876 6877 break; 6878 6879 case eEncodingA1: 6880 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 6881 t = Bits32(opcode, 15, 12); 6882 imm32 = Bits32(opcode, 11, 0); 6883 add = BitIsSet(opcode, 23); 6884 6885 // if t == 15 then UNPREDICTABLE; 6886 if (t == 15) 6887 return false; 6888 break; 6889 6890 default: 6891 return false; 6892 } 6893 6894 // base = Align(PC,4); 6895 uint32_t pc_val = ReadCoreReg(PC_REG, &success); 6896 if (!success) 6897 return false; 6898 6899 uint32_t base = AlignPC(pc_val); 6900 6901 addr_t address; 6902 // address = if add then (base + imm32) else (base - imm32); 6903 if (add) 6904 address = base + imm32; 6905 else 6906 address = base - imm32; 6907 6908 // R[t] = ZeroExtend(MemU[address,1], 32); 6909 EmulateInstruction::Context context; 6910 context.type = eContextRelativeBranchImmediate; 6911 context.SetImmediate(address - base); 6912 6913 uint64_t data = MemURead(context, address, 1, 0, &success); 6914 if (!success) 6915 return false; 6916 6917 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 6918 return false; 6919 } 6920 return true; 6921} 6922 6923// LDRB (register) calculates an address from a base register value and an 6924// offset rigister value, loads a byte from memory, zero-extends it to form a 6925// 32-bit word, and writes it to a register. The offset register value can 6926// optionally be shifted. 6927bool EmulateInstructionARM::EmulateLDRBRegister(const uint32_t opcode, 6928 const ARMEncoding encoding) { 6929#if 0 6930 if ConditionPassed() then 6931 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6932 offset = Shift(R[m], shift_t, shift_n, APSR.C); 6933 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 6934 address = if index then offset_addr else R[n]; 6935 R[t] = ZeroExtend(MemU[address,1],32); 6936 if wback then R[n] = offset_addr; 6937#endif 6938 6939 bool success = false; 6940 6941 if (ConditionPassed(opcode)) { 6942 uint32_t t; 6943 uint32_t n; 6944 uint32_t m; 6945 bool index; 6946 bool add; 6947 bool wback; 6948 ARM_ShifterType shift_t; 6949 uint32_t shift_n; 6950 6951 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 6952 switch (encoding) { 6953 case eEncodingT1: 6954 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6955 t = Bits32(opcode, 2, 0); 6956 n = Bits32(opcode, 5, 3); 6957 m = Bits32(opcode, 8, 6); 6958 6959 // index = TRUE; add = TRUE; wback = FALSE; 6960 index = true; 6961 add = true; 6962 wback = false; 6963 6964 // (shift_t, shift_n) = (SRType_LSL, 0); 6965 shift_t = SRType_LSL; 6966 shift_n = 0; 6967 break; 6968 6969 case eEncodingT2: 6970 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 6971 t = Bits32(opcode, 15, 12); 6972 n = Bits32(opcode, 19, 16); 6973 m = Bits32(opcode, 3, 0); 6974 6975 // index = TRUE; add = TRUE; wback = FALSE; 6976 index = true; 6977 add = true; 6978 wback = false; 6979 6980 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 6981 shift_t = SRType_LSL; 6982 shift_n = Bits32(opcode, 5, 4); 6983 6984 // if Rt == '1111' then SEE PLD; 6985 if (t == 15) 6986 return false; // PLD is not implemented yet 6987 6988 // if Rn == '1111' then SEE LDRB (literal); 6989 if (n == 15) 6990 return EmulateLDRBLiteral(opcode, eEncodingT1); 6991 6992 // if t == 13 || BadReg(m) then UNPREDICTABLE; 6993 if ((t == 13) || BadReg(m)) 6994 return false; 6995 break; 6996 6997 case eEncodingA1: { 6998 // if P == '0' && W == '1' then SEE LDRBT; 6999 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7000 t = Bits32(opcode, 15, 12); 7001 n = Bits32(opcode, 19, 16); 7002 m = Bits32(opcode, 3, 0); 7003 7004 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7005 // (W == '1'); 7006 index = BitIsSet(opcode, 24); 7007 add = BitIsSet(opcode, 23); 7008 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7009 7010 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 7011 uint32_t type = Bits32(opcode, 6, 5); 7012 uint32_t imm5 = Bits32(opcode, 11, 7); 7013 shift_n = DecodeImmShift(type, imm5, shift_t); 7014 7015 // if t == 15 || m == 15 then UNPREDICTABLE; 7016 if ((t == 15) || (m == 15)) 7017 return false; 7018 7019 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7020 if (wback && ((n == 15) || (n == t))) 7021 return false; 7022 } break; 7023 7024 default: 7025 return false; 7026 } 7027 7028 addr_t offset_addr; 7029 addr_t address; 7030 7031 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7032 uint32_t Rm = 7033 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7034 if (!success) 7035 return false; 7036 7037 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7038 if (!success) 7039 return false; 7040 7041 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7042 uint32_t Rn = 7043 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7044 if (!success) 7045 return false; 7046 7047 if (add) 7048 offset_addr = Rn + offset; 7049 else 7050 offset_addr = Rn - offset; 7051 7052 // address = if index then offset_addr else R[n]; 7053 if (index) 7054 address = offset_addr; 7055 else 7056 address = Rn; 7057 7058 // R[t] = ZeroExtend(MemU[address,1],32); 7059 RegisterInfo base_reg; 7060 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7061 7062 EmulateInstruction::Context context; 7063 context.type = eContextRegisterLoad; 7064 context.SetRegisterPlusOffset(base_reg, address - Rn); 7065 7066 uint64_t data = MemURead(context, address, 1, 0, &success); 7067 if (!success) 7068 return false; 7069 7070 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 7071 return false; 7072 7073 // if wback then R[n] = offset_addr; 7074 if (wback) { 7075 context.type = eContextAdjustBaseRegister; 7076 context.SetAddress(offset_addr); 7077 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7078 offset_addr)) 7079 return false; 7080 } 7081 } 7082 return true; 7083} 7084 7085// LDRH (immediate, Thumb) calculates an address from a base register value and 7086// an immediate offset, loads a 7087// halfword from memory, zero-extends it to form a 32-bit word, and writes it 7088// to a register. It can use offset, post-indexed, or pre-indexed addressing. 7089bool EmulateInstructionARM::EmulateLDRHImmediate(const uint32_t opcode, 7090 const ARMEncoding encoding) { 7091#if 0 7092 if ConditionPassed() then 7093 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7094 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7095 address = if index then offset_addr else R[n]; 7096 data = MemU[address,2]; 7097 if wback then R[n] = offset_addr; 7098 if UnalignedSupport() || address<0> = '0' then 7099 R[t] = ZeroExtend(data, 32); 7100 else // Can only apply before ARMv7 7101 R[t] = bits(32) UNKNOWN; 7102#endif 7103 7104 bool success = false; 7105 7106 if (ConditionPassed(opcode)) { 7107 uint32_t t; 7108 uint32_t n; 7109 uint32_t imm32; 7110 bool index; 7111 bool add; 7112 bool wback; 7113 7114 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7115 switch (encoding) { 7116 case eEncodingT1: 7117 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32); 7118 t = Bits32(opcode, 2, 0); 7119 n = Bits32(opcode, 5, 3); 7120 imm32 = Bits32(opcode, 10, 6) << 1; 7121 7122 // index = TRUE; add = TRUE; wback = FALSE; 7123 index = true; 7124 add = true; 7125 wback = false; 7126 7127 break; 7128 7129 case eEncodingT2: 7130 // if Rt == '1111' then SEE "Unallocated memory hints"; 7131 // if Rn == '1111' then SEE LDRH (literal); 7132 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7133 t = Bits32(opcode, 15, 12); 7134 n = Bits32(opcode, 19, 16); 7135 imm32 = Bits32(opcode, 11, 0); 7136 7137 // index = TRUE; add = TRUE; wback = FALSE; 7138 index = true; 7139 add = true; 7140 wback = false; 7141 7142 // if t == 13 then UNPREDICTABLE; 7143 if (t == 13) 7144 return false; 7145 break; 7146 7147 case eEncodingT3: 7148 // if Rn == '1111' then SEE LDRH (literal); 7149 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7150 // "Unallocated memory hints"; 7151 // if P == '1' && U == '1' && W == '0' then SEE LDRHT; 7152 // if P == '0' && W == '0' then UNDEFINED; 7153 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7154 return false; 7155 7156 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7157 t = Bits32(opcode, 15, 12); 7158 n = Bits32(opcode, 19, 16); 7159 imm32 = Bits32(opcode, 7, 0); 7160 7161 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7162 index = BitIsSet(opcode, 10); 7163 add = BitIsSet(opcode, 9); 7164 wback = BitIsSet(opcode, 8); 7165 7166 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7167 if (BadReg(t) || (wback && (n == t))) 7168 return false; 7169 break; 7170 7171 default: 7172 return false; 7173 } 7174 7175 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7176 uint32_t Rn = 7177 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7178 if (!success) 7179 return false; 7180 7181 addr_t offset_addr; 7182 addr_t address; 7183 7184 if (add) 7185 offset_addr = Rn + imm32; 7186 else 7187 offset_addr = Rn - imm32; 7188 7189 // address = if index then offset_addr else R[n]; 7190 if (index) 7191 address = offset_addr; 7192 else 7193 address = Rn; 7194 7195 // data = MemU[address,2]; 7196 RegisterInfo base_reg; 7197 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7198 7199 EmulateInstruction::Context context; 7200 context.type = eContextRegisterLoad; 7201 context.SetRegisterPlusOffset(base_reg, address - Rn); 7202 7203 uint64_t data = MemURead(context, address, 2, 0, &success); 7204 if (!success) 7205 return false; 7206 7207 // if wback then R[n] = offset_addr; 7208 if (wback) { 7209 context.type = eContextAdjustBaseRegister; 7210 context.SetAddress(offset_addr); 7211 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7212 offset_addr)) 7213 return false; 7214 } 7215 7216 // if UnalignedSupport() || address<0> = '0' then 7217 if (UnalignedSupport() || BitIsClear(address, 0)) { 7218 // R[t] = ZeroExtend(data, 32); 7219 context.type = eContextRegisterLoad; 7220 context.SetRegisterPlusOffset(base_reg, address - Rn); 7221 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7222 data)) 7223 return false; 7224 } else // Can only apply before ARMv7 7225 { 7226 // R[t] = bits(32) UNKNOWN; 7227 WriteBits32Unknown(t); 7228 } 7229 } 7230 return true; 7231} 7232 7233// LDRH (literal) caculates an address from the PC value and an immediate 7234// offset, loads a halfword from memory, 7235// zero-extends it to form a 32-bit word, and writes it to a register. 7236bool EmulateInstructionARM::EmulateLDRHLiteral(const uint32_t opcode, 7237 const ARMEncoding encoding) { 7238#if 0 7239 if ConditionPassed() then 7240 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7241 base = Align(PC,4); 7242 address = if add then (base + imm32) else (base - imm32); 7243 data = MemU[address,2]; 7244 if UnalignedSupport() || address<0> = '0' then 7245 R[t] = ZeroExtend(data, 32); 7246 else // Can only apply before ARMv7 7247 R[t] = bits(32) UNKNOWN; 7248#endif 7249 7250 bool success = false; 7251 7252 if (ConditionPassed(opcode)) { 7253 uint32_t t; 7254 uint32_t imm32; 7255 bool add; 7256 7257 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7258 switch (encoding) { 7259 case eEncodingT1: 7260 // if Rt == '1111' then SEE "Unallocated memory hints"; 7261 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7262 t = Bits32(opcode, 15, 12); 7263 imm32 = Bits32(opcode, 11, 0); 7264 add = BitIsSet(opcode, 23); 7265 7266 // if t == 13 then UNPREDICTABLE; 7267 if (t == 13) 7268 return false; 7269 7270 break; 7271 7272 case eEncodingA1: { 7273 uint32_t imm4H = Bits32(opcode, 11, 8); 7274 uint32_t imm4L = Bits32(opcode, 3, 0); 7275 7276 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7277 t = Bits32(opcode, 15, 12); 7278 imm32 = (imm4H << 4) | imm4L; 7279 add = BitIsSet(opcode, 23); 7280 7281 // if t == 15 then UNPREDICTABLE; 7282 if (t == 15) 7283 return false; 7284 break; 7285 } 7286 7287 default: 7288 return false; 7289 } 7290 7291 // base = Align(PC,4); 7292 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7293 if (!success) 7294 return false; 7295 7296 addr_t base = AlignPC(pc_value); 7297 addr_t address; 7298 7299 // address = if add then (base + imm32) else (base - imm32); 7300 if (add) 7301 address = base + imm32; 7302 else 7303 address = base - imm32; 7304 7305 // data = MemU[address,2]; 7306 RegisterInfo base_reg; 7307 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7308 7309 EmulateInstruction::Context context; 7310 context.type = eContextRegisterLoad; 7311 context.SetRegisterPlusOffset(base_reg, address - base); 7312 7313 uint64_t data = MemURead(context, address, 2, 0, &success); 7314 if (!success) 7315 return false; 7316 7317 // if UnalignedSupport() || address<0> = '0' then 7318 if (UnalignedSupport() || BitIsClear(address, 0)) { 7319 // R[t] = ZeroExtend(data, 32); 7320 context.type = eContextRegisterLoad; 7321 context.SetRegisterPlusOffset(base_reg, address - base); 7322 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7323 data)) 7324 return false; 7325 7326 } else // Can only apply before ARMv7 7327 { 7328 // R[t] = bits(32) UNKNOWN; 7329 WriteBits32Unknown(t); 7330 } 7331 } 7332 return true; 7333} 7334 7335// LDRH (literal) calculates an address from a base register value and an offset 7336// register value, loads a halfword 7337// from memory, zero-extends it to form a 32-bit word, and writes it to a 7338// register. The offset register value can be shifted left by 0, 1, 2, or 3 7339// bits. 7340bool EmulateInstructionARM::EmulateLDRHRegister(const uint32_t opcode, 7341 const ARMEncoding encoding) { 7342#if 0 7343 if ConditionPassed() then 7344 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7345 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7346 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7347 address = if index then offset_addr else R[n]; 7348 data = MemU[address,2]; 7349 if wback then R[n] = offset_addr; 7350 if UnalignedSupport() || address<0> = '0' then 7351 R[t] = ZeroExtend(data, 32); 7352 else // Can only apply before ARMv7 7353 R[t] = bits(32) UNKNOWN; 7354#endif 7355 7356 bool success = false; 7357 7358 if (ConditionPassed(opcode)) { 7359 uint32_t t; 7360 uint32_t n; 7361 uint32_t m; 7362 bool index; 7363 bool add; 7364 bool wback; 7365 ARM_ShifterType shift_t; 7366 uint32_t shift_n; 7367 7368 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7369 switch (encoding) { 7370 case eEncodingT1: 7371 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 7372 // in ThumbEE"; 7373 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7374 t = Bits32(opcode, 2, 0); 7375 n = Bits32(opcode, 5, 3); 7376 m = Bits32(opcode, 8, 6); 7377 7378 // index = TRUE; add = TRUE; wback = FALSE; 7379 index = true; 7380 add = true; 7381 wback = false; 7382 7383 // (shift_t, shift_n) = (SRType_LSL, 0); 7384 shift_t = SRType_LSL; 7385 shift_n = 0; 7386 7387 break; 7388 7389 case eEncodingT2: 7390 // if Rn == '1111' then SEE LDRH (literal); 7391 // if Rt == '1111' then SEE "Unallocated memory hints"; 7392 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7393 t = Bits32(opcode, 15, 12); 7394 n = Bits32(opcode, 19, 16); 7395 m = Bits32(opcode, 3, 0); 7396 7397 // index = TRUE; add = TRUE; wback = FALSE; 7398 index = true; 7399 add = true; 7400 wback = false; 7401 7402 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7403 shift_t = SRType_LSL; 7404 shift_n = Bits32(opcode, 5, 4); 7405 7406 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7407 if ((t == 13) || BadReg(m)) 7408 return false; 7409 break; 7410 7411 case eEncodingA1: 7412 // if P == '0' && W == '1' then SEE LDRHT; 7413 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7414 t = Bits32(opcode, 15, 12); 7415 n = Bits32(opcode, 19, 16); 7416 m = Bits32(opcode, 3, 0); 7417 7418 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7419 // (W == '1'); 7420 index = BitIsSet(opcode, 24); 7421 add = BitIsSet(opcode, 23); 7422 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7423 7424 // (shift_t, shift_n) = (SRType_LSL, 0); 7425 shift_t = SRType_LSL; 7426 shift_n = 0; 7427 7428 // if t == 15 || m == 15 then UNPREDICTABLE; 7429 if ((t == 15) || (m == 15)) 7430 return false; 7431 7432 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7433 if (wback && ((n == 15) || (n == t))) 7434 return false; 7435 7436 break; 7437 7438 default: 7439 return false; 7440 } 7441 7442 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7443 7444 uint64_t Rm = 7445 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7446 if (!success) 7447 return false; 7448 7449 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7450 if (!success) 7451 return false; 7452 7453 addr_t offset_addr; 7454 addr_t address; 7455 7456 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7457 uint64_t Rn = 7458 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7459 if (!success) 7460 return false; 7461 7462 if (add) 7463 offset_addr = Rn + offset; 7464 else 7465 offset_addr = Rn - offset; 7466 7467 // address = if index then offset_addr else R[n]; 7468 if (index) 7469 address = offset_addr; 7470 else 7471 address = Rn; 7472 7473 // data = MemU[address,2]; 7474 RegisterInfo base_reg; 7475 RegisterInfo offset_reg; 7476 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7477 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7478 7479 EmulateInstruction::Context context; 7480 context.type = eContextRegisterLoad; 7481 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7482 uint64_t data = MemURead(context, address, 2, 0, &success); 7483 if (!success) 7484 return false; 7485 7486 // if wback then R[n] = offset_addr; 7487 if (wback) { 7488 context.type = eContextAdjustBaseRegister; 7489 context.SetAddress(offset_addr); 7490 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7491 offset_addr)) 7492 return false; 7493 } 7494 7495 // if UnalignedSupport() || address<0> = '0' then 7496 if (UnalignedSupport() || BitIsClear(address, 0)) { 7497 // R[t] = ZeroExtend(data, 32); 7498 context.type = eContextRegisterLoad; 7499 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7500 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7501 data)) 7502 return false; 7503 } else // Can only apply before ARMv7 7504 { 7505 // R[t] = bits(32) UNKNOWN; 7506 WriteBits32Unknown(t); 7507 } 7508 } 7509 return true; 7510} 7511 7512// LDRSB (immediate) calculates an address from a base register value and an 7513// immediate offset, loads a byte from 7514// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7515// It can use offset, post-indexed, or pre-indexed addressing. 7516bool EmulateInstructionARM::EmulateLDRSBImmediate(const uint32_t opcode, 7517 const ARMEncoding encoding) { 7518#if 0 7519 if ConditionPassed() then 7520 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7521 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7522 address = if index then offset_addr else R[n]; 7523 R[t] = SignExtend(MemU[address,1], 32); 7524 if wback then R[n] = offset_addr; 7525#endif 7526 7527 bool success = false; 7528 7529 if (ConditionPassed(opcode)) { 7530 uint32_t t; 7531 uint32_t n; 7532 uint32_t imm32; 7533 bool index; 7534 bool add; 7535 bool wback; 7536 7537 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7538 switch (encoding) { 7539 case eEncodingT1: 7540 // if Rt == '1111' then SEE PLI; 7541 // if Rn == '1111' then SEE LDRSB (literal); 7542 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7543 t = Bits32(opcode, 15, 12); 7544 n = Bits32(opcode, 19, 16); 7545 imm32 = Bits32(opcode, 11, 0); 7546 7547 // index = TRUE; add = TRUE; wback = FALSE; 7548 index = true; 7549 add = true; 7550 wback = false; 7551 7552 // if t == 13 then UNPREDICTABLE; 7553 if (t == 13) 7554 return false; 7555 7556 break; 7557 7558 case eEncodingT2: 7559 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI; 7560 // if Rn == '1111' then SEE LDRSB (literal); 7561 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT; 7562 // if P == '0' && W == '0' then UNDEFINED; 7563 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7564 return false; 7565 7566 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7567 t = Bits32(opcode, 15, 12); 7568 n = Bits32(opcode, 19, 16); 7569 imm32 = Bits32(opcode, 7, 0); 7570 7571 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7572 index = BitIsSet(opcode, 10); 7573 add = BitIsSet(opcode, 9); 7574 wback = BitIsSet(opcode, 8); 7575 7576 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7577 if (((t == 13) || 7578 ((t == 15) && (BitIsClear(opcode, 10) || BitIsSet(opcode, 9) || 7579 BitIsSet(opcode, 8)))) || 7580 (wback && (n == t))) 7581 return false; 7582 7583 break; 7584 7585 case eEncodingA1: { 7586 // if Rn == '1111' then SEE LDRSB (literal); 7587 // if P == '0' && W == '1' then SEE LDRSBT; 7588 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7589 t = Bits32(opcode, 15, 12); 7590 n = Bits32(opcode, 19, 16); 7591 7592 uint32_t imm4H = Bits32(opcode, 11, 8); 7593 uint32_t imm4L = Bits32(opcode, 3, 0); 7594 imm32 = (imm4H << 4) | imm4L; 7595 7596 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7597 // (W == '1'); 7598 index = BitIsSet(opcode, 24); 7599 add = BitIsSet(opcode, 23); 7600 wback = (BitIsClear(opcode, 24) || BitIsSet(opcode, 21)); 7601 7602 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 7603 if ((t == 15) || (wback && (n == t))) 7604 return false; 7605 7606 break; 7607 } 7608 7609 default: 7610 return false; 7611 } 7612 7613 uint64_t Rn = ReadCoreReg(n, &success); 7614 if (!success) 7615 return false; 7616 7617 addr_t offset_addr; 7618 addr_t address; 7619 7620 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7621 if (add) 7622 offset_addr = Rn + imm32; 7623 else 7624 offset_addr = Rn - imm32; 7625 7626 // address = if index then offset_addr else R[n]; 7627 if (index) 7628 address = offset_addr; 7629 else 7630 address = Rn; 7631 7632 // R[t] = SignExtend(MemU[address,1], 32); 7633 RegisterInfo base_reg; 7634 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7635 7636 EmulateInstruction::Context context; 7637 context.type = eContextRegisterLoad; 7638 context.SetRegisterPlusOffset(base_reg, address - Rn); 7639 7640 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7641 if (!success) 7642 return false; 7643 7644 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7645 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7646 (uint64_t)signed_data)) 7647 return false; 7648 7649 // if wback then R[n] = offset_addr; 7650 if (wback) { 7651 context.type = eContextAdjustBaseRegister; 7652 context.SetAddress(offset_addr); 7653 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7654 offset_addr)) 7655 return false; 7656 } 7657 } 7658 7659 return true; 7660} 7661 7662// LDRSB (literal) calculates an address from the PC value and an immediate 7663// offset, loads a byte from memory, 7664// sign-extends it to form a 32-bit word, and writes tit to a register. 7665bool EmulateInstructionARM::EmulateLDRSBLiteral(const uint32_t opcode, 7666 const ARMEncoding encoding) { 7667#if 0 7668 if ConditionPassed() then 7669 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7670 base = Align(PC,4); 7671 address = if add then (base + imm32) else (base - imm32); 7672 R[t] = SignExtend(MemU[address,1], 32); 7673#endif 7674 7675 bool success = false; 7676 7677 if (ConditionPassed(opcode)) { 7678 uint32_t t; 7679 uint32_t imm32; 7680 bool add; 7681 7682 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 7683 switch (encoding) { 7684 case eEncodingT1: 7685 // if Rt == '1111' then SEE PLI; 7686 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 7687 t = Bits32(opcode, 15, 12); 7688 imm32 = Bits32(opcode, 11, 0); 7689 add = BitIsSet(opcode, 23); 7690 7691 // if t == 13 then UNPREDICTABLE; 7692 if (t == 13) 7693 return false; 7694 7695 break; 7696 7697 case eEncodingA1: { 7698 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 7699 t = Bits32(opcode, 15, 12); 7700 uint32_t imm4H = Bits32(opcode, 11, 8); 7701 uint32_t imm4L = Bits32(opcode, 3, 0); 7702 imm32 = (imm4H << 4) | imm4L; 7703 add = BitIsSet(opcode, 23); 7704 7705 // if t == 15 then UNPREDICTABLE; 7706 if (t == 15) 7707 return false; 7708 7709 break; 7710 } 7711 7712 default: 7713 return false; 7714 } 7715 7716 // base = Align(PC,4); 7717 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 7718 if (!success) 7719 return false; 7720 uint64_t base = AlignPC(pc_value); 7721 7722 // address = if add then (base + imm32) else (base - imm32); 7723 addr_t address; 7724 if (add) 7725 address = base + imm32; 7726 else 7727 address = base - imm32; 7728 7729 // R[t] = SignExtend(MemU[address,1], 32); 7730 RegisterInfo base_reg; 7731 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 7732 7733 EmulateInstruction::Context context; 7734 context.type = eContextRegisterLoad; 7735 context.SetRegisterPlusOffset(base_reg, address - base); 7736 7737 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7738 if (!success) 7739 return false; 7740 7741 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7742 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7743 (uint64_t)signed_data)) 7744 return false; 7745 } 7746 return true; 7747} 7748 7749// LDRSB (register) calculates an address from a base register value and an 7750// offset register value, loadsa byte from 7751// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7752// The offset register value can be shifted left by 0, 1, 2, or 3 bits. 7753bool EmulateInstructionARM::EmulateLDRSBRegister(const uint32_t opcode, 7754 const ARMEncoding encoding) { 7755#if 0 7756 if ConditionPassed() then 7757 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7758 offset = Shift(R[m], shift_t, shift_n, APSR.C); 7759 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7760 address = if index then offset_addr else R[n]; 7761 R[t] = SignExtend(MemU[address,1], 32); 7762 if wback then R[n] = offset_addr; 7763#endif 7764 7765 bool success = false; 7766 7767 if (ConditionPassed(opcode)) { 7768 uint32_t t; 7769 uint32_t n; 7770 uint32_t m; 7771 bool index; 7772 bool add; 7773 bool wback; 7774 ARM_ShifterType shift_t; 7775 uint32_t shift_n; 7776 7777 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7778 switch (encoding) { 7779 case eEncodingT1: 7780 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7781 t = Bits32(opcode, 2, 0); 7782 n = Bits32(opcode, 5, 3); 7783 m = Bits32(opcode, 8, 6); 7784 7785 // index = TRUE; add = TRUE; wback = FALSE; 7786 index = true; 7787 add = true; 7788 wback = false; 7789 7790 // (shift_t, shift_n) = (SRType_LSL, 0); 7791 shift_t = SRType_LSL; 7792 shift_n = 0; 7793 7794 break; 7795 7796 case eEncodingT2: 7797 // if Rt == '1111' then SEE PLI; 7798 // if Rn == '1111' then SEE LDRSB (literal); 7799 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7800 t = Bits32(opcode, 15, 12); 7801 n = Bits32(opcode, 19, 16); 7802 m = Bits32(opcode, 3, 0); 7803 7804 // index = TRUE; add = TRUE; wback = FALSE; 7805 index = true; 7806 add = true; 7807 wback = false; 7808 7809 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 7810 shift_t = SRType_LSL; 7811 shift_n = Bits32(opcode, 5, 4); 7812 7813 // if t == 13 || BadReg(m) then UNPREDICTABLE; 7814 if ((t == 13) || BadReg(m)) 7815 return false; 7816 break; 7817 7818 case eEncodingA1: 7819 // if P == '0' && W == '1' then SEE LDRSBT; 7820 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 7821 t = Bits32(opcode, 15, 12); 7822 n = Bits32(opcode, 19, 16); 7823 m = Bits32(opcode, 3, 0); 7824 7825 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7826 // (W == '1'); 7827 index = BitIsSet(opcode, 24); 7828 add = BitIsSet(opcode, 23); 7829 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7830 7831 // (shift_t, shift_n) = (SRType_LSL, 0); 7832 shift_t = SRType_LSL; 7833 shift_n = 0; 7834 7835 // if t == 15 || m == 15 then UNPREDICTABLE; 7836 if ((t == 15) || (m == 15)) 7837 return false; 7838 7839 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 7840 if (wback && ((n == 15) || (n == t))) 7841 return false; 7842 break; 7843 7844 default: 7845 return false; 7846 } 7847 7848 uint64_t Rm = 7849 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 7850 if (!success) 7851 return false; 7852 7853 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 7854 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 7855 if (!success) 7856 return false; 7857 7858 addr_t offset_addr; 7859 addr_t address; 7860 7861 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 7862 uint64_t Rn = 7863 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 7864 if (!success) 7865 return false; 7866 7867 if (add) 7868 offset_addr = Rn + offset; 7869 else 7870 offset_addr = Rn - offset; 7871 7872 // address = if index then offset_addr else R[n]; 7873 if (index) 7874 address = offset_addr; 7875 else 7876 address = Rn; 7877 7878 // R[t] = SignExtend(MemU[address,1], 32); 7879 RegisterInfo base_reg; 7880 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 7881 RegisterInfo offset_reg; 7882 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 7883 7884 EmulateInstruction::Context context; 7885 context.type = eContextRegisterLoad; 7886 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 7887 7888 uint64_t unsigned_data = MemURead(context, address, 1, 0, &success); 7889 if (!success) 7890 return false; 7891 7892 int64_t signed_data = llvm::SignExtend64<8>(unsigned_data); 7893 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 7894 (uint64_t)signed_data)) 7895 return false; 7896 7897 // if wback then R[n] = offset_addr; 7898 if (wback) { 7899 context.type = eContextAdjustBaseRegister; 7900 context.SetAddress(offset_addr); 7901 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 7902 offset_addr)) 7903 return false; 7904 } 7905 } 7906 return true; 7907} 7908 7909// LDRSH (immediate) calculates an address from a base register value and an 7910// immediate offset, loads a halfword from 7911// memory, sign-extends it to form a 32-bit word, and writes it to a register. 7912// It can use offset, post-indexed, or pre-indexed addressing. 7913bool EmulateInstructionARM::EmulateLDRSHImmediate(const uint32_t opcode, 7914 const ARMEncoding encoding) { 7915#if 0 7916 if ConditionPassed() then 7917 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7918 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 7919 address = if index then offset_addr else R[n]; 7920 data = MemU[address,2]; 7921 if wback then R[n] = offset_addr; 7922 if UnalignedSupport() || address<0> = '0' then 7923 R[t] = SignExtend(data, 32); 7924 else // Can only apply before ARMv7 7925 R[t] = bits(32) UNKNOWN; 7926#endif 7927 7928 bool success = false; 7929 7930 if (ConditionPassed(opcode)) { 7931 uint32_t t; 7932 uint32_t n; 7933 uint32_t imm32; 7934 bool index; 7935 bool add; 7936 bool wback; 7937 7938 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 7939 switch (encoding) { 7940 case eEncodingT1: 7941 // if Rn == '1111' then SEE LDRSH (literal); 7942 // if Rt == '1111' then SEE "Unallocated memory hints"; 7943 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 7944 t = Bits32(opcode, 15, 12); 7945 n = Bits32(opcode, 19, 16); 7946 imm32 = Bits32(opcode, 11, 0); 7947 7948 // index = TRUE; add = TRUE; wback = FALSE; 7949 index = true; 7950 add = true; 7951 wback = false; 7952 7953 // if t == 13 then UNPREDICTABLE; 7954 if (t == 13) 7955 return false; 7956 7957 break; 7958 7959 case eEncodingT2: 7960 // if Rn == '1111' then SEE LDRSH (literal); 7961 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE 7962 // "Unallocated memory hints"; 7963 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT; 7964 // if P == '0' && W == '0' then UNDEFINED; 7965 if (BitIsClear(opcode, 10) && BitIsClear(opcode, 8)) 7966 return false; 7967 7968 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32); 7969 t = Bits32(opcode, 15, 12); 7970 n = Bits32(opcode, 19, 16); 7971 imm32 = Bits32(opcode, 7, 0); 7972 7973 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 7974 index = BitIsSet(opcode, 10); 7975 add = BitIsSet(opcode, 9); 7976 wback = BitIsSet(opcode, 8); 7977 7978 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE; 7979 if (BadReg(t) || (wback && (n == t))) 7980 return false; 7981 7982 break; 7983 7984 case eEncodingA1: { 7985 // if Rn == '1111' then SEE LDRSH (literal); 7986 // if P == '0' && W == '1' then SEE LDRSHT; 7987 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32); 7988 t = Bits32(opcode, 15, 12); 7989 n = Bits32(opcode, 19, 16); 7990 uint32_t imm4H = Bits32(opcode, 11, 8); 7991 uint32_t imm4L = Bits32(opcode, 3, 0); 7992 imm32 = (imm4H << 4) | imm4L; 7993 7994 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 7995 // (W == '1'); 7996 index = BitIsSet(opcode, 24); 7997 add = BitIsSet(opcode, 23); 7998 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 7999 8000 // if t == 15 || (wback && n == t) then UNPREDICTABLE; 8001 if ((t == 15) || (wback && (n == t))) 8002 return false; 8003 8004 break; 8005 } 8006 8007 default: 8008 return false; 8009 } 8010 8011 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 8012 uint64_t Rn = 8013 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8014 if (!success) 8015 return false; 8016 8017 addr_t offset_addr; 8018 if (add) 8019 offset_addr = Rn + imm32; 8020 else 8021 offset_addr = Rn - imm32; 8022 8023 // address = if index then offset_addr else R[n]; 8024 addr_t address; 8025 if (index) 8026 address = offset_addr; 8027 else 8028 address = Rn; 8029 8030 // data = MemU[address,2]; 8031 RegisterInfo base_reg; 8032 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8033 8034 EmulateInstruction::Context context; 8035 context.type = eContextRegisterLoad; 8036 context.SetRegisterPlusOffset(base_reg, address - Rn); 8037 8038 uint64_t data = MemURead(context, address, 2, 0, &success); 8039 if (!success) 8040 return false; 8041 8042 // if wback then R[n] = offset_addr; 8043 if (wback) { 8044 context.type = eContextAdjustBaseRegister; 8045 context.SetAddress(offset_addr); 8046 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8047 offset_addr)) 8048 return false; 8049 } 8050 8051 // if UnalignedSupport() || address<0> = '0' then 8052 if (UnalignedSupport() || BitIsClear(address, 0)) { 8053 // R[t] = SignExtend(data, 32); 8054 int64_t signed_data = llvm::SignExtend64<16>(data); 8055 context.type = eContextRegisterLoad; 8056 context.SetRegisterPlusOffset(base_reg, address - Rn); 8057 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8058 (uint64_t)signed_data)) 8059 return false; 8060 } else // Can only apply before ARMv7 8061 { 8062 // R[t] = bits(32) UNKNOWN; 8063 WriteBits32Unknown(t); 8064 } 8065 } 8066 return true; 8067} 8068 8069// LDRSH (literal) calculates an address from the PC value and an immediate 8070// offset, loads a halfword from memory, 8071// sign-extends it to from a 32-bit word, and writes it to a register. 8072bool EmulateInstructionARM::EmulateLDRSHLiteral(const uint32_t opcode, 8073 const ARMEncoding encoding) { 8074#if 0 8075 if ConditionPassed() then 8076 EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8077 base = Align(PC,4); 8078 address = if add then (base + imm32) else (base - imm32); 8079 data = MemU[address,2]; 8080 if UnalignedSupport() || address<0> = '0' then 8081 R[t] = SignExtend(data, 32); 8082 else // Can only apply before ARMv7 8083 R[t] = bits(32) UNKNOWN; 8084#endif 8085 8086 bool success = false; 8087 8088 if (ConditionPassed(opcode)) { 8089 uint32_t t; 8090 uint32_t imm32; 8091 bool add; 8092 8093 // EncodingSpecificOperations(); NullCheckIfThumbEE(15); 8094 switch (encoding) { 8095 case eEncodingT1: 8096 // if Rt == '1111' then SEE "Unallocated memory hints"; 8097 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1'); 8098 t = Bits32(opcode, 15, 12); 8099 imm32 = Bits32(opcode, 11, 0); 8100 add = BitIsSet(opcode, 23); 8101 8102 // if t == 13 then UNPREDICTABLE; 8103 if (t == 13) 8104 return false; 8105 8106 break; 8107 8108 case eEncodingA1: { 8109 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1'); 8110 t = Bits32(opcode, 15, 12); 8111 uint32_t imm4H = Bits32(opcode, 11, 8); 8112 uint32_t imm4L = Bits32(opcode, 3, 0); 8113 imm32 = (imm4H << 4) | imm4L; 8114 add = BitIsSet(opcode, 23); 8115 8116 // if t == 15 then UNPREDICTABLE; 8117 if (t == 15) 8118 return false; 8119 8120 break; 8121 } 8122 default: 8123 return false; 8124 } 8125 8126 // base = Align(PC,4); 8127 uint64_t pc_value = ReadCoreReg(PC_REG, &success); 8128 if (!success) 8129 return false; 8130 8131 uint64_t base = AlignPC(pc_value); 8132 8133 addr_t address; 8134 // address = if add then (base + imm32) else (base - imm32); 8135 if (add) 8136 address = base + imm32; 8137 else 8138 address = base - imm32; 8139 8140 // data = MemU[address,2]; 8141 RegisterInfo base_reg; 8142 GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg); 8143 8144 EmulateInstruction::Context context; 8145 context.type = eContextRegisterLoad; 8146 context.SetRegisterPlusOffset(base_reg, imm32); 8147 8148 uint64_t data = MemURead(context, address, 2, 0, &success); 8149 if (!success) 8150 return false; 8151 8152 // if UnalignedSupport() || address<0> = '0' then 8153 if (UnalignedSupport() || BitIsClear(address, 0)) { 8154 // R[t] = SignExtend(data, 32); 8155 int64_t signed_data = llvm::SignExtend64<16>(data); 8156 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8157 (uint64_t)signed_data)) 8158 return false; 8159 } else // Can only apply before ARMv7 8160 { 8161 // R[t] = bits(32) UNKNOWN; 8162 WriteBits32Unknown(t); 8163 } 8164 } 8165 return true; 8166} 8167 8168// LDRSH (register) calculates an address from a base register value and an 8169// offset register value, loads a halfword 8170// from memory, sign-extends it to form a 32-bit word, and writes it to a 8171// register. The offset register value can be shifted left by 0, 1, 2, or 3 8172// bits. 8173bool EmulateInstructionARM::EmulateLDRSHRegister(const uint32_t opcode, 8174 const ARMEncoding encoding) { 8175#if 0 8176 if ConditionPassed() then 8177 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8178 offset = Shift(R[m], shift_t, shift_n, APSR.C); 8179 offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8180 address = if index then offset_addr else R[n]; 8181 data = MemU[address,2]; 8182 if wback then R[n] = offset_addr; 8183 if UnalignedSupport() || address<0> = '0' then 8184 R[t] = SignExtend(data, 32); 8185 else // Can only apply before ARMv7 8186 R[t] = bits(32) UNKNOWN; 8187#endif 8188 8189 bool success = false; 8190 8191 if (ConditionPassed(opcode)) { 8192 uint32_t t; 8193 uint32_t n; 8194 uint32_t m; 8195 bool index; 8196 bool add; 8197 bool wback; 8198 ARM_ShifterType shift_t; 8199 uint32_t shift_n; 8200 8201 // EncodingSpecificOperations(); NullCheckIfThumbEE(n); 8202 switch (encoding) { 8203 case eEncodingT1: 8204 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation 8205 // in ThumbEE"; 8206 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8207 t = Bits32(opcode, 2, 0); 8208 n = Bits32(opcode, 5, 3); 8209 m = Bits32(opcode, 8, 6); 8210 8211 // index = TRUE; add = TRUE; wback = FALSE; 8212 index = true; 8213 add = true; 8214 wback = false; 8215 8216 // (shift_t, shift_n) = (SRType_LSL, 0); 8217 shift_t = SRType_LSL; 8218 shift_n = 0; 8219 8220 break; 8221 8222 case eEncodingT2: 8223 // if Rn == '1111' then SEE LDRSH (literal); 8224 // if Rt == '1111' then SEE "Unallocated memory hints"; 8225 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8226 t = Bits32(opcode, 15, 12); 8227 n = Bits32(opcode, 19, 16); 8228 m = Bits32(opcode, 3, 0); 8229 8230 // index = TRUE; add = TRUE; wback = FALSE; 8231 index = true; 8232 add = true; 8233 wback = false; 8234 8235 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2)); 8236 shift_t = SRType_LSL; 8237 shift_n = Bits32(opcode, 5, 4); 8238 8239 // if t == 13 || BadReg(m) then UNPREDICTABLE; 8240 if ((t == 13) || BadReg(m)) 8241 return false; 8242 8243 break; 8244 8245 case eEncodingA1: 8246 // if P == '0' && W == '1' then SEE LDRSHT; 8247 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm); 8248 t = Bits32(opcode, 15, 12); 8249 n = Bits32(opcode, 19, 16); 8250 m = Bits32(opcode, 3, 0); 8251 8252 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || 8253 // (W == '1'); 8254 index = BitIsSet(opcode, 24); 8255 add = BitIsSet(opcode, 23); 8256 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 8257 8258 // (shift_t, shift_n) = (SRType_LSL, 0); 8259 shift_t = SRType_LSL; 8260 shift_n = 0; 8261 8262 // if t == 15 || m == 15 then UNPREDICTABLE; 8263 if ((t == 15) || (m == 15)) 8264 return false; 8265 8266 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 8267 if (wback && ((n == 15) || (n == t))) 8268 return false; 8269 8270 break; 8271 8272 default: 8273 return false; 8274 } 8275 8276 uint64_t Rm = 8277 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8278 if (!success) 8279 return false; 8280 8281 uint64_t Rn = 8282 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8283 if (!success) 8284 return false; 8285 8286 // offset = Shift(R[m], shift_t, shift_n, APSR.C); 8287 addr_t offset = Shift(Rm, shift_t, shift_n, APSR_C, &success); 8288 if (!success) 8289 return false; 8290 8291 addr_t offset_addr; 8292 addr_t address; 8293 8294 // offset_addr = if add then (R[n] + offset) else (R[n] - offset); 8295 if (add) 8296 offset_addr = Rn + offset; 8297 else 8298 offset_addr = Rn - offset; 8299 8300 // address = if index then offset_addr else R[n]; 8301 if (index) 8302 address = offset_addr; 8303 else 8304 address = Rn; 8305 8306 // data = MemU[address,2]; 8307 RegisterInfo base_reg; 8308 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8309 8310 RegisterInfo offset_reg; 8311 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 8312 8313 EmulateInstruction::Context context; 8314 context.type = eContextRegisterLoad; 8315 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8316 8317 uint64_t data = MemURead(context, address, 2, 0, &success); 8318 if (!success) 8319 return false; 8320 8321 // if wback then R[n] = offset_addr; 8322 if (wback) { 8323 context.type = eContextAdjustBaseRegister; 8324 context.SetAddress(offset_addr); 8325 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8326 offset_addr)) 8327 return false; 8328 } 8329 8330 // if UnalignedSupport() || address<0> = '0' then 8331 if (UnalignedSupport() || BitIsClear(address, 0)) { 8332 // R[t] = SignExtend(data, 32); 8333 context.type = eContextRegisterLoad; 8334 context.SetRegisterPlusIndirectOffset(base_reg, offset_reg); 8335 8336 int64_t signed_data = llvm::SignExtend64<16>(data); 8337 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 8338 (uint64_t)signed_data)) 8339 return false; 8340 } else // Can only apply before ARMv7 8341 { 8342 // R[t] = bits(32) UNKNOWN; 8343 WriteBits32Unknown(t); 8344 } 8345 } 8346 return true; 8347} 8348 8349// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and 8350// writes the result to the destination 8351// register. You can specifiy a rotation by 0, 8, 16, or 24 bits before 8352// extracting the 8-bit value. 8353bool EmulateInstructionARM::EmulateSXTB(const uint32_t opcode, 8354 const ARMEncoding encoding) { 8355#if 0 8356 if ConditionPassed() then 8357 EncodingSpecificOperations(); 8358 rotated = ROR(R[m], rotation); 8359 R[d] = SignExtend(rotated<7:0>, 32); 8360#endif 8361 8362 bool success = false; 8363 8364 if (ConditionPassed(opcode)) { 8365 uint32_t d; 8366 uint32_t m; 8367 uint32_t rotation; 8368 8369 // EncodingSpecificOperations(); 8370 switch (encoding) { 8371 case eEncodingT1: 8372 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8373 d = Bits32(opcode, 2, 0); 8374 m = Bits32(opcode, 5, 3); 8375 rotation = 0; 8376 8377 break; 8378 8379 case eEncodingT2: 8380 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8381 d = Bits32(opcode, 11, 8); 8382 m = Bits32(opcode, 3, 0); 8383 rotation = Bits32(opcode, 5, 4) << 3; 8384 8385 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8386 if (BadReg(d) || BadReg(m)) 8387 return false; 8388 8389 break; 8390 8391 case eEncodingA1: 8392 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8393 d = Bits32(opcode, 15, 12); 8394 m = Bits32(opcode, 3, 0); 8395 rotation = Bits32(opcode, 11, 10) << 3; 8396 8397 // if d == 15 || m == 15 then UNPREDICTABLE; 8398 if ((d == 15) || (m == 15)) 8399 return false; 8400 8401 break; 8402 8403 default: 8404 return false; 8405 } 8406 8407 uint64_t Rm = 8408 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8409 if (!success) 8410 return false; 8411 8412 // rotated = ROR(R[m], rotation); 8413 uint64_t rotated = ROR(Rm, rotation, &success); 8414 if (!success) 8415 return false; 8416 8417 // R[d] = SignExtend(rotated<7:0>, 32); 8418 int64_t data = llvm::SignExtend64<8>(rotated); 8419 8420 RegisterInfo source_reg; 8421 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8422 8423 EmulateInstruction::Context context; 8424 context.type = eContextRegisterLoad; 8425 context.SetRegister(source_reg); 8426 8427 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8428 (uint64_t)data)) 8429 return false; 8430 } 8431 return true; 8432} 8433 8434// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and 8435// writes the result to the destination 8436// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8437// extracting the 16-bit value. 8438bool EmulateInstructionARM::EmulateSXTH(const uint32_t opcode, 8439 const ARMEncoding encoding) { 8440#if 0 8441 if ConditionPassed() then 8442 EncodingSpecificOperations(); 8443 rotated = ROR(R[m], rotation); 8444 R[d] = SignExtend(rotated<15:0>, 32); 8445#endif 8446 8447 bool success = false; 8448 8449 if (ConditionPassed(opcode)) { 8450 uint32_t d; 8451 uint32_t m; 8452 uint32_t rotation; 8453 8454 // EncodingSpecificOperations(); 8455 switch (encoding) { 8456 case eEncodingT1: 8457 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8458 d = Bits32(opcode, 2, 0); 8459 m = Bits32(opcode, 5, 3); 8460 rotation = 0; 8461 8462 break; 8463 8464 case eEncodingT2: 8465 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8466 d = Bits32(opcode, 11, 8); 8467 m = Bits32(opcode, 3, 0); 8468 rotation = Bits32(opcode, 5, 4) << 3; 8469 8470 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8471 if (BadReg(d) || BadReg(m)) 8472 return false; 8473 8474 break; 8475 8476 case eEncodingA1: 8477 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8478 d = Bits32(opcode, 15, 12); 8479 m = Bits32(opcode, 3, 0); 8480 rotation = Bits32(opcode, 11, 10) << 3; 8481 8482 // if d == 15 || m == 15 then UNPREDICTABLE; 8483 if ((d == 15) || (m == 15)) 8484 return false; 8485 8486 break; 8487 8488 default: 8489 return false; 8490 } 8491 8492 uint64_t Rm = 8493 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8494 if (!success) 8495 return false; 8496 8497 // rotated = ROR(R[m], rotation); 8498 uint64_t rotated = ROR(Rm, rotation, &success); 8499 if (!success) 8500 return false; 8501 8502 // R[d] = SignExtend(rotated<15:0>, 32); 8503 RegisterInfo source_reg; 8504 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8505 8506 EmulateInstruction::Context context; 8507 context.type = eContextRegisterLoad; 8508 context.SetRegister(source_reg); 8509 8510 int64_t data = llvm::SignExtend64<16>(rotated); 8511 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8512 (uint64_t)data)) 8513 return false; 8514 } 8515 8516 return true; 8517} 8518 8519// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and 8520// writes the result to the destination 8521// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8522// extracting the 8-bit value. 8523bool EmulateInstructionARM::EmulateUXTB(const uint32_t opcode, 8524 const ARMEncoding encoding) { 8525#if 0 8526 if ConditionPassed() then 8527 EncodingSpecificOperations(); 8528 rotated = ROR(R[m], rotation); 8529 R[d] = ZeroExtend(rotated<7:0>, 32); 8530#endif 8531 8532 bool success = false; 8533 8534 if (ConditionPassed(opcode)) { 8535 uint32_t d; 8536 uint32_t m; 8537 uint32_t rotation; 8538 8539 // EncodingSpecificOperations(); 8540 switch (encoding) { 8541 case eEncodingT1: 8542 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8543 d = Bits32(opcode, 2, 0); 8544 m = Bits32(opcode, 5, 3); 8545 rotation = 0; 8546 8547 break; 8548 8549 case eEncodingT2: 8550 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8551 d = Bits32(opcode, 11, 8); 8552 m = Bits32(opcode, 3, 0); 8553 rotation = Bits32(opcode, 5, 4) << 3; 8554 8555 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8556 if (BadReg(d) || BadReg(m)) 8557 return false; 8558 8559 break; 8560 8561 case eEncodingA1: 8562 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8563 d = Bits32(opcode, 15, 12); 8564 m = Bits32(opcode, 3, 0); 8565 rotation = Bits32(opcode, 11, 10) << 3; 8566 8567 // if d == 15 || m == 15 then UNPREDICTABLE; 8568 if ((d == 15) || (m == 15)) 8569 return false; 8570 8571 break; 8572 8573 default: 8574 return false; 8575 } 8576 8577 uint64_t Rm = 8578 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8579 if (!success) 8580 return false; 8581 8582 // rotated = ROR(R[m], rotation); 8583 uint64_t rotated = ROR(Rm, rotation, &success); 8584 if (!success) 8585 return false; 8586 8587 // R[d] = ZeroExtend(rotated<7:0>, 32); 8588 RegisterInfo source_reg; 8589 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8590 8591 EmulateInstruction::Context context; 8592 context.type = eContextRegisterLoad; 8593 context.SetRegister(source_reg); 8594 8595 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8596 Bits32(rotated, 7, 0))) 8597 return false; 8598 } 8599 return true; 8600} 8601 8602// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and 8603// writes the result to the destination 8604// register. You can specify a rotation by 0, 8, 16, or 24 bits before 8605// extracting the 16-bit value. 8606bool EmulateInstructionARM::EmulateUXTH(const uint32_t opcode, 8607 const ARMEncoding encoding) { 8608#if 0 8609 if ConditionPassed() then 8610 EncodingSpecificOperations(); 8611 rotated = ROR(R[m], rotation); 8612 R[d] = ZeroExtend(rotated<15:0>, 32); 8613#endif 8614 8615 bool success = false; 8616 8617 if (ConditionPassed(opcode)) { 8618 uint32_t d; 8619 uint32_t m; 8620 uint32_t rotation; 8621 8622 switch (encoding) { 8623 case eEncodingT1: 8624 // d = UInt(Rd); m = UInt(Rm); rotation = 0; 8625 d = Bits32(opcode, 2, 0); 8626 m = Bits32(opcode, 5, 3); 8627 rotation = 0; 8628 8629 break; 8630 8631 case eEncodingT2: 8632 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8633 d = Bits32(opcode, 11, 8); 8634 m = Bits32(opcode, 3, 0); 8635 rotation = Bits32(opcode, 5, 4) << 3; 8636 8637 // if BadReg(d) || BadReg(m) then UNPREDICTABLE; 8638 if (BadReg(d) || BadReg(m)) 8639 return false; 8640 8641 break; 8642 8643 case eEncodingA1: 8644 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000'); 8645 d = Bits32(opcode, 15, 12); 8646 m = Bits32(opcode, 3, 0); 8647 rotation = Bits32(opcode, 11, 10) << 3; 8648 8649 // if d == 15 || m == 15 then UNPREDICTABLE; 8650 if ((d == 15) || (m == 15)) 8651 return false; 8652 8653 break; 8654 8655 default: 8656 return false; 8657 } 8658 8659 uint64_t Rm = 8660 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + m, 0, &success); 8661 if (!success) 8662 return false; 8663 8664 // rotated = ROR(R[m], rotation); 8665 uint64_t rotated = ROR(Rm, rotation, &success); 8666 if (!success) 8667 return false; 8668 8669 // R[d] = ZeroExtend(rotated<15:0>, 32); 8670 RegisterInfo source_reg; 8671 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, source_reg); 8672 8673 EmulateInstruction::Context context; 8674 context.type = eContextRegisterLoad; 8675 context.SetRegister(source_reg); 8676 8677 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 8678 Bits32(rotated, 15, 0))) 8679 return false; 8680 } 8681 return true; 8682} 8683 8684// RFE (Return From Exception) loads the PC and the CPSR from the word at the 8685// specified address and the following 8686// word respectively. 8687bool EmulateInstructionARM::EmulateRFE(const uint32_t opcode, 8688 const ARMEncoding encoding) { 8689#if 0 8690 if ConditionPassed() then 8691 EncodingSpecificOperations(); 8692 if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then 8693 UNPREDICTABLE; 8694 else 8695 address = if increment then R[n] else R[n]-8; 8696 if wordhigher then address = address+4; 8697 CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8698 BranchWritePC(MemA[address,4]); 8699 if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8700#endif 8701 8702 bool success = false; 8703 8704 if (ConditionPassed(opcode)) { 8705 uint32_t n; 8706 bool wback; 8707 bool increment; 8708 bool wordhigher; 8709 8710 // EncodingSpecificOperations(); 8711 switch (encoding) { 8712 case eEncodingT1: 8713 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = 8714 // FALSE; 8715 n = Bits32(opcode, 19, 16); 8716 wback = BitIsSet(opcode, 21); 8717 increment = false; 8718 wordhigher = false; 8719 8720 // if n == 15 then UNPREDICTABLE; 8721 if (n == 15) 8722 return false; 8723 8724 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8725 if (InITBlock() && !LastInITBlock()) 8726 return false; 8727 8728 break; 8729 8730 case eEncodingT2: 8731 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE; 8732 n = Bits32(opcode, 19, 16); 8733 wback = BitIsSet(opcode, 21); 8734 increment = true; 8735 wordhigher = false; 8736 8737 // if n == 15 then UNPREDICTABLE; 8738 if (n == 15) 8739 return false; 8740 8741 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 8742 if (InITBlock() && !LastInITBlock()) 8743 return false; 8744 8745 break; 8746 8747 case eEncodingA1: 8748 // n = UInt(Rn); 8749 n = Bits32(opcode, 19, 16); 8750 8751 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U); 8752 wback = BitIsSet(opcode, 21); 8753 increment = BitIsSet(opcode, 23); 8754 wordhigher = (Bit32(opcode, 24) == Bit32(opcode, 23)); 8755 8756 // if n == 15 then UNPREDICTABLE; 8757 if (n == 15) 8758 return false; 8759 8760 break; 8761 8762 default: 8763 return false; 8764 } 8765 8766 // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE 8767 // then 8768 if (!CurrentModeIsPrivileged()) 8769 // UNPREDICTABLE; 8770 return false; 8771 else { 8772 uint64_t Rn = 8773 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + n, 0, &success); 8774 if (!success) 8775 return false; 8776 8777 addr_t address; 8778 // address = if increment then R[n] else R[n]-8; 8779 if (increment) 8780 address = Rn; 8781 else 8782 address = Rn - 8; 8783 8784 // if wordhigher then address = address+4; 8785 if (wordhigher) 8786 address = address + 4; 8787 8788 // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE); 8789 RegisterInfo base_reg; 8790 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 8791 8792 EmulateInstruction::Context context; 8793 context.type = eContextReturnFromException; 8794 context.SetRegisterPlusOffset(base_reg, address - Rn); 8795 8796 uint64_t data = MemARead(context, address + 4, 4, 0, &success); 8797 if (!success) 8798 return false; 8799 8800 CPSRWriteByInstr(data, 15, true); 8801 8802 // BranchWritePC(MemA[address,4]); 8803 uint64_t data2 = MemARead(context, address, 4, 0, &success); 8804 if (!success) 8805 return false; 8806 8807 BranchWritePC(context, data2); 8808 8809 // if wback then R[n] = if increment then R[n]+8 else R[n]-8; 8810 if (wback) { 8811 context.type = eContextAdjustBaseRegister; 8812 if (increment) { 8813 context.SetOffset(8); 8814 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8815 Rn + 8)) 8816 return false; 8817 } else { 8818 context.SetOffset(-8); 8819 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 8820 Rn - 8)) 8821 return false; 8822 } 8823 } // if wback 8824 } 8825 } // if ConditionPassed() 8826 return true; 8827} 8828 8829// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a 8830// register value and an immediate value, and writes the result to the 8831// destination register. It can optionally update the condition flags based on 8832// the result. 8833bool EmulateInstructionARM::EmulateEORImm(const uint32_t opcode, 8834 const ARMEncoding encoding) { 8835#if 0 8836 // ARM pseudo code... 8837 if ConditionPassed() then 8838 EncodingSpecificOperations(); 8839 result = R[n] EOR imm32; 8840 if d == 15 then // Can only occur for ARM encoding 8841 ALUWritePC(result); // setflags is always FALSE here 8842 else 8843 R[d] = result; 8844 if setflags then 8845 APSR.N = result<31>; 8846 APSR.Z = IsZeroBit(result); 8847 APSR.C = carry; 8848 // APSR.V unchanged 8849#endif 8850 8851 bool success = false; 8852 8853 if (ConditionPassed(opcode)) { 8854 uint32_t Rd, Rn; 8855 uint32_t 8856 imm32; // the immediate value to be ORed to the value obtained from Rn 8857 bool setflags; 8858 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 8859 switch (encoding) { 8860 case eEncodingT1: 8861 Rd = Bits32(opcode, 11, 8); 8862 Rn = Bits32(opcode, 19, 16); 8863 setflags = BitIsSet(opcode, 20); 8864 imm32 = ThumbExpandImm_C( 8865 opcode, APSR_C, 8866 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 8867 // if Rd == '1111' && S == '1' then SEE TEQ (immediate); 8868 if (Rd == 15 && setflags) 8869 return EmulateTEQImm(opcode, eEncodingT1); 8870 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn)) 8871 return false; 8872 break; 8873 case eEncodingA1: 8874 Rd = Bits32(opcode, 15, 12); 8875 Rn = Bits32(opcode, 19, 16); 8876 setflags = BitIsSet(opcode, 20); 8877 imm32 = 8878 ARMExpandImm_C(opcode, APSR_C, 8879 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 8880 8881 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8882 // instructions; 8883 if (Rd == 15 && setflags) 8884 return EmulateSUBSPcLrEtc(opcode, encoding); 8885 break; 8886 default: 8887 return false; 8888 } 8889 8890 // Read the first operand. 8891 uint32_t val1 = ReadCoreReg(Rn, &success); 8892 if (!success) 8893 return false; 8894 8895 uint32_t result = val1 ^ imm32; 8896 8897 EmulateInstruction::Context context; 8898 context.type = EmulateInstruction::eContextImmediate; 8899 context.SetNoArgs(); 8900 8901 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8902 return false; 8903 } 8904 return true; 8905} 8906 8907// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a 8908// register value and an optionally-shifted register value, and writes the 8909// result to the destination register. It can optionally update the condition 8910// flags based on the result. 8911bool EmulateInstructionARM::EmulateEORReg(const uint32_t opcode, 8912 const ARMEncoding encoding) { 8913#if 0 8914 // ARM pseudo code... 8915 if ConditionPassed() then 8916 EncodingSpecificOperations(); 8917 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 8918 result = R[n] EOR shifted; 8919 if d == 15 then // Can only occur for ARM encoding 8920 ALUWritePC(result); // setflags is always FALSE here 8921 else 8922 R[d] = result; 8923 if setflags then 8924 APSR.N = result<31>; 8925 APSR.Z = IsZeroBit(result); 8926 APSR.C = carry; 8927 // APSR.V unchanged 8928#endif 8929 8930 bool success = false; 8931 8932 if (ConditionPassed(opcode)) { 8933 uint32_t Rd, Rn, Rm; 8934 ARM_ShifterType shift_t; 8935 uint32_t shift_n; // the shift applied to the value read from Rm 8936 bool setflags; 8937 uint32_t carry; 8938 switch (encoding) { 8939 case eEncodingT1: 8940 Rd = Rn = Bits32(opcode, 2, 0); 8941 Rm = Bits32(opcode, 5, 3); 8942 setflags = !InITBlock(); 8943 shift_t = SRType_LSL; 8944 shift_n = 0; 8945 break; 8946 case eEncodingT2: 8947 Rd = Bits32(opcode, 11, 8); 8948 Rn = Bits32(opcode, 19, 16); 8949 Rm = Bits32(opcode, 3, 0); 8950 setflags = BitIsSet(opcode, 20); 8951 shift_n = DecodeImmShiftThumb(opcode, shift_t); 8952 // if Rd == '1111' && S == '1' then SEE TEQ (register); 8953 if (Rd == 15 && setflags) 8954 return EmulateTEQReg(opcode, eEncodingT1); 8955 if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm)) 8956 return false; 8957 break; 8958 case eEncodingA1: 8959 Rd = Bits32(opcode, 15, 12); 8960 Rn = Bits32(opcode, 19, 16); 8961 Rm = Bits32(opcode, 3, 0); 8962 setflags = BitIsSet(opcode, 20); 8963 shift_n = DecodeImmShiftARM(opcode, shift_t); 8964 8965 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 8966 // instructions; 8967 if (Rd == 15 && setflags) 8968 return EmulateSUBSPcLrEtc(opcode, encoding); 8969 break; 8970 default: 8971 return false; 8972 } 8973 8974 // Read the first operand. 8975 uint32_t val1 = ReadCoreReg(Rn, &success); 8976 if (!success) 8977 return false; 8978 8979 // Read the second operand. 8980 uint32_t val2 = ReadCoreReg(Rm, &success); 8981 if (!success) 8982 return false; 8983 8984 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 8985 if (!success) 8986 return false; 8987 uint32_t result = val1 ^ shifted; 8988 8989 EmulateInstruction::Context context; 8990 context.type = EmulateInstruction::eContextImmediate; 8991 context.SetNoArgs(); 8992 8993 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 8994 return false; 8995 } 8996 return true; 8997} 8998 8999// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value 9000// and an immediate value, and writes the result to the destination register. 9001// It can optionally update the condition flags based on the result. 9002bool EmulateInstructionARM::EmulateORRImm(const uint32_t opcode, 9003 const ARMEncoding encoding) { 9004#if 0 9005 // ARM pseudo code... 9006 if ConditionPassed() then 9007 EncodingSpecificOperations(); 9008 result = R[n] OR imm32; 9009 if d == 15 then // Can only occur for ARM encoding 9010 ALUWritePC(result); // setflags is always FALSE here 9011 else 9012 R[d] = result; 9013 if setflags then 9014 APSR.N = result<31>; 9015 APSR.Z = IsZeroBit(result); 9016 APSR.C = carry; 9017 // APSR.V unchanged 9018#endif 9019 9020 bool success = false; 9021 9022 if (ConditionPassed(opcode)) { 9023 uint32_t Rd, Rn; 9024 uint32_t 9025 imm32; // the immediate value to be ORed to the value obtained from Rn 9026 bool setflags; 9027 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9028 switch (encoding) { 9029 case eEncodingT1: 9030 Rd = Bits32(opcode, 11, 8); 9031 Rn = Bits32(opcode, 19, 16); 9032 setflags = BitIsSet(opcode, 20); 9033 imm32 = ThumbExpandImm_C( 9034 opcode, APSR_C, 9035 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9036 // if Rn == '1111' then SEE MOV (immediate); 9037 if (Rn == 15) 9038 return EmulateMOVRdImm(opcode, eEncodingT2); 9039 if (BadReg(Rd) || Rn == 13) 9040 return false; 9041 break; 9042 case eEncodingA1: 9043 Rd = Bits32(opcode, 15, 12); 9044 Rn = Bits32(opcode, 19, 16); 9045 setflags = BitIsSet(opcode, 20); 9046 imm32 = 9047 ARMExpandImm_C(opcode, APSR_C, 9048 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9049 9050 if (Rd == 15 && setflags) 9051 return EmulateSUBSPcLrEtc(opcode, encoding); 9052 break; 9053 default: 9054 return false; 9055 } 9056 9057 // Read the first operand. 9058 uint32_t val1 = ReadCoreReg(Rn, &success); 9059 if (!success) 9060 return false; 9061 9062 uint32_t result = val1 | imm32; 9063 9064 EmulateInstruction::Context context; 9065 context.type = EmulateInstruction::eContextImmediate; 9066 context.SetNoArgs(); 9067 9068 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9069 return false; 9070 } 9071 return true; 9072} 9073 9074// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value 9075// and an optionally-shifted register value, and writes the result to the 9076// destination register. It can optionally update the condition flags based on 9077// the result. 9078bool EmulateInstructionARM::EmulateORRReg(const uint32_t opcode, 9079 const ARMEncoding encoding) { 9080#if 0 9081 // ARM pseudo code... 9082 if ConditionPassed() then 9083 EncodingSpecificOperations(); 9084 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9085 result = R[n] OR shifted; 9086 if d == 15 then // Can only occur for ARM encoding 9087 ALUWritePC(result); // setflags is always FALSE here 9088 else 9089 R[d] = result; 9090 if setflags then 9091 APSR.N = result<31>; 9092 APSR.Z = IsZeroBit(result); 9093 APSR.C = carry; 9094 // APSR.V unchanged 9095#endif 9096 9097 bool success = false; 9098 9099 if (ConditionPassed(opcode)) { 9100 uint32_t Rd, Rn, Rm; 9101 ARM_ShifterType shift_t; 9102 uint32_t shift_n; // the shift applied to the value read from Rm 9103 bool setflags; 9104 uint32_t carry; 9105 switch (encoding) { 9106 case eEncodingT1: 9107 Rd = Rn = Bits32(opcode, 2, 0); 9108 Rm = Bits32(opcode, 5, 3); 9109 setflags = !InITBlock(); 9110 shift_t = SRType_LSL; 9111 shift_n = 0; 9112 break; 9113 case eEncodingT2: 9114 Rd = Bits32(opcode, 11, 8); 9115 Rn = Bits32(opcode, 19, 16); 9116 Rm = Bits32(opcode, 3, 0); 9117 setflags = BitIsSet(opcode, 20); 9118 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9119 // if Rn == '1111' then SEE MOV (register); 9120 if (Rn == 15) 9121 return EmulateMOVRdRm(opcode, eEncodingT3); 9122 if (BadReg(Rd) || Rn == 13 || BadReg(Rm)) 9123 return false; 9124 break; 9125 case eEncodingA1: 9126 Rd = Bits32(opcode, 15, 12); 9127 Rn = Bits32(opcode, 19, 16); 9128 Rm = Bits32(opcode, 3, 0); 9129 setflags = BitIsSet(opcode, 20); 9130 shift_n = DecodeImmShiftARM(opcode, shift_t); 9131 9132 if (Rd == 15 && setflags) 9133 return EmulateSUBSPcLrEtc(opcode, encoding); 9134 break; 9135 default: 9136 return false; 9137 } 9138 9139 // Read the first operand. 9140 uint32_t val1 = ReadCoreReg(Rn, &success); 9141 if (!success) 9142 return false; 9143 9144 // Read the second operand. 9145 uint32_t val2 = ReadCoreReg(Rm, &success); 9146 if (!success) 9147 return false; 9148 9149 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9150 if (!success) 9151 return false; 9152 uint32_t result = val1 | shifted; 9153 9154 EmulateInstruction::Context context; 9155 context.type = EmulateInstruction::eContextImmediate; 9156 context.SetNoArgs(); 9157 9158 if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry)) 9159 return false; 9160 } 9161 return true; 9162} 9163 9164// Reverse Subtract (immediate) subtracts a register value from an immediate 9165// value, and writes the result to the destination register. It can optionally 9166// update the condition flags based on the result. 9167bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, 9168 const ARMEncoding encoding) { 9169#if 0 9170 // ARM pseudo code... 9171 if ConditionPassed() then 9172 EncodingSpecificOperations(); 9173 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1'); 9174 if d == 15 then // Can only occur for ARM encoding 9175 ALUWritePC(result); // setflags is always FALSE here 9176 else 9177 R[d] = result; 9178 if setflags then 9179 APSR.N = result<31>; 9180 APSR.Z = IsZeroBit(result); 9181 APSR.C = carry; 9182 APSR.V = overflow; 9183#endif 9184 9185 bool success = false; 9186 9187 uint32_t Rd; // the destination register 9188 uint32_t Rn; // the first operand 9189 bool setflags; 9190 uint32_t 9191 imm32; // the immediate value to be added to the value obtained from Rn 9192 switch (encoding) { 9193 case eEncodingT1: 9194 Rd = Bits32(opcode, 2, 0); 9195 Rn = Bits32(opcode, 5, 3); 9196 setflags = !InITBlock(); 9197 imm32 = 0; 9198 break; 9199 case eEncodingT2: 9200 Rd = Bits32(opcode, 11, 8); 9201 Rn = Bits32(opcode, 19, 16); 9202 setflags = BitIsSet(opcode, 20); 9203 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9204 if (BadReg(Rd) || BadReg(Rn)) 9205 return false; 9206 break; 9207 case eEncodingA1: 9208 Rd = Bits32(opcode, 15, 12); 9209 Rn = Bits32(opcode, 19, 16); 9210 setflags = BitIsSet(opcode, 20); 9211 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9212 9213 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9214 // instructions; 9215 if (Rd == 15 && setflags) 9216 return EmulateSUBSPcLrEtc(opcode, encoding); 9217 break; 9218 default: 9219 return false; 9220 } 9221 // Read the register value from the operand register Rn. 9222 uint32_t reg_val = ReadCoreReg(Rn, &success); 9223 if (!success) 9224 return false; 9225 9226 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1); 9227 9228 EmulateInstruction::Context context; 9229 context.type = EmulateInstruction::eContextImmediate; 9230 context.SetNoArgs(); 9231 9232 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9233 res.carry_out, res.overflow); 9234} 9235 9236// Reverse Subtract (register) subtracts a register value from an optionally- 9237// shifted register value, and writes the result to the destination register. 9238// It can optionally update the condition flags based on the result. 9239bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, 9240 const ARMEncoding encoding) { 9241#if 0 9242 // ARM pseudo code... 9243 if ConditionPassed() then 9244 EncodingSpecificOperations(); 9245 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9246 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1'); 9247 if d == 15 then // Can only occur for ARM encoding 9248 ALUWritePC(result); // setflags is always FALSE here 9249 else 9250 R[d] = result; 9251 if setflags then 9252 APSR.N = result<31>; 9253 APSR.Z = IsZeroBit(result); 9254 APSR.C = carry; 9255 APSR.V = overflow; 9256#endif 9257 9258 bool success = false; 9259 9260 uint32_t Rd; // the destination register 9261 uint32_t Rn; // the first operand 9262 uint32_t Rm; // the second operand 9263 bool setflags; 9264 ARM_ShifterType shift_t; 9265 uint32_t shift_n; // the shift applied to the value read from Rm 9266 switch (encoding) { 9267 case eEncodingT1: 9268 Rd = Bits32(opcode, 11, 8); 9269 Rn = Bits32(opcode, 19, 16); 9270 Rm = Bits32(opcode, 3, 0); 9271 setflags = BitIsSet(opcode, 20); 9272 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9273 // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE; 9274 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9275 return false; 9276 break; 9277 case eEncodingA1: 9278 Rd = Bits32(opcode, 15, 12); 9279 Rn = Bits32(opcode, 19, 16); 9280 Rm = Bits32(opcode, 3, 0); 9281 setflags = BitIsSet(opcode, 20); 9282 shift_n = DecodeImmShiftARM(opcode, shift_t); 9283 9284 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9285 // instructions; 9286 if (Rd == 15 && setflags) 9287 return EmulateSUBSPcLrEtc(opcode, encoding); 9288 break; 9289 default: 9290 return false; 9291 } 9292 // Read the register value from register Rn. 9293 uint32_t val1 = ReadCoreReg(Rn, &success); 9294 if (!success) 9295 return false; 9296 9297 // Read the register value from register Rm. 9298 uint32_t val2 = ReadCoreReg(Rm, &success); 9299 if (!success) 9300 return false; 9301 9302 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9303 if (!success) 9304 return false; 9305 AddWithCarryResult res = AddWithCarry(~val1, shifted, 1); 9306 9307 EmulateInstruction::Context context; 9308 context.type = EmulateInstruction::eContextImmediate; 9309 context.SetNoArgs(); 9310 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9311 res.carry_out, res.overflow); 9312} 9313 9314// Reverse Subtract with Carry (immediate) subtracts a register value and the 9315// value of NOT (Carry flag) from an immediate value, and writes the result to 9316// the destination register. It can optionally update the condition flags based 9317// on the result. 9318bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, 9319 const ARMEncoding encoding) { 9320#if 0 9321 // ARM pseudo code... 9322 if ConditionPassed() then 9323 EncodingSpecificOperations(); 9324 (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C); 9325 if d == 15 then 9326 ALUWritePC(result); // setflags is always FALSE here 9327 else 9328 R[d] = result; 9329 if setflags then 9330 APSR.N = result<31>; 9331 APSR.Z = IsZeroBit(result); 9332 APSR.C = carry; 9333 APSR.V = overflow; 9334#endif 9335 9336 bool success = false; 9337 9338 uint32_t Rd; // the destination register 9339 uint32_t Rn; // the first operand 9340 bool setflags; 9341 uint32_t 9342 imm32; // the immediate value to be added to the value obtained from Rn 9343 switch (encoding) { 9344 case eEncodingA1: 9345 Rd = Bits32(opcode, 15, 12); 9346 Rn = Bits32(opcode, 19, 16); 9347 setflags = BitIsSet(opcode, 20); 9348 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9349 9350 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9351 // instructions; 9352 if (Rd == 15 && setflags) 9353 return EmulateSUBSPcLrEtc(opcode, encoding); 9354 break; 9355 default: 9356 return false; 9357 } 9358 // Read the register value from the operand register Rn. 9359 uint32_t reg_val = ReadCoreReg(Rn, &success); 9360 if (!success) 9361 return false; 9362 9363 AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C); 9364 9365 EmulateInstruction::Context context; 9366 context.type = EmulateInstruction::eContextImmediate; 9367 context.SetNoArgs(); 9368 9369 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9370 res.carry_out, res.overflow); 9371} 9372 9373// Reverse Subtract with Carry (register) subtracts a register value and the 9374// value of NOT (Carry flag) from an optionally-shifted register value, and 9375// writes the result to the destination register. It can optionally update the 9376// condition flags based on the result. 9377bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, 9378 const ARMEncoding encoding) { 9379#if 0 9380 // ARM pseudo code... 9381 if ConditionPassed() then 9382 EncodingSpecificOperations(); 9383 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9384 (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C); 9385 if d == 15 then 9386 ALUWritePC(result); // setflags is always FALSE here 9387 else 9388 R[d] = result; 9389 if setflags then 9390 APSR.N = result<31>; 9391 APSR.Z = IsZeroBit(result); 9392 APSR.C = carry; 9393 APSR.V = overflow; 9394#endif 9395 9396 bool success = false; 9397 9398 uint32_t Rd; // the destination register 9399 uint32_t Rn; // the first operand 9400 uint32_t Rm; // the second operand 9401 bool setflags; 9402 ARM_ShifterType shift_t; 9403 uint32_t shift_n; // the shift applied to the value read from Rm 9404 switch (encoding) { 9405 case eEncodingA1: 9406 Rd = Bits32(opcode, 15, 12); 9407 Rn = Bits32(opcode, 19, 16); 9408 Rm = Bits32(opcode, 3, 0); 9409 setflags = BitIsSet(opcode, 20); 9410 shift_n = DecodeImmShiftARM(opcode, shift_t); 9411 9412 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9413 // instructions; 9414 if (Rd == 15 && setflags) 9415 return EmulateSUBSPcLrEtc(opcode, encoding); 9416 break; 9417 default: 9418 return false; 9419 } 9420 // Read the register value from register Rn. 9421 uint32_t val1 = ReadCoreReg(Rn, &success); 9422 if (!success) 9423 return false; 9424 9425 // Read the register value from register Rm. 9426 uint32_t val2 = ReadCoreReg(Rm, &success); 9427 if (!success) 9428 return false; 9429 9430 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9431 if (!success) 9432 return false; 9433 AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C); 9434 9435 EmulateInstruction::Context context; 9436 context.type = EmulateInstruction::eContextImmediate; 9437 context.SetNoArgs(); 9438 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9439 res.carry_out, res.overflow); 9440} 9441 9442// Subtract with Carry (immediate) subtracts an immediate value and the value 9443// of 9444// NOT (Carry flag) from a register value, and writes the result to the 9445// destination register. 9446// It can optionally update the condition flags based on the result. 9447bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, 9448 const ARMEncoding encoding) { 9449#if 0 9450 // ARM pseudo code... 9451 if ConditionPassed() then 9452 EncodingSpecificOperations(); 9453 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C); 9454 if d == 15 then // Can only occur for ARM encoding 9455 ALUWritePC(result); // setflags is always FALSE here 9456 else 9457 R[d] = result; 9458 if setflags then 9459 APSR.N = result<31>; 9460 APSR.Z = IsZeroBit(result); 9461 APSR.C = carry; 9462 APSR.V = overflow; 9463#endif 9464 9465 bool success = false; 9466 9467 uint32_t Rd; // the destination register 9468 uint32_t Rn; // the first operand 9469 bool setflags; 9470 uint32_t 9471 imm32; // the immediate value to be added to the value obtained from Rn 9472 switch (encoding) { 9473 case eEncodingT1: 9474 Rd = Bits32(opcode, 11, 8); 9475 Rn = Bits32(opcode, 19, 16); 9476 setflags = BitIsSet(opcode, 20); 9477 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9478 if (BadReg(Rd) || BadReg(Rn)) 9479 return false; 9480 break; 9481 case eEncodingA1: 9482 Rd = Bits32(opcode, 15, 12); 9483 Rn = Bits32(opcode, 19, 16); 9484 setflags = BitIsSet(opcode, 20); 9485 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9486 9487 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9488 // instructions; 9489 if (Rd == 15 && setflags) 9490 return EmulateSUBSPcLrEtc(opcode, encoding); 9491 break; 9492 default: 9493 return false; 9494 } 9495 // Read the register value from the operand register Rn. 9496 uint32_t reg_val = ReadCoreReg(Rn, &success); 9497 if (!success) 9498 return false; 9499 9500 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C); 9501 9502 EmulateInstruction::Context context; 9503 context.type = EmulateInstruction::eContextImmediate; 9504 context.SetNoArgs(); 9505 9506 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9507 res.carry_out, res.overflow); 9508} 9509 9510// Subtract with Carry (register) subtracts an optionally-shifted register 9511// value and the value of 9512// NOT (Carry flag) from a register value, and writes the result to the 9513// destination register. 9514// It can optionally update the condition flags based on the result. 9515bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, 9516 const ARMEncoding encoding) { 9517#if 0 9518 // ARM pseudo code... 9519 if ConditionPassed() then 9520 EncodingSpecificOperations(); 9521 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 9522 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C); 9523 if d == 15 then // Can only occur for ARM encoding 9524 ALUWritePC(result); // setflags is always FALSE here 9525 else 9526 R[d] = result; 9527 if setflags then 9528 APSR.N = result<31>; 9529 APSR.Z = IsZeroBit(result); 9530 APSR.C = carry; 9531 APSR.V = overflow; 9532#endif 9533 9534 bool success = false; 9535 9536 uint32_t Rd; // the destination register 9537 uint32_t Rn; // the first operand 9538 uint32_t Rm; // the second operand 9539 bool setflags; 9540 ARM_ShifterType shift_t; 9541 uint32_t shift_n; // the shift applied to the value read from Rm 9542 switch (encoding) { 9543 case eEncodingT1: 9544 Rd = Rn = Bits32(opcode, 2, 0); 9545 Rm = Bits32(opcode, 5, 3); 9546 setflags = !InITBlock(); 9547 shift_t = SRType_LSL; 9548 shift_n = 0; 9549 break; 9550 case eEncodingT2: 9551 Rd = Bits32(opcode, 11, 8); 9552 Rn = Bits32(opcode, 19, 16); 9553 Rm = Bits32(opcode, 3, 0); 9554 setflags = BitIsSet(opcode, 20); 9555 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9556 if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm)) 9557 return false; 9558 break; 9559 case eEncodingA1: 9560 Rd = Bits32(opcode, 15, 12); 9561 Rn = Bits32(opcode, 19, 16); 9562 Rm = Bits32(opcode, 3, 0); 9563 setflags = BitIsSet(opcode, 20); 9564 shift_n = DecodeImmShiftARM(opcode, shift_t); 9565 9566 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9567 // instructions; 9568 if (Rd == 15 && setflags) 9569 return EmulateSUBSPcLrEtc(opcode, encoding); 9570 break; 9571 default: 9572 return false; 9573 } 9574 // Read the register value from register Rn. 9575 uint32_t val1 = ReadCoreReg(Rn, &success); 9576 if (!success) 9577 return false; 9578 9579 // Read the register value from register Rm. 9580 uint32_t val2 = ReadCoreReg(Rm, &success); 9581 if (!success) 9582 return false; 9583 9584 uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success); 9585 if (!success) 9586 return false; 9587 AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C); 9588 9589 EmulateInstruction::Context context; 9590 context.type = EmulateInstruction::eContextImmediate; 9591 context.SetNoArgs(); 9592 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9593 res.carry_out, res.overflow); 9594} 9595 9596// This instruction subtracts an immediate value from a register value, and 9597// writes the result to the destination register. It can optionally update the 9598// condition flags based on the result. 9599bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, 9600 const ARMEncoding encoding) { 9601#if 0 9602 // ARM pseudo code... 9603 if ConditionPassed() then 9604 EncodingSpecificOperations(); 9605 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9606 R[d] = result; 9607 if setflags then 9608 APSR.N = result<31>; 9609 APSR.Z = IsZeroBit(result); 9610 APSR.C = carry; 9611 APSR.V = overflow; 9612#endif 9613 9614 bool success = false; 9615 9616 uint32_t Rd; // the destination register 9617 uint32_t Rn; // the first operand 9618 bool setflags; 9619 uint32_t imm32; // the immediate value to be subtracted from the value 9620 // obtained from Rn 9621 switch (encoding) { 9622 case eEncodingT1: 9623 Rd = Bits32(opcode, 2, 0); 9624 Rn = Bits32(opcode, 5, 3); 9625 setflags = !InITBlock(); 9626 imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32) 9627 break; 9628 case eEncodingT2: 9629 Rd = Rn = Bits32(opcode, 10, 8); 9630 setflags = !InITBlock(); 9631 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32) 9632 break; 9633 case eEncodingT3: 9634 Rd = Bits32(opcode, 11, 8); 9635 Rn = Bits32(opcode, 19, 16); 9636 setflags = BitIsSet(opcode, 20); 9637 imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8) 9638 9639 // if Rd == '1111' && S == '1' then SEE CMP (immediate); 9640 if (Rd == 15 && setflags) 9641 return EmulateCMPImm(opcode, eEncodingT2); 9642 9643 // if Rn == '1101' then SEE SUB (SP minus immediate); 9644 if (Rn == 13) 9645 return EmulateSUBSPImm(opcode, eEncodingT2); 9646 9647 // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; 9648 if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15) 9649 return false; 9650 break; 9651 case eEncodingT4: 9652 Rd = Bits32(opcode, 11, 8); 9653 Rn = Bits32(opcode, 19, 16); 9654 setflags = BitIsSet(opcode, 20); 9655 imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32) 9656 9657 // if Rn == '1111' then SEE ADR; 9658 if (Rn == 15) 9659 return EmulateADR(opcode, eEncodingT2); 9660 9661 // if Rn == '1101' then SEE SUB (SP minus immediate); 9662 if (Rn == 13) 9663 return EmulateSUBSPImm(opcode, eEncodingT3); 9664 9665 if (BadReg(Rd)) 9666 return false; 9667 break; 9668 default: 9669 return false; 9670 } 9671 // Read the register value from the operand register Rn. 9672 uint32_t reg_val = ReadCoreReg(Rn, &success); 9673 if (!success) 9674 return false; 9675 9676 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9677 9678 EmulateInstruction::Context context; 9679 context.type = EmulateInstruction::eContextImmediate; 9680 context.SetNoArgs(); 9681 9682 return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9683 res.carry_out, res.overflow); 9684} 9685 9686// This instruction subtracts an immediate value from a register value, and 9687// writes the result to the destination register. It can optionally update the 9688// condition flags based on the result. 9689bool EmulateInstructionARM::EmulateSUBImmARM(const uint32_t opcode, 9690 const ARMEncoding encoding) { 9691#if 0 9692 // ARM pseudo code... 9693 if ConditionPassed() then 9694 EncodingSpecificOperations(); 9695 (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1'); 9696 if d == 15 then 9697 ALUWritePC(result); // setflags is always FALSE here 9698 else 9699 R[d] = result; 9700 if setflags then 9701 APSR.N = result<31>; 9702 APSR.Z = IsZeroBit(result); 9703 APSR.C = carry; 9704 APSR.V = overflow; 9705#endif 9706 9707 bool success = false; 9708 9709 if (ConditionPassed(opcode)) { 9710 uint32_t Rd; // the destination register 9711 uint32_t Rn; // the first operand 9712 bool setflags; 9713 uint32_t imm32; // the immediate value to be subtracted from the value 9714 // obtained from Rn 9715 switch (encoding) { 9716 case eEncodingA1: 9717 Rd = Bits32(opcode, 15, 12); 9718 Rn = Bits32(opcode, 19, 16); 9719 setflags = BitIsSet(opcode, 20); 9720 imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12) 9721 9722 // if Rn == '1111' && S == '0' then SEE ADR; 9723 if (Rn == 15 && !setflags) 9724 return EmulateADR(opcode, eEncodingA2); 9725 9726 // if Rn == '1101' then SEE SUB (SP minus immediate); 9727 if (Rn == 13) 9728 return EmulateSUBSPImm(opcode, eEncodingA1); 9729 9730 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 9731 // instructions; 9732 if (Rd == 15 && setflags) 9733 return EmulateSUBSPcLrEtc(opcode, encoding); 9734 break; 9735 default: 9736 return false; 9737 } 9738 // Read the register value from the operand register Rn. 9739 uint32_t reg_val = ReadCoreReg(Rn, &success); 9740 if (!success) 9741 return false; 9742 9743 AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1); 9744 9745 EmulateInstruction::Context context; 9746 if (Rd == 13) 9747 context.type = EmulateInstruction::eContextAdjustStackPointer; 9748 else 9749 context.type = EmulateInstruction::eContextRegisterPlusOffset; 9750 9751 RegisterInfo dwarf_reg; 9752 GetRegisterInfo(eRegisterKindDWARF, Rn, dwarf_reg); 9753 int64_t imm32_signed = imm32; 9754 context.SetRegisterPlusOffset(dwarf_reg, -imm32_signed); 9755 9756 if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, 9757 res.carry_out, res.overflow)) 9758 return false; 9759 } 9760 return true; 9761} 9762 9763// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a 9764// register value and an immediate value. It updates the condition flags based 9765// on the result, and discards the result. 9766bool EmulateInstructionARM::EmulateTEQImm(const uint32_t opcode, 9767 const ARMEncoding encoding) { 9768#if 0 9769 // ARM pseudo code... 9770 if ConditionPassed() then 9771 EncodingSpecificOperations(); 9772 result = R[n] EOR imm32; 9773 APSR.N = result<31>; 9774 APSR.Z = IsZeroBit(result); 9775 APSR.C = carry; 9776 // APSR.V unchanged 9777#endif 9778 9779 bool success = false; 9780 9781 if (ConditionPassed(opcode)) { 9782 uint32_t Rn; 9783 uint32_t 9784 imm32; // the immediate value to be ANDed to the value obtained from Rn 9785 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9786 switch (encoding) { 9787 case eEncodingT1: 9788 Rn = Bits32(opcode, 19, 16); 9789 imm32 = ThumbExpandImm_C( 9790 opcode, APSR_C, 9791 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9792 if (BadReg(Rn)) 9793 return false; 9794 break; 9795 case eEncodingA1: 9796 Rn = Bits32(opcode, 19, 16); 9797 imm32 = 9798 ARMExpandImm_C(opcode, APSR_C, 9799 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9800 break; 9801 default: 9802 return false; 9803 } 9804 9805 // Read the first operand. 9806 uint32_t val1 = ReadCoreReg(Rn, &success); 9807 if (!success) 9808 return false; 9809 9810 uint32_t result = val1 ^ imm32; 9811 9812 EmulateInstruction::Context context; 9813 context.type = EmulateInstruction::eContextImmediate; 9814 context.SetNoArgs(); 9815 9816 if (!WriteFlags(context, result, carry)) 9817 return false; 9818 } 9819 return true; 9820} 9821 9822// Test Equivalence (register) performs a bitwise exclusive OR operation on a 9823// register value and an optionally-shifted register value. It updates the 9824// condition flags based on the result, and discards the result. 9825bool EmulateInstructionARM::EmulateTEQReg(const uint32_t opcode, 9826 const ARMEncoding encoding) { 9827#if 0 9828 // ARM pseudo code... 9829 if ConditionPassed() then 9830 EncodingSpecificOperations(); 9831 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9832 result = R[n] EOR shifted; 9833 APSR.N = result<31>; 9834 APSR.Z = IsZeroBit(result); 9835 APSR.C = carry; 9836 // APSR.V unchanged 9837#endif 9838 9839 bool success = false; 9840 9841 if (ConditionPassed(opcode)) { 9842 uint32_t Rn, Rm; 9843 ARM_ShifterType shift_t; 9844 uint32_t shift_n; // the shift applied to the value read from Rm 9845 uint32_t carry; 9846 switch (encoding) { 9847 case eEncodingT1: 9848 Rn = Bits32(opcode, 19, 16); 9849 Rm = Bits32(opcode, 3, 0); 9850 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9851 if (BadReg(Rn) || BadReg(Rm)) 9852 return false; 9853 break; 9854 case eEncodingA1: 9855 Rn = Bits32(opcode, 19, 16); 9856 Rm = Bits32(opcode, 3, 0); 9857 shift_n = DecodeImmShiftARM(opcode, shift_t); 9858 break; 9859 default: 9860 return false; 9861 } 9862 9863 // Read the first operand. 9864 uint32_t val1 = ReadCoreReg(Rn, &success); 9865 if (!success) 9866 return false; 9867 9868 // Read the second operand. 9869 uint32_t val2 = ReadCoreReg(Rm, &success); 9870 if (!success) 9871 return false; 9872 9873 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 9874 if (!success) 9875 return false; 9876 uint32_t result = val1 ^ shifted; 9877 9878 EmulateInstruction::Context context; 9879 context.type = EmulateInstruction::eContextImmediate; 9880 context.SetNoArgs(); 9881 9882 if (!WriteFlags(context, result, carry)) 9883 return false; 9884 } 9885 return true; 9886} 9887 9888// Test (immediate) performs a bitwise AND operation on a register value and an 9889// immediate value. It updates the condition flags based on the result, and 9890// discards the result. 9891bool EmulateInstructionARM::EmulateTSTImm(const uint32_t opcode, 9892 const ARMEncoding encoding) { 9893#if 0 9894 // ARM pseudo code... 9895 if ConditionPassed() then 9896 EncodingSpecificOperations(); 9897 result = R[n] AND imm32; 9898 APSR.N = result<31>; 9899 APSR.Z = IsZeroBit(result); 9900 APSR.C = carry; 9901 // APSR.V unchanged 9902#endif 9903 9904 bool success = false; 9905 9906 if (ConditionPassed(opcode)) { 9907 uint32_t Rn; 9908 uint32_t 9909 imm32; // the immediate value to be ANDed to the value obtained from Rn 9910 uint32_t carry; // the carry bit after ARM/Thumb Expand operation 9911 switch (encoding) { 9912 case eEncodingT1: 9913 Rn = Bits32(opcode, 19, 16); 9914 imm32 = ThumbExpandImm_C( 9915 opcode, APSR_C, 9916 carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C) 9917 if (BadReg(Rn)) 9918 return false; 9919 break; 9920 case eEncodingA1: 9921 Rn = Bits32(opcode, 19, 16); 9922 imm32 = 9923 ARMExpandImm_C(opcode, APSR_C, 9924 carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C) 9925 break; 9926 default: 9927 return false; 9928 } 9929 9930 // Read the first operand. 9931 uint32_t val1 = ReadCoreReg(Rn, &success); 9932 if (!success) 9933 return false; 9934 9935 uint32_t result = val1 & imm32; 9936 9937 EmulateInstruction::Context context; 9938 context.type = EmulateInstruction::eContextImmediate; 9939 context.SetNoArgs(); 9940 9941 if (!WriteFlags(context, result, carry)) 9942 return false; 9943 } 9944 return true; 9945} 9946 9947// Test (register) performs a bitwise AND operation on a register value and an 9948// optionally-shifted register value. It updates the condition flags based on 9949// the result, and discards the result. 9950bool EmulateInstructionARM::EmulateTSTReg(const uint32_t opcode, 9951 const ARMEncoding encoding) { 9952#if 0 9953 // ARM pseudo code... 9954 if ConditionPassed() then 9955 EncodingSpecificOperations(); 9956 (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C); 9957 result = R[n] AND shifted; 9958 APSR.N = result<31>; 9959 APSR.Z = IsZeroBit(result); 9960 APSR.C = carry; 9961 // APSR.V unchanged 9962#endif 9963 9964 bool success = false; 9965 9966 if (ConditionPassed(opcode)) { 9967 uint32_t Rn, Rm; 9968 ARM_ShifterType shift_t; 9969 uint32_t shift_n; // the shift applied to the value read from Rm 9970 uint32_t carry; 9971 switch (encoding) { 9972 case eEncodingT1: 9973 Rn = Bits32(opcode, 2, 0); 9974 Rm = Bits32(opcode, 5, 3); 9975 shift_t = SRType_LSL; 9976 shift_n = 0; 9977 break; 9978 case eEncodingT2: 9979 Rn = Bits32(opcode, 19, 16); 9980 Rm = Bits32(opcode, 3, 0); 9981 shift_n = DecodeImmShiftThumb(opcode, shift_t); 9982 if (BadReg(Rn) || BadReg(Rm)) 9983 return false; 9984 break; 9985 case eEncodingA1: 9986 Rn = Bits32(opcode, 19, 16); 9987 Rm = Bits32(opcode, 3, 0); 9988 shift_n = DecodeImmShiftARM(opcode, shift_t); 9989 break; 9990 default: 9991 return false; 9992 } 9993 9994 // Read the first operand. 9995 uint32_t val1 = ReadCoreReg(Rn, &success); 9996 if (!success) 9997 return false; 9998 9999 // Read the second operand. 10000 uint32_t val2 = ReadCoreReg(Rm, &success); 10001 if (!success) 10002 return false; 10003 10004 uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success); 10005 if (!success) 10006 return false; 10007 uint32_t result = val1 & shifted; 10008 10009 EmulateInstruction::Context context; 10010 context.type = EmulateInstruction::eContextImmediate; 10011 context.SetNoArgs(); 10012 10013 if (!WriteFlags(context, result, carry)) 10014 return false; 10015 } 10016 return true; 10017} 10018 10019// A8.6.216 SUB (SP minus register) 10020bool EmulateInstructionARM::EmulateSUBSPReg(const uint32_t opcode, 10021 const ARMEncoding encoding) { 10022#if 0 10023 if ConditionPassed() then 10024 EncodingSpecificOperations(); 10025 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10026 (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10027 if d == 15 then // Can only occur for ARM encoding 10028 ALUWritePC(result); // setflags is always FALSE here 10029 else 10030 R[d] = result; 10031 if setflags then 10032 APSR.N = result<31>; 10033 APSR.Z = IsZeroBit(result); 10034 APSR.C = carry; 10035 APSR.V = overflow; 10036#endif 10037 10038 bool success = false; 10039 10040 if (ConditionPassed(opcode)) { 10041 uint32_t d; 10042 uint32_t m; 10043 bool setflags; 10044 ARM_ShifterType shift_t; 10045 uint32_t shift_n; 10046 10047 switch (encoding) { 10048 case eEncodingT1: 10049 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10050 d = Bits32(opcode, 11, 8); 10051 m = Bits32(opcode, 3, 0); 10052 setflags = BitIsSet(opcode, 20); 10053 10054 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10055 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10056 10057 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then 10058 // UNPREDICTABLE; 10059 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3))) 10060 return false; 10061 10062 // if d == 15 || BadReg(m) then UNPREDICTABLE; 10063 if ((d == 15) || BadReg(m)) 10064 return false; 10065 break; 10066 10067 case eEncodingA1: 10068 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1'); 10069 d = Bits32(opcode, 15, 12); 10070 m = Bits32(opcode, 3, 0); 10071 setflags = BitIsSet(opcode, 20); 10072 10073 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10074 // instructions; 10075 if (d == 15 && setflags) 10076 EmulateSUBSPcLrEtc(opcode, encoding); 10077 10078 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10079 shift_n = DecodeImmShiftARM(opcode, shift_t); 10080 break; 10081 10082 default: 10083 return false; 10084 } 10085 10086 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10087 uint32_t Rm = ReadCoreReg(m, &success); 10088 if (!success) 10089 return false; 10090 10091 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10092 if (!success) 10093 return false; 10094 10095 // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1'); 10096 uint32_t sp_val = ReadCoreReg(SP_REG, &success); 10097 if (!success) 10098 return false; 10099 10100 AddWithCarryResult res = AddWithCarry(sp_val, ~shifted, 1); 10101 10102 EmulateInstruction::Context context; 10103 context.type = eContextArithmetic; 10104 RegisterInfo sp_reg; 10105 GetRegisterInfo(eRegisterKindDWARF, dwarf_sp, sp_reg); 10106 RegisterInfo dwarf_reg; 10107 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg); 10108 context.SetRegisterRegisterOperands(sp_reg, dwarf_reg); 10109 10110 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10111 res.carry_out, res.overflow)) 10112 return false; 10113 } 10114 return true; 10115} 10116 10117// A8.6.7 ADD (register-shifted register) 10118bool EmulateInstructionARM::EmulateADDRegShift(const uint32_t opcode, 10119 const ARMEncoding encoding) { 10120#if 0 10121 if ConditionPassed() then 10122 EncodingSpecificOperations(); 10123 shift_n = UInt(R[s]<7:0>); 10124 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10125 (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10126 R[d] = result; 10127 if setflags then 10128 APSR.N = result<31>; 10129 APSR.Z = IsZeroBit(result); 10130 APSR.C = carry; 10131 APSR.V = overflow; 10132#endif 10133 10134 bool success = false; 10135 10136 if (ConditionPassed(opcode)) { 10137 uint32_t d; 10138 uint32_t n; 10139 uint32_t m; 10140 uint32_t s; 10141 bool setflags; 10142 ARM_ShifterType shift_t; 10143 10144 switch (encoding) { 10145 case eEncodingA1: 10146 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs); 10147 d = Bits32(opcode, 15, 12); 10148 n = Bits32(opcode, 19, 16); 10149 m = Bits32(opcode, 3, 0); 10150 s = Bits32(opcode, 11, 8); 10151 10152 // setflags = (S == '1'); shift_t = DecodeRegShift(type); 10153 setflags = BitIsSet(opcode, 20); 10154 shift_t = DecodeRegShift(Bits32(opcode, 6, 5)); 10155 10156 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE; 10157 if ((d == 15) || (n == 15) || (m == 15) || (s == 15)) 10158 return false; 10159 break; 10160 10161 default: 10162 return false; 10163 } 10164 10165 // shift_n = UInt(R[s]<7:0>); 10166 uint32_t Rs = ReadCoreReg(s, &success); 10167 if (!success) 10168 return false; 10169 10170 uint32_t shift_n = Bits32(Rs, 7, 0); 10171 10172 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10173 uint32_t Rm = ReadCoreReg(m, &success); 10174 if (!success) 10175 return false; 10176 10177 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10178 if (!success) 10179 return false; 10180 10181 // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0'); 10182 uint32_t Rn = ReadCoreReg(n, &success); 10183 if (!success) 10184 return false; 10185 10186 AddWithCarryResult res = AddWithCarry(Rn, shifted, 0); 10187 10188 // R[d] = result; 10189 EmulateInstruction::Context context; 10190 context.type = eContextArithmetic; 10191 RegisterInfo reg_n; 10192 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10193 RegisterInfo reg_m; 10194 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10195 10196 context.SetRegisterRegisterOperands(reg_n, reg_m); 10197 10198 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 10199 res.result)) 10200 return false; 10201 10202 // if setflags then 10203 // APSR.N = result<31>; 10204 // APSR.Z = IsZeroBit(result); 10205 // APSR.C = carry; 10206 // APSR.V = overflow; 10207 if (setflags) 10208 return WriteFlags(context, res.result, res.carry_out, res.overflow); 10209 } 10210 return true; 10211} 10212 10213// A8.6.213 SUB (register) 10214bool EmulateInstructionARM::EmulateSUBReg(const uint32_t opcode, 10215 const ARMEncoding encoding) { 10216#if 0 10217 if ConditionPassed() then 10218 EncodingSpecificOperations(); 10219 shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10220 (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10221 if d == 15 then // Can only occur for ARM encoding 10222 ALUWritePC(result); // setflags is always FALSE here 10223 else 10224 R[d] = result; 10225 if setflags then 10226 APSR.N = result<31>; 10227 APSR.Z = IsZeroBit(result); 10228 APSR.C = carry; 10229 APSR.V = overflow; 10230#endif 10231 10232 bool success = false; 10233 10234 if (ConditionPassed(opcode)) { 10235 uint32_t d; 10236 uint32_t n; 10237 uint32_t m; 10238 bool setflags; 10239 ARM_ShifterType shift_t; 10240 uint32_t shift_n; 10241 10242 switch (encoding) { 10243 case eEncodingT1: 10244 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock(); 10245 d = Bits32(opcode, 2, 0); 10246 n = Bits32(opcode, 5, 3); 10247 m = Bits32(opcode, 8, 6); 10248 setflags = !InITBlock(); 10249 10250 // (shift_t, shift_n) = (SRType_LSL, 0); 10251 shift_t = SRType_LSL; 10252 shift_n = 0; 10253 10254 break; 10255 10256 case eEncodingT2: 10257 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1"); 10258 d = Bits32(opcode, 11, 8); 10259 n = Bits32(opcode, 19, 16); 10260 m = Bits32(opcode, 3, 0); 10261 setflags = BitIsSet(opcode, 20); 10262 10263 // if Rd == "1111" && S == "1" then SEE CMP (register); 10264 if (d == 15 && setflags == 1) 10265 return EmulateCMPImm(opcode, eEncodingT3); 10266 10267 // if Rn == "1101" then SEE SUB (SP minus register); 10268 if (n == 13) 10269 return EmulateSUBSPReg(opcode, eEncodingT1); 10270 10271 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2); 10272 shift_n = DecodeImmShiftThumb(opcode, shift_t); 10273 10274 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then 10275 // UNPREDICTABLE; 10276 if ((d == 13) || ((d == 15) && BitIsClear(opcode, 20)) || (n == 15) || 10277 BadReg(m)) 10278 return false; 10279 10280 break; 10281 10282 case eEncodingA1: 10283 // if Rn == '1101' then SEE SUB (SP minus register); 10284 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1'); 10285 d = Bits32(opcode, 15, 12); 10286 n = Bits32(opcode, 19, 16); 10287 m = Bits32(opcode, 3, 0); 10288 setflags = BitIsSet(opcode, 20); 10289 10290 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related 10291 // instructions; 10292 if ((d == 15) && setflags) 10293 EmulateSUBSPcLrEtc(opcode, encoding); 10294 10295 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 10296 shift_n = DecodeImmShiftARM(opcode, shift_t); 10297 10298 break; 10299 10300 default: 10301 return false; 10302 } 10303 10304 // shifted = Shift(R[m], shift_t, shift_n, APSR.C); 10305 uint32_t Rm = ReadCoreReg(m, &success); 10306 if (!success) 10307 return false; 10308 10309 uint32_t shifted = Shift(Rm, shift_t, shift_n, APSR_C, &success); 10310 if (!success) 10311 return false; 10312 10313 // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1'); 10314 uint32_t Rn = ReadCoreReg(n, &success); 10315 if (!success) 10316 return false; 10317 10318 AddWithCarryResult res = AddWithCarry(Rn, ~shifted, 1); 10319 10320 // if d == 15 then // Can only occur for ARM encoding ALUWritePC(result); 10321 // // setflags is always FALSE here else 10322 // R[d] = result; 10323 // if setflags then 10324 // APSR.N = result<31>; 10325 // APSR.Z = IsZeroBit(result); 10326 // APSR.C = carry; 10327 // APSR.V = overflow; 10328 10329 EmulateInstruction::Context context; 10330 context.type = eContextArithmetic; 10331 RegisterInfo reg_n; 10332 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, reg_n); 10333 RegisterInfo reg_m; 10334 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, reg_m); 10335 context.SetRegisterRegisterOperands(reg_n, reg_m); 10336 10337 if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, 10338 res.carry_out, res.overflow)) 10339 return false; 10340 } 10341 return true; 10342} 10343 10344// A8.6.202 STREX 10345// Store Register Exclusive calculates an address from a base register value 10346// and an immediate offset, and stores a word from a register to memory if the 10347// executing processor has exclusive access to the memory addressed. 10348bool EmulateInstructionARM::EmulateSTREX(const uint32_t opcode, 10349 const ARMEncoding encoding) { 10350#if 0 10351 if ConditionPassed() then 10352 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10353 address = R[n] + imm32; 10354 if ExclusiveMonitorsPass(address,4) then 10355 MemA[address,4] = R[t]; 10356 R[d] = 0; 10357 else 10358 R[d] = 1; 10359#endif 10360 10361 bool success = false; 10362 10363 if (ConditionPassed(opcode)) { 10364 uint32_t d; 10365 uint32_t t; 10366 uint32_t n; 10367 uint32_t imm32; 10368 const uint32_t addr_byte_size = GetAddressByteSize(); 10369 10370 switch (encoding) { 10371 case eEncodingT1: 10372 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = 10373 // ZeroExtend(imm8:'00', 10374 // 32); 10375 d = Bits32(opcode, 11, 8); 10376 t = Bits32(opcode, 15, 12); 10377 n = Bits32(opcode, 19, 16); 10378 imm32 = Bits32(opcode, 7, 0) << 2; 10379 10380 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE; 10381 if (BadReg(d) || BadReg(t) || (n == 15)) 10382 return false; 10383 10384 // if d == n || d == t then UNPREDICTABLE; 10385 if ((d == n) || (d == t)) 10386 return false; 10387 10388 break; 10389 10390 case eEncodingA1: 10391 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero 10392 // offset 10393 d = Bits32(opcode, 15, 12); 10394 t = Bits32(opcode, 3, 0); 10395 n = Bits32(opcode, 19, 16); 10396 imm32 = 0; 10397 10398 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; 10399 if ((d == 15) || (t == 15) || (n == 15)) 10400 return false; 10401 10402 // if d == n || d == t then UNPREDICTABLE; 10403 if ((d == n) || (d == t)) 10404 return false; 10405 10406 break; 10407 10408 default: 10409 return false; 10410 } 10411 10412 // address = R[n] + imm32; 10413 uint32_t Rn = ReadCoreReg(n, &success); 10414 if (!success) 10415 return false; 10416 10417 addr_t address = Rn + imm32; 10418 10419 RegisterInfo base_reg; 10420 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10421 RegisterInfo data_reg; 10422 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10423 EmulateInstruction::Context context; 10424 context.type = eContextRegisterStore; 10425 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, imm32); 10426 10427 // if ExclusiveMonitorsPass(address,4) then if (ExclusiveMonitorsPass 10428 // (address, addr_byte_size)) -- For now, for the sake of emulation, we 10429 // will say this 10430 // always return 10431 // true. 10432 if (true) { 10433 // MemA[address,4] = R[t]; 10434 uint32_t Rt = 10435 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_r0 + t, 0, &success); 10436 if (!success) 10437 return false; 10438 10439 if (!MemAWrite(context, address, Rt, addr_byte_size)) 10440 return false; 10441 10442 // R[d] = 0; 10443 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, 0)) 10444 return false; 10445 } 10446#if 0 // unreachable because if true 10447 else 10448 { 10449 // R[d] = 1; 10450 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1)) 10451 return false; 10452 } 10453#endif // unreachable because if true 10454 } 10455 return true; 10456} 10457 10458// A8.6.197 STRB (immediate, ARM) 10459bool EmulateInstructionARM::EmulateSTRBImmARM(const uint32_t opcode, 10460 const ARMEncoding encoding) { 10461#if 0 10462 if ConditionPassed() then 10463 EncodingSpecificOperations(); 10464 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10465 address = if index then offset_addr else R[n]; 10466 MemU[address,1] = R[t]<7:0>; 10467 if wback then R[n] = offset_addr; 10468#endif 10469 10470 bool success = false; 10471 10472 if (ConditionPassed(opcode)) { 10473 uint32_t t; 10474 uint32_t n; 10475 uint32_t imm32; 10476 bool index; 10477 bool add; 10478 bool wback; 10479 10480 switch (encoding) { 10481 case eEncodingA1: 10482 // if P == '0' && W == '1' then SEE STRBT; 10483 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10484 t = Bits32(opcode, 15, 12); 10485 n = Bits32(opcode, 19, 16); 10486 imm32 = Bits32(opcode, 11, 0); 10487 10488 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10489 index = BitIsSet(opcode, 24); 10490 add = BitIsSet(opcode, 23); 10491 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10492 10493 // if t == 15 then UNPREDICTABLE; 10494 if (t == 15) 10495 return false; 10496 10497 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10498 if (wback && ((n == 15) || (n == t))) 10499 return false; 10500 10501 break; 10502 10503 default: 10504 return false; 10505 } 10506 10507 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10508 uint32_t Rn = ReadCoreReg(n, &success); 10509 if (!success) 10510 return false; 10511 10512 addr_t offset_addr; 10513 if (add) 10514 offset_addr = Rn + imm32; 10515 else 10516 offset_addr = Rn - imm32; 10517 10518 // address = if index then offset_addr else R[n]; 10519 addr_t address; 10520 if (index) 10521 address = offset_addr; 10522 else 10523 address = Rn; 10524 10525 // MemU[address,1] = R[t]<7:0>; 10526 uint32_t Rt = ReadCoreReg(t, &success); 10527 if (!success) 10528 return false; 10529 10530 RegisterInfo base_reg; 10531 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10532 RegisterInfo data_reg; 10533 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10534 EmulateInstruction::Context context; 10535 context.type = eContextRegisterStore; 10536 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10537 10538 if (!MemUWrite(context, address, Bits32(Rt, 7, 0), 1)) 10539 return false; 10540 10541 // if wback then R[n] = offset_addr; 10542 if (wback) { 10543 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10544 offset_addr)) 10545 return false; 10546 } 10547 } 10548 return true; 10549} 10550 10551// A8.6.194 STR (immediate, ARM) 10552bool EmulateInstructionARM::EmulateSTRImmARM(const uint32_t opcode, 10553 const ARMEncoding encoding) { 10554#if 0 10555 if ConditionPassed() then 10556 EncodingSpecificOperations(); 10557 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10558 address = if index then offset_addr else R[n]; 10559 MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10560 if wback then R[n] = offset_addr; 10561#endif 10562 10563 bool success = false; 10564 10565 if (ConditionPassed(opcode)) { 10566 uint32_t t; 10567 uint32_t n; 10568 uint32_t imm32; 10569 bool index; 10570 bool add; 10571 bool wback; 10572 10573 const uint32_t addr_byte_size = GetAddressByteSize(); 10574 10575 switch (encoding) { 10576 case eEncodingA1: 10577 // if P == '0' && W == '1' then SEE STRT; 10578 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == 10579 // '000000000100' then SEE PUSH; 10580 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); 10581 t = Bits32(opcode, 15, 12); 10582 n = Bits32(opcode, 19, 16); 10583 imm32 = Bits32(opcode, 11, 0); 10584 10585 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10586 index = BitIsSet(opcode, 24); 10587 add = BitIsSet(opcode, 23); 10588 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10589 10590 // if wback && (n == 15 || n == t) then UNPREDICTABLE; 10591 if (wback && ((n == 15) || (n == t))) 10592 return false; 10593 10594 break; 10595 10596 default: 10597 return false; 10598 } 10599 10600 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10601 uint32_t Rn = ReadCoreReg(n, &success); 10602 if (!success) 10603 return false; 10604 10605 addr_t offset_addr; 10606 if (add) 10607 offset_addr = Rn + imm32; 10608 else 10609 offset_addr = Rn - imm32; 10610 10611 // address = if index then offset_addr else R[n]; 10612 addr_t address; 10613 if (index) 10614 address = offset_addr; 10615 else 10616 address = Rn; 10617 10618 RegisterInfo base_reg; 10619 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10620 RegisterInfo data_reg; 10621 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 10622 EmulateInstruction::Context context; 10623 context.type = eContextRegisterStore; 10624 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 10625 10626 // MemU[address,4] = if t == 15 then PCStoreValue() else R[t]; 10627 uint32_t Rt = ReadCoreReg(t, &success); 10628 if (!success) 10629 return false; 10630 10631 if (t == 15) { 10632 uint32_t pc_value = ReadCoreReg(PC_REG, &success); 10633 if (!success) 10634 return false; 10635 10636 if (!MemUWrite(context, address, pc_value, addr_byte_size)) 10637 return false; 10638 } else { 10639 if (!MemUWrite(context, address, Rt, addr_byte_size)) 10640 return false; 10641 } 10642 10643 // if wback then R[n] = offset_addr; 10644 if (wback) { 10645 context.type = eContextAdjustBaseRegister; 10646 context.SetImmediate(offset_addr); 10647 10648 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10649 offset_addr)) 10650 return false; 10651 } 10652 } 10653 return true; 10654} 10655 10656// A8.6.66 LDRD (immediate) 10657// Load Register Dual (immediate) calculates an address from a base register 10658// value and an immediate offset, loads two words from memory, and writes them 10659// to two registers. It can use offset, post-indexed, or pre-indexed 10660// addressing. 10661bool EmulateInstructionARM::EmulateLDRDImmediate(const uint32_t opcode, 10662 const ARMEncoding encoding) { 10663#if 0 10664 if ConditionPassed() then 10665 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10666 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10667 address = if index then offset_addr else R[n]; 10668 R[t] = MemA[address,4]; 10669 R[t2] = MemA[address+4,4]; 10670 if wback then R[n] = offset_addr; 10671#endif 10672 10673 bool success = false; 10674 10675 if (ConditionPassed(opcode)) { 10676 uint32_t t; 10677 uint32_t t2; 10678 uint32_t n; 10679 uint32_t imm32; 10680 bool index; 10681 bool add; 10682 bool wback; 10683 10684 switch (encoding) { 10685 case eEncodingT1: 10686 // if P == '0' && W == '0' then SEE 'Related encodings'; 10687 // if Rn == '1111' then SEE LDRD (literal); 10688 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10689 // ZeroExtend(imm8:'00', 32); 10690 t = Bits32(opcode, 15, 12); 10691 t2 = Bits32(opcode, 11, 8); 10692 n = Bits32(opcode, 19, 16); 10693 imm32 = Bits32(opcode, 7, 0) << 2; 10694 10695 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10696 index = BitIsSet(opcode, 24); 10697 add = BitIsSet(opcode, 23); 10698 wback = BitIsSet(opcode, 21); 10699 10700 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10701 if (wback && ((n == t) || (n == t2))) 10702 return false; 10703 10704 // if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE; 10705 if (BadReg(t) || BadReg(t2) || (t == t2)) 10706 return false; 10707 10708 break; 10709 10710 case eEncodingA1: 10711 // if Rn == '1111' then SEE LDRD (literal); 10712 // if Rt<0> == '1' then UNPREDICTABLE; 10713 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10714 // 32); 10715 t = Bits32(opcode, 15, 12); 10716 if (BitIsSet(t, 0)) 10717 return false; 10718 t2 = t + 1; 10719 n = Bits32(opcode, 19, 16); 10720 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10721 10722 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10723 index = BitIsSet(opcode, 24); 10724 add = BitIsSet(opcode, 23); 10725 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10726 10727 // if P == '0' && W == '1' then UNPREDICTABLE; 10728 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10729 return false; 10730 10731 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10732 if (wback && ((n == t) || (n == t2))) 10733 return false; 10734 10735 // if t2 == 15 then UNPREDICTABLE; 10736 if (t2 == 15) 10737 return false; 10738 10739 break; 10740 10741 default: 10742 return false; 10743 } 10744 10745 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10746 uint32_t Rn = ReadCoreReg(n, &success); 10747 if (!success) 10748 return false; 10749 10750 addr_t offset_addr; 10751 if (add) 10752 offset_addr = Rn + imm32; 10753 else 10754 offset_addr = Rn - imm32; 10755 10756 // address = if index then offset_addr else R[n]; 10757 addr_t address; 10758 if (index) 10759 address = offset_addr; 10760 else 10761 address = Rn; 10762 10763 // R[t] = MemA[address,4]; 10764 RegisterInfo base_reg; 10765 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10766 10767 EmulateInstruction::Context context; 10768 if (n == 13) 10769 context.type = eContextPopRegisterOffStack; 10770 else 10771 context.type = eContextRegisterLoad; 10772 context.SetAddress(address); 10773 10774 const uint32_t addr_byte_size = GetAddressByteSize(); 10775 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10776 if (!success) 10777 return false; 10778 10779 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10780 return false; 10781 10782 // R[t2] = MemA[address+4,4]; 10783 context.SetAddress(address + 4); 10784 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10785 if (!success) 10786 return false; 10787 10788 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10789 data)) 10790 return false; 10791 10792 // if wback then R[n] = offset_addr; 10793 if (wback) { 10794 context.type = eContextAdjustBaseRegister; 10795 context.SetAddress(offset_addr); 10796 10797 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10798 offset_addr)) 10799 return false; 10800 } 10801 } 10802 return true; 10803} 10804 10805// A8.6.68 LDRD (register) 10806// Load Register Dual (register) calculates an address from a base register 10807// value and a register offset, loads two words from memory, and writes them to 10808// two registers. It can use offset, post-indexed or pre-indexed addressing. 10809bool EmulateInstructionARM::EmulateLDRDRegister(const uint32_t opcode, 10810 const ARMEncoding encoding) { 10811#if 0 10812 if ConditionPassed() then 10813 EncodingSpecificOperations(); 10814 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10815 address = if index then offset_addr else R[n]; 10816 R[t] = MemA[address,4]; 10817 R[t2] = MemA[address+4,4]; 10818 if wback then R[n] = offset_addr; 10819#endif 10820 10821 bool success = false; 10822 10823 if (ConditionPassed(opcode)) { 10824 uint32_t t; 10825 uint32_t t2; 10826 uint32_t n; 10827 uint32_t m; 10828 bool index; 10829 bool add; 10830 bool wback; 10831 10832 switch (encoding) { 10833 case eEncodingA1: 10834 // if Rt<0> == '1' then UNPREDICTABLE; 10835 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 10836 t = Bits32(opcode, 15, 12); 10837 if (BitIsSet(t, 0)) 10838 return false; 10839 t2 = t + 1; 10840 n = Bits32(opcode, 19, 16); 10841 m = Bits32(opcode, 3, 0); 10842 10843 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10844 index = BitIsSet(opcode, 24); 10845 add = BitIsSet(opcode, 23); 10846 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 10847 10848 // if P == '0' && W == '1' then UNPREDICTABLE; 10849 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 10850 return false; 10851 10852 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE; 10853 if ((t2 == 15) || (m == 15) || (m == t) || (m == t2)) 10854 return false; 10855 10856 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 10857 if (wback && ((n == 15) || (n == t) || (n == t2))) 10858 return false; 10859 10860 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 10861 if ((ArchVersion() < 6) && wback && (m == n)) 10862 return false; 10863 break; 10864 10865 default: 10866 return false; 10867 } 10868 10869 uint32_t Rn = ReadCoreReg(n, &success); 10870 if (!success) 10871 return false; 10872 RegisterInfo base_reg; 10873 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 10874 10875 uint32_t Rm = ReadCoreReg(m, &success); 10876 if (!success) 10877 return false; 10878 RegisterInfo offset_reg; 10879 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 10880 10881 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 10882 addr_t offset_addr; 10883 if (add) 10884 offset_addr = Rn + Rm; 10885 else 10886 offset_addr = Rn - Rm; 10887 10888 // address = if index then offset_addr else R[n]; 10889 addr_t address; 10890 if (index) 10891 address = offset_addr; 10892 else 10893 address = Rn; 10894 10895 EmulateInstruction::Context context; 10896 if (n == 13) 10897 context.type = eContextPopRegisterOffStack; 10898 else 10899 context.type = eContextRegisterLoad; 10900 context.SetAddress(address); 10901 10902 // R[t] = MemA[address,4]; 10903 const uint32_t addr_byte_size = GetAddressByteSize(); 10904 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 10905 if (!success) 10906 return false; 10907 10908 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t, data)) 10909 return false; 10910 10911 // R[t2] = MemA[address+4,4]; 10912 10913 data = MemARead(context, address + 4, addr_byte_size, 0, &success); 10914 if (!success) 10915 return false; 10916 10917 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + t2, 10918 data)) 10919 return false; 10920 10921 // if wback then R[n] = offset_addr; 10922 if (wback) { 10923 context.type = eContextAdjustBaseRegister; 10924 context.SetAddress(offset_addr); 10925 10926 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 10927 offset_addr)) 10928 return false; 10929 } 10930 } 10931 return true; 10932} 10933 10934// A8.6.200 STRD (immediate) 10935// Store Register Dual (immediate) calculates an address from a base register 10936// value and an immediate offset, and stores two words from two registers to 10937// memory. It can use offset, post-indexed, or pre-indexed addressing. 10938bool EmulateInstructionARM::EmulateSTRDImm(const uint32_t opcode, 10939 const ARMEncoding encoding) { 10940#if 0 10941 if ConditionPassed() then 10942 EncodingSpecificOperations(); NullCheckIfThumbEE(n); 10943 offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 10944 address = if index then offset_addr else R[n]; 10945 MemA[address,4] = R[t]; 10946 MemA[address+4,4] = R[t2]; 10947 if wback then R[n] = offset_addr; 10948#endif 10949 10950 bool success = false; 10951 10952 if (ConditionPassed(opcode)) { 10953 uint32_t t; 10954 uint32_t t2; 10955 uint32_t n; 10956 uint32_t imm32; 10957 bool index; 10958 bool add; 10959 bool wback; 10960 10961 switch (encoding) { 10962 case eEncodingT1: 10963 // if P == '0' && W == '0' then SEE 'Related encodings'; 10964 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = 10965 // ZeroExtend(imm8:'00', 32); 10966 t = Bits32(opcode, 15, 12); 10967 t2 = Bits32(opcode, 11, 8); 10968 n = Bits32(opcode, 19, 16); 10969 imm32 = Bits32(opcode, 7, 0) << 2; 10970 10971 // index = (P == '1'); add = (U == '1'); wback = (W == '1'); 10972 index = BitIsSet(opcode, 24); 10973 add = BitIsSet(opcode, 23); 10974 wback = BitIsSet(opcode, 21); 10975 10976 // if wback && (n == t || n == t2) then UNPREDICTABLE; 10977 if (wback && ((n == t) || (n == t2))) 10978 return false; 10979 10980 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE; 10981 if ((n == 15) || BadReg(t) || BadReg(t2)) 10982 return false; 10983 10984 break; 10985 10986 case eEncodingA1: 10987 // if Rt<0> == '1' then UNPREDICTABLE; 10988 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 10989 // 32); 10990 t = Bits32(opcode, 15, 12); 10991 if (BitIsSet(t, 0)) 10992 return false; 10993 10994 t2 = t + 1; 10995 n = Bits32(opcode, 19, 16); 10996 imm32 = (Bits32(opcode, 11, 8) << 4) | Bits32(opcode, 3, 0); 10997 10998 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 10999 index = BitIsSet(opcode, 24); 11000 add = BitIsSet(opcode, 23); 11001 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11002 11003 // if P == '0' && W == '1' then UNPREDICTABLE; 11004 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11005 return false; 11006 11007 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11008 if (wback && ((n == 15) || (n == t) || (n == t2))) 11009 return false; 11010 11011 // if t2 == 15 then UNPREDICTABLE; 11012 if (t2 == 15) 11013 return false; 11014 11015 break; 11016 11017 default: 11018 return false; 11019 } 11020 11021 RegisterInfo base_reg; 11022 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11023 11024 uint32_t Rn = ReadCoreReg(n, &success); 11025 if (!success) 11026 return false; 11027 11028 // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32); 11029 addr_t offset_addr; 11030 if (add) 11031 offset_addr = Rn + imm32; 11032 else 11033 offset_addr = Rn - imm32; 11034 11035 // address = if index then offset_addr else R[n]; 11036 addr_t address; 11037 if (index) 11038 address = offset_addr; 11039 else 11040 address = Rn; 11041 11042 // MemA[address,4] = R[t]; 11043 RegisterInfo data_reg; 11044 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11045 11046 uint32_t data = ReadCoreReg(t, &success); 11047 if (!success) 11048 return false; 11049 11050 EmulateInstruction::Context context; 11051 if (n == 13) 11052 context.type = eContextPushRegisterOnStack; 11053 else 11054 context.type = eContextRegisterStore; 11055 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11056 11057 const uint32_t addr_byte_size = GetAddressByteSize(); 11058 11059 if (!MemAWrite(context, address, data, addr_byte_size)) 11060 return false; 11061 11062 // MemA[address+4,4] = R[t2]; 11063 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11064 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11065 (address + 4) - Rn); 11066 11067 data = ReadCoreReg(t2, &success); 11068 if (!success) 11069 return false; 11070 11071 if (!MemAWrite(context, address + 4, data, addr_byte_size)) 11072 return false; 11073 11074 // if wback then R[n] = offset_addr; 11075 if (wback) { 11076 if (n == 13) 11077 context.type = eContextAdjustStackPointer; 11078 else 11079 context.type = eContextAdjustBaseRegister; 11080 context.SetAddress(offset_addr); 11081 11082 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11083 offset_addr)) 11084 return false; 11085 } 11086 } 11087 return true; 11088} 11089 11090// A8.6.201 STRD (register) 11091bool EmulateInstructionARM::EmulateSTRDReg(const uint32_t opcode, 11092 const ARMEncoding encoding) { 11093#if 0 11094 if ConditionPassed() then 11095 EncodingSpecificOperations(); 11096 offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11097 address = if index then offset_addr else R[n]; 11098 MemA[address,4] = R[t]; 11099 MemA[address+4,4] = R[t2]; 11100 if wback then R[n] = offset_addr; 11101#endif 11102 11103 bool success = false; 11104 11105 if (ConditionPassed(opcode)) { 11106 uint32_t t; 11107 uint32_t t2; 11108 uint32_t n; 11109 uint32_t m; 11110 bool index; 11111 bool add; 11112 bool wback; 11113 11114 switch (encoding) { 11115 case eEncodingA1: 11116 // if Rt<0> == '1' then UNPREDICTABLE; 11117 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm); 11118 t = Bits32(opcode, 15, 12); 11119 if (BitIsSet(t, 0)) 11120 return false; 11121 11122 t2 = t + 1; 11123 n = Bits32(opcode, 19, 16); 11124 m = Bits32(opcode, 3, 0); 11125 11126 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); 11127 index = BitIsSet(opcode, 24); 11128 add = BitIsSet(opcode, 23); 11129 wback = BitIsClear(opcode, 24) || BitIsSet(opcode, 21); 11130 11131 // if P == '0' && W == '1' then UNPREDICTABLE; 11132 if (BitIsClear(opcode, 24) && BitIsSet(opcode, 21)) 11133 return false; 11134 11135 // if t2 == 15 || m == 15 then UNPREDICTABLE; 11136 if ((t2 == 15) || (m == 15)) 11137 return false; 11138 11139 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE; 11140 if (wback && ((n == 15) || (n == t) || (n == t2))) 11141 return false; 11142 11143 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; 11144 if ((ArchVersion() < 6) && wback && (m == n)) 11145 return false; 11146 11147 break; 11148 11149 default: 11150 return false; 11151 } 11152 11153 RegisterInfo base_reg; 11154 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11155 RegisterInfo offset_reg; 11156 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + m, offset_reg); 11157 RegisterInfo data_reg; 11158 11159 uint32_t Rn = ReadCoreReg(n, &success); 11160 if (!success) 11161 return false; 11162 11163 uint32_t Rm = ReadCoreReg(m, &success); 11164 if (!success) 11165 return false; 11166 11167 // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]); 11168 addr_t offset_addr; 11169 if (add) 11170 offset_addr = Rn + Rm; 11171 else 11172 offset_addr = Rn - Rm; 11173 11174 // address = if index then offset_addr else R[n]; 11175 addr_t address; 11176 if (index) 11177 address = offset_addr; 11178 else 11179 address = Rn; 11180 // MemA[address,4] = R[t]; 11181 uint32_t Rt = ReadCoreReg(t, &success); 11182 if (!success) 11183 return false; 11184 11185 EmulateInstruction::Context context; 11186 if (t == 13) 11187 context.type = eContextPushRegisterOnStack; 11188 else 11189 context.type = eContextRegisterStore; 11190 11191 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t, data_reg); 11192 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11193 data_reg); 11194 11195 const uint32_t addr_byte_size = GetAddressByteSize(); 11196 11197 if (!MemAWrite(context, address, Rt, addr_byte_size)) 11198 return false; 11199 11200 // MemA[address+4,4] = R[t2]; 11201 uint32_t Rt2 = ReadCoreReg(t2, &success); 11202 if (!success) 11203 return false; 11204 11205 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + t2, data_reg); 11206 11207 context.SetRegisterToRegisterPlusIndirectOffset(base_reg, offset_reg, 11208 data_reg); 11209 11210 if (!MemAWrite(context, address + 4, Rt2, addr_byte_size)) 11211 return false; 11212 11213 // if wback then R[n] = offset_addr; 11214 if (wback) { 11215 context.type = eContextAdjustBaseRegister; 11216 context.SetAddress(offset_addr); 11217 11218 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11219 offset_addr)) 11220 return false; 11221 } 11222 } 11223 return true; 11224} 11225 11226// A8.6.319 VLDM 11227// Vector Load Multiple loads multiple extension registers from consecutive 11228// memory locations using an address from an ARM core register. 11229bool EmulateInstructionARM::EmulateVLDM(const uint32_t opcode, 11230 const ARMEncoding encoding) { 11231#if 0 11232 if ConditionPassed() then 11233 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11234 address = if add then R[n] else R[n]-imm32; 11235 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11236 for r = 0 to regs-1 11237 if single_regs then 11238 S[d+r] = MemA[address,4]; address = address+4; 11239 else 11240 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8; 11241 // Combine the word-aligned words in the correct order for 11242 // current endianness. 11243 D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11244#endif 11245 11246 bool success = false; 11247 11248 if (ConditionPassed(opcode)) { 11249 bool single_regs; 11250 bool add; 11251 bool wback; 11252 uint32_t d; 11253 uint32_t n; 11254 uint32_t imm32; 11255 uint32_t regs; 11256 11257 switch (encoding) { 11258 case eEncodingT1: 11259 case eEncodingA1: 11260 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11261 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11262 // if P == '1' && W == '0' then SEE VLDR; 11263 // if P == U && W == '1' then UNDEFINED; 11264 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11265 return false; 11266 11267 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11268 // !), 101 (DB with !) 11269 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11270 single_regs = false; 11271 add = BitIsSet(opcode, 23); 11272 wback = BitIsSet(opcode, 21); 11273 11274 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11275 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11276 n = Bits32(opcode, 19, 16); 11277 imm32 = Bits32(opcode, 7, 0) << 2; 11278 11279 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'. 11280 regs = Bits32(opcode, 7, 0) / 2; 11281 11282 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11283 // UNPREDICTABLE; 11284 if (n == 15 && (wback || CurrentInstrSet() != eModeARM)) 11285 return false; 11286 11287 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11288 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11289 return false; 11290 11291 break; 11292 11293 case eEncodingT2: 11294 case eEncodingA2: 11295 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11296 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP; 11297 // if P == '1' && W == '0' then SEE VLDR; 11298 // if P == U && W == '1' then UNDEFINED; 11299 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11300 return false; 11301 11302 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11303 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11304 // == '1'); d = 11305 // UInt(Vd:D); n = UInt(Rn); 11306 single_regs = true; 11307 add = BitIsSet(opcode, 23); 11308 wback = BitIsSet(opcode, 21); 11309 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11310 n = Bits32(opcode, 19, 16); 11311 11312 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11313 imm32 = Bits32(opcode, 7, 0) << 2; 11314 regs = Bits32(opcode, 7, 0); 11315 11316 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11317 // UNPREDICTABLE; 11318 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11319 return false; 11320 11321 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11322 if ((regs == 0) || ((d + regs) > 32)) 11323 return false; 11324 break; 11325 11326 default: 11327 return false; 11328 } 11329 11330 RegisterInfo base_reg; 11331 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11332 11333 uint32_t Rn = ReadCoreReg(n, &success); 11334 if (!success) 11335 return false; 11336 11337 // address = if add then R[n] else R[n]-imm32; 11338 addr_t address; 11339 if (add) 11340 address = Rn; 11341 else 11342 address = Rn - imm32; 11343 11344 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11345 EmulateInstruction::Context context; 11346 11347 if (wback) { 11348 uint32_t value; 11349 if (add) 11350 value = Rn + imm32; 11351 else 11352 value = Rn - imm32; 11353 11354 context.type = eContextAdjustBaseRegister; 11355 context.SetImmediateSigned(value - Rn); 11356 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11357 value)) 11358 return false; 11359 } 11360 11361 const uint32_t addr_byte_size = GetAddressByteSize(); 11362 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11363 11364 context.type = eContextRegisterLoad; 11365 11366 // for r = 0 to regs-1 11367 for (uint32_t r = 0; r < regs; ++r) { 11368 if (single_regs) { 11369 // S[d+r] = MemA[address,4]; address = address+4; 11370 context.SetRegisterPlusOffset(base_reg, address - Rn); 11371 11372 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11373 if (!success) 11374 return false; 11375 11376 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11377 start_reg + d + r, data)) 11378 return false; 11379 11380 address = address + 4; 11381 } else { 11382 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = 11383 // address+8; 11384 context.SetRegisterPlusOffset(base_reg, address - Rn); 11385 uint32_t word1 = 11386 MemARead(context, address, addr_byte_size, 0, &success); 11387 if (!success) 11388 return false; 11389 11390 context.SetRegisterPlusOffset(base_reg, (address + 4) - Rn); 11391 uint32_t word2 = 11392 MemARead(context, address + 4, addr_byte_size, 0, &success); 11393 if (!success) 11394 return false; 11395 11396 address = address + 8; 11397 // // Combine the word-aligned words in the correct order for current 11398 // endianness. 11399 // D[d+r] = if BigEndian() then word1:word2 else word2:word1; 11400 uint64_t data; 11401 if (GetByteOrder() == eByteOrderBig) { 11402 data = word1; 11403 data = (data << 32) | word2; 11404 } else { 11405 data = word2; 11406 data = (data << 32) | word1; 11407 } 11408 11409 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, 11410 start_reg + d + r, data)) 11411 return false; 11412 } 11413 } 11414 } 11415 return true; 11416} 11417 11418// A8.6.399 VSTM 11419// Vector Store Multiple stores multiple extension registers to consecutive 11420// memory locations using an address from an 11421// ARM core register. 11422bool EmulateInstructionARM::EmulateVSTM(const uint32_t opcode, 11423 const ARMEncoding encoding) { 11424#if 0 11425 if ConditionPassed() then 11426 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11427 address = if add then R[n] else R[n]-imm32; 11428 if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11429 for r = 0 to regs-1 11430 if single_regs then 11431 MemA[address,4] = S[d+r]; address = address+4; 11432 else 11433 // Store as two word-aligned words in the correct order for 11434 // current endianness. 11435 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>; 11436 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>; 11437 address = address+8; 11438#endif 11439 11440 bool success = false; 11441 11442 if (ConditionPassed(opcode)) { 11443 bool single_regs; 11444 bool add; 11445 bool wback; 11446 uint32_t d; 11447 uint32_t n; 11448 uint32_t imm32; 11449 uint32_t regs; 11450 11451 switch (encoding) { 11452 case eEncodingT1: 11453 case eEncodingA1: 11454 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11455 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11456 // if P == '1' && W == '0' then SEE VSTR; 11457 // if P == U && W == '1' then UNDEFINED; 11458 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11459 return false; 11460 11461 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11462 // !), 101 (DB with !) 11463 // single_regs = FALSE; add = (U == '1'); wback = (W == '1'); 11464 single_regs = false; 11465 add = BitIsSet(opcode, 23); 11466 wback = BitIsSet(opcode, 21); 11467 11468 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32); 11469 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11470 n = Bits32(opcode, 19, 16); 11471 imm32 = Bits32(opcode, 7, 0) << 2; 11472 11473 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'. 11474 regs = Bits32(opcode, 7, 0) / 2; 11475 11476 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11477 // UNPREDICTABLE; 11478 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11479 return false; 11480 11481 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE; 11482 if ((regs == 0) || (regs > 16) || ((d + regs) > 32)) 11483 return false; 11484 11485 break; 11486 11487 case eEncodingT2: 11488 case eEncodingA2: 11489 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings'; 11490 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH; 11491 // if P == '1' && W == '0' then SEE VSTR; 11492 // if P == U && W == '1' then UNDEFINED; 11493 if ((Bit32(opcode, 24) == Bit32(opcode, 23)) && BitIsSet(opcode, 21)) 11494 return false; 11495 11496 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with 11497 // !), 101 (DB with !) single_regs = TRUE; add = (U == '1'); wback = (W 11498 // == '1'); d = 11499 // UInt(Vd:D); n = UInt(Rn); 11500 single_regs = true; 11501 add = BitIsSet(opcode, 23); 11502 wback = BitIsSet(opcode, 21); 11503 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11504 n = Bits32(opcode, 19, 16); 11505 11506 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8); 11507 imm32 = Bits32(opcode, 7, 0) << 2; 11508 regs = Bits32(opcode, 7, 0); 11509 11510 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then 11511 // UNPREDICTABLE; 11512 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM))) 11513 return false; 11514 11515 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE; 11516 if ((regs == 0) || ((d + regs) > 32)) 11517 return false; 11518 11519 break; 11520 11521 default: 11522 return false; 11523 } 11524 11525 RegisterInfo base_reg; 11526 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11527 11528 uint32_t Rn = ReadCoreReg(n, &success); 11529 if (!success) 11530 return false; 11531 11532 // address = if add then R[n] else R[n]-imm32; 11533 addr_t address; 11534 if (add) 11535 address = Rn; 11536 else 11537 address = Rn - imm32; 11538 11539 EmulateInstruction::Context context; 11540 // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32; 11541 if (wback) { 11542 uint32_t value; 11543 if (add) 11544 value = Rn + imm32; 11545 else 11546 value = Rn - imm32; 11547 11548 context.type = eContextAdjustBaseRegister; 11549 context.SetRegisterPlusOffset(base_reg, value - Rn); 11550 11551 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 11552 value)) 11553 return false; 11554 } 11555 11556 const uint32_t addr_byte_size = GetAddressByteSize(); 11557 uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0; 11558 11559 context.type = eContextRegisterStore; 11560 // for r = 0 to regs-1 11561 for (uint32_t r = 0; r < regs; ++r) { 11562 11563 if (single_regs) { 11564 // MemA[address,4] = S[d+r]; address = address+4; 11565 uint32_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11566 start_reg + d + r, 0, &success); 11567 if (!success) 11568 return false; 11569 11570 RegisterInfo data_reg; 11571 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11572 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11573 address - Rn); 11574 if (!MemAWrite(context, address, data, addr_byte_size)) 11575 return false; 11576 11577 address = address + 4; 11578 } else { 11579 // // Store as two word-aligned words in the correct order for current 11580 // endianness. MemA[address,4] = if BigEndian() then D[d+r]<63:32> else 11581 // D[d+r]<31:0>; 11582 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else 11583 // D[d+r]<63:32>; 11584 uint64_t data = ReadRegisterUnsigned(eRegisterKindDWARF, 11585 start_reg + d + r, 0, &success); 11586 if (!success) 11587 return false; 11588 11589 RegisterInfo data_reg; 11590 GetRegisterInfo(eRegisterKindDWARF, start_reg + d + r, data_reg); 11591 11592 if (GetByteOrder() == eByteOrderBig) { 11593 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11594 address - Rn); 11595 if (!MemAWrite(context, address, Bits64(data, 63, 32), 11596 addr_byte_size)) 11597 return false; 11598 11599 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11600 (address + 4) - Rn); 11601 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11602 addr_byte_size)) 11603 return false; 11604 } else { 11605 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11606 address - Rn); 11607 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11608 return false; 11609 11610 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11611 (address + 4) - Rn); 11612 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11613 addr_byte_size)) 11614 return false; 11615 } 11616 // address = address+8; 11617 address = address + 8; 11618 } 11619 } 11620 } 11621 return true; 11622} 11623 11624// A8.6.320 11625// This instruction loads a single extension register from memory, using an 11626// address from an ARM core register, with an optional offset. 11627bool EmulateInstructionARM::EmulateVLDR(const uint32_t opcode, 11628 ARMEncoding encoding) { 11629#if 0 11630 if ConditionPassed() then 11631 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11632 base = if n == 15 then Align(PC,4) else R[n]; 11633 address = if add then (base + imm32) else (base - imm32); 11634 if single_reg then 11635 S[d] = MemA[address,4]; 11636 else 11637 word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11638 // Combine the word-aligned words in the correct order for current 11639 // endianness. 11640 D[d] = if BigEndian() then word1:word2 else word2:word1; 11641#endif 11642 11643 bool success = false; 11644 11645 if (ConditionPassed(opcode)) { 11646 bool single_reg; 11647 bool add; 11648 uint32_t imm32; 11649 uint32_t d; 11650 uint32_t n; 11651 11652 switch (encoding) { 11653 case eEncodingT1: 11654 case eEncodingA1: 11655 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11656 // 32); 11657 single_reg = false; 11658 add = BitIsSet(opcode, 23); 11659 imm32 = Bits32(opcode, 7, 0) << 2; 11660 11661 // d = UInt(D:Vd); n = UInt(Rn); 11662 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11663 n = Bits32(opcode, 19, 16); 11664 11665 break; 11666 11667 case eEncodingT2: 11668 case eEncodingA2: 11669 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11670 single_reg = true; 11671 add = BitIsSet(opcode, 23); 11672 imm32 = Bits32(opcode, 7, 0) << 2; 11673 11674 // d = UInt(Vd:D); n = UInt(Rn); 11675 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11676 n = Bits32(opcode, 19, 16); 11677 11678 break; 11679 11680 default: 11681 return false; 11682 } 11683 RegisterInfo base_reg; 11684 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11685 11686 uint32_t Rn = ReadCoreReg(n, &success); 11687 if (!success) 11688 return false; 11689 11690 // base = if n == 15 then Align(PC,4) else R[n]; 11691 uint32_t base; 11692 if (n == 15) 11693 base = AlignPC(Rn); 11694 else 11695 base = Rn; 11696 11697 // address = if add then (base + imm32) else (base - imm32); 11698 addr_t address; 11699 if (add) 11700 address = base + imm32; 11701 else 11702 address = base - imm32; 11703 11704 const uint32_t addr_byte_size = GetAddressByteSize(); 11705 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11706 11707 EmulateInstruction::Context context; 11708 context.type = eContextRegisterLoad; 11709 context.SetRegisterPlusOffset(base_reg, address - base); 11710 11711 if (single_reg) { 11712 // S[d] = MemA[address,4]; 11713 uint32_t data = MemARead(context, address, addr_byte_size, 0, &success); 11714 if (!success) 11715 return false; 11716 11717 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11718 data)) 11719 return false; 11720 } else { 11721 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; 11722 uint32_t word1 = MemARead(context, address, addr_byte_size, 0, &success); 11723 if (!success) 11724 return false; 11725 11726 context.SetRegisterPlusOffset(base_reg, (address + 4) - base); 11727 uint32_t word2 = 11728 MemARead(context, address + 4, addr_byte_size, 0, &success); 11729 if (!success) 11730 return false; 11731 // // Combine the word-aligned words in the correct order for current 11732 // endianness. 11733 // D[d] = if BigEndian() then word1:word2 else word2:word1; 11734 uint64_t data64; 11735 if (GetByteOrder() == eByteOrderBig) { 11736 data64 = word1; 11737 data64 = (data64 << 32) | word2; 11738 } else { 11739 data64 = word2; 11740 data64 = (data64 << 32) | word1; 11741 } 11742 11743 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, start_reg + d, 11744 data64)) 11745 return false; 11746 } 11747 } 11748 return true; 11749} 11750 11751// A8.6.400 VSTR 11752// This instruction stores a signle extension register to memory, using an 11753// address from an ARM core register, with an optional offset. 11754bool EmulateInstructionARM::EmulateVSTR(const uint32_t opcode, 11755 ARMEncoding encoding) { 11756#if 0 11757 if ConditionPassed() then 11758 EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n); 11759 address = if add then (R[n] + imm32) else (R[n] - imm32); 11760 if single_reg then 11761 MemA[address,4] = S[d]; 11762 else 11763 // Store as two word-aligned words in the correct order for current 11764 // endianness. 11765 MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11766 MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11767#endif 11768 11769 bool success = false; 11770 11771 if (ConditionPassed(opcode)) { 11772 bool single_reg; 11773 bool add; 11774 uint32_t imm32; 11775 uint32_t d; 11776 uint32_t n; 11777 11778 switch (encoding) { 11779 case eEncodingT1: 11780 case eEncodingA1: 11781 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 11782 // 32); 11783 single_reg = false; 11784 add = BitIsSet(opcode, 23); 11785 imm32 = Bits32(opcode, 7, 0) << 2; 11786 11787 // d = UInt(D:Vd); n = UInt(Rn); 11788 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11789 n = Bits32(opcode, 19, 16); 11790 11791 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11792 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11793 return false; 11794 11795 break; 11796 11797 case eEncodingT2: 11798 case eEncodingA2: 11799 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32); 11800 single_reg = true; 11801 add = BitIsSet(opcode, 23); 11802 imm32 = Bits32(opcode, 7, 0) << 2; 11803 11804 // d = UInt(Vd:D); n = UInt(Rn); 11805 d = (Bits32(opcode, 15, 12) << 1) | Bit32(opcode, 22); 11806 n = Bits32(opcode, 19, 16); 11807 11808 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE; 11809 if ((n == 15) && (CurrentInstrSet() != eModeARM)) 11810 return false; 11811 11812 break; 11813 11814 default: 11815 return false; 11816 } 11817 11818 RegisterInfo base_reg; 11819 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11820 11821 uint32_t Rn = ReadCoreReg(n, &success); 11822 if (!success) 11823 return false; 11824 11825 // address = if add then (R[n] + imm32) else (R[n] - imm32); 11826 addr_t address; 11827 if (add) 11828 address = Rn + imm32; 11829 else 11830 address = Rn - imm32; 11831 11832 const uint32_t addr_byte_size = GetAddressByteSize(); 11833 uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0; 11834 11835 RegisterInfo data_reg; 11836 GetRegisterInfo(eRegisterKindDWARF, start_reg + d, data_reg); 11837 EmulateInstruction::Context context; 11838 context.type = eContextRegisterStore; 11839 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 11840 11841 if (single_reg) { 11842 // MemA[address,4] = S[d]; 11843 uint32_t data = 11844 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11845 if (!success) 11846 return false; 11847 11848 if (!MemAWrite(context, address, data, addr_byte_size)) 11849 return false; 11850 } else { 11851 // // Store as two word-aligned words in the correct order for current 11852 // endianness. 11853 // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>; 11854 // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>; 11855 uint64_t data = 11856 ReadRegisterUnsigned(eRegisterKindDWARF, start_reg + d, 0, &success); 11857 if (!success) 11858 return false; 11859 11860 if (GetByteOrder() == eByteOrderBig) { 11861 if (!MemAWrite(context, address, Bits64(data, 63, 32), addr_byte_size)) 11862 return false; 11863 11864 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11865 (address + 4) - Rn); 11866 if (!MemAWrite(context, address + 4, Bits64(data, 31, 0), 11867 addr_byte_size)) 11868 return false; 11869 } else { 11870 if (!MemAWrite(context, address, Bits64(data, 31, 0), addr_byte_size)) 11871 return false; 11872 11873 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 11874 (address + 4) - Rn); 11875 if (!MemAWrite(context, address + 4, Bits64(data, 63, 32), 11876 addr_byte_size)) 11877 return false; 11878 } 11879 } 11880 } 11881 return true; 11882} 11883 11884// A8.6.307 VLDI1 (multiple single elements) This instruction loads elements 11885// from memory into one, two, three or four registers, without de-interleaving. 11886// Every element of each register is loaded. 11887bool EmulateInstructionARM::EmulateVLD1Multiple(const uint32_t opcode, 11888 ARMEncoding encoding) { 11889#if 0 11890 if ConditionPassed() then 11891 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 11892 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 11893 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11894 for r = 0 to regs-1 11895 for e = 0 to elements-1 11896 Elem[D[d+r],e,esize] = MemU[address,ebytes]; 11897 address = address + ebytes; 11898#endif 11899 11900 bool success = false; 11901 11902 if (ConditionPassed(opcode)) { 11903 uint32_t regs; 11904 uint32_t alignment; 11905 uint32_t ebytes; 11906 uint32_t esize; 11907 uint32_t elements; 11908 uint32_t d; 11909 uint32_t n; 11910 uint32_t m; 11911 bool wback; 11912 bool register_index; 11913 11914 switch (encoding) { 11915 case eEncodingT1: 11916 case eEncodingA1: { 11917 // case type of 11918 // when '0111' 11919 // regs = 1; if align<1> == '1' then UNDEFINED; 11920 // when '1010' 11921 // regs = 2; if align == '11' then UNDEFINED; 11922 // when '0110' 11923 // regs = 3; if align<1> == '1' then UNDEFINED; 11924 // when '0010' 11925 // regs = 4; 11926 // otherwise 11927 // SEE 'Related encodings'; 11928 uint32_t type = Bits32(opcode, 11, 8); 11929 uint32_t align = Bits32(opcode, 5, 4); 11930 if (type == 7) // '0111' 11931 { 11932 regs = 1; 11933 if (BitIsSet(align, 1)) 11934 return false; 11935 } else if (type == 10) // '1010' 11936 { 11937 regs = 2; 11938 if (align == 3) 11939 return false; 11940 11941 } else if (type == 6) // '0110' 11942 { 11943 regs = 3; 11944 if (BitIsSet(align, 1)) 11945 return false; 11946 } else if (type == 2) // '0010' 11947 { 11948 regs = 4; 11949 } else 11950 return false; 11951 11952 // alignment = if align == '00' then 1 else 4 << UInt(align); 11953 if (align == 0) 11954 alignment = 1; 11955 else 11956 alignment = 4 << align; 11957 11958 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 11959 ebytes = 1 << Bits32(opcode, 7, 6); 11960 esize = 8 * ebytes; 11961 elements = 8 / ebytes; 11962 11963 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 11964 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 11965 n = Bits32(opcode, 19, 15); 11966 m = Bits32(opcode, 3, 0); 11967 11968 // wback = (m != 15); register_index = (m != 15 && m != 13); 11969 wback = (m != 15); 11970 register_index = ((m != 15) && (m != 13)); 11971 11972 // if d+regs > 32 then UNPREDICTABLE; 11973 if ((d + regs) > 32) 11974 return false; 11975 } break; 11976 11977 default: 11978 return false; 11979 } 11980 11981 RegisterInfo base_reg; 11982 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 11983 11984 uint32_t Rn = ReadCoreReg(n, &success); 11985 if (!success) 11986 return false; 11987 11988 // address = R[n]; if (address MOD alignment) != 0 then 11989 // GenerateAlignmentException(); 11990 addr_t address = Rn; 11991 if ((address % alignment) != 0) 11992 return false; 11993 11994 EmulateInstruction::Context context; 11995 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 11996 if (wback) { 11997 uint32_t Rm = ReadCoreReg(m, &success); 11998 if (!success) 11999 return false; 12000 12001 uint32_t offset; 12002 if (register_index) 12003 offset = Rm; 12004 else 12005 offset = 8 * regs; 12006 12007 uint32_t value = Rn + offset; 12008 context.type = eContextAdjustBaseRegister; 12009 context.SetRegisterPlusOffset(base_reg, offset); 12010 12011 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12012 value)) 12013 return false; 12014 } 12015 12016 // for r = 0 to regs-1 12017 for (uint32_t r = 0; r < regs; ++r) { 12018 // for e = 0 to elements-1 12019 uint64_t assembled_data = 0; 12020 for (uint32_t e = 0; e < elements; ++e) { 12021 // Elem[D[d+r],e,esize] = MemU[address,ebytes]; 12022 context.type = eContextRegisterLoad; 12023 context.SetRegisterPlusOffset(base_reg, address - Rn); 12024 uint64_t data = MemURead(context, address, ebytes, 0, &success); 12025 if (!success) 12026 return false; 12027 12028 assembled_data = 12029 (data << (e * esize)) | 12030 assembled_data; // New data goes to the left of existing data 12031 12032 // address = address + ebytes; 12033 address = address + ebytes; 12034 } 12035 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12036 assembled_data)) 12037 return false; 12038 } 12039 } 12040 return true; 12041} 12042 12043// A8.6.308 VLD1 (single element to one lane) 12044// 12045bool EmulateInstructionARM::EmulateVLD1Single(const uint32_t opcode, 12046 const ARMEncoding encoding) { 12047#if 0 12048 if ConditionPassed() then 12049 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12050 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12051 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12052 Elem[D[d],index,esize] = MemU[address,ebytes]; 12053#endif 12054 12055 bool success = false; 12056 12057 if (ConditionPassed(opcode)) { 12058 uint32_t ebytes; 12059 uint32_t esize; 12060 uint32_t index; 12061 uint32_t alignment; 12062 uint32_t d; 12063 uint32_t n; 12064 uint32_t m; 12065 bool wback; 12066 bool register_index; 12067 12068 switch (encoding) { 12069 case eEncodingT1: 12070 case eEncodingA1: { 12071 uint32_t size = Bits32(opcode, 11, 10); 12072 uint32_t index_align = Bits32(opcode, 7, 4); 12073 // if size == '11' then SEE VLD1 (single element to all lanes); 12074 if (size == 3) 12075 return EmulateVLD1SingleAll(opcode, encoding); 12076 // case size of 12077 if (size == 0) // when '00' 12078 { 12079 // if index_align<0> != '0' then UNDEFINED; 12080 if (BitIsClear(index_align, 0)) 12081 return false; 12082 12083 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12084 ebytes = 1; 12085 esize = 8; 12086 index = Bits32(index_align, 3, 1); 12087 alignment = 1; 12088 } else if (size == 1) // when '01' 12089 { 12090 // if index_align<1> != '0' then UNDEFINED; 12091 if (BitIsClear(index_align, 1)) 12092 return false; 12093 12094 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12095 ebytes = 2; 12096 esize = 16; 12097 index = Bits32(index_align, 3, 2); 12098 12099 // alignment = if index_align<0> == '0' then 1 else 2; 12100 if (BitIsClear(index_align, 0)) 12101 alignment = 1; 12102 else 12103 alignment = 2; 12104 } else if (size == 2) // when '10' 12105 { 12106 // if index_align<2> != '0' then UNDEFINED; 12107 if (BitIsClear(index_align, 2)) 12108 return false; 12109 12110 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12111 // UNDEFINED; 12112 if ((Bits32(index_align, 1, 0) != 0) && 12113 (Bits32(index_align, 1, 0) != 3)) 12114 return false; 12115 12116 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12117 ebytes = 4; 12118 esize = 32; 12119 index = Bit32(index_align, 3); 12120 12121 // alignment = if index_align<1:0> == '00' then 1 else 4; 12122 if (Bits32(index_align, 1, 0) == 0) 12123 alignment = 1; 12124 else 12125 alignment = 4; 12126 } else { 12127 return false; 12128 } 12129 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12130 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12131 n = Bits32(opcode, 19, 16); 12132 m = Bits32(opcode, 3, 0); 12133 12134 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12135 // then UNPREDICTABLE; 12136 wback = (m != 15); 12137 register_index = ((m != 15) && (m != 13)); 12138 12139 if (n == 15) 12140 return false; 12141 12142 } break; 12143 12144 default: 12145 return false; 12146 } 12147 12148 RegisterInfo base_reg; 12149 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12150 12151 uint32_t Rn = ReadCoreReg(n, &success); 12152 if (!success) 12153 return false; 12154 12155 // address = R[n]; if (address MOD alignment) != 0 then 12156 // GenerateAlignmentException(); 12157 addr_t address = Rn; 12158 if ((address % alignment) != 0) 12159 return false; 12160 12161 EmulateInstruction::Context context; 12162 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12163 if (wback) { 12164 uint32_t Rm = ReadCoreReg(m, &success); 12165 if (!success) 12166 return false; 12167 12168 uint32_t offset; 12169 if (register_index) 12170 offset = Rm; 12171 else 12172 offset = ebytes; 12173 12174 uint32_t value = Rn + offset; 12175 12176 context.type = eContextAdjustBaseRegister; 12177 context.SetRegisterPlusOffset(base_reg, offset); 12178 12179 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12180 value)) 12181 return false; 12182 } 12183 12184 // Elem[D[d],index,esize] = MemU[address,ebytes]; 12185 uint32_t element = MemURead(context, address, esize, 0, &success); 12186 if (!success) 12187 return false; 12188 12189 element = element << (index * esize); 12190 12191 uint64_t reg_data = 12192 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12193 if (!success) 12194 return false; 12195 12196 uint64_t all_ones = -1; 12197 uint64_t mask = all_ones 12198 << ((index + 1) * esize); // mask is all 1's to left of 12199 // where 'element' goes, & all 0's 12200 // at element & to the right of element. 12201 if (index > 0) 12202 mask = mask | Bits64(all_ones, (index * esize) - 1, 12203 0); // add 1's to the right of where 'element' goes. 12204 // now mask should be 0's where element goes & 1's everywhere else. 12205 12206 uint64_t masked_reg = 12207 reg_data & mask; // Take original reg value & zero out 'element' bits 12208 reg_data = 12209 masked_reg & element; // Put 'element' into those bits in reg_data. 12210 12211 context.type = eContextRegisterLoad; 12212 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + d, 12213 reg_data)) 12214 return false; 12215 } 12216 return true; 12217} 12218 12219// A8.6.391 VST1 (multiple single elements) Vector Store (multiple single 12220// elements) stores elements to memory from one, two, three, or four registers, 12221// without interleaving. Every element of each register is stored. 12222bool EmulateInstructionARM::EmulateVST1Multiple(const uint32_t opcode, 12223 ARMEncoding encoding) { 12224#if 0 12225 if ConditionPassed() then 12226 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12227 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12228 if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12229 for r = 0 to regs-1 12230 for e = 0 to elements-1 12231 MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12232 address = address + ebytes; 12233#endif 12234 12235 bool success = false; 12236 12237 if (ConditionPassed(opcode)) { 12238 uint32_t regs; 12239 uint32_t alignment; 12240 uint32_t ebytes; 12241 uint32_t esize; 12242 uint32_t elements; 12243 uint32_t d; 12244 uint32_t n; 12245 uint32_t m; 12246 bool wback; 12247 bool register_index; 12248 12249 switch (encoding) { 12250 case eEncodingT1: 12251 case eEncodingA1: { 12252 uint32_t type = Bits32(opcode, 11, 8); 12253 uint32_t align = Bits32(opcode, 5, 4); 12254 12255 // case type of 12256 if (type == 7) // when '0111' 12257 { 12258 // regs = 1; if align<1> == '1' then UNDEFINED; 12259 regs = 1; 12260 if (BitIsSet(align, 1)) 12261 return false; 12262 } else if (type == 10) // when '1010' 12263 { 12264 // regs = 2; if align == '11' then UNDEFINED; 12265 regs = 2; 12266 if (align == 3) 12267 return false; 12268 } else if (type == 6) // when '0110' 12269 { 12270 // regs = 3; if align<1> == '1' then UNDEFINED; 12271 regs = 3; 12272 if (BitIsSet(align, 1)) 12273 return false; 12274 } else if (type == 2) // when '0010' 12275 // regs = 4; 12276 regs = 4; 12277 else // otherwise 12278 // SEE 'Related encodings'; 12279 return false; 12280 12281 // alignment = if align == '00' then 1 else 4 << UInt(align); 12282 if (align == 0) 12283 alignment = 1; 12284 else 12285 alignment = 4 << align; 12286 12287 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes; 12288 ebytes = 1 << Bits32(opcode, 7, 6); 12289 esize = 8 * ebytes; 12290 elements = 8 / ebytes; 12291 12292 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12293 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12294 n = Bits32(opcode, 19, 16); 12295 m = Bits32(opcode, 3, 0); 12296 12297 // wback = (m != 15); register_index = (m != 15 && m != 13); 12298 wback = (m != 15); 12299 register_index = ((m != 15) && (m != 13)); 12300 12301 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12302 if ((d + regs) > 32) 12303 return false; 12304 12305 if (n == 15) 12306 return false; 12307 12308 } break; 12309 12310 default: 12311 return false; 12312 } 12313 12314 RegisterInfo base_reg; 12315 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12316 12317 uint32_t Rn = ReadCoreReg(n, &success); 12318 if (!success) 12319 return false; 12320 12321 // address = R[n]; if (address MOD alignment) != 0 then 12322 // GenerateAlignmentException(); 12323 addr_t address = Rn; 12324 if ((address % alignment) != 0) 12325 return false; 12326 12327 EmulateInstruction::Context context; 12328 // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs); 12329 if (wback) { 12330 uint32_t Rm = ReadCoreReg(m, &success); 12331 if (!success) 12332 return false; 12333 12334 uint32_t offset; 12335 if (register_index) 12336 offset = Rm; 12337 else 12338 offset = 8 * regs; 12339 12340 context.type = eContextAdjustBaseRegister; 12341 context.SetRegisterPlusOffset(base_reg, offset); 12342 12343 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12344 Rn + offset)) 12345 return false; 12346 } 12347 12348 RegisterInfo data_reg; 12349 context.type = eContextRegisterStore; 12350 // for r = 0 to regs-1 12351 for (uint32_t r = 0; r < regs; ++r) { 12352 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d + r, data_reg); 12353 uint64_t register_data = ReadRegisterUnsigned( 12354 eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success); 12355 if (!success) 12356 return false; 12357 12358 // for e = 0 to elements-1 12359 for (uint32_t e = 0; e < elements; ++e) { 12360 // MemU[address,ebytes] = Elem[D[d+r],e,esize]; 12361 uint64_t word = Bits64(register_data, ((e + 1) * esize) - 1, e * esize); 12362 12363 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, 12364 address - Rn); 12365 if (!MemUWrite(context, address, word, ebytes)) 12366 return false; 12367 12368 // address = address + ebytes; 12369 address = address + ebytes; 12370 } 12371 } 12372 } 12373 return true; 12374} 12375 12376// A8.6.392 VST1 (single element from one lane) This instruction stores one 12377// element to memory from one element of a register. 12378bool EmulateInstructionARM::EmulateVST1Single(const uint32_t opcode, 12379 ARMEncoding encoding) { 12380#if 0 12381 if ConditionPassed() then 12382 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12383 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12384 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12385 MemU[address,ebytes] = Elem[D[d],index,esize]; 12386#endif 12387 12388 bool success = false; 12389 12390 if (ConditionPassed(opcode)) { 12391 uint32_t ebytes; 12392 uint32_t esize; 12393 uint32_t index; 12394 uint32_t alignment; 12395 uint32_t d; 12396 uint32_t n; 12397 uint32_t m; 12398 bool wback; 12399 bool register_index; 12400 12401 switch (encoding) { 12402 case eEncodingT1: 12403 case eEncodingA1: { 12404 uint32_t size = Bits32(opcode, 11, 10); 12405 uint32_t index_align = Bits32(opcode, 7, 4); 12406 12407 // if size == '11' then UNDEFINED; 12408 if (size == 3) 12409 return false; 12410 12411 // case size of 12412 if (size == 0) // when '00' 12413 { 12414 // if index_align<0> != '0' then UNDEFINED; 12415 if (BitIsClear(index_align, 0)) 12416 return false; 12417 // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1; 12418 ebytes = 1; 12419 esize = 8; 12420 index = Bits32(index_align, 3, 1); 12421 alignment = 1; 12422 } else if (size == 1) // when '01' 12423 { 12424 // if index_align<1> != '0' then UNDEFINED; 12425 if (BitIsClear(index_align, 1)) 12426 return false; 12427 12428 // ebytes = 2; esize = 16; index = UInt(index_align<3:2>); 12429 ebytes = 2; 12430 esize = 16; 12431 index = Bits32(index_align, 3, 2); 12432 12433 // alignment = if index_align<0> == '0' then 1 else 2; 12434 if (BitIsClear(index_align, 0)) 12435 alignment = 1; 12436 else 12437 alignment = 2; 12438 } else if (size == 2) // when '10' 12439 { 12440 // if index_align<2> != '0' then UNDEFINED; 12441 if (BitIsClear(index_align, 2)) 12442 return false; 12443 12444 // if index_align<1:0> != '00' && index_align<1:0> != '11' then 12445 // UNDEFINED; 12446 if ((Bits32(index_align, 1, 0) != 0) && 12447 (Bits32(index_align, 1, 0) != 3)) 12448 return false; 12449 12450 // ebytes = 4; esize = 32; index = UInt(index_align<3>); 12451 ebytes = 4; 12452 esize = 32; 12453 index = Bit32(index_align, 3); 12454 12455 // alignment = if index_align<1:0> == '00' then 1 else 4; 12456 if (Bits32(index_align, 1, 0) == 0) 12457 alignment = 1; 12458 else 12459 alignment = 4; 12460 } else { 12461 return false; 12462 } 12463 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12464 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12465 n = Bits32(opcode, 19, 16); 12466 m = Bits32(opcode, 3, 0); 12467 12468 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 12469 // then UNPREDICTABLE; 12470 wback = (m != 15); 12471 register_index = ((m != 15) && (m != 13)); 12472 12473 if (n == 15) 12474 return false; 12475 } break; 12476 12477 default: 12478 return false; 12479 } 12480 12481 RegisterInfo base_reg; 12482 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12483 12484 uint32_t Rn = ReadCoreReg(n, &success); 12485 if (!success) 12486 return false; 12487 12488 // address = R[n]; if (address MOD alignment) != 0 then 12489 // GenerateAlignmentException(); 12490 addr_t address = Rn; 12491 if ((address % alignment) != 0) 12492 return false; 12493 12494 EmulateInstruction::Context context; 12495 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12496 if (wback) { 12497 uint32_t Rm = ReadCoreReg(m, &success); 12498 if (!success) 12499 return false; 12500 12501 uint32_t offset; 12502 if (register_index) 12503 offset = Rm; 12504 else 12505 offset = ebytes; 12506 12507 context.type = eContextAdjustBaseRegister; 12508 context.SetRegisterPlusOffset(base_reg, offset); 12509 12510 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12511 Rn + offset)) 12512 return false; 12513 } 12514 12515 // MemU[address,ebytes] = Elem[D[d],index,esize]; 12516 uint64_t register_data = 12517 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_d0 + d, 0, &success); 12518 if (!success) 12519 return false; 12520 12521 uint64_t word = 12522 Bits64(register_data, ((index + 1) * esize) - 1, index * esize); 12523 12524 RegisterInfo data_reg; 12525 GetRegisterInfo(eRegisterKindDWARF, dwarf_d0 + d, data_reg); 12526 context.type = eContextRegisterStore; 12527 context.SetRegisterToRegisterPlusOffset(data_reg, base_reg, address - Rn); 12528 12529 if (!MemUWrite(context, address, word, ebytes)) 12530 return false; 12531 } 12532 return true; 12533} 12534 12535// A8.6.309 VLD1 (single element to all lanes) This instruction loads one 12536// element from memory into every element of one or two vectors. 12537bool EmulateInstructionARM::EmulateVLD1SingleAll(const uint32_t opcode, 12538 const ARMEncoding encoding) { 12539#if 0 12540 if ConditionPassed() then 12541 EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n); 12542 address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException(); 12543 if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12544 replicated_element = Replicate(MemU[address,ebytes], elements); 12545 for r = 0 to regs-1 12546 D[d+r] = replicated_element; 12547#endif 12548 12549 bool success = false; 12550 12551 if (ConditionPassed(opcode)) { 12552 uint32_t ebytes; 12553 uint32_t elements; 12554 uint32_t regs; 12555 uint32_t alignment; 12556 uint32_t d; 12557 uint32_t n; 12558 uint32_t m; 12559 bool wback; 12560 bool register_index; 12561 12562 switch (encoding) { 12563 case eEncodingT1: 12564 case eEncodingA1: { 12565 // if size == '11' || (size == '00' && a == '1') then UNDEFINED; 12566 uint32_t size = Bits32(opcode, 7, 6); 12567 if ((size == 3) || ((size == 0) && BitIsSet(opcode, 4))) 12568 return false; 12569 12570 // ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' 12571 // then 1 else 2; 12572 ebytes = 1 << size; 12573 elements = 8 / ebytes; 12574 if (BitIsClear(opcode, 5)) 12575 regs = 1; 12576 else 12577 regs = 2; 12578 12579 // alignment = if a == '0' then 1 else ebytes; 12580 if (BitIsClear(opcode, 4)) 12581 alignment = 1; 12582 else 12583 alignment = ebytes; 12584 12585 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm); 12586 d = (Bit32(opcode, 22) << 4) | Bits32(opcode, 15, 12); 12587 n = Bits32(opcode, 19, 16); 12588 m = Bits32(opcode, 3, 0); 12589 12590 // wback = (m != 15); register_index = (m != 15 && m != 13); 12591 wback = (m != 15); 12592 register_index = ((m != 15) && (m != 13)); 12593 12594 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE; 12595 if ((d + regs) > 32) 12596 return false; 12597 12598 if (n == 15) 12599 return false; 12600 } break; 12601 12602 default: 12603 return false; 12604 } 12605 12606 RegisterInfo base_reg; 12607 GetRegisterInfo(eRegisterKindDWARF, dwarf_r0 + n, base_reg); 12608 12609 uint32_t Rn = ReadCoreReg(n, &success); 12610 if (!success) 12611 return false; 12612 12613 // address = R[n]; if (address MOD alignment) != 0 then 12614 // GenerateAlignmentException(); 12615 addr_t address = Rn; 12616 if ((address % alignment) != 0) 12617 return false; 12618 12619 EmulateInstruction::Context context; 12620 // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes); 12621 if (wback) { 12622 uint32_t Rm = ReadCoreReg(m, &success); 12623 if (!success) 12624 return false; 12625 12626 uint32_t offset; 12627 if (register_index) 12628 offset = Rm; 12629 else 12630 offset = ebytes; 12631 12632 context.type = eContextAdjustBaseRegister; 12633 context.SetRegisterPlusOffset(base_reg, offset); 12634 12635 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + n, 12636 Rn + offset)) 12637 return false; 12638 } 12639 12640 // replicated_element = Replicate(MemU[address,ebytes], elements); 12641 12642 context.type = eContextRegisterLoad; 12643 uint64_t word = MemURead(context, address, ebytes, 0, &success); 12644 if (!success) 12645 return false; 12646 12647 uint64_t replicated_element = 0; 12648 uint32_t esize = ebytes * 8; 12649 for (uint32_t e = 0; e < elements; ++e) 12650 replicated_element = 12651 (replicated_element << esize) | Bits64(word, esize - 1, 0); 12652 12653 // for r = 0 to regs-1 12654 for (uint32_t r = 0; r < regs; ++r) { 12655 // D[d+r] = replicated_element; 12656 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_d0 + d + r, 12657 replicated_element)) 12658 return false; 12659 } 12660 } 12661 return true; 12662} 12663 12664// B6.2.13 SUBS PC, LR and related instructions The SUBS PC, LR, #<const? 12665// instruction provides an exception return without the use of the stack. It 12666// subtracts the immediate constant from the LR, branches to the resulting 12667// address, and also copies the SPSR to the CPSR. 12668bool EmulateInstructionARM::EmulateSUBSPcLrEtc(const uint32_t opcode, 12669 const ARMEncoding encoding) { 12670#if 0 12671 if ConditionPassed() then 12672 EncodingSpecificOperations(); 12673 if CurrentInstrSet() == InstrSet_ThumbEE then 12674 UNPREDICTABLE; 12675 operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32; 12676 case opcode of 12677 when '0000' result = R[n] AND operand2; // AND 12678 when '0001' result = R[n] EOR operand2; // EOR 12679 when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12680 when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12681 when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12682 when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12683 when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12684 when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12685 when '1100' result = R[n] OR operand2; // ORR 12686 when '1101' result = operand2; // MOV 12687 when '1110' result = R[n] AND NOT(operand2); // BIC 12688 when '1111' result = NOT(operand2); // MVN 12689 CPSRWriteByInstr(SPSR[], '1111', TRUE); 12690 BranchWritePC(result); 12691#endif 12692 12693 bool success = false; 12694 12695 if (ConditionPassed(opcode)) { 12696 uint32_t n; 12697 uint32_t m; 12698 uint32_t imm32; 12699 bool register_form; 12700 ARM_ShifterType shift_t; 12701 uint32_t shift_n; 12702 uint32_t code; 12703 12704 switch (encoding) { 12705 case eEncodingT1: 12706 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE n = 14; 12707 // imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; 12708 // // = SUB 12709 n = 14; 12710 imm32 = Bits32(opcode, 7, 0); 12711 register_form = false; 12712 code = 2; 12713 12714 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE; 12715 if (InITBlock() && !LastInITBlock()) 12716 return false; 12717 12718 break; 12719 12720 case eEncodingA1: 12721 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE; 12722 n = Bits32(opcode, 19, 16); 12723 imm32 = ARMExpandImm(opcode); 12724 register_form = false; 12725 code = Bits32(opcode, 24, 21); 12726 12727 break; 12728 12729 case eEncodingA2: 12730 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE; 12731 n = Bits32(opcode, 19, 16); 12732 m = Bits32(opcode, 3, 0); 12733 register_form = true; 12734 12735 // (shift_t, shift_n) = DecodeImmShift(type, imm5); 12736 shift_n = DecodeImmShiftARM(opcode, shift_t); 12737 12738 break; 12739 12740 default: 12741 return false; 12742 } 12743 12744 // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) 12745 // else imm32; 12746 uint32_t operand2; 12747 if (register_form) { 12748 uint32_t Rm = ReadCoreReg(m, &success); 12749 if (!success) 12750 return false; 12751 12752 operand2 = Shift(Rm, shift_t, shift_n, APSR_C, &success); 12753 if (!success) 12754 return false; 12755 } else { 12756 operand2 = imm32; 12757 } 12758 12759 uint32_t Rn = ReadCoreReg(n, &success); 12760 if (!success) 12761 return false; 12762 12763 AddWithCarryResult result; 12764 12765 // case opcode of 12766 switch (code) { 12767 case 0: // when '0000' 12768 // result = R[n] AND operand2; // AND 12769 result.result = Rn & operand2; 12770 break; 12771 12772 case 1: // when '0001' 12773 // result = R[n] EOR operand2; // EOR 12774 result.result = Rn ^ operand2; 12775 break; 12776 12777 case 2: // when '0010' 12778 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB 12779 result = AddWithCarry(Rn, ~(operand2), 1); 12780 break; 12781 12782 case 3: // when '0011' 12783 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB 12784 result = AddWithCarry(~(Rn), operand2, 1); 12785 break; 12786 12787 case 4: // when '0100' 12788 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD 12789 result = AddWithCarry(Rn, operand2, 0); 12790 break; 12791 12792 case 5: // when '0101' 12793 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC 12794 result = AddWithCarry(Rn, operand2, APSR_C); 12795 break; 12796 12797 case 6: // when '0110' 12798 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC 12799 result = AddWithCarry(Rn, ~(operand2), APSR_C); 12800 break; 12801 12802 case 7: // when '0111' 12803 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC 12804 result = AddWithCarry(~(Rn), operand2, APSR_C); 12805 break; 12806 12807 case 10: // when '1100' 12808 // result = R[n] OR operand2; // ORR 12809 result.result = Rn | operand2; 12810 break; 12811 12812 case 11: // when '1101' 12813 // result = operand2; // MOV 12814 result.result = operand2; 12815 break; 12816 12817 case 12: // when '1110' 12818 // result = R[n] AND NOT(operand2); // BIC 12819 result.result = Rn & ~(operand2); 12820 break; 12821 12822 case 15: // when '1111' 12823 // result = NOT(operand2); // MVN 12824 result.result = ~(operand2); 12825 break; 12826 12827 default: 12828 return false; 12829 } 12830 // CPSRWriteByInstr(SPSR[], '1111', TRUE); 12831 12832 // For now, in emulation mode, we don't have access to the SPSR, so we will 12833 // use the CPSR instead, and hope for the best. 12834 uint32_t spsr = 12835 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 12836 if (!success) 12837 return false; 12838 12839 CPSRWriteByInstr(spsr, 15, true); 12840 12841 // BranchWritePC(result); 12842 EmulateInstruction::Context context; 12843 context.type = eContextAdjustPC; 12844 context.SetImmediate(result.result); 12845 12846 BranchWritePC(context, result.result); 12847 } 12848 return true; 12849} 12850 12851EmulateInstructionARM::ARMOpcode * 12852EmulateInstructionARM::GetARMOpcodeForInstruction(const uint32_t opcode, 12853 uint32_t arm_isa) { 12854 static ARMOpcode g_arm_opcodes[] = { 12855 // Prologue instructions 12856 12857 // push register(s) 12858 {0x0fff0000, 0x092d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12859 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 12860 {0x0fff0fff, 0x052d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12861 &EmulateInstructionARM::EmulatePUSH, "push <register>"}, 12862 12863 // set r7 to point to a stack offset 12864 {0x0ffff000, 0x028d7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12865 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>"}, 12866 {0x0ffff000, 0x024c7000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12867 &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"}, 12868 // copy the stack pointer to ip 12869 {0x0fffffff, 0x01a0c00d, ARMvAll, eEncodingA1, No_VFP, eSize32, 12870 &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp"}, 12871 {0x0ffff000, 0x028dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12872 &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>"}, 12873 {0x0ffff000, 0x024dc000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12874 &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"}, 12875 12876 // adjust the stack pointer 12877 {0x0ffff000, 0x024dd000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12878 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"}, 12879 {0x0fef0010, 0x004d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12880 &EmulateInstructionARM::EmulateSUBSPReg, 12881 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 12882 12883 // push one register 12884 // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH; 12885 {0x0e5f0000, 0x040d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12886 &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!"}, 12887 12888 // vector push consecutive extension register(s) 12889 {0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12890 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 12891 {0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12892 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 12893 12894 // Epilogue instructions 12895 12896 {0x0fff0000, 0x08bd0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12897 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 12898 {0x0fff0fff, 0x049d0004, ARMvAll, eEncodingA2, No_VFP, eSize32, 12899 &EmulateInstructionARM::EmulatePOP, "pop <register>"}, 12900 {0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, 12901 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 12902 {0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 12903 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 12904 12905 // Supervisor Call (previously Software Interrupt) 12906 {0x0f000000, 0x0f000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12907 &EmulateInstructionARM::EmulateSVC, "svc #imm24"}, 12908 12909 // Branch instructions 12910 // To resolve ambiguity, "blx <label>" should come before "b #imm24" and 12911 // "bl <label>". 12912 {0xfe000000, 0xfa000000, ARMV5_ABOVE, eEncodingA2, No_VFP, eSize32, 12913 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 12914 {0x0f000000, 0x0a000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12915 &EmulateInstructionARM::EmulateB, "b #imm24"}, 12916 {0x0f000000, 0x0b000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12917 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 12918 {0x0ffffff0, 0x012fff30, ARMV5_ABOVE, eEncodingA1, No_VFP, eSize32, 12919 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 12920 // for example, "bx lr" 12921 {0x0ffffff0, 0x012fff10, ARMvAll, eEncodingA1, No_VFP, eSize32, 12922 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 12923 // bxj 12924 {0x0ffffff0, 0x012fff20, ARMvAll, eEncodingA1, No_VFP, eSize32, 12925 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 12926 12927 // Data-processing instructions 12928 // adc (immediate) 12929 {0x0fe00000, 0x02a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12930 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"}, 12931 // adc (register) 12932 {0x0fe00010, 0x00a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12933 &EmulateInstructionARM::EmulateADCReg, 12934 "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12935 // add (immediate) 12936 {0x0fe00000, 0x02800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12937 &EmulateInstructionARM::EmulateADDImmARM, 12938 "add{s}<c> <Rd>, <Rn>, #const"}, 12939 // add (register) 12940 {0x0fe00010, 0x00800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12941 &EmulateInstructionARM::EmulateADDReg, 12942 "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12943 // add (register-shifted register) 12944 {0x0fe00090, 0x00800010, ARMvAll, eEncodingA1, No_VFP, eSize32, 12945 &EmulateInstructionARM::EmulateADDRegShift, 12946 "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"}, 12947 // adr 12948 {0x0fff0000, 0x028f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12949 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 12950 {0x0fff0000, 0x024f0000, ARMvAll, eEncodingA2, No_VFP, eSize32, 12951 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 12952 // and (immediate) 12953 {0x0fe00000, 0x02000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12954 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"}, 12955 // and (register) 12956 {0x0fe00010, 0x00000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12957 &EmulateInstructionARM::EmulateANDReg, 12958 "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12959 // bic (immediate) 12960 {0x0fe00000, 0x03c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12961 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"}, 12962 // bic (register) 12963 {0x0fe00010, 0x01c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12964 &EmulateInstructionARM::EmulateBICReg, 12965 "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12966 // eor (immediate) 12967 {0x0fe00000, 0x02200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12968 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"}, 12969 // eor (register) 12970 {0x0fe00010, 0x00200000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12971 &EmulateInstructionARM::EmulateEORReg, 12972 "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12973 // orr (immediate) 12974 {0x0fe00000, 0x03800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12975 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"}, 12976 // orr (register) 12977 {0x0fe00010, 0x01800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12978 &EmulateInstructionARM::EmulateORRReg, 12979 "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12980 // rsb (immediate) 12981 {0x0fe00000, 0x02600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12982 &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"}, 12983 // rsb (register) 12984 {0x0fe00010, 0x00600000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12985 &EmulateInstructionARM::EmulateRSBReg, 12986 "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12987 // rsc (immediate) 12988 {0x0fe00000, 0x02e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12989 &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"}, 12990 // rsc (register) 12991 {0x0fe00010, 0x00e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12992 &EmulateInstructionARM::EmulateRSCReg, 12993 "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 12994 // sbc (immediate) 12995 {0x0fe00000, 0x02c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12996 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 12997 // sbc (register) 12998 {0x0fe00010, 0x00c00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 12999 &EmulateInstructionARM::EmulateSBCReg, 13000 "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"}, 13001 // sub (immediate, ARM) 13002 {0x0fe00000, 0x02400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13003 &EmulateInstructionARM::EmulateSUBImmARM, 13004 "sub{s}<c> <Rd>, <Rn>, #<const>"}, 13005 // sub (sp minus immediate) 13006 {0x0fef0000, 0x024d0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13007 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"}, 13008 // sub (register) 13009 {0x0fe00010, 0x00400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13010 &EmulateInstructionARM::EmulateSUBReg, 13011 "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"}, 13012 // teq (immediate) 13013 {0x0ff0f000, 0x03300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13014 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"}, 13015 // teq (register) 13016 {0x0ff0f010, 0x01300000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13017 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13018 // tst (immediate) 13019 {0x0ff0f000, 0x03100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13020 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"}, 13021 // tst (register) 13022 {0x0ff0f010, 0x01100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13023 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"}, 13024 13025 // mov (immediate) 13026 {0x0fef0000, 0x03a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13027 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"}, 13028 {0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, 13029 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>"}, 13030 // mov (register) 13031 {0x0fef0ff0, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13032 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"}, 13033 // mvn (immediate) 13034 {0x0fef0000, 0x03e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13035 &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"}, 13036 // mvn (register) 13037 {0x0fef0010, 0x01e00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13038 &EmulateInstructionARM::EmulateMVNReg, 13039 "mvn{s}<c> <Rd>, <Rm> {,<shift>}"}, 13040 // cmn (immediate) 13041 {0x0ff0f000, 0x03700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13042 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13043 // cmn (register) 13044 {0x0ff0f010, 0x01700000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13045 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13046 // cmp (immediate) 13047 {0x0ff0f000, 0x03500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13048 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"}, 13049 // cmp (register) 13050 {0x0ff0f010, 0x01500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13051 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"}, 13052 // asr (immediate) 13053 {0x0fef0070, 0x01a00040, ARMvAll, eEncodingA1, No_VFP, eSize32, 13054 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"}, 13055 // asr (register) 13056 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13057 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"}, 13058 // lsl (immediate) 13059 {0x0fef0070, 0x01a00000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13060 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"}, 13061 // lsl (register) 13062 {0x0fef00f0, 0x01a00010, ARMvAll, eEncodingA1, No_VFP, eSize32, 13063 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"}, 13064 // lsr (immediate) 13065 {0x0fef0070, 0x01a00020, ARMvAll, eEncodingA1, No_VFP, eSize32, 13066 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"}, 13067 // lsr (register) 13068 {0x0fef00f0, 0x01a00050, ARMvAll, eEncodingA1, No_VFP, eSize32, 13069 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"}, 13070 // rrx is a special case encoding of ror (immediate) 13071 {0x0fef0ff0, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13072 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"}, 13073 // ror (immediate) 13074 {0x0fef0070, 0x01a00060, ARMvAll, eEncodingA1, No_VFP, eSize32, 13075 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"}, 13076 // ror (register) 13077 {0x0fef00f0, 0x01a00070, ARMvAll, eEncodingA1, No_VFP, eSize32, 13078 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"}, 13079 // mul 13080 {0x0fe000f0, 0x00000090, ARMvAll, eEncodingA1, No_VFP, eSize32, 13081 &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>"}, 13082 13083 // subs pc, lr and related instructions 13084 {0x0e10f000, 0x0210f000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13085 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13086 "<opc>S<c> PC,#<const> | <Rn>,#<const>"}, 13087 {0x0e10f010, 0x0010f000, ARMvAll, eEncodingA2, No_VFP, eSize32, 13088 &EmulateInstructionARM::EmulateSUBSPcLrEtc, 13089 "<opc>S<c> PC,<Rn>,<Rm{,<shift>}"}, 13090 13091 // Load instructions 13092 {0x0fd00000, 0x08900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13093 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13094 {0x0fd00000, 0x08100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13095 &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>"}, 13096 {0x0fd00000, 0x09100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13097 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13098 {0x0fd00000, 0x09900000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13099 &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>"}, 13100 {0x0e500000, 0x04100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13101 &EmulateInstructionARM::EmulateLDRImmediateARM, 13102 "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]"}, 13103 {0x0e500010, 0x06100000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13104 &EmulateInstructionARM::EmulateLDRRegister, 13105 "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}"}, 13106 {0x0e5f0000, 0x045f0000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13107 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"}, 13108 {0xfe500010, 0x06500000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13109 &EmulateInstructionARM::EmulateLDRBRegister, 13110 "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}"}, 13111 {0x0e5f00f0, 0x005f00b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13112 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13113 {0x0e5000f0, 0x001000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13114 &EmulateInstructionARM::EmulateLDRHRegister, 13115 "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13116 {0x0e5000f0, 0x005000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13117 &EmulateInstructionARM::EmulateLDRSBImmediate, 13118 "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]"}, 13119 {0x0e5f00f0, 0x005f00d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13120 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>"}, 13121 {0x0e5000f0, 0x001000d0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13122 &EmulateInstructionARM::EmulateLDRSBRegister, 13123 "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13124 {0x0e5000f0, 0x005000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13125 &EmulateInstructionARM::EmulateLDRSHImmediate, 13126 "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"}, 13127 {0x0e5f00f0, 0x005f00f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13128 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13129 {0x0e5000f0, 0x001000f0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13130 &EmulateInstructionARM::EmulateLDRSHRegister, 13131 "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"}, 13132 {0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13133 &EmulateInstructionARM::EmulateLDRDImmediate, 13134 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"}, 13135 {0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13136 &EmulateInstructionARM::EmulateLDRDRegister, 13137 "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13138 {0x0e100f00, 0x0c100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13139 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13140 {0x0e100f00, 0x0c100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13141 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13142 {0x0f300f00, 0x0d100b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13143 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13144 {0x0f300f00, 0x0d100a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13145 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13146 {0xffb00000, 0xf4200000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13147 &EmulateInstructionARM::EmulateVLD1Multiple, 13148 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13149 {0xffb00300, 0xf4a00000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13150 &EmulateInstructionARM::EmulateVLD1Single, 13151 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13152 {0xffb00f00, 0xf4a00c00, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13153 &EmulateInstructionARM::EmulateVLD1SingleAll, 13154 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13155 13156 // Store instructions 13157 {0x0fd00000, 0x08800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13158 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13159 {0x0fd00000, 0x08000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13160 &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>"}, 13161 {0x0fd00000, 0x09000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13162 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13163 {0x0fd00000, 0x09800000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13164 &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>"}, 13165 {0x0e500010, 0x06000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13166 &EmulateInstructionARM::EmulateSTRRegister, 13167 "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}"}, 13168 {0x0e5000f0, 0x000000b0, ARMvAll, eEncodingA1, No_VFP, eSize32, 13169 &EmulateInstructionARM::EmulateSTRHRegister, 13170 "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}"}, 13171 {0x0ff00ff0, 0x01800f90, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13172 &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"}, 13173 {0x0e500000, 0x04400000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13174 &EmulateInstructionARM::EmulateSTRBImmARM, 13175 "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13176 {0x0e500000, 0x04000000, ARMvAll, eEncodingA1, No_VFP, eSize32, 13177 &EmulateInstructionARM::EmulateSTRImmARM, 13178 "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"}, 13179 {0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13180 &EmulateInstructionARM::EmulateSTRDImm, 13181 "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"}, 13182 {0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, 13183 &EmulateInstructionARM::EmulateSTRDReg, 13184 "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"}, 13185 {0x0e100f00, 0x0c000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13186 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13187 {0x0e100f00, 0x0c000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13188 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"}, 13189 {0x0f300f00, 0x0d000b00, ARMvAll, eEncodingA1, VFPv2_ABOVE, eSize32, 13190 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"}, 13191 {0x0f300f00, 0x0d000a00, ARMvAll, eEncodingA2, VFPv2v3, eSize32, 13192 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"}, 13193 {0xffb00000, 0xf4000000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13194 &EmulateInstructionARM::EmulateVST1Multiple, 13195 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13196 {0xffb00300, 0xf4800000, ARMvAll, eEncodingA1, AdvancedSIMD, eSize32, 13197 &EmulateInstructionARM::EmulateVST1Single, 13198 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13199 13200 // Other instructions 13201 {0x0fff00f0, 0x06af00f0, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13202 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13203 {0x0fff00f0, 0x06bf0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13204 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}"}, 13205 {0x0fff00f0, 0x06ef0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13206 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}"}, 13207 {0x0fff00f0, 0x06ff0070, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13208 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}"}, 13209 {0xfe500000, 0xf8100000, ARMV6_ABOVE, eEncodingA1, No_VFP, eSize32, 13210 &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}"} 13211 13212 }; 13213 static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes); 13214 13215 for (size_t i = 0; i < k_num_arm_opcodes; ++i) { 13216 if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value && 13217 (g_arm_opcodes[i].variants & arm_isa) != 0) 13218 return &g_arm_opcodes[i]; 13219 } 13220 return nullptr; 13221} 13222 13223EmulateInstructionARM::ARMOpcode * 13224EmulateInstructionARM::GetThumbOpcodeForInstruction(const uint32_t opcode, 13225 uint32_t arm_isa) { 13226 13227 static ARMOpcode g_thumb_opcodes[] = { 13228 // Prologue instructions 13229 13230 // push register(s) 13231 {0xfffffe00, 0x0000b400, ARMvAll, eEncodingT1, No_VFP, eSize16, 13232 &EmulateInstructionARM::EmulatePUSH, "push <registers>"}, 13233 {0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13234 &EmulateInstructionARM::EmulatePUSH, "push.w <registers>"}, 13235 {0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13236 &EmulateInstructionARM::EmulatePUSH, "push.w <register>"}, 13237 13238 // set r7 to point to a stack offset 13239 {0xffffff00, 0x0000af00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13240 &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm"}, 13241 // copy the stack pointer to r7 13242 {0xffffffff, 0x0000466f, ARMvAll, eEncodingT1, No_VFP, eSize16, 13243 &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp"}, 13244 // move from high register to low register (comes after "mov r7, sp" to 13245 // resolve ambiguity) 13246 {0xffffffc0, 0x00004640, ARMvAll, eEncodingT1, No_VFP, eSize16, 13247 &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15"}, 13248 13249 // PC-relative load into register (see also EmulateADDSPRm) 13250 {0xfffff800, 0x00004800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13251 &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"}, 13252 13253 // adjust the stack pointer 13254 {0xffffff87, 0x00004485, ARMvAll, eEncodingT2, No_VFP, eSize16, 13255 &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"}, 13256 {0xffffff80, 0x0000b080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13257 &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"}, 13258 {0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13259 &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"}, 13260 {0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13261 &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"}, 13262 {0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13263 &EmulateInstructionARM::EmulateSUBSPReg, 13264 "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}"}, 13265 13266 // vector push consecutive extension register(s) 13267 {0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13268 &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"}, 13269 {0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13270 &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"}, 13271 13272 // Epilogue instructions 13273 13274 {0xfffff800, 0x0000a800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13275 &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"}, 13276 {0xffffff80, 0x0000b000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13277 &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"}, 13278 {0xfffffe00, 0x0000bc00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13279 &EmulateInstructionARM::EmulatePOP, "pop <registers>"}, 13280 {0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13281 &EmulateInstructionARM::EmulatePOP, "pop.w <registers>"}, 13282 {0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13283 &EmulateInstructionARM::EmulatePOP, "pop.w <register>"}, 13284 {0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13285 &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"}, 13286 {0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13287 &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"}, 13288 13289 // Supervisor Call (previously Software Interrupt) 13290 {0xffffff00, 0x0000df00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13291 &EmulateInstructionARM::EmulateSVC, "svc #imm8"}, 13292 13293 // If Then makes up to four following instructions conditional. 13294 // The next 5 opcode _must_ come before the if then instruction 13295 {0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13296 &EmulateInstructionARM::EmulateNop, "nop"}, 13297 {0xffffffff, 0x0000bf10, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13298 &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"}, 13299 {0xffffffff, 0x0000bf20, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13300 &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"}, 13301 {0xffffffff, 0x0000bf30, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13302 &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"}, 13303 {0xffffffff, 0x0000bf40, ARMV7_ABOVE, eEncodingT1, No_VFP, eSize16, 13304 &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"}, 13305 {0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13306 &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"}, 13307 13308 // Branch instructions 13309 // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8". 13310 {0xfffff000, 0x0000d000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13311 &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"}, 13312 {0xfffff800, 0x0000e000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13313 &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"}, 13314 {0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13315 &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"}, 13316 {0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13317 &EmulateInstructionARM::EmulateB, 13318 "b<c>.w #imm8 (outside or last in IT)"}, 13319 // J1 == J2 == 1 13320 {0xf800d000, 0xf000d000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize32, 13321 &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"}, 13322 // J1 == J2 == 1 13323 {0xf800d001, 0xf000c000, ARMV5_ABOVE, eEncodingT2, No_VFP, eSize32, 13324 &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"}, 13325 {0xffffff87, 0x00004780, ARMV5_ABOVE, eEncodingT1, No_VFP, eSize16, 13326 &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"}, 13327 // for example, "bx lr" 13328 {0xffffff87, 0x00004700, ARMvAll, eEncodingT1, No_VFP, eSize32, 13329 &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"}, 13330 // bxj 13331 {0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE, eEncodingT1, No_VFP, eSize32, 13332 &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"}, 13333 // compare and branch 13334 {0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13335 &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"}, 13336 // table branch byte 13337 {0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13338 &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"}, 13339 // table branch halfword 13340 {0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13341 &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"}, 13342 13343 // Data-processing instructions 13344 // adc (immediate) 13345 {0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13346 &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"}, 13347 // adc (register) 13348 {0xffffffc0, 0x00004140, ARMvAll, eEncodingT1, No_VFP, eSize16, 13349 &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"}, 13350 {0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13351 &EmulateInstructionARM::EmulateADCReg, 13352 "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13353 // add (register) 13354 {0xfffffe00, 0x00001800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13355 &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"}, 13356 // Make sure "add sp, <Rm>" comes before this instruction, so there's no 13357 // ambiguity decoding the two. 13358 {0xffffff00, 0x00004400, ARMvAll, eEncodingT2, No_VFP, eSize16, 13359 &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"}, 13360 // adr 13361 {0xfffff800, 0x0000a000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13362 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13363 {0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13364 &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"}, 13365 {0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13366 &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"}, 13367 // and (immediate) 13368 {0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13369 &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"}, 13370 // and (register) 13371 {0xffffffc0, 0x00004000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13372 &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"}, 13373 {0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13374 &EmulateInstructionARM::EmulateANDReg, 13375 "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13376 // bic (immediate) 13377 {0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13378 &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"}, 13379 // bic (register) 13380 {0xffffffc0, 0x00004380, ARMvAll, eEncodingT1, No_VFP, eSize16, 13381 &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"}, 13382 {0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13383 &EmulateInstructionARM::EmulateBICReg, 13384 "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13385 // eor (immediate) 13386 {0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13387 &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"}, 13388 // eor (register) 13389 {0xffffffc0, 0x00004040, ARMvAll, eEncodingT1, No_VFP, eSize16, 13390 &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"}, 13391 {0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13392 &EmulateInstructionARM::EmulateEORReg, 13393 "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13394 // orr (immediate) 13395 {0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13396 &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"}, 13397 // orr (register) 13398 {0xffffffc0, 0x00004300, ARMvAll, eEncodingT1, No_VFP, eSize16, 13399 &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"}, 13400 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13401 &EmulateInstructionARM::EmulateORRReg, 13402 "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13403 // rsb (immediate) 13404 {0xffffffc0, 0x00004240, ARMvAll, eEncodingT1, No_VFP, eSize16, 13405 &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"}, 13406 {0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13407 &EmulateInstructionARM::EmulateRSBImm, 13408 "rsb{s}<c>.w <Rd>, <Rn>, #<const>"}, 13409 // rsb (register) 13410 {0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13411 &EmulateInstructionARM::EmulateRSBReg, 13412 "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13413 // sbc (immediate) 13414 {0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13415 &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"}, 13416 // sbc (register) 13417 {0xffffffc0, 0x00004180, ARMvAll, eEncodingT1, No_VFP, eSize16, 13418 &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"}, 13419 {0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13420 &EmulateInstructionARM::EmulateSBCReg, 13421 "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"}, 13422 // add (immediate, Thumb) 13423 {0xfffffe00, 0x00001c00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13424 &EmulateInstructionARM::EmulateADDImmThumb, 13425 "adds|add<c> <Rd>,<Rn>,#<imm3>"}, 13426 {0xfffff800, 0x00003000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13427 &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>"}, 13428 {0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13429 &EmulateInstructionARM::EmulateADDImmThumb, 13430 "add{s}<c>.w <Rd>,<Rn>,#<const>"}, 13431 {0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13432 &EmulateInstructionARM::EmulateADDImmThumb, 13433 "addw<c> <Rd>,<Rn>,#<imm12>"}, 13434 // sub (immediate, Thumb) 13435 {0xfffffe00, 0x00001e00, ARMvAll, eEncodingT1, No_VFP, eSize16, 13436 &EmulateInstructionARM::EmulateSUBImmThumb, 13437 "subs|sub<c> <Rd>, <Rn> #imm3"}, 13438 {0xfffff800, 0x00003800, ARMvAll, eEncodingT2, No_VFP, eSize16, 13439 &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"}, 13440 {0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13441 &EmulateInstructionARM::EmulateSUBImmThumb, 13442 "sub{s}<c>.w <Rd>, <Rn>, #<const>"}, 13443 {0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13444 &EmulateInstructionARM::EmulateSUBImmThumb, 13445 "subw<c> <Rd>, <Rn>, #imm12"}, 13446 // sub (sp minus immediate) 13447 {0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13448 &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"}, 13449 {0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13450 &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"}, 13451 // sub (register) 13452 {0xfffffe00, 0x00001a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13453 &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"}, 13454 {0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13455 &EmulateInstructionARM::EmulateSUBReg, 13456 "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"}, 13457 // teq (immediate) 13458 {0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13459 &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"}, 13460 // teq (register) 13461 {0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13462 &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"}, 13463 // tst (immediate) 13464 {0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13465 &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"}, 13466 // tst (register) 13467 {0xffffffc0, 0x00004200, ARMvAll, eEncodingT1, No_VFP, eSize16, 13468 &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"}, 13469 {0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13470 &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"}, 13471 13472 // move from high register to high register 13473 {0xffffff00, 0x00004600, ARMvAll, eEncodingT1, No_VFP, eSize16, 13474 &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"}, 13475 // move from low register to low register 13476 {0xffffffc0, 0x00000000, ARMvAll, eEncodingT2, No_VFP, eSize16, 13477 &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"}, 13478 // mov{s}<c>.w <Rd>, <Rm> 13479 {0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13480 &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"}, 13481 // move immediate 13482 {0xfffff800, 0x00002000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13483 &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"}, 13484 {0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13485 &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"}, 13486 {0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13487 &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"}, 13488 // mvn (immediate) 13489 {0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13490 &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"}, 13491 // mvn (register) 13492 {0xffffffc0, 0x000043c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13493 &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"}, 13494 {0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13495 &EmulateInstructionARM::EmulateMVNReg, 13496 "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"}, 13497 // cmn (immediate) 13498 {0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13499 &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"}, 13500 // cmn (register) 13501 {0xffffffc0, 0x000042c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13502 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"}, 13503 {0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13504 &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"}, 13505 // cmp (immediate) 13506 {0xfffff800, 0x00002800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13507 &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"}, 13508 {0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13509 &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"}, 13510 // cmp (register) (Rn and Rm both from r0-r7) 13511 {0xffffffc0, 0x00004280, ARMvAll, eEncodingT1, No_VFP, eSize16, 13512 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13513 // cmp (register) (Rn and Rm not both from r0-r7) 13514 {0xffffff00, 0x00004500, ARMvAll, eEncodingT2, No_VFP, eSize16, 13515 &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"}, 13516 {0xfff08f00, 0xebb00f00, ARMvAll, eEncodingT3, No_VFP, eSize16, 13517 &EmulateInstructionARM::EmulateCMPReg, 13518 "cmp<c>.w <Rn>, <Rm> {, <shift>}"}, 13519 // asr (immediate) 13520 {0xfffff800, 0x00001000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13521 &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"}, 13522 {0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13523 &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"}, 13524 // asr (register) 13525 {0xffffffc0, 0x00004100, ARMvAll, eEncodingT1, No_VFP, eSize16, 13526 &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"}, 13527 {0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13528 &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13529 // lsl (immediate) 13530 {0xfffff800, 0x00000000, ARMvAll, eEncodingT1, No_VFP, eSize16, 13531 &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"}, 13532 {0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13533 &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"}, 13534 // lsl (register) 13535 {0xffffffc0, 0x00004080, ARMvAll, eEncodingT1, No_VFP, eSize16, 13536 &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"}, 13537 {0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13538 &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13539 // lsr (immediate) 13540 {0xfffff800, 0x00000800, ARMvAll, eEncodingT1, No_VFP, eSize16, 13541 &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"}, 13542 {0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13543 &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"}, 13544 // lsr (register) 13545 {0xffffffc0, 0x000040c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13546 &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"}, 13547 {0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13548 &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13549 // rrx is a special case encoding of ror (immediate) 13550 {0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13551 &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"}, 13552 // ror (immediate) 13553 {0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13554 &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"}, 13555 // ror (register) 13556 {0xffffffc0, 0x000041c0, ARMvAll, eEncodingT1, No_VFP, eSize16, 13557 &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"}, 13558 {0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13559 &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"}, 13560 // mul 13561 {0xffffffc0, 0x00004340, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13562 &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>"}, 13563 // mul 13564 {0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13565 &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>"}, 13566 13567 // subs pc, lr and related instructions 13568 {0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13569 &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>"}, 13570 13571 // RFE instructions *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE 13572 // LDM.. Instructions in this table; 13573 // otherwise the wrong instructions will be selected. 13574 13575 {0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13576 &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}"}, 13577 {0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13578 &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}"}, 13579 13580 // Load instructions 13581 {0xfffff800, 0x0000c800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13582 &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>"}, 13583 {0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13584 &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>"}, 13585 {0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13586 &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>"}, 13587 {0xfffff800, 0x00006800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13588 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"}, 13589 {0xfffff800, 0x00009800, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13590 &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"}, 13591 {0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13592 &EmulateInstructionARM::EmulateLDRRtRnImm, 13593 "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"}, 13594 {0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13595 &EmulateInstructionARM::EmulateLDRRtRnImm, 13596 "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"}, 13597 // Thumb2 PC-relative load into register 13598 {0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13599 &EmulateInstructionARM::EmulateLDRRtPCRelative, 13600 "ldr<c>.w <Rt>, [PC, +/-#imm}]"}, 13601 {0xfffffe00, 0x00005800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13602 &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]"}, 13603 {0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13604 &EmulateInstructionARM::EmulateLDRRegister, 13605 "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]"}, 13606 {0xfffff800, 0x00007800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13607 &EmulateInstructionARM::EmulateLDRBImmediate, 13608 "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]"}, 13609 {0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13610 &EmulateInstructionARM::EmulateLDRBImmediate, 13611 "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13612 {0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13613 &EmulateInstructionARM::EmulateLDRBImmediate, 13614 "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}"}, 13615 {0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13616 &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]"}, 13617 {0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, 13618 &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]"}, 13619 {0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13620 &EmulateInstructionARM::EmulateLDRBRegister, 13621 "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13622 {0xfffff800, 0x00008800, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13623 &EmulateInstructionARM::EmulateLDRHImmediate, 13624 "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"}, 13625 {0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13626 &EmulateInstructionARM::EmulateLDRHImmediate, 13627 "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]"}, 13628 {0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13629 &EmulateInstructionARM::EmulateLDRHImmediate, 13630 "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"}, 13631 {0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13632 &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>"}, 13633 {0xfffffe00, 0x00005a00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13634 &EmulateInstructionARM::EmulateLDRHRegister, 13635 "ldrh<c> <Rt>, [<Rn>,<Rm>]"}, 13636 {0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13637 &EmulateInstructionARM::EmulateLDRHRegister, 13638 "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13639 {0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13640 &EmulateInstructionARM::EmulateLDRSBImmediate, 13641 "ldrsb<c> <Rt>,[<Rn>,#<imm12>]"}, 13642 {0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13643 &EmulateInstructionARM::EmulateLDRSBImmediate, 13644 "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13645 {0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13646 &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>"}, 13647 {0xfffffe00, 0x00005600, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13648 &EmulateInstructionARM::EmulateLDRSBRegister, 13649 "ldrsb<c> <Rt>,[<Rn>,<Rm>]"}, 13650 {0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13651 &EmulateInstructionARM::EmulateLDRSBRegister, 13652 "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"}, 13653 {0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13654 &EmulateInstructionARM::EmulateLDRSHImmediate, 13655 "ldrsh<c> <Rt>,[<Rn>,#<imm12>]"}, 13656 {0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13657 &EmulateInstructionARM::EmulateLDRSHImmediate, 13658 "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]"}, 13659 {0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13660 &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>"}, 13661 {0xfffffe00, 0x00005e00, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13662 &EmulateInstructionARM::EmulateLDRSHRegister, 13663 "ldrsh<c> <Rt>,[<Rn>,<Rm>]"}, 13664 {0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13665 &EmulateInstructionARM::EmulateLDRSHRegister, 13666 "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13667 {0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13668 &EmulateInstructionARM::EmulateLDRDImmediate, 13669 "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"}, 13670 {0xfe100f00, 0xec100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13671 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13672 {0xfe100f00, 0xec100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13673 &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"}, 13674 {0xffe00f00, 0xed100b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13675 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13676 {0xff300f00, 0xed100a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13677 &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"}, 13678 {0xffb00000, 0xf9200000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13679 &EmulateInstructionARM::EmulateVLD1Multiple, 13680 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13681 {0xffb00300, 0xf9a00000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13682 &EmulateInstructionARM::EmulateVLD1Single, 13683 "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"}, 13684 {0xffb00f00, 0xf9a00c00, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13685 &EmulateInstructionARM::EmulateVLD1SingleAll, 13686 "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13687 13688 // Store instructions 13689 {0xfffff800, 0x0000c000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13690 &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>"}, 13691 {0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13692 &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>"}, 13693 {0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13694 &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>"}, 13695 {0xfffff800, 0x00006000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13696 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]"}, 13697 {0xfffff800, 0x00009000, ARMV4T_ABOVE, eEncodingT2, No_VFP, eSize16, 13698 &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]"}, 13699 {0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13700 &EmulateInstructionARM::EmulateSTRThumb, 13701 "str<c>.w <Rt>, [<Rn>,#<imm12>]"}, 13702 {0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, 13703 &EmulateInstructionARM::EmulateSTRThumb, 13704 "str<c> <Rt>, [<Rn>,#+/-<imm8>]"}, 13705 {0xfffffe00, 0x00005000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13706 &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]"}, 13707 {0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13708 &EmulateInstructionARM::EmulateSTRRegister, 13709 "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]"}, 13710 {0xfffff800, 0x00007000, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13711 &EmulateInstructionARM::EmulateSTRBThumb, 13712 "strb<c> <Rt>, [<Rn>, #<imm5>]"}, 13713 {0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13714 &EmulateInstructionARM::EmulateSTRBThumb, 13715 "strb<c>.w <Rt>, [<Rn>, #<imm12>]"}, 13716 {0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, 13717 &EmulateInstructionARM::EmulateSTRBThumb, 13718 "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}"}, 13719 {0xfffffe00, 0x00005200, ARMV4T_ABOVE, eEncodingT1, No_VFP, eSize16, 13720 &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]"}, 13721 {0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13722 &EmulateInstructionARM::EmulateSTRHRegister, 13723 "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]"}, 13724 {0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13725 &EmulateInstructionARM::EmulateSTREX, 13726 "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]"}, 13727 {0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, 13728 &EmulateInstructionARM::EmulateSTRDImm, 13729 "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"}, 13730 {0xfe100f00, 0xec000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13731 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13732 {0xfea00f00, 0xec000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13733 &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"}, 13734 {0xff300f00, 0xed000b00, ARMvAll, eEncodingT1, VFPv2_ABOVE, eSize32, 13735 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"}, 13736 {0xff300f00, 0xed000a00, ARMvAll, eEncodingT2, VFPv2v3, eSize32, 13737 &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"}, 13738 {0xffb00000, 0xf9000000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13739 &EmulateInstructionARM::EmulateVST1Multiple, 13740 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13741 {0xffb00300, 0xf9800000, ARMvAll, eEncodingT1, AdvancedSIMD, eSize32, 13742 &EmulateInstructionARM::EmulateVST1Single, 13743 "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 13744 13745 // Other instructions 13746 {0xffffffc0, 0x0000b240, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13747 &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>"}, 13748 {0xfffff080, 0xfa4ff080, ARMV6_ABOVE, eEncodingT2, No_VFP, eSize32, 13749 &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13750 {0xffffffc0, 0x0000b200, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13751 &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>"}, 13752 {0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13753 &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13754 {0xffffffc0, 0x0000b2c0, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13755 &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>"}, 13756 {0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13757 &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}"}, 13758 {0xffffffc0, 0x0000b280, ARMV6_ABOVE, eEncodingT1, No_VFP, eSize16, 13759 &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>"}, 13760 {0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, 13761 &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}"}, 13762 }; 13763 13764 const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes); 13765 for (size_t i = 0; i < k_num_thumb_opcodes; ++i) { 13766 if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value && 13767 (g_thumb_opcodes[i].variants & arm_isa) != 0) 13768 return &g_thumb_opcodes[i]; 13769 } 13770 return nullptr; 13771} 13772 13773bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { 13774 m_arch = arch; 13775 m_arm_isa = 0; 13776 const char *arch_cstr = arch.GetArchitectureName(); 13777 if (arch_cstr) { 13778 if (0 == ::strcasecmp(arch_cstr, "armv4t")) 13779 m_arm_isa = ARMv4T; 13780 else if (0 == ::strcasecmp(arch_cstr, "armv5tej")) 13781 m_arm_isa = ARMv5TEJ; 13782 else if (0 == ::strcasecmp(arch_cstr, "armv5te")) 13783 m_arm_isa = ARMv5TE; 13784 else if (0 == ::strcasecmp(arch_cstr, "armv5t")) 13785 m_arm_isa = ARMv5T; 13786 else if (0 == ::strcasecmp(arch_cstr, "armv6k")) 13787 m_arm_isa = ARMv6K; 13788 else if (0 == ::strcasecmp(arch_cstr, "armv6t2")) 13789 m_arm_isa = ARMv6T2; 13790 else if (0 == ::strcasecmp(arch_cstr, "armv7s")) 13791 m_arm_isa = ARMv7S; 13792 else if (0 == ::strcasecmp(arch_cstr, "arm")) 13793 m_arm_isa = ARMvAll; 13794 else if (0 == ::strcasecmp(arch_cstr, "thumb")) 13795 m_arm_isa = ARMvAll; 13796 else if (0 == ::strncasecmp(arch_cstr, "armv4", 5)) 13797 m_arm_isa = ARMv4; 13798 else if (0 == ::strncasecmp(arch_cstr, "armv6", 5)) 13799 m_arm_isa = ARMv6; 13800 else if (0 == ::strncasecmp(arch_cstr, "armv7", 5)) 13801 m_arm_isa = ARMv7; 13802 else if (0 == ::strncasecmp(arch_cstr, "armv8", 5)) 13803 m_arm_isa = ARMv8; 13804 } 13805 return m_arm_isa != 0; 13806} 13807 13808bool EmulateInstructionARM::SetInstruction(const Opcode &insn_opcode, 13809 const Address &inst_addr, 13810 Target *target) { 13811 if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { 13812 if (m_arch.GetTriple().getArch() == llvm::Triple::thumb || 13813 m_arch.IsAlwaysThumbInstructions()) 13814 m_opcode_mode = eModeThumb; 13815 else { 13816 AddressClass addr_class = inst_addr.GetAddressClass(); 13817 13818 if ((addr_class == AddressClass::eCode) || 13819 (addr_class == AddressClass::eUnknown)) 13820 m_opcode_mode = eModeARM; 13821 else if (addr_class == AddressClass::eCodeAlternateISA) 13822 m_opcode_mode = eModeThumb; 13823 else 13824 return false; 13825 } 13826 if (m_opcode_mode == eModeThumb || m_arch.IsAlwaysThumbInstructions()) 13827 m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T; 13828 else 13829 m_opcode_cpsr = CPSR_MODE_USR; 13830 return true; 13831 } 13832 return false; 13833} 13834 13835bool EmulateInstructionARM::ReadInstruction() { 13836 bool success = false; 13837 m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindGeneric, 13838 LLDB_REGNUM_GENERIC_FLAGS, 0, &success); 13839 if (success) { 13840 addr_t pc = 13841 ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, 13842 LLDB_INVALID_ADDRESS, &success); 13843 if (success) { 13844 Context read_inst_context; 13845 read_inst_context.type = eContextReadOpcode; 13846 read_inst_context.SetNoArgs(); 13847 13848 if ((m_opcode_cpsr & MASK_CPSR_T) || m_arch.IsAlwaysThumbInstructions()) { 13849 m_opcode_mode = eModeThumb; 13850 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success); 13851 13852 if (success) { 13853 if ((thumb_opcode & 0xe000) != 0xe000 || 13854 ((thumb_opcode & 0x1800u) == 0)) { 13855 m_opcode.SetOpcode16(thumb_opcode, GetByteOrder()); 13856 } else { 13857 m_opcode.SetOpcode32( 13858 (thumb_opcode << 16) | 13859 MemARead(read_inst_context, pc + 2, 2, 0, &success), 13860 GetByteOrder()); 13861 } 13862 } 13863 } else { 13864 m_opcode_mode = eModeARM; 13865 m_opcode.SetOpcode32(MemARead(read_inst_context, pc, 4, 0, &success), 13866 GetByteOrder()); 13867 } 13868 13869 if (!m_ignore_conditions) { 13870 // If we are not ignoreing the conditions then init the it session from 13871 // the current value of cpsr. 13872 uint32_t it = (Bits32(m_opcode_cpsr, 15, 10) << 2) | 13873 Bits32(m_opcode_cpsr, 26, 25); 13874 if (it != 0) 13875 m_it_session.InitIT(it); 13876 } 13877 } 13878 } 13879 if (!success) { 13880 m_opcode_mode = eModeInvalid; 13881 m_addr = LLDB_INVALID_ADDRESS; 13882 } 13883 return success; 13884} 13885 13886uint32_t EmulateInstructionARM::ArchVersion() { return m_arm_isa; } 13887 13888bool EmulateInstructionARM::ConditionPassed(const uint32_t opcode) { 13889 // If we are ignoring conditions, then always return true. this allows us to 13890 // iterate over disassembly code and still emulate an instruction even if we 13891 // don't have all the right bits set in the CPSR register... 13892 if (m_ignore_conditions) 13893 return true; 13894 13895 const uint32_t cond = CurrentCond(opcode); 13896 if (cond == UINT32_MAX) 13897 return false; 13898 13899 bool result = false; 13900 switch (UnsignedBits(cond, 3, 1)) { 13901 case 0: 13902 if (m_opcode_cpsr == 0) 13903 result = true; 13904 else 13905 result = (m_opcode_cpsr & MASK_CPSR_Z) != 0; 13906 break; 13907 case 1: 13908 if (m_opcode_cpsr == 0) 13909 result = true; 13910 else 13911 result = (m_opcode_cpsr & MASK_CPSR_C) != 0; 13912 break; 13913 case 2: 13914 if (m_opcode_cpsr == 0) 13915 result = true; 13916 else 13917 result = (m_opcode_cpsr & MASK_CPSR_N) != 0; 13918 break; 13919 case 3: 13920 if (m_opcode_cpsr == 0) 13921 result = true; 13922 else 13923 result = (m_opcode_cpsr & MASK_CPSR_V) != 0; 13924 break; 13925 case 4: 13926 if (m_opcode_cpsr == 0) 13927 result = true; 13928 else 13929 result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && 13930 ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13931 break; 13932 case 5: 13933 if (m_opcode_cpsr == 0) 13934 result = true; 13935 else { 13936 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13937 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13938 result = n == v; 13939 } 13940 break; 13941 case 6: 13942 if (m_opcode_cpsr == 0) 13943 result = true; 13944 else { 13945 bool n = (m_opcode_cpsr & MASK_CPSR_N); 13946 bool v = (m_opcode_cpsr & MASK_CPSR_V); 13947 result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0); 13948 } 13949 break; 13950 case 7: 13951 // Always execute (cond == 0b1110, or the special 0b1111 which gives 13952 // opcodes different meanings, but always means execution happens. 13953 return true; 13954 } 13955 13956 if (cond & 1) 13957 result = !result; 13958 return result; 13959} 13960 13961uint32_t EmulateInstructionARM::CurrentCond(const uint32_t opcode) { 13962 switch (m_opcode_mode) { 13963 case eModeInvalid: 13964 break; 13965 13966 case eModeARM: 13967 return UnsignedBits(opcode, 31, 28); 13968 13969 case eModeThumb: 13970 // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit 13971 // 'cond' field of the encoding. 13972 { 13973 const uint32_t byte_size = m_opcode.GetByteSize(); 13974 if (byte_size == 2) { 13975 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f) 13976 return Bits32(opcode, 11, 8); 13977 } else if (byte_size == 4) { 13978 if (Bits32(opcode, 31, 27) == 0x1e && Bits32(opcode, 15, 14) == 0x02 && 13979 Bits32(opcode, 12, 12) == 0x00 && Bits32(opcode, 25, 22) <= 0x0d) { 13980 return Bits32(opcode, 25, 22); 13981 } 13982 } else 13983 // We have an invalid thumb instruction, let's bail out. 13984 break; 13985 13986 return m_it_session.GetCond(); 13987 } 13988 } 13989 return UINT32_MAX; // Return invalid value 13990} 13991 13992bool EmulateInstructionARM::InITBlock() { 13993 return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock(); 13994} 13995 13996bool EmulateInstructionARM::LastInITBlock() { 13997 return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock(); 13998} 13999 14000bool EmulateInstructionARM::BadMode(uint32_t mode) { 14001 14002 switch (mode) { 14003 case 16: 14004 return false; // '10000' 14005 case 17: 14006 return false; // '10001' 14007 case 18: 14008 return false; // '10010' 14009 case 19: 14010 return false; // '10011' 14011 case 22: 14012 return false; // '10110' 14013 case 23: 14014 return false; // '10111' 14015 case 27: 14016 return false; // '11011' 14017 case 31: 14018 return false; // '11111' 14019 default: 14020 return true; 14021 } 14022 return true; 14023} 14024 14025bool EmulateInstructionARM::CurrentModeIsPrivileged() { 14026 uint32_t mode = Bits32(m_opcode_cpsr, 4, 0); 14027 14028 if (BadMode(mode)) 14029 return false; 14030 14031 if (mode == 16) 14032 return false; 14033 14034 return true; 14035} 14036 14037void EmulateInstructionARM::CPSRWriteByInstr(uint32_t value, uint32_t bytemask, 14038 bool affect_execstate) { 14039 bool privileged = CurrentModeIsPrivileged(); 14040 14041 uint32_t tmp_cpsr = Bits32(m_opcode_cpsr, 23, 20) << 20; 14042 14043 if (BitIsSet(bytemask, 3)) { 14044 tmp_cpsr = tmp_cpsr | (Bits32(value, 31, 27) << 27); 14045 if (affect_execstate) 14046 tmp_cpsr = tmp_cpsr | (Bits32(value, 26, 24) << 24); 14047 } 14048 14049 if (BitIsSet(bytemask, 2)) { 14050 tmp_cpsr = tmp_cpsr | (Bits32(value, 19, 16) << 16); 14051 } 14052 14053 if (BitIsSet(bytemask, 1)) { 14054 if (affect_execstate) 14055 tmp_cpsr = tmp_cpsr | (Bits32(value, 15, 10) << 10); 14056 tmp_cpsr = tmp_cpsr | (Bit32(value, 9) << 9); 14057 if (privileged) 14058 tmp_cpsr = tmp_cpsr | (Bit32(value, 8) << 8); 14059 } 14060 14061 if (BitIsSet(bytemask, 0)) { 14062 if (privileged) 14063 tmp_cpsr = tmp_cpsr | (Bits32(value, 7, 6) << 6); 14064 if (affect_execstate) 14065 tmp_cpsr = tmp_cpsr | (Bit32(value, 5) << 5); 14066 if (privileged) 14067 tmp_cpsr = tmp_cpsr | Bits32(value, 4, 0); 14068 } 14069 14070 m_opcode_cpsr = tmp_cpsr; 14071} 14072 14073bool EmulateInstructionARM::BranchWritePC(const Context &context, 14074 uint32_t addr) { 14075 addr_t target; 14076 14077 // Check the current instruction set. 14078 if (CurrentInstrSet() == eModeARM) 14079 target = addr & 0xfffffffc; 14080 else 14081 target = addr & 0xfffffffe; 14082 14083 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14084 LLDB_REGNUM_GENERIC_PC, target); 14085} 14086 14087// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by 14088// inspecting addr. 14089bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { 14090 addr_t target; 14091 // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE, 14092 // we want to record it and issue a WriteRegister callback so the clients can 14093 // track the mode changes accordingly. 14094 bool cpsr_changed = false; 14095 14096 if (BitIsSet(addr, 0)) { 14097 if (CurrentInstrSet() != eModeThumb) { 14098 SelectInstrSet(eModeThumb); 14099 cpsr_changed = true; 14100 } 14101 target = addr & 0xfffffffe; 14102 context.SetISA(eModeThumb); 14103 } else if (BitIsClear(addr, 1)) { 14104 if (CurrentInstrSet() != eModeARM) { 14105 SelectInstrSet(eModeARM); 14106 cpsr_changed = true; 14107 } 14108 target = addr & 0xfffffffc; 14109 context.SetISA(eModeARM); 14110 } else 14111 return false; // address<1:0> == '10' => UNPREDICTABLE 14112 14113 if (cpsr_changed) { 14114 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14115 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14116 return false; 14117 } 14118 return WriteRegisterUnsigned(context, eRegisterKindGeneric, 14119 LLDB_REGNUM_GENERIC_PC, target); 14120} 14121 14122// Dispatches to either BXWritePC or BranchWritePC based on architecture 14123// versions. 14124bool EmulateInstructionARM::LoadWritePC(Context &context, uint32_t addr) { 14125 if (ArchVersion() >= ARMv5T) 14126 return BXWritePC(context, addr); 14127 else 14128 return BranchWritePC((const Context)context, addr); 14129} 14130 14131// Dispatches to either BXWritePC or BranchWritePC based on architecture 14132// versions and current instruction set. 14133bool EmulateInstructionARM::ALUWritePC(Context &context, uint32_t addr) { 14134 if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) 14135 return BXWritePC(context, addr); 14136 else 14137 return BranchWritePC((const Context)context, addr); 14138} 14139 14140EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { 14141 return m_opcode_mode; 14142} 14143 14144// Set the 'T' bit of our CPSR. The m_opcode_mode gets updated when the next 14145// ReadInstruction() is performed. This function has a side effect of updating 14146// the m_new_inst_cpsr member variable if necessary. 14147bool EmulateInstructionARM::SelectInstrSet(Mode arm_or_thumb) { 14148 m_new_inst_cpsr = m_opcode_cpsr; 14149 switch (arm_or_thumb) { 14150 default: 14151 return false; 14152 case eModeARM: 14153 // Clear the T bit. 14154 m_new_inst_cpsr &= ~MASK_CPSR_T; 14155 break; 14156 case eModeThumb: 14157 // Set the T bit. 14158 m_new_inst_cpsr |= MASK_CPSR_T; 14159 break; 14160 } 14161 return true; 14162} 14163 14164// This function returns TRUE if the processor currently provides support for 14165// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7, 14166// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6. 14167bool EmulateInstructionARM::UnalignedSupport() { 14168 return (ArchVersion() >= ARMv7); 14169} 14170 14171// The main addition and subtraction instructions can produce status 14172// information about both unsigned carry and signed overflow conditions. This 14173// status information can be used to synthesize multi-word additions and 14174// subtractions. 14175EmulateInstructionARM::AddWithCarryResult 14176EmulateInstructionARM::AddWithCarry(uint32_t x, uint32_t y, uint8_t carry_in) { 14177 uint32_t result; 14178 uint8_t carry_out; 14179 uint8_t overflow; 14180 14181 uint64_t unsigned_sum = x + y + carry_in; 14182 int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in; 14183 14184 result = UnsignedBits(unsigned_sum, 31, 0); 14185 // carry_out = (result == unsigned_sum ? 0 : 1); 14186 overflow = ((int32_t)result == signed_sum ? 0 : 1); 14187 14188 if (carry_in) 14189 carry_out = ((int32_t)x >= (int32_t)(~y)) ? 1 : 0; 14190 else 14191 carry_out = ((int32_t)x > (int32_t)y) ? 1 : 0; 14192 14193 AddWithCarryResult res = {result, carry_out, overflow}; 14194 return res; 14195} 14196 14197uint32_t EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success) { 14198 lldb::RegisterKind reg_kind; 14199 uint32_t reg_num; 14200 switch (num) { 14201 case SP_REG: 14202 reg_kind = eRegisterKindGeneric; 14203 reg_num = LLDB_REGNUM_GENERIC_SP; 14204 break; 14205 case LR_REG: 14206 reg_kind = eRegisterKindGeneric; 14207 reg_num = LLDB_REGNUM_GENERIC_RA; 14208 break; 14209 case PC_REG: 14210 reg_kind = eRegisterKindGeneric; 14211 reg_num = LLDB_REGNUM_GENERIC_PC; 14212 break; 14213 default: 14214 if (num < SP_REG) { 14215 reg_kind = eRegisterKindDWARF; 14216 reg_num = dwarf_r0 + num; 14217 } else { 14218 // assert(0 && "Invalid register number"); 14219 *success = false; 14220 return UINT32_MAX; 14221 } 14222 break; 14223 } 14224 14225 // Read our register. 14226 uint32_t val = ReadRegisterUnsigned(reg_kind, reg_num, 0, success); 14227 14228 // When executing an ARM instruction , PC reads as the address of the current 14229 // instruction plus 8. When executing a Thumb instruction , PC reads as the 14230 // address of the current instruction plus 4. 14231 if (num == 15) { 14232 if (CurrentInstrSet() == eModeARM) 14233 val += 8; 14234 else 14235 val += 4; 14236 } 14237 14238 return val; 14239} 14240 14241// Write the result to the ARM core register Rd, and optionally update the 14242// condition flags based on the result. 14243// 14244// This helper method tries to encapsulate the following pseudocode from the 14245// ARM Architecture Reference Manual: 14246// 14247// if d == 15 then // Can only occur for encoding A1 14248// ALUWritePC(result); // setflags is always FALSE here 14249// else 14250// R[d] = result; 14251// if setflags then 14252// APSR.N = result<31>; 14253// APSR.Z = IsZeroBit(result); 14254// APSR.C = carry; 14255// // APSR.V unchanged 14256// 14257// In the above case, the API client does not pass in the overflow arg, which 14258// defaults to ~0u. 14259bool EmulateInstructionARM::WriteCoreRegOptionalFlags( 14260 Context &context, const uint32_t result, const uint32_t Rd, bool setflags, 14261 const uint32_t carry, const uint32_t overflow) { 14262 if (Rd == 15) { 14263 if (!ALUWritePC(context, result)) 14264 return false; 14265 } else { 14266 lldb::RegisterKind reg_kind; 14267 uint32_t reg_num; 14268 switch (Rd) { 14269 case SP_REG: 14270 reg_kind = eRegisterKindGeneric; 14271 reg_num = LLDB_REGNUM_GENERIC_SP; 14272 break; 14273 case LR_REG: 14274 reg_kind = eRegisterKindGeneric; 14275 reg_num = LLDB_REGNUM_GENERIC_RA; 14276 break; 14277 default: 14278 reg_kind = eRegisterKindDWARF; 14279 reg_num = dwarf_r0 + Rd; 14280 } 14281 if (!WriteRegisterUnsigned(context, reg_kind, reg_num, result)) 14282 return false; 14283 if (setflags) 14284 return WriteFlags(context, result, carry, overflow); 14285 } 14286 return true; 14287} 14288 14289// This helper method tries to encapsulate the following pseudocode from the 14290// ARM Architecture Reference Manual: 14291// 14292// APSR.N = result<31>; 14293// APSR.Z = IsZeroBit(result); 14294// APSR.C = carry; 14295// APSR.V = overflow 14296// 14297// Default arguments can be specified for carry and overflow parameters, which 14298// means not to update the respective flags. 14299bool EmulateInstructionARM::WriteFlags(Context &context, const uint32_t result, 14300 const uint32_t carry, 14301 const uint32_t overflow) { 14302 m_new_inst_cpsr = m_opcode_cpsr; 14303 SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS)); 14304 SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0); 14305 if (carry != ~0u) 14306 SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry); 14307 if (overflow != ~0u) 14308 SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow); 14309 if (m_new_inst_cpsr != m_opcode_cpsr) { 14310 if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, 14311 LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) 14312 return false; 14313 } 14314 return true; 14315} 14316 14317bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { 14318 ARMOpcode *opcode_data = nullptr; 14319 14320 if (m_opcode_mode == eModeThumb) 14321 opcode_data = 14322 GetThumbOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14323 else if (m_opcode_mode == eModeARM) 14324 opcode_data = GetARMOpcodeForInstruction(m_opcode.GetOpcode32(), m_arm_isa); 14325 14326 const bool auto_advance_pc = 14327 evaluate_options & eEmulateInstructionOptionAutoAdvancePC; 14328 m_ignore_conditions = 14329 evaluate_options & eEmulateInstructionOptionIgnoreConditions; 14330 14331 bool success = false; 14332 if (m_opcode_cpsr == 0 || !m_ignore_conditions) { 14333 m_opcode_cpsr = 14334 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); 14335 } 14336 14337 // Only return false if we are unable to read the CPSR if we care about 14338 // conditions 14339 if (!success && !m_ignore_conditions) 14340 return false; 14341 14342 uint32_t orig_pc_value = 0; 14343 if (auto_advance_pc) { 14344 orig_pc_value = 14345 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14346 if (!success) 14347 return false; 14348 } 14349 14350 // Call the Emulate... function if we managed to decode the opcode. 14351 if (opcode_data) { 14352 success = (this->*opcode_data->callback)(m_opcode.GetOpcode32(), 14353 opcode_data->encoding); 14354 if (!success) 14355 return false; 14356 } 14357 14358 // Advance the ITSTATE bits to their values for the next instruction if we 14359 // haven't just executed an IT instruction what initialized it. 14360 if (m_opcode_mode == eModeThumb && m_it_session.InITBlock() && 14361 (opcode_data == nullptr || 14362 opcode_data->callback != &EmulateInstructionARM::EmulateIT)) 14363 m_it_session.ITAdvance(); 14364 14365 if (auto_advance_pc) { 14366 uint32_t after_pc_value = 14367 ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc, 0, &success); 14368 if (!success) 14369 return false; 14370 14371 if (auto_advance_pc && (after_pc_value == orig_pc_value)) { 14372 after_pc_value += m_opcode.GetByteSize(); 14373 14374 EmulateInstruction::Context context; 14375 context.type = eContextAdvancePC; 14376 context.SetNoArgs(); 14377 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc, 14378 after_pc_value)) 14379 return false; 14380 } 14381 } 14382 return true; 14383} 14384 14385EmulateInstruction::InstructionCondition 14386EmulateInstructionARM::GetInstructionCondition() { 14387 const uint32_t cond = CurrentCond(m_opcode.GetOpcode32()); 14388 if (cond == 0xe || cond == 0xf || cond == UINT32_MAX) 14389 return EmulateInstruction::UnconditionalCondition; 14390 return cond; 14391} 14392 14393bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, 14394 OptionValueDictionary *test_data) { 14395 if (!test_data) { 14396 out_stream->Printf("TestEmulation: Missing test data.\n"); 14397 return false; 14398 } 14399 14400 static ConstString opcode_key("opcode"); 14401 static ConstString before_key("before_state"); 14402 static ConstString after_key("after_state"); 14403 14404 OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); 14405 14406 uint32_t test_opcode; 14407 if ((value_sp.get() == nullptr) || 14408 (value_sp->GetType() != OptionValue::eTypeUInt64)) { 14409 out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); 14410 return false; 14411 } 14412 test_opcode = value_sp->GetUInt64Value(); 14413 14414 if (arch.GetTriple().getArch() == llvm::Triple::thumb || 14415 arch.IsAlwaysThumbInstructions()) { 14416 m_opcode_mode = eModeThumb; 14417 if (test_opcode < 0x10000) 14418 m_opcode.SetOpcode16(test_opcode, endian::InlHostByteOrder()); 14419 else 14420 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14421 } else if (arch.GetTriple().getArch() == llvm::Triple::arm) { 14422 m_opcode_mode = eModeARM; 14423 m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); 14424 } else { 14425 out_stream->Printf("TestEmulation: Invalid arch.\n"); 14426 return false; 14427 } 14428 14429 EmulationStateARM before_state; 14430 EmulationStateARM after_state; 14431 14432 value_sp = test_data->GetValueForKey(before_key); 14433 if ((value_sp.get() == nullptr) || 14434 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14435 out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); 14436 return false; 14437 } 14438 14439 OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); 14440 if (!before_state.LoadStateFromDictionary(state_dictionary)) { 14441 out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); 14442 return false; 14443 } 14444 14445 value_sp = test_data->GetValueForKey(after_key); 14446 if ((value_sp.get() == nullptr) || 14447 (value_sp->GetType() != OptionValue::eTypeDictionary)) { 14448 out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); 14449 return false; 14450 } 14451 14452 state_dictionary = value_sp->GetAsDictionary(); 14453 if (!after_state.LoadStateFromDictionary(state_dictionary)) { 14454 out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); 14455 return false; 14456 } 14457 14458 SetBaton((void *)&before_state); 14459 SetCallbacks(&EmulationStateARM::ReadPseudoMemory, 14460 &EmulationStateARM::WritePseudoMemory, 14461 &EmulationStateARM::ReadPseudoRegister, 14462 &EmulationStateARM::WritePseudoRegister); 14463 14464 bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 14465 if (!success) { 14466 out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); 14467 return false; 14468 } 14469 14470 success = before_state.CompareState(after_state); 14471 if (!success) 14472 out_stream->Printf( 14473 "TestEmulation: 'before' and 'after' states do not match.\n"); 14474 14475 return success; 14476} 14477// 14478// 14479// const char * 14480// EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num) 14481//{ 14482// if (reg_kind == eRegisterKindGeneric) 14483// { 14484// switch (reg_num) 14485// { 14486// case LLDB_REGNUM_GENERIC_PC: return "pc"; 14487// case LLDB_REGNUM_GENERIC_SP: return "sp"; 14488// case LLDB_REGNUM_GENERIC_FP: return "fp"; 14489// case LLDB_REGNUM_GENERIC_RA: return "lr"; 14490// case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr"; 14491// default: return NULL; 14492// } 14493// } 14494// else if (reg_kind == eRegisterKindDWARF) 14495// { 14496// return GetARMDWARFRegisterName (reg_num); 14497// } 14498// return NULL; 14499//} 14500// 14501bool EmulateInstructionARM::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) { 14502 unwind_plan.Clear(); 14503 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 14504 14505 UnwindPlan::RowSP row(new UnwindPlan::Row); 14506 14507 // Our previous Call Frame Address is the stack pointer 14508 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp, 0); 14509 14510 unwind_plan.AppendRow(row); 14511 unwind_plan.SetSourceName("EmulateInstructionARM"); 14512 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 14513 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); 14514 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 14515 unwind_plan.SetReturnAddressRegister(dwarf_lr); 14516 return true; 14517} 14518