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