2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief This file implements the creation of the achitecture specific firm
9 * opcodes and the coresponding node constructors for the sparc
11 * @author Hannes Rapp, Matthias Braun
18 #include "irgraph_t.h"
28 #include "bearch_sparc_t.h"
30 #include "sparc_nodes_attr.h"
31 #include "sparc_new_nodes.h"
32 #include "gen_sparc_regalloc_if.h"
34 bool sparc_has_load_store_attr(const ir_node *node)
36 return is_sparc_Ld(node) || is_sparc_St(node) || is_sparc_Ldf(node)
37 || is_sparc_Stf(node);
40 static bool has_jmp_cond_attr(const ir_node *node)
42 return is_sparc_Bicc(node) || is_sparc_fbfcc(node);
45 static bool has_switch_jmp_attr(const ir_node *node)
47 return is_sparc_SwitchJmp(node);
50 static bool has_fp_attr(const ir_node *node)
52 return is_sparc_fadd(node) || is_sparc_fsub(node)
53 || is_sparc_fmul(node) || is_sparc_fdiv(node)
54 || is_sparc_fftoi(node) || is_sparc_fitof(node)
55 || is_sparc_fneg(node) || is_sparc_fcmp(node);
58 static bool has_fp_conv_attr(const ir_node *node)
60 return is_sparc_fftof(node);
64 * Dumper interface for dumping sparc nodes in vcg.
65 * @param F the output file
66 * @param n the node to dump
67 * @param reason indicates which kind of information should be dumped
69 static void sparc_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
71 const sparc_attr_t *sparc_attr;
74 case dump_node_opcode_txt:
75 fprintf(F, "%s", get_irn_opname(n));
78 case dump_node_mode_txt:
81 case dump_node_info_txt:
82 arch_dump_reqs_and_registers(F, n);
83 sparc_attr = get_sparc_attr_const(n);
84 if (sparc_attr->immediate_value_entity) {
85 ir_fprintf(F, "entity: %+F (offset %d)\n",
86 sparc_attr->immediate_value_entity,
87 sparc_attr->immediate_value);
89 ir_fprintf(F, "immediate value: %d\n", sparc_attr->immediate_value);
91 if (sparc_has_load_store_attr(n)) {
92 const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(n);
93 ir_fprintf(F, "load store mode: %+F\n", attr->load_store_mode);
94 fprintf(F, "is frame entity: %s\n",
95 attr->is_frame_entity ? "true" : "false");
97 if (has_jmp_cond_attr(n)) {
98 const sparc_jmp_cond_attr_t *attr
99 = get_sparc_jmp_cond_attr_const(n);
100 fprintf(F, "relation: %d (%s)\n", (int)attr->relation,
101 get_relation_string(attr->relation));
102 fprintf(F, "unsigned: %s\n", attr->is_unsigned ? "true" : "false");
104 if (has_fp_attr(n)) {
105 const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(n);
106 ir_fprintf(F, "fp_mode: %+F\n", attr->fp_mode);
108 if (has_fp_conv_attr(n)) {
109 const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(n);
110 ir_fprintf(F, "conv from: %+F\n", attr->src_mode);
111 ir_fprintf(F, "conv to: %+F\n", attr->dest_mode);
115 case dump_node_nodeattr_txt:
120 static void sparc_set_attr_imm(ir_node *res, ir_entity *entity,
121 int32_t immediate_value)
123 sparc_attr_t *attr = (sparc_attr_t*)get_irn_generic_attr(res);
124 attr->immediate_value_entity = entity;
125 attr->immediate_value = immediate_value;
126 arch_add_irn_flags(res, (arch_irn_flags_t)sparc_arch_irn_flag_immediate_form);
129 static void init_sparc_jmp_cond_attr(ir_node *node, ir_relation relation,
132 sparc_jmp_cond_attr_t *attr = get_sparc_jmp_cond_attr(node);
133 attr->relation = relation;
134 attr->is_unsigned = is_unsigned;
137 sparc_attr_t *get_sparc_attr(ir_node *node)
139 assert(is_sparc_irn(node));
140 return (sparc_attr_t*) get_irn_generic_attr(node);
143 const sparc_attr_t *get_sparc_attr_const(const ir_node *node)
145 assert(is_sparc_irn(node));
146 return (const sparc_attr_t*) get_irn_generic_attr_const(node);
149 sparc_load_store_attr_t *get_sparc_load_store_attr(ir_node *node)
151 assert(sparc_has_load_store_attr(node));
152 return (sparc_load_store_attr_t*) get_irn_generic_attr_const(node);
155 const sparc_load_store_attr_t *get_sparc_load_store_attr_const(const ir_node *node)
157 assert(sparc_has_load_store_attr(node));
158 return (const sparc_load_store_attr_t*) get_irn_generic_attr_const(node);
161 sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr(ir_node *node)
163 assert(has_jmp_cond_attr(node));
164 return (sparc_jmp_cond_attr_t*) get_irn_generic_attr_const(node);
167 const sparc_jmp_cond_attr_t *get_sparc_jmp_cond_attr_const(const ir_node *node)
169 assert(has_jmp_cond_attr(node));
170 return (const sparc_jmp_cond_attr_t*) get_irn_generic_attr_const(node);
173 sparc_switch_jmp_attr_t *get_sparc_switch_jmp_attr(ir_node *node)
175 assert(has_switch_jmp_attr(node));
176 return (sparc_switch_jmp_attr_t*) get_irn_generic_attr_const(node);
179 const sparc_switch_jmp_attr_t *get_sparc_switch_jmp_attr_const(const ir_node *node)
181 assert(has_switch_jmp_attr(node));
182 return (const sparc_switch_jmp_attr_t*) get_irn_generic_attr_const(node);
185 sparc_fp_attr_t *get_sparc_fp_attr(ir_node *node)
187 assert(has_fp_attr(node));
188 return (sparc_fp_attr_t*) get_irn_generic_attr(node);
191 const sparc_fp_attr_t *get_sparc_fp_attr_const(const ir_node *node)
193 assert(has_fp_attr(node));
194 return (const sparc_fp_attr_t*) get_irn_generic_attr_const(node);
197 sparc_fp_conv_attr_t *get_sparc_fp_conv_attr(ir_node *node)
199 assert(has_fp_conv_attr(node));
200 return (sparc_fp_conv_attr_t*) get_irn_generic_attr(node);
203 const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node)
205 assert(has_fp_conv_attr(node));
206 return (const sparc_fp_conv_attr_t*) get_irn_generic_attr_const(node);
210 * Initializes the nodes attributes.
212 static void init_sparc_attributes(ir_node *node, arch_irn_flags_t flags,
213 const arch_register_req_t **in_reqs,
216 ir_graph *irg = get_irn_irg(node);
217 struct obstack *obst = get_irg_obstack(irg);
218 backend_info_t *info;
220 arch_set_irn_flags(node, flags);
221 arch_set_irn_register_reqs_in(node, in_reqs);
223 info = be_get_info(node);
224 info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
227 static void init_sparc_load_store_attributes(ir_node *res, ir_mode *ls_mode,
228 ir_entity *entity, int32_t offset,
229 bool is_frame_entity,
232 sparc_load_store_attr_t *attr = get_sparc_load_store_attr(res);
233 attr->base.immediate_value_entity = entity;
234 attr->base.immediate_value = offset;
235 attr->load_store_mode = ls_mode;
236 attr->is_frame_entity = is_frame_entity;
237 attr->is_reg_reg = is_reg_reg;
240 static void init_sparc_fp_attributes(ir_node *res, ir_mode *fp_mode)
242 sparc_fp_attr_t *attr = get_sparc_fp_attr(res);
243 attr->fp_mode = fp_mode;
246 static void init_sparc_fp_conv_attributes(ir_node *res, ir_mode *src_mode,
249 sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr(res);
250 attr->src_mode = src_mode;
251 attr->dest_mode = dest_mode;
254 static void init_sparc_switch_jmp_attributes(ir_node *node,
255 const ir_switch_table *table,
256 ir_entity *table_entity)
258 sparc_switch_jmp_attr_t *attr = get_sparc_switch_jmp_attr(node);
260 attr->table_entity = table_entity;
262 be_foreach_out(node, o) {
263 arch_set_irn_register_req_out(node, o, arch_no_register_req);
268 * copies sparc attributes of node
270 static void sparc_copy_attr(ir_graph *irg, const ir_node *old_node,
273 struct obstack *obst = get_irg_obstack(irg);
274 const sparc_attr_t *attr_old = get_sparc_attr_const(old_node);
275 sparc_attr_t *attr_new = get_sparc_attr(new_node);
276 backend_info_t *old_info = be_get_info(old_node);
277 backend_info_t *new_info = be_get_info(new_node);
279 /* copy the attributes */
280 memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
282 new_info->flags = old_info->flags;
283 new_info->out_infos =
284 DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
285 new_info->in_reqs = old_info->in_reqs;
289 * compare some node's attributes
291 static int cmp_attr_sparc(const ir_node *a, const ir_node *b)
293 const sparc_attr_t *attr_a = get_sparc_attr_const(a);
294 const sparc_attr_t *attr_b = get_sparc_attr_const(b);
296 return attr_a->immediate_value != attr_b->immediate_value
297 || attr_a->immediate_value_entity != attr_b->immediate_value_entity;
300 static int cmp_attr_sparc_load_store(const ir_node *a, const ir_node *b)
302 const sparc_load_store_attr_t *attr_a = get_sparc_load_store_attr_const(a);
303 const sparc_load_store_attr_t *attr_b = get_sparc_load_store_attr_const(b);
305 if (cmp_attr_sparc(a, b))
308 return attr_a->is_frame_entity != attr_b->is_frame_entity
309 || attr_a->load_store_mode != attr_b->load_store_mode;
312 static int cmp_attr_sparc_jmp_cond(const ir_node *a, const ir_node *b)
314 const sparc_jmp_cond_attr_t *attr_a = get_sparc_jmp_cond_attr_const(a);
315 const sparc_jmp_cond_attr_t *attr_b = get_sparc_jmp_cond_attr_const(b);
317 if (cmp_attr_sparc(a, b))
320 return attr_a->relation != attr_b->relation
321 || attr_a->is_unsigned != attr_b->is_unsigned;
324 static int cmp_attr_sparc_fp(const ir_node *a, const ir_node *b)
326 const sparc_fp_attr_t *attr_a = get_sparc_fp_attr_const(a);
327 const sparc_fp_attr_t *attr_b = get_sparc_fp_attr_const(b);
329 if (cmp_attr_sparc(a, b))
332 return attr_a->fp_mode != attr_b->fp_mode;
335 static int cmp_attr_sparc_fp_conv(const ir_node *a, const ir_node *b)
337 const sparc_fp_conv_attr_t *attr_a = get_sparc_fp_conv_attr_const(a);
338 const sparc_fp_conv_attr_t *attr_b = get_sparc_fp_conv_attr_const(b);
340 if (cmp_attr_sparc(a, b))
343 return attr_a->src_mode != attr_b->src_mode
344 || attr_a->dest_mode != attr_b->dest_mode;
347 /* Include the generated constructor functions */
348 #include "gen_sparc_new_nodes.c.inl"