#include "irnode.h"
#include "debug.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../beemitter.h"
#include "bearch_TEMPLATE_t.h"
#include "irnode.h"
#include "set.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "TEMPLATE_nodes_attr.h"
int TEMPLATE_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
#include "irprintf.h"
#include "xmalloc.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "TEMPLATE_nodes_attr.h"
#include "TEMPLATE_new_nodes.h"
#ifndef _TEMPLATE_NODES_ATTR_H_
#define _TEMPLATE_NODES_ATTR_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
typedef struct _TEMPLATE_attr_t {
arch_irn_flags_t flags; /**< indicating if spillable, rematerializeable ... etc. */
#include "bitset.h"
#include "debug.h"
-#include "../bearch.h" /* the general register allocator interface */
+#include "../bearch_t.h" /* the general register allocator interface */
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
* Initializes the code generator.
*/
static void *TEMPLATE_cg_init(be_irg_t *birg) {
- TEMPLATE_isa_t *isa = (TEMPLATE_isa_t *)birg->main_env->arch_env->isa;
- TEMPLATE_code_gen_t *cg = xmalloc(sizeof(*cg));
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ TEMPLATE_isa_t *isa = (TEMPLATE_isa_t *) arch_env->isa;
+ TEMPLATE_code_gen_t *cg = xmalloc(sizeof(*cg));
cg->impl = &TEMPLATE_code_gen_if;
- cg->irg = birg->irg;
+ cg->irg = be_get_birg_irg(birg);
cg->reg_set = new_set(TEMPLATE_cmp_irn_reg_assoc, 1024);
- cg->arch_env = birg->main_env->arch_env;
+ cg->arch_env = arch_env;
cg->isa = isa;
cg->birg = birg;
FIRM_DBG_REGISTER(cg->mod, "firm.be.TEMPLATE.cg");
#ifndef _BEARCH_TEMPLATE_H_
#define _BEARCH_TEMPLATE_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
extern const arch_isa_if_t TEMPLATE_isa_if;
#include "../besched.h"
#include "../beblocksched.h"
+#include "../beirg_t.h"
#include "arm_emitter.h"
#include "gen_arm_emitter.h"
#include "irargs_t.h"
#include "debug.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "bearch_arm_t.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "arm_nodes_attr.h"
#include "irprintf.h"
#include "xmalloc.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
#ifndef _ARM_NODES_ATTR_H_
#define _ARM_NODES_ATTR_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../../common/firm_types.h"
/**
#include "bitset.h"
#include "debug.h"
-#include "../bearch.h" /* the general register allocator interface */
+#include "../bearch_t.h" /* the general register allocator interface */
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
#include "../bemachine.h"
#include "../beilpsched.h"
#include "../bemodule.h"
+#include "../beirg_t.h"
#include "bearch_arm_t.h"
#ifndef _BEARCH_ARM_H_
#define _BEARCH_ARM_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
extern const arch_isa_if_t arm_isa_if;
*/
const char *be_retrieve_dbg_info(const dbg_info *dbg, unsigned *line);
-typedef struct _be_main_env_t be_main_env_t;
-typedef struct _be_options_t be_options_t;
+typedef struct be_main_env_t be_main_env_t;
+typedef struct be_options_t be_options_t;
#endif /* _BE_MAIN_H */
* @date 8.12.2004
*/
-#ifndef _BE_T_H
-#define _BE_T_H
+#ifndef FIRM_BE_T_H
+#define FIRM_BE_T_H
#include "firm_types.h"
#include "obst.h"
#include "be.h"
#include "bearch.h"
#include "be_dbgout.h"
-#include "beirg_t.h"
+#include "beirg.h"
#define DUMP_NONE 0
#define DUMP_INITIAL (1 << 0)
};
/** Backend options */
-struct _be_options_t {
+struct be_options_t {
unsigned dump_flags; /**< backend dumping flags */
int timing; /**< time the backend phases */
int opt_profile; /**< instrument code for profiling */
char stat_file_name[256]; /**< name of the file where the statistics are put to */
};
-struct _be_main_env_t {
- struct obstack obst;
- struct _arch_env_t *arch_env;
- struct _be_options_t *options;
- struct _arch_code_generator_t *cg;
- struct _arch_irn_handler_t *phi_handler;
- dbg_handle *db_handle;
- DEBUG_ONLY(firm_dbg_module_t *dbg;)
+struct be_main_env_t {
+ struct obstack obst;
+ arch_env_t *arch_env;
+ be_options_t *options;
+ arch_code_generator_t *cg;
+ arch_irn_handler_t *phi_handler;
+ dbg_handle *db_handle;
};
/**
* @param bs The bitset (may be NULL).
* @return The number of registers to be ignored.
*/
-int be_put_ignore_regs(const struct _be_irg_t *birg, const struct _arch_register_class_t *cls, bitset_t *bs);
+int be_put_ignore_regs(const be_irg_t *birg, const arch_register_class_t *cls,
+ bitset_t *bs);
-
-
-#endif /* _BE_T_H */
+#endif
#include "be.h"
#include "beabi.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "benode_t.h"
#include "belive_t.h"
#include "besched_t.h"
-#include "beirg.h"
+#include "beirg_t.h"
#include "bessaconstr.h"
typedef struct _be_abi_call_arg_t {
-
/**
* Backend ABI implementation.
*/
-
-#ifndef _BEABI_H
-#define _BEABI_H
+#ifndef FIRM_BEABI_H
+#define FIRM_BEABI_H
#include "firm_types.h"
#include "bitset.h"
#include "be.h"
+#include "beirg.h"
#include "bearch.h"
#include "beabi_t.h"
#include <string.h>
-#include "bearch.h"
+#include "bearch_t.h"
#include "ircons_t.h"
#include "irnode_t.h"
#include "xmalloc.h"
-#ifndef _FIRM_BEARCH_H
-#define _FIRM_BEARCH_H
-
-#include "firm_config.h"
+#ifndef FIRM_BEARCH_H
+#define FIRM_BEARCH_H
#include "firm_types.h"
-
#include "bitset.h"
-
-#include "belistsched.h"
-#include "beilpsched.h"
-#include "beabi_t.h"
-#include "bearch_t.h"
-#include "be_t.h"
-#include "bemachine.h"
-#include "beirg.h"
-
-typedef enum _arch_register_type_t {
+#include "be.h"
+
+typedef struct arch_register_class_t arch_register_class_t;
+typedef struct arch_register_req_t arch_register_req_t;
+typedef struct arch_register_t arch_register_t;
+typedef struct arch_flag_t arch_flag_t;
+typedef struct arch_inverse_t arch_inverse_t;
+typedef struct arch_isa_if_t arch_isa_if_t;
+typedef struct arch_isa_t arch_isa_t;
+typedef struct arch_env_t arch_env_t;
+typedef struct arch_irn_ops_if_t arch_irn_ops_if_t;
+typedef struct arch_irn_ops_t arch_irn_ops_t;
+typedef struct arch_irn_handler_t arch_irn_handler_t;
+typedef struct arch_code_generator_t arch_code_generator_t;
+typedef struct arch_code_generator_if_t arch_code_generator_if_t;
+
+typedef enum arch_register_type_t {
arch_register_type_none = 0,
arch_register_type_caller_save = 1, /**< The register must be saved by the caller
upon a function call. It thus can be overwritten
arch_register_type_state = 32,
} arch_register_type_t;
-/**
- * Convenience macro to check for register type.
- * @param req A pointer to register.
- * @param kind The kind of type to check for (see arch_register_type_t).
- * @return 1, If register is of given kind, 0 if not.
- */
-#define arch_register_type_is(reg, kind) \
- (((reg)->type & arch_register_type_ ## kind) != 0)
-
-/**
- * A register.
- */
-struct _arch_register_t {
- const char *name; /**< The name of the register. */
- const arch_register_class_t *reg_class; /**< The class the register belongs to. */
- int index; /**< The index of the register in the class. */
- arch_register_type_t type; /**< The type of the register. */
- void *data; /**< Custom data. */
-};
-
-static INLINE const arch_register_class_t *
-_arch_register_get_class(const arch_register_t *reg)
-{
- return reg->reg_class;
-}
-
-static INLINE int _arch_register_get_index(const arch_register_t *reg)
-{
- return reg->index;
-}
-
-static INLINE const char *_arch_register_get_name(const arch_register_t *reg)
-{
- return reg->name;
-}
-
-#define arch_register_get_class(reg) _arch_register_get_class(reg)
-#define arch_register_get_index(reg) _arch_register_get_index(reg)
-#define arch_register_get_name(reg) _arch_register_get_name(reg)
-
-/**
- * A class of registers.
- * Like general purpose or floating point.
- */
-struct _arch_register_class_t {
- const char *name; /**< The name of the register class. */
- int n_regs; /**< Number of registers in this class. */
- ir_mode *mode; /**< The mode of the register class. */
- const arch_register_t *regs; /**< The array of registers. */
-};
-
-/** return the number of registers in this register class */
-#define arch_register_class_n_regs(cls) ((cls)->n_regs)
-
-/** return the largest mode of this register class */
-#define arch_register_class_mode(cls) ((cls)->mode)
-
-/** return the name of this register class */
-#define arch_register_class_name(cls) ((cls)->name)
-
/**
* Put all registers in a class into a bitset.
* @param cls The class.
*/
extern int arch_register_class_put(const arch_register_class_t *cls, bitset_t *bs);
-static INLINE const arch_register_t *
-_arch_register_for_index(const arch_register_class_t *cls, int idx)
-{
- assert(0 <= idx && idx < cls->n_regs);
- return &cls->regs[idx];
-}
-
-#define arch_register_for_index(cls, idx) \
- _arch_register_for_index(cls, idx)
-
-typedef enum _arch_operand_type_t {
+typedef enum arch_operand_type_t {
arch_operand_type_invalid,
arch_operand_type_memory,
arch_operand_type_register,
/**
* Different types of register allocation requirements.
*/
-typedef enum _arch_register_req_type_t {
+typedef enum arch_register_req_type_t {
arch_register_req_type_none = 0, /**< No register requirement. */
arch_register_req_type_normal = 1, /**< All registers in the class are allowed. */
arch_register_req_type_limited = 2, /**< Only a real subset of the class is allowed. */
arch_register_req_type_should_be_different_from_all = 16, /**< The register must be different from all in's at the node */
} arch_register_req_type_t;
-/**
- * Convenience macro to check for set constraints.
- * @param req A pointer to register requirements.
- * @param kind The kind of constraint to check for (see arch_register_req_type_t).
- * @return 1, If the kind of constraint is present, 0 if not.
- */
-#define arch_register_req_is(req, kind) \
- (((req)->type & (arch_register_req_type_ ## kind)) != 0)
-
-/**
- * Expresses requirements to register allocation for an operand.
- */
-typedef struct _arch_register_req_t {
- arch_register_req_type_t type; /**< The type of the constraint. */
- const arch_register_class_t *cls; /**< The register class this constraint belongs to. */
-
- const unsigned *limited; /**< allowed register bitset */
-
- int other_same; /**< The in number which shall have
- the same res (should_be_same)*/
- int other_different; /**< The other node from which this
- one's register must be different
- (case must_be_different). */
-} arch_register_req_t;
-
extern const arch_register_req_t *arch_no_register_req;
/**
*/
extern char *arch_register_req_format(char *buf, size_t len, const arch_register_req_t *req, const ir_node *node);
-
/**
* Certain node classes which are relevant for the register allocator.
*/
-typedef enum _arch_irn_class_t {
+typedef enum arch_irn_class_t {
arch_irn_class_normal = 1 << 0,
arch_irn_class_spill = 1 << 1,
arch_irn_class_reload = 1 << 2,
arch_irn_class_stackparam = 1 << 10,
} arch_irn_class_t;
-/**
- * An inverse operation returned by the backend
- */
-typedef struct _arch_inverse_t {
- int n; /**< count of nodes returned in nodes array */
- int costs; /**< costs of this remat */
-
- /**< nodes for this inverse operation. shall be in
- * schedule order. last element is the target value
- */
- ir_node **nodes;
-} arch_inverse_t;
-
/**
* Some flags describing a node in more detail.
*/
-typedef enum _arch_irn_flags_t {
+typedef enum arch_irn_flags_t {
arch_irn_flags_none = 0, /**< Node flags. */
arch_irn_flags_dont_spill = 1, /**< This must not be spilled. */
arch_irn_flags_rematerializable = 2, /**< This can be replicated instead of spilled/reloaded. */
*/
extern const char *arch_irn_flag_str(arch_irn_flags_t flag);
-struct _arch_irn_ops_if_t {
-
- /**
- * Get the register requirements for a given operand.
- * @param self The self pointer.
- * @param irn The node.
- * @param pos The operand's position
- * (-1 for the result of the node, 0..n for the input operands).
- * @return The register requirements for the selected operand.
- * The pointer returned is never NULL.
- */
- const arch_register_req_t *(*get_irn_reg_req)(const void *self,
- const ir_node *irn, int pos);
-
- /**
- * Set the register for an output operand.
- * @param irn The node.
- * @param reg The register allocated to that operand.
- * @note If the operand is not a register operand,
- * the call is ignored.
- */
- void (*set_irn_reg)(const void *self, ir_node *irn, const arch_register_t *reg);
-
- /**
- * Get the register allocated for an output operand.
- * @param irn The node.
- * @return The register allocated at that operand. NULL, if
- * the operand was no register operand or
- * @c arch_register_invalid, if no register has yet been
- * allocated for this node.
- */
- const arch_register_t *(*get_irn_reg)(const void *self, const ir_node *irn);
-
- /**
- * Classify the node.
- * @param irn The node.
- * @return A classification.
- */
- arch_irn_class_t (*classify)(const void *self, const ir_node *irn);
-
- /**
- * Get the flags of a node.
- * @param self The irn ops themselves.
- * @param irn The node.
- * @return A set of flags.
- */
- arch_irn_flags_t (*get_flags)(const void *self, const ir_node *irn);
-
- /**
- * Get the entity on the stack frame this node depends on.
- * @param self The this pointer.
- * @param irn The node in question.
- * @return The entity on the stack frame or NULL, if the node does not have a
- * stack frame entity.
- */
- ir_entity *(*get_frame_entity)(const void *self, const ir_node *irn);
-
- /**
- * Set the entity on the stack frame this node depends on.
- * @param self The this pointer.
- * @param irn The node in question.
- * @param ent The entity to set
- */
- void (*set_frame_entity)(const void *self, ir_node *irn, ir_entity *ent);
-
- /**
- * Set the offset of a node carrying an entity on the stack frame.
- * @param self The this pointer.
- * @param irn The node.
- * @param offset The offset of the node's stack frame entity.
- */
- void (*set_frame_offset)(const void *self, ir_node *irn, int offset);
-
- /**
- * Returns the delta of the stackpointer for nodes that increment or
- * decrement the stackpointer with a constant value. (push, pop
- * nodes on most architectures).
- * A positive value stands for an expanding stack area, a negative value for
- * a shrinking one.
- *
- * @param self The this pointer
- * @param irn The node
- * @return 0 if the stackpointer is not modified with a constant
- * value, otherwise the increment/decrement value
- */
- int (*get_sp_bias)(const void *self, const ir_node *irn);
-
- /**
- * Returns an inverse operation which yields the i-th argument
- * of the given node as result.
- *
- * @param self The this pointer.
- * @param irn The original operation
- * @param i Index of the argument we want the inverse operation to yield
- * @param inverse struct to be filled with the resulting inverse op
- * @param obstack The obstack to use for allocation of the returned nodes array
- * @return The inverse operation or NULL if operation invertible
- */
- arch_inverse_t *(*get_inverse)(const void *self, const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack);
-
- /**
- * Get the estimated cycle count for @p irn.
- *
- * @param self The this pointer.
- * @param irn The node.
- *
- * @return The estimated cycle count for this operation
- */
- int (*get_op_estimated_cost)(const void *self, const ir_node *irn);
-
- /**
- * Asks the backend whether operand @p i of @p irn can be loaded form memory internally
- *
- * @param self The this pointer.
- * @param irn The node.
- * @param i Index of the argument we would like to know whether @p irn can load it form memory internally
- *
- * @return nonzero if argument can be loaded or zero otherwise
- */
- int (*possible_memory_operand)(const void *self, const ir_node *irn, unsigned int i);
-
- /**
- * Ask the backend to assimilate @p reload of operand @p i into @p irn.
- *
- * @param self The this pointer.
- * @param irn The node.
- * @param spill The spill.
- * @param i The position of the reload.
- */
- void (*perform_memory_operand)(const void *self, ir_node *irn, ir_node *spill, unsigned int i);
-};
-
-/**
- * irn_ops base class.
- */
-struct _arch_irn_ops_t {
- const arch_irn_ops_if_t *impl;
-};
-
-extern const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env, const ir_node *irn);
+extern const arch_irn_ops_t *arch_get_irn_ops(const arch_env_t *env,
+ const ir_node *irn);
extern void arch_set_frame_offset(const arch_env_t *env, ir_node *irn, int bias);
#define arch_irn_consider_in_reg_alloc(env, cls, irn) \
(arch_irn_has_reg_class(env, irn, -1, cls) && !arch_irn_is(env, irn, ignore))
-/**
- * Somebody who can be asked about IR nodes.
- */
-struct _arch_irn_handler_t {
-
- /**
- * Get the operations of an irn.
- * @param self The handler from which the method is invoked.
- * @param irn Some node.
- * @return Operations for that irn.
- */
- const void *(*get_irn_ops)(const arch_irn_handler_t *handler,
- const ir_node *irn);
-};
-
-/**
- * The code generator interface.
- */
-struct _arch_code_generator_if_t {
- /**
- * Initialize the code generator.
- * @param birg A backend IRG session.
- * @return A newly created code generator.
- */
- void *(*init)(be_irg_t *birg);
-
- /**
- * Called before abi introduce.
- */
- void (*before_abi)(void *self);
-
- /**
- * Called, when the graph is being normalized.
- */
- void (*prepare_graph)(void *self);
-
- /**
- * Backend may provide an own spiller.
- * This spiller needs to spill all register classes.
- */
- void (*spill)(void *self, be_irg_t *birg);
-
- /**
- * Called before scheduling.
- */
- void (*before_sched)(void *self);
-
- /**
- * Called before register allocation.
- */
- void (*before_ra)(void *self);
-
- /**
- * Called after register allocation.
- */
- void (*after_ra)(void *self);
-
- /**
- * Called directly before done is called. This should be the last place
- * where the irg is modified.
- */
- void (*finish)(void *self);
-
- /**
- * Called after everything happened. This call should emit the final
- * assembly code but avoid changing the irg.
- * The code generator must also be de-allocated here.
- */
- void (*done)(void *self);
-};
-
-/**
- * helper macro: call function func from the code generator
- * if it's implemented.
- */
-#define _arch_cg_call(cg, func) \
-do { \
- if((cg)->impl->func) \
- (cg)->impl->func(cg); \
-} while(0)
-
-#define _arch_cg_call_env(cg, env, func) \
-do { \
- if((cg)->impl->func) \
- (cg)->impl->func(cg, env); \
-} while(0)
-
-#define arch_code_generator_before_abi(cg) _arch_cg_call(cg, before_abi)
-#define arch_code_generator_prepare_graph(cg) _arch_cg_call(cg, prepare_graph)
-#define arch_code_generator_before_sched(cg) _arch_cg_call(cg, before_sched)
-#define arch_code_generator_before_ra(cg) _arch_cg_call(cg, before_ra)
-#define arch_code_generator_after_ra(cg) _arch_cg_call(cg, after_ra)
-#define arch_code_generator_finish(cg) _arch_cg_call(cg, finish)
-#define arch_code_generator_done(cg) _arch_cg_call(cg, done)
-#define arch_code_generator_spill(cg, birg) _arch_cg_call_env(cg, birg, spill)
-#define arch_code_generator_has_spiller(cg) ((cg)->impl->spill != NULL)
-
-/**
- * Code generator base class.
- */
-struct _arch_code_generator_t {
- const arch_code_generator_if_t *impl;
-};
-
-/**
- * ISA base class.
- */
-struct _arch_isa_t {
- const arch_isa_if_t *impl;
- const arch_register_t *sp; /** The stack pointer register. */
- const arch_register_t *bp; /** The base pointer register. */
- const int stack_dir; /** -1 for decreasing, 1 for increasing. */
- const be_main_env_t *main_env; /** the be main environment */
-};
-
-#define arch_isa_stack_dir(isa) ((isa)->stack_dir)
-#define arch_isa_sp(isa) ((isa)->sp)
-#define arch_isa_bp(isa) ((isa)->bp)
-
-/**
- * Architecture interface.
- */
-struct _arch_isa_if_t {
- /**
- * Initialize the isa interface.
- * @param file_handle the file handle to write the output to
- * @param main_env the be main environment
- * @return a new isa instance
- */
- void *(*init)(FILE *file_handle);
-
- /**
- * Free the isa instance.
- */
- void (*done)(void *self);
-
- /**
- * Get the the number of register classes in the isa.
- * @return The number of register classes.
- */
- int (*get_n_reg_class)(const void *self);
-
- /**
- * Get the i-th register class.
- * @param i The number of the register class.
- * @return The register class.
- */
- const arch_register_class_t *(*get_reg_class)(const void *self, int 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.
- */
- const arch_register_class_t *(*get_reg_class_for_mode)(const void *self, const ir_mode *mode);
-
- /**
- * Get the ABI restrictions for procedure calls.
- * @param self The this pointer.
- * @param method_type The type of the method (procedure) in question.
- * @param p The array of parameter locations to be filled.
- */
- void (*get_call_abi)(const void *self, ir_type *method_type, be_abi_call_t *abi);
-
- /**
- * The irn handler for this architecture.
- * The irn handler is registered by the Firm back end
- * when the architecture is initialized.
- * (May be NULL).
- */
- const arch_irn_handler_t *(*get_irn_handler)(const void *self);
-
- /**
- * Get the code generator interface.
- * @param self The this pointer.
- * @return Some code generator interface.
- */
- const arch_code_generator_if_t *(*get_code_generator_if)(void *self);
-
- /**
- * Get the list scheduler to use. There is already a selector given, the
- * backend is free to modify and/or ignore it.
- *
- * @param self The isa object.
- * @param selector The selector given by options.
- * @return The list scheduler selector.
- */
- const list_sched_selector_t *(*get_list_sched_selector)(const void *self, list_sched_selector_t *selector);
-
- /**
- * Get the ILP scheduler to use.
- * @param self The isa object.
- * @return The ILP scheduler selector
- */
- const ilp_sched_selector_t *(*get_ilp_sched_selector)(const void *self);
-
- /**
- * Get the necessary alignment for storing a register of given class.
- * @param self The isa object.
- * @param cls The register class.
- * @return The alignment in bytes.
- */
- int (*get_reg_class_alignment)(const void *self, const arch_register_class_t *cls);
-
- /**
- * A "static" function, returns the frontend settings
- * needed for this backend.
- */
- const backend_params *(*get_params)(void);
-
- /**
- * Returns an 2-dim array of execution units, @p irn can be executed on.
- * The first dimension is the type, the second the allowed units of this type.
- * Each dimension is a NULL terminated list.
- * @param self The isa object.
- * @param irn The node.
- * @return An array of allowed execution units.
- * exec_unit = {
- * { unit1_of_tp1, ..., unitX1_of_tp1, NULL },
- * ...,
- * { unit1_of_tpY, ..., unitXn_of_tpY, NULL },
- * NULL
- * };
- */
- const be_execution_unit_t ***(*get_allowed_execution_units)(const void *self, const ir_node *irn);
-
- /**
- * Return the abstract machine for this isa.
- * @param self The isa object.
- */
- const be_machine_t *(*get_machine)(const void *self);
-
- /**
- * Return an ordered list of irgs where code should be generated for.
- * If NULL is returned, all irg will be taken into account and they will be
- * generated in an arbitrary order.
- * @param self The isa object.
- * @param irgs A flexible array ARR_F of length 0 where the backend cann append the desired irgs.
- * @return A flexible array ARR_F containing all desired irgs in the desired order.
- */
- ir_graph **(*get_backend_irg_list)(const void *self, ir_graph ***irgs);
-};
-
-#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))
-#define arch_isa_get_reg_class(isa,i) ((isa)->impl->get_reg_class(isa, i))
-#define arch_isa_get_irn_handler(isa) ((isa)->impl->get_irn_handler(isa))
-#define arch_isa_get_call_abi(isa,tp,abi) ((isa)->impl->get_call_abi((isa), (tp), (abi)))
-#define arch_isa_get_reg_class_for_mode(isa,mode) ((isa)->impl->get_reg_class_for_mode((isa), (mode)))
-#define arch_isa_make_code_generator(isa,irg) ((isa)->impl->make_code_generator((isa), (irg)))
-#define arch_isa_get_reg_class_alignment(isa, cls) ((isa)->impl->get_reg_class_alignment((isa), (cls)))
-#define arch_isa_get_allowed_execution_units(isa, irn) ((isa)->impl->get_allowed_execution_units((isa), (irn)))
-#define arch_isa_get_machine(isa) ((isa)->impl->get_machine((isa)))
-#define arch_isa_get_backend_irg_list(isa, irgs) ((isa)->impl->get_backend_irg_list((isa), (irgs)))
-
-#define ARCH_MAX_HANDLERS 8
-
-/**
- * Environment for the architecture infrastructure.
- * Keep this everywhere you're going.
- */
-struct _arch_env_t {
- arch_isa_t *isa; /**< The isa about which everything is. */
-
- arch_irn_handler_t const *handlers[ARCH_MAX_HANDLERS]; /**< The handlers are organized as
- a stack. */
-
- int handlers_tos; /**< The stack pointer of the handler
- stack. */
-};
-
-/**
- * Get the isa of an arch environment.
- * @param env The environment.
- * @return The isa with which the env was initialized with.
- */
-#define arch_env_get_isa(env) ((env)->isa)
-
/**
* Initialize the architecture environment struct.
* @param isa The isa which shall be put into the environment.
* @param file_handle The file handle
* @return The environment.
*/
-extern arch_env_t *arch_env_init(arch_env_t *env, const arch_isa_if_t *isa, FILE *file_handle, be_main_env_t *main_env);
+extern arch_env_t *arch_env_init(arch_env_t *env, const arch_isa_if_t *isa,
+ FILE *file_handle, be_main_env_t *main_env);
/**
* Add a node handler to the environment.
*/
void be_register_isa_if(const char *name, const arch_isa_if_t *isa);
-#endif /* _FIRM_BEARCH_H */
+#endif
+++ /dev/null
-
-/**
- * Type declarations for the BEARCH module.
- * $Id$
- */
-
-#ifndef _BEARCH_T_H_
-#define _BEARCH_T_H_
-
-typedef struct _arch_register_class_t arch_register_class_t;
-typedef struct _arch_register_t arch_register_t;
-typedef struct _arch_isa_if_t arch_isa_if_t;
-typedef struct _arch_isa_t arch_isa_t;
-typedef struct _arch_env_t arch_env_t;
-typedef struct _arch_irn_ops_if_t arch_irn_ops_if_t;
-typedef struct _arch_irn_ops_t arch_irn_ops_t;
-typedef struct _arch_irn_handler_t arch_irn_handler_t;
-typedef struct _arch_code_generator_t arch_code_generator_t;
-typedef struct _arch_code_generator_if_t arch_code_generator_if_t;
-
-#endif /* _BEARCH_T_H_ */
#include "besched_t.h"
#include "belive_t.h"
#include "benode_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beirgmod.h"
#include "beifg.h"
#include "beinsn_t.h"
b->irn = irn;
b->step = step;
list_add_tail(&b->list, head);
- DBG((env->dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n", is_def ? "def" : "use", irn, step));
+ DBG((dbg, LEVEL_5, "\t\t%s adding %+F, step: %d\n", is_def ? "def" : "use", irn, step));
return b;
sched_add_before(irn, copy);
set_irn_n(irn, i, copy);
- DBG((env->dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, irn, i));
+ DBG((dbg, LEVEL_3, "inserting ignore arg copy %+F for %+F pos %d\n", copy, irn, i));
}
insn = chordal_scan_insn(env, irn);
sched_add_before(insn->irn, copy);
set_irn_n(insn->irn, a_op->pos, copy);
- DBG((env->dbg, LEVEL_3, "inserting multiple constr copy %+F for %+F pos %d\n", copy, insn->irn, a_op->pos));
+ DBG((dbg, LEVEL_3, "inserting multiple constr copy %+F for %+F pos %d\n", copy, insn->irn, a_op->pos));
}
}
sched_add_before(insn->irn, copy);
set_irn_n(insn->irn, op->pos, copy);
- DBG((env->dbg, LEVEL_3, "inserting constr copy %+F for %+F pos %d\n", copy, insn->irn, op->pos));
+ DBG((dbg, LEVEL_3, "inserting constr copy %+F for %+F pos %d\n", copy, insn->irn, op->pos));
be_liveness_update(lv, op->carrier);
}
#ifndef __BECHORDAL_H
#define __BECHORDAL_H
-#include "bearch.h"
+#include "bearch_t.h"
#include "bera.h"
-typedef struct _be_chordal_env_t be_chordal_env_t;
+typedef struct be_chordal_env_t be_chordal_env_t;
#endif
#ifndef _BECHORDAL_DRAW_H
#define _BECHORDAL_DRAW_H
-#include "bearch.h"
+#include "bearch_t.h"
typedef struct _plotter_t plotter_t;
typedef struct _plotter_if_t plotter_if_t;
#include "besched.h"
#include "besched_t.h"
#include "belive_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beifg_t.h"
#include "beifg_impl.h"
#include "benode_t.h"
#include "bestatevent.h"
#include "bestat.h"
#include "bemodule.h"
+#include "be_t.h"
#include "bespillbelady.h"
#include "bespillmorgan.h"
assert(src && "outedges broken!");
if (get_nodes_block(src) == block && arch_possible_memory_operand(aenv, src, pos)) {
- DBG((cenv->dbg, LEVEL_3, "performing memory operand %+F at %+F\n", irn, src));
arch_perform_memory_operand(aenv, src, spill, pos);
}
}
chordal_env.opts = &options;
chordal_env.irg = irg;
chordal_env.birg = birg;
- FIRM_DBG_REGISTER(chordal_env.dbg, "firm.be.chordal");
obstack_init(&chordal_env.obst);
#include "be_t.h"
#include "beifg.h"
#include "bera.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bechordal.h"
#include "belive.h"
-#include "beirg.h"
+#include "beirg_t.h"
-typedef struct _be_ra_chordal_opts_t be_ra_chordal_opts_t;
+typedef struct be_ra_chordal_opts_t be_ra_chordal_opts_t;
+typedef struct border_t border_t;
/** Defines an invalid register index. */
#define NO_COLOR (-1)
/**
* A liveness interval border.
*/
-typedef struct _border_t {
+struct border_t {
DEBUG_ONLY(unsigned magic;) /**< A magic number for checking. */
- struct list_head list; /**< list head for queuing. */
- struct _border_t *other_end; /**< The other end of the border. */
- ir_node *irn; /**< The node. */
- unsigned step; /**< The number equal to the interval border. */
- unsigned pressure; /**< The pressure at this interval border. (The border itself is counting). */
- unsigned is_def : 1; /**< Does this border denote a use or a def. */
- unsigned is_real : 1; /**< Is the def/use real? Or is it just inserted
- at block beginnings or ends to ensure that inside
- a block, each value has one begin and one end. */
-} border_t;
+ struct list_head list; /**< list head for queuing. */
+ border_t *other_end; /**< The other end of the border. */
+ ir_node *irn; /**< The node. */
+ unsigned step; /**< The number equal to the interval border. */
+ unsigned pressure; /**< The pressure at this interval border. (The border itself is counting). */
+ unsigned is_def : 1; /**< Does this border denote a use or a def. */
+ unsigned is_real : 1; /**< Is the def/use real? Or is it just
+ inserted at block beginnings or ends
+ to ensure that inside a block, each
+ value has one begin and one end. */
+};
/**
* Environment for each of the chordal register allocator phases
*/
-struct _be_chordal_env_t {
- struct obstack obst; /**< An obstack for temporary storage. */
+struct be_chordal_env_t {
+ struct obstack obst; /**< An obstack for temporary storage. */
be_ra_chordal_opts_t *opts; /**< A pointer to the chordal ra options. */
- be_irg_t *birg; /**< Back-end IRG session. */
- ir_graph *irg; /**< The graph under examination. */
+ be_irg_t *birg; /**< Back-end IRG session. */
+ ir_graph *irg; /**< The graph under examination. */
const arch_register_class_t *cls; /**< The current register class. */
- pmap *border_heads; /**< Maps blocks to border heads. */
- be_ifg_t *ifg; /**< The interference graph. */
- bitset_t *ignore_colors; /**< A set of colors which shall be ignored in register allocation. */
- DEBUG_ONLY(firm_dbg_module_t *dbg;) /**< Debug module for the chordal register allocator. */
+ pmap *border_heads; /**< Maps blocks to border heads. */
+ be_ifg_t *ifg; /**< The interference graph. */
+ bitset_t *ignore_colors;/**< A set of colors which shall be ignored in register allocation. */
};
static INLINE struct list_head *_get_block_border_head(const be_chordal_env_t *inf, ir_node *bl) {
BE_CH_VRFY_ASSERT = 3,
};
-struct _be_ra_chordal_opts_t {
+struct be_ra_chordal_opts_t {
int dump_flags;
int lower_perm_opt;
int vrfy_option;
#include "irprintf_t.h"
#include "bemodule.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "benode_t.h"
#include "beutil.h"
#include "beifg_t.h"
irn = insn->next_insn;
}
- DBG((env->co->cenv->dbg, LEVEL_2, "%+F\n", bl));
+ DBG((dbg, LEVEL_2, "%+F\n", bl));
be_liveness_end_of_block(lv, env->co->aenv, env->co->cls, bl, live);
/* Generate the bad and ugly. */
#include <obstack.h>
#include "list.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bechordal_t.h"
#include "becopyopt.h"
#include "benodesets.h"
#include "firm_config.h"
#include "irgraph.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bechordal_t.h"
void copystat_add_max_costs(int costs);
#include "beilpsched.h"
#include "beutil.h"
#include "bestat.h"
+#include "beirg_t.h"
typedef struct _ilpsched_options_t {
unsigned regpress;
*/
void be_ilp_sched(const be_irg_t *birg, be_options_t *be_opts) {
be_ilpsched_env_t env;
- const char *name = "be ilp scheduling";
- arch_isa_t *isa = birg->main_env->arch_env->isa;
- const ilp_sched_selector_t *sel = isa->impl->get_ilp_sched_selector(isa);
+ const char *name = "be ilp scheduling";
+ ir_graph *irg = be_get_birg_irg(birg);
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ const arch_isa_t *isa = arch_env->isa;
+ const ilp_sched_selector_t *sel = isa->impl->get_ilp_sched_selector(isa);
FIRM_DBG_REGISTER(env.dbg, "firm.be.sched.ilp");
// firm_dbg_set_mask(env.dbg, 1);
- env.irg_env = be_ilp_sched_init_irg_ilp_schedule(sel, birg->irg);
+ env.irg_env = be_ilp_sched_init_irg_ilp_schedule(sel, irg);
env.sel = sel;
- env.irg = birg->irg;
- env.height = heights_new(birg->irg);
+ env.irg = irg;
+ env.height = heights_new(irg);
env.main_env = birg->main_env;
- env.arch_env = birg->main_env->arch_env;
- env.cpu = arch_isa_get_machine(birg->main_env->arch_env->isa);
+ env.arch_env = arch_env;
+ env.cpu = arch_isa_get_machine(arch_env->isa);
env.opts = &ilp_opts;
env.birg = birg;
env.be_opts = be_opts;
#include "besched_t.h"
#include "beinsn_t.h"
+#include "beirg_t.h"
#include "beabi.h"
#include "raw_bitset.h"
return insn;
}
-be_insn_env_t *be_insn_env_init(be_insn_env_t *ie, const be_irg_t *birg, const arch_register_class_t *cls, struct obstack *obst)
+be_insn_env_t *be_insn_env_init(be_insn_env_t *ie, const be_irg_t *birg,
+ const arch_register_class_t *cls,
+ struct obstack *obst)
{
- ie->aenv = birg->main_env->arch_env;
+ ie->aenv = be_get_birg_arch_env(birg);
ie->cls = cls;
ie->obst = obst;
ie->ignore_colors = bitset_obstack_alloc(obst, cls->n_regs);
#include "bitset.h"
-#include "bearch.h"
+#include "bearch_t.h"
typedef struct _be_operand_t be_operand_t;
typedef struct _be_insn_t be_insn_t;
birg->lv = NULL;
}
}
+
+ir_graph* (be_get_birg_irg) (const be_irg_t *birg)
+{
+ return _be_get_birg_irg(birg);
+}
+
+ir_exec_freq* (be_get_birg_exec_freq) (const be_irg_t *birg)
+{
+ return _be_get_birg_exec_freq(birg);
+}
+
+be_lv_t* (be_get_birg_liveness) (const be_irg_t *birg)
+{
+ return _be_get_birg_liveness(birg);
+}
+
+be_dom_front_info_t* (be_get_birg_dom_front) (const be_irg_t *birg)
+{
+ return _be_get_birg_dom_front(birg);
+}
+
+const arch_env_t* (be_get_birg_arch_env) (const be_irg_t *birg)
+{
+ return _be_get_birg_arch_env(birg);
+}
*
* Backend irg - a ir_graph with additional analysis information
*/
-#ifndef BEIRG_H_
-#define BEIRG_H_
+#ifndef BEIRG_H
+#define BEIRG_H
#include "belive.h"
#include "bedomfront.h"
-typedef struct _be_irg_t be_irg_t;
+typedef struct be_irg_t be_irg_t;
ir_graph *be_get_birg_irg(const be_irg_t *birg);
void be_invalidate_dom_front(be_irg_t *birg);
be_dom_front_info_t *be_get_birg_dom_front(const be_irg_t *birg);
+const arch_env_t *be_get_birg_arch_env(const be_irg_t *birg);
+
ir_exec_freq *be_get_birg_exec_freq(const be_irg_t *birg);
/**
*
* Backend irg - a ir_graph with additional analysis information
*/
-#ifndef BEIRG_T_H_
-#define BEIRG_T_H_
+#ifndef BEIRG_T_H
+#define BEIRG_T_H
#include "beirg.h"
+#include "be_t.h"
/**
* An ir_graph with additional analysis data about this irg. Also includes some
* backend structures
*/
-struct _be_irg_t {
- ir_graph *irg;
- struct _be_main_env_t *main_env;
- struct _be_abi_irg_t *abi;
- struct _arch_code_generator_t *cg;
- ir_exec_freq *exec_freq;
- be_dom_front_info_t *dom_front;
- be_lv_t *lv;
+struct be_irg_t {
+ ir_graph *irg;
+ be_main_env_t *main_env;
+ be_abi_irg_t *abi;
+ arch_code_generator_t *cg;
+ ir_exec_freq *exec_freq;
+ be_dom_front_info_t *dom_front;
+ be_lv_t *lv;
};
static INLINE be_lv_t *
return birg->irg;
}
+static INLINE const arch_env_t *
+_be_get_birg_arch_env(const be_irg_t *birg) {
+ return birg->main_env->arch_env;
+}
+
#define be_get_birg_exec_freq(birg) _be_get_birg_exec_freq(birg)
#define be_get_birg_liveness(birg) _be_get_birg_liveness(birg)
#define be_get_birg_dom_front(birg) _be_get_birg_dom_front(birg)
#include "be_t.h"
#include "bechordal_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "besched_t.h"
#include "belive_t.h"
#include "benode_t.h"
#include "belistsched.h"
#include "beschedmris.h"
#include "beschedrss.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bestat.h"
+#include "beirg_t.h"
#include <libcore/lc_opts.h>
#include <libcore/lc_opts_enum.h>
* @date 6.12.2004
* @cvs-id $Id$
*/
-
-#ifndef _BELIVE_H
-#define _BELIVE_H
+#ifndef FIRM_BELIVE_H
+#define FIRM_BELIVE_H
#include "firm_types.h"
#include "pset.h"
-#include "bearch_t.h"
+#include "bearch.h"
#include <stdio.h>
#include "irtools.h"
#include "irloop_t.h"
#include "error.h"
+#include "debug.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "belive.h"
#include "besched.h"
#include "beloopana.h"
* @return The highest register pressure in the given block.
*/
static unsigned be_compute_block_pressure(be_loopana_t *loop_ana, ir_node *block, const arch_register_class_t *cls) {
- const arch_env_t *aenv = loop_ana->birg->main_env->arch_env;
+ const be_irg_t *birg = loop_ana->birg;
+ const arch_env_t *aenv = be_get_birg_arch_env(birg);
+ be_lv_t *lv = be_get_birg_liveness(birg);
pset *live_nodes = pset_new_ptr_default();
ir_node *irn;
int max_live;
DBG((dbg, LEVEL_1, "Processing Block %+F\n", block));
/* determine largest pressure with this block */
- live_nodes = be_liveness_end_of_block(loop_ana->birg->lv, aenv, cls, block, live_nodes);
+ live_nodes = be_liveness_end_of_block(lv, aenv, cls, block, live_nodes);
max_live = pset_count(live_nodes);
sched_foreach_reverse(block, irn) {
* @param cls The register class to compute the pressure for
* @return The loop analysis object.
*/
-be_loopana_t *be_new_loop_pressure_cls(be_irg_t *birg, const arch_register_class_t *cls) {
+be_loopana_t *be_new_loop_pressure_cls(be_irg_t *birg,
+ const arch_register_class_t *cls) {
+ ir_graph *irg = be_get_birg_irg(birg);
be_loopana_t *loop_ana = xmalloc(sizeof(*loop_ana));
loop_ana->data = new_set(cmp_loop_info, 16);
DBG((dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
DBG((dbg, LEVEL_1, "=====================================================\n", cls->name));
- be_compute_loop_pressure(loop_ana, get_irg_loop(birg->irg), cls);
+ be_compute_loop_pressure(loop_ana, get_irg_loop(irg), cls);
return loop_ana;
}
* @return The loop analysis object.
*/
be_loopana_t *be_new_loop_pressure(be_irg_t *birg) {
- be_loopana_t *loop_ana = xmalloc(sizeof(*loop_ana));
- ir_loop *irg_loop = get_irg_loop(birg->irg);
- int i;
+ ir_graph *irg = be_get_birg_irg(birg);
+ be_loopana_t *loop_ana = xmalloc(sizeof(*loop_ana));
+ ir_loop *irg_loop = get_irg_loop(irg);
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ const arch_isa_t *isa = arch_env->isa;
+ int i;
loop_ana->data = new_set(cmp_loop_info, 16);
loop_ana->birg = birg;
- for (i = arch_isa_get_n_reg_class(birg->main_env->arch_env->isa) - 1; i >= 0; --i) {
- const arch_register_class_t *cls = arch_isa_get_reg_class(birg->main_env->arch_env->isa, i);
+ for (i = arch_isa_get_n_reg_class(isa) - 1; i >= 0; --i) {
+ const arch_register_class_t *cls = arch_isa_get_reg_class(isa, i);
DBG((dbg, LEVEL_1, "\n=====================================================\n", cls->name));
DBG((dbg, LEVEL_1, " Computing register pressure for class %s:\n", cls->name));
DBG((dbg, LEVEL_1, "=====================================================\n", cls->name));
#include "irloop.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beirg.h"
typedef struct _be_loopana_t be_loopana_t;
#include "irhooks.h"
#include "xmalloc.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "belower.h"
#include "benode_t.h"
#include "besched_t.h"
* @param walk_env The environment
*/
static void lower_perm_node(ir_node *irn, void *walk_env) {
+ ir_graph *irg = get_irn_irg(irn);
const arch_register_class_t *reg_class;
const arch_env_t *arch_env;
lower_env_t *env = walk_env;
DBG((mod, LEVEL_1, "%+F (%+F, %s) and (%+F, %s)\n",
irn, res1, cycle->elems[i]->name, res2, cycle->elems[i + 1]->name));
- cpyxchg = be_new_Perm(reg_class, env->birg->irg, block, 2, in);
+ cpyxchg = be_new_Perm(reg_class, irg, block, 2, in);
n_ops++;
if (i > 0) {
int pidx = get_pairidx_for_regidx(pairs, n, cycle->elems[i]->index, 0);
/* create intermediate proj */
- res1 = new_r_Proj(get_irn_irg(irn), block, cpyxchg, get_irn_mode(res1), 0);
+ res1 = new_r_Proj(irg, block, cpyxchg, get_irn_mode(res1), 0);
/* set as in for next Perm */
pairs[pidx].in_node = res1;
DBG((mod, LEVEL_1, "%+F creating copy node (%+F, %s) -> (%+F, %s)\n",
irn, arg1, cycle->elems[i]->name, res2, cycle->elems[i + 1]->name));
- cpyxchg = be_new_Copy(reg_class, env->birg->irg, block, arg1);
+ cpyxchg = be_new_Copy(reg_class, irg, block, arg1);
arch_set_irn_register(arch_env, cpyxchg, cycle->elems[i + 1]);
n_ops++;
}
static ir_node *find_copy(constraint_env_t *env, ir_node *irn, ir_node *op) {
- const arch_env_t *arch_env = env->birg->main_env->arch_env;
+ const arch_env_t *arch_env = be_get_birg_arch_env(env->birg);
ir_node *block = get_nodes_block(irn);
ir_node *cur_node;
static void gen_assure_different_pattern(ir_node *irn, ir_node *other_different, constraint_env_t *env) {
be_irg_t *birg = env->birg;
+ ir_graph *irg = be_get_birg_irg(birg);
pset *op_set = env->op_set;
- const arch_env_t *arch_env = birg->main_env->arch_env;
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
ir_node *block = get_nodes_block(irn);
const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, other_different, -1);
ir_node *in[2], *keep, *cpy;
/* check if already exists such a copy in the schedule immediatly before */
cpy = find_copy(env, belower_skip_proj(irn), other_different);
if (! cpy) {
- cpy = be_new_Copy(cls, birg->irg, block, other_different);
+ cpy = be_new_Copy(cls, irg, block, other_different);
be_node_set_flags(cpy, BE_OUT_POS(0), arch_irn_flags_dont_spill);
DBG((mod, LEVEL_1, "created non-spillable %+F for value %+F\n", cpy, other_different));
}
/* Add the Keep resp. CopyKeep and reroute the users */
/* of the other_different irn in case of CopyKeep. */
if (get_n_out_edges(other_different) == 0) {
- keep = be_new_Keep(cls, birg->irg, block, 2, in);
+ keep = be_new_Keep(cls, irg, block, 2, in);
}
else {
- keep = be_new_CopyKeep_single(cls, birg->irg, block, cpy, irn, get_irn_mode(other_different));
+ keep = be_new_CopyKeep_single(cls, irg, block, cpy, irn, get_irn_mode(other_different));
be_node_set_reg_class(keep, 1, cls);
}
*/
static void assure_different_constraints(ir_node *irn, constraint_env_t *env) {
const arch_register_req_t *req;
+ const arch_env_t *arch_env = be_get_birg_arch_env(env->birg);
- req = arch_get_register_req(env->birg->main_env->arch_env, irn, -1);
+ req = arch_get_register_req(arch_env, irn, -1);
if (arch_register_req_is(req, should_be_different)) {
ir_node *different_from = get_irn_n(belower_skip_proj(irn), req->other_different);
* (or Projs of the same node), copying the same operand.
*/
static void melt_copykeeps(constraint_env_t *cenv) {
+ be_irg_t *birg = cenv->birg;
+ ir_graph *irg = be_get_birg_irg(birg);
op_copy_assoc_t *entry;
/* for all */
}
#ifdef KEEP_ALIVE_COPYKEEP_HACK
- new_ck = be_new_CopyKeep(entry->cls, cenv->birg->irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, mode_ANY);
+ new_ck = be_new_CopyKeep(entry->cls, irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, mode_ANY);
keep_alive(new_ck);
#else
- new_ck = be_new_CopyKeep(entry->cls, cenv->birg->irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, get_irn_mode(ref));
+ new_ck = be_new_CopyKeep(entry->cls, irg, get_nodes_block(ref), be_get_CopyKeep_op(ref), n_melt, new_ck_in, get_irn_mode(ref));
#endif /* KEEP_ALIVE_COPYKEEP_HACK */
/* set register class for all keeped inputs */
* @param birg The birg structure containing the irg
*/
void assure_constraints(be_irg_t *birg) {
+ ir_graph *irg = be_get_birg_irg(birg);
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
constraint_env_t cenv;
op_copy_assoc_t *entry;
ir_node **nodes;
cenv.op_set = new_pset(cmp_op_copy_assoc, 16);
obstack_init(&cenv.obst);
- irg_walk_blkwise_graph(birg->irg, NULL, assure_constraints_walker, &cenv);
+ irg_walk_blkwise_graph(irg, NULL, assure_constraints_walker, &cenv);
/* melt copykeeps, pointing to projs of */
/* the same mode_T node and keeping the */
ir_node *keep;
int n = get_irn_arity(cp);
- keep = be_new_Keep(arch_get_irn_reg_class(birg->main_env->arch_env, cp, -1),
- birg->irg, get_nodes_block(cp), n, (ir_node **)&get_irn_in(cp)[1]);
+ keep = be_new_Keep(arch_get_irn_reg_class(arch_env, cp, -1),
+ irg, get_nodes_block(cp), n, (ir_node **)&get_irn_in(cp)[1]);
sched_add_before(cp, keep);
/* Set all ins (including the block) of the CopyKeep BAD to keep the verifier happy. */
*/
void lower_nodes_after_ra(be_irg_t *birg, int do_copy) {
lower_env_t env;
+ ir_graph *irg = be_get_birg_irg(birg);
env.birg = birg;
- env.arch_env = birg->main_env->arch_env;
+ env.arch_env = be_get_birg_arch_env(birg);
env.do_copy = do_copy;
FIRM_DBG_REGISTER(env.dbg_module, "firm.be.lower");
- irg_walk_blkwise_graph(birg->irg, NULL, lower_nodes_after_ra_walker, &env);
+ irg_walk_blkwise_graph(irg, NULL, lower_nodes_after_ra_walker, &env);
}
#include "cfopt.h"
#include "execfreq.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "be_t.h"
#include "bemodule.h"
#include "beutil.h"
obstack_init(&env->obst);
env->arch_env = obstack_alloc(&env->obst, sizeof(env->arch_env[0]));
env->options = &be_options;
- FIRM_DBG_REGISTER(env->dbg, "be.main");
arch_env_init(env->arch_env, isa_if, file_handle, env);
edges_deactivate_kind(irg, EDGE_KIND_DEP);
edges_activate_kind(irg, EDGE_KIND_DEP);
- DBG((env->dbg, LEVEL_2, "====> IRG: %F\n", irg));
dump(DUMP_INITIAL, irg, "-begin", dump_ir_block_graph);
be_stat_init_irg(env->arch_env, irg);
#include "entity_t.h"
#include "be_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
#define BE_OUT_POS(p) (-((p) + 1))
#include "belive_t.h"
#include "besched_t.h"
#include "beirgmod.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "benode_t.h"
#include "beutil.h"
#include "bespillremat.h"
#include "belive_t.h"
#include "besched_t.h"
#include "beirgmod.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beabi.h"
#include "benode_t.h"
#include "beutil.h"
#include "bemodule.h"
#include "beraextern.h"
#include "beabi.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "benode_t.h"
#include "beirgmod.h"
#include "besched_t.h"
#include "debug.h"
#include "bemodule.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "besched_t.h"
#include "beutil.h"
#include "belistsched.h"
#include "besched_t.h"
#include "beschedmris.h"
#include "benodesets.h"
+#include "beirg.h"
struct _mris_env_t {
ir_phase ph;
mris_env_t *be_sched_mris_preprocess(const be_irg_t *birg)
{
mris_env_t *env = xmalloc(sizeof(env[0]));
+ ir_graph *irg = be_get_birg_irg(birg);
- phase_init(&env->ph, "mris", birg->irg, 2 * PHASE_DEFAULT_GROWTH, mris_irn_data_init);
- env->aenv = birg->main_env->arch_env;
- env->irg = birg->irg;
+ phase_init(&env->ph, "mris", irg, 2 * PHASE_DEFAULT_GROWTH, mris_irn_data_init);
+ env->aenv = be_get_birg_arch_env(birg);
+ env->irg = irg;
env->visited = 0;
- env->heights = heights_new(birg->irg);
+ env->heights = heights_new(irg);
INIT_LIST_HEAD(&env->lineage_head);
FIRM_DBG_REGISTER(env->dbg, "firm.be.sched.mris");
obstack_init(&env->obst);
- irg_walk_graph(env->irg, firm_clear_link, NULL, NULL);
- irg_block_walk_graph(birg->irg, block_walker, NULL, env);
+ irg_walk_graph(irg, firm_clear_link, NULL, NULL);
+ irg_block_walk_graph(irg, block_walker, NULL, env);
obstack_free(&env->obst, NULL);
// dump_ir_block_graph_mris(env, "-mris");
return env;
#include "bemodule.h"
#include "benode_t.h"
#include "besched_t.h"
+#include "beirg_t.h"
#include <libcore/lc_opts.h>
#include <libcore/lc_opts_enum.h>
* Preprocess the irg for scheduling.
*/
void rss_schedule_preparation(const be_irg_t *birg) {
+ ir_graph *irg = be_get_birg_irg(birg);
rss_t rss;
FIRM_DBG_REGISTER(rss.dbg, "firm.be.sched.rss");
//firm_dbg_set_mask(rss.dbg, LEVEL_1 | LEVEL_2 | LEVEL_3);
- init_rss_special_nodes(birg->irg);
+ init_rss_special_nodes(irg);
- rss.irg = birg->irg;
- rss.arch_env = birg->main_env->arch_env;
+ rss.irg = irg;
+ rss.arch_env = be_get_birg_arch_env(birg);
rss.abi = birg->abi;
- rss.h = heights_new(birg->irg);
+ rss.h = heights_new(irg);
rss.nodes = plist_new();
rss.opts = &rss_options;
- rss.liveness = be_liveness(birg->irg);
- irg_block_walk_graph(birg->irg, NULL, process_block, &rss);
+ rss.liveness = be_liveness(irg);
+ irg_block_walk_graph(irg, NULL, process_block, &rss);
heights_free(rss.h);
plist_free(rss.nodes);
be_liveness_free(rss.liveness);
#include "bechordal.h"
#include "be_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
typedef struct _spill_env_t spill_env_t;
#include "xmalloc.h"
#include "beutil.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bespillbelady.h"
#include "beuses_t.h"
#include "besched_t.h"
#include "be_t.h"
#include "bechordal.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "bespill.h"
/**
#include "irtools.h"
#include "return.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "firm/bearch_firm.h"
#include "ia32/bearch_ia32.h"
#include "arm/bearch_arm.h"
#include <lpp/lpp_cplex.h>
#include "be_t.h"
+#include "beirg_t.h"
#include "belive_t.h"
#include "besched_t.h"
#include "bessaconstr.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beabi.h"
#include "benode_t.h"
#include "beutil.h"
#include "be_t.h"
#include "beutil.h"
#include "bechordal_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "belive_t.h"
#include "benode_t.h"
#include "besched_t.h"
#include "beraextern.h"
#include "beabi.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "benode_t.h"
#include "beirgmod.h"
#include "besched_t.h"
static void stat_reg_pressure_block(ir_node *block, void *data) {
struct a_pressure_walker *env = data;
be_irg_t *birg = env->birg;
- const arch_env_t *aenv = birg->main_env->arch_env;
+ ir_graph *irg = be_get_birg_irg(birg);
+ const arch_env_t *aenv = be_get_birg_arch_env(birg);
int i, n = arch_isa_get_n_reg_class(aenv->isa);
for (i = 0; i < n; i++) {
max_live = cnt < max_live ? max_live : cnt;
}
- stat_be_block_regpressure(birg->irg, block, max_live, cls->name);
+ stat_be_block_regpressure(irg, block, max_live, cls->name);
}
}
void be_do_stat_reg_pressure(be_irg_t *birg) {
+ ir_graph *irg = be_get_birg_irg(birg);
+
if (stat_is_active()) {
struct a_pressure_walker w;
w.birg = birg;
- w.lv = be_liveness(birg->irg);
+ w.lv = be_liveness(irg);
/* Collect register pressure information for each block */
- irg_block_walk_graph(birg->irg, stat_reg_pressure_block, NULL, &w);
+ irg_block_walk_graph(irg, stat_reg_pressure_block, NULL, &w);
be_liveness_free(w.lv);
}
}
#include "ircons_t.h"
#include "irgmod.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beuses_t.h"
#include "besched_t.h"
#include "belive_t.h"
}
obstack_init(&env.obst);
- env.arch_env = birg->main_env->arch_env;
+ env.arch_env = be_get_birg_arch_env(birg);
env.reg = reg;
env.func_env = func_env;
env.create_spill = create_spill;
#include "irnode.h"
#include "beirg.h"
-#include "bearch.h"
+#include "bearch_t.h"
/**
* Callback that should create a spill for a certain value. Can return NULL
#include "benode_t.h"
#include "besched_t.h"
#include "beirgmod.h"
-#include "bearch.h"
+#include "bearch_t.h"
#include "beuses_t.h"
#include "benodesets.h"
#ifndef _BEUSES_H
#define _BEUSES_H
-#include "bearch.h"
+#include "bearch_t.h"
#include "belive.h"
typedef struct _be_next_use_t {
#include "beutil.h"
#include "besched_t.h"
-#include "bearch.h"
+#include "bearch_t.h"
/* Get an always empty set. */
pset *be_empty_set(void)
#include "pset.h"
#include "irnode.h"
-#include "bearch.h"
+#include "bearch_t.h"
/* iterate over a list of ir_nodes linked by link field */
#define foreach_linked_irns(head, iter) for ((iter) = (head); (iter); (iter) = get_irn_link((iter)))
#include "belive.h"
#include "besched_t.h"
#include "benode_t.h"
+#include "beirg_t.h"
static int my_values_interfere(const ir_node *a, const ir_node *b);
/**
* Start a walk over the irg and check the register pressure.
*/
-int be_verify_register_pressure(const be_irg_t *birg, const arch_register_class_t *cls, ir_graph *irg) {
+int be_verify_register_pressure(const be_irg_t *birg,
+ const arch_register_class_t *cls,
+ ir_graph *irg) {
be_verify_register_pressure_env_t env;
env.lv = be_liveness(irg);
#include "irtools.h"
#include "../be_t.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../besched.h"
#include "../beutil.h"
#include "../beabi.h"
{
firm_code_gen_t *cg = xmalloc(sizeof(*cg));
cg->impl = &firm_code_gen_if;
- cg->irg = birg->irg;
+ cg->irg = be_get_birg_irg(birg);
return cg;
}
#ifndef _BEARCH_FIRM_H
#define _BEARCH_FIRM_H
-#include "../bearch.h"
+#include "../bearch_t.h"
extern const arch_isa_if_t firm_isa;
extern const arch_irn_handler_t firm_irn_handler;
#include "xmalloc.h"
#include "../beabi.h"
-#include "../beirg.h"
+#include "../beirg_t.h"
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
store = new_rd_ia32_xStore(dbg, irg, block, ptr, noreg, val, nomem);
else
store = new_rd_ia32_vfst(dbg, irg, block, ptr, noreg, val, nomem);
- }
- else if (get_mode_size_bits(mode) == 128) {
+ } else if (get_mode_size_bits(mode) == 128) {
// Spill 128 bit SSE registers
store = new_rd_ia32_xxStore(dbg, irg, block, ptr, noreg, val, nomem);
- }
- else if (get_mode_size_bits(mode) == 8) {
+ } else if (get_mode_size_bits(mode) == 8) {
store = new_rd_ia32_Store8Bit(dbg, irg, block, ptr, noreg, val, nomem);
- }
- else {
+ } else {
store = new_rd_ia32_Store(dbg, irg, block, ptr, noreg, val, nomem);
}
#include "../be_dbgout.h"
#include "../beemitter.h"
#include "../begnuas.h"
+#include "../beirg_t.h"
#include "ia32_emitter.h"
#include "gen_ia32_emitter.h"
ir_entity *ent;
ident *id;
+ be_emit_char(env, '$');
+
switch(get_ia32_immop_type(node)) {
case ia32_ImmConst:
tv = get_ia32_Immop_tarval(node);
switch(get_ia32_op_type(node)) {
case ia32_Normal:
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
- be_emit_char(env, '$');
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_source_register(env, node, 2);
}
break;
case ia32_AddrModeS:
+ ia32_emit_am(env, node);
+ be_emit_cstring(env, ", ");
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
assert(!produces_result(node) && "Source AM with Const must not produce result");
- ia32_emit_am(env, node);
- be_emit_cstring(env, ", $");
ia32_emit_immediate(env, node);
} else if (produces_result(node)) {
- ia32_emit_am(env, node);
- be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
} else {
- ia32_emit_am(env, node);
- be_emit_cstring(env, ", ");
ia32_emit_source_register(env, node, 2);
}
break;
case ia32_AddrModeD:
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
- be_emit_char(env, '$');
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_am(env, node);
switch(get_ia32_op_type(node)) {
case ia32_Normal:
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
- be_emit_char(env, '$');
ia32_emit_immediate(env, node);
} else {
if (is_ia32_Mul(node) || is_ia32_IMul1OP(node)) {
static
void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
if(is_ia32_ImmSymConst(node) || is_ia32_ImmConst(node)) {
- be_emit_cstring(env, "\ttest $");
+ be_emit_cstring(env, "\ttest ");
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_source_register(env, node, 0);
void Copy_emitter(ia32_emit_env_t *env, const ir_node *node, const ir_node *op)
{
const arch_env_t *aenv = env->arch_env;
+ ir_mode *mode;
if (REGS_ARE_EQUAL(arch_get_irn_register(aenv, node), arch_get_irn_register(aenv, op)) ||
arch_register_type_is(arch_get_irn_register(aenv, op), virtual))
return;
- if (mode_is_float(get_irn_mode(node))) {
+ mode = get_irn_mode(node);
+ if (mode == mode_LLu) {
be_emit_cstring(env, "\tmovsd ");
ia32_emit_source_register(env, node, 0);
be_emit_cstring(env, ", ");
ia32_immop_type_t imm_tp = get_ia32_immop_type(node);
if (imm_tp == ia32_ImmSymConst) {
- be_emit_cstring(env, "\tmovl $");
+ be_emit_cstring(env, "\tmovl ");
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
} else {
- be_emit_cstring(env, "\tmovl $");
+ be_emit_cstring(env, "\tmovl ");
ia32_emit_immediate(env, node);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
#include "irnode.h"
#include "debug.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../beemitter.h"
#include "bearch_ia32_t.h"
#include "pdeq.h"
#include "error.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../besched_t.h"
#include "../benode_t.h"
#include "array.h"
#include "../beirgmod.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../besched.h"
#include "../beabi.h"
#include "../benode_t.h"
#include "../bestate.h"
#include "../beutil.h"
#include "../bessaconstr.h"
+#include "../beirg_t.h"
static ir_node *create_fpu_mode_spill(void *env, ir_node *state, int force,
ir_node *after)
int i, len;
/* do ssa construction for the fpu modes */
- env.arch_env = birg->main_env->arch_env;
+ env.arch_env = be_get_birg_arch_env(birg);
env.state_nodes = NEW_ARR_F(ir_node*, 0);
irg_walk_graph(irg, collect_fpu_mode_nodes_walker, NULL, &env);
#include "irnode.h"
#include "set.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "ia32_nodes_attr.h"
/**
#include "raw_bitset.h"
#include "xmalloc.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
#include <obstack.h>
#include "firm_types.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "../bemachine.h"
typedef enum { flavour_Div = 1, flavour_Mod, flavour_DivMod } ia32_op_flavour_t;
ir_entity *sc; /**< the symconst ident */
} cnst_val;
- ir_mode *ls_mode; /**< the mode of the stored/loaded value, or the mode to convert to */
+ ir_mode *ls_mode; /**< Load/Store mode: This is the mode of the value
+ that is manipulated by this node. */
ir_entity *frame_ent; /**< the frame entity attached to this node */
{ name => "xmm7", type => 1 },
{ name => "xmm_NOREG", type => 4 | 16 }, # we need a dummy register for NoReg nodes
{ name => "xmm_UKNWN", type => 4 | 8 | 16}, # we need a dummy register for Unknown nodes
- { mode => "mode_E" }
+ { mode => "mode_LLu" }
],
vfp => [
{ name => "vf0", type => 1 | 16 },
{ name => "fpcw", type => 4 | 32},
{ mode => "mode_Hu" }
],
+ flags => [
+ { name => "eflags", type => 4 },
+ { mode => "mode_Iu" }
+ ],
+ fp_sw => [
+ { name => "fpsw", type => 4 },
+ { mode => "mode_Hu" }
+ ],
); # %reg_classes
+%flags = (
+ CF => { reg => "eflags", bit => 0 },
+ PF => { reg => "eflags", bit => 2 },
+ AF => { reg => "eflags", bit => 4 },
+ ZF => { reg => "eflags", bit => 6 },
+ SF => { reg => "eflags", bit => 7 },
+ TF => { reg => "eflags", bit => 8 },
+ IF => { reg => "eflags", bit => 9 },
+ DF => { reg => "eflags", bit => 10 },
+ OF => { reg => "eflags", bit => 11 },
+ IOPL0 => { reg => "eflags", bit => 12 },
+ IOPL1 => { reg => "eflags", bit => 13 },
+ NT => { reg => "eflags", bit => 14 },
+ RF => { reg => "eflags", bit => 16 },
+ VM => { reg => "eflags", bit => 17 },
+ AC => { reg => "eflags", bit => 18 },
+ VIF => { reg => "eflags", bit => 19 },
+ VIP => { reg => "eflags", bit => 20 },
+ ID => { reg => "eflags", bit => 21 },
+
+ FP_IE => { reg => "fpsw", bit => 0 },
+ FP_DE => { reg => "fpsw", bit => 1 },
+ FP_ZE => { reg => "fpsw", bit => 2 },
+ FP_OE => { reg => "fpsw", bit => 3 },
+ FP_UE => { reg => "fpsw", bit => 4 },
+ FP_PE => { reg => "fpsw", bit => 5 },
+ FP_SF => { reg => "fpsw", bit => 6 },
+ FP_ES => { reg => "fpsw", bit => 7 },
+ FP_C0 => { reg => "fpsw", bit => 8 },
+ FP_C1 => { reg => "fpsw", bit => 9 },
+ FP_C2 => { reg => "fpsw", bit => 10 },
+ FP_TOP0 => { reg => "fpsw", bit => 11 },
+ FP_TOP1 => { reg => "fpsw", bit => 12 },
+ FP_TOP2 => { reg => "fpsw", bit => 13 },
+ FP_C3 => { reg => "fpsw", bit => 14 },
+ FP_B => { reg => "fpsw", bit => 15 },
+
+ FP_IM => { reg => "fpcw", bit => 0 },
+ FP_DM => { reg => "fpcw", bit => 1 },
+ FP_ZM => { reg => "fpcw", bit => 2 },
+ FP_OM => { reg => "fpcw", bit => 3 },
+ FP_UM => { reg => "fpcw", bit => 4 },
+ FP_PM => { reg => "fpcw", bit => 5 },
+ FP_PC0 => { reg => "fpcw", bit => 8 },
+ FP_PC1 => { reg => "fpcw", bit => 9 },
+ FP_RC0 => { reg => "fpcw", bit => 10 },
+ FP_RC1 => { reg => "fpcw", bit => 11 },
+ FP_X => { reg => "fpcw", bit => 12 }
+); # %flags
+
%cpu = (
GP => [ 1, "GP_EAX", "GP_EBX", "GP_ECX", "GP_EDX", "GP_ESI", "GP_EDI", "GP_EBP" ],
SSE => [ 1, "SSE_XMM0", "SSE_XMM1", "SSE_XMM2", "SSE_XMM3", "SSE_XMM4", "SSE_XMM5", "SSE_XMM6", "SSE_XMM7" ],
C => "${arch}_emit_immediate(env, node);",
SE => "${arch}_emit_extend_suffix(env, get_ia32_ls_mode(node));",
ME => "if(get_mode_size_bits(get_ia32_ls_mode(node)) != 32)\n
- ia32_emit_mode_suffix(env, get_ia32_ls_mode(node));",
+ ia32_emit_mode_suffix(env, get_ia32_ls_mode(node));",
M => "${arch}_emit_mode_suffix(env, get_ia32_ls_mode(node));",
XM => "${arch}_emit_x87_mode_suffix(env, node);",
XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
%operands = (
);
+$mode_xmm = "mode_LLu";
+$mode_gp = "mode_Iu";
+$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
+$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
+ "FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
+
%nodes = (
#-----------------------------------------------------------------#
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. addl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Adc => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. adcl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Add64Bit => {
',
outs => [ "low_res", "high_res" ],
units => [ "GP" ],
+ modified_flags => $status_flags
},
l_Add => {
outs => [ "EAX", "EDX", "M" ],
latency => 10,
units => [ "GP" ],
+ modified_flags => $status_flags
},
l_Mul => {
emit => '. imull %binop',
latency => 5,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
IMul1OP => {
outs => [ "EAX", "EDX", "M" ],
latency => 5,
units => [ "GP" ],
+ modified_flags => $status_flags
},
l_IMul => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. andl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Or => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. orl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Xor => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. xorl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_Xor => {
op_flags => "C",
cmp_attr => "return 1;",
comment => "construct lowered Xor: Xor(a, b) = Xor(b, a) = a XOR b",
- arity => 2
+ arity => 2,
+ modified_flags => $status_flags
},
# not commutative operations
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. subl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Sbb => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. sbbl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Sub64Bit => {
',
outs => [ "low_res", "high_res" ],
units => [ "GP" ],
+ modified_flags => $status_flags
},
l_Sub => {
outs => [ "div_res", "mod_res", "M" ],
latency => 25,
units => [ "GP" ],
+ modified_flags => $status_flags
},
Div => {
outs => [ "div_res", "mod_res", "M" ],
latency => 25,
units => [ "GP" ],
+ modified_flags => $status_flags
},
Shl => {
reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. shll %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_Shl => {
',
latency => 6,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_ShlD => {
reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. shrl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_Shr => {
',
latency => 6,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_ShrD => {
reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. sarl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
l_Sar => {
reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. rorl %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Rol => {
reg_req => { in => [ "gp", "gp", "gp", "ecx", "none" ], out => [ "in_r3 !in_r4" ] },
emit => '. roll %binop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
# unary operations
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. negl %unop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Minus64Bit => {
',
outs => [ "low_res", "high_res" ],
units => [ "GP" ],
+ modified_flags => $status_flags
},
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. incl %unop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ]
},
Dec => {
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. decl %unop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => [ "OF", "SF", "ZF", "AF", "PF" ]
},
Not => {
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3" ] },
emit => '. notl %unop',
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => []
},
# other operations
comment => "represents an integer constant",
reg_req => { out => [ "gp" ] },
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
Unknown_GP => {
reg_req => { out => [ "gp_UKNWN" ] },
units => [],
emit => "",
- mode => "mode_Iu"
+ mode => $mode_gp
},
Unknown_VFP => {
reg_req => { out => [ "gp_NOREG" ] },
units => [],
emit => "",
- mode => "mode_Iu"
+ mode => $mode_gp
},
NoReg_VFP => {
mode => "mode_Hu",
latency => 3,
units => [ "GP" ],
+ modified_flags => $fpcw_flags
},
FldCW => {
emit => ". fldcw %AM",
mode => "mode_Hu",
units => [ "GP" ],
+ modified_flags => $fpcw_flags
},
FnstCW => {
emit => '. leal %AM, %D1',
latency => 2,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
+ modified_flags => [],
},
Push => {
outs => [ "stack:I|S", "M" ],
latency => 3,
units => [ "GP" ],
+ modified_flags => [],
},
Pop => {
outs => [ "stack:I|S", "res", "M" ],
latency => 4,
units => [ "GP" ],
+ modified_flags => [],
},
Enter => {
emit => '. addl %binop',
outs => [ "stack:S", "M" ],
units => [ "GP" ],
+ modified_flags => $status_flags
},
SubSP => {
emit => '. subl %binop',
outs => [ "stack:S", "M" ],
units => [ "GP" ],
+ modified_flags => $status_flags
},
LdTls => {
mode => "mode_M",
},
+CvtSI2SS => {
+ op_flags => "L|F",
+ reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "xmm" ] },
+ emit => '. cvtsi2ss %D1, %AM',
+ latency => 2,
+ units => [ "SSE" ],
+ mode => $mode_xmm
+},
+
+CvtSI2SD => {
+ op_flags => "L|F",
+ reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "xmm" ] },
+ emit => '. cvtsi2sd %unop',
+ latency => 2,
+ units => [ "SSE" ],
+ mode => $mode_xmm
+},
+
+
l_X87toSSE => {
op_flags => "L|F",
comment => "construct: transfer a value from x87 FPU into a SSE register",
comment => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
outs => [ "DST", "SRC", "CNT", "M" ],
- units => [ "GP" ],
+ units => [ "GP" ],
+ modified_flags => [ "DF" ]
},
CopyB_i => {
comment => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
outs => [ "DST", "SRC", "M" ],
- units => [ "GP" ],
+ units => [ "GP" ],
+ modified_flags => [ "DF" ]
},
# Conversions
Conv_I2I => {
reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] },
comment => "construct Conv Int -> Int",
- units => [ "GP" ],
- mode => "mode_Iu",
+ units => [ "GP" ],
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Conv_I2I8Bit => {
reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] },
comment => "construct Conv Int -> Int",
- units => [ "GP" ],
- mode => "mode_Iu",
+ units => [ "GP" ],
+ mode => $mode_gp,
+ modified_flags => $status_flags
},
Conv_I2FP => {
comment => "construct Conv Floating Point -> Int",
latency => 10,
units => [ "SSE" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
Conv_FP2FP => {
reg_req => { in => [ "gp", "gp", "gp", "gp" ], out => [ "in_r4" ] },
latency => 2,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
PsiCondCMov => {
reg_req => { in => [ "gp", "gp", "gp" ], out => [ "in_r3" ] },
latency => 2,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
xCmpCMov => {
reg_req => { in => [ "xmm", "xmm", "gp", "gp" ], out => [ "in_r4" ] },
latency => 5,
units => [ "SSE" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
vfCmpCMov => {
reg_req => { in => [ "vfp", "vfp", "gp", "gp" ], out => [ "in_r4" ] },
latency => 10,
units => [ "VFP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
CmpSet => {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "eax ebx ecx edx" ] },
latency => 2,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
PsiCondSet => {
reg_req => { in => [ "gp" ], out => [ "eax ebx ecx edx" ] },
latency => 2,
units => [ "GP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
xCmpSet => {
reg_req => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "eax ebx ecx edx" ] },
latency => 5,
units => [ "SSE" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
vfCmpSet => {
reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "eax ebx ecx edx" ] },
latency => 10,
units => [ "VFP" ],
- mode => "mode_Iu",
+ mode => $mode_gp,
},
vfCMov => {
#include "../besched.h"
#include "../beabi.h"
#include "../beutil.h"
+#include "../beirg_t.h"
#include "bearch_ia32_t.h"
#include "ia32_nodes_attr.h"
#define ENT_SFP_ABS "IA32_SFP_ABS"
#define ENT_DFP_ABS "IA32_DFP_ABS"
+#define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
+#define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
+
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
typedef struct ia32_transform_env_t {
current_ir_graph = rem;
pmap_insert(cg->isa->tv_ent, tv, res);
- }
- else
+ } else {
res = e->value;
+ }
+
return res;
}
if (clss == CNST_NULL) {
load = new_rd_ia32_vfldz(dbgi, irg, block);
- res = load;
+ res = load;
} else if (clss == CNST_ONE) {
load = new_rd_ia32_vfld1(dbgi, irg, block);
- res = load;
+ res = load;
} else {
floatent = get_entity_for_tv(env->cg, node);
- load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem);
+ load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem);
set_ia32_am_support(load, ia32_am_Source);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_flavour(load, ia32_am_N);
set_ia32_am_sc(load, floatent);
- res = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
+ res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
}
+ set_ia32_ls_mode(load, mode);
} else {
floatent = get_entity_for_tv(env->cg, node);
- load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem);
+ load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem);
set_ia32_am_support(load, ia32_am_Source);
set_ia32_op_type(load, ia32_AddrModeS);
set_ia32_am_flavour(load, ia32_am_N);
set_ia32_am_sc(load, floatent);
- res = new_r_Proj(irg, block, load, mode_E, pn_ia32_xLoad_res);
+ set_ia32_ls_mode(load, mode);
+
+ res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
}
- set_ia32_ls_mode(load, mode);
SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env->cg, node));
/* Const Nodes before the initial IncSP are a bad idea, because
}
/**
-* SSE convert of an float node into a double node.
-*/
+ * SSE convert of an float node into a double node.
+ */
static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbgi,
ir_graph *irg, ir_node *block,
ir_node *in, ir_node *old_node)
ir_node *conv = new_rd_ia32_Conv_FP2FP(dbgi, irg, block, noreg, noreg, in, nomem);
set_ia32_am_support(conv, ia32_am_Source);
- set_ia32_ls_mode(conv, mode_E);
+ set_ia32_ls_mode(conv, mode_xmm);
SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));
return conv;
cnst_str = names[kct].cnst_str;
//mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
- mode = mode_LLu;
+ mode = mode_xmm;
tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
tp = new_type_primitive(new_id_from_str(tp_name), mode);
ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
/* determine if one operator is an Imm */
static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
- if (op1)
+ if (op1) {
return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
- else return is_ia32_Cnst(op2) ? op2 : NULL;
+ } else {
+ return is_ia32_Cnst(op2) ? op2 : NULL;
+ }
}
/* determine if one operator is not an Imm */
/* in case the compare operands are int, we move them into xmm register */
if (! mode_is_float(get_irn_mode(cmp_a))) {
- new_cmp_a = gen_sse_conv_int2float(cg, dbgi, irg, block, new_cmp_a, node, mode_E);
- new_cmp_b = gen_sse_conv_int2float(cg, dbgi, irg, block, new_cmp_b, node, mode_E);
+ new_cmp_a = gen_sse_conv_int2float(cg, dbgi, irg, block, new_cmp_a, node, mode_xmm);
+ new_cmp_b = gen_sse_conv_int2float(cg, dbgi, irg, block, new_cmp_b, node, mode_xmm);
pnc |= 8; /* transform integer compare to fp compare */
}
ia32_code_gen_t *cg = env->cg;
#endif
ir_graph *irg = env->irg;
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_mode *mode = get_irn_mode(node);
+ dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = transform_node(env, get_nodes_block(node));
ir_node *noreg = ia32_new_NoReg_gp(env->cg);
ir_node *nomem = new_NoMem();
set_ia32_am_flavour(fild, ia32_am_OB);
set_ia32_ls_mode(fild, mode_Iu);
- return new_r_Proj(irg, block, fild, mode_F, pn_ia32_vfild_res);
+ return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
}
/**
} else {
return gen_x87_gp_to_fp(env, node, src_mode);
}
- }
- else {
+ } else {
+ /* to int */
ir_mode *smaller_mode;
int smaller_bits;
FP_USED(env->cg);
if (USE_SSE2(env->cg)) {
new_op = new_rd_ia32_xLoad(dbgi, irg, block, new_ptr, noreg, nomem);
- pn_res = pn_ia32_xLoad_res;
+ pn_res = pn_ia32_xLoad_res;
+ proj_mode = mode_xmm;
} else {
new_op = new_rd_ia32_vfld(dbgi, irg, block, new_ptr, noreg, nomem);
- pn_res = pn_ia32_vfld_res;
+ pn_res = pn_ia32_vfld_res;
+ proj_mode = mode_vfp;
}
-
- proj_mode = mode_E;
} else {
new_op = new_rd_ia32_Load(dbgi, irg, block, new_ptr, noreg, nomem);
proj_mode = mode_Iu;
FP_USED(env->cg);
if (USE_SSE2(env->cg)) {
new_op = new_rd_ia32_xStore(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
- }
- else {
+ } else {
new_op = new_rd_ia32_vfst(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
}
- }
- else if (get_mode_size_bits(mode) == 8) {
+ } else if (get_mode_size_bits(mode) == 8) {
new_op = new_rd_ia32_Store8Bit(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
- }
- else {
+ } else {
new_op = new_rd_ia32_Store(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
}
set_ia32_am_support(fld, ia32_am_Source);
mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_SetST0_M);
- fld = new_r_Proj(irg, block, fld, mode_E, pn_ia32_SetST0_res);
+ fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_SetST0_res);
arch_set_irn_register(env->cg->arch_env, fld, &ia32_vfp_regs[REG_VF0]);
/* create a new barrier */
mode = mode_Iu;
} else if(mode_is_float(mode)) {
assert(mode == mode_D || mode == mode_F);
- // all float operations are on mode_E registers
- mode = mode_E;
+ if (USE_SSE2(env->cg)) {
+ mode = mode_xmm;
+ } else {
+ mode = mode_vfp;
+ }
}
/* phi nodes allow loops, so we use the old arguments for now
set_ia32_am_support(res, ia32_am_Source);
set_ia32_am_flavour(res, ia32_B);
set_ia32_op_type(res, ia32_AddrModeS);
- res = new_rd_Proj(dbgi, irg, block, res, mode_E, pn_ia32_xLoad_res);
+ res = new_rd_Proj(dbgi, irg, block, res, mode_xmm, pn_ia32_xLoad_res);
return res;
}
set_ia32_am_support(res, ia32_am_Source);
set_ia32_am_flavour(res, ia32_B);
set_ia32_op_type(res, ia32_AddrModeS);
- res = new_rd_Proj(dbgi, irg, block, res, lsmode, pn_ia32_vfld_res);
+ res = new_rd_Proj(dbgi, irg, block, res, mode_vfp, pn_ia32_vfld_res);
return res;
}
}
} else if(is_ia32_xLoad(new_pred)) {
if(proj == pn_Load_res) {
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_E, pn_ia32_xLoad_res);
+ return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
} else if(proj == pn_Load_M) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
}
} else if(is_ia32_vfld(new_pred)) {
if(proj == pn_Load_res) {
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_E, pn_ia32_vfld_res);
+ return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
} else if(proj == pn_Load_M) {
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
}
case pn_ia32_l_vfdiv_M:
return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
case pn_ia32_l_vfdiv_res:
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_E, pn_ia32_vfdiv_res);
+ return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
default:
assert(0);
}
break;
case pn_Quot_res:
if(is_ia32_xDiv(new_pred)) {
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_E,
+ return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm,
pn_ia32_xDiv_res);
} else if(is_ia32_vfdiv(new_pred)) {
- return new_rd_Proj(dbgi, irg, block, new_pred, mode_E,
+ return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp,
pn_ia32_vfdiv_res);
}
break;
set_ia32_am_flavour(sse_load, ia32_am_B);
set_ia32_am_support(sse_load, ia32_am_Source);
- //mproj = new_rd_Proj(dbgi, irg, block, sse_load, mode_M, pn_ia32_xLoad_M);
- sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_E, pn_ia32_xLoad_res);
+ sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm, pn_ia32_xLoad_res);
/* now: create new Keep whith all former ins and one additional in - the result Proj */
return sse_load;
}
- /* transform call modes to the mode_Iu or mode_E */
+ /* transform call modes */
if(mode != mode_M) {
cls = arch_get_irn_reg_class(env->cg->arch_env, node, -1);
mode = cls->mode;
if (! mode_is_float(m)) {
cmp_a = gen_sse_conv_int2float(cg, dbgi, irg, block, cmp_a, cmp_a, mode);
cmp_b = gen_sse_conv_int2float(cg, dbgi, irg, block, cmp_b, cmp_b, mode);
- }
- else if (m == mode_F) {
+ } else if (m == mode_F) {
/* we convert cmp values always to double, to get correct bitmask with cmpsd */
cmp_a = gen_sse_conv_f2d(cg, dbgi, irg, block, cmp_a, cmp_a);
cmp_b = gen_sse_conv_f2d(cg, dbgi, irg, block, cmp_b, cmp_b);
new_op = new_rd_ia32_xCmp(dbgi, irg, block, noreg, noreg, cmp_a, cmp_b, nomem);
set_ia32_pncode(new_op, pnc);
SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(cg, cmp));
- }
- else {
+ } else {
/* x87 FPU */
assert(0);
}
- }
- else {
+ } else {
/* integer Psi */
construct_binop_func *set_func = NULL;
if (USE_SSE2(cg)) {
/* SSE FPU */
set_func = new_rd_ia32_xCmpSet;
- }
- else {
+ } else {
/* x87 FPU */
set_func = new_rd_ia32_vfCmpSet;
}
pnc &= 7; /* fp compare -> int compare */
- }
- else {
+ } else {
/* 2nd case: compare operand are integer too */
set_func = new_rd_ia32_CmpSet;
}
/* the the new compare as in */
set_irn_n(cond, i, new_op);
- }
- else {
+ } else {
/* another complex condition */
transform_psi_cond(in, mode, cg);
}
/**
* The Psi selector can be a tree of compares combined with "And"s and "Or"s.
- * We create a Set node, respectively a xCmp in case the Psi is a float, for each
- * compare, which causes the compare result to be stores in a register. The
+ * We create a Set node, respectively a xCmp in case the Psi is a float, for
+ * each compare, which causes the compare result to be stored in a register. The
* "And"s and "Or"s are transformed later, we just have to set their mode right.
*/
void ia32_transform_psi_cond_tree(ir_node *node, void *env) {
psi_sel = get_Psi_cond(node, 0);
/* if psi_cond is a cmp: do nothing, this case is covered by gen_Psi */
- if (is_Proj(psi_sel))
+ if (is_Proj(psi_sel)) {
+ assert(is_Cmp(get_Proj_pred(psi_sel)));
return;
+ }
//mode = get_irn_mode(node);
- // TODO this is probably wrong...
+ // TODO probably wrong...
mode = mode_Iu;
transform_psi_cond(psi_sel, mode, cg);
block = get_nodes_block(node);
/* we need to compare the evaluated condition tree with 0 */
- mode = get_irn_mode(node);
+ mode = get_irn_mode(node);
if (mode_is_float(mode)) {
- psi_sel = gen_sse_conv_int2float(cg, NULL, irg, block, psi_sel, NULL, mode);
/* BEWARE: new_r_Const_long works for floating point as well */
- new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode, 0));
+ ir_node *zero = new_r_Const_long(irg, block, mode, 0);
+
+ psi_sel = gen_sse_conv_int2float(cg, NULL, irg, block, psi_sel, NULL, mode);
+ new_cmp = new_r_Cmp(irg, block, psi_sel, zero);
new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Ne);
- }
- else {
- new_cmp = new_r_Cmp(irg, block, psi_sel, new_r_Const_long(irg, block, mode_Iu, 0));
+ } else {
+ ir_node *zero = new_r_Const_long(irg, block, mode_Iu, 0);
+ new_cmp = new_r_Cmp(irg, block, psi_sel, zero);
new_cmp = new_r_Proj(irg, block, new_cmp, mode_b, pn_Cmp_Gt | pn_Cmp_Lt);
}
ir_node *block, *start_block;
blk_state *bl_state;
x87_simulator sim;
- ir_graph *irg = birg->irg;
+ ir_graph *irg = be_get_birg_irg(birg);
/* create the simulator */
x87_init_simulator(&sim, irg, arch_env);
be_invalidate_liveness(birg);
be_assure_liveness(birg);
- sim.lv = birg->lv;
+ sim.lv = be_get_birg_liveness(birg);
/* Calculate the liveness for all nodes. We must precalculate this info,
* because the simulator adds new nodes (possible before Phi nodes) which
#ifndef _IA32_X87_H_
#define _IA32_X87_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
/**
* Run a simulation and fix all virtual instructions for a graph.
#include "bitset.h"
#include "debug.h"
-#include "../bearch.h" /* the general register allocator interface */
+#include "../bearch_t.h" /* the general register allocator interface */
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
* Initializes the code generator.
*/
static void *mips_cg_init(be_irg_t *birg) {
- mips_isa_t *isa = (mips_isa_t *)birg->main_env->arch_env->isa;
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ mips_isa_t *isa = (mips_isa_t *) arch_env->isa;
mips_code_gen_t *cg = xmalloc(sizeof(*cg));
cg->impl = &mips_code_gen_if;
- cg->irg = birg->irg;
+ cg->irg = be_get_birg_irg(birg);
cg->reg_set = new_set(mips_cmp_irn_reg_assoc, 1024);
- cg->arch_env = birg->main_env->arch_env;
+ cg->arch_env = arch_env;
cg->isa = isa;
cg->birg = birg;
cg->bl_list = NULL;
#ifndef _BEARCH_MIPS_H_
#define _BEARCH_MIPS_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
typedef struct _mips_code_gen_t mips_code_gen_t;
#include "irnode.h"
#include "debug.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "bearch_mips_t.h"
#include "irnode.h"
#include "set.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "mips_nodes_attr.h"
int mips_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
#include "irprintf.h"
#include "xmalloc.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "mips_nodes_attr.h"
#include "mips_new_nodes.h"
#ifndef _MIPS_NODES_ATTR_H_
#define _MIPS_NODES_ATTR_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "irmode_t.h"
typedef struct _mips_attr_t {
#include "../beabi.h"
#include "../besched.h"
#include "../besched_t.h"
+#include "../beirg_t.h"
#include "bearch_mips_t.h"
#include "mips_nodes_attr.h"
#include "bitset.h"
#include "debug.h"
-#include "../bearch.h" /* the general register allocator interface */
+#include "../bearch_t.h" /* the general register allocator interface */
#include "../benode_t.h"
#include "../belower.h"
#include "../besched_t.h"
#include "../bemachine.h"
#include "../bemodule.h"
#include "../beblocksched.h"
+#include "../beirg_t.h"
#include "pset.h"
#ifndef _BEARCH_PPC32_H_
#define _BEARCH_PPC32_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
extern const arch_isa_if_t ppc32_isa_if;
#include "irnode.h"
#include "debug.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "bearch_ppc32_t.h"
#include "irnode.h"
#include "set.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "ppc32_nodes_attr.h"
int ppc32_cmp_irn_reg_assoc(const void *a, const void *b, size_t len);
#include "irprintf.h"
#include "xmalloc.h"
-#include "../bearch.h"
+#include "../bearch_t.h"
#include "ppc32_nodes_attr.h"
#include "ppc32_new_nodes.h"
#ifndef _PPC32_NODES_ATTR_H_
#define _PPC32_NODES_ATTR_H_
-#include "../bearch.h"
+#include "../bearch_t.h"
typedef struct
{
no strict "subs";
unless ($return = do $specfile) {
- warn "couldn't parse $specfile: $@" if $@;
- warn "couldn't do $specfile: $!" unless defined $return;
- warn "couldn't run $specfile" unless $return;
+ die "couldn't parse $specfile: $@" if $@;
+ die "couldn't do $specfile: $!" unless defined $return;
+ die "couldn't run $specfile" unless $return;
}
use strict "subs";
if ($new_emit_syntax) {
my $newscript = dirname($myname) . "/generate_emitter_new.pl";
unless ($return = do "$newscript") {
- warn "couldn't parse $newscript: $@" if $@;
- warn "couldn't do $newscript: $!" unless defined $return;
- warn "couldn't run $newscript" unless $return;
+ die "couldn't parse $newscript: $@" if $@;
+ die "couldn't do $newscript: $!" unless defined $return;
+ die "couldn't run $newscript" unless $return;
}
exit;
}
no strict "subs";
unless ($return = do $specfile) {
- warn "couldn't parse $specfile: $@" if $@;
- warn "couldn't do $specfile: $!" unless defined $return;
- warn "couldn't run $specfile" unless $return;
+ die "couldn't parse $specfile: $@" if $@;
+ die "couldn't do $specfile: $!" unless defined $return;
+ die "couldn't run $specfile" unless $return;
}
use strict "subs";
no strict "subs";
unless ($return = do $specfile) {
- warn "couldn't parse $specfile: $@" if $@;
- warn "couldn't do $specfile: $!" unless defined $return;
- warn "couldn't run $specfile" unless $return;
+ die "couldn't parse $specfile: $@" if $@;
+ die "couldn't do $specfile: $!" unless defined $return;
+ die "couldn't run $specfile" unless $return;
}
use strict "subs";
use strict "subs";
unless ($return = do $specfile) {
- warn "couldn't parse $specfile: $@" if $@;
- warn "couldn't do $specfile: $!" unless defined $return;
- warn "couldn't run $specfile" unless $return;
+ die "couldn't parse $specfile: $@" if $@;
+ die "couldn't do $specfile: $!" unless defined $return;
+ die "couldn't run $specfile" unless $return;
}
use strict "subs";
// recursive test, by bearophile, Jan 24 2006
// Compile with: -O3 -s -fomit-frame-pointer -funroll-loops
-#include <stdio.h>
+//#include <stdio.h>
int Ack(int x, int y) {
if (x == 0)
}
int Tak(int x, int y, int z) {
+ printf("X %d Y %d Z %d\n", x, y, z);
if (y < x)
return Tak( Tak(x-1, y, z), Tak(y-1, z, x), Tak(z-1, x, y) );
return z;
printf("Ack(3,%d): %d\n", n+1, Ack(3, n+1));
printf("Fib(%.1f): %.1f\n", 28.0+n, FibFP(28.0+n));
printf("Tak(%d,%d,%d): %d\n", 3*n, 2*n, n, Tak(3*n, 2*n, n));
- printf("Fib(3): %d\n", Fib(3));
- printf("Tak(3.0,2.0,1.0): %.1f\n", TakFP(3.0, 2.0, 1.0));
+#if 0
+ fprintf(stderr, "Fib(3): %d\n", Fib(3));
+ fprintf(stderr, "Tak(3.0,2.0,1.0): %.1f\n", TakFP(3.0, 2.0, 1.0));
+#endif
return 0;
}