mem.isa revision 7129:0eb03024678f
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// Stephen Hines 43 44//////////////////////////////////////////////////////////////////// 45// 46// Memory-format instructions 47// 48 49def template LoadStoreDeclare {{ 50 /** 51 * Static instruction class for "%(mnemonic)s". 52 */ 53 class %(class_name)s : public %(base_class)s 54 { 55 public: 56 57 /// Constructor. 58 %(class_name)s(ExtMachInst machInst); 59 60 %(BasicExecDeclare)s 61 62 %(InitiateAccDeclare)s 63 64 %(CompleteAccDeclare)s 65 }; 66}}; 67 68 69def template InitiateAccDeclare {{ 70 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 71}}; 72 73 74def template CompleteAccDeclare {{ 75 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 76}}; 77 78 79def template LoadStoreConstructor {{ 80 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 81 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 82 { 83 %(constructor)s; 84 } 85}}; 86 87def format AddrMode2(imm) {{ 88 if eval(imm): 89 imm = True 90 else: 91 imm = False 92 93 def buildPUBWLCase(p, u, b, w, l): 94 return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 95 96 header_output = decoder_output = exec_output = "" 97 decode_block = "switch(PUBWL) {\n" 98 99 # Loop over all the values of p, u, b, w and l and build instructions and 100 # a decode block for them. 101 for p in (0, 1): 102 for u in (0, 1): 103 for b in (0, 1): 104 for w in (0, 1): 105 post = (p == 0) 106 user = (p == 0 and w == 1) 107 writeback = (p == 0 or w == 1) 108 add = (u == 1) 109 if b == 0: 110 size = 4 111 else: 112 size = 1 113 if add: 114 addStr = "true" 115 else: 116 addStr = "false" 117 if imm: 118 newDecode = "return new %s(machInst, RD, RN," + \ 119 "%s, machInst.immed11_0);" 120 loadClass = loadImmClassName(post, add, writeback, 121 size, False, user) 122 storeClass = storeImmClassName(post, add, writeback, 123 size, False, user) 124 loadDecode = newDecode % (loadClass, addStr) 125 storeDecode = newDecode % (storeClass, addStr) 126 else: 127 newDecode = "return new %s(machInst, RD, RN, %s," + \ 128 "machInst.shiftSize," + \ 129 "machInst.shift, RM);" 130 loadClass = loadRegClassName(post, add, writeback, 131 size, False, user) 132 storeClass = storeRegClassName(post, add, writeback, 133 size, False, user) 134 loadDecode = newDecode % (loadClass, addStr) 135 storeDecode = newDecode % (storeClass, addStr) 136 decode = ''' 137 case %#x: 138 {%s} 139 break; 140 ''' 141 decode_block += decode % \ 142 (buildPUBWLCase(p,u,b,w,1), loadDecode) 143 decode_block += decode % \ 144 (buildPUBWLCase(p,u,b,w,0), storeDecode) 145 decode_block += ''' 146 default: 147 return new Unknown(machInst); 148 break; 149 }''' 150}}; 151 152def format AddrMode3() {{ 153 decode = ''' 154 { 155 const uint32_t op1 = bits(machInst, 24, 20); 156 const uint32_t op2 = bits(machInst, 6, 5); 157 const uint32_t puiw = bits(machInst, 24, 21); 158 const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0; 159 switch (op2) { 160 case 0x1: 161 if (op1 & 0x1) { 162 %(ldrh)s 163 } else { 164 %(strh)s 165 } 166 case 0x2: 167 if (op1 & 0x1) { 168 %(ldrsb)s 169 } else { 170 %(ldrd)s 171 } 172 case 0x3: 173 if (op1 & 0x1) { 174 %(ldrsh)s 175 } else { 176 %(strd)s 177 } 178 default: 179 return new Unknown(machInst); 180 } 181 } 182 ''' 183 184 def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False): 185 post = (p == 0) 186 user = (p == 0 and w == 1) 187 writeback = (p == 0 or w == 1) 188 add = (u == 1) 189 caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0) 190 decode = ''' 191 case %#x: 192 return new '''% caseVal 193 if add: 194 addStr = "true" 195 else: 196 addStr = "false" 197 if i: 198 if load: 199 if d: 200 className = loadDoubleImmClassName(post, add, writeback) 201 else: 202 className = loadImmClassName(post, add, writeback, \ 203 size=size, sign=sign, \ 204 user=user) 205 else: 206 if d: 207 className = storeDoubleImmClassName(post, add, writeback) 208 else: 209 className = storeImmClassName(post, add, writeback, \ 210 size=size, sign=sign, \ 211 user=user) 212 decode += ("%s(machInst, RT, RN, %s, imm);\n" % \ 213 (className, addStr)) 214 else: 215 if load: 216 if d: 217 className = loadDoubleRegClassName(post, add, writeback) 218 else: 219 className = loadRegClassName(post, add, writeback, \ 220 size=size, sign=sign, \ 221 user=user) 222 else: 223 if d: 224 className = storeDoubleRegClassName(post, add, writeback) 225 else: 226 className = storeRegClassName(post, add, writeback, \ 227 size=size, sign=sign, \ 228 user=user) 229 decode += ("%s(machInst, RT, RN, %s, 0, LSL, RM);\n" % \ 230 (className, addStr)) 231 return decode 232 233 def decodePuiw(load, d, size=4, sign=False): 234 global decodePuiwCase 235 decode = "switch (puiw) {\n" 236 for p in (0, 1): 237 for u in (0, 1): 238 for i in (0, 1): 239 for w in (0, 1): 240 decode += decodePuiwCase(load, d, p, u, i, w, 241 size, sign) 242 decode += ''' 243 default: 244 return new Unknown(machInst); 245 } 246 ''' 247 return decode 248 249 subs = { 250 "ldrh" : decodePuiw(True, False, size=2), 251 "strh" : decodePuiw(False, False, size=2), 252 "ldrsb" : decodePuiw(True, False, size=1, sign=True), 253 "ldrd" : decodePuiw(True, True), 254 "ldrsh" : decodePuiw(True, False, size=2, sign=True), 255 "strd" : decodePuiw(False, True) 256 } 257 decode_block = decode % subs 258}}; 259 260def format Thumb32LoadWord() {{ 261 decode = ''' 262 { 263 uint32_t op1 = bits(machInst, 24, 23); 264 if (bits(op1, 1) == 0) { 265 uint32_t op2 = bits(machInst, 11, 6); 266 if (HTRN == 0xF) { 267 if (UP) { 268 return new %(literal_u)s(machInst, RT, INTREG_PC, 269 true, IMMED_11_0); 270 } else { 271 return new %(literal)s(machInst, RT, INTREG_PC, 272 false, IMMED_11_0); 273 } 274 } else if (op1 == 0x1) { 275 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 276 } else if (op2 == 0) { 277 return new %(register)s(machInst, RT, RN, UP, 278 bits(machInst, 5, 4), LSL, RM); 279 } else if ((op2 & 0x3c) == 0x38) { 280 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 281 } else if ((op2 & 0x3c) == 0x30 || //P 282 (op2 & 0x24) == 0x24) { //W 283 uint32_t puw = bits(machInst, 10, 8); 284 uint32_t imm = IMMED_7_0; 285 switch (puw) { 286 case 0: 287 case 2: 288 // If we're here, either P or W must have been set. 289 panic("Neither P or W set, but that " 290 "shouldn't be possible.\\n"); 291 case 1: 292 return new %(imm_w)s(machInst, RT, RN, false, imm); 293 case 3: 294 return new %(imm_uw)s(machInst, RT, RN, true, imm); 295 case 4: 296 return new %(imm_p)s(machInst, RT, RN, false, imm); 297 case 5: 298 return new %(imm_pw)s(machInst, RT, RN, false, imm); 299 case 6: 300 return new %(imm_pu)s(machInst, RT, RN, true, imm); 301 case 7: 302 return new %(imm_puw)s(machInst, RT, RN, true, imm); 303 } 304 } 305 } else { 306 return new Unknown(machInst); 307 } 308 } 309 ''' 310 classNames = { 311 "literal_u" : loadImmClassName(False, True, False), 312 "literal" : loadImmClassName(False, False, False), 313 "register" : loadRegClassName(False, True, False), 314 "ldrt" : loadImmClassName(False, True, False, user=True), 315 "imm_w" : loadImmClassName(True, False, True), 316 "imm_uw" : loadImmClassName(True, True, True), 317 "imm_p" : loadImmClassName(False, False, False), 318 "imm_pw" : loadImmClassName(False, False, True), 319 "imm_pu" : loadImmClassName(False, True, False), 320 "imm_puw" : loadImmClassName(False, True, True) 321 } 322 decode_block = decode % classNames 323}}; 324 325def format Thumb32StoreSingle() {{ 326 def buildPuwDecode(size): 327 puwDecode = ''' 328 { 329 uint32_t puw = bits(machInst, 10, 8); 330 uint32_t imm = IMMED_7_0; 331 switch (puw) { 332 case 0: 333 case 2: 334 // If we're here, either P or W must have been set. 335 panic("Neither P or W set, but that " 336 "shouldn't be possible.\\n"); 337 case 1: 338 return new %(imm_w)s(machInst, RT, RN, false, imm); 339 case 3: 340 return new %(imm_uw)s(machInst, RT, RN, true, imm); 341 case 4: 342 return new %(imm_p)s(machInst, RT, RN, false, imm); 343 case 5: 344 return new %(imm_pw)s(machInst, RT, RN, false, imm); 345 case 6: 346 return new %(imm_pu)s(machInst, RT, RN, true, imm); 347 case 7: 348 return new %(imm_puw)s(machInst, RT, RN, true, imm); 349 } 350 } 351 ''' 352 return puwDecode % { 353 "imm_w" : storeImmClassName(True, False, True, size=size), 354 "imm_uw" : storeImmClassName(True, True, True, size=size), 355 "imm_p" : storeImmClassName(False, False, False, size=size), 356 "imm_pw" : storeImmClassName(False, False, True, size=size), 357 "imm_pu" : storeImmClassName(False, True, False, size=size), 358 "imm_puw" : storeImmClassName(False, True, True, size=size) 359 } 360 decode = ''' 361 { 362 uint32_t op1 = bits(machInst, 23, 21); 363 uint32_t op2 = bits(machInst, 11, 6); 364 bool op2Puw = ((op2 & 0x24) == 0x24 || 365 (op2 & 0x3c) == 0x30); 366 if (op1 == 4) { 367 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 368 } else if (op1 == 0 && op2Puw) { 369 %(strb_puw)s; 370 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 371 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 372 } else if (op1 == 0 && op2 == 0) { 373 return new %(strb_reg)s(machInst, RT, RN, true, 374 bits(machInst, 5, 4), LSL, RM); 375 } else if (op1 == 5) { 376 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 377 } else if (op1 == 1 && op2Puw) { 378 %(strh_puw)s; 379 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 380 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 381 } else if (op1 == 1 && op2 == 0) { 382 return new %(strh_reg)s(machInst, RT, RN, true, 383 bits(machInst, 5, 4), LSL, RM); 384 } else if (op1 == 6) { 385 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 386 } else if (op1 == 2 && op2Puw) { 387 %(str_puw)s; 388 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 389 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 390 } else if (op1 == 2 && op2 == 0) { 391 return new %(str_reg)s(machInst, RT, RN, true, 392 bits(machInst, 5, 4), LSL, RM); 393 } else { 394 return new Unknown(machInst); 395 } 396 } 397 ''' 398 classNames = { 399 "strb_imm" : storeImmClassName(False, True, False, size=1), 400 "strb_puw" : buildPuwDecode(1), 401 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 402 "strb_reg" : storeRegClassName(False, True, False, size=1), 403 "strh_imm" : storeImmClassName(False, True, False, size=2), 404 "strh_puw" : buildPuwDecode(2), 405 "strht" : storeImmClassName(False, True, False, user=True, size=2), 406 "strh_reg" : storeRegClassName(False, True, False, size=2), 407 "str_imm" : storeImmClassName(False, True, False), 408 "str_puw" : buildPuwDecode(4), 409 "strt" : storeImmClassName(False, True, False, user=True), 410 "str_reg" : storeRegClassName(False, True, False) 411 } 412 decode_block = decode % classNames 413}}; 414 415def format Thumb16MemReg() {{ 416 decode = ''' 417 { 418 const uint32_t opb = bits(machInst, 11, 9); 419 const uint32_t rt = bits(machInst, 2, 0); 420 const uint32_t rn = bits(machInst, 5, 3); 421 const uint32_t rm = bits(machInst, 8, 6); 422 switch (opb) { 423 case 0x0: 424 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 425 case 0x1: 426 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 427 case 0x2: 428 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 429 case 0x3: 430 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 431 case 0x4: 432 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 433 case 0x5: 434 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 435 case 0x6: 436 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 437 case 0x7: 438 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 439 } 440 } 441 ''' 442 classNames = { 443 "str" : storeRegClassName(False, True, False), 444 "strh" : storeRegClassName(False, True, False, size=2), 445 "strb" : storeRegClassName(False, True, False, size=1), 446 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 447 "ldr" : loadRegClassName(False, True, False), 448 "ldrh" : loadRegClassName(False, True, False, size=2), 449 "ldrb" : loadRegClassName(False, True, False, size=1), 450 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 451 } 452 decode_block = decode % classNames 453}}; 454 455def format Thumb16MemImm() {{ 456 decode = ''' 457 { 458 const uint32_t opa = bits(machInst, 15, 12); 459 const uint32_t opb = bits(machInst, 11, 9); 460 const uint32_t lrt = bits(machInst, 2, 0); 461 const uint32_t lrn = bits(machInst, 5, 3); 462 const uint32_t hrt = bits(machInst, 10, 8); 463 const uint32_t imm5 = bits(machInst, 10, 6); 464 const uint32_t imm8 = bits(machInst, 7, 0); 465 const bool load = bits(opb, 2); 466 switch (opa) { 467 case 0x6: 468 if (load) { 469 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 470 } else { 471 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 472 } 473 case 0x7: 474 if (load) { 475 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 476 } else { 477 return new %(strb)s(machInst, lrt, lrn, true, imm5); 478 } 479 case 0x8: 480 if (load) { 481 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 482 } else { 483 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 484 } 485 case 0x9: 486 if (load) { 487 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 488 } else { 489 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 490 } 491 default: 492 return new Unknown(machInst); 493 } 494 } 495 ''' 496 classNames = { 497 "ldr" : loadImmClassName(False, True, False), 498 "str" : storeImmClassName(False, True, False), 499 "ldrh" : loadImmClassName(False, True, False, size=2), 500 "strh" : storeImmClassName(False, True, False, size=2), 501 "ldrb" : loadImmClassName(False, True, False, size=1), 502 "strb" : storeImmClassName(False, True, False, size=1), 503 } 504 decode_block = decode % classNames 505}}; 506 507def format Thumb16MemLit() {{ 508 decode_block = ''' 509 { 510 const uint32_t rt = bits(machInst, 10, 8); 511 const uint32_t imm8 = bits(machInst, 7, 0); 512 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 513 } 514 ''' % loadImmClassName(False, True, False) 515}}; 516 517def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 518 mem_flags = [], inst_flags = []) {{ 519 ea_code = ArmGenericCodeSubs(ea_code) 520 memacc_code = ArmGenericCodeSubs(memacc_code) 521 (header_output, decoder_output, decode_block, exec_output) = \ 522 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 523 decode_template = BasicDecode, 524 exec_template_base = 'Load') 525}}; 526 527def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 528 mem_flags = [], inst_flags = []) {{ 529 ea_code = ArmGenericCodeSubs(ea_code) 530 memacc_code = ArmGenericCodeSubs(memacc_code) 531 (header_output, decoder_output, decode_block, exec_output) = \ 532 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 533 exec_template_base = 'Store') 534}}; 535 536