#include "ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
#include "gen_ia32_machine.h"
#include "ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
#include "gen_ia32_machine.h"
#include "ia32_transform.h"
#include "ia32_emitter.h"
#include "ia32_map_regs.h"
#include "ia32_transform.h"
#include "ia32_emitter.h"
#include "ia32_map_regs.h"
if (env->flags.try_omit_fp) {
/* simply remove the stack frame here */
curr_sp = be_new_IncSP(arch_env->sp, irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
if (env->flags.try_omit_fp) {
/* simply remove the stack frame here */
curr_sp = be_new_IncSP(arch_env->sp, irg, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
- if(is_ia32_use_frame(irn) ||
- (is_ia32_NoReg_GP(get_irn_n(irn, 0)) &&
- is_ia32_NoReg_GP(get_irn_n(irn, 1)))) {
+ if (is_ia32_use_frame(irn) || (
+ is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_base)) &&
+ is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_index))
+ )) {
ia32_code_gen_t *cg = ia32_current_cg;
assert(ia32_possible_memory_operand(irn, i) && "Cannot perform memory operand change");
ia32_code_gen_t *cg = ia32_current_cg;
assert(ia32_possible_memory_operand(irn, i) && "Cannot perform memory operand change");
- set_ia32_ls_mode(irn, get_irn_mode(get_irn_n(irn, i)));
+
+ load_mode = get_irn_mode(get_irn_n(irn, i));
+ dest_op_mode = get_ia32_ls_mode(irn);
+ if (get_mode_size_bits(load_mode) <= get_mode_size_bits(dest_op_mode)) {
+ set_ia32_ls_mode(irn, load_mode);
+ }
set_ia32_use_frame(irn);
set_ia32_need_stackent(irn);
set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn)));
set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(cg, irn, n_ia32_binary_right));
set_irn_n(irn, n_ia32_mem, spill);
set_ia32_use_frame(irn);
set_ia32_need_stackent(irn);
set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn)));
set_irn_n(irn, n_ia32_binary_right, ia32_get_admissible_noreg(cg, irn, n_ia32_binary_right));
set_irn_n(irn, n_ia32_mem, spill);
/* immediates are only allowed on the right side */
if (i == n_ia32_binary_left && is_ia32_Immediate(get_irn_n(irn, n_ia32_binary_left))) {
/* immediates are only allowed on the right side */
if (i == n_ia32_binary_left && is_ia32_Immediate(get_irn_n(irn, n_ia32_binary_left))) {
-#ifdef FIRM_GRGEN_BE
- // disable CSE, because of two-step node-construction
- set_opt_cse(0);
+ switch (be_transformer) {
+ case TRANSFORMER_DEFAULT:
+ /* transform remaining nodes into assembler instructions */
+ ia32_transform_graph(cg);
+ break;
if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
const ir_mode *mode = get_ia32_ls_mode(node);
const ia32_attr_t *attr = get_ia32_attr_const(node);
if (is_ia32_need_stackent(node) || is_ia32_Load(node)) {
const ir_mode *mode = get_ia32_ls_mode(node);
const ia32_attr_t *attr = get_ia32_attr_const(node);
be_node_needs_frame_entity(env, node, mode, align);
} else if (is_ia32_vfild(node) || is_ia32_xLoad(node)
|| is_ia32_vfld(node)) {
be_node_needs_frame_entity(env, node, mode, align);
} else if (is_ia32_vfild(node) || is_ia32_xLoad(node)
|| is_ia32_vfld(node)) {
call_flags.bits.store_args_sequential = 0;
/* call_flags.bits.try_omit_fp not changed: can handle both settings */
call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
call_flags.bits.store_args_sequential = 0;
/* call_flags.bits.try_omit_fp not changed: can handle both settings */
call_flags.bits.fp_free = 0; /* the frame pointer is fixed in IA32 */
/* set parameter passing style */
be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
/* set parameter passing style */
be_abi_call_set_flags(abi, call_flags, &ia32_abi_callbacks);
- if (get_method_additional_properties(method_type) & mtp_property_private
- && (ia32_cg_config.optimize_cc)) {
+ if (get_method_additional_properties(method_type) & mtp_property_private &&
+ ia32_cg_config.optimize_cc) {
/* we have to pop the shadow parameter ourself for compound calls */
if( (get_method_calling_convention(method_type) & cc_compound_ret)
&& !(cc & cc_reg_param)) {
/* we have to pop the shadow parameter ourself for compound calls */
if( (get_method_calling_convention(method_type) & cc_compound_ret)
&& !(cc & cc_reg_param)) {
/* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes.
* movl has a shorter opcode than mov[sz][bw]l */
ir_mode *load_mode = mode;
/* Micro optimisation: if the mode is shorter than 4 bytes, load 4 bytes.
* movl has a shorter opcode than mov[sz][bw]l */
ir_mode *load_mode = mode;
- if (mode != NULL && get_mode_size_bytes(mode) < 4) load_mode = mode_Iu;
+
+ if (mode != NULL) {
+ unsigned size = get_mode_size_bytes(mode);
+
+ if (cc & cc_callee_clear_stk) {
+ pop_amount += (size + 3U) & ~3U;
+ }
+
+ if (size < 4) load_mode = mode_Iu;
+ }
+
be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0);
}
}
be_abi_call_param_stack(abi, i, load_mode, 4, 0, 0);
}
}
+static const lc_opt_enum_int_items_t transformer_items[] = {
+ { "default", TRANSFORMER_DEFAULT },
+#ifdef FIRM_GRGEN_BE
+ { "pbqp", TRANSFORMER_PBQP },
+#endif
+ { NULL, 0 }
+};
+
+static lc_opt_enum_int_var_t transformer_var = {
+ (int*)&be_transformer, transformer_items
+};
+
static const lc_opt_table_entry_t ia32_options[] = {
LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
static const lc_opt_table_entry_t ia32_options[] = {
LC_OPT_ENT_ENUM_INT("gasmode", "set the GAS compatibility mode", &gas_var),
LC_OPT_ENT_INT("stackalign", "set power of two stack alignment for calls",
&ia32_isa_template.arch_env.stack_alignment),
LC_OPT_LAST
LC_OPT_ENT_INT("stackalign", "set power of two stack alignment for calls",
&ia32_isa_template.arch_env.stack_alignment),
LC_OPT_LAST