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