export interface cs_tricore_op {
  type: TRICORE; // operand type
  reg?: TRICORE; // register value for REG operand
  imm?: number; // immediate value for IMM operand
  mem?: {
    // base/disp value for MEM operand
    base: number; // base register
    disp: number; // displacement/offset value
  };
  // This field is combined of cs_ac_type.
  access; // How is this operand accessed? (READ, WRITE or READ|WRITE)
}

export enum TRICORE {
  // Operand type for instruction's operands
  OP_INVALID = 0, // cs.OP_INVALID (Uninitialized).
  OP_REG = 1, // cs.OP_REG (Register operand).
  OP_IMM = 2, // cs.OP_IMM (Immediate operand).
  OP_MEM = 128, // cs.OP_MEM (Memory operand).

  OP_COUNT = 8,

  // TriCore registers
  REG_INVALID = 0,
  REG_FCX = 1,
  REG_PC = 2,
  REG_PCXI = 3,
  REG_PSW = 4,
  REG_A0 = 5,
  REG_A1 = 6,
  REG_A2 = 7,
  REG_A3 = 8,
  REG_A4 = 9,
  REG_A5 = 10,
  REG_A6 = 11,
  REG_A7 = 12,
  REG_A8 = 13,
  REG_A9 = 14,
  REG_A10 = 15,
  REG_A11 = 16,
  REG_A12 = 17,
  REG_A13 = 18,
  REG_A14 = 19,
  REG_A15 = 20,
  REG_D0 = 21,
  REG_D1 = 22,
  REG_D2 = 23,
  REG_D3 = 24,
  REG_D4 = 25,
  REG_D5 = 26,
  REG_D6 = 27,
  REG_D7 = 28,
  REG_D8 = 29,
  REG_D9 = 30,
  REG_D10 = 31,
  REG_D11 = 32,
  REG_D12 = 33,
  REG_D13 = 34,
  REG_D14 = 35,
  REG_D15 = 36,
  REG_E0 = 37,
  REG_E2 = 38,
  REG_E4 = 39,
  REG_E6 = 40,
  REG_E8 = 41,
  REG_E10 = 42,
  REG_E12 = 43,
  REG_E14 = 44,
  REG_P0 = 45,
  REG_P2 = 46,
  REG_P4 = 47,
  REG_P6 = 48,
  REG_P8 = 49,
  REG_P10 = 50,
  REG_P12 = 51,
  REG_P14 = 52,
  REG_A0_A1 = 53,
  REG_A2_A3 = 54,
  REG_A4_A5 = 55,
  REG_A6_A7 = 56,
  REG_A8_A9 = 57,
  REG_A10_A11 = 58,
  REG_A12_A13 = 59,
  REG_A14_A15 = 60,
  REG_ENDING = 61,

  // TriCore instruction
  INS_INVALID = 0,
  INS_XOR_T = 1,
  INS_ABSDIFS_B = 2,
  INS_ABSDIFS_H = 3,
  INS_ABSDIFS = 4,
  INS_ABSDIF_B = 5,
  INS_ABSDIF_H = 6,
  INS_ABSDIF = 7,
  INS_ABSS_B = 8,
  INS_ABSS_H = 9,
  INS_ABSS = 10,
  INS_ABS_B = 11,
  INS_ABS_H = 12,
  INS_ABS = 13,
  INS_ADDC = 14,
  INS_ADDIH_A = 15,
  INS_ADDIH = 16,
  INS_ADDI = 17,
  INS_ADDSC_AT = 18,
  INS_ADDSC_A = 19,
  INS_ADDS_BU = 20,
  INS_ADDS_B = 21,
  INS_ADDS_H = 22,
  INS_ADDS_HU = 23,
  INS_ADDS_U = 24,
  INS_ADDS = 25,
  INS_ADDX = 26,
  INS_ADD_A = 27,
  INS_ADD_B = 28,
  INS_ADD_F = 29,
  INS_ADD_H = 30,
  INS_ADD = 31,
  INS_ANDN_T = 32,
  INS_ANDN = 33,
  INS_AND_ANDN_T = 34,
  INS_AND_AND_T = 35,
  INS_AND_EQ = 36,
  INS_AND_GE_U = 37,
  INS_AND_GE = 38,
  INS_AND_LT_U = 39,
  INS_AND_LT = 40,
  INS_AND_NE = 41,
  INS_AND_NOR_T = 42,
  INS_AND_OR_T = 43,
  INS_AND_T = 44,
  INS_AND = 45,
  INS_BISR = 46,
  INS_BMERGE = 47,
  INS_BSPLIT = 48,
  INS_CACHEA_I = 49,
  INS_CACHEA_WI = 50,
  INS_CACHEA_W = 51,
  INS_CACHEI_I = 52,
  INS_CACHEI_WI = 53,
  INS_CACHEI_W = 54,
  INS_CADDN_A = 55,
  INS_CADDN = 56,
  INS_CADD_A = 57,
  INS_CADD = 58,
  INS_CALLA = 59,
  INS_CALLI = 60,
  INS_CALL = 61,
  INS_CLO_B = 62,
  INS_CLO_H = 63,
  INS_CLO = 64,
  INS_CLS_B = 65,
  INS_CLS_H = 66,
  INS_CLS = 67,
  INS_CLZ_B = 68,
  INS_CLZ_H = 69,
  INS_CLZ = 70,
  INS_CMOVN = 71,
  INS_CMOV = 72,
  INS_CMPSWAP_W = 73,
  INS_CMP_F = 74,
  INS_CRC32B_W = 75,
  INS_CRC32L_W = 76,
  INS_CRC32_B = 77,
  INS_CRCN = 78,
  INS_CSUBN_A = 79,
  INS_CSUBN = 80,
  INS_CSUB_A = 81,
  INS_CSUB = 82,
  INS_DEBUG = 83,
  INS_DEXTR = 84,
  INS_DIFSC_A = 85,
  INS_DISABLE = 86,
  INS_DIV_F = 87,
  INS_DIV_U = 88,
  INS_DIV = 89,
  INS_DSYNC = 90,
  INS_DVADJ = 91,
  INS_DVINIT_BU = 92,
  INS_DVINIT_B = 93,
  INS_DVINIT_HU = 94,
  INS_DVINIT_H = 95,
  INS_DVINIT_U = 96,
  INS_DVINIT = 97,
  INS_DVSTEP_U = 98,
  INS_DVSTEP = 99,
  INS_ENABLE = 100,
  INS_EQANY_B = 101,
  INS_EQANY_H = 102,
  INS_EQZ_A = 103,
  INS_EQ_A = 104,
  INS_EQ_B = 105,
  INS_EQ_H = 106,
  INS_EQ_W = 107,
  INS_EQ = 108,
  INS_EXTR_U = 109,
  INS_EXTR = 110,
  INS_FCALLA = 111,
  INS_FCALLI = 112,
  INS_FCALL = 113,
  INS_FRET = 114,
  INS_FTOHP = 115,
  INS_FTOIZ = 116,
  INS_FTOI = 117,
  INS_FTOQ31Z = 118,
  INS_FTOQ31 = 119,
  INS_FTOUZ = 120,
  INS_FTOU = 121,
  INS_GE_A = 122,
  INS_GE_U = 123,
  INS_GE = 124,
  INS_HPTOF = 125,
  INS_IMASK = 126,
  INS_INSERT = 127,
  INS_INSN_T = 128,
  INS_INS_T = 129,
  INS_ISYNC = 130,
  INS_ITOF = 131,
  INS_IXMAX_U = 132,
  INS_IXMAX = 133,
  INS_IXMIN_U = 134,
  INS_IXMIN = 135,
  INS_JA = 136,
  INS_JEQ_A = 137,
  INS_JEQ = 138,
  INS_JGEZ = 139,
  INS_JGE_U = 140,
  INS_JGE = 141,
  INS_JGTZ = 142,
  INS_JI = 143,
  INS_JLA = 144,
  INS_JLEZ = 145,
  INS_JLI = 146,
  INS_JLTZ = 147,
  INS_JLT_U = 148,
  INS_JLT = 149,
  INS_JL = 150,
  INS_JNED = 151,
  INS_JNEI = 152,
  INS_JNE_A = 153,
  INS_JNE = 154,
  INS_JNZ_A = 155,
  INS_JNZ_T = 156,
  INS_JNZ = 157,
  INS_JZ_A = 158,
  INS_JZ_T = 159,
  INS_JZ = 160,
  INS_J = 161,
  INS_LDLCX = 162,
  INS_LDMST = 163,
  INS_LDUCX = 164,
  INS_LD_A = 165,
  INS_LD_BU = 166,
  INS_LD_B = 167,
  INS_LD_DA = 168,
  INS_LD_D = 169,
  INS_LD_HU = 170,
  INS_LD_H = 171,
  INS_LD_Q = 172,
  INS_LD_W = 173,
  INS_LEA = 174,
  INS_LHA = 175,
  INS_LOOPU = 176,
  INS_LOOP = 177,
  INS_LT_A = 178,
  INS_LT_B = 179,
  INS_LT_BU = 180,
  INS_LT_H = 181,
  INS_LT_HU = 182,
  INS_LT_U = 183,
  INS_LT_W = 184,
  INS_LT_WU = 185,
  INS_LT = 186,
  INS_MADDMS_H = 187,
  INS_MADDMS_U = 188,
  INS_MADDMS = 189,
  INS_MADDM_H = 190,
  INS_MADDM_Q = 191,
  INS_MADDM_U = 192,
  INS_MADDM = 193,
  INS_MADDRS_H = 194,
  INS_MADDRS_Q = 195,
  INS_MADDR_H = 196,
  INS_MADDR_Q = 197,
  INS_MADDSUMS_H = 198,
  INS_MADDSUM_H = 199,
  INS_MADDSURS_H = 200,
  INS_MADDSUR_H = 201,
  INS_MADDSUS_H = 202,
  INS_MADDSU_H = 203,
  INS_MADDS_H = 204,
  INS_MADDS_Q = 205,
  INS_MADDS_U = 206,
  INS_MADDS = 207,
  INS_MADD_F = 208,
  INS_MADD_H = 209,
  INS_MADD_Q = 210,
  INS_MADD_U = 211,
  INS_MADD = 212,
  INS_MAX_B = 213,
  INS_MAX_BU = 214,
  INS_MAX_H = 215,
  INS_MAX_HU = 216,
  INS_MAX_U = 217,
  INS_MAX = 218,
  INS_MFCR = 219,
  INS_MIN_B = 220,
  INS_MIN_BU = 221,
  INS_MIN_H = 222,
  INS_MIN_HU = 223,
  INS_MIN_U = 224,
  INS_MIN = 225,
  INS_MOVH_A = 226,
  INS_MOVH = 227,
  INS_MOVZ_A = 228,
  INS_MOV_AA = 229,
  INS_MOV_A = 230,
  INS_MOV_D = 231,
  INS_MOV_U = 232,
  INS_MOV = 233,
  INS_MSUBADMS_H = 234,
  INS_MSUBADM_H = 235,
  INS_MSUBADRS_H = 236,
  INS_MSUBADR_H = 237,
  INS_MSUBADS_H = 238,
  INS_MSUBAD_H = 239,
  INS_MSUBMS_H = 240,
  INS_MSUBMS_U = 241,
  INS_MSUBMS = 242,
  INS_MSUBM_H = 243,
  INS_MSUBM_Q = 244,
  INS_MSUBM_U = 245,
  INS_MSUBM = 246,
  INS_MSUBRS_H = 247,
  INS_MSUBRS_Q = 248,
  INS_MSUBR_H = 249,
  INS_MSUBR_Q = 250,
  INS_MSUBS_H = 251,
  INS_MSUBS_Q = 252,
  INS_MSUBS_U = 253,
  INS_MSUBS = 254,
  INS_MSUB_F = 255,
  INS_MSUB_H = 256,
  INS_MSUB_Q = 257,
  INS_MSUB_U = 258,
  INS_MSUB = 259,
  INS_MTCR = 260,
  INS_MULMS_H = 261,
  INS_MULM_H = 262,
  INS_MULM_U = 263,
  INS_MULM = 264,
  INS_MULR_H = 265,
  INS_MULR_Q = 266,
  INS_MULS_U = 267,
  INS_MULS = 268,
  INS_MUL_F = 269,
  INS_MUL_H = 270,
  INS_MUL_Q = 271,
  INS_MUL_U = 272,
  INS_MUL = 273,
  INS_NAND_T = 274,
  INS_NAND = 275,
  INS_NEZ_A = 276,
  INS_NE_A = 277,
  INS_NE = 278,
  INS_NOP = 279,
  INS_NOR_T = 280,
  INS_NOR = 281,
  INS_NOT = 282,
  INS_ORN_T = 283,
  INS_ORN = 284,
  INS_OR_ANDN_T = 285,
  INS_OR_AND_T = 286,
  INS_OR_EQ = 287,
  INS_OR_GE_U = 288,
  INS_OR_GE = 289,
  INS_OR_LT_U = 290,
  INS_OR_LT = 291,
  INS_OR_NE = 292,
  INS_OR_NOR_T = 293,
  INS_OR_OR_T = 294,
  INS_OR_T = 295,
  INS_OR = 296,
  INS_PACK = 297,
  INS_PARITY = 298,
  INS_POPCNT_W = 299,
  INS_Q31TOF = 300,
  INS_QSEED_F = 301,
  INS_RESTORE = 302,
  INS_RET = 303,
  INS_RFE = 304,
  INS_RFM = 305,
  INS_RSLCX = 306,
  INS_RSTV = 307,
  INS_RSUBS_U = 308,
  INS_RSUBS = 309,
  INS_RSUB = 310,
  INS_SAT_BU = 311,
  INS_SAT_B = 312,
  INS_SAT_HU = 313,
  INS_SAT_H = 314,
  INS_SELN_A = 315,
  INS_SELN = 316,
  INS_SEL_A = 317,
  INS_SEL = 318,
  INS_SHAS = 319,
  INS_SHA_B = 320,
  INS_SHA_H = 321,
  INS_SHA = 322,
  INS_SHUFFLE = 323,
  INS_SH_ANDN_T = 324,
  INS_SH_AND_T = 325,
  INS_SH_B = 326,
  INS_SH_EQ = 327,
  INS_SH_GE_U = 328,
  INS_SH_GE = 329,
  INS_SH_H = 330,
  INS_SH_LT_U = 331,
  INS_SH_LT = 332,
  INS_SH_NAND_T = 333,
  INS_SH_NE = 334,
  INS_SH_NOR_T = 335,
  INS_SH_ORN_T = 336,
  INS_SH_OR_T = 337,
  INS_SH_XNOR_T = 338,
  INS_SH_XOR_T = 339,
  INS_SH = 340,
  INS_STLCX = 341,
  INS_STUCX = 342,
  INS_ST_A = 343,
  INS_ST_B = 344,
  INS_ST_DA = 345,
  INS_ST_D = 346,
  INS_ST_H = 347,
  INS_ST_Q = 348,
  INS_ST_T = 349,
  INS_ST_W = 350,
  INS_SUBC = 351,
  INS_SUBSC_A = 352,
  INS_SUBS_BU = 353,
  INS_SUBS_B = 354,
  INS_SUBS_HU = 355,
  INS_SUBS_H = 356,
  INS_SUBS_U = 357,
  INS_SUBS = 358,
  INS_SUBX = 359,
  INS_SUB_A = 360,
  INS_SUB_B = 361,
  INS_SUB_F = 362,
  INS_SUB_H = 363,
  INS_SUB = 364,
  INS_SVLCX = 365,
  INS_SWAPMSK_W = 366,
  INS_SWAP_A = 367,
  INS_SWAP_W = 368,
  INS_SYSCALL = 369,
  INS_TLBDEMAP = 370,
  INS_TLBFLUSH_A = 371,
  INS_TLBFLUSH_B = 372,
  INS_TLBMAP = 373,
  INS_TLBPROBE_A = 374,
  INS_TLBPROBE_I = 375,
  INS_TRAPSV = 376,
  INS_TRAPV = 377,
  INS_UNPACK = 378,
  INS_UPDFL = 379,
  INS_UTOF = 380,
  INS_WAIT = 381,
  INS_XNOR_T = 382,
  INS_XNOR = 383,
  INS_XOR_EQ = 384,
  INS_XOR_GE_U = 385,
  INS_XOR_GE = 386,
  INS_XOR_LT_U = 387,
  INS_XOR_LT = 388,
  INS_XOR_NE = 389,
  INS_XOR = 390,
  INS_ENDING = 391,

  // Group of TriCore instructions
  GRP_INVALID = 392, // cs.GRP_INVALID
  GRP_CALL = 393, // cs.GRP_CALL
  GRP_JUMP = 394, // cs.GRP_JUMP
  GRP_ENDING = 395, // mark the end of the list of groups

  FEATURE_INVALID = 0,
  FEATURE_HasV110 = 128,
  FEATURE_HasV120_UP = 129,
  FEATURE_HasV130_UP = 130,
  FEATURE_HasV161 = 131,
  FEATURE_HasV160_UP = 132,
  FEATURE_HasV131_UP = 133,
  FEATURE_HasV161_UP = 134,
  FEATURE_HasV162 = 135,
  FEATURE_HasV162_UP = 136,
  FEATURE_ENDING = 137, // mark the end of the list of features
}

export class cs_tricore {
  public op_count: number; // number of operands of this instruction.
  public operands: cs_tricore_op[]; // operands for this instruction.
  public update_flags: boolean; // whether the flags register is updated.

  constructor(arch_info_ptr: number, Memory: any) {
    this.operands = [];
    this.op_count = Memory.read(arch_info_ptr + 0, 'ubyte');
    this.update_flags = Memory.read(arch_info_ptr + 132, 'bool');
    for (let i = 0; i < this.op_count; i++) {
      const op: cs_tricore_op = {} as cs_tricore_op;
      const op_ptr: number = arch_info_ptr + 4 + i * 16;
      op.type = Memory.read(op_ptr + 0, 'i32');
      switch (op.type) {
        case TRICORE.OP_REG:
          op.reg = Memory.read(op_ptr + 4, 'u32');
          break;
        case TRICORE.OP_IMM:
          op.imm = Memory.read(op_ptr + 4, 'i32');
          break;
        case TRICORE.OP_MEM:
          op.mem = {
            base: Memory.read(op_ptr + 4, 'ubyte'),
            disp: Memory.read(op_ptr + 8, 'i32'),
          };
          break;
      }
      this.operands[i] = op;
    }
    return this;
  }
}
