xref: /netbsd-src/external/gpl3/binutils/dist/gas/ginsn.h (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* ginsn.h - GAS instruction representation.
2    Copyright (C) 2023 Free Software Foundation, Inc.
3 
4    This file is part of GAS, the GNU Assembler.
5 
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 #ifndef GINSN_H
22 #define GINSN_H
23 
24 #include "as.h"
25 
26 /* Maximum number of source operands of a ginsn.  */
27 #define GINSN_NUM_SRC_OPNDS   2
28 
29 /* A ginsn in printed in the following format:
30       "ginsn: OPCD SRC1, SRC2, DST"
31       "<-5->  <--------125------->"
32    where each of SRC1, SRC2, and DST are in the form:
33       "%rNN,"  (up to 5 chars)
34       "imm,"   (up to int32_t+1 chars)
35       "[%rNN+-imm]," (up to int32_t+9 chars)
36       Hence a max of 19 chars.  */
37 
38 #define GINSN_LISTING_OPND_LEN	40
39 #define GINSN_LISTING_LEN 156
40 
41 enum ginsn_gen_mode
42 {
43   GINSN_GEN_NONE,
44   /* Generate ginsns for program validation passes.  */
45   GINSN_GEN_FVAL,
46   /* Generate ginsns for synthesizing DWARF CFI.  */
47   GINSN_GEN_SCFI,
48 };
49 
50 /* ginsn types.
51 
52    GINSN_TYPE_PHANTOM are phantom ginsns.  They are used where there is no real
53    machine instruction counterpart, but a ginsn is needed only to carry
54    information to GAS.  For example, to carry an SCFI Op.
55 
56    Note that, ginsns do not have a push / pop instructions.
57    Instead, following are used:
58       type=GINSN_TYPE_LOAD, src=GINSN_SRC_INDIRECT, REG_SP: Load from stack.
59       type=GINSN_TYPE_STORE, dst=GINSN_DST_INDIRECT, REG_SP: Store to stack.
60 */
61 
62 #define _GINSN_TYPES \
63   _GINSN_TYPE_ITEM (GINSN_TYPE_SYMBOL, "SYM") \
64   _GINSN_TYPE_ITEM (GINSN_TYPE_PHANTOM, "PHANTOM")  \
65   _GINSN_TYPE_ITEM (GINSN_TYPE_ADD, "ADD")  \
66   _GINSN_TYPE_ITEM (GINSN_TYPE_AND, "AND")  \
67   _GINSN_TYPE_ITEM (GINSN_TYPE_CALL, "CALL") \
68   _GINSN_TYPE_ITEM (GINSN_TYPE_JUMP, "JMP") \
69   _GINSN_TYPE_ITEM (GINSN_TYPE_JUMP_COND, "JCC")  \
70   _GINSN_TYPE_ITEM (GINSN_TYPE_MOV, "MOV")  \
71   _GINSN_TYPE_ITEM (GINSN_TYPE_LOAD, "LOAD")  \
72   _GINSN_TYPE_ITEM (GINSN_TYPE_STORE, "STORE")  \
73   _GINSN_TYPE_ITEM (GINSN_TYPE_RETURN, "RET") \
74   _GINSN_TYPE_ITEM (GINSN_TYPE_SUB, "SUB")  \
75   _GINSN_TYPE_ITEM (GINSN_TYPE_OTHER, "OTH")
76 
77 enum ginsn_type
78 {
79 #define _GINSN_TYPE_ITEM(NAME, STR) NAME,
80   _GINSN_TYPES
81 #undef _GINSN_TYPE_ITEM
82 };
83 
84 enum ginsn_src_type
85 {
86   GINSN_SRC_UNKNOWN,
87   GINSN_SRC_REG,
88   GINSN_SRC_IMM,
89   GINSN_SRC_INDIRECT,
90   GINSN_SRC_SYMBOL,
91 };
92 
93 /* GAS instruction source operand representation.  */
94 
95 struct ginsn_src
96 {
97   enum ginsn_src_type type;
98   /* DWARF register number.  */
99   unsigned int reg;
100   /* Immediate or disp for indirect memory access.  */
101   offsetT immdisp;
102   /* Src symbol.  May be needed for some control flow instructions.  */
103   const symbolS *sym;
104 };
105 
106 enum ginsn_dst_type
107 {
108   GINSN_DST_UNKNOWN,
109   GINSN_DST_REG,
110   GINSN_DST_INDIRECT,
111 };
112 
113 /* GAS instruction destination operand representation.  */
114 
115 struct ginsn_dst
116 {
117   enum ginsn_dst_type type;
118   /* DWARF register number.  */
119   unsigned int reg;
120   /* Disp for indirect memory access.  */
121   offsetT disp;
122 };
123 
124 /* Various flags for additional information per GAS instruction.  */
125 
126 /* Function begin or end symbol.  */
127 #define GINSN_F_FUNC_MARKER	    0x1
128 /* Identify real or implicit GAS insn.
129    Some targets employ CISC-like instructions.  Multiple ginsn's may be used
130    for a single machine instruction in some ISAs.  For some optimizations,
131    there is need to identify whether a ginsn, e.g., GINSN_TYPE_ADD or
132    GINSN_TYPE_SUB is a result of an user-specified instruction or not.  */
133 #define GINSN_F_INSN_REAL	    0x2
134 /* Identify if the GAS insn of type GINSN_TYPE_SYMBOL is due to a user-defined
135    label.  Each user-defined labels in a function will cause addition of a new
136    ginsn.  This simplifies control flow graph creation.
137    See htab_t label_ginsn_map usage.  */
138 #define GINSN_F_USER_LABEL	    0x4
139 /* Max bit position for flags (uint32_t).  */
140 #define GINSN_F_MAX		    0x20
141 
142 #define GINSN_F_FUNC_BEGIN_P(ginsn)	    \
143   ((ginsn != NULL)			    \
144    && (ginsn->type == GINSN_TYPE_SYMBOL)    \
145    && (ginsn->flags & GINSN_F_FUNC_MARKER))
146 
147 /* PS: For ginsn associated with a user-defined symbol location,
148    GINSN_F_FUNC_MARKER is unset, but GINSN_F_USER_LABEL is set.  */
149 #define GINSN_F_FUNC_END_P(ginsn)	    \
150   ((ginsn != NULL)			    \
151    && (ginsn->type == GINSN_TYPE_SYMBOL)    \
152    && !(ginsn->flags & GINSN_F_FUNC_MARKER) \
153    && !(ginsn->flags & GINSN_F_USER_LABEL))
154 
155 #define GINSN_F_INSN_REAL_P(ginsn)	    \
156   ((ginsn != NULL)			    \
157    && (ginsn->flags & GINSN_F_INSN_REAL))
158 
159 #define GINSN_F_USER_LABEL_P(ginsn)	    \
160   ((ginsn != NULL)			    \
161    && (ginsn->type == GINSN_TYPE_SYMBOL)    \
162    && !(ginsn->flags & GINSN_F_FUNC_MARKER) \
163    && (ginsn->flags & GINSN_F_USER_LABEL))
164 
165 typedef struct ginsn ginsnS;
166 typedef struct scfi_op scfi_opS;
167 typedef struct scfi_state scfi_stateS;
168 
169 /* GAS generic instruction.
170 
171    Generic instructions are used by GAS to abstract out the binary machine
172    instructions.  In other words, ginsn is a target/ABI independent internal
173    representation for GAS.  Note that, depending on the target, there may be
174    more than one ginsn per binary machine instruction.
175 
176    ginsns can be used by GAS to perform validations, or even generate
177    additional information like, sythesizing DWARF CFI for hand-written asm.  */
178 
179 struct ginsn
180 {
181   enum ginsn_type type;
182   /* GAS instructions are simple instructions with GINSN_NUM_SRC_OPNDS number
183      of source operands and one destination operand at this time.  */
184   struct ginsn_src src[GINSN_NUM_SRC_OPNDS];
185   struct ginsn_dst dst;
186   /* Additional information per instruction.  */
187   uint32_t flags;
188   /* Symbol.  For ginsn of type other than GINSN_TYPE_SYMBOL, this identifies
189      the end of the corresponding machine instruction in the .text segment.
190      These symbols are created anew by the targets and are not used elsewhere
191      in GAS.  The only exception is some ginsns of type GINSN_TYPE_SYMBOL, when
192      generated for the user-defined labels.  See ginsn_frob_label.  */
193   const symbolS *sym;
194   /* Identifier (linearly increasing natural number) for each ginsn.  Used as
195      a proxy for program order of ginsns.  */
196   uint64_t id;
197   /* Location information for user-interfacing messaging.  Only ginsns with
198      GINSN_F_FUNC_BEGIN_P and GINSN_F_FUNC_END_P may present themselves with no
199      file or line information.  */
200   const char *file;
201   unsigned int line;
202 
203   /* Information needed for synthesizing CFI.  */
204   scfi_opS **scfi_ops;
205   uint32_t num_scfi_ops;
206 
207   /* Flag to keep track of visited instructions for CFG creation.  */
208   bool visited;
209 
210   ginsnS *next; /* A linked list.  */
211 };
212 
213 struct ginsn_src *ginsn_get_src1 (ginsnS *ginsn);
214 struct ginsn_src *ginsn_get_src2 (ginsnS *ginsn);
215 struct ginsn_dst *ginsn_get_dst (ginsnS *ginsn);
216 
217 unsigned int ginsn_get_src_reg (struct ginsn_src *src);
218 enum ginsn_src_type ginsn_get_src_type (struct ginsn_src *src);
219 offsetT ginsn_get_src_disp (struct ginsn_src *src);
220 offsetT ginsn_get_src_imm (struct ginsn_src *src);
221 
222 unsigned int ginsn_get_dst_reg (struct ginsn_dst *dst);
223 enum ginsn_dst_type ginsn_get_dst_type (struct ginsn_dst *dst);
224 offsetT ginsn_get_dst_disp (struct ginsn_dst *dst);
225 
226 /* Data object for book-keeping information related to GAS generic
227    instructions.  */
228 struct frch_ginsn_data
229 {
230   /* Mode for GINSN creation.  */
231   enum ginsn_gen_mode mode;
232   /* Head of the list of ginsns.  */
233   ginsnS *gins_rootP;
234   /* Tail of the list of ginsns.  */
235   ginsnS *gins_lastP;
236   /* Function symbol.  */
237   const symbolS *func;
238   /* Start address of the function.  */
239   symbolS *start_addr;
240   /* User-defined label to ginsn mapping.  */
241   htab_t label_ginsn_map;
242   /* Is the list of ginsn apt for creating CFG.  */
243   bool gcfg_apt_p;
244 };
245 
246 int ginsn_data_begin (const symbolS *func);
247 int ginsn_data_end (const symbolS *label);
248 const symbolS *ginsn_data_func_symbol (void);
249 void ginsn_frob_label (const symbolS *sym);
250 
251 void frch_ginsn_data_init (const symbolS *func, symbolS *start_addr,
252 			   enum ginsn_gen_mode gmode);
253 void frch_ginsn_data_cleanup (void);
254 int frch_ginsn_data_append (ginsnS *ginsn);
255 enum ginsn_gen_mode frch_ginsn_gen_mode (void);
256 
257 void label_ginsn_map_insert (const symbolS *label, ginsnS *ginsn);
258 ginsnS *label_ginsn_map_find (const symbolS *label);
259 
260 ginsnS *ginsn_new_symbol_func_begin (const symbolS *sym);
261 ginsnS *ginsn_new_symbol_func_end (const symbolS *sym);
262 ginsnS *ginsn_new_symbol_user_label (const symbolS *sym);
263 
264 ginsnS *ginsn_new_phantom (const symbolS *sym);
265 ginsnS *ginsn_new_symbol (const symbolS *sym, bool real_p);
266 ginsnS *ginsn_new_add (const symbolS *sym, bool real_p,
267 		       enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp,
268 		       enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp,
269 		       enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp);
270 ginsnS *ginsn_new_and (const symbolS *sym, bool real_p,
271 		       enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp,
272 		       enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp,
273 		       enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp);
274 ginsnS *ginsn_new_call (const symbolS *sym, bool real_p,
275 			enum ginsn_src_type src_type, unsigned int src_reg,
276 			const symbolS *src_text_sym);
277 ginsnS *ginsn_new_jump (const symbolS *sym, bool real_p,
278 			enum ginsn_src_type src_type, unsigned int src_reg,
279 			const symbolS *src_ginsn_sym);
280 ginsnS *ginsn_new_jump_cond (const symbolS *sym, bool real_p,
281 			     enum ginsn_src_type src_type, unsigned int src_reg,
282 			     const symbolS *src_ginsn_sym);
283 ginsnS *ginsn_new_mov (const symbolS *sym, bool real_p,
284 		       enum ginsn_src_type src_type, unsigned int src_reg, offsetT src_disp,
285 		       enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp);
286 ginsnS *ginsn_new_store (const symbolS *sym, bool real_p,
287 			 enum ginsn_src_type src_type, unsigned int src_reg,
288 			 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp);
289 ginsnS *ginsn_new_load (const symbolS *sym, bool real_p,
290 			enum ginsn_src_type src_type, unsigned int src_reg, offsetT src_disp,
291 			enum ginsn_dst_type dst_type, unsigned int dst_reg);
292 ginsnS *ginsn_new_sub (const symbolS *sym, bool real_p,
293 		       enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp,
294 		       enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp,
295 		       enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp);
296 ginsnS *ginsn_new_other (const symbolS *sym, bool real_p,
297 			 enum ginsn_src_type src1_type, unsigned int src1_val,
298 			 enum ginsn_src_type src2_type, unsigned int src2_val,
299 			 enum ginsn_dst_type dst_type, unsigned int dst_reg);
300 ginsnS *ginsn_new_return (const symbolS *sym, bool real_p);
301 
302 void ginsn_set_where (ginsnS *ginsn);
303 
304 bool ginsn_track_reg_p (unsigned int dw2reg, enum ginsn_gen_mode);
305 
306 int ginsn_link_next (ginsnS *ginsn, ginsnS *next);
307 
308 enum gcfg_err_code
309 {
310   GCFG_OK = 0,
311   GCFG_JLABEL_NOT_PRESENT = 1, /* Warning-level code.  */
312 };
313 
314 typedef struct gbb gbbS;
315 typedef struct gedge gedgeS;
316 
317 /* GBB - Basic block of generic GAS instructions.  */
318 
319 struct gbb
320 {
321   ginsnS *first_ginsn;
322   ginsnS *last_ginsn;
323   uint64_t num_ginsns;
324 
325   /* Identifier (linearly increasing natural number) for each gbb.  Added for
326      debugging purpose only.  */
327   uint64_t id;
328 
329   bool visited;
330 
331   uint32_t num_out_gedges;
332   gedgeS *out_gedges;
333 
334   /* Members for SCFI purposes.  */
335   /* SCFI state at the entry of basic block.  */
336   scfi_stateS *entry_state;
337   /* SCFI state at the exit of basic block.  */
338   scfi_stateS *exit_state;
339 
340   /* A linked list.  In order of addition.  */
341   gbbS *next;
342 };
343 
344 struct gedge
345 {
346   gbbS *dst_bb;
347   /* A linked list.  In order of addition.  */
348   gedgeS *next;
349   bool visited;
350 };
351 
352 /* Control flow graph of generic GAS instructions.  */
353 
354 struct gcfg
355 {
356   uint64_t num_gbbs;
357   gbbS *root_bb;
358 };
359 
360 typedef struct gcfg gcfgS;
361 
362 #define bb_for_each_insn(bb, ginsn)  \
363   for (ginsn = bb->first_ginsn; ginsn; \
364        ginsn = (ginsn != bb->last_ginsn) ? ginsn->next : NULL)
365 
366 #define bb_for_each_edge(bb, edge) \
367   for (edge = (edge == NULL) ? bb->out_gedges : edge; edge; edge = edge->next)
368 
369 #define cfg_for_each_bb(cfg, bb) \
370   for (bb = cfg->root_bb; bb; bb = bb->next)
371 
372 #define bb_get_first_ginsn(bb)	  \
373   (bb->first_ginsn)
374 
375 #define bb_get_last_ginsn(bb)	  \
376   (bb->last_ginsn)
377 
378 gcfgS *gcfg_build (const symbolS *func, int *errp);
379 void gcfg_cleanup (gcfgS **gcfg);
380 void gcfg_print (const gcfgS *gcfg, FILE *outfile);
381 gbbS *gcfg_get_rootbb (gcfgS *gcfg);
382 void gcfg_get_bbs_in_prog_order (gcfgS *gcfg, gbbS **prog_order_bbs);
383 
384 #endif /* GINSN_H.  */
385