arm.isa revision 6303
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 + (up ? disp : -disp); }}, 50 inst_flags = [IsMicroop]); 51 0x3: ArmStoreMemory::str_uop({{ Mem = Rd; }}, 52 {{ EA = Raddr + (up ? disp : -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 + (up ? disp : -disp); }}, 67 inst_flags = [IsMicroop]); 68 0x3: ArmLoadMemory::ldlo_uop({{ Rlo = Mem; }}, 69 {{ EA = Rn + (up ? disp : -disp); }}, 70 inst_flags = [IsMicroop]); 71 0x4: ArmStoreMemory::sthi_uop({{ Mem = Rhi; }}, 72 {{ EA = Rn + (up ? disp : -disp); }}, 73 inst_flags = [IsMicroop]); 74 0x5: ArmStoreMemory::stlo_uop({{ Mem = Rlo; }}, 75 {{ EA = Rn + (up ? disp : -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: AddrMode2::addrMode2(Disp, disp); 229 0x3: decode OPCODE_4 { 230 0: AddrMode2::addrMode2(Shift, Rm_Imm); 231 1: decode MEDIA_OPCODE { 232 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7: WarnUnimpl::parallel_add_subtract_instructions(); 233 0x8: decode MISC_OPCODE { 234 0x1, 0x9: WarnUnimpl::pkhbt(); 235 0x7: WarnUnimpl::sxtab16(); 236 0xb: WarnUnimpl::sel(); 237 0x5, 0xd: WarnUnimpl::pkhtb(); 238 0x3: WarnUnimpl::sign_zero_extend_add(); 239 } 240 0xa, 0xb: decode SHIFT { 241 0x0, 0x2: WarnUnimpl::ssat(); 242 0x1: WarnUnimpl::ssat16(); 243 } 244 0xe, 0xf: decode SHIFT { 245 0x0, 0x2: WarnUnimpl::usat(); 246 0x1: WarnUnimpl::usat16(); 247 } 248 0x10: decode RN { 249 0xf: decode MISC_OPCODE { 250 0x1: WarnUnimpl::smuad(); 251 0x3: WarnUnimpl::smuadx(); 252 0x5: WarnUnimpl::smusd(); 253 0x7: WarnUnimpl::smusdx(); 254 } 255 default: decode MISC_OPCODE { 256 0x1: WarnUnimpl::smlad(); 257 0x3: WarnUnimpl::smladx(); 258 0x5: WarnUnimpl::smlsd(); 259 0x7: WarnUnimpl::smlsdx(); 260 } 261 } 262 0x14: decode MISC_OPCODE { 263 0x1: WarnUnimpl::smlald(); 264 0x3: WarnUnimpl::smlaldx(); 265 0x5: WarnUnimpl::smlsld(); 266 0x7: WarnUnimpl::smlsldx(); 267 } 268 0x15: decode RN { 269 0xf: decode MISC_OPCODE { 270 0x1: WarnUnimpl::smmul(); 271 0x3: WarnUnimpl::smmulr(); 272 } 273 default: decode MISC_OPCODE { 274 0x1: WarnUnimpl::smmla(); 275 0x3: WarnUnimpl::smmlar(); 276 0xd: WarnUnimpl::smmls(); 277 0xf: WarnUnimpl::smmlsr(); 278 } 279 } 280 0x18: decode RN { 281 0xf: WarnUnimpl::usada8(); 282 default: WarnUnimpl::usad8(); 283 } 284 } 285 } 286 0x4: decode PUSWL { 287 // Right now we only handle cases when S (PSRUSER) is not set 288 default: ArmMacroStore::ldmstm({{ }}); 289 } 290 0x5: decode OPCODE_24 { 291 // Branch (and Link) Instructions 292 0: Branch::b({{ }}); 293 1: Branch::bl({{ }}, Link); 294 } 295 0x6: decode CPNUM { 296 0x1: decode PUNWL { 297 0x02,0x0a: decode OPCODE_15 { 298 0: ArmStoreMemory::stfs_({{ Mem.sf = Fd.sf; 299 Rn = Rn + disp8; }}, 300 {{ EA = Rn; }}); 301 1: ArmMacroFPAOp::stfd_({{ }}); 302 } 303 0x03,0x0b: decode OPCODE_15 { 304 0: ArmLoadMemory::ldfs_({{ Fd.sf = Mem.sf; 305 Rn = Rn + disp8; }}, 306 {{ EA = Rn; }}); 307 1: ArmMacroFPAOp::ldfd_({{ }}); 308 } 309 0x06,0x0e: decode OPCODE_15 { 310 0: ArmMacroFPAOp::stfe_nw({{ }}); 311 } 312 0x07,0x0f: decode OPCODE_15 { 313 0: ArmMacroFPAOp::ldfe_nw({{ }}); 314 } 315 0x10,0x18: decode OPCODE_15 { 316 0: ArmStoreMemory::stfs_p({{ Mem.sf = Fd.sf; }}, 317 {{ EA = Rn + disp8; }}); 318 1: ArmMacroFPAOp::stfd_p({{ }}); 319 } 320 0x11,0x19: decode OPCODE_15 { 321 0: ArmLoadMemory::ldfs_p({{ Fd.sf = Mem.sf; }}, 322 {{ EA = Rn + disp8; }}); 323 1: ArmMacroFPAOp::ldfd_p({{ }}); 324 } 325 0x12,0x1a: decode OPCODE_15 { 326 0: ArmStoreMemory::stfs_pw({{ Mem.sf = Fd.sf; 327 Rn = Rn + disp8; }}, 328 {{ EA = Rn + disp8; }}); 329 1: ArmMacroFPAOp::stfd_pw({{ }}); 330 } 331 0x13,0x1b: decode OPCODE_15 { 332 0: ArmLoadMemory::ldfs_pw({{ Fd.sf = Mem.sf; 333 Rn = Rn + disp8; }}, 334 {{ EA = Rn + disp8; }}); 335 1: ArmMacroFPAOp::ldfd_pw({{ }}); 336 } 337 0x14,0x1c: decode OPCODE_15 { 338 0: ArmMacroFPAOp::stfe_pn({{ }}); 339 } 340 0x15,0x1d: decode OPCODE_15 { 341 0: ArmMacroFPAOp::ldfe_pn({{ }}); 342 } 343 0x16,0x1e: decode OPCODE_15 { 344 0: ArmMacroFPAOp::stfe_pnw({{ }}); 345 } 346 0x17,0x1f: decode OPCODE_15 { 347 0: ArmMacroFPAOp::ldfe_pnw({{ }}); 348 } 349 } 350 0x2: decode PUNWL { 351 // could really just decode as a single instruction 352 0x00,0x04,0x08,0x0c: ArmMacroFMOp::sfm_({{ }}); 353 0x01,0x05,0x09,0x0d: ArmMacroFMOp::lfm_({{ }}); 354 0x02,0x06,0x0a,0x0e: ArmMacroFMOp::sfm_w({{ }}); 355 0x03,0x07,0x0b,0x0f: ArmMacroFMOp::lfm_w({{ }}); 356 0x10,0x14,0x18,0x1c: ArmMacroFMOp::sfm_p({{ }}); 357 0x11,0x15,0x19,0x1d: ArmMacroFMOp::lfm_p({{ }}); 358 0x12,0x16,0x1a,0x1e: ArmMacroFMOp::sfm_pw({{ }}); 359 0x13,0x17,0x1b,0x1f: ArmMacroFMOp::lfm_pw({{ }}); 360 } 361 } 362 0x7: decode OPCODE_24 { 363 0: decode CPNUM { 364 // Coprocessor Instructions 365 0x1: decode OPCODE_4 { 366 format FloatOp { 367 // Basic FPA Instructions 368 0: decode OPCODE_23_20 { 369 0x0: decode OPCODE_15 { 370 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); 371 1: mvf({{ Fd.sf = Fm.sf; }}); 372 } 373 0x1: decode OPCODE_15 { 374 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); 375 1: mnf({{ Fd.sf = -Fm.sf; }}); 376 } 377 0x2: decode OPCODE_15 { 378 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); 379 1: abs({{ Fd.sf = fabs(Fm.sf); }}); 380 } 381 0x3: decode OPCODE_15 { 382 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); 383 1: rnd({{ Fd.sf = rint(Fm.sf); }}); 384 } 385 0x4: decode OPCODE_15 { 386 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); 387 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); 388 } 389 0x5: decode OPCODE_15 { 390 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); 391 1: log({{ Fd.sf = log10(Fm.sf); }}); 392 } 393 0x6: decode OPCODE_15 { 394 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); 395 1: lgn({{ Fd.sf = log(Fm.sf); }}); 396 } 397 0x7: decode OPCODE_15 { 398 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); 399 1: exp({{ Fd.sf = exp(Fm.sf); }}); 400 } 401 0x8: decode OPCODE_15 { 402 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); 403 1: sin({{ Fd.sf = sin(Fm.sf); }}); 404 } 405 0x9: decode OPCODE_15 { 406 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); 407 1: cos({{ Fd.sf = cos(Fm.sf); }}); 408 } 409 0xa: decode OPCODE_15 { 410 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); 411 1: tan({{ Fd.sf = tan(Fm.sf); }}); 412 } 413 0xb: decode OPCODE_15 { 414 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); 415 1: asn({{ Fd.sf = asin(Fm.sf); }}); 416 } 417 0xc: decode OPCODE_15 { 418 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); 419 1: acs({{ Fd.sf = acos(Fm.sf); }}); 420 } 421 0xd: decode OPCODE_15 { 422 1: atn({{ Fd.sf = atan(Fm.sf); }}); 423 } 424 0xe: decode OPCODE_15 { 425 // Unnormalised Round 426 1: FailUnimpl::urd(); 427 } 428 0xf: decode OPCODE_15 { 429 // Normalise 430 1: FailUnimpl::nrm(); 431 } 432 } 433 1: decode OPCODE_15_12 { 434 0xf: decode OPCODE_23_21 { 435 format FloatCmp { 436 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); 437 0x5: cnf({{ Fn.df }}, {{ -Fm.df }}); 438 0x6: cmfe({{ Fn.df }}, {{ Fm.df}}); 439 0x7: cnfe({{ Fn.df }}, {{ -Fm.df}}); 440 } 441 } 442 default: decode OPCODE_23_20 { 443 0x0: decode OPCODE_7 { 444 0: flts({{ Fn.sf = (float) Rd.sw; }}); 445 1: fltd({{ Fn.df = (double) Rd.sw; }}); 446 } 447 0x1: decode OPCODE_7 { 448 0: fixs({{ Rd = (uint32_t) Fm.sf; }}); 449 1: fixd({{ Rd = (uint32_t) Fm.df; }}); 450 } 451 0x2: wfs({{ Fpsr = Rd; }}); 452 0x3: rfs({{ Rd = Fpsr; }}); 453 0x4: FailUnimpl::wfc(); 454 0x5: FailUnimpl::rfc(); 455 } 456 } 457 } 458 } 459 } 460 format PredOp { 461 // ARM System Call (SoftWare Interrupt) 462 1: swi({{ if (testPredicate(Cpsr, condCode)) 463 { 464 xc->syscall(IMMED_23_0); 465 } 466 }}); 467 } 468 } 469} 470} 471} 472 473