Commit ede86ffb authored by Michael Beck's avatar Michael Beck
Browse files

refactored immediates:

 - now stored as long values (should be enough)
 - floating point values are emitted right

[r18088]
parent 1af2ed0c
......@@ -222,9 +222,9 @@ void arm_emit_immediate(const ir_node *node) {
const arm_attr_t *attr = get_arm_attr_const(node);
if (ARM_GET_SHF_MOD(attr) == ARM_SHF_IMM) {
be_emit_irprintf("#0x%X", arm_decode_imm_w_shift(get_arm_value(node)));
be_emit_irprintf("#0x%X", arm_decode_imm_w_shift(get_arm_imm_value(node)));
} else if (ARM_GET_FPA_IMM(attr)) {
be_emit_irprintf("#0x%F", get_arm_value(node));
be_emit_irprintf("#%s", arm_get_fpa_imm_name(get_arm_imm_value(node)));
} else if (is_arm_SymConst(node))
be_emit_ident(get_arm_symconst_id(node));
else {
......@@ -240,7 +240,7 @@ void arm_emit_shift(const ir_node *node) {
mod = get_arm_shift_modifier(node);
if (ARM_HAS_SHIFT(mod)) {
long v = get_tarval_long(get_arm_value(node));
long v = get_arm_imm_value(node);
be_emit_irprintf(", %s #%l", arm_shf_mod_name(mod), v);
}
......@@ -297,7 +297,7 @@ static void emit_arm_fpaConst(const ir_node *irn) {
unsigned label;
ir_mode *mode;
key.u.tv = get_arm_value(irn);
key.u.tv = get_fpaConst_value(irn);
key.is_ident = 0;
key.label = 0;
entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
......@@ -478,7 +478,7 @@ static int reg_cmp(const void *a, const void *b) {
* Create the CopyB instruction sequence.
*/
static void emit_arm_CopyB(const ir_node *irn) {
unsigned int size = get_tarval_long(get_arm_value(irn));
unsigned size = (unsigned)get_arm_imm_value(irn);
const char *tgt = arch_register_get_name(get_in_reg(irn, 0));
const char *src = arch_register_get_name(get_in_reg(irn, 1));
......@@ -505,7 +505,7 @@ static void emit_arm_CopyB(const ir_node *irn) {
be_emit_string(src);
be_emit_cstring(")->(");
arm_emit_source_register(irn, 0);
be_emit_irprintf(" [%d bytes], Uses ", size);
be_emit_irprintf(" [%u bytes], Uses ", size);
be_emit_string(t0);
be_emit_cstring(", ");
be_emit_string(t1);
......@@ -1164,7 +1164,6 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
ir_node *last_block = NULL;
cg = arm_cg;
isa = (const arm_isa_t *)cg->arch_env->isa;
arch_env = cg->arch_env;
sym_or_tv = new_set(cmp_sym_or_tv, 8);
......
......@@ -55,10 +55,27 @@
* Returns the shift modifier string.
*/
const char *arm_shf_mod_name(arm_shift_modifier mod) {
static const char *names[] = { NULL, NULL, "asr", "lsl", "lsr", "ror", "rrx" };
static const char *names[] = { NULL, NULL, "asr", "lsl", "lsr", "ror", "rrx" };
return names[mod];
}
/**
* Return the fpa immediate from the encoding.
*/
const char *arm_get_fpa_imm_name(long imm_value) {
static const char *fpa_imm[] = {
"0",
"1",
"2",
"3",
"4",
"5",
"10",
"0.5"
};
return fpa_imm[imm_value];
}
/***********************************************************************************
* _ _ _ __
* | | (_) | | / _|
......@@ -167,11 +184,11 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
case dump_node_nodeattr_txt:
mod = ARM_GET_SHF_MOD(attr);
if (ARM_HAS_SHIFT(mod)) {
fprintf(F, "[%s #%ld]", arm_shf_mod_name(mod), get_tarval_long(attr->value));
fprintf(F, "[%s #%ld]", arm_shf_mod_name(mod), attr->imm_value);
}
else if (mod == ARM_SHF_IMM) {
/* immediate */
fprintf(F, "[#0x%X]", arm_decode_imm_w_shift(attr->value));
fprintf(F, "[#0x%X]", arm_decode_imm_w_shift(attr->imm_value));
}
break;
......@@ -225,22 +242,17 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
}
fprintf(F, " (%d)\n", attr->flags);
if (get_arm_value(n)) {
if (is_arm_CopyB(n)) {
fprintf(F, "size = %lu\n", get_tarval_long(get_arm_value(n)));
if (is_arm_CopyB(n)) {
fprintf(F, "size = %lu\n", get_arm_imm_value(n));
} else {
long v = get_arm_imm_value(n);
if (ARM_GET_FPA_IMM(attr)) {
fprintf(F, "immediate float value = %s\n", arm_get_fpa_imm_name(v));
} else {
if (mode_is_float(get_irn_mode(n))) {
fprintf(F, "float value = (%f)\n", (double) get_tarval_double(get_arm_value(n)));
} else if (mode_is_int(get_irn_mode(n))) {
long v = get_tarval_long(get_arm_value(n));
fprintf(F, "long value = %ld (0x%08lx)\n", v, v);
} else if (mode_is_reference(get_irn_mode(n))) {
fprintf(F, "pointer\n");
} else {
assert(0 && "unbehandelter Typ im const-Knoten");
}
fprintf(F, "immediate value = %ld (0x%08lx)\n", v, v);
}
}
if (is_arm_CmpBra(n) && get_arm_CondJmp_proj_num(n) >= 0) {
fprintf(F, "proj_num = (%d)\n", get_arm_CondJmp_proj_num(n));
}
......@@ -290,6 +302,20 @@ const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node) {
return get_irn_generic_attr_const(node);
}
static const arm_fpaConst_attr_t *get_arm_fpaConst_attr_const(const ir_node *node) {
const arm_attr_t *attr = get_arm_attr_const(node);
const arm_fpaConst_attr_t *fpa_attr = CONST_CAST_ARM_ATTR(arm_fpaConst_attr_t, attr);
return fpa_attr;
}
static arm_fpaConst_attr_t *get_arm_fpaConst_attr(ir_node *node) {
arm_attr_t *attr = get_arm_attr(node);
arm_fpaConst_attr_t *fpa_attr = CAST_ARM_ATTR(arm_fpaConst_attr_t, attr);
return fpa_attr;
}
static int is_arm_CondJmp(const ir_node *node) {
int code = get_arm_irn_opcode(node);
......@@ -464,20 +490,37 @@ int get_arm_n_res(const ir_node *node) {
const arm_attr_t *attr = get_arm_attr_const(node);
return ARR_LEN(attr->slots);
}
/**
* Returns the tarvalue
* Returns the immediate value
*/
tarval *get_arm_value(const ir_node *node) {
long get_arm_imm_value(const ir_node *node) {
const arm_attr_t *attr = get_arm_attr_const(node);
return attr->value;
return attr->imm_value;
}
/**
* Sets the tarvalue
* Sets the tarval value
*/
void set_arm_value(ir_node *node, tarval *tv) {
void set_arm_imm_value(ir_node *node, long imm_value) {
arm_attr_t *attr = get_arm_attr(node);
attr->value = tv;
attr->imm_value = imm_value;
}
/**
* Returns the fpaConst value
*/
tarval *get_fpaConst_value(const ir_node *node) {
const arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr_const(node);
return attr->tv;
}
/**
* Sets the tarval value
*/
void set_fpaConst_value(ir_node *node, tarval *tv) {
arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr(node);
attr->tv = tv;
}
/**
......@@ -567,7 +610,7 @@ static void init_arm_attributes(ir_node *node, int flags,
attr->out_req = out_reqs;
attr->flags = flags;
attr->instr_fl = (ARM_COND_AL << 3) | ARM_SHF_NONE;
attr->value = NULL;
attr->imm_value = 0;
attr->out_flags = NEW_ARR_D(int, obst, n_res);
memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0]));
......@@ -624,16 +667,22 @@ 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);
return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);
}
static int cmp_attr_arm_SymConst(ir_node *a, ir_node *b) {
const arm_SymConst_attr_t *attr_a;
const arm_SymConst_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_irn_generic_attr_const(a);
attr_b = get_irn_generic_attr_const(b);
return attr_a->symconst_id != attr_b->symconst_id;
}
static int cmp_attr_arm_CondJmp(ir_node *a, ir_node *b) {
......@@ -650,6 +699,19 @@ static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b) {
return 1;
}
static int cmp_attr_arm_fpaConst(ir_node *a, ir_node *b) {
const arm_fpaConst_attr_t *attr_a;
const arm_fpaConst_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_fpaConst_attr_const(a);
attr_b = get_arm_fpaConst_attr_const(b);
return attr_a->tv != attr_b->tv;
}
/** copies the ARM attributes of a node. */
static void arm_copy_attr(const ir_node *old_node, ir_node *new_node) {
ir_graph *irg = get_irn_irg(new_node);
......
......@@ -145,14 +145,24 @@ void set_arm_out_flags(ir_node *node, arch_irn_flags_t flags, int pos);
arch_irn_flags_t get_arm_out_flags(const ir_node *node, int pos);
/**
* Returns the tarval
* Returns the immediate value
*/
tarval *get_arm_value(const ir_node *node);
long get_arm_imm_value(const ir_node *node);
/**
* Sets the tarval
* Sets the immediate value
*/
void set_arm_value(ir_node *node, tarval *tv);
void set_arm_imm_value(ir_node *node, long imm_value);
/**
* Return the tarval of a fpaConst
*/
tarval *get_fpaConst_value(const ir_node *node);
/**
* Sets the tarval of a fpaConst
*/
void set_fpaConst_value(ir_node *node, tarval *tv);
/**
* Returns the proj num
......@@ -198,7 +208,7 @@ arm_shift_modifier get_arm_shift_modifier(const ir_node *node);
/**
* Decode an immediate with shifter operand
*/
unsigned int arm_decode_imm_w_shift(tarval *tv);
unsigned int arm_decode_imm_w_shift(long imm_value);
/* Include the generated headers */
#include "gen_arm_new_nodes.h"
......
......@@ -19,8 +19,8 @@
/**
* @file
* @brief declarations for arm node attributes
* @author Oliver Richter, Tobias Gneist
* @brief declarations for ARM node attributes
* @author Oliver Richter, Tobias Gneist, Michael Beck
* @version $Id$
*/
#ifndef FIRM_BE_ARM_ARM_NODES_ATTR_H
......@@ -87,6 +87,19 @@ typedef enum _arm_condition {
/** Set the condition code to flags */
#define ARM_SET_COND(attr, code) ((attr)->instr_fl = (((attr)->instr_fl & ~(15 << 4)) | ((code) << 4)))
/** Encoding for fpa immediates */
enum fpa_immediates {
fpa_null = 0,
fpa_one,
fpa_two,
fpa_three,
fpa_four,
fpa_five,
fpa_ten,
fpa_half,
fpa_max
};
/** Generic ARM node attributes. */
typedef struct _arm_attr_t {
except_attr exc; /**< the exception attribute. MUST be the first one. */
......@@ -97,7 +110,7 @@ typedef struct _arm_attr_t {
ir_mode *op_mode; /**< operation mode if different from node's mode */
unsigned instr_fl; /**< condition code, shift modifier */
tarval *value; /**< immediate */
long imm_value; /**< immediate */
int *out_flags; /**< flags for each produced value */
const arch_register_t **slots; /**< register slots for assigned registers */
......@@ -105,26 +118,40 @@ typedef struct _arm_attr_t {
/** Attributes for a SymConst */
typedef struct _arm_SymConst_attr_t {
arm_attr_t attr;
arm_attr_t attr; /**< base attributes */
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;
arm_attr_t attr; /**< base attributes */
int proj_num;
} arm_CondJmp_attr_t;
/** Attributes for a SwitchJmp */
typedef struct _arm_SwitchJmp_attr_t {
arm_attr_t attr;
arm_attr_t attr; /**< base attributes */
int n_projs;
long default_proj_num;
long default_proj_num;
} arm_SwitchJmp_attr_t;
/** Attributes for a fpaConst */
typedef struct _arm_fpaConst_attr_t {
arm_attr_t attr; /**< base attributes */
tarval *tv; /**< the tarval representing the FP const */
} arm_fpaConst_attr_t;
/**
* Returns the shift modifier string.
*/
const char *arm_shf_mod_name(arm_shift_modifier mod);
/**
* Return the fpa immediate from the encoding.
*/
const char *arm_get_fpa_imm_name(long imm_value);
#define CAST_ARM_ATTR(type,ptr) ((type *)(ptr))
#define CONST_CAST_ARM_ATTR(type,ptr) ((const type *)(ptr))
#endif
......@@ -183,6 +183,7 @@ $default_copy_attr = "arm_copy_attr";
arm_SymConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
arm_CondJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
arm_fpaConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);",
);
%compare_attr = (
......@@ -190,6 +191,7 @@ $default_copy_attr = "arm_copy_attr";
arm_SymConst_attr_t => "cmp_attr_arm_SymConst",
arm_CondJmp_attr_t => "cmp_attr_arm_CondJmp",
arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp",
arm_fpaConst_attr_t => "cmp_attr_arm_fpaConst",
);
#%operands = (
......@@ -258,9 +260,9 @@ 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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. add %D0, %S0, %S1%X'
},
......@@ -268,9 +270,9 @@ Add => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. add %D0, %S0, %C'
},
......@@ -313,9 +315,9 @@ 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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. and %D0, %S0, %S1%X'
},
......@@ -323,20 +325,20 @@ And => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. and %D0, %S0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
cmp_attr => 'return attr_a->imm_value != attr_b->imm_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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. orr %D0, %S0, %S1%X'
},
......@@ -344,10 +346,10 @@ Or => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
cmp_attr => 'return attr_a->value != attr_b->value;',
cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;',
emit => '. orr %D0, %S0, %C'
},
......@@ -355,9 +357,9 @@ 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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. eor %D0, %S0, %S1%X'
},
......@@ -365,10 +367,10 @@ Eor => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
cmp_attr => 'return attr_a->value != attr_b->value;',
cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;',
emit => '. eor %D0, %S0, %C'
},
......@@ -377,9 +379,9 @@ Eor_i => {
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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. bic %D0, %S0, %S1%X'
},
......@@ -387,19 +389,19 @@ Bic => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. bic %D0, %S0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
cmp_attr => 'return attr_a->imm_value != attr_b->imm_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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. sub %D0, %S0, %S1%X'
},
......@@ -407,9 +409,9 @@ Sub => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. sub %D0, %S0, %C',
},
......@@ -417,9 +419,9 @@ Sub_i => {
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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
emit => '. rsb %D0, %S0, %S1%X'
},
......@@ -427,11 +429,11 @@ Rsb => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. rsb %D0, %S0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;'
},
Shl => {
......@@ -480,9 +482,9 @@ Shrs => {
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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. mov %D0, %S0%X'
},
......@@ -490,19 +492,19 @@ Mov => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',
reg_req => { "out" => [ "gp" ] },
emit => '. mov %D0, %C',
cmp_attr => 'return attr_a->value != attr_b->value;'
cmp_attr => 'return attr_a->imm_value != attr_b->imm_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);',
attr => "arm_shift_modifier mod, long shf",
init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;',
cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);',
reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] },
emit => '. mvn %D0, %S0%X'
},
......@@ -510,9 +512,9 @@ Mvn => {
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;',
attr => "long imm",
init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;',