127 } 128 case 0x3: 129 if (op1 & 0x1) { 130 %(ldrsh)s 131 } else { 132 %(strd)s 133 } 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 ''' 139 140 def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False): 141 post = (p == 0) 142 user = (p == 0 and w == 1) 143 writeback = (p == 0 or w == 1) 144 add = (u == 1) 145 caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0) 146 decode = ''' 147 case %#x: 148 return new '''% caseVal 149 if add: 150 addStr = "true" 151 else: 152 addStr = "false" 153 if d: 154 dests = "RT & ~1, RT | 1" 155 else: 156 dests = "RT" 157 if i: 158 if load: 159 if d: 160 className = loadDoubleImmClassName(post, add, writeback) 161 else: 162 className = loadImmClassName(post, add, writeback, \ 163 size=size, sign=sign, \ 164 user=user) 165 else: 166 if d: 167 className = storeDoubleImmClassName(post, add, writeback) 168 else: 169 className = storeImmClassName(post, add, writeback, \ 170 size=size, sign=sign, \ 171 user=user) 172 decode += ("%s(machInst, %s, RN, %s, imm);\n" % \ 173 (className, dests, addStr)) 174 else: 175 if load: 176 if d: 177 className = loadDoubleRegClassName(post, add, writeback) 178 else: 179 className = loadRegClassName(post, add, writeback, \ 180 size=size, sign=sign, \ 181 user=user) 182 else: 183 if d: 184 className = storeDoubleRegClassName(post, add, writeback) 185 else: 186 className = storeRegClassName(post, add, writeback, \ 187 size=size, sign=sign, \ 188 user=user) 189 decode += ("%s(machInst, %s, RN, %s, 0, LSL, RM);\n" % \ 190 (className, dests, addStr)) 191 return decode 192 193 def decodePuiw(load, d, size=4, sign=False): 194 global decodePuiwCase 195 decode = "switch (puiw) {\n" 196 for p in (0, 1): 197 for u in (0, 1): 198 for i in (0, 1): 199 for w in (0, 1): 200 decode += decodePuiwCase(load, d, p, u, i, w, 201 size, sign) 202 decode += ''' 203 default: 204 return new Unknown(machInst); 205 } 206 ''' 207 return decode 208 209 subs = { 210 "ldrh" : decodePuiw(True, False, size=2), 211 "strh" : decodePuiw(False, False, size=2), 212 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 213 "ldrd" : decodePuiw(True, True), 214 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 215 "strd" : decodePuiw(False, True) 216 } 217 decode_block = decode % subs 218}}; 219 220def format ArmSyncMem() {{ 221 decode_block = ''' 222 { 223 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 224 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 225 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 226 switch (PUBWL) { 227 case 0x10: 228 return new Swp(machInst, rt, rt2, rn); 229 case 0x14: 230 return new Swpb(machInst, rt, rt2, rn); 231 case 0x18: 232 return new %(strex)s(machInst, rt, rt2, rn, true, 0); 233 case 0x19: 234 return new %(ldrex)s(machInst, rt, rn, true, 0); 235 case 0x1a: 236 return new %(strexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); 237 case 0x1b: 238 return new %(ldrexd)s(machInst, rt, rt + 1, rn, true, 0); 239 case 0x1c: 240 return new %(strexb)s(machInst, rt, rt2, rn, true, 0); 241 case 0x1d: 242 return new %(ldrexb)s(machInst, rt, rn, true, 0); 243 case 0x1e: 244 return new %(strexh)s(machInst, rt, rt2, rn, true, 0); 245 case 0x1f: 246 return new %(ldrexh)s(machInst, rt, rn, true, 0); 247 default: 248 return new Unknown(machInst); 249 } 250 } 251 ''' % { 252 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 253 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 254 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 255 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 256 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 257 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 258 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 259 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False) 260 } 261}}; 262 263def format Thumb32SrsRfe() {{ 264 decode_block = ''' 265 { 266 const bool wb = (bits(machInst, 21) == 1); 267 const bool add = (bits(machInst, 24, 23) == 0x3); 268 if (bits(machInst, 20) == 1) { 269 // post == add 270 const IntRegIndex rn = 271 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 272 if (!add && !wb) { 273 return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb); 274 } else if (add && !wb) { 275 return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb); 276 } else if (!add && wb) { 277 return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb); 278 } else { 279 return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb); 280 } 281 } else { 282 const uint32_t mode = bits(machInst, 4, 0); 283 if (!add && !wb) { 284 return new %(srs)s(machInst, mode, 285 SrsOp::DecrementBefore, wb); 286 } else if (add && !wb) { 287 return new %(srs_u)s(machInst, mode, 288 SrsOp::IncrementAfter, wb); 289 } else if (!add && wb) { 290 return new %(srs_w)s(machInst, mode, 291 SrsOp::DecrementBefore, wb); 292 } else { 293 return new %(srs_uw)s(machInst, mode, 294 SrsOp::IncrementAfter, wb); 295 } 296 } 297 } 298 ''' % { 299 "rfe" : "RFE_" + loadImmClassName(False, False, False, 8), 300 "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), 301 "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8), 302 "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8), 303 "srs" : "SRS_" + storeImmClassName(False, False, False, 8), 304 "srs_u" : "SRS_" + storeImmClassName(True, True, False, 8), 305 "srs_w" : "SRS_" + storeImmClassName(False, False, True, 8), 306 "srs_uw" : "SRS_" + storeImmClassName(True, True, True, 8) 307 } 308}}; 309 310def format Thumb32LdrStrDExTbh() {{ 311 decode_block = ''' 312 { 313 const uint32_t op1 = bits(machInst, 24, 23); 314 const uint32_t op2 = bits(machInst, 21, 20); 315 const uint32_t op3 = bits(machInst, 7, 4); 316 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 317 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 318 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 319 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 320 const uint32_t imm8 = bits(machInst, 7, 0); 321 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 322 if (op1 == 0) { 323 const uint32_t imm = bits(machInst, 7, 0) << 2; 324 if (op2 == 0) { 325 return new %(strex)s(machInst, rt2, rt, rn, true, imm); 326 } else { 327 return new %(ldrex)s(machInst, rt, rn, true, imm); 328 } 329 } else { 330 if (op2 == 0) { 331 switch (op3) { 332 case 0x4: 333 return new %(strexb)s(machInst, rd, rt, rn, true, 0); 334 case 0x5: 335 return new %(strexh)s(machInst, rd, rt, rn, true, 0); 336 case 0x7: 337 return new %(strexd)s(machInst, rd, rt, 338 rt2, rn, true, 0); 339 default: 340 return new Unknown(machInst); 341 } 342 } else { 343 switch (op3) { 344 case 0x0: 345 return new Tbb(machInst, rn, rd); 346 case 0x1: 347 return new Tbh(machInst, rn, rd); 348 case 0x4: 349 return new %(ldrexb)s(machInst, rt, rn, true, 0); 350 case 0x5: 351 return new %(ldrexh)s(machInst, rt, rn, true, 0); 352 case 0x7: 353 return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); 354 default: 355 return new Unknown(machInst); 356 } 357 } 358 } 359 } else { 360 const uint32_t puw = (bits(machInst, 24, 23) << 1) | 361 bits(machInst, 21); 362 const uint32_t dimm = imm8 << 2; 363 if (bits(op2, 0) == 0) { 364 switch (puw) { 365 case 0x1: 366 return new %(strd_w)s(machInst, rt, rt2, rn, false, dimm); 367 case 0x3: 368 return new %(strd_uw)s(machInst, rt, rt2, rn, true, dimm); 369 case 0x4: 370 return new %(strd_p)s(machInst, rt, rt2, rn, false, dimm); 371 case 0x5: 372 return new %(strd_pw)s(machInst, rt, rt2, rn, false, dimm); 373 case 0x6: 374 return new %(strd_pu)s(machInst, rt, rt2, rn, true, dimm); 375 case 0x7: 376 return new %(strd_puw)s(machInst, rt, rt2, rn, true, dimm); 377 default: 378 return new Unknown(machInst); 379 } 380 } else { 381 switch (puw) { 382 case 0x1: 383 return new %(ldrd_w)s(machInst, rt, rt2, rn, false, dimm); 384 case 0x3: 385 return new %(ldrd_uw)s(machInst, rt, rt2, rn, true, dimm); 386 case 0x4: 387 return new %(ldrd_p)s(machInst, rt, rt2, rn, false, dimm); 388 case 0x5: 389 return new %(ldrd_pw)s(machInst, rt, rt2, rn, false, dimm); 390 case 0x6: 391 return new %(ldrd_pu)s(machInst, rt, rt2, rn, true, dimm); 392 case 0x7: 393 return new %(ldrd_puw)s(machInst, rt, rt2, rn, true, dimm); 394 default: 395 return new Unknown(machInst); 396 } 397 } 398 } 399 } 400 ''' % { 401 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 402 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 403 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 404 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 405 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 406 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 407 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 408 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False), 409 "ldrd_w" : loadDoubleImmClassName(True, False, True), 410 "ldrd_uw" : loadDoubleImmClassName(True, True, True), 411 "ldrd_p" : loadDoubleImmClassName(False, False, False), 412 "ldrd_pw" : loadDoubleImmClassName(False, False, True), 413 "ldrd_pu" : loadDoubleImmClassName(False, True, False), 414 "ldrd_puw" : loadDoubleImmClassName(False, True, True), 415 "strd_w" : storeDoubleImmClassName(True, False, True), 416 "strd_uw" : storeDoubleImmClassName(True, True, True), 417 "strd_p" : storeDoubleImmClassName(False, False, False), 418 "strd_pw" : storeDoubleImmClassName(False, False, True), 419 "strd_pu" : storeDoubleImmClassName(False, True, False), 420 "strd_puw" : storeDoubleImmClassName(False, True, True) 421 } 422}}; 423 424def format Thumb32LoadWord() {{ 425 decode = ''' 426 { 427 uint32_t op1 = bits(machInst, 24, 23); 428 if (bits(op1, 1) == 0) { 429 uint32_t op2 = bits(machInst, 11, 6); 430 if (HTRN == 0xF) { 431 if (UP) { 432 return new %(literal_u)s(machInst, RT, INTREG_PC, 433 true, IMMED_11_0); 434 } else { 435 return new %(literal)s(machInst, RT, INTREG_PC, 436 false, IMMED_11_0); 437 } 438 } else if (op1 == 0x1) { 439 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 440 } else if (op2 == 0) { 441 return new %(register)s(machInst, RT, RN, UP, 442 bits(machInst, 5, 4), LSL, RM); 443 } else if ((op2 & 0x3c) == 0x38) { 444 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 445 } else if ((op2 & 0x3c) == 0x30 || //P 446 (op2 & 0x24) == 0x24) { //W 447 uint32_t puw = bits(machInst, 10, 8); 448 uint32_t imm = IMMED_7_0; 449 switch (puw) { 450 case 0: 451 case 2: 452 // If we're here, either P or W must have been set. 453 panic("Neither P or W set, but that " 454 "shouldn't be possible.\\n"); 455 case 1: 456 return new %(imm_w)s(machInst, RT, RN, false, imm); 457 case 3: 458 return new %(imm_uw)s(machInst, RT, RN, true, imm); 459 case 4: 460 return new %(imm_p)s(machInst, RT, RN, false, imm); 461 case 5: 462 return new %(imm_pw)s(machInst, RT, RN, false, imm); 463 case 6: 464 return new %(imm_pu)s(machInst, RT, RN, true, imm); 465 case 7: 466 return new %(imm_puw)s(machInst, RT, RN, true, imm); 467 } 468 } 469 } else { 470 return new Unknown(machInst); 471 } 472 } 473 ''' 474 classNames = { 475 "literal_u" : loadImmClassName(False, True, False), 476 "literal" : loadImmClassName(False, False, False), 477 "register" : loadRegClassName(False, True, False), 478 "ldrt" : loadImmClassName(False, True, False, user=True), 479 "imm_w" : loadImmClassName(True, False, True), 480 "imm_uw" : loadImmClassName(True, True, True), 481 "imm_p" : loadImmClassName(False, False, False), 482 "imm_pw" : loadImmClassName(False, False, True), 483 "imm_pu" : loadImmClassName(False, True, False), 484 "imm_puw" : loadImmClassName(False, True, True) 485 } 486 decode_block = decode % classNames 487}}; 488 489def format Thumb32StoreSingle() {{ 490 def buildPuwDecode(size): 491 puwDecode = ''' 492 { 493 uint32_t puw = bits(machInst, 10, 8); 494 uint32_t imm = IMMED_7_0; 495 switch (puw) { 496 case 0: 497 case 2: 498 // If we're here, either P or W must have been set. 499 panic("Neither P or W set, but that " 500 "shouldn't be possible.\\n"); 501 case 1: 502 return new %(imm_w)s(machInst, RT, RN, false, imm); 503 case 3: 504 return new %(imm_uw)s(machInst, RT, RN, true, imm); 505 case 4: 506 return new %(imm_p)s(machInst, RT, RN, false, imm); 507 case 5: 508 return new %(imm_pw)s(machInst, RT, RN, false, imm); 509 case 6: 510 return new %(imm_pu)s(machInst, RT, RN, true, imm); 511 case 7: 512 return new %(imm_puw)s(machInst, RT, RN, true, imm); 513 } 514 } 515 ''' 516 return puwDecode % { 517 "imm_w" : storeImmClassName(True, False, True, size=size), 518 "imm_uw" : storeImmClassName(True, True, True, size=size), 519 "imm_p" : storeImmClassName(False, False, False, size=size), 520 "imm_pw" : storeImmClassName(False, False, True, size=size), 521 "imm_pu" : storeImmClassName(False, True, False, size=size), 522 "imm_puw" : storeImmClassName(False, True, True, size=size) 523 } 524 decode = ''' 525 { 526 uint32_t op1 = bits(machInst, 23, 21); 527 uint32_t op2 = bits(machInst, 11, 6); 528 bool op2Puw = ((op2 & 0x24) == 0x24 || 529 (op2 & 0x3c) == 0x30); 530 if (RN == 0xf) { 531 return new Unknown(machInst); 532 } 533 if (op1 == 4) { 534 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 535 } else if (op1 == 0 && op2Puw) { 536 %(strb_puw)s; 537 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 538 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 539 } else if (op1 == 0 && op2 == 0) { 540 return new %(strb_reg)s(machInst, RT, RN, true, 541 bits(machInst, 5, 4), LSL, RM); 542 } else if (op1 == 5) { 543 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 544 } else if (op1 == 1 && op2Puw) { 545 %(strh_puw)s; 546 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 547 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 548 } else if (op1 == 1 && op2 == 0) { 549 return new %(strh_reg)s(machInst, RT, RN, true, 550 bits(machInst, 5, 4), LSL, RM); 551 } else if (op1 == 6) { 552 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 553 } else if (op1 == 2 && op2Puw) { 554 %(str_puw)s; 555 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 556 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 557 } else if (op1 == 2 && op2 == 0) { 558 return new %(str_reg)s(machInst, RT, RN, true, 559 bits(machInst, 5, 4), LSL, RM); 560 } else { 561 return new Unknown(machInst); 562 } 563 } 564 ''' 565 classNames = { 566 "strb_imm" : storeImmClassName(False, True, False, size=1), 567 "strb_puw" : buildPuwDecode(1), 568 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 569 "strb_reg" : storeRegClassName(False, True, False, size=1), 570 "strh_imm" : storeImmClassName(False, True, False, size=2), 571 "strh_puw" : buildPuwDecode(2), 572 "strht" : storeImmClassName(False, True, False, user=True, size=2), 573 "strh_reg" : storeRegClassName(False, True, False, size=2), 574 "str_imm" : storeImmClassName(False, True, False), 575 "str_puw" : buildPuwDecode(4), 576 "strt" : storeImmClassName(False, True, False, user=True), 577 "str_reg" : storeRegClassName(False, True, False) 578 } 579 decode_block = decode % classNames 580}}; 581 582def format LoadByteMemoryHints() {{ 583 decode = ''' 584 { 585 const uint32_t op1 = bits(machInst, 24, 23); 586 const uint32_t op2 = bits(machInst, 11, 6); 587 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 588 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 589 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 590 const uint32_t imm12 = bits(machInst, 11, 0); 591 const uint32_t imm8 = bits(machInst, 7, 0); 592 bool pldw = bits(machInst, 21); 593 const uint32_t imm2 = bits(machInst, 5, 4); 594 if (rn == 0xf) { 595 if (rt == 0xf) { 596 const bool add = bits(machInst, 23); 597 if (bits(op1, 1) == 1) { 598 if (add) { 599 return new %(pli_iulit)s(machInst, INTREG_ZERO, 600 INTREG_PC, true, imm12); 601 } else { 602 return new %(pli_ilit)s(machInst, INTREG_ZERO, 603 INTREG_PC, false, imm12); 604 } 605 } else { 606 if (add) { 607 return new %(pld_iulit)s(machInst, INTREG_ZERO, 608 INTREG_PC, true, imm12); 609 } else { 610 return new %(pld_ilit)s(machInst, INTREG_ZERO, 611 INTREG_PC, false, imm12); 612 } 613 } 614 } else { 615 if (bits(op1, 1) == 1) { 616 if (bits(machInst, 23)) { 617 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 618 true, imm12); 619 } else { 620 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 621 false, imm12); 622 } 623 } else { 624 if (bits(machInst, 23)) { 625 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 626 true, imm12); 627 } else { 628 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 629 false, imm12); 630 } 631 } 632 } 633 } else if (rt == 0xf) { 634 switch (op1) { 635 case 0x0: 636 if (op2 == 0x0) { 637 if (pldw) { 638 return new %(pldw_radd)s(machInst, INTREG_ZERO, 639 rn, true, imm2, LSL, rm); 640 } else { 641 return new %(pld_radd)s(machInst, INTREG_ZERO, 642 rn, true, imm2, LSL, rm); 643 } 644 } else if (bits(op2, 5, 2) == 0xc) { 645 if (pldw) { 646 return new %(pldw_isub)s(machInst, INTREG_ZERO, 647 rn, false, imm8); 648 } else { 649 return new %(pld_isub)s(machInst, INTREG_ZERO, 650 rn, false, imm8); 651 } 652 } 653 break; 654 case 0x1: 655 if (pldw) { 656 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 657 rn, true, imm12); 658 } else { 659 return new %(pld_iadd)s(machInst, INTREG_ZERO, 660 rn, true, imm12); 661 } 662 case 0x2: 663 if (op2 == 0x0) { 664 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 665 true, imm2, LSL, rm); 666 } else if (bits(op2, 5, 2) == 0xc) { 667 return new %(pli_ilit)s(machInst, INTREG_ZERO, 668 INTREG_PC, false, imm8); 669 } 670 break; 671 case 0x3: 672 return new %(pli_iulit)s(machInst, INTREG_ZERO, 673 INTREG_PC, true, imm12); 674 } 675 return new Unknown(machInst); 676 } else { 677 switch (op1) { 678 case 0x0: 679 if (op2 == 0) { 680 return new %(ldrb_radd)s(machInst, rt, rn, true, 681 imm2, LSL, rm); 682 } else if (bits(op2, 5, 2) == 0xe) { 683 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 684 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 685 const uint32_t puw = bits(machInst, 10, 8); 686 switch (puw) { 687 case 0x1: 688 return new %(ldrb_iw)s(machInst, rt, 689 rn, false, imm8); 690 case 0x3: 691 return new %(ldrb_iuw)s(machInst, rt, 692 rn, true, imm8); 693 case 0x4: 694 return new %(ldrb_ip)s(machInst, rt, 695 rn, false, imm8); 696 case 0x5: 697 return new %(ldrb_ipw)s(machInst, rt, 698 rn, false, imm8); 699 case 0x7: 700 return new %(ldrb_ipuw)s(machInst, rt, 701 rn, true, imm8); 702 } 703 } 704 break; 705 case 0x1: 706 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 707 case 0x2: 708 if (op2 == 0) { 709 return new %(ldrsb_radd)s(machInst, rt, rn, true, 710 imm2, LSL, rm); 711 } else if (bits(op2, 5, 2) == 0xe) { 712 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 713 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 714 const uint32_t puw = bits(machInst, 10, 8); 715 switch (puw) { 716 case 0x1: 717 return new %(ldrsb_iw)s(machInst, rt, 718 rn, false, imm8); 719 case 0x3: 720 return new %(ldrsb_iuw)s(machInst, rt, 721 rn, true, imm8); 722 case 0x4: 723 return new %(ldrsb_ip)s(machInst, rt, 724 rn, false, imm8); 725 case 0x5: 726 return new %(ldrsb_ipw)s(machInst, rt, 727 rn, false, imm8); 728 case 0x7: 729 return new %(ldrsb_ipuw)s(machInst, rt, 730 rn, true, imm8); 731 } 732 } 733 break; 734 case 0x3: 735 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 736 } 737 return new Unknown(machInst); 738 } 739 } 740 ''' 741 substDict = { 742 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 743 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 744 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 745 "ldrb_lit" : loadImmClassName(False, False, False, 1), 746 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 747 "ldrb_radd" : loadRegClassName(False, True, False, 1), 748 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 749 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 750 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 751 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 752 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 753 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 754 "ldrb_iw" : loadImmClassName(True, False, True, 1), 755 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 756 "ldrb_ip" : loadImmClassName(False, False, False, 1), 757 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 758 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 759 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 760 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 761 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 762 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 763 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 764 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 765 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 766 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 767 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 768 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 769 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 770 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 771 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 772 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 773 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 774 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 775 } 776 decode_block = decode % substDict 777}}; 778 779def format LoadHalfwordMemoryHints() {{ 780 decode = ''' 781 { 782 const uint32_t op1 = bits(machInst, 24, 23); 783 const uint32_t op2 = bits(machInst, 11, 6); 784 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 785 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 786 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 787 const uint32_t imm12 = bits(machInst, 11, 0); 788 const uint32_t imm8 = bits(machInst, 7, 0); 789 bool pldw = bits(machInst, 21); 790 const uint32_t imm2 = bits(machInst, 5, 4); 791 if (rn == 0xf) { 792 if (rt == 0xf) { 793 if (bits(op1, 1) == 1) { 794 // Unallocated memory hint 795 return new NopInst(machInst); 796 } else { 797 return new Unknown(machInst); 798 } 799 } else { 800 if (bits(op1, 1) == 1) { 801 if (bits(machInst, 23)) { 802 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 803 true, imm12); 804 } else { 805 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 806 false, imm12); 807 } 808 } else { 809 if (bits(machInst, 23)) { 810 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 811 true, imm12); 812 } else { 813 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 814 false, imm12); 815 } 816 } 817 } 818 } else if (rt == 0xf) { 819 switch (op1) { 820 case 0x0: 821 if (op2 == 0x0) { 822 if (pldw) { 823 return new %(pldw_radd)s(machInst, INTREG_ZERO, 824 rn, true, imm2, LSL, rm); 825 } else { 826 return new %(pld_radd)s(machInst, INTREG_ZERO, 827 rn, true, imm2, LSL, rm); 828 } 829 } else if (bits(op2, 5, 2) == 0xc) { 830 if (pldw) { 831 return new %(pldw_isub)s(machInst, INTREG_ZERO, 832 rn, false, imm8); 833 } else { 834 return new %(pld_isub)s(machInst, INTREG_ZERO, 835 rn, false, imm8); 836 } 837 } 838 break; 839 case 0x1: 840 if (pldw) { 841 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 842 rn, true, imm12); 843 } else { 844 return new %(pld_iadd)s(machInst, INTREG_ZERO, 845 rn, true, imm12); 846 } 847 case 0x2: 848 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 849 // Unallocated memory hint 850 return new NopInst(machInst); 851 } 852 break; 853 case 0x3: 854 return new NopInst(machInst); 855 } 856 return new Unknown(machInst); 857 } else { 858 switch (op1) { 859 case 0x0: 860 if (op2 == 0) { 861 return new %(ldrh_radd)s(machInst, rt, rn, true, 862 imm2, LSL, rm); 863 } else if (bits(op2, 5, 2) == 0xe) { 864 return new %(ldrht)s(machInst, rt, rn, true, imm8); 865 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 866 const uint32_t puw = bits(machInst, 10, 8); 867 switch (puw) { 868 case 0x1: 869 return new %(ldrh_iw)s(machInst, rt, 870 rn, false, imm8); 871 case 0x3: 872 return new %(ldrh_iuw)s(machInst, rt, 873 rn, true, imm8); 874 case 0x4: 875 return new %(ldrh_ip)s(machInst, rt, 876 rn, false, imm8); 877 case 0x5: 878 return new %(ldrh_ipw)s(machInst, rt, 879 rn, false, imm8); 880 case 0x7: 881 return new %(ldrh_ipuw)s(machInst, rt, 882 rn, true, imm8); 883 } 884 } 885 break; 886 case 0x1: 887 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 888 case 0x2: 889 if (op2 == 0) { 890 return new %(ldrsh_radd)s(machInst, rt, rn, true, 891 imm2, LSL, rm); 892 } else if (bits(op2, 5, 2) == 0xe) { 893 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 894 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 895 const uint32_t puw = bits(machInst, 10, 8); 896 switch (puw) { 897 case 0x1: 898 return new %(ldrsh_iw)s(machInst, rt, 899 rn, false, imm8); 900 case 0x3: 901 return new %(ldrsh_iuw)s(machInst, rt, 902 rn, true, imm8); 903 case 0x4: 904 return new %(ldrsh_ip)s(machInst, rt, 905 rn, false, imm8); 906 case 0x5: 907 return new %(ldrsh_ipw)s(machInst, rt, 908 rn, false, imm8); 909 case 0x7: 910 return new %(ldrsh_ipuw)s(machInst, rt, 911 rn, true, imm8); 912 } 913 } 914 break; 915 case 0x3: 916 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 917 } 918 return new Unknown(machInst); 919 } 920 } 921 ''' 922 substDict = { 923 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 924 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 925 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 926 "ldrh_lit" : loadImmClassName(False, False, False, 2), 927 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 928 "ldrh_radd" : loadRegClassName(False, True, False, 2), 929 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 930 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 931 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 932 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 933 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 934 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 935 "ldrh_iw" : loadImmClassName(True, False, True, 2), 936 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 937 "ldrh_ip" : loadImmClassName(False, False, False, 2), 938 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 939 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 940 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 941 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 942 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 943 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 944 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 945 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 946 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 947 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 948 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 949 } 950 decode_block = decode % substDict 951}}; 952 953def format Thumb16MemReg() {{ 954 decode = ''' 955 { 956 const uint32_t opb = bits(machInst, 11, 9); 957 const uint32_t rt = bits(machInst, 2, 0); 958 const uint32_t rn = bits(machInst, 5, 3); 959 const uint32_t rm = bits(machInst, 8, 6); 960 switch (opb) { 961 case 0x0: 962 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 963 case 0x1: 964 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 965 case 0x2: 966 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 967 case 0x3: 968 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 969 case 0x4: 970 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 971 case 0x5: 972 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 973 case 0x6: 974 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 975 case 0x7: 976 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 977 } 978 } 979 ''' 980 classNames = { 981 "str" : storeRegClassName(False, True, False), 982 "strh" : storeRegClassName(False, True, False, size=2), 983 "strb" : storeRegClassName(False, True, False, size=1), 984 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 985 "ldr" : loadRegClassName(False, True, False), 986 "ldrh" : loadRegClassName(False, True, False, size=2), 987 "ldrb" : loadRegClassName(False, True, False, size=1), 988 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 989 } 990 decode_block = decode % classNames 991}}; 992 993def format Thumb16MemImm() {{ 994 decode = ''' 995 { 996 const uint32_t opa = bits(machInst, 15, 12); 997 const uint32_t opb = bits(machInst, 11, 9); 998 const uint32_t lrt = bits(machInst, 2, 0); 999 const uint32_t lrn = bits(machInst, 5, 3); 1000 const uint32_t hrt = bits(machInst, 10, 8); 1001 const uint32_t imm5 = bits(machInst, 10, 6); 1002 const uint32_t imm8 = bits(machInst, 7, 0); 1003 const bool load = bits(opb, 2); 1004 switch (opa) { 1005 case 0x6: 1006 if (load) { 1007 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 1008 } else { 1009 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 1010 } 1011 case 0x7: 1012 if (load) { 1013 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 1014 } else { 1015 return new %(strb)s(machInst, lrt, lrn, true, imm5); 1016 } 1017 case 0x8: 1018 if (load) { 1019 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 1020 } else { 1021 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 1022 } 1023 case 0x9: 1024 if (load) { 1025 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1026 } else { 1027 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1028 } 1029 default: 1030 return new Unknown(machInst); 1031 } 1032 } 1033 ''' 1034 classNames = { 1035 "ldr" : loadImmClassName(False, True, False), 1036 "str" : storeImmClassName(False, True, False), 1037 "ldrh" : loadImmClassName(False, True, False, size=2), 1038 "strh" : storeImmClassName(False, True, False, size=2), 1039 "ldrb" : loadImmClassName(False, True, False, size=1), 1040 "strb" : storeImmClassName(False, True, False, size=1), 1041 } 1042 decode_block = decode % classNames 1043}}; 1044 1045def format Thumb16MemLit() {{ 1046 decode_block = ''' 1047 { 1048 const uint32_t rt = bits(machInst, 10, 8); 1049 const uint32_t imm8 = bits(machInst, 7, 0); 1050 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1051 } 1052 ''' % loadImmClassName(False, True, False) 1053}}; 1054
| 129 } 130 case 0x3: 131 if (op1 & 0x1) { 132 %(ldrsh)s 133 } else { 134 %(strd)s 135 } 136 default: 137 return new Unknown(machInst); 138 } 139 } 140 ''' 141 142 def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False): 143 post = (p == 0) 144 user = (p == 0 and w == 1) 145 writeback = (p == 0 or w == 1) 146 add = (u == 1) 147 caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0) 148 decode = ''' 149 case %#x: 150 return new '''% caseVal 151 if add: 152 addStr = "true" 153 else: 154 addStr = "false" 155 if d: 156 dests = "RT & ~1, RT | 1" 157 else: 158 dests = "RT" 159 if i: 160 if load: 161 if d: 162 className = loadDoubleImmClassName(post, add, writeback) 163 else: 164 className = loadImmClassName(post, add, writeback, \ 165 size=size, sign=sign, \ 166 user=user) 167 else: 168 if d: 169 className = storeDoubleImmClassName(post, add, writeback) 170 else: 171 className = storeImmClassName(post, add, writeback, \ 172 size=size, sign=sign, \ 173 user=user) 174 decode += ("%s(machInst, %s, RN, %s, imm);\n" % \ 175 (className, dests, addStr)) 176 else: 177 if load: 178 if d: 179 className = loadDoubleRegClassName(post, add, writeback) 180 else: 181 className = loadRegClassName(post, add, writeback, \ 182 size=size, sign=sign, \ 183 user=user) 184 else: 185 if d: 186 className = storeDoubleRegClassName(post, add, writeback) 187 else: 188 className = storeRegClassName(post, add, writeback, \ 189 size=size, sign=sign, \ 190 user=user) 191 decode += ("%s(machInst, %s, RN, %s, 0, LSL, RM);\n" % \ 192 (className, dests, addStr)) 193 return decode 194 195 def decodePuiw(load, d, size=4, sign=False): 196 global decodePuiwCase 197 decode = "switch (puiw) {\n" 198 for p in (0, 1): 199 for u in (0, 1): 200 for i in (0, 1): 201 for w in (0, 1): 202 decode += decodePuiwCase(load, d, p, u, i, w, 203 size, sign) 204 decode += ''' 205 default: 206 return new Unknown(machInst); 207 } 208 ''' 209 return decode 210 211 subs = { 212 "ldrh" : decodePuiw(True, False, size=2), 213 "strh" : decodePuiw(False, False, size=2), 214 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 215 "ldrd" : decodePuiw(True, True), 216 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 217 "strd" : decodePuiw(False, True) 218 } 219 decode_block = decode % subs 220}}; 221 222def format ArmSyncMem() {{ 223 decode_block = ''' 224 { 225 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 226 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 227 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 228 switch (PUBWL) { 229 case 0x10: 230 return new Swp(machInst, rt, rt2, rn); 231 case 0x14: 232 return new Swpb(machInst, rt, rt2, rn); 233 case 0x18: 234 return new %(strex)s(machInst, rt, rt2, rn, true, 0); 235 case 0x19: 236 return new %(ldrex)s(machInst, rt, rn, true, 0); 237 case 0x1a: 238 return new %(strexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); 239 case 0x1b: 240 return new %(ldrexd)s(machInst, rt, rt + 1, rn, true, 0); 241 case 0x1c: 242 return new %(strexb)s(machInst, rt, rt2, rn, true, 0); 243 case 0x1d: 244 return new %(ldrexb)s(machInst, rt, rn, true, 0); 245 case 0x1e: 246 return new %(strexh)s(machInst, rt, rt2, rn, true, 0); 247 case 0x1f: 248 return new %(ldrexh)s(machInst, rt, rn, true, 0); 249 default: 250 return new Unknown(machInst); 251 } 252 } 253 ''' % { 254 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 255 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 256 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 257 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 258 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 259 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 260 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 261 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False) 262 } 263}}; 264 265def format Thumb32SrsRfe() {{ 266 decode_block = ''' 267 { 268 const bool wb = (bits(machInst, 21) == 1); 269 const bool add = (bits(machInst, 24, 23) == 0x3); 270 if (bits(machInst, 20) == 1) { 271 // post == add 272 const IntRegIndex rn = 273 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 274 if (!add && !wb) { 275 return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb); 276 } else if (add && !wb) { 277 return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb); 278 } else if (!add && wb) { 279 return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb); 280 } else { 281 return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb); 282 } 283 } else { 284 const uint32_t mode = bits(machInst, 4, 0); 285 if (!add && !wb) { 286 return new %(srs)s(machInst, mode, 287 SrsOp::DecrementBefore, wb); 288 } else if (add && !wb) { 289 return new %(srs_u)s(machInst, mode, 290 SrsOp::IncrementAfter, wb); 291 } else if (!add && wb) { 292 return new %(srs_w)s(machInst, mode, 293 SrsOp::DecrementBefore, wb); 294 } else { 295 return new %(srs_uw)s(machInst, mode, 296 SrsOp::IncrementAfter, wb); 297 } 298 } 299 } 300 ''' % { 301 "rfe" : "RFE_" + loadImmClassName(False, False, False, 8), 302 "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), 303 "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8), 304 "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8), 305 "srs" : "SRS_" + storeImmClassName(False, False, False, 8), 306 "srs_u" : "SRS_" + storeImmClassName(True, True, False, 8), 307 "srs_w" : "SRS_" + storeImmClassName(False, False, True, 8), 308 "srs_uw" : "SRS_" + storeImmClassName(True, True, True, 8) 309 } 310}}; 311 312def format Thumb32LdrStrDExTbh() {{ 313 decode_block = ''' 314 { 315 const uint32_t op1 = bits(machInst, 24, 23); 316 const uint32_t op2 = bits(machInst, 21, 20); 317 const uint32_t op3 = bits(machInst, 7, 4); 318 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 319 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 320 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 321 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 322 const uint32_t imm8 = bits(machInst, 7, 0); 323 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 324 if (op1 == 0) { 325 const uint32_t imm = bits(machInst, 7, 0) << 2; 326 if (op2 == 0) { 327 return new %(strex)s(machInst, rt2, rt, rn, true, imm); 328 } else { 329 return new %(ldrex)s(machInst, rt, rn, true, imm); 330 } 331 } else { 332 if (op2 == 0) { 333 switch (op3) { 334 case 0x4: 335 return new %(strexb)s(machInst, rd, rt, rn, true, 0); 336 case 0x5: 337 return new %(strexh)s(machInst, rd, rt, rn, true, 0); 338 case 0x7: 339 return new %(strexd)s(machInst, rd, rt, 340 rt2, rn, true, 0); 341 default: 342 return new Unknown(machInst); 343 } 344 } else { 345 switch (op3) { 346 case 0x0: 347 return new Tbb(machInst, rn, rd); 348 case 0x1: 349 return new Tbh(machInst, rn, rd); 350 case 0x4: 351 return new %(ldrexb)s(machInst, rt, rn, true, 0); 352 case 0x5: 353 return new %(ldrexh)s(machInst, rt, rn, true, 0); 354 case 0x7: 355 return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); 356 default: 357 return new Unknown(machInst); 358 } 359 } 360 } 361 } else { 362 const uint32_t puw = (bits(machInst, 24, 23) << 1) | 363 bits(machInst, 21); 364 const uint32_t dimm = imm8 << 2; 365 if (bits(op2, 0) == 0) { 366 switch (puw) { 367 case 0x1: 368 return new %(strd_w)s(machInst, rt, rt2, rn, false, dimm); 369 case 0x3: 370 return new %(strd_uw)s(machInst, rt, rt2, rn, true, dimm); 371 case 0x4: 372 return new %(strd_p)s(machInst, rt, rt2, rn, false, dimm); 373 case 0x5: 374 return new %(strd_pw)s(machInst, rt, rt2, rn, false, dimm); 375 case 0x6: 376 return new %(strd_pu)s(machInst, rt, rt2, rn, true, dimm); 377 case 0x7: 378 return new %(strd_puw)s(machInst, rt, rt2, rn, true, dimm); 379 default: 380 return new Unknown(machInst); 381 } 382 } else { 383 switch (puw) { 384 case 0x1: 385 return new %(ldrd_w)s(machInst, rt, rt2, rn, false, dimm); 386 case 0x3: 387 return new %(ldrd_uw)s(machInst, rt, rt2, rn, true, dimm); 388 case 0x4: 389 return new %(ldrd_p)s(machInst, rt, rt2, rn, false, dimm); 390 case 0x5: 391 return new %(ldrd_pw)s(machInst, rt, rt2, rn, false, dimm); 392 case 0x6: 393 return new %(ldrd_pu)s(machInst, rt, rt2, rn, true, dimm); 394 case 0x7: 395 return new %(ldrd_puw)s(machInst, rt, rt2, rn, true, dimm); 396 default: 397 return new Unknown(machInst); 398 } 399 } 400 } 401 } 402 ''' % { 403 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 404 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 405 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 406 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 407 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 408 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 409 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 410 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False), 411 "ldrd_w" : loadDoubleImmClassName(True, False, True), 412 "ldrd_uw" : loadDoubleImmClassName(True, True, True), 413 "ldrd_p" : loadDoubleImmClassName(False, False, False), 414 "ldrd_pw" : loadDoubleImmClassName(False, False, True), 415 "ldrd_pu" : loadDoubleImmClassName(False, True, False), 416 "ldrd_puw" : loadDoubleImmClassName(False, True, True), 417 "strd_w" : storeDoubleImmClassName(True, False, True), 418 "strd_uw" : storeDoubleImmClassName(True, True, True), 419 "strd_p" : storeDoubleImmClassName(False, False, False), 420 "strd_pw" : storeDoubleImmClassName(False, False, True), 421 "strd_pu" : storeDoubleImmClassName(False, True, False), 422 "strd_puw" : storeDoubleImmClassName(False, True, True) 423 } 424}}; 425 426def format Thumb32LoadWord() {{ 427 decode = ''' 428 { 429 uint32_t op1 = bits(machInst, 24, 23); 430 if (bits(op1, 1) == 0) { 431 uint32_t op2 = bits(machInst, 11, 6); 432 if (HTRN == 0xF) { 433 if (UP) { 434 return new %(literal_u)s(machInst, RT, INTREG_PC, 435 true, IMMED_11_0); 436 } else { 437 return new %(literal)s(machInst, RT, INTREG_PC, 438 false, IMMED_11_0); 439 } 440 } else if (op1 == 0x1) { 441 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 442 } else if (op2 == 0) { 443 return new %(register)s(machInst, RT, RN, UP, 444 bits(machInst, 5, 4), LSL, RM); 445 } else if ((op2 & 0x3c) == 0x38) { 446 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 447 } else if ((op2 & 0x3c) == 0x30 || //P 448 (op2 & 0x24) == 0x24) { //W 449 uint32_t puw = bits(machInst, 10, 8); 450 uint32_t imm = IMMED_7_0; 451 switch (puw) { 452 case 0: 453 case 2: 454 // If we're here, either P or W must have been set. 455 panic("Neither P or W set, but that " 456 "shouldn't be possible.\\n"); 457 case 1: 458 return new %(imm_w)s(machInst, RT, RN, false, imm); 459 case 3: 460 return new %(imm_uw)s(machInst, RT, RN, true, imm); 461 case 4: 462 return new %(imm_p)s(machInst, RT, RN, false, imm); 463 case 5: 464 return new %(imm_pw)s(machInst, RT, RN, false, imm); 465 case 6: 466 return new %(imm_pu)s(machInst, RT, RN, true, imm); 467 case 7: 468 return new %(imm_puw)s(machInst, RT, RN, true, imm); 469 } 470 } 471 } else { 472 return new Unknown(machInst); 473 } 474 } 475 ''' 476 classNames = { 477 "literal_u" : loadImmClassName(False, True, False), 478 "literal" : loadImmClassName(False, False, False), 479 "register" : loadRegClassName(False, True, False), 480 "ldrt" : loadImmClassName(False, True, False, user=True), 481 "imm_w" : loadImmClassName(True, False, True), 482 "imm_uw" : loadImmClassName(True, True, True), 483 "imm_p" : loadImmClassName(False, False, False), 484 "imm_pw" : loadImmClassName(False, False, True), 485 "imm_pu" : loadImmClassName(False, True, False), 486 "imm_puw" : loadImmClassName(False, True, True) 487 } 488 decode_block = decode % classNames 489}}; 490 491def format Thumb32StoreSingle() {{ 492 def buildPuwDecode(size): 493 puwDecode = ''' 494 { 495 uint32_t puw = bits(machInst, 10, 8); 496 uint32_t imm = IMMED_7_0; 497 switch (puw) { 498 case 0: 499 case 2: 500 // If we're here, either P or W must have been set. 501 panic("Neither P or W set, but that " 502 "shouldn't be possible.\\n"); 503 case 1: 504 return new %(imm_w)s(machInst, RT, RN, false, imm); 505 case 3: 506 return new %(imm_uw)s(machInst, RT, RN, true, imm); 507 case 4: 508 return new %(imm_p)s(machInst, RT, RN, false, imm); 509 case 5: 510 return new %(imm_pw)s(machInst, RT, RN, false, imm); 511 case 6: 512 return new %(imm_pu)s(machInst, RT, RN, true, imm); 513 case 7: 514 return new %(imm_puw)s(machInst, RT, RN, true, imm); 515 } 516 } 517 ''' 518 return puwDecode % { 519 "imm_w" : storeImmClassName(True, False, True, size=size), 520 "imm_uw" : storeImmClassName(True, True, True, size=size), 521 "imm_p" : storeImmClassName(False, False, False, size=size), 522 "imm_pw" : storeImmClassName(False, False, True, size=size), 523 "imm_pu" : storeImmClassName(False, True, False, size=size), 524 "imm_puw" : storeImmClassName(False, True, True, size=size) 525 } 526 decode = ''' 527 { 528 uint32_t op1 = bits(machInst, 23, 21); 529 uint32_t op2 = bits(machInst, 11, 6); 530 bool op2Puw = ((op2 & 0x24) == 0x24 || 531 (op2 & 0x3c) == 0x30); 532 if (RN == 0xf) { 533 return new Unknown(machInst); 534 } 535 if (op1 == 4) { 536 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 537 } else if (op1 == 0 && op2Puw) { 538 %(strb_puw)s; 539 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 540 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 541 } else if (op1 == 0 && op2 == 0) { 542 return new %(strb_reg)s(machInst, RT, RN, true, 543 bits(machInst, 5, 4), LSL, RM); 544 } else if (op1 == 5) { 545 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 546 } else if (op1 == 1 && op2Puw) { 547 %(strh_puw)s; 548 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 549 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 550 } else if (op1 == 1 && op2 == 0) { 551 return new %(strh_reg)s(machInst, RT, RN, true, 552 bits(machInst, 5, 4), LSL, RM); 553 } else if (op1 == 6) { 554 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 555 } else if (op1 == 2 && op2Puw) { 556 %(str_puw)s; 557 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 558 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 559 } else if (op1 == 2 && op2 == 0) { 560 return new %(str_reg)s(machInst, RT, RN, true, 561 bits(machInst, 5, 4), LSL, RM); 562 } else { 563 return new Unknown(machInst); 564 } 565 } 566 ''' 567 classNames = { 568 "strb_imm" : storeImmClassName(False, True, False, size=1), 569 "strb_puw" : buildPuwDecode(1), 570 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 571 "strb_reg" : storeRegClassName(False, True, False, size=1), 572 "strh_imm" : storeImmClassName(False, True, False, size=2), 573 "strh_puw" : buildPuwDecode(2), 574 "strht" : storeImmClassName(False, True, False, user=True, size=2), 575 "strh_reg" : storeRegClassName(False, True, False, size=2), 576 "str_imm" : storeImmClassName(False, True, False), 577 "str_puw" : buildPuwDecode(4), 578 "strt" : storeImmClassName(False, True, False, user=True), 579 "str_reg" : storeRegClassName(False, True, False) 580 } 581 decode_block = decode % classNames 582}}; 583 584def format LoadByteMemoryHints() {{ 585 decode = ''' 586 { 587 const uint32_t op1 = bits(machInst, 24, 23); 588 const uint32_t op2 = bits(machInst, 11, 6); 589 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 590 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 591 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 592 const uint32_t imm12 = bits(machInst, 11, 0); 593 const uint32_t imm8 = bits(machInst, 7, 0); 594 bool pldw = bits(machInst, 21); 595 const uint32_t imm2 = bits(machInst, 5, 4); 596 if (rn == 0xf) { 597 if (rt == 0xf) { 598 const bool add = bits(machInst, 23); 599 if (bits(op1, 1) == 1) { 600 if (add) { 601 return new %(pli_iulit)s(machInst, INTREG_ZERO, 602 INTREG_PC, true, imm12); 603 } else { 604 return new %(pli_ilit)s(machInst, INTREG_ZERO, 605 INTREG_PC, false, imm12); 606 } 607 } else { 608 if (add) { 609 return new %(pld_iulit)s(machInst, INTREG_ZERO, 610 INTREG_PC, true, imm12); 611 } else { 612 return new %(pld_ilit)s(machInst, INTREG_ZERO, 613 INTREG_PC, false, imm12); 614 } 615 } 616 } else { 617 if (bits(op1, 1) == 1) { 618 if (bits(machInst, 23)) { 619 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 620 true, imm12); 621 } else { 622 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 623 false, imm12); 624 } 625 } else { 626 if (bits(machInst, 23)) { 627 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 628 true, imm12); 629 } else { 630 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 631 false, imm12); 632 } 633 } 634 } 635 } else if (rt == 0xf) { 636 switch (op1) { 637 case 0x0: 638 if (op2 == 0x0) { 639 if (pldw) { 640 return new %(pldw_radd)s(machInst, INTREG_ZERO, 641 rn, true, imm2, LSL, rm); 642 } else { 643 return new %(pld_radd)s(machInst, INTREG_ZERO, 644 rn, true, imm2, LSL, rm); 645 } 646 } else if (bits(op2, 5, 2) == 0xc) { 647 if (pldw) { 648 return new %(pldw_isub)s(machInst, INTREG_ZERO, 649 rn, false, imm8); 650 } else { 651 return new %(pld_isub)s(machInst, INTREG_ZERO, 652 rn, false, imm8); 653 } 654 } 655 break; 656 case 0x1: 657 if (pldw) { 658 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 659 rn, true, imm12); 660 } else { 661 return new %(pld_iadd)s(machInst, INTREG_ZERO, 662 rn, true, imm12); 663 } 664 case 0x2: 665 if (op2 == 0x0) { 666 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 667 true, imm2, LSL, rm); 668 } else if (bits(op2, 5, 2) == 0xc) { 669 return new %(pli_ilit)s(machInst, INTREG_ZERO, 670 INTREG_PC, false, imm8); 671 } 672 break; 673 case 0x3: 674 return new %(pli_iulit)s(machInst, INTREG_ZERO, 675 INTREG_PC, true, imm12); 676 } 677 return new Unknown(machInst); 678 } else { 679 switch (op1) { 680 case 0x0: 681 if (op2 == 0) { 682 return new %(ldrb_radd)s(machInst, rt, rn, true, 683 imm2, LSL, rm); 684 } else if (bits(op2, 5, 2) == 0xe) { 685 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 686 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 687 const uint32_t puw = bits(machInst, 10, 8); 688 switch (puw) { 689 case 0x1: 690 return new %(ldrb_iw)s(machInst, rt, 691 rn, false, imm8); 692 case 0x3: 693 return new %(ldrb_iuw)s(machInst, rt, 694 rn, true, imm8); 695 case 0x4: 696 return new %(ldrb_ip)s(machInst, rt, 697 rn, false, imm8); 698 case 0x5: 699 return new %(ldrb_ipw)s(machInst, rt, 700 rn, false, imm8); 701 case 0x7: 702 return new %(ldrb_ipuw)s(machInst, rt, 703 rn, true, imm8); 704 } 705 } 706 break; 707 case 0x1: 708 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 709 case 0x2: 710 if (op2 == 0) { 711 return new %(ldrsb_radd)s(machInst, rt, rn, true, 712 imm2, LSL, rm); 713 } else if (bits(op2, 5, 2) == 0xe) { 714 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 715 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 716 const uint32_t puw = bits(machInst, 10, 8); 717 switch (puw) { 718 case 0x1: 719 return new %(ldrsb_iw)s(machInst, rt, 720 rn, false, imm8); 721 case 0x3: 722 return new %(ldrsb_iuw)s(machInst, rt, 723 rn, true, imm8); 724 case 0x4: 725 return new %(ldrsb_ip)s(machInst, rt, 726 rn, false, imm8); 727 case 0x5: 728 return new %(ldrsb_ipw)s(machInst, rt, 729 rn, false, imm8); 730 case 0x7: 731 return new %(ldrsb_ipuw)s(machInst, rt, 732 rn, true, imm8); 733 } 734 } 735 break; 736 case 0x3: 737 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 738 } 739 return new Unknown(machInst); 740 } 741 } 742 ''' 743 substDict = { 744 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 745 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 746 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 747 "ldrb_lit" : loadImmClassName(False, False, False, 1), 748 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 749 "ldrb_radd" : loadRegClassName(False, True, False, 1), 750 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 751 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 752 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 753 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 754 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 755 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 756 "ldrb_iw" : loadImmClassName(True, False, True, 1), 757 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 758 "ldrb_ip" : loadImmClassName(False, False, False, 1), 759 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 760 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 761 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 762 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 763 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 764 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 765 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 766 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 767 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 768 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 769 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 770 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 771 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 772 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 773 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 774 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 775 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 776 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 777 } 778 decode_block = decode % substDict 779}}; 780 781def format LoadHalfwordMemoryHints() {{ 782 decode = ''' 783 { 784 const uint32_t op1 = bits(machInst, 24, 23); 785 const uint32_t op2 = bits(machInst, 11, 6); 786 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 787 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 788 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 789 const uint32_t imm12 = bits(machInst, 11, 0); 790 const uint32_t imm8 = bits(machInst, 7, 0); 791 bool pldw = bits(machInst, 21); 792 const uint32_t imm2 = bits(machInst, 5, 4); 793 if (rn == 0xf) { 794 if (rt == 0xf) { 795 if (bits(op1, 1) == 1) { 796 // Unallocated memory hint 797 return new NopInst(machInst); 798 } else { 799 return new Unknown(machInst); 800 } 801 } else { 802 if (bits(op1, 1) == 1) { 803 if (bits(machInst, 23)) { 804 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 805 true, imm12); 806 } else { 807 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 808 false, imm12); 809 } 810 } else { 811 if (bits(machInst, 23)) { 812 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 813 true, imm12); 814 } else { 815 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 816 false, imm12); 817 } 818 } 819 } 820 } else if (rt == 0xf) { 821 switch (op1) { 822 case 0x0: 823 if (op2 == 0x0) { 824 if (pldw) { 825 return new %(pldw_radd)s(machInst, INTREG_ZERO, 826 rn, true, imm2, LSL, rm); 827 } else { 828 return new %(pld_radd)s(machInst, INTREG_ZERO, 829 rn, true, imm2, LSL, rm); 830 } 831 } else if (bits(op2, 5, 2) == 0xc) { 832 if (pldw) { 833 return new %(pldw_isub)s(machInst, INTREG_ZERO, 834 rn, false, imm8); 835 } else { 836 return new %(pld_isub)s(machInst, INTREG_ZERO, 837 rn, false, imm8); 838 } 839 } 840 break; 841 case 0x1: 842 if (pldw) { 843 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 844 rn, true, imm12); 845 } else { 846 return new %(pld_iadd)s(machInst, INTREG_ZERO, 847 rn, true, imm12); 848 } 849 case 0x2: 850 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 851 // Unallocated memory hint 852 return new NopInst(machInst); 853 } 854 break; 855 case 0x3: 856 return new NopInst(machInst); 857 } 858 return new Unknown(machInst); 859 } else { 860 switch (op1) { 861 case 0x0: 862 if (op2 == 0) { 863 return new %(ldrh_radd)s(machInst, rt, rn, true, 864 imm2, LSL, rm); 865 } else if (bits(op2, 5, 2) == 0xe) { 866 return new %(ldrht)s(machInst, rt, rn, true, imm8); 867 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 868 const uint32_t puw = bits(machInst, 10, 8); 869 switch (puw) { 870 case 0x1: 871 return new %(ldrh_iw)s(machInst, rt, 872 rn, false, imm8); 873 case 0x3: 874 return new %(ldrh_iuw)s(machInst, rt, 875 rn, true, imm8); 876 case 0x4: 877 return new %(ldrh_ip)s(machInst, rt, 878 rn, false, imm8); 879 case 0x5: 880 return new %(ldrh_ipw)s(machInst, rt, 881 rn, false, imm8); 882 case 0x7: 883 return new %(ldrh_ipuw)s(machInst, rt, 884 rn, true, imm8); 885 } 886 } 887 break; 888 case 0x1: 889 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 890 case 0x2: 891 if (op2 == 0) { 892 return new %(ldrsh_radd)s(machInst, rt, rn, true, 893 imm2, LSL, rm); 894 } else if (bits(op2, 5, 2) == 0xe) { 895 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 896 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 897 const uint32_t puw = bits(machInst, 10, 8); 898 switch (puw) { 899 case 0x1: 900 return new %(ldrsh_iw)s(machInst, rt, 901 rn, false, imm8); 902 case 0x3: 903 return new %(ldrsh_iuw)s(machInst, rt, 904 rn, true, imm8); 905 case 0x4: 906 return new %(ldrsh_ip)s(machInst, rt, 907 rn, false, imm8); 908 case 0x5: 909 return new %(ldrsh_ipw)s(machInst, rt, 910 rn, false, imm8); 911 case 0x7: 912 return new %(ldrsh_ipuw)s(machInst, rt, 913 rn, true, imm8); 914 } 915 } 916 break; 917 case 0x3: 918 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 919 } 920 return new Unknown(machInst); 921 } 922 } 923 ''' 924 substDict = { 925 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 926 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 927 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 928 "ldrh_lit" : loadImmClassName(False, False, False, 2), 929 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 930 "ldrh_radd" : loadRegClassName(False, True, False, 2), 931 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 932 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 933 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 934 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 935 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 936 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 937 "ldrh_iw" : loadImmClassName(True, False, True, 2), 938 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 939 "ldrh_ip" : loadImmClassName(False, False, False, 2), 940 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 941 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 942 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 943 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 944 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 945 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 946 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 947 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 948 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 949 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 950 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 951 } 952 decode_block = decode % substDict 953}}; 954 955def format Thumb16MemReg() {{ 956 decode = ''' 957 { 958 const uint32_t opb = bits(machInst, 11, 9); 959 const uint32_t rt = bits(machInst, 2, 0); 960 const uint32_t rn = bits(machInst, 5, 3); 961 const uint32_t rm = bits(machInst, 8, 6); 962 switch (opb) { 963 case 0x0: 964 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 965 case 0x1: 966 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 967 case 0x2: 968 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 969 case 0x3: 970 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 971 case 0x4: 972 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 973 case 0x5: 974 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 975 case 0x6: 976 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 977 case 0x7: 978 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 979 } 980 } 981 ''' 982 classNames = { 983 "str" : storeRegClassName(False, True, False), 984 "strh" : storeRegClassName(False, True, False, size=2), 985 "strb" : storeRegClassName(False, True, False, size=1), 986 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 987 "ldr" : loadRegClassName(False, True, False), 988 "ldrh" : loadRegClassName(False, True, False, size=2), 989 "ldrb" : loadRegClassName(False, True, False, size=1), 990 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 991 } 992 decode_block = decode % classNames 993}}; 994 995def format Thumb16MemImm() {{ 996 decode = ''' 997 { 998 const uint32_t opa = bits(machInst, 15, 12); 999 const uint32_t opb = bits(machInst, 11, 9); 1000 const uint32_t lrt = bits(machInst, 2, 0); 1001 const uint32_t lrn = bits(machInst, 5, 3); 1002 const uint32_t hrt = bits(machInst, 10, 8); 1003 const uint32_t imm5 = bits(machInst, 10, 6); 1004 const uint32_t imm8 = bits(machInst, 7, 0); 1005 const bool load = bits(opb, 2); 1006 switch (opa) { 1007 case 0x6: 1008 if (load) { 1009 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 1010 } else { 1011 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 1012 } 1013 case 0x7: 1014 if (load) { 1015 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 1016 } else { 1017 return new %(strb)s(machInst, lrt, lrn, true, imm5); 1018 } 1019 case 0x8: 1020 if (load) { 1021 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 1022 } else { 1023 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 1024 } 1025 case 0x9: 1026 if (load) { 1027 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1028 } else { 1029 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1030 } 1031 default: 1032 return new Unknown(machInst); 1033 } 1034 } 1035 ''' 1036 classNames = { 1037 "ldr" : loadImmClassName(False, True, False), 1038 "str" : storeImmClassName(False, True, False), 1039 "ldrh" : loadImmClassName(False, True, False, size=2), 1040 "strh" : storeImmClassName(False, True, False, size=2), 1041 "ldrb" : loadImmClassName(False, True, False, size=1), 1042 "strb" : storeImmClassName(False, True, False, size=1), 1043 } 1044 decode_block = decode % classNames 1045}}; 1046 1047def format Thumb16MemLit() {{ 1048 decode_block = ''' 1049 { 1050 const uint32_t rt = bits(machInst, 10, 8); 1051 const uint32_t imm8 = bits(machInst, 7, 0); 1052 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1053 } 1054 ''' % loadImmClassName(False, True, False) 1055}}; 1056
|