-
Notifications
You must be signed in to change notification settings - Fork 5
/
operand.h
134 lines (118 loc) · 3.32 KB
/
operand.h
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
133
134
#ifndef OPERAND_H
#define OPERAND_H
#include "imm.h"
#include "register.h"
#include <string.h>
typedef enum
{
VOPERAND_INVALID,
VOPERAND_IMMEDIATE,
VOPERAND_INDIRECT,
VOPERAND_REGISTER,
VOPERAND_INDIRECT_REGISTER,
VOPERAND_INDIRECT_REGISTER_DISPLACEMENT,
VOPERAND_INDIRECT_REGISTER_INDEXED,
// for dst only register and address are valid
VOPERAND_LABEL
} voperand_type_t;
static const char *voperand_type_strings[] = {"invalid","immediate","indirect","register","indirect register","indirect register displacement","register indexed",NULL};
typedef enum
{
VOPERAND_SIZE_NATIVE, // e.g native register size for the architecture (x86 -> 32, x64 -> 64),
VOPERAND_SIZE_8_BITS = 1,
VOPERAND_SIZE_16_BITS = 2,
VOPERAND_SIZE_32_BITS = 4,
VOPERAND_SIZE_64_BITS = 8,
VOPERAND_SIZE_DOUBLE,
VOPERAND_SIZE_FLOAT
} voperand_size_t;
static const char *voperand_size_names[] = {"native","","word","","dword","","","","qword","double","float",NULL};
typedef struct
{
int type;
voperand_size_t size;
union
{
imm_t imm;
vregister_t reg;
imm_t indirect;
struct
{
i32 disp;
vregister_t reg;
} reg_indirect_displacement;
struct
{
i32 scale;
vregister_t indexed_reg;
vregister_t reg;
} reg_indirect_indexed;
size_t label;
};
bool virtual;
} voperand_t;
static voperand_t indirect_operand(imm_t imm, voperand_size_t size)
{
voperand_t op = {.type = VOPERAND_INDIRECT, .size = size, .virtual = true};
op.imm = imm;
return op;
}
static voperand_t indirect_register_operand(vregister_t reg)
{
voperand_t op = {.type = VOPERAND_INDIRECT_REGISTER, .size = VOPERAND_SIZE_NATIVE, .virtual = true};
op.reg = reg;
return op;
}
static voperand_t indirect_register_displacement_operand(vregister_t reg, u32 disp, voperand_size_t size)
{
voperand_t op = {.type = VOPERAND_INDIRECT_REGISTER_DISPLACEMENT, .size = size, .virtual = true};
op.reg_indirect_displacement.reg = reg;
op.reg_indirect_displacement.disp = disp;
return op;
}
static voperand_t indirect_register_indexed_operand(vregister_t reg, vregister_t indexreg, u32 scale, voperand_size_t size)
{
voperand_t op = {.type = VOPERAND_INDIRECT_REGISTER_INDEXED, .size = size, .virtual = true};
op.reg_indirect_indexed.indexed_reg = indexreg;
op.reg_indirect_indexed.reg = reg;
op.reg_indirect_indexed.scale = scale;
return op;
}
static voperand_t label_operand(size_t label_value)
{
voperand_t op = {.type = VOPERAND_LABEL, .size = VOPERAND_SIZE_NATIVE, .virtual = true};
op.label = label_value;
return op;
}
static voperand_t imm32_operand(i32 i)
{
voperand_t op = {.type = VOPERAND_IMMEDIATE, .size = VOPERAND_SIZE_32_BITS, .virtual = true};
op.imm.nbits = 32;
op.imm.dd = i;
return op;
}
static voperand_t imm64_operand(i64 i)
{
voperand_t op = {.type = VOPERAND_IMMEDIATE, .size = VOPERAND_SIZE_64_BITS, .virtual = true};
op.imm.nbits = 64;
op.imm.dq = i;
return op;
}
static voperand_t invalid_operand()
{
voperand_t op = {.type = VOPERAND_INVALID, .virtual = true};
return op;
}
static voperand_t register_operand(vregister_t reg)
{
voperand_t op = {.type = VOPERAND_REGISTER, .size = VOPERAND_SIZE_NATIVE, .virtual = true};
op.reg = reg;
return op;
}
static bool voperand_type_equal(voperand_t* a, voperand_t* b)
{
if (a->type == VOPERAND_REGISTER && b->type == VOPERAND_REGISTER && a->size == b->size)
return true;
return !memcmp(a, b, sizeof(voperand_t));
}
#endif