Commit 63ee53cd authored by Matthias Braun's avatar Matthias Braun
Browse files

Cleanup

parent 027175a4
......@@ -614,19 +614,22 @@ static void emit_amd64_asm_operand(ir_node const *const node, char const modifie
panic("invalid asm operand");
case ASM_OP_IN_REG: {
arch_register_t const *const reg = arch_get_irn_register_in(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_in(node, op->inout_pos);
emit_amd64_asm_register(reg, modifier, op->u.mode);
return;
}
case ASM_OP_OUT_REG: {
arch_register_t const *const reg = arch_get_irn_register_out(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_out(node, op->inout_pos);
emit_amd64_asm_register(reg, modifier, op->u.mode);
return;
}
case ASM_OP_MEMORY: {
arch_register_t const *const reg = arch_get_irn_register_in(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_in(node, op->inout_pos);
be_emit_irprintf("(%%%s)", reg->name);
return;
}
......
......@@ -224,11 +224,17 @@ static lc_opt_enum_int_var_t opt_arch_var = {
(int*) &opt_arch, arch_items
};
typedef enum ia32_fpu_mode_t {
IA32_FPU_X87,
IA32_FPU_SSE2,
IA32_FPU_SOFTFLOAT,
} ia32_fpu_mode_t;
static const lc_opt_enum_int_items_t fp_unit_items[] = {
{ "387" , IA32_FPU_ARCH_X87 },
{ "sse", IA32_FPU_ARCH_SSE2 },
{ "softfloat", IA32_FPU_ARCH_SOFTFLOAT },
{ NULL, IA32_FPU_ARCH_NONE }
{ "387" , IA32_FPU_X87 },
{ "sse", IA32_FPU_SSE2 },
{ "softfloat", IA32_FPU_SOFTFLOAT },
{ NULL, IA32_FPU_X87 }
};
static lc_opt_enum_int_var_t fp_unit_var = {
......@@ -868,7 +874,7 @@ static bool flags(cpu_arch_features features, cpu_arch_features flags)
void ia32_setup_cg_config(void)
{
if (use_softfloat)
fpu_arch = IA32_FPU_ARCH_SOFTFLOAT;
fpu_arch = IA32_FPU_SOFTFLOAT;
#ifdef NATIVE_X86
if (arch == cpu_autodetect)
......@@ -888,8 +894,8 @@ void ia32_setup_cg_config(void)
/* P4s don't like inc/decs because they only partially write the flags
* register which produces false dependencies */
c->use_incdec = !flags(opt_arch, arch_netburst | arch_nocona | arch_core2 | arch_geode) || opt_size;
c->use_softfloat = (fpu_arch & IA32_FPU_ARCH_SOFTFLOAT) != 0;
c->use_sse2 = (fpu_arch & IA32_FPU_ARCH_SSE2) != 0 && flags(arch, arch_feature_sse2);
c->use_softfloat = (fpu_arch & IA32_FPU_SOFTFLOAT) != 0;
c->use_sse2 = (fpu_arch & IA32_FPU_SSE2) != 0 && flags(arch, arch_feature_sse2);
c->use_ffreep = flags(opt_arch, arch_athlon_plus);
c->use_femms = flags(opt_arch, arch_athlon_plus) && flags(arch, arch_feature_3DNow);
c->use_fucomi = flags(arch, arch_feature_p6_insn);
......
......@@ -11,80 +11,84 @@
#ifndef FIRM_BE_IA32_ARCHITECTURE_H
#define FIRM_BE_IA32_ARCHITECTURE_H
#include <stdbool.h>
#include "firm_types.h"
#include "irarch_t.h"
typedef struct {
/** optimize for size */
unsigned optimize_size:1;
bool optimize_size:1;
/** use leave in function epilogue */
unsigned use_leave:1;
bool use_leave:1;
/** use inc, dec instead of add $1, reg and add $-1, reg */
unsigned use_incdec:1;
bool use_incdec:1;
/** use soft float library */
unsigned use_softfloat:1;
bool use_softfloat:1;
/** use sse2 instructions (instead of x87) */
unsigned use_sse2:1;
bool use_sse2:1;
/** use ffreep instead of fpop */
unsigned use_ffreep:1;
bool use_ffreep:1;
/** use femms to pop all float registers */
unsigned use_femms:1;
bool use_femms:1;
/** use emms to pop all float registers */
unsigned use_emms:1;
bool use_emms:1;
/** use the fucomi instruction */
unsigned use_fucomi:1;
bool use_fucomi:1;
/** use cmovXX instructions */
unsigned use_cmov:1;
bool use_cmov:1;
/** mode_D moves instead of 2 integer moves */
unsigned use_modeD_moves:1;
bool use_modeD_moves:1;
/** use add esp, 4 instead of pop */
unsigned use_add_esp_4:1;
bool use_add_esp_4:1;
/** use add esp, 8 instead of 2 pops */
unsigned use_add_esp_8:1;
bool use_add_esp_8:1;
/** use sub esp, 4 instead of push */
unsigned use_sub_esp_4:1;
bool use_sub_esp_4:1;
/** use sub esp, 8 instead of 2 pushs */
unsigned use_sub_esp_8:1;
bool use_sub_esp_8:1;
/** use imul mem, imm32 instruction (slow on some CPUs) */
unsigned use_imul_mem_imm32:1;
bool use_imul_mem_imm32:1;
/** use pxor instead xorps/xorpd */
unsigned use_pxor:1;
bool use_pxor:1;
/** use mov reg, 0 instruction */
unsigned use_mov_0:1;
bool use_mov_0:1;
/** use cwtl/cltd, which are shorter, to sign extend ax/eax */
unsigned use_short_sex_eax:1;
/** pad Ret instructions that are destination of conditional jump or directly preceded
by other jump instruction. */
unsigned use_pad_return:1;
bool use_short_sex_eax:1;
/** pad Ret instructions that are destination of conditional jump or
* directly preceded by other jump instruction. */
bool use_pad_return:1;
/** use the bt instruction */
unsigned use_bt:1;
bool use_bt:1;
/** use fisttp instruction (requires SSE3) */
unsigned use_fisttp:1;
bool use_fisttp:1;
/** use SSE prefetch instructions */
unsigned use_sse_prefetch:1;
bool use_sse_prefetch:1;
/** use 3DNow! prefetch instructions */
unsigned use_3dnow_prefetch:1;
bool use_3dnow_prefetch:1;
/** use SSE4.2 or SSE4a popcnt instruction */
unsigned use_popcnt:1;
bool use_popcnt:1;
/** use i486 instructions */
unsigned use_bswap:1;
bool use_bswap:1;
/** use cmpxchg */
unsigned use_cmpxchg:1;
bool use_cmpxchg:1;
/** optimize calling convention where possible */
unsigned optimize_cc:1;
bool optimize_cc:1;
/**
* disrespect current floating point rounding mode at entry and exit of
* functions (this is ok for programs that don't explicitly change the
* rounding mode
*/
unsigned use_unsafe_floatconv:1;
bool use_unsafe_floatconv:1;
/** emit machine code instead of assembler */
unsigned emit_machcode:1;
bool emit_machcode:1;
/** function alignment (a power of two in bytes) */
unsigned function_alignment;
/** alignment for labels (which are expected to be frequent jump targets) */
unsigned label_alignment;
/** maximum skip alignment for labels (which are expected to be frequent jump targets) */
/** maximum skip alignment for labels (which are expected to be frequent
* jump targets) */
unsigned label_alignment_max_skip;
/** if a blocks execfreq is factor higher than its predecessor then align
* the blocks label (0 switches off label alignment) */
......@@ -93,15 +97,7 @@ typedef struct {
unsigned po2_stack_alignment;
} ia32_code_gen_config_t;
extern ia32_code_gen_config_t ia32_cg_config;
typedef enum ia32_fp_architectures {
IA32_FPU_ARCH_NONE = 0,
IA32_FPU_ARCH_X87 = 0x00000001,
IA32_FPU_ARCH_SSE2 = 0x00000002,
IA32_FPU_ARCH_SOFTFLOAT = 0x00000004,
}
ia32_fp_architectures;
extern ia32_code_gen_config_t ia32_cg_config;
/** Initialize the ia32 architecture module. */
void ia32_init_architecture(void);
......
......@@ -24,8 +24,6 @@
#include "ia32_architecture.h"
#include "ia32_emitter.h"
#include "ia32_encode.h"
#include "ia32_finish.h"
#include "ia32_fpu.h"
#include "ia32_new_nodes.h"
#include "ia32_optimize.h"
#include "ia32_transform.h"
......
......@@ -111,4 +111,15 @@ int ia32_get_sp_change(ir_node *node);
void ia32_cconv_init(void);
/**
* Handle switching of fpu mode
*/
void ia32_setup_fpu_mode(ir_graph *irg);
/**
* Check 2-Addresscode constraints and call peephole optimizations.
* @param irg The irg to finish
*/
void ia32_finish_irg(ir_graph *irg);
#endif
......@@ -901,19 +901,22 @@ static void emit_ia32_asm_operand(ir_node const *const node, char const modifier
panic("invalid asm operand");
case ASM_OP_IN_REG: {
arch_register_t const *const reg = arch_get_irn_register_in(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_in(node, op->inout_pos);
emit_ia32_asm_register(reg, modifier, op->u.mode);
return;
}
case ASM_OP_OUT_REG: {
arch_register_t const *const reg = arch_get_irn_register_out(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_out(node, op->inout_pos);
emit_ia32_asm_register(reg, modifier, op->u.mode);
return;
}
case ASM_OP_MEMORY: {
arch_register_t const *const reg = arch_get_irn_register_in(node, op->inout_pos);
arch_register_t const *const reg
= arch_get_irn_register_in(node, op->inout_pos);
be_emit_irprintf("(%%%s)", reg->name);
return;
}
......@@ -977,7 +980,7 @@ static void emit_ia32_CopyB_i(const ir_node *node)
* Emit code for conversions (I, FP), (FP, I) and (FP, FP).
*/
static void emit_ia32_Conv_with_FP(const ir_node *node, const char* conv_f,
const char* conv_d)
const char* conv_d)
{
ir_mode *ls_mode = get_ia32_ls_mode(node);
int ls_bits = get_mode_size_bits(ls_mode);
......
......@@ -8,8 +8,6 @@
* @brief This file implements functions to finalize the irg for emit.
* @author Christian Wuerdig
*/
#include "ia32_finish.h"
#include "be2addr.h"
#include "bearch.h"
#include "besched.h"
......@@ -157,7 +155,8 @@ carry:;
return true;
}
static bool ia32_transform_ShlD_to_ShrD_imm(ir_node *const irn, arch_register_t const *const out_reg)
static bool ia32_transform_ShlD_to_ShrD_imm(ir_node *const irn,
arch_register_t const *const out_reg)
{
ir_node *const in1 = get_irn_n(irn, n_ia32_ShlD_val_low);
if (arch_get_irn_register(in1) != out_reg)
......@@ -178,22 +177,6 @@ static bool ia32_transform_ShlD_to_ShrD_imm(ir_node *const irn, arch_register_t
return true;
}
static inline int need_constraint_copy(ir_node *irn)
{
/* TODO this should be determined from the node specification */
if (is_ia32_irn(irn)) {
switch (get_ia32_irn_opcode(irn)) {
case iro_ia32_Lea:
case iro_ia32_Minus64:
return 0;
default:
return 1;
}
}
return be_is_Asm(irn);
}
/**
* Following Problem:
* We have a source address mode node with base or index register equal to
......@@ -220,7 +203,7 @@ static bool ia32_handle_2addr(ir_node *const node, arch_register_req_t const *co
{
/* Some nodes are just a bit less efficient, but need no fixing if the
* should_be_same requirement is not fulfilled. */
if (!need_constraint_copy(node))
if (is_ia32_Lea(node) || is_ia32_Minus64(node))
return true;
fix_am_source(node, reg);
if (req->should_be_same == (1U << n_ia32_binary_left | 1U << n_ia32_binary_right)) {
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief This file implements functions to finalize the irg for emit.
* @author Christian Wuerdig
*/
#ifndef FIRM_BE_IA32_IA32_FINISH_H
#define FIRM_BE_IA32_IA32_FINISH_H
#include "firm_types.h"
/**
* Check 2-Addresscode constraints and call peephole optimizations.
* @param irg The irg to finish
*/
void ia32_finish_irg(ir_graph *irg);
#endif
......@@ -13,8 +13,6 @@
* to int conversion which are specified as truncation in the C standard we have
* to spill, change and restore the fpu rounding mode between spills.
*/
#include "ia32_fpu.h"
#include "ia32_bearch_t.h"
#include "ia32_new_nodes.h"
#include "ia32_architecture.h"
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Handles fpu rounding modes
* @author Matthias Braun
*/
#ifndef FIRM_BE_IA32_IA32_FPU_H
#define FIRM_BE_IA32_IA32_FPU_H
#include "firm_types.h"
/**
* Handle switching of fpu mode
*/
void ia32_setup_fpu_mode(ir_graph *irg);
#endif
......@@ -140,7 +140,8 @@ void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
fprintf(F, "%s", get_irn_opname(n));
if (is_ia32_Immediate(n) || is_ia32_Const(n)) {
ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(n);
ia32_immediate_attr_t const *const attr
= get_ia32_immediate_attr_const(n);
fputc(' ', F);
ia32_dump_immediate(F, attr->imm.entity, attr->imm.offset);
} else {
......@@ -216,17 +217,21 @@ void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
fprintf(F, "condition_code = <invalid (0x%X)>\n",
(unsigned)get_ia32_condcode(n));
}
fprintf(F, "ins_permuted = %s\n", be_dump_yesno(attr->ins_permuted));
fprintf(F, "ins_permuted = %s\n",
be_dump_yesno(attr->ins_permuted));
} else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
} else if (has_ia32_x87_attr(n)) {
ia32_x87_attr_t const *const attr = get_ia32_x87_attr_const(n);
fprintf(F, "explicit operand = %s\n", be_dump_reg_name(attr->x87.reg));
fprintf(F, "result to explicit operand = %s\n", be_dump_yesno(attr->x87.res_in_reg));
fprintf(F, "explicit operand = %s\n",
be_dump_reg_name(attr->x87.reg));
fprintf(F, "result to explicit operand = %s\n",
be_dump_yesno(attr->x87.res_in_reg));
fprintf(F, "pop = %s\n", be_dump_yesno(attr->x87.pop));
}
fprintf(F, "commutative = %s\n", be_dump_yesno(is_ia32_commutative(n)));
fprintf(F, "commutative = %s\n",
be_dump_yesno(is_ia32_commutative(n)));
fprintf(F, "is reload = %s\n", be_dump_yesno(is_ia32_is_reload(n)));
fprintf(F, "latency = %u\n", get_ia32_latency(n));
......@@ -255,8 +260,7 @@ void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
/* dump original ir node name */
char const *orig = get_ia32_attr_const(n)->orig_node;
fprintf(F, "orig node = %s\n", orig ? orig : "n/a");
#endif /* NDEBUG */
#endif
break;
}
}
......@@ -529,7 +533,6 @@ void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
}
#ifndef NDEBUG
static const char *ia32_get_old_node_name(const ir_node *irn)
{
ir_graph *irg = get_irn_irg(irn);
......@@ -546,8 +549,7 @@ void set_ia32_orig_node(ir_node *node, const ir_node *old)
ia32_attr_t *attr = get_ia32_attr(node);
attr->orig_node = name;
}
#endif /* NDEBUG */
#endif
void ia32_swap_left_right(ir_node *node)
{
......@@ -575,8 +577,8 @@ void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
void init_ia32_x87_attributes(ir_node *res)
{
#ifndef NDEBUG
ia32_attr_t *attr = get_ia32_attr(res);
attr->attr_type |= IA32_ATTR_ia32_x87_attr_t;
ia32_attr_t *attr = get_ia32_attr(res);
attr->attr_type |= IA32_ATTR_ia32_x87_attr_t;
#endif
ir_graph *const irg = get_irn_irg(res);
ia32_request_x87_sim(irg);
......@@ -587,7 +589,7 @@ void init_ia32_immediate_attributes(ir_node *res, x86_imm32_t const *const imm)
ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
#endif
attr->imm = *imm;
}
......@@ -597,7 +599,7 @@ void init_ia32_call_attributes(ir_node* res, unsigned pop, ir_type* call_tp)
ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_call_attr_t;
attr->attr.attr_type |= IA32_ATTR_ia32_call_attr_t;
#endif
attr->pop = pop;
attr->call_tp = call_tp;
......@@ -608,7 +610,7 @@ void init_ia32_copyb_attributes(ir_node *res, unsigned size)
ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t;
attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t;
#endif
attr->size = size;
}
......@@ -618,7 +620,7 @@ void init_ia32_condcode_attributes(ir_node *res, x86_condition_code_t cc)
ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
#ifndef NDEBUG
attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t;
attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t;
#endif
attr->condition_code = cc;
}
......@@ -698,7 +700,6 @@ int ia32_copyb_attrs_equal(const ir_node *a, const ir_node *b)
unsigned ia32_hash_Immediate(const ir_node *irn)
{
const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
return hash_ptr(a->imm.entity) + (unsigned)a->imm.offset;
}
......
......@@ -25,9 +25,9 @@ typedef enum ia32_op_type_t {
} ia32_op_type_t;
typedef enum ia32_am_type_t {
ia32_am_none = 0,
ia32_am_unary = 1,
ia32_am_binary = 2
ia32_am_none,
ia32_am_unary,
ia32_am_binary
} ia32_am_type_t;
typedef enum match_flags_t {
......@@ -66,16 +66,16 @@ struct ia32_op_attr_t {
#ifndef NDEBUG
typedef enum ia32_attr_type_t {
IA32_ATTR_INVALID = 0,
IA32_ATTR_ia32_attr_t = 1 << 0,
IA32_ATTR_ia32_x87_attr_t = 1 << 1,
IA32_ATTR_ia32_asm_attr_t = 1 << 2,
IA32_ATTR_ia32_immediate_attr_t = 1 << 3,
IA32_ATTR_ia32_condcode_attr_t = 1 << 4,
IA32_ATTR_ia32_copyb_attr_t = 1 << 5,
IA32_ATTR_ia32_call_attr_t = 1 << 6,
IA32_ATTR_ia32_switch_attr_t = 1 << 7,
IA32_ATTR_ia32_return_attr_t = 1 << 8,
IA32_ATTR_INVALID = 0,
IA32_ATTR_ia32_attr_t = 1 << 0,
IA32_ATTR_ia32_x87_attr_t = 1 << 1,
IA32_ATTR_ia32_asm_attr_t = 1 << 2,
IA32_ATTR_ia32_immediate_attr_t = 1 << 3,
IA32_ATTR_ia32_condcode_attr_t = 1 << 4,
IA32_ATTR_ia32_copyb_attr_t = 1 << 5,
IA32_ATTR_ia32_call_attr_t = 1 << 6,
IA32_ATTR_ia32_switch_attr_t = 1 << 7,
IA32_ATTR_ia32_return_attr_t = 1 << 8,
} ia32_attr_type_t;
#endif
......@@ -125,9 +125,9 @@ struct ia32_attr_t {
*/
typedef struct ia32_call_attr_t ia32_call_attr_t;
struct ia32_call_attr_t {
ia32_attr_t attr; /**< generic attribute */
unsigned pop; /**< number of bytes that get popped by the callee */
ir_type *call_tp; /**< The call type, copied from the original Call node. */
ia32_attr_t attr; /**< generic attribute */
unsigned pop; /**< number of bytes that get popped by the callee */
ir_type *call_tp; /**< The call type, copied from the original Call node. */
};
/**
......@@ -154,8 +154,8 @@ struct ia32_switch_attr_t {
*/
typedef struct ia32_copyb_attr_t ia32_copyb_attr_t;
struct ia32_copyb_attr_t {
ia32_attr_t attr; /**< generic attribute */
unsigned size; /**< size of copied block */
ia32_attr_t attr; /**< generic attribute */
unsigned size; /**< size of copied block */
};
/**
......@@ -163,8 +163,8 @@ struct ia32_copyb_attr_t {
*/
typedef struct ia32_immediate_attr_t ia32_immediate_attr_t;
struct ia32_immediate_attr_t {
ia32_attr_t attr; /**< generic attribute */
x86_imm32_t imm;
ia32_attr_t attr; /**< generic attribute */
x86_imm32_t imm;
};
/**
......@@ -186,14 +186,14 @@ struct ia32_return_attr_t {
/* the following union is necessary to indicate to the compiler that we might want to cast
* the structs (we use them to simulate OO-inheritance) */
union allow_casts_attr_t_ {
ia32_attr_t attr;
ia32_call_attr_t call_attr;
ia32_condcode_attr_t cc_attr;
ia32_copyb_attr_t cpy_attr;
ia32_x87_attr_t x87_attr;
ia32_immediate_attr_t immediate_attr;
ia32_switch_attr_t switch_attr;
ia32_return_attr_t return_attr;
ia32_attr_t attr;
ia32_call_attr_t call_attr;
ia32_condcode_attr_t cc_attr;
ia32_copyb_attr_t cpy_attr;
ia32_x87_attr_t x87_attr;
ia32_immediate_attr_t immediate_attr;
ia32_switch_attr_t switch_attr;
ia32_return_attr_t return_attr;
};
#ifndef NDEBUG
......
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