/*
 *      Interactive disassembler (IDA).
 *      Copyright (c) 1990-98 by Ilfak Guilfanov.
 *      ALL RIGHTS RESERVED.
 *                              E-mail: ig@estar.msk.su
 *                              FIDO:   2:5020/209
 *
 *
 *      TMS320C6xx - VLIW (very long instruction word) architecture
 *
 */

#ifndef _TMS6_HPP
#define _TMS6_HPP

#include "../idaidp.hpp"
#include "ins.hpp"

//---------------------------------
// Functional units:

enum funit_t {
  FU_NONE,                      // No unit (NOP, IDLE)
  FU_L1, FU_L2,                 // 32/40-bit arithmetic and compare operations
                                // Leftmost 1 or 0 bit counting for 32 bits
                                // Normalization count for 32 and 40 bits
                                // 32-bit logical operations

  FU_S1, FU_S2,                 // 32-bit arithmetic operations
                                // 32/40-bit shifts and 32-bit bit-field operations
                                // 32-bit logical operations
                                // Branches
                                // Constant generation
                                // Register transfers to/from the control register file (.S2 only)

  FU_M1, FU_M2,                 // 16 x 16 bit multiply operations

  FU_D1, FU_D2,                 // 32-bit add, subtract, linear and circular address calculation
                                // Loads and stores with a 5-bit constant offset
                                // Loads and stores with 15-bit constant offset (.D2 only)
};

//---------------------------------
// Operand types:
#define o_regpair       o_idpspec0      // Register pair (A1:A0..B15:B14)
                                        // Register pair is denoted by its
                                        // even register in op.reg
                                        // (Odd register keeps MSB)

// o_phrase: the second register is held in secreg (specflag1)
#define secreg          specflag1
// o_phrase, o_displ: mode
#define mode            specflag2

#define src2            specflag2       // for field instructions

//------------------------------------------------------------------
#define funit           segpref            // Functional unit for insn
#define cond            auxpref_chars.low  // The condition code of instruction
#define cflags          auxpref_chars.high // Various bit definitions:
#  define aux_para      0x0001  // parallel execution with the next insn
#  define aux_src2      0x0002  // src2 register for immediate form of
                                // field instructions is present at "Op1.src2"
#  define aux_xp        0x0004  // X path is used
#  define aux_pseudo    0x0008  // Pseudo instruction

//------------------------------------------------------------------
// condition codes:
#define cAL  0x0 // unconditional
#define cB0  0x2 // B0
#define cnB0 0x3 // !B0
#define cB1  0x4 // B1
#define cnB1 0x5 // !B1
#define cB2  0x6 // B2
#define cnB2 0x7 // !B2
#define cA1  0x8 // A1
#define cnA1 0x9 // !A1
#define cA2  0xA // A2
#define cnA2 0xB // !A2

//------------------------------------------------------------------
// Bit definitions. Just for convenience:
#define BIT0    0x00000001L
#define BIT1    0x00000002L
#define BIT2    0x00000004L
#define BIT3    0x00000008L
#define BIT4    0x00000010L
#define BIT5    0x00000020L
#define BIT6    0x00000040L
#define BIT7    0x00000080L
#define BIT8    0x00000100L
#define BIT9    0x00000200L
#define BIT10   0x00000400L
#define BIT11   0x00000800L
#define BIT12   0x00001000L
#define BIT13   0x00002000L
#define BIT14   0x00004000L
#define BIT15   0x00008000L
#define BIT16   0x00010000L
#define BIT17   0x00020000L
#define BIT18   0x00040000L
#define BIT19   0x00080000L
#define BIT20   0x00100000L
#define BIT21   0x00200000L
#define BIT22   0x00400000L
#define BIT23   0x00800000L
#define BIT24   0x01000000L
#define BIT25   0x02000000L
#define BIT26   0x04000000L
#define BIT27   0x08000000L
#define BIT28   0x10000000L
#define BIT29   0x20000000L
#define BIT30   0x40000000L
#define BIT31   0x80000000L

//------------------------------------------------------------------
enum RegNo {
 rA0, rA1,  rA2,  rA3,  rA4,  rA5,  rA6,  rA7,
 rA8, rA9, rA10, rA11, rA12, rA13, rA14, rA15,
 rB0, rB1,  rB2,  rB3,  rB4,  rB5,  rB6,  rB7,
 rB8, rB9, rB10, rB11, rB12, rB13, rB14, rB15,
 rAMR,
 rCSR,
 rIFR,
 rISR,
 rICR,
 rIER,
 rISTP,
 rIRP,
 rNRP,
 rACR,
 rADR,
 rPCE1,
 rFADCR,
 rFAUCR,
 rFMCR,
 rVcs, rVds,            // virtual registers for code and data segments
};

//------------------------------------------------------------------
void header(void);
void footer(void);

void segstart(ea_t ea);
void segend(ea_t ea);

void out(void);
bool outspec(ea_t ea, uchar segtype);
void data(ea_t ea);

int  ana(void);
int  emu(void);
bool outop(op_t &op);

int  is_align_insn(ea_t ea);

ea_t find_first_insn_in_packet(ea_t ea);

extern netnode tnode;

#endif // _TMS6_HPP
