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