1e71b7053SJung-uk Kim#! /usr/bin/env perl 217f01e99SJung-uk Kim# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. 3e71b7053SJung-uk Kim# 4*b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License"). You may not use 5e71b7053SJung-uk Kim# this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html 8e71b7053SJung-uk Kim 9e71b7053SJung-uk Kim 10e71b7053SJung-uk Kim# ==================================================================== 11e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL 12e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and 13e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further 14e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/. 15e71b7053SJung-uk Kim# ==================================================================== 16e71b7053SJung-uk Kim 17e71b7053SJung-uk Kim# Poly1305 hash for MIPS64. 18e71b7053SJung-uk Kim# 19e71b7053SJung-uk Kim# May 2016 20e71b7053SJung-uk Kim# 21e71b7053SJung-uk Kim# Numbers are cycles per processed byte with poly1305_blocks alone. 22e71b7053SJung-uk Kim# 23e71b7053SJung-uk Kim# IALU/gcc 24e71b7053SJung-uk Kim# R1x000 5.64/+120% (big-endian) 25e71b7053SJung-uk Kim# Octeon II 3.80/+280% (little-endian) 26e71b7053SJung-uk Kim 27e71b7053SJung-uk Kim###################################################################### 28e71b7053SJung-uk Kim# There is a number of MIPS ABI in use, O32 and N32/64 are most 29e71b7053SJung-uk Kim# widely used. Then there is a new contender: NUBI. It appears that if 30e71b7053SJung-uk Kim# one picks the latter, it's possible to arrange code in ABI neutral 31e71b7053SJung-uk Kim# manner. Therefore let's stick to NUBI register layout: 32e71b7053SJung-uk Kim# 33e71b7053SJung-uk Kim($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25)); 34e71b7053SJung-uk Kim($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); 35e71b7053SJung-uk Kim($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23)); 36e71b7053SJung-uk Kim($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31)); 37e71b7053SJung-uk Kim# 38e71b7053SJung-uk Kim# The return value is placed in $a0. Following coding rules facilitate 39e71b7053SJung-uk Kim# interoperability: 40e71b7053SJung-uk Kim# 41e71b7053SJung-uk Kim# - never ever touch $tp, "thread pointer", former $gp [o32 can be 42e71b7053SJung-uk Kim# excluded from the rule, because it's specified volatile]; 43e71b7053SJung-uk Kim# - copy return value to $t0, former $v0 [or to $a0 if you're adapting 44e71b7053SJung-uk Kim# old code]; 45e71b7053SJung-uk Kim# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary; 46e71b7053SJung-uk Kim# 47e71b7053SJung-uk Kim# For reference here is register layout for N32/64 MIPS ABIs: 48e71b7053SJung-uk Kim# 49e71b7053SJung-uk Kim# ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); 50e71b7053SJung-uk Kim# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); 51e71b7053SJung-uk Kim# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); 52e71b7053SJung-uk Kim# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); 53e71b7053SJung-uk Kim# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); 54e71b7053SJung-uk Kim# 55e71b7053SJung-uk Kim# <appro@openssl.org> 56e71b7053SJung-uk Kim# 57e71b7053SJung-uk Kim###################################################################### 58e71b7053SJung-uk Kim 59*b077aed3SPierre Pronchery# $output is the last argument if it looks like a file (it has an extension) 60*b077aed3SPierre Pronchery# $flavour is the first argument if it doesn't look like a file 61*b077aed3SPierre Pronchery$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; 62*b077aed3SPierre Pronchery# supported flavours are o32,n32,64,nubi32,nubi64, default is o32 63*b077aed3SPierre Pronchery$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : "o32"; 64e71b7053SJung-uk Kim 65e71b7053SJung-uk Kimdie "MIPS64 only" unless ($flavour =~ /64|n32/i); 66e71b7053SJung-uk Kim 67e71b7053SJung-uk Kim$v0 = ($flavour =~ /nubi/i) ? $a0 : $t0; 68e71b7053SJung-uk Kim$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0x0003f000" : "0x00030000"; 69e71b7053SJung-uk Kim 70e71b7053SJung-uk Kim($ctx,$inp,$len,$padbit) = ($a0,$a1,$a2,$a3); 71e71b7053SJung-uk Kim($in0,$in1,$tmp0,$tmp1,$tmp2,$tmp3,$tmp4) = ($a4,$a5,$a6,$a7,$at,$t0,$t1); 72e71b7053SJung-uk Kim 73e71b7053SJung-uk Kim$code.=<<___; 74e71b7053SJung-uk Kim#include "mips_arch.h" 75e71b7053SJung-uk Kim 76e71b7053SJung-uk Kim#ifdef MIPSEB 77e71b7053SJung-uk Kim# define MSB 0 78e71b7053SJung-uk Kim# define LSB 7 79e71b7053SJung-uk Kim#else 80e71b7053SJung-uk Kim# define MSB 7 81e71b7053SJung-uk Kim# define LSB 0 82e71b7053SJung-uk Kim#endif 83e71b7053SJung-uk Kim 84e71b7053SJung-uk Kim.text 85e71b7053SJung-uk Kim.set noat 86e71b7053SJung-uk Kim.set noreorder 87e71b7053SJung-uk Kim 88e71b7053SJung-uk Kim.align 5 89e71b7053SJung-uk Kim.globl poly1305_init 90e71b7053SJung-uk Kim.ent poly1305_init 91e71b7053SJung-uk Kimpoly1305_init: 92e71b7053SJung-uk Kim .frame $sp,0,$ra 93e71b7053SJung-uk Kim .set reorder 94e71b7053SJung-uk Kim 95e71b7053SJung-uk Kim sd $zero,0($ctx) 96e71b7053SJung-uk Kim sd $zero,8($ctx) 97e71b7053SJung-uk Kim sd $zero,16($ctx) 98e71b7053SJung-uk Kim 99e71b7053SJung-uk Kim beqz $inp,.Lno_key 100e71b7053SJung-uk Kim 101e71b7053SJung-uk Kim#if defined(_MIPS_ARCH_MIPS64R6) 102e71b7053SJung-uk Kim ld $in0,0($inp) 103e71b7053SJung-uk Kim ld $in1,8($inp) 104e71b7053SJung-uk Kim#else 105e71b7053SJung-uk Kim ldl $in0,0+MSB($inp) 106e71b7053SJung-uk Kim ldl $in1,8+MSB($inp) 107e71b7053SJung-uk Kim ldr $in0,0+LSB($inp) 108e71b7053SJung-uk Kim ldr $in1,8+LSB($inp) 109e71b7053SJung-uk Kim#endif 110e71b7053SJung-uk Kim#ifdef MIPSEB 111e71b7053SJung-uk Kim# if defined(_MIPS_ARCH_MIPS64R2) 112e71b7053SJung-uk Kim dsbh $in0,$in0 # byte swap 113e71b7053SJung-uk Kim dsbh $in1,$in1 114e71b7053SJung-uk Kim dshd $in0,$in0 115e71b7053SJung-uk Kim dshd $in1,$in1 116e71b7053SJung-uk Kim# else 117e71b7053SJung-uk Kim ori $tmp0,$zero,0xFF 118e71b7053SJung-uk Kim dsll $tmp2,$tmp0,32 119e71b7053SJung-uk Kim or $tmp0,$tmp2 # 0x000000FF000000FF 120e71b7053SJung-uk Kim 121e71b7053SJung-uk Kim and $tmp1,$in0,$tmp0 # byte swap 122e71b7053SJung-uk Kim and $tmp3,$in1,$tmp0 123e71b7053SJung-uk Kim dsrl $tmp2,$in0,24 124e71b7053SJung-uk Kim dsrl $tmp4,$in1,24 125e71b7053SJung-uk Kim dsll $tmp1,24 126e71b7053SJung-uk Kim dsll $tmp3,24 127e71b7053SJung-uk Kim and $tmp2,$tmp0 128e71b7053SJung-uk Kim and $tmp4,$tmp0 129e71b7053SJung-uk Kim dsll $tmp0,8 # 0x0000FF000000FF00 130e71b7053SJung-uk Kim or $tmp1,$tmp2 131e71b7053SJung-uk Kim or $tmp3,$tmp4 132e71b7053SJung-uk Kim and $tmp2,$in0,$tmp0 133e71b7053SJung-uk Kim and $tmp4,$in1,$tmp0 134e71b7053SJung-uk Kim dsrl $in0,8 135e71b7053SJung-uk Kim dsrl $in1,8 136e71b7053SJung-uk Kim dsll $tmp2,8 137e71b7053SJung-uk Kim dsll $tmp4,8 138e71b7053SJung-uk Kim and $in0,$tmp0 139e71b7053SJung-uk Kim and $in1,$tmp0 140e71b7053SJung-uk Kim or $tmp1,$tmp2 141e71b7053SJung-uk Kim or $tmp3,$tmp4 142e71b7053SJung-uk Kim or $in0,$tmp1 143e71b7053SJung-uk Kim or $in1,$tmp3 144e71b7053SJung-uk Kim dsrl $tmp1,$in0,32 145e71b7053SJung-uk Kim dsrl $tmp3,$in1,32 146e71b7053SJung-uk Kim dsll $in0,32 147e71b7053SJung-uk Kim dsll $in1,32 148e71b7053SJung-uk Kim or $in0,$tmp1 149e71b7053SJung-uk Kim or $in1,$tmp3 150e71b7053SJung-uk Kim# endif 151e71b7053SJung-uk Kim#endif 152e71b7053SJung-uk Kim li $tmp0,1 153e71b7053SJung-uk Kim dsll $tmp0,32 154e71b7053SJung-uk Kim daddiu $tmp0,-63 155e71b7053SJung-uk Kim dsll $tmp0,28 156e71b7053SJung-uk Kim daddiu $tmp0,-1 # 0ffffffc0fffffff 157e71b7053SJung-uk Kim 158e71b7053SJung-uk Kim and $in0,$tmp0 159e71b7053SJung-uk Kim daddiu $tmp0,-3 # 0ffffffc0ffffffc 160e71b7053SJung-uk Kim and $in1,$tmp0 161e71b7053SJung-uk Kim 162e71b7053SJung-uk Kim sd $in0,24($ctx) 163e71b7053SJung-uk Kim dsrl $tmp0,$in1,2 164e71b7053SJung-uk Kim sd $in1,32($ctx) 165e71b7053SJung-uk Kim daddu $tmp0,$in1 # s1 = r1 + (r1 >> 2) 166e71b7053SJung-uk Kim sd $tmp0,40($ctx) 167e71b7053SJung-uk Kim 168e71b7053SJung-uk Kim.Lno_key: 169e71b7053SJung-uk Kim li $v0,0 # return 0 170e71b7053SJung-uk Kim jr $ra 171e71b7053SJung-uk Kim.end poly1305_init 172e71b7053SJung-uk Kim___ 173e71b7053SJung-uk Kim{ 174e71b7053SJung-uk Kimmy ($h0,$h1,$h2,$r0,$r1,$s1,$d0,$d1,$d2) = 175e71b7053SJung-uk Kim ($s0,$s1,$s2,$s3,$s4,$s5,$in0,$in1,$t2); 176e71b7053SJung-uk Kim 177e71b7053SJung-uk Kim$code.=<<___; 178e71b7053SJung-uk Kim.align 5 179e71b7053SJung-uk Kim.globl poly1305_blocks 180e71b7053SJung-uk Kim.ent poly1305_blocks 181e71b7053SJung-uk Kimpoly1305_blocks: 182e71b7053SJung-uk Kim .set noreorder 183e71b7053SJung-uk Kim dsrl $len,4 # number of complete blocks 184e71b7053SJung-uk Kim bnez $len,poly1305_blocks_internal 185e71b7053SJung-uk Kim nop 186e71b7053SJung-uk Kim jr $ra 187e71b7053SJung-uk Kim nop 188e71b7053SJung-uk Kim.end poly1305_blocks 189e71b7053SJung-uk Kim 190e71b7053SJung-uk Kim.align 5 191e71b7053SJung-uk Kim.ent poly1305_blocks_internal 192e71b7053SJung-uk Kimpoly1305_blocks_internal: 193e71b7053SJung-uk Kim .frame $sp,6*8,$ra 194e71b7053SJung-uk Kim .mask $SAVED_REGS_MASK,-8 195e71b7053SJung-uk Kim .set noreorder 196e71b7053SJung-uk Kim dsubu $sp,6*8 197e71b7053SJung-uk Kim sd $s5,40($sp) 198e71b7053SJung-uk Kim sd $s4,32($sp) 199e71b7053SJung-uk Kim___ 200e71b7053SJung-uk Kim$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue 201e71b7053SJung-uk Kim sd $s3,24($sp) 202e71b7053SJung-uk Kim sd $s2,16($sp) 203e71b7053SJung-uk Kim sd $s1,8($sp) 204e71b7053SJung-uk Kim sd $s0,0($sp) 205e71b7053SJung-uk Kim___ 206e71b7053SJung-uk Kim$code.=<<___; 207e71b7053SJung-uk Kim .set reorder 208e71b7053SJung-uk Kim 209e71b7053SJung-uk Kim ld $h0,0($ctx) # load hash value 210e71b7053SJung-uk Kim ld $h1,8($ctx) 211e71b7053SJung-uk Kim ld $h2,16($ctx) 212e71b7053SJung-uk Kim 213e71b7053SJung-uk Kim ld $r0,24($ctx) # load key 214e71b7053SJung-uk Kim ld $r1,32($ctx) 215e71b7053SJung-uk Kim ld $s1,40($ctx) 216e71b7053SJung-uk Kim 217e71b7053SJung-uk Kim.Loop: 218e71b7053SJung-uk Kim#if defined(_MIPS_ARCH_MIPS64R6) 219e71b7053SJung-uk Kim ld $in0,0($inp) # load input 220e71b7053SJung-uk Kim ld $in1,8($inp) 221e71b7053SJung-uk Kim#else 222e71b7053SJung-uk Kim ldl $in0,0+MSB($inp) # load input 223e71b7053SJung-uk Kim ldl $in1,8+MSB($inp) 224e71b7053SJung-uk Kim ldr $in0,0+LSB($inp) 225e71b7053SJung-uk Kim ldr $in1,8+LSB($inp) 226e71b7053SJung-uk Kim#endif 227e71b7053SJung-uk Kim daddiu $len,-1 228e71b7053SJung-uk Kim daddiu $inp,16 229e71b7053SJung-uk Kim#ifdef MIPSEB 230e71b7053SJung-uk Kim# if defined(_MIPS_ARCH_MIPS64R2) 231e71b7053SJung-uk Kim dsbh $in0,$in0 # byte swap 232e71b7053SJung-uk Kim dsbh $in1,$in1 233e71b7053SJung-uk Kim dshd $in0,$in0 234e71b7053SJung-uk Kim dshd $in1,$in1 235e71b7053SJung-uk Kim# else 236e71b7053SJung-uk Kim ori $tmp0,$zero,0xFF 237e71b7053SJung-uk Kim dsll $tmp2,$tmp0,32 238e71b7053SJung-uk Kim or $tmp0,$tmp2 # 0x000000FF000000FF 239e71b7053SJung-uk Kim 240e71b7053SJung-uk Kim and $tmp1,$in0,$tmp0 # byte swap 241e71b7053SJung-uk Kim and $tmp3,$in1,$tmp0 242e71b7053SJung-uk Kim dsrl $tmp2,$in0,24 243e71b7053SJung-uk Kim dsrl $tmp4,$in1,24 244e71b7053SJung-uk Kim dsll $tmp1,24 245e71b7053SJung-uk Kim dsll $tmp3,24 246e71b7053SJung-uk Kim and $tmp2,$tmp0 247e71b7053SJung-uk Kim and $tmp4,$tmp0 248e71b7053SJung-uk Kim dsll $tmp0,8 # 0x0000FF000000FF00 249e71b7053SJung-uk Kim or $tmp1,$tmp2 250e71b7053SJung-uk Kim or $tmp3,$tmp4 251e71b7053SJung-uk Kim and $tmp2,$in0,$tmp0 252e71b7053SJung-uk Kim and $tmp4,$in1,$tmp0 253e71b7053SJung-uk Kim dsrl $in0,8 254e71b7053SJung-uk Kim dsrl $in1,8 255e71b7053SJung-uk Kim dsll $tmp2,8 256e71b7053SJung-uk Kim dsll $tmp4,8 257e71b7053SJung-uk Kim and $in0,$tmp0 258e71b7053SJung-uk Kim and $in1,$tmp0 259e71b7053SJung-uk Kim or $tmp1,$tmp2 260e71b7053SJung-uk Kim or $tmp3,$tmp4 261e71b7053SJung-uk Kim or $in0,$tmp1 262e71b7053SJung-uk Kim or $in1,$tmp3 263e71b7053SJung-uk Kim dsrl $tmp1,$in0,32 264e71b7053SJung-uk Kim dsrl $tmp3,$in1,32 265e71b7053SJung-uk Kim dsll $in0,32 266e71b7053SJung-uk Kim dsll $in1,32 267e71b7053SJung-uk Kim or $in0,$tmp1 268e71b7053SJung-uk Kim or $in1,$tmp3 269e71b7053SJung-uk Kim# endif 270e71b7053SJung-uk Kim#endif 271e71b7053SJung-uk Kim daddu $h0,$in0 # accumulate input 272e71b7053SJung-uk Kim daddu $h1,$in1 273e71b7053SJung-uk Kim sltu $tmp0,$h0,$in0 274e71b7053SJung-uk Kim sltu $tmp1,$h1,$in1 275e71b7053SJung-uk Kim daddu $h1,$tmp0 276e71b7053SJung-uk Kim 277e71b7053SJung-uk Kim dmultu ($r0,$h0) # h0*r0 278e71b7053SJung-uk Kim daddu $h2,$padbit 279e71b7053SJung-uk Kim sltu $tmp0,$h1,$tmp0 280e71b7053SJung-uk Kim mflo ($d0,$r0,$h0) 281e71b7053SJung-uk Kim mfhi ($d1,$r0,$h0) 282e71b7053SJung-uk Kim 283e71b7053SJung-uk Kim dmultu ($s1,$h1) # h1*5*r1 284e71b7053SJung-uk Kim daddu $tmp0,$tmp1 285e71b7053SJung-uk Kim daddu $h2,$tmp0 286e71b7053SJung-uk Kim mflo ($tmp0,$s1,$h1) 287e71b7053SJung-uk Kim mfhi ($tmp1,$s1,$h1) 288e71b7053SJung-uk Kim 289e71b7053SJung-uk Kim dmultu ($r1,$h0) # h0*r1 290e71b7053SJung-uk Kim daddu $d0,$tmp0 291e71b7053SJung-uk Kim daddu $d1,$tmp1 292e71b7053SJung-uk Kim mflo ($tmp2,$r1,$h0) 293e71b7053SJung-uk Kim mfhi ($d2,$r1,$h0) 294e71b7053SJung-uk Kim sltu $tmp0,$d0,$tmp0 295e71b7053SJung-uk Kim daddu $d1,$tmp0 296e71b7053SJung-uk Kim 297e71b7053SJung-uk Kim dmultu ($r0,$h1) # h1*r0 298e71b7053SJung-uk Kim daddu $d1,$tmp2 299e71b7053SJung-uk Kim sltu $tmp2,$d1,$tmp2 300e71b7053SJung-uk Kim mflo ($tmp0,$r0,$h1) 301e71b7053SJung-uk Kim mfhi ($tmp1,$r0,$h1) 302e71b7053SJung-uk Kim daddu $d2,$tmp2 303e71b7053SJung-uk Kim 304e71b7053SJung-uk Kim dmultu ($s1,$h2) # h2*5*r1 305e71b7053SJung-uk Kim daddu $d1,$tmp0 306e71b7053SJung-uk Kim daddu $d2,$tmp1 307e71b7053SJung-uk Kim mflo ($tmp2,$s1,$h2) 308e71b7053SJung-uk Kim 309e71b7053SJung-uk Kim dmultu ($r0,$h2) # h2*r0 310e71b7053SJung-uk Kim sltu $tmp0,$d1,$tmp0 311e71b7053SJung-uk Kim daddu $d2,$tmp0 312e71b7053SJung-uk Kim mflo ($tmp3,$r0,$h2) 313e71b7053SJung-uk Kim 314e71b7053SJung-uk Kim daddu $d1,$tmp2 315e71b7053SJung-uk Kim daddu $d2,$tmp3 316e71b7053SJung-uk Kim sltu $tmp2,$d1,$tmp2 317e71b7053SJung-uk Kim daddu $d2,$tmp2 318e71b7053SJung-uk Kim 319e71b7053SJung-uk Kim li $tmp0,-4 # final reduction 320e71b7053SJung-uk Kim and $tmp0,$d2 321e71b7053SJung-uk Kim dsrl $tmp1,$d2,2 322e71b7053SJung-uk Kim andi $h2,$d2,3 323e71b7053SJung-uk Kim daddu $tmp0,$tmp1 324e71b7053SJung-uk Kim daddu $h0,$d0,$tmp0 325e71b7053SJung-uk Kim sltu $tmp0,$h0,$tmp0 326e71b7053SJung-uk Kim daddu $h1,$d1,$tmp0 327e71b7053SJung-uk Kim sltu $tmp0,$h1,$tmp0 328e71b7053SJung-uk Kim daddu $h2,$h2,$tmp0 329e71b7053SJung-uk Kim 330e71b7053SJung-uk Kim bnez $len,.Loop 331e71b7053SJung-uk Kim 332e71b7053SJung-uk Kim sd $h0,0($ctx) # store hash value 333e71b7053SJung-uk Kim sd $h1,8($ctx) 334e71b7053SJung-uk Kim sd $h2,16($ctx) 335e71b7053SJung-uk Kim 336e71b7053SJung-uk Kim .set noreorder 337e71b7053SJung-uk Kim ld $s5,40($sp) # epilogue 338e71b7053SJung-uk Kim ld $s4,32($sp) 339e71b7053SJung-uk Kim___ 340e71b7053SJung-uk Kim$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi epilogue 341e71b7053SJung-uk Kim ld $s3,24($sp) 342e71b7053SJung-uk Kim ld $s2,16($sp) 343e71b7053SJung-uk Kim ld $s1,8($sp) 344e71b7053SJung-uk Kim ld $s0,0($sp) 345e71b7053SJung-uk Kim___ 346e71b7053SJung-uk Kim$code.=<<___; 347e71b7053SJung-uk Kim jr $ra 348e71b7053SJung-uk Kim daddu $sp,6*8 349e71b7053SJung-uk Kim.end poly1305_blocks_internal 350e71b7053SJung-uk Kim___ 351e71b7053SJung-uk Kim} 352e71b7053SJung-uk Kim{ 353e71b7053SJung-uk Kimmy ($ctx,$mac,$nonce) = ($a0,$a1,$a2); 354e71b7053SJung-uk Kim 355e71b7053SJung-uk Kim$code.=<<___; 356e71b7053SJung-uk Kim.align 5 357e71b7053SJung-uk Kim.globl poly1305_emit 358e71b7053SJung-uk Kim.ent poly1305_emit 359e71b7053SJung-uk Kimpoly1305_emit: 360e71b7053SJung-uk Kim .frame $sp,0,$ra 361e71b7053SJung-uk Kim .set reorder 362e71b7053SJung-uk Kim 363e71b7053SJung-uk Kim ld $tmp0,0($ctx) 364e71b7053SJung-uk Kim ld $tmp1,8($ctx) 365e71b7053SJung-uk Kim ld $tmp2,16($ctx) 366e71b7053SJung-uk Kim 367e71b7053SJung-uk Kim daddiu $in0,$tmp0,5 # compare to modulus 368e71b7053SJung-uk Kim sltiu $tmp3,$in0,5 369e71b7053SJung-uk Kim daddu $in1,$tmp1,$tmp3 370e71b7053SJung-uk Kim sltu $tmp3,$in1,$tmp3 371e71b7053SJung-uk Kim daddu $tmp2,$tmp2,$tmp3 372e71b7053SJung-uk Kim 373e71b7053SJung-uk Kim dsrl $tmp2,2 # see if it carried/borrowed 374e71b7053SJung-uk Kim dsubu $tmp2,$zero,$tmp2 375e71b7053SJung-uk Kim nor $tmp3,$zero,$tmp2 376e71b7053SJung-uk Kim 377e71b7053SJung-uk Kim and $in0,$tmp2 378e71b7053SJung-uk Kim and $tmp0,$tmp3 379e71b7053SJung-uk Kim and $in1,$tmp2 380e71b7053SJung-uk Kim and $tmp1,$tmp3 381e71b7053SJung-uk Kim or $in0,$tmp0 382e71b7053SJung-uk Kim or $in1,$tmp1 383e71b7053SJung-uk Kim 384e71b7053SJung-uk Kim lwu $tmp0,0($nonce) # load nonce 385e71b7053SJung-uk Kim lwu $tmp1,4($nonce) 386e71b7053SJung-uk Kim lwu $tmp2,8($nonce) 387e71b7053SJung-uk Kim lwu $tmp3,12($nonce) 388e71b7053SJung-uk Kim dsll $tmp1,32 389e71b7053SJung-uk Kim dsll $tmp3,32 390e71b7053SJung-uk Kim or $tmp0,$tmp1 391e71b7053SJung-uk Kim or $tmp2,$tmp3 392e71b7053SJung-uk Kim 393e71b7053SJung-uk Kim daddu $in0,$tmp0 # accumulate nonce 394e71b7053SJung-uk Kim daddu $in1,$tmp2 395e71b7053SJung-uk Kim sltu $tmp0,$in0,$tmp0 396e71b7053SJung-uk Kim daddu $in1,$tmp0 397e71b7053SJung-uk Kim 398e71b7053SJung-uk Kim dsrl $tmp0,$in0,8 # write mac value 399e71b7053SJung-uk Kim dsrl $tmp1,$in0,16 400e71b7053SJung-uk Kim dsrl $tmp2,$in0,24 401e71b7053SJung-uk Kim sb $in0,0($mac) 402e71b7053SJung-uk Kim dsrl $tmp3,$in0,32 403e71b7053SJung-uk Kim sb $tmp0,1($mac) 404e71b7053SJung-uk Kim dsrl $tmp0,$in0,40 405e71b7053SJung-uk Kim sb $tmp1,2($mac) 406e71b7053SJung-uk Kim dsrl $tmp1,$in0,48 407e71b7053SJung-uk Kim sb $tmp2,3($mac) 408e71b7053SJung-uk Kim dsrl $tmp2,$in0,56 409e71b7053SJung-uk Kim sb $tmp3,4($mac) 410e71b7053SJung-uk Kim dsrl $tmp3,$in1,8 411e71b7053SJung-uk Kim sb $tmp0,5($mac) 412e71b7053SJung-uk Kim dsrl $tmp0,$in1,16 413e71b7053SJung-uk Kim sb $tmp1,6($mac) 414e71b7053SJung-uk Kim dsrl $tmp1,$in1,24 415e71b7053SJung-uk Kim sb $tmp2,7($mac) 416e71b7053SJung-uk Kim 417e71b7053SJung-uk Kim sb $in1,8($mac) 418e71b7053SJung-uk Kim dsrl $tmp2,$in1,32 419e71b7053SJung-uk Kim sb $tmp3,9($mac) 420e71b7053SJung-uk Kim dsrl $tmp3,$in1,40 421e71b7053SJung-uk Kim sb $tmp0,10($mac) 422e71b7053SJung-uk Kim dsrl $tmp0,$in1,48 423e71b7053SJung-uk Kim sb $tmp1,11($mac) 424e71b7053SJung-uk Kim dsrl $tmp1,$in1,56 425e71b7053SJung-uk Kim sb $tmp2,12($mac) 426e71b7053SJung-uk Kim sb $tmp3,13($mac) 427e71b7053SJung-uk Kim sb $tmp0,14($mac) 428e71b7053SJung-uk Kim sb $tmp1,15($mac) 429e71b7053SJung-uk Kim 430e71b7053SJung-uk Kim jr $ra 431e71b7053SJung-uk Kim.end poly1305_emit 432e71b7053SJung-uk Kim.rdata 433e71b7053SJung-uk Kim.asciiz "Poly1305 for MIPS64, CRYPTOGAMS by <appro\@openssl.org>" 434e71b7053SJung-uk Kim.align 2 435e71b7053SJung-uk Kim___ 436e71b7053SJung-uk Kim} 437e71b7053SJung-uk Kim 438*b077aed3SPierre Pronchery$output and open STDOUT,">$output"; 439e71b7053SJung-uk Kimprint $code; 44017f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!"; 441e71b7053SJung-uk Kim 442