diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /erts/emulator/hipe/hipe_x86_asm.m4 | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'erts/emulator/hipe/hipe_x86_asm.m4')
-rw-r--r-- | erts/emulator/hipe/hipe_x86_asm.m4 | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/erts/emulator/hipe/hipe_x86_asm.m4 b/erts/emulator/hipe/hipe_x86_asm.m4 new file mode 100644 index 0000000000..4c1d612ccd --- /dev/null +++ b/erts/emulator/hipe/hipe_x86_asm.m4 @@ -0,0 +1,286 @@ +changecom(`/*', `*/')dnl +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * $Id$ + */ +`#ifndef HIPE_X86_ASM_H +#define HIPE_X86_ASM_H' + +/* + * Tunables. + */ +define(LEAF_WORDS,24)dnl number of stack words for leaf functions +define(NR_ARG_REGS,3)dnl admissible values are 0 to 5, inclusive +define(HP_IN_ESI,1)dnl change to 0 to not reserve a global register for HP +define(SIMULATE_NSP,0)dnl change to 1 to simulate call/ret insns + +`#define X86_LEAF_WORDS 'LEAF_WORDS +`#define LEAF_WORDS 'LEAF_WORDS + +/* + * Workarounds for Darwin. + */ +ifelse(OPSYS,darwin,`` +/* Darwin */ +#define TEXT .text +#define JOIN(X,Y) X##Y +#define CSYM(NAME) JOIN(_,NAME) +#define ASYM(NAME) CSYM(NAME) +#define GLOBAL(NAME) .globl NAME +#define SET_SIZE(NAME) /*empty*/ +#define TYPE_FUNCTION(NAME) /*empty*/ +'',`` +/* Not Darwin */ +#define TEXT .section ".text" +#define CSYM(NAME) NAME +#define ASYM(NAME) NAME +#define GLOBAL(NAME) .global NAME +#define SET_SIZE(NAME) .size NAME,.-NAME +#define TYPE_FUNCTION(NAME) .type NAME,@function +'')dnl + +/* + * Reserved registers. + */ +`#define P %ebp' + +`#define X86_HP_IN_ESI 'HP_IN_ESI +`#if X86_HP_IN_ESI +#define SAVE_HP movl %esi, P_HP(P) +#define RESTORE_HP movl P_HP(P), %esi +#else +#define SAVE_HP /*empty*/ +#define RESTORE_HP /*empty*/ +#endif' + +`#define NSP %esp +#define SAVE_CSP movl %esp, P_CSP(P) +#define RESTORE_CSP movl P_CSP(P), %esp' + +`#define X86_SIMULATE_NSP 'SIMULATE_NSP + +/* + * Context switching macros. + */ +`#define SWITCH_C_TO_ERLANG_QUICK \ + SAVE_CSP; \ + movl P_NSP(P), NSP' + +`#define SWITCH_ERLANG_TO_C_QUICK \ + movl NSP, P_NSP(P); \ + RESTORE_CSP' + +`#define SAVE_CACHED_STATE \ + SAVE_HP' + +`#define RESTORE_CACHED_STATE \ + RESTORE_HP' + +`#define SWITCH_C_TO_ERLANG \ + RESTORE_CACHED_STATE; \ + SWITCH_C_TO_ERLANG_QUICK' + +`#define SWITCH_ERLANG_TO_C \ + SAVE_CACHED_STATE; \ + SWITCH_ERLANG_TO_C_QUICK' + +/* + * Argument (parameter) registers. + */ +`#define X86_NR_ARG_REGS 'NR_ARG_REGS +`#define NR_ARG_REGS 'NR_ARG_REGS + +ifelse(eval(NR_ARG_REGS >= 1),0,, +``#define ARG0 %eax +'')dnl +ifelse(eval(NR_ARG_REGS >= 2),0,, +``#define ARG1 %edx +'')dnl +ifelse(eval(NR_ARG_REGS >= 3),0,, +``#define ARG2 %ecx +'')dnl +ifelse(eval(NR_ARG_REGS >= 4),0,, +``#define ARG3 %ebx +'')dnl +ifelse(eval(NR_ARG_REGS >= 5),0,, +``#define ARG4 %edi +'')dnl + +/* + * TEMP_RV: + * Used in nbif_stack_trap_ra to preserve the return value. + * Must be a C callee-save register. + * Must be otherwise unused in the return path. + */ +`#define TEMP_RV %ebx' + +/* + * TEMP_NSP: + * Used in BIF wrappers to permit copying stacked parameter from + * the native stack to the C stack. + * Set up by NBIF_COPY_NSP(arity) and used by NBIF_ARG(arity,argno). + * TEMP_NSP may alias the last BIF argument register. + * NBIF_COPY_NSP and NBIF_ARG currently fail if ARITY > NR_ARG_REGS! + */ +`#define TEMP_NSP %edi' + +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +dnl X X +dnl X hipe_x86_glue.S support X +dnl X X +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +dnl +dnl LOAD_ARG_REGS +dnl +define(LAR_1,`movl P_ARG$1(P), ARG$1 ; ')dnl +define(LAR_N,`ifelse(eval($1 >= 0),0,,`LAR_N(eval($1-1))LAR_1($1)')')dnl +define(LOAD_ARG_REGS,`LAR_N(eval(NR_ARG_REGS-1))')dnl +`#define LOAD_ARG_REGS 'LOAD_ARG_REGS + +dnl +dnl STORE_ARG_REGS +dnl +define(SAR_1,`movl ARG$1, P_ARG$1(P) ; ')dnl +define(SAR_N,`ifelse(eval($1 >= 0),0,,`SAR_N(eval($1-1))SAR_1($1)')')dnl +define(STORE_ARG_REGS,`SAR_N(eval(NR_ARG_REGS-1))')dnl +`#define STORE_ARG_REGS 'STORE_ARG_REGS + +dnl +dnl NSP_CALL(FUN) +dnl Emit a CALL FUN instruction, or simulate it. +dnl FUN must not be an NSP-based memory operand. +dnl +ifelse(eval(SIMULATE_NSP),0, +``#define NSP_CALL(FUN) call FUN'', +``#define NSP_CALL(FUN) subl $4,NSP; movl $1f,(NSP); jmp FUN; 1:'')dnl + +dnl +dnl NSP_RETN(NPOP) +dnl Emit a RET $NPOP instruction, or simulate it. +dnl NPOP should be non-zero. +dnl +ifelse(eval(SIMULATE_NSP),0, +``#define NSP_RETN(NPOP) ret $NPOP'', +``#define NSP_RETN(NPOP) movl (NSP),TEMP_RV; addl $4+NPOP,NSP; jmp *TEMP_RV'')dnl + +dnl +dnl NSP_RET0 +dnl Emit a RET instruction, or simulate it. +dnl +ifelse(eval(SIMULATE_NSP),0, +``#define NSP_RET0 ret'', +``#define NSP_RET0 movl (NSP),TEMP_RV; addl $4,NSP; jmp *TEMP_RV'')dnl + +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +dnl X X +dnl X hipe_x86_bifs.m4 support X +dnl X X +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +dnl +dnl NBIF_COPY_NSP(ARITY) +dnl if ARITY > NR_ARG_REGS then TEMP_NSP := %esp. +dnl Allows the stacked formals to be referenced via TEMP_NSP after the stack switch. +dnl +define(NBIF_COPY_NSP,`ifelse(eval($1 > NR_ARG_REGS),0,,`movl %esp, TEMP_NSP')')dnl +`/* #define NBIF_COPY_NSP_0 'NBIF_COPY_NSP(0)` */' +`/* #define NBIF_COPY_NSP_1 'NBIF_COPY_NSP(1)` */' +`/* #define NBIF_COPY_NSP_2 'NBIF_COPY_NSP(2)` */' +`/* #define NBIF_COPY_NSP_3 'NBIF_COPY_NSP(3)` */' +`/* #define NBIF_COPY_NSP_5 'NBIF_COPY_NSP(5)` */' + +dnl +dnl BASE_OFFSET(N) +dnl Generates a base-register offset operand for the value N. +dnl When N is zero the offset becomes the empty string, as this +dnl may allow the assembler to choose a more compat encoding. +dnl +define(BASE_OFFSET,`ifelse(eval($1),0,`',`$1')')dnl + +dnl +dnl NBIF_ARG_OPND(ARITY,ARGNO) +dnl Generates an operand for this formal parameter. +dnl It will be a register operand when 0 <= ARGNO < NR_ARG_REGS. +dnl It will be a memory operand via TEMP_NSP when ARGNO >= NR_ARG_REGS. +dnl +define(NBIF_ARG_OPND,`ifelse(eval($2 >= NR_ARG_REGS),0,`ARG'$2,BASE_OFFSET(eval(($1-NR_ARG_REGS)*4-($2-NR_ARG_REGS)*4))`(TEMP_NSP)')')dnl +`/* #define NBIF_ARG_OPND_1_0 'NBIF_ARG_OPND(1,0)` */' +`/* #define NBIF_ARG_OPND_2_0 'NBIF_ARG_OPND(2,0)` */' +`/* #define NBIF_ARG_OPND_2_1 'NBIF_ARG_OPND(2,1)` */' +`/* #define NBIF_ARG_OPND_3_0 'NBIF_ARG_OPND(3,0)` */' +`/* #define NBIF_ARG_OPND_3_1 'NBIF_ARG_OPND(3,1)` */' +`/* #define NBIF_ARG_OPND_3_2 'NBIF_ARG_OPND(3,2)` */' +`/* #define NBIF_ARG_OPND_5_0 'NBIF_ARG_OPND(5,0)` */' +`/* #define NBIF_ARG_OPND_5_1 'NBIF_ARG_OPND(5,1)` */' +`/* #define NBIF_ARG_OPND_5_2 'NBIF_ARG_OPND(5,2)` */' +`/* #define NBIF_ARG_OPND_5_3 'NBIF_ARG_OPND(5,3)` */' +`/* #define NBIF_ARG_OPND_5_4 'NBIF_ARG_OPND(5,4)` */' + +dnl +dnl NBIF_ARG_REG(CARGNO,REG) +dnl Generates code to move REG to C argument number CARGNO. +dnl +define(NBIF_ARG_REG,`movl $2,BASE_OFFSET(eval(4*$1))(%esp)')dnl +`/* #define NBIF_ARG_REG_0_P 'NBIF_ARG_REG(0,P)` */' + +dnl +dnl NBIF_ARG(CARGNO,ARITY,ARGNO) +dnl Generates code to move Erlang parameter number ARGNO +dnl in a BIF of arity ARITY to C parameter number CARGNO. +dnl +dnl This must be called after NBIF_COPY_NSP(ARITY). +dnl +dnl NBIF_ARG(_,_,ARGNO2) must be called after NBIF_ARG(_,_,ARGNO1) +dnl if ARGNO2 > ARGNO1. (ARG0 may be reused as a temporary register +dnl for Erlang parameters passed on the stack.) +dnl +define(NBIF_ARG_MEM,`movl NBIF_ARG_OPND($2,$3),%eax; NBIF_ARG_REG($1,%eax)')dnl +define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_ARG_REG($1,`ARG'$3)',`NBIF_ARG_MEM($1,$2,$3)')')dnl + +dnl +dnl NBIF_RET(ARITY) +dnl Generates a return from a native BIF, taking care to pop +dnl any stacked formal parameters. +dnl +define(RET_POP,`ifelse(eval($1 > NR_ARG_REGS),0,0,eval(4*($1 - NR_ARG_REGS)))')dnl +define(NBIF_RET_N,`ifelse(eval($1),0,`NSP_RET0',`NSP_RETN($1)')')dnl +define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl +`/* #define NBIF_RET_0 'NBIF_RET(0)` */' +`/* #define NBIF_RET_1 'NBIF_RET(1)` */' +`/* #define NBIF_RET_2 'NBIF_RET(2)` */' +`/* #define NBIF_RET_3 'NBIF_RET(3)` */' +`/* #define NBIF_RET_5 'NBIF_RET(5)` */' + +dnl +dnl STORE_CALLER_SAVE +dnl LOAD_CALLER_SAVE +dnl Used to save and restore C caller-save argument registers around +dnl calls to hipe_inc_nstack. The first 3 arguments registers are C +dnl caller-save, remaining ones are C callee-save. +dnl +define(NBIF_MIN,`ifelse(eval($1 > $2),0,$1,$2)')dnl +define(NR_CALLER_SAVE,NBIF_MIN(NR_ARG_REGS,3))dnl +define(STORE_CALLER_SAVE,`SAR_N(eval(NR_CALLER_SAVE-1))')dnl +define(LOAD_CALLER_SAVE,`LAR_N(eval(NR_CALLER_SAVE-1))')dnl +`#define STORE_CALLER_SAVE 'STORE_CALLER_SAVE +`#define LOAD_CALLER_SAVE 'LOAD_CALLER_SAVE + +`#endif /* HIPE_X86_ASM_H */' |