From 4658dc6dbc1a84e71be79fe074c08329af93ad9c Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sun, 10 Jun 2007 09:13:38 +0000 Subject: [PATCH] Fixed some ugly "const" code split arm attributes fixed "SymConst get combined" Bug, HelloWorld runs now ;-) [r14396] --- ir/be/arm/arm_emitter.c | 20 +- ir/be/arm/arm_new_nodes.c | 143 +++-- ir/be/arm/arm_new_nodes.h | 41 +- ir/be/arm/arm_nodes_attr.h | 26 +- ir/be/arm/arm_spec.pl | 1126 ++++++++++++++++++------------------ ir/be/arm/arm_transform.c | 37 +- ir/be/arm/arm_transform.h | 1 - ir/be/arm/bearch_arm.c | 1 - 8 files changed, 742 insertions(+), 653 deletions(-) diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index 7a462c136..cb4119938 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -176,13 +176,9 @@ void arm_emit_offset(arm_emit_env_t *env, const ir_node *node) { * Emit the instruction suffix depending on the mode. */ void arm_emit_mode(arm_emit_env_t *env, const ir_node *node) { - arm_attr_t *attr; - ir_mode *mode; - int bits; - - attr = get_arm_attr(node); - mode = attr->op_mode ? attr->op_mode : get_irn_mode(node); - bits = get_mode_size_bits(mode); + const arm_attr_t *attr = get_arm_attr_const(node); + ir_mode *mode = attr->op_mode ? attr->op_mode : get_irn_mode(node); + int bits = get_mode_size_bits(mode); if (bits == 32) be_emit_char(env->emit, 's'); @@ -197,7 +193,7 @@ void arm_emit_mode(arm_emit_env_t *env, const ir_node *node) { * Returns non-zero if a mode has a Immediate attribute. */ int is_immediate_node(const ir_node *irn) { - arm_attr_t *attr = get_arm_attr(irn); + const arm_attr_t *attr = get_arm_attr_const(irn); return ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM; } @@ -276,7 +272,7 @@ static void emit_arm_CondJmp(arm_emit_env_t *env, const ir_node *irn) { ir_node *op1 = get_irn_n(irn, 0); ir_mode *opmode = get_irn_mode(op1); const char *suffix; - int proj_num = get_arm_proj_num(irn); + int proj_num = get_arm_CondJmp_proj_num(irn); foreach_out_edge(irn, edge) { ir_node *proj = get_edge_src_irn(edge); @@ -482,7 +478,7 @@ static void emit_arm_SwitchJmp(arm_emit_env_t *env, const ir_node *irn) { ir_node *default_block = NULL; block_nr = get_irn_node_nr(irn); - n_projs = get_arm_n_projs(irn); + n_projs = get_arm_SwitchJmp_n_projs(irn); projs = xcalloc(n_projs , sizeof(ir_node*)); @@ -490,7 +486,7 @@ static void emit_arm_SwitchJmp(arm_emit_env_t *env, const ir_node *irn) { proj = get_edge_src_irn(edge); assert(is_Proj(proj) && "Only proj allowed at SwitchJmp"); - if (get_Proj_proj(proj) == get_arm_default_proj_num(irn)) + if (get_Proj_proj(proj) == get_arm_SwitchJmp_default_proj_num(irn)) default_block = get_irn_link(proj); projs[get_Proj_proj(proj)] = proj; @@ -541,7 +537,7 @@ static void emit_arm_SwitchJmp(arm_emit_env_t *env, const ir_node *irn) { if ( proj ) { block = get_irn_link(proj); } else { - block = get_irn_link(projs[get_arm_default_proj_num(irn)]); + block = get_irn_link(projs[get_arm_SwitchJmp_default_proj_num(irn)]); } be_emit_cstring(env->emit, "\t.word\t"); arm_emit_block_label(env, block); diff --git a/ir/be/arm/arm_new_nodes.c b/ir/be/arm/arm_new_nodes.c index 3ceefa5ed..e1b6e1f18 100644 --- a/ir/be/arm/arm_new_nodes.c +++ b/ir/be/arm/arm_new_nodes.c @@ -226,8 +226,8 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { } } } - if (get_arm_proj_num(n) >= 0) { - fprintf(F, "proj_num = (%d)\n", get_arm_proj_num(n)); + if (is_arm_CondJmp(n) && get_arm_CondJmp_proj_num(n) >= 0) { + fprintf(F, "proj_num = (%d)\n", get_arm_CondJmp_proj_num(n)); } /* TODO: dump all additional attributes */ @@ -251,20 +251,57 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) { * |___/ ***************************************************************************************************/ +/* Returns the attributes of a generic Arm node. */ +arm_attr_t *get_arm_attr(ir_node *node) { + assert(is_arm_irn(node) && "need arm node to get attributes"); + return get_irn_generic_attr(node); +} + +const arm_attr_t *get_arm_attr_const(const ir_node *node) { + assert(is_arm_irn(node) && "need arm node to get attributes"); + return get_irn_generic_attr_const(node); +} + /** - * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast. - * Firm was made by people hating const :-( + * Returns the attributes of an ARM SymConst node. */ -arm_attr_t *get_arm_attr(const ir_node *node) { - assert(is_arm_irn(node) && "need arm node to get attributes"); - return (arm_attr_t *)get_irn_generic_attr((ir_node *)node); +arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node) { + assert(is_arm_SymConst(node)); + return get_irn_generic_attr(node); +} + +const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node) { + assert(is_arm_SymConst(node)); + return get_irn_generic_attr_const(node); +} + +/* Returns the attributes of a CondJmp node. */ +arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node) { + assert(is_arm_CondJmp(node)); + return get_irn_generic_attr(node); +} + +const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node) { + assert(is_arm_CondJmp(node)); + return get_irn_generic_attr_const(node); +} + +/* Returns the attributes of a SwitchJmp node. */ +arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr(ir_node *node) { + assert(is_arm_SwitchJmp(node)); + return get_irn_generic_attr(node); +} + +const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node) { + assert(is_arm_SwitchJmp(node)); + return get_irn_generic_attr_const(node); } /** * Returns the argument register requirements of a arm node. */ const arch_register_req_t **get_arm_in_req_all(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->in_req; } @@ -272,7 +309,7 @@ const arch_register_req_t **get_arm_in_req_all(const ir_node *node) { * Returns the result register requirements of an arm node. */ const arch_register_req_t **get_arm_out_req_all(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->out_req; } @@ -280,7 +317,7 @@ const arch_register_req_t **get_arm_out_req_all(const ir_node *node) { * Returns the argument register requirement at position pos of an arm node. */ const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->in_req[pos]; } @@ -288,7 +325,7 @@ const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos) { * Returns the result register requirement at position pos of an arm node. */ const arch_register_req_t *get_arm_out_req(const ir_node *node, int pos) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->out_req[pos]; } @@ -320,14 +357,14 @@ void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos) { * Returns the register flag of an arm node. */ arch_irn_flags_t get_arm_flags(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->flags; } /** * Sets the register flag of an arm node. */ -void set_arm_flags(const ir_node *node, arch_irn_flags_t flags) { +void set_arm_flags(ir_node *node, arch_irn_flags_t flags) { arm_attr_t *attr = get_arm_attr(node); attr->flags = flags; } @@ -336,7 +373,7 @@ void set_arm_flags(const ir_node *node, arch_irn_flags_t flags) { * Returns the result register slots of an arm node. */ const arch_register_t **get_arm_slots(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->slots; } @@ -344,7 +381,7 @@ const arch_register_t **get_arm_slots(const ir_node *node) { * Returns the name of the OUT register at position pos. */ const char *get_arm_out_reg_name(const ir_node *node, int pos) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); assert(is_arm_irn(node) && "Not an arm node."); assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position."); @@ -357,7 +394,7 @@ const char *get_arm_out_reg_name(const ir_node *node, int pos) { * Returns the index of the OUT register at position pos within its register class. */ int get_arm_out_regnr(const ir_node *node, int pos) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); assert(is_arm_irn(node) && "Not an arm node."); assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position."); @@ -370,7 +407,7 @@ int get_arm_out_regnr(const ir_node *node, int pos) { * Returns the OUT register at position pos. */ const arch_register_t *get_arm_out_reg(const ir_node *node, int pos) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); assert(is_arm_irn(node) && "Not an arm node."); assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position."); @@ -383,14 +420,14 @@ const arch_register_t *get_arm_out_reg(const ir_node *node, int pos) { * Returns the number of results. */ int get_arm_n_res(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return ARR_LEN(attr->slots); } /** * Returns the tarvalue */ tarval *get_arm_value(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return attr->value; } @@ -405,24 +442,24 @@ void set_arm_value(ir_node *node, tarval *tv) { /** * Returns the proj num */ -int get_arm_proj_num(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); +int get_arm_CondJmp_proj_num(const ir_node *node) { + const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node); return attr->proj_num; } /** * Sets the proj num */ -void set_arm_proj_num(ir_node *node, int proj_num) { - arm_attr_t *attr = get_arm_attr(node); - attr->proj_num = proj_num; +void set_arm_CondJmp_proj_num(ir_node *node, int proj_num) { + arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node); + attr->proj_num = proj_num; } /** * Returns the SymConst label */ ident *get_arm_symconst_id(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(node); return attr->symconst_id; } @@ -430,40 +467,39 @@ ident *get_arm_symconst_id(const ir_node *node) { * Sets the SymConst label */ void set_arm_symconst_id(ir_node *node, ident *symconst_id) { - arm_attr_t *attr = get_arm_attr(node); + arm_SymConst_attr_t *attr = get_arm_SymConst_attr(node); attr->symconst_id = symconst_id; } - /** - * Returns the number of projs. + * Returns the number of projs of a SwitchJmp. */ -int get_arm_n_projs(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); +int get_arm_SwitchJmp_n_projs(const ir_node *node) { + const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node); return attr->n_projs; } /** * Sets the number of projs. */ -void set_arm_n_projs(ir_node *node, int n_projs) { - arm_attr_t *attr = get_arm_attr(node); +void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs) { + arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node); attr->n_projs = n_projs; } /** * Returns the default_proj_num. */ -long get_arm_default_proj_num(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); +long get_arm_SwitchJmp_default_proj_num(const ir_node *node) { + const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node); return attr->default_proj_num; } /** * Sets the default_proj_num. */ -void set_arm_default_proj_num(ir_node *node, long default_proj_num) { - arm_attr_t *attr = get_arm_attr(node); +void set_arm_SwitchJmp_default_proj_num(ir_node *node, long default_proj_num) { + arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node); attr->default_proj_num = default_proj_num; } @@ -471,7 +507,7 @@ void set_arm_default_proj_num(ir_node *node, long default_proj_num) { * Gets the shift modifier attribute. */ arm_shift_modifier get_arm_shift_modifier(const ir_node *node) { - arm_attr_t *attr = get_arm_attr(node); + const arm_attr_t *attr = get_arm_attr_const(node); return ARM_GET_SHF_MOD(attr); } @@ -488,20 +524,11 @@ void init_arm_attributes(ir_node *node, int flags, const arch_register_req_t ** attr->flags = flags; attr->instr_fl = (ARM_COND_AL << 3) | ARM_SHF_NONE; attr->value = NULL; - attr->proj_num = -42; - attr->symconst_id = NULL; - attr->n_projs = 0; - attr->default_proj_num = 0; attr->slots = NEW_ARR_D(const arch_register_t*, obst, n_res); memset((arch_register_t **)attr->slots, 0, n_res * sizeof(attr->slots[0])); } -static int arm_comp_condJmp(arm_attr_t *attr_a, arm_attr_t *attr_b) { - return 1; -} - - /*************************************************************************************** * _ _ _ * | | | | | | @@ -619,5 +646,29 @@ void arm_set_optimizers(void) { */ } +static int cmp_attr_arm_SymConst(ir_node *a, ir_node *b) { + const arm_SymConst_attr_t *attr_a = get_irn_generic_attr_const(a); + const arm_SymConst_attr_t *attr_b = get_irn_generic_attr_const(b); + return attr_a->symconst_id != attr_b->symconst_id; +} + +static int cmp_attr_arm(ir_node *a, ir_node *b) { + arm_attr_t *attr_a = get_irn_generic_attr(a); + arm_attr_t *attr_b = get_irn_generic_attr(b); + return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value); +} + +static int cmp_attr_arm_CondJmp(ir_node *a, ir_node *b) { + /* never identical */ + return 1; +} + +static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b) { + /* never identical */ + return 1; +} + + + /* Include the generated constructor functions */ #include "gen_arm_new_nodes.c.inl" diff --git a/ir/be/arm/arm_new_nodes.h b/ir/be/arm/arm_new_nodes.h index 1ace38768..6fe6a7b8b 100644 --- a/ir/be/arm/arm_new_nodes.h +++ b/ir/be/arm/arm_new_nodes.h @@ -41,9 +41,28 @@ ***************************************************************************************************/ /** - * Returns the attributes of an arm node. + * Returns the attributes of a generic Arm node. */ -arm_attr_t *get_arm_attr(const ir_node *node); +arm_attr_t *get_arm_attr(ir_node *node); +const arm_attr_t *get_arm_attr_const(const ir_node *node); + +/** + * Returns the attributes of an ARM SymConst node. + */ +arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node); +const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node); + +/** + * Returns the attributes of an ARM CondJmp node. + */ +arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node); +const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node); + +/** + * Returns the attributes of an ARM SwitchJmp node. + */ +arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr(ir_node *node); +const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node); /** * Returns the argument register requirements of an arm node. @@ -88,7 +107,7 @@ arch_irn_flags_t get_arm_flags(const ir_node *node); /** * Sets the register flag of an arm node. */ -void set_arm_flags(const ir_node *node, arch_irn_flags_t flags); +void set_arm_flags(ir_node *node, arch_irn_flags_t flags); /** * Returns the result register slots of an arm node. @@ -134,12 +153,12 @@ void set_arm_value(ir_node *node, tarval *tv); /** * Returns the proj num */ -int get_arm_proj_num(const ir_node *node); +int get_arm_CondJmp_proj_num(const ir_node *node); /** * Sets the proj num */ -void set_arm_proj_num(ir_node *node, int proj_num); +void set_arm_CondJmp_proj_num(ir_node *node, int proj_num); ident *get_arm_symconst_id(const ir_node *node); void set_arm_symconst_id(ir_node *node, ident *symconst_id); @@ -148,24 +167,24 @@ ir_node *new_r_arm_StoreStackMInc(ir_graph *irg, ir_node *block, ir_node *mem, i int n_regs, ir_node **regs, ir_mode *mode); /** - * Returns the number of projs. + * Returns the number of projs of a SwitchJmp. */ -int get_arm_n_projs(const ir_node *node); +int get_arm_SwitchJmp_n_projs(const ir_node *node); /** - * Sets the number of projs. + * Sets the number of projs of a SwitchJmp. */ -void set_arm_n_projs(ir_node *node, int n_projs); +void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs); /** * Returns the default_proj_num. */ -long get_arm_default_proj_num(const ir_node *node); +long get_arm_SwitchJmp_default_proj_num(const ir_node *node); /** * Sets the default_proj_num. */ -void set_arm_default_proj_num(ir_node *node, long default_proj_num); +void set_arm_SwitchJmp_default_proj_num(ir_node *node, long default_proj_num); /** * Gets the shift modifier attribute. diff --git a/ir/be/arm/arm_nodes_attr.h b/ir/be/arm/arm_nodes_attr.h index 795736e5d..ae98d1aea 100644 --- a/ir/be/arm/arm_nodes_attr.h +++ b/ir/be/arm/arm_nodes_attr.h @@ -80,23 +80,39 @@ typedef enum _arm_condition { /** Set the condition code to flags */ #define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 3)) | ((code) << 3))) +/** Generic ARM node attributes. */ typedef struct _arm_attr_t { arch_irn_flags_t flags; /**< indicating if spillable, rematerializeable ... etc. */ const arch_register_req_t **in_req; /**< register requirements for arguments */ const arch_register_req_t **out_req; /**< register requirements for results */ - ir_mode *op_mode; /**< operation mode */ + ir_mode *op_mode; /**< operation mode if different from node's mode */ unsigned instr_fl; /**< condition code, shift modifier */ tarval *value; /**< immediate */ - ident *symconst_id; /**< for SymConsts: its ident */ - int proj_num; - int n_projs; - long default_proj_num; const arch_register_t **slots; /**< register slots for assigned registers */ } arm_attr_t; +/** Attributes for a SymConst */ +typedef struct _arm_SymConst_attr_t { + arm_attr_t attr; + ident *symconst_id; /**< for SymConsts: its ident */ +} arm_SymConst_attr_t; + +/** Attributes for a CondJmp */ +typedef struct _arm_CondJmp_attr_t { + arm_attr_t attr; + int proj_num; +} arm_CondJmp_attr_t; + +/** Attributes for a SwitchJmp */ +typedef struct _arm_SwitchJmp_attr_t { + arm_attr_t attr; + int n_projs; + long default_proj_num; +} arm_SwitchJmp_attr_t; + /** * Returns the shift modifier string. */ diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index 68d3b6f7a..6db19790a 100644 --- a/ir/be/arm/arm_spec.pl +++ b/ir/be/arm/arm_spec.pl @@ -16,22 +16,24 @@ $new_emit_syntax = 1; # %nodes = ( # # => { -# "op_flags" => "N|L|C|X|I|F|Y|H|c|K", -# "irn_flags" => "R|N|I" -# "arity" => "0|1|2|3 ... |variable|dynamic|any", -# "state" => "floats|pinned|mem_pinned|exc_pinned", -# "args" => [ -# { "type" => "type 1", "name" => "name 1" }, -# { "type" => "type 2", "name" => "name 2" }, +# op_flags => "N|L|C|X|I|F|Y|H|c|K", +# irn_flags => "R|N|I|S" +# arity => "0|1|2|3 ... |variable|dynamic|any", +# state => "floats|pinned|mem_pinned|exc_pinned", +# args => [ +# { type => "type 1", name => "name 1" }, +# { type => "type 2", name => "name 2" }, # ... # ], -# "comment" => "any comment for constructor", -# "reg_req" => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] }, -# "cmp_attr" => "c source code for comparing node attributes", -# "emit" => "emit code with templates", -# "attr" => "attitional attribute arguments for constructor" -# "init_attr" => "emit attribute initialization template" -# "rd_constructor" => "c source code which constructs an ir_node" +# comment => "any comment for constructor", +# reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] }, +# cmp_attr => "c source code for comparing node attributes", +# emit => "emit code with templates", +# attr => "attitional attribute arguments for constructor" +# init_attr => "emit attribute initialization template" +# rd_constructor => "c source code which constructs an ir_node" +# latency => "latency of this operation (can be float)" +# attr_type => "name of the attribute struct", # }, # # ... # (all nodes you need to describe) @@ -56,6 +58,7 @@ $new_emit_syntax = 1; # R rematerializeable # N not spillable # I ignore for register allocation +# S modifies stack pointer # # state: state of the operation, OPTIONAL (default is "floats") # @@ -70,6 +73,10 @@ $new_emit_syntax = 1; # # outs: if a node defines more than one output, the names of the projections # nodes having outs having automatically the mode mode_T +# One can also annotate some flags for each out, additional to irn_flags. +# They are separated from name with a colon ':', and concatenated by pipe '|' +# Only I and S are available at the moment (same meaning as in irn_flags). +# example: [ "frame:I", "stack:I|S", "M" ] # # comment: OPTIONAL comment for the node constructor # @@ -88,15 +95,21 @@ $new_emit_syntax = 1; # return res # # NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3 +# +# latency: the latency of the operation, default is 1 +# # register types: # 0 - no special type # 1 - caller save (register must be saved by the caller of a function) # 2 - callee save (register must be saved by the called function) # 4 - ignore (do not assign this register) +# 8 - emitter can choose an arbitrary register of this class +# 16 - the register is a virtual one +# 32 - register represents a state # NOTE: Last entry of each class is the largest Firm-Mode a register can hold %reg_classes = ( - "gp" => [ + gp => [ { "name" => "r0", "type" => 1 }, { "name" => "r1", "type" => 1 }, { "name" => "r2", "type" => 1 }, @@ -115,7 +128,7 @@ $new_emit_syntax = 1; { "name" => "pc", "realname" => "r15", "type" => 6 }, # this is our program counter { "mode" => "mode_Iu" } ], - "fpa" => [ + fpa => [ { "name" => "f0", "type" => 1 }, { "name" => "f1", "type" => 1 }, { "name" => "f2", "type" => 1 }, @@ -154,7 +167,21 @@ $new_emit_syntax = 1; # |_| # #--------------------------------------------------# -$default_cmp_attr = "NULL"; +$default_attr_type = "arm_attr_t"; + +%init_attr = ( + arm_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + arm_SymConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + arm_CondJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", +); + +%compare_attr = ( + arm_attr_t => "cmp_attr_arm", + arm_SymConst_attr_t => "cmp_attr_arm_SymConst", + arm_CondJmp_attr_t => "cmp_attr_arm_CondJmp", + arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp", +); %nodes = ( @@ -171,447 +198,452 @@ $default_cmp_attr = "NULL"; # commutative operations -"Add" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct Add: Add(a, b) = Add(b, a) = a + b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. add %D0, %S0, %S1%X' -}, - -"Add_i" => { - "irn_flags" => "R", - "comment" => "construct Add: Add(a, const) = Add(const, a) = a + const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "cmp_attr" => 'return attr_a->value != attr_b->value;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. add %D0, %S0, %C' -}, - -"Mul" => { - #"op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] }, - "emit" =>'. mul %D0, %S0, %S1' -}, - -"Smull" => { - #"op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, - "emit" =>'. smull %D0, %D1, %S0, %S1', - "outs" => [ "low", "high" ], -}, - -"Umull" => { - #"op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, - "emit" =>'. umull %D0, %D1, %S0, %S1', - "outs" => [ "low", "high" ], -}, - -"Mla" => { - #"op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct Mla: Mla(a, b, c) = a * b + c", - "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] }, - "emit" =>'. mla %D0, %S0, %S1, %S2' -}, - -"And" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct And: And(a, b) = And(b, a) = a AND b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. and %D0, %S0, %S1%X' -}, - -"And_i" => { - "irn_flags" => "R", - "comment" => "construct And: And(a, const) = And(const, a) = a AND const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. and %D0, %S0, %C', - "cmp_attr" => 'return attr_a->value != attr_b->value;' -}, - -"Or" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct Or: Or(a, b) = Or(b, a) = a OR b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. orr %D0, %S0, %S1%X' -}, - -"Or_i" => { - "irn_flags" => "R", - "comment" => "construct Or: Or(a, const) = Or(const, a) = a OR const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "cmp_attr" => 'return attr_a->value != attr_b->value;', - "emit" => '. orr %D0, %S0, %C' -}, - -"Eor" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. eor %D0, %S0, %S1%X' -}, - -"Eor_i" => { - "irn_flags" => "R", - "comment" => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "cmp_attr" => 'return attr_a->value != attr_b->value;', - "emit" => '. eor %D0, %S0, %C' +Add => { + op_flags => "C", + irn_flags => "R", + comment => "construct Add: Add(a, b) = Add(b, a) = a + b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. add %D0, %S0, %S1%X' +}, + +Add_i => { + irn_flags => "R", + comment => "construct Add: Add(a, const) = Add(const, a) = a + const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. add %D0, %S0, %C' +}, + +Mul => { + #op_flags => "C", + irn_flags => "R", + comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] }, + emit =>'. mul %D0, %S0, %S1' +}, + +Smull => { + #op_flags => "C", + irn_flags => "R", + comment => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, + emit =>'. smull %D0, %D1, %S0, %S1', + outs => [ "low", "high" ], +}, + +Umull => { + #op_flags => "C", + irn_flags => "R", + comment => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, + emit =>'. umull %D0, %D1, %S0, %S1', + outs => [ "low", "high" ], +}, + +Mla => { + #op_flags => "C", + irn_flags => "R", + comment => "construct Mla: Mla(a, b, c) = a * b + c", + reg_req => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] }, + emit =>'. mla %D0, %S0, %S1, %S2' +}, + +And => { + op_flags => "C", + irn_flags => "R", + comment => "construct And: And(a, b) = And(b, a) = a AND b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. and %D0, %S0, %S1%X' +}, + +And_i => { + irn_flags => "R", + comment => "construct And: And(a, const) = And(const, a) = a AND const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. and %D0, %S0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + +Or => { + op_flags => "C", + irn_flags => "R", + comment => "construct Or: Or(a, b) = Or(b, a) = a OR b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. orr %D0, %S0, %S1%X' +}, + +Or_i => { + irn_flags => "R", + comment => "construct Or: Or(a, const) = Or(const, a) = a OR const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + cmp_attr => 'return attr_a->value != attr_b->value;', + emit => '. orr %D0, %S0, %C' +}, + +Eor => { + op_flags => "C", + irn_flags => "R", + comment => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. eor %D0, %S0, %S1%X' +}, + +Eor_i => { + irn_flags => "R", + comment => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + cmp_attr => 'return attr_a->value != attr_b->value;', + emit => '. eor %D0, %S0, %C' }, # not commutative operations -"Bic" => { - "irn_flags" => "R", - "comment" => "construct Bic: Bic(a, b) = a AND ~b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. bic %D0, %S0, %S1%X' -}, - -"Bic_i" => { - "irn_flags" => "R", - "comment" => "construct Bic: Bic(a, const) = a AND ~const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. bic %D0, %S0, %C', - "cmp_attr" => 'return attr_a->value != attr_b->value;' -}, - -"Sub" => { - "irn_flags" => "R", - "comment" => "construct Sub: Sub(a, b) = a - b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. sub %D0, %S0, %S1%X' -}, - -"Sub_i" => { - "irn_flags" => "R", - "comment" => "construct Sub: Sub(a, const) = a - const", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "cmp_attr" => 'return attr_a->value != attr_b->value;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. sub %D0, %S0, %C', -}, - -"Rsb" => { - "irn_flags" => "R", - "comment" => "construct Rsb: Rsb(a, b) = b - a", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. rsb %D0, %S0, %S1%X' -}, - -"Rsb_i" => { - "irn_flags" => "R", - "comment" => "construct Rsb: Rsb(a, const) = const - a", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. rsb %D0, %S0, %C', - "cmp_attr" => 'return attr_a->value != attr_b->value;' -}, - -"Shl" => { - "irn_flags" => "R", - "comment" => "construct Shl: Shl(a, b) = a << b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - "emit" => '. mov %D0, %S0, lsl %S1' -}, - -"Shr" => { - "irn_flags" => "R", - "comment" => "construct Shr: Shr(a, b) = a >> b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, - "emit" => '. mov %D0, %S0, lsr %S1' -}, - -"Shrs" => { - "irn_flags" => "R", - "comment" => "construct Shrs: Shrs(a, b) = a >> b", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, - "emit" => '. mov %D0, %S0, asr %S1' -}, - -#"RotR" => { -# "irn_flags" => "R", -# "comment" => "construct RotR: RotR(a, b) = a ROTR b", -# "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, -# "emit" => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */' -## "emit" => '. ror %S0, %S1, %D0' +Bic => { + irn_flags => "R", + comment => "construct Bic: Bic(a, b) = a AND ~b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. bic %D0, %S0, %S1%X' +}, + +Bic_i => { + irn_flags => "R", + comment => "construct Bic: Bic(a, const) = a AND ~const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. bic %D0, %S0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + +Sub => { + irn_flags => "R", + comment => "construct Sub: Sub(a, b) = a - b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. sub %D0, %S0, %S1%X' +}, + +Sub_i => { + irn_flags => "R", + comment => "construct Sub: Sub(a, const) = a - const", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. sub %D0, %S0, %C', +}, + +Rsb => { + irn_flags => "R", + comment => "construct Rsb: Rsb(a, b) = b - a", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. rsb %D0, %S0, %S1%X' +}, + +Rsb_i => { + irn_flags => "R", + comment => "construct Rsb: Rsb(a, const) = const - a", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. rsb %D0, %S0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + +Shl => { + irn_flags => "R", + comment => "construct Shl: Shl(a, b) = a << b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. mov %D0, %S0, lsl %S1' +}, + +Shr => { + irn_flags => "R", + comment => "construct Shr: Shr(a, b) = a >> b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, + emit => '. mov %D0, %S0, lsr %S1' +}, + +Shrs => { + irn_flags => "R", + comment => "construct Shrs: Shrs(a, b) = a >> b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, + emit => '. mov %D0, %S0, asr %S1' +}, + +#RotR => { +# irn_flags => "R", +# comment => "construct RotR: RotR(a, b) = a ROTR b", +# reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, +# emit => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */' +## emit => '. ror %S0, %S1, %D0' #}, -#"RotL" => { -# "irn_flags" => "R", -# "comment" => "construct RotL: RotL(a, b) = a ROTL b", -# "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, -# "emit" => '. rol %S0, %S1, %D0' +#RotL => { +# irn_flags => "R", +# comment => "construct RotL: RotL(a, b) = a ROTL b", +# reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, +# emit => '. rol %S0, %S1, %D0' #}, -#"RotL_i" => { -# "irn_flags" => "R", -# "comment" => "construct RotL: RotL(a, const) = a ROTL const", -# "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, -# "emit" => '. rol %S0, %C, %D0' +#RotL_i => { +# irn_flags => "R", +# comment => "construct RotL: RotL(a, const) = a ROTL const", +# reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, +# emit => '. rol %S0, %C, %D0' #}, -"Mov" => { - "irn_flags" => "R", - "comment" => "construct Mov: a = b", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. mov %D0, %S0%X' -}, - -"Mov_i" => { - "irn_flags" => "R", - "comment" => "represents an integer constant", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "reg_req" => { "out" => [ "gp" ] }, - "emit" => '. mov %D0, %C', - "cmp_attr" => 'return attr_a->value != attr_b->value;' -}, - -"Mvn" => { - "irn_flags" => "R", - "comment" => "construct Not: Not(a) = !a", - "attr" => "arm_shift_modifier mod, tarval *shf", - "init_attr" => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - "cmp_attr" => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => '. mvn %D0, %S0%X' -}, - -"Mvn_i" => { - "irn_flags" => "R", - "comment" => "represents a negated integer constant", - "attr" => "tarval *tv", - "init_attr" => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - "cmp_attr" => 'return attr_a->value != attr_b->value;', - "reg_req" => { "out" => [ "gp" ] }, - "emit" => '. mvn %D0, %C', -}, - -"Abs" => { - "irn_flags" => "R", - "comment" => "construct Abs: Abs(a) = |a|", - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, - "emit" => +Mov => { + irn_flags => "R", + comment => "construct Mov: a = b", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. mov %D0, %S0%X' +}, + +Mov_i => { + irn_flags => "R", + comment => "represents an integer constant", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + reg_req => { "out" => [ "gp" ] }, + emit => '. mov %D0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;' +}, + +Mvn => { + irn_flags => "R", + comment => "construct Not: Not(a) = !a", + attr => "arm_shift_modifier mod, tarval *shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. mvn %D0, %S0%X' +}, + +Mvn_i => { + irn_flags => "R", + comment => "represents a negated integer constant", + attr => "tarval *tv", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', + cmp_attr => 'return attr_a->value != attr_b->value;', + reg_req => { "out" => [ "gp" ] }, + emit => '. mvn %D0, %C', +}, + +Abs => { + irn_flags => "R", + comment => "construct Abs: Abs(a) = |a|", + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. movs %S0, %S0, #0 . rsbmi %D0, %S0, #0' }, # other operations -"EmptyReg" => { - "op_flags" => "c", - "irn_flags" => "R", - "comment" => "allocate an empty register for calculations", - "reg_req" => { "out" => [ "gp" ] }, - "emit" => '. /* %D0 now available for calculations */', - "cmp_attr" => 'return 1;' +EmptyReg => { + op_flags => "c", + irn_flags => "R", + comment => "allocate an empty register for calculations", + reg_req => { "out" => [ "gp" ] }, + emit => '. /* %D0 now available for calculations */', + cmp_attr => 'return 1;' }, -"Copy" => { - "comment" => "implements a register copy", - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }, +Copy => { + comment => "implements a register copy", + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, }, -"CopyB" => { - "op_flags" => "F|H", - "state" => "pinned", - "comment" => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)", - "reg_req" => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] }, +CopyB => { + op_flags => "F|H", + state => "pinned", + comment => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)", + reg_req => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] }, }, -"SymConst" => { - "op_flags" => "c", - "irn_flags" => "R", - "comment" => "represents a symbolic constant", - "attr" => "ident *id", - "init_attr" => ' attr->symconst_id = id;', - "reg_req" => { "out" => [ "gp" ] }, - "cmp_attr" => -' /* should be identical but ...*/ - return attr_a->symconst_id == attr_b->symconst_id;' +SymConst => { + op_flags => "c", + irn_flags => "R", + comment => "represents a symbolic constant", + attr => "ident *id", + init_attr => "\tset_arm_symconst_id(res, id);", + reg_req => { "out" => [ "gp" ] }, + attr_type => "arm_SymConst_attr_t", }, -"CondJmp" => { - "op_flags" => "L|X|Y", - "comment" => "construct conditional jump: CMP A, B && JMPxx LABEL", - "cmp_attr" => " return arm_comp_condJmp(attr_a, attr_b);\n", - "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] }, +CondJmp => { + op_flags => "L|X|Y", + comment => "construct conditional jump: CMP A, B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", }, -"SwitchJmp" => { - "op_flags" => "L|X|Y", - "comment" => "construct switch", - "reg_req" => { "in" => [ "gp" ], "out" => [ "none" ] }, - "cmp_attr" => " return 0;\n", +SwitchJmp => { + op_flags => "L|X|Y", + comment => "construct switch", + mode => "mode_T", + attr => "int n_projs, long def_proj_num", + init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n". + "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);", + reg_req => { "in" => [ "gp" ], "out" => [ "none" ] }, + attr_type => "arm_SwitchJmp_attr_t", }, # Load / Store -"Load" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. ldr %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"Loadb" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. ldrb %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"Loadbs" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. ldrsb %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"Loadh" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. ldrh %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"Loadhs" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. ldrsh %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"Storeb" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, - "emit" => '. strb %S1, [%S0, #0]', - "outs" => [ "M" ], -}, - -"Storebs" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, - "emit" => '. strsb %S1, [%S0, #0]', - "outs" => [ "M" ], -}, - -"Storeh" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, - "emit" => '. strh %S1, [%S0, #0]', - "outs" => [ "M" ], -}, - -"Storehs" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, - "emit" => '. strhs %S1, [%S0, #0]', - "outs" => [ "M" ], -}, - -"Store" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, - "emit" => '. str %S1, [%S0, #0]', - "outs" => [ "M" ], -}, - -"StoreStackM4Inc" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "reg_req" => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] }, - "emit" => '. stmfd %S0!, {%S1, %S2, %S3, %S4}', - "outs" => [ "ptr", "M" ], -}, - -"LoadStackM3" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg", - "reg_req" => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] }, - "emit" => '. ldmfd %S0, {%D0, %D1, %D2}', - "outs" => [ "res0", "res1", "res2", "M" ], +Load => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldr %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +Loadb => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrb %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +Loadbs => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrsb %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +Loadh => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrh %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +Loadhs => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrsh %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +Storeb => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, + emit => '. strb %S1, [%S0, #0]', + outs => [ "M" ], +}, + +Storebs => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, + emit => '. strsb %S1, [%S0, #0]', + outs => [ "M" ], +}, + +Storeh => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. strh %S1, [%S0, #0]', + outs => [ "M" ], +}, + +Storehs => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. strhs %S1, [%S0, #0]', + outs => [ "M" ], +}, + +Store => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. str %S1, [%S0, #0]', + outs => [ "M" ], +}, + +StoreStackM4Inc => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. stmfd %S0!, {%S1, %S2, %S3, %S4}', + outs => [ "ptr", "M" ], +}, + +LoadStackM3 => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] }, + emit => '. ldmfd %S0, {%D0, %D1, %D2}', + outs => [ "res0", "res1", "res2", "M" ], }, @@ -628,165 +660,165 @@ $default_cmp_attr = "NULL"; # commutative operations -"fpaAdd" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. adf%M %D0, %S0, %S1', +fpaAdd => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. adf%M %D0, %S0, %S1', }, -"fpaMul" => { - "op_flags" => "C", - "comment" => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. muf%M %D0, %S0, %S1', +fpaMul => { + op_flags => "C", + comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. muf%M %D0, %S0, %S1', }, -"fpaFMul" => { - "op_flags" => "C", - "comment" => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. fml%M %D0, %S0, %S1', +fpaFMul => { + op_flags => "C", + comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fml%M %D0, %S0, %S1', }, -"fpaMax" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. fmax %S0, %S1, %D0', +fpaMax => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fmax %S0, %S1, %D0', }, -"fpaMin" => { - "op_flags" => "C", - "irn_flags" => "R", - "comment" => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. fmin %S0, %S1, %D0', +fpaMin => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fmin %S0, %S1, %D0', }, # not commutative operations -"fpaSub" => { - "irn_flags" => "R", - "comment" => "construct FPA Sub: Sub(a, b) = a - b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. suf%M %D0, %S0, %S1' +fpaSub => { + irn_flags => "R", + comment => "construct FPA Sub: Sub(a, b) = a - b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. suf%M %D0, %S0, %S1' }, -"fpaRsb" => { - "irn_flags" => "R", - "comment" => "construct FPA reverse Sub: Sub(a, b) = b - a", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. rsf%M %D0, %S0, %S1' +fpaRsb => { + irn_flags => "R", + comment => "construct FPA reverse Sub: Sub(a, b) = b - a", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. rsf%M %D0, %S0, %S1' }, -"fpaDiv" => { - "comment" => "construct FPA Div: Div(a, b) = a / b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. dvf%M %D0, %S0, %S1', +fpaDiv => { + comment => "construct FPA Div: Div(a, b) = a / b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. dvf%M %D0, %S0, %S1', }, -"fpaRdv" => { - "comment" => "construct FPA reverse Div: Div(a, b) = b / a", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. rdf%M %D0, %S0, %S1', +fpaRdv => { + comment => "construct FPA reverse Div: Div(a, b) = b / a", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. rdf%M %D0, %S0, %S1', }, -"fpaFDiv" => { - "comment" => "construct FPA Fast Div: Div(a, b) = a / b", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. fdv%M %D0, %S0, %S1', +fpaFDiv => { + comment => "construct FPA Fast Div: Div(a, b) = a / b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fdv%M %D0, %S0, %S1', }, -"fpaFRdv" => { - "comment" => "construct FPA Fast reverse Div: Div(a, b) = b / a", - "reg_req" => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - "emit" =>'. frd%M %D0, %S0, %S1', +fpaFRdv => { + comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. frd%M %D0, %S0, %S1', }, -"fpaMov" => { - "irn_flags" => "R", - "comment" => "construct FPA Move: b = a", - "reg_req" => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. mvf%M %S0, %D0', +fpaMov => { + irn_flags => "R", + comment => "construct FPA Move: b = a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mvf%M %S0, %D0', }, -"fpaMnv" => { - "irn_flags" => "R", - "comment" => "construct FPA Move Negated: b = -a", - "reg_req" => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. mnf%M %S0, %D0', +fpaMnv => { + irn_flags => "R", + comment => "construct FPA Move Negated: b = -a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mnf%M %S0, %D0', }, -"fpaAbs" => { - "irn_flags" => "R", - "comment" => "construct FPA Absolute value: fAbsd(a) = |a|", - "reg_req" => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - "emit" => '. abs%M %D0, %S0', +fpaAbs => { + irn_flags => "R", + comment => "construct FPA Absolute value: fAbsd(a) = |a|", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. abs%M %D0, %S0', }, # other operations -"fpaConst" => { - "op_flags" => "c", - "irn_flags" => "R", - "comment" => "represents a FPA constant", - "attr" => "tarval *val", - "init_attr" => 'attr->value = val;', - "reg_req" => { "out" => [ "fpa" ] }, - "emit" => '. fmov %D0, %C', - "cmp_attr" => 'return attr_a->value != attr_b->value;', +fpaConst => { + op_flags => "c", + irn_flags => "R", + comment => "represents a FPA constant", + attr => "tarval *val", + init_attr => 'attr->value = val;', + reg_req => { "out" => [ "fpa" ] }, + emit => '. fmov %D0, %C', + cmp_attr => 'return attr_a->value != attr_b->value;', }, -"fpaFlt" => { - "irn_flags" => "R", - "comment" => "construct a FPA integer->float conversion", - "reg_req" => { "in" => ["gp"], "out" => [ "fpa" ] }, - "emit" => '. flt%M %D0, %S0', +fpaFlt => { + irn_flags => "R", + comment => "construct a FPA integer->float conversion", + reg_req => { "in" => ["gp"], "out" => [ "fpa" ] }, + emit => '. flt%M %D0, %S0', }, -"fpaFix" => { - "irn_flags" => "R", - "comment" => "construct a FPA float->integer conversion", - "reg_req" => { "in" => ["fpa"], "out" => [ "gp" ] }, - "emit" => '. fix %D0, %S0', +fpaFix => { + irn_flags => "R", + comment => "construct a FPA float->integer conversion", + reg_req => { "in" => ["fpa"], "out" => [ "gp" ] }, + emit => '. fix %D0, %S0', }, # Load / Store -"fpaLdf" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct FPA Load: Load(ptr, mem) = LD ptr", - "attr" => "ir_mode *op_mode", - "init_attr" => "attr->op_mode = op_mode;", - "reg_req" => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] }, - "emit" => '. ldf%M %D0, [%S0, #0]', - "outs" => [ "res", "M" ], -}, - -"fpaStf" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val", - "attr" => "ir_mode *op_mode", - "init_attr" => "attr->op_mode = op_mode;", - "reg_req" => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] }, - "emit" => '. stf%M [%S1, #0], %S0', - "outs" => [ "M" ], -}, - -"fpaDbl2GP" => { - "op_flags" => "L|F", - "irn_flags" => "R", - "state" => "exc_pinned", - "comment" => "construct fp double to 2 gp register transfer", - "reg_req" => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] }, - "outs" => [ "low", "high", "M" ], +fpaLdf => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct FPA Load: Load(ptr, mem) = LD ptr", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] }, + emit => '. ldf%M %D0, [%S0, #0]', + outs => [ "res", "M" ], +}, + +fpaStf => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] }, + emit => '. stf%M [%S1, #0], %S0', + outs => [ "M" ], +}, + +fpaDbl2GP => { + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct fp double to 2 gp register transfer", + reg_req => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] }, + outs => [ "low", "high", "M" ], }, diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index cd31b58d0..8af57d182 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -840,8 +840,7 @@ static ir_node *gen_Cond(ir_node *irn, arm_code_gen_t *cg) { ir_node *cmp_node = get_Proj_pred(proj_node); ir_node *op1 = get_Cmp_left(cmp_node); ir_node *op2 = get_Cmp_right(cmp_node); - result = new_rd_arm_CondJmp(dbg, irg, block, op1, op2, mode_T); - set_arm_proj_num(result, get_Proj_proj(proj_node)); + result = new_rd_arm_CondJmp(dbg, irg, block, op1, op2, get_Proj_proj(proj_node)); } else { //SwitchJmp ir_node *op = get_irn_n(irn, 0); @@ -889,9 +888,8 @@ static ir_node *gen_Cond(ir_node *irn, arm_code_gen_t *cg) { const_node = new_rd_Const(dbg, irg, block, mode_Iu, new_tarval_from_long(translation, mode_Iu)); const_graph = gen_Const(const_node, cg); sub = new_rd_arm_Sub(dbg, irg, block, op, const_graph, get_irn_mode(op), ARM_SHF_NONE, NULL); - result = new_rd_arm_SwitchJmp(dbg, irg, block, sub, mode_T); - set_arm_n_projs(result, n_projs); - set_arm_default_proj_num(result, get_Cond_defaultProj(irn)-translation); + result = new_rd_arm_SwitchJmp(dbg, irg, block, sub, + n_projs, get_Cond_defaultProj(irn)-translation); } return result; } @@ -901,7 +899,7 @@ static ir_node *gen_Cond(ir_node *irn, arm_code_gen_t *cg) { * @param symc the SymConst * @return name of the SymConst */ -ident *get_sc_ident(ir_node *symc) { +static ident *get_sc_ident(ir_node *symc) { ir_entity *ent; switch (get_SymConst_kind(symc)) { @@ -920,6 +918,9 @@ ident *get_sc_ident(ir_node *symc) { return NULL; } +/** + * Transforms a SymConst node. + */ static ir_node *gen_SymConst(ir_node *irn, arm_code_gen_t *cg) { ir_node *block = get_nodes_block(irn); ir_mode *mode = get_irn_mode(irn); @@ -1200,30 +1201,6 @@ void arm_move_consts(ir_node *node, void *env) { } -/************************************************************************/ -/* move symbolic constants out of startblock */ -/************************************************************************/ -void arm_move_symconsts(ir_node *node, void *env) { - int i; - - if (is_Block(node)) - return; - - for (i = 0; i < get_irn_arity(node); i++) { - ir_node *pred = get_irn_n(node,i); - ir_opcode pred_code = get_irn_opcode(pred); - - if (pred_code == iro_SymConst) { - ident *id = get_sc_ident(pred); - ir_node *symconst_node; - - symconst_node = new_rd_arm_SymConst(get_irn_dbg_info(pred), - current_ir_graph, get_nodes_block(node), get_irn_mode(pred), id); - set_irn_n(node, i, symconst_node); - } - } -} - /** * the BAD transformer. */ diff --git a/ir/be/arm/arm_transform.h b/ir/be/arm/arm_transform.h index 352d62978..27efeaea8 100644 --- a/ir/be/arm/arm_transform.h +++ b/ir/be/arm/arm_transform.h @@ -27,7 +27,6 @@ #define FIRM_BE_ARM_ARM_TRANSFORM_H void arm_move_consts(ir_node *node, void *env); -void arm_move_symconsts(ir_node *node, void *env); void arm_register_transformers(void); void arm_transform_node(ir_node *node, void *env); diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 5fd8f583c..72a282acc 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -322,7 +322,6 @@ static void arm_emit_and_done(void *self) { arm_code_gen_t *cg = self; ir_graph *irg = cg->irg; - dump_ir_block_graph_sched(irg, "-arm-finished"); arm_gen_routine(cg, irg); cur_reg_set = NULL; -- 2.20.1