1// -*- mode:c++ -*- 2 3// Copyright (c) 2010,2019 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 if ((RT %% 2) == 0) { 126 %(ldrd)s 127 } else { 128 return new Unknown(machInst); 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 229 const auto type_L = bits(machInst, 22, 20); 230 const auto ex_ord = bits(machInst, 9, 8); 231 const auto dec_fields = (type_L << 2) | ex_ord; 232 233 switch (dec_fields) { 234 case 0x00: 235 return new %(stl)s(machInst, rt, rn, true, 0); 236 case 0x02: 237 return new %(stlex)s(machInst, rt, rt2, rn, true, 0); 238 case 0x03: 239 return new %(strex)s(machInst, rt, rt2, rn, true, 0); 240 case 0x04: 241 return new %(lda)s(machInst, rt, rn, true, 0); 242 case 0x06: 243 return new %(ldaex)s(machInst, rt, rn, true, 0); 244 case 0x07: 245 return new %(ldrex)s(machInst, rt, rn, true, 0); 246 case 0x0a: 247 return new %(stlexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); 248 case 0x0b: 249 return new %(strexd)s(machInst, rt, rt2, rt2 + 1, rn, true, 0); 250 case 0x0e: 251 return new %(ldaexd)s(machInst, rt, rt + 1, rn, true, 0); 252 case 0x0f: 253 return new %(ldrexd)s(machInst, rt, rt + 1, rn, true, 0); 254 case 0x10: 255 return new %(stlb)s(machInst, rt, rn, true, 0); 256 case 0x12: 257 return new %(stlexb)s(machInst, rt, rt2, rn, true, 0); 258 case 0x13: 259 return new %(strexb)s(machInst, rt, rt2, rn, true, 0); 260 case 0x14: 261 return new %(ldab)s(machInst, rt, rn, true, 0); 262 case 0x16: 263 return new %(ldaexb)s(machInst, rt, rn, true, 0); 264 case 0x17: 265 return new %(ldrexb)s(machInst, rt, rn, true, 0); 266 case 0x18: 267 return new %(stlh)s(machInst, rt, rn, true, 0); 268 case 0x1a: 269 return new %(stlexh)s(machInst, rt, rt2, rn, true, 0); 270 case 0x1b: 271 return new %(strexh)s(machInst, rt, rt2, rn, true, 0); 272 case 0x1c: 273 return new %(ldah)s(machInst, rt, rn, true, 0); 274 case 0x1e: 275 return new %(ldaexh)s(machInst, rt, rn, true, 0); 276 case 0x1f: 277 return new %(ldrexh)s(machInst, rt, rn, true, 0); 278 default: 279 return new Unknown(machInst); 280 } 281 } 282 ''' % { 283 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 284 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 285 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 286 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 287 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 288 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 289 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 290 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False), 291 292 "lda" : "LDA_" + loadImmClassName(False, True, False, size=4), 293 "ldab" : "LDAB_" + loadImmClassName(False, True, False, size=1), 294 "ldah" : "LDAH_" + loadImmClassName(False, True, False, size=2), 295 "ldaex" : "LDAEX_" + loadImmClassName(False, True, False, size=4), 296 "ldaexb" : "LDAEXB_" + loadImmClassName(False, True, False, size=1), 297 "ldaexh" : "LDAEXH_" + loadImmClassName(False, True, False, size=2), 298 "ldaexd" : "LDAEXD_" + loadDoubleImmClassName(False, True, False), 299 300 "stl" : "STL_" + storeImmClassName(False, True, False, size=4), 301 "stlb" : "STLB_" + storeImmClassName(False, True, False, size=1), 302 "stlh" : "STLH_" + storeImmClassName(False, True, False, size=2), 303 "stlex" : "STLEX_" + storeImmClassName(False, True, False, size=4), 304 "stlexb" : "STLEXB_" + storeImmClassName(False, True, False, size=1), 305 "stlexh" : "STLEXH_" + storeImmClassName(False, True, False, size=2), 306 "stlexd" : "STLEXD_" + storeDoubleImmClassName(False, True, False) 307 } 308}}; 309 310def format Thumb32SrsRfe() {{ 311 decode_block = ''' 312 { 313 const bool wb = (bits(machInst, 21) == 1); 314 const bool add = (bits(machInst, 24, 23) == 0x3); 315 if (bits(machInst, 20) == 1) { 316 // post == add 317 const IntRegIndex rn = 318 (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 319 if (!add && !wb) { 320 return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb); 321 } else if (add && !wb) { 322 return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb); 323 } else if (!add && wb) { 324 return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb); 325 } else { 326 return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb); 327 } 328 } else { 329 const uint32_t mode = bits(machInst, 4, 0); 330 // We check at decode stage if the mode exists even 331 // if the checking is re-done by Srs::execute. 332 // This is done because we will otherwise panic if 333 // trying to read the banked stack pointer of an 334 // unrecognized mode. 335 if (unknownMode32((OperatingMode)mode)) 336 return new Unknown(machInst); 337 if (!add && !wb) { 338 return new %(srs)s(machInst, mode, 339 SrsOp::DecrementBefore, wb); 340 } else if (add && !wb) { 341 return new %(srs_u)s(machInst, mode, 342 SrsOp::IncrementAfter, wb); 343 } else if (!add && wb) { 344 return new %(srs_w)s(machInst, mode, 345 SrsOp::DecrementBefore, wb); 346 } else { 347 return new %(srs_uw)s(machInst, mode, 348 SrsOp::IncrementAfter, wb); 349 } 350 } 351 } 352 ''' % { 353 "rfe" : "RFE_" + loadImmClassName(False, False, False, 8), 354 "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), 355 "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8), 356 "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8), 357 "srs" : "SRS_" + storeImmClassName(False, False, False, 8), 358 "srs_u" : "SRS_" + storeImmClassName(True, True, False, 8), 359 "srs_w" : "SRS_" + storeImmClassName(False, False, True, 8), 360 "srs_uw" : "SRS_" + storeImmClassName(True, True, True, 8) 361 } 362}}; 363 364def format Thumb32LdrStrDExTbh() {{ 365 decode_block = ''' 366 { 367 const uint32_t op1 = bits(machInst, 24, 23); 368 const uint32_t op2 = bits(machInst, 21, 20); 369 const uint32_t op3 = bits(machInst, 7, 4); 370 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 371 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 372 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 373 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 374 const uint32_t imm8 = bits(machInst, 7, 0); 375 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 376 if (op1 == 0) { 377 const uint32_t imm = bits(machInst, 7, 0) << 2; 378 if (op2 == 0) { 379 return new %(strex)s(machInst, rt2, rt, rn, true, imm); 380 } else { 381 return new %(ldrex)s(machInst, rt, rn, true, imm); 382 } 383 } else { 384 if (op2 == 0) { 385 switch (op3) { 386 case 0x4: 387 return new %(strexb)s(machInst, rd, rt, rn, true, 0); 388 case 0x5: 389 return new %(strexh)s(machInst, rd, rt, rn, true, 0); 390 case 0x7: 391 return new %(strexd)s(machInst, rd, rt, 392 rt2, rn, true, 0); 393 case 0x8: 394 return new %(stlb)s(machInst, rt, rn, true, 0); 395 case 0x9: 396 return new %(stlh)s(machInst, rt, rn, true, 0); 397 case 0xa: 398 return new %(stl)s(machInst, rt, rn, true, 0); 399 case 0xc: 400 return new %(stlexb)s(machInst, rd, rt, rn, true, 0); 401 case 0xd: 402 return new %(stlexh)s(machInst, rd, rt, rn, true, 0); 403 case 0xe: 404 return new %(stlex)s(machInst, rd, rt, rn, true, 0); 405 case 0xf: 406 return new %(stlexd)s(machInst, rd, rt, 407 rt2, rn, true, 0); 408 default: 409 return new Unknown(machInst); 410 } 411 } else { 412 switch (op3) { 413 case 0x0: 414 return new Tbb(machInst, rn, rd); 415 case 0x1: 416 return new Tbh(machInst, rn, rd); 417 case 0x4: 418 return new %(ldrexb)s(machInst, rt, rn, true, 0); 419 case 0x5: 420 return new %(ldrexh)s(machInst, rt, rn, true, 0); 421 case 0x7: 422 return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); 423 case 0x8: 424 return new %(ldab)s(machInst, rt, rn, true, 0); 425 case 0x9: 426 return new %(ldah)s(machInst, rt, rn, true, 0); 427 case 0xa: 428 return new %(lda)s(machInst, rt, rn, true, 0); 429 case 0xc: 430 return new %(ldaexb)s(machInst, rt, rn, true, 0); 431 case 0xd: 432 return new %(ldaexh)s(machInst, rt, rn, true, 0); 433 case 0xe: 434 return new %(ldaex)s(machInst, rt, rn, true, 0); 435 case 0xf: 436 return new %(ldaexd)s(machInst, rt, rt2, rn, true, 0); 437 default: 438 return new Unknown(machInst); 439 } 440 } 441 } 442 } else { 443 const uint32_t puw = (bits(machInst, 24, 23) << 1) | 444 bits(machInst, 21); 445 const uint32_t dimm = imm8 << 2; 446 if (bits(op2, 0) == 0) { 447 switch (puw) { 448 case 0x1: 449 return new %(strd_w)s(machInst, rt, rt2, rn, false, dimm); 450 case 0x3: 451 return new %(strd_uw)s(machInst, rt, rt2, rn, true, dimm); 452 case 0x4: 453 return new %(strd_p)s(machInst, rt, rt2, rn, false, dimm); 454 case 0x5: 455 return new %(strd_pw)s(machInst, rt, rt2, rn, false, dimm); 456 case 0x6: 457 return new %(strd_pu)s(machInst, rt, rt2, rn, true, dimm); 458 case 0x7: 459 return new %(strd_puw)s(machInst, rt, rt2, rn, true, dimm); 460 default: 461 return new Unknown(machInst); 462 } 463 } else { 464 switch (puw) { 465 case 0x1: 466 return new %(ldrd_w)s(machInst, rt, rt2, rn, false, dimm); 467 case 0x3: 468 return new %(ldrd_uw)s(machInst, rt, rt2, rn, true, dimm); 469 case 0x4: 470 return new %(ldrd_p)s(machInst, rt, rt2, rn, false, dimm); 471 case 0x5: 472 return new %(ldrd_pw)s(machInst, rt, rt2, rn, false, dimm); 473 case 0x6: 474 return new %(ldrd_pu)s(machInst, rt, rt2, rn, true, dimm); 475 case 0x7: 476 return new %(ldrd_puw)s(machInst, rt, rt2, rn, true, dimm); 477 default: 478 return new Unknown(machInst); 479 } 480 } 481 } 482 } 483 ''' % { 484 "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 485 "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 486 "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 487 "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 488 "strex" : "STREX_" + storeImmClassName(False, True, False, size=4), 489 "strexb" : "STREXB_" + storeImmClassName(False, True, False, size=1), 490 "strexh" : "STREXH_" + storeImmClassName(False, True, False, size=2), 491 "strexd" : "STREXD_" + storeDoubleImmClassName(False, True, False), 492 "ldrd_w" : loadDoubleImmClassName(True, False, True), 493 "ldrd_uw" : loadDoubleImmClassName(True, True, True), 494 "ldrd_p" : loadDoubleImmClassName(False, False, False), 495 "ldrd_pw" : loadDoubleImmClassName(False, False, True), 496 "ldrd_pu" : loadDoubleImmClassName(False, True, False), 497 "ldrd_puw" : loadDoubleImmClassName(False, True, True), 498 "strd_w" : storeDoubleImmClassName(True, False, True), 499 "strd_uw" : storeDoubleImmClassName(True, True, True), 500 "strd_p" : storeDoubleImmClassName(False, False, False), 501 "strd_pw" : storeDoubleImmClassName(False, False, True), 502 "strd_pu" : storeDoubleImmClassName(False, True, False), 503 "strd_puw" : storeDoubleImmClassName(False, True, True), 504 505 "stl" : "STL_" + storeImmClassName(False, True, False, size=4), 506 "stlh" : "STLH_" + storeImmClassName(False, True, False, size=2), 507 "stlb" : "STLB_" + storeImmClassName(False, True, False, size=1), 508 "stlex" : "STLEX_" + storeImmClassName(False, True, False, size=4), 509 "stlexh" : "STLEXH_" + storeImmClassName(False, True, False, size=2), 510 "stlexb" : "STLEXB_" + storeImmClassName(False, True, False, size=1), 511 "stlexd" : "STLEXD_" + storeDoubleImmClassName(False, True, False), 512 "lda" : "LDA_" + loadImmClassName(False, True, False, size=4), 513 "ldah" : "LDAH_" + loadImmClassName(False, True, False, size=2), 514 "ldab" : "LDAB_" + loadImmClassName(False, True, False, size=1), 515 "ldaex" : "LDAEX_" + loadImmClassName(False, True, False, size=4), 516 "ldaexh" : "LDAEXH_" + loadImmClassName(False, True, False, size=2), 517 "ldaexb" : "LDAEXB_" + loadImmClassName(False, True, False, size=1), 518 "ldaexd" : "LDAEXD_" + loadDoubleImmClassName(False, True, False) 519 } 520}}; 521 522def format Thumb32LoadWord() {{ 523 decode = ''' 524 { 525 uint32_t op1 = bits(machInst, 24, 23); 526 if (bits(op1, 1) == 0) { 527 uint32_t op2 = bits(machInst, 11, 6); 528 if (HTRN == 0xF) { 529 if (UP) { 530 return new %(literal_u)s(machInst, RT, INTREG_PC, 531 true, IMMED_11_0); 532 } else { 533 return new %(literal)s(machInst, RT, INTREG_PC, 534 false, IMMED_11_0); 535 } 536 } else if (op1 == 0x1) { 537 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 538 } else if (op2 == 0) { 539 return new %(register)s(machInst, RT, RN, UP, 540 bits(machInst, 5, 4), LSL, RM); 541 } else if ((op2 & 0x3c) == 0x38) { 542 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 543 } else if ((op2 & 0x3c) == 0x30 || //P 544 (op2 & 0x24) == 0x24) { //W 545 uint32_t puw = bits(machInst, 10, 8); 546 uint32_t imm = IMMED_7_0; 547 switch (puw) { 548 case 0: 549 case 2: 550 // If we're here, either P or W must have been set. 551 panic("Neither P or W set, but that " 552 "shouldn't be possible.\\n"); 553 case 1: 554 return new %(imm_w)s(machInst, RT, RN, false, imm); 555 case 3: 556 return new %(imm_uw)s(machInst, RT, RN, true, imm); 557 case 4: 558 return new %(imm_p)s(machInst, RT, RN, false, imm); 559 case 5: 560 return new %(imm_pw)s(machInst, RT, RN, false, imm); 561 case 6: 562 return new %(imm_pu)s(machInst, RT, RN, true, imm); 563 case 7: 564 return new %(imm_puw)s(machInst, RT, RN, true, imm); 565 } 566 } 567 return new Unknown(machInst); 568 } else { 569 return new Unknown(machInst); 570 } 571 } 572 ''' 573 classNames = { 574 "literal_u" : loadImmClassName(False, True, False), 575 "literal" : loadImmClassName(False, False, False), 576 "register" : loadRegClassName(False, True, False), 577 "ldrt" : loadImmClassName(False, True, False, user=True), 578 "imm_w" : loadImmClassName(True, False, True), 579 "imm_uw" : loadImmClassName(True, True, True), 580 "imm_p" : loadImmClassName(False, False, False), 581 "imm_pw" : loadImmClassName(False, False, True), 582 "imm_pu" : loadImmClassName(False, True, False), 583 "imm_puw" : loadImmClassName(False, True, True) 584 } 585 decode_block = decode % classNames 586}}; 587 588def format Thumb32StoreSingle() {{ 589 def buildPuwDecode(size): 590 puwDecode = ''' 591 { 592 uint32_t puw = bits(machInst, 10, 8); 593 uint32_t imm = IMMED_7_0; 594 switch (puw) { 595 case 0: 596 case 2: 597 // If we're here, either P or W must have been set. 598 panic("Neither P or W set, but that " 599 "shouldn't be possible.\\n"); 600 case 1: 601 return new %(imm_w)s(machInst, RT, RN, false, imm); 602 case 3: 603 return new %(imm_uw)s(machInst, RT, RN, true, imm); 604 case 4: 605 return new %(imm_p)s(machInst, RT, RN, false, imm); 606 case 5: 607 return new %(imm_pw)s(machInst, RT, RN, false, imm); 608 case 6: 609 return new %(imm_pu)s(machInst, RT, RN, true, imm); 610 case 7: 611 return new %(imm_puw)s(machInst, RT, RN, true, imm); 612 default: 613 M5_UNREACHABLE; 614 } 615 } 616 ''' 617 return puwDecode % { 618 "imm_w" : storeImmClassName(True, False, True, size=size), 619 "imm_uw" : storeImmClassName(True, True, True, size=size), 620 "imm_p" : storeImmClassName(False, False, False, size=size), 621 "imm_pw" : storeImmClassName(False, False, True, size=size), 622 "imm_pu" : storeImmClassName(False, True, False, size=size), 623 "imm_puw" : storeImmClassName(False, True, True, size=size) 624 } 625 decode = ''' 626 { 627 uint32_t op1 = bits(machInst, 23, 21); 628 uint32_t op2 = bits(machInst, 11, 6); 629 bool op2Puw = ((op2 & 0x24) == 0x24 || 630 (op2 & 0x3c) == 0x30); 631 if (RN == 0xf) { 632 return new Unknown(machInst); 633 } 634 if (op1 == 4) { 635 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 636 } else if (op1 == 0 && op2Puw) { 637 %(strb_puw)s; 638 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 639 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 640 } else if (op1 == 0 && op2 == 0) { 641 return new %(strb_reg)s(machInst, RT, RN, true, 642 bits(machInst, 5, 4), LSL, RM); 643 } else if (op1 == 5) { 644 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 645 } else if (op1 == 1 && op2Puw) { 646 %(strh_puw)s; 647 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 648 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 649 } else if (op1 == 1 && op2 == 0) { 650 return new %(strh_reg)s(machInst, RT, RN, true, 651 bits(machInst, 5, 4), LSL, RM); 652 } else if (op1 == 6) { 653 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 654 } else if (op1 == 2 && op2Puw) { 655 %(str_puw)s; 656 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 657 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 658 } else if (op1 == 2 && op2 == 0) { 659 return new %(str_reg)s(machInst, RT, RN, true, 660 bits(machInst, 5, 4), LSL, RM); 661 } else { 662 return new Unknown(machInst); 663 } 664 } 665 ''' 666 classNames = { 667 "strb_imm" : storeImmClassName(False, True, False, size=1), 668 "strb_puw" : buildPuwDecode(1), 669 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 670 "strb_reg" : storeRegClassName(False, True, False, size=1), 671 "strh_imm" : storeImmClassName(False, True, False, size=2), 672 "strh_puw" : buildPuwDecode(2), 673 "strht" : storeImmClassName(False, True, False, user=True, size=2), 674 "strh_reg" : storeRegClassName(False, True, False, size=2), 675 "str_imm" : storeImmClassName(False, True, False), 676 "str_puw" : buildPuwDecode(4), 677 "strt" : storeImmClassName(False, True, False, user=True), 678 "str_reg" : storeRegClassName(False, True, False) 679 } 680 decode_block = decode % classNames 681}}; 682 683def format LoadByteMemoryHints() {{ 684 decode = ''' 685 { 686 const uint32_t op1 = bits(machInst, 24, 23); 687 const uint32_t op2 = bits(machInst, 11, 6); 688 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 689 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 690 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 691 const uint32_t imm12 = bits(machInst, 11, 0); 692 const uint32_t imm8 = bits(machInst, 7, 0); 693 bool pldw = bits(machInst, 21); 694 const uint32_t imm2 = bits(machInst, 5, 4); 695 if (rn == 0xf) { 696 if (rt == 0xf) { 697 const bool add = bits(machInst, 23); 698 if (bits(op1, 1) == 1) { 699 if (add) { 700 return new %(pli_iulit)s(machInst, INTREG_ZERO, 701 INTREG_PC, true, imm12); 702 } else { 703 return new %(pli_ilit)s(machInst, INTREG_ZERO, 704 INTREG_PC, false, imm12); 705 } 706 } else { 707 if (add) { 708 return new %(pld_iulit)s(machInst, INTREG_ZERO, 709 INTREG_PC, true, imm12); 710 } else { 711 return new %(pld_ilit)s(machInst, INTREG_ZERO, 712 INTREG_PC, false, imm12); 713 } 714 } 715 } else { 716 if (bits(op1, 1) == 1) { 717 if (bits(machInst, 23)) { 718 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 719 true, imm12); 720 } else { 721 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 722 false, imm12); 723 } 724 } else { 725 if (bits(machInst, 23)) { 726 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 727 true, imm12); 728 } else { 729 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 730 false, imm12); 731 } 732 } 733 } 734 } else if (rt == 0xf) { 735 switch (op1) { 736 case 0x0: 737 if (op2 == 0x0) { 738 if (pldw) { 739 return new %(pldw_radd)s(machInst, INTREG_ZERO, 740 rn, true, imm2, LSL, rm); 741 } else { 742 return new %(pld_radd)s(machInst, INTREG_ZERO, 743 rn, true, imm2, LSL, rm); 744 } 745 } else if (bits(op2, 5, 2) == 0xc) { 746 if (pldw) { 747 return new %(pldw_isub)s(machInst, INTREG_ZERO, 748 rn, false, imm8); 749 } else { 750 return new %(pld_isub)s(machInst, INTREG_ZERO, 751 rn, false, imm8); 752 } 753 } 754 break; 755 case 0x1: 756 if (pldw) { 757 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 758 rn, true, imm12); 759 } else { 760 return new %(pld_iadd)s(machInst, INTREG_ZERO, 761 rn, true, imm12); 762 } 763 case 0x2: 764 if (op2 == 0x0) { 765 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 766 true, imm2, LSL, rm); 767 } else if (bits(op2, 5, 2) == 0xc) { 768 return new %(pli_ilit)s(machInst, INTREG_ZERO, 769 INTREG_PC, false, imm8); 770 } 771 break; 772 case 0x3: 773 return new %(pli_iulit)s(machInst, INTREG_ZERO, 774 INTREG_PC, true, imm12); 775 } 776 return new Unknown(machInst); 777 } else { 778 switch (op1) { 779 case 0x0: 780 if (op2 == 0) { 781 return new %(ldrb_radd)s(machInst, rt, rn, true, 782 imm2, LSL, rm); 783 } else if (bits(op2, 5, 2) == 0xe) { 784 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 785 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 786 const uint32_t puw = bits(machInst, 10, 8); 787 switch (puw) { 788 case 0x1: 789 return new %(ldrb_iw)s(machInst, rt, 790 rn, false, imm8); 791 case 0x3: 792 return new %(ldrb_iuw)s(machInst, rt, 793 rn, true, imm8); 794 case 0x4: 795 return new %(ldrb_ip)s(machInst, rt, 796 rn, false, imm8); 797 case 0x5: 798 return new %(ldrb_ipw)s(machInst, rt, 799 rn, false, imm8); 800 case 0x7: 801 return new %(ldrb_ipuw)s(machInst, rt, 802 rn, true, imm8); 803 } 804 } 805 break; 806 case 0x1: 807 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 808 case 0x2: 809 if (op2 == 0) { 810 return new %(ldrsb_radd)s(machInst, rt, rn, true, 811 imm2, LSL, rm); 812 } else if (bits(op2, 5, 2) == 0xe) { 813 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 814 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 815 const uint32_t puw = bits(machInst, 10, 8); 816 switch (puw) { 817 case 0x1: 818 return new %(ldrsb_iw)s(machInst, rt, 819 rn, false, imm8); 820 case 0x3: 821 return new %(ldrsb_iuw)s(machInst, rt, 822 rn, true, imm8); 823 case 0x4: 824 return new %(ldrsb_ip)s(machInst, rt, 825 rn, false, imm8); 826 case 0x5: 827 return new %(ldrsb_ipw)s(machInst, rt, 828 rn, false, imm8); 829 case 0x7: 830 return new %(ldrsb_ipuw)s(machInst, rt, 831 rn, true, imm8); 832 } 833 } 834 break; 835 case 0x3: 836 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 837 } 838 return new Unknown(machInst); 839 } 840 } 841 ''' 842 substDict = { 843 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 844 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 845 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 846 "ldrb_lit" : loadImmClassName(False, False, False, 1), 847 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 848 "ldrb_radd" : loadRegClassName(False, True, False, 1), 849 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 850 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 851 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 852 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 853 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 854 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 855 "ldrb_iw" : loadImmClassName(True, False, True, 1), 856 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 857 "ldrb_ip" : loadImmClassName(False, False, False, 1), 858 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 859 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 860 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 861 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 862 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 863 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 864 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 865 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 866 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 867 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 868 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 869 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 870 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 871 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 872 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 873 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 874 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 875 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 876 } 877 decode_block = decode % substDict 878}}; 879 880def format LoadHalfwordMemoryHints() {{ 881 decode = ''' 882 { 883 const uint32_t op1 = bits(machInst, 24, 23); 884 const uint32_t op2 = bits(machInst, 11, 6); 885 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 886 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 887 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 888 const uint32_t imm12 = bits(machInst, 11, 0); 889 const uint32_t imm8 = bits(machInst, 7, 0); 890 bool pldw = bits(machInst, 21); 891 const uint32_t imm2 = bits(machInst, 5, 4); 892 if (rn == 0xf) { 893 if (rt == 0xf) { 894 if (bits(op1, 1) == 1) { 895 // Unallocated memory hint 896 return new NopInst(machInst); 897 } else { 898 return new Unknown(machInst); 899 } 900 } else { 901 if (bits(op1, 1) == 1) { 902 if (bits(machInst, 23)) { 903 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 904 true, imm12); 905 } else { 906 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 907 false, imm12); 908 } 909 } else { 910 if (bits(machInst, 23)) { 911 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 912 true, imm12); 913 } else { 914 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 915 false, imm12); 916 } 917 } 918 } 919 } else if (rt == 0xf) { 920 switch (op1) { 921 case 0x0: 922 if (op2 == 0x0) { 923 if (pldw) { 924 return new %(pldw_radd)s(machInst, INTREG_ZERO, 925 rn, true, imm2, LSL, rm); 926 } else { 927 return new %(pld_radd)s(machInst, INTREG_ZERO, 928 rn, true, imm2, LSL, rm); 929 } 930 } else if (bits(op2, 5, 2) == 0xc) { 931 if (pldw) { 932 return new %(pldw_isub)s(machInst, INTREG_ZERO, 933 rn, false, imm8); 934 } else { 935 return new %(pld_isub)s(machInst, INTREG_ZERO, 936 rn, false, imm8); 937 } 938 } 939 break; 940 case 0x1: 941 if (pldw) { 942 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 943 rn, true, imm12); 944 } else { 945 return new %(pld_iadd)s(machInst, INTREG_ZERO, 946 rn, true, imm12); 947 } 948 case 0x2: 949 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 950 // Unallocated memory hint 951 return new NopInst(machInst); 952 } 953 break; 954 case 0x3: 955 return new NopInst(machInst); 956 } 957 return new Unknown(machInst); 958 } else { 959 switch (op1) { 960 case 0x0: 961 if (op2 == 0) { 962 return new %(ldrh_radd)s(machInst, rt, rn, true, 963 imm2, LSL, rm); 964 } else if (bits(op2, 5, 2) == 0xe) { 965 return new %(ldrht)s(machInst, rt, rn, true, imm8); 966 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 967 const uint32_t puw = bits(machInst, 10, 8); 968 switch (puw) { 969 case 0x1: 970 return new %(ldrh_iw)s(machInst, rt, 971 rn, false, imm8); 972 case 0x3: 973 return new %(ldrh_iuw)s(machInst, rt, 974 rn, true, imm8); 975 case 0x4: 976 return new %(ldrh_ip)s(machInst, rt, 977 rn, false, imm8); 978 case 0x5: 979 return new %(ldrh_ipw)s(machInst, rt, 980 rn, false, imm8); 981 case 0x7: 982 return new %(ldrh_ipuw)s(machInst, rt, 983 rn, true, imm8); 984 } 985 } 986 break; 987 case 0x1: 988 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 989 case 0x2: 990 if (op2 == 0) { 991 return new %(ldrsh_radd)s(machInst, rt, rn, true, 992 imm2, LSL, rm); 993 } else if (bits(op2, 5, 2) == 0xe) { 994 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 995 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 996 const uint32_t puw = bits(machInst, 10, 8); 997 switch (puw) { 998 case 0x1: 999 return new %(ldrsh_iw)s(machInst, rt, 1000 rn, false, imm8); 1001 case 0x3: 1002 return new %(ldrsh_iuw)s(machInst, rt, 1003 rn, true, imm8); 1004 case 0x4: 1005 return new %(ldrsh_ip)s(machInst, rt, 1006 rn, false, imm8); 1007 case 0x5: 1008 return new %(ldrsh_ipw)s(machInst, rt, 1009 rn, false, imm8); 1010 case 0x7: 1011 return new %(ldrsh_ipuw)s(machInst, rt, 1012 rn, true, imm8); 1013 } 1014 } 1015 break; 1016 case 0x3: 1017 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 1018 } 1019 return new Unknown(machInst); 1020 } 1021 } 1022 ''' 1023 substDict = { 1024 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 1025 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 1026 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 1027 "ldrh_lit" : loadImmClassName(False, False, False, 2), 1028 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 1029 "ldrh_radd" : loadRegClassName(False, True, False, 2), 1030 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 1031 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 1032 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 1033 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 1034 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 1035 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 1036 "ldrh_iw" : loadImmClassName(True, False, True, 2), 1037 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 1038 "ldrh_ip" : loadImmClassName(False, False, False, 2), 1039 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 1040 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 1041 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 1042 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 1043 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 1044 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 1045 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 1046 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 1047 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 1048 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 1049 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 1050 } 1051 decode_block = decode % substDict 1052}}; 1053 1054def format Thumb16MemReg() {{ 1055 decode = ''' 1056 { 1057 const uint32_t opb = bits(machInst, 11, 9); 1058 const uint32_t rt = bits(machInst, 2, 0); 1059 const uint32_t rn = bits(machInst, 5, 3); 1060 const uint32_t rm = bits(machInst, 8, 6); 1061 switch (opb) { 1062 case 0x0: 1063 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 1064 case 0x1: 1065 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 1066 case 0x2: 1067 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 1068 case 0x3: 1069 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 1070 case 0x4: 1071 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 1072 case 0x5: 1073 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 1074 case 0x6: 1075 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 1076 case 0x7: 1077 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 1078 default: 1079 M5_UNREACHABLE; 1080 } 1081 } 1082 ''' 1083 classNames = { 1084 "str" : storeRegClassName(False, True, False), 1085 "strh" : storeRegClassName(False, True, False, size=2), 1086 "strb" : storeRegClassName(False, True, False, size=1), 1087 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 1088 "ldr" : loadRegClassName(False, True, False), 1089 "ldrh" : loadRegClassName(False, True, False, size=2), 1090 "ldrb" : loadRegClassName(False, True, False, size=1), 1091 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 1092 } 1093 decode_block = decode % classNames 1094}}; 1095 1096def format Thumb16MemImm() {{ 1097 decode = ''' 1098 { 1099 const uint32_t opa = bits(machInst, 15, 12); 1100 const uint32_t opb = bits(machInst, 11, 9); 1101 const uint32_t lrt = bits(machInst, 2, 0); 1102 const uint32_t lrn = bits(machInst, 5, 3); 1103 const uint32_t hrt = bits(machInst, 10, 8); 1104 const uint32_t imm5 = bits(machInst, 10, 6); 1105 const uint32_t imm8 = bits(machInst, 7, 0); 1106 const bool load = bits(opb, 2); 1107 switch (opa) { 1108 case 0x6: 1109 if (load) { 1110 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 1111 } else { 1112 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 1113 } 1114 case 0x7: 1115 if (load) { 1116 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 1117 } else { 1118 return new %(strb)s(machInst, lrt, lrn, true, imm5); 1119 } 1120 case 0x8: 1121 if (load) { 1122 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 1123 } else { 1124 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 1125 } 1126 case 0x9: 1127 if (load) { 1128 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1129 } else { 1130 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1131 } 1132 default: 1133 return new Unknown(machInst); 1134 } 1135 } 1136 ''' 1137 classNames = { 1138 "ldr" : loadImmClassName(False, True, False), 1139 "str" : storeImmClassName(False, True, False), 1140 "ldrh" : loadImmClassName(False, True, False, size=2), 1141 "strh" : storeImmClassName(False, True, False, size=2), 1142 "ldrb" : loadImmClassName(False, True, False, size=1), 1143 "strb" : storeImmClassName(False, True, False, size=1), 1144 } 1145 decode_block = decode % classNames 1146}}; 1147 1148def format Thumb16MemLit() {{ 1149 decode_block = ''' 1150 { 1151 const uint32_t rt = bits(machInst, 10, 8); 1152 const uint32_t imm8 = bits(machInst, 7, 0); 1153 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1154 } 1155 ''' % loadImmClassName(False, True, False) 1156}}; 1157 1158