2 * This file implements the creation of the achitecture specific firm opcodes
3 * and the coresponding node constructors for the ppc assembler irg.
13 #include "irgraph_t.h"
19 #include "firm_common_t.h"
24 #include "../bearch_t.h"
26 #include "ppc32_nodes_attr.h"
27 #include "ppc32_new_nodes.h"
28 #include "gen_ppc32_regalloc_if.h"
32 /***********************************************************************************
35 * __| |_ _ _ __ ___ _ __ ___ _ __ _ _ __ | |_ ___ _ __| |_ __ _ ___ ___
36 * / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
37 * | (_| | |_| | | | | | | |_) | __/ | | | | | | || __/ | | || (_| | (_| __/
38 * \__,_|\__,_|_| |_| |_| .__/ \___|_| |_|_| |_|\__\___|_| |_| \__,_|\___\___|
41 ***********************************************************************************/
44 * Dumps the register requirements for either in or out.
46 static void dump_reg_req(FILE *F, ir_node *n, const arch_register_req_t **reqs, int inout) {
47 char *dir = inout ? "out" : "in";
48 int max = inout ? get_ppc32_n_res(n) : get_irn_arity(n);
52 memset(buf, 0, sizeof(buf));
55 for (i = 0; i < max; i++) {
56 fprintf(F, "%sreq #%d =", dir, i);
58 if (reqs[i]->type == arch_register_req_type_none) {
62 if (reqs[i]->type & arch_register_req_type_normal) {
63 fprintf(F, " %s", reqs[i]->cls->name);
66 if (reqs[i]->type & arch_register_req_type_limited) {
68 arch_register_req_format(buf, sizeof(buf), reqs[i], n));
71 if (reqs[i]->type & arch_register_req_type_should_be_same) {
72 ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->other_same));
75 if (reqs[i]->type & arch_register_req_type_should_be_different) {
76 ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->other_different));
84 fprintf(F, "%sreq = N/A\n", dir);
90 * Dumper interface for dumping ppc32 nodes in vcg.
91 * @param n the node to dump
92 * @param F the output file
93 * @param reason indicates which kind of information should be dumped
94 * @return 0 on success or != 0 on failure
96 static int ppc32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
101 const arch_register_req_t **reqs;
102 const arch_register_t **slots;
105 case dump_node_opcode_txt:
106 fprintf(F, "%s", get_irn_opname(n));
109 case dump_node_mode_txt:
110 mode = get_irn_mode(n);
113 fprintf(F, "[%s]", get_mode_name(mode));
116 fprintf(F, "[?NOMODE?]");
120 case dump_node_nodeattr_txt:
122 /* TODO: dump some attributes which should show up */
123 /* in node name in dump (e.g. consts or the like) */
127 case dump_node_info_txt:
128 attr = get_ppc32_attr(n);
129 fprintf(F, "=== ppc attr begin ===\n");
131 /* dump IN requirements */
132 if (get_irn_arity(n) > 0) {
133 reqs = get_ppc32_in_req_all(n);
134 dump_reg_req(F, n, reqs, 0);
137 /* dump OUT requirements */
138 if (attr->n_res > 0) {
139 reqs = get_ppc32_out_req_all(n);
140 dump_reg_req(F, n, reqs, 1);
143 /* dump assigned registers */
144 slots = get_ppc32_slots(n);
145 if (slots && attr->n_res > 0) {
146 for (i = 0; i < attr->n_res; i++) {
148 fprintf(F, "reg #%d = %s\n", i, slots[i]->name);
151 fprintf(F, "reg #%d = n/a\n", i);
158 fprintf(F, "n_res = %d\n", get_ppc32_n_res(n));
161 fprintf(F, "flags =");
162 if (attr->flags == arch_irn_flags_none) {
166 if (attr->flags & arch_irn_flags_dont_spill) {
167 fprintf(F, " unspillable");
169 if (attr->flags & arch_irn_flags_rematerializable) {
170 fprintf(F, " remat");
172 if (attr->flags & arch_irn_flags_ignore) {
173 fprintf(F, " ignore");
176 fprintf(F, " (%d)\n", attr->flags);
178 /* TODO: dump all additional attributes */
180 fprintf(F, "=== ppc attr end ===\n");
181 /* end of: case dump_node_info_txt */
191 /***************************************************************************************************
193 * | | | | | | / / | | | | | | | |
194 * __ _| |_| |_ _ __ ___ ___| |_ / /_ _ ___| |_ _ __ ___ ___| |_| |__ ___ __| |___
195 * / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
196 * | (_| | |_| |_| | \__ \ __/ |_ / / (_| | __/ |_ | | | | | | __/ |_| | | | (_) | (_| \__ \
197 * \__,_|\__|\__|_| |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
200 ***************************************************************************************************/
203 * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
204 * Firm was made by people hating const :-(
206 ppc32_attr_t *get_ppc32_attr(const ir_node *node) {
207 assert(is_ppc32_irn(node) && "need ppc node to get attributes");
208 return (ppc32_attr_t *)get_irn_generic_attr((ir_node *)node);
212 * Returns the argument register requirements of a ppc node.
214 const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node) {
215 ppc32_attr_t *attr = get_ppc32_attr(node);
220 * Returns the result register requirements of an ppc node.
222 const arch_register_req_t **get_ppc32_out_req_all(const ir_node *node) {
223 ppc32_attr_t *attr = get_ppc32_attr(node);
224 return attr->out_req;
228 * Returns the argument register requirement at position pos of an ppc node.
230 const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos) {
231 ppc32_attr_t *attr = get_ppc32_attr(node);
232 return attr->in_req[pos];
236 * Returns the result register requirement at position pos of an ppc node.
238 const arch_register_req_t *get_ppc32_out_req(const ir_node *node, int pos) {
239 ppc32_attr_t *attr = get_ppc32_attr(node);
240 return attr->out_req[pos];
244 * Sets the OUT register requirements at position pos.
246 void set_ppc32_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
247 ppc32_attr_t *attr = get_ppc32_attr(node);
248 attr->out_req[pos] = req;
252 * Sets the IN register requirements at position pos.
254 void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
255 ppc32_attr_t *attr = get_ppc32_attr(node);
256 attr->in_req[pos] = req;
260 * Returns the register flag of an ppc node.
262 arch_irn_flags_t get_ppc32_flags(const ir_node *node) {
263 ppc32_attr_t *attr = get_ppc32_attr(node);
268 * Sets the register flag of an ppc node.
270 void set_ppc32_flags(const ir_node *node, arch_irn_flags_t flags) {
271 ppc32_attr_t *attr = get_ppc32_attr(node);
276 * Returns the result register slots of an ppc node.
278 const arch_register_t **get_ppc32_slots(const ir_node *node) {
279 ppc32_attr_t *attr = get_ppc32_attr(node);
284 * Returns the name of the OUT register at position pos.
286 const char *get_ppc32_out_reg_name(const ir_node *node, int pos) {
287 ppc32_attr_t *attr = get_ppc32_attr(node);
289 assert(is_ppc32_irn(node) && "Not an ppc node.");
290 assert(pos < attr->n_res && "Invalid OUT position.");
291 assert(attr->slots[pos] && "No register assigned");
293 return arch_register_get_name(attr->slots[pos]);
297 * Returns the index of the OUT register at position pos within its register class.
299 int get_ppc32_out_regnr(const ir_node *node, int pos) {
300 ppc32_attr_t *attr = get_ppc32_attr(node);
302 assert(is_ppc32_irn(node) && "Not an ppc node.");
303 assert(pos < attr->n_res && "Invalid OUT position.");
304 assert(attr->slots[pos] && "No register assigned");
306 return arch_register_get_index(attr->slots[pos]);
310 * Returns the OUT register at position pos.
312 const arch_register_t *get_ppc32_out_reg(const ir_node *node, int pos) {
313 ppc32_attr_t *attr = get_ppc32_attr(node);
315 assert(is_ppc32_irn(node) && "Not an ppc node.");
316 assert(pos < attr->n_res && "Invalid OUT position.");
317 assert(attr->slots[pos] && "No register assigned");
319 return attr->slots[pos];
323 * Sets the number of results.
325 void set_ppc32_n_res(ir_node *node, int n_res) {
326 ppc32_attr_t *attr = get_ppc32_attr(node);
331 * Returns the number of results.
333 int get_ppc32_n_res(const ir_node *node) {
334 ppc32_attr_t *attr = get_ppc32_attr(node);
339 * Sets the type of the constant (if any)
340 * May be either iro_Const or iro_SymConst
342 /* void set_ppc32_type(const ir_node *node, opcode type) {
343 ppc32_attr_t *attr = get_ppc32_attr(node);
348 * Returns the type of the content (if any)
350 ppc32_attr_content_type get_ppc32_type(const ir_node *node) {
351 ppc32_attr_t *attr = get_ppc32_attr(node);
352 return attr->content_type;
356 * Sets a tarval type content (also updating the content_type)
358 void set_ppc32_constant_tarval(const ir_node *node, tarval *const_tarval) {
359 ppc32_attr_t *attr = get_ppc32_attr(node);
360 attr->content_type = ppc32_ac_Const;
361 attr->data.constant_tarval = const_tarval;
365 * Returns a tarval type constant
367 tarval *get_ppc32_constant_tarval(const ir_node *node) {
368 ppc32_attr_t *attr = get_ppc32_attr(node);
369 return attr->data.constant_tarval;
373 * Sets an ident type constant (also updating the content_type)
375 void set_ppc32_symconst_ident(const ir_node *node, ident *symconst_ident) {
376 ppc32_attr_t *attr = get_ppc32_attr(node);
377 attr->content_type = ppc32_ac_SymConst;
378 attr->data.symconst_ident = symconst_ident;
382 * Returns an ident type constant
384 ident *get_ppc32_symconst_ident(const ir_node *node) {
385 ppc32_attr_t *attr = get_ppc32_attr(node);
386 return attr->data.symconst_ident;
391 * Sets an entity (also updating the content_type)
393 void set_ppc32_frame_entity(const ir_node *node, ir_entity *ent) {
394 ppc32_attr_t *attr = get_ppc32_attr(node);
395 attr->content_type = ppc32_ac_FrameEntity;
396 attr->data.frame_entity = ent;
402 ir_entity *get_ppc32_frame_entity(const ir_node *node) {
403 ppc32_attr_t *attr = get_ppc32_attr(node);
404 return attr->data.frame_entity;
408 * Sets a Rlwimi const (also updating the content_type)
410 void set_ppc32_rlwimi_const(const ir_node *node, unsigned shift, unsigned maskA, unsigned maskB) {
411 ppc32_attr_t *attr = get_ppc32_attr(node);
412 attr->content_type = ppc32_ac_RlwimiConst;
413 attr->data.rlwimi_const.shift = shift;
414 attr->data.rlwimi_const.maskA = maskA;
415 attr->data.rlwimi_const.maskB = maskB;
419 * Returns the rlwimi const structure
421 rlwimi_const_t *get_ppc32_rlwimi_const(const ir_node *node) {
422 ppc32_attr_t *attr = get_ppc32_attr(node);
423 return &attr->data.rlwimi_const;
427 * Sets a Proj number (also updating the content_type)
429 void set_ppc32_proj_nr(const ir_node *node, int proj_nr) {
430 ppc32_attr_t *attr = get_ppc32_attr(node);
431 attr->content_type = ppc32_ac_BranchProj;
432 attr->data.proj_nr = proj_nr;
436 * Returns the proj number
438 int get_ppc32_proj_nr(const ir_node *node) {
439 ppc32_attr_t *attr = get_ppc32_attr(node);
440 return attr->data.proj_nr;
444 * Sets an offset for a memory access (also updating the content_type)
446 void set_ppc32_offset(const ir_node *node, int offset) {
447 ppc32_attr_t *attr = get_ppc32_attr(node);
448 attr->content_type = ppc32_ac_Offset;
449 attr->data.offset = offset;
455 int get_ppc32_offset(const ir_node *node) {
456 ppc32_attr_t *attr = get_ppc32_attr(node);
457 return attr->data.offset;
461 * Sets the offset mode (ppc32_ao_None, ppc32_ao_Lo16, ppc32_ao_Hi16 or ppc32_ao_Ha16)
463 void set_ppc32_offset_mode(const ir_node *node, ppc32_attr_offset_mode mode) {
464 ppc32_attr_t *attr = get_ppc32_attr(node);
465 attr->offset_mode = mode;
469 * Returns the offset mode
471 ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node) {
472 ppc32_attr_t *attr = get_ppc32_attr(node);
473 return attr->offset_mode;
478 * Initializes ppc specific node attributes
480 void init_ppc32_attributes(ir_node *node, int flags,
481 const arch_register_req_t **in_reqs, const arch_register_req_t **out_reqs,
482 const be_execution_unit_t ***execution_units,
483 int n_res, unsigned latency) {
484 ppc32_attr_t *attr = get_ppc32_attr(node);
487 attr->in_req = in_reqs;
488 attr->out_req = out_reqs;
491 attr->content_type = ppc32_ac_None;
492 attr->offset_mode = ppc32_ao_Illegal;
493 attr->data.empty = NULL;
495 memset((void *)attr->slots, 0, n_res * sizeof(attr->slots[0]));
499 /***************************************************************************************
502 * _ __ ___ __| | ___ ___ ___ _ __ ___| |_ _ __ _ _ ___| |_ ___ _ __ ___
503 * | '_ \ / _ \ / _` |/ _ \ / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
504 * | | | | (_) | (_| | __/ | (_| (_) | | | \__ \ |_| | | |_| | (__| || (_) | | \__ \
505 * |_| |_|\___/ \__,_|\___| \___\___/|_| |_|___/\__|_| \__,_|\___|\__\___/|_| |___/
507 ***************************************************************************************/
509 /* Include the generated constructor functions */
510 #include "gen_ppc32_new_nodes.c.inl"