summaryrefslogtreecommitdiffhomepage
path: root/ir/lower
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2018-05-08 11:43:40 +0200
committerChristoph Mallon <christoph.mallon@gmx.de>2018-05-08 11:43:40 +0200
commit314369bc156ad55385d5d761e0013ff8d9f13549 (patch)
treebcf1d4821708758926504a3aa16d69383a00c9e9 /ir/lower
parentfdbad50c80b6be19414d6f955f1213809d3117d9 (diff)
lower_dw: Move the ia32-specific ASM lowerer into the ia32 backend.
Diffstat (limited to 'ir/lower')
-rw-r--r--ir/lower/lower_dw.c92
-rw-r--r--ir/lower/lower_dw.h6
2 files changed, 13 insertions, 85 deletions
diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c
index 3540ab5..9a0357e 100644
--- a/ir/lower/lower_dw.c
+++ b/ir/lower/lower_dw.c
@@ -118,7 +118,7 @@ static lower_dw_env_t env;
static void lower_node(ir_node *node);
-static bool needs_lowering(const ir_mode *mode)
+bool needs_lowering(ir_mode const *const mode)
{
return get_mode_size_bits(mode) == env.p.doubleword_size
&& get_mode_arithmetic(mode) == irma_twos_complement;
@@ -152,7 +152,7 @@ static void lower_mode(void (*const set)(ir_type*, size_t, ir_type*), ir_type *c
}
}
-static ir_mode *get_high_mode(ir_mode *const mode)
+ir_mode *get_high_mode(ir_mode *const mode)
{
return mode_is_signed(mode) ? env.p.word_signed : env.p.word_unsigned;
}
@@ -1962,96 +1962,18 @@ static void lower_Mux(ir_node *const mux)
*/
static void lower_ASM(ir_node *const asmn)
{
- size_t n_outs = get_ASM_n_output_constraints(asmn);
- ir_asm_constraint *output_constraints = get_ASM_output_constraints(asmn);
- ir_asm_constraint *input_constraints = get_ASM_input_constraints(asmn);
- unsigned n_64bit_outs = 0;
-
foreach_irn_in_r(asmn, i, op) {
ir_mode *op_mode = get_irn_mode(op);
- if (needs_lowering(op_mode)) {
+ if (needs_lowering(op_mode))
panic("lowering ASM 64bit input unimplemented");
- }
}
+ ir_asm_constraint *const output_constraints = get_ASM_output_constraints(asmn);
+ size_t const n_outs = get_ASM_n_output_constraints(asmn);
for (size_t o = 0; o < n_outs; ++o) {
const ir_asm_constraint *constraint = &output_constraints[o];
- if (needs_lowering(constraint->mode)) {
- const char *constr = get_id_str(constraint->constraint);
- ++n_64bit_outs;
- /* TODO: How to do this architecture neutral? This is very
- * i386 specific... */
- if (constr[0] != '=' || constr[1] != 'A') {
- panic("lowering ASM 64bit output only supports '=A' currently");
- }
- }
- }
-
- if (n_64bit_outs == 0)
- return;
-
- dbg_info *dbgi = get_irn_dbg_info(asmn);
- ir_node *block = get_nodes_block(asmn);
- ir_node *mem = get_ASM_mem(asmn);
- size_t new_n_outs = 0;
- size_t n_clobber = get_ASM_n_clobbers(asmn);
- unsigned *proj_map = ALLOCAN(unsigned, n_outs);
- ident **clobbers = get_ASM_clobbers(asmn);
- ident *asm_text = get_ASM_text(asmn);
- ir_asm_constraint *new_outputs
- = ALLOCAN(ir_asm_constraint, n_outs+n_64bit_outs);
- ir_node *new_asm;
-
- for (size_t o = 0; o < n_outs; ++o) {
- const ir_asm_constraint *constraint = &output_constraints[o];
- if (needs_lowering(constraint->mode)) {
- new_outputs[new_n_outs].pos = constraint->pos;
- new_outputs[new_n_outs].constraint = new_id_from_str("=a");
- new_outputs[new_n_outs].mode = env.p.word_unsigned;
- proj_map[o] = new_n_outs;
- ++new_n_outs;
- new_outputs[new_n_outs].pos = constraint->pos;
- new_outputs[new_n_outs].constraint = new_id_from_str("=d");
- new_outputs[new_n_outs].mode = get_high_mode(constraint->mode);
- ++new_n_outs;
- } else {
- new_outputs[new_n_outs] = *constraint;
- proj_map[o] = new_n_outs;
- ++new_n_outs;
- }
- }
- assert(new_n_outs == n_outs+n_64bit_outs);
-
- int n_inputs = get_ASM_n_inputs(asmn);
- ir_node **new_ins = ALLOCAN(ir_node*, n_inputs);
- for (int i = 0; i < n_inputs; ++i)
- new_ins[i] = get_ASM_input(asmn, i);
-
- new_asm = new_rd_ASM(dbgi, block, mem, n_inputs, new_ins, input_constraints,
- new_n_outs, new_outputs, n_clobber, clobbers,
- asm_text);
-
- foreach_out_edge_safe(asmn, edge) {
- ir_node *proj = get_edge_src_irn(edge);
- if (!is_Proj(proj))
- continue;
-
- unsigned pn = get_Proj_num(proj);
- if (pn < n_outs)
- pn = proj_map[pn];
- else
- pn = new_n_outs + pn - n_outs;
-
- ir_mode *proj_mode = get_irn_mode(proj);
- if (needs_lowering(proj_mode)) {
- ir_mode *high_mode = get_high_mode(proj_mode);
- ir_node *np_low = new_r_Proj(new_asm, env.p.word_unsigned, pn);
- ir_node *np_high = new_r_Proj(new_asm, high_mode, pn+1);
- ir_set_dw_lowered(proj, np_low, np_high);
- } else {
- ir_node *np = new_r_Proj(new_asm, proj_mode, pn);
- exchange(proj, np);
- }
+ if (needs_lowering(constraint->mode))
+ panic("lowering ASM 64bit output unimplemented");
}
}
diff --git a/ir/lower/lower_dw.h b/ir/lower/lower_dw.h
index 122810d..1b6a5ac 100644
--- a/ir/lower/lower_dw.h
+++ b/ir/lower/lower_dw.h
@@ -11,6 +11,8 @@
#ifndef FIRM_LOWER_LOWER_DW_H
#define FIRM_LOWER_LOWER_DW_H
+#include <stdbool.h>
+
#include "firm_types.h"
/**
@@ -57,6 +59,10 @@ void ir_register_dw_lower_function(ir_op *op, lower_dw_func func);
*/
void ir_set_dw_lowered(ir_node *old, ir_node *new_low, ir_node *new_high);
+bool needs_lowering(ir_mode const *mode);
+
+ir_mode *get_high_mode(ir_mode *mode);
+
ir_mode *get_node_high_mode(ir_node *node);
/**