2 # gen-insn-attr-x86.awk: Instruction attribute table generator
3 # Written by Masami Hiramatsu <mhiramat@redhat.com>
5 # Usage: awk -f gen-insn-attr-x86.awk x86-opcode-map.txt > inat-tables.c
8 print "/* x86 opcode map generated from x86-opcode-map.txt */"
9 print "/* Do not change this code. */"
13 opnd_expr =
"^[[:alpha:]]"
16 group_expr =
"^Grp[[:alnum:]]+"
18 imm_expr =
"^[IJAO][[:lower:]]"
19 imm_flag
["Ib"] =
"INAT_MAKE_IMM(INAT_IMM_BYTE)"
20 imm_flag
["Jb"] =
"INAT_MAKE_IMM(INAT_IMM_BYTE)"
21 imm_flag
["Iw"] =
"INAT_MAKE_IMM(INAT_IMM_WORD)"
22 imm_flag
["Id"] =
"INAT_MAKE_IMM(INAT_IMM_DWORD)"
23 imm_flag
["Iq"] =
"INAT_MAKE_IMM(INAT_IMM_QWORD)"
24 imm_flag
["Ap"] =
"INAT_MAKE_IMM(INAT_IMM_PTR)"
25 imm_flag
["Iz"] =
"INAT_MAKE_IMM(INAT_IMM_VWORD32)"
26 imm_flag
["Jz"] =
"INAT_MAKE_IMM(INAT_IMM_VWORD32)"
27 imm_flag
["Iv"] =
"INAT_MAKE_IMM(INAT_IMM_VWORD)"
28 imm_flag
["Ob"] =
"INAT_MOFFSET"
29 imm_flag
["Ov"] =
"INAT_MOFFSET"
31 modrm_expr =
"^([CDEGMNPQRSUVW][[:lower:]]+|NTA|T[012])"
32 force64_expr =
"\\([df]64\\)"
33 rex_expr =
"^REX(\\.[XRWB]+)*"
34 fpu_expr =
"^ESC" # TODO
36 lprefix1_expr =
"\\(66\\)"
38 lprefix2_expr =
"\\(F2\\)"
40 lprefix3_expr =
"\\(F3\\)"
44 prefix_expr =
"\\(Prefix\\)"
45 prefix_num
["Operand-Size"] =
"INAT_PFX_OPNDSZ"
46 prefix_num
["REPNE"] =
"INAT_PFX_REPNE"
47 prefix_num
["REP/REPE"] =
"INAT_PFX_REPE"
48 prefix_num
["LOCK"] =
"INAT_PFX_LOCK"
49 prefix_num
["SEG=CS"] =
"INAT_PFX_CS"
50 prefix_num
["SEG=DS"] =
"INAT_PFX_DS"
51 prefix_num
["SEG=ES"] =
"INAT_PFX_ES"
52 prefix_num
["SEG=FS"] =
"INAT_PFX_FS"
53 prefix_num
["SEG=GS"] =
"INAT_PFX_GS"
54 prefix_num
["SEG=SS"] =
"INAT_PFX_SS"
55 prefix_num
["Address-Size"] =
"INAT_PFX_ADDRSZ"
64 function semantic_error
(msg
) {
65 print "Semantic error at " NR ": " msg
> "/dev/stderr"
73 function array_size
(arr
, i
,c
) {
86 # primary opcode table
87 tname =
"inat_primary_table"
92 for (i =
2; i
<=
NF; i
++)
95 tname =
sprintf("inat_escape_table_%d", eid
)
102 semantic_error
("No group: " $
2 )
104 tname =
"inat_group_table_" gid
107 function print_table
(tbl
,name
,fmt
,n
)
109 print "const insn_attr_t " name
" = {"
110 for (i =
0; i
< n
; i
++) {
113 print " [" id
"] = " tbl
[id
] ","
121 if (array_size
(table
) != 0) {
122 print_table
(table
, tname
"[INAT_GROUP_TABLE_SIZE]",
124 gtable
[gid
,0] = tname
126 if (array_size
(lptable1
) != 0) {
127 print_table
(lptable1
, tname
"_1[INAT_GROUP_TABLE_SIZE]",
129 gtable
[gid
,1] = tname
"_1"
131 if (array_size
(lptable2
) != 0) {
132 print_table
(lptable2
, tname
"_2[INAT_GROUP_TABLE_SIZE]",
134 gtable
[gid
,2] = tname
"_2"
136 if (array_size
(lptable3
) != 0) {
137 print_table
(lptable3
, tname
"_3[INAT_GROUP_TABLE_SIZE]",
139 gtable
[gid
,3] = tname
"_3"
142 # print primary/escaped tables
143 if (array_size
(table
) != 0) {
144 print_table
(table
, tname
"[INAT_OPCODE_TABLE_SIZE]",
146 etable
[eid
,0] = tname
148 if (array_size
(lptable1
) != 0) {
149 print_table
(lptable1
,tname
"_1[INAT_OPCODE_TABLE_SIZE]",
151 etable
[eid
,1] = tname
"_1"
153 if (array_size
(lptable2
) != 0) {
154 print_table
(lptable2
,tname
"_2[INAT_OPCODE_TABLE_SIZE]",
156 etable
[eid
,2] = tname
"_2"
158 if (array_size
(lptable3
) != 0) {
159 print_table
(lptable3
,tname
"_3[INAT_OPCODE_TABLE_SIZE]",
161 etable
[eid
,3] = tname
"_3"
173 function add_flags
(old
,new
) {
182 # convert operands to flags.
183 function convert_operands
(opnd
, i
,imm
,mod
)
189 if (match(i
, imm_expr
) ==
1) {
191 semantic_error
("Unknown imm opnd: " i
)
194 semantic_error
("Second IMM error")
195 imm = add_flags
(imm
, "INAT_SCNDIMM")
198 } else if (match(i
, modrm_expr
))
201 return add_flags
(imm
, mod
)
208 idx =
"0x" substr($
1, 1, index($
1,":") - 1)
210 semantic_error
("Redefine " idx
" in " tname
)
212 # check if escaped opcode
213 if ("escape" == $
2) {
215 semantic_error
("No escaped name")
217 for (i =
4; i
<=
NF; i
++)
220 semantic_error
("Redefine escape (" ref
")")
223 table
[idx
] =
"INAT_MAKE_ESCAPE(" escape
[ref
] ")"
237 if (match($i
, opnd_expr
)) {
239 split($
(i
++), opnds
, ",")
240 flags = convert_operands
(opnds
)
242 if (match($i
, ext_expr
))
244 if (match($i
, sep_expr
))
247 semantic_error
($i
" is not a separator")
249 # check if group opcode
250 if (match(opcode
, group_expr
)) {
251 if (!
(opcode in group
)) {
255 flags = add_flags
(flags
, "INAT_MAKE_GROUP(" group
[opcode
] ")")
257 # check force(or default) 64bit
258 if (match(ext
, force64_expr
))
259 flags = add_flags
(flags
, "INAT_FORCE64")
262 if (match(opcode
, rex_expr
))
263 flags = add_flags
(flags
, "INAT_REXPFX")
265 # check coprocessor escape : TODO
266 if (match(opcode
, fpu_expr
))
267 flags = add_flags
(flags
, "INAT_MODRM")
270 if (match(ext
, prefix_expr
)) {
271 if (!prefix_num
[opcode
])
272 semantic_error
("Unknown prefix: " opcode
)
273 flags = add_flags
(flags
, "INAT_MAKE_PREFIX(" prefix_num
[opcode
] ")")
275 if (length(flags
) ==
0)
277 # check if last prefix
278 if (match(ext
, lprefix1_expr
)) {
279 lptable1
[idx
] = add_flags
(lptable1
[idx
],flags
)
280 variant =
"INAT_VARIANT"
281 } else if (match(ext
, lprefix2_expr
)) {
282 lptable2
[idx
] = add_flags
(lptable2
[idx
],flags
)
283 variant =
"INAT_VARIANT"
284 } else if (match(ext
, lprefix3_expr
)) {
285 lptable3
[idx
] = add_flags
(lptable3
[idx
],flags
)
286 variant =
"INAT_VARIANT"
288 table
[idx
] = add_flags
(table
[idx
],flags
)
292 table
[idx
] = add_flags
(table
[idx
],variant
)
296 # print escape opcode map's array
297 print "/* Escape opcode map array */"
298 print "const insn_attr_t const *inat_escape_tables[INAT_ESC_MAX + 1]" \
299 "[INAT_LPREFIX_MAX + 1] = {"
300 for (i =
0; i
< geid
; i
++)
301 for (j =
0; j
< max_lprefix
; j
++)
303 print " ["i
"]["j
"] = "etable
[i
,j
]","
305 # print group opcode map's array
306 print "/* Group opcode map array */"
307 print "const insn_attr_t const *inat_group_tables[INAT_GRP_MAX + 1]"\
308 "[INAT_LPREFIX_MAX + 1] = {"
309 for (i =
0; i
< ggid
; i
++)
310 for (j =
0; j
< max_lprefix
; j
++)
312 print " ["i
"]["j
"] = "gtable
[i
,j
]","
This page took 0.0437 seconds and 5 git commands to generate.