summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJonas Haag <jonas@lophus.org>2015-11-25 15:27:38 +0100
committerPhilipp Serrer <philipp@serrer.de>2018-01-18 17:57:27 +0100
commit0a797f4129b4e111fc21a58bc41d74b91f382b0d (patch)
tree71728a2f4daf58e712ff60b9001517640075925a
parent4f989c0d097e1ea9997b0ca0e0c096c07126fe32 (diff)
amd64 backend: Light refactoring
-rw-r--r--ir/be/amd64/amd64_emitter.c27
-rw-r--r--ir/be/amd64/amd64_transform.c2
2 files changed, 29 insertions, 0 deletions
diff --git a/ir/be/amd64/amd64_emitter.c b/ir/be/amd64/amd64_emitter.c
index fb510f2..5bfa295 100644
--- a/ir/be/amd64/amd64_emitter.c
+++ b/ir/be/amd64/amd64_emitter.c
@@ -34,6 +34,11 @@ static bool omit_fp;
static int frame_type_size;
static int callframe_offset;
+static bool fallthrough_possible(const ir_node *block, const ir_node *target)
+{
+ return be_emit_get_prev_block(target) == block;
+}
+
static char get_gp_size_suffix(x86_insn_size_t const size)
{
switch (size) {
@@ -592,6 +597,28 @@ static void emit_amd64_asm(const ir_node *node)
be_emit_asm(node, emit_amd64_asm_operand);
}
+static void emit_amd64_call(const ir_node* node)
+{
+ amd64_emitf(node, "call %*AM");
+
+ if (is_cfop(node)) {
+ /* If the call throws we have to add a jump to its X_regular block. */
+ const ir_node* const block = get_nodes_block(node);
+ const ir_node* const x_regular_proj = get_Proj_for_pn(node, node->op->pn_x_regular);
+ if (x_regular_proj == NULL) {
+ /* Call always throws and/or never returns. */
+ } else {
+ const ir_node* const x_regular_block = be_emit_get_cfop_target(x_regular_proj);
+ assert(x_regular_block != NULL);
+ if (!fallthrough_possible(block, x_regular_block)) {
+ amd64_emitf(x_regular_proj, "jmp %L");
+ } else if (be_options.verbose_asm) {
+ amd64_emitf(x_regular_proj, "/* fallthrough to %L */");
+ }
+ }
+ }
+}
+
/**
* Emit a Jmp.
*/
diff --git a/ir/be/amd64/amd64_transform.c b/ir/be/amd64/amd64_transform.c
index 207a7b0..6fe2299 100644
--- a/ir/be/amd64/amd64_transform.c
+++ b/ir/be/amd64/amd64_transform.c
@@ -2198,6 +2198,8 @@ static ir_node *match_mov(dbg_info *dbgi, ir_node *block, ir_node *value,
mem_proj = get_Proj_for_pn(load, pn_Load_M);
op_mode = AMD64_OP_ADDR;
} else {
+ assert(arity == 0); /* AMD64_OP_REG is currently hardcoded to always
+ * output the register of the first input. */
ir_node *new_value = be_transform_node(value);
int const input = arity++;
addr = (x86_addr_t) {