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