1/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store 2 * the result in a second limb vector. 3 * 4 * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. 5 * 6 * This file is part of Libgcrypt. 7 * 8 * Libgcrypt is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as 10 * published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * Libgcrypt is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 21 */ 22 23#include "sysdep.h" 24#include "asm-syntax.h" 25 26/* 27# INPUT PARAMETERS 28# res_ptr r3 29# s1_ptr r4 30# size r5 31# s2_limb r6 32 33# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To 34# obtain that operation, we have to use the 32x32->64 signed multiplication 35# instruction, and add the appropriate compensation to the high limb of the 36# result. We add the multiplicand if the multiplier has its most significant 37# bit set, and we add the multiplier if the multiplicand has its most 38# significant bit set. We need to preserve the carry flag between each 39# iteration, so we have to compute the compensation carefully (the natural, 40# srai+and doesn't work). Since the POWER architecture has a branch unit 41# we can branch in zero cycles, so that's how we perform the additions. 42 */ 43 44 .toc 45 .csect ._gcry_mpih_mul_1[PR] 46 .align 2 47 .globl _gcry_mpih_mul_1 48 .globl ._gcry_mpih_mul_1 49 .csect _gcry_mpih_mul_1[DS] 50_gcry_mpih_mul_1: 51 .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0 52 .csect ._gcry_mpih_mul_1[PR] 53._gcry_mpih_mul_1: 54 55 cal 3,-4(3) 56 l 0,0(4) 57 cmpi 0,6,0 58 mtctr 5 59 mul 9,0,6 60 srai 7,0,31 61 and 7,7,6 62 mfmq 8 63 ai 0,0,0 # reset carry 64 cax 9,9,7 65 blt Lneg 66Lpos: bdz Lend 67Lploop: lu 0,4(4) 68 stu 8,4(3) 69 cmpi 0,0,0 70 mul 10,0,6 71 mfmq 0 72 ae 8,0,9 73 bge Lp0 74 cax 10,10,6 # adjust high limb for negative limb from s1 75Lp0: bdz Lend0 76 lu 0,4(4) 77 stu 8,4(3) 78 cmpi 0,0,0 79 mul 9,0,6 80 mfmq 0 81 ae 8,0,10 82 bge Lp1 83 cax 9,9,6 # adjust high limb for negative limb from s1 84Lp1: bdn Lploop 85 b Lend 86 87Lneg: cax 9,9,0 88 bdz Lend 89Lnloop: lu 0,4(4) 90 stu 8,4(3) 91 cmpi 0,0,0 92 mul 10,0,6 93 cax 10,10,0 # adjust high limb for negative s2_limb 94 mfmq 0 95 ae 8,0,9 96 bge Ln0 97 cax 10,10,6 # adjust high limb for negative limb from s1 98Ln0: bdz Lend0 99 lu 0,4(4) 100 stu 8,4(3) 101 cmpi 0,0,0 102 mul 9,0,6 103 cax 9,9,0 # adjust high limb for negative s2_limb 104 mfmq 0 105 ae 8,0,10 106 bge Ln1 107 cax 9,9,6 # adjust high limb for negative limb from s1 108Ln1: bdn Lnloop 109 b Lend 110 111Lend0: cal 9,0(10) 112Lend: st 8,4(3) 113 aze 3,9 114 br 115 116