Clean up references to FIPS
[openssl.git] / crypto / aes / asm / aes-mips.pl
index 8431f9fcfb12c50c8f00bb65704116b27c27addd..ba3e4545dffebe44da5f02479f2153b9d166b057 100644 (file)
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
 
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
 # thing about this module is its endian neutrality, which means that
 # it processes data without ever changing byte order...
 
+# September 2012
+#
+# Add MIPS32R2 (~10% less instructions) and SmartMIPS ASE (further
+# ~25% less instructions) code. Note that there is no run-time switch,
+# instead, code path is chosen upon pre-process time, pass -mips32r2
+# or/and -msmartmips.
+
 ######################################################################
 # There is a number of MIPS ABI in use, O32 and N32/64 are most
 # widely used. Then there is a new contender: NUBI. It appears that if
 # ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23));
 # ($gp,$sp,$fp,$ra)=map("\$$_",(28..31));
 #
-$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64
+$flavour = shift || "o32"; # supported flavours are o32,n32,64,nubi32,nubi64
 
 if ($flavour =~ /64|n32/i) {
-       $PTR_ADD="dadd";        # incidentally works even on n32
-       $PTR_SUB="dsub";        # incidentally works even on n32
+       $PTR_LA="dla";
+       $PTR_ADD="daddu";       # incidentally works even on n32
+       $PTR_SUB="dsubu";       # incidentally works even on n32
+       $PTR_INS="dins";
        $REG_S="sd";
        $REG_L="ld";
        $PTR_SLL="dsll";        # incidentally works even on n32
        $SZREG=8;
 } else {
-       $PTR_ADD="add";
-       $PTR_SUB="sub";
+       $PTR_LA="la";
+       $PTR_ADD="addu";
+       $PTR_SUB="subu";
+       $PTR_INS="ins";
        $REG_S="sw";
        $REG_L="lw";
        $PTR_SLL="sll";
@@ -70,29 +88,32 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
 #
 ######################################################################
 
-for (@ARGV) {  $big_endian=1 if (/\-DB_ENDIAN/);
-               $big_endian=0 if (/\-DL_ENDIAN/);
-               $output=$_ if (/^\w[\w\-]*\.\w+$/);     }
+$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
+
+for (@ARGV) {  $output=$_ if (/\w[\w\-]*\.\w+$/);      }
 open STDOUT,">$output";
 
 if (!defined($big_endian))
 {    $big_endian=(unpack('L',pack('N',1))==1);   }
 
-while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
+while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
 open STDOUT,">$output";
 
 my ($MSB,$LSB)=(0,3);  # automatically converted to little-endian
 
 $code.=<<___;
-.text
+#include "mips_arch.h"
 
+.text
+#if !defined(__mips_eabi) && (!defined(__vxworks) || defined(__pic__))
 .option        pic2
+#endif
 .set   noat
 ___
 \f
 {{{
 my $FRAMESIZE=16*$SZREG;
-my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000;
+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc0fff008" : "0xc0ff0000";
 
 my ($inp,$out,$key,$Tbl,$s0,$s1,$s2,$s3)=($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7);
 my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2);
@@ -119,7 +140,90 @@ _mips_AES_encrypt:
        xor     $s2,$t2
        xor     $s3,$t3
 
-       sub     $cnt,1
+       subu    $cnt,1
+#if defined(__mips_smartmips)
+       ext     $i0,$s1,16,8
+.Loop_enc:
+       ext     $i1,$s2,16,8
+       ext     $i2,$s3,16,8
+       ext     $i3,$s0,16,8
+       lwxs    $t0,$i0($Tbl)           # Te1[s1>>16]
+       ext     $i0,$s2,8,8
+       lwxs    $t1,$i1($Tbl)           # Te1[s2>>16]
+       ext     $i1,$s3,8,8
+       lwxs    $t2,$i2($Tbl)           # Te1[s3>>16]
+       ext     $i2,$s0,8,8
+       lwxs    $t3,$i3($Tbl)           # Te1[s0>>16]
+       ext     $i3,$s1,8,8
+
+       lwxs    $t4,$i0($Tbl)           # Te2[s2>>8]
+       ext     $i0,$s3,0,8
+       lwxs    $t5,$i1($Tbl)           # Te2[s3>>8]
+       ext     $i1,$s0,0,8
+       lwxs    $t6,$i2($Tbl)           # Te2[s0>>8]
+       ext     $i2,$s1,0,8
+       lwxs    $t7,$i3($Tbl)           # Te2[s1>>8]
+       ext     $i3,$s2,0,8
+
+       lwxs    $t8,$i0($Tbl)           # Te3[s3]
+       ext     $i0,$s0,24,8
+       lwxs    $t9,$i1($Tbl)           # Te3[s0]
+       ext     $i1,$s1,24,8
+       lwxs    $t10,$i2($Tbl)          # Te3[s1]
+       ext     $i2,$s2,24,8
+       lwxs    $t11,$i3($Tbl)          # Te3[s2]
+       ext     $i3,$s3,24,8
+
+       rotr    $t0,$t0,8
+       rotr    $t1,$t1,8
+       rotr    $t2,$t2,8
+       rotr    $t3,$t3,8
+
+       rotr    $t4,$t4,16
+       rotr    $t5,$t5,16
+       rotr    $t6,$t6,16
+       rotr    $t7,$t7,16
+
+       xor     $t0,$t4
+       lwxs    $t4,$i0($Tbl)           # Te0[s0>>24]
+       xor     $t1,$t5
+       lwxs    $t5,$i1($Tbl)           # Te0[s1>>24]
+       xor     $t2,$t6
+       lwxs    $t6,$i2($Tbl)           # Te0[s2>>24]
+       xor     $t3,$t7
+       lwxs    $t7,$i3($Tbl)           # Te0[s3>>24]
+
+       rotr    $t8,$t8,24
+       lw      $s0,0($key0)
+       rotr    $t9,$t9,24
+       lw      $s1,4($key0)
+       rotr    $t10,$t10,24
+       lw      $s2,8($key0)
+       rotr    $t11,$t11,24
+       lw      $s3,12($key0)
+
+       xor     $t0,$t8
+       xor     $t1,$t9
+       xor     $t2,$t10
+       xor     $t3,$t11
+
+       xor     $t0,$t4
+       xor     $t1,$t5
+       xor     $t2,$t6
+       xor     $t3,$t7
+
+       subu    $cnt,1
+       $PTR_ADD $key0,16
+       xor     $s0,$t0
+       xor     $s1,$t1
+       xor     $s2,$t2
+       xor     $s3,$t3
+       .set    noreorder
+       bnez    $cnt,.Loop_enc
+       ext     $i0,$s1,16,8
+
+       _xtr    $i0,$s1,16-2
+#else
        _xtr    $i0,$s1,16-2
 .Loop_enc:
        _xtr    $i1,$s2,16-2
@@ -133,19 +237,29 @@ _mips_AES_encrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+       lw      $t0,0($i0)              # Te1[s1>>16]
+       _xtr    $i0,$s2,8-2
+       lw      $t1,0($i1)              # Te1[s2>>16]
+       _xtr    $i1,$s3,8-2
+       lw      $t2,0($i2)              # Te1[s3>>16]
+       _xtr    $i2,$s0,8-2
+       lw      $t3,0($i3)              # Te1[s0>>16]
+       _xtr    $i3,$s1,8-2
+#else
        lwl     $t0,3($i0)              # Te1[s1>>16]
        lwl     $t1,3($i1)              # Te1[s2>>16]
        lwl     $t2,3($i2)              # Te1[s3>>16]
        lwl     $t3,3($i3)              # Te1[s0>>16]
        lwr     $t0,2($i0)              # Te1[s1>>16]
-       lwr     $t1,2($i1)              # Te1[s2>>16]
-       lwr     $t2,2($i2)              # Te1[s3>>16]
-       lwr     $t3,2($i3)              # Te1[s0>>16]
-
        _xtr    $i0,$s2,8-2
+       lwr     $t1,2($i1)              # Te1[s2>>16]
        _xtr    $i1,$s3,8-2
+       lwr     $t2,2($i2)              # Te1[s3>>16]
        _xtr    $i2,$s0,8-2
+       lwr     $t3,2($i3)              # Te1[s0>>16]
        _xtr    $i3,$s1,8-2
+#endif
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -154,19 +268,88 @@ _mips_AES_encrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+       rotr    $t0,$t0,8
+       rotr    $t1,$t1,8
+       rotr    $t2,$t2,8
+       rotr    $t3,$t3,8
+# if defined(_MIPSEL)
+       lw      $t4,0($i0)              # Te2[s2>>8]
+       _xtr    $i0,$s3,0-2
+       lw      $t5,0($i1)              # Te2[s3>>8]
+       _xtr    $i1,$s0,0-2
+       lw      $t6,0($i2)              # Te2[s0>>8]
+       _xtr    $i2,$s1,0-2
+       lw      $t7,0($i3)              # Te2[s1>>8]
+       _xtr    $i3,$s2,0-2
+
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+       lw      $t8,0($i0)              # Te3[s3]
+       $PTR_INS $i0,$s0,2,8
+       lw      $t9,0($i1)              # Te3[s0]
+       $PTR_INS $i1,$s1,2,8
+       lw      $t10,0($i2)             # Te3[s1]
+       $PTR_INS $i2,$s2,2,8
+       lw      $t11,0($i3)             # Te3[s2]
+       $PTR_INS $i3,$s3,2,8
+# else
+       lw      $t4,0($i0)              # Te2[s2>>8]
+       $PTR_INS $i0,$s3,2,8
+       lw      $t5,0($i1)              # Te2[s3>>8]
+       $PTR_INS $i1,$s0,2,8
+       lw      $t6,0($i2)              # Te2[s0>>8]
+       $PTR_INS $i2,$s1,2,8
+       lw      $t7,0($i3)              # Te2[s1>>8]
+       $PTR_INS $i3,$s2,2,8
+
+       lw      $t8,0($i0)              # Te3[s3]
+       _xtr    $i0,$s0,24-2
+       lw      $t9,0($i1)              # Te3[s0]
+       _xtr    $i1,$s1,24-2
+       lw      $t10,0($i2)             # Te3[s1]
+       _xtr    $i2,$s2,24-2
+       lw      $t11,0($i3)             # Te3[s2]
+       _xtr    $i3,$s3,24-2
+
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+# endif
+       rotr    $t4,$t4,16
+       rotr    $t5,$t5,16
+       rotr    $t6,$t6,16
+       rotr    $t7,$t7,16
+
+       rotr    $t8,$t8,24
+       rotr    $t9,$t9,24
+       rotr    $t10,$t10,24
+       rotr    $t11,$t11,24
+#else
        lwl     $t4,2($i0)              # Te2[s2>>8]
        lwl     $t5,2($i1)              # Te2[s3>>8]
        lwl     $t6,2($i2)              # Te2[s0>>8]
        lwl     $t7,2($i3)              # Te2[s1>>8]
        lwr     $t4,1($i0)              # Te2[s2>>8]
-       lwr     $t5,1($i1)              # Te2[s3>>8]
-       lwr     $t6,1($i2)              # Te2[s0>>8]
-       lwr     $t7,1($i3)              # Te2[s1>>8]
-
        _xtr    $i0,$s3,0-2
+       lwr     $t5,1($i1)              # Te2[s3>>8]
        _xtr    $i1,$s0,0-2
+       lwr     $t6,1($i2)              # Te2[s0>>8]
        _xtr    $i2,$s1,0-2
+       lwr     $t7,1($i3)              # Te2[s1>>8]
        _xtr    $i3,$s2,0-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -180,14 +363,14 @@ _mips_AES_encrypt:
        lwl     $t10,1($i2)             # Te3[s1]
        lwl     $t11,1($i3)             # Te3[s2]
        lwr     $t8,0($i0)              # Te3[s3]
-       lwr     $t9,0($i1)              # Te3[s0]
-       lwr     $t10,0($i2)             # Te3[s1]
-       lwr     $t11,0($i3)             # Te3[s2]
-
        _xtr    $i0,$s0,24-2
+       lwr     $t9,0($i1)              # Te3[s0]
        _xtr    $i1,$s1,24-2
+       lwr     $t10,0($i2)             # Te3[s1]
        _xtr    $i2,$s2,24-2
+       lwr     $t11,0($i3)             # Te3[s2]
        _xtr    $i3,$s3,24-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -196,31 +379,31 @@ _mips_AES_encrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#endif
        xor     $t0,$t4
-       xor     $t1,$t5
-       xor     $t2,$t6
-       xor     $t3,$t7
        lw      $t4,0($i0)              # Te0[s0>>24]
+       xor     $t1,$t5
        lw      $t5,0($i1)              # Te0[s1>>24]
+       xor     $t2,$t6
        lw      $t6,0($i2)              # Te0[s2>>24]
+       xor     $t3,$t7
        lw      $t7,0($i3)              # Te0[s3>>24]
 
-       lw      $s0,0($key0)
-       lw      $s1,4($key0)
-       lw      $s2,8($key0)
-       lw      $s3,12($key0)
-
        xor     $t0,$t8
+       lw      $s0,0($key0)
        xor     $t1,$t9
+       lw      $s1,4($key0)
        xor     $t2,$t10
+       lw      $s2,8($key0)
        xor     $t3,$t11
+       lw      $s3,12($key0)
 
        xor     $t0,$t4
        xor     $t1,$t5
        xor     $t2,$t6
        xor     $t3,$t7
 
-       sub     $cnt,1
+       subu    $cnt,1
        $PTR_ADD $key0,16
        xor     $s0,$t0
        xor     $s1,$t1
@@ -229,6 +412,7 @@ _mips_AES_encrypt:
        .set    noreorder
        bnez    $cnt,.Loop_enc
        _xtr    $i0,$s1,16-2
+#endif
 
        .set    reorder
        _xtr    $i1,$s2,16-2
@@ -243,14 +427,14 @@ _mips_AES_encrypt:
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
        lbu     $t0,2($i0)              # Te4[s1>>16]
-       lbu     $t1,2($i1)              # Te4[s2>>16]
-       lbu     $t2,2($i2)              # Te4[s3>>16]
-       lbu     $t3,2($i3)              # Te4[s0>>16]
-
        _xtr    $i0,$s2,8-2
+       lbu     $t1,2($i1)              # Te4[s2>>16]
        _xtr    $i1,$s3,8-2
+       lbu     $t2,2($i2)              # Te4[s3>>16]
        _xtr    $i2,$s0,8-2
+       lbu     $t3,2($i3)              # Te4[s0>>16]
        _xtr    $i3,$s1,8-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -259,15 +443,44 @@ _mips_AES_encrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+# if defined(_MIPSEL)
        lbu     $t4,2($i0)              # Te4[s2>>8]
+       $PTR_INS $i0,$s0,2,8
        lbu     $t5,2($i1)              # Te4[s3>>8]
+       $PTR_INS $i1,$s1,2,8
        lbu     $t6,2($i2)              # Te4[s0>>8]
+       $PTR_INS $i2,$s2,2,8
        lbu     $t7,2($i3)              # Te4[s1>>8]
+       $PTR_INS $i3,$s3,2,8
 
+       lbu     $t8,2($i0)              # Te4[s0>>24]
+       _xtr    $i0,$s3,0-2
+       lbu     $t9,2($i1)              # Te4[s1>>24]
+       _xtr    $i1,$s0,0-2
+       lbu     $t10,2($i2)             # Te4[s2>>24]
+       _xtr    $i2,$s1,0-2
+       lbu     $t11,2($i3)             # Te4[s3>>24]
+       _xtr    $i3,$s2,0-2
+
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+# else
+       lbu     $t4,2($i0)              # Te4[s2>>8]
        _xtr    $i0,$s0,24-2
+       lbu     $t5,2($i1)              # Te4[s3>>8]
        _xtr    $i1,$s1,24-2
+       lbu     $t6,2($i2)              # Te4[s0>>8]
        _xtr    $i2,$s2,24-2
+       lbu     $t7,2($i3)              # Te4[s1>>8]
        _xtr    $i3,$s3,24-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -277,18 +490,76 @@ _mips_AES_encrypt:
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
        lbu     $t8,2($i0)              # Te4[s0>>24]
+       $PTR_INS $i0,$s3,2,8
        lbu     $t9,2($i1)              # Te4[s1>>24]
+       $PTR_INS $i1,$s0,2,8
        lbu     $t10,2($i2)             # Te4[s2>>24]
+       $PTR_INS $i2,$s1,2,8
        lbu     $t11,2($i3)             # Te4[s3>>24]
+       $PTR_INS $i3,$s2,2,8
+# endif
+       _ins    $t0,16
+       _ins    $t1,16
+       _ins    $t2,16
+       _ins    $t3,16
+
+       _ins2   $t0,$t4,8
+       lbu     $t4,2($i0)              # Te4[s3]
+       _ins2   $t1,$t5,8
+       lbu     $t5,2($i1)              # Te4[s0]
+       _ins2   $t2,$t6,8
+       lbu     $t6,2($i2)              # Te4[s1]
+       _ins2   $t3,$t7,8
+       lbu     $t7,2($i3)              # Te4[s2]
+
+       _ins2   $t0,$t8,24
+       lw      $s0,0($key0)
+       _ins2   $t1,$t9,24
+       lw      $s1,4($key0)
+       _ins2   $t2,$t10,24
+       lw      $s2,8($key0)
+       _ins2   $t3,$t11,24
+       lw      $s3,12($key0)
+
+       _ins2   $t0,$t4,0
+       _ins2   $t1,$t5,0
+       _ins2   $t2,$t6,0
+       _ins2   $t3,$t7,0
+#else
+       lbu     $t4,2($i0)              # Te4[s2>>8]
+       _xtr    $i0,$s0,24-2
+       lbu     $t5,2($i1)              # Te4[s3>>8]
+       _xtr    $i1,$s1,24-2
+       lbu     $t6,2($i2)              # Te4[s0>>8]
+       _xtr    $i2,$s2,24-2
+       lbu     $t7,2($i3)              # Te4[s1>>8]
+       _xtr    $i3,$s3,24-2
 
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+       lbu     $t8,2($i0)              # Te4[s0>>24]
        _xtr    $i0,$s3,0-2
+       lbu     $t9,2($i1)              # Te4[s1>>24]
        _xtr    $i1,$s0,0-2
+       lbu     $t10,2($i2)             # Te4[s2>>24]
        _xtr    $i2,$s1,0-2
+       lbu     $t11,2($i3)             # Te4[s3>>24]
        _xtr    $i3,$s2,0-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
        and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
 
        _ins    $t0,16
        _ins    $t1,16
@@ -301,27 +572,21 @@ _mips_AES_encrypt:
        _ins    $t7,8
 
        xor     $t0,$t4
-       xor     $t1,$t5
-       xor     $t2,$t6
-       xor     $t3,$t7
-
-       $PTR_ADD $i0,$Tbl
-       $PTR_ADD $i1,$Tbl
-       $PTR_ADD $i2,$Tbl
-       $PTR_ADD $i3,$Tbl
        lbu     $t4,2($i0)              # Te4[s3]
+       xor     $t1,$t5
        lbu     $t5,2($i1)              # Te4[s0]
+       xor     $t2,$t6
        lbu     $t6,2($i2)              # Te4[s1]
+       xor     $t3,$t7
        lbu     $t7,2($i3)              # Te4[s2]
 
        _ins    $t8,24
-       _ins    $t9,24
-       _ins    $t10,24
-       _ins    $t11,24
-
        lw      $s0,0($key0)
+       _ins    $t9,24
        lw      $s1,4($key0)
+       _ins    $t10,24
        lw      $s2,8($key0)
+       _ins    $t11,24
        lw      $s3,12($key0)
 
        xor     $t0,$t8
@@ -338,7 +603,7 @@ _mips_AES_encrypt:
        xor     $t1,$t5
        xor     $t2,$t6
        xor     $t3,$t7
-
+#endif
        xor     $s0,$t0
        xor     $s1,$t1
        xor     $s2,$t2
@@ -384,8 +649,14 @@ $code.=<<___ if ($flavour !~ /o32/i);      # non-o32 PIC-ification
 ___
 $code.=<<___;
        .set    reorder
-       la      $Tbl,AES_Te             # PIC-ified 'load address'
-
+       $PTR_LA $Tbl,AES_Te             # PIC-ified 'load address'
+
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       lw      $s0,0($inp)
+       lw      $s1,4($inp)
+       lw      $s2,8($inp)
+       lw      $s3,12($inp)
+#else
        lwl     $s0,0+$MSB($inp)
        lwl     $s1,4+$MSB($inp)
        lwl     $s2,8+$MSB($inp)
@@ -394,9 +665,16 @@ $code.=<<___;
        lwr     $s1,4+$LSB($inp)
        lwr     $s2,8+$LSB($inp)
        lwr     $s3,12+$LSB($inp)
+#endif
 
        bal     _mips_AES_encrypt
 
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       sw      $s0,0($out)
+       sw      $s1,4($out)
+       sw      $s2,8($out)
+       sw      $s3,12($out)
+#else
        swr     $s0,0+$LSB($out)
        swr     $s1,4+$LSB($out)
        swr     $s2,8+$LSB($out)
@@ -405,6 +683,7 @@ $code.=<<___;
        swl     $s1,4+$MSB($out)
        swl     $s2,8+$MSB($out)
        swl     $s3,12+$MSB($out)
+#endif
 
        .set    noreorder
        $REG_L  $ra,$FRAMESIZE-1*$SZREG($sp)
@@ -449,7 +728,90 @@ _mips_AES_decrypt:
        xor     $s2,$t2
        xor     $s3,$t3
 
-       sub     $cnt,1
+       subu    $cnt,1
+#if defined(__mips_smartmips)
+       ext     $i0,$s3,16,8
+.Loop_dec:
+       ext     $i1,$s0,16,8
+       ext     $i2,$s1,16,8
+       ext     $i3,$s2,16,8
+       lwxs    $t0,$i0($Tbl)           # Td1[s3>>16]
+       ext     $i0,$s2,8,8
+       lwxs    $t1,$i1($Tbl)           # Td1[s0>>16]
+       ext     $i1,$s3,8,8
+       lwxs    $t2,$i2($Tbl)           # Td1[s1>>16]
+       ext     $i2,$s0,8,8
+       lwxs    $t3,$i3($Tbl)           # Td1[s2>>16]
+       ext     $i3,$s1,8,8
+
+       lwxs    $t4,$i0($Tbl)           # Td2[s2>>8]
+       ext     $i0,$s1,0,8
+       lwxs    $t5,$i1($Tbl)           # Td2[s3>>8]
+       ext     $i1,$s2,0,8
+       lwxs    $t6,$i2($Tbl)           # Td2[s0>>8]
+       ext     $i2,$s3,0,8
+       lwxs    $t7,$i3($Tbl)           # Td2[s1>>8]
+       ext     $i3,$s0,0,8
+
+       lwxs    $t8,$i0($Tbl)           # Td3[s1]
+       ext     $i0,$s0,24,8
+       lwxs    $t9,$i1($Tbl)           # Td3[s2]
+       ext     $i1,$s1,24,8
+       lwxs    $t10,$i2($Tbl)          # Td3[s3]
+       ext     $i2,$s2,24,8
+       lwxs    $t11,$i3($Tbl)          # Td3[s0]
+       ext     $i3,$s3,24,8
+
+       rotr    $t0,$t0,8
+       rotr    $t1,$t1,8
+       rotr    $t2,$t2,8
+       rotr    $t3,$t3,8
+
+       rotr    $t4,$t4,16
+       rotr    $t5,$t5,16
+       rotr    $t6,$t6,16
+       rotr    $t7,$t7,16
+
+       xor     $t0,$t4
+       lwxs    $t4,$i0($Tbl)           # Td0[s0>>24]
+       xor     $t1,$t5
+       lwxs    $t5,$i1($Tbl)           # Td0[s1>>24]
+       xor     $t2,$t6
+       lwxs    $t6,$i2($Tbl)           # Td0[s2>>24]
+       xor     $t3,$t7
+       lwxs    $t7,$i3($Tbl)           # Td0[s3>>24]
+
+       rotr    $t8,$t8,24
+       lw      $s0,0($key0)
+       rotr    $t9,$t9,24
+       lw      $s1,4($key0)
+       rotr    $t10,$t10,24
+       lw      $s2,8($key0)
+       rotr    $t11,$t11,24
+       lw      $s3,12($key0)
+
+       xor     $t0,$t8
+       xor     $t1,$t9
+       xor     $t2,$t10
+       xor     $t3,$t11
+
+       xor     $t0,$t4
+       xor     $t1,$t5
+       xor     $t2,$t6
+       xor     $t3,$t7
+
+       subu    $cnt,1
+       $PTR_ADD $key0,16
+       xor     $s0,$t0
+       xor     $s1,$t1
+       xor     $s2,$t2
+       xor     $s3,$t3
+       .set    noreorder
+       bnez    $cnt,.Loop_dec
+       ext     $i0,$s3,16,8
+
+       _xtr    $i0,$s3,16-2
+#else
        _xtr    $i0,$s3,16-2
 .Loop_dec:
        _xtr    $i1,$s0,16-2
@@ -463,19 +825,30 @@ _mips_AES_decrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+       lw      $t0,0($i0)              # Td1[s3>>16]
+       _xtr    $i0,$s2,8-2
+       lw      $t1,0($i1)              # Td1[s0>>16]
+       _xtr    $i1,$s3,8-2
+       lw      $t2,0($i2)              # Td1[s1>>16]
+       _xtr    $i2,$s0,8-2
+       lw      $t3,0($i3)              # Td1[s2>>16]
+       _xtr    $i3,$s1,8-2
+#else
        lwl     $t0,3($i0)              # Td1[s3>>16]
        lwl     $t1,3($i1)              # Td1[s0>>16]
        lwl     $t2,3($i2)              # Td1[s1>>16]
        lwl     $t3,3($i3)              # Td1[s2>>16]
        lwr     $t0,2($i0)              # Td1[s3>>16]
-       lwr     $t1,2($i1)              # Td1[s0>>16]
-       lwr     $t2,2($i2)              # Td1[s1>>16]
-       lwr     $t3,2($i3)              # Td1[s2>>16]
-
        _xtr    $i0,$s2,8-2
+       lwr     $t1,2($i1)              # Td1[s0>>16]
        _xtr    $i1,$s3,8-2
+       lwr     $t2,2($i2)              # Td1[s1>>16]
        _xtr    $i2,$s0,8-2
+       lwr     $t3,2($i3)              # Td1[s2>>16]
        _xtr    $i3,$s1,8-2
+#endif
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -484,19 +857,88 @@ _mips_AES_decrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+       rotr    $t0,$t0,8
+       rotr    $t1,$t1,8
+       rotr    $t2,$t2,8
+       rotr    $t3,$t3,8
+# if defined(_MIPSEL)
+       lw      $t4,0($i0)              # Td2[s2>>8]
+       _xtr    $i0,$s1,0-2
+       lw      $t5,0($i1)              # Td2[s3>>8]
+       _xtr    $i1,$s2,0-2
+       lw      $t6,0($i2)              # Td2[s0>>8]
+       _xtr    $i2,$s3,0-2
+       lw      $t7,0($i3)              # Td2[s1>>8]
+       _xtr    $i3,$s0,0-2
+
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+       lw      $t8,0($i0)              # Td3[s1]
+       $PTR_INS $i0,$s0,2,8
+       lw      $t9,0($i1)              # Td3[s2]
+       $PTR_INS $i1,$s1,2,8
+       lw      $t10,0($i2)             # Td3[s3]
+       $PTR_INS $i2,$s2,2,8
+       lw      $t11,0($i3)             # Td3[s0]
+       $PTR_INS $i3,$s3,2,8
+#else
+       lw      $t4,0($i0)              # Td2[s2>>8]
+       $PTR_INS $i0,$s1,2,8
+       lw      $t5,0($i1)              # Td2[s3>>8]
+       $PTR_INS $i1,$s2,2,8
+       lw      $t6,0($i2)              # Td2[s0>>8]
+       $PTR_INS $i2,$s3,2,8
+       lw      $t7,0($i3)              # Td2[s1>>8]
+       $PTR_INS $i3,$s0,2,8
+
+       lw      $t8,0($i0)              # Td3[s1]
+       _xtr    $i0,$s0,24-2
+       lw      $t9,0($i1)              # Td3[s2]
+       _xtr    $i1,$s1,24-2
+       lw      $t10,0($i2)             # Td3[s3]
+       _xtr    $i2,$s2,24-2
+       lw      $t11,0($i3)             # Td3[s0]
+       _xtr    $i3,$s3,24-2
+
+       and     $i0,0x3fc
+       and     $i1,0x3fc
+       and     $i2,0x3fc
+       and     $i3,0x3fc
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+#endif
+       rotr    $t4,$t4,16
+       rotr    $t5,$t5,16
+       rotr    $t6,$t6,16
+       rotr    $t7,$t7,16
+
+       rotr    $t8,$t8,24
+       rotr    $t9,$t9,24
+       rotr    $t10,$t10,24
+       rotr    $t11,$t11,24
+#else
        lwl     $t4,2($i0)              # Td2[s2>>8]
        lwl     $t5,2($i1)              # Td2[s3>>8]
        lwl     $t6,2($i2)              # Td2[s0>>8]
        lwl     $t7,2($i3)              # Td2[s1>>8]
        lwr     $t4,1($i0)              # Td2[s2>>8]
-       lwr     $t5,1($i1)              # Td2[s3>>8]
-       lwr     $t6,1($i2)              # Td2[s0>>8]
-       lwr     $t7,1($i3)              # Td2[s1>>8]
-
        _xtr    $i0,$s1,0-2
+       lwr     $t5,1($i1)              # Td2[s3>>8]
        _xtr    $i1,$s2,0-2
+       lwr     $t6,1($i2)              # Td2[s0>>8]
        _xtr    $i2,$s3,0-2
+       lwr     $t7,1($i3)              # Td2[s1>>8]
        _xtr    $i3,$s0,0-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -510,14 +952,14 @@ _mips_AES_decrypt:
        lwl     $t10,1($i2)             # Td3[s3]
        lwl     $t11,1($i3)             # Td3[s0]
        lwr     $t8,0($i0)              # Td3[s1]
-       lwr     $t9,0($i1)              # Td3[s2]
-       lwr     $t10,0($i2)             # Td3[s3]
-       lwr     $t11,0($i3)             # Td3[s0]
-
        _xtr    $i0,$s0,24-2
+       lwr     $t9,0($i1)              # Td3[s2]
        _xtr    $i1,$s1,24-2
+       lwr     $t10,0($i2)             # Td3[s3]
        _xtr    $i2,$s2,24-2
+       lwr     $t11,0($i3)             # Td3[s0]
        _xtr    $i3,$s3,24-2
+
        and     $i0,0x3fc
        and     $i1,0x3fc
        and     $i2,0x3fc
@@ -526,34 +968,32 @@ _mips_AES_decrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#endif
 
        xor     $t0,$t4
-       xor     $t1,$t5
-       xor     $t2,$t6
-       xor     $t3,$t7
-
-
        lw      $t4,0($i0)              # Td0[s0>>24]
+       xor     $t1,$t5
        lw      $t5,0($i1)              # Td0[s1>>24]
+       xor     $t2,$t6
        lw      $t6,0($i2)              # Td0[s2>>24]
+       xor     $t3,$t7
        lw      $t7,0($i3)              # Td0[s3>>24]
 
-       lw      $s0,0($key0)
-       lw      $s1,4($key0)
-       lw      $s2,8($key0)
-       lw      $s3,12($key0)
-
        xor     $t0,$t8
+       lw      $s0,0($key0)
        xor     $t1,$t9
+       lw      $s1,4($key0)
        xor     $t2,$t10
+       lw      $s2,8($key0)
        xor     $t3,$t11
+       lw      $s3,12($key0)
 
        xor     $t0,$t4
        xor     $t1,$t5
        xor     $t2,$t6
        xor     $t3,$t7
 
-       sub     $cnt,1
+       subu    $cnt,1
        $PTR_ADD $key0,16
        xor     $s0,$t0
        xor     $s1,$t1
@@ -562,38 +1002,39 @@ _mips_AES_decrypt:
        .set    noreorder
        bnez    $cnt,.Loop_dec
        _xtr    $i0,$s3,16-2
+#endif
 
        .set    reorder
        lw      $t4,1024($Tbl)          # prefetch Td4
-       lw      $t5,1024+32($Tbl)
-       lw      $t6,1024+64($Tbl)
-       lw      $t7,1024+96($Tbl)
-       lw      $t8,1024+128($Tbl)
-       lw      $t9,1024+160($Tbl)
-       lw      $t10,1024+192($Tbl)
-       lw      $t11,1024+224($Tbl)
-
        _xtr    $i0,$s3,16
+       lw      $t5,1024+32($Tbl)
        _xtr    $i1,$s0,16
+       lw      $t6,1024+64($Tbl)
        _xtr    $i2,$s1,16
+       lw      $t7,1024+96($Tbl)
        _xtr    $i3,$s2,16
+       lw      $t8,1024+128($Tbl)
        and     $i0,0xff
+       lw      $t9,1024+160($Tbl)
        and     $i1,0xff
+       lw      $t10,1024+192($Tbl)
        and     $i2,0xff
+       lw      $t11,1024+224($Tbl)
        and     $i3,0xff
+
        $PTR_ADD $i0,$Tbl
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
        lbu     $t0,1024($i0)           # Td4[s3>>16]
-       lbu     $t1,1024($i1)           # Td4[s0>>16]
-       lbu     $t2,1024($i2)           # Td4[s1>>16]
-       lbu     $t3,1024($i3)           # Td4[s2>>16]
-
        _xtr    $i0,$s2,8
+       lbu     $t1,1024($i1)           # Td4[s0>>16]
        _xtr    $i1,$s3,8
+       lbu     $t2,1024($i2)           # Td4[s1>>16]
        _xtr    $i2,$s0,8
+       lbu     $t3,1024($i3)           # Td4[s2>>16]
        _xtr    $i3,$s1,8
+
        and     $i0,0xff
        and     $i1,0xff
        and     $i2,0xff
@@ -602,29 +1043,108 @@ _mips_AES_decrypt:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+# if defined(_MIPSEL)
        lbu     $t4,1024($i0)           # Td4[s2>>8]
+       $PTR_INS $i0,$s0,0,8
        lbu     $t5,1024($i1)           # Td4[s3>>8]
+       $PTR_INS $i1,$s1,0,8
        lbu     $t6,1024($i2)           # Td4[s0>>8]
+       $PTR_INS $i2,$s2,0,8
        lbu     $t7,1024($i3)           # Td4[s1>>8]
+       $PTR_INS $i3,$s3,0,8
 
+       lbu     $t8,1024($i0)           # Td4[s0>>24]
+       _xtr    $i0,$s1,0
+       lbu     $t9,1024($i1)           # Td4[s1>>24]
+       _xtr    $i1,$s2,0
+       lbu     $t10,1024($i2)          # Td4[s2>>24]
+       _xtr    $i2,$s3,0
+       lbu     $t11,1024($i3)          # Td4[s3>>24]
+       _xtr    $i3,$s0,0
+
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+# else
+       lbu     $t4,1024($i0)           # Td4[s2>>8]
        _xtr    $i0,$s0,24
+       lbu     $t5,1024($i1)           # Td4[s3>>8]
        _xtr    $i1,$s1,24
+       lbu     $t6,1024($i2)           # Td4[s0>>8]
        _xtr    $i2,$s2,24
+       lbu     $t7,1024($i3)           # Td4[s1>>8]
        _xtr    $i3,$s3,24
+
        $PTR_ADD $i0,$Tbl
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
        lbu     $t8,1024($i0)           # Td4[s0>>24]
+       $PTR_INS $i0,$s1,0,8
        lbu     $t9,1024($i1)           # Td4[s1>>24]
+       $PTR_INS $i1,$s2,0,8
        lbu     $t10,1024($i2)          # Td4[s2>>24]
+       $PTR_INS $i2,$s3,0,8
        lbu     $t11,1024($i3)          # Td4[s3>>24]
+       $PTR_INS $i3,$s0,0,8
+# endif
+       _ins    $t0,16
+       _ins    $t1,16
+       _ins    $t2,16
+       _ins    $t3,16
+
+       _ins2   $t0,$t4,8
+       lbu     $t4,1024($i0)           # Td4[s1]
+       _ins2   $t1,$t5,8
+       lbu     $t5,1024($i1)           # Td4[s2]
+       _ins2   $t2,$t6,8
+       lbu     $t6,1024($i2)           # Td4[s3]
+       _ins2   $t3,$t7,8
+       lbu     $t7,1024($i3)           # Td4[s0]
+
+       _ins2   $t0,$t8,24
+       lw      $s0,0($key0)
+       _ins2   $t1,$t9,24
+       lw      $s1,4($key0)
+       _ins2   $t2,$t10,24
+       lw      $s2,8($key0)
+       _ins2   $t3,$t11,24
+       lw      $s3,12($key0)
 
+       _ins2   $t0,$t4,0
+       _ins2   $t1,$t5,0
+       _ins2   $t2,$t6,0
+       _ins2   $t3,$t7,0
+#else
+       lbu     $t4,1024($i0)           # Td4[s2>>8]
+       _xtr    $i0,$s0,24
+       lbu     $t5,1024($i1)           # Td4[s3>>8]
+       _xtr    $i1,$s1,24
+       lbu     $t6,1024($i2)           # Td4[s0>>8]
+       _xtr    $i2,$s2,24
+       lbu     $t7,1024($i3)           # Td4[s1>>8]
+       _xtr    $i3,$s3,24
+
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+       lbu     $t8,1024($i0)           # Td4[s0>>24]
        _xtr    $i0,$s1,0
+       lbu     $t9,1024($i1)           # Td4[s1>>24]
        _xtr    $i1,$s2,0
+       lbu     $t10,1024($i2)          # Td4[s2>>24]
        _xtr    $i2,$s3,0
+       lbu     $t11,1024($i3)          # Td4[s3>>24]
        _xtr    $i3,$s0,0
 
+       $PTR_ADD $i0,$Tbl
+       $PTR_ADD $i1,$Tbl
+       $PTR_ADD $i2,$Tbl
+       $PTR_ADD $i3,$Tbl
+
        _ins    $t0,16
        _ins    $t1,16
        _ins    $t2,16
@@ -636,44 +1156,38 @@ _mips_AES_decrypt:
        _ins    $t7,8
 
        xor     $t0,$t4
-       xor     $t1,$t5
-       xor     $t2,$t6
-       xor     $t3,$t7
-
-       $PTR_ADD $i0,$Tbl
-       $PTR_ADD $i1,$Tbl
-       $PTR_ADD $i2,$Tbl
-       $PTR_ADD $i3,$Tbl
        lbu     $t4,1024($i0)           # Td4[s1]
+       xor     $t1,$t5
        lbu     $t5,1024($i1)           # Td4[s2]
+       xor     $t2,$t6
        lbu     $t6,1024($i2)           # Td4[s3]
+       xor     $t3,$t7
        lbu     $t7,1024($i3)           # Td4[s0]
 
        _ins    $t8,24
-       _ins    $t9,24
-       _ins    $t10,24
-       _ins    $t11,24
-
        lw      $s0,0($key0)
+       _ins    $t9,24
        lw      $s1,4($key0)
+       _ins    $t10,24
        lw      $s2,8($key0)
+       _ins    $t11,24
        lw      $s3,12($key0)
 
-       _ins    $t4,0
-       _ins    $t5,0
-       _ins    $t6,0
-       _ins    $t7,0
-
-
        xor     $t0,$t8
        xor     $t1,$t9
        xor     $t2,$t10
        xor     $t3,$t11
 
+       _ins    $t4,0
+       _ins    $t5,0
+       _ins    $t6,0
+       _ins    $t7,0
+
        xor     $t0,$t4
        xor     $t1,$t5
        xor     $t2,$t6
        xor     $t3,$t7
+#endif
 
        xor     $s0,$t0
        xor     $s1,$t1
@@ -720,8 +1234,14 @@ $code.=<<___ if ($flavour !~ /o32/i);     # non-o32 PIC-ification
 ___
 $code.=<<___;
        .set    reorder
-       la      $Tbl,AES_Td             # PIC-ified 'load address'
-
+       $PTR_LA $Tbl,AES_Td             # PIC-ified 'load address'
+
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       lw      $s0,0($inp)
+       lw      $s1,4($inp)
+       lw      $s2,8($inp)
+       lw      $s3,12($inp)
+#else
        lwl     $s0,0+$MSB($inp)
        lwl     $s1,4+$MSB($inp)
        lwl     $s2,8+$MSB($inp)
@@ -730,9 +1250,16 @@ $code.=<<___;
        lwr     $s1,4+$LSB($inp)
        lwr     $s2,8+$LSB($inp)
        lwr     $s3,12+$LSB($inp)
+#endif
 
        bal     _mips_AES_decrypt
 
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       sw      $s0,0($out)
+       sw      $s1,4($out)
+       sw      $s2,8($out)
+       sw      $s3,12($out)
+#else
        swr     $s0,0+$LSB($out)
        swr     $s1,4+$LSB($out)
        swr     $s2,8+$LSB($out)
@@ -741,6 +1268,7 @@ $code.=<<___;
        swl     $s1,4+$MSB($out)
        swl     $s2,8+$MSB($out)
        swl     $s3,12+$MSB($out)
+#endif
 
        .set    noreorder
        $REG_L  $ra,$FRAMESIZE-1*$SZREG($sp)
@@ -770,7 +1298,7 @@ ___
 \f
 {{{
 my $FRAMESIZE=8*$SZREG;
-my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc000f008 : 0xc0000000;
+my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? "0xc000f008" : "0xc0000000";
 
 my ($inp,$bits,$key,$Tbl)=($a0,$a1,$a2,$a3);
 my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
@@ -786,38 +1314,55 @@ _mips_AES_set_encrypt_key:
        beqz    $inp,.Lekey_done
        li      $t0,-1
        beqz    $key,.Lekey_done
-       $PTR_ADD $rcon,$Tbl,1024+256
+       $PTR_ADD $rcon,$Tbl,256
 
        .set    reorder
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       lw      $rk0,0($inp)            # load 128 bits
+       lw      $rk1,4($inp)
+       lw      $rk2,8($inp)
+       lw      $rk3,12($inp)
+#else
        lwl     $rk0,0+$MSB($inp)       # load 128 bits
        lwl     $rk1,4+$MSB($inp)
        lwl     $rk2,8+$MSB($inp)
        lwl     $rk3,12+$MSB($inp)
-       li      $at,128
        lwr     $rk0,0+$LSB($inp)
        lwr     $rk1,4+$LSB($inp)
        lwr     $rk2,8+$LSB($inp)
        lwr     $rk3,12+$LSB($inp)
+#endif
+       li      $at,128
        .set    noreorder
        beq     $bits,$at,.L128bits
        li      $cnt,10
 
        .set    reorder
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       lw      $rk4,16($inp)           # load 192 bits
+       lw      $rk5,20($inp)
+#else
        lwl     $rk4,16+$MSB($inp)      # load 192 bits
        lwl     $rk5,20+$MSB($inp)
-       li      $at,192
        lwr     $rk4,16+$LSB($inp)
        lwr     $rk5,20+$LSB($inp)
+#endif
+       li      $at,192
        .set    noreorder
        beq     $bits,$at,.L192bits
        li      $cnt,8
 
        .set    reorder
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+       lw      $rk6,24($inp)           # load 256 bits
+       lw      $rk7,28($inp)
+#else
        lwl     $rk6,24+$MSB($inp)      # load 256 bits
        lwl     $rk7,28+$MSB($inp)
-       li      $at,256
        lwr     $rk6,24+$LSB($inp)
        lwr     $rk7,28+$LSB($inp)
+#endif
+       li      $at,256
        .set    noreorder
        beq     $bits,$at,.L256bits
        li      $cnt,7
@@ -838,16 +1383,16 @@ _mips_AES_set_encrypt_key:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
-       lbu     $i0,1024($i0)
-       lbu     $i1,1024($i1)
-       lbu     $i2,1024($i2)
-       lbu     $i3,1024($i3)
+       lbu     $i0,0($i0)
+       lbu     $i1,0($i1)
+       lbu     $i2,0($i2)
+       lbu     $i3,0($i3)
 
        sw      $rk0,0($key)
        sw      $rk1,4($key)
        sw      $rk2,8($key)
        sw      $rk3,12($key)
-       sub     $cnt,1
+       subu    $cnt,1
        $PTR_ADD $key,16
 
        _bias   $i0,24
@@ -893,10 +1438,10 @@ _mips_AES_set_encrypt_key:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
-       lbu     $i0,1024($i0)
-       lbu     $i1,1024($i1)
-       lbu     $i2,1024($i2)
-       lbu     $i3,1024($i3)
+       lbu     $i0,0($i0)
+       lbu     $i1,0($i1)
+       lbu     $i2,0($i2)
+       lbu     $i3,0($i3)
 
        sw      $rk0,0($key)
        sw      $rk1,4($key)
@@ -904,7 +1449,7 @@ _mips_AES_set_encrypt_key:
        sw      $rk3,12($key)
        sw      $rk4,16($key)
        sw      $rk5,20($key)
-       sub     $cnt,1
+       subu    $cnt,1
        $PTR_ADD $key,24
 
        _bias   $i0,24
@@ -952,10 +1497,10 @@ _mips_AES_set_encrypt_key:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
-       lbu     $i0,1024($i0)
-       lbu     $i1,1024($i1)
-       lbu     $i2,1024($i2)
-       lbu     $i3,1024($i3)
+       lbu     $i0,0($i0)
+       lbu     $i1,0($i1)
+       lbu     $i2,0($i2)
+       lbu     $i3,0($i3)
 
        sw      $rk0,0($key)
        sw      $rk1,4($key)
@@ -965,7 +1510,7 @@ _mips_AES_set_encrypt_key:
        sw      $rk5,20($key)
        sw      $rk6,24($key)
        sw      $rk7,28($key)
-       sub     $cnt,1
+       subu    $cnt,1
 
        _bias   $i0,24
        _bias   $i1,16
@@ -994,10 +1539,10 @@ _mips_AES_set_encrypt_key:
        $PTR_ADD $i1,$Tbl
        $PTR_ADD $i2,$Tbl
        $PTR_ADD $i3,$Tbl
-       lbu     $i0,1024($i0)
-       lbu     $i1,1024($i1)
-       lbu     $i2,1024($i2)
-       lbu     $i3,1024($i3)
+       lbu     $i0,0($i0)
+       lbu     $i1,0($i1)
+       lbu     $i2,0($i2)
+       lbu     $i3,0($i3)
        sll     $i0,24
        sll     $i1,16
        sll     $i2,8
@@ -1059,7 +1604,7 @@ $code.=<<___ if ($flavour !~ /o32/i);     # non-o32 PIC-ification
 ___
 $code.=<<___;
        .set    reorder
-       la      $Tbl,AES_Te             # PIC-ified 'load address'
+       $PTR_LA $Tbl,AES_Te4            # PIC-ified 'load address'
 
        bal     _mips_AES_set_encrypt_key
 
@@ -1114,7 +1659,7 @@ $code.=<<___ if ($flavour !~ /o32/i);     # non-o32 PIC-ification
 ___
 $code.=<<___;
        .set    reorder
-       la      $Tbl,AES_Te             # PIC-ified 'load address'
+       $PTR_LA $Tbl,AES_Te4            # PIC-ified 'load address'
 
        bal     _mips_AES_set_encrypt_key
 
@@ -1147,7 +1692,7 @@ $code.=<<___;
 
        lw      $tp1,16($key)           # modulo-scheduled
        lui     $x80808080,0x8080
-       sub     $cnt,1
+       subu    $cnt,1
        or      $x80808080,0x8080
        sll     $cnt,2
        $PTR_ADD $key,16
@@ -1185,6 +1730,16 @@ $code.=<<___;
        xor     $tpb,$tp9,$tp2
        xor     $tpd,$tp9,$tp4
 
+#if defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2)
+       rotr    $tp1,$tpd,16
+        xor    $tpe,$tp2
+       rotr    $tp2,$tp9,8
+       xor     $tpe,$tp1
+       rotr    $tp4,$tpb,24
+       xor     $tpe,$tp2
+       lw      $tp1,4($key)            # modulo-scheduled
+       xor     $tpe,$tp4
+#else
        _ror    $tp1,$tpd,16
         xor    $tpe,$tp2
        _ror    $tp2,$tpd,-16
@@ -1199,7 +1754,8 @@ $code.=<<___;
        xor     $tpe,$tp1
        lw      $tp1,4($key)            # modulo-scheduled
        xor     $tpe,$tp2
-       sub     $cnt,1
+#endif
+       subu    $cnt,1
        sw      $tpe,0($key)
        $PTR_ADD $key,4
        bnez    $cnt,.Lmix
@@ -1229,7 +1785,7 @@ ___
 # Tables are kept in endian-neutral manner
 $code.=<<___;
 .rdata
-.align 6
+.align 10
 AES_Te:
 .byte  0xc6,0x63,0x63,0xa5,    0xf8,0x7c,0x7c,0x84     # Te0
 .byte  0xee,0x77,0x77,0x99,    0xf6,0x7b,0x7b,0x8d
@@ -1360,46 +1916,6 @@ AES_Te:
 .byte  0x7b,0xb0,0xb0,0xcb,    0xa8,0x54,0x54,0xfc
 .byte  0x6d,0xbb,0xbb,0xd6,    0x2c,0x16,0x16,0x3a
 
-.byte  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5  # Te4
-.byte  0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
-.byte  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
-.byte  0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
-.byte  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
-.byte  0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
-.byte  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
-.byte  0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
-.byte  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
-.byte  0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
-.byte  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
-.byte  0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
-.byte  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
-.byte  0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
-.byte  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
-.byte  0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
-.byte  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
-.byte  0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
-.byte  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
-.byte  0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
-.byte  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
-.byte  0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
-.byte  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
-.byte  0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
-.byte  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
-.byte  0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
-.byte  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
-.byte  0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
-.byte  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
-.byte  0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
-.byte  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
-.byte  0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-
-.byte  0x01,0x00,0x00,0x00,    0x02,0x00,0x00,0x00     # rcon
-.byte  0x04,0x00,0x00,0x00,    0x08,0x00,0x00,0x00
-.byte  0x10,0x00,0x00,0x00,    0x20,0x00,0x00,0x00
-.byte  0x40,0x00,0x00,0x00,    0x80,0x00,0x00,0x00
-.byte  0x1B,0x00,0x00,0x00,    0x36,0x00,0x00,0x00
-
-.align 6
 AES_Td:
 .byte  0x51,0xf4,0xa7,0x50,    0x7e,0x41,0x65,0x53     # Td0
 .byte  0x1a,0x17,0xa4,0xc3,    0x3a,0x27,0x5e,0x96
@@ -1562,6 +2078,46 @@ AES_Td:
 .byte  0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
 .byte  0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
 .byte  0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+
+AES_Te4:
+.byte  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5  # Te4
+.byte  0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte  0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte  0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte  0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte  0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte  0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte  0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte  0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte  0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte  0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte  0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte  0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte  0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte  0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte  0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte  0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+
+.byte  0x01,0x00,0x00,0x00,    0x02,0x00,0x00,0x00     # rcon
+.byte  0x04,0x00,0x00,0x00,    0x08,0x00,0x00,0x00
+.byte  0x10,0x00,0x00,0x00,    0x20,0x00,0x00,0x00
+.byte  0x40,0x00,0x00,0x00,    0x80,0x00,0x00,0x00
+.byte  0x1B,0x00,0x00,0x00,    0x36,0x00,0x00,0x00
 ___
 \f
 foreach (split("\n",$code)) {
@@ -1578,6 +2134,9 @@ foreach (split("\n",$code)) {
            s/_ins\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
                sprintf("sll\t$1,$2,%d",$big_endian ?   eval($3)
                                        :               eval("24-$3"))/e or
+           s/_ins2\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/
+               sprintf("ins\t$1,$2,%d,8",$big_endian ? eval($3)
+                                       :               eval("24-$3"))/e or
            s/_ror\s+(\$[0-9]+),(\$[0-9]+),(\-?[0-9]+)/
                sprintf("srl\t$1,$2,%d",$big_endian ?   eval($3)
                                        :               eval("$3*-1"))/e or
@@ -1600,6 +2159,11 @@ foreach (split("\n",$code)) {
                sprintf("$1%d($3)",eval("$2-$2%4+($2%4+1)&3"))/e;
        }
 
+       if (!$big_endian) {
+           s/(rotr\s+\$[0-9]+,\$[0-9]+),([0-9]+)/sprintf("$1,%d",32-$2)/e;
+           s/(ext\s+\$[0-9]+,\$[0-9]+),([0-9]+),8/sprintf("$1,%d,8",24-$2)/e;
+       }
+
        print $_,"\n";
 }