--- /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 emit assembler for a backend graph
+ * @version $Id: amd64_emitter.c 26746 2009-11-27 08:53:15Z matze $
+ */
+#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 "irargs_t.h"
+#include "irprog.h"
+
+#include "../besched.h"
+
+#include "amd64_emitter.h"
+#include "gen_amd64_emitter.h"
+#include "amd64_nodes_attr.h"
+#include "amd64_new_nodes.h"
+
+#define SNPRINTF_BUF_LEN 128
+
+/**
+ * Returns the register at in position pos.
+ */
+static const arch_register_t *get_in_reg(const ir_node *node, int pos)
+{
+ ir_node *op;
+ const arch_register_t *reg = NULL;
+
+ assert(get_irn_arity(node) > pos && "Invalid IN position");
+
+ /* The out register of the operator at position pos is the
+ in register we need. */
+ op = get_irn_n(node, 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 *node, int pos)
+{
+ ir_node *proj;
+ const arch_register_t *reg = NULL;
+
+ /* 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(node) != mode_T) {
+ reg = arch_get_irn_register(node);
+ } else if (is_amd64_irn(node)) {
+ reg = arch_irn_get_register(node, pos);
+ } else {
+ const ir_edge_t *edge;
+
+ foreach_out_edge(node, 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;
+}
+
+/*************************************************************
+ * _ _ __ _ _
+ * (_) | | / _| | | | |
+ * _ __ _ __ _ _ __ | |_| |_ | |__ ___| |_ __ ___ _ __
+ * | '_ \| '__| | '_ \| __| _| | '_ \ / _ \ | '_ \ / _ \ '__|
+ * | |_) | | | | | | | |_| | | | | | __/ | |_) | __/ |
+ * | .__/|_| |_|_| |_|\__|_| |_| |_|\___|_| .__/ \___|_|
+ * | | | |
+ * |_| |_|
+ *************************************************************/
+
+void amd64_emit_immediate(const ir_node *node)
+{
+ (void) node;
+ /* TODO */
+}
+
+void amd64_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));
+}
+
+void amd64_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));
+}
+
+/**
+ * Returns the target label for a control flow node.
+ */
+static void amd64_emit_cfop_target(const ir_node *node)
+{
+ ir_node *block = get_irn_link(node);
+
+ be_emit_irprintf("BLOCK_%ld", get_irn_node_nr(block));
+}
+
+/***********************************************************************************
+ * _ __ _
+ * (_) / _| | |
+ * _ __ ___ __ _ _ _ __ | |_ _ __ __ _ _ __ ___ _____ _____ _ __| | __
+ * | '_ ` _ \ / _` | | '_ \ | _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
+ * | | | | | | (_| | | | | | | | | | | (_| | | | | | | __/\ V V / (_) | | | <
+ * |_| |_| |_|\__,_|_|_| |_| |_| |_| \__,_|_| |_| |_|\___| \_/\_/ \___/|_| |_|\_\
+ *
+ ***********************************************************************************/
+
+/**
+ * Emits code for a unconditional jump.
+ */
+static void emit_Jmp(const ir_node *node)
+{
+ ir_node *block;
+
+ /* for now, the code works for scheduled and non-schedules blocks */
+ block = get_nodes_block(node);
+
+ be_emit_cstring("\tjmp ");
+ amd64_emit_cfop_target(node);
+ be_emit_finish_line_gas(node);
+}
+
+/**
+ * Enters the emitter functions for handled nodes into the generic
+ * pointer of an opcode.
+ */
+static void amd64_register_emitters(void)
+{
+
+/* some convienience macros to register additional emitter functions
+ (other than the generated ones) */
+#define amd64_EMIT(a) op_amd64_##a->ops.generic = (op_func)emit_amd64_##a
+#define EMIT(a) op_##a->ops.generic = (op_func)emit_##a
+#define BE_EMIT(a) op_be_##a->ops.generic = (op_func)emit_be_##a
+
+ /* first clear the generic function pointer for all ops */
+ clear_irp_opcodes_generic_func();
+
+ /* register all emitter functions defined in spec */
+ amd64_register_spec_emitters();
+
+ /* register addtional emitter functions if needed */
+ EMIT(Jmp);
+
+#undef amd64_EMIT
+#undef BE_EMIT
+#undef EMIT
+}
+
+typedef void (*emit_func_ptr) (const ir_node *);
+
+/**
+ * Emits code for a node.
+ */
+static void amd64_emit_node(const ir_node *node)
+{
+ ir_op *op = get_irn_op(node);
+
+ if (op->ops.generic) {
+ emit_func_ptr func = (emit_func_ptr) op->ops.generic;
+ (*func) (node);
+ } else {
+ ir_fprintf(stderr, "No emitter for node %+F\n", node);
+ }
+}
+
+/**
+ * Walks over the nodes in a block connected by scheduling edges
+ * and emits code for each node.
+ */
+static void amd64_gen_block(ir_node *block, void *data)
+{
+ ir_node *node;
+ (void) data;
+
+ if (! is_Block(block))
+ return;
+
+ be_emit_cstring("BLOCK_");
+ be_emit_irprintf("%ld:\n", get_irn_node_nr(block));
+ be_emit_write_line();
+
+ sched_foreach(block, node) {
+ amd64_emit_node(node);
+ }
+}
+
+
+/**
+ * Emits code for function start.
+ */
+static void amd64_emit_func_prolog(ir_graph *irg)
+{
+ const char *irg_name = get_entity_name(get_irg_entity(irg));
+
+ /* TODO: emit function header */
+ be_emit_cstring("/* start of ");
+ be_emit_string(irg_name);
+ be_emit_cstring(" */\n");
+ be_emit_write_line();
+}
+
+/**
+ * Emits code for function end
+ */
+static void amd64_emit_func_epilog(ir_graph *irg)
+{
+ const char *irg_name = get_entity_name(get_irg_entity(irg));
+
+ /* TODO: emit function end */
+ be_emit_cstring("/* end of ");
+ be_emit_string(irg_name);
+ be_emit_cstring(" */\n");
+ be_emit_write_line();
+}
+
+/**
+ * Sets labels for control flow nodes (jump target)
+ * TODO: Jump optimization
+ */
+static void amd64_gen_labels(ir_node *block, void *env)
+{
+ ir_node *pred;
+ int n = get_Block_n_cfgpreds(block);
+ (void) env;
+
+ for (n--; n >= 0; n--) {
+ pred = get_Block_cfgpred(block, n);
+ set_irn_link(pred, block);
+ }
+}
+
+/**
+ * Main driver
+ */
+void amd64_gen_routine(const amd64_code_gen_t *cg, ir_graph *irg)
+{
+ (void)cg;
+
+ /* register all emitter functions */
+ amd64_register_emitters();
+
+ amd64_emit_func_prolog(irg);
+ irg_block_walk_graph(irg, amd64_gen_labels, NULL, NULL);
+ irg_walk_blkwise_graph(irg, NULL, amd64_gen_block, NULL);
+ amd64_emit_func_epilog(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 emit functions
+ * @version $Id: amd64_emitter.h 26317 2009-08-05 10:53:46Z matze $
+ */
+#ifndef FIRM_BE_amd64_amd64_EMITTER_H
+#define FIRM_BE_amd64_amd64_EMITTER_H
+
+#include "irargs_t.h"
+#include "irnode.h"
+#include "debug.h"
+
+#include "../bearch.h"
+#include "../beemitter.h"
+
+#include "bearch_amd64_t.h"
+
+void amd64_emit_source_register(const ir_node *node, int pos);
+void amd64_emit_dest_register(const ir_node *node, int pos);
+void amd64_emit_immediate(const ir_node *node);
+
+int get_amd64_reg_nr(ir_node *irn, int posi, int in_out);
+const char *get_amd64_in_reg_name(ir_node *irn, int pos);
+
+
+void amd64_gen_routine(const amd64_code_gen_t *cg, ir_graph *irg);
+
+#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 achitecture specific firm
+ * opcodes and the coresponding node constructors for the amd64
+ * assembler irg.
+ * @version $Id: amd64_new_nodes.c 26673 2009-10-01 16:43:13Z matze $
+ */
+#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 "amd64_nodes_attr.h"
+#include "amd64_new_nodes.h"
+#include "gen_amd64_regalloc_if.h"
+
+/**
+ * Dumper interface for dumping amd64 nodes in vcg.
+ * @param n the node to dump
+ * @param F the output file
+ * @param reason indicates which kind of information should be dumped
+ * @return 0 on success or != 0 on failure
+ */
+static int amd64_dump_node(ir_node *n, FILE *F, 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;
+ }
+
+ return 0;
+}
+
+const amd64_attr_t *get_amd64_attr_const(const ir_node *node)
+{
+ assert(is_amd64_irn(node) && "need amd64 node to get attributes");
+ return (const amd64_attr_t *)get_irn_generic_attr_const(node);
+}
+
+amd64_attr_t *get_amd64_attr(ir_node *node)
+{
+ assert(is_amd64_irn(node) && "need amd64 node to get attributes");
+ return (amd64_attr_t *)get_irn_generic_attr(node);
+}
+
+static const amd64_immediate_attr_t *get_amd64_immediate_attr_const(const ir_node *node)
+{
+ const amd64_attr_t *attr = get_amd64_attr_const(node);
+ const amd64_immediate_attr_t *imm_attr = CONST_CAST_AMD64_ATTR(amd64_immediate_attr_t, attr);
+
+ return imm_attr;
+}
+
+/*
+static amd64_immediate_attr_t *get_amd64_immediate_attr(ir_node *node)
+{
+ amd64_attr_t *attr = get_amd64_attr(node);
+ amd64_immediate_attr_t *imm_attr = CAST_AMD64_ATTR(amd64_immediate_attr_t, attr);
+
+ return imm_attr;
+}
+*/
+
+
+/**
+ * Returns the argument register requirements of a amd64 node.
+ */
+const arch_register_req_t **get_amd64_in_req_all(const ir_node *node)
+{
+ const amd64_attr_t *attr = get_amd64_attr_const(node);
+ return attr->in_req;
+}
+
+/**
+ * Returns the argument register requirement at position pos of an amd64 node.
+ */
+const arch_register_req_t *get_amd64_in_req(const ir_node *node, int pos)
+{
+ const amd64_attr_t *attr = get_amd64_attr_const(node);
+ return attr->in_req[pos];
+}
+
+/**
+ * Sets the IN register requirements at position pos.
+ */
+void set_amd64_req_in(ir_node *node, const arch_register_req_t *req, int pos)
+{
+ amd64_attr_t *attr = get_amd64_attr(node);
+ attr->in_req[pos] = req;
+}
+
+/**
+ * Initializes the nodes attributes.
+ */
+static void init_amd64_attributes(ir_node *node, arch_irn_flags_t 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);
+ amd64_attr_t *attr = get_amd64_attr(node);
+ backend_info_t *info;
+ (void) execution_units;
+
+ arch_irn_set_flags(node, flags);
+ attr->in_req = in_reqs;
+
+ 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]));
+}
+
+/**
+ * Initialize immediate attributes.
+ */
+static void init_amd64_immediate_attributes(ir_node *node, unsigned imm_value)
+{
+ amd64_immediate_attr_t *attr = get_irn_generic_attr (node);
+ attr->imm_value = imm_value;
+}
+
+/** Compare node attributes for Immediates. */
+static int cmp_amd64_attr_immediate(ir_node *a, ir_node *b)
+{
+ const amd64_immediate_attr_t *attr_a = get_amd64_immediate_attr_const(a);
+ const amd64_immediate_attr_t *attr_b = get_amd64_immediate_attr_const(b);
+
+ if (attr_a->imm_value != attr_b->imm_value)
+ return 1;
+
+ return 0;
+}
+
+static int cmp_amd64_attr(ir_node *a, ir_node *b)
+{
+ const amd64_attr_t *attr_a = get_amd64_attr_const(a);
+ const amd64_attr_t *attr_b = get_amd64_attr_const(b);
+ (void) attr_a;
+ (void) attr_b;
+
+ return 0;
+}
+
+/* Include the generated constructor functions */
+#include "gen_amd64_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 assembler ir node constructors.
+ * @version $Id: amd64_new_nodes.h 26549 2009-09-18 17:48:23Z matze $
+ */
+#ifndef FIRM_BE_TEMPALTE_amd64_NEW_NODES_H
+#define FIRM_BE_amd64_amd64_NEW_NODES_H
+
+#include "amd64_nodes_attr.h"
+
+/***************************************************************************************************
+ * _ _ _ __ _ _ _ _
+ * | | | | | | / / | | | | | | | |
+ * __ _| |_| |_ _ __ ___ ___| |_ / /_ _ ___| |_ _ __ ___ ___| |_| |__ ___ __| |___
+ * / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
+ * | (_| | |_| |_| | \__ \ __/ |_ / / (_| | __/ |_ | | | | | | __/ |_| | | | (_) | (_| \__ \
+ * \__,_|\__|\__|_| |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
+ * __/ |
+ * |___/
+ ***************************************************************************************************/
+
+/**
+ * Returns the attributes of an amd64 node.
+ */
+amd64_attr_t *get_amd64_attr(ir_node *node);
+
+const amd64_attr_t *get_amd64_attr_const(const ir_node *node);
+
+/**
+ * Returns the argument register requirements of an amd64 node.
+ */
+const arch_register_req_t **get_amd64_in_req_all(const ir_node *node);
+
+/**
+ * Returns the argument register requirements of an amd64 node.
+ */
+const arch_register_req_t *get_amd64_in_req(const ir_node *node, int pos);
+
+/**
+ * Sets the IN register requirements at position pos.
+ */
+void set_amd64_req_in(ir_node *node, const arch_register_req_t *req, int pos);
+
+/* Include the generated headers */
+#include "gen_amd64_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 attributes attached to all amd64 nodes
+ * @version $Id: amd64_nodes_attr.h 26317 2009-08-05 10:53:46Z matze $
+ */
+#ifndef FIRM_BE_amd64_amd64_NODES_ATTR_H
+#define FIRM_BE_amd64_amd64_NODES_ATTR_H
+
+#include "../bearch.h"
+
+typedef struct amd64_attr_t amd64_attr_t;
+typedef struct amd64_immediate_attr_t amd64_immediate_attr_t;
+
+struct amd64_attr_t
+{
+ const arch_register_req_t **in_req; /**< register requirements for arguments */
+ const arch_register_req_t **out_req; /**< register requirements for results */
+};
+
+struct amd64_immediate_attr_t
+{
+ unsigned imm_value; /**< the immediate value to load */
+};
+
+#define CAST_AMD64_ATTR(type,ptr) ((type *)(ptr))
+#define CONST_CAST_AMD64_ATTR(type,ptr) ((const type *)(ptr))
+
+#endif
--- /dev/null
+# Creation: 2006/02/13
+# $Id: amd64_spec.pl 26673 2009-10-01 16:43:13Z matze $
+
+# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
+
+$arch = "amd64";
+
+# The node description is done as a perl hash initializer with the
+# following structure:
+#
+# %nodes = (
+#
+# <op-name> => {
+# op_flags => "N|L|C|X|I|F|Y|H|c|K", # optional
+# irn_flags => "R|N|I" # optional
+# arity => "0|1|2|3 ... |variable|dynamic|any", # optional
+# state => "floats|pinned|mem_pinned|exc_pinned", # optional
+# args => [
+# { type => "type 1", name => "name 1" },
+# { type => "type 2", name => "name 2" },
+# ...
+# ],
+# comment => "any comment for constructor", # optional
+# reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] },
+# cmp_attr => "c source code for comparing node attributes", # optional
+# outs => { "out1", "out2" },# optional, creates pn_op_out1, ... consts
+# ins => { "in1", "in2" }, # optional, creates n_op_in1, ... consts
+# mode => "mode_Iu", # optional, predefines the mode
+# emit => "emit code with templates", # optional for virtual nodes
+# attr => "additional attribute arguments for constructor", # optional
+# init_attr => "emit attribute initialization template", # optional
+# rd_constructor => "c source code which constructs an ir_node", # optional
+# hash_func => "name of the hash function for this operation", # optional, get the default hash function else
+# latency => "latency of this operation (can be float)" # optional
+# attr_type => "name of the attribute struct", # optional
+# },
+#
+# ... # (all nodes you need to describe)
+#
+# ); # close the %nodes initializer
+
+# op_flags: flags for the operation, OPTIONAL (default is "N")
+# the op_flags correspond to the firm irop_flags:
+# N irop_flag_none
+# L irop_flag_labeled
+# C irop_flag_commutative
+# X irop_flag_cfopcode
+# I irop_flag_ip_cfopcode
+# F irop_flag_fragile
+# Y irop_flag_forking
+# H irop_flag_highlevel
+# c irop_flag_constlike
+# K irop_flag_keep
+#
+# irn_flags: special node flags, OPTIONAL (default is 0)
+# following irn_flags are supported:
+# R rematerializeable
+# N not spillable
+# I ignore for register allocation
+#
+# state: state of the operation, OPTIONAL (default is "floats")
+#
+# arity: arity of the operation, MUST NOT BE OMITTED
+#
+# args: the OPTIONAL arguments of the node constructor (debug, irg and block
+# are always the first 3 arguments and are always autmatically
+# created)
+# If this key is missing the following arguments will be created:
+# for i = 1 .. arity: ir_node *op_i
+# ir_mode *mode
+#
+# outs: if a node defines more than one output, the names of the projections
+# nodes having outs having automatically the mode mode_T
+#
+# comment: OPTIONAL comment for the node constructor
+#
+# rd_constructor: for every operation there will be a
+# new_rd_<arch>_<op-name> function with the arguments from above
+# which creates the ir_node corresponding to the defined operation
+# you can either put the complete source code of this function here
+#
+# This key is OPTIONAL. If omitted, the following constructor will
+# be created:
+# if (!op_<arch>_<op-name>) assert(0);
+# for i = 1 to arity
+# set in[i] = op_i
+# done
+# res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
+# return res
+#
+# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
+
+# 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 => "rax", type => 1 },
+ { name => "rcx", type => 1 },
+ { name => "rdx", type => 1 },
+ { name => "rbx", type => 2 },
+ { name => "rsi", type => 2 },
+ { name => "rdi", type => 2 },
+ { name => "rbp", type => 2 },
+ { name => "rsp", type => 4 }, # stackpointer?
+ { name => "r8", type => 1 },
+ { name => "r9", type => 1 },
+ { name => "r10", type => 1 },
+ { name => "r11", type => 1 },
+ { name => "r12", type => 2 },
+ { name => "r13", type => 2 },
+ { name => "r14", type => 2 },
+ { name => "r15", type => 2 },
+ { mode => "mode_Iu" }
+ ],
+ fp => [
+ { name => "xmm0", type => 1 },
+ { name => "xmm1", type => 1 },
+ { name => "xmm2", type => 1 },
+ { name => "xmm3", type => 1 },
+ { name => "xmm4", type => 1 },
+ { name => "xmm5", type => 1 },
+ { name => "xmm6", type => 1 },
+ { name => "xmm7", type => 1 },
+ { name => "xmm8", type => 1 },
+ { name => "xmm9", type => 1 },
+ { name => "xmm10", type => 1 },
+ { name => "xmm11", type => 1 },
+ { name => "xmm12", type => 1 },
+ { name => "xmm13", type => 1 },
+ { name => "xmm14", type => 1 },
+ { name => "xmm15", type => 1 },
+ { mode => "mode_D" }
+ ]
+);
+
+%emit_templates = (
+ S1 => "${arch}_emit_source_register(node, 0);",
+ S2 => "${arch}_emit_source_register(node, 1);",
+ S3 => "${arch}_emit_source_register(node, 2);",
+ S4 => "${arch}_emit_source_register(node, 3);",
+ S5 => "${arch}_emit_source_register(node, 4);",
+ S6 => "${arch}_emit_source_register(node, 5);",
+ D1 => "${arch}_emit_dest_register(node, 0);",
+ D2 => "${arch}_emit_dest_register(node, 1);",
+ D3 => "${arch}_emit_dest_register(node, 2);",
+ D4 => "${arch}_emit_dest_register(node, 3);",
+ D5 => "${arch}_emit_dest_register(node, 4);",
+ D6 => "${arch}_emit_dest_register(node, 5);",
+ C => "${arch}_emit_immediate(node);"
+);
+
+%init_attr = (
+ amd64_attr_t =>
+ "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);",
+ amd64_immediate_attr_t =>
+ "\tinit_amd64_attributes(res, flags, in_reqs, exec_units, n_res);"
+ . "\tinit_amd64_immediate_attributes(res, imm_value);",
+);
+
+%compare_attr = (
+ amd64_attr_t => "cmp_amd64_attr",
+ amd64_immediate_attr_t => "cmp_amd64_attr_immediate",
+);
+
+%nodes = (
+Push => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp", "rsp" ], out => [ "rsp:I|S", "none" ] },
+ ins => [ "base", "index", "mem", "val", "stack" ],
+ emit => '. push %S1',
+ outs => [ "stack", "M" ],
+ am => "source,unary",
+ latency => 2,
+# units => [ "GP" ],
+},
+Immediate => {
+ op_flags => "c",
+ attr => "unsigned imm_value",
+ attr_type => "amd64_immediate_attr_t",
+ reg_req => { out => [ "gp" ] },
+ emit => '. movq %C, %D1',
+ mode => "mode_Iu",
+},
+);
--- /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 code selection (transform FIRM into amd64 FIRM)
+ * @version $Id: amd64_transform.c 26673 2009-10-01 16:43:13Z matze $
+ */
+#include "config.h"
+
+#include "irnode_t.h"
+#include "irgraph_t.h"
+#include "irmode_t.h"
+#include "irgmod.h"
+#include "iredges.h"
+#include "irvrfy.h"
+#include "ircons.h"
+#include "iropt_t.h"
+#include "debug.h"
+
+#include "../benode.h"
+#include "../betranshlp.h"
+#include "bearch_amd64_t.h"
+
+#include "amd64_nodes_attr.h"
+#include "amd64_transform.h"
+#include "amd64_new_nodes.h"
+
+#include "gen_amd64_regalloc_if.h"
+
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
+
+/** holds the current code generator during transformation */
+static amd64_code_gen_t *env_cg;
+
+/* Some support functions: */
+
+/**
+ * Create a DAG constructing a given Const.
+ *
+ * @param irn a Firm const
+ */
+static ir_node *create_const_graph(ir_node *irn, ir_node *block)
+{
+ tarval *tv = get_Const_tarval(irn);
+ ir_mode *mode = get_tarval_mode(tv);
+ dbg_info *dbgi = get_irn_dbg_info(irn);
+ unsigned value;
+
+ if (mode_is_reference(mode)) {
+ /* AMD64 is 64bit, so we can safely convert a reference tarval into Iu */
+ assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
+ tv = tarval_convert_to(tv, mode_Iu);
+ }
+
+ value = get_tarval_long(tv);
+ printf ("TEST GENERATE %d\n", value);
+
+ return new_bd_amd64_Immediate(dbgi, block, value);
+}
+
+/* Op transformers: */
+
+/**
+ * Transforms a Const node.
+ *
+ * @return The transformed ARM node.
+ */
+static ir_node *gen_Const(ir_node *node) {
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_mode *mode = get_irn_mode(node);
+ (void) mode;
+
+ ir_node *res = create_const_graph(node, block);
+ be_dep_on_frame (res);
+
+ return res;
+}
+
+/* Boilerplate code for transformation: */
+
+static void amd64_pretransform_node(void)
+{
+ amd64_code_gen_t *cg = env_cg;
+ (void) cg;
+}
+
+static void set_transformer(ir_op *op, be_transform_func amd64_transform_func)
+{
+ op->ops.generic = (op_func)amd64_transform_func;
+}
+
+static void amd64_register_transformers(void)
+{
+ clear_irp_opcodes_generic_func();
+
+ set_transformer(op_Const, gen_Const);
+}
+
+
+void amd64_transform_graph(amd64_code_gen_t *cg)
+{
+ amd64_register_transformers();
+ env_cg = cg;
+ be_transform_graph(cg->birg, amd64_pretransform_node);
+}
+
+void amd64_init_transform(void)
+{
+ FIRM_DBG_REGISTER(dbg, "firm.be.amd64.transform");
+}
--- /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 declaration for the transform function (code selection)
+ * @version $Id: amd64_transform.h 26542 2009-09-18 09:18:32Z matze $
+ */
+#ifndef FIRM_BE_amd64_amd64_TRANSFORM_H
+#define FIRM_BE_amd64_amd64_TRANSFORM_H
+
+void amd64_init_transform(void);
+
+void amd64_transform_graph(amd64_code_gen_t *cg);
+
+#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 main amd64 backend driver file.
+ * @version $Id: bearch_amd64.c 26909 2010-01-05 15:56:54Z matze $
+ */
+#include "config.h"
+
+#include "pseudo_irg.h"
+#include "irgwalk.h"
+#include "irprog.h"
+#include "irprintf.h"
+#include "ircons.h"
+#include "irgmod.h"
+
+#include "bitset.h"
+#include "debug.h"
+
+#include "be.h"
+#include "../bearch.h"
+#include "../benode.h"
+#include "../belower.h"
+#include "../besched.h"
+#include "../beabi.h"
+#include "../bemodule.h"
+#include "../begnuas.h"
+#include "../belistsched.h"
+
+#include "bearch_amd64_t.h"
+
+#include "amd64_new_nodes.h"
+#include "gen_amd64_regalloc_if.h"
+#include "amd64_transform.h"
+#include "amd64_emitter.h"
+
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
+
+static arch_irn_class_t amd64_classify(const ir_node *irn)
+{
+ (void) irn;
+ return 0;
+}
+
+static ir_entity *amd64_get_frame_entity(const ir_node *node)
+{
+ (void) node;
+ /* TODO: return the ir_entity assigned to the frame */
+ return NULL;
+}
+
+static void amd64_set_frame_entity(ir_node *node, ir_entity *ent)
+{
+ (void) node;
+ (void) ent;
+ /* TODO: set the ir_entity assigned to the frame */
+}
+
+/**
+ * This function is called by the generic backend to correct offsets for
+ * nodes accessing the stack.
+ */
+static void amd64_set_frame_offset(ir_node *irn, int offset)
+{
+ (void) irn;
+ (void) offset;
+ /* TODO: correct offset if irn accesses the stack */
+}
+
+static int amd64_get_sp_bias(const ir_node *irn)
+{
+ (void) irn;
+ return 0;
+}
+
+/* fill register allocator interface */
+
+static const arch_irn_ops_t amd64_irn_ops = {
+ get_amd64_in_req,
+ amd64_classify,
+ amd64_get_frame_entity,
+ amd64_set_frame_entity,
+ amd64_set_frame_offset,
+ amd64_get_sp_bias,
+ NULL, /* get_inverse */
+ NULL, /* get_op_estimated_cost */
+ NULL, /* possible_memory_operand */
+ NULL, /* perform_memory_operand */
+};
+
+
+
+/**
+ * Transforms the standard firm graph into
+ * a amd64 firm graph
+ */
+static void amd64_prepare_graph(void *self)
+{
+ amd64_code_gen_t *cg = self;
+
+ amd64_transform_graph (cg);
+
+ if (cg->dump)
+ be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
+}
+
+
+
+/**
+ * Called immediatly before emit phase.
+ */
+static void amd64_finish_irg(void *self)
+{
+ amd64_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ dump_ir_block_graph_sched(irg, "-amd64-finished");
+}
+
+
+static void amd64_before_ra(void *self)
+{
+ (void) self;
+ /* Some stuff you need to do after scheduling but before register allocation */
+}
+
+static void amd64_after_ra(void *self)
+{
+ (void) self;
+ /* Some stuff you need to do immediatly after register allocation */
+}
+
+
+
+/**
+ * Emits the code, closes the output file and frees
+ * the code generator interface.
+ */
+static void amd64_emit_and_done(void *self)
+{
+ amd64_code_gen_t *cg = self;
+ ir_graph *irg = cg->irg;
+
+ amd64_gen_routine(cg, irg);
+
+ /* de-allocate code generator */
+ free(cg);
+}
+
+static void *amd64_cg_init(be_irg_t *birg);
+
+static const arch_code_generator_if_t amd64_code_gen_if = {
+ amd64_cg_init,
+ NULL, /* get_pic_base hook */
+ NULL, /* before abi introduce hook */
+ amd64_prepare_graph,
+ NULL, /* spill hook */
+ amd64_before_ra, /* before register allocation hook */
+ amd64_after_ra, /* after register allocation hook */
+ amd64_finish_irg,
+ amd64_emit_and_done
+};
+
+/**
+ * Initializes the code generator.
+ */
+static void *amd64_cg_init(be_irg_t *birg)
+{
+ const arch_env_t *arch_env = be_get_birg_arch_env(birg);
+ amd64_isa_t *isa = (amd64_isa_t *) arch_env;
+ amd64_code_gen_t *cg = XMALLOC(amd64_code_gen_t);
+
+ cg->impl = &amd64_code_gen_if;
+ cg->irg = be_get_birg_irg(birg);
+ cg->isa = isa;
+ cg->birg = birg;
+ cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0;
+
+ return (arch_code_generator_t *)cg;
+}
+
+
+
+const arch_isa_if_t amd64_isa_if;
+static amd64_isa_t amd64_isa_template = {
+ {
+ &amd64_isa_if, /* isa interface implementation */
+ &amd64_gp_regs[REG_RSP], /* stack pointer register */
+ &amd64_gp_regs[REG_RBP], /* base pointer register */
+ &amd64_reg_classes[CLASS_amd64_gp], /* link pointer register class */
+ -1, /* stack direction */
+ 2, /* power of two stack alignment for calls, 2^2 == 4 */
+ NULL, /* main environment */
+ 7, /* costs for a spill instruction */
+ 5, /* costs for a reload instruction */
+ },
+};
+
+/**
+ * Initializes the backend ISA
+ */
+static arch_env_t *amd64_init(FILE *outfile)
+{
+ static int run_once = 0;
+ amd64_isa_t *isa;
+
+ if(run_once)
+ return NULL;
+ run_once = 1;
+
+ isa = XMALLOC(amd64_isa_t);
+ memcpy(isa, &amd64_isa_template, sizeof(*isa));
+
+ be_emit_init(outfile);
+
+ amd64_register_init();
+ amd64_create_opcodes(&amd64_irn_ops);
+
+ return &isa->arch_env;
+}
+
+
+
+/**
+ * Closes the output file and frees the ISA structure.
+ */
+static void amd64_done(void *self)
+{
+ amd64_isa_t *isa = self;
+
+ /* emit now all global declarations */
+ be_gas_emit_decls(isa->arch_env.main_env);
+
+ be_emit_exit();
+ free(self);
+}
+
+
+static unsigned amd64_get_n_reg_class(void)
+{
+ return N_CLASSES;
+}
+
+static const arch_register_class_t *amd64_get_reg_class(unsigned i)
+{
+ assert(i < N_CLASSES);
+ return &amd64_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 *amd64_get_reg_class_for_mode(const ir_mode *mode)
+{
+ if (mode_is_float(mode))
+ return &amd64_reg_classes[CLASS_amd64_fp];
+ else
+ return &amd64_reg_classes[CLASS_amd64_gp];
+}
+
+
+
+typedef struct {
+ be_abi_call_flags_bits_t flags;
+ const arch_env_t *arch_env;
+ ir_graph *irg;
+} amd64_abi_env_t;
+
+static void *amd64_abi_init(const be_abi_call_t *call, const arch_env_t *arch_env, ir_graph *irg)
+{
+ amd64_abi_env_t *env = XMALLOC(amd64_abi_env_t);
+ be_abi_call_flags_t fl = be_abi_call_get_flags(call);
+ env->flags = fl.bits;
+ env->irg = irg;
+ env->arch_env = arch_env;
+ return env;
+}
+
+/**
+ * Get the between type for that call.
+ * @param self The callback object.
+ * @return The between type of for that call.
+ */
+static ir_type *amd64_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("amd64_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;
+}
+
+/**
+ * Build the prolog, return the BASE POINTER register
+ */
+static const arch_register_t *amd64_abi_prologue(void *self, ir_node **mem,
+ pmap *reg_map, int *stack_bias)
+{
+ amd64_abi_env_t *env = self;
+ const arch_env_t *aenv = env->arch_env;
+ (void) mem;
+ (void) stack_bias;
+ (void) aenv;
+ (void) reg_map;
+
+ if (!env->flags.try_omit_fp) {
+ /* FIXME: maybe later here should be some code to generate
+ * the usual abi prologue */
+ return env->arch_env->bp;
+ }
+
+ return env->arch_env->sp;
+}
+
+/* Build the epilog */
+static void amd64_abi_epilogue(void *self, ir_node *bl, ir_node **mem,
+ pmap *reg_map)
+{
+ amd64_abi_env_t *env = self;
+ const arch_env_t *aenv = env->arch_env;
+ ir_node *curr_sp = be_abi_reg_map_get(reg_map, aenv->sp);
+ ir_node *curr_bp = be_abi_reg_map_get(reg_map, aenv->bp);
+ (void) bl;
+ (void) mem;
+
+ if (env->flags.try_omit_fp) {
+ curr_sp = be_new_IncSP(aenv->sp, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
+ }
+
+ be_abi_reg_map_set(reg_map, aenv->sp, curr_sp);
+ be_abi_reg_map_set(reg_map, aenv->bp, curr_bp);
+}
+
+static const be_abi_callbacks_t amd64_abi_callbacks = {
+ amd64_abi_init,
+ free,
+ amd64_get_between_type,
+ amd64_abi_prologue,
+ amd64_abi_epilogue,
+};
+
+/**
+ * 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 amd64_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);
+ be_abi_call_flags_t call_flags;
+ (void) self;
+
+ /* set abi flags for calls */
+ call_flags.bits.left_to_right = 0;
+ call_flags.bits.store_args_sequential = 1;
+ call_flags.bits.try_omit_fp = 1;
+ call_flags.bits.fp_free = 0;
+ call_flags.bits.call_has_imm = 1;
+
+ /* set stack parameter passing style */
+ be_abi_call_set_flags(abi, call_flags, &amd64_abi_callbacks);
+
+ for (i = 0; i < n; i++) {
+ /* TODO: implement register parameter: */
+ /* reg = get reg for param i; */
+ /* be_abi_call_param_reg(abi, i, reg); */
+
+ /* default: all parameters on stack */
+ tp = get_method_param_type(method_type, i);
+ mode = get_type_mode(tp);
+ be_abi_call_param_stack(abi, i, mode, 4, 0, 0, ABI_CONTEXT_BOTH);
+ }
+
+ /* TODO: set correct return register */
+ /* default: return value is in R0 resp. F0 */
+ if (get_method_n_ress(method_type) > 0) {
+ tp = get_method_res_type(method_type, 0);
+ mode = get_type_mode(tp);
+
+ /* FIXME: No floating point yet */
+ /* be_abi_call_res_reg(abi, 0,
+ mode_is_float(mode) ? &amd64_fp_regs[REG_F0] : &amd64_gp_regs[REG_R0], ABI_CONTEXT_BOTH) */;
+
+ be_abi_call_res_reg(abi, 0,
+ &amd64_gp_regs[REG_RAX], ABI_CONTEXT_BOTH);
+ }
+}
+
+static int amd64_to_appear_in_schedule(void *block_env, const ir_node *irn)
+{
+ (void) block_env;
+
+ if(!is_amd64_irn(irn))
+ return -1;
+
+ return 1;
+}
+
+/**
+ * Initializes the code generator interface.
+ */
+static const arch_code_generator_if_t *amd64_get_code_generator_if(
+ void *self)
+{
+ (void) self;
+ return &amd64_code_gen_if;
+}
+
+list_sched_selector_t amd64_sched_selector;
+
+/**
+ * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
+ */
+static const list_sched_selector_t *amd64_get_list_sched_selector(
+ const void *self, list_sched_selector_t *selector)
+{
+ (void) self;
+ (void) selector;
+
+ amd64_sched_selector = trivial_selector;
+ amd64_sched_selector.to_appear_in_schedule = amd64_to_appear_in_schedule;
+ return &amd64_sched_selector;
+}
+
+static const ilp_sched_selector_t *amd64_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 amd64_get_reg_class_alignment(const arch_register_class_t *cls)
+{
+ ir_mode *mode = arch_register_class_mode(cls);
+ return get_mode_size_bytes(mode);
+}
+
+/**
+ * Returns the libFirm configuration parameter for this backend.
+ */
+static const backend_params *amd64_get_backend_params(void) {
+ static backend_params p = {
+ 0, /* no dword lowering */
+ 0, /* no inline assembly */
+ NULL, /* will be set later */
+ NULL, /* no creator function */
+ NULL, /* context for create_intrinsic_fkt */
+ NULL, /* parameter for if conversion */
+ NULL, /* float arithmetic mode */
+ 0, /* no trampoline support: size 0 */
+ 0, /* no trampoline support: align 0 */
+ NULL, /* no trampoline support: no trampoline builder */
+ 4 /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
+ };
+ return &p;
+}
+
+static const be_execution_unit_t ***amd64_get_allowed_execution_units(
+ const ir_node *irn)
+{
+ (void) irn;
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+static const be_machine_t *amd64_get_machine(const void *self)
+{
+ (void) self;
+ /* TODO */
+ assert(0);
+ return NULL;
+}
+
+static ir_graph **amd64_get_backend_irg_list(const void *self,
+ ir_graph ***irgs)
+{
+ (void) self;
+ (void) irgs;
+ return NULL;
+}
+
+static asm_constraint_flags_t amd64_parse_asm_constraint(const char **c)
+{
+ (void) c;
+ return ASM_CONSTRAINT_FLAG_INVALID;
+}
+
+static int amd64_is_valid_clobber(const char *clobber)
+{
+ (void) clobber;
+ return 0;
+}
+
+const arch_isa_if_t amd64_isa_if = {
+ amd64_init,
+ amd64_done,
+ NULL, /* handle intrinsics */
+ amd64_get_n_reg_class,
+ amd64_get_reg_class,
+ amd64_get_reg_class_for_mode,
+ amd64_get_call_abi,
+ amd64_get_code_generator_if,
+ amd64_get_list_sched_selector,
+ amd64_get_ilp_sched_selector,
+ amd64_get_reg_class_alignment,
+ amd64_get_backend_params,
+ amd64_get_allowed_execution_units,
+ amd64_get_machine,
+ amd64_get_backend_irg_list,
+ NULL, /* mark remat */
+ amd64_parse_asm_constraint,
+ amd64_is_valid_clobber
+};
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_amd64);
+void be_init_arch_amd64(void)
+{
+ be_register_isa_if("amd64", &amd64_isa_if);
+ FIRM_DBG_REGISTER(dbg, "firm.be.amd64.cg");
+ amd64_init_transform();
+}
--- /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 TEMPALTE backend -- private header
+ * @version $Id: bearch_amd64_t.h 26542 2009-09-18 09:18:32Z matze $
+ */
+#ifndef FIRM_BE_amd64_BEARCH_amd64_T_H
+#define FIRM_BE_amd64_BEARCH_amd64_T_H
+
+#include "debug.h"
+#include "amd64_nodes_attr.h"
+#include "be.h"
+#include "../beemitter.h"
+#include "set.h"
+
+typedef struct amd64_isa_t amd64_isa_t;
+typedef struct amd64_code_gen_t amd64_code_gen_t;
+typedef struct amd64_transform_env_t amd64_transform_env_t;
+
+struct amd64_code_gen_t {
+ const arch_code_generator_if_t *impl; /**< implementation */
+ ir_graph *irg; /**< current irg */
+ amd64_isa_t *isa; /**< the isa instance */
+ be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */
+ char dump; /**< set to 1 if graphs should be dumped */
+};
+
+struct amd64_isa_t {
+ arch_env_t arch_env; /**< must be derived from arch_isa */
+};
+
+/**
+ * this is a struct to minimize the number of parameters
+ * for transformation walker
+ */
+struct amd64_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 */
+};
+
+#endif
void be_init_arch_mips(void);
void be_init_arch_arm(void);
void be_init_arch_sparc(void);
+void be_init_arch_amd64(void);
void be_init_arch_sta(void);
void be_init_arch_sparc(void);
void be_init_arch_TEMPLATE(void);
be_init_arch_mips();
be_init_arch_arm();
be_init_arch_sparc();
+ be_init_arch_amd64();
be_init_arch_TEMPLATE();
#ifdef WITH_ILP