]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/ocaml/contrib/otherlibs/num/bng_ppc.c
Inital import
[l4.git] / l4 / pkg / ocaml / contrib / otherlibs / num / bng_ppc.c
1 /***********************************************************************/
2 /*                                                                     */
3 /*                           Objective Caml                            */
4 /*                                                                     */
5 /*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
6 /*                                                                     */
7 /*  Copyright 2003 Institut National de Recherche en Informatique et   */
8 /*  en Automatique.  All rights reserved.  This file is distributed    */
9 /*  under the terms of the GNU Library General Public License, with    */
10 /*  the special exception on linking described in file ../../LICENSE.  */
11 /*                                                                     */
12 /***********************************************************************/
13
14 /* $Id: bng_ppc.c 7430 2006-05-31 08:16:34Z xleroy $ */
15
16 /* Code specific to the PowerPC architecture. */
17
18 #define BngAdd2(res,carryout,arg1,arg2)                                     \
19   asm("addc %0, %2, %3 \n\t"                                                \
20       "li %1, 0 \n\t"                                                       \
21       "addze %1, %1"                                                        \
22       : "=r" (res), "=r" (carryout)                                         \
23       : "r" (arg1), "r" (arg2))
24
25 #define BngAdd2Carry(res,carryout,arg1,arg2,carryin)                        \
26   asm("addic %1, %4, -1 \n\t"                                               \
27       "adde %0, %2, %3 \n\t"                                                \
28       "li %1, 0 \n\t"                                                       \
29       "addze %1, %1"                                                        \
30       : "=r" (res), "=&r" (carryout)                                        \
31       : "r" (arg1), "r" (arg2), "1" (carryin))
32
33 #define BngAdd3(res,carryaccu,arg1,arg2,arg3)                               \
34   asm("addc %0, %2, %3 \n\t"                                                \
35       "addze %1, %1 \n\t"                                                   \
36       "addc %0, %0, %4 \n\t"                                                \
37       "addze %1, %1"                                                        \
38       : "=&r" (res), "=&r" (carryaccu)                                      \
39       : "r" (arg1), "r" (arg2), "r" (arg3), "1" (carryaccu))
40
41 /* The "subtract" instructions interpret carry differently than what we
42    need: the processor carry bit CA is 1 if no carry occured,
43    0 if a carry occured.  In other terms, CA = !carry.
44    Thus, subfe rd,ra,rb computes rd = ra - rb - !CA
45          subfe rd,rd,rd sets rd = - !CA
46          subfe rd,rd,rd; neg rd, rd sets rd = !CA and recovers "our" carry. */
47
48 #define BngSub2(res,carryout,arg1,arg2)                                     \
49   asm("subfc %0, %3, %2 \n\t"                                               \
50       "subfe %1, %1, %1\n\t"                                                \
51       "neg %1, %1"                                                          \
52       : "=r" (res), "=r" (carryout)                                         \
53       : "r" (arg1), "r" (arg2))
54
55 #define BngSub2Carry(res,carryout,arg1,arg2,carryin)                        \
56   asm("subfic %1, %4, 0 \n\t"                                               \
57       "subfe %0, %3, %2 \n\t"                                               \
58       "subfe %1, %1, %1 \n\t"                                               \
59       "neg %1, %1"                                                          \
60       : "=r" (res), "=&r" (carryout)                                        \
61       : "r" (arg1), "r" (arg2), "1" (carryin))
62
63 /* Here is what happens with carryaccu:
64        neg %1, %1       carryaccu = -carryaccu
65        addze %1, %1     carryaccu += !carry1
66        addze %1, %1     carryaccu += !carry2
67        subifc %1, %1, 2 carryaccu = 2 - carryaccu
68    Thus, carryaccu_final = carryaccu_initial + 2 - (1 - carry1) - (1 - carry2)
69                          = carryaccu_initial + carry1 + carry2
70 */
71
72 #define BngSub3(res,carryaccu,arg1,arg2,arg3)                               \
73   asm("neg %1, %1 \n\t"                                                     \
74       "subfc %0, %3, %2 \n\t"                                               \
75       "addze %1, %1 \n\t"                                                   \
76       "subfc %0, %4, %0 \n\t"                                               \
77       "addze %1, %1 \n\t"                                                   \
78       "subfic %1, %1, 2 \n\t"                                               \
79       : "=&r" (res), "=&r" (carryaccu)                                      \
80       : "r" (arg1), "r" (arg2), "r" (arg3), "1" (carryaccu))
81
82 #ifdef __ppc64__
83 #define BngMult(resh,resl,arg1,arg2)                                        \
84   asm("mulld %0, %2, %3 \n\t"                                               \
85       "mulhdu %1, %2, %3"                                                   \
86       : "=&r" (resl), "=r" (resh)                                           \
87       : "r" (arg1), "r" (arg2))
88 #else
89 #define BngMult(resh,resl,arg1,arg2)                                        \
90   asm("mullw %0, %2, %3 \n\t"                                               \
91       "mulhwu %1, %2, %3"                                                   \
92       : "=&r" (resl), "=r" (resh)                                           \
93       : "r" (arg1), "r" (arg2))
94 #endif