1 /// Types and constants of SPARC architecturem 2 module capstone.sparc; 3 4 import std.conv: to; 5 import std.typecons: BitFlags; 6 7 import capstone.api; 8 import capstone.capstone; 9 import capstone.detail; 10 import capstone.instruction; 11 import capstone.instructiongroup; 12 import capstone.internal; 13 import capstone.register; 14 import capstone.utils; 15 16 /// Architecture-specific Register variant 17 class SparcRegister : RegisterImpl!SparcRegisterId { 18 package this(in Capstone cs, in int id) { 19 super(cs, id); 20 } 21 } 22 23 /// Architecture-specific InstructionGroup variant 24 class SparcInstructionGroup : InstructionGroupImpl!SparcInstructionGroupId { 25 package this(in Capstone cs, in int id) { 26 super(cs, id); 27 } 28 } 29 30 /// Architecture-specific Detail variant 31 class SparcDetail : DetailImpl!(SparcRegister, SparcInstructionGroup, SparcInstructionDetail) { 32 package this(in Capstone cs, cs_detail* internal) { 33 super(cs, internal); 34 } 35 } 36 37 /// Architecture-specific instruction variant 38 class SparcInstruction : InstructionImpl!(SparcInstructionId, SparcRegister, SparcDetail) { 39 package this(in Capstone cs, cs_insn* internal) { 40 super(cs, internal); 41 } 42 } 43 44 /// Architecture-specific Capstone variant 45 class CapstoneSparc : CapstoneImpl!(SparcInstructionId, SparcInstruction) { 46 /** Creates an architecture-specific instance with a given mode of interpretation 47 48 Params: 49 modeFlags = The (initial) mode of interpretation, which can still be changed later on 50 */ 51 this(in ModeFlags modeFlags){ 52 super(Arch.sparc, modeFlags); 53 } 54 } 55 56 /** Instruction's operand referring to memory 57 58 This is associated with the `SparcOpType.mem` operand type 59 */ 60 struct SparcOpMem { 61 SparcRegister base; /// Base register 62 SparcRegister index; /// Index register 63 int disp; /// Displacement/offset value 64 65 package this(in Capstone cs, sparc_op_mem internal){ 66 base = new SparcRegister(cs, internal.base); 67 index = new SparcRegister(cs, internal.index); 68 disp = internal.disp; 69 } 70 } 71 72 /// Union of possible operand types 73 union SparcOpValue { 74 SparcRegister reg; /// Register 75 long imm; /// Immediate 76 SparcOpMem mem; /// Memory 77 } 78 79 /// Instruction's operand 80 struct SparcOp { 81 SparcOpType type; /// Operand type 82 SafeUnion!SparcOpValue value; /// Operand value of type `type` 83 alias value this; /// Convenient access to value (as in original bindings) 84 85 package this(in Capstone cs, cs_sparc_op internal){ 86 type = internal.type.to!SparcOpType; 87 final switch(internal.type) { 88 case SparcOpType.invalid: 89 break; 90 case SparcOpType.reg: 91 value.reg = new SparcRegister(cs, internal.reg); 92 break; 93 case SparcOpType.imm: 94 value.imm = internal.imm; 95 break; 96 case SparcOpType.mem: 97 value.mem = SparcOpMem(cs, internal.mem); 98 break; 99 } 100 } 101 } 102 103 /// Sparc-specific information about an instruction 104 struct SparcInstructionDetail { 105 SparcCc cc; /// Code condition for this instruction 106 BitFlags!SparcHint hint; /// Branch hint: encoding as bitwise OR of `SparcHint`, invalid if = 0 107 SparcOp[] operands; /// Operands for this instruction. 108 109 package this(in Capstone cs, cs_arch_detail arch_detail){ 110 auto internal = arch_detail.sparc; 111 cc = internal.cc.to!SparcCc; 112 hint = cast(SparcHint)internal.hint; 113 foreach(op; internal.operands[0..internal.op_count]) 114 operands ~= SparcOp(cs, op); 115 } 116 } 117 118 //============================================================================= 119 // Constants 120 //============================================================================= 121 122 /// Operand type for instruction's operands 123 enum SparcOpType { 124 invalid = 0, /// Uninitialized 125 reg, /// Register operand 126 imm, /// Immediate operand 127 mem, /// Memory operand 128 } 129 130 /// Enums corresponding to Sparc condition codes, both icc's and fcc's. 131 enum SparcCc { 132 invalid = 0, /// Invalid CC (default) 133 134 // Integer condition codes 135 icc_a = 8+256, /// Always 136 icc_n = 0+256, /// Never 137 icc_ne = 9+256, /// Not Equal 138 icc_e = 1+256, /// Equal 139 icc_g = 10+256, /// Greater 140 icc_le = 2+256, /// Less or Equal 141 icc_ge = 11+256, /// Greater or Equal 142 icc_l = 3+256, /// Less 143 icc_gu = 12+256, /// Greater Unsigned 144 icc_leu = 4+256, /// Less or Equal Unsigned 145 icc_cc = 13+256, /// Carry Clear/Great or Equal Unsigned 146 icc_cs = 5+256, /// Carry Set/Less Unsigned 147 icc_pos = 14+256, /// Positive 148 icc_neg = 6+256, /// Negative 149 icc_vc = 15+256, /// Overflow Clear 150 icc_vs = 7+256, /// Overflow Set 151 152 // Floating condition codes 153 fcc_a = 8+16+256, /// Always 154 fcc_n = 0+16+256, /// Never 155 fcc_u = 7+16+256, /// Unordered 156 fcc_g = 6+16+256, /// Greater 157 fcc_ug = 5+16+256, /// Unordered or Greater 158 fcc_l = 4+16+256, /// Less 159 fcc_ul = 3+16+256, /// Unordered or Less 160 fcc_lg = 2+16+256, /// Less or Greater 161 fcc_ne = 1+16+256, /// Not Equal 162 fcc_e = 9+16+256, /// Equal 163 fcc_ue = 10+16+256, /// Unordered or Equal 164 fcc_ge = 11+16+256, /// Greater or Equal 165 fcc_uge = 12+16+256, /// Unordered or Greater or Equal 166 fcc_le = 13+16+256, /// Less or Equal 167 fcc_ule = 14+16+256, /// Unordered or Less or Equal 168 fcc_o = 15+16+256, /// Ordered 169 } 170 171 /// Branch hint 172 enum SparcHint { 173 invalid = 0, /// No hint 174 a = 1 << 0, /// Annul delay slot instruction 175 pt = 1 << 1, /// Branch taken 176 pn = 1 << 2, /// Branch NOT taken 177 } 178 179 /// SPARC registers 180 enum SparcRegisterId { 181 invalid = 0, 182 183 f0, 184 f1, 185 f2, 186 f3, 187 f4, 188 f5, 189 f6, 190 f7, 191 f8, 192 f9, 193 f10, 194 f11, 195 f12, 196 f13, 197 f14, 198 f15, 199 f16, 200 f17, 201 f18, 202 f19, 203 f20, 204 f21, 205 f22, 206 f23, 207 f24, 208 f25, 209 f26, 210 f27, 211 f28, 212 f29, 213 f30, 214 f31, 215 f32, 216 f34, 217 f36, 218 f38, 219 f40, 220 f42, 221 f44, 222 f46, 223 f48, 224 f50, 225 f52, 226 f54, 227 f56, 228 f58, 229 f60, 230 f62, 231 fcc0, // Floating condition codes 232 fcc1, 233 fcc2, 234 fcc3, 235 fp, 236 g0, 237 g1, 238 g2, 239 g3, 240 g4, 241 g5, 242 g6, 243 g7, 244 i0, 245 i1, 246 i2, 247 i3, 248 i4, 249 i5, 250 i7, 251 icc, // Integer condition codes 252 l0, 253 l1, 254 l2, 255 l3, 256 l4, 257 l5, 258 l6, 259 l7, 260 o0, 261 o1, 262 o2, 263 o3, 264 o4, 265 o5, 266 o7, 267 sp, 268 y, 269 270 // Special register 271 xcc, 272 273 // Extras 274 o6 = sp, 275 i6 = fp, 276 } 277 278 /// SPARC instruction 279 enum SparcInstructionId { 280 invalid = 0, 281 282 addcc, 283 addx, 284 addxcc, 285 addxc, 286 addxccc, 287 add, 288 alignaddr, 289 alignaddrl, 290 andcc, 291 andncc, 292 andn, 293 and, 294 array16, 295 array32, 296 array8, 297 b, 298 jmp, 299 bmask, 300 fb, 301 brgez, 302 brgz, 303 brlez, 304 brlz, 305 brnz, 306 brz, 307 bshuffle, 308 call, 309 casx, 310 cas, 311 cmask16, 312 cmask32, 313 cmask8, 314 cmp, 315 edge16, 316 edge16l, 317 edge16ln, 318 edge16n, 319 edge32, 320 edge32l, 321 edge32ln, 322 edge32n, 323 edge8, 324 edge8l, 325 edge8ln, 326 edge8n, 327 fabsd, 328 fabsq, 329 fabss, 330 faddd, 331 faddq, 332 fadds, 333 faligndata, 334 fand, 335 fandnot1, 336 fandnot1s, 337 fandnot2, 338 fandnot2s, 339 fands, 340 fchksm16, 341 fcmpd, 342 fcmpeq16, 343 fcmpeq32, 344 fcmpgt16, 345 fcmpgt32, 346 fcmple16, 347 fcmple32, 348 fcmpne16, 349 fcmpne32, 350 fcmpq, 351 fcmps, 352 fdivd, 353 fdivq, 354 fdivs, 355 fdmulq, 356 fdtoi, 357 fdtoq, 358 fdtos, 359 fdtox, 360 fexpand, 361 fhaddd, 362 fhadds, 363 fhsubd, 364 fhsubs, 365 fitod, 366 fitoq, 367 fitos, 368 flcmpd, 369 flcmps, 370 flushw, 371 fmean16, 372 fmovd, 373 fmovq, 374 fmovrdgez, 375 fmovrqgez, 376 fmovrsgez, 377 fmovrdgz, 378 fmovrqgz, 379 fmovrsgz, 380 fmovrdlez, 381 fmovrqlez, 382 fmovrslez, 383 fmovrdlz, 384 fmovrqlz, 385 fmovrslz, 386 fmovrdnz, 387 fmovrqnz, 388 fmovrsnz, 389 fmovrdz, 390 fmovrqz, 391 fmovrsz, 392 fmovs, 393 fmul8sux16, 394 fmul8ulx16, 395 fmul8x16, 396 fmul8x16al, 397 fmul8x16au, 398 fmuld, 399 fmuld8sux16, 400 fmuld8ulx16, 401 fmulq, 402 fmuls, 403 fnaddd, 404 fnadds, 405 fnand, 406 fnands, 407 fnegd, 408 fnegq, 409 fnegs, 410 fnhaddd, 411 fnhadds, 412 fnor, 413 fnors, 414 fnot1, 415 fnot1s, 416 fnot2, 417 fnot2s, 418 fone, 419 fones, 420 for_, 421 fornot1, 422 fornot1s, 423 fornot2, 424 fornot2s, 425 fors, 426 fpack16, 427 fpack32, 428 fpackfix, 429 fpadd16, 430 fpadd16s, 431 fpadd32, 432 fpadd32s, 433 fpadd64, 434 fpmerge, 435 fpsub16, 436 fpsub16s, 437 fpsub32, 438 fpsub32s, 439 fqtod, 440 fqtoi, 441 fqtos, 442 fqtox, 443 fslas16, 444 fslas32, 445 fsll16, 446 fsll32, 447 fsmuld, 448 fsqrtd, 449 fsqrtq, 450 fsqrts, 451 fsra16, 452 fsra32, 453 fsrc1, 454 fsrc1s, 455 fsrc2, 456 fsrc2s, 457 fsrl16, 458 fsrl32, 459 fstod, 460 fstoi, 461 fstoq, 462 fstox, 463 fsubd, 464 fsubq, 465 fsubs, 466 fxnor, 467 fxnors, 468 fxor, 469 fxors, 470 fxtod, 471 fxtoq, 472 fxtos, 473 fzero, 474 fzeros, 475 jmpl, 476 ldd, 477 ld, 478 ldq, 479 ldsb, 480 ldsh, 481 ldsw, 482 ldub, 483 lduh, 484 ldx, 485 lzcnt, 486 membar, 487 movdtox, 488 mov, 489 movrgez, 490 movrgz, 491 movrlez, 492 movrlz, 493 movrnz, 494 movrz, 495 movstosw, 496 movstouw, 497 mulx, 498 nop, 499 orcc, 500 orncc, 501 orn, 502 or, 503 pdist, 504 pdistn, 505 popc, 506 rd, 507 restore, 508 rett, 509 save, 510 sdivcc, 511 sdivx, 512 sdiv, 513 sethi, 514 shutdown, 515 siam, 516 sllx, 517 sll, 518 smulcc, 519 smul, 520 srax, 521 sra, 522 srlx, 523 srl, 524 stbar, 525 stb, 526 std, 527 st, 528 sth, 529 stq, 530 stx, 531 subcc, 532 subx, 533 subxcc, 534 sub, 535 swap, 536 taddcctv, 537 taddcc, 538 t, 539 tsubcctv, 540 tsubcc, 541 udivcc, 542 udivx, 543 udiv, 544 umulcc, 545 umulxhi, 546 umul, 547 unimp, 548 fcmped, 549 fcmpeq, 550 fcmpes, 551 wr, 552 xmulx, 553 xmulxhi, 554 xnorcc, 555 xnor, 556 xorcc, 557 xor, 558 559 // alias instructions 560 ret, 561 retl, 562 } 563 564 /// Group of SPARC instructions 565 enum SparcInstructionGroupId { 566 invalid = 0, 567 568 // Generic groups 569 // all jump instructions (conditional+direct+indirect jumps) 570 jump, 571 572 // Architecture-specific groups 573 hardquad = 128, 574 v9, 575 vis, 576 vis2, 577 vis3, 578 bit32, 579 bit64, 580 }