BACKENDS=""
if test "$enable_backend" = yes; then
- BACKENDS="arm ia32 mips ppc32 sparc amd64"
+ BACKENDS="arm ia32 mips sparc amd64"
fi
AC_SUBST([BACKENDS])
be/mips/mips_spec.pl be/scripts/generate_machine.pl
$(PERL) $(srcdir)/be/scripts/generate_regalloc_if.pl $(srcdir)/be/mips/mips_spec.pl $(srcdir)/be/mips
-# ppc32 backend
-
-ppc32_sources = \
- be/ppc32/bearch_ppc32.c \
- be/ppc32/ppc32_emitter.c \
- be/ppc32/ppc32_map_regs.c \
- be/ppc32/ppc32_new_nodes.c \
- be/ppc32/ppc32_transform.c \
- be/ppc32/ppc32_transform_conv.c
-ppc32_built_sources = \
- be/ppc32/gen_ppc32_emitter.c \
- be/ppc32/gen_ppc32_emitter.h \
- be/ppc32/gen_ppc32_machine.c \
- be/ppc32/gen_ppc32_machine.h \
- be/ppc32/gen_ppc32_new_nodes.c.inl \
- be/ppc32/gen_ppc32_new_nodes.h \
- be/ppc32/gen_ppc32_regalloc_if.c \
- be/ppc32/gen_ppc32_regalloc_if.h
-MAINTAINERCLEANFILES += $(ppc32_built_sources)
-BUILT_SOURCES += $(ppc32_built_sources)
-libfirm_la_SOURCES += $(ppc32_sources) $(ppc32_built_sources)
-
-EXTRA_DIST += \
- be/ppc32/bearch_ppc32.h \
- be/ppc32/bearch_ppc32_t.h \
- be/ppc32/ppc32_emitter.h \
- be/ppc32/ppc32_map_regs.h \
- be/ppc32/ppc32_new_nodes.h \
- be/ppc32/ppc32_nodes_attr.h \
- be/ppc32/ppc32_spec.pl \
- be/ppc32/ppc32_transform.h \
- be/ppc32/ppc32_transform_conv.h
-
-$(srcdir)/be/ppc32/gen_ppc32_new_nodes.c.inl $(srcdir)/be/ppc32/gen_ppc32_new_nodes.h: \
- be/ppc32/ppc32_spec.pl be/scripts/generate_new_opcodes.pl
- $(PERL) $(srcdir)/be/scripts/generate_new_opcodes.pl $(srcdir)/be/ppc32/ppc32_spec.pl $(srcdir)/be/ppc32
-
-$(srcdir)/be/ppc32/gen_ppc32_emitter.c $(srcdir)/be/ppc32/gen_ppc32_emitter.h: \
- be/ppc32/ppc32_spec.pl be/scripts/generate_emitter.pl
- $(PERL) $(srcdir)/be/scripts/generate_emitter.pl $(srcdir)/be/ppc32/ppc32_spec.pl $(srcdir)/be/ppc32
-
-$(srcdir)/be/ppc32/gen_ppc32_machine.c $(srcdir)/be/ppc32/gen_ppc32_machine.h: \
- be/ppc32/ppc32_spec.pl be/scripts/generate_machine.pl
- $(PERL) $(srcdir)/be/scripts/generate_machine.pl $(srcdir)/be/ppc32/ppc32_spec.pl $(srcdir)/be/ppc32
-
-$(srcdir)/be/ppc32/gen_ppc32_regalloc_if.c $(srcdir)/be/ppc32/gen_ppc32_regalloc_if.h: \
- be/ppc32/ppc32_spec.pl be/scripts/generate_machine.pl
- $(PERL) $(srcdir)/be/scripts/generate_regalloc_if.pl $(srcdir)/be/ppc32/ppc32_spec.pl $(srcdir)/be/ppc32
-
# sparc backend
sparc_sources = \
void be_init_daemelspill(void);
void be_init_dbgout(void);
void be_init_arch_ia32(void);
-void be_init_arch_ppc32(void);
void be_init_arch_mips(void);
void be_init_arch_arm(void);
void be_init_arch_sparc(void);
be_init_stabs();
be_init_arch_ia32();
- be_init_arch_ppc32();
be_init_arch_mips();
be_init_arch_arm();
be_init_arch_sparc();
+++ /dev/null
-/*
- * 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 The main ppc backend driver file.
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include "pseudo_irg.h"
-#include "irgwalk.h"
-#include "irprog.h"
-#include "irprintf.h"
-#include "ircons.h"
-#include "irgmod.h"
-#include "irdump.h"
-
-#include "bitset.h"
-#include "debug.h"
-#include "error.h"
-
-#include "../bearch.h"
-#include "../benode.h"
-#include "../belower.h"
-#include "../besched.h"
-#include "be.h"
-#include "../beabi.h"
-#include "../bemachine.h"
-#include "../bemodule.h"
-#include "../bespillslots.h"
-#include "../beblocksched.h"
-#include "../beirg.h"
-#include "../begnuas.h"
-#include "../belistsched.h"
-
-#include "pset.h"
-
-#include "bearch_ppc32_t.h"
-
-#include "ppc32_new_nodes.h"
-#include "gen_ppc32_regalloc_if.h"
-#include "ppc32_transform.h"
-#include "ppc32_transform_conv.h"
-#include "ppc32_emitter.h"
-#include "ppc32_map_regs.h"
-
-#define DEBUG_MODULE "firm.be.ppc.isa"
-
-int isleaf;
-
-/**************************************************
- * _ _ _ __
- * | | | (_)/ _|
- * _ __ ___ __ _ __ _| | | ___ ___ _| |_
- * | '__/ _ \/ _` | / _` | | |/ _ \ / __| | | _|
- * | | | __/ (_| | | (_| | | | (_) | (__ | | |
- * |_| \___|\__, | \__,_|_|_|\___/ \___| |_|_|
- * __/ |
- * |___/
- **************************************************/
-
-static arch_irn_class_t ppc32_classify(const ir_node *irn)
-{
- (void) irn;
- return 0;
-}
-
-static ir_entity *ppc32_get_frame_entity(const ir_node *irn)
-{
- if (!is_ppc32_irn(irn)) return NULL;
- if (get_ppc32_type(irn)!=ppc32_ac_FrameEntity) return NULL;
- return get_ppc32_frame_entity(irn);
-}
-
-static void ppc32_set_frame_entity(ir_node *irn, ir_entity *ent)
-{
- if (! is_ppc32_irn(irn) || get_ppc32_type(irn) != ppc32_ac_FrameEntity)
- return;
- set_ppc32_frame_entity(irn, ent);
-}
-
-/**
- * This function is called by the generic backend to correct offsets for
- * nodes accessing the stack.
- */
-static void ppc32_set_stack_bias(ir_node *irn, int bias)
-{
- set_ppc32_offset(irn, bias);
-}
-
-static int ppc32_get_sp_bias(const ir_node *irn)
-{
- (void) irn;
- return 0;
-}
-
-typedef struct
-{
- const be_abi_call_t *call;
- ir_graph *irg;
-} ppc32_abi_env;
-
-/**
- * Initialize the callback object.
- * @param call The call object.
- * @param aenv The architecture environment.
- * @param irg The graph with the method.
- * @return Some pointer. This pointer is passed to all other callback functions as self object.
- */
-static void *ppc32_abi_init(const be_abi_call_t *call, const arch_env_t *aenv, ir_graph *irg)
-{
- ppc32_abi_env *env = XMALLOC(ppc32_abi_env);
- (void) aenv;
-
- env->call = call;
- env->irg = irg;
- return env;
-}
-
-/**
- * Destroy the callback object.
- * @param self The callback object.
- */
-static void ppc32_abi_done(void *self)
-{
- free(self);
-}
-
-/**
- * Get the between type for that call.
- * @param self The callback object.
- * @return The between type of for that call.
- */
-static ir_type *ppc32_abi_get_between_type(void *self)
-{
- static ir_type *between_type = NULL;
- static ir_entity *old_bp_ent = NULL;
- (void) self;
-
- if (!between_type) {
- ir_entity *ret_addr_ent;
- ir_type *ret_addr_type = new_type_primitive(mode_P);
- ir_type *old_bp_type = new_type_primitive(mode_P);
-
- between_type = new_type_class(new_id_from_str("ppc32_between_type"));
- old_bp_ent = new_entity(between_type, new_id_from_str("old_bp"), old_bp_type);
- ret_addr_ent = new_entity(between_type, new_id_from_str("old_bp"), ret_addr_type);
-
- set_entity_offset(old_bp_ent, 0);
- set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
- set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
- }
-
- return between_type;
-}
-
-/**
- * Generate the prologue.
- * @param self The callback object.
- * @param mem A pointer to the mem node. Update this if you define new memory.
- * @param reg_map A mapping mapping all callee_save/ignore/parameter registers to their defining nodes.
- * @param stack_bias Points to the current stack bias, can be modified if needed.
- *
- * @return The register which shall be used as a stack frame base.
- *
- * All nodes which define registers in @p reg_map must keep @p reg_map current.
- */
-static const arch_register_t *ppc32_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
-{
- ppc32_abi_env *env = (ppc32_abi_env *) self;
- be_abi_call_flags_t flags = be_abi_call_get_flags(env->call);
- (void) mem;
- (void) reg_map;
- (void) stack_bias;
- isleaf = flags.bits.irg_is_leaf;
-
- if (flags.bits.try_omit_fp)
- return &ppc32_gp_regs[REG_R1];
- else
- return &ppc32_gp_regs[REG_R31];
-}
-
-/**
- * Generate the epilogue.
- * @param self The callback object.
- * @param mem Memory one can attach to.
- * @param reg_map A mapping mapping all callee_save/ignore/return registers to their defining nodes.
- *
- * All nodes which define registers in @p reg_map must keep @p reg_map current.
- * Also, the @p mem variable must be updated, if memory producing nodes are inserted.
- */
-static void ppc32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
-{
- (void) self;
- (void) bl;
- (void) mem;
- (void) reg_map;
-}
-
-static const be_abi_callbacks_t ppc32_abi_callbacks = {
- ppc32_abi_init,
- ppc32_abi_done,
- ppc32_abi_get_between_type,
- ppc32_abi_prologue,
- ppc32_abi_epilogue,
-};
-
-/* fill register allocator interface */
-
-static const arch_irn_ops_t ppc32_irn_ops = {
- get_ppc32_in_req,
- ppc32_classify,
- ppc32_get_frame_entity,
- ppc32_set_frame_entity,
- ppc32_set_stack_bias,
- ppc32_get_sp_bias,
- NULL, /* get_inverse */
- NULL, /* get_op_estimated_cost */
- NULL, /* possible_memory_operand */
- NULL, /* perform_memory_operand */
-};
-
-/**************************************************
- * _ _ __
- * | | (_)/ _|
- * ___ ___ __| | ___ __ _ ___ _ __ _| |_
- * / __/ _ \ / _` |/ _ \/ _` |/ _ \ '_ \ | | _|
- * | (_| (_) | (_| | __/ (_| | __/ | | | | | |
- * \___\___/ \__,_|\___|\__, |\___|_| |_| |_|_|
- * __/ |
- * |___/
- **************************************************/
-
-static void ppc32_before_abi(void *self)
-{
- ppc32_code_gen_t *cg = self;
- ir_type *frame_type = get_irg_frame_type(cg->irg);
-
- frame_alloc_area(frame_type, 24, 4, 1);
-
- ppc32_init_conv_walk();
- irg_walk_blkwise_graph(cg->irg, NULL, ppc32_conv_walk, cg);
-
- if (cg->area_size) {
- if (cg->area_size < 32) cg->area_size = 32;
- cg->area = frame_alloc_area(get_irg_frame_type(cg->irg), cg->area_size+24, 16, 1);
- }
-}
-
-static void ppc32_search_start_successor(ir_node *block, void *env)
-{
- ppc32_code_gen_t *cg = env;
- int n = get_Block_n_cfgpreds(block);
- ir_node *startblock = get_irg_start_block(cg->irg);
- if (block == startblock) return;
-
- for (n--; n >= 0; n--) {
- ir_node *predblock = get_irn_n(get_Block_cfgpred(block, n), -1);
- if (predblock == startblock)
- {
- cg->start_succ_block = block;
- return;
- }
- }
-}
-
-/**
- * Transforms the standard firm graph into
- * a ppc firm graph
- */
-static void ppc32_prepare_graph(void *self)
-{
- ppc32_code_gen_t *cg = self;
-
- irg_block_walk_graph(cg->irg, NULL, ppc32_search_start_successor, cg);
- irg_walk_blkwise_graph(cg->irg, NULL, ppc32_pretransform_walk, cg);
- dump_ir_graph(cg->irg, "pretransformed");
-
- ppc32_register_transformers();
- irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_node, cg);
- dump_ir_graph(cg->irg, "transformed");
- irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_const, cg);
-}
-
-
-
-/**
- * Called immediatly before emit phase.
- */
-static void ppc32_finish_irg(void *self)
-{
- (void) self;
- /* TODO: - fix offsets for nodes accessing stack
- - ...
- */
-}
-
-
-/**
- * Called before the register allocator.
- * Calculate a block schedule here. We need it for the x87
- * simulator and the emitter.
- */
-static void ppc32_before_ra(void *self)
-{
- ppc32_code_gen_t *cg = self;
- cg->blk_sched = be_create_block_schedule(cg->irg);
-}
-
-static void ppc32_transform_spill(ir_node *node, void *env)
-{
- (void)env;
-
- if (be_is_Spill(node))
- {
- ir_node *store, *proj;
- dbg_info *dbg = get_irn_dbg_info(node);
- ir_node *block = get_nodes_block(node);
-
- const arch_register_class_t *regclass = arch_get_irn_reg_class(node, 1);
-
- if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp])
- {
- store = new_bd_ppc32_Stw(dbg, block,
- get_irn_n(node, 0), get_irn_n(node, 1), new_NoMem());
- }
- else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp])
- {
- store = new_bd_ppc32_Stfd(dbg, block,
- get_irn_n(node, 0), get_irn_n(node, 1), new_NoMem());
- }
- else panic("Spill for register class not supported yet!");
-
- set_ppc32_frame_entity(store, be_get_frame_entity(node));
-
- proj = new_rd_Proj(dbg, store, mode_M, pn_Store_M);
-
- if (sched_is_scheduled(node)) {
- sched_add_after(sched_prev(node), store);
- sched_add_after(store, proj);
-
- sched_remove(node);
- }
-
- exchange(node, proj);
- }
-
- if (be_is_Reload(node))
- {
- ir_node *load, *proj;
- const arch_register_t *reg;
- dbg_info *dbg = get_irn_dbg_info(node);
- ir_node *block = get_nodes_block(node);
- ir_mode *mode = get_irn_mode(node);
-
- const arch_register_class_t *regclass = arch_get_irn_reg_class_out(node);
-
- if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp])
- {
- load = new_bd_ppc32_Lwz(dbg, block, get_irn_n(node, 0), get_irn_n(node, 1));
- }
- else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp])
- {
- load = new_bd_ppc32_Lfd(dbg, block, get_irn_n(node, 0), get_irn_n(node, 1));
- }
- else panic("Reload for register class not supported yet!");
-
- set_ppc32_frame_entity(load, be_get_frame_entity(node));
-
- proj = new_rd_Proj(dbg, load, mode, pn_Load_res);
-
- if (sched_is_scheduled(node)) {
- sched_add_after(sched_prev(node), load);
- sched_add_after(load, proj);
-
- sched_remove(node);
- }
-
- /* copy the register from the old node to the new Load */
- reg = arch_get_irn_register(node);
- arch_set_irn_register(load, reg);
-
- exchange(node, proj);
- }
-}
-
-/**
- * Some stuff to do immediately after register allocation
- */
-static void ppc32_after_ra(void *self)
-{
- ppc32_code_gen_t *cg = self;
- be_coalesce_spillslots(cg->birg);
- irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_spill, NULL);
-}
-
-/**
- * Emits the code, closes the output file and frees
- * the code generator interface.
- */
-static void ppc32_emit_and_done(void *self)
-{
- ppc32_code_gen_t *cg = self;
- ir_graph *irg = cg->irg;
-
- dump_ir_graph(irg, "ppc-finished");
- ppc32_gen_routine(cg, irg);
-
- /* de-allocate code generator */
- del_set(cg->reg_set);
- free(self);
-}
-
-int is_direct_entity(ir_entity *ent);
-
-static void *ppc32_cg_init(be_irg_t *birg);
-
-static const arch_code_generator_if_t ppc32_code_gen_if = {
- ppc32_cg_init,
- NULL, /* get_pic_base */
- ppc32_before_abi,
- ppc32_prepare_graph,
- NULL, /* spill */
- ppc32_before_ra, /* before register allocation hook */
- ppc32_after_ra,
- ppc32_finish_irg,
- ppc32_emit_and_done
-};
-
-/**
- * Initializes the code generator.
- */
-static void *ppc32_cg_init(be_irg_t *birg)
-{
- ppc32_isa_t *isa = (ppc32_isa_t *)birg->main_env->arch_env;
- ppc32_code_gen_t *cg = XMALLOC(ppc32_code_gen_t);
-
- cg->impl = &ppc32_code_gen_if;
- cg->irg = birg->irg;
- cg->reg_set = new_set(ppc32_cmp_irn_reg_assoc, 1024);
- cg->isa = isa;
- cg->birg = birg;
- cg->area_size = 0;
- cg->area = NULL;
- cg->start_succ_block = NULL;
- cg->blk_sched = NULL;
- FIRM_DBG_REGISTER(cg->mod, "firm.be.ppc.cg");
-
- return (arch_code_generator_t *)cg;
-}
-
-
-
-/*****************************************************************
- * ____ _ _ _____ _____
- * | _ \ | | | | |_ _|/ ____| /\
- * | |_) | __ _ ___| | _____ _ __ __| | | | | (___ / \
- * | _ < / _` |/ __| |/ / _ \ '_ \ / _` | | | \___ \ / /\ \
- * | |_) | (_| | (__| < __/ | | | (_| | _| |_ ____) / ____ \
- * |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |_____|_____/_/ \_\
- *
- *****************************************************************/
-
-static ppc32_isa_t ppc32_isa_template = {
- {
- &ppc32_isa_if, /* isa interface */
- &ppc32_gp_regs[REG_R1], /* stack pointer */
- &ppc32_gp_regs[REG_R31], /* base pointer */
- &ppc32_reg_classes[CLASS_ppc32_gp], /* static link pointer class */
- -1, /* stack is decreasing */
- 2, /* power of two stack alignment for calls, 2^2 == 4 */
- NULL, /* main environment */
- 7, /* spill costs */
- 5, /* reload costs */
- },
- NULL /* symbol set */
-};
-
-/**
- * Collects all SymConsts which need to be accessed "indirectly"
- *
- * @param node the firm node
- * @param env the symbol set
- */
-static void ppc32_collect_symconsts_walk(ir_node *node, void *env)
-{
- pset *symbol_set = env;
-
- if (is_SymConst(node)) {
- ir_entity *ent = get_SymConst_entity(node);
- pset_insert_ptr(symbol_set, ent);
- }
-}
-
-/**
- * Initializes the backend ISA and opens the output file.
- */
-static arch_env_t *ppc32_init(FILE *file_handle)
-{
- static int inited = 0;
- ppc32_isa_t *isa;
- int i;
-
- if (inited)
- return NULL;
-
- isa = XMALLOC(ppc32_isa_t);
- memcpy(isa, &ppc32_isa_template, sizeof(*isa));
-
- be_emit_init(file_handle);
-
- ppc32_register_init();
- ppc32_create_opcodes(&ppc32_irn_ops);
-
- inited = 1;
-
- isa->symbol_set = pset_new_ptr(8);
- for (i = 0; i < get_irp_n_irgs(); ++i) {
- ir_graph *irg = get_irp_irg(i);
- irg_walk_blkwise_graph(irg, NULL, ppc32_collect_symconsts_walk, isa->symbol_set);
- }
-
- /* we mark referenced global entities, so we can only emit those which
- * are actually referenced. (Note: you mustn't use the type visited flag
- * elsewhere in the backend)
- */
- inc_master_type_visited();
-
- return &isa->arch_env;
-}
-
-static void ppc32_dump_indirect_symbols(ppc32_isa_t *isa)
-{
- ir_entity *ent;
-
- foreach_pset(isa->symbol_set, ent) {
- const char *ld_name = get_entity_ld_name(ent);
- be_emit_irprintf(".non_lazy_symbol_pointer\n%s:\n\t.indirect_symbol _%s\n\t.long 0\n\n", ld_name, ld_name);
- be_emit_write_line();
- }
-}
-
-/**
- * Closes the output file and frees the ISA structure.
- */
-static void ppc32_done(void *self)
-{
- ppc32_isa_t *isa = self;
-
- be_gas_emit_decls(isa->arch_env.main_env);
- be_gas_emit_switch_section(GAS_SECTION_DATA);
- ppc32_dump_indirect_symbols(isa);
-
- be_emit_exit();
- del_pset(isa->symbol_set);
-
- free(self);
-}
-
-
-
-static unsigned ppc32_get_n_reg_class(void)
-{
- return N_CLASSES;
-}
-
-static const arch_register_class_t *ppc32_get_reg_class(unsigned i)
-{
- assert(i < N_CLASSES && "Invalid ppc register class requested.");
- return &ppc32_reg_classes[i];
-}
-
-
-
-/**
- * Get the register class which shall be used to store a value of a given mode.
- * @param self The this pointer.
- * @param mode The mode in question.
- * @return A register class which can hold values of the given mode.
- */
-static const arch_register_class_t *ppc32_get_reg_class_for_mode(const ir_mode *mode)
-{
- if (mode_is_float(mode))
- return &ppc32_reg_classes[CLASS_ppc32_fp];
- else
- return &ppc32_reg_classes[CLASS_ppc32_gp];
-}
-
-
-/**
- * Get the ABI restrictions for procedure calls.
- * @param self The this pointer.
- * @param method_type The type of the method (procedure) in question.
- * @param abi The abi object to be modified
- */
-static void ppc32_get_call_abi(const void *self, ir_type *method_type, be_abi_call_t *abi)
-{
- ir_type *tp;
- ir_mode *mode;
- int i, n = get_method_n_params(method_type);
- int stackoffs = 0, lastoffs = 0, stackparamsize;
-
- int gpregi = REG_R3;
- int fpregi = REG_F1;
-
- const arch_register_t *reg;
- be_abi_call_flags_t call_flags = { { 0, 0, 1, 0, 0, 0, 1 } };
-
- (void) self;
- call_flags.bits.call_has_imm = 1;
-
- /* set stack parameter passing style */
- be_abi_call_set_flags(abi, call_flags, &ppc32_abi_callbacks);
-
- for (i = 0; i < n; i++) {
- tp = get_method_param_type(method_type, i);
- mode = get_type_mode(tp);
- if (is_atomic_type(tp))
- {
- if (mode_is_float(mode))
- {
- if (fpregi <= REG_F13)
- {
- if (get_mode_size_bits(mode) == 32) gpregi++, stackparamsize=4;
- else gpregi += 2, stackparamsize=8; // mode == irm_D
- reg = &ppc32_fp_regs[fpregi++];
- }
- else
- {
- if (get_mode_size_bits(mode) == 32) stackparamsize=4;
- else stackparamsize=8; // mode == irm_D
- reg = NULL;
- }
- }
- else
- {
- if (gpregi <= REG_R10)
- reg = &ppc32_gp_regs[gpregi++];
- else
- reg = NULL;
- stackparamsize=4;
- }
-
- if (reg)
- be_abi_call_param_reg(abi, i, reg, ABI_CONTEXT_BOTH);
- else
- {
- be_abi_call_param_stack(abi, i, mode, 4, stackoffs - lastoffs, 0, ABI_CONTEXT_BOTH);
- lastoffs = stackoffs+stackparamsize;
- }
- stackoffs += stackparamsize;
- }
- else
- {
- be_abi_call_param_stack(abi, i, mode, 4, stackoffs - lastoffs, 0, ABI_CONTEXT_BOTH);
- stackoffs += (get_type_size_bytes(tp)+3) & -4;
- lastoffs = stackoffs;
- }
- }
-
- /* explain where result can be found if any */
- if (get_method_n_ress(method_type) > 0) {
- tp = get_method_res_type(method_type, 0);
- mode = get_type_mode(tp);
-
- be_abi_call_res_reg(abi, 0,
- mode_is_float(mode) ? &ppc32_fp_regs[REG_F1] : &ppc32_gp_regs[REG_R3], ABI_CONTEXT_BOTH);
- }
-}
-
-static int ppc32_to_appear_in_schedule(void *block_env, const ir_node *irn)
-{
- (void) block_env;
- if (!is_ppc32_irn(irn))
- return -1;
-
- return 1;
-}
-
-/**
- * Initializes the code generator interface.
- */
-static const arch_code_generator_if_t *ppc32_get_code_generator_if(void *self)
-{
- (void) self;
- return &ppc32_code_gen_if;
-}
-
-list_sched_selector_t ppc32_sched_selector;
-
-/**
- * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
- */
-static const list_sched_selector_t *ppc32_get_list_sched_selector(const void *self, list_sched_selector_t *selector)
-{
- (void) self;
- (void) selector;
- ppc32_sched_selector = trivial_selector;
- ppc32_sched_selector.to_appear_in_schedule = ppc32_to_appear_in_schedule;
- return &ppc32_sched_selector;
-}
-
-static const ilp_sched_selector_t *ppc32_get_ilp_sched_selector(const void *self)
-{
- (void) self;
- return NULL;
-}
-
-/**
- * Returns the necessary byte alignment for storing a register of given class.
- */
-static int ppc32_get_reg_class_alignment(const arch_register_class_t *cls)
-{
- ir_mode *mode = arch_register_class_mode(cls);
- return get_mode_size_bytes(mode);
-}
-
-static const be_execution_unit_t ***ppc32_get_allowed_execution_units(const ir_node *irn)
-{
- (void) irn;
- /* TODO */
- panic("Unimplemented ppc32_get_allowed_execution_units()");
-}
-
-static const be_machine_t *ppc32_get_machine(const void *self)
-{
- (void) self;
- /* TODO */
- panic("Unimplemented ppc32_get_machine()");
-}
-
-/**
- * Return irp irgs in the desired order.
- */
-static ir_graph **ppc32_get_irg_list(const void *self, ir_graph ***irg_list)
-{
- (void) self;
- (void) irg_list;
- return NULL;
-}
-
-/**
- * Returns the libFirm configuration parameter for this backend.
- */
-static const backend_params *ppc32_get_libfirm_params(void)
-{
- static backend_params p = {
- 1, /* need dword lowering */
- 0, /* don't support inline assembler yet */
- NULL, /* will be set later */
- NULL, /* but yet no creator function */
- NULL, /* context for create_intrinsic_fkt */
- NULL, /* no if conversion settings */
- NULL, /* no float arithmetic mode (TODO) */
- 0, /* no trampoline support: size 0 */
- 0, /* no trampoline support: align 0 */
- NULL, /* no trampoline support: no trampoline builder */
- 4 /* alignment of stack parameter */
- };
-
- return &p;
-}
-
-static asm_constraint_flags_t ppc32_parse_asm_constraint(const char **c)
-{
- /* no asm support yet */
- (void) c;
- return ASM_CONSTRAINT_FLAG_INVALID;
-}
-
-static int ppc32_is_valid_clobber(const char *clobber)
-{
- /* no asm support yet */
- (void) clobber;
- return 0;
-}
-
-const arch_isa_if_t ppc32_isa_if = {
- ppc32_init,
- ppc32_done,
- NULL, /* handle intrinsics */
- ppc32_get_n_reg_class,
- ppc32_get_reg_class,
- ppc32_get_reg_class_for_mode,
- ppc32_get_call_abi,
- ppc32_get_code_generator_if,
- ppc32_get_list_sched_selector,
- ppc32_get_ilp_sched_selector,
- ppc32_get_reg_class_alignment,
- ppc32_get_libfirm_params,
- ppc32_get_allowed_execution_units,
- ppc32_get_machine,
- ppc32_get_irg_list,
- NULL, /* mark remat */
- ppc32_parse_asm_constraint,
- ppc32_is_valid_clobber
-};
-
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_ppc32);
-void be_init_arch_ppc32(void)
-{
- be_register_isa_if("ppc32", &ppc32_isa_if);
-}
+++ /dev/null
-/*
- * 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 ppc32 backend
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_BEARCH_PPC32_H
-#define FIRM_BE_PPC32_BEARCH_PPC32_H
-
-#include "../bearch.h"
-
-extern const arch_isa_if_t ppc32_isa_if;
-
-#endif
+++ /dev/null
-/*
- * 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 -- private header
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_BEARCH_PPC32_T_H
-#define FIRM_BE_PPC32_BEARCH_PPC32_T_H
-
-#include "debug.h"
-#include "bearch_ppc32.h"
-#include "ppc32_nodes_attr.h"
-#include "be.h"
-#include "../beemitter.h"
-#include "pset.h"
-#include "set.h"
-
-typedef struct _ppc32_isa_t ppc32_isa_t;
-
-typedef struct _ppc32_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) */
- ppc32_isa_t *isa; /**< the isa instance */
- be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */
- unsigned area_size; /**< size of call area for the current irg */
- ir_entity *area; /**< the entity representing the call area or NULL for leaf functions */
- ir_node *start_succ_block; /**< the block succeeding the start block in the cfg */
- ir_node **blk_sched; /**< an array containing the scheduled blocks */
- DEBUG_ONLY(firm_dbg_module_t *mod;) /**< debugging module */
-} ppc32_code_gen_t;
-
-
-struct _ppc32_isa_t {
- arch_env_t arch_env; /**< must be derived from arch_env_t */
- pset *symbol_set; /**< A set containing the indirect symbols. */
-};
-
-
-/** this is a struct to minimize the number of parameters
- for transformation walker */
-typedef struct _ppc32_transform_env_t {
- dbg_info *dbg; /**< The node debug info */
- ir_graph *irg; /**< The irg, the node should be created in */
- ir_node *block; /**< The block, the node should belong to */
- ir_node *irn; /**< The irn, to be transformed */
- ir_mode *mode; /**< The mode of the irn */
- DEBUG_ONLY(firm_dbg_module_t *mod;) /**< The firm debugger */
-} ppc32_transform_env_t;
-
-#endif
+++ /dev/null
-/*
- * 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 ppc emitter
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include <limits.h>
-
-#include "xmalloc.h"
-#include "tv.h"
-#include "iredges.h"
-#include "debug.h"
-#include "irgwalk.h"
-#include "irprintf.h"
-#include "irop_t.h"
-#include "irnode_t.h"
-#include "irargs_t.h"
-#include "error.h"
-
-#include "../besched.h"
-#include "../benode.h"
-#include "../begnuas.h"
-
-#include "ppc32_emitter.h"
-#include "gen_ppc32_emitter.h"
-#include "gen_ppc32_regalloc_if.h"
-#include "ppc32_nodes_attr.h"
-#include "ppc32_new_nodes.h"
-#include "ppc32_map_regs.h"
-
-#define SNPRINTF_BUF_LEN 128
-
-static char printbuf[SNPRINTF_BUF_LEN];
-
-extern int isleaf;
-
-
-/*************************************************************
- * _ _ __ _ _
- * (_) | | / _| | | | |
- * _ __ _ __ _ _ __ | |_| |_ | |__ ___| |_ __ ___ _ __
- * | '_ \| '__| | '_ \| __| _| | '_ \ / _ \ | '_ \ / _ \ '__|
- * | |_) | | | | | | | |_| | | | | | __/ | |_) | __/ |
- * | .__/|_| |_|_| |_|\__|_| |_| |_|\___|_| .__/ \___|_|
- * | | | |
- * |_| |_|
- *************************************************************/
-/**
- * Returns the register at in position pos.
- */
-static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
-{
- ir_node *op;
- const arch_register_t *reg = NULL;
-
- assert(get_irn_arity(irn) > pos && "Invalid IN position");
-
- /* The out register of the operator at position pos is the
- in register we need. */
- op = get_irn_n(irn, pos);
-
- reg = arch_get_irn_register(op);
-
- assert(reg && "no in register found");
- return reg;
-}
-
-/**
- * Returns the register at out position pos.
- */
-static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
-{
- ir_node *proj;
- const arch_register_t *reg = NULL;
-
- assert(get_irn_n_edges(irn) > pos && "Invalid OUT position");
-
- /* 1st case: irn is not of mode_T, so it has only */
- /* one OUT register -> good */
- /* 2nd case: irn is of mode_T -> collect all Projs and ask the */
- /* Proj with the corresponding projnum for the register */
-
- if (get_irn_mode(irn) != mode_T) {
- reg = arch_get_irn_register(irn);
- } else if (is_ppc32_irn(irn)) {
- reg = arch_irn_get_register(irn, pos);
- } else {
- const ir_edge_t *edge;
-
- foreach_out_edge(irn, edge) {
- proj = get_edge_src_irn(edge);
- assert(is_Proj(proj) && "non-Proj from mode_T node");
- if (get_Proj_proj(proj) == pos) {
- reg = arch_get_irn_register(proj);
- break;
- }
- }
- }
-
- assert(reg && "no out register found");
- return reg;
-}
-
-/**
- * Emit the name of the source register at given input position.
- */
-void ppc32_emit_source_register(const ir_node *node, int pos)
-{
- const arch_register_t *reg = get_in_reg(node, pos);
- be_emit_string(arch_register_get_name(reg));
-}
-
-/**
- * Emit the name of the destination register at given output position.
- */
-void ppc32_emit_dest_register(const ir_node *node, int pos)
-{
- const arch_register_t *reg = get_out_reg(node, pos);
- be_emit_string(arch_register_get_name(reg));
-}
-
-void ppc32_emit_rlwimi_helper(const ir_node *n)
-{
- const rlwimi_const_t *rlwimi_const = get_ppc32_rlwimi_const(n);
-
- be_emit_irprintf("%i, %i, %i", rlwimi_const->shift,
- rlwimi_const->maskA, rlwimi_const->maskB);
-}
-
-/**
- * Emit a const or symconst.
- */
-void ppc32_emit_immediate(const ir_node *n)
-{
- const char *buf;
-
- switch (get_ppc32_type(n)) {
- case ppc32_ac_Const:
- tarval_snprintf(printbuf, SNPRINTF_BUF_LEN, get_ppc32_constant_tarval(n));
- buf = printbuf;
- break;
- case ppc32_ac_SymConst:
- buf = get_id_str(get_ppc32_symconst_ident(n));
- break;
- case ppc32_ac_Offset:
- be_emit_irprintf("%i", get_ppc32_offset(n));
- return;
- default:
- assert(0 && "node_const_to_str(): Illegal offset type");
- return;
- }
- switch (get_ppc32_offset_mode(n)) {
- case ppc32_ao_None:
- be_emit_string(buf);
- return;
- case ppc32_ao_Lo16:
- be_emit_irprintf("lo16(%s)", buf);
- return;
- case ppc32_ao_Hi16:
- be_emit_irprintf("hi16(%s)", buf);
- return;
- case ppc32_ao_Ha16:
- be_emit_irprintf("ha16(%s)", buf);
- return;
- default:
- assert(0 && "node_const_to_str(): Illegal offset mode");
- return;
- }
-}
-
-/**
- * Emits a node's offset.
- */
-void ppc32_emit_offset(const ir_node *n)
-{
- const char *buf;
- if (get_ppc32_type(n) == ppc32_ac_None) {
- be_emit_char('0');
- return;
- }
-
- switch (get_ppc32_type(n)) {
- case ppc32_ac_Const:
- tarval_snprintf(printbuf, SNPRINTF_BUF_LEN, get_ppc32_constant_tarval(n));
- buf = printbuf;
- break;
- case ppc32_ac_SymConst:
- buf = get_id_str(get_ppc32_symconst_ident(n));
- break;
- case ppc32_ac_Offset:
- be_emit_irprintf("%i", get_ppc32_offset(n));
- return;
- default:
- assert(0 && "node_offset_to_str(): Illegal offset type");
- return;
- }
- switch (get_ppc32_offset_mode(n)) {
- case ppc32_ao_None:
- be_emit_string(buf);
- return;
- case ppc32_ao_Lo16:
- be_emit_irprintf("lo16(%s)", buf);
- return;
- case ppc32_ao_Hi16:
- be_emit_irprintf("hi16(%s)", buf);
- return;
- case ppc32_ao_Ha16:
- be_emit_irprintf("ha16(%s)", buf);
- return;
- default:
- assert(0 && "node_offset_to_str(): Illegal offset mode");
- return;
- }
-}
-
-/**
- * Emits code for a unconditional jump.
- */
-static void emit_Jmp(const ir_node *irn)
-{
- ir_node *block = get_nodes_block(irn);
-
- if (get_irn_link(irn) != get_irn_link(block)) {
- ir_node *dest = get_irn_link(irn);
- be_emit_cstring("\tb ");
- be_gas_emit_block_name(dest);
- } else {
- be_emit_irprintf("/* fallthrough(%+F) */", get_irn_link(irn));
- }
- be_emit_finish_line_gas(irn);
-}
-
-/**
- * Emits code for a call
- */
-static void emit_be_Call(const ir_node *irn)
-{
- ir_entity *call_ent = be_Call_get_entity(irn);
-
- if (call_ent) {
- be_emit_irprintf("\tbl %s", get_entity_ld_name(call_ent));
- } else {
- be_emit_cstring("\tmtlr ");
- ppc32_emit_source_register(irn, be_pos_Call_ptr);
- be_emit_pad_comment();
- be_emit_cstring("/* Move to link register and link */\n");
- be_emit_write_line();
- be_emit_cstring("\tblrl");
- }
- be_emit_finish_line_gas(irn);
-}
-
-static void emit_ppc32_Branch(const ir_node *irn)
-{
- static const char *branchops[8] = { 0, "beq", "blt", "ble", "bgt", "bge", "bne", "b" };
- int projnum = get_ppc32_proj_nr(irn);
-
- const ir_edge_t *edge = get_irn_out_edge_first(irn);
- ir_node *proj = get_edge_src_irn(edge);
-
- int opind;
-
- if (get_Proj_proj(proj) == pn_Cond_true)
- opind = projnum;
- else
- opind = 7 - projnum;
-
- assert(opind>=0 && opind<8);
-
- if (opind){
- be_emit_irprintf("\t%8s", branchops[opind]);
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- be_gas_emit_block_name(get_irn_link(proj));
- be_emit_finish_line_gas(irn);
- }
-
- edge = get_irn_out_edge_next(irn, edge);
- if (edge) {
- ir_node *blk = get_edge_src_irn(edge);
- be_emit_cstring("\tb ");
- be_gas_emit_block_name(get_irn_link(blk));
- be_emit_finish_line_gas(irn);
- }
-}
-
-static void emit_ppc32_LoopCopy(const ir_node *irn)
-{
- be_emit_irprintf("LOOP_%ld:\n", get_irn_node_nr(irn));
- be_emit_write_line();
-
- be_emit_cstring("\tlwzu ");
- ppc32_emit_dest_register(irn, 4);
- be_emit_cstring(", 4(");
- ppc32_emit_source_register(irn, 1);
- be_emit_char(')');
- be_emit_pad_comment();
- be_emit_cstring("/* Load with update */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tstwu ");
- ppc32_emit_dest_register(irn, 4);
- be_emit_cstring(", 4(");
- ppc32_emit_source_register(irn, 2);
- be_emit_char(')');
- be_emit_pad_comment();
- be_emit_cstring("/* Store with update */\n");
- be_emit_write_line();
-
- be_emit_irprintf("\tbdnz LOOP_%i", get_irn_node_nr(irn));
- be_emit_finish_line_gas(irn);
-}
-
-static void emit_ppc32_Switch(const ir_node *irn)
-{
- ir_node *proj, *defproj = NULL;
- int pn;
-
- const ir_edge_t* edge;
- foreach_out_edge(irn, edge) {
- proj = get_edge_src_irn(edge);
- assert(is_Proj(proj) && "Only proj allowed at Switch");
- if (get_irn_mode(proj) != mode_X) continue;
-
- pn = get_Proj_proj(proj);
- /* check for default proj */
- if (pn == get_ppc32_proj_nr(irn)) {
- assert(defproj == NULL && "found two defProjs at Switch");
- defproj = proj;
- } else {
- be_emit_cstring("\taddis ");
- ppc32_emit_source_register(irn, 1);
- be_emit_irprintf(", 0, hi16(%i)", pn);
- be_emit_pad_comment();
- be_emit_cstring("/* Load upper immediate */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tori ");
- ppc32_emit_source_register(irn, 1);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_irprintf(", lo16(%i)", pn);
- be_emit_pad_comment();
- be_emit_cstring("/* Load lower immediate */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tcmp ");
- ppc32_emit_source_register(irn, 2);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_pad_comment();
- be_emit_cstring("/* Compare */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tbeq ");
- ppc32_emit_source_register(irn, 2);
- be_emit_cstring(", ");
- be_gas_emit_block_name(get_irn_link(proj));
- be_emit_cstring("/* Branch if equal */\n");
- be_emit_write_line();
- }
- }
- assert(defproj != NULL && "didn't find defProj at Switch");
- be_emit_cstring("\tb ");
- be_gas_emit_block_name(get_irn_link(defproj));
- be_emit_finish_line_gas(irn);
-}
-
-/**
- * Emits code for a backend Copy node
- */
-static void emit_be_Copy(const ir_node *irn)
-{
- const arch_register_class_t *regclass = arch_get_irn_reg_class(irn, 0);
-
- if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp]) {
- be_emit_cstring("\tmr ");
- } else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp]) {
- be_emit_cstring("\tfmr ");
- } else if (regclass == &ppc32_reg_classes[CLASS_ppc32_condition]) {
- be_emit_cstring("\tmcrf ");
- } else {
- panic("ppc32 Emitter: Illegal register class for Copy");
- }
- ppc32_emit_dest_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 0);
- be_emit_finish_line_gas(irn);
-}
-
-/**
- * Emits code for a backend Perm node
- */
-static void emit_be_Perm(const ir_node *irn)
-{
- const arch_register_class_t *regclass = arch_get_irn_reg_class(irn, 0);
-
- if (regclass == &ppc32_reg_classes[CLASS_ppc32_gp]) {
- be_emit_cstring("\txor ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_pad_comment();
- be_emit_cstring("/* Swap with XOR */\n");
- be_emit_write_line();
-
- be_emit_cstring("\txor ");
- ppc32_emit_source_register(irn, 1);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_pad_comment();
- be_emit_cstring("/* (continued) */\n");
- be_emit_write_line();
-
- be_emit_cstring("\txor ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- } else if (regclass == &ppc32_reg_classes[CLASS_ppc32_fp]) {
- be_emit_cstring("\tfmr f0, ");
- ppc32_emit_source_register(irn, 0);
- be_emit_pad_comment();
- be_emit_cstring("/* Swap with moves */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tfmr ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_pad_comment();
- be_emit_cstring("/* (continued) */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tfmr ");
- ppc32_emit_source_register(irn, 1);
- be_emit_cstring(", f0");
- } else if (regclass == &ppc32_reg_classes[CLASS_ppc32_condition]) {
- be_emit_cstring("\tmcrf cr7, ");
- ppc32_emit_source_register(irn, 0);
- be_emit_pad_comment();
- be_emit_cstring("/* Swap with moves */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tmcrf ");
- ppc32_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- ppc32_emit_source_register(irn, 1);
- be_emit_pad_comment();
- be_emit_cstring("/* (continued) */\n");
- be_emit_write_line();
-
- be_emit_cstring("\tmcrf ");
- ppc32_emit_source_register(irn, 1);
- be_emit_cstring(", cr7");
- } else {
- panic("ppc32 Emitter: Illegal register class for Perm");
- }
- be_emit_finish_line_gas(irn);
-}
-
-
-/**
- * Emits code for a proj -> node
- */
-static void emit_Proj(const ir_node *irn)
-{
- ir_node *pred = get_Proj_pred(irn);
-
- if (is_Start(pred)) {
- if (get_Proj_proj(irn) == pn_Start_X_initial_exec) {
- emit_Jmp(irn);
- }
- }
-}
-
-static void emit_be_IncSP(const ir_node *irn)
-{
- int offs = be_get_IncSP_offset(irn);
-
- be_emit_irprintf("\t/* ignored IncSP with %d */", -offs);
- be_emit_finish_line_gas(irn);
-
-// if (offs) {
-// assert(offs<=0x7fff);
-// lc_efprintf(ppc32_get_arg_env(), F, "\taddi %1S, %1S, %d\t\t\t/* %+F (IncSP) */\n", irn, irn,
-// -offs, irn);
-// }
-// else {
-// fprintf(F, "\t\t\t\t\t/* omitted IncSP with 0 */\n");
-// }
-}
-
-/*static void emit_Spill(const ir_node *irn, ppc32_emit_env_t *emit_env) {
- ir_node *context = be_get_Spill_context(irn);
- ir_entity *entity = be_get_spill_entity(irn);
-}*/
-
-/***********************************************************************************
- * _ __ _
- * (_) / _| | |
- * _ __ ___ __ _ _ _ __ | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
- * | '_ ` _ \ / _` | | '_ \ | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
- * | | | | | | (_| | | | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
- * |_| |_| |_|\__,_|_|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
- *
- ***********************************************************************************/
-/**
- * The type of a emitter function.
- */
-typedef void (emit_func)(const ir_node *irn);
-
-/**
- * Set a node emitter. Make it a bit more type safe.
- */
-static inline void set_emitter(ir_op *op, emit_func ppc32_emit_node)
-{
- op->ops.generic = (op_func)ppc32_emit_node;
-}
-
-static void ppc32_register_emitters(void)
-{
- /* first clear generic function pointers */
- clear_irp_opcodes_generic_func();
-
- /* register generated emitter functions */
- ppc32_register_spec_emitters();
-
- set_emitter(op_ppc32_Branch, emit_ppc32_Branch);
- set_emitter(op_ppc32_LoopCopy, emit_ppc32_LoopCopy);
- set_emitter(op_ppc32_Switch, emit_ppc32_Switch);
- set_emitter(op_be_Call, emit_be_Call);
- set_emitter(op_Jmp, emit_Jmp);
- set_emitter(op_Proj, emit_Proj);
- set_emitter(op_be_IncSP, emit_be_IncSP);
- set_emitter(op_be_Copy, emit_be_Copy);
- set_emitter(op_be_Perm, emit_be_Perm);
-// set_emitter(op_Spill, emit_Spill);
-// set_emitter(op_Reload, emit_Reload);
-}
-
-/**
- * Emits code for a node.
- */
-static void ppc32_emit_node(const ir_node *irn)
-{
- ir_op *op = get_irn_op(irn);
-
- if (op->ops.generic) {
- emit_func *emit = (emit_func *)op->ops.generic;
- (*emit)(irn);
- } else {
- be_emit_cstring("\t/* TODO */");
- be_emit_finish_line_gas(irn);
- }
-}
-
-
-/**
- * Walks over the nodes in a block connected by scheduling edges
- * and emits code for each node.
- */
-static void ppc32_gen_block(const ir_node *block)
-{
- ir_node *irn;
-
- if (! is_Block(block))
- return;
-
- be_gas_emit_block_name(block);
- be_emit_cstring(":\n");
- be_emit_write_line();
- sched_foreach(block, irn) {
- ppc32_emit_node(irn);
- }
-}
-
-
-/**
- * Emits code for function start.
- */
-static void ppc32_emit_start(ir_graph *irg)
-{
- const char *irg_name = get_entity_ld_name(get_irg_entity(irg));
- int framesize = get_type_size_bytes(get_irg_frame_type(irg));
-
- if (! strcmp(irg_name, "main")) { // XXX: underscore hack
- irg_name = "_main";
- }
-
- be_emit_irprintf("\t.text\n\t.globl %s\n\t.align 4\n%s:\n", irg_name, irg_name);
-
- if (framesize > 24) {
- be_emit_cstring("\tmflr r0\n");
- be_emit_cstring("\tstw r0, 8(r1)\n");
- be_emit_irprintf("\tstwu r1, -%i(r1)\n", framesize);
- } else {
- be_emit_irprintf("\t/* set new frame (%d) omitted */\n", framesize);
- }
- be_emit_write_line();
-
-/* if (!isleaf) {
- // store link register in linkage area (TODO: if needed)
-
- be_emit_cstring("\tmflr r0\n");
- be_emit_cstring("\tstwu r0, -4(r1)\n"); // stw r0, 8(SP)
- be_emit_write_line();
- }*/
-}
-
-/**
- * Emits code for function end
- */
-static void ppc32_emit_end(ir_graph *irg)
-{
- int framesize = get_type_size_bytes(get_irg_frame_type(irg));
- (void) irg;
-
-/* if (!isleaf) {
- // restore link register
-
- be_emit_cstring("\tlwz r0, 0(r1)\n");
- be_emit_cstring("\taddi r1, r1, 4\n");
- be_emit_cstring("\tmtlr r0\n");
- be_emit_write_line();
- }*/
- if (framesize > 24) {
- be_emit_cstring("\tlwz r1, 0(r1)\n");
- be_emit_cstring("\tlwz r0, 8(r1)\n");
- be_emit_cstring("\tmtlr r0\n");
- be_emit_write_line();
- }
- be_emit_cstring("\tblr\n\n");
- be_emit_write_line();
-}
-
-/**
- * Sets labels for control flow nodes (jump target)
- * TODO: Jump optimization
- */
-static void ppc32_gen_labels(ir_node *block, void *env)
-{
- ir_node *pred;
- int n;
- (void) env;
-
- for (n = get_Block_n_cfgpreds(block) - 1; n >= 0; --n) {
- pred = get_Block_cfgpred(block, n);
- set_irn_link(pred, block);
- }
-}
-
-/**
- * Main driver: generates code for one routine
- */
-void ppc32_gen_routine(const ppc32_code_gen_t *cg, ir_graph *irg)
-{
- ir_node *block;
- int i, n;
-
- ppc32_register_emitters();
-
- ppc32_emit_start(irg);
- irg_block_walk_graph(irg, ppc32_gen_labels, NULL, NULL);
-
- n = ARR_LEN(cg->blk_sched);
- for (i = 0; i < n;) {
- ir_node *next_bl;
-
- block = cg->blk_sched[i];
- ++i;
- next_bl = i < n ? cg->blk_sched[i] : NULL;
-
- /* set here the link. the emitter expects to find the next block here */
- set_irn_link(block, next_bl);
- ppc32_gen_block(block);
- }
- ppc32_emit_end(irg);
-}
+++ /dev/null
-/*
- * 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 ppc32 emitter
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_EMITTER_H
-#define FIRM_BE_PPC32_PPC32_EMITTER_H
-
-#include "firm_types.h"
-#include "irargs_t.h"
-#include "debug.h"
-
-#include "../bearch.h"
-
-#include "bearch_ppc32_t.h"
-
-void ppc32_gen_routine(const ppc32_code_gen_t *cg, ir_graph *irg);
-
-
-void ppc32_emit_source_register(const ir_node *node, int pos);
-void ppc32_emit_dest_register(const ir_node *node, int pos);
-void ppc32_emit_offset(const ir_node *n);
-void ppc32_emit_immediate(const ir_node *n);
-void ppc32_emit_rlwimi_helper(const ir_node *n);
-
-#endif
+++ /dev/null
-/*
- * 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 Register mapping for firm nodes. Stolen from bearch_firm :)
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "ppc32_map_regs.h"
-#include "ppc32_new_nodes.h"
-
-/* Mapping to store registers in firm nodes */
-
-struct ppc32_irn_reg_assoc {
- const ir_node *irn;
- const arch_register_t *reg;
-};
-
-int ppc32_cmp_irn_reg_assoc(const void *a, const void *b, size_t len)
-{
- const struct ppc32_irn_reg_assoc *x = a;
- const struct ppc32_irn_reg_assoc *y = b;
- (void) len;
-
- return x->irn != y->irn;
-}
-
-static struct ppc32_irn_reg_assoc *get_irn_reg_assoc(const ir_node *irn, set *reg_set)
-{
- struct ppc32_irn_reg_assoc templ;
- unsigned int hash;
-
- templ.irn = irn;
- templ.reg = NULL;
- hash = HASH_PTR(irn);
-
- return set_insert(reg_set, &templ, sizeof(templ), hash);
-}
-
-void ppc32_set_firm_reg(ir_node *irn, const arch_register_t *reg, set *reg_set)
-{
- struct ppc32_irn_reg_assoc *assoc = get_irn_reg_assoc(irn, reg_set);
- assoc->reg = reg;
-}
-
-const arch_register_t *ppc32_get_firm_reg(const ir_node *irn, set *reg_set)
-{
- struct ppc32_irn_reg_assoc *assoc = get_irn_reg_assoc(irn, reg_set);
- return assoc->reg;
-}
-
-
-static int is_ppc32_Load(const ir_node *n)
-{
- ir_op *op = get_irn_op(n);
- if (op == op_ppc32_Lbz) return 1;
- if (op == op_ppc32_Lhz) return 1;
- if (op == op_ppc32_Lha) return 1;
- if (op == op_ppc32_Lwz) return 1;
- if (op == op_ppc32_Lfd) return 1;
- if (op == op_ppc32_Lfs) return 1;
-
- return 0;
-}
-
-static int is_ppc32_Store(const ir_node *n)
-{
- ir_op *op = get_irn_op(n);
- if (op == op_ppc32_Stb) return 1;
- if (op == op_ppc32_Sth) return 1;
- if (op == op_ppc32_Stw) return 1;
- if (op == op_ppc32_Stfd) return 1;
- if (op == op_ppc32_Stfs) return 1;
-
- return 0;
-}
-
-
-/**
- * Translates the projnum into a "real" argument position for register
- * requirements dependend on the predecessor.
- */
-long ppc32_translate_proj_pos(const ir_node *proj)
-{
- ir_node *pred = get_Proj_pred(proj);
- long nr = get_Proj_proj(proj);
-
-
- if (is_ppc32_Load(pred)) {
- if (nr == pn_Load_res)
- return 0;
- assert(0 && "unsupported Proj(Load) number");
- }
- else if (is_ppc32_Store(pred)) {
- return 0;
- }
- else if (is_ppc32_fDiv(pred)) {
- if (nr == pn_Quot_res)
- return 0;
- else
- assert(0 && "there should be no more Projs for a fDiv");
- }
- else if (is_ppc32_Divw(pred) || is_ppc32_Divwu(pred)) {
- if (nr == pn_DivMod_res_div)
- return 0;
- else
- assert(0 && "there should be no more Projs for a ppc32_Divw or ppc32_Divwu");
- }
-
- else if (is_ppc32_Cmp(pred))
- return 0;
- else if (is_ppc32_Cmpi(pred))
- return 0;
- else if (is_ppc32_Cmpl(pred))
- return 0;
- else if (is_ppc32_Cmpli(pred))
- return 0;
-
-
-
-// assert(0 && "unsupported Proj(X)");
- return nr;
-}
+++ /dev/null
-/*
- * 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 register allocation interface of ppc32
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_MAP_REGS_H
-#define FIRM_BE_PPC32_PPC32_MAP_REGS_H
-
-#include "irnode.h"
-#include "set.h"
-
-#include "../bearch.h"
-#include "ppc32_nodes_attr.h"
-
-int ppc32_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
-void ppc32_set_firm_reg(ir_node *irn, const arch_register_t *reg, set *reg_set);
-const arch_register_t *ppc32_get_firm_reg(const ir_node *irn, set *reg_set);
-
-long ppc32_translate_proj_pos(const ir_node *proj);
-
-#endif
+++ /dev/null
-/*
- * 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 This file implements the creation of the architecture specific firm
- * opcodes and the corresponding node constructors for the ppc assembler
- * irg.
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include <stdlib.h>
-
-#include "irprog_t.h"
-#include "irgraph_t.h"
-#include "irnode_t.h"
-#include "irmode_t.h"
-#include "ircons_t.h"
-#include "iropt_t.h"
-#include "irop.h"
-#include "irvrfy_t.h"
-#include "irprintf.h"
-#include "xmalloc.h"
-
-#include "../bearch.h"
-
-#include "ppc32_nodes_attr.h"
-#include "ppc32_new_nodes.h"
-#include "gen_ppc32_regalloc_if.h"
-
-
-
-/***********************************************************************************
- * _ _ _ __
- * | | (_) | | / _|
- * __| |_ _ _ __ ___ _ __ ___ _ __ _ _ __ | |_ ___ _ __| |_ __ _ ___ ___
- * / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__| _/ _` |/ __/ _ \
- * | (_| | |_| | | | | | | |_) | __/ | | | | | | || __/ | | || (_| | (_| __/
- * \__,_|\__,_|_| |_| |_| .__/ \___|_| |_|_| |_|\__\___|_| |_| \__,_|\___\___|
- * | |
- * |_|
- ***********************************************************************************/
-
-/**
- * Dumper interface for dumping ppc32 nodes in vcg.
- * @param F the output file
- * @param n the node to dump
- * @param reason indicates which kind of information should be dumped
- */
-static void ppc32_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
-{
- ir_mode *mode = NULL;
-
- switch (reason) {
- case dump_node_opcode_txt:
- fprintf(F, "%s", get_irn_opname(n));
- break;
-
- case dump_node_mode_txt:
- mode = get_irn_mode(n);
-
- if (mode) {
- fprintf(F, "[%s]", get_mode_name(mode));
- }
- else {
- fprintf(F, "[?NOMODE?]");
- }
- break;
-
- case dump_node_nodeattr_txt:
-
- /* TODO: dump some attributes which should show up */
- /* in node name in dump (e.g. consts or the like) */
-
- break;
-
- case dump_node_info_txt:
- arch_dump_reqs_and_registers(F, n);
- break;
- }
-}
-
-
-
-/***************************************************************************************************
- * _ _ _ __ _ _ _ _
- * | | | | | | / / | | | | | | | |
- * __ _| |_| |_ _ __ ___ ___| |_ / /_ _ ___| |_ _ __ ___ ___| |_| |__ ___ __| |___
- * / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
- * | (_| | |_| |_| | \__ \ __/ |_ / / (_| | __/ |_ | | | | | | __/ |_| | | | (_) | (_| \__ \
- * \__,_|\__|\__|_| |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
- * __/ |
- * |___/
- ***************************************************************************************************/
-
-ppc32_attr_t *get_ppc32_attr(ir_node *node)
-{
- assert(is_ppc32_irn(node) && "need ppc node to get attributes");
- return (ppc32_attr_t *)get_irn_generic_attr(node);
-}
-
-const ppc32_attr_t *get_ppc32_attr_const(const ir_node *node)
-{
- assert(is_ppc32_irn(node) && "need ppc node to get attributes");
- return (const ppc32_attr_t *)get_irn_generic_attr_const(node);
-}
-
-
-
-/**
- * Returns the argument register requirements of a ppc node.
- */
-const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->in_req;
-}
-
-/**
- * Returns the argument register requirement at position pos of an ppc node.
- */
-const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->in_req[pos];
-}
-
-/**
- * Sets the IN register requirements at position pos.
- */
-void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->in_req[pos] = req;
-}
-
-/**
- * Sets the type of the constant (if any)
- * May be either iro_Const or iro_SymConst
- */
-/* void set_ppc32_type(const ir_node *node, opcode type) {
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->type = type;
-} */
-
-/**
- * Returns the type of the content (if any)
- */
-ppc32_attr_content_type get_ppc32_type(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->content_type;
-}
-
-/**
- * Sets a tarval type content (also updating the content_type)
- */
-void set_ppc32_constant_tarval(ir_node *node, tarval *const_tarval)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_Const;
- attr->data.constant_tarval = const_tarval;
-}
-
-/**
- * Returns a tarval type constant
- */
-tarval *get_ppc32_constant_tarval(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->data.constant_tarval;
-}
-
-/**
- * Sets an ident type constant (also updating the content_type)
- */
-void set_ppc32_symconst_ident(ir_node *node, ident *symconst_ident)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_SymConst;
- attr->data.symconst_ident = symconst_ident;
-}
-
-/**
- * Returns an ident type constant
- */
-ident *get_ppc32_symconst_ident(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->data.symconst_ident;
-}
-
-
-/**
- * Sets an entity (also updating the content_type)
- */
-void set_ppc32_frame_entity(ir_node *node, ir_entity *ent)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_FrameEntity;
- attr->data.frame_entity = ent;
-}
-
-/**
- * Returns an entity
- */
-ir_entity *get_ppc32_frame_entity(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->data.frame_entity;
-}
-
-/**
- * Sets a Rlwimi const (also updating the content_type)
- */
-void set_ppc32_rlwimi_const(ir_node *node, unsigned shift, unsigned maskA, unsigned maskB)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_RlwimiConst;
- attr->data.rlwimi_const.shift = shift;
- attr->data.rlwimi_const.maskA = maskA;
- attr->data.rlwimi_const.maskB = maskB;
-}
-
-/**
- * Returns the rlwimi const structure
- */
-const rlwimi_const_t *get_ppc32_rlwimi_const(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return &attr->data.rlwimi_const;
-}
-
-/**
- * Sets a Proj number (also updating the content_type)
- */
-void set_ppc32_proj_nr(ir_node *node, int proj_nr)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_BranchProj;
- attr->data.proj_nr = proj_nr;
-}
-
-/**
- * Returns the proj number
- */
-int get_ppc32_proj_nr(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->data.proj_nr;
-}
-
-/**
- * Sets an offset for a memory access (also updating the content_type)
- */
-void set_ppc32_offset(ir_node *node, int offset)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->content_type = ppc32_ac_Offset;
- attr->data.offset = offset;
-}
-
-/**
- * Returns the offset
- */
-int get_ppc32_offset(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->data.offset;
-}
-
-/**
- * Sets the offset mode (ppc32_ao_None, ppc32_ao_Lo16, ppc32_ao_Hi16 or ppc32_ao_Ha16)
- */
-void set_ppc32_offset_mode(ir_node *node, ppc32_attr_offset_mode mode)
-{
- ppc32_attr_t *attr = get_ppc32_attr(node);
- attr->offset_mode = mode;
-}
-
-/**
- * Returns the offset mode
- */
-ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node)
-{
- const ppc32_attr_t *attr = get_ppc32_attr_const(node);
- return attr->offset_mode;
-}
-
-
-/**
- * Initializes ppc specific node attributes
- */
-static void init_ppc32_attributes(ir_node *node, int flags,
- const arch_register_req_t **in_reqs,
- const be_execution_unit_t ***execution_units,
- int n_res)
-{
- ir_graph *irg = get_irn_irg(node);
- struct obstack *obst = get_irg_obstack(irg);
- ppc32_attr_t *attr = get_ppc32_attr(node);
- backend_info_t *info;
- (void) execution_units;
-
- arch_irn_set_flags(node, flags);
- attr->in_req = in_reqs;
-
- attr->content_type = ppc32_ac_None;
- attr->offset_mode = ppc32_ao_Illegal;
- attr->data.empty = NULL;
-
- info = be_get_info(node);
- info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
- memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
-}
-
-
-/***************************************************************************************
- * _ _ _
- * | | | | | |
- * _ __ ___ __| | ___ ___ ___ _ __ ___| |_ _ __ _ _ ___| |_ ___ _ __ ___
- * | '_ \ / _ \ / _` |/ _ \ / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
- * | | | | (_) | (_| | __/ | (_| (_) | | | \__ \ |_| | | |_| | (__| || (_) | | \__ \
- * |_| |_|\___/ \__,_|\___| \___\___/|_| |_|___/\__|_| \__,_|\___|\__\___/|_| |___/
- *
- ***************************************************************************************/
-
-/* Include the generated constructor functions */
-#include "gen_ppc32_new_nodes.c.inl"
+++ /dev/null
-/*
- * 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 Function prototypes for the ppc32 assembler ir node constructors.
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_NEW_NODES_H
-#define FIRM_BE_PPC32_PPC32_NEW_NODES_H
-
-#include "ppc32_nodes_attr.h"
-
-/***************************************************************************************************
- * _ _ _ __ _ _ _ _
- * | | | | | | / / | | | | | | | |
- * __ _| |_| |_ _ __ ___ ___| |_ / /_ _ ___| |_ _ __ ___ ___| |_| |__ ___ __| |___
- * / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
- * | (_| | |_| |_| | \__ \ __/ |_ / / (_| | __/ |_ | | | | | | __/ |_| | | | (_) | (_| \__ \
- * \__,_|\__|\__|_| |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
- * __/ |
- * |___/
- ***************************************************************************************************/
-
-/**
- * Returns the attributes of an ppc node.
- */
-ppc32_attr_t *get_ppc32_attr(ir_node *node);
-const ppc32_attr_t *get_ppc32_attr_const(const ir_node *node);
-
-/**
- * Returns the argument register requirements of an ppc node.
- */
-const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node);
-
-/**
- * Returns the argument register requirements of an ppc node.
- */
-const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos);
-
-/**
- * Sets the IN register requirements at position pos.
- */
-void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos);
-
-ppc32_attr_content_type get_ppc32_type(const ir_node *node);
-
-void set_ppc32_constant_tarval(ir_node *node, tarval *const_tarval);
-tarval *get_ppc32_constant_tarval(const ir_node *node);
-
-void set_ppc32_symconst_ident(ir_node *node, ident *symconst_ident);
-ident *get_ppc32_symconst_ident(const ir_node *node);
-
-void set_ppc32_frame_entity(ir_node *node, ir_entity *ent);
-ir_entity *get_ppc32_frame_entity(const ir_node *node);
-
-void set_ppc32_rlwimi_const(ir_node *node, unsigned shift, unsigned maskA, unsigned maskB);
-const rlwimi_const_t *get_ppc32_rlwimi_const(const ir_node *node);
-
-void set_ppc32_proj_nr(ir_node *node, int proj_nr);
-int get_ppc32_proj_nr(const ir_node *node);
-
-void set_ppc32_offset(ir_node *node, int offset);
-int get_ppc32_offset(const ir_node *node);
-
-void set_ppc32_offset_mode(ir_node *node, ppc32_attr_offset_mode mode);
-ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node);
-
-void ppc32_register_additional_opcodes(int opcode_num);
-
-/* Include the generated headers */
-#include "gen_ppc32_new_nodes.h"
-
-#endif
+++ /dev/null
-/*
- * 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 ppc32 node attributes
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_NODES_ATTR_H
-#define FIRM_BE_PPC32_PPC32_NODES_ATTR_H
-
-#include "irnode_t.h"
-#include "../bearch.h"
-
-typedef struct
-{
- unsigned shift:5;
- unsigned maskA:5;
- unsigned maskB:5;
-} rlwimi_const_t;
-
-
-typedef enum {
- ppc32_ac_None,
- ppc32_ac_Const,
- ppc32_ac_SymConst,
- ppc32_ac_FrameEntity,
- ppc32_ac_RlwimiConst,
- ppc32_ac_BranchProj,
- ppc32_ac_Offset
-} ppc32_attr_content_type;
-
-typedef enum {
- ppc32_ao_None, ppc32_ao_Lo16, ppc32_ao_Hi16, ppc32_ao_Ha16, ppc32_ao_Illegal
-} ppc32_attr_offset_mode;
-
-typedef struct _ppc32_attr_t {
- except_attr exc; /**< the exception attribute. MUST be the first one. */
-
- const arch_register_req_t **in_req; /**< register requirements for arguments */
-
- ppc32_attr_content_type content_type;
- ppc32_attr_offset_mode offset_mode;
- union {
- tarval *constant_tarval;
- ident *symconst_ident;
- ir_entity *frame_entity;
- rlwimi_const_t rlwimi_const;
- int proj_nr;
- int offset;
- void* empty;
- } data;
-
-} ppc32_attr_t;
-
-#endif
+++ /dev/null
-# Creation: 2006/02/13
-# $Id$
-
-# the cpu architecture (ia32, ia64, mips, sparc, ppc32, ...)
-
-$arch = "ppc32";
-
-# register types:
-# 0 - no special type
-# 1 - caller save (register must be saved by the caller of a function)
-# 2 - callee save (register must be saved by the called function)
-# 4 - ignore (do not assign this register)
-# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
-%reg_classes = (
- gp => [
- { name => "r0", type => 1 },
- { name => "r2", type => 1 },
- { name => "r3", type => 1 },
- { name => "r4", type => 1 },
- { name => "r5", type => 1 },
- { name => "r6", type => 1 },
- { name => "r7", type => 1 },
- { name => "r8", type => 1 },
- { name => "r9", type => 1 },
- { name => "r10", type => 1 },
-# { name => "r11", type => 1 },
-# { name => "r12", type => 1 },
- { name => "r13", type => 2 },
- { name => "r14", type => 2 },
- { name => "r15", type => 2 },
-# { name => "r16", type => 2 },
-# { name => "r17", type => 2 },
-# { name => "r18", type => 2 },
-# { name => "r19", type => 2 },
-# { name => "r20", type => 2 },
-# { name => "r21", type => 2 },
-# { name => "r22", type => 2 },
-# { name => "r23", type => 2 },
-# { name => "r24", type => 2 },
-# { name => "r25", type => 2 },
-# { name => "r26", type => 2 },
-# { name => "r27", type => 2 },
-# { name => "r28", type => 2 },
-# { name => "r29", type => 2 },
-# { name => "r30", type => 2 },
- { name => "r31", type => 2 },
- { name => "r1", type => 6 }, # this is our stackpointer
- { "mode" => "mode_P" }
- ],
- fp => [
-# { name => "f0", type => 1 }, # => reserved for FP Perm
- { name => "f1", type => 1 },
- { name => "f2", type => 1 },
- { name => "f3", type => 1 },
- { name => "f4", type => 1 },
- { name => "f5", type => 1 },
- { name => "f6", type => 1 },
- { name => "f7", type => 1 },
- { name => "f8", type => 1 },
- { name => "f9", type => 1 },
- { name => "f10", type => 1 },
- { name => "f11", type => 1 },
- { name => "f12", type => 1 },
- { name => "f13", type => 1 },
- { name => "f14", type => 2 },
- { name => "f15", type => 2 },
- { name => "f16", type => 2 },
-# { name => "f17", type => 2 },
-# { name => "f18", type => 2 },
-# { name => "f19", type => 2 },
-# { name => "f20", type => 2 },
-# { name => "f21", type => 2 },
-# { name => "f22", type => 2 },
-# { name => "f23", type => 2 },
-# { name => "f24", type => 2 },
-# { name => "f25", type => 2 },
-# { name => "f26", type => 2 },
-# { name => "f27", type => 2 },
-# { name => "f28", type => 2 },
-# { name => "f29", type => 2 },
-# { name => "f30", type => 2 },
-# { name => "f31", type => 2 },
- { mode => "mode_D" }
- ],
- condition => [
- { name => "cr0", type => 1 },
- { name => "cr1", type => 1 },
- { name => "cr2", type => 2 },
- { name => "cr3", type => 2 },
- { name => "cr4", type => 2 },
- { name => "cr5", type => 1 },
- { name => "cr6", type => 1 },
-# { name => "cr7", type => 1 }, # => reserved for Condition Perm
- { mode => "mode_P" } # real mode is 4 bit, but doesn't matter ...
- ],
- link => [
- { name => "lr", type => 4 }, # 3
- { mode => "mode_P" }
- ],
- count => [
- { name => "ctr", type => 1 },
- { mode => "mode_P" }
- ]
-); # %reg_classes
-
-%emit_templates = (
- S0 => "${arch}_emit_source_register(node, 0);",
- S1 => "${arch}_emit_source_register(node, 1);",
- S2 => "${arch}_emit_source_register(node, 2);",
- D0 => "${arch}_emit_dest_register(node, 0);",
- D1 => "${arch}_emit_dest_register(node, 1);",
- D2 => "${arch}_emit_dest_register(node, 2);",
- O => "${arch}_emit_offset(node);",
- C => "${arch}_emit_immediate(node);",
- RLWIMI => "${arch}_emit_rlwimi_helper(node);",
-);
-
-$default_cmp_attr = "NULL";
-
-#--------------------------------------------------#
-# _ #
-# (_) #
-# _ __ _____ __ _ _ __ ___ _ __ ___ #
-# | '_ \ / _ \ \ /\ / / | | '__| / _ \| '_ \/ __| #
-# | | | | __/\ V V / | | | | (_) | |_) \__ \ #
-# |_| |_|\___| \_/\_/ |_|_| \___/| .__/|___/ #
-# | | #
-# |_| #
-#--------------------------------------------------#
-
-%nodes = (
-
-#-----------------------------------------------------------------#
-# _ _ _ #
-# (_) | | | | #
-# _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ #
-# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
-# | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ #
-# |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ #
-# __/ | #
-# |___/ #
-#-----------------------------------------------------------------#
-
-# commutative operations
-
-Add => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Add: Add(a, b) = Add(b, a) = a + b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. add %D0, %S0, %S1',
-},
-
-Addi => {
- irn_flags => "R",
- comment => "construct Add: Addi(a, const) = Addi(const, a) = a + const",
- reg_req => { in => [ "!r0" ], out => [ "gp" ] },
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. addi %D0, %S0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Mullw => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Mul: Mullw(a, b) = Mullw(b, a) = lo32(a * b)",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. mullw %D0, %S0, %S1',
-},
-
-Mulhw => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Mul: Mulhw(a, b) = Mulhw(b, a) = hi32(a * b)",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. mulhw %D0, %S0, %S1',
-},
-
-Mulhwu => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Mul: Mulhwu(a, b) = Mulhwu(b, a) = hi32(a * b)",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. mulhwu %D0, %S0, %S1',
-},
-
-#Mul_i => {
-# irn_flags => "R",
-# comment => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. mul %S0, %C, %D0',
-#},
-
-And => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct And: And(a, b) = And(b, a) = a AND b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. and %D0, %S0, %S1',
-},
-
-#And_i => {
-# irn_flags => "R",
-# comment => "construct And: And(a, const) = And(const, a) = a AND const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. and %S0, %C, %D0',
-#},
-
-Or => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Or: Or(a, b) = Or(b, a) = a OR b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. or %D0, %S0, %S1',
-},
-
-#Or_i => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct Or: Or(a, const) = Or(const, a) = a OR const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. or %S0, %C, %D0',
-#},
-
-Xor => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct Xor: Xor(a, b) = Xor(b, a) = a XOR b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. xor %D0, %S0, %S1',
-},
-
-#Xor_i => {
-# irn_flags => "R",
-# comment => "construct Xor: Xor(a, const) = Xor(const, a) = a EOR const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. xor %S0, %C, %D0',
-#},
-
-# not commutative operations
-
-Sub => {
- irn_flags => "R",
- comment => "construct Sub: Sub(a, b) = a - b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. sub %D0, %S0, %S1',
-},
-
-#Sub_i => {
-# irn_flags => "R",
-# comment => "construct Sub: Sub(a, const) = a - const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. subl %S0, %C, %D0',
-#},
-
-Slw => {
- irn_flags => "R",
- comment => "construct Shl: Shl(a, b) = a << b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. slw %D0, %S0, %S1',
-},
-
-#Shl_i => {
-# irn_flags => "R",
-# comment => "construct Shl: Shl(a, const) = a << const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. shl %S0, %C, %D0',
-#},
-
-Srw => {
- irn_flags => "R",
- comment => "construct Shr: Srw(a, b): c = a >> b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. srw %D0, %S0, %S1',
-},
-
-#Shr_i => {
-# irn_flags => "R",
-# comment => "construct Shr: Shr(a, const) = a >> const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. shr %S0, %C, %D0',
-#},
-
-Sraw => {
- irn_flags => "R",
- comment => "construct Shrs: Sraw(a, b): c = a >> b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. sraw %D0, %S0, %S1',
-},
-
-Srawi => {
- irn_flags => "R",
- comment => "construct Shrs: Srawi(a, const): c = a >> const",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. sraw %D0, %S0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-
-},
-
-Rlwnm => {
- irn_flags => "R",
- comment => "construct ???: Rlwnm(a, b): c = a ROTL b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. rlwnm %D0, %S0, %S1',
-},
-
-Rlwinm => {
- irn_flags => "R",
- comment => "construct ???: Rlwinm(a, b_const, c_const, d_const): (m = MASK(c, d)) e = (a ROTL b) & m",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. rlwinm %D0, %S0, %RLWIMI',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Neg => {
- irn_flags => "R",
- comment => "construct Minus: Neg(a) = -a",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. neg %D0, %S0',
-},
-
-Not => {
- irn_flags => "R",
- comment => "construct Not: Not(a) = !a",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. nor %D0, %S0, %S0',
-},
-
-Extsb => {
- irn_flags => "R",
- comment => "construct Sign extension of byte: Extsb(char a) = (int) a",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. extsb %D0, %S0',
-},
-
-Extsh => {
- irn_flags => "R",
- comment => "construct Sign extension of halfword: Extsh(char a) = (short) a",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. extsh %D0, %S0',
-},
-
-Divw => {
- irn_flags => "R",
- comment => "construct Div (signed): Div(a, b) = a div b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. divw %D0, %S0, %S1',
-},
-
-Divwu => {
- irn_flags => "R",
- comment => "construct Div (unsigned): Div(a, b) = a div b",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. divwu %D0, %S0, %S1',
-},
-
-Mtctr => {
- irn_flags => "R",
- comment => "construct Mtctr: Ctr = a",
- reg_req => { in => [ "gp" ], out => [ "count" ] },
- emit => '. mtctr %S0',
-},
-
-
-# other operations
-
-Const => {
- op_flags => "c",
- irn_flags => "R",
- comment => "Const (high-level node)",
- reg_req => { out => [ "gp" ] },
- cmp_attr =>
-'
- return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
-',
-},
-
-fConst => {
- op_flags => "c",
- irn_flags => "R",
- comment => "float Const (high-level node)",
- reg_req => { out => [ "fp" ] },
- cmp_attr =>
-'
- return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
-',
-},
-
-SymConst => {
- op_flags => "c",
- irn_flags => "R",
- comment => "SymConst (high-level node)",
- reg_req => { out => [ "gp" ] },
- cmp_attr =>
-'
- return attr_a->data.constant_tarval != attr_b->data.constant_tarval;
-',
-},
-
-Unknown => {
- op_flags => "c",
- irn_flags => "R",
- comment => "construct unknown register",
- reg_req => { out => [ "gp" ] },
- emit => '. \t\t /* use %D0 as uninitialized value */',
- cmp_attr =>
-'
- return 1;
-',
-},
-
-fUnknown => {
- op_flags => "c",
- irn_flags => "R",
- comment => "construct unknown float register",
- reg_req => { out => [ "fp" ] },
- emit => '. \t\t /* use %D0 as uninitialized value */',
- cmp_attr =>
-'
- return 1;
-',
-},
-
-cUnknown => {
- op_flags => "c",
- irn_flags => "R",
- comment => "construct unknown condition register",
- reg_req => { out => [ "condition" ] },
- emit => '. \t\t /* use %D0 as uninitialized value */',
- cmp_attr =>
-'
- return 1;
-',
-},
-
-Addi_zero => {
- op_flags => "c",
- irn_flags => "R",
- comment => "load constant (16bit with sign extension)",
- reg_req => { out => [ "gp" ] },
- emit => '. addi %D0, 0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Branch => {
- op_flags => "L|X|Y",
- comment => "branch somewhere",
- reg_req => { in => [ "condition" ], out => [ "none", "none" ] },
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-LoopCopy => {
- irn_flags => "R",
- comment => "construct LoopCopy(src, dest, count, mem): Copy count words from src to dest",
- reg_req => { in => [ "gp", "gp", "count", "none" ], out => [ "none", "in_r1", "in_r2", "in_r3", "gp" ] },
-},
-
-Switch => {
- op_flags => "L|X|Y",
- comment => "construct Switch(selector): Jump to whatever",
- reg_req => { in => [ "gp", "gp", "condition" ], out => [ "none" ] },
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Addis_zero => {
- op_flags => "c",
- irn_flags => "R",
- comment => "load the constant to higher 16 bit of register",
- reg_req => { out => [ "gp" ] },
- emit => '. addis %D0, 0, %C',
- "attr" => "ppc32_attr_offset_mode om, tarval *tv, ident *id",
- "init_attr" =>
-'
- attr->offset_mode = om;
- if (tv) {
- attr->content_type = ppc32_ac_Const;
- attr->data.constant_tarval = tv;
- }
- else if (id) {
- attr->content_type = ppc32_ac_SymConst;
- attr->data.symconst_ident = id;
- }
-',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Ori => {
- irn_flags => "R",
- comment => "ors constant with register",
- reg_req => { in => [ "gp"], out => [ "gp" ] },
- emit => '. ori %D0, %S0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Andi_dot => {
- irn_flags => "R",
- comment => "ands constant with register with cr0 update",
- reg_req => { in => [ "gp"], out => [ "gp", "cr0" ] },
- emit => '. andi. %D0, %S0,%C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Cmp => {
- irn_flags => "R",
- comment => "construct Cmp: Cmp(a, b) = Flags in crX",
- reg_req => { in => [ "gp", "gp" ], out => [ "condition" ] },
- emit => '. cmp %D0, 0, %S0, %S1',
-},
-
-Cmpi => {
- irn_flags => "R",
- comment => "construct Cmp immediate: Cmpi(a, const) = Flags in crX",
- reg_req => { in => [ "gp" ], out => [ "condition" ] },
- emit => '. cmpi %D0, 0, %S0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-Cmpl => {
- irn_flags => "R",
- comment => "construct Cmp logical: Cmpl(a, b) = Flags in crX",
- reg_req => { in => [ "gp", "gp" ], out => [ "condition" ] },
- emit => '. cmpl %D0, 0, %S0, %S1',
-},
-
-Cmpli => {
- irn_flags => "R",
- comment => "construct Cmp logical immediate: Cmpli(a, const) = Flags in crX",
- reg_req => { in => [ "gp" ], out => [ "condition" ] },
- emit => '. cmpli %D0, 0, %S0, %C',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
-},
-
-
-# Load / Store
-
-Lbz => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct Load (byte unsigned): Load(ptr, mem) = LD ptr -> reg",
- reg_req => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
- emit => '. lbz %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Lhz => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct Load (halfword unsigned): Load(ptr, mem) = LD ptr -> reg",
- reg_req => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
- emit => '. lhz %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Lha => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct Load (halfword signed): Load(ptr, mem) = LD ptr -> reg",
- reg_req => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
- emit => '. lha %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Lwz => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct Load (word): Load(ptr, mem) = LD ptr -> reg",
- reg_req => { in => [ "!r0", "none" ], out => [ "gp", "none" ] },
- emit => '. lwz %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Lwzu => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct Load with update (word): Load(ptr, mem) = LD ptr -> reg",
- reg_req => { in => [ "!r0", "none" ], out => [ "gp", "in_r1", "none"] },
- emit => '. lwzu %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "ptr", "M" ],
-},
-
-Stb => {
- op_flags => "L|F",
- state => "exc_pinned",
- comment => "construct Store: Store (byte) (ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
- emit => '. stb %S1, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "M" ],
-},
-
-Sth => {
- op_flags => "L|F",
- state => "exc_pinned",
- comment => "construct Store: Store (halfword) (ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
- emit => '. sth %S1, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "M" ],
-},
-
-Stw => {
- op_flags => "L|F",
- state => "exc_pinned",
- comment => "construct Store: Store (word) (ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "!r0", "gp", "none" ], out => [ "none" ] },
- emit => '. stw %S1, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "M" ],
-},
-
-#--------------------------------------------------------#
-# __ _ _ _ #
-# / _| | | | | | #
-# | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ #
-# | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
-# | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ #
-# |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
-#--------------------------------------------------------#
-
-# commutative operations
-
-fAdd => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fadd %D0, %S0, %S1',
-},
-
-fAdds => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct FP Add (single): Add(a, b) = Add(b, a) = a + b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fadds %D0, %S0, %S1',
-},
-
-fMul => {
- op_flags => "C",
- comment => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fmul %D0, %S0, %S1',
-},
-
-fMuls => {
- op_flags => "C",
- comment => "construct FP Mul (single): Mul(a, b) = Mul(b, a) = a * b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fmuls %D0, %S0, %S1',
-},
-
-fNeg => {
- comment => "construct FP Negation: fNeg(a) = -a",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit => '. fneg %D0, %S0',
-},
-
-fMax => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fmax %S0, %S1, %D0',
-},
-
-fMin => {
- op_flags => "C",
- irn_flags => "R",
- comment => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fmin %S0, %S1, %D0',
-},
-
-# not commutative operations
-
-fSub => {
- irn_flags => "R",
- comment => "construct FP Sub: Sub(a, b) = a - b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fsub %D0, %S0, %S1',
-},
-
-fSubs => {
- irn_flags => "R",
- comment => "construct FP Sub (single): Sub(a, b) = a - b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fsubs %D0, %S0, %S1',
-},
-
-fDiv => {
- comment => "construct FP Div: Div(a, b) = a / b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fdiv %D0, %S0, %S1',
-},
-
-fDivs => {
- comment => "construct FP Div (single): Div(a, b) = a / b",
- reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fdivs %D0, %S0, %S1',
-},
-
-fMinus => {
- irn_flags => "R",
- comment => "construct FP Minus: fMinus(a) = -a",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit => '. fneg %D0, %S0',
-},
-
-fCtiw => {
- irn_flags => "R",
- comment => "construct FP Convert to integer word: fCtiw(a) = (int) a",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit => '. fctiw %D0, %S0',
-},
-
-fRsp => {
- irn_flags => "R",
- comment => "construct FP Round to single: fRsp(a) = (float) a",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit => '. frsp %D0, %S0',
-},
-
-fAbs => {
- irn_flags => "R",
- comment => "construct FP Abs: fAbs(a) = |a|",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit => '. fabs %D0, %S0',
-},
-
-fCmpu => {
- irn_flags => "R",
- comment => "construct FP Cmp unordered: fCmpu(a, b) = a ? b",
- reg_req => { in => [ "fp", "fp" ], out => [ "condition" ] },
- emit => '. fcmpu %D0, %S0, %S1',
-},
-
-# other operations
-
-#fConst => {
-# op_flags => "c",
-# irn_flags => "R",
-# comment => "represents a FP constant",
-# reg_req => { out => [ "fp" ] },
-# emit => '. fmov %C, %D0',
-# cmp_attr =>
-#'
-# /* TODO: compare fConst attributes */
-# return 1;
-#',
-#},
-
-fUnknown => {
- op_flags => "c",
- irn_flags => "R",
- comment => "construct unknown floating point register",
- reg_req => { out => [ "fp" ] },
- emit => '. \t\t /* use %D0 as uninitialized value */',
- cmp_attr =>
-'
- return 1;
-',
-},
-
-# Load / Store
-
-Lfd => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct FP Load (double): Load(ptr, mem) = LD ptr",
- reg_req => { in => [ "!r0", "none" ], out => [ "fp", "none" ] },
- emit => '. lfd %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Lfs => {
- op_flags => "L|F",
- irn_flags => "R",
- state => "exc_pinned",
- comment => "construct FP Load (single): Load(ptr, mem) = LD ptr",
- reg_req => { in => [ "!r0", "none" ], out => [ "fp","none" ] },
- emit => '. lfs %D0, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "res", "M" ],
-},
-
-Stfd => {
- op_flags => "L|F",
- state => "exc_pinned",
- comment => "construct Store (double): Store(ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "!r0", "fp", "none" ], out => [ "none" ] },
- emit => '. stfd %S1, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "M" ],
-},
-
-Stfs => {
- op_flags => "L|F",
- state => "exc_pinned",
- comment => "construct Store (single): Store(ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "!r0", "fp", "none" ], out => [ "none" ] },
- emit => '. stfs %S1, %O(%S0)',
- cmp_attr =>
-'
- return (attr_a->data.constant_tarval != attr_b->data.constant_tarval);
-',
- outs => [ "M" ],
-},
-
-); # end of %nodes
+++ /dev/null
-/*
- * 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 The codegenerator (transform FIRM into ppc FIRM)
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irmode_t.h"
-#include "irgmod.h"
-#include "iredges.h"
-#include "iredges_t.h"
-#include "irvrfy.h"
-#include "ircons.h"
-#include "iropt_t.h"
-#include "irprintf.h"
-#include "debug.h"
-#include "error.h"
-
-#include "../benode.h"
-#include "bearch_ppc32_t.h"
-
-#include "ppc32_nodes_attr.h"
-#include "ppc32_transform.h"
-#include "ppc32_new_nodes.h"
-#include "ppc32_map_regs.h"
-
-#include "gen_ppc32_regalloc_if.h"
-
-extern ir_op *get_op_Mulh(void);
-
-ir_mode* ppc32_mode_Cond = NULL;
-
-/**
- * Returns the proj of a given node with the given proj number
- */
-static inline ir_node *get_succ_Proj(ir_node *node, long proj)
-{
- const ir_edge_t *edge;
- foreach_out_edge(node, edge)
- {
- if (is_Proj(edge->src) && get_Proj_proj(edge->src) == proj)
- return edge->src;
- }
- return NULL;
-}
-
-/**
- * Returns a singleton condition mode
- */
-static ir_mode *get_ppc32_mode_Cond(void)
-{
- if (ppc32_mode_Cond)
- return ppc32_mode_Cond;
- else {
- ppc32_mode_Cond = new_ir_mode("mode_Cond", irms_int_number, 4, 0, irma_none, 0);
- return ppc32_mode_Cond;
- }
-}
-
-/**
- * Calculates the ppc32_modecode with size, sort and signed attributes
- */
-ppc32_modecode get_nice_modecode(ir_mode *irmode)
-{
- ppc32_modecode mode = irm_max;
- int sign = mode_is_signed(irmode);
- int bits = get_mode_size_bits(irmode);
- if (mode_is_int(irmode))
- {
- switch (bits)
- {
- case 8:
- mode = sign ? irm_Bs : irm_Bu;
- break;
- case 16:
- mode = sign ? irm_Hs : irm_Hu;
- break;
- case 32:
- mode = sign ? irm_Is : irm_Iu;
- break;
- }
- }
- else if (mode_is_float(irmode))
- {
- switch (bits)
- {
- case 32:
- mode = irm_F;
- break;
- case 64:
- mode = irm_D;
- break;
- }
- }
- else if (mode_is_reference(irmode))
- {
- switch (bits)
- {
- case 32:
- mode = irm_P;
- break;
- }
- }
- return mode;
-}
-
-/**
- * Returns true, if the given node is a Const node and it's value fits into
- * a signed 16-bit variable
- */
-static int is_16bit_signed_const(ir_node *node)
-{
- tarval *tv_const;
-
- if (!is_ppc32_Const(node)) return 0;
-
- tv_const = get_ppc32_constant_tarval(node);
-
- switch (get_nice_modecode(get_irn_mode(node)))
- {
- case irm_Bu:
- case irm_Bs:
- case irm_Hs:
- return 1;
- case irm_Iu:
- case irm_P:
- {
- unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
- unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
- if (val2 || val3)
- return 0;
-
- // fall through
- }
- case irm_Hu:
- {
- unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
- if (val1&0x80)
- return 0;
- return 1;
- }
-
- case irm_Is:
- {
- unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
- unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
- if (val2==0 && val3==0)
- {
- unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
- if (val1&0x80)
- return 0;
- return 1;
- }
- if (!(val2==0xff && val3==0xff))
- {
- unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
- if (!(val1&0x80))
- return 0;
- return 1;
- }
- return 0;
- }
- default:
- panic("is_16bit_signed_const(): Mode not supported: %F", get_irn_mode(node));
- }
-}
-
-/**
- * Returns true, if the given node is a Const node and it's value fits into
- * a unsigned 16-bit variable
- */
-static int is_16bit_unsigned_const(ir_node *node)
-{
- tarval *tv_const;
-
- if (!is_ppc32_Const(node)) return 0;
-
- tv_const = get_ppc32_constant_tarval(node);
- switch (get_nice_modecode(get_irn_mode(node)))
- {
- case irm_Bu:
- case irm_Bs:
- case irm_Hs:
- case irm_Hu:
- return 1;
- case irm_Iu:
- case irm_P:
- case irm_Is:
- {
- unsigned char val2 = get_tarval_sub_bits(tv_const, 2);
- unsigned char val3 = get_tarval_sub_bits(tv_const, 3);
- if (val2 || val3)
- return 0;
- return 1;
- }
- default:
- panic("is_16bit_unsigned_const(): Mode not supported: %F", get_irn_mode(node));
- }
-}
-
-
-/****************************************************************************************************
- * _ _ __ _ _
- * | | | | / _| | | (_)
- * _ __ ___ __| | ___ | |_ _ __ __ _ _ __ ___| |_ ___ _ __ _ __ ___ __ _| |_ _ ___ _ __
- * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __| _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
- * | | | | (_) | (_| | __/ | |_| | | (_| | | | \__ \ || (_) | | | | | | | | (_| | |_| | (_) | | | |
- * |_| |_|\___/ \__,_|\___| \__|_| \__,_|_| |_|___/_| \___/|_| |_| |_| |_|\__,_|\__|_|\___/|_| |_|
- *
- ****************************************************************************************************/
-
-/**
- * Creates an ppc Add.
- *
- * @param env The transformation environment
- * @return the created ppc Add node
- */
-static ir_node *gen_Add(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Add_left(env->irn);
- ir_node *op2 = get_Add_right(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- return new_bd_ppc32_fAdd(env->dbg, env->block, op1, op2, env->mode);
- case irm_F:
- return new_bd_ppc32_fAdds(env->dbg, env->block, op1, op2, env->mode);
- case irm_Is:
- case irm_Iu:
- case irm_Hs:
- case irm_Hu:
- case irm_Bs:
- case irm_Bu:
- case irm_P:
- if (is_16bit_signed_const(op1))
- {
- ir_node *addnode = new_bd_ppc32_Addi(env->dbg, env->block, op2, env->mode);
- set_ppc32_constant_tarval(addnode, get_ppc32_constant_tarval(op1));
- set_ppc32_offset_mode(addnode, ppc32_ao_None);
- return addnode;
- }
- if (is_16bit_signed_const(op2))
- {
- ir_node *addnode = new_bd_ppc32_Addi(env->dbg, env->block, op1, env->mode);
- set_ppc32_constant_tarval(addnode, get_ppc32_constant_tarval(op2));
- set_ppc32_offset_mode(addnode, ppc32_ao_None);
- return addnode;
- }
-
- return new_bd_ppc32_Add(env->dbg, env->block, op1, op2, env->mode);
-
- default:
- panic("Mode for Add not supported: %F", env->mode);
- }
-}
-
-/**
- * Creates an ppc Mul.
- *
- * @param env The transformation environment
- * @return the created ppc Mul node
- */
-static ir_node *gen_Mul(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Mul_left(env->irn);
- ir_node *op2 = get_Mul_right(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- return new_bd_ppc32_fMul(env->dbg, env->block, op1, op2, env->mode);
- case irm_F:
- return new_bd_ppc32_fMuls(env->dbg, env->block, op1, op2, env->mode);
- case irm_Is:
- case irm_Iu:
- case irm_Hs:
- case irm_Hu:
- case irm_Bs:
- case irm_Bu:
- return new_bd_ppc32_Mullw(env->dbg, env->block, op1, op2, env->mode);
-
- case irm_P:
- default:
- panic("Mode for Mul not supported: %F", env->mode);
- }
-}
-
-/**
- * Creates an ppc Mulh.
- *
- * @param env The transformation environment
- * @return the created ppc Mulh node
- */
-static ir_node *gen_Mulh(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_irn_n(env->irn, 0);
- ir_node *op2 = get_irn_n(env->irn, 1);
-
- switch (get_nice_modecode(env->mode)){
- case irm_Is:
- case irm_Hs:
- case irm_Bs:
- return new_bd_ppc32_Mulhw(env->dbg, env->block, op1, op2, env->mode);
-
- case irm_Iu:
- case irm_Hu:
- case irm_Bu:
- return new_bd_ppc32_Mulhwu(env->dbg, env->block, op1, op2, env->mode);
-
- case irm_D:
- case irm_F:
- case irm_P:
- default:
- panic("Mode for Mulh not supported: %F", env->mode);
- }
-}
-
-/**
- * Creates an ppc And.
- *
- * @param env The transformation environment
- * @return the created ppc And node
- */
-static ir_node *gen_And(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_And_left(env->irn);
- ir_node *op2 = get_And_right(env->irn);
-
- return new_bd_ppc32_And(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Or.
- *
- * @param env The transformation environment
- * @return the created ppc Or node
- */
-static ir_node *gen_Or(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Or_left(env->irn);
- ir_node *op2 = get_Or_right(env->irn);
-
- return new_bd_ppc32_Or(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Xor.
- *
- * @param env The transformation environment
- * @return the created ppc Xor node
- */
-static ir_node *gen_Eor(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Eor_left(env->irn);
- ir_node *op2 = get_Eor_right(env->irn);
-
- return new_bd_ppc32_Xor(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Sub.
- *
- * @param env The transformation environment
- * @return the created ppc Sub node
- */
-static ir_node *gen_Sub(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Sub_left(env->irn);
- ir_node *op2 = get_Sub_right(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- return new_bd_ppc32_fSub(env->dbg, env->block, op1, op2, env->mode);
- case irm_F:
- return new_bd_ppc32_fSubs(env->dbg, env->block, op1, op2, env->mode);
- case irm_Is:
- case irm_Iu:
- case irm_Hs:
- case irm_Hu:
- case irm_Bs:
- case irm_Bu:
- case irm_P:
- return new_bd_ppc32_Sub(env->dbg, env->block, op1, op2, env->mode);
-
- default:
- panic("Mode for Sub not supported: %F", env->mode);
- }
-}
-
-/**
- * Creates an ppc floating Div.
- *
- * @param env The transformation environment
- * @return the created ppc fDiv node
- */
-static ir_node *gen_Quot(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Quot_left(env->irn);
- ir_node *op2 = get_Quot_right(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- return new_bd_ppc32_fDiv(env->dbg, env->block, op1, op2, env->mode);
- case irm_F:
- return new_bd_ppc32_fDivs(env->dbg, env->block, op1, op2, env->mode);
-
- default:
- panic("Mode for Quot not supported: %F", env->mode);
- }
-}
-
-/**
- * Creates an ppc integer Div.
- *
- * @param env The transformation environment
- * @return the created ppc Div node
- */
-static ir_node *gen_Div(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Div_left(env->irn);
- ir_node *op2 = get_Div_right(env->irn);
-
- switch (get_nice_modecode(get_irn_mode(op1))){
- case irm_Is:
- case irm_Hs:
- case irm_Bs:
- return new_bd_ppc32_Divw(env->dbg, env->block, op1, op2, mode_T);
-
- case irm_Iu:
- case irm_Hu:
- case irm_Bu:
- return new_bd_ppc32_Divwu(env->dbg, env->block, op1, op2, mode_T);
-
- default:
- panic("Mode for Div not supported: %F", get_irn_mode(op1));
- }
-}
-
-/**
- * Creates an ppc integer Div and Mod.
- *
- * @param env The transformation environment
- * @return the created ppc Div node
- */
-static ir_node *gen_DivMod(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_DivMod_left(env->irn);
- ir_node *op2 = get_DivMod_right(env->irn);
- ir_node *proj_div = NULL, *proj_mod = NULL;
- ir_node *div_result;
- const ir_edge_t *edge;
- ir_mode *res_mode;
-
- foreach_out_edge(env->irn, edge)
- {
- if (is_Proj(edge->src))
- {
- switch (get_Proj_proj(edge->src)){
- case pn_DivMod_res_div:
- proj_div = edge->src;
- break;
- case pn_DivMod_res_mod:
- proj_mod = edge->src;
- break;
- default:
- break;
- }
- }
- }
-
- assert(proj_div!=NULL || proj_mod!=NULL);
-
- res_mode = get_irn_mode(proj_div);
-
- switch (get_nice_modecode(res_mode))
- {
- case irm_Is:
- case irm_Hs:
- case irm_Bs:
- div_result = new_bd_ppc32_Divw(env->dbg, env->block, op1, op2, mode_T);
- break;
-
- case irm_Iu:
- case irm_Hu:
- case irm_Bu:
- div_result = new_bd_ppc32_Divwu(env->dbg, env->block, op1, op2, mode_T);
- break;
-
- default:
- panic("Mode for DivMod not supported: %F", res_mode);
- }
-
- if (proj_div == NULL)
- proj_div = new_rd_Proj(env->dbg, div_result, get_irn_mode(proj_mod), pn_DivMod_res_div);
-
- if (proj_mod!=NULL){
- ir_node *mul_result;
- ir_node *mod_result;
-
- mul_result = new_bd_ppc32_Mullw(env->dbg, env->block, proj_div, op2, res_mode);
- mod_result = new_bd_ppc32_Sub(env->dbg, env->block, op1, mul_result, res_mode);
-
- exchange(proj_mod, mod_result);
- }
-
- return div_result;
-}
-
-/**
- * Creates an ppc integer Mod.
- *
- * @param env The transformation environment
- * @return the created ppc Mod result node
- */
-static ir_node *gen_Mod(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Mod_left(env->irn);
- ir_node *op2 = get_Mod_right(env->irn);
- ir_node *proj_div = NULL, *proj_mod = NULL;
- ir_node *div_result;
- ir_mode *res_mode;
- ir_node *mul_result;
- ir_node *mod_result;
-
- proj_mod = get_succ_Proj(env->irn, pn_Mod_res);
-
- assert(proj_mod != NULL);
- res_mode = get_irn_mode(proj_mod);
-
- switch (get_nice_modecode(res_mode))
- {
- case irm_Is:
- case irm_Hs:
- case irm_Bs:
- div_result = new_bd_ppc32_Divw(env->dbg, env->block, op1, op2, mode_T);
- break;
-
- case irm_Iu:
- case irm_Hu:
- case irm_Bu:
- div_result = new_bd_ppc32_Divwu(env->dbg, env->block, op1, op2, mode_T);
- break;
-
- default:
- panic("Mode for Mod not supported: %s\n", get_mode_name(res_mode));
- }
-
- proj_div = new_rd_Proj(env->dbg, div_result, res_mode, pn_DivMod_res_div);
-
- mul_result = new_bd_ppc32_Mullw(env->dbg, env->block, proj_div, op2, res_mode);
- mod_result = new_bd_ppc32_Sub(env->dbg, env->block, op1, mul_result, res_mode);
-
- exchange(proj_mod, mod_result);
-
- return div_result;
-}
-
-/**
- * Creates an ppc Shl.
- *
- * @param env The transformation environment
- * @return the created ppc Shl node
- */
-static ir_node *gen_Shl(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Shl_left(env->irn);
- ir_node *op2 = get_Shl_right(env->irn);
-
- if (is_ppc32_Const(op2))
- {
- ir_node *shift = new_bd_ppc32_Rlwinm(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- int sh = get_tarval_long(tv_const);
- assert(0<=sh && sh<=31);
- set_ppc32_rlwimi_const(shift, sh, 0, 31-sh);
- return shift;
- }
- return new_bd_ppc32_Slw(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Srw.
- *
- * @param env The transformation environment
- * @return the created ppc Shr node
- */
-static ir_node *gen_Shr(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Shr_left(env->irn);
- ir_node *op2 = get_Shr_right(env->irn);
-
- if (is_ppc32_Const(op2))
- {
- ir_node *shift = new_bd_ppc32_Rlwinm(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- int sh = get_tarval_long(tv_const);
- assert(0<=sh && sh<=31);
- set_ppc32_rlwimi_const(shift, 32-sh, sh, 31);
- return shift;
- }
- return new_bd_ppc32_Srw(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Sraw.
- *
- * @param env The transformation environment
- * @return the created ppc Sraw node
- */
-static ir_node *gen_Shrs(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Shrs_left(env->irn);
- ir_node *op2 = get_Shrs_right(env->irn);
-
- if (is_ppc32_Const(op2))
- {
- ir_node *shift = new_bd_ppc32_Srawi(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- int sh = get_tarval_long(tv_const);
- assert(0<=sh && sh<=31);
- (void) sh;
- set_ppc32_constant_tarval(shift, tv_const);
- set_ppc32_offset_mode(shift, ppc32_ao_None);
- return shift;
- }
- return new_bd_ppc32_Sraw(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Rotl.
- *
- * @param env The transformation environment
- * @return the created ppc Rotl node
- */
-static ir_node *gen_Rotl(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Rotl_left(env->irn);
- ir_node *op2 = get_Rotl_right(env->irn);
-
- if (is_ppc32_Const(op2))
- {
- ir_node *rot = new_bd_ppc32_Rlwinm(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- int sh = get_tarval_long(tv_const);
- assert(0<=sh && sh<=31);
- set_ppc32_rlwimi_const(rot, sh, 0, 31);
- return rot;
- }
- return new_bd_ppc32_Rlwnm(env->dbg, env->block, op1, op2, env->mode);
-}
-
-/**
- * Creates an ppc Cmp.
- *
- * @param env The transformation environment
- * @return the created ppc Cmp node
- */
-static ir_node *gen_Cmp(ppc32_transform_env_t *env)
-{
- ir_node *op1 = get_Cmp_left(env->irn);
- ir_node *op2 = get_Cmp_right(env->irn);
-
- const ir_edge_t *edge;
- foreach_out_edge(env->irn, edge)
- {
- if (is_Proj(edge->src))
- set_irn_mode(edge->src, get_ppc32_mode_Cond());
- }
-
- if (mode_is_float(env->mode))
- return new_bd_ppc32_fCmpu(env->dbg, env->block, op1, op2, env->mode);
- else if (mode_is_signed(env->mode))
- {
- if (is_16bit_signed_const(op2))
- {
- ir_node *cmp = new_bd_ppc32_Cmpi(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- set_ppc32_constant_tarval(cmp, tv_const);
- set_ppc32_offset_mode(cmp, ppc32_ao_None);
- return cmp;
- }
- else
- {
- return new_bd_ppc32_Cmp(env->dbg, env->block, op1, op2, env->mode);
- }
- }
- else
- {
- if (is_16bit_unsigned_const(op2))
- {
- ir_node *cmp = new_bd_ppc32_Cmpli(env->dbg, env->block, op1, env->mode);
- tarval *tv_const = get_ppc32_constant_tarval(op2);
- set_ppc32_constant_tarval(cmp, tv_const);
- set_ppc32_offset_mode(cmp, ppc32_ao_None);
-
- return cmp;
- }
- else
- {
- return new_bd_ppc32_Cmpl(env->dbg, env->block, op1, op2, env->mode);
- }
- }
-}
-
-/**
- * Transforms a Minus node.
- *
- * @param env The transformation environment
- * @return the created ppc Minus node
- */
-static ir_node *gen_Minus(ppc32_transform_env_t *env)
-{
- ir_node *op = get_Minus_op(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- case irm_F:
- return new_bd_ppc32_fNeg(env->dbg, env->block, op, env->mode);
- case irm_Is:
- case irm_Iu:
- case irm_Hs:
- case irm_Hu:
- case irm_Bs:
- case irm_Bu:
- case irm_P:
- return new_bd_ppc32_Neg(env->dbg, env->block, op, env->mode);
-
- default:
- panic("Mode for Neg not supported: %F", env->mode);
- }
-}
-
-/**
- * Transforms a Not node.
- *
- * @param env The transformation environment
- * @return the created ppc Not node
- */
-static ir_node *gen_Not(ppc32_transform_env_t *env)
-{
- return new_bd_ppc32_Not(env->dbg, env->block, get_Not_op(env->irn), env->mode);
-}
-
-
-static ir_node *own_gen_Andi_dot_lo16(ppc32_transform_env_t *env, ir_node *op, int mask)
-{
- ir_node *andi = new_bd_ppc32_Andi_dot(env->dbg, env->block, op, mode_T);
- ir_node* in[1];
- set_ppc32_offset_mode(andi, ppc32_ao_Lo16);
- set_ppc32_constant_tarval(andi, new_tarval_from_long(mask, mode_Is));
- in[0] = new_rd_Proj(env->dbg, andi, env->mode,1);
- be_new_Keep(env->block, 1, in);
- return new_rd_Proj(env->dbg, andi, env->mode,0);
-}
-
-/**
- * Transforms a Conv node.
- *
- * @param env The transformation environment
- * @return the created ppc Conv node
- */
-static ir_node *gen_Conv(ppc32_transform_env_t *env)
-{
- ir_node *op = get_Conv_op(env->irn);
- ppc32_modecode from_mode=get_nice_modecode(get_irn_mode(op));
- ppc32_modecode to_mode=get_nice_modecode(env->mode);
-
-#define SKIP return op
-
- if (from_mode == to_mode) SKIP;
-
- switch (from_mode){
- case irm_F:
- switch (to_mode)
- {
- case irm_D: SKIP;
- default:
- break;
- }
- break;
-
- case irm_D:
- switch (to_mode)
- {
- case irm_F:
- return new_bd_ppc32_fRsp(env->dbg, env->block, op, env->mode);
- default:
- break;
- }
- break;
-
- case irm_Is:
- case irm_Iu:
- switch (to_mode)
- {
- case irm_Hs:
- return new_bd_ppc32_Extsh(env->dbg, env->block, op, env->mode);
- case irm_Hu:
- return own_gen_Andi_dot_lo16(env, op, 0xffff);
- case irm_Bs:
- return new_bd_ppc32_Extsb(env->dbg, env->block, op, env->mode);
- case irm_Bu:
- return own_gen_Andi_dot_lo16(env, op, 0xff);
- case irm_Is:
- case irm_Iu:
- SKIP;
- default:
- break;
- }
- break;
-
- case irm_Hs:
- case irm_Hu:
- switch (to_mode)
- {
- case irm_Iu:
- if (from_mode==irm_Hu)
- case irm_Hu:
- return own_gen_Andi_dot_lo16(env, op, 0xffff);
- case irm_Is:
- SKIP;
- case irm_Bs:
- return new_bd_ppc32_Extsb(env->dbg, env->block, op, env->mode);
- case irm_Bu:
- return own_gen_Andi_dot_lo16(env, op, 0xff);
- case irm_Hs:
- return new_bd_ppc32_Extsh(env->dbg, env->block, op, env->mode);
- default:
- break;
- }
- break;
-
- case irm_Bs:
- case irm_Bu:
- switch (to_mode)
- {
- case irm_Iu:
- case irm_Hu:
- if (from_mode==irm_Bs)
- case irm_Bu:
- return own_gen_Andi_dot_lo16(env, op, 0xff);
- case irm_Is:
- case irm_Hs:
- SKIP;
- case irm_Bs:
- return new_bd_ppc32_Extsb(env->dbg, env->block, op, env->mode);
- default:
- break;
- }
- break;
- case irm_P:
- if (to_mode==irm_Is || to_mode==irm_Iu) SKIP;
- break;
- default:
- break;
- }
-
- panic("Mode for Conv not supported: %F -> %F", get_irn_mode(op), env->mode);
-#undef SKIP
-}
-
-/**
- * Transforms an Abs node.
- *
- * @param env The transformation environment
- * @return the ppc node generating the absolute value
- */
-static ir_node *gen_Abs(ppc32_transform_env_t *env)
-{
- ir_node *op = get_Abs_op(env->irn);
- int shift = 7;
- ir_node *n1,*n2;
-
- switch (get_nice_modecode(env->mode))
- {
- case irm_F:
- case irm_D:
- return new_bd_ppc32_fAbs(env->dbg, env->block, op, env->mode);
- case irm_Is:
- shift += 16;
- case irm_Hs:
- shift += 8;
- case irm_Bs:
- n1 = new_bd_ppc32_Srawi(env->dbg, env->block, op, env->mode);
- set_ppc32_constant_tarval(n1, new_tarval_from_long(shift, mode_Is));
- set_ppc32_offset_mode(n1, ppc32_ao_None);
- n2 = new_bd_ppc32_Add(env->dbg, env->block, op, n1, env->mode);
- return new_bd_ppc32_Xor(env->dbg, env->block, n2, n1, env->mode);
- default:
- break;
- }
- panic("Mode for Abs not supported: %F", env->mode);
-}
-
-/**
- * Transforms an Cond node.
- *
- * @param env The transformation environment
- * @return a ppc branch node
- */
-static ir_node *gen_Cond(ppc32_transform_env_t *env)
-{
- ir_node *selector = get_Cond_selector(env->irn);
- ir_mode *projmode = get_irn_mode(selector);
- if (is_Proj(selector) && projmode==get_ppc32_mode_Cond())
- {
- int projnum = get_Proj_proj(selector);
- ir_node *branch = new_bd_ppc32_Branch(env->dbg, env->block, selector, env->mode);
- set_ppc32_proj_nr(branch, projnum);
- return branch;
- }
- else
- {
- ir_node *unknown_gpr = new_bd_ppc32_Unknown(env->dbg, env->block, mode_Is);
- ir_node *unknown_cond = new_bd_ppc32_cUnknown(env->dbg, env->block, get_ppc32_mode_Cond());
-
- ir_node *switch_node = new_bd_ppc32_Switch(env->dbg, env->block, selector,
- unknown_gpr, unknown_cond, env->mode);
- set_ppc32_proj_nr(switch_node, get_Cond_default_proj(env->irn));
-
- return switch_node;
- }
-}
-
-/**
- * Transforms an Unknown node.
- *
- * @param env The transformation environment
- * @return a ppc Unknown node
- */
-static ir_node *gen_Unknown(ppc32_transform_env_t *env)
-{
- if (mode_is_float(env->mode))
- return new_bd_ppc32_fUnknown(env->dbg, env->block, env->mode);
- else if (mode_is_int(env->mode))
- return new_bd_ppc32_Unknown(env->dbg, env->block, env->mode);
- else
- panic("Mode %F for unknown value not supported.", env->mode);
-}
-
-static ir_node *ldst_insert_const(ir_node *ptr, tarval **ptv, ident **pid, ppc32_transform_env_t *env)
-{
- tarval *tv_const = NULL;
- ident *id_symconst = NULL;
-
- if (is_ppc32_Const(ptr))
- {
- tv_const = get_ppc32_constant_tarval(ptr);
- ptr = new_bd_ppc32_Addis_zero(env->dbg, env->block, mode_P, ppc32_ao_Ha16, tv_const, NULL);
- }
- else if (is_ppc32_SymConst(ptr))
- {
-#if 0
- ir_entity *ent = get_ppc32_frame_entity(ptr);
- if (is_direct_entity(ent))
- {
- id_symconst = get_entity_ident(ent);
- ptr = new_bd_ppc32_Addis_zero(env->dbg, env->block, mode_P, ppc32_ao_Ha16, NULL, id_symconst);
- }
-#endif
- }
- *ptv = tv_const;
- *pid = id_symconst;
- return ptr;
-}
-
-/**
- * Transforms a Load.
- *
- * @param env The transformation environment
- * @return the created ppc Load node
- */
-static ir_node *gen_Load(ppc32_transform_env_t *env)
-{
- ir_node *node = env->irn;
- ir_node *loadptr = get_Load_ptr(node);
- ir_node *load;
- ir_mode *mode = get_Load_mode(node);
- tarval *tv_const = NULL;
- ident *id_symconst = NULL;
-
- loadptr = ldst_insert_const(loadptr, &tv_const, &id_symconst, env);
- switch (get_nice_modecode(mode)){
- case irm_Bu:
- load = new_bd_ppc32_Lbz(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
-
- case irm_Bs:
- {
- ir_node *proj_load, *extsb_node;
- load = new_bd_ppc32_Lbz(env->dbg, env->block, loadptr, get_Load_mem(node));
- proj_load = new_rd_Proj(env->dbg, load, mode, pn_Load_res);
- extsb_node = new_bd_ppc32_Extsb(env->dbg, env->block, proj_load, mode);
- exchange(get_succ_Proj(env->irn, pn_Load_res), extsb_node);
- break;
- }
-
-
- case irm_Hu:
- load = new_bd_ppc32_Lhz(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
- case irm_Hs:
- load =new_bd_ppc32_Lha(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
- case irm_Is:
- case irm_Iu:
- case irm_P:
- load = new_bd_ppc32_Lwz(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
-
- case irm_D:
- load = new_bd_ppc32_Lfd(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
- case irm_F:
- load = new_bd_ppc32_Lfs(env->dbg, env->block, loadptr, get_Load_mem(node));
- break;
-
- default:
- panic("Mode for Load not supported: %F", env->mode);
- }
-
- if (tv_const)
- {
- set_ppc32_offset_mode(load, ppc32_ao_Lo16);
- set_ppc32_constant_tarval(load, tv_const);
- }
- else if (id_symconst)
- {
- set_ppc32_offset_mode(load, ppc32_ao_Lo16);
- set_ppc32_symconst_ident(load, id_symconst);
- }
- return load;
-}
-
-
-
-/**
- * Transforms a Store.
- *
- * @param env The transformation environment
- * @return the created ppc Store node
- */
-static ir_node *gen_Store(ppc32_transform_env_t *env)
-{
- ir_node *node = env->irn;
- ir_node *storeptr = get_Store_ptr(node);
- ir_node *valuenode = get_Store_value(node);
- ir_mode *mode = get_irn_mode(valuenode);
- ir_node *store;
- tarval *tv_const = NULL;
- ident *id_symconst = NULL;
-
- storeptr = ldst_insert_const(storeptr, &tv_const, &id_symconst, env);
-
- switch (get_nice_modecode(mode)){
- case irm_Bu:
- case irm_Bs:
- store = new_bd_ppc32_Stb(env->dbg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
- break;
-
- case irm_Hu:
- case irm_Hs:
- store = new_bd_ppc32_Sth(env->dbg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
- break;
- case irm_Is:
- case irm_Iu:
- case irm_P:
- store = new_bd_ppc32_Stw(env->dbg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
- break;
-
- case irm_D:
- store = new_bd_ppc32_Stfd(env->dbg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
- break;
- case irm_F:
- store = new_bd_ppc32_Stfs(env->dbg, env->block, storeptr, get_Store_value(node), get_Store_mem(node));
- break;
-
- default:
- panic("Mode for Store not supported: %F", env->mode);
- }
- if (tv_const)
- {
- set_ppc32_offset_mode(store, ppc32_ao_Lo16);
- set_ppc32_constant_tarval(store, tv_const);
- }
- else if (id_symconst)
- {
- set_ppc32_offset_mode(store, ppc32_ao_Lo16);
- set_ppc32_symconst_ident(store, id_symconst);
- }
- return store;
-}
-
-/**
- * Transforms a CopyB.
- *
- * @param env The transformation environment
- * @return the created ppc CopyB node
- */
-static ir_node *gen_CopyB(ppc32_transform_env_t *env)
-{
- ir_node *mem = get_CopyB_mem(env->irn);
- ir_node *src = get_CopyB_src(env->irn);
- ir_node *dest = get_CopyB_dst(env->irn);
- ir_type *type = get_CopyB_type(env->irn);
- int size = get_type_size_bytes(type);
- int offset = 0;
-
- ir_node *load, *store = NULL;
-
- if (size/4 >= 1)
- {
- ir_node *res;
- tarval *offset0 = new_tarval_from_long(0, mode_Is);
- tarval *offset4 = new_tarval_from_long(4, mode_Is);
-
- load = new_bd_ppc32_Lwz(env->dbg, env->block, src, mem);
- set_ppc32_constant_tarval(load, offset0);
- set_ppc32_offset_mode(load, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, load, mode_M, pn_Load_M);
- res = new_rd_Proj(env->dbg, load, mode_Is, pn_Load_res);
-
- store = new_bd_ppc32_Stw(env->dbg, env->block, dest, res, mem);
- set_ppc32_constant_tarval(store, offset0);
- set_ppc32_offset_mode(store, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, store, mode_M, pn_Store_M);
-
- if (size/4==2)
- {
- load = new_bd_ppc32_Lwz(env->dbg, env->block, src, mem);
- set_ppc32_constant_tarval(load, offset4);
- set_ppc32_offset_mode(load, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, load, mode_M, pn_Load_M);
- res = new_rd_Proj(env->dbg, load, mode_Is, pn_Load_res);
-
- store = new_bd_ppc32_Stw(env->dbg, env->block, dest, res, mem);
- set_ppc32_constant_tarval(store, offset4);
- set_ppc32_offset_mode(store, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, store, mode_M, pn_Store_M);
-
- offset = 8;
- }
- else
- {
- ir_node *ornode, *mtctrnode;
- ir_node* in[3];
- assert(size/4-1<=0xffff);
- if (size/4-1<0x8000)
- {
- ornode = new_bd_ppc32_Addi_zero(env->dbg, env->block, mode_Is);
- set_ppc32_offset_mode(ornode, ppc32_ao_None);
- }
- else
- {
- ir_node *zeroreg = new_bd_ppc32_Addi_zero(env->dbg, env->block, mode_Is);
- set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
- set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
- ornode = new_bd_ppc32_Ori(env->dbg, env->block, zeroreg, mode_Is);
- set_ppc32_offset_mode(ornode, ppc32_ao_Lo16);
- }
-
- set_ppc32_constant_tarval(ornode, new_tarval_from_long(size/4-1, mode_Is));
- mtctrnode = new_bd_ppc32_Mtctr(env->dbg, env->block, ornode, mode_Is);
- store = new_bd_ppc32_LoopCopy(env->dbg, env->block, src, dest, mtctrnode, mem, mode_T);
-
- in[0] = new_rd_Proj(env->dbg, store, mode_Is, 1); // src
- in[1] = new_rd_Proj(env->dbg, store, mode_Is, 2); // dest
- in[2] = new_rd_Proj(env->dbg, store, mode_Is, 4); // temp
- be_new_Keep(env->block, 3, in);
- in[0] = new_rd_Proj(env->dbg, store, mode_Is, 3); // ctr
- be_new_Keep(env->block, 1, in);
-
- mem = new_rd_Proj(env->dbg, store, mode_M, 0);
-
- offset = 4;
- }
- }
-
- if (size & 2)
- {
- ir_node *res;
- tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
- load = new_bd_ppc32_Lhz(env->dbg, env->block, src, mem);
- set_ppc32_constant_tarval(load, offset_tarval);
- set_ppc32_offset_mode(load, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, load, mode_M, pn_Load_M);
- res = new_rd_Proj(env->dbg, load, mode_Is, pn_Load_res);
-
- store = new_bd_ppc32_Sth(env->dbg, env->block, dest, res, mem);
- set_ppc32_constant_tarval(store, offset_tarval);
- set_ppc32_offset_mode(store, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, store, mode_M, pn_Store_M);
-
- offset += 2;
- }
-
- if (size & 1)
- {
- ir_node *res;
- tarval* offset_tarval = new_tarval_from_long(offset, mode_Is);
- load = new_bd_ppc32_Lbz(env->dbg, env->block, src, mem);
- set_ppc32_constant_tarval(load, offset_tarval);
- set_ppc32_offset_mode(load, ppc32_ao_None);
- mem = new_rd_Proj(env->dbg, load, mode_M, pn_Load_M);
- res = new_rd_Proj(env->dbg, load, mode_Is, pn_Load_res);
-
- store = new_bd_ppc32_Stb(env->dbg, env->block, dest, res, mem);
- set_ppc32_constant_tarval(store, offset_tarval);
- set_ppc32_offset_mode(store, ppc32_ao_None);
- // mem = new_rd_Proj(env->dbg, env->irg, store, mode_M, pn_Store_M);
- }
-
- return store;
-}
-
-/**
- * Transforms a FrameAddr into a ppc Add.
- *
- * @param env The transformation environment
- */
-static ir_node *gen_be_FrameAddr(ppc32_transform_env_t *env)
-{
- ir_node *op = get_irn_n(env->irn, 0);
- ir_node *add = new_bd_ppc32_Addi(env->dbg, env->block, op, mode_P);
- set_ppc32_frame_entity(add, be_get_frame_entity(env->irn));
- return add;
-}
-
-
-/*********************************************************
- * _ _ _
- * (_) | | (_)
- * _ __ ___ __ _ _ _ __ __| |_ __ ___ _____ _ __
- * | '_ ` _ \ / _` | | '_ \ / _` | '__| \ \ / / _ \ '__|
- * | | | | | | (_| | | | | | | (_| | | | |\ V / __/ |
- * |_| |_| |_|\__,_|_|_| |_| \__,_|_| |_| \_/ \___|_|
- *
- *********************************************************/
-
-/**
- * the BAD transformer.
- */
-static ir_node *bad_transform(ppc32_transform_env_t *env)
-{
- panic("Transformation not implemented: %+F\n", env->irn);
-}
-
-/**
- * Enters all transform functions into the generic pointer
- */
-void ppc32_register_transformers(void)
-{
- /* first clear the generic function pointer for all ops */
- clear_irp_opcodes_generic_func();
-
-#define FIRM_OP(a) op_##a->ops.generic = (op_func)gen_##a
-#define BAD(a) op_##a->ops.generic = (op_func)bad_transform
-#define IGN(a)
-
- FIRM_OP(Add);
- FIRM_OP(Mul);
- FIRM_OP(Mulh);
- FIRM_OP(And);
- FIRM_OP(Or);
- FIRM_OP(Eor);
-
- FIRM_OP(Sub);
- FIRM_OP(Shl);
- FIRM_OP(Shr);
- FIRM_OP(Shrs);
- FIRM_OP(Rotl);
- FIRM_OP(Quot);
- FIRM_OP(Div);
- FIRM_OP(DivMod);
- FIRM_OP(Mod);
- FIRM_OP(Cmp);
-
- FIRM_OP(Minus);
- FIRM_OP(Not);
- FIRM_OP(Conv);
- FIRM_OP(Abs);
-
- FIRM_OP(Load);
- FIRM_OP(Store);
- FIRM_OP(Cond);
- FIRM_OP(Unknown);
- FIRM_OP(CopyB);
-
- /* TODO: implement these nodes */
- BAD(Mux);
-
- /* You probably don't need to handle the following nodes */
-
- IGN(Call);
- IGN(Proj);
- IGN(Alloc);
-
- IGN(Block);
- IGN(Start);
- IGN(End);
- IGN(NoMem);
- IGN(Phi);
- IGN(IJmp);
- IGN(Jmp);
- IGN(Break);
- IGN(Sync);
-
- BAD(Raise);
- BAD(Sel);
- BAD(InstOf);
- BAD(Cast);
- BAD(Free);
- BAD(Tuple);
- BAD(Id);
- //BAD(Bad);
- BAD(Confirm);
- BAD(Filter);
- BAD(CallBegin);
- BAD(EndReg);
- BAD(EndExcept);
-
- /* handle builtins */
- BAD(Builtin);
-
- /* handle generic backend nodes */
- FIRM_OP(be_FrameAddr);
-}
-
-typedef ir_node *(transform_func)(ppc32_transform_env_t *env);
-
-/**
- * Transforms the given firm node (and maybe some other related nodes)
- * into one or more assembler nodes.
- *
- * @param node the firm node
- * @param env the debug module
- */
-void ppc32_transform_node(ir_node *node, void *env)
-{
- ppc32_code_gen_t *cg = (ppc32_code_gen_t *)env;
- ir_op *op = get_irn_op(node);
- ir_node *asm_node = NULL;
- (void) cg;
-
- if (op == op_Block)
- return;
-
- DBG((cg->mod, LEVEL_1, "check %+F ... ", node));
-
- if (op->ops.generic) {
- ppc32_transform_env_t tenv;
- transform_func *transform = (transform_func *)op->ops.generic;
-
- tenv.block = get_nodes_block(node);
- tenv.dbg = get_irn_dbg_info(node);
- tenv.irg = current_ir_graph;
- tenv.irn = node;
- tenv.mode = get_irn_mode(node);
- DEBUG_ONLY(tenv.mod = cg->mod;)
-
- asm_node = (*transform)(&tenv);
- }
-
- if (asm_node) {
- exchange(node, asm_node);
- DB((cg->mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
- }
- else {
- DB((cg->mod, LEVEL_1, "ignored\n"));
- }
-}
-
-/**
- * Constant generating code
- */
-
-struct tv_ent {
- ir_entity *ent;
- tarval *tv;
-};
-
-/** Compares two (entity, tarval) combinations */
-static int cmp_tv_ent(const void *a, const void *b, size_t len)
-{
- const struct tv_ent *e1 = a;
- const struct tv_ent *e2 = b;
- (void) len;
-
- return !(e1->tv == e2->tv);
-}
-
-/** Generates a SymConst node for a known FP const */
-static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env,
- tarval *known_const)
-{
- static set *const_set = NULL;
- static ir_type *tp = NULL;
- struct tv_ent key;
- struct tv_ent *entry;
- ir_node *cnst,*symcnst;
- ir_graph *rem;
- ir_entity *ent = NULL;
-
- if (!const_set)
- const_set = new_set(cmp_tv_ent, 10);
- if (!tp)
- tp = new_type_primitive(env->mode);
-
- key.tv = known_const;
- key.ent = NULL;
-
- entry = set_insert(const_set, &key, sizeof(key), HASH_PTR(key.tv));
-
- if (!entry->ent) {
- char buf[80];
- sprintf(buf, "const_%ld", get_irn_node_nr(env->irn));
- ent = new_entity(get_glob_type(), new_id_from_str(buf), tp);
-
- set_entity_ld_ident(ent, get_entity_ident(ent));
- set_entity_visibility(ent, ir_visibility_local);
- add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
-
- /* we create a new entity here: It's initialization must resist on the
- const code irg */
- rem = current_ir_graph;
- current_ir_graph = get_const_code_irg();
- cnst = new_Const(key.tv);
- current_ir_graph = rem;
-
- set_atomic_ent_value(ent, cnst);
-
- /* set the entry for hashmap */
- entry->ent = ent;
- } // TODO: Wird nicht richtig in global type gesteckt, ppc32_gen_decls.c findet ihn nicht
-
- symcnst = new_bd_ppc32_SymConst(env->dbg, env->block, env->mode);
- set_ppc32_frame_entity(symcnst, ent);
- return symcnst;
-}
-
-static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env);
-
-/**
- * Transforms a Const.
- *
- * @param mod the debug module
- * @param block the block the new node should belong to
- * @param node the ir Const node
- * @param mode node mode
- * @return the created ppc Load immediate node
- */
-static ir_node *gen_ppc32_Const(ppc32_transform_env_t *env)
-{
- tarval *tv_const = get_ppc32_constant_tarval(env->irn);
- ir_node *node;
-
- switch (get_nice_modecode(env->mode)){
- case irm_Hu:
- {
- unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
- if (val1&0x80)
- {
- ir_node *zeroreg = new_bd_ppc32_Addi_zero(env->dbg, env->block, mode_Is);
- set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
- set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
- node = new_bd_ppc32_Ori(env->dbg, env->block, zeroreg, mode_Is);
- set_ppc32_offset_mode(node, ppc32_ao_Lo16);
- break;
- }
- }
- case irm_Bu:
- case irm_Bs:
- case irm_Hs:
- node = new_bd_ppc32_Addi_zero(env->dbg, env->block, env->mode);
- set_ppc32_offset_mode(node, ppc32_ao_None);
- break;
- case irm_Is:
- case irm_Iu:
- case irm_P:
- {
- unsigned char val2 = get_tarval_sub_bits(tv_const,2);
- unsigned char val3 = get_tarval_sub_bits(tv_const,3);
- if (!val2 && !val3)
- {
- unsigned char val1 = get_tarval_sub_bits(tv_const, 1);
- if (val1&0x80)
- {
- ir_node *zeroreg = new_bd_ppc32_Addi_zero(env->dbg, env->block, mode_Is);
- set_ppc32_constant_tarval(zeroreg, new_tarval_from_long(0, mode_Is));
- set_ppc32_offset_mode(zeroreg, ppc32_ao_None);
- node = new_bd_ppc32_Ori(env->dbg, env->block, zeroreg, mode_Is);
- set_ppc32_offset_mode(node, ppc32_ao_Lo16);
- }
- else
- {
- node = new_bd_ppc32_Addi_zero(env->dbg, env->block, env->mode);
- set_ppc32_offset_mode(node, ppc32_ao_None);
- }
- }
- else
- {
- unsigned char val0 = get_tarval_sub_bits(tv_const,0);
- unsigned char val1 = get_tarval_sub_bits(tv_const,1);
- node = new_bd_ppc32_Addis_zero(env->dbg, env->block, env->mode, ppc32_ao_Hi16, tv_const, NULL);
- if (val0 || val1)
- {
- set_ppc32_constant_tarval(node, tv_const);
- node = new_bd_ppc32_Ori(env->dbg, env->block, node, env->mode);
- set_ppc32_offset_mode(node, ppc32_ao_Lo16);
- }
- }
- break;
- }
-
- default:
- panic("Mode for Const not supported: %F", env->mode);
- }
- set_ppc32_constant_tarval(node, tv_const);
- return node;
-}
-
-/**
- * Transforms a fConst.
- *
- * @param mod the debug module
- * @param block the block the new node should belong to
- * @param node the ir Const node
- * @param mode node mode
- * @return the created ppc float Load node
- */
-static ir_node *gen_ppc32_fConst(ppc32_transform_env_t *env)
-{
- tarval *tv_const = get_ppc32_constant_tarval(env->irn);
-
- switch (get_nice_modecode(env->mode)){
- case irm_D:
- case irm_F:
- {
- ir_node *addr, *load;
- ir_mode *mode = env->mode;
- ir_entity *ent;
- env->irn = gen_fp_known_symconst(env, tv_const);
- env->mode = mode_P;
- ent = get_ppc32_frame_entity(env->irn);
-#if 0
- if (is_direct_entity(ent))
- {
- ident *id_symconst = get_entity_ident(ent);
- ir_node *node_addis = new_bd_ppc32_Addis_zero(env->dbg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
-
- if (mode==mode_D)
- load = new_bd_ppc32_Lfd(env->dbg, env->block, node_addis, new_NoMem());
- else // mode_F
- load = new_bd_ppc32_Lfs(env->dbg, env->block, node_addis, new_NoMem());
-
- set_ppc32_symconst_ident(load, id_symconst);
- set_ppc32_offset_mode(load, ppc32_ao_Lo16);
- }
- else
- {
-#endif
- addr = gen_ppc32_SymConst (env);
- if (mode==mode_D)
- load = new_bd_ppc32_Lfd(env->dbg, env->block, addr, new_NoMem());
- else // mode_F
- load = new_bd_ppc32_Lfs(env->dbg, env->block, addr, new_NoMem());
-#if 0
- }
-#endif
- return new_rd_Proj(env->dbg, load, mode, pn_Load_res);
- }
-
- default:
- panic("Mode for fConst not supported: %F", env->mode);
- }
-}
-
-/**
- * Transforms a SymConst.
- *
- * @param mod the debug module
- * @param block the block the new node should belong to
- * @param node the ir Const node
- * @param mode node mode
- * @return the created ppc Load immediate node
- */
-static ir_node *gen_ppc32_SymConst(ppc32_transform_env_t *env)
-{
- ir_entity *ent = get_ppc32_frame_entity(env->irn);
- ident *id_symconst = get_entity_ident(ent);
- ir_node *node;
- switch (get_nice_modecode(env->mode)){
- case irm_P:
- {
- /*
- if (is_direct_entity(ent))
- {
- */
- ir_node *node_addis = new_bd_ppc32_Addis_zero(env->dbg, env->block, env->mode, ppc32_ao_Hi16, NULL, id_symconst);
- node = new_bd_ppc32_Ori(env->dbg, env->block, node_addis, env->mode);
- set_ppc32_symconst_ident(node, id_symconst);
- set_ppc32_offset_mode(node, ppc32_ao_Lo16);
-#if 0
- }
- else
- {
- ir_node *node_addis = new_bd_ppc32_Addis_zero(env->dbg, env->block, env->mode, ppc32_ao_Ha16, NULL, id_symconst);
- node = new_bd_ppc32_Lwz(env->dbg, env->block, node_addis, new_NoMem());
- set_ppc32_symconst_ident(node, id_symconst);
- set_ppc32_offset_mode(node, ppc32_ao_Lo16);
- node = new_rd_Proj(env->dbg, node, env->mode, pn_Load_res);
- }
-#endif
- break;
- }
-
- default:
- panic("Mode for SymConst not supported: %F", env->mode);
- }
- return node;
-}
-
-/**
- * Transforms the given firm node (and maybe some other related nodes)
- * into one or more assembler nodes.
- *
- * @param node the firm node
- * @param env the debug module
- */
-void ppc32_transform_const(ir_node *node, void *env)
-{
- ppc32_code_gen_t *cgenv = (ppc32_code_gen_t *)env;
- ir_node *asm_node = NULL;
- ppc32_transform_env_t tenv;
- (void) cgenv;
-
- if (is_Block(node))
- return;
-
- tenv.block = get_nodes_block(node);
- tenv.dbg = get_irn_dbg_info(node);
- tenv.irg = current_ir_graph;
- tenv.irn = node;
- DEBUG_ONLY(tenv.mod = cgenv->mod;)
- tenv.mode = get_irn_mode(node);
-
-#define OTHER_GEN(a) \
- if (get_irn_op(node) == get_op_##a()) { \
- asm_node = gen_##a(&tenv); \
- }
-
- DBG((tenv.mod, LEVEL_1, "check %+F ... ", node));
-
- OTHER_GEN(ppc32_Const)
- else OTHER_GEN(ppc32_fConst)
- else OTHER_GEN(ppc32_SymConst)
-
- if (asm_node) {
- exchange(node, asm_node);
- DB((tenv.mod, LEVEL_1, "created node %+F[%p]\n", asm_node, asm_node));
- }
- else {
- DB((tenv.mod, LEVEL_1, "ignored\n"));
- }
-#undef OTHER_GEN
-}
+++ /dev/null
-/*
- * 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 transform functions (code selection)
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_TRANSFORM_H
-#define FIRM_BE_PPC32_PPC32_TRANSFORM_H
-
-void ppc32_register_transformers(void);
-void ppc32_transform_node(ir_node *node, void *env);
-void ppc32_transform_const(ir_node *node, void *env);
-
-typedef enum {
- irm_Bs,
- irm_Bu,
- irm_Hs,
- irm_Hu,
- irm_Is,
- irm_Iu,
- irm_F,
- irm_D,
- irm_P,
- irm_max
-} ppc32_modecode;
-
-ppc32_modecode get_nice_modecode(ir_mode *irmode);
-
-#endif
+++ /dev/null
-/*
- * 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 The codegenerator (transform FIRM Conv nodes into ppc FIRM)
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#include "config.h"
-
-#include "irnode_t.h"
-#include "irgraph_t.h"
-#include "irmode_t.h"
-#include "irgmod.h"
-#include "iredges.h"
-#include "iredges_t.h"
-#include "irvrfy.h"
-#include "ircons.h"
-#include "iropt_t.h"
-#include "debug.h"
-#include "error.h"
-
-#include "../benode.h"
-#include "bearch_ppc32_t.h"
-
-#include "ppc32_nodes_attr.h"
-#include "ppc32_transform_conv.h"
-#include "ppc32_transform.h"
-#include "ppc32_new_nodes.h"
-#include "ppc32_map_regs.h"
-
-#include "gen_ppc32_regalloc_if.h"
-
-typedef struct
-{
- ir_node *first_conv;
- ir_node **convs;
- int conv_count;
-} cw_block_attr;
-
-
-ir_node *current_block;
-int conv_nodes_found;
-ir_entity *memslot;
-ir_node *memory;
-
-/**
- * Conv walker initialization
- */
-void ppc32_init_conv_walk(void)
-{
- current_block = NULL;
- conv_nodes_found = 0;
- memslot = NULL;
-}
-
-static ir_node *own_gen_convert_call(ppc32_transform_env_t *env, ir_node *op, const char *funcname,
- ir_mode *from_mode, ir_mode *to_mode)
-{
- ir_type *method_type;
- ir_entity *method_ent;
- ir_node *in[1];
- ir_node *call, *callee, *call_results;
-
- in[0] = op;
-
- method_type = new_type_method(1, 1);
- set_method_param_type(method_type, 0, new_type_primitive(from_mode));
- set_method_res_type(method_type, 0, new_type_primitive(to_mode));
-
- method_ent = new_entity(get_glob_type(), new_id_from_str(funcname), method_type);
- callee = new_rd_SymConst_addr_ent(env->dbg, env->irg, mode_P_code, method_ent, method_type);
- call = new_rd_Call(env->dbg, env->block, memory, callee, 1, in, method_type);
- call_results = new_rd_Proj(env->dbg, call, mode_T, pn_Call_T_result);
- memory = new_rd_Proj(env->dbg, call, mode_M, pn_Call_M);
-
- return new_rd_Proj(env->dbg, call_results, to_mode, 0);
-}
-
-/**
- * Transforms a Conv node.
- *
- * @param mod the debug module
- * @param block the block the new node should belong to
- * @param node the ir Conv node
- * @param op operator
- * @param mode node mode
- * @return the created ppc Conv node
- */
-static ir_node *gen_Conv(ppc32_transform_env_t *env, ir_node *op)
-{
- ir_mode *from_mode = get_irn_mode(get_irn_n(env->irn,0));
- ir_mode *to_mode = env->mode;
- ppc32_modecode from_modecode=get_nice_modecode(from_mode);
- ppc32_modecode to_modecode=get_nice_modecode(to_mode);
-
- switch (from_modecode){
- case irm_F:
- op = new_rd_Conv(env->dbg, env->block, op, mode_D);
- // fall through
- case irm_D:
- {
- ir_node *res;
- if (mode_is_signed(to_mode)) // Float to integer
- {
- ir_node *fctiw = new_bd_ppc32_fCtiw(env->dbg, env->block, op, from_mode);
- ir_node *stfd = new_bd_ppc32_Stfd(env->dbg, env->block, get_irg_frame(env->irg),
- fctiw, memory);
- ir_node *storememproj = new_rd_Proj(env->dbg, stfd, mode_M, pn_Store_M);
- ir_node *lwz = new_bd_ppc32_Lwz(env->dbg, env->block, get_irg_frame(env->irg),
- storememproj);
- set_ppc32_frame_entity(stfd, memslot);
- set_ppc32_offset_mode(stfd, ppc32_ao_Lo16); // TODO: only allows a 16-bit offset on stack
- set_ppc32_frame_entity(lwz, memslot);
- set_ppc32_offset_mode(stfd, ppc32_ao_Lo16); // TODO: only allows a 16-bit offset on stack
- memory = new_rd_Proj(env->dbg, lwz, mode_M, pn_Store_M);
- res = new_rd_Proj(env->dbg, lwz, to_mode, pn_Load_res);
-
- }
- else
- {
- res = own_gen_convert_call(env, op, "conv_double_to_unsigned_int", mode_D, mode_Iu);
- }
-
- switch (to_modecode)
- {
- case irm_Bs:
- case irm_Hs:
- case irm_Bu:
- case irm_Hu:
- return new_rd_Conv(env->dbg, env->block, res, to_mode);
- case irm_Is:
- case irm_Iu:
- return res;
- default:
- break;
- }
- break;
- }
- case irm_Hs:
- case irm_Bs:
- op = new_rd_Conv(env->dbg, env->block, op, mode_Is);
- case irm_Is:
- return own_gen_convert_call(env, op, (to_mode == mode_D) ? "conv_int_to_double" : "conv_int_to_single", mode_Is, to_mode);
-
-
- case irm_Hu:
- case irm_Bu:
- op = new_rd_Conv(env->dbg, env->block, op, mode_Iu);
- case irm_Iu:
- return own_gen_convert_call(env, op, (to_mode == mode_D) ? "conv_unsigned_int_to_double": "conv_unsigned_int_to_single", mode_Iu, to_mode);
-
- case irm_P:
- break;
-
- default:
- break;
- }
- panic("Mode for Conv not supported: %F -> %F", from_mode, to_mode);
-}
-
-static int search_from_node_in_block(ir_node *from, ir_node *to)
-{
- int n = get_irn_arity(from), i;
- for (i=0;i<n;i++)
- {
- ir_node *pred = get_irn_n(from, i);
- if (pred==to) return 1;
- if (get_irn_n(pred, -1)==current_block)
- {
- if (search_from_node_in_block(pred, to)) return 1;
- }
- }
- return 0;
-}
-
-static int nodes_dependency_order(ir_node **a, ir_node **b)
-{
- if (search_from_node_in_block(*a,*b)) return 1;
- if (search_from_node_in_block(*b,*a)) return -1;
- return 0;
-}
-
-static void finalize_block(ppc32_code_gen_t *cgenv)
-{
- int i;
- ir_node *current_conv;
- cw_block_attr *attr = current_block->link;
- ppc32_transform_env_t tenv;
-
- if (!attr->conv_count) return;
-
- if (!memslot)
- {
- ir_type *frame_type = get_irg_frame_type(cgenv->irg);
- memslot = frame_alloc_area(frame_type, get_mode_size_bytes(mode_D), 4, 0);
- }
-
- attr->convs = XMALLOCN(ir_node*, attr->conv_count);
-
- for (i = 0, current_conv = attr->first_conv; i < attr->conv_count; i++, current_conv = current_conv->link)
- {
- attr->convs[i] = current_conv;
- }
-
- qsort(attr->convs, attr->conv_count, sizeof(ir_node *),
- (int (*)(const void *, const void *)) nodes_dependency_order);
-
- tenv.block = current_block;
- tenv.irg = current_ir_graph;
- DEBUG_ONLY(tenv.mod = cgenv->mod;)
-
- memory = get_irg_no_mem(current_ir_graph);
- for (i = 0; i < attr->conv_count; i++)
- {
- tenv.dbg = get_irn_dbg_info(attr->convs[i]);
- tenv.irn = attr->convs[i];
- tenv.mode = get_irn_mode(attr->convs[i]);
-
- exchange(attr->convs[i], gen_Conv(&tenv, get_Conv_op(attr->convs[i])));
- }
-}
-
-static void init_block(void)
-{
- cw_block_attr *attr = XMALLOC(cw_block_attr);
- attr->first_conv = NULL;
- attr->convs = NULL; /* attr->convs is set in finalize_block() */
- attr->conv_count = 0;
- current_block->link = attr;
-}
-
-/**
- * Constant generating code
- */
-
-#if 0
-struct tv_ent {
- ir_entity *ent;
- tarval *tv;
-};
-
-/* Compares two (entity, tarval) combinations */
-static int cmp_tv_ent(const void *a, const void *b, size_t len)
-{
- const struct tv_ent *e1 = a;
- const struct tv_ent *e2 = b;
-
- return !(e1->tv == e2->tv);
-}
-
-/* Generates a SymConst node for a known FP const */
-static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env, tarval *known_const)
-{
- static set *const_set = NULL;
- static ir_type *tp = NULL;
- struct tv_ent key;
- struct tv_ent *entry;
- ir_node *cnst;
- ir_graph *rem;
- ir_entity *ent;
-
- if (!const_set)
- const_set = new_set(cmp_tv_ent, 10);
- if (!tp)
- tp = new_type_primitive(new_id_from_str("const_double_t"), env->mode);
-
-
- key.tv = known_const;
- key.ent = NULL;
-
- entry = set_insert(const_set, &key, sizeof(key), HASH_PTR(key.tv));
-
- if (!entry->ent) {
- char buf[80];
- sprintf(buf, "const_%ld", get_irn_node_nr(env->irn));
- ent = new_entity(get_glob_type(), new_id_from_str(buf), tp);
-
- set_entity_ld_ident(ent, get_entity_ident(ent));
- set_entity_visibility(ent, visibility_local);
- set_entity_variability(ent, variability_constant);
- set_entity_allocation(ent, allocation_static);
-
- /* we create a new entity here: It's initialization must resist on the
- const code irg */
- rem = current_ir_graph;
- current_ir_graph = get_const_code_irg();
- cnst = new_Const(env->mode, key.tv);
- current_ir_graph = rem;
-
- set_atomic_ent_value(ent, cnst);
-
- /* set the entry for hashmap */
- entry->ent = ent;
- }
-
- return new_rd_SymConst_addr_ent(env->dbg, env->irg, ent, tp);
-}
-#endif
-
-/**
- * Transforms a Const
- *
- * @param env transformation environment
- * @return the created ppc Const node
- */
-static ir_node *gen_Const(ppc32_transform_env_t *env)
-{
- tarval *tv_const = get_Const_tarval(env->irn);
- ir_node *constant;
-
- if (mode_is_float(env->mode))
- constant = new_bd_ppc32_fConst(env->dbg, env->block, env->mode);
- else
- constant = new_bd_ppc32_Const(env->dbg, env->block, env->mode);
- set_ppc32_constant_tarval(constant, tv_const);
- return constant;
-}
-
-/**
- * Transforms a SymConst.
- *
- * @param env transformation environment
- * @return the created ppc SymConst node
- */
-static ir_node *gen_SymConst(ppc32_transform_env_t *env)
-{
- ir_node *symconst;
- symconst = new_bd_ppc32_SymConst(env->dbg, env->block, env->mode);
- set_ppc32_frame_entity(symconst, get_SymConst_entity(env->irn));
- return symconst;
-}
-
-/*********************************************************
- * _ _ _
- * (_) | | (_)
- * _ __ ___ __ _ _ _ __ __| |_ __ ___ _____ _ __
- * | '_ ` _ \ / _` | | '_ \ / _` | '__| \ \ / / _ \ '__|
- * | | | | | | (_| | | | | | | (_| | | | |\ V / __/ |
- * |_| |_| |_|\__,_|_|_| |_| \__,_|_| |_| \_/ \___|_|
- *
- *********************************************************/
-
-
-
-/**
- * Transforms all conv nodes into ppc convs before abi
- *
- * @param node the firm node
- * @param env the debug module
- */
-void ppc32_conv_walk(ir_node *node, void *env)
-{
- ppc32_code_gen_t *cgenv = (ppc32_code_gen_t *)env;
- ir_opcode code = get_irn_opcode(node);
- ppc32_transform_env_t tenv;
-
- if (is_Block(node))
- {
- if (current_block != NULL)
- finalize_block(cgenv);
-
- current_block = node;
- init_block();
-
- return;
- }
-
- tenv.irg = current_ir_graph;
- DEBUG_ONLY(tenv.mod = cgenv->mod;)
-
- if (code == iro_Conv)
- {
- ppc32_modecode from_mode=get_nice_modecode(get_irn_mode(get_irn_n(node,0)));
- ppc32_modecode to_mode=get_nice_modecode(get_irn_mode(node));
- cw_block_attr *attr;
-
- if (from_mode == to_mode) return;
- if (from_mode == irm_F || from_mode == irm_D)
- {
- switch (to_mode)
- {
- case irm_Bs:
- case irm_Bu:
- case irm_Hs:
- case irm_Hu:
- case irm_Is:
- case irm_Iu:
- break;
- default:
- return;
-
- }
- }
- else if (to_mode == irm_F || to_mode == irm_D)
- {
- switch (from_mode)
- {
- case irm_Bs:
- case irm_Bu:
- case irm_Hs:
- case irm_Hu:
- case irm_Is:
- case irm_Iu:
- break;
- default:
- return;
- }
- }
- else return;
-
- /* in Liste eintragen */
- attr = get_irn_link(current_block);
- set_irn_link(node, attr->first_conv);
- attr->first_conv = node;
- attr->conv_count++;
- conv_nodes_found++;
- }
- else if (code == iro_Call) {
- int i, size = 0;
- ir_type *tp = get_Call_type(node);
- ir_type *ptp;
- int stack_alignment = 4;
-
- for (i = get_Call_n_params(node) - 1; i >= 0; --i) {
- ir_mode *mode = get_irn_mode(get_Call_param(node, i));
- int s;
-
- if (mode_is_reference(mode)) {
- /* might be a compound parameter */
- ptp = get_method_param_type(tp, i);
-
- if (is_compound_type(ptp)) {
- s = (get_type_size_bytes(ptp) + stack_alignment - 1) & -stack_alignment;
-
- size += s;
- continue;
- }
- }
- s = (get_mode_size_bytes(mode) + stack_alignment - 1) & -stack_alignment;
- size += s;
- }
- if ((unsigned) size > cgenv->area_size)
- cgenv->area_size = size;
- }
-}
-
-/**
- * Transforms all const nodes into ppc const nodes inside the using block
- *
- * @param node the firm node
- * @param env the debug module
- */
-void ppc32_pretransform_walk(ir_node *node, void *env)
-{
- ppc32_code_gen_t *cgenv = (ppc32_code_gen_t *)env;
- ir_opcode code = get_irn_opcode(node);
- ppc32_transform_env_t tenv;
-
- if (is_Block(node))
- {
- current_block = node;
- return;
- }
-
- tenv.irg = current_ir_graph;
- DEBUG_ONLY(tenv.mod = cgenv->mod;)
-
- if (code == iro_Const || code == iro_SymConst)
- {
- ir_node *newconst;
-
- tenv.block = cgenv->start_succ_block;
- tenv.irn = node;
- tenv.mode = get_irn_mode(node);
- tenv.dbg = get_irn_dbg_info(node);
-
- if (code == iro_Const)
- newconst = gen_Const(&tenv);
- else
- newconst = gen_SymConst(&tenv);
-
- exchange(node, newconst);
- }
-}
+++ /dev/null
-/*
- * 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 conv transform functions
- * @author Moritz Kroll, Jens Mueller
- * @version $Id$
- */
-#ifndef FIRM_BE_PPC32_PPC32_TRANSFORM_CONV_H
-#define FIRM_BE_PPC32_PPC32_TRANSFORM_CONV_H
-
-void ppc32_init_conv_walk(void);
-
-void ppc32_conv_walk(ir_node *node, void *env);
-void ppc32_pretransform_walk(ir_node *node, void *env);
-
-#endif