diff options
author | Pekka Enberg <penberg@kernel.org> | 2012-01-14 12:20:35 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-01-14 12:28:58 +0200 |
commit | f3a677cab69f8300875b65e3b3c372f3683a5bda (patch) | |
tree | e40be041f7850ed9d5dec05ee44db39ac144a2a8 | |
parent | 84ce358a2ca281de8ba35cdb0a03a2aaa560af4a (diff) | |
download | jato-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.c | 31 | ||||
-rw-r--r-- | arch/x86/include/arch/registers_32.h | 3 | ||||
-rw-r--r-- | arch/x86/registers_32.c | 10 |
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", |