Commit 5624adba authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Add and use register set helper functions for calling conventions.

parent 3287d11c
......@@ -13,6 +13,7 @@
* - MSDN - "x64 Software Conventions"
*/
#include "be_t.h"
#include "becconv.h"
#include "beirg.h"
#include "irmode_t.h"
#include "irgwalk.h"
......@@ -207,15 +208,10 @@ x86_cconv_t *amd64_decide_calling_convention(ir_type *function_type,
cconv->n_reg_results = n_reg_results;
if (irg != NULL) {
be_irg_t *birg = be_birg_from_irg(irg);
size_t n_ignores = ARRAY_SIZE(ignore_regs);
struct obstack *obst = &birg->obst;
be_irg_t *birg = be_birg_from_irg(irg);
birg->allocatable_regs = rbitset_obstack_alloc(obst, N_AMD64_REGISTERS);
rbitset_set_all(birg->allocatable_regs, N_AMD64_REGISTERS);
for (size_t r = 0; r < n_ignores; ++r) {
rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
}
birg->allocatable_regs = be_cconv_alloc_all_regs(&birg->obst, N_AMD64_REGISTERS);
be_cconv_rem_regs(birg->allocatable_regs, ignore_regs, ARRAY_SIZE(ignore_regs));
if (!omit_fp)
rbitset_clear(birg->allocatable_regs, REG_RBP);
}
......@@ -258,13 +254,11 @@ void amd64_cconv_init(void)
REG_ST6,
REG_ST7,
};
for (size_t i = 0; i < ARRAY_SIZE(common_caller_saves); ++i) {
rbitset_set(default_caller_saves, common_caller_saves[i]);
}
if (!amd64_use_x64_abi) {
rbitset_set(default_caller_saves, REG_RSI);
rbitset_set(default_caller_saves, REG_RDI);
}
static unsigned const x64_callee_saves[] = { REG_RSI, REG_RDI };
be_cconv_add_regs(default_caller_saves, common_caller_saves, ARRAY_SIZE(common_caller_saves));
if (!amd64_use_x64_abi)
be_cconv_add_regs(default_caller_saves, x64_callee_saves, ARRAY_SIZE(x64_callee_saves));
static const unsigned common_callee_saves[] = {
REG_RBX,
......@@ -274,13 +268,9 @@ void amd64_cconv_init(void)
REG_R14,
REG_R15,
};
for (size_t i = 0; i < ARRAY_SIZE(common_callee_saves); ++i) {
rbitset_set(default_callee_saves, common_callee_saves[i]);
}
if (amd64_use_x64_abi) {
rbitset_set(default_callee_saves, REG_RSI);
rbitset_set(default_callee_saves, REG_RDI);
}
be_cconv_add_regs(default_callee_saves, common_callee_saves, ARRAY_SIZE(common_callee_saves));
if (amd64_use_x64_abi)
be_cconv_add_regs(default_callee_saves, x64_callee_saves, ARRAY_SIZE(x64_callee_saves));
static const arch_register_t* const param_regs_list[] = {
&amd64_registers[REG_RDI],
......
......@@ -9,6 +9,7 @@
* @author Matthias Braun
*/
#include "arm_cconv.h"
#include "becconv.h"
#include "beirg.h"
#include "irmode_t.h"
#include "typerep.h"
......@@ -141,16 +142,11 @@ calling_convention_t *arm_decide_calling_convention(const ir_graph *irg,
/* setup allocatable registers */
if (irg != NULL) {
be_irg_t *birg = be_birg_from_irg(irg);
size_t n_ignores = ARRAY_SIZE(ignore_regs);
struct obstack *obst = &birg->obst;
be_irg_t *birg = be_birg_from_irg(irg);
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 (size_t r = 0; r < n_ignores; ++r) {
rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
}
birg->allocatable_regs = be_cconv_alloc_all_regs(&birg->obst, N_ARM_REGISTERS);
be_cconv_rem_regs(birg->allocatable_regs, ignore_regs, ARRAY_SIZE(ignore_regs));
}
return cconv;
......
/*
* This file is part of libFirm.
* Copyright (C) 2016 University of Karlsruhe.
*/
/**
* @file
* @brief Helper functions for calling conventions
*/
#ifndef FIRM_BE_BECCONV_H
#define FIRM_BE_BECCONV_H
#include "obstack.h"
#include "raw_bitset.h"
static inline unsigned *be_cconv_alloc_all_regs(struct obstack *const obst, size_t const n)
{
unsigned *const res = rbitset_obstack_alloc(obst, n);
rbitset_set_all(res, n);
return res;
}
static inline void be_cconv_add_regs(unsigned *const dst, unsigned const *const regs, size_t const n)
{
for (size_t i = 0; i != n; ++i) {
rbitset_set(dst, regs[i]);
}
}
static inline void be_cconv_rem_regs(unsigned *const dst, unsigned const *const regs, size_t const n)
{
for (size_t i = 0; i != n; ++i) {
rbitset_clear(dst, regs[i]);
}
}
#endif
......@@ -10,6 +10,7 @@
*/
#include "be_t.h"
#include "bearch_ia32_t.h"
#include "becconv.h"
#include "beirg.h"
#include "x86_cconv.h"
#include "irmode_t.h"
......@@ -218,15 +219,10 @@ align_stack:;
cconv->n_reg_results = n_reg_results;
if (irg != NULL) {
be_irg_t *birg = be_birg_from_irg(irg);
size_t n_ignores = ARRAY_SIZE(ignore_regs);
struct obstack *obst = &birg->obst;
birg->allocatable_regs = rbitset_obstack_alloc(obst, N_IA32_REGISTERS);
rbitset_set_all(birg->allocatable_regs, N_IA32_REGISTERS);
for (size_t r = 0; r < n_ignores; ++r) {
rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
}
be_irg_t *birg = be_birg_from_irg(irg);
birg->allocatable_regs = be_cconv_alloc_all_regs(&birg->obst, N_IA32_REGISTERS);
be_cconv_rem_regs(birg->allocatable_regs, ignore_regs, ARRAY_SIZE(ignore_regs));
if (!omit_fp)
rbitset_clear(birg->allocatable_regs, REG_EBP);
}
......@@ -236,10 +232,6 @@ align_stack:;
void ia32_cconv_init(void)
{
for (size_t i = 0; i < ARRAY_SIZE(caller_saves); ++i) {
rbitset_set(default_caller_saves, caller_saves[i]);
}
for (size_t i = 0; i < ARRAY_SIZE(callee_saves); ++i) {
rbitset_set(default_callee_saves, callee_saves[i]);
}
be_cconv_add_regs(default_caller_saves, caller_saves, ARRAY_SIZE(caller_saves));
be_cconv_add_regs(default_callee_saves, callee_saves, ARRAY_SIZE(callee_saves));
}
......@@ -9,6 +9,7 @@
* @author Matthias Braun
*/
#include "be_t.h"
#include "becconv.h"
#include "beirg.h"
#include "sparc_cconv.h"
#include "irmode_t.h"
......@@ -325,16 +326,10 @@ calling_convention_t *sparc_decide_calling_convention(ir_type *function_type,
/* setup ignore register array */
if (irg != NULL) {
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;
birg->allocatable_regs = rbitset_obstack_alloc(obst, N_SPARC_REGISTERS);
rbitset_set_all(birg->allocatable_regs, N_SPARC_REGISTERS);
for (r = 0; r < n_ignores; ++r) {
rbitset_clear(birg->allocatable_regs, ignore_regs[r]);
}
be_irg_t *birg = be_birg_from_irg(irg);
birg->allocatable_regs = be_cconv_alloc_all_regs(&birg->obst, N_SPARC_REGISTERS);
be_cconv_rem_regs(birg->allocatable_regs, ignore_regs, ARRAY_SIZE(ignore_regs));
}
return cconv;
......@@ -350,17 +345,11 @@ void sparc_free_calling_convention(calling_convention_t *cconv)
void sparc_cconv_init(void)
{
for (size_t i = 0; i < ARRAY_SIZE(caller_saves); ++i) {
rbitset_set(default_caller_saves, caller_saves[i]);
}
be_cconv_add_regs(default_caller_saves, caller_saves, ARRAY_SIZE(caller_saves));
rbitset_set_all(default_returns_twice_saves, N_SPARC_REGISTERS);
for (size_t i = 0; i < ARRAY_SIZE(returns_twice_saved); ++i) {
rbitset_clear(default_returns_twice_saves, returns_twice_saved[i]);
}
for (size_t i = 0; i < ARRAY_SIZE(ignore_regs); ++i) {
rbitset_clear(default_returns_twice_saves, ignore_regs[i]);
}
be_cconv_rem_regs(default_returns_twice_saves, returns_twice_saved, ARRAY_SIZE(returns_twice_saved));
be_cconv_rem_regs(default_returns_twice_saves, ignore_regs, ARRAY_SIZE(ignore_regs));
for (size_t i = 0; i < ARRAY_SIZE(float_result_reqs_double); i += 2) {
arch_register_req_t *req = &float_result_reqs_double[i];
......
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