// Copyright 2021 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

//go:generate go run gen.go

// Package armneonintrinsics is a database of ARM Neon intrinsics - a list of C
// function signatures. It knows each function's name, return type and their
// arguments' names and types.
//
// It does not call or run those intrinsic functions (or the underlying CPU
// ops). It just lists their signatures (in a structured way, not as strings)
// so that other tools can more easily generate or bind to those C functions.
//
// See the example for more detail.
package armneonintrinsics

type element struct {
	stringTableOffset      uint16
	stringTableLengthFinal uint8 // The 0x80 bit indicates the final element.
	typ                    Type
}

func (e element) isFinal() bool {
	return (e.stringTableLengthFinal & 0x80) != 0
}

func (e element) name() string {
	i := int(e.stringTableOffset)
	j := int(e.stringTableOffset) + int(e.stringTableLength())
	return stringTable[i:j]
}

func (e element) stringTableLength() uint8 {
	return e.stringTableLengthFinal & 0x7F
}

// Argument is an intrinsic function's argument.
type Argument struct {
	index uint32
}

func (a Argument) IsValid() bool { return a.index != 0 }
func (a Argument) Name() string  { return elementTable[a.index].name() }
func (a Argument) Type() Type    { return elementTable[a.index].typ }

// NextArgument iterates through a function's arguments in call order. It
// returns an invalid Argument if called on the final argument.
func (a Argument) NextArgument() Argument {
	if (a.index == 0) || elementTable[a.index].isFinal() {
		return Argument{}
	}
	return Argument{a.index + 1}
}

// Argument is an intrinsic function.
type Function struct {
	index uint32
}

// FindFunction looks up a function by name, like "vsetq_lane_u8". It returns
// an invalid Function if no function has that name.
func FindFunction(cFuncName string) Function {
	hash := jenkins(cFuncName) & uint32(len(hashTable)-1)
	for {
		h := uint32(hashTable[hash])
		if h == 0 {
			break
		}
		if cFuncName == elementTable[h].name() {
			return Function{h}
		}
		hash = (hash + 1) & uint32(len(hashTable)-1)
	}
	return Function{}
}

// FirstFunction returns the first function (in alphabetical order). Calling
// NextFunction can then iterate through the remaining functions.
func FirstFunction() Function {
	return Function{1}
}

func (f Function) IsValid() bool    { return f.index != 0 }
func (f Function) Name() string     { return elementTable[f.index].name() }
func (f Function) ReturnType() Type { return elementTable[f.index].typ }

// NumArguments returns f's argument count.
func (f Function) NumArguments() int {
	n := 0
	for a := f.FirstArgument(); a.IsValid(); a = a.NextArgument() {
		n++
	}
	return n
}

// FirstArgument returns f's first argument. Calling NextArgument can then
// iterate through the remaining arguments. It returns an invalid Argument if f
// has no arguments.
func (f Function) FirstArgument() Argument {
	if (f.index == 0) || elementTable[f.index].isFinal() {
		return Argument{}
	}
	return Argument{f.index + 1}
}

// NextFunction iterates through the known Functions in alphabetical order. It
// returns an invalid Function if called on the final Function.
func (f Function) NextFunction() Function {
	if f.index == 0 {
		return Function{}
	}
	i := f.index
	for {
		i++
		if !elementTable[i-1].isFinal() {
			continue
		} else if int(i) < len(elementTable) {
			return Function{i}
		}
		break
	}
	return Function{}
}

// String returns the C function signature like "int8x8_t vaba_s8(int8x8_t __a,
// int8x8_t __b, int8x8_t __c)".
func (f Function) String() string {
	if f.index == 0 {
		return "no_such_function"
	}
	i := f.index
	elem := elementTable[i]
	b := make([]byte, 0, 256)
	b = elem.typ.appendString(b)
	b = append(b, ' ')
	b = append(b, elem.name()...)
	b = append(b, '(')
	for comma := false; !elem.isFinal(); comma = true {
		if comma {
			b = append(b, ", "...)
		}
		i++
		elem = elementTable[i]
		b = elem.typ.appendString(b)
		b = append(b, ' ')
		b = append(b, elem.name()...)
	}
	b = append(b, ')')
	return string(b)
}

// jenkins implements https://en.wikipedia.org/wiki/Jenkins_hash_function
func jenkins(s string) (hash uint32) {
	for i := 0; i < len(s); i++ {
		hash += uint32(s[i])
		hash += hash << 10
		hash ^= hash >> 6
	}
	hash += hash << 3
	hash ^= hash >> 11
	hash += hash << 15
	return hash
}
