aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-01-14 12:34:23 +0200
committerPekka Enberg <penberg@kernel.org>2012-01-14 12:37:38 +0200
commitd82be0b568d665678faf21fa79f1772d6ebbdf98 (patch)
treec983ebdba91b582a08bc23e4cd8e63dc24f6dc5b
parentf3a677cab69f8300875b65e3b3c372f3683a5bda (diff)
downloadjato-d82be0b568d665678faf21fa79f1772d6ebbdf98.tar.gz
x86-64: Simplify prolog and epilog code generation
Same as commit f3a677c ("x86-32: Simplify prolog and epilog code generation") but on x86-64. Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--arch/x86/emit-code.c34
-rw-r--r--arch/x86/include/arch/registers_64.h3
-rw-r--r--arch/x86/registers_64.c10
3 files changed, 36 insertions, 11 deletions
diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index dfd7f151..9cbd2913 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -1974,6 +1974,28 @@ static void __emit64_pop_xmm(struct buffer *buf, enum machine_reg reg)
__emit_add_imm_reg(buf, 0x08, MACH_REG_RSP);
}
+static void emit_save_callee_save_regs(struct buffer *buf)
+{
+ int i;
+
+ for (i = 0; i < NR_CALLEE_SAVE_REGS; i++) {
+ enum machine_reg reg = callee_save_regs[i];
+
+ __emit_push_reg(buf, reg);
+ }
+}
+
+static void emit_restore_callee_save_regs(struct buffer *buf)
+{
+ int i;
+
+ for (i = 0; i < NR_CALLEE_SAVE_REGS; i++) {
+ enum machine_reg reg = callee_save_regs[NR_CALLEE_SAVE_REGS - i - 1];
+
+ __emit_pop_reg(buf, reg);
+ }
+}
+
void emit_prolog(struct buffer *buf, struct stack_frame *frame,
unsigned long frame_size)
{
@@ -1989,11 +2011,7 @@ void emit_prolog(struct buffer *buf, struct stack_frame *frame,
if (frame_size)
__emit64_sub_imm_reg(buf, frame_size, MACH_REG_RSP);
- __emit_push_reg(buf, MACH_REG_RBX);
- __emit_push_reg(buf, MACH_REG_R12);
- __emit_push_reg(buf, MACH_REG_R13);
- __emit_push_reg(buf, MACH_REG_R14);
- __emit_push_reg(buf, MACH_REG_R15);
+ emit_save_callee_save_regs(buf);
/* Save *this. */
__emit_push_reg(buf, MACH_REG_RDI);
@@ -2011,11 +2029,7 @@ static void emit_restore_regs(struct buffer *buf)
/* Clear *this from stack. */
__emit_add_imm_reg(buf, 0x08, MACH_REG_RSP);
- __emit_pop_reg(buf, MACH_REG_R15);
- __emit_pop_reg(buf, MACH_REG_R14);
- __emit_pop_reg(buf, MACH_REG_R13);
- __emit_pop_reg(buf, MACH_REG_R12);
- __emit_pop_reg(buf, MACH_REG_RBX);
+ emit_restore_callee_save_regs(buf);
}
static void emit_save_regparm(struct buffer *buf)
diff --git a/arch/x86/include/arch/registers_64.h b/arch/x86/include/arch/registers_64.h
index 712e7677..117f5eca 100644
--- a/arch/x86/include/arch/registers_64.h
+++ b/arch/x86/include/arch/registers_64.h
@@ -72,6 +72,9 @@ enum machine_reg {
#define NR_CALLER_SAVE_REGS 25
extern enum machine_reg caller_save_regs[NR_CALLER_SAVE_REGS];
+#define NR_CALLEE_SAVE_REGS 5
+extern enum machine_reg callee_save_regs[NR_CALLEE_SAVE_REGS];
+
const char *reg_name(enum machine_reg reg);
enum machine_reg_type reg_type(enum machine_reg reg);
bool reg_supports_type(enum machine_reg reg, enum vm_type type);
diff --git a/arch/x86/registers_64.c b/arch/x86/registers_64.c
index dd177816..6a235bd6 100644
--- a/arch/x86/registers_64.c
+++ b/arch/x86/registers_64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Pekka Enberg
+ * Copyright (c) 2008, 2012 Pekka Enberg
*
* This file is released under the GPL version 2 with the following
* clarification and special exception:
@@ -58,6 +58,14 @@ enum machine_reg caller_save_regs[NR_CALLER_SAVE_REGS] = {
MACH_REG_XMM15,
};
+enum machine_reg callee_save_regs[NR_CALLEE_SAVE_REGS] = {
+ MACH_REG_RBX,
+ MACH_REG_R12,
+ MACH_REG_R13,
+ MACH_REG_R14,
+ MACH_REG_R15,
+};
+
static const char *register_names[] = {
[MACH_REG_RAX] = "RAX",
[MACH_REG_RCX] = "RCX",