arm.isa revision 6270
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 OPCODE { 362 format DataImmOp { 363 0x0: andi({{ uint32_t resTemp; 364 Rd = resTemp = Rn & rotated_imm; }}, 365 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 366 {{ Cpsr<28:> }}); 367 0x1: eori({{ uint32_t resTemp; 368 Rd = resTemp = Rn ^ rotated_imm; }}, 369 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 370 {{ Cpsr<28:> }}); 371 0x2: subi({{ uint32_t resTemp; 372 Rd = resTemp = Rn - rotated_imm; }}, 373 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 374 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 375 0x3: rsbi({{ uint32_t resTemp; 376 Rd = resTemp = rotated_imm - Rn; }}, 377 {{ arm_sub_carry(resTemp, rotated_imm, Rn) }}, 378 {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }}); 379 0x4: addi({{ uint32_t resTemp; 380 Rd = resTemp = Rn + rotated_imm; }}, 381 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 382 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 383 0x5: adci({{ uint32_t resTemp; 384 Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, 385 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 386 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 387 0x6: sbci({{ uint32_t resTemp; 388 Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, 389 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 390 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 391 0x7: rsci({{ uint32_t resTemp; 392 Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, 393 {{ arm_sub_carry(resTemp, rotated_imm, Rn) }}, 394 {{ arm_sub_overflow(resTemp, rotated_imm, Rn) }}); 395 0x8: tsti({{ uint32_t resTemp; 396 resTemp = Rn & rotated_imm; }}, 397 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 398 {{ Cpsr<28:> }}); 399 0x9: teqi({{ uint32_t resTemp; 400 resTemp = Rn ^ rotated_imm; }}, 401 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 402 {{ Cpsr<28:> }}); 403 0xa: cmpi({{ uint32_t resTemp; 404 resTemp = Rn - rotated_imm; }}, 405 {{ arm_sub_carry(resTemp, Rn, rotated_imm) }}, 406 {{ arm_sub_overflow(resTemp, Rn, rotated_imm) }}); 407 0xb: cmni({{ uint32_t resTemp; 408 resTemp = Rn + rotated_imm; }}, 409 {{ arm_add_carry(resTemp, Rn, rotated_imm) }}, 410 {{ arm_add_overflow(resTemp, Rn, rotated_imm) }}); 411 0xc: orri({{ uint32_t resTemp; 412 Rd = resTemp = Rn | rotated_imm; }}, 413 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 414 {{ Cpsr<28:> }}); 415 0xd: movi({{ uint32_t resTemp; 416 Rd = resTemp = rotated_imm; }}, 417 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 418 {{ Cpsr<28:> }}); 419 0xe: bici({{ uint32_t resTemp; 420 Rd = resTemp = Rn & ~rotated_imm; }}, 421 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 422 {{ Cpsr<28:> }}); 423 0xf: mvni({{ uint32_t resTemp; 424 Rd = resTemp = ~rotated_imm; }}, 425 {{ (rotate ? rotated_carry:Cpsr<29:>) }}, 426 {{ Cpsr<28:> }}); 427 } 428 } 429 1: decode OPCODE { 430 // The following two instructions aren't supposed to be defined 431 0x8: WarnUnimpl::undefined_instruction(); 432 0x9: WarnUnimpl::undefined_instruction(); 433 434 0xa: WarnUnimpl::mrs_i_cpsr(); 435 0xb: WarnUnimpl::mrs_i_spsr(); 436 } 437 } 438 0x2: decode PUBWL { 439 // CAREFUL: 440 // Can always do EA + disp, since we negate disp using the UP flag 441 // Post-indexed variants 442 0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd; 443 Rn = Rn + disp; }}, 444 {{ EA = Rn; }}); 445 0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; 446 Rd = Mem; }}, 447 {{ EA = Rn; }}); 448 0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub; 449 Rn = Rn + disp; }}, 450 {{ EA = Rn; }}); 451 0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; 452 Rd.ub = Mem.ub; }}, 453 {{ EA = Rn; }}); 454 // Pre-indexed variants 455 0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }}); 456 0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }}); 457 0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd; 458 Rn = Rn + disp; }}); 459 0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; 460 Rd = Mem; }}); 461 0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }}); 462 0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }}); 463 0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub; 464 Rn = Rn + disp; }}); 465 0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; 466 Rd.ub = Mem.ub; }}); 467 } 468 0x3: decode OPCODE_4 { 469 0: decode PUBWL { 470 0x00,0x08: ArmStoreMemory::strr_({{ 471 Mem = Rd; 472 Rn = Rn + Rm_Imm; }}, 473 {{ EA = Rn; }}); 474 0x01,0x09: ArmLoadMemory::ldrr_l({{ 475 Rd = Mem; 476 Rn = Rn + Rm_Imm; }}, 477 {{ EA = Rn; }}); 478 0x04,0x0c: ArmStoreMemory::strr_b({{ 479 Mem.ub = Rd.ub; 480 Rn = Rn + Rm_Imm; }}, 481 {{ EA = Rn; }}); 482 0x05,0x0d: ArmLoadMemory::ldrr_bl({{ 483 Rd.ub = Mem.ub; 484 Rn = Rn + Rm_Imm; }}, 485 {{ EA = Rn; }}); 486 0x10,0x18: ArmStoreMemory::strr_p({{ 487 Mem = Rd; }}, 488 {{ EA = Rn + Rm_Imm; }}); 489 0x11,0x19: ArmLoadMemory::ldrr_pl({{ 490 Rd = Mem; }}, 491 {{ EA = Rn + Rm_Imm; }}); 492 0x12,0x1a: ArmStoreMemory::strr_pw({{ 493 Mem = Rd; 494 Rn = Rn + Rm_Imm; }}, 495 {{ EA = Rn + Rm_Imm; }}); 496 0x13,0x1b: ArmLoadMemory::ldrr_pwl({{ 497 Rd = Mem; 498 Rn = Rn + Rm_Imm; }}, 499 {{ EA = Rn + Rm_Imm; }}); 500 0x14,0x1c: ArmStoreMemory::strr_pb({{ 501 Mem.ub = Rd.ub; }}, 502 {{ EA = Rn + Rm_Imm; }}); 503 0x15,0x1d: ArmLoadMemory::ldrr_pbl({{ 504 Rd.ub = Mem.ub; }}, 505 {{ EA = Rn + Rm_Imm; }}); 506 0x16,0x1e: ArmStoreMemory::strr_pbw({{ 507 Mem.ub = Rd.ub; 508 Rn = Rn + Rm_Imm; }}, 509 {{ EA = Rn + Rm_Imm; }}); 510 0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{ 511 Rd.ub = Mem.ub; 512 Rn = Rn + Rm_Imm; }}, 513 {{ EA = Rn + Rm_Imm; }}); 514 } 515 1: decode MEDIA_OPCODE { 516 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 517 0x8: decode MISC_OPCODE { 518 0x1, 0x9: WarnUnimpl::pkhbt(); 519 0x7: WarnUnimpl::sxtab16(); 520 0xb: WarnUnimpl::sel(); 521 0x5, 0xd: WarnUnimpl::pkhtb(); 522 0x3: WarnUnimpl::sign_zero_extend_add(); 523 } 524 0xa, 0xb: decode SHIFT { 525 0x0, 0x2: WarnUnimpl::ssat(); 526 0x1: WarnUnimpl::ssat16(); 527 } 528 0xe, 0xf: decode SHIFT { 529 0x0, 0x2: WarnUnimpl::usat(); 530 0x1: WarnUnimpl::usat16(); 531 } 532 0x10: decode RN { 533 0xf: decode MISC_OPCODE { 534 0x1: WarnUnimpl::smuad(); 535 0x3: WarnUnimpl::smuadx(); 536 0x5: WarnUnimpl::smusd(); 537 0x7: WarnUnimpl::smusdx(); 538 } 539 default: decode MISC_OPCODE { 540 0x1: WarnUnimpl::smlad(); 541 0x3: WarnUnimpl::smladx(); 542 0x5: WarnUnimpl::smlsd(); 543 0x7: WarnUnimpl::smlsdx(); 544 } 545 } 546 0x14: decode MISC_OPCODE { 547 0x1: WarnUnimpl::smlald(); 548 0x3: WarnUnimpl::smlaldx(); 549 0x5: WarnUnimpl::smlsld(); 550 0x7: WarnUnimpl::smlsldx(); 551 } 552 0x15: decode RN { 553 0xf: decode MISC_OPCODE { 554 0x1: WarnUnimpl::smmul(); 555 0x3: WarnUnimpl::smmulr(); 556 } 557 default: decode MISC_OPCODE { 558 0x1: WarnUnimpl::smmla(); 559 0x3: WarnUnimpl::smmlar(); 560 0xd: WarnUnimpl::smmls(); 561 0xf: WarnUnimpl::smmlsr(); 562 } 563 } 564 0x18: decode RN { 565 0xf: WarnUnimpl::usada8(); 566 default: WarnUnimpl::usad8(); 567 } 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