// Copyright 2009 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.

package ogle

import (
	"debug/proc";
	"math";
)

type Arch interface {
	// ToWord converts an array of up to 8 bytes in memory order
	// to a word.
	ToWord(data []byte) proc.Word;
	// FromWord converts a word to an array of up to 8 bytes in
	// memory order.
	FromWord(v proc.Word, out []byte);
	// ToFloat32 converts a word to a float.  The order of this
	// word will be the order returned by ToWord on the memory
	// representation of a float, and thus may require reversing.
	ToFloat32(bits uint32) float32;
	// FromFloat32 converts a float to a word.  This should return
	// a word that can be passed to FromWord to get the memory
	// representation of a float on this architecture.
	FromFloat32(f float32) uint32;
	// ToFloat64 is to float64 as ToFloat32 is to float32.
	ToFloat64(bits uint64) float64;
	// FromFloat64 is to float64 as FromFloat32 is to float32.
	FromFloat64(f float64) uint64;

	// IntSize returns the number of bytes in an 'int'.
	IntSize() int;
	// PtrSize returns the number of bytes in a 'uintptr'.
	PtrSize() int;
	// FloatSize returns the number of bytes in a 'float'.
	FloatSize() int;
	// Align rounds offset up to the appropriate offset for a
	// basic type with the given width.
	Align(offset, width int) int;

	// G returns the current G pointer.
	G(regs proc.Regs) proc.Word;

	// ClosureSize returns the number of bytes expected by
	// ParseClosure.
	ClosureSize() int;
	// ParseClosure takes ClosureSize bytes read from a return PC
	// in a remote process, determines if the code is a closure,
	// and returns the frame size of the closure if it is.
	ParseClosure(data []byte) (frame int, ok bool);
}

type ArchLSB struct{}

func (ArchLSB) ToWord(data []byte) proc.Word {
	var v proc.Word;
	for i, b := range data {
		v |= proc.Word(b) << (uint(i) * 8)
	}
	return v;
}

func (ArchLSB) FromWord(v proc.Word, out []byte) {
	for i := range out {
		out[i] = byte(v);
		v >>= 8;
	}
}

func (ArchLSB) ToFloat32(bits uint32) float32 {
	// TODO(austin) Do these definitions depend on my current
	// architecture?
	return math.Float32frombits(bits)
}

func (ArchLSB) FromFloat32(f float32) uint32	{ return math.Float32bits(f) }

func (ArchLSB) ToFloat64(bits uint64) float64	{ return math.Float64frombits(bits) }

func (ArchLSB) FromFloat64(f float64) uint64	{ return math.Float64bits(f) }

type ArchAlignedMultiple struct{}

func (ArchAlignedMultiple) Align(offset, width int) int {
	return ((offset - 1) | (width - 1)) + 1
}

type amd64 struct {
	ArchLSB;
	ArchAlignedMultiple;
	gReg	int;
}

func (a *amd64) IntSize() int	{ return 4 }

func (a *amd64) PtrSize() int	{ return 8 }

func (a *amd64) FloatSize() int	{ return 4 }

func (a *amd64) G(regs proc.Regs) proc.Word {
	// See src/pkg/runtime/mkasmh
	if a.gReg == -1 {
		ns := regs.Names();
		for i, n := range ns {
			if n == "r15" {
				a.gReg = i;
				break;
			}
		}
	}

	return regs.Get(a.gReg);
}

func (a *amd64) ClosureSize() int	{ return 8 }

func (a *amd64) ParseClosure(data []byte) (int, bool) {
	if data[0] == 0x48 && data[1] == 0x81 && data[2] == 0xc4 && data[7] == 0xc3 {
		return int(a.ToWord(data[3:7]) + 8), true
	}
	return 0, false;
}

var Amd64 = &amd64{gReg: -1}
