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