thumb.isa revision 6268
1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// The actual ARM ISA decoder 34// -------------------------- 35// The following instructions are specified in the ARM ISA 36// Specification. Decoding closely follows the style specified 37// in the ARM ISA specification document starting with Table B.1 or 3-1 38// 39// 40decode COND_CODE default Unknown::unknown() { 41 0xf: decode COND_CODE { 42 0x0: decode OPCODE { 43 // Just a simple trick to allow us to specify our new uops here 44 0x0: PredImmOp::addi_uop({{ Raddr = Rn + rotated_imm; }}, 45 'IsMicroop'); 46 0x1: PredImmOp::subi_uop({{ Raddr = Rn - rotated_imm; }}, 47 'IsMicroop'); 48 0x2: ArmLoadMemory::ldr_uop({{ Rd = Mem; }}, 49 {{ EA = Raddr + disp; }}, 50 inst_flags = [IsMicroop]); 51 0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }}, 52 {{ EA = Raddr + disp; }}, 53 inst_flags = [IsMicroop]); 54 0x4: PredImmOp::addi_rd_uop({{ Rd = Rn + rotated_imm; }}, 55 'IsMicroop'); 56 0x5: PredImmOp::subi_rd_uop({{ Rd = Rn - rotated_imm; }}, 57 'IsMicroop'); 58 } 59 0x1: decode OPCODE { 60 0x0: PredIntOp::mvtd_uop({{ Fd.ud = ((uint64_t) Rhi << 32)|Rlo; }}, 61 'IsMicroop'); 62 0x1: PredIntOp::mvfd_uop({{ Rhi = (Fd.ud >> 32) & 0xffffffff; 63 Rlo = Fd.ud & 0xffffffff; }}, 64 'IsMicroop'); 65 0x2: ArmLoadMemory::ldhi_uop({{ Rhi = Mem; }}, 66 {{ EA = Rn + disp; }}, 67 inst_flags = [IsMicroop]); 68 0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }}, 69 {{ EA = Rn + disp; }}, 70 inst_flags = [IsMicroop]); 71 0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }}, 72 {{ EA = Rn + disp; }}, 73 inst_flags = [IsMicroop]); 74 0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }}, 75 {{ EA = Rn + disp; }}, 76 inst_flags = [IsMicroop]); 77 } 78 default: Unknown::unknown(); // TODO: Ignore other NV space for now 79 } 80default: decode ENCODING { 81format DataOp { 82 0x0: decode SEVEN_AND_FOUR { 83 1: decode MISC_OPCODE { 84 0x9: decode PREPOST { 85 0: decode OPCODE { 86 0x0: mul({{ uint32_t resTemp; 87 Rn = resTemp = Rm * Rs; }}, 88 {{ Cpsr<29:> }}, 89 {{ Cpsr<28:> }}); 90 0x1: mla({{ uint32_t resTemp; 91 Rn = resTemp = Rm * Rs; }}, 92 {{ Cpsr<29:> }}, 93 {{ Cpsr<28:> }}); 94 0x2: WarnUnimpl::umall(); 95 0x4: umull({{ 96 uint64_t resTemp; 97 resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 98 Rd = (uint32_t)(resTemp & 0xffffffff); 99 Rn = (uint32_t)(resTemp >> 32); 100 }}, {{ 1 }}, {{ 1 }}); 101 0x5: WarnUnimpl::smlal(); 102 0x6: smull({{ 103 int64_t resTemp; 104 resTemp = ((int64_t)Rm.sw)*((int64_t)Rs.sw); 105 Rd = (int32_t)(resTemp & 0xffffffff); 106 Rn = (int32_t)(resTemp >> 32); 107 }}, {{ 1 }}, {{ 1 }}); 108 0x7: umlal({{ 109 uint64_t resTemp; 110 resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 111 resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); 112 Rd = (uint32_t)(resTemp & 0xffffffff); 113 Rn = (uint32_t)(resTemp >> 32); 114 }}, {{ 1 }}, {{ 1 }}); 115 } 116 1: decode PUBWL { 117 0x10: WarnUnimpl::swp(); 118 0x14: WarnUnimpl::swpb(); 119 0x18: WarnUnimpl::strex(); 120 0x19: WarnUnimpl::ldrex(); 121 } 122 } 123 0xb: decode PUBWL { 124 format ArmStoreMemory { 125 0x0, 0x8: strh_({{ Mem.uh = Rd.uh; 126 Rn = Rn + Rm; }}, 127 {{ EA = Rn; }}); 128 0x4, 0xc: strh_il({{ Mem.uh = Rd.uh; 129 Rn = Rn + hilo; }}, 130 {{ EA = Rn; }}); 131 0x10, 0x18: strh_p({{ Mem.uh = Rd.uh; }}, 132 {{ EA = Rn + Rm; }}); 133 0x12, 0x1a: strh_pw({{ Mem.uh = Rd.uh; 134 Rn = Rn + Rm; }}, 135 {{ EA = Rn + Rm; }}); 136 0x14, 0x1c: strh_pil({{ Mem.uh = Rd.uh; }}, 137 {{ EA = Rn + hilo; }}); 138 0x16, 0x1e: strh_piwl({{ Mem.uh = Rd.uh; 139 Rn = Rn + hilo; }}, 140 {{ EA = Rn + hilo; }}); 141 } 142 format ArmLoadMemory { 143 0x1, 0x9: ldrh_l({{ Rd.uh = Mem.uh; 144 Rn = Rn + Rm; }}, 145 {{ EA = Rn; }}); 146 0x5, 0xd: ldrh_il({{ Rd.uh = Mem.uh; 147 Rn = Rn + hilo; }}, 148 {{ EA = Rn; }}); 149 0x11, 0x19: ldrh_pl({{ Rd.uh = Mem.uh; }}, 150 {{ EA = Rn + Rm; }}); 151 0x13, 0x1b: ldrh_pwl({{ Rd.uh = Mem.uh; 152 Rn = Rn + Rm; }}, 153 {{ EA = Rn + Rm; }}); 154 0x15, 0x1d: ldrh_pil({{ Rd.uh = Mem.uh; }}, 155 {{ EA = Rn + hilo; }}); 156 0x17, 0x1f: ldrh_piwl({{ Rd.uh = Mem.uh; 157 Rn = Rn + hilo; }}, 158 {{ EA = Rn + hilo; }}); 159 } 160 } 161 format ArmLoadMemory { 162 0xd: decode PUBWL { 163 0x1: ldrsb_l({{ Rd = Mem.sb; 164 Rn = Rn + Rm; }}, 165 {{ EA = Rn; }}); 166 0x5: ldrsb_il({{ Rd = Mem.sb; 167 Rn = Rn + hilo; }}, 168 {{ EA = Rn; }}); 169 0x9: ldrsb_ul({{ Rd = Mem.sb; 170 Rn = Rn - Rm; }}, 171 {{ EA = Rn; }}); 172 0xd: ldrsb_uil({{ Rd = Mem.sb; 173 Rn = Rn - hilo; }}, 174 {{ EA = Rn; }}); 175 0x11: ldrsb_pl({{ Rd = Mem.sb; }}, 176 {{ EA = Rn + Rm; }}); 177 0x13: ldrsb_pwl({{ Rd = Mem.sb; 178 Rn = Rn + Rm; }}, 179 {{ EA = Rn + Rm; }}); 180 0x15: ldrsb_pil({{ Rd = Mem.sb; }}, 181 {{ EA = Rn + hilo; }}); 182 0x17: ldrsb_piwl({{ Rd = Mem.sb; 183 Rn = Rn + hilo; }}, 184 {{ EA = Rn + hilo; }}); 185 0x19: ldrsb_pul({{ Rd = Mem.sb; }}, 186 {{ EA = Rn - Rm; }}); 187 0x1b: ldrsb_puwl({{ Rd = Mem.sb; 188 Rn = Rn - Rm; }}, 189 {{ EA = Rn - Rm; }}); 190 0x1d: ldrsb_puil({{ Rd = Mem.sb; }}, 191 {{ EA = Rn - hilo; }}); 192 0x1f: ldrsb_puiwl({{ Rd = Mem.sb; 193 Rn = Rn - hilo; }}, 194 {{ EA = Rn - hilo; }}); 195 } 196 0xf: decode PUBWL { 197 0x1: ldrsh_l({{ Rd = Mem.sh; 198 Rn = Rn + Rm; }}, 199 {{ EA = Rn; }}); 200 0x5: ldrsh_il({{ Rd = Mem.sh; 201 Rn = Rn + hilo; }}, 202 {{ EA = Rn; }}); 203 0x9: ldrsh_ul({{ Rd = Mem.sh; 204 Rn = Rn - Rm; }}, 205 {{ EA = Rn; }}); 206 0xd: ldrsh_uil({{ Rd = Mem.sh; 207 Rn = Rn - hilo; }}, 208 {{ EA = Rn; }}); 209 0x11: ldrsh_pl({{ Rd = Mem.sh; }}, 210 {{ EA = Rn + Rm; }}); 211 0x13: ldrsh_pwl({{ Rd = Mem.sh; 212 Rn = Rn + Rm; }}, 213 {{ EA = Rn + Rm; }}); 214 0x15: ldrsh_pil({{ Rd = Mem.sh; }}, 215 {{ EA = Rn + hilo; }}); 216 0x17: ldrsh_piwl({{ Rd = Mem.sh; 217 Rn = Rn + hilo; }}, 218 {{ EA = Rn + hilo; }}); 219 0x19: ldrsh_pul({{ Rd = Mem.sh; }}, 220 {{ EA = Rn - Rm; }}); 221 0x1b: ldrsh_puwl({{ Rd = Mem.sh; 222 Rn = Rn - Rm; }}, 223 {{ EA = Rn - Rm; }}); 224 0x1d: ldrsh_puil({{ Rd = Mem.sh; }}, 225 {{ EA = Rn - hilo; }}); 226 0x1f: ldrsh_puiwl({{ Rd = Mem.sh; 227 Rn = Rn - hilo; }}, 228 {{ EA = Rn - hilo; }}); 229 } 230 } 231 } 232 0: decode IS_MISC { 233 0: decode OPCODE { 234 0x0: and({{ uint32_t resTemp; 235 Rd = resTemp = Rn & op2; }}, 236 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 237 {{ Cpsr<28:> }}); 238 0x1: eor({{ uint32_t resTemp; 239 Rd = resTemp = Rn ^ op2; }}, 240 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 241 {{ Cpsr<28:> }}); 242 0x2: sub({{ uint32_t resTemp, val2 = op2; 243 Rd = resTemp = Rn - val2; }}, 244 {{ arm_sub_carry(resTemp, Rn, val2) }}, 245 {{ arm_sub_overflow(resTemp, Rn, val2) }}); 246 0x3: rsb({{ uint32_t resTemp, val2 = op2; 247 Rd = resTemp = val2 - Rn; }}, 248 {{ arm_sub_carry(resTemp, val2, Rn) }}, 249 {{ arm_sub_overflow(resTemp, val2, Rn) }}); 250 0x4: add({{ uint32_t resTemp, val2 = op2; 251 Rd = resTemp = Rn + val2; }}, 252 {{ arm_add_carry(resTemp, Rn, val2) }}, 253 {{ arm_add_overflow(resTemp, Rn, val2) }}); 254 0x5: adc({{ uint32_t resTemp, val2 = op2; 255 Rd = resTemp = Rn + val2 + Cpsr<29:>; }}, 256 {{ arm_add_carry(resTemp, Rn, val2) }}, 257 {{ arm_add_overflow(resTemp, Rn, val2) }}); 258 0x6: sbc({{ uint32_t resTemp, val2 = op2; 259 Rd = resTemp = Rn - val2 - !Cpsr<29:>; }}, 260 {{ arm_sub_carry(resTemp, Rn, val2) }}, 261 {{ arm_sub_overflow(resTemp, Rn, val2) }}); 262 0x7: rsc({{ uint32_t resTemp, val2 = op2; 263 Rd = resTemp = val2 - Rn - !Cpsr<29:>; }}, 264 {{ arm_sub_carry(resTemp, val2, Rn) }}, 265 {{ arm_sub_overflow(resTemp, val2, Rn) }}); 266 0x8: tst({{ uint32_t resTemp = Rn & op2; }}, 267 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 268 {{ Cpsr<28:> }}); 269 0x9: teq({{ uint32_t resTemp = Rn ^ op2; }}, 270 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 271 {{ Cpsr<28:> }}); 272 0xa: cmp({{ uint32_t resTemp, val2 = op2; 273 resTemp = Rn - val2; }}, 274 {{ arm_sub_carry(resTemp, Rn, val2) }}, 275 {{ arm_sub_overflow(resTemp, Rn, val2) }}); 276 0xb: cmn({{ uint32_t resTemp, val2 = op2; 277 resTemp = Rn + val2; }}, 278 {{ arm_add_carry(resTemp, Rn, val2) }}, 279 {{ arm_add_overflow(resTemp, Rn, val2) }}); 280 0xc: orr({{ uint32_t resTemp, val2 = op2; 281 Rd = resTemp = Rn | val2; }}, 282 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 283 {{ Cpsr<28:> }}); 284 0xd: mov({{ uint32_t resTemp; 285 Rd = resTemp = op2; }}, 286 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 287 {{ Cpsr<28:> }}); 288 0xe: bic({{ uint32_t resTemp; 289 Rd = resTemp = Rn & ~op2; }}, 290 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 291 {{ Cpsr<28:> }}); 292 0xf: mvn({{ uint32_t resTemp; 293 Rd = resTemp = ~op2; }}, 294 {{ shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>) }}, 295 {{ Cpsr<28:> }}); 296 } 297 1: decode MISC_OPCODE { 298 0x0: decode OPCODE { 299 0x8: WarnUnimpl::mrs_cpsr(); 300 0x9: WarnUnimpl::msr_cpsr(); 301 0xa: WarnUnimpl::mrs_spsr(); 302 0xb: WarnUnimpl::msr_spsr(); 303 } 304 0x1: decode OPCODE { 305 0x9: BranchExchange::bx({{ }}); 306 0xb: PredOp::clz({{ 307 if (Rm == 0) 308 Rd = 32; 309 else 310 { 311 int i; 312 for (i = 0; i < 32; i++) 313 { 314 if (Rm & (1<<(31-i))) 315 break; 316 } 317 Rd = i; 318 } 319 }}); 320 } 321 0x2: decode OPCODE { 322 0x9: WarnUnimpl::bxj(); 323 } 324 0x3: decode OPCODE { 325 0x9: BranchExchange::blx({{ }}, Link); 326 } 327 0x5: decode OPCODE { 328 0x8: WarnUnimpl::qadd(); 329 0x9: WarnUnimpl::qsub(); 330 0xa: WarnUnimpl::qdadd(); 331 0xb: WarnUnimpl::qdsub(); 332 } 333 0x8: decode OPCODE { 334 0x8: WarnUnimpl::smlabb(); 335 0x9: WarnUnimpl::smlalbb(); 336 0xa: WarnUnimpl::smlawb(); 337 0xb: WarnUnimpl::smulbb(); 338 } 339 0xa: decode OPCODE { 340 0x8: WarnUnimpl::smlatb(); 341 0x9: WarnUnimpl::smulwb(); 342 0xa: WarnUnimpl::smlaltb(); 343 0xb: WarnUnimpl::smultb(); 344 } 345 0xc: decode OPCODE { 346 0x8: WarnUnimpl::smlabt(); 347 0x9: WarnUnimpl::smlawt(); 348 0xa: WarnUnimpl::smlalbt(); 349 0xb: WarnUnimpl::smulbt(); 350 } 351 0xe: decode OPCODE { 352 0x8: WarnUnimpl::smlatt(); 353 0x9: WarnUnimpl::smulwt(); 354 0xa: WarnUnimpl::smlaltt(); 355 0xb: WarnUnimpl::smultt(); 356 } 357 } 358 } 359 } 360 0x1: decode IS_MISC { 361 0: decode S_FIELD { 362 0: decode OPCODE { 363 format PredImmOp { 364 0x0: andi({{ Rd = Rn & rotated_imm; }}); 365 0x1: eori({{ Rd = Rn ^ rotated_imm; }}); 366 0x2: subi({{ Rd = Rn - rotated_imm; }}); 367 0x3: rsbi({{ Rd = rotated_imm - Rn; }}); 368 0x4: addi({{ Rd = Rn + rotated_imm; }}); 369 0x5: adci({{ Rd = Rn + rotated_imm + Cpsr<29:>; }}); 370 0x6: sbci({{ Rd = Rn - rotated_imm + Cpsr<29:> - 1; }}); 371 0x7: rsci({{ Rd = rotated_imm - Rn + Cpsr<29:> - 1; }}); 372 0xc: orri({{ Rd = Rn | rotated_imm; }}); 373 0xd: decode RN { 374 0: movi({{ Rd = rotated_imm; }}); 375 } 376 0xe: bici({{ Rd = Rn & ~rotated_imm; }}); 377 0xf: decode RN { 378 0: mvni({{ Rd = ~rotated_imm; }}); 379 } 380 } 381 } 382 1: decode OPCODE { 383 format PredImmOpCc { 384 0x0: andsi({{ 385 uint32_t resTemp; 386 Rd = resTemp = Rn & rotated_imm; 387 }}, 388 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 389 {{ Cpsr<28:> }}); 390 0x1: eorsi({{ 391 uint32_t resTemp; 392 Rd = resTemp = Rn ^ rotated_imm; 393 }}, 394 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 395 {{ Cpsr<28:> }}); 396 0x2: subsi({{ 397 uint32_t resTemp; 398 Rd = resTemp = Rn - rotated_imm; 399 }}, 400 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 401 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 402 0x3: rsbsi({{ 403 uint32_t resTemp; 404 Rd = resTemp = rotated_imm - Rn; 405 }}, 406 {{ arm_sub_carry(resTemp, rotated_imm, Rn) }}, 407 {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }}); 408 0x4: addsi({{ 409 uint32_t resTemp; 410 Rd = resTemp = Rn + rotated_imm; 411 }}, 412 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 413 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 414 0x5: adcsi({{ 415 uint32_t resTemp; 416 Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; 417 }}, 418 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 419 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 420 0x6: sbcsi({{ 421 uint32_t resTemp; 422 Rd = resTemp = Rn -rotated_imm + Cpsr<29:> - 1; 423 }}, 424 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 425 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 426 0x7: rscsi({{ 427 uint32_t resTemp; 428 Rd = resTemp = rotated_imm - Rn + Cpsr<29:> - 1; 429 }}, 430 {{ arm_sub_carry(resTemp, rotated_imm, Rn) }}, 431 {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }}); 432 0x8: tsti({{ 433 uint32_t resTemp; 434 resTemp = Rn & rotated_imm; 435 }}, 436 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 437 {{ Cpsr<28:> }}); 438 0x9: teqi({{ 439 uint32_t resTemp; 440 resTemp = Rn ^ rotated_imm; 441 }}, 442 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 443 {{ Cpsr<28:> }}); 444 0xa: cmpi({{ 445 uint32_t resTemp; 446 resTemp = Rn - rotated_imm; 447 }}, 448 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 449 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 450 0xb: cmni({{ 451 uint32_t resTemp; 452 resTemp = Rn + rotated_imm; 453 }}, 454 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 455 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 456 0xc: orrsi({{ 457 uint32_t resTemp; 458 Rd = resTemp = Rn | rotated_imm; 459 }}, 460 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 461 {{ Cpsr<28:> }}); 462 0xd: movsi({{ 463 uint32_t resTemp; 464 Rd = resTemp = rotated_imm; 465 }}, 466 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 467 {{ Cpsr<28:> }}); 468 0xe: bicsi({{ 469 uint32_t resTemp; 470 Rd = resTemp = Rn & ~rotated_imm; 471 }}, 472 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 473 {{ Cpsr<28:> }}); 474 0xf: mvnsi({{ 475 uint32_t resTemp; 476 Rd = resTemp = ~rotated_imm; 477 }}, 478 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 479 {{ Cpsr<28:> }}); 480 } 481 } 482 } 483 1: decode OPCODE { 484 // The following two instructions aren't supposed to be defined 485 0x8: WarnUnimpl::undefined_instruction(); 486 0x9: WarnUnimpl::undefined_instruction(); 487 488 0xa: WarnUnimpl::mrs_i_cpsr(); 489 0xb: WarnUnimpl::mrs_i_spsr(); 490 } 491 } 492 0x2: decode PUBWL { 493 // CAREFUL: 494 // Can always do EA + disp, since we negate disp using the UP flag 495 // Post-indexed variants 496 0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd; 497 Rn = Rn + disp; }}, 498 {{ EA = Rn; }}); 499 0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; 500 Rd = Mem; }}, 501 {{ EA = Rn; }}); 502 0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub; 503 Rn = Rn + disp; }}, 504 {{ EA = Rn; }}); 505 0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; 506 Rd.ub = Mem.ub; }}, 507 {{ EA = Rn; }}); 508 // Pre-indexed variants 509 0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }}); 510 0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }}); 511 0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd; 512 Rn = Rn + disp; }}); 513 0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; 514 Rd = Mem; }}); 515 0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }}); 516 0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }}); 517 0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub; 518 Rn = Rn + disp; }}); 519 0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; 520 Rd.ub = Mem.ub; }}); 521 } 522 0x3: decode OPCODE_4 { 523 0: decode PUBWL { 524 0x00,0x08: ArmStoreMemory::strr_({{ 525 Mem = Rd; 526 Rn = Rn + Rm_Imm; }}, 527 {{ EA = Rn; }}); 528 0x01,0x09: ArmLoadMemory::ldrr_l({{ 529 Rd = Mem; 530 Rn = Rn + Rm_Imm; }}, 531 {{ EA = Rn; }}); 532 0x04,0x0c: ArmStoreMemory::strr_b({{ 533 Mem.ub = Rd.ub; 534 Rn = Rn + Rm_Imm; }}, 535 {{ EA = Rn; }}); 536 0x05,0x0d: ArmLoadMemory::ldrr_bl({{ 537 Rd.ub = Mem.ub; 538 Rn = Rn + Rm_Imm; }}, 539 {{ EA = Rn; }}); 540 0x10,0x18: ArmStoreMemory::strr_p({{ 541 Mem = Rd; }}, 542 {{ EA = Rn + Rm_Imm; }}); 543 0x11,0x19: ArmLoadMemory::ldrr_pl({{ 544 Rd = Mem; }}, 545 {{ EA = Rn + Rm_Imm; }}); 546 0x12,0x1a: ArmStoreMemory::strr_pw({{ 547 Mem = Rd; 548 Rn = Rn + Rm_Imm; }}, 549 {{ EA = Rn + Rm_Imm; }}); 550 0x13,0x1b: ArmLoadMemory::ldrr_pwl({{ 551 Rd = Mem; 552 Rn = Rn + Rm_Imm; }}, 553 {{ EA = Rn + Rm_Imm; }}); 554 0x14,0x1c: ArmStoreMemory::strr_pb({{ 555 Mem.ub = Rd.ub; }}, 556 {{ EA = Rn + Rm_Imm; }}); 557 0x15,0x1d: ArmLoadMemory::ldrr_pbl({{ 558 Rd.ub = Mem.ub; }}, 559 {{ EA = Rn + Rm_Imm; }}); 560 0x16,0x1e: ArmStoreMemory::strr_pbw({{ 561 Mem.ub = Rd.ub; 562 Rn = Rn + Rm_Imm; }}, 563 {{ EA = Rn + Rm_Imm; }}); 564 0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{ 565 Rd.ub = Mem.ub; 566 Rn = Rn + Rm_Imm; }}, 567 {{ EA = Rn + Rm_Imm; }}); 568 } 569 } 570 0x4: decode PUSWL { 571 // Right now we only handle cases when S (PSRUSER) is not set 572 default: ArmMacroStore::ldmstm({{ }}); 573 } 574 0x5: decode OPCODE_24 { 575 // Branch (and Link) Instructions 576 0: Branch::b({{ }}); 577 1: Branch::bl({{ }}, Link); 578 } 579 0x6: decode CPNUM { 580 0x1: decode PUNWL { 581 0x02,0x0a: decode OPCODE_15 { 582 0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf; 583 Rn = Rn + disp8; }}, 584 {{ EA = Rn; }}); 585 1: ArmMacroFPAOp::stfd_({{ }}); 586 } 587 0x03,0x0b: decode OPCODE_15 { 588 0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf; 589 Rn = Rn + disp8; }}, 590 {{ EA = Rn; }}); 591 1: ArmMacroFPAOp::ldfd_({{ }}); 592 } 593 0x06,0x0e: decode OPCODE_15 { 594 0: ArmMacroFPAOp::stfe_nw({{ }}); 595 } 596 0x07,0x0f: decode OPCODE_15 { 597 0: ArmMacroFPAOp::ldfe_nw({{ }}); 598 } 599 0x10,0x18: decode OPCODE_15 { 600 0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }}, 601 {{ EA = Rn + disp8; }}); 602 1: ArmMacroFPAOp::stfd_p({{ }}); 603 } 604 0x11,0x19: decode OPCODE_15 { 605 0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }}, 606 {{ EA = Rn + disp8; }}); 607 1: ArmMacroFPAOp::ldfd_p({{ }}); 608 } 609 0x12,0x1a: decode OPCODE_15 { 610 0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf; 611 Rn = Rn + disp8; }}, 612 {{ EA = Rn + disp8; }}); 613 1: ArmMacroFPAOp::stfd_pw({{ }}); 614 } 615 0x13,0x1b: decode OPCODE_15 { 616 0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf; 617 Rn = Rn + disp8; }}, 618 {{ EA = Rn + disp8; }}); 619 1: ArmMacroFPAOp::ldfd_pw({{ }}); 620 } 621 0x14,0x1c: decode OPCODE_15 { 622 0: ArmMacroFPAOp::stfe_pn({{ }}); 623 } 624 0x15,0x1d: decode OPCODE_15 { 625 0: ArmMacroFPAOp::ldfe_pn({{ }}); 626 } 627 0x16,0x1e: decode OPCODE_15 { 628 0: ArmMacroFPAOp::stfe_pnw({{ }}); 629 } 630 0x17,0x1f: decode OPCODE_15 { 631 0: ArmMacroFPAOp::ldfe_pnw({{ }}); 632 } 633 } 634 0x2: decode PUNWL { 635 // could really just decode as a single instruction 636 0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }}); 637 0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }}); 638 0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }}); 639 0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }}); 640 0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }}); 641 0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }}); 642 0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }}); 643 0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }}); 644 } 645 } 646 0x7: decode OPCODE_24 { 647 0: decode CPNUM { 648 // Coprocessor Instructions 649 0x1: decode OPCODE_4 { 650 format FloatOp { 651 // Basic FPA Instructions 652 0: decode OPCODE_23_20 { 653 0x0: decode OPCODE_15 { 654 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); 655 1: mvf({{ Fd.sf = Fm.sf; }}); 656 } 657 0x1: decode OPCODE_15 { 658 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); 659 1: mnf({{ Fd.sf = -Fm.sf; }}); 660 } 661 0x2: decode OPCODE_15 { 662 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); 663 1: abs({{ Fd.sf = fabs(Fm.sf); }}); 664 } 665 0x3: decode OPCODE_15 { 666 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); 667 1: rnd({{ Fd.sf = rint(Fm.sf); }}); 668 } 669 0x4: decode OPCODE_15 { 670 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); 671 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); 672 } 673 0x5: decode OPCODE_15 { 674 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); 675 1: log({{ Fd.sf = log10(Fm.sf); }}); 676 } 677 0x6: decode OPCODE_15 { 678 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); 679 1: lgn({{ Fd.sf = log(Fm.sf); }}); 680 } 681 0x7: decode OPCODE_15 { 682 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); 683 1: exp({{ Fd.sf = exp(Fm.sf); }}); 684 } 685 0x8: decode OPCODE_15 { 686 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); 687 1: sin({{ Fd.sf = sin(Fm.sf); }}); 688 } 689 0x9: decode OPCODE_15 { 690 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); 691 1: cos({{ Fd.sf = cos(Fm.sf); }}); 692 } 693 0xa: decode OPCODE_15 { 694 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); 695 1: tan({{ Fd.sf = tan(Fm.sf); }}); 696 } 697 0xb: decode OPCODE_15 { 698 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); 699 1: asn({{ Fd.sf = asin(Fm.sf); }}); 700 } 701 0xc: decode OPCODE_15 { 702 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); 703 1: acs({{ Fd.sf = acos(Fm.sf); }}); 704 } 705 0xd: decode OPCODE_15 { 706 1: atn({{ Fd.sf = atan(Fm.sf); }}); 707 } 708 0xe: decode OPCODE_15 { 709 // Unnormalised Round 710 1: FailUnimpl::urd(); 711 } 712 0xf: decode OPCODE_15 { 713 // Normalise 714 1: FailUnimpl::nrm(); 715 } 716 } 717 1: decode OPCODE_15_12 { 718 0xf: decode OPCODE_23_21 { 719 format FloatCmp { 720 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); 721 0x5: cnf({{ Fn.df }}, {{ -Fm.df }}); 722 0x6: cmfe({{ Fn.df }}, {{ Fm.df}}); 723 0x7: cnfe({{ Fn.df }}, {{ -Fm.df}}); 724 } 725 } 726 default: decode OPCODE_23_20 { 727 0x0: decode OPCODE_7 { 728 0: flts({{ Fn.sf = (float) Rd.sw; }}); 729 1: fltd({{ Fn.df = (double) Rd.sw; }}); 730 } 731 0x1: decode OPCODE_7 { 732 0: fixs({{ Rd = (uint32_t) Fm.sf; }}); 733 1: fixd({{ Rd = (uint32_t) Fm.df; }}); 734 } 735 0x2: wfs({{ Fpsr = Rd; }}); 736 0x3: rfs({{ Rd = Fpsr; }}); 737 0x4: FailUnimpl::wfc(); 738 0x5: FailUnimpl::rfc(); 739 } 740 } 741 } 742 } 743 } 744 format PredOp { 745 // ARM System Call (SoftWare Interrupt) 746 1: swi({{ if (testPredicate(Cpsr, condCode)) 747 { 748 xc->syscall(IMMED_23_0); 749 } 750 }}); 751 } 752 } 753} 754} 755} 756 757