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

merge ia32_cconv_t and amd64_cconv_t to x86_cconv_t

parent 6402e483
......@@ -10,7 +10,6 @@
*/
#include "be_t.h"
#include "beirg.h"
#include "amd64_cconv.h"
#include "irmode.h"
#include "irgwalk.h"
#include "typerep.h"
......@@ -19,6 +18,8 @@
#include "panic.h"
#include "gen_amd64_regalloc_if.h"
#include "bitfiddle.h"
#include "bearch_amd64_t.h"
#include "../ia32/x86_cconv.h"
static const unsigned ignore_regs[] = {
REG_RSP,
......@@ -96,8 +97,8 @@ static void check_omit_fp(ir_node *node, void *env)
}
}
amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
ir_graph *irg)
x86_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
ir_graph *irg)
{
bool omit_fp = false;
if (irg != NULL) {
......@@ -196,7 +197,7 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
}
}
amd64_cconv_t *cconv = XMALLOCZ(amd64_cconv_t);
x86_cconv_t *cconv = XMALLOCZ(x86_cconv_t);
cconv->parameters = params;
cconv->param_stack_size = stack_offset;
cconv->n_param_regs = n_param_regs_used;
......@@ -224,15 +225,6 @@ amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
return cconv;
}
void amd64_free_calling_convention(amd64_cconv_t *cconv)
{
free(cconv->parameters);
free(cconv->results);
free(cconv->caller_saves);
free(cconv->callee_saves);
free(cconv);
}
void amd64_cconv_init(void)
{
for (size_t i = 0; i < ARRAY_SIZE(caller_saves); ++i) {
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief support functions for calling conventions
* @author Matthias Braun
*/
#ifndef FIRM_BE_AMD64_AMD64_CCONV_H
#define FIRM_BE_AMD64_AMD64_CCONV_H
#include "firm_types.h"
#include "bearch_amd64_t.h"
#include "be_types.h"
#include "benode.h"
#include "gen_amd64_regalloc_if.h"
/** information about a single parameter or result */
typedef struct reg_or_stackslot_t
{
const arch_register_req_t *req; /**< if != NULL, register requirements
for this parameter (or the first
part of it). */
const arch_register_t *reg;
unsigned reg_offset;
ir_type *type; /**< indicates that an entity of the specific
type is needed */
unsigned offset; /**< if transmitted via stack, the offset for
this parameter. */
ir_entity *entity; /**< entity in frame type */
} reg_or_stackslot_t;
/** The calling convention info for one call site. */
typedef struct amd64_cconv_t
{
bool omit_fp; /**< do not use frame pointer (and no
save/restore) */
reg_or_stackslot_t *parameters; /**< parameter info. */
unsigned param_stack_size; /**< stack size for parameters */
unsigned n_param_regs; /**< number of values passed in a
register (gp + xmm) */
unsigned n_xmm_regs; /**< number of xmm registers used */
reg_or_stackslot_t *results; /**< result info. */
unsigned n_reg_results;
unsigned *caller_saves; /**< bitset of caller saved registers */
unsigned *callee_saves; /**< bitset of callee saved registers */
} amd64_cconv_t;
/**
* Determine how function parameters and return values are passed.
* Decides what goes to register or to stack and what stack offsets/
* datatypes are used.
*
* @param function_type the type of the caller/callee function
* @param caller true for convention for the caller, false for callee
*/
amd64_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
ir_graph *irg);
/**
* free memory used by a amd64_cconv_t
*/
void amd64_free_calling_convention(amd64_cconv_t *cconv);
void amd64_cconv_init(void);
#endif
......@@ -26,11 +26,11 @@
#include "beirg.h"
#include "besched.h"
#include "amd64_cconv.h"
#include "amd64_new_nodes.h"
#include "amd64_nodes_attr.h"
#include "amd64_transform.h"
#include "../ia32/x86_address_mode.h"
#include "../ia32/x86_cconv.h"
#include "gen_amd64_regalloc_if.h"
......@@ -38,7 +38,7 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
static ir_mode *mode_gp;
static ir_mode *mode_flags;
static amd64_cconv_t *current_cconv = NULL;
static x86_cconv_t *current_cconv = NULL;
static be_start_info_t start_mem;
static be_start_info_t start_val[N_AMD64_REGISTERS];
static size_t start_params_offset;
......@@ -1382,7 +1382,7 @@ static ir_node *gen_Start(ir_node *node)
dbg_info *dbgi = get_irn_dbg_info(node);
struct obstack *obst = be_get_be_obst(irg);
amd64_cconv_t const *const cconv = current_cconv;
x86_cconv_t const *const cconv = current_cconv;
/* start building list of start constraints */
......@@ -1478,7 +1478,7 @@ static ir_node *gen_Return(ir_node *node)
ir_node *sp = get_stack_pointer_for(node);
size_t n_res = get_Return_n_ress(node);
struct obstack *be_obst = be_get_be_obst(irg);
amd64_cconv_t *cconv = current_cconv;
x86_cconv_t *cconv = current_cconv;
/* estimate number of return values */
size_t n_ins = 2 + n_res; /* memory + stackpointer, return values */
......@@ -1540,7 +1540,7 @@ static ir_node *gen_Call(ir_node *node)
ir_node **sync_ins = ALLOCAN(ir_node*, n_params+1);
ir_graph *irg = get_irn_irg(node);
struct obstack *obst = be_get_be_obst(irg);
amd64_cconv_t *cconv
x86_cconv_t *cconv
= amd64_decide_calling_convention(type, NULL);
size_t n_param_regs = cconv->n_param_regs;
/* param-regs + mem + stackpointer + callee(2) + n_sse_regs */
......@@ -1767,7 +1767,7 @@ static ir_node *gen_Call(ir_node *node)
pmap_insert(node_to_stack, node, incsp);
amd64_free_calling_convention(cconv);
x86_free_calling_convention(cconv);
return call;
}
......@@ -1789,11 +1789,11 @@ static ir_node *gen_Proj_Call(ir_node *node)
static ir_node *gen_Proj_Proj_Call(ir_node *node)
{
unsigned pn = get_Proj_num(node);
ir_node *call = get_Proj_pred(get_Proj_pred(node));
ir_node *new_call = be_transform_node(call);
ir_type *tp = get_Call_type(call);
amd64_cconv_t *cconv = amd64_decide_calling_convention(tp, NULL);
unsigned pn = get_Proj_num(node);
ir_node *call = get_Proj_pred(get_Proj_pred(node));
ir_node *new_call = be_transform_node(call);
ir_type *tp = get_Call_type(call);
x86_cconv_t *cconv = amd64_decide_calling_convention(tp, NULL);
const reg_or_stackslot_t *res = &cconv->results[pn];
ir_mode *mode = get_irn_mode(node);
unsigned new_pn = pn_amd64_Call_first_res+res->reg_offset;
......@@ -1803,7 +1803,7 @@ static ir_node *gen_Proj_Proj_Call(ir_node *node)
mode = mode_gp;
else if (mode_is_float(mode))
mode = mode_D;
amd64_free_calling_convention(cconv);
x86_free_calling_convention(cconv);
return new_r_Proj(new_call, mode, new_pn);
}
......@@ -2578,14 +2578,13 @@ static ir_type *amd64_get_between_type(bool omit_fp)
return omit_fp ? omit_fp_between_type : between_type;
}
static void amd64_create_stacklayout(ir_graph *irg, amd64_cconv_t *cconv)
static void amd64_create_stacklayout(ir_graph *irg, const x86_cconv_t *cconv)
{
ir_entity *entity = get_irg_entity(irg);
ir_type *function_type = get_entity_type(entity);
be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
/* construct argument type */
assert(cconv != NULL);
ident *const arg_id = id_mangle3("", get_entity_ident(entity), "_arg_type");
ir_type *const arg_type = new_type_struct(arg_id);
size_t const n_params = get_method_n_params(function_type);
......@@ -2644,7 +2643,7 @@ void amd64_transform_graph(ir_graph *irg)
heights = NULL;
be_free_stackorder(stackorder);
amd64_free_calling_convention(current_cconv);
x86_free_calling_convention(current_cconv);
pmap_destroy(node_to_stack);
node_to_stack = NULL;
......
......@@ -42,7 +42,6 @@
#include "gen_amd64_regalloc_if.h"
#include "amd64_transform.h"
#include "amd64_emitter.h"
#include "amd64_cconv.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
......
......@@ -11,6 +11,7 @@
#define FIRM_BE_AMD64_BEARCH_AMD64_T_H
#include "bearch.h"
#include "../ia32/x86_cconv.h"
typedef struct amd64_isa_t amd64_isa_t;
......@@ -23,4 +24,17 @@ struct amd64_isa_t {
/** power of two stack alignment on calls */
#define AMD64_PO2_STACK_ALIGNMENT 4
/**
* Determine how function parameters and return values are passed.
* Decides what goes to register or to stack and what stack offsets/
* datatypes are used.
*
* @param function_type the type of the caller/callee function
* @param caller true for convention for the caller, false for callee
*/
x86_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
ir_graph *irg);
void amd64_cconv_init(void);
#endif
......@@ -58,7 +58,6 @@
#include "gen_ia32_regalloc_if.h"
#include "ia32_architecture.h"
#include "ia32_cconv.h"
#include "ia32_common_transform.h"
#include "ia32_emitter.h"
#include "ia32_finish.h"
......
......@@ -14,6 +14,7 @@
#include "bearch.h"
#include "beirg.h"
#include "pmap.h"
#include "x86_cconv.h"
#ifdef NDEBUG
#define SET_IA32_ORIG_NODE(n, o) ((void)(n), (void)(o), (void)0)
......@@ -120,4 +121,17 @@ static inline bool ia32_is_8bit_val(int32_t const v)
return -128 <= v && v < 128;
}
/**
* Determine how function parameters and return values are passed.
* Decides what goes to register or to stack and what stack offsets/
* datatypes are used.
*
* @param function_type the type of the caller/callee function
* @param caller true for convention for the caller, false for callee
*/
x86_cconv_t *ia32_decide_calling_convention(ir_type *function_type,
ir_graph *irg);
void ia32_cconv_init(void);
#endif
......@@ -9,8 +9,9 @@
* @author Matthias Braun
*/
#include "be_t.h"
#include "bearch_ia32_t.h"
#include "beirg.h"
#include "ia32_cconv.h"
#include "x86_cconv.h"
#include "irmode.h"
#include "irgwalk.h"
#include "typerep.h"
......@@ -110,8 +111,8 @@ static void check_omit_fp(ir_node *node, void *env)
}
}
ia32_cconv_t *ia32_decide_calling_convention(ir_type *function_type,
ir_graph *irg)
x86_cconv_t *ia32_decide_calling_convention(ir_type *function_type,
ir_graph *irg)
{
bool omit_fp = false;
if (irg != NULL) {
......@@ -217,7 +218,7 @@ align_stack:;
calling_convention cc = get_method_calling_convention(function_type);
ia32_cconv_t *cconv = XMALLOCZ(ia32_cconv_t);
x86_cconv_t *cconv = XMALLOCZ(x86_cconv_t);
cconv->sp_delta = (cc & cc_compound_ret) && !(cc & cc_reg_param)
? IA32_REGISTER_SIZE : 0;
cconv->parameters = params;
......@@ -247,15 +248,6 @@ align_stack:;
return cconv;
}
void ia32_free_calling_convention(ia32_cconv_t *cconv)
{
free(cconv->parameters);
free(cconv->results);
free(cconv->caller_saves);
free(cconv->callee_saves);
free(cconv);
}
void ia32_cconv_init(void)
{
for (size_t i = 0; i < ARRAY_SIZE(caller_saves); ++i) {
......
......@@ -41,7 +41,6 @@
#include "bearch_ia32_t.h"
#include "gen_ia32_regalloc_if.h"
#include "ia32_architecture.h"
#include "ia32_cconv.h"
#include "ia32_common_transform.h"
#include "ia32_new_nodes.h"
#include "ia32_nodes_attr.h"
......@@ -49,6 +48,7 @@
#include "ia32_transform.h"
#include "util.h"
#include "x86_address_mode.h"
#include "x86_cconv.h"
/* define this to construct SSE constants instead of load them */
#undef CONSTRUCT_SSE_CONST
......@@ -58,7 +58,7 @@
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
static ia32_cconv_t *current_cconv;
static x86_cconv_t *current_cconv;
static be_start_info_t start_mem;
static be_start_info_t start_val[N_IA32_REGISTERS];
static unsigned start_params_offset;
......@@ -4170,7 +4170,7 @@ static ir_node *gen_Start(ir_node *node)
dbg_info *dbgi = get_irn_dbg_info(node);
struct obstack *obst = be_get_be_obst(irg);
ia32_cconv_t const *const cconv = current_cconv;
x86_cconv_t const *const cconv = current_cconv;
/* start building list of start constraints */
......@@ -4285,8 +4285,8 @@ static ir_node *gen_Return(ir_node *node)
ir_node *new_mem = be_transform_node(mem);
ir_node *sp = get_stack_pointer_for(node);
unsigned n_res = get_Return_n_ress(node);
struct obstack *obst = be_get_be_obst(irg);
ia32_cconv_t *cconv = current_cconv;
struct obstack *obst = be_get_be_obst(irg);
x86_cconv_t *cconv = current_cconv;
/* estimate number of return values */
unsigned n_ins = 2 + n_res; /* memory + stackpointer, return values */
......@@ -4917,7 +4917,7 @@ static ir_node *gen_Call(ir_node *node)
/* max inputs: memory, callee, register arguments */
ir_graph *irg = get_irn_irg(node);
struct obstack *obst = be_get_be_obst(irg);
ia32_cconv_t *cconv
x86_cconv_t *cconv
= ia32_decide_calling_convention(type, NULL);
unsigned n_param_regs = cconv->n_param_regs;
/* base,index,mem,callee,esp,fpcw + regparams*/
......@@ -5107,7 +5107,7 @@ static ir_node *gen_Call(ir_node *node)
}
pmap_insert(node_to_stack, node, new_stack);
ia32_free_calling_convention(cconv);
x86_free_calling_convention(cconv);
ia32_no_pic_adjust = old_no_pic_adjust;
return res;
......@@ -5131,11 +5131,11 @@ static ir_node *gen_Proj_Call(ir_node *node)
static ir_node *gen_Proj_Proj_Call(ir_node *node)
{
unsigned pn = get_Proj_num(node);
ir_node *call = get_Proj_pred(get_Proj_pred(node));
ir_node *new_call = be_transform_node(call);
ir_type *tp = get_Call_type(call);
ia32_cconv_t *cconv = ia32_decide_calling_convention(tp, NULL);
unsigned pn = get_Proj_num(node);
ir_node *call = get_Proj_pred(get_Proj_pred(node));
ir_node *new_call = be_transform_node(call);
ir_type *tp = get_Call_type(call);
x86_cconv_t *cconv = ia32_decide_calling_convention(tp, NULL);
const reg_or_stackslot_t *res = &cconv->results[pn];
ir_mode *mode = get_irn_mode(node);
unsigned new_pn = pn_ia32_Call_first_result + res->reg_offset;
......@@ -5145,7 +5145,7 @@ static ir_node *gen_Proj_Proj_Call(ir_node *node)
mode = ia32_mode_gp;
else if (mode_is_float(mode))
mode = ia32_mode_E;
ia32_free_calling_convention(cconv);
x86_free_calling_convention(cconv);
return new_r_Proj(new_call, mode, new_pn);
}
......@@ -5831,7 +5831,7 @@ static void register_transformers(void)
be_set_upper_bits_clean_function(op_Mux, ia32_mux_upper_bits_clean);
}
static void add_parameter_loads(ir_graph *irg, const ia32_cconv_t *cconv)
static void add_parameter_loads(ir_graph *irg, const x86_cconv_t *cconv)
{
ir_node *start = get_irg_start(irg);
ir_node *start_block = get_irg_start_block(irg);
......@@ -5876,14 +5876,13 @@ static ir_type *ia32_get_between_type(bool omit_fp)
return omit_fp ? omit_fp_between_type : between_type;
}
static void ia32_create_stacklayout(ir_graph *irg, ia32_cconv_t *cconv)
static void ia32_create_stacklayout(ir_graph *irg, const x86_cconv_t *cconv)
{
ir_entity *entity = get_irg_entity(irg);
ir_type *function_type = get_entity_type(entity);
be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
/* construct argument type */
assert(cconv != NULL);
ident *arg_id = id_mangle3("", get_entity_ident(entity), "_arg_type");
ir_type *arg_type = new_type_struct(arg_id);
ir_type *frame_type = get_irg_frame_type(irg);
......@@ -5994,7 +5993,7 @@ void ia32_transform_graph(ir_graph *irg)
heights_free(ia32_heights);
ia32_heights = NULL;
be_free_stackorder(stackorder);
ia32_free_calling_convention(current_cconv);
x86_free_calling_convention(current_cconv);
pmap_destroy(node_to_stack);
node_to_stack = NULL;
}
......
/*
* This file is part of libFirm.
* Copyright (C) 2014 University of Karlsruhe.
*/
/**
* @file
* @brief calling convention helpers
* @author Matthias Braun
*/
#include <stdlib.h>
#include "x86_cconv.h"
void x86_free_calling_convention(x86_cconv_t *cconv)
{
free(cconv->parameters);
free(cconv->results);
free(cconv->caller_saves);
free(cconv->callee_saves);
free(cconv);
}
......@@ -8,32 +8,29 @@
* @brief support functions for calling conventions
* @author Matthias Braun
*/
#ifndef FIRM_BE_IA32_IA32_CCONV_H
#define FIRM_BE_IA32_IA32_CCONV_H
#ifndef FIRM_BE_IA32_X86_CCONV_H
#define FIRM_BE_IA32_X86_CCONV_H
#include "firm_types.h"
#include "bearch_ia32_t.h"
#include "be_types.h"
#include "benode.h"
#include "gen_ia32_regalloc_if.h"
/** information about a single parameter or result */
/** Information about a single function parameter or result */
typedef struct reg_or_stackslot_t
{
const arch_register_req_t *req; /**< if != NULL, register requirements
for this parameter (or the first
part of it). */
const arch_register_t *reg;
unsigned reg_offset;
ir_type *type; /**< indicates that an entity of the specific
type is needed */
unsigned offset; /**< if transmitted via stack, the offset for
this parameter. */
ir_entity *entity; /**< entity in frame type */
/** Register requirement or NULL if no register should be used. */
const arch_register_req_t *req;
const arch_register_t *reg;
unsigned reg_offset;
ir_type *type; /**< indicates that an entity of the
specific type is needed */
unsigned offset; /**< if transmitted via stack, the offset
for this parameter. */
ir_entity *entity; /**< entity in frame type */
} reg_or_stackslot_t;
/** The calling convention info for one call site. */
typedef struct ia32_cconv_t
typedef struct x86_cconv_t
{
bool omit_fp; /**< do not use frame pointer (and no
save/restore) */
......@@ -45,26 +42,13 @@ typedef struct ia32_cconv_t
unsigned n_xmm_regs; /**< number of xmm registers used */
reg_or_stackslot_t *results; /**< result info. */
unsigned n_reg_results;
unsigned *caller_saves; /**< bitset of caller saved registers */
unsigned *callee_saves; /**< bitset of callee saved registers */
} ia32_cconv_t;
unsigned *caller_saves; /**< bitset: caller saved registers */
unsigned *callee_saves; /**< bitset: callee saved registers */
} x86_cconv_t;
/**
* Determine how function parameters and return values are passed.
* Decides what goes to register or to stack and what stack offsets/
* datatypes are used.
*
* @param function_type the type of the caller/callee function
* @param caller true for convention for the caller, false for callee
* free memory used by a x86_cconv_t
*/
ia32_cconv_t *ia32_decide_calling_convention(ir_type *function_type,
ir_graph *irg);
/**
* free memory used by a ia32_cconv_t
*/
void ia32_free_calling_convention(ia32_cconv_t *cconv);
void ia32_cconv_init(void);
void x86_free_calling_convention(x86_cconv_t *cconv);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment