cleanup: Remove pointless assert(is_${NODE}(x)) just before get_${NODE}_${FOO}(x...
[libfirm] / ir / be / beemitter_binary.h
1 /*
2  * Copyright (C) 1995-2o008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Interface for binary machine code output.
23  * @author      Matthias Braun
24  * @date        12.03.2007
25  */
26 #ifndef FIRM_BE_BEEMITTER_BINARY_H
27 #define FIRM_BE_BEEMITTER_BINARY_H
28
29 #include <stdio.h>
30 #include <stdbool.h>
31 #include <stdint.h>
32 #include "firm_types.h"
33 #include "obst.h"
34
35 extern struct obstack code_fragment_obst;
36
37 typedef struct code_fragment_t code_fragment_t;
38 struct code_fragment_t {
39 #ifndef NDEBUG
40         unsigned         magic;
41 #endif
42         unsigned         len;          /**< size of the fragments data (the jump is
43                                             included in the data if its size is
44                                             unknown) */
45         unsigned         alignment;    /**< alignment of the fragment in bytes */
46         code_fragment_t *next;         /**< pointer to next fragment in line */
47         unsigned         offset;       /**< offset of this fragment relative to the
48                                             "start" */
49         unsigned         max_offset;   /**< maximum offset */
50         int              jump_type;    /**< can be used by the backend to indicate
51                                             the type of jump at the end of this
52                                             fragment */
53         void            *jump_data;    /**< can be used by the backend to encode
54                                             additional data for the jump (like its
55                                             destination) */
56         code_fragment_t *destination;  /**< destination fragment of this jump */
57
58         unsigned short   jumpsize_min;
59         unsigned short   jumpsize_max;
60
61         unsigned char    data[];       /**< data starts here */
62 };
63
64 typedef struct binary_emiter_interface_t binary_emiter_interface_t;
65 struct binary_emiter_interface_t {
66         /** create @p size of NOP instructions for alignment */
67         void (*create_nops) (unsigned char *buffer, unsigned size);
68
69         /**
70          * emits a jump by writing it to the buffer. The code for the jump must be
71          * exactly fragment->jumpsize_min bytes long.
72          * TODO: create a stream API which we can use here...
73          */
74         void (*emit_jump) (code_fragment_t *fragment, unsigned char *buffer);
75
76         /**
77          * determines the minimum and maximum size of bytes needed to emit
78          * the jump at the end of the fragment. The function must update the
79          * jumpsize_min and jumpsize_max fields in the fragment.
80          */
81         void (*determine_jumpsize) (code_fragment_t *fragment);
82 };
83
84 /** Initializes and prepares for emitting a routine with code "fragments".
85  * Creates an initial fragment in which you can emit right away.
86  */
87 void be_start_code_emitter(void);
88
89 /** finalizes and emits current procedure */
90 void be_emit_code(FILE *output, const binary_emiter_interface_t *interface);
91
92 /** finish current fragment and return its final address */
93 code_fragment_t *be_finish_fragment(void);
94
95 /** Create a new code fragment (and append it to the previous one) */
96 void be_start_new_fragment(void);
97
98 /** returns current fragment (the address stays only valid until the next
99     be_emit(8/16/32/entity) call!) */
100 code_fragment_t *be_get_current_fragment(void);
101
102 /** appends a byte to the current fragment */
103 static inline void be_emit8(const unsigned char byte)
104 {
105         obstack_1grow(&code_fragment_obst, byte);
106 }
107
108 /** appends a word (16bits) to the current fragment */
109 static inline void be_emit16(const uint16_t u16)
110 {
111         /* TODO: fix endianess if needed */
112         obstack_grow(&code_fragment_obst, &u16, 2);
113 }
114
115 /** appends a dword (32bits) to the current fragment */
116 static inline void be_emit32(const uint32_t u32)
117 {
118         /* TODO: fix endianess if needed */
119         obstack_grow(&code_fragment_obst, &u32, 4);
120 }
121
122 /** leave space where an entity reference is put at the finish stage */
123 void be_emit_entity(ir_entity *entity, bool entity_sign, int offset,
124                     bool is_relative);
125
126 #endif