1 #ifndef CAPSTONE_M68K_H 2 #define CAPSTONE_M68K_H 3 4 /* Capstone Disassembly Engine */ 5 /* By Daniel Collin <daniel@collin.com>, 2015-2016 */ 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 11 #include "platform.h" 12 13 #ifdef _MSC_VER 14 #pragma warning(disable:4201) 15 #endif 16 17 #define M68K_OPERAND_COUNT 4 18 19 /// M68K registers and special registers 20 typedef enum m68k_reg { 21 M68K_REG_INVALID = 0, 22 23 M68K_REG_D0, 24 M68K_REG_D1, 25 M68K_REG_D2, 26 M68K_REG_D3, 27 M68K_REG_D4, 28 M68K_REG_D5, 29 M68K_REG_D6, 30 M68K_REG_D7, 31 32 M68K_REG_A0, 33 M68K_REG_A1, 34 M68K_REG_A2, 35 M68K_REG_A3, 36 M68K_REG_A4, 37 M68K_REG_A5, 38 M68K_REG_A6, 39 M68K_REG_A7, 40 41 M68K_REG_FP0, 42 M68K_REG_FP1, 43 M68K_REG_FP2, 44 M68K_REG_FP3, 45 M68K_REG_FP4, 46 M68K_REG_FP5, 47 M68K_REG_FP6, 48 M68K_REG_FP7, 49 50 M68K_REG_PC, 51 52 M68K_REG_SR, 53 M68K_REG_CCR, 54 M68K_REG_SFC, 55 M68K_REG_DFC, 56 M68K_REG_USP, 57 M68K_REG_VBR, 58 M68K_REG_CACR, 59 M68K_REG_CAAR, 60 M68K_REG_MSP, 61 M68K_REG_ISP, 62 M68K_REG_TC, 63 M68K_REG_ITT0, 64 M68K_REG_ITT1, 65 M68K_REG_DTT0, 66 M68K_REG_DTT1, 67 M68K_REG_MMUSR, 68 M68K_REG_URP, 69 M68K_REG_SRP, 70 71 M68K_REG_FPCR, 72 M68K_REG_FPSR, 73 M68K_REG_FPIAR, 74 75 M68K_REG_ENDING, // <-- mark the end of the list of registers 76 } m68k_reg; 77 78 /// M68K Addressing Modes 79 typedef enum m68k_address_mode { 80 M68K_AM_NONE = 0, ///< No address mode. 81 82 M68K_AM_REG_DIRECT_DATA, ///< Register Direct - Data 83 M68K_AM_REG_DIRECT_ADDR, ///< Register Direct - Address 84 85 M68K_AM_REGI_ADDR, ///< Register Indirect - Address 86 M68K_AM_REGI_ADDR_POST_INC, ///< Register Indirect - Address with Postincrement 87 M68K_AM_REGI_ADDR_PRE_DEC, ///< Register Indirect - Address with Predecrement 88 M68K_AM_REGI_ADDR_DISP, ///< Register Indirect - Address with Displacement 89 90 M68K_AM_AREGI_INDEX_8_BIT_DISP, ///< Address Register Indirect With Index- 8-bit displacement 91 M68K_AM_AREGI_INDEX_BASE_DISP, ///< Address Register Indirect With Index- Base displacement 92 93 M68K_AM_MEMI_POST_INDEX, ///< Memory indirect - Postindex 94 M68K_AM_MEMI_PRE_INDEX, ///< Memory indirect - Preindex 95 96 M68K_AM_PCI_DISP, ///< Program Counter Indirect - with Displacement 97 98 M68K_AM_PCI_INDEX_8_BIT_DISP, ///< Program Counter Indirect with Index - with 8-Bit Displacement 99 M68K_AM_PCI_INDEX_BASE_DISP, ///< Program Counter Indirect with Index - with Base Displacement 100 101 M68K_AM_PC_MEMI_POST_INDEX, ///< Program Counter Memory Indirect - Postindexed 102 M68K_AM_PC_MEMI_PRE_INDEX, ///< Program Counter Memory Indirect - Preindexed 103 104 M68K_AM_ABSOLUTE_DATA_SHORT, ///< Absolute Data Addressing - Short 105 M68K_AM_ABSOLUTE_DATA_LONG, ///< Absolute Data Addressing - Long 106 M68K_AM_IMMEDIATE, ///< Immediate value 107 108 M68K_AM_BRANCH_DISPLACEMENT, ///< Address as displacement from (PC+2) used by branches 109 } m68k_address_mode; 110 111 /// Operand type for instruction's operands 112 typedef enum m68k_op_type { 113 M68K_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized). 114 M68K_OP_REG, ///< = CS_OP_REG (Register operand). 115 M68K_OP_IMM, ///< = CS_OP_IMM (Immediate operand). 116 M68K_OP_MEM, ///< = CS_OP_MEM (Memory operand). 117 M68K_OP_FP_SINGLE, ///< single precision Floating-Point operand 118 M68K_OP_FP_DOUBLE, ///< double precision Floating-Point operand 119 M68K_OP_REG_BITS, ///< Register bits move 120 M68K_OP_REG_PAIR, ///< Register pair in the same op (upper 4 bits for first reg, lower for second) 121 M68K_OP_BR_DISP, ///< Branch displacement 122 } m68k_op_type; 123 124 /// Instruction's operand referring to memory 125 /// This is associated with M68K_OP_MEM operand type above 126 typedef struct m68k_op_mem { 127 m68k_reg base_reg; ///< base register (or M68K_REG_INVALID if irrelevant) 128 m68k_reg index_reg; ///< index register (or M68K_REG_INVALID if irrelevant) 129 m68k_reg in_base_reg; ///< indirect base register (or M68K_REG_INVALID if irrelevant) 130 uint32_t in_disp; ///< indirect displacement 131 uint32_t out_disp; ///< other displacement 132 int16_t disp; ///< displacement value 133 uint8_t scale; ///< scale for index register 134 uint8_t bitfield; ///< set to true if the two values below should be used 135 uint8_t width; ///< used for bf* instructions 136 uint8_t offset; ///< used for bf* instructions 137 uint8_t index_size; ///< 0 = w, 1 = l 138 } m68k_op_mem; 139 140 /// Operand type for instruction's operands 141 typedef enum m68k_op_br_disp_size { 142 M68K_OP_BR_DISP_SIZE_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized). 143 M68K_OP_BR_DISP_SIZE_BYTE = 1, ///< signed 8-bit displacement 144 M68K_OP_BR_DISP_SIZE_WORD = 2, ///< signed 16-bit displacement 145 M68K_OP_BR_DISP_SIZE_LONG = 4, ///< signed 32-bit displacement 146 } m68k_op_br_disp_size; 147 148 typedef struct m68k_op_br_disp { 149 int32_t disp; ///< displacement value 150 uint8_t disp_size; ///< Size from m68k_op_br_disp_size type above 151 } m68k_op_br_disp; 152 153 /// Instruction operand 154 typedef struct cs_m68k_op { 155 union { 156 uint64_t imm; ///< immediate value for IMM operand 157 double dimm; ///< double imm 158 float simm; ///< float imm 159 m68k_reg reg; ///< register value for REG operand 160 struct { ///< register pair in one operand 161 m68k_reg reg_0; 162 m68k_reg reg_1; 163 } reg_pair; 164 }; 165 166 m68k_op_mem mem; ///< data when operand is targeting memory 167 m68k_op_br_disp br_disp; ///< data when operand is a branch displacement 168 uint32_t register_bits; ///< register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order) 169 m68k_op_type type; 170 m68k_address_mode address_mode; ///< M68K addressing mode for this op 171 } cs_m68k_op; 172 173 /// Operation size of the CPU instructions 174 typedef enum m68k_cpu_size { 175 M68K_CPU_SIZE_NONE = 0, ///< unsized or unspecified 176 M68K_CPU_SIZE_BYTE = 1, ///< 1 byte in size 177 M68K_CPU_SIZE_WORD = 2, ///< 2 bytes in size 178 M68K_CPU_SIZE_LONG = 4, ///< 4 bytes in size 179 } m68k_cpu_size; 180 181 /// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed) 182 typedef enum m68k_fpu_size { 183 M68K_FPU_SIZE_NONE = 0, ///< unsized like fsave/frestore 184 M68K_FPU_SIZE_SINGLE = 4, ///< 4 byte in size (single float) 185 M68K_FPU_SIZE_DOUBLE = 8, ///< 8 byte in size (double) 186 M68K_FPU_SIZE_EXTENDED = 12, ///< 12 byte in size (extended real format) 187 } m68k_fpu_size; 188 189 /// Type of size that is being used for the current instruction 190 typedef enum m68k_size_type { 191 M68K_SIZE_TYPE_INVALID = 0, 192 193 M68K_SIZE_TYPE_CPU, 194 M68K_SIZE_TYPE_FPU, 195 } m68k_size_type; 196 197 /// Operation size of the current instruction (NOT the actually size of instruction) 198 typedef struct m68k_op_size { 199 m68k_size_type type; 200 union { 201 m68k_cpu_size cpu_size; 202 m68k_fpu_size fpu_size; 203 }; 204 } m68k_op_size; 205 206 /// The M68K instruction and it's operands 207 typedef struct cs_m68k { 208 // Number of operands of this instruction or 0 when instruction has no operand. 209 cs_m68k_op operands[M68K_OPERAND_COUNT]; ///< operands for this instruction. 210 m68k_op_size op_size; ///< size of data operand works on in bytes (.b, .w, .l, etc) 211 uint8_t op_count; ///< number of operands for the instruction 212 } cs_m68k; 213 214 /// M68K instruction 215 typedef enum m68k_insn { 216 M68K_INS_INVALID = 0, 217 218 M68K_INS_ABCD, 219 M68K_INS_ADD, 220 M68K_INS_ADDA, 221 M68K_INS_ADDI, 222 M68K_INS_ADDQ, 223 M68K_INS_ADDX, 224 M68K_INS_AND, 225 M68K_INS_ANDI, 226 M68K_INS_ASL, 227 M68K_INS_ASR, 228 M68K_INS_BHS, 229 M68K_INS_BLO, 230 M68K_INS_BHI, 231 M68K_INS_BLS, 232 M68K_INS_BCC, 233 M68K_INS_BCS, 234 M68K_INS_BNE, 235 M68K_INS_BEQ, 236 M68K_INS_BVC, 237 M68K_INS_BVS, 238 M68K_INS_BPL, 239 M68K_INS_BMI, 240 M68K_INS_BGE, 241 M68K_INS_BLT, 242 M68K_INS_BGT, 243 M68K_INS_BLE, 244 M68K_INS_BRA, 245 M68K_INS_BSR, 246 M68K_INS_BCHG, 247 M68K_INS_BCLR, 248 M68K_INS_BSET, 249 M68K_INS_BTST, 250 M68K_INS_BFCHG, 251 M68K_INS_BFCLR, 252 M68K_INS_BFEXTS, 253 M68K_INS_BFEXTU, 254 M68K_INS_BFFFO, 255 M68K_INS_BFINS, 256 M68K_INS_BFSET, 257 M68K_INS_BFTST, 258 M68K_INS_BKPT, 259 M68K_INS_CALLM, 260 M68K_INS_CAS, 261 M68K_INS_CAS2, 262 M68K_INS_CHK, 263 M68K_INS_CHK2, 264 M68K_INS_CLR, 265 M68K_INS_CMP, 266 M68K_INS_CMPA, 267 M68K_INS_CMPI, 268 M68K_INS_CMPM, 269 M68K_INS_CMP2, 270 M68K_INS_CINVL, 271 M68K_INS_CINVP, 272 M68K_INS_CINVA, 273 M68K_INS_CPUSHL, 274 M68K_INS_CPUSHP, 275 M68K_INS_CPUSHA, 276 M68K_INS_DBT, 277 M68K_INS_DBF, 278 M68K_INS_DBHI, 279 M68K_INS_DBLS, 280 M68K_INS_DBCC, 281 M68K_INS_DBCS, 282 M68K_INS_DBNE, 283 M68K_INS_DBEQ, 284 M68K_INS_DBVC, 285 M68K_INS_DBVS, 286 M68K_INS_DBPL, 287 M68K_INS_DBMI, 288 M68K_INS_DBGE, 289 M68K_INS_DBLT, 290 M68K_INS_DBGT, 291 M68K_INS_DBLE, 292 M68K_INS_DBRA, 293 M68K_INS_DIVS, 294 M68K_INS_DIVSL, 295 M68K_INS_DIVU, 296 M68K_INS_DIVUL, 297 M68K_INS_EOR, 298 M68K_INS_EORI, 299 M68K_INS_EXG, 300 M68K_INS_EXT, 301 M68K_INS_EXTB, 302 M68K_INS_FABS, 303 M68K_INS_FSABS, 304 M68K_INS_FDABS, 305 M68K_INS_FACOS, 306 M68K_INS_FADD, 307 M68K_INS_FSADD, 308 M68K_INS_FDADD, 309 M68K_INS_FASIN, 310 M68K_INS_FATAN, 311 M68K_INS_FATANH, 312 M68K_INS_FBF, 313 M68K_INS_FBEQ, 314 M68K_INS_FBOGT, 315 M68K_INS_FBOGE, 316 M68K_INS_FBOLT, 317 M68K_INS_FBOLE, 318 M68K_INS_FBOGL, 319 M68K_INS_FBOR, 320 M68K_INS_FBUN, 321 M68K_INS_FBUEQ, 322 M68K_INS_FBUGT, 323 M68K_INS_FBUGE, 324 M68K_INS_FBULT, 325 M68K_INS_FBULE, 326 M68K_INS_FBNE, 327 M68K_INS_FBT, 328 M68K_INS_FBSF, 329 M68K_INS_FBSEQ, 330 M68K_INS_FBGT, 331 M68K_INS_FBGE, 332 M68K_INS_FBLT, 333 M68K_INS_FBLE, 334 M68K_INS_FBGL, 335 M68K_INS_FBGLE, 336 M68K_INS_FBNGLE, 337 M68K_INS_FBNGL, 338 M68K_INS_FBNLE, 339 M68K_INS_FBNLT, 340 M68K_INS_FBNGE, 341 M68K_INS_FBNGT, 342 M68K_INS_FBSNE, 343 M68K_INS_FBST, 344 M68K_INS_FCMP, 345 M68K_INS_FCOS, 346 M68K_INS_FCOSH, 347 M68K_INS_FDBF, 348 M68K_INS_FDBEQ, 349 M68K_INS_FDBOGT, 350 M68K_INS_FDBOGE, 351 M68K_INS_FDBOLT, 352 M68K_INS_FDBOLE, 353 M68K_INS_FDBOGL, 354 M68K_INS_FDBOR, 355 M68K_INS_FDBUN, 356 M68K_INS_FDBUEQ, 357 M68K_INS_FDBUGT, 358 M68K_INS_FDBUGE, 359 M68K_INS_FDBULT, 360 M68K_INS_FDBULE, 361 M68K_INS_FDBNE, 362 M68K_INS_FDBT, 363 M68K_INS_FDBSF, 364 M68K_INS_FDBSEQ, 365 M68K_INS_FDBGT, 366 M68K_INS_FDBGE, 367 M68K_INS_FDBLT, 368 M68K_INS_FDBLE, 369 M68K_INS_FDBGL, 370 M68K_INS_FDBGLE, 371 M68K_INS_FDBNGLE, 372 M68K_INS_FDBNGL, 373 M68K_INS_FDBNLE, 374 M68K_INS_FDBNLT, 375 M68K_INS_FDBNGE, 376 M68K_INS_FDBNGT, 377 M68K_INS_FDBSNE, 378 M68K_INS_FDBST, 379 M68K_INS_FDIV, 380 M68K_INS_FSDIV, 381 M68K_INS_FDDIV, 382 M68K_INS_FETOX, 383 M68K_INS_FETOXM1, 384 M68K_INS_FGETEXP, 385 M68K_INS_FGETMAN, 386 M68K_INS_FINT, 387 M68K_INS_FINTRZ, 388 M68K_INS_FLOG10, 389 M68K_INS_FLOG2, 390 M68K_INS_FLOGN, 391 M68K_INS_FLOGNP1, 392 M68K_INS_FMOD, 393 M68K_INS_FMOVE, 394 M68K_INS_FSMOVE, 395 M68K_INS_FDMOVE, 396 M68K_INS_FMOVECR, 397 M68K_INS_FMOVEM, 398 M68K_INS_FMUL, 399 M68K_INS_FSMUL, 400 M68K_INS_FDMUL, 401 M68K_INS_FNEG, 402 M68K_INS_FSNEG, 403 M68K_INS_FDNEG, 404 M68K_INS_FNOP, 405 M68K_INS_FREM, 406 M68K_INS_FRESTORE, 407 M68K_INS_FSAVE, 408 M68K_INS_FSCALE, 409 M68K_INS_FSGLDIV, 410 M68K_INS_FSGLMUL, 411 M68K_INS_FSIN, 412 M68K_INS_FSINCOS, 413 M68K_INS_FSINH, 414 M68K_INS_FSQRT, 415 M68K_INS_FSSQRT, 416 M68K_INS_FDSQRT, 417 M68K_INS_FSF, 418 M68K_INS_FSBEQ, 419 M68K_INS_FSOGT, 420 M68K_INS_FSOGE, 421 M68K_INS_FSOLT, 422 M68K_INS_FSOLE, 423 M68K_INS_FSOGL, 424 M68K_INS_FSOR, 425 M68K_INS_FSUN, 426 M68K_INS_FSUEQ, 427 M68K_INS_FSUGT, 428 M68K_INS_FSUGE, 429 M68K_INS_FSULT, 430 M68K_INS_FSULE, 431 M68K_INS_FSNE, 432 M68K_INS_FST, 433 M68K_INS_FSSF, 434 M68K_INS_FSSEQ, 435 M68K_INS_FSGT, 436 M68K_INS_FSGE, 437 M68K_INS_FSLT, 438 M68K_INS_FSLE, 439 M68K_INS_FSGL, 440 M68K_INS_FSGLE, 441 M68K_INS_FSNGLE, 442 M68K_INS_FSNGL, 443 M68K_INS_FSNLE, 444 M68K_INS_FSNLT, 445 M68K_INS_FSNGE, 446 M68K_INS_FSNGT, 447 M68K_INS_FSSNE, 448 M68K_INS_FSST, 449 M68K_INS_FSUB, 450 M68K_INS_FSSUB, 451 M68K_INS_FDSUB, 452 M68K_INS_FTAN, 453 M68K_INS_FTANH, 454 M68K_INS_FTENTOX, 455 M68K_INS_FTRAPF, 456 M68K_INS_FTRAPEQ, 457 M68K_INS_FTRAPOGT, 458 M68K_INS_FTRAPOGE, 459 M68K_INS_FTRAPOLT, 460 M68K_INS_FTRAPOLE, 461 M68K_INS_FTRAPOGL, 462 M68K_INS_FTRAPOR, 463 M68K_INS_FTRAPUN, 464 M68K_INS_FTRAPUEQ, 465 M68K_INS_FTRAPUGT, 466 M68K_INS_FTRAPUGE, 467 M68K_INS_FTRAPULT, 468 M68K_INS_FTRAPULE, 469 M68K_INS_FTRAPNE, 470 M68K_INS_FTRAPT, 471 M68K_INS_FTRAPSF, 472 M68K_INS_FTRAPSEQ, 473 M68K_INS_FTRAPGT, 474 M68K_INS_FTRAPGE, 475 M68K_INS_FTRAPLT, 476 M68K_INS_FTRAPLE, 477 M68K_INS_FTRAPGL, 478 M68K_INS_FTRAPGLE, 479 M68K_INS_FTRAPNGLE, 480 M68K_INS_FTRAPNGL, 481 M68K_INS_FTRAPNLE, 482 M68K_INS_FTRAPNLT, 483 M68K_INS_FTRAPNGE, 484 M68K_INS_FTRAPNGT, 485 M68K_INS_FTRAPSNE, 486 M68K_INS_FTRAPST, 487 M68K_INS_FTST, 488 M68K_INS_FTWOTOX, 489 M68K_INS_HALT, 490 M68K_INS_ILLEGAL, 491 M68K_INS_JMP, 492 M68K_INS_JSR, 493 M68K_INS_LEA, 494 M68K_INS_LINK, 495 M68K_INS_LPSTOP, 496 M68K_INS_LSL, 497 M68K_INS_LSR, 498 M68K_INS_MOVE, 499 M68K_INS_MOVEA, 500 M68K_INS_MOVEC, 501 M68K_INS_MOVEM, 502 M68K_INS_MOVEP, 503 M68K_INS_MOVEQ, 504 M68K_INS_MOVES, 505 M68K_INS_MOVE16, 506 M68K_INS_MULS, 507 M68K_INS_MULU, 508 M68K_INS_NBCD, 509 M68K_INS_NEG, 510 M68K_INS_NEGX, 511 M68K_INS_NOP, 512 M68K_INS_NOT, 513 M68K_INS_OR, 514 M68K_INS_ORI, 515 M68K_INS_PACK, 516 M68K_INS_PEA, 517 M68K_INS_PFLUSH, 518 M68K_INS_PFLUSHA, 519 M68K_INS_PFLUSHAN, 520 M68K_INS_PFLUSHN, 521 M68K_INS_PLOADR, 522 M68K_INS_PLOADW, 523 M68K_INS_PLPAR, 524 M68K_INS_PLPAW, 525 M68K_INS_PMOVE, 526 M68K_INS_PMOVEFD, 527 M68K_INS_PTESTR, 528 M68K_INS_PTESTW, 529 M68K_INS_PULSE, 530 M68K_INS_REMS, 531 M68K_INS_REMU, 532 M68K_INS_RESET, 533 M68K_INS_ROL, 534 M68K_INS_ROR, 535 M68K_INS_ROXL, 536 M68K_INS_ROXR, 537 M68K_INS_RTD, 538 M68K_INS_RTE, 539 M68K_INS_RTM, 540 M68K_INS_RTR, 541 M68K_INS_RTS, 542 M68K_INS_SBCD, 543 M68K_INS_ST, 544 M68K_INS_SF, 545 M68K_INS_SHI, 546 M68K_INS_SLS, 547 M68K_INS_SCC, 548 M68K_INS_SHS, 549 M68K_INS_SCS, 550 M68K_INS_SLO, 551 M68K_INS_SNE, 552 M68K_INS_SEQ, 553 M68K_INS_SVC, 554 M68K_INS_SVS, 555 M68K_INS_SPL, 556 M68K_INS_SMI, 557 M68K_INS_SGE, 558 M68K_INS_SLT, 559 M68K_INS_SGT, 560 M68K_INS_SLE, 561 M68K_INS_STOP, 562 M68K_INS_SUB, 563 M68K_INS_SUBA, 564 M68K_INS_SUBI, 565 M68K_INS_SUBQ, 566 M68K_INS_SUBX, 567 M68K_INS_SWAP, 568 M68K_INS_TAS, 569 M68K_INS_TRAP, 570 M68K_INS_TRAPV, 571 M68K_INS_TRAPT, 572 M68K_INS_TRAPF, 573 M68K_INS_TRAPHI, 574 M68K_INS_TRAPLS, 575 M68K_INS_TRAPCC, 576 M68K_INS_TRAPHS, 577 M68K_INS_TRAPCS, 578 M68K_INS_TRAPLO, 579 M68K_INS_TRAPNE, 580 M68K_INS_TRAPEQ, 581 M68K_INS_TRAPVC, 582 M68K_INS_TRAPVS, 583 M68K_INS_TRAPPL, 584 M68K_INS_TRAPMI, 585 M68K_INS_TRAPGE, 586 M68K_INS_TRAPLT, 587 M68K_INS_TRAPGT, 588 M68K_INS_TRAPLE, 589 M68K_INS_TST, 590 M68K_INS_UNLK, 591 M68K_INS_UNPK, 592 M68K_INS_ENDING, // <-- mark the end of the list of instructions 593 } m68k_insn; 594 595 /// Group of M68K instructions 596 typedef enum m68k_group_type { 597 M68K_GRP_INVALID = 0, ///< CS_GRUP_INVALID 598 M68K_GRP_JUMP, ///< = CS_GRP_JUMP 599 M68K_GRP_RET = 3, ///< = CS_GRP_RET 600 M68K_GRP_IRET = 5, ///< = CS_GRP_IRET 601 M68K_GRP_BRANCH_RELATIVE = 7, ///< = CS_GRP_BRANCH_RELATIVE 602 603 M68K_GRP_ENDING,// <-- mark the end of the list of groups 604 } m68k_group_type; 605 606 #ifdef __cplusplus 607 } 608 #endif 609 610 #endif 611