1289848Sjkim#!/usr/bin/env perl 2289848Sjkim 3289848Sjkim# Specific modes implementations for SPARC Architecture 2011. There 4289848Sjkim# is T4 dependency though, an ASI value that is not specified in the 5289848Sjkim# Architecture Manual. But as SPARC universe is rather monocultural, 6289848Sjkim# we imply that processor capable of executing crypto instructions 7289848Sjkim# can handle the ASI in question as well. This means that we ought to 8289848Sjkim# keep eyes open when new processors emerge... 9289848Sjkim# 10289848Sjkim# As for above mentioned ASI. It's so called "block initializing 11289848Sjkim# store" which cancels "read" in "read-update-write" on cache lines. 12289848Sjkim# This is "cooperative" optimization, as it reduces overall pressure 13289848Sjkim# on memory interface. Benefits can't be observed/quantified with 14289848Sjkim# usual benchmarks, on the contrary you can notice that single-thread 15289848Sjkim# performance for parallelizable modes is ~1.5% worse for largest 16289848Sjkim# block sizes [though few percent better for not so long ones]. All 17289848Sjkim# this based on suggestions from David Miller. 18289848Sjkim 19289848Sjkimsub asm_init { # to be called with @ARGV as argument 20289848Sjkim for (@_) { $::abibits=64 if (/\-m64/ || /\-xarch\=v9/); } 21289848Sjkim if ($::abibits==64) { $::bias=2047; $::frame=192; $::size_t_cc="%xcc"; } 22289848Sjkim else { $::bias=0; $::frame=112; $::size_t_cc="%icc"; } 23289848Sjkim} 24289848Sjkim 25289848Sjkim# unified interface 26289848Sjkimmy ($inp,$out,$len,$key,$ivec)=map("%i$_",(0..5)); 27289848Sjkim# local variables 28289848Sjkimmy ($ileft,$iright,$ooff,$omask,$ivoff,$blk_init)=map("%l$_",(0..7)); 29289848Sjkim 30289848Sjkimsub alg_cbc_encrypt_implement { 31289848Sjkimmy ($alg,$bits) = @_; 32289848Sjkim 33289848Sjkim$::code.=<<___; 34289848Sjkim.globl ${alg}${bits}_t4_cbc_encrypt 35289848Sjkim.align 32 36289848Sjkim${alg}${bits}_t4_cbc_encrypt: 37289848Sjkim save %sp, -$::frame, %sp 38289848Sjkim cmp $len, 0 39289848Sjkim be,pn $::size_t_cc, .L${bits}_cbc_enc_abort 40306195Sjkim srln $len, 0, $len ! needed on v8+, "nop" on v9 41289848Sjkim sub $inp, $out, $blk_init ! $inp!=$out 42289848Sjkim___ 43289848Sjkim$::code.=<<___ if (!$::evp); 44289848Sjkim andcc $ivec, 7, $ivoff 45289848Sjkim alignaddr $ivec, %g0, $ivec 46289848Sjkim 47289848Sjkim ldd [$ivec + 0], %f0 ! load ivec 48289848Sjkim bz,pt %icc, 1f 49289848Sjkim ldd [$ivec + 8], %f2 50289848Sjkim ldd [$ivec + 16], %f4 51289848Sjkim faligndata %f0, %f2, %f0 52289848Sjkim faligndata %f2, %f4, %f2 53289848Sjkim1: 54289848Sjkim___ 55289848Sjkim$::code.=<<___ if ($::evp); 56289848Sjkim ld [$ivec + 0], %f0 57289848Sjkim ld [$ivec + 4], %f1 58289848Sjkim ld [$ivec + 8], %f2 59289848Sjkim ld [$ivec + 12], %f3 60289848Sjkim___ 61289848Sjkim$::code.=<<___; 62289848Sjkim prefetch [$inp], 20 63289848Sjkim prefetch [$inp + 63], 20 64289848Sjkim call _${alg}${bits}_load_enckey 65289848Sjkim and $inp, 7, $ileft 66289848Sjkim andn $inp, 7, $inp 67289848Sjkim sll $ileft, 3, $ileft 68289848Sjkim mov 64, $iright 69289848Sjkim mov 0xff, $omask 70289848Sjkim sub $iright, $ileft, $iright 71289848Sjkim and $out, 7, $ooff 72289848Sjkim cmp $len, 127 73289848Sjkim movrnz $ooff, 0, $blk_init ! if ( $out&7 || 74289848Sjkim movleu $::size_t_cc, 0, $blk_init ! $len<128 || 75289848Sjkim brnz,pn $blk_init, .L${bits}cbc_enc_blk ! $inp==$out) 76289848Sjkim srl $omask, $ooff, $omask 77289848Sjkim 78289848Sjkim alignaddrl $out, %g0, $out 79289848Sjkim srlx $len, 4, $len 80289848Sjkim prefetch [$out], 22 81289848Sjkim 82289848Sjkim.L${bits}_cbc_enc_loop: 83289848Sjkim ldx [$inp + 0], %o0 84289848Sjkim brz,pt $ileft, 4f 85289848Sjkim ldx [$inp + 8], %o1 86289848Sjkim 87289848Sjkim ldx [$inp + 16], %o2 88289848Sjkim sllx %o0, $ileft, %o0 89289848Sjkim srlx %o1, $iright, %g1 90289848Sjkim sllx %o1, $ileft, %o1 91289848Sjkim or %g1, %o0, %o0 92289848Sjkim srlx %o2, $iright, %o2 93289848Sjkim or %o2, %o1, %o1 94289848Sjkim4: 95289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 96289848Sjkim xor %g5, %o1, %o1 97289848Sjkim movxtod %o0, %f12 98289848Sjkim movxtod %o1, %f14 99289848Sjkim 100289848Sjkim fxor %f12, %f0, %f0 ! ^= ivec 101289848Sjkim fxor %f14, %f2, %f2 102289848Sjkim prefetch [$out + 63], 22 103289848Sjkim prefetch [$inp + 16+63], 20 104289848Sjkim call _${alg}${bits}_encrypt_1x 105289848Sjkim add $inp, 16, $inp 106289848Sjkim 107289848Sjkim brnz,pn $ooff, 2f 108289848Sjkim sub $len, 1, $len 109289848Sjkim 110289848Sjkim std %f0, [$out + 0] 111289848Sjkim std %f2, [$out + 8] 112289848Sjkim brnz,pt $len, .L${bits}_cbc_enc_loop 113289848Sjkim add $out, 16, $out 114289848Sjkim___ 115289848Sjkim$::code.=<<___ if ($::evp); 116289848Sjkim st %f0, [$ivec + 0] 117289848Sjkim st %f1, [$ivec + 4] 118289848Sjkim st %f2, [$ivec + 8] 119289848Sjkim st %f3, [$ivec + 12] 120289848Sjkim___ 121289848Sjkim$::code.=<<___ if (!$::evp); 122289848Sjkim brnz,pn $ivoff, 3f 123289848Sjkim nop 124289848Sjkim 125289848Sjkim std %f0, [$ivec + 0] ! write out ivec 126289848Sjkim std %f2, [$ivec + 8] 127289848Sjkim___ 128289848Sjkim$::code.=<<___; 129289848Sjkim.L${bits}_cbc_enc_abort: 130289848Sjkim ret 131289848Sjkim restore 132289848Sjkim 133289848Sjkim.align 16 134289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 135289848Sjkim ! and ~3x deterioration 136289848Sjkim ! in inp==out case 137289848Sjkim faligndata %f0, %f0, %f4 ! handle unaligned output 138289848Sjkim faligndata %f0, %f2, %f6 139289848Sjkim faligndata %f2, %f2, %f8 140289848Sjkim 141289848Sjkim stda %f4, [$out + $omask]0xc0 ! partial store 142289848Sjkim std %f6, [$out + 8] 143289848Sjkim add $out, 16, $out 144289848Sjkim orn %g0, $omask, $omask 145289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 146289848Sjkim 147289848Sjkim brnz,pt $len, .L${bits}_cbc_enc_loop+4 148289848Sjkim orn %g0, $omask, $omask 149289848Sjkim___ 150289848Sjkim$::code.=<<___ if ($::evp); 151289848Sjkim st %f0, [$ivec + 0] 152289848Sjkim st %f1, [$ivec + 4] 153289848Sjkim st %f2, [$ivec + 8] 154289848Sjkim st %f3, [$ivec + 12] 155289848Sjkim___ 156289848Sjkim$::code.=<<___ if (!$::evp); 157289848Sjkim brnz,pn $ivoff, 3f 158289848Sjkim nop 159289848Sjkim 160289848Sjkim std %f0, [$ivec + 0] ! write out ivec 161289848Sjkim std %f2, [$ivec + 8] 162289848Sjkim ret 163289848Sjkim restore 164289848Sjkim 165289848Sjkim.align 16 166289848Sjkim3: alignaddrl $ivec, $ivoff, %g0 ! handle unaligned ivec 167289848Sjkim mov 0xff, $omask 168289848Sjkim srl $omask, $ivoff, $omask 169289848Sjkim faligndata %f0, %f0, %f4 170289848Sjkim faligndata %f0, %f2, %f6 171289848Sjkim faligndata %f2, %f2, %f8 172289848Sjkim stda %f4, [$ivec + $omask]0xc0 173289848Sjkim std %f6, [$ivec + 8] 174289848Sjkim add $ivec, 16, $ivec 175289848Sjkim orn %g0, $omask, $omask 176289848Sjkim stda %f8, [$ivec + $omask]0xc0 177289848Sjkim___ 178289848Sjkim$::code.=<<___; 179289848Sjkim ret 180289848Sjkim restore 181289848Sjkim 182289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 183289848Sjkim.align 32 184289848Sjkim.L${bits}cbc_enc_blk: 185289848Sjkim add $out, $len, $blk_init 186289848Sjkim and $blk_init, 63, $blk_init ! tail 187289848Sjkim sub $len, $blk_init, $len 188289848Sjkim add $blk_init, 15, $blk_init ! round up to 16n 189289848Sjkim srlx $len, 4, $len 190289848Sjkim srl $blk_init, 4, $blk_init 191289848Sjkim 192289848Sjkim.L${bits}_cbc_enc_blk_loop: 193289848Sjkim ldx [$inp + 0], %o0 194289848Sjkim brz,pt $ileft, 5f 195289848Sjkim ldx [$inp + 8], %o1 196289848Sjkim 197289848Sjkim ldx [$inp + 16], %o2 198289848Sjkim sllx %o0, $ileft, %o0 199289848Sjkim srlx %o1, $iright, %g1 200289848Sjkim sllx %o1, $ileft, %o1 201289848Sjkim or %g1, %o0, %o0 202289848Sjkim srlx %o2, $iright, %o2 203289848Sjkim or %o2, %o1, %o1 204289848Sjkim5: 205289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 206289848Sjkim xor %g5, %o1, %o1 207289848Sjkim movxtod %o0, %f12 208289848Sjkim movxtod %o1, %f14 209289848Sjkim 210289848Sjkim fxor %f12, %f0, %f0 ! ^= ivec 211289848Sjkim fxor %f14, %f2, %f2 212289848Sjkim prefetch [$inp + 16+63], 20 213289848Sjkim call _${alg}${bits}_encrypt_1x 214289848Sjkim add $inp, 16, $inp 215289848Sjkim sub $len, 1, $len 216289848Sjkim 217289848Sjkim stda %f0, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 218289848Sjkim add $out, 8, $out 219289848Sjkim stda %f2, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 220289848Sjkim brnz,pt $len, .L${bits}_cbc_enc_blk_loop 221289848Sjkim add $out, 8, $out 222289848Sjkim 223289848Sjkim membar #StoreLoad|#StoreStore 224289848Sjkim brnz,pt $blk_init, .L${bits}_cbc_enc_loop 225289848Sjkim mov $blk_init, $len 226289848Sjkim___ 227289848Sjkim$::code.=<<___ if ($::evp); 228289848Sjkim st %f0, [$ivec + 0] 229289848Sjkim st %f1, [$ivec + 4] 230289848Sjkim st %f2, [$ivec + 8] 231289848Sjkim st %f3, [$ivec + 12] 232289848Sjkim___ 233289848Sjkim$::code.=<<___ if (!$::evp); 234289848Sjkim brnz,pn $ivoff, 3b 235289848Sjkim nop 236289848Sjkim 237289848Sjkim std %f0, [$ivec + 0] ! write out ivec 238289848Sjkim std %f2, [$ivec + 8] 239289848Sjkim___ 240289848Sjkim$::code.=<<___; 241289848Sjkim ret 242289848Sjkim restore 243289848Sjkim.type ${alg}${bits}_t4_cbc_encrypt,#function 244289848Sjkim.size ${alg}${bits}_t4_cbc_encrypt,.-${alg}${bits}_t4_cbc_encrypt 245289848Sjkim___ 246289848Sjkim} 247289848Sjkim 248289848Sjkimsub alg_cbc_decrypt_implement { 249289848Sjkimmy ($alg,$bits) = @_; 250289848Sjkim 251289848Sjkim$::code.=<<___; 252289848Sjkim.globl ${alg}${bits}_t4_cbc_decrypt 253289848Sjkim.align 32 254289848Sjkim${alg}${bits}_t4_cbc_decrypt: 255289848Sjkim save %sp, -$::frame, %sp 256289848Sjkim cmp $len, 0 257289848Sjkim be,pn $::size_t_cc, .L${bits}_cbc_dec_abort 258306195Sjkim srln $len, 0, $len ! needed on v8+, "nop" on v9 259289848Sjkim sub $inp, $out, $blk_init ! $inp!=$out 260289848Sjkim___ 261289848Sjkim$::code.=<<___ if (!$::evp); 262289848Sjkim andcc $ivec, 7, $ivoff 263289848Sjkim alignaddr $ivec, %g0, $ivec 264289848Sjkim 265289848Sjkim ldd [$ivec + 0], %f12 ! load ivec 266289848Sjkim bz,pt %icc, 1f 267289848Sjkim ldd [$ivec + 8], %f14 268289848Sjkim ldd [$ivec + 16], %f0 269289848Sjkim faligndata %f12, %f14, %f12 270289848Sjkim faligndata %f14, %f0, %f14 271289848Sjkim1: 272289848Sjkim___ 273289848Sjkim$::code.=<<___ if ($::evp); 274289848Sjkim ld [$ivec + 0], %f12 ! load ivec 275289848Sjkim ld [$ivec + 4], %f13 276289848Sjkim ld [$ivec + 8], %f14 277289848Sjkim ld [$ivec + 12], %f15 278289848Sjkim___ 279289848Sjkim$::code.=<<___; 280289848Sjkim prefetch [$inp], 20 281289848Sjkim prefetch [$inp + 63], 20 282289848Sjkim call _${alg}${bits}_load_deckey 283289848Sjkim and $inp, 7, $ileft 284289848Sjkim andn $inp, 7, $inp 285289848Sjkim sll $ileft, 3, $ileft 286289848Sjkim mov 64, $iright 287289848Sjkim mov 0xff, $omask 288289848Sjkim sub $iright, $ileft, $iright 289289848Sjkim and $out, 7, $ooff 290289848Sjkim cmp $len, 255 291289848Sjkim movrnz $ooff, 0, $blk_init ! if ( $out&7 || 292289848Sjkim movleu $::size_t_cc, 0, $blk_init ! $len<256 || 293289848Sjkim brnz,pn $blk_init, .L${bits}cbc_dec_blk ! $inp==$out) 294289848Sjkim srl $omask, $ooff, $omask 295289848Sjkim 296289848Sjkim andcc $len, 16, %g0 ! is number of blocks even? 297289848Sjkim srlx $len, 4, $len 298289848Sjkim alignaddrl $out, %g0, $out 299289848Sjkim bz %icc, .L${bits}_cbc_dec_loop2x 300289848Sjkim prefetch [$out], 22 301289848Sjkim.L${bits}_cbc_dec_loop: 302289848Sjkim ldx [$inp + 0], %o0 303289848Sjkim brz,pt $ileft, 4f 304289848Sjkim ldx [$inp + 8], %o1 305289848Sjkim 306289848Sjkim ldx [$inp + 16], %o2 307289848Sjkim sllx %o0, $ileft, %o0 308289848Sjkim srlx %o1, $iright, %g1 309289848Sjkim sllx %o1, $ileft, %o1 310289848Sjkim or %g1, %o0, %o0 311289848Sjkim srlx %o2, $iright, %o2 312289848Sjkim or %o2, %o1, %o1 313289848Sjkim4: 314289848Sjkim xor %g4, %o0, %o2 ! ^= rk[0] 315289848Sjkim xor %g5, %o1, %o3 316289848Sjkim movxtod %o2, %f0 317289848Sjkim movxtod %o3, %f2 318289848Sjkim 319289848Sjkim prefetch [$out + 63], 22 320289848Sjkim prefetch [$inp + 16+63], 20 321289848Sjkim call _${alg}${bits}_decrypt_1x 322289848Sjkim add $inp, 16, $inp 323289848Sjkim 324289848Sjkim fxor %f12, %f0, %f0 ! ^= ivec 325289848Sjkim fxor %f14, %f2, %f2 326289848Sjkim movxtod %o0, %f12 327289848Sjkim movxtod %o1, %f14 328289848Sjkim 329289848Sjkim brnz,pn $ooff, 2f 330289848Sjkim sub $len, 1, $len 331289848Sjkim 332289848Sjkim std %f0, [$out + 0] 333289848Sjkim std %f2, [$out + 8] 334289848Sjkim brnz,pt $len, .L${bits}_cbc_dec_loop2x 335289848Sjkim add $out, 16, $out 336289848Sjkim___ 337289848Sjkim$::code.=<<___ if ($::evp); 338289848Sjkim st %f12, [$ivec + 0] 339289848Sjkim st %f13, [$ivec + 4] 340289848Sjkim st %f14, [$ivec + 8] 341289848Sjkim st %f15, [$ivec + 12] 342289848Sjkim___ 343289848Sjkim$::code.=<<___ if (!$::evp); 344289848Sjkim brnz,pn $ivoff, .L${bits}_cbc_dec_unaligned_ivec 345289848Sjkim nop 346289848Sjkim 347289848Sjkim std %f12, [$ivec + 0] ! write out ivec 348289848Sjkim std %f14, [$ivec + 8] 349289848Sjkim___ 350289848Sjkim$::code.=<<___; 351289848Sjkim.L${bits}_cbc_dec_abort: 352289848Sjkim ret 353289848Sjkim restore 354289848Sjkim 355289848Sjkim.align 16 356289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 357289848Sjkim ! and ~3x deterioration 358289848Sjkim ! in inp==out case 359289848Sjkim faligndata %f0, %f0, %f4 ! handle unaligned output 360289848Sjkim faligndata %f0, %f2, %f6 361289848Sjkim faligndata %f2, %f2, %f8 362289848Sjkim 363289848Sjkim stda %f4, [$out + $omask]0xc0 ! partial store 364289848Sjkim std %f6, [$out + 8] 365289848Sjkim add $out, 16, $out 366289848Sjkim orn %g0, $omask, $omask 367289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 368289848Sjkim 369289848Sjkim brnz,pt $len, .L${bits}_cbc_dec_loop2x+4 370289848Sjkim orn %g0, $omask, $omask 371289848Sjkim___ 372289848Sjkim$::code.=<<___ if ($::evp); 373289848Sjkim st %f12, [$ivec + 0] 374289848Sjkim st %f13, [$ivec + 4] 375289848Sjkim st %f14, [$ivec + 8] 376289848Sjkim st %f15, [$ivec + 12] 377289848Sjkim___ 378289848Sjkim$::code.=<<___ if (!$::evp); 379289848Sjkim brnz,pn $ivoff, .L${bits}_cbc_dec_unaligned_ivec 380289848Sjkim nop 381289848Sjkim 382289848Sjkim std %f12, [$ivec + 0] ! write out ivec 383289848Sjkim std %f14, [$ivec + 8] 384289848Sjkim___ 385289848Sjkim$::code.=<<___; 386289848Sjkim ret 387289848Sjkim restore 388289848Sjkim 389289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 390289848Sjkim.align 32 391289848Sjkim.L${bits}_cbc_dec_loop2x: 392289848Sjkim ldx [$inp + 0], %o0 393289848Sjkim ldx [$inp + 8], %o1 394289848Sjkim ldx [$inp + 16], %o2 395289848Sjkim brz,pt $ileft, 4f 396289848Sjkim ldx [$inp + 24], %o3 397289848Sjkim 398289848Sjkim ldx [$inp + 32], %o4 399289848Sjkim sllx %o0, $ileft, %o0 400289848Sjkim srlx %o1, $iright, %g1 401289848Sjkim or %g1, %o0, %o0 402289848Sjkim sllx %o1, $ileft, %o1 403289848Sjkim srlx %o2, $iright, %g1 404289848Sjkim or %g1, %o1, %o1 405289848Sjkim sllx %o2, $ileft, %o2 406289848Sjkim srlx %o3, $iright, %g1 407289848Sjkim or %g1, %o2, %o2 408289848Sjkim sllx %o3, $ileft, %o3 409289848Sjkim srlx %o4, $iright, %o4 410289848Sjkim or %o4, %o3, %o3 411289848Sjkim4: 412289848Sjkim xor %g4, %o0, %o4 ! ^= rk[0] 413289848Sjkim xor %g5, %o1, %o5 414289848Sjkim movxtod %o4, %f0 415289848Sjkim movxtod %o5, %f2 416289848Sjkim xor %g4, %o2, %o4 417289848Sjkim xor %g5, %o3, %o5 418289848Sjkim movxtod %o4, %f4 419289848Sjkim movxtod %o5, %f6 420289848Sjkim 421289848Sjkim prefetch [$out + 63], 22 422289848Sjkim prefetch [$inp + 32+63], 20 423289848Sjkim call _${alg}${bits}_decrypt_2x 424289848Sjkim add $inp, 32, $inp 425289848Sjkim 426289848Sjkim movxtod %o0, %f8 427289848Sjkim movxtod %o1, %f10 428289848Sjkim fxor %f12, %f0, %f0 ! ^= ivec 429289848Sjkim fxor %f14, %f2, %f2 430289848Sjkim movxtod %o2, %f12 431289848Sjkim movxtod %o3, %f14 432289848Sjkim fxor %f8, %f4, %f4 433289848Sjkim fxor %f10, %f6, %f6 434289848Sjkim 435289848Sjkim brnz,pn $ooff, 2f 436289848Sjkim sub $len, 2, $len 437289848Sjkim 438289848Sjkim std %f0, [$out + 0] 439289848Sjkim std %f2, [$out + 8] 440289848Sjkim std %f4, [$out + 16] 441289848Sjkim std %f6, [$out + 24] 442289848Sjkim brnz,pt $len, .L${bits}_cbc_dec_loop2x 443289848Sjkim add $out, 32, $out 444289848Sjkim___ 445289848Sjkim$::code.=<<___ if ($::evp); 446289848Sjkim st %f12, [$ivec + 0] 447289848Sjkim st %f13, [$ivec + 4] 448289848Sjkim st %f14, [$ivec + 8] 449289848Sjkim st %f15, [$ivec + 12] 450289848Sjkim___ 451289848Sjkim$::code.=<<___ if (!$::evp); 452289848Sjkim brnz,pn $ivoff, .L${bits}_cbc_dec_unaligned_ivec 453289848Sjkim nop 454289848Sjkim 455289848Sjkim std %f12, [$ivec + 0] ! write out ivec 456289848Sjkim std %f14, [$ivec + 8] 457289848Sjkim___ 458289848Sjkim$::code.=<<___; 459289848Sjkim ret 460289848Sjkim restore 461289848Sjkim 462289848Sjkim.align 16 463289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 464289848Sjkim ! and ~3x deterioration 465289848Sjkim ! in inp==out case 466289848Sjkim faligndata %f0, %f0, %f8 ! handle unaligned output 467289848Sjkim faligndata %f0, %f2, %f0 468289848Sjkim faligndata %f2, %f4, %f2 469289848Sjkim faligndata %f4, %f6, %f4 470289848Sjkim faligndata %f6, %f6, %f6 471289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 472289848Sjkim std %f0, [$out + 8] 473289848Sjkim std %f2, [$out + 16] 474289848Sjkim std %f4, [$out + 24] 475289848Sjkim add $out, 32, $out 476289848Sjkim orn %g0, $omask, $omask 477289848Sjkim stda %f6, [$out + $omask]0xc0 ! partial store 478289848Sjkim 479289848Sjkim brnz,pt $len, .L${bits}_cbc_dec_loop2x+4 480289848Sjkim orn %g0, $omask, $omask 481289848Sjkim___ 482289848Sjkim$::code.=<<___ if ($::evp); 483289848Sjkim st %f12, [$ivec + 0] 484289848Sjkim st %f13, [$ivec + 4] 485289848Sjkim st %f14, [$ivec + 8] 486289848Sjkim st %f15, [$ivec + 12] 487289848Sjkim___ 488289848Sjkim$::code.=<<___ if (!$::evp); 489289848Sjkim brnz,pn $ivoff, .L${bits}_cbc_dec_unaligned_ivec 490289848Sjkim nop 491289848Sjkim 492289848Sjkim std %f12, [$ivec + 0] ! write out ivec 493289848Sjkim std %f14, [$ivec + 8] 494289848Sjkim ret 495289848Sjkim restore 496289848Sjkim 497289848Sjkim.align 16 498289848Sjkim.L${bits}_cbc_dec_unaligned_ivec: 499289848Sjkim alignaddrl $ivec, $ivoff, %g0 ! handle unaligned ivec 500289848Sjkim mov 0xff, $omask 501289848Sjkim srl $omask, $ivoff, $omask 502289848Sjkim faligndata %f12, %f12, %f0 503289848Sjkim faligndata %f12, %f14, %f2 504289848Sjkim faligndata %f14, %f14, %f4 505289848Sjkim stda %f0, [$ivec + $omask]0xc0 506289848Sjkim std %f2, [$ivec + 8] 507289848Sjkim add $ivec, 16, $ivec 508289848Sjkim orn %g0, $omask, $omask 509289848Sjkim stda %f4, [$ivec + $omask]0xc0 510289848Sjkim___ 511289848Sjkim$::code.=<<___; 512289848Sjkim ret 513289848Sjkim restore 514289848Sjkim 515289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 516289848Sjkim.align 32 517289848Sjkim.L${bits}cbc_dec_blk: 518289848Sjkim add $out, $len, $blk_init 519289848Sjkim and $blk_init, 63, $blk_init ! tail 520289848Sjkim sub $len, $blk_init, $len 521289848Sjkim add $blk_init, 15, $blk_init ! round up to 16n 522289848Sjkim srlx $len, 4, $len 523289848Sjkim srl $blk_init, 4, $blk_init 524289848Sjkim sub $len, 1, $len 525289848Sjkim add $blk_init, 1, $blk_init 526289848Sjkim 527289848Sjkim.L${bits}_cbc_dec_blk_loop2x: 528289848Sjkim ldx [$inp + 0], %o0 529289848Sjkim ldx [$inp + 8], %o1 530289848Sjkim ldx [$inp + 16], %o2 531289848Sjkim brz,pt $ileft, 5f 532289848Sjkim ldx [$inp + 24], %o3 533289848Sjkim 534289848Sjkim ldx [$inp + 32], %o4 535289848Sjkim sllx %o0, $ileft, %o0 536289848Sjkim srlx %o1, $iright, %g1 537289848Sjkim or %g1, %o0, %o0 538289848Sjkim sllx %o1, $ileft, %o1 539289848Sjkim srlx %o2, $iright, %g1 540289848Sjkim or %g1, %o1, %o1 541289848Sjkim sllx %o2, $ileft, %o2 542289848Sjkim srlx %o3, $iright, %g1 543289848Sjkim or %g1, %o2, %o2 544289848Sjkim sllx %o3, $ileft, %o3 545289848Sjkim srlx %o4, $iright, %o4 546289848Sjkim or %o4, %o3, %o3 547289848Sjkim5: 548289848Sjkim xor %g4, %o0, %o4 ! ^= rk[0] 549289848Sjkim xor %g5, %o1, %o5 550289848Sjkim movxtod %o4, %f0 551289848Sjkim movxtod %o5, %f2 552289848Sjkim xor %g4, %o2, %o4 553289848Sjkim xor %g5, %o3, %o5 554289848Sjkim movxtod %o4, %f4 555289848Sjkim movxtod %o5, %f6 556289848Sjkim 557289848Sjkim prefetch [$inp + 32+63], 20 558289848Sjkim call _${alg}${bits}_decrypt_2x 559289848Sjkim add $inp, 32, $inp 560289848Sjkim subcc $len, 2, $len 561289848Sjkim 562289848Sjkim movxtod %o0, %f8 563289848Sjkim movxtod %o1, %f10 564289848Sjkim fxor %f12, %f0, %f0 ! ^= ivec 565289848Sjkim fxor %f14, %f2, %f2 566289848Sjkim movxtod %o2, %f12 567289848Sjkim movxtod %o3, %f14 568289848Sjkim fxor %f8, %f4, %f4 569289848Sjkim fxor %f10, %f6, %f6 570289848Sjkim 571289848Sjkim stda %f0, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 572289848Sjkim add $out, 8, $out 573289848Sjkim stda %f2, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 574289848Sjkim add $out, 8, $out 575289848Sjkim stda %f4, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 576289848Sjkim add $out, 8, $out 577289848Sjkim stda %f6, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 578289848Sjkim bgu,pt $::size_t_cc, .L${bits}_cbc_dec_blk_loop2x 579289848Sjkim add $out, 8, $out 580289848Sjkim 581289848Sjkim add $blk_init, $len, $len 582289848Sjkim andcc $len, 1, %g0 ! is number of blocks even? 583289848Sjkim membar #StoreLoad|#StoreStore 584289848Sjkim bnz,pt %icc, .L${bits}_cbc_dec_loop 585289848Sjkim srl $len, 0, $len 586289848Sjkim brnz,pn $len, .L${bits}_cbc_dec_loop2x 587289848Sjkim nop 588289848Sjkim___ 589289848Sjkim$::code.=<<___ if ($::evp); 590289848Sjkim st %f12, [$ivec + 0] ! write out ivec 591289848Sjkim st %f13, [$ivec + 4] 592289848Sjkim st %f14, [$ivec + 8] 593289848Sjkim st %f15, [$ivec + 12] 594289848Sjkim___ 595289848Sjkim$::code.=<<___ if (!$::evp); 596289848Sjkim brnz,pn $ivoff, 3b 597289848Sjkim nop 598289848Sjkim 599289848Sjkim std %f12, [$ivec + 0] ! write out ivec 600289848Sjkim std %f14, [$ivec + 8] 601289848Sjkim___ 602289848Sjkim$::code.=<<___; 603289848Sjkim ret 604289848Sjkim restore 605289848Sjkim.type ${alg}${bits}_t4_cbc_decrypt,#function 606289848Sjkim.size ${alg}${bits}_t4_cbc_decrypt,.-${alg}${bits}_t4_cbc_decrypt 607289848Sjkim___ 608289848Sjkim} 609289848Sjkim 610289848Sjkimsub alg_ctr32_implement { 611289848Sjkimmy ($alg,$bits) = @_; 612289848Sjkim 613289848Sjkim$::code.=<<___; 614289848Sjkim.globl ${alg}${bits}_t4_ctr32_encrypt 615289848Sjkim.align 32 616289848Sjkim${alg}${bits}_t4_ctr32_encrypt: 617289848Sjkim save %sp, -$::frame, %sp 618306195Sjkim srln $len, 0, $len ! needed on v8+, "nop" on v9 619289848Sjkim 620289848Sjkim prefetch [$inp], 20 621289848Sjkim prefetch [$inp + 63], 20 622289848Sjkim call _${alg}${bits}_load_enckey 623289848Sjkim sllx $len, 4, $len 624289848Sjkim 625289848Sjkim ld [$ivec + 0], %l4 ! counter 626289848Sjkim ld [$ivec + 4], %l5 627289848Sjkim ld [$ivec + 8], %l6 628289848Sjkim ld [$ivec + 12], %l7 629289848Sjkim 630289848Sjkim sllx %l4, 32, %o5 631289848Sjkim or %l5, %o5, %o5 632289848Sjkim sllx %l6, 32, %g1 633289848Sjkim xor %o5, %g4, %g4 ! ^= rk[0] 634289848Sjkim xor %g1, %g5, %g5 635289848Sjkim movxtod %g4, %f14 ! most significant 64 bits 636289848Sjkim 637289848Sjkim sub $inp, $out, $blk_init ! $inp!=$out 638289848Sjkim and $inp, 7, $ileft 639289848Sjkim andn $inp, 7, $inp 640289848Sjkim sll $ileft, 3, $ileft 641289848Sjkim mov 64, $iright 642289848Sjkim mov 0xff, $omask 643289848Sjkim sub $iright, $ileft, $iright 644289848Sjkim and $out, 7, $ooff 645289848Sjkim cmp $len, 255 646289848Sjkim movrnz $ooff, 0, $blk_init ! if ( $out&7 || 647289848Sjkim movleu $::size_t_cc, 0, $blk_init ! $len<256 || 648289848Sjkim brnz,pn $blk_init, .L${bits}_ctr32_blk ! $inp==$out) 649289848Sjkim srl $omask, $ooff, $omask 650289848Sjkim 651289848Sjkim andcc $len, 16, %g0 ! is number of blocks even? 652289848Sjkim alignaddrl $out, %g0, $out 653289848Sjkim bz %icc, .L${bits}_ctr32_loop2x 654289848Sjkim srlx $len, 4, $len 655289848Sjkim.L${bits}_ctr32_loop: 656289848Sjkim ldx [$inp + 0], %o0 657289848Sjkim brz,pt $ileft, 4f 658289848Sjkim ldx [$inp + 8], %o1 659289848Sjkim 660289848Sjkim ldx [$inp + 16], %o2 661289848Sjkim sllx %o0, $ileft, %o0 662289848Sjkim srlx %o1, $iright, %g1 663289848Sjkim sllx %o1, $ileft, %o1 664289848Sjkim or %g1, %o0, %o0 665289848Sjkim srlx %o2, $iright, %o2 666289848Sjkim or %o2, %o1, %o1 667289848Sjkim4: 668289848Sjkim xor %g5, %l7, %g1 ! ^= rk[0] 669289848Sjkim add %l7, 1, %l7 670289848Sjkim movxtod %g1, %f2 671289848Sjkim srl %l7, 0, %l7 ! clruw 672289848Sjkim prefetch [$out + 63], 22 673289848Sjkim prefetch [$inp + 16+63], 20 674289848Sjkim___ 675289848Sjkim$::code.=<<___ if ($alg eq "aes"); 676289848Sjkim aes_eround01 %f16, %f14, %f2, %f4 677289848Sjkim aes_eround23 %f18, %f14, %f2, %f2 678289848Sjkim___ 679289848Sjkim$::code.=<<___ if ($alg eq "cmll"); 680289848Sjkim camellia_f %f16, %f2, %f14, %f2 681289848Sjkim camellia_f %f18, %f14, %f2, %f0 682289848Sjkim___ 683289848Sjkim$::code.=<<___; 684289848Sjkim call _${alg}${bits}_encrypt_1x+8 685289848Sjkim add $inp, 16, $inp 686289848Sjkim 687289848Sjkim movxtod %o0, %f10 688289848Sjkim movxtod %o1, %f12 689289848Sjkim fxor %f10, %f0, %f0 ! ^= inp 690289848Sjkim fxor %f12, %f2, %f2 691289848Sjkim 692289848Sjkim brnz,pn $ooff, 2f 693289848Sjkim sub $len, 1, $len 694289848Sjkim 695289848Sjkim std %f0, [$out + 0] 696289848Sjkim std %f2, [$out + 8] 697289848Sjkim brnz,pt $len, .L${bits}_ctr32_loop2x 698289848Sjkim add $out, 16, $out 699289848Sjkim 700289848Sjkim ret 701289848Sjkim restore 702289848Sjkim 703289848Sjkim.align 16 704289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 705289848Sjkim ! and ~3x deterioration 706289848Sjkim ! in inp==out case 707289848Sjkim faligndata %f0, %f0, %f4 ! handle unaligned output 708289848Sjkim faligndata %f0, %f2, %f6 709289848Sjkim faligndata %f2, %f2, %f8 710289848Sjkim stda %f4, [$out + $omask]0xc0 ! partial store 711289848Sjkim std %f6, [$out + 8] 712289848Sjkim add $out, 16, $out 713289848Sjkim orn %g0, $omask, $omask 714289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 715289848Sjkim 716289848Sjkim brnz,pt $len, .L${bits}_ctr32_loop2x+4 717289848Sjkim orn %g0, $omask, $omask 718289848Sjkim 719289848Sjkim ret 720289848Sjkim restore 721289848Sjkim 722289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 723289848Sjkim.align 32 724289848Sjkim.L${bits}_ctr32_loop2x: 725289848Sjkim ldx [$inp + 0], %o0 726289848Sjkim ldx [$inp + 8], %o1 727289848Sjkim ldx [$inp + 16], %o2 728289848Sjkim brz,pt $ileft, 4f 729289848Sjkim ldx [$inp + 24], %o3 730289848Sjkim 731289848Sjkim ldx [$inp + 32], %o4 732289848Sjkim sllx %o0, $ileft, %o0 733289848Sjkim srlx %o1, $iright, %g1 734289848Sjkim or %g1, %o0, %o0 735289848Sjkim sllx %o1, $ileft, %o1 736289848Sjkim srlx %o2, $iright, %g1 737289848Sjkim or %g1, %o1, %o1 738289848Sjkim sllx %o2, $ileft, %o2 739289848Sjkim srlx %o3, $iright, %g1 740289848Sjkim or %g1, %o2, %o2 741289848Sjkim sllx %o3, $ileft, %o3 742289848Sjkim srlx %o4, $iright, %o4 743289848Sjkim or %o4, %o3, %o3 744289848Sjkim4: 745289848Sjkim xor %g5, %l7, %g1 ! ^= rk[0] 746289848Sjkim add %l7, 1, %l7 747289848Sjkim movxtod %g1, %f2 748289848Sjkim srl %l7, 0, %l7 ! clruw 749289848Sjkim xor %g5, %l7, %g1 750289848Sjkim add %l7, 1, %l7 751289848Sjkim movxtod %g1, %f6 752289848Sjkim srl %l7, 0, %l7 ! clruw 753289848Sjkim prefetch [$out + 63], 22 754289848Sjkim prefetch [$inp + 32+63], 20 755289848Sjkim___ 756289848Sjkim$::code.=<<___ if ($alg eq "aes"); 757289848Sjkim aes_eround01 %f16, %f14, %f2, %f8 758289848Sjkim aes_eround23 %f18, %f14, %f2, %f2 759289848Sjkim aes_eround01 %f16, %f14, %f6, %f10 760289848Sjkim aes_eround23 %f18, %f14, %f6, %f6 761289848Sjkim___ 762289848Sjkim$::code.=<<___ if ($alg eq "cmll"); 763289848Sjkim camellia_f %f16, %f2, %f14, %f2 764289848Sjkim camellia_f %f16, %f6, %f14, %f6 765289848Sjkim camellia_f %f18, %f14, %f2, %f0 766289848Sjkim camellia_f %f18, %f14, %f6, %f4 767289848Sjkim___ 768289848Sjkim$::code.=<<___; 769289848Sjkim call _${alg}${bits}_encrypt_2x+16 770289848Sjkim add $inp, 32, $inp 771289848Sjkim 772289848Sjkim movxtod %o0, %f8 773289848Sjkim movxtod %o1, %f10 774289848Sjkim movxtod %o2, %f12 775289848Sjkim fxor %f8, %f0, %f0 ! ^= inp 776289848Sjkim movxtod %o3, %f8 777289848Sjkim fxor %f10, %f2, %f2 778289848Sjkim fxor %f12, %f4, %f4 779289848Sjkim fxor %f8, %f6, %f6 780289848Sjkim 781289848Sjkim brnz,pn $ooff, 2f 782289848Sjkim sub $len, 2, $len 783289848Sjkim 784289848Sjkim std %f0, [$out + 0] 785289848Sjkim std %f2, [$out + 8] 786289848Sjkim std %f4, [$out + 16] 787289848Sjkim std %f6, [$out + 24] 788289848Sjkim brnz,pt $len, .L${bits}_ctr32_loop2x 789289848Sjkim add $out, 32, $out 790289848Sjkim 791289848Sjkim ret 792289848Sjkim restore 793289848Sjkim 794289848Sjkim.align 16 795289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 796289848Sjkim ! and ~3x deterioration 797289848Sjkim ! in inp==out case 798289848Sjkim faligndata %f0, %f0, %f8 ! handle unaligned output 799289848Sjkim faligndata %f0, %f2, %f0 800289848Sjkim faligndata %f2, %f4, %f2 801289848Sjkim faligndata %f4, %f6, %f4 802289848Sjkim faligndata %f6, %f6, %f6 803289848Sjkim 804289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 805289848Sjkim std %f0, [$out + 8] 806289848Sjkim std %f2, [$out + 16] 807289848Sjkim std %f4, [$out + 24] 808289848Sjkim add $out, 32, $out 809289848Sjkim orn %g0, $omask, $omask 810289848Sjkim stda %f6, [$out + $omask]0xc0 ! partial store 811289848Sjkim 812289848Sjkim brnz,pt $len, .L${bits}_ctr32_loop2x+4 813289848Sjkim orn %g0, $omask, $omask 814289848Sjkim 815289848Sjkim ret 816289848Sjkim restore 817289848Sjkim 818289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 819289848Sjkim.align 32 820289848Sjkim.L${bits}_ctr32_blk: 821289848Sjkim add $out, $len, $blk_init 822289848Sjkim and $blk_init, 63, $blk_init ! tail 823289848Sjkim sub $len, $blk_init, $len 824289848Sjkim add $blk_init, 15, $blk_init ! round up to 16n 825289848Sjkim srlx $len, 4, $len 826289848Sjkim srl $blk_init, 4, $blk_init 827289848Sjkim sub $len, 1, $len 828289848Sjkim add $blk_init, 1, $blk_init 829289848Sjkim 830289848Sjkim.L${bits}_ctr32_blk_loop2x: 831289848Sjkim ldx [$inp + 0], %o0 832289848Sjkim ldx [$inp + 8], %o1 833289848Sjkim ldx [$inp + 16], %o2 834289848Sjkim brz,pt $ileft, 5f 835289848Sjkim ldx [$inp + 24], %o3 836289848Sjkim 837289848Sjkim ldx [$inp + 32], %o4 838289848Sjkim sllx %o0, $ileft, %o0 839289848Sjkim srlx %o1, $iright, %g1 840289848Sjkim or %g1, %o0, %o0 841289848Sjkim sllx %o1, $ileft, %o1 842289848Sjkim srlx %o2, $iright, %g1 843289848Sjkim or %g1, %o1, %o1 844289848Sjkim sllx %o2, $ileft, %o2 845289848Sjkim srlx %o3, $iright, %g1 846289848Sjkim or %g1, %o2, %o2 847289848Sjkim sllx %o3, $ileft, %o3 848289848Sjkim srlx %o4, $iright, %o4 849289848Sjkim or %o4, %o3, %o3 850289848Sjkim5: 851289848Sjkim xor %g5, %l7, %g1 ! ^= rk[0] 852289848Sjkim add %l7, 1, %l7 853289848Sjkim movxtod %g1, %f2 854289848Sjkim srl %l7, 0, %l7 ! clruw 855289848Sjkim xor %g5, %l7, %g1 856289848Sjkim add %l7, 1, %l7 857289848Sjkim movxtod %g1, %f6 858289848Sjkim srl %l7, 0, %l7 ! clruw 859289848Sjkim prefetch [$inp + 32+63], 20 860289848Sjkim___ 861289848Sjkim$::code.=<<___ if ($alg eq "aes"); 862289848Sjkim aes_eround01 %f16, %f14, %f2, %f8 863289848Sjkim aes_eround23 %f18, %f14, %f2, %f2 864289848Sjkim aes_eround01 %f16, %f14, %f6, %f10 865289848Sjkim aes_eround23 %f18, %f14, %f6, %f6 866289848Sjkim___ 867289848Sjkim$::code.=<<___ if ($alg eq "cmll"); 868289848Sjkim camellia_f %f16, %f2, %f14, %f2 869289848Sjkim camellia_f %f16, %f6, %f14, %f6 870289848Sjkim camellia_f %f18, %f14, %f2, %f0 871289848Sjkim camellia_f %f18, %f14, %f6, %f4 872289848Sjkim___ 873289848Sjkim$::code.=<<___; 874289848Sjkim call _${alg}${bits}_encrypt_2x+16 875289848Sjkim add $inp, 32, $inp 876289848Sjkim subcc $len, 2, $len 877289848Sjkim 878289848Sjkim movxtod %o0, %f8 879289848Sjkim movxtod %o1, %f10 880289848Sjkim movxtod %o2, %f12 881289848Sjkim fxor %f8, %f0, %f0 ! ^= inp 882289848Sjkim movxtod %o3, %f8 883289848Sjkim fxor %f10, %f2, %f2 884289848Sjkim fxor %f12, %f4, %f4 885289848Sjkim fxor %f8, %f6, %f6 886289848Sjkim 887289848Sjkim stda %f0, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 888289848Sjkim add $out, 8, $out 889289848Sjkim stda %f2, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 890289848Sjkim add $out, 8, $out 891289848Sjkim stda %f4, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 892289848Sjkim add $out, 8, $out 893289848Sjkim stda %f6, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 894289848Sjkim bgu,pt $::size_t_cc, .L${bits}_ctr32_blk_loop2x 895289848Sjkim add $out, 8, $out 896289848Sjkim 897289848Sjkim add $blk_init, $len, $len 898289848Sjkim andcc $len, 1, %g0 ! is number of blocks even? 899289848Sjkim membar #StoreLoad|#StoreStore 900289848Sjkim bnz,pt %icc, .L${bits}_ctr32_loop 901289848Sjkim srl $len, 0, $len 902289848Sjkim brnz,pn $len, .L${bits}_ctr32_loop2x 903289848Sjkim nop 904289848Sjkim 905289848Sjkim ret 906289848Sjkim restore 907289848Sjkim.type ${alg}${bits}_t4_ctr32_encrypt,#function 908289848Sjkim.size ${alg}${bits}_t4_ctr32_encrypt,.-${alg}${bits}_t4_ctr32_encrypt 909289848Sjkim___ 910289848Sjkim} 911289848Sjkim 912289848Sjkimsub alg_xts_implement { 913289848Sjkimmy ($alg,$bits,$dir) = @_; 914289848Sjkimmy ($inp,$out,$len,$key1,$key2,$ivec)=map("%i$_",(0..5)); 915289848Sjkimmy $rem=$ivec; 916289848Sjkim 917289848Sjkim$::code.=<<___; 918289848Sjkim.globl ${alg}${bits}_t4_xts_${dir}crypt 919289848Sjkim.align 32 920289848Sjkim${alg}${bits}_t4_xts_${dir}crypt: 921289848Sjkim save %sp, -$::frame-16, %sp 922306195Sjkim srln $len, 0, $len ! needed on v8+, "nop" on v9 923289848Sjkim 924289848Sjkim mov $ivec, %o0 925289848Sjkim add %fp, $::bias-16, %o1 926289848Sjkim call ${alg}_t4_encrypt 927289848Sjkim mov $key2, %o2 928289848Sjkim 929289848Sjkim add %fp, $::bias-16, %l7 930289848Sjkim ldxa [%l7]0x88, %g2 931289848Sjkim add %fp, $::bias-8, %l7 932289848Sjkim ldxa [%l7]0x88, %g3 ! %g3:%g2 is tweak 933289848Sjkim 934289848Sjkim sethi %hi(0x76543210), %l7 935289848Sjkim or %l7, %lo(0x76543210), %l7 936289848Sjkim bmask %l7, %g0, %g0 ! byte swap mask 937289848Sjkim 938289848Sjkim prefetch [$inp], 20 939289848Sjkim prefetch [$inp + 63], 20 940289848Sjkim call _${alg}${bits}_load_${dir}ckey 941289848Sjkim and $len, 15, $rem 942289848Sjkim and $len, -16, $len 943289848Sjkim___ 944289848Sjkim$code.=<<___ if ($dir eq "de"); 945289848Sjkim mov 0, %l7 946289848Sjkim movrnz $rem, 16, %l7 947289848Sjkim sub $len, %l7, $len 948289848Sjkim___ 949289848Sjkim$code.=<<___; 950289848Sjkim 951289848Sjkim sub $inp, $out, $blk_init ! $inp!=$out 952289848Sjkim and $inp, 7, $ileft 953289848Sjkim andn $inp, 7, $inp 954289848Sjkim sll $ileft, 3, $ileft 955289848Sjkim mov 64, $iright 956289848Sjkim mov 0xff, $omask 957289848Sjkim sub $iright, $ileft, $iright 958289848Sjkim and $out, 7, $ooff 959289848Sjkim cmp $len, 255 960289848Sjkim movrnz $ooff, 0, $blk_init ! if ( $out&7 || 961289848Sjkim movleu $::size_t_cc, 0, $blk_init ! $len<256 || 962289848Sjkim brnz,pn $blk_init, .L${bits}_xts_${dir}blk ! $inp==$out) 963289848Sjkim srl $omask, $ooff, $omask 964289848Sjkim 965289848Sjkim andcc $len, 16, %g0 ! is number of blocks even? 966289848Sjkim___ 967289848Sjkim$code.=<<___ if ($dir eq "de"); 968289848Sjkim brz,pn $len, .L${bits}_xts_${dir}steal 969289848Sjkim___ 970289848Sjkim$code.=<<___; 971289848Sjkim alignaddrl $out, %g0, $out 972289848Sjkim bz %icc, .L${bits}_xts_${dir}loop2x 973289848Sjkim srlx $len, 4, $len 974289848Sjkim.L${bits}_xts_${dir}loop: 975289848Sjkim ldx [$inp + 0], %o0 976289848Sjkim brz,pt $ileft, 4f 977289848Sjkim ldx [$inp + 8], %o1 978289848Sjkim 979289848Sjkim ldx [$inp + 16], %o2 980289848Sjkim sllx %o0, $ileft, %o0 981289848Sjkim srlx %o1, $iright, %g1 982289848Sjkim sllx %o1, $ileft, %o1 983289848Sjkim or %g1, %o0, %o0 984289848Sjkim srlx %o2, $iright, %o2 985289848Sjkim or %o2, %o1, %o1 986289848Sjkim4: 987289848Sjkim movxtod %g2, %f12 988289848Sjkim movxtod %g3, %f14 989289848Sjkim bshuffle %f12, %f12, %f12 990289848Sjkim bshuffle %f14, %f14, %f14 991289848Sjkim 992289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 993289848Sjkim xor %g5, %o1, %o1 994289848Sjkim movxtod %o0, %f0 995289848Sjkim movxtod %o1, %f2 996289848Sjkim 997289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 998289848Sjkim fxor %f14, %f2, %f2 999289848Sjkim 1000289848Sjkim prefetch [$out + 63], 22 1001289848Sjkim prefetch [$inp + 16+63], 20 1002289848Sjkim call _${alg}${bits}_${dir}crypt_1x 1003289848Sjkim add $inp, 16, $inp 1004289848Sjkim 1005289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1006289848Sjkim fxor %f14, %f2, %f2 1007289848Sjkim 1008289848Sjkim srax %g3, 63, %l7 ! next tweak value 1009289848Sjkim addcc %g2, %g2, %g2 1010289848Sjkim and %l7, 0x87, %l7 1011289848Sjkim addxc %g3, %g3, %g3 1012289848Sjkim xor %l7, %g2, %g2 1013289848Sjkim 1014289848Sjkim brnz,pn $ooff, 2f 1015289848Sjkim sub $len, 1, $len 1016289848Sjkim 1017289848Sjkim std %f0, [$out + 0] 1018289848Sjkim std %f2, [$out + 8] 1019289848Sjkim brnz,pt $len, .L${bits}_xts_${dir}loop2x 1020289848Sjkim add $out, 16, $out 1021289848Sjkim 1022289848Sjkim brnz,pn $rem, .L${bits}_xts_${dir}steal 1023289848Sjkim nop 1024289848Sjkim 1025289848Sjkim ret 1026289848Sjkim restore 1027289848Sjkim 1028289848Sjkim.align 16 1029289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 1030289848Sjkim ! and ~3x deterioration 1031289848Sjkim ! in inp==out case 1032289848Sjkim faligndata %f0, %f0, %f4 ! handle unaligned output 1033289848Sjkim faligndata %f0, %f2, %f6 1034289848Sjkim faligndata %f2, %f2, %f8 1035289848Sjkim stda %f4, [$out + $omask]0xc0 ! partial store 1036289848Sjkim std %f6, [$out + 8] 1037289848Sjkim add $out, 16, $out 1038289848Sjkim orn %g0, $omask, $omask 1039289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 1040289848Sjkim 1041289848Sjkim brnz,pt $len, .L${bits}_xts_${dir}loop2x+4 1042289848Sjkim orn %g0, $omask, $omask 1043289848Sjkim 1044289848Sjkim brnz,pn $rem, .L${bits}_xts_${dir}steal 1045289848Sjkim nop 1046289848Sjkim 1047289848Sjkim ret 1048289848Sjkim restore 1049289848Sjkim 1050289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1051289848Sjkim.align 32 1052289848Sjkim.L${bits}_xts_${dir}loop2x: 1053289848Sjkim ldx [$inp + 0], %o0 1054289848Sjkim ldx [$inp + 8], %o1 1055289848Sjkim ldx [$inp + 16], %o2 1056289848Sjkim brz,pt $ileft, 4f 1057289848Sjkim ldx [$inp + 24], %o3 1058289848Sjkim 1059289848Sjkim ldx [$inp + 32], %o4 1060289848Sjkim sllx %o0, $ileft, %o0 1061289848Sjkim srlx %o1, $iright, %g1 1062289848Sjkim or %g1, %o0, %o0 1063289848Sjkim sllx %o1, $ileft, %o1 1064289848Sjkim srlx %o2, $iright, %g1 1065289848Sjkim or %g1, %o1, %o1 1066289848Sjkim sllx %o2, $ileft, %o2 1067289848Sjkim srlx %o3, $iright, %g1 1068289848Sjkim or %g1, %o2, %o2 1069289848Sjkim sllx %o3, $ileft, %o3 1070289848Sjkim srlx %o4, $iright, %o4 1071289848Sjkim or %o4, %o3, %o3 1072289848Sjkim4: 1073289848Sjkim movxtod %g2, %f12 1074289848Sjkim movxtod %g3, %f14 1075289848Sjkim bshuffle %f12, %f12, %f12 1076289848Sjkim bshuffle %f14, %f14, %f14 1077289848Sjkim 1078289848Sjkim srax %g3, 63, %l7 ! next tweak value 1079289848Sjkim addcc %g2, %g2, %g2 1080289848Sjkim and %l7, 0x87, %l7 1081289848Sjkim addxc %g3, %g3, %g3 1082289848Sjkim xor %l7, %g2, %g2 1083289848Sjkim 1084289848Sjkim movxtod %g2, %f8 1085289848Sjkim movxtod %g3, %f10 1086289848Sjkim bshuffle %f8, %f8, %f8 1087289848Sjkim bshuffle %f10, %f10, %f10 1088289848Sjkim 1089289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 1090289848Sjkim xor %g5, %o1, %o1 1091289848Sjkim xor %g4, %o2, %o2 ! ^= rk[0] 1092289848Sjkim xor %g5, %o3, %o3 1093289848Sjkim movxtod %o0, %f0 1094289848Sjkim movxtod %o1, %f2 1095289848Sjkim movxtod %o2, %f4 1096289848Sjkim movxtod %o3, %f6 1097289848Sjkim 1098289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1099289848Sjkim fxor %f14, %f2, %f2 1100289848Sjkim fxor %f8, %f4, %f4 ! ^= tweak[0] 1101289848Sjkim fxor %f10, %f6, %f6 1102289848Sjkim 1103289848Sjkim prefetch [$out + 63], 22 1104289848Sjkim prefetch [$inp + 32+63], 20 1105289848Sjkim call _${alg}${bits}_${dir}crypt_2x 1106289848Sjkim add $inp, 32, $inp 1107289848Sjkim 1108289848Sjkim movxtod %g2, %f8 1109289848Sjkim movxtod %g3, %f10 1110289848Sjkim 1111289848Sjkim srax %g3, 63, %l7 ! next tweak value 1112289848Sjkim addcc %g2, %g2, %g2 1113289848Sjkim and %l7, 0x87, %l7 1114289848Sjkim addxc %g3, %g3, %g3 1115289848Sjkim xor %l7, %g2, %g2 1116289848Sjkim 1117289848Sjkim bshuffle %f8, %f8, %f8 1118289848Sjkim bshuffle %f10, %f10, %f10 1119289848Sjkim 1120289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1121289848Sjkim fxor %f14, %f2, %f2 1122289848Sjkim fxor %f8, %f4, %f4 1123289848Sjkim fxor %f10, %f6, %f6 1124289848Sjkim 1125289848Sjkim brnz,pn $ooff, 2f 1126289848Sjkim sub $len, 2, $len 1127289848Sjkim 1128289848Sjkim std %f0, [$out + 0] 1129289848Sjkim std %f2, [$out + 8] 1130289848Sjkim std %f4, [$out + 16] 1131289848Sjkim std %f6, [$out + 24] 1132289848Sjkim brnz,pt $len, .L${bits}_xts_${dir}loop2x 1133289848Sjkim add $out, 32, $out 1134289848Sjkim 1135289848Sjkim fsrc2 %f4, %f0 1136289848Sjkim fsrc2 %f6, %f2 1137289848Sjkim brnz,pn $rem, .L${bits}_xts_${dir}steal 1138289848Sjkim nop 1139289848Sjkim 1140289848Sjkim ret 1141289848Sjkim restore 1142289848Sjkim 1143289848Sjkim.align 16 1144289848Sjkim2: ldxa [$inp]0x82, %o0 ! avoid read-after-write hazard 1145289848Sjkim ! and ~3x deterioration 1146289848Sjkim ! in inp==out case 1147289848Sjkim faligndata %f0, %f0, %f8 ! handle unaligned output 1148289848Sjkim faligndata %f0, %f2, %f10 1149289848Sjkim faligndata %f2, %f4, %f12 1150289848Sjkim faligndata %f4, %f6, %f14 1151289848Sjkim faligndata %f6, %f6, %f0 1152289848Sjkim 1153289848Sjkim stda %f8, [$out + $omask]0xc0 ! partial store 1154289848Sjkim std %f10, [$out + 8] 1155289848Sjkim std %f12, [$out + 16] 1156289848Sjkim std %f14, [$out + 24] 1157289848Sjkim add $out, 32, $out 1158289848Sjkim orn %g0, $omask, $omask 1159289848Sjkim stda %f0, [$out + $omask]0xc0 ! partial store 1160289848Sjkim 1161289848Sjkim brnz,pt $len, .L${bits}_xts_${dir}loop2x+4 1162289848Sjkim orn %g0, $omask, $omask 1163289848Sjkim 1164289848Sjkim fsrc2 %f4, %f0 1165289848Sjkim fsrc2 %f6, %f2 1166289848Sjkim brnz,pn $rem, .L${bits}_xts_${dir}steal 1167289848Sjkim nop 1168289848Sjkim 1169289848Sjkim ret 1170289848Sjkim restore 1171289848Sjkim 1172289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1173289848Sjkim.align 32 1174289848Sjkim.L${bits}_xts_${dir}blk: 1175289848Sjkim add $out, $len, $blk_init 1176289848Sjkim and $blk_init, 63, $blk_init ! tail 1177289848Sjkim sub $len, $blk_init, $len 1178289848Sjkim add $blk_init, 15, $blk_init ! round up to 16n 1179289848Sjkim srlx $len, 4, $len 1180289848Sjkim srl $blk_init, 4, $blk_init 1181289848Sjkim sub $len, 1, $len 1182289848Sjkim add $blk_init, 1, $blk_init 1183289848Sjkim 1184289848Sjkim.L${bits}_xts_${dir}blk2x: 1185289848Sjkim ldx [$inp + 0], %o0 1186289848Sjkim ldx [$inp + 8], %o1 1187289848Sjkim ldx [$inp + 16], %o2 1188289848Sjkim brz,pt $ileft, 5f 1189289848Sjkim ldx [$inp + 24], %o3 1190289848Sjkim 1191289848Sjkim ldx [$inp + 32], %o4 1192289848Sjkim sllx %o0, $ileft, %o0 1193289848Sjkim srlx %o1, $iright, %g1 1194289848Sjkim or %g1, %o0, %o0 1195289848Sjkim sllx %o1, $ileft, %o1 1196289848Sjkim srlx %o2, $iright, %g1 1197289848Sjkim or %g1, %o1, %o1 1198289848Sjkim sllx %o2, $ileft, %o2 1199289848Sjkim srlx %o3, $iright, %g1 1200289848Sjkim or %g1, %o2, %o2 1201289848Sjkim sllx %o3, $ileft, %o3 1202289848Sjkim srlx %o4, $iright, %o4 1203289848Sjkim or %o4, %o3, %o3 1204289848Sjkim5: 1205289848Sjkim movxtod %g2, %f12 1206289848Sjkim movxtod %g3, %f14 1207289848Sjkim bshuffle %f12, %f12, %f12 1208289848Sjkim bshuffle %f14, %f14, %f14 1209289848Sjkim 1210289848Sjkim srax %g3, 63, %l7 ! next tweak value 1211289848Sjkim addcc %g2, %g2, %g2 1212289848Sjkim and %l7, 0x87, %l7 1213289848Sjkim addxc %g3, %g3, %g3 1214289848Sjkim xor %l7, %g2, %g2 1215289848Sjkim 1216289848Sjkim movxtod %g2, %f8 1217289848Sjkim movxtod %g3, %f10 1218289848Sjkim bshuffle %f8, %f8, %f8 1219289848Sjkim bshuffle %f10, %f10, %f10 1220289848Sjkim 1221289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 1222289848Sjkim xor %g5, %o1, %o1 1223289848Sjkim xor %g4, %o2, %o2 ! ^= rk[0] 1224289848Sjkim xor %g5, %o3, %o3 1225289848Sjkim movxtod %o0, %f0 1226289848Sjkim movxtod %o1, %f2 1227289848Sjkim movxtod %o2, %f4 1228289848Sjkim movxtod %o3, %f6 1229289848Sjkim 1230289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1231289848Sjkim fxor %f14, %f2, %f2 1232289848Sjkim fxor %f8, %f4, %f4 ! ^= tweak[0] 1233289848Sjkim fxor %f10, %f6, %f6 1234289848Sjkim 1235289848Sjkim prefetch [$inp + 32+63], 20 1236289848Sjkim call _${alg}${bits}_${dir}crypt_2x 1237289848Sjkim add $inp, 32, $inp 1238289848Sjkim 1239289848Sjkim movxtod %g2, %f8 1240289848Sjkim movxtod %g3, %f10 1241289848Sjkim 1242289848Sjkim srax %g3, 63, %l7 ! next tweak value 1243289848Sjkim addcc %g2, %g2, %g2 1244289848Sjkim and %l7, 0x87, %l7 1245289848Sjkim addxc %g3, %g3, %g3 1246289848Sjkim xor %l7, %g2, %g2 1247289848Sjkim 1248289848Sjkim bshuffle %f8, %f8, %f8 1249289848Sjkim bshuffle %f10, %f10, %f10 1250289848Sjkim 1251289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1252289848Sjkim fxor %f14, %f2, %f2 1253289848Sjkim fxor %f8, %f4, %f4 1254289848Sjkim fxor %f10, %f6, %f6 1255289848Sjkim 1256289848Sjkim subcc $len, 2, $len 1257289848Sjkim stda %f0, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 1258289848Sjkim add $out, 8, $out 1259289848Sjkim stda %f2, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 1260289848Sjkim add $out, 8, $out 1261289848Sjkim stda %f4, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 1262289848Sjkim add $out, 8, $out 1263289848Sjkim stda %f6, [$out]0xe2 ! ASI_BLK_INIT, T4-specific 1264289848Sjkim bgu,pt $::size_t_cc, .L${bits}_xts_${dir}blk2x 1265289848Sjkim add $out, 8, $out 1266289848Sjkim 1267289848Sjkim add $blk_init, $len, $len 1268289848Sjkim andcc $len, 1, %g0 ! is number of blocks even? 1269289848Sjkim membar #StoreLoad|#StoreStore 1270289848Sjkim bnz,pt %icc, .L${bits}_xts_${dir}loop 1271289848Sjkim srl $len, 0, $len 1272289848Sjkim brnz,pn $len, .L${bits}_xts_${dir}loop2x 1273289848Sjkim nop 1274289848Sjkim 1275289848Sjkim fsrc2 %f4, %f0 1276289848Sjkim fsrc2 %f6, %f2 1277289848Sjkim brnz,pn $rem, .L${bits}_xts_${dir}steal 1278289848Sjkim nop 1279289848Sjkim 1280289848Sjkim ret 1281289848Sjkim restore 1282289848Sjkim!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1283289848Sjkim___ 1284289848Sjkim$code.=<<___ if ($dir eq "en"); 1285289848Sjkim.align 32 1286289848Sjkim.L${bits}_xts_${dir}steal: 1287289848Sjkim std %f0, [%fp + $::bias-16] ! copy of output 1288289848Sjkim std %f2, [%fp + $::bias-8] 1289289848Sjkim 1290289848Sjkim srl $ileft, 3, $ileft 1291289848Sjkim add %fp, $::bias-16, %l7 1292289848Sjkim add $inp, $ileft, $inp ! original $inp+$len&-15 1293289848Sjkim add $out, $ooff, $out ! original $out+$len&-15 1294289848Sjkim mov 0, $ileft 1295289848Sjkim nop ! align 1296289848Sjkim 1297289848Sjkim.L${bits}_xts_${dir}stealing: 1298289848Sjkim ldub [$inp + $ileft], %o0 1299289848Sjkim ldub [%l7 + $ileft], %o1 1300289848Sjkim dec $rem 1301289848Sjkim stb %o0, [%l7 + $ileft] 1302289848Sjkim stb %o1, [$out + $ileft] 1303289848Sjkim brnz $rem, .L${bits}_xts_${dir}stealing 1304289848Sjkim inc $ileft 1305289848Sjkim 1306289848Sjkim mov %l7, $inp 1307289848Sjkim sub $out, 16, $out 1308289848Sjkim mov 0, $ileft 1309289848Sjkim sub $out, $ooff, $out 1310289848Sjkim ba .L${bits}_xts_${dir}loop ! one more time 1311289848Sjkim mov 1, $len ! $rem is 0 1312289848Sjkim___ 1313289848Sjkim$code.=<<___ if ($dir eq "de"); 1314289848Sjkim.align 32 1315289848Sjkim.L${bits}_xts_${dir}steal: 1316289848Sjkim ldx [$inp + 0], %o0 1317289848Sjkim brz,pt $ileft, 8f 1318289848Sjkim ldx [$inp + 8], %o1 1319289848Sjkim 1320289848Sjkim ldx [$inp + 16], %o2 1321289848Sjkim sllx %o0, $ileft, %o0 1322289848Sjkim srlx %o1, $iright, %g1 1323289848Sjkim sllx %o1, $ileft, %o1 1324289848Sjkim or %g1, %o0, %o0 1325289848Sjkim srlx %o2, $iright, %o2 1326289848Sjkim or %o2, %o1, %o1 1327289848Sjkim8: 1328289848Sjkim srax %g3, 63, %l7 ! next tweak value 1329289848Sjkim addcc %g2, %g2, %o2 1330289848Sjkim and %l7, 0x87, %l7 1331289848Sjkim addxc %g3, %g3, %o3 1332289848Sjkim xor %l7, %o2, %o2 1333289848Sjkim 1334289848Sjkim movxtod %o2, %f12 1335289848Sjkim movxtod %o3, %f14 1336289848Sjkim bshuffle %f12, %f12, %f12 1337289848Sjkim bshuffle %f14, %f14, %f14 1338289848Sjkim 1339289848Sjkim xor %g4, %o0, %o0 ! ^= rk[0] 1340289848Sjkim xor %g5, %o1, %o1 1341289848Sjkim movxtod %o0, %f0 1342289848Sjkim movxtod %o1, %f2 1343289848Sjkim 1344289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1345289848Sjkim fxor %f14, %f2, %f2 1346289848Sjkim 1347289848Sjkim call _${alg}${bits}_${dir}crypt_1x 1348289848Sjkim add $inp, 16, $inp 1349289848Sjkim 1350289848Sjkim fxor %f12, %f0, %f0 ! ^= tweak[0] 1351289848Sjkim fxor %f14, %f2, %f2 1352289848Sjkim 1353289848Sjkim std %f0, [%fp + $::bias-16] 1354289848Sjkim std %f2, [%fp + $::bias-8] 1355289848Sjkim 1356289848Sjkim srl $ileft, 3, $ileft 1357289848Sjkim add %fp, $::bias-16, %l7 1358289848Sjkim add $inp, $ileft, $inp ! original $inp+$len&-15 1359289848Sjkim add $out, $ooff, $out ! original $out+$len&-15 1360289848Sjkim mov 0, $ileft 1361289848Sjkim add $out, 16, $out 1362289848Sjkim nop ! align 1363289848Sjkim 1364289848Sjkim.L${bits}_xts_${dir}stealing: 1365289848Sjkim ldub [$inp + $ileft], %o0 1366289848Sjkim ldub [%l7 + $ileft], %o1 1367289848Sjkim dec $rem 1368289848Sjkim stb %o0, [%l7 + $ileft] 1369289848Sjkim stb %o1, [$out + $ileft] 1370289848Sjkim brnz $rem, .L${bits}_xts_${dir}stealing 1371289848Sjkim inc $ileft 1372289848Sjkim 1373289848Sjkim mov %l7, $inp 1374289848Sjkim sub $out, 16, $out 1375289848Sjkim mov 0, $ileft 1376289848Sjkim sub $out, $ooff, $out 1377289848Sjkim ba .L${bits}_xts_${dir}loop ! one more time 1378289848Sjkim mov 1, $len ! $rem is 0 1379289848Sjkim___ 1380289848Sjkim$code.=<<___; 1381289848Sjkim ret 1382289848Sjkim restore 1383289848Sjkim.type ${alg}${bits}_t4_xts_${dir}crypt,#function 1384289848Sjkim.size ${alg}${bits}_t4_xts_${dir}crypt,.-${alg}${bits}_t4_xts_${dir}crypt 1385289848Sjkim___ 1386289848Sjkim} 1387289848Sjkim 1388289848Sjkim# Purpose of these subroutines is to explicitly encode VIS instructions, 1389289848Sjkim# so that one can compile the module without having to specify VIS 1390289848Sjkim# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a. 1391289848Sjkim# Idea is to reserve for option to produce "universal" binary and let 1392289848Sjkim# programmer detect if current CPU is VIS capable at run-time. 1393289848Sjkimsub unvis { 1394289848Sjkimmy ($mnemonic,$rs1,$rs2,$rd)=@_; 1395289848Sjkimmy ($ref,$opf); 1396289848Sjkimmy %visopf = ( "faligndata" => 0x048, 1397289848Sjkim "bshuffle" => 0x04c, 1398289848Sjkim "fnot2" => 0x066, 1399289848Sjkim "fxor" => 0x06c, 1400289848Sjkim "fsrc2" => 0x078 ); 1401289848Sjkim 1402289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rd"; 1403289848Sjkim 1404289848Sjkim if ($opf=$visopf{$mnemonic}) { 1405289848Sjkim foreach ($rs1,$rs2,$rd) { 1406289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1407289848Sjkim $_=$1; 1408289848Sjkim if ($1>=32) { 1409289848Sjkim return $ref if ($1&1); 1410289848Sjkim # re-encode for upper double register addressing 1411289848Sjkim $_=($1|$1>>5)&31; 1412289848Sjkim } 1413289848Sjkim } 1414289848Sjkim 1415289848Sjkim return sprintf ".word\t0x%08x !%s", 1416289848Sjkim 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2, 1417289848Sjkim $ref; 1418289848Sjkim } else { 1419289848Sjkim return $ref; 1420289848Sjkim } 1421289848Sjkim} 1422289848Sjkim 1423289848Sjkimsub unvis3 { 1424289848Sjkimmy ($mnemonic,$rs1,$rs2,$rd)=@_; 1425289848Sjkimmy %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 ); 1426289848Sjkimmy ($ref,$opf); 1427289848Sjkimmy %visopf = ( "addxc" => 0x011, 1428289848Sjkim "addxccc" => 0x013, 1429289848Sjkim "umulxhi" => 0x016, 1430289848Sjkim "alignaddr" => 0x018, 1431289848Sjkim "bmask" => 0x019, 1432289848Sjkim "alignaddrl" => 0x01a ); 1433289848Sjkim 1434289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rd"; 1435289848Sjkim 1436289848Sjkim if ($opf=$visopf{$mnemonic}) { 1437289848Sjkim foreach ($rs1,$rs2,$rd) { 1438289848Sjkim return $ref if (!/%([goli])([0-9])/); 1439289848Sjkim $_=$bias{$1}+$2; 1440289848Sjkim } 1441289848Sjkim 1442289848Sjkim return sprintf ".word\t0x%08x !%s", 1443289848Sjkim 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2, 1444289848Sjkim $ref; 1445289848Sjkim } else { 1446289848Sjkim return $ref; 1447289848Sjkim } 1448289848Sjkim} 1449289848Sjkim 1450289848Sjkimsub unaes_round { # 4-argument instructions 1451289848Sjkimmy ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_; 1452289848Sjkimmy ($ref,$opf); 1453289848Sjkimmy %aesopf = ( "aes_eround01" => 0, 1454289848Sjkim "aes_eround23" => 1, 1455289848Sjkim "aes_dround01" => 2, 1456289848Sjkim "aes_dround23" => 3, 1457289848Sjkim "aes_eround01_l"=> 4, 1458289848Sjkim "aes_eround23_l"=> 5, 1459289848Sjkim "aes_dround01_l"=> 6, 1460289848Sjkim "aes_dround23_l"=> 7, 1461289848Sjkim "aes_kexpand1" => 8 ); 1462289848Sjkim 1463289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd"; 1464289848Sjkim 1465289848Sjkim if (defined($opf=$aesopf{$mnemonic})) { 1466289848Sjkim $rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3; 1467289848Sjkim foreach ($rs1,$rs2,$rd) { 1468289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1469289848Sjkim $_=$1; 1470289848Sjkim if ($1>=32) { 1471289848Sjkim return $ref if ($1&1); 1472289848Sjkim # re-encode for upper double register addressing 1473289848Sjkim $_=($1|$1>>5)&31; 1474289848Sjkim } 1475289848Sjkim } 1476289848Sjkim 1477289848Sjkim return sprintf ".word\t0x%08x !%s", 1478289848Sjkim 2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|$opf<<5|$rs2, 1479289848Sjkim $ref; 1480289848Sjkim } else { 1481289848Sjkim return $ref; 1482289848Sjkim } 1483289848Sjkim} 1484289848Sjkim 1485289848Sjkimsub unaes_kexpand { # 3-argument instructions 1486289848Sjkimmy ($mnemonic,$rs1,$rs2,$rd)=@_; 1487289848Sjkimmy ($ref,$opf); 1488289848Sjkimmy %aesopf = ( "aes_kexpand0" => 0x130, 1489289848Sjkim "aes_kexpand2" => 0x131 ); 1490289848Sjkim 1491289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rd"; 1492289848Sjkim 1493289848Sjkim if (defined($opf=$aesopf{$mnemonic})) { 1494289848Sjkim foreach ($rs1,$rs2,$rd) { 1495289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1496289848Sjkim $_=$1; 1497289848Sjkim if ($1>=32) { 1498289848Sjkim return $ref if ($1&1); 1499289848Sjkim # re-encode for upper double register addressing 1500289848Sjkim $_=($1|$1>>5)&31; 1501289848Sjkim } 1502289848Sjkim } 1503289848Sjkim 1504289848Sjkim return sprintf ".word\t0x%08x !%s", 1505289848Sjkim 2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2, 1506289848Sjkim $ref; 1507289848Sjkim } else { 1508289848Sjkim return $ref; 1509289848Sjkim } 1510289848Sjkim} 1511289848Sjkim 1512289848Sjkimsub uncamellia_f { # 4-argument instructions 1513289848Sjkimmy ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_; 1514289848Sjkimmy ($ref,$opf); 1515289848Sjkim 1516289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd"; 1517289848Sjkim 1518289848Sjkim if (1) { 1519289848Sjkim $rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3; 1520289848Sjkim foreach ($rs1,$rs2,$rd) { 1521289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1522289848Sjkim $_=$1; 1523289848Sjkim if ($1>=32) { 1524289848Sjkim return $ref if ($1&1); 1525289848Sjkim # re-encode for upper double register addressing 1526289848Sjkim $_=($1|$1>>5)&31; 1527289848Sjkim } 1528289848Sjkim } 1529289848Sjkim 1530289848Sjkim return sprintf ".word\t0x%08x !%s", 1531289848Sjkim 2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|0xc<<5|$rs2, 1532289848Sjkim $ref; 1533289848Sjkim } else { 1534289848Sjkim return $ref; 1535289848Sjkim } 1536289848Sjkim} 1537289848Sjkim 1538289848Sjkimsub uncamellia3 { # 3-argument instructions 1539289848Sjkimmy ($mnemonic,$rs1,$rs2,$rd)=@_; 1540289848Sjkimmy ($ref,$opf); 1541289848Sjkimmy %cmllopf = ( "camellia_fl" => 0x13c, 1542289848Sjkim "camellia_fli" => 0x13d ); 1543289848Sjkim 1544289848Sjkim $ref = "$mnemonic\t$rs1,$rs2,$rd"; 1545289848Sjkim 1546289848Sjkim if (defined($opf=$cmllopf{$mnemonic})) { 1547289848Sjkim foreach ($rs1,$rs2,$rd) { 1548289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1549289848Sjkim $_=$1; 1550289848Sjkim if ($1>=32) { 1551289848Sjkim return $ref if ($1&1); 1552289848Sjkim # re-encode for upper double register addressing 1553289848Sjkim $_=($1|$1>>5)&31; 1554289848Sjkim } 1555289848Sjkim } 1556289848Sjkim 1557289848Sjkim return sprintf ".word\t0x%08x !%s", 1558289848Sjkim 2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2, 1559289848Sjkim $ref; 1560289848Sjkim } else { 1561289848Sjkim return $ref; 1562289848Sjkim } 1563289848Sjkim} 1564289848Sjkim 1565289848Sjkimsub unmovxtox { # 2-argument instructions 1566289848Sjkimmy ($mnemonic,$rs,$rd)=@_; 1567289848Sjkimmy %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24, "f" => 0 ); 1568289848Sjkimmy ($ref,$opf); 1569289848Sjkimmy %movxopf = ( "movdtox" => 0x110, 1570289848Sjkim "movstouw" => 0x111, 1571289848Sjkim "movstosw" => 0x113, 1572289848Sjkim "movxtod" => 0x118, 1573289848Sjkim "movwtos" => 0x119 ); 1574289848Sjkim 1575289848Sjkim $ref = "$mnemonic\t$rs,$rd"; 1576289848Sjkim 1577289848Sjkim if (defined($opf=$movxopf{$mnemonic})) { 1578289848Sjkim foreach ($rs,$rd) { 1579289848Sjkim return $ref if (!/%([fgoli])([0-9]{1,2})/); 1580289848Sjkim $_=$bias{$1}+$2; 1581289848Sjkim if ($2>=32) { 1582289848Sjkim return $ref if ($2&1); 1583289848Sjkim # re-encode for upper double register addressing 1584289848Sjkim $_=($2|$2>>5)&31; 1585289848Sjkim } 1586289848Sjkim } 1587289848Sjkim 1588289848Sjkim return sprintf ".word\t0x%08x !%s", 1589289848Sjkim 2<<30|$rd<<25|0x36<<19|$opf<<5|$rs, 1590289848Sjkim $ref; 1591289848Sjkim } else { 1592289848Sjkim return $ref; 1593289848Sjkim } 1594289848Sjkim} 1595289848Sjkim 1596289848Sjkimsub undes { 1597289848Sjkimmy ($mnemonic)=shift; 1598289848Sjkimmy @args=@_; 1599289848Sjkimmy ($ref,$opf); 1600289848Sjkimmy %desopf = ( "des_round" => 0b1001, 1601289848Sjkim "des_ip" => 0b100110100, 1602289848Sjkim "des_iip" => 0b100110101, 1603289848Sjkim "des_kexpand" => 0b100110110 ); 1604289848Sjkim 1605289848Sjkim $ref = "$mnemonic\t".join(",",@_); 1606289848Sjkim 1607289848Sjkim if (defined($opf=$desopf{$mnemonic})) { # 4-arg 1608289848Sjkim if ($mnemonic eq "des_round") { 1609289848Sjkim foreach (@args[0..3]) { 1610289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1611289848Sjkim $_=$1; 1612289848Sjkim if ($1>=32) { 1613289848Sjkim return $ref if ($1&1); 1614289848Sjkim # re-encode for upper double register addressing 1615289848Sjkim $_=($1|$1>>5)&31; 1616289848Sjkim } 1617289848Sjkim } 1618289848Sjkim return sprintf ".word\t0x%08x !%s", 1619289848Sjkim 2<<30|0b011001<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<9|$args[3]<<25, 1620289848Sjkim $ref; 1621289848Sjkim } elsif ($mnemonic eq "des_kexpand") { # 3-arg 1622289848Sjkim foreach (@args[0..2]) { 1623289848Sjkim return $ref if (!/(%f)?([0-9]{1,2})/); 1624289848Sjkim $_=$2; 1625289848Sjkim if ($2>=32) { 1626289848Sjkim return $ref if ($2&1); 1627289848Sjkim # re-encode for upper double register addressing 1628289848Sjkim $_=($2|$2>>5)&31; 1629289848Sjkim } 1630289848Sjkim } 1631289848Sjkim return sprintf ".word\t0x%08x !%s", 1632289848Sjkim 2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<25, 1633289848Sjkim $ref; 1634289848Sjkim } else { # 2-arg 1635289848Sjkim foreach (@args[0..1]) { 1636289848Sjkim return $ref if (!/%f([0-9]{1,2})/); 1637289848Sjkim $_=$1; 1638289848Sjkim if ($1>=32) { 1639289848Sjkim return $ref if ($2&1); 1640289848Sjkim # re-encode for upper double register addressing 1641289848Sjkim $_=($1|$1>>5)&31; 1642289848Sjkim } 1643289848Sjkim } 1644289848Sjkim return sprintf ".word\t0x%08x !%s", 1645289848Sjkim 2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]<<25, 1646289848Sjkim $ref; 1647289848Sjkim } 1648289848Sjkim } else { 1649289848Sjkim return $ref; 1650289848Sjkim } 1651289848Sjkim} 1652289848Sjkim 1653289848Sjkimsub emit_assembler { 1654289848Sjkim foreach (split("\n",$::code)) { 1655289848Sjkim s/\`([^\`]*)\`/eval $1/ge; 1656289848Sjkim 1657289848Sjkim s/\b(f[a-z]+2[sd]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})\s*$/$1\t%f0,$2,$3/go; 1658289848Sjkim 1659289848Sjkim s/\b(aes_[edk][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/ 1660289848Sjkim &unaes_round($1,$2,$3,$4,$5) 1661289848Sjkim /geo or 1662289848Sjkim s/\b(aes_kexpand[02])\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/ 1663289848Sjkim &unaes_kexpand($1,$2,$3,$4) 1664289848Sjkim /geo or 1665289848Sjkim s/\b(camellia_f)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/ 1666289848Sjkim &uncamellia_f($1,$2,$3,$4,$5) 1667289848Sjkim /geo or 1668289848Sjkim s/\b(camellia_[^s]+)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/ 1669289848Sjkim &uncamellia3($1,$2,$3,$4) 1670289848Sjkim /geo or 1671289848Sjkim s/\b(des_\w+)\s+(%f[0-9]{1,2}),\s*([%fx0-9]+)(?:,\s*(%f[0-9]{1,2})(?:,\s*(%f[0-9]{1,2}))?)?/ 1672289848Sjkim &undes($1,$2,$3,$4,$5) 1673289848Sjkim /geo or 1674289848Sjkim s/\b(mov[ds]to\w+)\s+(%f[0-9]{1,2}),\s*(%[goli][0-7])/ 1675289848Sjkim &unmovxtox($1,$2,$3) 1676289848Sjkim /geo or 1677289848Sjkim s/\b(mov[xw]to[ds])\s+(%[goli][0-7]),\s*(%f[0-9]{1,2})/ 1678289848Sjkim &unmovxtox($1,$2,$3) 1679289848Sjkim /geo or 1680289848Sjkim s/\b([fb][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/ 1681289848Sjkim &unvis($1,$2,$3,$4) 1682289848Sjkim /geo or 1683289848Sjkim s/\b(umulxhi|bmask|addxc[c]{0,2}|alignaddr[l]*)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/ 1684289848Sjkim &unvis3($1,$2,$3,$4) 1685289848Sjkim /geo; 1686289848Sjkim 1687289848Sjkim print $_,"\n"; 1688289848Sjkim } 1689289848Sjkim} 1690289848Sjkim 1691289848Sjkim1; 1692