amd64: small changes w.r.t. stack alignment.
[libfirm] / ir / be / beemitter_binary.h
1 /*
2  * Copyright (C) 1995-2008 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  * @version     $Id$
26  */
27 #ifndef FIRM_BE_BEEMITTER_BINARY_H
28 #define FIRM_BE_BEEMITTER_BINARY_H
29
30 #include <stdio.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include "firm_types.h"
34 #include "obst.h"
35
36 extern struct obstack code_fragment_obst;
37
38 typedef struct code_fragment_t code_fragment_t;
39 struct code_fragment_t {
40 #ifndef NDEBUG
41         unsigned         magic;
42 #endif
43         unsigned         len;          /**< size of the fragments data (the jump is
44                                             included in the data if its size is
45                                             unknown) */
46         unsigned         alignment;    /**< alignment of the fragment in bytes */
47         code_fragment_t *next;         /**< pointer to next fragment in line */
48         unsigned         offset;       /**< offset of this fragment relative to the
49                                             "start" */
50         unsigned         max_offset;   /**< maximum offset */
51         int              jump_type;    /**< can be used by the backend to indicate
52                                             the type of jump at the end of this
53                                             fragment */
54         void            *jump_data;    /**< can be used by the backend to encode
55                                             additional data for the jump (like its
56                                             destination) */
57         code_fragment_t *destination;  /**< destination fragment of this jump */
58
59         unsigned short   jumpsize_min;
60         unsigned short   jumpsize_max;
61
62         unsigned char    data[0];      /**< data starts here */
63 };
64
65 typedef struct binary_emiter_interface_t binary_emiter_interface_t;
66 struct binary_emiter_interface_t {
67         /** create @p size of NOP instructions for alignment */
68         void (*create_nops) (unsigned char *buffer, unsigned size);
69
70         /**
71          * emits a jump by writing it to the buffer. The code for the jump must be
72          * exactly fragment->jumpsize_min bytes long.
73          * TODO: create a stream API which we can use here...
74          */
75         void (*emit_jump) (code_fragment_t *fragment, unsigned char *buffer);
76
77         /**
78          * determines the minimum and maximum size of bytes needed to emit
79          * the jump at the end of the fragment. The function must update the
80          * jumpsize_min and jumpsize_max fields in the fragment.
81          */
82         void (*determine_jumpsize) (code_fragment_t *fragment);
83 };
84
85 /** Initializes and prepares for emitting a routine with code "fragments".
86  * Creates an initial fragment in which you can emit right away.
87  */
88 void be_start_code_emitter(void);
89
90 /** finalizes and emits current procedure */
91 void be_emit_code(FILE *output, const binary_emiter_interface_t *interface);
92
93 /** finish current fragment and return its final address */
94 code_fragment_t *be_finish_fragment(void);
95
96 /** Create a new code fragment (and append it to the previous one) */
97 void be_start_new_fragment(void);
98
99 /** returns current fragment (the address stays only valid until the next
100     be_emit(8/16/32/entity) call!) */
101 code_fragment_t *be_get_current_fragment(void);
102
103 /** appends a byte to the current fragment */
104 static inline void be_emit8(const unsigned char byte)
105 {
106         obstack_1grow(&code_fragment_obst, byte);
107 }
108
109 /** appends a word (16bits) to the current fragment */
110 static inline void be_emit16(const uint16_t u16)
111 {
112         /* TODO: fix endianess if needed */
113         obstack_grow(&code_fragment_obst, &u16, 2);
114 }
115
116 /** appends a dword (32bits) to the current fragment */
117 static inline void be_emit32(const uint32_t u32)
118 {
119         /* TODO: fix endianess if needed */
120         obstack_grow(&code_fragment_obst, &u32, 4);
121 }
122
123 /** leave space where an entity reference is put at the finish stage */
124 void be_emit_entity(ir_entity *entity, bool entity_sign, int offset,
125                     bool is_relative);
126
127 #endif