mult.isa revision 7161:a1e9b36bd4bf
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 NewMulCc(machInst, rd, rm, rn); 53 } else { 54 return new NewMul(machInst, rd, rm, rn); 55 } 56 case 0x1: 57 if (s) { 58 return new NewMlaCc(machInst, rd, rn, rm, ra); 59 } else { 60 return new NewMla(machInst, rd, rn, rm, ra); 61 } 62 case 0x2: 63 return new NewUmaal(machInst, ra, rd, rn, rm); 64 case 0x3: 65 return new NewMls(machInst, rd, rn, rm, ra); 66 case 0x4: 67 if (s) { 68 return new NewUmullCc(machInst, ra, rd, rn, rm); 69 } else { 70 return new NewUmull(machInst, ra, rd, rn, rm); 71 } 72 case 0x5: 73 if (s) { 74 return new NewUmlalCc(machInst, ra, rd, rn, rm); 75 } else { 76 return new NewUmlal(machInst, ra, rd, rn, rm); 77 } 78 case 0x6: 79 if (s) { 80 return new NewSmullCc(machInst, ra, rd, rn, rm); 81 } else { 82 return new NewSmull(machInst, ra, rd, rn, rm); 83 } 84 case 0x7: 85 if (s) { 86 return new NewSmlalCc(machInst, ra, rd, rn, rm); 87 } else { 88 return new NewSmlal(machInst, ra, rd, rn, rm); 89 } 90 } 91 } 92 ''' 93}}; 94 95def format ArmHalfWordMultAndMultAcc() {{ 96 decode_block = ''' 97 { 98 const uint32_t op1 = bits(machInst, 22, 21); 99 const bool op = bits(machInst, 5); 100 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 101 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 102 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 103 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 104 switch (op1) { 105 case 0x0: 106 switch (bits(machInst, 6, 5)) { 107 case 0x0: 108 return new NewSmlabbCc(machInst, rd, rn, rm, ra); 109 case 0x1: 110 return new NewSmlatbCc(machInst, rd, rn, rm, ra); 111 case 0x2: 112 return new NewSmlabtCc(machInst, rd, rn, rm, ra); 113 case 0x3: 114 return new NewSmlattCc(machInst, rd, rn, rm, ra); 115 } 116 case 0x1: 117 if (op) { 118 if (bits(machInst, 6)) { 119 return new NewSmulwt(machInst, rd, rn, rm); 120 } else { 121 return new NewSmulwb(machInst, rd, rn, rm); 122 } 123 } else { 124 if (bits(machInst, 6)) { 125 return new NewSmlawtCc(machInst, rd, rn, rm, ra); 126 } else { 127 return new NewSmlawbCc(machInst, rd, rn, rm, ra); 128 } 129 } 130 case 0x2: 131 switch (bits(machInst, 6, 5)) { 132 case 0x0: 133 return new NewSmlalbb(machInst, ra, rd, rn, rm); 134 case 0x1: 135 return new NewSmlaltb(machInst, ra, rd, rn, rm); 136 case 0x2: 137 return new NewSmlalbt(machInst, ra, rd, rn, rm); 138 case 0x3: 139 return new NewSmlaltt(machInst, ra, rd, rn, rm); 140 } 141 case 0x3: 142 switch (bits(machInst, 6, 5)) { 143 case 0x0: 144 return new NewSmulbb(machInst, rd, rn, rm); 145 case 0x1: 146 return new NewSmultb(machInst, rd, rn, rm); 147 case 0x2: 148 return new NewSmulbt(machInst, rd, rn, rm); 149 case 0x3: 150 return new NewSmultt(machInst, rd, rn, rm); 151 } 152 } 153 } 154 ''' 155}}; 156 157def format Thumb32MulMulAccAndAbsDiff() {{ 158 decode_block = ''' 159 { 160 const uint32_t op1 = bits(machInst, 22, 20); 161 const uint32_t op2 = bits(machInst, 5, 4); 162 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 163 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 164 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 165 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 166 if (op1 != 0x1 && bits(op2, 1) != 0) { 167 return new Unknown(machInst); 168 } 169 switch (op1) { 170 case 0x0: 171 if (op2 == 0) { 172 if (ra == 0xf) { 173 return new NewMul(machInst, rd, rn, rm); 174 } else { 175 return new NewMla(machInst, rd, rn, rm, ra); 176 } 177 } else { 178 return new NewMls(machInst, rd, rn, rm, ra); 179 } 180 case 0x1: 181 if (ra == 0xf) { 182 switch (bits(machInst, 5, 4)) { 183 case 0x0: 184 return new NewSmulbb(machInst, rd, rn, rm); 185 case 0x1: 186 return new NewSmulbt(machInst, rd, rn, rm); 187 case 0x2: 188 return new NewSmultb(machInst, rd, rn, rm); 189 case 0x3: 190 return new NewSmultt(machInst, rd, rn, rm); 191 } 192 } else { 193 switch (bits(machInst, 5, 4)) { 194 case 0x0: 195 return new NewSmlabbCc(machInst, rd, rn, rm, ra); 196 case 0x1: 197 return new NewSmlabtCc(machInst, rd, rn, rm, ra); 198 case 0x2: 199 return new NewSmlatbCc(machInst, rd, rn, rm, ra); 200 case 0x3: 201 return new NewSmlattCc(machInst, rd, rn, rm, ra); 202 } 203 } 204 case 0x2: 205 if (ra == 0xf) { 206 if (bits(machInst, 4)) { 207 return new NewSmuadxCc(machInst, rd, rn, rm); 208 } else { 209 return new NewSmuadCc(machInst, rd, rn, rm); 210 } 211 } else { 212 if (bits(machInst, 4)) { 213 return new NewSmladxCc(machInst, rd, rn, rm, ra); 214 } else { 215 return new NewSmladCc(machInst, rd, rn, rm, ra); 216 } 217 } 218 case 0x3: 219 if (ra == 0xf) { 220 if (bits(machInst, 4)) { 221 return new NewSmulwt(machInst, rd, rn, rm); 222 } else { 223 return new NewSmulwb(machInst, rd, rn, rm); 224 } 225 } else { 226 if (bits(machInst, 4)) { 227 return new NewSmlawtCc(machInst, rd, rn, rm, ra); 228 } else { 229 return new NewSmlawbCc(machInst, rd, rn, rm, ra); 230 } 231 } 232 case 0x4: 233 if (ra == 0xf) { 234 if (bits(machInst, 4)) { 235 return new NewSmusdx(machInst, rd, rn, rm); 236 } else { 237 return new NewSmusd(machInst, rd, rn, rm); 238 } 239 } else { 240 if (bits(machInst, 4)) { 241 return new NewSmlsdxCc(machInst, rd, rn, rm, ra); 242 } else { 243 return new NewSmlsdCc(machInst, rd, rn, rm, ra); 244 } 245 } 246 case 0x5: 247 if (ra == 0xf) { 248 if (bits(machInst, 4)) { 249 return new NewSmmulr(machInst, rd, rn, rm); 250 } else { 251 return new NewSmmul(machInst, rd, rn, rm); 252 } 253 } else { 254 if (bits(machInst, 4)) { 255 return new NewSmmlar(machInst, rd, rn, rm, ra); 256 } else { 257 return new NewSmmla(machInst, rd, rn, rm, ra); 258 } 259 } 260 case 0x6: 261 if (bits(machInst, 4)) { 262 return new NewSmmlsr(machInst, rd, rn, rm, ra); 263 } else { 264 return new NewSmmls(machInst, rd, rn, rm, ra); 265 } 266 case 0x7: 267 if (op2 != 0x0) { 268 return new Unknown(machInst); 269 } else if (ra == 0xf) { 270 return new WarnUnimplemented("usada8", machInst); 271 } else { 272 return new WarnUnimplemented("usad8", machInst); 273 } 274 } 275 } 276 ''' 277}}; 278 279def format Thumb32LongMulMulAccAndDiv() {{ 280 decode_block = ''' 281 { 282 const uint32_t op1 = bits(machInst, 22, 20); 283 const uint32_t op2 = bits(machInst, 7, 4); 284 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 285 const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 286 const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 287 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 288 switch (op1) { 289 case 0x0: 290 if (op2 == 0x0) { 291 return new NewSmull(machInst, rdlo, rdhi, rn, rm); 292 } 293 break; 294 case 0x1: 295 if (op2 == 0xf) { 296 return new WarnUnimplemented("sdiv", machInst); 297 } 298 break; 299 case 0x2: 300 if (op2 == 0x0) { 301 return new NewUmull(machInst, rdlo, rdhi, rn, rm); 302 } 303 break; 304 case 0x3: 305 if (op2 == 0xf) { 306 return new WarnUnimplemented("udiv", machInst); 307 } 308 break; 309 case 0x4: 310 if (op2 == 0) { 311 return new NewSmlal(machInst, rdlo, rdhi, rn, rm); 312 } else if (bits(op2, 3, 2) == 0x2) { 313 switch (bits(machInst, 5, 4)) { 314 case 0x0: 315 return new NewSmlalbb(machInst, rdlo, rdhi, rn, rm); 316 case 0x1: 317 return new NewSmlalbt(machInst, rdlo, rdhi, rn, rm); 318 case 0x2: 319 return new NewSmlaltb(machInst, rdlo, rdhi, rn, rm); 320 case 0x3: 321 return new NewSmlaltt(machInst, rdlo, rdhi, rn, rm); 322 } 323 } else if (bits(op2, 3, 1) == 0x6) { 324 if (bits(machInst, 4)) { 325 return new NewSmlaldx(machInst, rdlo, rdhi, rn, rm); 326 } else { 327 return new NewSmlald(machInst, rdlo, rdhi, rn, rm); 328 } 329 } 330 break; 331 case 0x5: 332 if (bits(op2, 3, 1) == 0x6) { 333 if (bits(machInst, 4)) { 334 return new NewSmlsldx(machInst, rdlo, rdhi, rn, rm); 335 } else { 336 return new NewSmlsld(machInst, rdlo, rdhi, rn, rm); 337 } 338 } 339 case 0x6: 340 if (op2 == 0) { 341 return new NewUmlal(machInst, rdlo, rdhi, rn, rm); 342 } else if (op2 == 0x6) { 343 return new NewUmaal(machInst, rdlo, rdhi, rn, rm); 344 } 345 break; 346 } 347 return new Unknown(machInst); 348 } 349 ''' 350}}; 351 352def format ArmSignedMultiplies() {{ 353 decode_block = ''' 354 { 355 const uint32_t op1 = bits(machInst, 22, 20); 356 // This is 7-5 in the manual, but bit 5 is always ignored. 357 const uint32_t op2 = bits(machInst, 7, 6); 358 const bool aIsF = (bits(machInst, 15, 12) == 0xf); 359 const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 360 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 361 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 362 const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 363 const bool m = bits(machInst, 5); 364 switch (op1) { 365 case 0x0: 366 if (op2 == 0) { 367 if (aIsF) { 368 if (m) { 369 return new NewSmuadxCc(machInst, rd, rn, rm); 370 } else { 371 return new NewSmuadCc(machInst, rd, rn, rm); 372 } 373 } else { 374 if (m) { 375 return new NewSmladxCc(machInst, rd, rn, rm, ra); 376 } else { 377 return new NewSmladCc(machInst, rd, rn, rm, ra); 378 } 379 } 380 } else if (op2 == 1) { 381 if (aIsF) { 382 if (m) { 383 return new NewSmusdx(machInst, rd, rn, rm); 384 } else { 385 return new NewSmusd(machInst, rd, rn, rm); 386 } 387 } else { 388 if (m) { 389 return new NewSmlsdxCc(machInst, rd, rn, rm, ra); 390 } else { 391 return new NewSmlsdCc(machInst, rd, rn, rm, ra); 392 } 393 } 394 } 395 break; 396 case 0x4: 397 if (op2 == 0) { 398 if (m) { 399 return new NewSmlaldx(machInst, ra, rd, rn, rm); 400 } else { 401 return new NewSmlald(machInst, ra, rd, rn, rm); 402 } 403 } else if (op2 == 1) { 404 if (m) { 405 return new NewSmlsldx(machInst, ra, rd, rn, rm); 406 } else { 407 return new NewSmlsld(machInst, ra, rd, rn, rm); 408 } 409 } 410 break; 411 case 0x5: 412 if (op2 == 0) { 413 if (aIsF) { 414 if (m) { 415 return new NewSmmulr(machInst, rd, rn, rm); 416 } else { 417 return new NewSmmul(machInst, rd, rn, rm); 418 } 419 } else { 420 if (m) { 421 return new NewSmmlar(machInst, rd, rn, rm, ra); 422 } else { 423 return new NewSmmla(machInst, rd, rn, rm, ra); 424 } 425 } 426 } else if (op2 == 0x3) { 427 if (m) { 428 return new NewSmmlsr(machInst, rd, rn, rm, ra); 429 } else { 430 return new NewSmmls(machInst, rd, rn, rm, ra); 431 } 432 } 433 break; 434 default: 435 break; 436 } 437 return new Unknown(machInst); 438 } 439 ''' 440}}; 441