// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ppc64le,!gccgo,!appengine

package chacha20

import (
	"encoding/binary"
)

var haveAsm = true

const bufSize = 256

//go:noescape
func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)

func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
	// This implementation can handle buffers that aren't multiples of
	// 256.
	if len(src) >= bufSize {
		chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)
	} else if len(src)%bufSize != 0 {
		chaCha20_ctr32_vsx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter)
		start := len(src) - len(src)%bufSize
		ts, td, tb := src[start:], dst[start:], c.buf[:]
		// Unroll loop to XOR 32 bytes per iteration.
		for i := 0; i < len(ts)-32; i += 32 {
			td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
			s0 := binary.LittleEndian.Uint64(ts[0:8])
			s1 := binary.LittleEndian.Uint64(ts[8:16])
			s2 := binary.LittleEndian.Uint64(ts[16:24])
			s3 := binary.LittleEndian.Uint64(ts[24:32])
			b0 := binary.LittleEndian.Uint64(tb[0:8])
			b1 := binary.LittleEndian.Uint64(tb[8:16])
			b2 := binary.LittleEndian.Uint64(tb[16:24])
			b3 := binary.LittleEndian.Uint64(tb[24:32])
			binary.LittleEndian.PutUint64(td[0:8], s0^b0)
			binary.LittleEndian.PutUint64(td[8:16], s1^b1)
			binary.LittleEndian.PutUint64(td[16:24], s2^b2)
			binary.LittleEndian.PutUint64(td[24:32], s3^b3)
			ts, td, tb = ts[32:], td[32:], tb[32:]
		}
		td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination
		for i, v := range ts {
			td[i] = tb[i] ^ v
		}
		c.len = bufSize - (len(src) % bufSize)
	}

}
