aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/hipe/hipe_ppc_asm.m4
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/hipe/hipe_ppc_asm.m4')
-rw-r--r--erts/emulator/hipe/hipe_ppc_asm.m4286
1 files changed, 286 insertions, 0 deletions
diff --git a/erts/emulator/hipe/hipe_ppc_asm.m4 b/erts/emulator/hipe/hipe_ppc_asm.m4
new file mode 100644
index 0000000000..a0f8b78679
--- /dev/null
+++ b/erts/emulator/hipe/hipe_ppc_asm.m4
@@ -0,0 +1,286 @@
+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_PPC_ASM_H
+#define HIPE_PPC_ASM_H'
+
+/*
+ * Handle 32 vs 64-bit.
+ */
+ifelse(ARCH,ppc64,`
+/* 64-bit PowerPC */
+define(LOAD,ld)dnl
+define(STORE,std)dnl
+define(CMPI,cmpdi)dnl
+define(WSIZE,8)dnl
+',`
+/* 32-bit PowerPC */
+define(LOAD,lwz)dnl
+define(STORE,stw)dnl
+define(CMPI,cmpwi)dnl
+define(WSIZE,4)dnl
+')dnl
+`#define LOAD 'LOAD
+`#define STORE 'STORE
+`#define CMPI 'CMPI
+
+/*
+ * Tunables.
+ */
+define(LEAF_WORDS,16)dnl number of stack words for leaf functions
+define(NR_ARG_REGS,4)dnl admissible values are 0 to 6, inclusive
+
+`#define PPC_LEAF_WORDS 'LEAF_WORDS
+
+/*
+ * Workarounds for Darwin.
+ */
+ifelse(OPSYS,darwin,``
+/* Darwin */
+#define JOIN(X,Y) X##Y
+#define CSYM(NAME) JOIN(_,NAME)
+#define ASYM(NAME) CSYM(NAME)
+#define GLOBAL(NAME) .globl NAME
+#define SEMI @
+#define SET_SIZE(NAME) /*empty*/
+#define TYPE_FUNCTION(NAME) /*empty*/
+'',``
+/* Not Darwin */''
+`ifelse(ARCH,ppc64,``
+/* 64-bit */
+#define JOIN(X,Y) X##Y
+#define CSYM(NAME) JOIN(.,NAME)
+'',``
+/* 32-bit */
+#define CSYM(NAME) NAME
+'')'
+``#define ASYM(NAME) NAME
+#define GLOBAL(NAME) .global NAME
+#define SEMI ;
+#define SET_SIZE(NAME) .size NAME,.-NAME
+#define TYPE_FUNCTION(NAME) .type NAME,@function
+#define lo16(X) X@l
+#define ha16(X) X@ha
+
+/*
+ * Standard register names.
+ */
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+'')dnl
+
+/*
+ * Reserved registers.
+ */
+`#define P r31'
+`#define NSP r30'
+`#define HP r29'
+`#define TEMP_LR r28'
+
+/*
+ * Context switching macros.
+ *
+ * RESTORE_CONTEXT and RESTORE_CONTEXT_QUICK do not affect
+ * the condition register.
+ */
+`#define SAVE_CONTEXT_QUICK \
+ mflr TEMP_LR'
+
+`#define RESTORE_CONTEXT_QUICK \
+ mtlr TEMP_LR'
+
+`#define SAVE_CACHED_STATE \
+ STORE HP, P_HP(P) SEMI\
+ STORE NSP, P_NSP(P)'
+
+`#define RESTORE_CACHED_STATE \
+ LOAD HP, P_HP(P) SEMI\
+ LOAD NSP, P_NSP(P)'
+
+`#define SAVE_CONTEXT_BIF \
+ mflr TEMP_LR SEMI \
+ STORE HP, P_HP(P)'
+
+`#define RESTORE_CONTEXT_BIF \
+ mtlr TEMP_LR SEMI \
+ LOAD HP, P_HP(P)'
+
+`#define SAVE_CONTEXT_GC \
+ mflr TEMP_LR SEMI \
+ STORE TEMP_LR, P_NRA(P) SEMI \
+ STORE NSP, P_NSP(P) SEMI \
+ STORE HP, P_HP(P)'
+
+`#define RESTORE_CONTEXT_GC \
+ mtlr TEMP_LR SEMI \
+ LOAD HP, P_HP(P)'
+
+/*
+ * Argument (parameter) registers.
+ */
+`#define PPC_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,`r4')')dnl
+ifelse(eval(NR_ARG_REGS >= 2),0,,
+`defarg(1,`r5')')dnl
+ifelse(eval(NR_ARG_REGS >= 3),0,,
+`defarg(2,`r6')')dnl
+ifelse(eval(NR_ARG_REGS >= 4),0,,
+`defarg(3,`r7')')dnl
+ifelse(eval(NR_ARG_REGS >= 5),0,,
+`defarg(4,`r8')')dnl
+ifelse(eval(NR_ARG_REGS >= 6),0,,
+`defarg(5,`r9')')dnl
+
+/*
+ * TEMP_ARG0:
+ * 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.
+ *
+ * TEMP_ARG0:
+ * Used in hipe_ppc_inc_stack to preserve the return address
+ * (TEMP_LR contains the caller's saved return address).
+ * Must be a C callee-save register.
+ * Must be otherwise unused in the call path.
+ */
+`#define TEMP_ARG0 r27'
+
+dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+dnl X X
+dnl X hipe_ppc_glue.S support X
+dnl X X
+dnl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+dnl
+dnl LOAD_ARG_REGS
+dnl
+define(LAR_1,`LOAD ARG$1, P_ARG$1(P) SEMI ')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,`STORE ARG$1, P_ARG$1(P) SEMI ')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 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+dnl X X
+dnl X hipe_ppc_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
+define(NBIF_MOVE_REG,`ifelse($1,$2,`# mr $1, $2',`mr $1, $2')')dnl
+define(NBIF_REG_ARG,`NBIF_MOVE_REG($1,ARG$2)')dnl
+define(NBIF_STK_LOAD,`LOAD $1, $2(NSP)')dnl
+define(NBIF_STK_ARG,`NBIF_STK_LOAD($1,eval(WSIZE*(($2-$3)-1)))')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(r3,1,0)` */'
+`/* #define NBIF_ARG_2_0 'NBIF_ARG(r3,2,0)` */'
+`/* #define NBIF_ARG_2_1 'NBIF_ARG(r3,2,1)` */'
+`/* #define NBIF_ARG_3_0 'NBIF_ARG(r3,3,0)` */'
+`/* #define NBIF_ARG_3_1 'NBIF_ARG(r3,3,1)` */'
+`/* #define NBIF_ARG_3_2 'NBIF_ARG(r3,3,2)` */'
+`/* #define NBIF_ARG_5_0 'NBIF_ARG(r3,5,0)` */'
+`/* #define NBIF_ARG_5_1 'NBIF_ARG(r3,5,1)` */'
+`/* #define NBIF_ARG_5_2 'NBIF_ARG(r3,5,2)` */'
+`/* #define NBIF_ARG_5_3 'NBIF_ARG(r3,5,3)` */'
+`/* #define NBIF_ARG_5_4 'NBIF_ARG(r3,5,4)` */'
+
+dnl
+dnl NBIF_RET(ARITY)
+dnl Generates a return from a native BIF, taking care to pop
+dnl any stacked formal parameters.
+dnl
+define(NSP_RETN,`addi NSP, NSP, $1
+ blr')dnl
+define(NSP_RET0,`blr')dnl
+define(RET_POP,`ifelse(eval($1 > NR_ARG_REGS),0,0,eval(WSIZE*($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 QUICK_CALL_RET(CFUN,ARITY)
+dnl Used in nocons_nofail and noproc primop interfaces to optimise
+dnl SAVE_CONTEXT_QUICK; bl CFUN; RESTORE_CONTEXT_QUICK; NBIF_RET(ARITY).
+dnl
+define(NBIF_POP_N,`ifelse(eval($1),0,`',`addi NSP, NSP, $1 SEMI ')')dnl
+define(QUICK_CALL_RET,`NBIF_POP_N(eval(RET_POP($2)))b $1')dnl
+`/* #define QUICK_CALL_RET_F_0 'QUICK_CALL_RET(F,0)` */'
+`/* #define QUICK_CALL_RET_F_1 'QUICK_CALL_RET(F,1)` */'
+`/* #define QUICK_CALL_RET_F_2 'QUICK_CALL_RET(F,2)` */'
+`/* #define QUICK_CALL_RET_F_3 'QUICK_CALL_RET(F,3)` */'
+`/* #define QUICK_CALL_RET_F_5 'QUICK_CALL_RET(F,5)` */'
+
+`#endif /* HIPE_PPC_ASM_H */'