Blame crypto/rc4/asm/rc4-c64xplus.pl

Packit c4476c
#! /usr/bin/env perl
Packit c4476c
# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
#
Packit c4476c
# Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
# this file except in compliance with the License.  You can obtain a copy
Packit c4476c
# in the file LICENSE in the source distribution or at
Packit c4476c
# https://www.openssl.org/source/license.html
Packit c4476c
Packit c4476c
#
Packit c4476c
# ====================================================================
Packit c4476c
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
Packit c4476c
# project. The module is, however, dual licensed under OpenSSL and
Packit c4476c
# CRYPTOGAMS licenses depending on where you obtain it. For further
Packit c4476c
# details see http://www.openssl.org/~appro/cryptogams/.
Packit c4476c
# ====================================================================
Packit c4476c
#
Packit c4476c
# RC4 for C64x+.
Packit c4476c
#
Packit c4476c
# April 2014
Packit c4476c
#
Packit c4476c
# RC4 subroutine processes one byte in 7.0 cycles, which is 3x faster
Packit c4476c
# than TI CGT-generated code. Loop is scheduled in such way that
Packit c4476c
# there is only one reference to memory in each cycle. This is done
Packit c4476c
# to avoid L1D memory banking conflicts, see SPRU871 TI publication
Packit c4476c
# for further details. Otherwise it should be possible to schedule
Packit c4476c
# the loop for iteration interval of 6...
Packit c4476c
Packit c4476c
($KEY,$LEN,$INP,$OUT)=("A4","B4","A6","B6");
Packit c4476c
Packit c4476c
($KEYA,$XX,$TY,$xx,$ONE,$ret)=map("A$_",(5,7,8,9,1,2));
Packit c4476c
($KEYB,$YY,$TX,$tx,$SUM,$dat)=map("B$_",(5,7,8,9,1,2));
Packit c4476c
Packit c4476c
$code.=<<___;
Packit c4476c
	.text
Packit c4476c
Packit c4476c
	.if	.ASSEMBLER_VERSION<7000000
Packit c4476c
	.asg	0,__TI_EABI__
Packit c4476c
	.endif
Packit c4476c
	.if	__TI_EABI__
Packit c4476c
	.nocmp
Packit c4476c
	.asg	RC4,_RC4
Packit c4476c
	.asg	RC4_set_key,_RC4_set_key
Packit c4476c
	.asg	RC4_options,_RC4_options
Packit c4476c
	.endif
Packit c4476c
Packit c4476c
	.global	_RC4
Packit c4476c
	.align	16
Packit c4476c
_RC4:
Packit c4476c
	.asmfunc
Packit c4476c
	MV	$LEN,B0
Packit c4476c
  [!B0]	BNOP	B3			; if (len==0) return;
Packit c4476c
||[B0]	ADD	$KEY,2,$KEYA
Packit c4476c
||[B0]	ADD	$KEY,2,$KEYB
Packit c4476c
  [B0]	MVK	1,$ONE
Packit c4476c
||[B0]	LDBU	*${KEYA}[-2],$XX	; key->x
Packit c4476c
  [B0]	LDBU	*${KEYB}[-1],$YY	; key->y
Packit c4476c
||	NOP	4
Packit c4476c
Packit c4476c
	ADD4	$ONE,$XX,$XX
Packit c4476c
	LDBU	*${KEYA}[$XX],$TX
Packit c4476c
||	MVC	$LEN,ILC
Packit c4476c
	NOP	4
Packit c4476c
;;==================================================
Packit c4476c
	SPLOOP	7
Packit c4476c
||	ADD4	$TX,$YY,$YY
Packit c4476c
Packit c4476c
	LDBU	*${KEYB}[$YY],$TY
Packit c4476c
||	MVD	$XX,$xx
Packit c4476c
||	ADD4	$ONE,$XX,$XX
Packit c4476c
	LDBU	*${KEYA}[$XX],$tx
Packit c4476c
	CMPEQ	$YY,$XX,B0
Packit c4476c
||	NOP	3
Packit c4476c
	STB	$TX,*${KEYB}[$YY]
Packit c4476c
||[B0]	ADD4	$TX,$YY,$YY
Packit c4476c
	STB	$TY,*${KEYA}[$xx]
Packit c4476c
||[!B0]	ADD4	$tx,$YY,$YY
Packit c4476c
||[!B0]	MVD	$tx,$TX
Packit c4476c
	ADD4	$TY,$TX,$SUM		; [0,0] $TX is not replaced by $tx yet!
Packit c4476c
||	NOP	2
Packit c4476c
	LDBU	*$INP++,$dat
Packit c4476c
||	NOP	2
Packit c4476c
	LDBU	*${KEYB}[$SUM],$ret
Packit c4476c
||	NOP	5
Packit c4476c
	XOR.L	$dat,$ret,$ret
Packit c4476c
	SPKERNEL
Packit c4476c
||	STB	$ret,*$OUT++
Packit c4476c
;;==================================================
Packit c4476c
	SUB4	$XX,$ONE,$XX
Packit c4476c
||	NOP	5
Packit c4476c
	STB	$XX,*${KEYA}[-2]	; key->x
Packit c4476c
||	SUB4	$YY,$TX,$YY
Packit c4476c
||	BNOP	B3
Packit c4476c
	STB	$YY,*${KEYB}[-1]	; key->y
Packit c4476c
||	NOP	5
Packit c4476c
	.endasmfunc
Packit c4476c
Packit c4476c
	.global	_RC4_set_key
Packit c4476c
	.align	16
Packit c4476c
_RC4_set_key:
Packit c4476c
	.asmfunc
Packit c4476c
	.if	.BIG_ENDIAN
Packit c4476c
	MVK	0x00000404,$ONE
Packit c4476c
||	MVK	0x00000203,B0
Packit c4476c
	MVKH	0x04040000,$ONE
Packit c4476c
||	MVKH	0x00010000,B0
Packit c4476c
	.else
Packit c4476c
	MVK	0x00000404,$ONE
Packit c4476c
||	MVK	0x00000100,B0
Packit c4476c
	MVKH	0x04040000,$ONE
Packit c4476c
||	MVKH	0x03020000,B0
Packit c4476c
	.endif
Packit c4476c
	ADD	$KEY,2,$KEYA
Packit c4476c
||	ADD	$KEY,2,$KEYB
Packit c4476c
||	ADD	$INP,$LEN,$ret		; end of input
Packit c4476c
	LDBU	*${INP}++,$dat
Packit c4476c
||	MVK	0,$TX
Packit c4476c
	STH	$TX,*${KEY}++		; key->x=key->y=0
Packit c4476c
||	MV	B0,A0
Packit c4476c
||	MVK	64-4,B0
Packit c4476c
Packit c4476c
;;==================================================
Packit c4476c
	SPLOOPD	1
Packit c4476c
||	MVC	B0,ILC
Packit c4476c
Packit c4476c
	STNW	A0,*${KEY}++
Packit c4476c
||	ADD4	$ONE,A0,A0
Packit c4476c
	SPKERNEL
Packit c4476c
;;==================================================
Packit c4476c
Packit c4476c
	MVK	0,$YY
Packit c4476c
||	MVK	0,$XX
Packit c4476c
	MVK	1,$ONE
Packit c4476c
||	MVK	256-1,B0
Packit c4476c
Packit c4476c
;;==================================================
Packit c4476c
	SPLOOPD	8
Packit c4476c
||	MVC	B0,ILC
Packit c4476c
Packit c4476c
	ADD4	$dat,$YY,$YY
Packit c4476c
||	CMPEQ	$INP,$ret,A0		; end of input?
Packit c4476c
	LDBU	*${KEYB}[$YY],$TY
Packit c4476c
||	MVD	$XX,$xx
Packit c4476c
||	ADD4	$ONE,$XX,$XX
Packit c4476c
	LDBU	*${KEYA}[$XX],$tx
Packit c4476c
||[A0]	SUB	$INP,$LEN,$INP		; rewind
Packit c4476c
	LDBU	*${INP}++,$dat
Packit c4476c
||	CMPEQ	$YY,$XX,B0
Packit c4476c
||	NOP	3
Packit c4476c
	STB	$TX,*${KEYB}[$YY]
Packit c4476c
||[B0]	ADD4	$TX,$YY,$YY
Packit c4476c
	STB	$TY,*${KEYA}[$xx]
Packit c4476c
||[!B0]	ADD4	$tx,$YY,$YY
Packit c4476c
||[!B0]	MV	$tx,$TX
Packit c4476c
	SPKERNEL
Packit c4476c
;;==================================================
Packit c4476c
Packit c4476c
	BNOP	B3,5
Packit c4476c
	.endasmfunc
Packit c4476c
Packit c4476c
	.global	_RC4_options
Packit c4476c
	.align	16
Packit c4476c
_RC4_options:
Packit c4476c
_rc4_options:
Packit c4476c
	.asmfunc
Packit c4476c
	BNOP	B3,1
Packit c4476c
	ADDKPC	_rc4_options,B4
Packit c4476c
	.if	__TI_EABI__
Packit c4476c
	MVKL	\$PCR_OFFSET(rc4_options,_rc4_options),A4
Packit c4476c
	MVKH	\$PCR_OFFSET(rc4_options,_rc4_options),A4
Packit c4476c
	.else
Packit c4476c
	MVKL	(rc4_options-_rc4_options),A4
Packit c4476c
	MVKH	(rc4_options-_rc4_options),A4
Packit c4476c
	.endif
Packit c4476c
	ADD	B4,A4,A4
Packit c4476c
	.endasmfunc
Packit c4476c
Packit c4476c
	.if	__TI_EABI__
Packit c4476c
	.sect	".text:rc4_options.const"
Packit c4476c
	.else
Packit c4476c
	.sect	".const:rc4_options"
Packit c4476c
	.endif
Packit c4476c
	.align	4
Packit c4476c
rc4_options:
Packit c4476c
	.cstring "rc4(sploop,char)"
Packit c4476c
	.cstring "RC4 for C64+, CRYPTOGAMS by <appro\@openssl.org>"
Packit c4476c
	.align	4
Packit c4476c
___
Packit c4476c
Packit c4476c
$output=pop;
Packit c4476c
open STDOUT,">$output";
Packit c4476c
print $code;
Packit c4476c
close STDOUT or die "error closing STDOUT: $!";