Commit c3689ef7 authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup,refactoring of some arm node attribute handling

[r27708]
parent 2f572ce1
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "config.h" #include "config.h"
#include <limits.h> #include <limits.h>
#include <stdbool.h>
#include "xmalloc.h" #include "xmalloc.h"
#include "tv.h" #include "tv.h"
...@@ -193,6 +194,16 @@ void arm_emit_mode(const ir_node *node) ...@@ -193,6 +194,16 @@ void arm_emit_mode(const ir_node *node)
arm_emit_fpa_postfix(mode); arm_emit_fpa_postfix(mode);
} }
void arm_emit_symconst(const ir_node *node)
{
const arm_SymConst_attr_t *symconst = get_arm_SymConst_attr_const(node);
ir_entity *entity = symconst->entity;
be_gas_emit_entity(entity);
/* TODO do something with offset */
}
void arm_emit_load_mode(const ir_node *node) void arm_emit_load_mode(const ir_node *node)
{ {
const arm_load_store_attr_t *attr = get_arm_load_store_attr_const(node); const arm_load_store_attr_t *attr = get_arm_load_store_attr_const(node);
...@@ -223,7 +234,7 @@ void arm_emit_store_mode(const ir_node *node) ...@@ -223,7 +234,7 @@ void arm_emit_store_mode(const ir_node *node)
} }
static void emit_shf_mod_name(arm_shift_modifier mod) static void emit_shf_mod_name(arm_shift_modifier_t mod)
{ {
switch (mod) { switch (mod) {
case ARM_SHF_ASR_REG: case ARM_SHF_ASR_REG:
...@@ -298,12 +309,12 @@ void arm_emit_shifter_operand(const ir_node *node) ...@@ -298,12 +309,12 @@ void arm_emit_shifter_operand(const ir_node *node)
/** An entry in the sym_or_tv set. */ /** An entry in the sym_or_tv set. */
typedef struct sym_or_tv_t { typedef struct sym_or_tv_t {
union { union {
ident *id; /**< An ident. */ ir_entity *entity; /**< An entity. */
tarval *tv; /**< A tarval. */ tarval *tv; /**< A tarval. */
const void *generic; /**< For generic compare. */ const void *generic; /**< For generic compare. */
} u; } u;
unsigned label; /**< the associated label. */ unsigned label; /**< the associated label. */
char is_ident; /**< Non-zero if an ident is stored. */ bool is_entity; /**< true if an entity is stored. */
} sym_or_tv_t; } sym_or_tv_t;
/** /**
...@@ -324,8 +335,8 @@ static void emit_arm_SymConst(const ir_node *irn) ...@@ -324,8 +335,8 @@ static void emit_arm_SymConst(const ir_node *irn)
sym_or_tv_t key, *entry; sym_or_tv_t key, *entry;
unsigned label; unsigned label;
key.u.id = get_entity_ld_ident(attr->entity); key.u.entity = attr->entity;
key.is_ident = 1; key.is_entity = true;
key.label = 0; key.label = 0;
entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic)); entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
if (entry->label == 0) { if (entry->label == 0) {
...@@ -337,7 +348,7 @@ static void emit_arm_SymConst(const ir_node *irn) ...@@ -337,7 +348,7 @@ static void emit_arm_SymConst(const ir_node *irn)
/* load the symbol indirect */ /* load the symbol indirect */
be_emit_cstring("\tldr "); be_emit_cstring("\tldr ");
arm_emit_dest_register(irn, 0); arm_emit_dest_register(irn, 0);
be_emit_irprintf(", .L%u", label); be_emit_irprintf(", %s%u", be_gas_get_private_prefix(), label);
be_emit_finish_line_gas(irn); be_emit_finish_line_gas(irn);
} }
...@@ -364,7 +375,7 @@ static void emit_arm_fpaConst(const ir_node *irn) ...@@ -364,7 +375,7 @@ static void emit_arm_fpaConst(const ir_node *irn)
ir_mode *mode; ir_mode *mode;
key.u.tv = get_fpaConst_value(irn); key.u.tv = get_fpaConst_value(irn);
key.is_ident = 0; key.is_entity = false;
key.label = 0; key.label = 0;
entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic)); entry = (sym_or_tv_t *)set_insert(sym_or_tv, &key, sizeof(key), HASH_PTR(key.u.generic));
if (entry->label == 0) { if (entry->label == 0) {
...@@ -380,7 +391,7 @@ static void emit_arm_fpaConst(const ir_node *irn) ...@@ -380,7 +391,7 @@ static void emit_arm_fpaConst(const ir_node *irn)
be_emit_char(' '); be_emit_char(' ');
arm_emit_dest_register(irn, 0); arm_emit_dest_register(irn, 0);
be_emit_irprintf(", .L%u", label); be_emit_irprintf(", %s%u", be_gas_get_private_prefix(), label);
be_emit_finish_line_gas(irn); be_emit_finish_line_gas(irn);
} }
...@@ -422,7 +433,7 @@ static void emit_arm_B(const ir_node *irn) ...@@ -422,7 +433,7 @@ static void emit_arm_B(const ir_node *irn)
const ir_node *next_block; const ir_node *next_block;
ir_node *op1 = get_irn_n(irn, 0); ir_node *op1 = get_irn_n(irn, 0);
const char *suffix; const char *suffix;
int proj_num = get_arm_CondJmp_proj_num(irn); pn_Cmp pnc = get_arm_CondJmp_pnc(irn);
const arm_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1); const arm_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1);
bool is_signed = !cmp_attr->is_unsigned; bool is_signed = !cmp_attr->is_unsigned;
...@@ -439,7 +450,7 @@ static void emit_arm_B(const ir_node *irn) ...@@ -439,7 +450,7 @@ static void emit_arm_B(const ir_node *irn)
} }
if (cmp_attr->ins_permuted) { if (cmp_attr->ins_permuted) {
proj_num = get_mirrored_pnc(proj_num); pnc = get_mirrored_pnc(pnc);
} }
/* for now, the code works for scheduled and non-schedules blocks */ /* for now, the code works for scheduled and non-schedules blocks */
...@@ -448,8 +459,8 @@ static void emit_arm_B(const ir_node *irn) ...@@ -448,8 +459,8 @@ static void emit_arm_B(const ir_node *irn)
/* we have a block schedule */ /* we have a block schedule */
next_block = sched_next_block(block); next_block = sched_next_block(block);
assert(proj_num != pn_Cmp_False); assert(pnc != pn_Cmp_False);
assert(proj_num != pn_Cmp_True); assert(pnc != pn_Cmp_True);
if (get_cfop_target_block(proj_true) == next_block) { if (get_cfop_target_block(proj_true) == next_block) {
/* exchange both proj's so the second one can be omitted */ /* exchange both proj's so the second one can be omitted */
...@@ -457,10 +468,10 @@ static void emit_arm_B(const ir_node *irn) ...@@ -457,10 +468,10 @@ static void emit_arm_B(const ir_node *irn)
proj_true = proj_false; proj_true = proj_false;
proj_false = t; proj_false = t;
proj_num = get_negated_pnc(proj_num, mode_Iu); pnc = get_negated_pnc(pnc, mode_Iu);
} }
switch (proj_num) { switch (pnc) {
case pn_Cmp_Eq: suffix = "eq"; break; case pn_Cmp_Eq: suffix = "eq"; break;
case pn_Cmp_Lt: suffix = is_signed ? "lt" : "lo"; break; case pn_Cmp_Lt: suffix = is_signed ? "lt" : "lo"; break;
case pn_Cmp_Le: suffix = is_signed ? "le" : "ls"; break; case pn_Cmp_Le: suffix = is_signed ? "le" : "ls"; break;
...@@ -1141,11 +1152,12 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) ...@@ -1141,11 +1152,12 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg)
be_emit_cstring("\t.align 2\n"); be_emit_cstring("\t.align 2\n");
foreach_set(sym_or_tv, entry) { foreach_set(sym_or_tv, entry) {
be_emit_irprintf(".L%u:\n", entry->label); be_emit_irprintf("%s%u:\n", be_gas_get_private_prefix(),
entry->label);
if (entry->is_ident) { if (entry->is_entity) {
be_emit_cstring("\t.word\t"); be_emit_cstring("\t.word\t");
be_emit_ident(entry->u.id); be_gas_emit_entity(entry->u.entity);
be_emit_char('\n'); be_emit_char('\n');
be_emit_write_line(); be_emit_write_line();
} else { } else {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "bearch_arm_t.h" #include "bearch_arm_t.h"
void arm_emit_mode(const ir_node *node); void arm_emit_mode(const ir_node *node);
void arm_emit_symconst(const ir_node *node);
void arm_emit_source_register(const ir_node *node, int pos); void arm_emit_source_register(const ir_node *node, int pos);
void arm_emit_dest_register(const ir_node *node, int pos); void arm_emit_dest_register(const ir_node *node, int pos);
void arm_emit_offset(const ir_node *node); void arm_emit_offset(const ir_node *node);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "config.h" #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include "irprog_t.h" #include "irprog_t.h"
#include "irgraph_t.h" #include "irgraph_t.h"
...@@ -49,9 +50,6 @@ ...@@ -49,9 +50,6 @@
#include "../beabi.h" #include "../beabi.h"
#include "bearch_arm_t.h" #include "bearch_arm_t.h"
/**
* Return the fpa immediate from the encoding.
*/
const char *arm_get_fpa_imm_name(long imm_value) const char *arm_get_fpa_imm_name(long imm_value)
{ {
static const char *fpa_imm[] = { static const char *fpa_imm[] = {
...@@ -67,6 +65,28 @@ const char *arm_get_fpa_imm_name(long imm_value) ...@@ -67,6 +65,28 @@ const char *arm_get_fpa_imm_name(long imm_value)
return fpa_imm[imm_value]; return fpa_imm[imm_value];
} }
static bool arm_has_immediate(const ir_node *node)
{
return is_arm_SymConst(node) || is_arm_FrameAddr(node);
}
static bool has_load_store_attr(const ir_node *node)
{
return is_arm_Ldr(node) || is_arm_Str(node);
}
static bool has_shifter_operand(const ir_node *node)
{
return is_arm_Add(node) || is_arm_And(node) || is_arm_Or(node)
|| is_arm_Eor(node) || is_arm_Bic(node) || is_arm_Sub(node)
|| is_arm_Rsb(node) || is_arm_Mov(node) || is_arm_Mvn(node)
|| is_arm_Cmp(node) || is_arm_Tst(node);
}
static bool has_cmp_attr(const ir_node *node)
{
return is_arm_Cmp(node) || is_arm_Tst(node);
}
/** /**
* Dumper interface for dumping arm nodes in vcg. * Dumper interface for dumping arm nodes in vcg.
...@@ -76,25 +96,23 @@ const char *arm_get_fpa_imm_name(long imm_value) ...@@ -76,25 +96,23 @@ const char *arm_get_fpa_imm_name(long imm_value)
*/ */
static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason) static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
{ {
ir_mode *mode = NULL;
//arm_attr_t *attr = get_arm_attr(n);
switch (reason) { switch (reason) {
case dump_node_opcode_txt: case dump_node_opcode_txt:
fprintf(F, "%s", get_irn_opname(n)); fprintf(F, "%s", get_irn_opname(n));
break;
case dump_node_mode_txt: if (arm_has_immediate(n)) {
mode = get_irn_mode(n); const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(n);
if (attr->entity != NULL) {
if (mode) { fputc(' ', F);
fprintf(F, "[%s]", get_mode_name(mode)); fputs(get_entity_name(attr->entity), F);
} }
else {
fprintf(F, "[?NOMODE?]");
} }
break; break;
case dump_node_mode_txt:
/* mode isn't relevant in the backend */
break;
case dump_node_nodeattr_txt: case dump_node_nodeattr_txt:
/* TODO: dump shift modifiers */ /* TODO: dump shift modifiers */
break; break;
...@@ -102,31 +120,75 @@ static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason) ...@@ -102,31 +120,75 @@ static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
case dump_node_info_txt: case dump_node_info_txt:
arch_dump_reqs_and_registers(F, n); arch_dump_reqs_and_registers(F, n);
if (is_arm_CopyB(n)) { if (has_load_store_attr(n)) {
//fprintf(F, "size = %lu\n", get_arm_imm_value(n)); const arm_load_store_attr_t *attr
} else { = get_arm_load_store_attr_const(n);
/* TODO */ ir_fprintf(F, "load_store_mode = %+F\n", attr->load_store_mode);
#if 0 ir_fprintf(F, "entity = %+F\n", attr->entity);
long v = get_arm_imm_value(n); fprintf(F, "offset = %ld\n", attr->offset);
if (ARM_GET_FPA_IMM(attr)) { fprintf(F, "is_frame_entity = %s\n",
fprintf(F, "immediate float value = %s\n", arm_get_fpa_imm_name(v)); attr->is_frame_entity ? "yes" : "no");
} else { fprintf(F, "entity_sign = %s\n",
fprintf(F, "immediate value = %ld (0x%08lx)\n", v, v); attr->entity_sign ? "yes" : "no");
} }
#endif if (has_shifter_operand(n)) {
const arm_shifter_operand_t *attr
= get_arm_shifter_operand_attr_const(n);
switch (attr->shift_modifier) {
case ARM_SHF_REG:
break;
case ARM_SHF_IMM:
fprintf(F, "modifier = imm %d ror %d\n",
attr->immediate_value, attr->shift_immediate);
break;
case ARM_SHF_ASR_IMM:
fprintf(F, "modifier = V >>s %d\n", attr->shift_immediate);
break;
case ARM_SHF_ASR_REG:
fprintf(F, "modifier = V >>s R\n");
break;
case ARM_SHF_LSL_IMM:
fprintf(F, "modifier = V << %d\n", attr->shift_immediate);
break;
case ARM_SHF_LSL_REG:
fprintf(F, "modifier = V << R\n");
break;
case ARM_SHF_LSR_IMM:
fprintf(F, "modifier = V >> %d\n", attr->shift_immediate);
break;
case ARM_SHF_LSR_REG:
fprintf(F, "modifier = V >> R\n");
break;
case ARM_SHF_ROR_IMM:
fprintf(F, "modifier = V ROR %d\n", attr->shift_immediate);
break;
case ARM_SHF_ROR_REG:
fprintf(F, "modifier = V ROR R\n");
break;
case ARM_SHF_RRX:
fprintf(F, "modifier = RRX\n");
break;
default:
case ARM_SHF_INVALID:
fprintf(F, "modifier = INVALID SHIFT MODIFIER\n");
break;
} }
#if 0
if (is_arm_CmpBra(n) && get_arm_CondJmp_proj_num(n) >= 0) {
fprintf(F, "proj_num = (%d)\n", get_arm_CondJmp_proj_num(n));
} }
#endif if (has_cmp_attr(n)) {
const arm_cmp_attr_t *attr = get_arm_cmp_attr_const(n);
fprintf(F, "cmp_attr =");
if (attr->is_unsigned) {
fprintf(F, " unsigned");
}
if (attr->ins_permuted) {
fprintf(F, " inputs swapped");
}
fprintf(F, "\n");
}
break; break;
} }
} }
/* Returns the attributes of a generic Arm node. */
arm_attr_t *get_arm_attr(ir_node *node) arm_attr_t *get_arm_attr(ir_node *node)
{ {
assert(is_arm_irn(node) && "need arm node to get attributes"); assert(is_arm_irn(node) && "need arm node to get attributes");
...@@ -139,22 +201,25 @@ const arm_attr_t *get_arm_attr_const(const ir_node *node) ...@@ -139,22 +201,25 @@ const arm_attr_t *get_arm_attr_const(const ir_node *node)
return get_irn_generic_attr_const(node); return get_irn_generic_attr_const(node);
} }
/** static bool has_symconst_attr(const ir_node *node)
* Returns the attributes of an ARM SymConst node. {
*/ return is_arm_SymConst(node) || is_arm_FrameAddr(node);
}
arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node) arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node)
{ {
assert(is_arm_SymConst(node) || is_arm_FrameAddr(node)); assert(has_symconst_attr(node));
return get_irn_generic_attr(node); return get_irn_generic_attr(node);
} }
const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node) const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node)
{ {
assert(is_arm_SymConst(node) || is_arm_FrameAddr(node)); assert(has_symconst_attr(node));
return get_irn_generic_attr_const(node); return get_irn_generic_attr_const(node);
} }
static const arm_fpaConst_attr_t *get_arm_fpaConst_attr_const(const ir_node *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_attr_t *attr = get_arm_attr_const(node);
const arm_fpaConst_attr_t *fpa_attr = CONST_CAST_ARM_ATTR(arm_fpaConst_attr_t, attr); const arm_fpaConst_attr_t *fpa_attr = CONST_CAST_ARM_ATTR(arm_fpaConst_attr_t, attr);
...@@ -170,7 +235,6 @@ static arm_fpaConst_attr_t *get_arm_fpaConst_attr(ir_node *node) ...@@ -170,7 +235,6 @@ static arm_fpaConst_attr_t *get_arm_fpaConst_attr(ir_node *node)
return fpa_attr; return fpa_attr;
} }
/* Returns the attributes of a CondJmp node. */
arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node) arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node)
{ {
assert(is_arm_B(node)); assert(is_arm_B(node));
...@@ -183,7 +247,6 @@ const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node) ...@@ -183,7 +247,6 @@ const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node)
return get_irn_generic_attr_const(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) arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr(ir_node *node)
{ {
assert(is_arm_SwitchJmp(node)); assert(is_arm_SwitchJmp(node));
...@@ -196,99 +259,66 @@ const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node) ...@@ -196,99 +259,66 @@ const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node)
return get_irn_generic_attr_const(node); return get_irn_generic_attr_const(node);
} }
/** void set_arm_in_req_all(ir_node *node, const arch_register_req_t **reqs)
* Returns the argument register requirements of a arm node.
*/
const arch_register_req_t **get_arm_in_req_all(const ir_node *node)
{ {
const arm_attr_t *attr = get_arm_attr_const(node); arm_attr_t *attr = get_arm_attr(node);
return attr->in_req; attr->in_req = reqs;
} }
/**
* 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) const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos)
{ {
const arm_attr_t *attr = get_arm_attr_const(node); const arm_attr_t *attr = get_arm_attr_const(node);
return attr->in_req[pos]; return attr->in_req[pos];
} }
/**
* Sets the IN register requirements at position pos.
*/
void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos) void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos)
{ {
arm_attr_t *attr = get_arm_attr(node); arm_attr_t *attr = get_arm_attr(node);
attr->in_req[pos] = req; attr->in_req[pos] = req;
} }
/**
* Returns the fpaConst value
*/
tarval *get_fpaConst_value(const ir_node *node) tarval *get_fpaConst_value(const ir_node *node)
{ {
const arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr_const(node); const arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr_const(node);
return attr->tv; return attr->tv;
} }
/**
* Sets the tarval value
*/
void set_fpaConst_value(ir_node *node, tarval *tv) void set_fpaConst_value(ir_node *node, tarval *tv)
{ {
arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr(node); arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr(node);
attr->tv = tv; attr->tv = tv;
} }
/** pn_Cmp get_arm_CondJmp_pnc(const ir_node *node)
* Returns the proj num
*/
int get_arm_CondJmp_proj_num(const ir_node *node)
{ {
const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node); const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node);
return attr->proj_num; return attr->pnc;
} }
/** void set_arm_CondJmp_pnc(ir_node *node, pn_Cmp pnc)
* Sets the proj num
*/
void set_arm_CondJmp_proj_num(ir_node *node, int proj_num)
{ {
arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node); arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node);
attr->proj_num = proj_num; attr->pnc = pnc;
} }
/**
* Returns the number of projs of a SwitchJmp.
*/
int get_arm_SwitchJmp_n_projs(const ir_node *node) int get_arm_SwitchJmp_n_projs(const ir_node *node)
{ {
const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node); const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node);
return attr->n_projs; return attr->n_projs;
} }
/**
* Sets the number of projs.
*/
void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs) void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs)
{ {
arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node);