Commit 2b3e33ed authored by Matthias Braun's avatar Matthias Braun
Browse files

some cleanups in arm+sparc backends

[r27753]
parent c5ed920d
......@@ -323,7 +323,6 @@ static void arm_emit_and_done(void *self)
arm_gen_routine(cg, irg);
/* de-allocate code generator */
del_set(cg->reg_set);
free(self);
}
......@@ -347,24 +346,14 @@ static const arch_code_generator_if_t arm_code_gen_if = {
*/
static void *arm_cg_init(ir_graph *irg)
{
static ir_type *int_tp = NULL;
arm_isa_t *isa = (arm_isa_t *) be_get_irg_arch_env(irg);
arm_isa_t *isa = (arm_isa_t*) be_get_irg_arch_env(irg);
arm_code_gen_t *cg;
if (! int_tp) {
/* create an integer type with machine size */
int_tp = new_type_primitive(mode_Is);
}
cg = XMALLOC(arm_code_gen_t);
cg->impl = &arm_code_gen_if;
cg->irg = irg;
cg->reg_set = new_set(arm_cmp_irn_reg_assoc, 1024);
cg->isa = isa;
cg->int_tp = int_tp;
cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
FIRM_DBG_REGISTER(cg->mod, "firm.be.arm.cg");
cg = XMALLOCZ(arm_code_gen_t);
cg->impl = &arm_code_gen_if;
cg->irg = irg;
cg->isa = isa;
cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
/* enter the current code generator */
isa->cg = cg;
......@@ -388,8 +377,8 @@ static void arm_handle_intrinsics(void)
#define ID(x) new_id_from_chars(x, sizeof(x)-1)
int_tp = new_type_primitive(mode_Is);
uint_tp = new_type_primitive(mode_Iu);
int_tp = get_type_for_mode(mode_Is);
uint_tp = get_type_for_mode(mode_Iu);
/* ARM has neither a signed div instruction ... */
{
......@@ -501,7 +490,7 @@ static void arm_handle_intrinsics(void)
lower_intrinsics(records, n_records, /*part_block_used=*/0);
}
const arch_isa_if_t arm_isa_if;
static arm_isa_t arm_isa_template = {
{
&arm_isa_if, /* isa interface */
......@@ -515,7 +504,6 @@ static arm_isa_t arm_isa_template = {
5, /* reload costs */
true, /* we do have custom abi handling */
},
0, /* use generic register names instead of SP, LR, PC */
ARM_FPU_ARCH_FPE, /* FPU architecture */
NULL, /* current code generator */
};
......@@ -757,7 +745,6 @@ static lc_opt_enum_int_var_t arch_fpu_var = {
static const lc_opt_table_entry_t arm_options[] = {
LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &arch_fpu_var),
LC_OPT_ENT_BOOL("gen_reg_names", "use generic register names", &arm_isa_template.gen_reg_names),
LC_OPT_LAST
};
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief declarations for arm backend
* @author Oliver Richter, Tobias Gneist
* @version $Id$
*/
#ifndef FIRM_BE_ARM_BEARCH_ARM_H
#define FIRM_BE_ARM_BEARCH_ARM_H
#include "../bearch.h"
extern const arch_isa_if_t arm_isa_if;
#endif
......@@ -28,12 +28,8 @@
#include <stdio.h>
#include "debug.h"
#include "bearch_arm.h"
#include "arm_nodes_attr.h"
#include "be.h"
#include "../beemitter.h"
#include "set.h"
typedef struct _arm_isa_t arm_isa_t;
......@@ -139,17 +135,13 @@ enum arm_processor_types {
typedef struct _arm_code_gen_t {
const arch_code_generator_if_t *impl; /**< implementation */
ir_graph *irg; /**< current irg */
set *reg_set; /**< set to memorize registers for FIRM nodes (e.g. phi) */
arm_isa_t *isa; /**< the isa instance */
ir_type *int_tp; /**< the int type, needed for Call conversion */
char dump; /**< set to 1 if graphs should be dumped */
DEBUG_ONLY(firm_dbg_module_t *mod;) /**< debugging module */
char dump; /**< set to 1 if graphs should be dumped */
} arm_code_gen_t;
struct _arm_isa_t {
arch_env_t base; /**< must be derived from arch_env_t */
int gen_reg_names; /**< use generic register names instead of SP, LR, PC */
int fpu_arch; /**< FPU architecture */
arm_code_gen_t *cg; /**< current code generator */
};
......
......@@ -59,7 +59,6 @@ typedef struct ia32_intrinsic_env_t ia32_intrinsic_env_t;
struct ia32_code_gen_t {
const arch_code_generator_if_t *impl; /**< implementation */
ir_graph *irg; /**< current irg */
set *reg_set; /**< set to memorize registers for non-ia32 nodes (e.g. phi nodes) */
ia32_isa_t *isa; /**< for fast access to the isa object */
ir_node **blk_sched; /**< an array containing the scheduled blocks */
unsigned do_x87_sim:1; /**< set to 1 if x87 simulation should be enforced */
......
......@@ -160,6 +160,7 @@ print OUT<<EOF;
#include "irnode.h"
#include "irop_t.h"
#include "irprog_t.h"
#include "../beemitter.h"
#include "gen_${arch}_emitter.h"
#include "${arch}_new_nodes.h"
......
......@@ -22,7 +22,6 @@
* @brief The main sparc backend driver file.
* @version $Id$
*/
#include "config.h"
#include "lc_opts.h"
......@@ -60,13 +59,16 @@
#include "../beflags.h"
#include "bearch_sparc_t.h"
#include "bearch_sparc.h"
#include "sparc_new_nodes.h"
#include "gen_sparc_regalloc_if.h"
#include "sparc_transform.h"
#include "sparc_emitter.h"
#include "sparc_map_regs.h"
// sparc ABI requires a min stacksize to
// save registers in case of a trap etc.
// by now we assume only non-leaf procedures: 92 + 4 (padding)
#define SPARC_MIN_STACKSIZE 112
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
......@@ -276,10 +278,10 @@ static void *sparc_cg_init(ir_graph *irg);
static const arch_code_generator_if_t sparc_code_gen_if = {
sparc_cg_init,
NULL, /* get_pic_base hook */
NULL, /* before abi introduce hook */
NULL, /* get_pic_base hook */
NULL, /* before abi introduce hook */
sparc_prepare_graph,
NULL, /* spill hook */
NULL, /* spill hook */
sparc_before_ra, /* before register allocation hook */
sparc_after_ra, /* after register allocation hook */
NULL,
......@@ -291,38 +293,24 @@ static const arch_code_generator_if_t sparc_code_gen_if = {
*/
static void *sparc_cg_init(ir_graph *irg)
{
static ir_type *int_tp = NULL;
sparc_isa_t *isa = (sparc_isa_t *) be_get_irg_arch_env(irg);
sparc_code_gen_t *cg;
sparc_code_gen_t *cg = XMALLOCZ(sparc_code_gen_t);
if (! int_tp) {
/* create an integer type with machine size */
int_tp = new_type_primitive(mode_Is);
}
cg = XMALLOC(sparc_code_gen_t);
cg->impl = &sparc_code_gen_if;
cg->irg = irg;
//cg->reg_set = new_set(arm_cmp_irn_reg_assoc, 1024);
cg->isa = isa;
//cg->int_tp = int_tp;
//cg->have_fp_insn = 0;
//cg->unknown_gp = NULL;
//cg->unknown_fpa = NULL;
cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) ? 1 : 0;
cg->impl = &sparc_code_gen_if;
cg->irg = irg;
cg->isa = isa;
cg->dump = (be_get_irg_options(irg)->dump_flags & DUMP_BE) != 0;
/* enter the current code generator */
isa->cg = cg;
return (arch_code_generator_t *)cg;
return (arch_code_generator_t*) cg;
}
const arch_isa_if_t sparc_isa_if;
static sparc_isa_t sparc_isa_template = {
{
&sparc_isa_if, /* isa interface implementation */
&sparc_isa_if, /* isa interface implementation */
&sparc_gp_regs[REG_SP], /* stack pointer register */
&sparc_gp_regs[REG_FP], /* base pointer register */
&sparc_reg_classes[CLASS_sparc_gp], /* link pointer register class */
......@@ -516,7 +504,7 @@ static ir_type *sparc_get_between_type(void *self)
* Build the prolog, return the BASE POINTER register
*/
static const arch_register_t *sparc_abi_prologue(void *self, ir_node **mem,
pmap *reg_map, int *stack_bias)
pmap *reg_map, int *stack_bias)
{
sparc_abi_env_t *env = self;
ir_node *block = get_irg_start_block(env->irg);
......@@ -551,7 +539,7 @@ static const arch_register_t *sparc_abi_prologue(void *self, ir_node **mem,
/* Build the epilog */
static void sparc_abi_epilogue(void *self, ir_node *bl, ir_node **mem,
pmap *reg_map)
pmap *reg_map)
{
(void) self;
(void) bl;
......@@ -567,6 +555,42 @@ static const be_abi_callbacks_t sparc_abi_callbacks = {
sparc_abi_epilogue,
};
static const arch_register_t *gp_param_out_regs[] = {
&sparc_gp_regs[REG_O0],
&sparc_gp_regs[REG_O1],
&sparc_gp_regs[REG_O2],
&sparc_gp_regs[REG_O3],
&sparc_gp_regs[REG_O4],
&sparc_gp_regs[REG_O5],
};
static const arch_register_t *gp_param_in_regs[] = {
&sparc_gp_regs[REG_I0],
&sparc_gp_regs[REG_I1],
&sparc_gp_regs[REG_I2],
&sparc_gp_regs[REG_I3],
&sparc_gp_regs[REG_I4],
&sparc_gp_regs[REG_I5],
};
/**
* get register for outgoing parameters 1-6
*/
static const arch_register_t *sparc_get_RegParamOut_reg(int n)
{
assert(n < 6 && n >=0 && "trying to get (out) register for param >= 6");
return gp_param_out_regs[n];
}
/**
* get register for incoming parameters 1-6
*/
static const arch_register_t *sparc_get_RegParamIn_reg(int n)
{
assert(n < 6 && n >=0 && "trying to get (in) register for param >= 6");
return gp_param_in_regs[n];
}
/**
* Get the ABI restrictions for procedure calls.
* @param self The this pointer.
......@@ -585,7 +609,6 @@ static void sparc_get_call_abi(const void *self, ir_type *method_type,
/* set abi flags for calls */
call_flags.bits.left_to_right = 0;
call_flags.bits.store_args_sequential = 1;
/* */
call_flags.bits.try_omit_fp = 0;
call_flags.bits.fp_free = 0;
call_flags.bits.call_has_imm = 1;
......@@ -711,7 +734,7 @@ static const be_machine_t *sparc_get_machine(const void *self)
}
static ir_graph **sparc_get_backend_irg_list(const void *self,
ir_graph ***irgs)
ir_graph ***irgs)
{
(void) self;
(void) irgs;
......@@ -742,7 +765,7 @@ const arch_isa_if_t sparc_isa_if = {
sparc_get_list_sched_selector,
sparc_get_ilp_sched_selector,
sparc_get_reg_class_alignment,
sparc_get_backend_params,
sparc_get_backend_params,
sparc_get_allowed_execution_units,
sparc_get_machine,
sparc_get_backend_irg_list,
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief declarations for arm backend
* @author Hannes Rapp
* @version $Id$
*/
#ifndef FIRM_BE_SPARC_BEARCH_SPARC_H
#define FIRM_BE_SPARC_BEARCH_SPARC_H
#include "../bearch.h"
extern const arch_isa_if_t sparc_isa_if;
#endif
......@@ -22,38 +22,29 @@
* @brief declarations for SPARC backend -- private header
* @version $Id$
*/
#ifndef FIRM_BE_SPARC_BEARCH_TEMPLATE_T_H
#define FIRM_BE_SPARC_BEARCH_TEMPLATE_T_H
#ifndef FIRM_BE_SPARC_BEARCH_SPARC_T_H
#define FIRM_BE_SPARC_BEARCH_SPARC_T_H
#include "debug.h"
#include <stdbool.h>
#include "sparc_nodes_attr.h"
#include "be.h"
#include "../beemitter.h"
#include "set.h"
// sparc ABI requires a min stacksize to
// save registers in case of a trap etc.
// by now we assume only non-leaf procedures: 92 + 4 (padding)
#define SPARC_MIN_STACKSIZE 112
typedef struct sparc_transform_env_t sparc_transform_env_t;
typedef struct _sparc_isa_t sparc_isa_t;
typedef struct _sparc_code_gen_t {
const arch_code_generator_if_t *impl; /**< implementation */
ir_graph *irg; /**< current irg */
set *reg_set; /**< set to memorize registers for FIRM nodes (e.g. phi) */
sparc_isa_t *isa; /**< the isa instance */
char dump; /**< set to 1 if graphs should be dumped */
typedef struct sparc_isa_t sparc_isa_t;
typedef struct sparc_code_gen_t {
const arch_code_generator_if_t *impl; /**< implementation */
ir_graph *irg; /**< current irg */
sparc_isa_t *isa; /**< the isa instance */
bool dump; /**< set to 1 if graphs should
be dumped */
} sparc_code_gen_t;
struct _sparc_isa_t {
arch_env_t base; /**< must be derived from arch_env_t */
sparc_code_gen_t *cg; /**< current code generator */
struct sparc_isa_t {
arch_env_t base; /**< must be derived from arch_env_t */
sparc_code_gen_t *cg; /**< current code generator */
};
/**
* this is a struct to minimize the number of parameters
* for transformation walker
......
......@@ -118,17 +118,6 @@ static const arch_register_t *get_out_reg(const ir_node *node, int pos)
return reg;
}
/*************************************************************
* _ _ __ _ _
* (_) | | / _| | | | |
* _ __ _ __ _ _ __ | |_| |_ | |__ ___| |_ __ ___ _ __
* | '_ \| '__| | '_ \| __| _| | '_ \ / _ \ | '_ \ / _ \ '__|
* | |_) | | | | | | | |_| | | | | | __/ | |_) | __/ |
* | .__/|_| |_|_| |_|\__|_| |_| |_|\___|_| .__/ \___|_|
* | | | |
* |_| |_|
*************************************************************/
void sparc_emit_immediate(const ir_node *node)
{
int const val = get_sparc_attr_const(node)->immediate_value;
......@@ -185,19 +174,19 @@ void sparc_emit_offset(const ir_node *node)
void sparc_emit_load_mode(const ir_node *node)
{
const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
bool is_signed = mode_is_signed(mode);
if (bits == 16) {
be_emit_string(is_signed ? "sh" : "uh");
} else if (bits == 8) {
be_emit_string(is_signed ? "sb" : "ub");
} else if (bits == 64) {
be_emit_string("d");
} else {
assert(bits == 32);
}
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
bool is_signed = mode_is_signed(mode);
if (bits == 16) {
be_emit_string(is_signed ? "sh" : "uh");
} else if (bits == 8) {
be_emit_string(is_signed ? "sb" : "ub");
} else if (bits == 64) {
be_emit_string("d");
} else {
assert(bits == 32);
}
}
/**
......@@ -206,18 +195,18 @@ void sparc_emit_load_mode(const ir_node *node)
void sparc_emit_store_mode(const ir_node *node)
{
const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
if (bits == 16) {
be_emit_string("h");
} else if (bits == 8) {
be_emit_string("b");
} else if (bits == 64) {
be_emit_string("d");
} else {
assert(bits == 32);
}
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
if (bits == 16) {
be_emit_string("h");
} else if (bits == 8) {
be_emit_string("b");
} else if (bits == 64) {
be_emit_string("d");
} else {
assert(bits == 32);
}
}
/**
......@@ -225,9 +214,9 @@ void sparc_emit_store_mode(const ir_node *node)
*/
void sparc_emit_mode_sign_prefix(const ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
bool is_signed = mode_is_signed(mode);
be_emit_string(is_signed ? "s" : "u");
ir_mode *mode = get_irn_mode(node);
bool is_signed = mode_is_signed(mode);
be_emit_string(is_signed ? "s" : "u");
}
/**
......@@ -236,18 +225,18 @@ void sparc_emit_mode_sign_prefix(const ir_node *node)
void sparc_emit_fp_load_mode(const ir_node *node)
{
const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
assert(mode_is_float(mode));
assert(mode_is_float(mode));
if (bits == 32) {
be_emit_string("f");
} else if (bits == 64) {
be_emit_string("df");
} else {
if (bits == 32) {
be_emit_string("f");
} else if (bits == 64) {
be_emit_string("df");
} else {
panic("FP load mode > 64bits not implemented yet");
}
}
}
/**
......@@ -256,18 +245,18 @@ void sparc_emit_fp_load_mode(const ir_node *node)
void sparc_emit_fp_store_mode(const ir_node *node)
{
const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
ir_mode *mode = attr->load_store_mode;
int bits = get_mode_size_bits(mode);
assert(mode_is_float(mode));
assert(mode_is_float(mode));
if (bits == 32) {
be_emit_string("f");
} else if (bits == 64) {
be_emit_string("df");
} else {
if (bits == 32) {
be_emit_string("f");
} else if (bits == 64) {
be_emit_string("df");
} else {
panic("FP store mode > 64bits not implemented yet");
}
}
}
/**
......@@ -275,18 +264,18 @@ void sparc_emit_fp_store_mode(const ir_node *node)
*/
void sparc_emit_fp_mode_suffix(const ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
int bits = get_mode_size_bits(mode);
ir_mode *mode = get_irn_mode(node);
int bits = get_mode_size_bits(mode);
assert(mode_is_float(mode));
assert(mode_is_float(mode));
if (bits == 32) {
if (bits == 32) {
be_emit_string("s");
} else if (bits == 64) {
} else if (bits == 64) {
be_emit_string("d");
} else {
} else {
panic("FP mode > 64bits not implemented yet");
}
}
}
/**
......@@ -306,17 +295,6 @@ static void sparc_emit_entity(ir_entity *entity)
be_gas_emit_entity(entity);
}
/***********************************************************************************
* _ __ _
* (_) / _| | |
* _ __ ___ __ _ _ _ __ | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
* | '_ ` _ \ / _` | | '_ \ | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
* | | | | | | (_| | | | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
* |_| |_| |_|\__,_|_|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
*
***********************************************************************************/
/**
* Emits code for stack space management
*/
......@@ -770,50 +748,35 @@ static inline void set_emitter(ir_op *op, emit_func sparc_emit_node)
*/
static void sparc_register_emitters(void)
{
/* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func();
/* register all emitter functions defined in spec */
sparc_register_spec_emitters();
/* custom emitter */
set_emitter(op_be_IncSP, emit_be_IncSP);
set_emitter(op_be_Return, emit_be_Return);
set_emitter(op_be_Call, emit_be_Call);
set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
set_emitter(op_sparc_Branch, emit_sparc_Branch);
set_emitter(op_sparc_SymConst, emit_sparc_SymConst);
set_emitter(op_sparc_Jmp, emit_sparc_Jmp);
set_emitter(op_sparc_Save, emit_sparc_Save);