-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopc-asmdis.scm
188 lines (161 loc) · 4.84 KB
/
opc-asmdis.scm
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
; Assembler/disassembler support generator.
; Copyright (C) 2000, 2001, 2005, 2009 Red Hat, Inc.
; This file is part of CGEN.
; Assembler support.
(define (/gen-parse-switch)
(logit 2 "Generating parse switch ...\n")
(string-list
"\
const char * @arch@_cgen_parse_operand
(CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
/* Main entry point for operand parsing.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `parse_insn_normal', but keeping it
separate makes clear the interface between `parse_insn_normal' and each of
the handlers. */
const char *
@arch@_cgen_parse_operand (CGEN_CPU_DESC cd,
int opindex,
const char ** strp,
CGEN_FIELDS * fields)
{
const char * errmsg = NULL;
/* Used by scalar operands that still need to be parsed. */
" (gen-ifield-default-type #f) " junk ATTRIBUTE_UNUSED;
switch (opindex)
{
"
(gen-switch 'parse)
"
default :
/* xgettext:c-format */
opcodes_error_handler
(_(\"internal error: unrecognized field %d while parsing\"),
opindex);
abort ();
}
return errmsg;
}\n\n")
)
; Assembler initialization C code
; Code is appended during processing.
(define /asm-init-code "")
(define (add-asm-init code)
(set! /asm-init-code (string-append /asm-init-code code))
)
; Return C code to define the assembler init function.
; This is called after opcode_open.
(define (/gen-init-asm-fn)
(string-append
"\
void
@arch@_cgen_init_asm (CGEN_CPU_DESC cd)
{
@arch@_cgen_init_opcode_table (cd);
@arch@_cgen_init_ibld_table (cd);
cd->parse_handlers = & @arch@_cgen_parse_handlers[0];
cd->parse_operand = @arch@_cgen_parse_operand;
#ifdef CGEN_ASM_INIT_HOOK
CGEN_ASM_INIT_HOOK
#endif
"
/asm-init-code
"}\n\n"
)
)
; Generate C code that is inserted into the assembler source.
(define (cgen-asm.in)
(logit 1 "Generating " (current-arch-name) "-asm.in ...\n")
(string-write
; No need for copyright, appended to file with one.
"\n"
(lambda () (gen-extra-asm.c (opc-file-path) (current-arch-name)))
"\n"
/gen-parse-switch
(lambda () (gen-handler-table "parse" opc-parse-handlers))
/gen-init-asm-fn
)
)
; Disassembler support.
(define (/gen-print-switch)
(logit 2 "Generating print switch ...\n")
(string-list
"\
void @arch@_cgen_print_operand
(CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
/* Main entry point for printing operands.
XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
of dis-asm.h on cgen.h.
This function is basically just a big switch statement. Earlier versions
used tables to look up the function to use, but
- if the table contains both assembler and disassembler functions then
the disassembler contains much of the assembler and vice-versa,
- there's a lot of inlining possibilities as things grow,
- using a switch statement avoids the function call overhead.
This function could be moved into `print_insn_normal', but keeping it
separate makes clear the interface between `print_insn_normal' and each of
the handlers. */
void
@arch@_cgen_print_operand (CGEN_CPU_DESC cd,
int opindex,
void * xinfo,
CGEN_FIELDS *fields,
void const *attrs ATTRIBUTE_UNUSED,
bfd_vma pc,
int length)
{
disassemble_info *info = (disassemble_info *) xinfo;
switch (opindex)
{
"
(gen-switch 'print)
"
default :
/* xgettext:c-format */
opcodes_error_handler
(_(\"internal error: unrecognized field %d while printing insn\"),
opindex);
abort ();
}
}\n\n")
)
; Disassembler initialization C code.
; Code is appended during processing.
(define /dis-init-code "")
(define (add-dis-init code)
(set! /dis-init-code (string-append /dis-init-code code))
)
; Return C code to define the disassembler init function.
(define (/gen-init-dis-fn)
(string-append
"
void
@arch@_cgen_init_dis (CGEN_CPU_DESC cd)
{
@arch@_cgen_init_opcode_table (cd);
@arch@_cgen_init_ibld_table (cd);
cd->print_handlers = & @arch@_cgen_print_handlers[0];
cd->print_operand = @arch@_cgen_print_operand;
"
/dis-init-code
"}\n\n"
)
)
; Generate C code that is inserted into the disassembler source.
(define (cgen-dis.in)
(logit 1 "Generating " (current-arch-name) "-dis.in ...\n")
(string-write
; No need for copyright, appended to file with one.
"\n"
(lambda () (gen-extra-dis.c (opc-file-path) (current-arch-name)))
"\n"
/gen-print-switch
(lambda () (gen-handler-table "print" opc-print-handlers))
/gen-init-dis-fn
)
)