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_amd64_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_amd64_asm.m4')
-rw-r--r-- | erts/emulator/hipe/hipe_amd64_asm.m4 | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/erts/emulator/hipe/hipe_amd64_asm.m4 b/erts/emulator/hipe/hipe_amd64_asm.m4 new file mode 100644 index 0000000000..9ce9b4fc5b --- /dev/null +++ b/erts/emulator/hipe/hipe_amd64_asm.m4 @@ -0,0 +1,244 @@ +changecom(`/*', `*/')dnl +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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_AMD64_ASM_H +#define HIPE_AMD64_ASM_H' + +dnl +dnl Tunables. +dnl +define(LEAF_WORDS,24)dnl number of stack words for leaf functions +define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive +define(HP_IN_REGISTER,1)dnl 1 to reserve a global register for HP +define(FCALLS_IN_REGISTER,0)dnl 1 to reserve global register for FCALLS +define(HEAP_LIMIT_IN_REGISTER,0)dnl global for HL +define(SIMULATE_NSP,0)dnl change to 1 to simulate call/ret insns + +`#define AMD64_LEAF_WORDS 'LEAF_WORDS +`#define LEAF_WORDS 'LEAF_WORDS + +/* + * Reserved registers. + */ +`#define P %rbp' + +`#define AMD64_HP_IN_REGISTER 'HP_IN_REGISTER +`#if AMD64_HP_IN_REGISTER +#define AMD64_HEAP_POINTER 15' +define(HP,%r15)dnl Only change this together with above +`#define SAVE_HP movq 'HP`, P_HP(P) +#define RESTORE_HP movq P_HP(P), 'HP` +#else +#define SAVE_HP /*empty*/ +#define RESTORE_HP /*empty*/ +#endif' + +`#define AMD64_FCALLS_IN_REGISTER 'FCALLS_IN_REGISTER +`#if AMD64_FCALLS_IN_REGISTER +#define AMD64_FCALLS_REGISTER 11' +define(FCALLS,%r11)dnl This goes together with line above +`#define SAVE_FCALLS movq 'FCALLS`, P_FCALLS(P) +#define RESTORE_FCALLS movq P_FCALLS(P), 'FCALLS` +#else +#define SAVE_FCALLS /*empty*/ +#define RESTORE_FCALLS /*empty*/ +#endif' + +`#define AMD64_HEAP_LIMIT_IN_REGISTER 'HEAP_LIMIT_IN_REGISTER +`#if AMD64_HEAP_LIMIT_IN_REGISTER +#define AMD64_HEAP_LIMIT_REGISTER 12' +define(HEAP_LIMIT,%r12)dnl Change this together with line above +`#define RESTORE_HEAP_LIMIT movq P_HP_LIMIT(P), 'HEAP_LIMIT` +#else +#define RESTORE_HEAP_LIMIT /*empty*/ +#endif' + +define(NSP,%rsp)dnl +`#define NSP 'NSP +`#define SAVE_CSP movq %rsp, P_CSP(P) +#define RESTORE_CSP movq P_CSP(P), %rsp' + +`#define AMD64_SIMULATE_NSP 'SIMULATE_NSP + +/* + * Context switching macros. + */ +`#define SWITCH_C_TO_ERLANG_QUICK \ + SAVE_CSP; \ + movq P_NSP(P), NSP' + +`#define SWITCH_ERLANG_TO_C_QUICK \ + movq NSP, P_NSP(P); \ + RESTORE_CSP' + +`#define SAVE_CACHED_STATE \ + SAVE_HP; \ + SAVE_FCALLS' + +`#define RESTORE_CACHED_STATE \ + RESTORE_HP; \ + RESTORE_HEAP_LIMIT; \ + RESTORE_FCALLS' + +`#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 AMD64_NR_ARG_REGS 'NR_ARG_REGS +`#define NR_ARG_REGS 'NR_ARG_REGS + +define(defarg,`define(ARG$1,`$2')dnl +#`define ARG'$1 $2' +)dnl + +ifelse(eval(NR_ARG_REGS >= 1),0,, +`defarg(0,`%rsi')')dnl +ifelse(eval(NR_ARG_REGS >= 2),0,, +`defarg(1,`%rdx')')dnl +ifelse(eval(NR_ARG_REGS >= 3),0,, +`defarg(2,`%rcx')')dnl +ifelse(eval(NR_ARG_REGS >= 4),0,, +`defarg(3,`%r8')')dnl +ifelse(eval(NR_ARG_REGS >= 5),0,, +`defarg(4,`%r9')')dnl +ifelse(eval(NR_ARG_REGS >= 6),0,, +`defarg(5,`%rdi')')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 %rbx' + +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +dnl X X +dnl X hipe_amd64_glue.S support X +dnl X X +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +dnl +dnl LOAD_ARG_REGS +dnl (identical to x86 version except for movq) +dnl +define(LAR_1,`movq 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 (identical to x86 version except for movq) +dnl +define(SAR_1,`movq 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) subq $8,NSP; leaq 1f(%rip),%rax; movq %rax,(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) movq (NSP),TEMP_RV; addq $8+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 movq (NSP),TEMP_RV; addq $8,NSP; jmp *TEMP_RV'')dnl + +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +dnl X X +dnl X hipe_amd64_bifs.m4 support X +dnl X X +dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +dnl +dnl NBIF_ARG(DST,ARITY,ARGNO) +dnl Access a formal parameter. +dnl It will be a memory load via NSP when ARGNO >= NR_ARG_REGS. +dnl It will be a register move when 0 <= ARGNO < NR_ARG_REGS; if +dnl the source and destination are the same, the move is suppressed. +dnl +dnl This must be called before SWITCH_ERLANG_TO_C{,QUICK}. +dnl This must not be called if the C BIF's arity > 6. +dnl +define(NBIF_MOVE_REG,`ifelse($1,$2,`# movq $2, $1',`movq $2, $1')')dnl +define(NBIF_REG_ARG,`NBIF_MOVE_REG($1,ARG$2)')dnl +define(NBIF_STK_LOAD,`movq $2(NSP), $1')dnl +define(NBIF_STK_ARG,`NBIF_STK_LOAD($1,eval(8*($2-$3)))')dnl +define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_STK_ARG($1,$2,$3)')')dnl +`/* #define NBIF_ARG_1_0 'NBIF_ARG(%rsi,1,0)` */' +`/* #define NBIF_ARG_2_0 'NBIF_ARG(%rsi,2,0)` */' +`/* #define NBIF_ARG_2_1 'NBIF_ARG(%rdx,2,1)` */' +`/* #define NBIF_ARG_3_0 'NBIF_ARG(%rsi,3,0)` */' +`/* #define NBIF_ARG_3_1 'NBIF_ARG(%rdx,3,1)` */' +`/* #define NBIF_ARG_3_2 'NBIF_ARG(%rcx,3,2)` */' +`/* #define NBIF_ARG_5_0 'NBIF_ARG(%rsi,5,0)` */' +`/* #define NBIF_ARG_5_1 'NBIF_ARG(%rdx,5,1)` */' +`/* #define NBIF_ARG_5_2 'NBIF_ARG(%rcx,5,2)` */' +`/* #define NBIF_ARG_5_3 'NBIF_ARG(%r8,5,3)` */' +`/* #define NBIF_ARG_5_4 'NBIF_ARG(%r9,5,4)` */' + +dnl XXX: For >6 arity C BIFs, we need: +dnl NBIF_COPY_NSP(ARITY) +dnl SWITCH_ERLANG_TO_C +dnl NBIF_GE6_ARG_MOVE(DSTREG,ARITY,ARGNO) +dnl pushq NBIF_GE6_ARG_OPND(ARITY,ARGNO) <-- uses NSP copied above + +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(8*($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)` */' + +`#endif /* HIPE_AMD64_ASM_H */' |