Commit 4bfc787a authored by Matthias Braun's avatar Matthias Braun
Browse files

arm: cleanup, use C99

parent 45449d34
......@@ -45,26 +45,15 @@ static const arch_register_t* const float_result_regs[] = {
calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
ir_type *function_type)
{
unsigned stack_offset = 0;
unsigned n_param_regs_used = 0;
reg_or_stackslot_t *params;
reg_or_stackslot_t *results;
size_t const n_param_regs = ARRAY_SIZE(param_regs);
size_t const n_result_regs = ARRAY_SIZE(result_regs);
size_t const n_float_result_regs = ARRAY_SIZE(float_result_regs);
size_t n_params;
size_t n_results;
size_t i;
size_t regnum;
size_t float_regnum;
calling_convention_t *cconv;
/* determine how parameters are passed */
n_params = get_method_n_params(function_type);
regnum = 0;
params = XMALLOCNZ(reg_or_stackslot_t, n_params);
unsigned stack_offset = 0;
size_t const n_param_regs = ARRAY_SIZE(param_regs);
size_t const n_params = get_method_n_params(function_type);
size_t regnum = 0;
reg_or_stackslot_t *params = XMALLOCNZ(reg_or_stackslot_t, n_params);
for (i = 0; i < n_params; ++i) {
for (size_t i = 0; i < n_params; ++i) {
ir_type *param_type = get_method_param_type(function_type,i);
ir_mode *mode = get_type_mode(param_type);
int bits = get_mode_size_bits(mode);
......@@ -99,13 +88,15 @@ calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
}
}
}
n_param_regs_used = regnum;
n_results = get_method_n_ress(function_type);
regnum = 0;
float_regnum = 0;
results = XMALLOCNZ(reg_or_stackslot_t, n_results);
for (i = 0; i < n_results; ++i) {
unsigned const n_param_regs_used = regnum;
size_t const n_result_regs= ARRAY_SIZE(result_regs);
size_t const n_float_result_regs = ARRAY_SIZE(float_result_regs);
size_t n_results = get_method_n_ress(function_type);
size_t float_regnum = 0;
reg_or_stackslot_t *results = XMALLOCNZ(reg_or_stackslot_t, n_results);
regnum = 0;
for (size_t i = 0; i < n_results; ++i) {
ir_type *result_type = get_method_res_type(function_type, i);
ir_mode *result_mode = get_type_mode(result_type);
reg_or_stackslot_t *result = &results[i];
......@@ -131,7 +122,7 @@ calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
}
}
cconv = XMALLOCZ(calling_convention_t);
calling_convention_t *cconv = XMALLOCZ(calling_convention_t);
cconv->parameters = params;
cconv->param_stack_size = stack_offset;
cconv->n_reg_params = n_param_regs_used;
......@@ -142,12 +133,11 @@ calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
be_irg_t *birg = be_birg_from_irg(irg);
size_t n_ignores = ARRAY_SIZE(ignore_regs);
struct obstack *obst = &birg->obst;
size_t r;
assert(birg->allocatable_regs == NULL);
birg->allocatable_regs = rbitset_obstack_alloc(obst, N_ARM_REGISTERS);
rbitset_set_all(birg->allocatable_regs, N_ARM_REGISTERS);
for (r = 0; r < n_ignores; ++r) {
for (size_t r = 0; r < n_ignores; ++r) {
rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
}
}
......
......@@ -35,7 +35,6 @@
#include "gen_arm_emitter.h"
#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
#include "arm_map_regs.h"
#include "gen_arm_regalloc_if.h"
#include "benode.h"
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Register mapping for firm nodes. Stolen from bearch_firm :)
* @author Oliver Richter, Tobias Gneist
*/
#include <stdlib.h>
#include "arm_map_regs.h"
#include "arm_new_nodes.h"
#include "gen_arm_regalloc_if.h"
static const arch_register_t *gpreg_param_reg_std[] = {
&arm_registers[REG_R0],
&arm_registers[REG_R1],
&arm_registers[REG_R2],
&arm_registers[REG_R3],
};
const arch_register_t *arm_get_RegParam_reg(int n)
{
assert(n < 4 && n >=0 && "register param > 3 angefordert");
return gpreg_param_reg_std[n];
}
/* Mapping to store registers in firm nodes */
typedef struct arm_irn_reg_assoc {
const ir_node *irn;
const arch_register_t *reg;
} arm_irn_reg_assoc;
int arm_cmp_irn_reg_assoc(const void *a, const void *b, size_t size)
{
const arm_irn_reg_assoc *x = (const arm_irn_reg_assoc*)a;
const arm_irn_reg_assoc *y = (const arm_irn_reg_assoc*)b;
(void) size;
return x->irn != y->irn;
}
static arm_irn_reg_assoc *get_irn_reg_assoc(const ir_node *irn, set *reg_set)
{
arm_irn_reg_assoc templ;
unsigned int hash;
templ.irn = irn;
templ.reg = NULL;
hash = hash_ptr(irn);
return set_insert(arm_irn_reg_assoc, reg_set, &templ, sizeof(templ), hash);
}
void arm_set_firm_reg(ir_node *irn, const arch_register_t *reg, set *reg_set)
{
arm_irn_reg_assoc *assoc = get_irn_reg_assoc(irn, reg_set);
assoc->reg = reg;
}
const arch_register_t *arm_get_firm_reg(const ir_node *irn, set *reg_set)
{
const arm_irn_reg_assoc *assoc = get_irn_reg_assoc(irn, reg_set);
return assoc->reg;
}
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief declarations for ARM register allocation
* @author Oliver Richter, Tobias Gneist, Michael Beck
*/
#ifndef FIRM_BE_ARM_ARM_MAP_REGS_H
#define FIRM_BE_ARM_ARM_MAP_REGS_H
#include "irnode.h"
#include "set.h"
#include "bearch.h"
#include "arm_nodes_attr.h"
const arch_register_t *arm_get_RegParam_reg(int n);
int arm_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
void arm_set_firm_reg(ir_node *irn, const arch_register_t *reg, set *reg_set);
const arch_register_t *arm_get_firm_reg(const ir_node *irn, set *reg_set);
#endif
......@@ -294,13 +294,11 @@ static void init_arm_attributes(ir_node *node, arch_irn_flags_t flags,
ir_graph *irg = get_irn_irg(node);
struct obstack *obst = get_irg_obstack(irg);
arm_attr_t *attr = get_arm_attr(node);
backend_info_t *info;
arch_set_irn_flags(node, flags);
arch_set_irn_register_reqs_in(node, in_reqs);
attr->is_load_store = false;
info = be_get_info(node);
backend_info_t *info = be_get_info(node);
info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
}
......@@ -367,65 +365,55 @@ static void init_arm_SwitchJmp_attributes(ir_node *res,
static int cmp_attr_arm(const ir_node *a, const ir_node *b)
{
(void) a;
(void) b;
(void)a;
(void)b;
return 0;
}
static int cmp_attr_arm_Address(const ir_node *a, const ir_node *b)
{
const arm_Address_attr_t *attr_a;
const arm_Address_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_Address_attr_const(a);
attr_b = get_arm_Address_attr_const(b);
const arm_Address_attr_t *attr_a = get_arm_Address_attr_const(a);
const arm_Address_attr_t *attr_b = get_arm_Address_attr_const(b);
return attr_a->entity != attr_b->entity
|| attr_a->fp_offset != attr_b->fp_offset;
}
static int cmp_attr_arm_CopyB(const ir_node *a, const ir_node *b)
{
const arm_CopyB_attr_t *attr_a;
const arm_CopyB_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_CopyB_attr_const(a);
attr_b = get_arm_CopyB_attr_const(b);
const arm_CopyB_attr_t *attr_a = get_arm_CopyB_attr_const(a);
const arm_CopyB_attr_t *attr_b = get_arm_CopyB_attr_const(b);
return attr_a->size != attr_b->size;
}
static int cmp_attr_arm_CondJmp(const ir_node *a, const ir_node *b)
{
(void) a;
(void) b;
(void)a;
(void)b;
/* never identical */
return 1;
}
static int cmp_attr_arm_SwitchJmp(const ir_node *a, const ir_node *b)
{
(void) a;
(void) b;
(void)a;
(void)b;
/* never identical */
return 1;
}
static int cmp_attr_arm_fConst(const ir_node *a, const ir_node *b)
{
const arm_fConst_attr_t *attr_a;
const arm_fConst_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_fConst_attr_const(a);
attr_b = get_arm_fConst_attr_const(b);
const arm_fConst_attr_t *attr_a = get_arm_fConst_attr_const(a);
const arm_fConst_attr_t *attr_b = get_arm_fConst_attr_const(b);
return attr_a->tv != attr_b->tv;
}
......@@ -463,17 +451,14 @@ const arm_cmp_attr_t *get_arm_cmp_attr_const(const ir_node *node)
static int cmp_attr_arm_load_store(const ir_node *a, const ir_node *b)
{
const arm_load_store_attr_t *attr_a;
const arm_load_store_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_load_store_attr_const(a);
attr_b = get_arm_load_store_attr_const(b);
const arm_load_store_attr_t *attr_a = get_arm_load_store_attr_const(a);
const arm_load_store_attr_t *attr_b = get_arm_load_store_attr_const(b);
if (attr_a->entity != attr_b->entity
|| attr_a->entity_sign != attr_b->entity_sign
|| attr_a->offset != attr_b->offset)
|| attr_a->entity_sign != attr_b->entity_sign
|| attr_a->offset != attr_b->offset)
return 1;
return 0;
......@@ -481,17 +466,14 @@ static int cmp_attr_arm_load_store(const ir_node *a, const ir_node *b)
static int cmp_attr_arm_shifter_operand(const ir_node *a, const ir_node *b)
{
const arm_shifter_operand_t *attr_a;
const arm_shifter_operand_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_shifter_operand_attr_const(a);
attr_b = get_arm_shifter_operand_attr_const(b);
const arm_shifter_operand_t *attr_a = get_arm_shifter_operand_attr_const(a);
const arm_shifter_operand_t *attr_b = get_arm_shifter_operand_attr_const(b);
if (attr_a->shift_modifier != attr_b->shift_modifier
|| attr_a->immediate_value != attr_b->immediate_value
|| attr_a->shift_immediate != attr_b->shift_immediate)
|| attr_a->immediate_value != attr_b->immediate_value
|| attr_a->shift_immediate != attr_b->shift_immediate)
return 1;
return 0;
......@@ -499,30 +481,24 @@ static int cmp_attr_arm_shifter_operand(const ir_node *a, const ir_node *b)
static int cmp_attr_arm_cmp(const ir_node *a, const ir_node *b)
{
const arm_cmp_attr_t *attr_a;
const arm_cmp_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_cmp_attr_const(a);
attr_b = get_arm_cmp_attr_const(b);
const arm_cmp_attr_t *attr_a = get_arm_cmp_attr_const(a);
const arm_cmp_attr_t *attr_b = get_arm_cmp_attr_const(b);
if (attr_a->ins_permuted != attr_b->ins_permuted
|| attr_a->is_unsigned != attr_b->is_unsigned)
|| attr_a->is_unsigned != attr_b->is_unsigned)
return 1;
return 0;
}
static int cmp_attr_arm_farith(const ir_node *a, const ir_node *b)
{
const arm_farith_attr_t *attr_a;
const arm_farith_attr_t *attr_b;
if (cmp_attr_arm(a, b))
return 1;
attr_a = get_arm_farith_attr_const(a);
attr_b = get_arm_farith_attr_const(b);
const arm_farith_attr_t *attr_a = get_arm_farith_attr_const(a);
const arm_farith_attr_t *attr_b = get_arm_farith_attr_const(b);
return attr_a->mode != attr_b->mode;
}
......@@ -530,7 +506,7 @@ static int cmp_attr_arm_farith(const ir_node *a, const ir_node *b)
static void arm_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
struct obstack *obst = get_irg_obstack(irg);
struct obstack *obst = get_irg_obstack(irg);
const arm_attr_t *attr_old = get_arm_attr_const(old_node);
arm_attr_t *attr_new = get_arm_attr(new_node);
backend_info_t *old_info = be_get_info(old_node);
......@@ -540,10 +516,9 @@ static void arm_copy_attr(ir_graph *irg, const ir_node *old_node,
memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
/* copy out flags */
new_info->flags = old_info->flags;
new_info->out_infos =
DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
new_info->in_reqs = old_info->in_reqs;
new_info->flags = old_info->flags;
new_info->out_infos = DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
new_info->in_reqs = old_info->in_reqs;
}
......
......@@ -59,8 +59,8 @@ typedef struct arm_attr_t {
typedef struct arm_shifter_operand_t {
arm_attr_t base;
arm_shift_modifier_t shift_modifier;
unsigned char immediate_value;
unsigned char shift_immediate;
uint8_t immediate_value;
uint8_t shift_immediate;
} arm_shifter_operand_t;
typedef struct arm_cmp_attr_t {
......
......@@ -23,49 +23,16 @@
#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
static unsigned arm_ror(unsigned v, unsigned ror)
static uint32_t arm_ror(uint32_t v, uint32_t ror)
{
return (v << (32 - ror)) | (v >> ror);
}
/*
* construct 8bit values and rot amounts for a value.
*/
void arm_gen_vals_from_word(unsigned int value, arm_vals *result)
{
int initial = 0;
/* TODO: not optimal yet, as we only "shift" the value and don't take advantage of rotations */
/* special case: we prefer shift amount 0 */
if (value <= 0xFF) {
result->values[0] = value;
result->rors[0] = 0;
result->ops = 1;
return;
}
result->ops = 0;
do {
while ( (value & 0x3) == 0) {
value >>= 2;
initial += 2;
}
result->values[result->ops] = value & 0xFF;
result->rors[result->ops] = (32-initial) % 32;
++result->ops;
value >>= 8;
initial += 8;
} while (value != 0);
}
/**
* Returns non.zero if the given offset can be directly encoded into an ARM
* instruction.
*/
static int allowed_arm_immediate(int offset, arm_vals *result)
static bool allowed_arm_immediate(int offset, arm_vals *result)
{
arm_gen_vals_from_word(offset, result);
return result->ops <= 1;
......@@ -76,31 +43,25 @@ static int allowed_arm_immediate(int offset, arm_vals *result)
*/
static void peephole_be_IncSP(ir_node *node)
{
ir_node *first;
ir_node *last;
ir_node *block;
int offset;
int cnt;
int sign = 1;
arm_vals v;
/* first optimize incsp->incsp combinations */
node = be_peephole_IncSP_IncSP(node);
offset = be_get_IncSP_offset(node);
int offset = be_get_IncSP_offset(node);
/* can be transformed into Add OR Sub */
int sign = 1;
if (offset < 0) {
sign = -1;
offset = -offset;
}
arm_vals v;
if (allowed_arm_immediate(offset, &v))
return;
be_set_IncSP_offset(node, sign * arm_ror(v.values[0], v.rors[0]));
first = node;
block = get_nodes_block(node);
for (cnt = 1; cnt < v.ops; ++cnt) {
ir_node *first = node;
ir_node *block = get_nodes_block(node);
for (unsigned cnt = 1; cnt < v.ops; ++cnt) {
int value = sign * arm_ror(v.values[cnt], v.rors[cnt]);
ir_node *incsp = be_new_IncSP(&arm_registers[REG_SP], block, node,
value, 1);
......@@ -109,7 +70,7 @@ static void peephole_be_IncSP(ir_node *node)
}
/* reattach IncSP users */
last = node;
ir_node *last = node;
node = sched_next(first);
foreach_out_edge_safe(first, edge) {
ir_node *user = get_edge_src_irn(edge);
......@@ -123,18 +84,16 @@ static void peephole_be_IncSP(ir_node *node)
/**
* creates the address by Adds
*/
static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, arm_vals *v)
static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, const arm_vals *v)
{
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = get_nodes_block(node);
int cnt;
ir_node *ptr;
ptr = new_bd_arm_Add_imm(dbgi, block, frame, v->values[0], v->rors[0]);
ir_node *ptr = new_bd_arm_Add_imm(dbgi, block, frame, v->values[0],
v->rors[0]);
arch_set_irn_register(ptr, &arm_registers[REG_R12]);
sched_add_before(node, ptr);
for (cnt = 1; cnt < v->ops; ++cnt) {
for (unsigned cnt = 1; cnt < v->ops; ++cnt) {
ir_node *next = new_bd_arm_Add_imm(dbgi, block, ptr, v->values[cnt],
v->rors[cnt]);
arch_set_irn_register(next, &arm_registers[REG_R12]);
......@@ -147,18 +106,16 @@ static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, arm_vals *v)
/**
* creates the address by Subs
*/
static ir_node *gen_ptr_sub(ir_node *node, ir_node *frame, arm_vals *v)
static ir_node *gen_ptr_sub(ir_node *node, ir_node *frame, const arm_vals *v)
{
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = get_nodes_block(node);
int cnt;
ir_node *ptr;
ptr = new_bd_arm_Sub_imm(dbgi, block, frame, v->values[0], v->rors[0]);
ir_node *ptr = new_bd_arm_Sub_imm(dbgi, block, frame, v->values[0],
v->rors[0]);
arch_set_irn_register(ptr, &arm_registers[REG_R12]);
sched_add_before(node, ptr);
for (cnt = 1; cnt < v->ops; ++cnt) {
for (unsigned cnt = 1; cnt < v->ops; ++cnt) {
ir_node *next = new_bd_arm_Sub_imm(dbgi, block, ptr, v->values[cnt],
v->rors[cnt]);
arch_set_irn_register(next, &arm_registers[REG_R12]);
......@@ -174,15 +131,12 @@ static void peephole_arm_FrameAddr(ir_node *node)
arm_Address_attr_t *attr = get_arm_Address_attr(node);
int offset = attr->fp_offset;
arm_vals v;
ir_node *base;
ir_node *ptr;
if (allowed_arm_immediate(offset, &v))
return;
base = get_irn_n(node, n_arm_FrameAddr_base);
ir_node *base = get_irn_n(node, n_arm_FrameAddr_base);
/* TODO: suboptimal */
ptr = gen_ptr_add(node, base, &v);
ir_node *ptr = gen_ptr_add(node, base, &v);
attr->fp_offset = 0;
set_irn_n(node, n_arm_FrameAddr_base, ptr);
......@@ -195,10 +149,7 @@ static void peephole_arm_Str_Ldr(ir_node *node)
{
arm_load_store_attr_t *attr = get_arm_load_store_attr(node);
const int offset = attr->offset;
int use_add = 1;
ir_node *ptr;
arm_vals v;
arm_vals v;
if (allowed_arm_immediate(offset, &v))
return;
......@@ -207,10 +158,9 @@ static void peephole_arm_Str_Ldr(ir_node *node)
fprintf(stderr,
"POSSIBLE ARM BACKEND PROBLEM: offset in Store too big\n");
}
if (offset < 0) {
use_add = 0;
}
bool use_add = offset >= 0;
ir_node *ptr;
if (is_arm_Str(node)) {
ptr = get_irn_n(node, n_arm_Str_ptr);
} else {
......
......@@ -13,32 +13,22 @@
#include "firm_types.h"
typedef struct arm_vals {
int ops;
unsigned char values[4];
unsigned char rors[4];
} arm_vals;
/**
* Encodes an immediate with shifter operand
* Performs Peephole Optimizations an a graph.
*
* @param irg the graph
*/
unsigned int arm_encode_imm_w_shift(unsigned int shift, unsigned int immediate);
void arm_peephole_optimization(ir_graph *irg);
/**
* Decode an immediate with shifter operand
*/
unsigned int arm_decode_imm_w_shift(long imm_value);
typedef struct arm_vals {
unsigned ops;
uint8_t values[4];
uint8_t rors[4];
} arm_vals;
/**
* construct 8bit values and rot amounts for a 32bit value.
*/
void arm_gen_vals_from_word(unsigned int value, arm_vals *result);
/**
* Performs Peephole Optimizations an a graph.
*
* @param irg the graph