summaryrefslogtreecommitdiff
path: root/include/insns.h
blob: 00de2887cb0af345e836f1c054871824347223e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* insns.h   header file for insns.c
 *
 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
 * Julian Hall. All rights reserved. The software is
 * redistributable under the license given in the file "LICENSE"
 * distributed in the NASM archive.
 */

#ifndef NASM_INSNS_H
#define NASM_INSNS_H

#include "nasm.h"
#include "tokens.h"
#include "iflag.h"

/* if changed, ITEMPLATE_END should be also changed accordingly */
struct itemplate {
    enum opcode     opcode;             /* the token, passed from "parser.c" */
    int             operands;           /* number of operands */
    opflags_t       opd[MAX_OPERANDS];  /* bit flags for operand types */
    decoflags_t     deco[MAX_OPERANDS]; /* bit flags for operand decorators */
    const uint8_t   *code;              /* the code it assembles to */
    uint32_t        iflag_idx;          /* some flags referenced by index */
};

/* Use this helper to test instruction template flags */
static inline bool itemp_has(const struct itemplate *itemp, unsigned int bit)
{
    return iflag_test(&insns_flags[itemp->iflag_idx], bit);
}

/* Disassembler table structure */

/*
 * If n == -1, then p points to another table of 256
 * struct disasm_index, otherwise p points to a list of n
 * struct itemplates to consider.
 */
struct disasm_index {
    const void *p;
    int n;
};

/* Tables for the assembler and disassembler, respectively */
extern const struct itemplate * const nasm_instructions[];
extern const struct disasm_index itable[256];
extern const struct disasm_index * const itable_vex[NASM_VEX_CLASSES][32][4];

/* Common table for the byte codes */
extern const uint8_t nasm_bytecodes[];

/*
 * this define is used to signify the end of an itemplate
 */
#define ITEMPLATE_END {I_none,0,{0,},{0,},NULL,0}

/*
 * Pseudo-op tests
 */
/* DB-type instruction (DB, DW, ...) */
static inline bool const_func opcode_is_db(enum opcode opcode)
{
    return opcode >= I_DB && opcode < I_RESB;
}

/* RESB-type instruction (RESB, RESW, ...) */
static inline bool const_func opcode_is_resb(enum opcode opcode)
{
    return opcode >= I_RESB && opcode < I_INCBIN;
}

/* Width of Dx and RESx instructions */

/*
 * initialized data bytes length from opcode
 */
static inline int const_func db_bytes(enum opcode opcode)
{
    switch (opcode) {
    case I_DB:
        return 1;
    case I_DW:
        return 2;
    case I_DD:
        return 4;
    case I_DQ:
        return 8;
    case I_DT:
        return 10;
    case I_DO:
        return 16;
    case I_DY:
        return 32;
    case I_DZ:
        return 64;
    case I_none:
        return -1;
    default:
        return 0;
    }
}

/*
 * Uninitialized data bytes length from opcode
 */
static inline int const_func resb_bytes(enum opcode opcode)
{
    switch (opcode) {
    case I_RESB:
        return 1;
    case I_RESW:
        return 2;
    case I_RESD:
        return 4;
    case I_RESQ:
        return 8;
    case I_REST:
        return 10;
    case I_RESO:
        return 16;
    case I_RESY:
        return 32;
    case I_RESZ:
        return 64;
    case I_none:
        return -1;
    default:
        return 0;
    }
}

#endif /* NASM_INSNS_H */