arm.isa revision 6280
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({{ Rn = resTemp = Rm * Rs; }}, none); 87 0x1: mla({{ Rn = resTemp = (Rm * Rs) + Rd; }}, none); 88 0x2: WarnUnimpl::umall(); 89 0x4: umull({{ 90 resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 91 Rd = (uint32_t)(resTemp & 0xffffffff); 92 Rn = (uint32_t)(resTemp >> 32); 93 }}); 94 0x5: WarnUnimpl::smlal(); 95 0x6: smull({{ 96 resTemp = ((int64_t)(int32_t)Rm)* 97 ((int64_t)(int32_t)Rs); 98 Rd = (int32_t)(resTemp & 0xffffffff); 99 Rn = (int32_t)(resTemp >> 32); 100 }}); 101 0x7: umlal({{ 102 resTemp = ((uint64_t)Rm)*((uint64_t)Rs); 103 resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); 104 Rd = (uint32_t)(resTemp & 0xffffffff); 105 Rn = (uint32_t)(resTemp >> 32); 106 }}); 107 } 108 1: decode PUBWL { 109 0x10: WarnUnimpl::swp(); 110 0x14: WarnUnimpl::swpb(); 111 0x18: WarnUnimpl::strex(); 112 0x19: WarnUnimpl::ldrex(); 113 } 114 } 115 0xb: decode PUBWL { 116 format ArmStoreMemory { 117 0x0, 0x8: strh_({{ Mem.uh = Rd.uh; 118 Rn = Rn + Rm; }}, 119 {{ EA = Rn; }}); 120 0x4, 0xc: strh_il({{ Mem.uh = Rd.uh; 121 Rn = Rn + hilo; }}, 122 {{ EA = Rn; }}); 123 0x10, 0x18: strh_p({{ Mem.uh = Rd.uh; }}, 124 {{ EA = Rn + Rm; }}); 125 0x12, 0x1a: strh_pw({{ Mem.uh = Rd.uh; 126 Rn = Rn + Rm; }}, 127 {{ EA = Rn + Rm; }}); 128 0x14, 0x1c: strh_pil({{ Mem.uh = Rd.uh; }}, 129 {{ EA = Rn + hilo; }}); 130 0x16, 0x1e: strh_piwl({{ Mem.uh = Rd.uh; 131 Rn = Rn + hilo; }}, 132 {{ EA = Rn + hilo; }}); 133 } 134 format ArmLoadMemory { 135 0x1, 0x9: ldrh_l({{ Rd.uh = Mem.uh; 136 Rn = Rn + Rm; }}, 137 {{ EA = Rn; }}); 138 0x5, 0xd: ldrh_il({{ Rd.uh = Mem.uh; 139 Rn = Rn + hilo; }}, 140 {{ EA = Rn; }}); 141 0x11, 0x19: ldrh_pl({{ Rd.uh = Mem.uh; }}, 142 {{ EA = Rn + Rm; }}); 143 0x13, 0x1b: ldrh_pwl({{ Rd.uh = Mem.uh; 144 Rn = Rn + Rm; }}, 145 {{ EA = Rn + Rm; }}); 146 0x15, 0x1d: ldrh_pil({{ Rd.uh = Mem.uh; }}, 147 {{ EA = Rn + hilo; }}); 148 0x17, 0x1f: ldrh_piwl({{ Rd.uh = Mem.uh; 149 Rn = Rn + hilo; }}, 150 {{ EA = Rn + hilo; }}); 151 } 152 } 153 format ArmLoadMemory { 154 0xd: decode PUBWL { 155 0x1: ldrsb_l({{ Rd = Mem.sb; 156 Rn = Rn + Rm; }}, 157 {{ EA = Rn; }}); 158 0x5: ldrsb_il({{ Rd = Mem.sb; 159 Rn = Rn + hilo; }}, 160 {{ EA = Rn; }}); 161 0x9: ldrsb_ul({{ Rd = Mem.sb; 162 Rn = Rn - Rm; }}, 163 {{ EA = Rn; }}); 164 0xd: ldrsb_uil({{ Rd = Mem.sb; 165 Rn = Rn - hilo; }}, 166 {{ EA = Rn; }}); 167 0x11: ldrsb_pl({{ Rd = Mem.sb; }}, 168 {{ EA = Rn + Rm; }}); 169 0x13: ldrsb_pwl({{ Rd = Mem.sb; 170 Rn = Rn + Rm; }}, 171 {{ EA = Rn + Rm; }}); 172 0x15: ldrsb_pil({{ Rd = Mem.sb; }}, 173 {{ EA = Rn + hilo; }}); 174 0x17: ldrsb_piwl({{ Rd = Mem.sb; 175 Rn = Rn + hilo; }}, 176 {{ EA = Rn + hilo; }}); 177 0x19: ldrsb_pul({{ Rd = Mem.sb; }}, 178 {{ EA = Rn - Rm; }}); 179 0x1b: ldrsb_puwl({{ Rd = Mem.sb; 180 Rn = Rn - Rm; }}, 181 {{ EA = Rn - Rm; }}); 182 0x1d: ldrsb_puil({{ Rd = Mem.sb; }}, 183 {{ EA = Rn - hilo; }}); 184 0x1f: ldrsb_puiwl({{ Rd = Mem.sb; 185 Rn = Rn - hilo; }}, 186 {{ EA = Rn - hilo; }}); 187 } 188 0xf: decode PUBWL { 189 0x1: ldrsh_l({{ Rd = Mem.sh; 190 Rn = Rn + Rm; }}, 191 {{ EA = Rn; }}); 192 0x5: ldrsh_il({{ Rd = Mem.sh; 193 Rn = Rn + hilo; }}, 194 {{ EA = Rn; }}); 195 0x9: ldrsh_ul({{ Rd = Mem.sh; 196 Rn = Rn - Rm; }}, 197 {{ EA = Rn; }}); 198 0xd: ldrsh_uil({{ Rd = Mem.sh; 199 Rn = Rn - hilo; }}, 200 {{ EA = Rn; }}); 201 0x11: ldrsh_pl({{ Rd = Mem.sh; }}, 202 {{ EA = Rn + Rm; }}); 203 0x13: ldrsh_pwl({{ Rd = Mem.sh; 204 Rn = Rn + Rm; }}, 205 {{ EA = Rn + Rm; }}); 206 0x15: ldrsh_pil({{ Rd = Mem.sh; }}, 207 {{ EA = Rn + hilo; }}); 208 0x17: ldrsh_piwl({{ Rd = Mem.sh; 209 Rn = Rn + hilo; }}, 210 {{ EA = Rn + hilo; }}); 211 0x19: ldrsh_pul({{ Rd = Mem.sh; }}, 212 {{ EA = Rn - Rm; }}); 213 0x1b: ldrsh_puwl({{ Rd = Mem.sh; 214 Rn = Rn - Rm; }}, 215 {{ EA = Rn - Rm; }}); 216 0x1d: ldrsh_puil({{ Rd = Mem.sh; }}, 217 {{ EA = Rn - hilo; }}); 218 0x1f: ldrsh_puiwl({{ Rd = Mem.sh; 219 Rn = Rn - hilo; }}, 220 {{ EA = Rn - hilo; }}); 221 } 222 } 223 } 224 0: decode IS_MISC { 225 0: decode OPCODE { 226 0x0: and({{ Rd = resTemp = Rn & op2; }}); 227 0x1: eor({{ Rd = resTemp = Rn ^ op2; }}); 228 0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub); 229 0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb); 230 0x4: add({{ Rd = resTemp = Rn + op2; }}, add); 231 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add); 232 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub); 233 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb); 234 0x8: tst({{ resTemp = Rn & op2; }}); 235 0x9: teq({{ resTemp = Rn ^ op2; }}); 236 0xa: cmp({{ resTemp = Rn - op2; }}, sub); 237 0xb: cmn({{ resTemp = Rn + op2; }}, add); 238 0xc: orr({{ Rd = resTemp = Rn | op2; }}); 239 0xd: mov({{ Rd = resTemp = op2; }}); 240 0xe: bic({{ Rd = resTemp = Rn & ~op2; }}); 241 0xf: mvn({{ Rd = resTemp = ~op2; }}); 242 } 243 1: decode MISC_OPCODE { 244 0x0: decode OPCODE { 245 0x8: WarnUnimpl::mrs_cpsr(); 246 0x9: WarnUnimpl::msr_cpsr(); 247 0xa: WarnUnimpl::mrs_spsr(); 248 0xb: WarnUnimpl::msr_spsr(); 249 } 250 0x1: decode OPCODE { 251 0x9: BranchExchange::bx({{ }}); 252 0xb: PredOp::clz({{ 253 unsigned lsb = findLsbSet(Rm); 254 Rd = (lsb > 31) ? 32 : lsb; 255 }}); 256 } 257 0x2: decode OPCODE { 258 0x9: WarnUnimpl::bxj(); 259 } 260 0x3: decode OPCODE { 261 0x9: BranchExchange::blx({{ }}, Link); 262 } 263 0x5: decode OPCODE { 264 0x8: WarnUnimpl::qadd(); 265 0x9: WarnUnimpl::qsub(); 266 0xa: WarnUnimpl::qdadd(); 267 0xb: WarnUnimpl::qdsub(); 268 } 269 0x8: decode OPCODE { 270 0x8: WarnUnimpl::smlabb(); 271 0x9: WarnUnimpl::smlalbb(); 272 0xa: WarnUnimpl::smlawb(); 273 0xb: WarnUnimpl::smulbb(); 274 } 275 0xa: decode OPCODE { 276 0x8: WarnUnimpl::smlatb(); 277 0x9: WarnUnimpl::smulwb(); 278 0xa: WarnUnimpl::smlaltb(); 279 0xb: WarnUnimpl::smultb(); 280 } 281 0xc: decode OPCODE { 282 0x8: WarnUnimpl::smlabt(); 283 0x9: WarnUnimpl::smlawt(); 284 0xa: WarnUnimpl::smlalbt(); 285 0xb: WarnUnimpl::smulbt(); 286 } 287 0xe: decode OPCODE { 288 0x8: WarnUnimpl::smlatt(); 289 0x9: WarnUnimpl::smulwt(); 290 0xa: WarnUnimpl::smlaltt(); 291 0xb: WarnUnimpl::smultt(); 292 } 293 } 294 } 295 } 296 0x1: decode IS_MISC { 297 0: decode OPCODE { 298 format DataImmOp { 299 0x0: andi({{ Rd = resTemp = Rn & rotated_imm; }}); 300 0x1: eori({{ Rd = resTemp = Rn ^ rotated_imm; }}); 301 0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub); 302 0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb); 303 0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add); 304 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add); 305 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub); 306 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb); 307 0x8: tsti({{ resTemp = Rn & rotated_imm; }}); 308 0x9: teqi({{ resTemp = Rn ^ rotated_imm; }}); 309 0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub); 310 0xb: cmni({{ resTemp = Rn + rotated_imm; }}, add); 311 0xc: orri({{ Rd = resTemp = Rn | rotated_imm; }}); 312 0xd: movi({{ Rd = resTemp = rotated_imm; }}); 313 0xe: bici({{ Rd = resTemp = Rn & ~rotated_imm; }}); 314 0xf: mvni({{ Rd = resTemp = ~rotated_imm; }}); 315 } 316 } 317 1: decode OPCODE { 318 // The following two instructions aren't supposed to be defined 319 0x8: WarnUnimpl::undefined_instruction(); 320 0x9: WarnUnimpl::undefined_instruction(); 321 322 0xa: WarnUnimpl::mrs_i_cpsr(); 323 0xb: WarnUnimpl::mrs_i_spsr(); 324 } 325 } 326 0x2: decode PUBWL { 327 // CAREFUL: 328 // Can always do EA + disp, since we negate disp using the UP flag 329 // Post-indexed variants 330 0x00,0x08: ArmStoreMemory::str_({{ Mem = Rd; 331 Rn = Rn + disp; }}, 332 {{ EA = Rn; }}); 333 0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; 334 Rd = Mem; }}, 335 {{ EA = Rn; }}); 336 0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub; 337 Rn = Rn + disp; }}, 338 {{ EA = Rn; }}); 339 0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; 340 Rd.ub = Mem.ub; }}, 341 {{ EA = Rn; }}); 342 // Pre-indexed variants 343 0x10,0x18: ArmStoreMemory::str_p({{ Mem = Rd; }}); 344 0x11,0x19: ArmLoadMemory::ldr_pl({{ Rd = Mem; }}); 345 0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd; 346 Rn = Rn + disp; }}); 347 0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; 348 Rd = Mem; }}); 349 0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }}); 350 0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }}); 351 0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub; 352 Rn = Rn + disp; }}); 353 0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; 354 Rd.ub = Mem.ub; }}); 355 } 356 0x3: decode OPCODE_4 { 357 0: decode PUBWL { 358 0x00,0x08: ArmStoreMemory::strr_({{ 359 Mem = Rd; 360 Rn = Rn + Rm_Imm; }}, 361 {{ EA = Rn; }}); 362 0x01,0x09: ArmLoadMemory::ldrr_l({{ 363 Rd = Mem; 364 Rn = Rn + Rm_Imm; }}, 365 {{ EA = Rn; }}); 366 0x04,0x0c: ArmStoreMemory::strr_b({{ 367 Mem.ub = Rd.ub; 368 Rn = Rn + Rm_Imm; }}, 369 {{ EA = Rn; }}); 370 0x05,0x0d: ArmLoadMemory::ldrr_bl({{ 371 Rd.ub = Mem.ub; 372 Rn = Rn + Rm_Imm; }}, 373 {{ EA = Rn; }}); 374 0x10,0x18: ArmStoreMemory::strr_p({{ 375 Mem = Rd; }}, 376 {{ EA = Rn + Rm_Imm; }}); 377 0x11,0x19: ArmLoadMemory::ldrr_pl({{ 378 Rd = Mem; }}, 379 {{ EA = Rn + Rm_Imm; }}); 380 0x12,0x1a: ArmStoreMemory::strr_pw({{ 381 Mem = Rd; 382 Rn = Rn + Rm_Imm; }}, 383 {{ EA = Rn + Rm_Imm; }}); 384 0x13,0x1b: ArmLoadMemory::ldrr_pwl({{ 385 Rd = Mem; 386 Rn = Rn + Rm_Imm; }}, 387 {{ EA = Rn + Rm_Imm; }}); 388 0x14,0x1c: ArmStoreMemory::strr_pb({{ 389 Mem.ub = Rd.ub; }}, 390 {{ EA = Rn + Rm_Imm; }}); 391 0x15,0x1d: ArmLoadMemory::ldrr_pbl({{ 392 Rd.ub = Mem.ub; }}, 393 {{ EA = Rn + Rm_Imm; }}); 394 0x16,0x1e: ArmStoreMemory::strr_pbw({{ 395 Mem.ub = Rd.ub; 396 Rn = Rn + Rm_Imm; }}, 397 {{ EA = Rn + Rm_Imm; }}); 398 0x17,0x1f: ArmLoadMemory::ldrr_pbwl({{ 399 Rd.ub = Mem.ub; 400 Rn = Rn + Rm_Imm; }}, 401 {{ EA = Rn + Rm_Imm; }}); 402 } 403 1: decode MEDIA_OPCODE { 404 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 405 0x8: decode MISC_OPCODE { 406 0x1, 0x9: WarnUnimpl::pkhbt(); 407 0x7: WarnUnimpl::sxtab16(); 408 0xb: WarnUnimpl::sel(); 409 0x5, 0xd: WarnUnimpl::pkhtb(); 410 0x3: WarnUnimpl::sign_zero_extend_add(); 411 } 412 0xa, 0xb: decode SHIFT { 413 0x0, 0x2: WarnUnimpl::ssat(); 414 0x1: WarnUnimpl::ssat16(); 415 } 416 0xe, 0xf: decode SHIFT { 417 0x0, 0x2: WarnUnimpl::usat(); 418 0x1: WarnUnimpl::usat16(); 419 } 420 0x10: decode RN { 421 0xf: decode MISC_OPCODE { 422 0x1: WarnUnimpl::smuad(); 423 0x3: WarnUnimpl::smuadx(); 424 0x5: WarnUnimpl::smusd(); 425 0x7: WarnUnimpl::smusdx(); 426 } 427 default: decode MISC_OPCODE { 428 0x1: WarnUnimpl::smlad(); 429 0x3: WarnUnimpl::smladx(); 430 0x5: WarnUnimpl::smlsd(); 431 0x7: WarnUnimpl::smlsdx(); 432 } 433 } 434 0x14: decode MISC_OPCODE { 435 0x1: WarnUnimpl::smlald(); 436 0x3: WarnUnimpl::smlaldx(); 437 0x5: WarnUnimpl::smlsld(); 438 0x7: WarnUnimpl::smlsldx(); 439 } 440 0x15: decode RN { 441 0xf: decode MISC_OPCODE { 442 0x1: WarnUnimpl::smmul(); 443 0x3: WarnUnimpl::smmulr(); 444 } 445 default: decode MISC_OPCODE { 446 0x1: WarnUnimpl::smmla(); 447 0x3: WarnUnimpl::smmlar(); 448 0xd: WarnUnimpl::smmls(); 449 0xf: WarnUnimpl::smmlsr(); 450 } 451 } 452 0x18: decode RN { 453 0xf: WarnUnimpl::usada8(); 454 default: WarnUnimpl::usad8(); 455 } 456 } 457 } 458 0x4: decode PUSWL { 459 // Right now we only handle cases when S (PSRUSER) is not set 460 default: ArmMacroStore::ldmstm({{ }}); 461 } 462 0x5: decode OPCODE_24 { 463 // Branch (and Link) Instructions 464 0: Branch::b({{ }}); 465 1: Branch::bl({{ }}, Link); 466 } 467 0x6: decode CPNUM { 468 0x1: decode PUNWL { 469 0x02,0x0a: decode OPCODE_15 { 470 0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf; 471 Rn = Rn + disp8; }}, 472 {{ EA = Rn; }}); 473 1: ArmMacroFPAOp::stfd_({{ }}); 474 } 475 0x03,0x0b: decode OPCODE_15 { 476 0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf; 477 Rn = Rn + disp8; }}, 478 {{ EA = Rn; }}); 479 1: ArmMacroFPAOp::ldfd_({{ }}); 480 } 481 0x06,0x0e: decode OPCODE_15 { 482 0: ArmMacroFPAOp::stfe_nw({{ }}); 483 } 484 0x07,0x0f: decode OPCODE_15 { 485 0: ArmMacroFPAOp::ldfe_nw({{ }}); 486 } 487 0x10,0x18: decode OPCODE_15 { 488 0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }}, 489 {{ EA = Rn + disp8; }}); 490 1: ArmMacroFPAOp::stfd_p({{ }}); 491 } 492 0x11,0x19: decode OPCODE_15 { 493 0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }}, 494 {{ EA = Rn + disp8; }}); 495 1: ArmMacroFPAOp::ldfd_p({{ }}); 496 } 497 0x12,0x1a: decode OPCODE_15 { 498 0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf; 499 Rn = Rn + disp8; }}, 500 {{ EA = Rn + disp8; }}); 501 1: ArmMacroFPAOp::stfd_pw({{ }}); 502 } 503 0x13,0x1b: decode OPCODE_15 { 504 0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf; 505 Rn = Rn + disp8; }}, 506 {{ EA = Rn + disp8; }}); 507 1: ArmMacroFPAOp::ldfd_pw({{ }}); 508 } 509 0x14,0x1c: decode OPCODE_15 { 510 0: ArmMacroFPAOp::stfe_pn({{ }}); 511 } 512 0x15,0x1d: decode OPCODE_15 { 513 0: ArmMacroFPAOp::ldfe_pn({{ }}); 514 } 515 0x16,0x1e: decode OPCODE_15 { 516 0: ArmMacroFPAOp::stfe_pnw({{ }}); 517 } 518 0x17,0x1f: decode OPCODE_15 { 519 0: ArmMacroFPAOp::ldfe_pnw({{ }}); 520 } 521 } 522 0x2: decode PUNWL { 523 // could really just decode as a single instruction 524 0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }}); 525 0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }}); 526 0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }}); 527 0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }}); 528 0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }}); 529 0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }}); 530 0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }}); 531 0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }}); 532 } 533 } 534 0x7: decode OPCODE_24 { 535 0: decode CPNUM { 536 // Coprocessor Instructions 537 0x1: decode OPCODE_4 { 538 format FloatOp { 539 // Basic FPA Instructions 540 0: decode OPCODE_23_20 { 541 0x0: decode OPCODE_15 { 542 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); 543 1: mvf({{ Fd.sf = Fm.sf; }}); 544 } 545 0x1: decode OPCODE_15 { 546 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); 547 1: mnf({{ Fd.sf = -Fm.sf; }}); 548 } 549 0x2: decode OPCODE_15 { 550 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); 551 1: abs({{ Fd.sf = fabs(Fm.sf); }}); 552 } 553 0x3: decode OPCODE_15 { 554 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); 555 1: rnd({{ Fd.sf = rint(Fm.sf); }}); 556 } 557 0x4: decode OPCODE_15 { 558 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); 559 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); 560 } 561 0x5: decode OPCODE_15 { 562 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); 563 1: log({{ Fd.sf = log10(Fm.sf); }}); 564 } 565 0x6: decode OPCODE_15 { 566 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); 567 1: lgn({{ Fd.sf = log(Fm.sf); }}); 568 } 569 0x7: decode OPCODE_15 { 570 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); 571 1: exp({{ Fd.sf = exp(Fm.sf); }}); 572 } 573 0x8: decode OPCODE_15 { 574 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); 575 1: sin({{ Fd.sf = sin(Fm.sf); }}); 576 } 577 0x9: decode OPCODE_15 { 578 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); 579 1: cos({{ Fd.sf = cos(Fm.sf); }}); 580 } 581 0xa: decode OPCODE_15 { 582 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); 583 1: tan({{ Fd.sf = tan(Fm.sf); }}); 584 } 585 0xb: decode OPCODE_15 { 586 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); 587 1: asn({{ Fd.sf = asin(Fm.sf); }}); 588 } 589 0xc: decode OPCODE_15 { 590 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); 591 1: acs({{ Fd.sf = acos(Fm.sf); }}); 592 } 593 0xd: decode OPCODE_15 { 594 1: atn({{ Fd.sf = atan(Fm.sf); }}); 595 } 596 0xe: decode OPCODE_15 { 597 // Unnormalised Round 598 1: FailUnimpl::urd(); 599 } 600 0xf: decode OPCODE_15 { 601 // Normalise 602 1: FailUnimpl::nrm(); 603 } 604 } 605 1: decode OPCODE_15_12 { 606 0xf: decode OPCODE_23_21 { 607 format FloatCmp { 608 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); 609 0x5: cnf({{ Fn.df }}, {{ -Fm.df }}); 610 0x6: cmfe({{ Fn.df }}, {{ Fm.df}}); 611 0x7: cnfe({{ Fn.df }}, {{ -Fm.df}}); 612 } 613 } 614 default: decode OPCODE_23_20 { 615 0x0: decode OPCODE_7 { 616 0: flts({{ Fn.sf = (float) Rd.sw; }}); 617 1: fltd({{ Fn.df = (double) Rd.sw; }}); 618 } 619 0x1: decode OPCODE_7 { 620 0: fixs({{ Rd = (uint32_t) Fm.sf; }}); 621 1: fixd({{ Rd = (uint32_t) Fm.df; }}); 622 } 623 0x2: wfs({{ Fpsr = Rd; }}); 624 0x3: rfs({{ Rd = Fpsr; }}); 625 0x4: FailUnimpl::wfc(); 626 0x5: FailUnimpl::rfc(); 627 } 628 } 629 } 630 } 631 } 632 format PredOp { 633 // ARM System Call (SoftWare Interrupt) 634 1: swi({{ if (testPredicate(Cpsr, condCode)) 635 { 636 xc->syscall(IMMED_23_0); 637 } 638 }}); 639 } 640 } 641} 642} 643} 644 645