
;; multi-dimensional arrays macros 2005-01-26
;; by Beppe(beppe85@gmail.com)

include '%fasminc%/win32ax.inc'

macro do_fix name,[value] { common name fix value }

macro ARRAY name, size, [dim]
{
common
  local ..len
  ..len = 1
name:
forward
  ..len = ..len * dim
common
;  times size * ..len db 0
  rb size * ..len
  do_fix bounds.#name, dim
  elem.#name = size
}

macro __mulsl dim, ret_size, [dimensions]
{
common
  local ..dim, ..size
  ..dim = dim
  ..size = 1
reverse
  if ..dim > 0
    ..dim = ..dim - 1
    ..size = dimensions * ..size
  end if
common
  ret_size = ..size
}

macro mulsl dim, ret_size, [dimensions] { common __mulsl dim, ret_size, dimensions }

macro mdl dest, array, [dim]
{
common
  local ..size, ..count
  ..count = 0
  xor eax, eax
reverse
  if ~ dim2 eq
      mulsl ..count, ..size, bounds.#array
      if dim eqtype 0
	add  eax, dim * ..size * elem.#array
      else
	imul edx, dim, ..size * elem.#array
	add  eax, edx
      end if
  end if
  ..count = ..count + 1
common
  mov dest, [array + eax]
}

macro mds src, array, [dim]
{
common
  local ..size, ..count
  ..count = 0
  xor eax, eax
reverse
  if ~ dim2 eq
      mulsl ..count, ..size, bounds.#array
      if dim eqtype 0
	add  eax, dim * ..size * elem.#array
      else
	imul edx, dim, ..size * elem.#array
	add  eax, edx
      end if
  end if
  ..count = ..count + 1
common
  mov [array + eax], src
}

macro mda dest, array, [dim]
{
common
  local ..size, ..count
  ..count = 0
  xor eax, eax
reverse
  if ~ dim2 eq
      mulsl ..count, ..size, bounds.#array
      if dim eqtype 0
	add  eax, dim * ..size * elem.#array
      else
	imul edx, dim, ..size * elem.#array
	add  eax, edx
      end if
  end if
  ..count = ..count + 1
common
  lea dest, [array + eax]
}

ARRAY arr, 4, 4, 7, 9

.code
Main:
	; ecx := arr[3, 5, 8]
	mdl ecx, arr, 3, 5, 8
	mov edi, 3
	mov esi, 5
	mov ebp, 8
	; arr[3, 5, 8] := ecx
	mds ecx, arr, edi, esi, ebp
	; ecx := @arr[3, 5, 8]
	mda ecx, arr, edi, esi, ebp
	ret
.end Main