Blame crypto/bn/asm/vis3-mont.pl

Packit Service 084de1
#! /usr/bin/env perl
Packit Service 084de1
# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
#
Packit Service 084de1
# Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
# this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
# in the file LICENSE in the source distribution or at
Packit Service 084de1
# https://www.openssl.org/source/license.html
Packit Service 084de1
Packit Service 084de1
Packit Service 084de1
# ====================================================================
Packit Service 084de1
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
Packit Service 084de1
# project. The module is, however, dual licensed under OpenSSL and
Packit Service 084de1
# CRYPTOGAMS licenses depending on where you obtain it. For further
Packit Service 084de1
# details see http://www.openssl.org/~appro/cryptogams/.
Packit Service 084de1
# ====================================================================
Packit Service 084de1
Packit Service 084de1
# October 2012.
Packit Service 084de1
#
Packit Service 084de1
# SPARCv9 VIS3 Montgomery multiplication procedure suitable for T3 and
Packit Service 084de1
# onward. There are three new instructions used here: umulxhi,
Packit Service 084de1
# addxc[cc] and initializing store. On T3 RSA private key operations
Packit Service 084de1
# are 1.54/1.87/2.11/2.26 times faster for 512/1024/2048/4096-bit key
Packit Service 084de1
# lengths. This is without dedicated squaring procedure. On T4
Packit Service 084de1
# corresponding coefficients are 1.47/2.10/2.80/2.90x, which is mostly
Packit Service 084de1
# for reference purposes, because T4 has dedicated Montgomery
Packit Service 084de1
# multiplication and squaring *instructions* that deliver even more.
Packit Service 084de1
Packit Service 084de1
$output = pop;
Packit Service 084de1
open STDOUT,">$output";
Packit Service 084de1
Packit Service 084de1
$frame = "STACK_FRAME";
Packit Service 084de1
$bias = "STACK_BIAS";
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
#include "sparc_arch.h"
Packit Service 084de1
Packit Service 084de1
#ifdef	__arch64__
Packit Service 084de1
.register	%g2,#scratch
Packit Service 084de1
.register	%g3,#scratch
Packit Service 084de1
#endif
Packit Service 084de1
Packit Service 084de1
.section	".text",#alloc,#execinstr
Packit Service 084de1
___
Packit Service 084de1
Packit Service 084de1
($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
Packit Service 084de1
	(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
Packit Service 084de1
Packit Service 084de1
# int bn_mul_mont(
Packit Service 084de1
$rp="%o0";	# BN_ULONG *rp,
Packit Service 084de1
$ap="%o1";	# const BN_ULONG *ap,
Packit Service 084de1
$bp="%o2";	# const BN_ULONG *bp,
Packit Service 084de1
$np="%o3";	# const BN_ULONG *np,
Packit Service 084de1
$n0p="%o4";	# const BN_ULONG *n0,
Packit Service 084de1
$num="%o5";	# int num);	# caller ensures that num is even
Packit Service 084de1
				# and >=6
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
.globl	bn_mul_mont_vis3
Packit Service 084de1
.align	32
Packit Service 084de1
bn_mul_mont_vis3:
Packit Service 084de1
	add	%sp,	$bias,	%g4	! real top of stack
Packit Service 084de1
	sll	$num,	2,	$num	! size in bytes
Packit Service 084de1
	add	$num,	63,	%g5
Packit Service 084de1
	andn	%g5,	63,	%g5	! buffer size rounded up to 64 bytes
Packit Service 084de1
	add	%g5,	%g5,	%g1
Packit Service 084de1
	add	%g5,	%g1,	%g1	! 3*buffer size
Packit Service 084de1
	sub	%g4,	%g1,	%g1
Packit Service 084de1
	andn	%g1,	63,	%g1	! align at 64 byte
Packit Service 084de1
	sub	%g1,	$frame,	%g1	! new top of stack
Packit Service 084de1
	sub	%g1,	%g4,	%g1
Packit Service 084de1
Packit Service 084de1
	save	%sp,	%g1,	%sp
Packit Service 084de1
___
Packit Service 084de1

Packit Service 084de1
#	+-------------------------------+<-----	%sp
Packit Service 084de1
#	.				.
Packit Service 084de1
#	+-------------------------------+<-----	aligned at 64 bytes
Packit Service 084de1
#	| __int64 tmp[0]		|
Packit Service 084de1
#	+-------------------------------+
Packit Service 084de1
#	.				.
Packit Service 084de1
#	.				.
Packit Service 084de1
#	+-------------------------------+<----- aligned at 64 bytes
Packit Service 084de1
#	| __int64 ap[1..0]		|	converted ap[]
Packit Service 084de1
#	+-------------------------------+
Packit Service 084de1
#	| __int64 np[1..0]		|	converted np[]
Packit Service 084de1
#	+-------------------------------+
Packit Service 084de1
#	| __int64 ap[3..2]		|
Packit Service 084de1
#	.				.
Packit Service 084de1
#	.				.
Packit Service 084de1
#	+-------------------------------+
Packit Service 084de1
($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
Packit Service 084de1
($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$anp)=map("%l$_",(0..7));
Packit Service 084de1
($ovf,$i)=($t0,$t1);
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
	ld	[$n0p+0],	$t0	! pull n0[0..1] value
Packit Service 084de1
	add	%sp, $bias+$frame, $tp
Packit Service 084de1
	ld	[$n0p+4],	$t1
Packit Service 084de1
	add	$tp,	%g5,	$anp
Packit Service 084de1
	ld	[$bp+0],	$t2	! m0=bp[0]
Packit Service 084de1
	sllx	$t1,	32,	$n0
Packit Service 084de1
	ld	[$bp+4],	$t3
Packit Service 084de1
	or	$t0,	$n0,	$n0
Packit Service 084de1
	add	$bp,	8,	$bp
Packit Service 084de1

Packit Service 084de1
	ld	[$ap+0],	$t0	! ap[0]
Packit Service 084de1
	sllx	$t3,	32,	$m0
Packit Service 084de1
	ld	[$ap+4],	$t1
Packit Service 084de1
	or	$t2,	$m0,	$m0
Packit Service 084de1
Packit Service 084de1
	ld	[$ap+8],	$t2	! ap[1]
Packit Service 084de1
	sllx	$t1,	32,	$aj
Packit Service 084de1
	ld	[$ap+12],	$t3
Packit Service 084de1
	or	$t0,	$aj,	$aj
Packit Service 084de1
	add	$ap,	16,	$ap
Packit Service 084de1
	stx	$aj,	[$anp]		! converted ap[0]
Packit Service 084de1
Packit Service 084de1
	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
Packit Service 084de1
	umulxhi	$aj,	$m0,	$hi0
Packit Service 084de1
Packit Service 084de1
	ld	[$np+0],	$t0	! np[0]
Packit Service 084de1
	sllx	$t3,	32,	$aj
Packit Service 084de1
	ld	[$np+4],	$t1
Packit Service 084de1
	or	$t2,	$aj,	$aj
Packit Service 084de1
Packit Service 084de1
	ld	[$np+8],	$t2	! np[1]
Packit Service 084de1
	sllx	$t1,	32,	$nj
Packit Service 084de1
	ld	[$np+12],	$t3
Packit Service 084de1
	or	$t0, $nj,	$nj
Packit Service 084de1
	add	$np,	16,	$np
Packit Service 084de1
	stx	$nj,	[$anp+8]	! converted np[0]
Packit Service 084de1
Packit Service 084de1
	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
Packit Service 084de1
	stx	$aj,	[$anp+16]	! converted ap[1]
Packit Service 084de1
Packit Service 084de1
	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
Packit Service 084de1
	umulxhi	$aj,	$m0,	$aj	! ahi=aj
Packit Service 084de1
Packit Service 084de1
	mulx	$nj,	$m1,	$lo1	! np[0]*m1
Packit Service 084de1
	umulxhi	$nj,	$m1,	$hi1
Packit Service 084de1
Packit Service 084de1
	sllx	$t3,	32,	$nj
Packit Service 084de1
	or	$t2,	$nj,	$nj
Packit Service 084de1
	stx	$nj,	[$anp+24]	! converted np[1]
Packit Service 084de1
	add	$anp,	32,	$anp
Packit Service 084de1
Packit Service 084de1
	addcc	$lo0,	$lo1,	$lo1
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
Packit Service 084de1
	mulx	$nj,	$m1,	$nlo	! np[1]*m1
Packit Service 084de1
	umulxhi	$nj,	$m1,	$nj	! nhi=nj
Packit Service 084de1

Packit Service 084de1
	ba	.L1st
Packit Service 084de1
	sub	$num,	24,	$cnt	! cnt=num-3
Packit Service 084de1
Packit Service 084de1
.align	16
Packit Service 084de1
.L1st:
Packit Service 084de1
	ld	[$ap+0],	$t0	! ap[j]
Packit Service 084de1
	addcc	$alo,	$hi0,	$lo0
Packit Service 084de1
	ld	[$ap+4],	$t1
Packit Service 084de1
	addxc	$aj,	%g0,	$hi0
Packit Service 084de1
Packit Service 084de1
	sllx	$t1,	32,	$aj
Packit Service 084de1
	add	$ap,	8,	$ap
Packit Service 084de1
	or	$t0,	$aj,	$aj
Packit Service 084de1
	stx	$aj,	[$anp]		! converted ap[j]
Packit Service 084de1
Packit Service 084de1
	ld	[$np+0],	$t2	! np[j]
Packit Service 084de1
	addcc	$nlo,	$hi1,	$lo1
Packit Service 084de1
	ld	[$np+4],	$t3
Packit Service 084de1
	addxc	$nj,	%g0,	$hi1	! nhi=nj
Packit Service 084de1
Packit Service 084de1
	sllx	$t3,	32,	$nj
Packit Service 084de1
	add	$np,	8,	$np
Packit Service 084de1
	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
Packit Service 084de1
	or	$t2,	$nj,	$nj
Packit Service 084de1
	umulxhi	$aj,	$m0,	$aj	! ahi=aj
Packit Service 084de1
	stx	$nj,	[$anp+8]	! converted np[j]
Packit Service 084de1
	add	$anp,	16,	$anp	! anp++
Packit Service 084de1
Packit Service 084de1
	mulx	$nj,	$m1,	$nlo	! np[j]*m1
Packit Service 084de1
	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
Packit Service 084de1
	umulxhi	$nj,	$m1,	$nj	! nhi=nj
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
	stx	$lo1,	[$tp]		! tp[j-1]
Packit Service 084de1
	add	$tp,	8,	$tp	! tp++
Packit Service 084de1
Packit Service 084de1
	brnz,pt	$cnt,	.L1st
Packit Service 084de1
	sub	$cnt,	8,	$cnt	! j--
Packit Service 084de1
!.L1st
Packit Service 084de1
	addcc	$alo,	$hi0,	$lo0
Packit Service 084de1
	addxc	$aj,	%g0,	$hi0	! ahi=aj
Packit Service 084de1
Packit Service 084de1
	addcc	$nlo,	$hi1,	$lo1
Packit Service 084de1
	addxc	$nj,	%g0,	$hi1
Packit Service 084de1
	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
	stx	$lo1,	[$tp]		! tp[j-1]
Packit Service 084de1
	add	$tp,	8,	$tp
Packit Service 084de1
Packit Service 084de1
	addcc	$hi0,	$hi1,	$hi1
Packit Service 084de1
	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
Packit Service 084de1
	stx	$hi1,	[$tp]
Packit Service 084de1
	add	$tp,	8,	$tp
Packit Service 084de1

Packit Service 084de1
	ba	.Louter
Packit Service 084de1
	sub	$num,	16,	$i	! i=num-2
Packit Service 084de1
Packit Service 084de1
.align	16
Packit Service 084de1
.Louter:
Packit Service 084de1
	ld	[$bp+0],	$t2	! m0=bp[i]
Packit Service 084de1
	ld	[$bp+4],	$t3
Packit Service 084de1
Packit Service 084de1
	sub	$anp,	$num,	$anp	! rewind
Packit Service 084de1
	sub	$tp,	$num,	$tp
Packit Service 084de1
	sub	$anp,	$num,	$anp
Packit Service 084de1
Packit Service 084de1
	add	$bp,	8,	$bp
Packit Service 084de1
	sllx	$t3,	32,	$m0
Packit Service 084de1
	ldx	[$anp+0],	$aj	! ap[0]
Packit Service 084de1
	or	$t2,	$m0,	$m0
Packit Service 084de1
	ldx	[$anp+8],	$nj	! np[0]
Packit Service 084de1
Packit Service 084de1
	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
Packit Service 084de1
	ldx	[$tp],		$tj	! tp[0]
Packit Service 084de1
	umulxhi	$aj,	$m0,	$hi0
Packit Service 084de1
	ldx	[$anp+16],	$aj	! ap[1]
Packit Service 084de1
	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
Packit Service 084de1
	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
Packit Service 084de1
	addxc	%g0,	$hi0,	$hi0
Packit Service 084de1
	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
Packit Service 084de1
	umulxhi	$aj,	$m0,	$aj	! ahi=aj
Packit Service 084de1
	mulx	$nj,	$m1,	$lo1	! np[0]*m1
Packit Service 084de1
	umulxhi	$nj,	$m1,	$hi1
Packit Service 084de1
	ldx	[$anp+24],	$nj	! np[1]
Packit Service 084de1
	add	$anp,	32,	$anp
Packit Service 084de1
	addcc	$lo1,	$lo0,	$lo1
Packit Service 084de1
	mulx	$nj,	$m1,	$nlo	! np[1]*m1
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
	umulxhi	$nj,	$m1,	$nj	! nhi=nj
Packit Service 084de1

Packit Service 084de1
	ba	.Linner
Packit Service 084de1
	sub	$num,	24,	$cnt	! cnt=num-3
Packit Service 084de1
.align	16
Packit Service 084de1
.Linner:
Packit Service 084de1
	addcc	$alo,	$hi0,	$lo0
Packit Service 084de1
	ldx	[$tp+8],	$tj	! tp[j]
Packit Service 084de1
	addxc	$aj,	%g0,	$hi0	! ahi=aj
Packit Service 084de1
	ldx	[$anp+0],	$aj	! ap[j]
Packit Service 084de1
	addcc	$nlo,	$hi1,	$lo1
Packit Service 084de1
	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
Packit Service 084de1
	addxc	$nj,	%g0,	$hi1	! nhi=nj
Packit Service 084de1
	ldx	[$anp+8],	$nj	! np[j]
Packit Service 084de1
	add	$anp,	16,	$anp
Packit Service 084de1
	umulxhi	$aj,	$m0,	$aj	! ahi=aj
Packit Service 084de1
	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
Packit Service 084de1
	mulx	$nj,	$m1,	$nlo	! np[j]*m1
Packit Service 084de1
	addxc	%g0,	$hi0,	$hi0
Packit Service 084de1
	umulxhi	$nj,	$m1,	$nj	! nhi=nj
Packit Service 084de1
	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
	stx	$lo1,	[$tp]		! tp[j-1]
Packit Service 084de1
	add	$tp,	8,	$tp
Packit Service 084de1
	brnz,pt	$cnt,	.Linner
Packit Service 084de1
	sub	$cnt,	8,	$cnt
Packit Service 084de1
!.Linner
Packit Service 084de1
	ldx	[$tp+8],	$tj	! tp[j]
Packit Service 084de1
	addcc	$alo,	$hi0,	$lo0
Packit Service 084de1
	addxc	$aj,	%g0,	$hi0	! ahi=aj
Packit Service 084de1
	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
Packit Service 084de1
	addxc	%g0,	$hi0,	$hi0
Packit Service 084de1
Packit Service 084de1
	addcc	$nlo,	$hi1,	$lo1
Packit Service 084de1
	addxc	$nj,	%g0,	$hi1	! nhi=nj
Packit Service 084de1
	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
Packit Service 084de1
	addxc	%g0,	$hi1,	$hi1
Packit Service 084de1
	stx	$lo1,	[$tp]		! tp[j-1]
Packit Service 084de1
Packit Service 084de1
	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
Packit Service 084de1
	addxccc	$hi1,	$hi0,	$hi1
Packit Service 084de1
	addxc	%g0,	%g0,	$ovf
Packit Service 084de1
	stx	$hi1,	[$tp+8]
Packit Service 084de1
	add	$tp,	16,	$tp
Packit Service 084de1
Packit Service 084de1
	brnz,pt	$i,	.Louter
Packit Service 084de1
	sub	$i,	8,	$i
Packit Service 084de1

Packit Service 084de1
	sub	$anp,	$num,	$anp	! rewind
Packit Service 084de1
	sub	$tp,	$num,	$tp
Packit Service 084de1
	sub	$anp,	$num,	$anp
Packit Service 084de1
	ba	.Lsub
Packit Service 084de1
	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
Packit Service 084de1
Packit Service 084de1
.align	16
Packit Service 084de1
.Lsub:
Packit Service 084de1
	ldx	[$tp],		$tj
Packit Service 084de1
	add	$tp,	8,	$tp
Packit Service 084de1
	ldx	[$anp+8],	$nj
Packit Service 084de1
	add	$anp,	16,	$anp
Packit Service 084de1
	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
Packit Service 084de1
	srlx	$tj,	32,	$tj
Packit Service 084de1
	srlx	$nj,	32,	$nj
Packit Service 084de1
	subccc	$tj,	$nj,	$t3
Packit Service 084de1
	add	$rp,	8,	$rp
Packit Service 084de1
	st	$t2,	[$rp-4]		! reverse order
Packit Service 084de1
	st	$t3,	[$rp-8]
Packit Service 084de1
	brnz,pt	$cnt,	.Lsub
Packit Service 084de1
	sub	$cnt,	8,	$cnt
Packit Service 084de1
Packit Service 084de1
	sub	$anp,	$num,	$anp	! rewind
Packit Service 084de1
	sub	$tp,	$num,	$tp
Packit Service 084de1
	sub	$anp,	$num,	$anp
Packit Service 084de1
	sub	$rp,	$num,	$rp
Packit Service 084de1
Packit Service 084de1
	subccc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
Packit Service 084de1
	ba	.Lcopy
Packit Service 084de1
	sub	$num,	8,	$cnt
Packit Service 084de1
Packit Service 084de1
.align	16
Packit Service 084de1
.Lcopy:					! conditional copy
Packit Service 084de1
	ld	[$tp+0],	$t0
Packit Service 084de1
	ld	[$tp+4],	$t1
Packit Service 084de1
	ld	[$rp+0],	$t2
Packit Service 084de1
	ld	[$rp+4],	$t3
Packit Service 084de1
	stx	%g0,	[$tp]		! zap
Packit Service 084de1
	add	$tp,	8,	$tp
Packit Service 084de1
	stx	%g0,	[$anp]		! zap
Packit Service 084de1
	stx	%g0,	[$anp+8]
Packit Service 084de1
	add	$anp,	16,	$anp
Packit Service 084de1
	movcs	%icc,	$t0,	$t2
Packit Service 084de1
	movcs	%icc,	$t1,	$t3
Packit Service 084de1
	st	$t3,	[$rp+0]		! flip order
Packit Service 084de1
	st	$t2,	[$rp+4]
Packit Service 084de1
	add	$rp,	8,	$rp
Packit Service 084de1
	brnz	$cnt,	.Lcopy
Packit Service 084de1
	sub	$cnt,	8,	$cnt
Packit Service 084de1
Packit Service 084de1
	mov	1,	%o0
Packit Service 084de1
	ret
Packit Service 084de1
	restore
Packit Service 084de1
.type	bn_mul_mont_vis3, #function
Packit Service 084de1
.size	bn_mul_mont_vis3, .-bn_mul_mont_vis3
Packit Service 084de1
.asciz  "Montgomery Multiplication for SPARCv9 VIS3, CRYPTOGAMS by <appro\@openssl.org>"
Packit Service 084de1
.align	4
Packit Service 084de1
___
Packit Service 084de1

Packit Service 084de1
# Purpose of these subroutines is to explicitly encode VIS instructions,
Packit Service 084de1
# so that one can compile the module without having to specify VIS
Packit Service 084de1
# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
Packit Service 084de1
# Idea is to reserve for option to produce "universal" binary and let
Packit Service 084de1
# programmer detect if current CPU is VIS capable at run-time.
Packit Service 084de1
sub unvis3 {
Packit Service 084de1
my ($mnemonic,$rs1,$rs2,$rd)=@_;
Packit Service 084de1
my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
Packit Service 084de1
my ($ref,$opf);
Packit Service 084de1
my %visopf = (	"addxc"		=> 0x011,
Packit Service 084de1
		"addxccc"	=> 0x013,
Packit Service 084de1
		"umulxhi"	=> 0x016	);
Packit Service 084de1
Packit Service 084de1
    $ref = "$mnemonic\t$rs1,$rs2,$rd";
Packit Service 084de1
Packit Service 084de1
    if ($opf=$visopf{$mnemonic}) {
Packit Service 084de1
	foreach ($rs1,$rs2,$rd) {
Packit Service 084de1
	    return $ref if (!/%([goli])([0-9])/);
Packit Service 084de1
	    $_=$bias{$1}+$2;
Packit Service 084de1
	}
Packit Service 084de1
Packit Service 084de1
	return	sprintf ".word\t0x%08x !%s",
Packit Service 084de1
			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
Packit Service 084de1
			$ref;
Packit Service 084de1
    } else {
Packit Service 084de1
	return $ref;
Packit Service 084de1
    }
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
foreach (split("\n",$code)) {
Packit Service 084de1
	s/\`([^\`]*)\`/eval $1/ge;
Packit Service 084de1
Packit Service 084de1
	s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
Packit Service 084de1
		&unvis3($1,$2,$3,$4)
Packit Service 084de1
	 /ge;
Packit Service 084de1
Packit Service 084de1
	print $_,"\n";
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
close STDOUT or die "error closing STDOUT: $!";