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
8extern "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
20typedef 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
79typedef 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
112typedef 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
126typedef 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
141typedef 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
148typedef 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/// Register pair in one operand.
154typedef struct cs_m68k_op_reg_pair {
155 m68k_reg reg_0;
156 m68k_reg reg_1;
157} cs_m68k_op_reg_pair;
158
159/// Instruction operand
160typedef struct cs_m68k_op {
161 union {
162 uint64_t imm; ///< immediate value for IMM operand
163 double dimm; ///< double imm
164 float simm; ///< float imm
165 m68k_reg reg; ///< register value for REG operand
166 cs_m68k_op_reg_pair reg_pair; ///< register pair in one operand
167 };
168
169 m68k_op_mem mem; ///< data when operand is targeting memory
170 m68k_op_br_disp br_disp; ///< data when operand is a branch displacement
171 uint32_t register_bits; ///< register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
172 m68k_op_type type;
173 m68k_address_mode address_mode; ///< M68K addressing mode for this op
174} cs_m68k_op;
175
176/// Operation size of the CPU instructions
177typedef enum m68k_cpu_size {
178 M68K_CPU_SIZE_NONE = 0, ///< unsized or unspecified
179 M68K_CPU_SIZE_BYTE = 1, ///< 1 byte in size
180 M68K_CPU_SIZE_WORD = 2, ///< 2 bytes in size
181 M68K_CPU_SIZE_LONG = 4, ///< 4 bytes in size
182} m68k_cpu_size;
183
184/// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed)
185typedef enum m68k_fpu_size {
186 M68K_FPU_SIZE_NONE = 0, ///< unsized like fsave/frestore
187 M68K_FPU_SIZE_SINGLE = 4, ///< 4 byte in size (single float)
188 M68K_FPU_SIZE_DOUBLE = 8, ///< 8 byte in size (double)
189 M68K_FPU_SIZE_EXTENDED = 12, ///< 12 byte in size (extended real format)
190} m68k_fpu_size;
191
192/// Type of size that is being used for the current instruction
193typedef enum m68k_size_type {
194 M68K_SIZE_TYPE_INVALID = 0,
195
196 M68K_SIZE_TYPE_CPU,
197 M68K_SIZE_TYPE_FPU,
198} m68k_size_type;
199
200/// Operation size of the current instruction (NOT the actually size of instruction)
201typedef struct m68k_op_size {
202 m68k_size_type type;
203 union {
204 m68k_cpu_size cpu_size;
205 m68k_fpu_size fpu_size;
206 };
207} m68k_op_size;
208
209/// The M68K instruction and it's operands
210typedef struct cs_m68k {
211 // Number of operands of this instruction or 0 when instruction has no operand.
212 cs_m68k_op operands[M68K_OPERAND_COUNT]; ///< operands for this instruction.
213 m68k_op_size op_size; ///< size of data operand works on in bytes (.b, .w, .l, etc)
214 uint8_t op_count; ///< number of operands for the instruction
215} cs_m68k;
216
217/// M68K instruction
218typedef enum m68k_insn {
219 M68K_INS_INVALID = 0,
220
221 M68K_INS_ABCD,
222 M68K_INS_ADD,
223 M68K_INS_ADDA,
224 M68K_INS_ADDI,
225 M68K_INS_ADDQ,
226 M68K_INS_ADDX,
227 M68K_INS_AND,
228 M68K_INS_ANDI,
229 M68K_INS_ASL,
230 M68K_INS_ASR,
231 M68K_INS_BHS,
232 M68K_INS_BLO,
233 M68K_INS_BHI,
234 M68K_INS_BLS,
235 M68K_INS_BCC,
236 M68K_INS_BCS,
237 M68K_INS_BNE,
238 M68K_INS_BEQ,
239 M68K_INS_BVC,
240 M68K_INS_BVS,
241 M68K_INS_BPL,
242 M68K_INS_BMI,
243 M68K_INS_BGE,
244 M68K_INS_BLT,
245 M68K_INS_BGT,
246 M68K_INS_BLE,
247 M68K_INS_BRA,
248 M68K_INS_BSR,
249 M68K_INS_BCHG,
250 M68K_INS_BCLR,
251 M68K_INS_BSET,
252 M68K_INS_BTST,
253 M68K_INS_BFCHG,
254 M68K_INS_BFCLR,
255 M68K_INS_BFEXTS,
256 M68K_INS_BFEXTU,
257 M68K_INS_BFFFO,
258 M68K_INS_BFINS,
259 M68K_INS_BFSET,
260 M68K_INS_BFTST,
261 M68K_INS_BKPT,
262 M68K_INS_CALLM,
263 M68K_INS_CAS,
264 M68K_INS_CAS2,
265 M68K_INS_CHK,
266 M68K_INS_CHK2,
267 M68K_INS_CLR,
268 M68K_INS_CMP,
269 M68K_INS_CMPA,
270 M68K_INS_CMPI,
271 M68K_INS_CMPM,
272 M68K_INS_CMP2,
273 M68K_INS_CINVL,
274 M68K_INS_CINVP,
275 M68K_INS_CINVA,
276 M68K_INS_CPUSHL,
277 M68K_INS_CPUSHP,
278 M68K_INS_CPUSHA,
279 M68K_INS_DBT,
280 M68K_INS_DBF,
281 M68K_INS_DBHI,
282 M68K_INS_DBLS,
283 M68K_INS_DBCC,
284 M68K_INS_DBCS,
285 M68K_INS_DBNE,
286 M68K_INS_DBEQ,
287 M68K_INS_DBVC,
288 M68K_INS_DBVS,
289 M68K_INS_DBPL,
290 M68K_INS_DBMI,
291 M68K_INS_DBGE,
292 M68K_INS_DBLT,
293 M68K_INS_DBGT,
294 M68K_INS_DBLE,
295 M68K_INS_DBRA,
296 M68K_INS_DIVS,
297 M68K_INS_DIVSL,
298 M68K_INS_DIVU,
299 M68K_INS_DIVUL,
300 M68K_INS_EOR,
301 M68K_INS_EORI,
302 M68K_INS_EXG,
303 M68K_INS_EXT,
304 M68K_INS_EXTB,
305 M68K_INS_FABS,
306 M68K_INS_FSABS,
307 M68K_INS_FDABS,
308 M68K_INS_FACOS,
309 M68K_INS_FADD,
310 M68K_INS_FSADD,
311 M68K_INS_FDADD,
312 M68K_INS_FASIN,
313 M68K_INS_FATAN,
314 M68K_INS_FATANH,
315 M68K_INS_FBF,
316 M68K_INS_FBEQ,
317 M68K_INS_FBOGT,
318 M68K_INS_FBOGE,
319 M68K_INS_FBOLT,
320 M68K_INS_FBOLE,
321 M68K_INS_FBOGL,
322 M68K_INS_FBOR,
323 M68K_INS_FBUN,
324 M68K_INS_FBUEQ,
325 M68K_INS_FBUGT,
326 M68K_INS_FBUGE,
327 M68K_INS_FBULT,
328 M68K_INS_FBULE,
329 M68K_INS_FBNE,
330 M68K_INS_FBT,
331 M68K_INS_FBSF,
332 M68K_INS_FBSEQ,
333 M68K_INS_FBGT,
334 M68K_INS_FBGE,
335 M68K_INS_FBLT,
336 M68K_INS_FBLE,
337 M68K_INS_FBGL,
338 M68K_INS_FBGLE,
339 M68K_INS_FBNGLE,
340 M68K_INS_FBNGL,
341 M68K_INS_FBNLE,
342 M68K_INS_FBNLT,
343 M68K_INS_FBNGE,
344 M68K_INS_FBNGT,
345 M68K_INS_FBSNE,
346 M68K_INS_FBST,
347 M68K_INS_FCMP,
348 M68K_INS_FCOS,
349 M68K_INS_FCOSH,
350 M68K_INS_FDBF,
351 M68K_INS_FDBEQ,
352 M68K_INS_FDBOGT,
353 M68K_INS_FDBOGE,
354 M68K_INS_FDBOLT,
355 M68K_INS_FDBOLE,
356 M68K_INS_FDBOGL,
357 M68K_INS_FDBOR,
358 M68K_INS_FDBUN,
359 M68K_INS_FDBUEQ,
360 M68K_INS_FDBUGT,
361 M68K_INS_FDBUGE,
362 M68K_INS_FDBULT,
363 M68K_INS_FDBULE,
364 M68K_INS_FDBNE,
365 M68K_INS_FDBT,
366 M68K_INS_FDBSF,
367 M68K_INS_FDBSEQ,
368 M68K_INS_FDBGT,
369 M68K_INS_FDBGE,
370 M68K_INS_FDBLT,
371 M68K_INS_FDBLE,
372 M68K_INS_FDBGL,
373 M68K_INS_FDBGLE,
374 M68K_INS_FDBNGLE,
375 M68K_INS_FDBNGL,
376 M68K_INS_FDBNLE,
377 M68K_INS_FDBNLT,
378 M68K_INS_FDBNGE,
379 M68K_INS_FDBNGT,
380 M68K_INS_FDBSNE,
381 M68K_INS_FDBST,
382 M68K_INS_FDIV,
383 M68K_INS_FSDIV,
384 M68K_INS_FDDIV,
385 M68K_INS_FETOX,
386 M68K_INS_FETOXM1,
387 M68K_INS_FGETEXP,
388 M68K_INS_FGETMAN,
389 M68K_INS_FINT,
390 M68K_INS_FINTRZ,
391 M68K_INS_FLOG10,
392 M68K_INS_FLOG2,
393 M68K_INS_FLOGN,
394 M68K_INS_FLOGNP1,
395 M68K_INS_FMOD,
396 M68K_INS_FMOVE,
397 M68K_INS_FSMOVE,
398 M68K_INS_FDMOVE,
399 M68K_INS_FMOVECR,
400 M68K_INS_FMOVEM,
401 M68K_INS_FMUL,
402 M68K_INS_FSMUL,
403 M68K_INS_FDMUL,
404 M68K_INS_FNEG,
405 M68K_INS_FSNEG,
406 M68K_INS_FDNEG,
407 M68K_INS_FNOP,
408 M68K_INS_FREM,
409 M68K_INS_FRESTORE,
410 M68K_INS_FSAVE,
411 M68K_INS_FSCALE,
412 M68K_INS_FSGLDIV,
413 M68K_INS_FSGLMUL,
414 M68K_INS_FSIN,
415 M68K_INS_FSINCOS,
416 M68K_INS_FSINH,
417 M68K_INS_FSQRT,
418 M68K_INS_FSSQRT,
419 M68K_INS_FDSQRT,
420 M68K_INS_FSF,
421 M68K_INS_FSBEQ,
422 M68K_INS_FSOGT,
423 M68K_INS_FSOGE,
424 M68K_INS_FSOLT,
425 M68K_INS_FSOLE,
426 M68K_INS_FSOGL,
427 M68K_INS_FSOR,
428 M68K_INS_FSUN,
429 M68K_INS_FSUEQ,
430 M68K_INS_FSUGT,
431 M68K_INS_FSUGE,
432 M68K_INS_FSULT,
433 M68K_INS_FSULE,
434 M68K_INS_FSNE,
435 M68K_INS_FST,
436 M68K_INS_FSSF,
437 M68K_INS_FSSEQ,
438 M68K_INS_FSGT,
439 M68K_INS_FSGE,
440 M68K_INS_FSLT,
441 M68K_INS_FSLE,
442 M68K_INS_FSGL,
443 M68K_INS_FSGLE,
444 M68K_INS_FSNGLE,
445 M68K_INS_FSNGL,
446 M68K_INS_FSNLE,
447 M68K_INS_FSNLT,
448 M68K_INS_FSNGE,
449 M68K_INS_FSNGT,
450 M68K_INS_FSSNE,
451 M68K_INS_FSST,
452 M68K_INS_FSUB,
453 M68K_INS_FSSUB,
454 M68K_INS_FDSUB,
455 M68K_INS_FTAN,
456 M68K_INS_FTANH,
457 M68K_INS_FTENTOX,
458 M68K_INS_FTRAPF,
459 M68K_INS_FTRAPEQ,
460 M68K_INS_FTRAPOGT,
461 M68K_INS_FTRAPOGE,
462 M68K_INS_FTRAPOLT,
463 M68K_INS_FTRAPOLE,
464 M68K_INS_FTRAPOGL,
465 M68K_INS_FTRAPOR,
466 M68K_INS_FTRAPUN,
467 M68K_INS_FTRAPUEQ,
468 M68K_INS_FTRAPUGT,
469 M68K_INS_FTRAPUGE,
470 M68K_INS_FTRAPULT,
471 M68K_INS_FTRAPULE,
472 M68K_INS_FTRAPNE,
473 M68K_INS_FTRAPT,
474 M68K_INS_FTRAPSF,
475 M68K_INS_FTRAPSEQ,
476 M68K_INS_FTRAPGT,
477 M68K_INS_FTRAPGE,
478 M68K_INS_FTRAPLT,
479 M68K_INS_FTRAPLE,
480 M68K_INS_FTRAPGL,
481 M68K_INS_FTRAPGLE,
482 M68K_INS_FTRAPNGLE,
483 M68K_INS_FTRAPNGL,
484 M68K_INS_FTRAPNLE,
485 M68K_INS_FTRAPNLT,
486 M68K_INS_FTRAPNGE,
487 M68K_INS_FTRAPNGT,
488 M68K_INS_FTRAPSNE,
489 M68K_INS_FTRAPST,
490 M68K_INS_FTST,
491 M68K_INS_FTWOTOX,
492 M68K_INS_HALT,
493 M68K_INS_ILLEGAL,
494 M68K_INS_JMP,
495 M68K_INS_JSR,
496 M68K_INS_LEA,
497 M68K_INS_LINK,
498 M68K_INS_LPSTOP,
499 M68K_INS_LSL,
500 M68K_INS_LSR,
501 M68K_INS_MOVE,
502 M68K_INS_MOVEA,
503 M68K_INS_MOVEC,
504 M68K_INS_MOVEM,
505 M68K_INS_MOVEP,
506 M68K_INS_MOVEQ,
507 M68K_INS_MOVES,
508 M68K_INS_MOVE16,
509 M68K_INS_MULS,
510 M68K_INS_MULU,
511 M68K_INS_NBCD,
512 M68K_INS_NEG,
513 M68K_INS_NEGX,
514 M68K_INS_NOP,
515 M68K_INS_NOT,
516 M68K_INS_OR,
517 M68K_INS_ORI,
518 M68K_INS_PACK,
519 M68K_INS_PEA,
520 M68K_INS_PFLUSH,
521 M68K_INS_PFLUSHA,
522 M68K_INS_PFLUSHAN,
523 M68K_INS_PFLUSHN,
524 M68K_INS_PLOADR,
525 M68K_INS_PLOADW,
526 M68K_INS_PLPAR,
527 M68K_INS_PLPAW,
528 M68K_INS_PMOVE,
529 M68K_INS_PMOVEFD,
530 M68K_INS_PTESTR,
531 M68K_INS_PTESTW,
532 M68K_INS_PULSE,
533 M68K_INS_REMS,
534 M68K_INS_REMU,
535 M68K_INS_RESET,
536 M68K_INS_ROL,
537 M68K_INS_ROR,
538 M68K_INS_ROXL,
539 M68K_INS_ROXR,
540 M68K_INS_RTD,
541 M68K_INS_RTE,
542 M68K_INS_RTM,
543 M68K_INS_RTR,
544 M68K_INS_RTS,
545 M68K_INS_SBCD,
546 M68K_INS_ST,
547 M68K_INS_SF,
548 M68K_INS_SHI,
549 M68K_INS_SLS,
550 M68K_INS_SCC,
551 M68K_INS_SHS,
552 M68K_INS_SCS,
553 M68K_INS_SLO,
554 M68K_INS_SNE,
555 M68K_INS_SEQ,
556 M68K_INS_SVC,
557 M68K_INS_SVS,
558 M68K_INS_SPL,
559 M68K_INS_SMI,
560 M68K_INS_SGE,
561 M68K_INS_SLT,
562 M68K_INS_SGT,
563 M68K_INS_SLE,
564 M68K_INS_STOP,
565 M68K_INS_SUB,
566 M68K_INS_SUBA,
567 M68K_INS_SUBI,
568 M68K_INS_SUBQ,
569 M68K_INS_SUBX,
570 M68K_INS_SWAP,
571 M68K_INS_TAS,
572 M68K_INS_TRAP,
573 M68K_INS_TRAPV,
574 M68K_INS_TRAPT,
575 M68K_INS_TRAPF,
576 M68K_INS_TRAPHI,
577 M68K_INS_TRAPLS,
578 M68K_INS_TRAPCC,
579 M68K_INS_TRAPHS,
580 M68K_INS_TRAPCS,
581 M68K_INS_TRAPLO,
582 M68K_INS_TRAPNE,
583 M68K_INS_TRAPEQ,
584 M68K_INS_TRAPVC,
585 M68K_INS_TRAPVS,
586 M68K_INS_TRAPPL,
587 M68K_INS_TRAPMI,
588 M68K_INS_TRAPGE,
589 M68K_INS_TRAPLT,
590 M68K_INS_TRAPGT,
591 M68K_INS_TRAPLE,
592 M68K_INS_TST,
593 M68K_INS_UNLK,
594 M68K_INS_UNPK,
595 M68K_INS_ENDING, // <-- mark the end of the list of instructions
596} m68k_insn;
597
598/// Group of M68K instructions
599typedef enum m68k_group_type {
600 M68K_GRP_INVALID = 0, ///< CS_GRUP_INVALID
601 M68K_GRP_JUMP, ///< = CS_GRP_JUMP
602 M68K_GRP_RET = 3, ///< = CS_GRP_RET
603 M68K_GRP_IRET = 5, ///< = CS_GRP_IRET
604 M68K_GRP_BRANCH_RELATIVE = 7, ///< = CS_GRP_BRANCH_RELATIVE
605
606 M68K_GRP_ENDING,// <-- mark the end of the list of groups
607} m68k_group_type;
608
609#ifdef __cplusplus
610}
611#endif
612
613#endif
614