2 * This file implements the creation of the achitecture specific firm opcodes
3 * and the coresponding node constructors for the $arch assembler irg.
4 * @author Christian Wuerdig
15 #include "irgraph_t.h"
20 #include "firm_common_t.h"
23 #include "../bearch.h"
25 #include "ia32_nodes_attr.h"
26 #include "ia32_new_nodes.h"
28 #include "gen_ia32_regalloc_if.c.inl"
32 /***********************************************************************************
35 * __| |_ _ _ __ ___ _ __ ___ _ __ _ _ __ | |_ ___ _ __| |_ __ _ ___ ___
36 * / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
37 * | (_| | |_| | | | | | | |_) | __/ | | | | | | || __/ | | || (_| | (_| __/
38 * \__,_|\__,_|_| |_| |_| .__/ \___|_| |_|_| |_|\__\___|_| |_| \__,_|\___\___|
41 ***********************************************************************************/
46 * Prints a tarval to file F.
47 * @param F output file
49 * @param brackets 1 == print square brackets around tarval
51 static void fprintf_tv(FILE *F, tarval *tv, int brackets) {
53 tarval_snprintf(buf, sizeof(buf), tv);
56 fprintf(F, "[%s]", buf);
58 fprintf(F, "%s", buf);
62 * Returns the name of a SymConst.
63 * @param symc the SymConst
64 * @return name of the SymConst
66 const char *get_sc_name(ir_node *symc) {
67 if (get_irn_opcode(symc) != iro_SymConst)
70 switch (get_SymConst_kind(symc)) {
71 case symconst_addr_name:
72 return get_id_str(get_SymConst_name(symc));
74 case symconst_addr_ent:
75 return get_entity_ld_name(get_SymConst_entity(symc));
78 assert(0 && "Unsupported SymConst");
83 * Dumper interface for dumping ia32 nodes in vcg.
84 * @param n the node to dump
85 * @param F the output file
86 * @param reason indicates which kind of information should be dumped
87 * @return 0 on success or != 0 on failure
89 static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
95 case dump_node_opcode_txt:
96 name = get_irn_opname(n);
97 fprintf(F, "%s", name);
100 case dump_node_mode_txt:
101 mode = get_irn_mode(n);
103 if (mode == mode_BB || mode == mode_ANY || mode == mode_BAD || mode == mode_T) {
106 else if (is_ia32_Load(n)) {
107 mode = get_irn_mode(get_irn_n(n, 1));
109 else if (is_ia32_Store(n)) {
110 mode = get_irn_mode(get_irn_n(n, 2));
114 fprintf(F, "[%s]", get_mode_name(mode));
117 case dump_node_nodeattr_txt:
118 name = get_irn_opname(n);
119 p = name + strlen(name) - 2;
120 if (p[0] == '_' && p[1] == 'i') {
121 tarval *tv = get_ia32_Immop_tarval(n);
123 fprintf_tv(F, tv, 1);
125 fprintf(F, "[SymC &%s]", get_sc_name(get_ia32_old_ir(n)));
128 else if (is_ia32_Call(n)) {
129 ir_node *old_call = get_ia32_old_ir(n);
130 ir_node *sc = get_Call_ptr(old_call);
132 fprintf(F, "&%s ", get_sc_name(sc));
136 case dump_node_info_txt:
137 if (is_ia32_Lea(n)) {
138 tarval *o = get_ia32_offs(n);
139 tarval *tv = get_ia32_Immop_tarval(n);
144 fprintf(F, "(%s, %s", get_irn_opname(get_irn_n(n, 0)), get_irn_opname(get_irn_n(n, 1)));
147 fprintf_tv(F, tv, 0);
159 /***************************************************************************************************
161 * | | | | | | / / | | | | | | | |
162 * __ _| |_| |_ _ __ ___ ___| |_ / /_ _ ___| |_ _ __ ___ ___| |_| |__ ___ __| |___
163 * / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
164 * | (_| | |_| |_| | \__ \ __/ |_ / / (_| | __/ |_ | | | | | | __/ |_| | | | (_) | (_| \__ \
165 * \__,_|\__|\__|_| |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
168 ***************************************************************************************************/
171 * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
172 * Firm was made by people hating const :-(
174 asmop_attr *get_ia32_attr(const ir_node *node) {
175 return (asmop_attr *)get_irn_generic_attr((ir_node *)node);
179 * Return the tarval of an immediate operation or NULL in case of SymConst
181 tarval *get_ia32_Immop_tarval(const ir_node *node) {
182 asmop_attr *attr = get_ia32_attr(node);
183 if (attr->tp == asmop_Const)
190 * Return the old_ir attribute.
192 ir_node *get_ia32_old_ir(const ir_node *node) {
193 asmop_attr *attr = get_ia32_attr(node);
198 * Copy the attributes from an ia32_Const to an Immop (Add_i, Sub_i, ...) node
200 void set_ia32_Immop_attr(ir_node *node, ir_node *cnst) {
201 asmop_attr *na = get_ia32_attr(node);
202 asmop_attr *ca = get_ia32_attr(cnst);
204 assert(is_ia32_Const(cnst) && "Need ia32_Const to set Immop attr");
208 na->old_ir = ca->old_ir;
212 * Copy the attributes from a Const to an ia32_Const
214 void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst) {
215 asmop_attr *attr = get_ia32_attr(ia32_cnst);
217 assert(is_ia32_Const(ia32_cnst) && "Need ia32_Const to set Const attr");
219 switch (get_irn_opcode(cnst)) {
221 attr->tp = asmop_Const;
222 attr->tv = get_Const_tarval(cnst);
225 attr->tp = asmop_SymConst;
229 assert(0 && "Unknown Const NYI");
232 assert(0 && "Cannot create ia32_Const for this opcode");
237 * Sets the type of an ia32_Const.
239 void set_ia32_Const_type(ir_node *node, int type) {
240 asmop_attr *attr = get_ia32_attr(node);
242 assert(is_ia32_Const(node) && "Need ia32_Const to set type");
243 assert((type == asmop_Const || type == asmop_SymConst) && "Unsupported ia32_Const type");
249 * Sets the attributes of an immediate operation to the specified tarval
251 void set_ia32_Immop_tarval(ir_node *node, tarval *tv) {
252 asmop_attr *attr = get_ia32_attr(node);
254 attr->tp = asmop_Const;
259 * Sets the offset for a Lea.
261 void set_ia32_offs(ir_node *node, tarval *offs) {
262 asmop_attr *attr = get_ia32_attr(node);
267 * Gets the offset for a Lea.
269 tarval *get_ia32_offs(const ir_node *node) {
270 asmop_attr *attr = get_ia32_attr(node);
275 * Returns the argument register requirements of an ia32 node.
277 const arch_register_req_t **get_ia32_in_req(const ir_node *node) {
278 asmop_attr *attr = get_ia32_attr(node);
283 * Returns the result register requirements of an ia32 node.
285 const arch_register_req_t **get_ia32_out_req(const ir_node *node) {
286 asmop_attr *attr = get_ia32_attr(node);
287 return attr->out_req;
291 * Returns the register flag of an ia32 node.
293 arch_irn_flags_t get_ia32_flags(const ir_node *node) {
294 asmop_attr *attr = get_ia32_attr(node);
299 * Returns the argument register slots of an ia32 node.
301 const arch_register_t **get_ia32_in_slots(const ir_node *node) {
302 asmop_attr *attr = get_ia32_attr(node);
307 * Returns the result register slots of an ia32 node.
309 const arch_register_t **get_ia32_out_slots(const ir_node *node) {
310 asmop_attr *attr = get_ia32_attr(node);
315 * Returns the name of the IN register at position pos.
317 const char *get_ia32_in_reg_name(const ir_node *node, int pos) {
318 asmop_attr *attr = get_ia32_attr(node);
320 assert(is_ia32_irn(node) && "Not an ia32 node.");
321 assert(pos < get_irn_arity(node) && "Invalid IN position.");
323 return attr->in[pos]->name;
327 * Returns the name of the OUT register at position pos.
329 const char *get_ia32_out_reg_name(const ir_node *node, int pos) {
330 asmop_attr *attr = get_ia32_attr(node);
332 assert(is_ia32_irn(node) && "Not an ia32 node.");
333 assert(pos < attr->n_res && "Invalid OUT position.");
335 return attr->out[pos]->name;
339 * Returns the index of the IN register at position pos within its register class.
341 int get_ia32_in_regnr(const ir_node *node, int pos) {
342 asmop_attr *attr = get_ia32_attr(node);
344 assert(is_ia32_irn(node) && "Not an ia32 node.");
345 assert(pos < get_irn_arity(node) && "Invalid IN position.");
347 return attr->in[pos]->index;
351 * Returns the index of the OUT register at position pos within its register class.
353 int get_ia32_out_regnr(const ir_node *node, int pos) {
354 asmop_attr *attr = get_ia32_attr(node);
356 assert(is_ia32_irn(node) && "Not an ia32 node.");
357 assert(pos < attr->n_res && "Invalid OUT position.");
359 return attr->out[pos]->index;
363 * Sets the number of results.
365 void set_ia32_n_res(ir_node *node, int n_res) {
366 asmop_attr *attr = get_ia32_attr(node);
371 * Returns the number of results.
373 int get_ia32_n_res(const ir_node *node) {
374 asmop_attr *attr = get_ia32_attr(node);
379 * Sets the flavour of an ia32 DivMod node to flavour_Div/Mod/DivMod.
381 void set_ia32_DivMod_flavour(ir_node *node, divmod_flavour_t dm_flav) {
382 asmop_attr *attr = get_ia32_attr(node);
383 attr->dm_flav = dm_flav;
386 /* Include the generated functions */
387 #include "gen_ia32_new_nodes.c.inl"