1// Copyright (c) 2010 ARM Limited 2// All rights reserved 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35// 36// Authors: Gabe Black 37 38def format ArmMultAndMultAcc() {{ 39 decode_block = ''' 40 { 41 // The manual defines this field as 23-20, but bit 20 is usually 42 // ignored. 43 const uint32_t op = bits(machInst, 23, 21); 44 const bool s = bits(machInst, 20); 45 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 46 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 47 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 48 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 49 switch (op) { 50 case 0x0: 51 if (s) { 52 return new MulCc(machInst, rd, rm, rn); 53 } else { 54 return new Mul(machInst, rd, rm, rn); 55 } 56 case 0x1: 57 if (s) { 58 return new MlaCc(machInst, rd, rn, rm, ra); 59 } else { 60 return new Mla(machInst, rd, rn, rm, ra); 61 } 62 case 0x2: 63 return new Umaal(machInst, ra, rd, rn, rm); 64 case 0x3: 65 return new Mls(machInst, rd, rn, rm, ra); 66 case 0x4: 67 if (s) { 68 return new UmullCc(machInst, ra, rd, rn, rm); 69 } else { 70 return new Umull(machInst, ra, rd, rn, rm); 71 } 72 case 0x5: 73 if (s) { 74 return new UmlalCc(machInst, ra, rd, rn, rm); 75 } else { 76 return new Umlal(machInst, ra, rd, rn, rm); 77 } 78 case 0x6: 79 if (s) { 80 return new SmullCc(machInst, ra, rd, rn, rm); 81 } else { 82 return new Smull(machInst, ra, rd, rn, rm); 83 } 84 case 0x7: 85 if (s) { 86 return new SmlalCc(machInst, ra, rd, rn, rm); 87 } else { 88 return new Smlal(machInst, ra, rd, rn, rm); 89 } 90 default: 91 M5_UNREACHABLE; 92 } 93 } 94 ''' 95}}; 96 97def format ArmHalfWordMultAndMultAcc() {{ 98 decode_block = ''' 99 { 100 const uint32_t op1 = bits(machInst, 22, 21); 101 const bool op = bits(machInst, 5); 102 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 103 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 104 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 105 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 106 switch (op1) { 107 case 0x0: 108 switch (bits(machInst, 6, 5)) { 109 case 0x0: 110 return new SmlabbCc(machInst, rd, rn, rm, ra); 111 case 0x1: 112 return new SmlatbCc(machInst, rd, rn, rm, ra); 113 case 0x2: 114 return new SmlabtCc(machInst, rd, rn, rm, ra); 115 case 0x3: 116 return new SmlattCc(machInst, rd, rn, rm, ra); 117 default: 118 M5_UNREACHABLE; 119 } 120 case 0x1: 121 if (op) { 122 if (bits(machInst, 6)) { 123 return new Smulwt(machInst, rd, rn, rm); 124 } else { 125 return new Smulwb(machInst, rd, rn, rm); 126 } 127 } else { 128 if (bits(machInst, 6)) { 129 return new SmlawtCc(machInst, rd, rn, rm, ra); 130 } else { 131 return new SmlawbCc(machInst, rd, rn, rm, ra); 132 } 133 } 134 case 0x2: 135 switch (bits(machInst, 6, 5)) { 136 case 0x0: 137 return new Smlalbb(machInst, ra, rd, rn, rm); 138 case 0x1: 139 return new Smlaltb(machInst, ra, rd, rn, rm); 140 case 0x2: 141 return new Smlalbt(machInst, ra, rd, rn, rm); 142 case 0x3: 143 return new Smlaltt(machInst, ra, rd, rn, rm); 144 default: 145 M5_UNREACHABLE; 146 } 147 case 0x3: 148 switch (bits(machInst, 6, 5)) { 149 case 0x0: 150 return new Smulbb(machInst, rd, rn, rm); 151 case 0x1: 152 return new Smultb(machInst, rd, rn, rm); 153 case 0x2: 154 return new Smulbt(machInst, rd, rn, rm); 155 case 0x3: 156 return new Smultt(machInst, rd, rn, rm); 157 default: 158 M5_UNREACHABLE; 159 } 160 default: 161 M5_UNREACHABLE; 162 } 163 } 164 ''' 165}}; 166 167def format Thumb32MulMulAccAndAbsDiff() {{ 168 decode_block = ''' 169 { 170 const uint32_t op1 = bits(machInst, 22, 20); 171 const uint32_t op2 = bits(machInst, 5, 4); 172 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 173 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 174 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 175 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 176 if (op1 != 0x1 && bits(op2, 1) != 0) { 177 return new Unknown(machInst); 178 } 179 switch (op1) { 180 case 0x0: 181 if (op2 == 0) { 182 if (ra == 0xf) { 183 return new Mul(machInst, rd, rn, rm); 184 } else { 185 return new Mla(machInst, rd, rn, rm, ra); 186 } 187 } else { 188 return new Mls(machInst, rd, rn, rm, ra); 189 } 190 case 0x1: 191 if (ra == 0xf) { 192 switch (bits(machInst, 5, 4)) { 193 case 0x0: 194 return new Smulbb(machInst, rd, rn, rm); 195 case 0x1: 196 return new Smulbt(machInst, rd, rn, rm); 197 case 0x2: 198 return new Smultb(machInst, rd, rn, rm); 199 case 0x3: 200 return new Smultt(machInst, rd, rn, rm); 201 } 202 } else { 203 switch (bits(machInst, 5, 4)) { 204 case 0x0: 205 return new SmlabbCc(machInst, rd, rn, rm, ra); 206 case 0x1: 207 return new SmlabtCc(machInst, rd, rn, rm, ra); 208 case 0x2: 209 return new SmlatbCc(machInst, rd, rn, rm, ra); 210 case 0x3: 211 return new SmlattCc(machInst, rd, rn, rm, ra); 212 } 213 } 214 M5_UNREACHABLE; 215 case 0x2: 216 if (ra == 0xf) { 217 if (bits(machInst, 4)) { 218 return new SmuadxCc(machInst, rd, rn, rm); 219 } else { 220 return new SmuadCc(machInst, rd, rn, rm); 221 } 222 } else { 223 if (bits(machInst, 4)) { 224 return new SmladxCc(machInst, rd, rn, rm, ra); 225 } else { 226 return new SmladCc(machInst, rd, rn, rm, ra); 227 } 228 } 229 case 0x3: 230 if (ra == 0xf) { 231 if (bits(machInst, 4)) { 232 return new Smulwt(machInst, rd, rn, rm); 233 } else { 234 return new Smulwb(machInst, rd, rn, rm); 235 } 236 } else { 237 if (bits(machInst, 4)) { 238 return new SmlawtCc(machInst, rd, rn, rm, ra); 239 } else { 240 return new SmlawbCc(machInst, rd, rn, rm, ra); 241 } 242 } 243 case 0x4: 244 if (ra == 0xf) { 245 if (bits(machInst, 4)) { 246 return new Smusdx(machInst, rd, rn, rm); 247 } else { 248 return new Smusd(machInst, rd, rn, rm); 249 } 250 } else { 251 if (bits(machInst, 4)) { 252 return new SmlsdxCc(machInst, rd, rn, rm, ra); 253 } else { 254 return new SmlsdCc(machInst, rd, rn, rm, ra); 255 } 256 } 257 case 0x5: 258 if (ra == 0xf) { 259 if (bits(machInst, 4)) { 260 return new Smmulr(machInst, rd, rn, rm); 261 } else { 262 return new Smmul(machInst, rd, rn, rm); 263 } 264 } else { 265 if (bits(machInst, 4)) { 266 return new Smmlar(machInst, rd, rn, rm, ra); 267 } else { 268 return new Smmla(machInst, rd, rn, rm, ra); 269 } 270 } 271 case 0x6: 272 if (bits(machInst, 4)) { 273 return new Smmlsr(machInst, rd, rn, rm, ra); 274 } else { 275 return new Smmls(machInst, rd, rn, rm, ra); 276 } 277 case 0x7: 278 if (op2 != 0x0) { 279 return new Unknown(machInst); 280 } else if (ra == 0xf) { 281 return new Usad8(machInst, rd, rn, rm); 282 } else { 283 return new Usada8(machInst, rd, rn, rm, ra); 284 } 285 default: 286 M5_UNREACHABLE; 287 } 288 } 289 ''' 290}}; 291 292def format Thumb32LongMulMulAccAndDiv() {{ 293 decode_block = ''' 294 { 295 const uint32_t op1 = bits(machInst, 22, 20); 296 const uint32_t op2 = bits(machInst, 7, 4); 297 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 298 const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 299 const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 300 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 301 switch (op1) { 302 case 0x0: 303 if (op2 == 0x0) { 304 return new Smull(machInst, rdlo, rdhi, rn, rm); 305 } 306 break; 307 case 0x1: 308 if (op2 == 0xf) { 309 return new Sdiv(machInst, rdhi, rn, rm); 310 } 311 break; 312 case 0x2: 313 if (op2 == 0x0) { 314 return new Umull(machInst, rdlo, rdhi, rn, rm); 315 } 316 break; 317 case 0x3: 318 if (op2 == 0xf) { 319 return new Udiv(machInst, rdhi, rn, rm); 320 } 321 break; 322 case 0x4: 323 if (op2 == 0) { 324 return new Smlal(machInst, rdlo, rdhi, rn, rm); 325 } else if (bits(op2, 3, 2) == 0x2) { 326 switch (bits(machInst, 5, 4)) { 327 case 0x0: 328 return new Smlalbb(machInst, rdlo, rdhi, rn, rm); 329 case 0x1: 330 return new Smlalbt(machInst, rdlo, rdhi, rn, rm); 331 case 0x2: 332 return new Smlaltb(machInst, rdlo, rdhi, rn, rm); 333 case 0x3: 334 return new Smlaltt(machInst, rdlo, rdhi, rn, rm); 335 } 336 } else if (bits(op2, 3, 1) == 0x6) { 337 if (bits(machInst, 4)) { 338 return new Smlaldx(machInst, rdlo, rdhi, rn, rm); 339 } else { 340 return new Smlald(machInst, rdlo, rdhi, rn, rm); 341 } 342 } 343 break; 344 case 0x5: 345 if (bits(op2, 3, 1) == 0x6) { 346 if (bits(machInst, 4)) { 347 return new Smlsldx(machInst, rdlo, rdhi, rn, rm); 348 } else { 349 return new Smlsld(machInst, rdlo, rdhi, rn, rm); 350 } 351 } 352 break; 353 case 0x6: 354 if (op2 == 0) { 355 return new Umlal(machInst, rdlo, rdhi, rn, rm); 356 } else if (op2 == 0x6) { 357 return new Umaal(machInst, rdlo, rdhi, rn, rm); 358 } 359 break; 360 } 361 return new Unknown(machInst); 362 } 363 ''' 364}}; 365 366def format ArmSignedMultiplies() {{ 367 decode_block = ''' 368 { 369 const uint32_t op1 = bits(machInst, 22, 20); 370 // This is 7-5 in the manual, but bit 5 is always ignored. 371 const uint32_t op2 = bits(machInst, 7, 6); 372 const bool aIsF = (bits(machInst, 15, 12) == 0xf); 373 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 374 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 375 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 376 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 377 const bool m = bits(machInst, 5); 378 switch (op1) { 379 case 0x0: 380 if (op2 == 0) { 381 if (aIsF) { 382 if (m) { 383 return new SmuadxCc(machInst, rd, rn, rm); 384 } else { 385 return new SmuadCc(machInst, rd, rn, rm); 386 } 387 } else { 388 if (m) { 389 return new SmladxCc(machInst, rd, rn, rm, ra); 390 } else { 391 return new SmladCc(machInst, rd, rn, rm, ra); 392 } 393 } 394 } else if (op2 == 1) { 395 if (aIsF) { 396 if (m) { 397 return new Smusdx(machInst, rd, rn, rm); 398 } else { 399 return new Smusd(machInst, rd, rn, rm); 400 } 401 } else { 402 if (m) { 403 return new SmlsdxCc(machInst, rd, rn, rm, ra); 404 } else { 405 return new SmlsdCc(machInst, rd, rn, rm, ra); 406 } 407 } 408 } 409 break; 410 case 0x1: 411 if (op2 == 0 && m == 0 && ra == 0xf) { 412 return new Sdiv(machInst, rd, rn, rm); 413 } 414 break; 415 case 0x3: 416 if (op2 == 0 && m == 0 && ra == 0xf) { 417 return new Udiv(machInst, rd, rn, rm); 418 } 419 break; 420 case 0x4: 421 if (op2 == 0) { 422 if (m) { 423 return new Smlaldx(machInst, ra, rd, rn, rm); 424 } else { 425 return new Smlald(machInst, ra, rd, rn, rm); 426 } 427 } else if (op2 == 1) { 428 if (m) { 429 return new Smlsldx(machInst, ra, rd, rn, rm); 430 } else { 431 return new Smlsld(machInst, ra, rd, rn, rm); 432 } 433 } 434 break; 435 case 0x5: 436 if (op2 == 0) { 437 if (aIsF) { 438 if (m) { 439 return new Smmulr(machInst, rd, rn, rm); 440 } else { 441 return new Smmul(machInst, rd, rn, rm); 442 } 443 } else { 444 if (m) { 445 return new Smmlar(machInst, rd, rn, rm, ra); 446 } else { 447 return new Smmla(machInst, rd, rn, rm, ra); 448 } 449 } 450 } else if (op2 == 0x3) { 451 if (m) { 452 return new Smmlsr(machInst, rd, rn, rm, ra); 453 } else { 454 return new Smmls(machInst, rd, rn, rm, ra); 455 } 456 } 457 break; 458 default: 459 break; 460 } 461 return new Unknown(machInst); 462 } 463 ''' 464}}; 465