-
Notifications
You must be signed in to change notification settings - Fork 5
/
reg.cpp
228 lines (196 loc) · 5.63 KB
/
reg.cpp
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#include "rx63.hpp"
#include <diskio.hpp>
#include <ieee.h>
#include "../iohandler.hpp"
netnode helper;
static const char *const reg_names[] =
{
"sp"/*"r0"*/, "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"isp", "usp", "intb", "pc", "psw", "bpc", "bpsw", "fintv", "fpsw",
"cs", "ds",
};
static qstring device;
static ioports_t ports;
//----------------------------------------------------------------------
// This old-style callback only returns the processor module object.
static ssize_t idaapi notify(void*, int msgid, va_list /*va*/)
{
if (msgid == processor_t::ev_get_procmod)
return size_t(new rx63_t);
return 0;
}
void rx63_t::load_from_idb()
{
int n = ph.get_proc_index();
inf_set_be(!(n > 0));
ioh.restore_device();
}
//--------------------------------------------------------------------------
ssize_t idaapi rx63_t::on_event(ssize_t msgid, va_list va)
{
outctx_t *ctx;
op_t *op;
iohandler_t::parse_area_line0_t cb(ioh);
switch (msgid) {
case processor_t::ev_init:
helper.create("$ RX63");
break;
case processor_t::ev_newfile:
{
char cfgfile[QMAXFILE];
ioh.get_cfg_filename(cfgfile, sizeof(cfgfile));
if (choose_ioport_device2(&ioh.device, cfgfile, &cb))
ioh.set_device_name(device.c_str(), IORESP_AREA);
break;
}
case processor_t::ev_out_header:
ctx = va_arg(va, outctx_t*);
header(*ctx);
return 1;
case processor_t::ev_out_footer:
ctx = va_arg(va, outctx_t*);
footer(*ctx);
return 1;
case processor_t::ev_out_segstart:
{
ctx = va_arg(va, outctx_t*);
segment_t *seg = va_arg(va, segment_t *);
segstart(*ctx, seg);
return 1;
}
case processor_t::ev_out_segend:
{
ctx = va_arg(va, outctx_t*);
segment_t *seg = va_arg(va, segment_t *);
segend(*ctx, seg);
return 1;
}
case processor_t::ev_ana_insn:
{
insn_t *insn = va_arg(va, insn_t *);
return ana(insn);
}
case processor_t::ev_emu_insn:
{
const insn_t *insn = va_arg(va, const insn_t *);
return emu(*insn)?1:-1;
}
case processor_t::ev_out_insn:
ctx = va_arg(va, outctx_t*);
out_insn(*ctx);
return 1;
case processor_t::ev_out_operand:
ctx = va_arg(va, outctx_t*);
op = va_arg(va, op_t*);
return out_opnd(*ctx, *op)?1:-1;
default:
break;
}
return 0;
}
//--------------------------------------------------------------------------
static asm_t rx63_asm =
{
AS_COLON |AS_ASCIIZ | AS_ASCIIC | AS_1TEXT,
0,
"Renesas RX family assembler",
0, // help screen number
NULL, // header
NULL, // origin
".end", // end
";", // comment string
'"', // string delimiter
'\'', // char delimiter (no char consts)
"\\\"'", // special symbols in char and string constants
".string", // ascii string directive
".byte", // byte directive
".word", // word directive
".dword", // dword (4 bytes)
NULL, // qword (8 bytes)
NULL, // oword (16 bytes)
".float", // float (4 bytes)
".double", // double (8 bytes)
NULL, // tbyte (10/12 bytes)
NULL, // packed decimal real
NULL, // arrays (#h,#d,#v,#s(...)
".block %s", // uninited arrays
".equ", // Equ
NULL, // seg prefix
"$", // current IP
NULL, // func_header
NULL, // func_footer
".global", // public
NULL, // weak
NULL, // extrn
NULL, // comm
NULL, // get_type_name
NULL, // align
'(', ')', // lbrace, rbrace
"%", // mod
"&", // and
"|", // or
"^", // xor
"!", // not
"<<", // shl
">>", // shr
NULL, // sizeof
};
static const asm_t *const asms[] = { &rx63_asm, NULL };
//--------------------------------------------------------------------------
#define FAMILY "Renesas RX63 series:"
static const char *const shnames[] =
{
"RX63",
"RX63l",
NULL
};
static const char *const lnames[] =
{
"Renesas RX63 (big endian)",
"Renesas RX63 (little endian)",
NULL
};
static const uchar rtscode[] = { 0x2 }; // rts
static const uchar rtsdcode1[] = { 0x67 }; // rtsd
static const uchar rtsdcode2[] = { 0x4f }; // rtsd
static const uchar rtecode[] = { 0x7f, 0x95 }; // rte
static const uchar rtfcode[] = { 0x7f, 0x94 }; // rtf
static const bytes_t retcodes[] =
{
{ sizeof(rtscode), rtscode },
{ sizeof(rtsdcode1), rtsdcode1 },
{ sizeof(rtsdcode2), rtsdcode2 },
{ sizeof(rtecode), rtecode },
{ sizeof(rtfcode), rtfcode },
{ 0, NULL }
};
processor_t LPH =
{
IDP_INTERFACE_VERSION, // version
PLFM_RX63, // id
PRN_HEX |
PR_USE32 |
PR_BINMEM |
PR_RNAMESOK |
PR_DEFSEG32, // flag
0, // flag2
8, // 8 bits in a byte for code segments
8, // 8 bits in a byte for other segments
shnames, // short processor names (null term)
lnames, // long processor names (null term)
asms, // array of enabled assemblers
notify, // Various messages:
reg_names, // Register names
qnumber(reg_names), // Number of registers
r_cs,r_ds, // reg_{first|last}_sreg
0, // size of a segment register
r_cs,r_ds, // reg_{code|data}_sreg
NULL, // No known code start sequences
retcodes,
0, RX63_last,
Instructions,
0, // int tbyte_size; -- doesn't exist
{ 0, 7, 15, 0 }, // char real_width[4];
RX63_rte, // Icode of return instruction. It is ok to give any of possible return instructions
NULL, // unused_slot
};