mem.isa revision 7245:bee7e6b76d38
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Gabe Black 42 43def format AddrMode2(imm) {{ 44 if eval(imm): 45 imm = True 46 else: 47 imm = False 48 49 def buildPUBWLCase(p, u, b, w, l): 50 return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 51 52 header_output = decoder_output = exec_output = "" 53 decode_block = "switch(PUBWL) {\n" 54 55 # Loop over all the values of p, u, b, w and l and build instructions and 56 # a decode block for them. 57 for p in (0, 1): 58 for u in (0, 1): 59 for b in (0, 1): 60 for w in (0, 1): 61 post = (p == 0) 62 user = (p == 0 and w == 1) 63 writeback = (p == 0 or w == 1) 64 add = (u == 1) 65 if b == 0: 66 size = 4 67 else: 68 size = 1 69 if add: 70 addStr = "true" 71 else: 72 addStr = "false" 73 if imm: 74 newDecode = "return new %s(machInst, RD, RN," + \ 75 "%s, machInst.immed11_0);" 76 loadClass = loadImmClassName(post, add, writeback, 77 size, False, user) 78 storeClass = storeImmClassName(post, add, writeback, 79 size, False, user) 80 loadDecode = newDecode % (loadClass, addStr) 81 storeDecode = newDecode % (storeClass, addStr) 82 else: 83 newDecode = "return new %s(machInst, RD, RN, %s," + \ 84 "machInst.shiftSize," + \ 85 "machInst.shift, RM);" 86 loadClass = loadRegClassName(post, add, writeback, 87 size, False, user) 88 storeClass = storeRegClassName(post, add, writeback, 89 size, False, user) 90 loadDecode = newDecode % (loadClass, addStr) 91 storeDecode = newDecode % (storeClass, addStr) 92 decode = ''' 93 case %#x: 94 {%s} 95 break; 96 ''' 97 decode_block += decode % \ 98 (buildPUBWLCase(p,u,b,w,1), loadDecode) 99 decode_block += decode % \ 100 (buildPUBWLCase(p,u,b,w,0), storeDecode) 101 decode_block += ''' 102 default: 103 return new Unknown(machInst); 104 break; 105 }''' 106}}; 107 108def format AddrMode3() {{ 109 decode = ''' 110 { 111 const uint32_t op1 = bits(machInst, 24, 20); 112 const uint32_t op2 = bits(machInst, 6, 5); 113 const uint32_t puiw = bits(machInst, 24, 21); 114 const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0; 115 switch (op2) { 116 case 0x1: 117 if (op1 & 0x1) { 118 %(ldrh)s 119 } else { 120 %(strh)s 121 } 122 case 0x2: 123 if (op1 & 0x1) { 124 %(ldrsb)s 125 } else { 126 %(ldrd)s 127 } 128 case 0x3: 129 if (op1 & 0x1) { 130 %(ldrsh)s 131 } else { 132 %(strd)s 133 } 134 default: 135 return new Unknown(machInst); 136 } 137 } 138 ''' 139 140 def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False): 141 post = (p == 0) 142 user = (p == 0 and w == 1) 143 writeback = (p == 0 or w == 1) 144 add = (u == 1) 145 caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0) 146 decode = ''' 147 case %#x: 148 return new '''% caseVal 149 if add: 150 addStr = "true" 151 else: 152 addStr = "false" 153 if i: 154 if load: 155 if d: 156 className = loadDoubleImmClassName(post, add, writeback) 157 else: 158 className = loadImmClassName(post, add, writeback, \ 159 size=size, sign=sign, \ 160 user=user) 161 else: 162 if d: 163 className = storeDoubleImmClassName(post, add, writeback) 164 else: 165 className = storeImmClassName(post, add, writeback, \ 166 size=size, sign=sign, \ 167 user=user) 168 decode += ("%s(machInst, RT, RN, %s, imm);\n" % \ 169 (className, addStr)) 170 else: 171 if load: 172 if d: 173 className = loadDoubleRegClassName(post, add, writeback) 174 else: 175 className = loadRegClassName(post, add, writeback, \ 176 size=size, sign=sign, \ 177 user=user) 178 else: 179 if d: 180 className = storeDoubleRegClassName(post, add, writeback) 181 else: 182 className = storeRegClassName(post, add, writeback, \ 183 size=size, sign=sign, \ 184 user=user) 185 decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \ 186 (className, addStr)) 187 return decode 188 189 def decodePuiw(load, d, size=4, sign=False): 190 global decodePuiwCase 191 decode = "switch (puiw) {\n" 192 for p in (0, 1): 193 for u in (0, 1): 194 for i in (0, 1): 195 for w in (0, 1): 196 decode += decodePuiwCase(load, d, p, u, i, w, 197 size, sign) 198 decode += ''' 199 default: 200 return new Unknown(machInst); 201 } 202 ''' 203 return decode 204 205 subs = { 206 "ldrh" : decodePuiw(True, False, size=2), 207 "strh" : decodePuiw(False, False, size=2), 208 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 209 "ldrd" : decodePuiw(True, True), 210 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 211 "strd" : decodePuiw(False, True) 212 } 213 decode_block = decode % subs 214}}; 215 216def format ArmSyncMem() {{ 217 decode_block = ''' 218 { 219 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 220 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 221 const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 222 switch (PUBWL) { 223 case 0x10: 224 return new Swp(machInst, rt, rt2, rn); 225 case 0x14: 226 return new Swpb(machInst, rt, rt2, rn); 227 case 0x18: 228 return new WarnUnimplemented("strex", machInst); 229 case 0x19: 230 return new WarnUnimplemented("ldrex", machInst); 231 default: 232 return new Unknown(machInst); 233 } 234 } 235 ''' 236}}; 237 238def format Thumb32LdrStrDExTbh() {{ 239 decode_block = ''' 240 { 241 const uint32_t op1 = bits(machInst, 24, 23); 242 const uint32_t op2 = bits(machInst, 21, 20); 243 const uint32_t op3 = bits(machInst, 7, 4); 244 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 245 if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 246 if (op1 == 0) { 247 if (op2 == 0) { 248 return new WarnUnimplemented("strex", machInst); 249 } else { 250 return new WarnUnimplemented("ldrex", machInst); 251 } 252 } else { 253 if (op2 == 0) { 254 switch (op3) { 255 case 0x4: 256 return new WarnUnimplemented("strexb", machInst); 257 case 0x5: 258 return new WarnUnimplemented("strexh", machInst); 259 case 0x7: 260 return new WarnUnimplemented("strexd", machInst); 261 default: 262 return new Unknown(machInst); 263 } 264 } else { 265 switch (op3) { 266 case 0x0: 267 return new WarnUnimplemented("tbb", machInst); 268 case 0x1: 269 return new WarnUnimplemented("tbh", machInst); 270 case 0x4: 271 return new WarnUnimplemented("ldrexb", machInst); 272 case 0x5: 273 return new WarnUnimplemented("ldrexh", machInst); 274 case 0x7: 275 return new WarnUnimplemented("ldrexd", machInst); 276 default: 277 return new Unknown(machInst); 278 } 279 } 280 } 281 } else { 282 if (bits(op2, 0) == 0) { 283 return new WarnUnimplemented("strd", machInst); 284 } else { 285 return new WarnUnimplemented("ldrd", machInst); 286 } 287 } 288 } 289 ''' 290}}; 291 292def format Thumb32LoadWord() {{ 293 decode = ''' 294 { 295 uint32_t op1 = bits(machInst, 24, 23); 296 if (bits(op1, 1) == 0) { 297 uint32_t op2 = bits(machInst, 11, 6); 298 if (HTRN == 0xF) { 299 if (UP) { 300 return new %(literal_u)s(machInst, RT, INTREG_PC, 301 true, IMMED_11_0); 302 } else { 303 return new %(literal)s(machInst, RT, INTREG_PC, 304 false, IMMED_11_0); 305 } 306 } else if (op1 == 0x1) { 307 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 308 } else if (op2 == 0) { 309 return new %(register)s(machInst, RT, RN, UP, 310 bits(machInst, 5, 4), LSL, RM); 311 } else if ((op2 & 0x3c) == 0x38) { 312 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 313 } else if ((op2 & 0x3c) == 0x30 || //P 314 (op2 & 0x24) == 0x24) { //W 315 uint32_t puw = bits(machInst, 10, 8); 316 uint32_t imm = IMMED_7_0; 317 switch (puw) { 318 case 0: 319 case 2: 320 // If we're here, either P or W must have been set. 321 panic("Neither P or W set, but that " 322 "shouldn't be possible.\\n"); 323 case 1: 324 return new %(imm_w)s(machInst, RT, RN, false, imm); 325 case 3: 326 return new %(imm_uw)s(machInst, RT, RN, true, imm); 327 case 4: 328 return new %(imm_p)s(machInst, RT, RN, false, imm); 329 case 5: 330 return new %(imm_pw)s(machInst, RT, RN, false, imm); 331 case 6: 332 return new %(imm_pu)s(machInst, RT, RN, true, imm); 333 case 7: 334 return new %(imm_puw)s(machInst, RT, RN, true, imm); 335 } 336 } 337 } else { 338 return new Unknown(machInst); 339 } 340 } 341 ''' 342 classNames = { 343 "literal_u" : loadImmClassName(False, True, False), 344 "literal" : loadImmClassName(False, False, False), 345 "register" : loadRegClassName(False, True, False), 346 "ldrt" : loadImmClassName(False, True, False, user=True), 347 "imm_w" : loadImmClassName(True, False, True), 348 "imm_uw" : loadImmClassName(True, True, True), 349 "imm_p" : loadImmClassName(False, False, False), 350 "imm_pw" : loadImmClassName(False, False, True), 351 "imm_pu" : loadImmClassName(False, True, False), 352 "imm_puw" : loadImmClassName(False, True, True) 353 } 354 decode_block = decode % classNames 355}}; 356 357def format Thumb32StoreSingle() {{ 358 def buildPuwDecode(size): 359 puwDecode = ''' 360 { 361 uint32_t puw = bits(machInst, 10, 8); 362 uint32_t imm = IMMED_7_0; 363 switch (puw) { 364 case 0: 365 case 2: 366 // If we're here, either P or W must have been set. 367 panic("Neither P or W set, but that " 368 "shouldn't be possible.\\n"); 369 case 1: 370 return new %(imm_w)s(machInst, RT, RN, false, imm); 371 case 3: 372 return new %(imm_uw)s(machInst, RT, RN, true, imm); 373 case 4: 374 return new %(imm_p)s(machInst, RT, RN, false, imm); 375 case 5: 376 return new %(imm_pw)s(machInst, RT, RN, false, imm); 377 case 6: 378 return new %(imm_pu)s(machInst, RT, RN, true, imm); 379 case 7: 380 return new %(imm_puw)s(machInst, RT, RN, true, imm); 381 } 382 } 383 ''' 384 return puwDecode % { 385 "imm_w" : storeImmClassName(True, False, True, size=size), 386 "imm_uw" : storeImmClassName(True, True, True, size=size), 387 "imm_p" : storeImmClassName(False, False, False, size=size), 388 "imm_pw" : storeImmClassName(False, False, True, size=size), 389 "imm_pu" : storeImmClassName(False, True, False, size=size), 390 "imm_puw" : storeImmClassName(False, True, True, size=size) 391 } 392 decode = ''' 393 { 394 uint32_t op1 = bits(machInst, 23, 21); 395 uint32_t op2 = bits(machInst, 11, 6); 396 bool op2Puw = ((op2 & 0x24) == 0x24 || 397 (op2 & 0x3c) == 0x30); 398 if (op1 == 4) { 399 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 400 } else if (op1 == 0 && op2Puw) { 401 %(strb_puw)s; 402 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 403 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 404 } else if (op1 == 0 && op2 == 0) { 405 return new %(strb_reg)s(machInst, RT, RN, true, 406 bits(machInst, 5, 4), LSL, RM); 407 } else if (op1 == 5) { 408 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 409 } else if (op1 == 1 && op2Puw) { 410 %(strh_puw)s; 411 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 412 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 413 } else if (op1 == 1 && op2 == 0) { 414 return new %(strh_reg)s(machInst, RT, RN, true, 415 bits(machInst, 5, 4), LSL, RM); 416 } else if (op1 == 6) { 417 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 418 } else if (op1 == 2 && op2Puw) { 419 %(str_puw)s; 420 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 421 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 422 } else if (op1 == 2 && op2 == 0) { 423 return new %(str_reg)s(machInst, RT, RN, true, 424 bits(machInst, 5, 4), LSL, RM); 425 } else { 426 return new Unknown(machInst); 427 } 428 } 429 ''' 430 classNames = { 431 "strb_imm" : storeImmClassName(False, True, False, size=1), 432 "strb_puw" : buildPuwDecode(1), 433 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 434 "strb_reg" : storeRegClassName(False, True, False, size=1), 435 "strh_imm" : storeImmClassName(False, True, False, size=2), 436 "strh_puw" : buildPuwDecode(2), 437 "strht" : storeImmClassName(False, True, False, user=True, size=2), 438 "strh_reg" : storeRegClassName(False, True, False, size=2), 439 "str_imm" : storeImmClassName(False, True, False), 440 "str_puw" : buildPuwDecode(4), 441 "strt" : storeImmClassName(False, True, False, user=True), 442 "str_reg" : storeRegClassName(False, True, False) 443 } 444 decode_block = decode % classNames 445}}; 446 447def format Thumb16MemReg() {{ 448 decode = ''' 449 { 450 const uint32_t opb = bits(machInst, 11, 9); 451 const uint32_t rt = bits(machInst, 2, 0); 452 const uint32_t rn = bits(machInst, 5, 3); 453 const uint32_t rm = bits(machInst, 8, 6); 454 switch (opb) { 455 case 0x0: 456 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 457 case 0x1: 458 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 459 case 0x2: 460 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 461 case 0x3: 462 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 463 case 0x4: 464 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 465 case 0x5: 466 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 467 case 0x6: 468 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 469 case 0x7: 470 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 471 } 472 } 473 ''' 474 classNames = { 475 "str" : storeRegClassName(False, True, False), 476 "strh" : storeRegClassName(False, True, False, size=2), 477 "strb" : storeRegClassName(False, True, False, size=1), 478 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 479 "ldr" : loadRegClassName(False, True, False), 480 "ldrh" : loadRegClassName(False, True, False, size=2), 481 "ldrb" : loadRegClassName(False, True, False, size=1), 482 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 483 } 484 decode_block = decode % classNames 485}}; 486 487def format Thumb16MemImm() {{ 488 decode = ''' 489 { 490 const uint32_t opa = bits(machInst, 15, 12); 491 const uint32_t opb = bits(machInst, 11, 9); 492 const uint32_t lrt = bits(machInst, 2, 0); 493 const uint32_t lrn = bits(machInst, 5, 3); 494 const uint32_t hrt = bits(machInst, 10, 8); 495 const uint32_t imm5 = bits(machInst, 10, 6); 496 const uint32_t imm8 = bits(machInst, 7, 0); 497 const bool load = bits(opb, 2); 498 switch (opa) { 499 case 0x6: 500 if (load) { 501 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 502 } else { 503 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 504 } 505 case 0x7: 506 if (load) { 507 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 508 } else { 509 return new %(strb)s(machInst, lrt, lrn, true, imm5); 510 } 511 case 0x8: 512 if (load) { 513 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 514 } else { 515 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 516 } 517 case 0x9: 518 if (load) { 519 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 520 } else { 521 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 522 } 523 default: 524 return new Unknown(machInst); 525 } 526 } 527 ''' 528 classNames = { 529 "ldr" : loadImmClassName(False, True, False), 530 "str" : storeImmClassName(False, True, False), 531 "ldrh" : loadImmClassName(False, True, False, size=2), 532 "strh" : storeImmClassName(False, True, False, size=2), 533 "ldrb" : loadImmClassName(False, True, False, size=1), 534 "strb" : storeImmClassName(False, True, False, size=1), 535 } 536 decode_block = decode % classNames 537}}; 538 539def format Thumb16MemLit() {{ 540 decode_block = ''' 541 { 542 const uint32_t rt = bits(machInst, 10, 8); 543 const uint32_t imm8 = bits(machInst, 7, 0); 544 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 545 } 546 ''' % loadImmClassName(False, True, False) 547}}; 548 549