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