1 /*
2  * lbnarm.h - This file defines the interfaces to the ARM
3  * assembly primitives.  It is intended to be included in "lbn.h"
4  * via the "#include BNINCLUDE" mechanism.
5  */
6 
7 #define BN_LITTLE_ENDIAN 1
8 
9 typedef unsigned bnword32;
10 #define BNWORD32 bnword32
11 
12 /* Function prototypes for the asm routines */
13 void
14 lbnMulN1_32(bnword32 *out, bnword32 const *in, unsigned len, bnword32 k);
15 #define lbnMulN1_32 lbnMulN1_32
16 
17 bnword32
18 lbnMulAdd1_32(bnword32 *out, bnword32 const *in, unsigned len, bnword32 k);
19 #define lbnMulAdd1_32 lbnMulAdd1_32
20 
21 /* Not implemented yet */
22 bnword32
23 lbnMulSub1_32(bnword32 *out, bnword32 const *in, unsigned len, bnword32 k);
24 #define lbnMulSub1_32 lbnMulSub1_32
25 
26 #if __GNUC__ && 0
27 /*
28  * Use the (massively cool) GNU inline-assembler extension to define
29  * inline expansions for various operations.
30  *
31  * The massively cool part is that the assembler can have inputs
32  * and outputs, and you specify the operands and which effective
33  * addresses are legal and they get substituted into the code.
34  * (For example, some of the code requires a zero.  Rather than
35  * specify an immediate constant, the expansion specifies an operand
36  * of zero which can be in various places.  This lets GCC use an
37  * immediate zero, or a register which contains zero if it's available.)
38  *
39  * The syntax is asm("asm_code" : outputs : inputs : trashed)
40  * %0, %1 and so on in the asm code are substituted by the operands
41  * in left-to-right order (outputs, then inputs).
42  * The operands contain constraint strings and values to use.
43  * Outputs must be lvalues, inputs may be rvalues.  In the constraints:
44  * "r" means that the operand may be in a register.
45  * "=" means that the operand is assigned to.
46  * "%" means that this operand and the following one may be
47  *     interchanged if desirable.
48  * "&" means that this output operand is written before the input operands
49  *     are read, so it may NOT overlap with any input operands.
50  * "0" and "1" mean that this operand may be in the same place as the
51  *     given operand.
52  * Multiple sets of constraints may be listed, separated by commas.
53  *
54  * Note that ARM multi-precision multiply syntax lists destLo before destHi.
55  * Also, the first source (%2) may not be the same as %0 or %1.
56  * The second source, however, may be.
57  */
58 
59 /* (ph<<32) + pl = x*y */
60 #define mul32_ppmm(ph,pl,x,y)	\
61 	__asm__("umull	%1,%0,%2,%3" : "=&r,&r"(ph), "=&r,&r"(pl) \
62 				     : "%r,%r"(x), "r0,r1"(y))
63 
64 /* (ph<<32) + pl = x*y + a */
65 #define mul32_ppmma(ph,pl,x,y,a)	\
66 	__asm__("umlal	%1,%0,%2,%3" : "=&r"(ph), "=&r"(pl) \
67 				     : "%r"(x), "r"(y), "0"(0), "1"(a))
68 
69 /* (ph<<32) + pl = x*y + a + b */
70 /* %4 (a) may share a register with %0, but nothing else may. */
71 #define mul32_ppmmaa(ph,pl,x,y,a,b)	\
72 	__asm__("adds	%1, %4, %5\n\t"	\
73 		"movcc	%0, #0\n\t"	\
74 		"movcs	%0, #1\n\t"	\
75 		"umlal	%1,%0,%2,%3"	\
76 		: "=&r"(ph), "=&r"(pl)	\
77 		: "%r"(x), "r"(y), "%r"(a), "r1"(b))
78 
79 #endif /* __GNUC__ */
80