diff options
author | Pekka Enberg <penberg@kernel.org> | 2012-01-14 12:34:23 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-01-14 12:37:38 +0200 |
commit | d82be0b568d665678faf21fa79f1772d6ebbdf98 (patch) | |
tree | c983ebdba91b582a08bc23e4cd8e63dc24f6dc5b | |
parent | f3a677cab69f8300875b65e3b3c372f3683a5bda (diff) | |
download | jato-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.c | 34 | ||||
-rw-r--r-- | arch/x86/include/arch/registers_64.h | 3 | ||||
-rw-r--r-- | arch/x86/registers_64.c | 10 |
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", |