aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-01-14 12:20:35 +0200
committerPekka Enberg <penberg@kernel.org>2012-01-14 12:28:58 +0200
commitf3a677cab69f8300875b65e3b3c372f3683a5bda (patch)
treee40be041f7850ed9d5dec05ee44db39ac144a2a8
parent84ce358a2ca281de8ba35cdb0a03a2aaa560af4a (diff)
downloadjato-f3a677cab69f8300875b65e3b3c372f3683a5bda.tar.gz
x86-32: Simplify prolog and epilog code generation
This patch introduces a 'callee_save_regs' array and changes emit_prolog() and emit_epilog() to use it. Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--arch/x86/emit-code.c31
-rw-r--r--arch/x86/include/arch/registers_32.h3
-rw-r--r--arch/x86/registers_32.c10
3 files changed, 35 insertions, 9 deletions
diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index 34107add..dfd7f151 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -664,13 +664,32 @@ static void emit_test_imm_memdisp(struct insn *insn, struct buffer *buf, struct
__emit_test_imm_memdisp(buf, insn->src.imm, insn->dest.disp);
}
+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)
{
- /* Unconditionally push callee-saved registers */
- __emit_push_reg(buf, MACH_REG_EDI);
- __emit_push_reg(buf, MACH_REG_ESI);
- __emit_push_reg(buf, MACH_REG_EBX);
+ emit_save_callee_save_regs(buf);
__emit_push_reg(buf, MACH_REG_EBP);
__emit_mov_reg_reg(buf, MACH_REG_ESP, MACH_REG_EBP);
@@ -693,9 +712,7 @@ static void emit_push_imm(struct insn *insn, struct buffer *buf, struct basic_bl
static void emit_restore_regs(struct buffer *buf)
{
- __emit_pop_reg(buf, MACH_REG_EBX);
- __emit_pop_reg(buf, MACH_REG_ESI);
- __emit_pop_reg(buf, MACH_REG_EDI);
+ emit_restore_callee_save_regs(buf);
}
static void emit_fld_membase(struct insn *insn, struct buffer *buf, struct basic_block *bb)
diff --git a/arch/x86/include/arch/registers_32.h b/arch/x86/include/arch/registers_32.h
index f953643d..d8f2145f 100644
--- a/arch/x86/include/arch/registers_32.h
+++ b/arch/x86/include/arch/registers_32.h
@@ -55,6 +55,9 @@ enum machine_reg {
#define NR_CALLER_SAVE_REGS 11
extern enum machine_reg caller_save_regs[NR_CALLER_SAVE_REGS];
+#define NR_CALLEE_SAVE_REGS 3
+extern enum machine_reg callee_save_regs[NR_CALLEE_SAVE_REGS];
+
const char *reg_name(enum machine_reg reg);
extern uint32_t reg_type_table[NR_REGISTERS];
diff --git a/arch/x86/registers_32.c b/arch/x86/registers_32.c
index bc1efa9a..306c2ecf 100644
--- a/arch/x86/registers_32.c
+++ b/arch/x86/registers_32.c
@@ -1,6 +1,6 @@
/*
- * 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:
*
@@ -46,6 +46,12 @@ enum machine_reg caller_save_regs[NR_CALLER_SAVE_REGS] = {
MACH_REG_XMM7
};
+enum machine_reg callee_save_regs[NR_CALLEE_SAVE_REGS] = {
+ MACH_REG_EDI,
+ MACH_REG_ESI,
+ MACH_REG_EBX,
+};
+
static const char *register_names[] = {
[MACH_REG_EAX] = "EAX",
[MACH_REG_ECX] = "ECX",