mem.isa revision 7277:85e4f11ad2c3
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Gabe Black 42 43def format AddrMode2(imm) {{ 44 if eval(imm): 45 imm = True 46 else: 47 imm = False 48 49 def buildPUBWLCase(p, u, b, w, l): 50 return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 51 52 header_output = decoder_output = exec_output = "" 53 decode_block = "switch(PUBWL) {\n" 54 55 # Loop over all the values of p, u, b, w and l and build instructions and 56 # a decode block for them. 57 for p in (0, 1): 58 for u in (0, 1): 59 for b in (0, 1): 60 for w in (0, 1): 61 post = (p == 0) 62 user = (p == 0 and w == 1) 63 writeback = (p == 0 or w == 1) 64 add = (u == 1) 65 if b == 0: 66 size = 4 67 else: 68 size = 1 69 if add: 70 addStr = "true" 71 else: 72 addStr = "false" 73 if imm: 74 newDecode = "return new %s(machInst, RD, RN," + \ 75 "%s, machInst.immed11_0);" 76 loadClass = loadImmClassName(post, add, writeback, 77 size, False, user) 78 storeClass = storeImmClassName(post, add, writeback, 79 size, False, user) 80 loadDecode = newDecode % (loadClass, addStr) 81 storeDecode = newDecode % (storeClass, addStr) 82 else: 83 newDecode = "return new %s(machInst, RD, RN, %s," + \ 84 "machInst.shiftSize," + \ 85 "machInst.shift, RM);" 86 loadClass = loadRegClassName(post, add, writeback, 87 size, False, user) 88 storeClass = storeRegClassName(post, add, writeback, 89 size, False, user) 90 loadDecode = newDecode % (loadClass, addStr) 91 storeDecode = newDecode % (storeClass, addStr) 92 decode = ''' 93 case %#x: 94 {%s} 95 break; 96 ''' 97 decode_block += decode % \ 98 (buildPUBWLCase(p,u,b,w,1), loadDecode) 99 decode_block += decode % \ 100 (buildPUBWLCase(p,u,b,w,0), storeDecode) 101 decode_block += ''' 102 default: 103 return new Unknown(machInst); 104 break; 105 }''' 106}}; 107 108def format AddrMode3() {{ 109 decode = ''' 110 { 111 const uint32_t op1 = bits(machInst, 24, 20); 112 const uint32_t op2 = bits(machInst, 6, 5); 113 const uint32_t puiw = bits(machInst, 24, 21); 114 const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0; 115 switch (op2) { 116 case 0x1: 117 if (op1 & 0x1) { 118 %(ldrh)s 119 } else { 120 %(strh)s 121 } 122 case 0x2: 123 if (op1 & 0x1) { 124 %(ldrsb)s 125 } else { 126 %(ldrd)s 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 i: 154 if load: 155 if d: 156 className = loadDoubleImmClassName(post, add, writeback) 157 else: 158 className = loadImmClassName(post, add, writeback, \ 159 size=size, sign=sign, \ 160 user=user) 161 else: 162 if d: 163 className = storeDoubleImmClassName(post, add, writeback) 164 else: 165 className = storeImmClassName(post, add, writeback, \ 166 size=size, sign=sign, \ 167 user=user) 168 decode += ("%s(machInst, RT, RN, %s, imm);\n" % \ 169 (className, addStr)) 170 else: 171 if load: 172 if d: 173 className = loadDoubleRegClassName(post, add, writeback) 174 else: 175 className = loadRegClassName(post, add, writeback, \ 176 size=size, sign=sign, \ 177 user=user) 178 else: 179 if d: 180 className = storeDoubleRegClassName(post, add, writeback) 181 else: 182 className = storeRegClassName(post, add, writeback, \ 183 size=size, sign=sign, \ 184 user=user) 185 decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \ 186 (className, addStr)) 187 return decode 188 189 def decodePuiw(load, d, size=4, sign=False): 190 global decodePuiwCase 191 decode = "switch (puiw) {\n" 192 for p in (0, 1): 193 for u in (0, 1): 194 for i in (0, 1): 195 for w in (0, 1): 196 decode += decodePuiwCase(load, d, p, u, i, w, 197 size, sign) 198 decode += ''' 199 default: 200 return new Unknown(machInst); 201 } 202 ''' 203 return decode 204 205 subs = { 206 "ldrh" : decodePuiw(True, False, size=2), 207 "strh" : decodePuiw(False, False, size=2), 208 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 209 "ldrd" : decodePuiw(True, True), 210 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 211 "strd" : decodePuiw(False, True) 212 } 213 decode_block = decode % subs 214}}; 215 216def format ArmSyncMem() {{ 217 decode_block = ''' 218 { 219 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 220 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 221 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 222 switch (PUBWL) { 223 case 0x10: 224 return new Swp(machInst, rt, rt2, rn); 225 case 0x14: 226 return new Swpb(machInst, rt, rt2, rn); 227 case 0x18: 228 return new WarnUnimplemented("strex", machInst); 229 case 0x19: 230 return new %(ldrex)s(machInst, rt, rn, true, 0); 231 case 0x1a: 232 return new WarnUnimplemented("strexd", machInst); 233 case 0x1b: 234 return new WarnUnimplemented("ldrexd", machInst); 235 case 0x1c: 236 return new WarnUnimplemented("strexb", machInst); 237 case 0x1d: 238 return new %(ldrexb)s(machInst, rt, rn, true, 0); 239 case 0x1e: 240 return new WarnUnimplemented("strexh", machInst); 241 case 0x1f: 242 return new %(ldrexh)s(machInst, rt, rn, true, 0); 243 default: 244 return new Unknown(machInst); 245 } 246 } 247 ''' % { 248 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 249 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 250 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 251 } 252}}; 253 254def format Thumb32LdrStrDExTbh() {{ 255 decode_block = ''' 256 { 257 const uint32_t op1 = bits(machInst, 24, 23); 258 const uint32_t op2 = bits(machInst, 21, 20); 259 const uint32_t op3 = bits(machInst, 7, 4); 260 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 261 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 262 /* This isn't used yet, and that makes gcc upset. */ 263 //const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 264 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 265 if (op1 == 0) { 266 const uint32_t imm = bits(machInst, 7, 0) << 2; 267 if (op2 == 0) { 268 return new WarnUnimplemented("strex", machInst); 269 } else { 270 return new %(ldrex)s(machInst, rt, rn, true, imm); 271 } 272 } else { 273 if (op2 == 0) { 274 switch (op3) { 275 case 0x4: 276 return new WarnUnimplemented("strexb", machInst); 277 case 0x5: 278 return new WarnUnimplemented("strexh", machInst); 279 case 0x7: 280 return new WarnUnimplemented("strexd", machInst); 281 default: 282 return new Unknown(machInst); 283 } 284 } else { 285 switch (op3) { 286 case 0x0: 287 return new WarnUnimplemented("tbb", machInst); 288 case 0x1: 289 return new WarnUnimplemented("tbh", machInst); 290 case 0x4: 291 return new %(ldrexb)s(machInst, rt, rn, true, 0); 292 case 0x5: 293 return new %(ldrexh)s(machInst, rt, rn, true, 0); 294 case 0x7: 295 return new WarnUnimplemented("ldrexd", machInst); 296 default: 297 return new Unknown(machInst); 298 } 299 } 300 } 301 } else { 302 if (bits(op2, 0) == 0) { 303 return new WarnUnimplemented("strd", machInst); 304 } else { 305 return new WarnUnimplemented("ldrd", machInst); 306 } 307 } 308 } 309 ''' % { 310 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 311 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 312 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 313 } 314}}; 315 316def format Thumb32LoadWord() {{ 317 decode = ''' 318 { 319 uint32_t op1 = bits(machInst, 24, 23); 320 if (bits(op1, 1) == 0) { 321 uint32_t op2 = bits(machInst, 11, 6); 322 if (HTRN == 0xF) { 323 if (UP) { 324 return new %(literal_u)s(machInst, RT, INTREG_PC, 325 true, IMMED_11_0); 326 } else { 327 return new %(literal)s(machInst, RT, INTREG_PC, 328 false, IMMED_11_0); 329 } 330 } else if (op1 == 0x1) { 331 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 332 } else if (op2 == 0) { 333 return new %(register)s(machInst, RT, RN, UP, 334 bits(machInst, 5, 4), LSL, RM); 335 } else if ((op2 & 0x3c) == 0x38) { 336 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 337 } else if ((op2 & 0x3c) == 0x30 || //P 338 (op2 & 0x24) == 0x24) { //W 339 uint32_t puw = bits(machInst, 10, 8); 340 uint32_t imm = IMMED_7_0; 341 switch (puw) { 342 case 0: 343 case 2: 344 // If we're here, either P or W must have been set. 345 panic("Neither P or W set, but that " 346 "shouldn't be possible.\\n"); 347 case 1: 348 return new %(imm_w)s(machInst, RT, RN, false, imm); 349 case 3: 350 return new %(imm_uw)s(machInst, RT, RN, true, imm); 351 case 4: 352 return new %(imm_p)s(machInst, RT, RN, false, imm); 353 case 5: 354 return new %(imm_pw)s(machInst, RT, RN, false, imm); 355 case 6: 356 return new %(imm_pu)s(machInst, RT, RN, true, imm); 357 case 7: 358 return new %(imm_puw)s(machInst, RT, RN, true, imm); 359 } 360 } 361 } else { 362 return new Unknown(machInst); 363 } 364 } 365 ''' 366 classNames = { 367 "literal_u" : loadImmClassName(False, True, False), 368 "literal" : loadImmClassName(False, False, False), 369 "register" : loadRegClassName(False, True, False), 370 "ldrt" : loadImmClassName(False, True, False, user=True), 371 "imm_w" : loadImmClassName(True, False, True), 372 "imm_uw" : loadImmClassName(True, True, True), 373 "imm_p" : loadImmClassName(False, False, False), 374 "imm_pw" : loadImmClassName(False, False, True), 375 "imm_pu" : loadImmClassName(False, True, False), 376 "imm_puw" : loadImmClassName(False, True, True) 377 } 378 decode_block = decode % classNames 379}}; 380 381def format Thumb32StoreSingle() {{ 382 def buildPuwDecode(size): 383 puwDecode = ''' 384 { 385 uint32_t puw = bits(machInst, 10, 8); 386 uint32_t imm = IMMED_7_0; 387 switch (puw) { 388 case 0: 389 case 2: 390 // If we're here, either P or W must have been set. 391 panic("Neither P or W set, but that " 392 "shouldn't be possible.\\n"); 393 case 1: 394 return new %(imm_w)s(machInst, RT, RN, false, imm); 395 case 3: 396 return new %(imm_uw)s(machInst, RT, RN, true, imm); 397 case 4: 398 return new %(imm_p)s(machInst, RT, RN, false, imm); 399 case 5: 400 return new %(imm_pw)s(machInst, RT, RN, false, imm); 401 case 6: 402 return new %(imm_pu)s(machInst, RT, RN, true, imm); 403 case 7: 404 return new %(imm_puw)s(machInst, RT, RN, true, imm); 405 } 406 } 407 ''' 408 return puwDecode % { 409 "imm_w" : storeImmClassName(True, False, True, size=size), 410 "imm_uw" : storeImmClassName(True, True, True, size=size), 411 "imm_p" : storeImmClassName(False, False, False, size=size), 412 "imm_pw" : storeImmClassName(False, False, True, size=size), 413 "imm_pu" : storeImmClassName(False, True, False, size=size), 414 "imm_puw" : storeImmClassName(False, True, True, size=size) 415 } 416 decode = ''' 417 { 418 uint32_t op1 = bits(machInst, 23, 21); 419 uint32_t op2 = bits(machInst, 11, 6); 420 bool op2Puw = ((op2 & 0x24) == 0x24 || 421 (op2 & 0x3c) == 0x30); 422 if (op1 == 4) { 423 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 424 } else if (op1 == 0 && op2Puw) { 425 %(strb_puw)s; 426 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 427 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 428 } else if (op1 == 0 && op2 == 0) { 429 return new %(strb_reg)s(machInst, RT, RN, true, 430 bits(machInst, 5, 4), LSL, RM); 431 } else if (op1 == 5) { 432 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 433 } else if (op1 == 1 && op2Puw) { 434 %(strh_puw)s; 435 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 436 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 437 } else if (op1 == 1 && op2 == 0) { 438 return new %(strh_reg)s(machInst, RT, RN, true, 439 bits(machInst, 5, 4), LSL, RM); 440 } else if (op1 == 6) { 441 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 442 } else if (op1 == 2 && op2Puw) { 443 %(str_puw)s; 444 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 445 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 446 } else if (op1 == 2 && op2 == 0) { 447 return new %(str_reg)s(machInst, RT, RN, true, 448 bits(machInst, 5, 4), LSL, RM); 449 } else { 450 return new Unknown(machInst); 451 } 452 } 453 ''' 454 classNames = { 455 "strb_imm" : storeImmClassName(False, True, False, size=1), 456 "strb_puw" : buildPuwDecode(1), 457 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 458 "strb_reg" : storeRegClassName(False, True, False, size=1), 459 "strh_imm" : storeImmClassName(False, True, False, size=2), 460 "strh_puw" : buildPuwDecode(2), 461 "strht" : storeImmClassName(False, True, False, user=True, size=2), 462 "strh_reg" : storeRegClassName(False, True, False, size=2), 463 "str_imm" : storeImmClassName(False, True, False), 464 "str_puw" : buildPuwDecode(4), 465 "strt" : storeImmClassName(False, True, False, user=True), 466 "str_reg" : storeRegClassName(False, True, False) 467 } 468 decode_block = decode % classNames 469}}; 470 471def format LoadHalfwordMemoryHints() {{ 472 decode = ''' 473 { 474 const uint32_t op1 = bits(machInst, 24, 23); 475 const uint32_t op2 = bits(machInst, 11, 6); 476 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 477 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 478 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 479 const uint32_t imm12 = bits(machInst, 11, 0); 480 const uint32_t imm8 = bits(machInst, 7, 0); 481 bool pldw = bits(machInst, 21); 482 const uint32_t imm2 = bits(machInst, 5, 4); 483 if (rn == 0xf) { 484 if (rt == 0xf) { 485 if (bits(op1, 1) == 1) { 486 // Unallocated memory hint 487 return new NopInst(machInst); 488 } else { 489 return new Unknown(machInst); 490 } 491 } else { 492 if (bits(op1, 1) == 1) { 493 if (bits(machInst, 23)) { 494 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 495 true, imm12); 496 } else { 497 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 498 false, imm12); 499 } 500 } else { 501 if (bits(machInst, 23)) { 502 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 503 true, imm12); 504 } else { 505 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 506 false, imm12); 507 } 508 } 509 } 510 } else if (rt == 0xf) { 511 switch (op1) { 512 case 0x0: 513 if (op2 == 0x0) { 514 if (pldw) { 515 return new %(pldw_radd)s(machInst, INTREG_ZERO, 516 rn, true, imm2, LSL, rm); 517 } else { 518 return new %(pld_radd)s(machInst, INTREG_ZERO, 519 rn, true, imm2, LSL, rm); 520 } 521 } else if (bits(op2, 5, 2) == 0xc) { 522 if (pldw) { 523 return new %(pldw_isub)s(machInst, INTREG_ZERO, 524 rn, false, imm8); 525 } else { 526 return new %(pld_isub)s(machInst, INTREG_ZERO, 527 rn, false, imm8); 528 } 529 } 530 break; 531 case 0x1: 532 if (pldw) { 533 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 534 rn, true, imm12); 535 } else { 536 return new %(pld_iadd)s(machInst, INTREG_ZERO, 537 rn, true, imm12); 538 } 539 case 0x2: 540 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 541 // Unallocated memory hint 542 return new NopInst(machInst); 543 } 544 break; 545 case 0x3: 546 return new NopInst(machInst); 547 } 548 return new Unknown(machInst); 549 } else { 550 switch (op1) { 551 case 0x0: 552 if (op2 == 0) { 553 return new %(ldrh_radd)s(machInst, rt, rn, true, 554 imm2, LSL, rm); 555 } else if (bits(op2, 5, 2) == 0xe) { 556 return new %(ldrht)s(machInst, rt, rn, true, imm8); 557 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 558 const uint32_t puw = bits(machInst, 10, 8); 559 switch (puw) { 560 case 0x1: 561 return new %(ldrh_iw)s(machInst, rt, 562 rn, false, imm8); 563 case 0x3: 564 return new %(ldrh_iuw)s(machInst, rt, 565 rn, true, imm8); 566 case 0x4: 567 return new %(ldrh_ip)s(machInst, rt, 568 rn, false, imm8); 569 case 0x5: 570 return new %(ldrh_ipw)s(machInst, rt, 571 rn, false, imm8); 572 case 0x7: 573 return new %(ldrh_ipuw)s(machInst, rt, 574 rn, true, imm8); 575 } 576 } 577 break; 578 case 0x1: 579 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 580 case 0x2: 581 if (op2 == 0) { 582 return new %(ldrsh_radd)s(machInst, rt, rn, true, 583 imm2, LSL, rm); 584 } else if (bits(op2, 5, 2) == 0xe) { 585 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 586 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 587 const uint32_t puw = bits(machInst, 10, 8); 588 switch (puw) { 589 case 0x1: 590 return new %(ldrsh_iw)s(machInst, rt, 591 rn, false, imm8); 592 case 0x3: 593 return new %(ldrsh_iuw)s(machInst, rt, 594 rn, true, imm8); 595 case 0x4: 596 return new %(ldrsh_ip)s(machInst, rt, 597 rn, false, imm8); 598 case 0x5: 599 return new %(ldrsh_ipw)s(machInst, rt, 600 rn, false, imm8); 601 case 0x7: 602 return new %(ldrsh_ipuw)s(machInst, rt, 603 rn, true, imm8); 604 } 605 } 606 break; 607 case 0x3: 608 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 609 } 610 return new Unknown(machInst); 611 } 612 } 613 ''' 614 substDict = { 615 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 616 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 617 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 618 "ldrh_lit" : loadImmClassName(False, False, False, 2), 619 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 620 "ldrh_radd" : loadRegClassName(False, True, False, 2), 621 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 622 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 623 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 624 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 625 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 626 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 627 "ldrh_iw" : loadImmClassName(True, False, True, 2), 628 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 629 "ldrh_ip" : loadImmClassName(False, False, False, 2), 630 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 631 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 632 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 633 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 634 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 635 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 636 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 637 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 638 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 639 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 640 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 641 } 642 decode_block = decode % substDict 643}}; 644 645def format Thumb16MemReg() {{ 646 decode = ''' 647 { 648 const uint32_t opb = bits(machInst, 11, 9); 649 const uint32_t rt = bits(machInst, 2, 0); 650 const uint32_t rn = bits(machInst, 5, 3); 651 const uint32_t rm = bits(machInst, 8, 6); 652 switch (opb) { 653 case 0x0: 654 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 655 case 0x1: 656 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 657 case 0x2: 658 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 659 case 0x3: 660 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 661 case 0x4: 662 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 663 case 0x5: 664 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 665 case 0x6: 666 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 667 case 0x7: 668 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 669 } 670 } 671 ''' 672 classNames = { 673 "str" : storeRegClassName(False, True, False), 674 "strh" : storeRegClassName(False, True, False, size=2), 675 "strb" : storeRegClassName(False, True, False, size=1), 676 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 677 "ldr" : loadRegClassName(False, True, False), 678 "ldrh" : loadRegClassName(False, True, False, size=2), 679 "ldrb" : loadRegClassName(False, True, False, size=1), 680 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 681 } 682 decode_block = decode % classNames 683}}; 684 685def format Thumb16MemImm() {{ 686 decode = ''' 687 { 688 const uint32_t opa = bits(machInst, 15, 12); 689 const uint32_t opb = bits(machInst, 11, 9); 690 const uint32_t lrt = bits(machInst, 2, 0); 691 const uint32_t lrn = bits(machInst, 5, 3); 692 const uint32_t hrt = bits(machInst, 10, 8); 693 const uint32_t imm5 = bits(machInst, 10, 6); 694 const uint32_t imm8 = bits(machInst, 7, 0); 695 const bool load = bits(opb, 2); 696 switch (opa) { 697 case 0x6: 698 if (load) { 699 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 700 } else { 701 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 702 } 703 case 0x7: 704 if (load) { 705 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 706 } else { 707 return new %(strb)s(machInst, lrt, lrn, true, imm5); 708 } 709 case 0x8: 710 if (load) { 711 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 712 } else { 713 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 714 } 715 case 0x9: 716 if (load) { 717 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 718 } else { 719 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 720 } 721 default: 722 return new Unknown(machInst); 723 } 724 } 725 ''' 726 classNames = { 727 "ldr" : loadImmClassName(False, True, False), 728 "str" : storeImmClassName(False, True, False), 729 "ldrh" : loadImmClassName(False, True, False, size=2), 730 "strh" : storeImmClassName(False, True, False, size=2), 731 "ldrb" : loadImmClassName(False, True, False, size=1), 732 "strb" : storeImmClassName(False, True, False, size=1), 733 } 734 decode_block = decode % classNames 735}}; 736 737def format Thumb16MemLit() {{ 738 decode_block = ''' 739 { 740 const uint32_t rt = bits(machInst, 10, 8); 741 const uint32_t imm8 = bits(machInst, 7, 0); 742 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 743 } 744 ''' % loadImmClassName(False, True, False) 745}}; 746 747