mfc_tag_release.c: New file.

* config/spu/mfc_tag_release.c: New file.
	* config/spu/mfc_multi_tag_release.c: Likewise.
	* config/spu/mfc_multi_tag_reserve.c: Likewise.
	* config/spu/mfc_tag_release.c: Likewise.
	* config/spu/mfc_tag_reserve.c: Likewise.
	* config/spu/mfc_tag_table.c: Likewise.
	* config/spu/t-spu-elf (LIB2FUNCS_STATIC_EXTRA): Compile them.
	(TARGET_LIBGCC2_CFLAGS): Define __IN_LIBGCC2.
	* config/spu/spu_mfcio.h (uint64_t): Typedef if __IN_LIBGCC2
	is defined and avoid <stdint.h>.
	(MFC_TAG_INVALID, MFC_TAG_VALID): New macros.
	(mfc_tag_reserve, mfc_tag_release, mfc_multi_tag_reserve,
	mfc_multi_tag_release): Likewise.
	(__mfc_tag_reserve, __mfc_tag_release, __mfc_multi_tag_reserve,
	__mfc_multi_tag_release): Declare.

Co-Authored-By: Ben Elliston <bje@au.ibm.com>

From-SVN: r130306
This commit is contained in:
Ulrich Weigand 2007-11-20 16:12:09 +11:00 committed by Ben Elliston
parent 457784b849
commit 1763dfa74d
9 changed files with 693 additions and 2 deletions

View File

@ -1,3 +1,22 @@
2007-11-20 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Ben Elliston <bje@au.ibm.com>
* config/spu/mfc_tag_release.c: New file.
* config/spu/mfc_multi_tag_release.c: Likewise.
* config/spu/mfc_multi_tag_reserve.c: Likewise.
* config/spu/mfc_tag_release.c: Likewise.
* config/spu/mfc_tag_reserve.c: Likewise.
* config/spu/mfc_tag_table.c: Likewise.
* config/spu/t-spu-elf (LIB2FUNCS_STATIC_EXTRA): Compile them.
(TARGET_LIBGCC2_CFLAGS): Define __IN_LIBGCC2.
* config/spu/spu_mfcio.h: Avoid <stdint.h>.
(uint64_t): Typedef if __IN_LIBGCC2 is defined.
(MFC_TAG_INVALID, MFC_TAG_VALID): New macros.
(mfc_tag_reserve, mfc_tag_release, mfc_multi_tag_reserve,
mfc_multi_tag_release): Likewise.
(__mfc_tag_reserve, __mfc_tag_release, __mfc_multi_tag_reserve,
__mfc_multi_tag_release): Declare.
2007-11-19 Jason Merrill <jason@redhat.com>
PR debug/28834, debug/29436, c/32326

View File

@ -0,0 +1,77 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include <spu_mfcio.h>
extern vector unsigned int __mfc_tag_table;
/* Release a sequential group of tags from exclusive use. The sequential
group of tags is the range starting from <first_tag> through
<first_tag>+<number_of_tags>-1. Upon sucessful release, MFC_DMA_TAG_VALID
is returned and the tags become available for future reservation.
If the specified tags were not previously reserved, no action is
taken and MFC_DMA_TAG_INVALID is returned. */
unsigned int
__mfc_multi_tag_release (unsigned int first_tag, unsigned int number_of_tags)
{
vector unsigned int table_copy, tmp, tmp1;
vector unsigned int one = (vector unsigned int)
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
vector unsigned int is_invalid;
unsigned int last_tag;
vector unsigned int has_been_reserved;
last_tag = first_tag + number_of_tags;
table_copy = spu_sl (one, number_of_tags);
table_copy = spu_rl (table_copy, -last_tag);
table_copy = spu_xor (table_copy, -1);
/* Make sure the tags are in range and valid. */
tmp = spu_cmpgt (spu_promote(last_tag, 0), 32);
tmp1 = spu_cmpgt (spu_promote(number_of_tags, 0), 32);
is_invalid = spu_cmpgt (spu_promote(first_tag, 0), 31);
/* All bits are set to 1 if invalid, 0 if valid. */
is_invalid = spu_or (tmp, is_invalid);
is_invalid = spu_or (tmp1, is_invalid);
/* check whether these tags have been reserved */
tmp = spu_rlmask (one, (int)-number_of_tags);
tmp1 = spu_sl (__mfc_tag_table, first_tag);
has_been_reserved = spu_cmpgt(tmp1, tmp);
is_invalid = spu_or (has_been_reserved, is_invalid);
table_copy = spu_sel (__mfc_tag_table, table_copy, table_copy);
__mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_invalid);
return spu_extract (is_invalid, 0);
}

View File

@ -0,0 +1,89 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include <spu_mfcio.h>
extern vector unsigned int __mfc_tag_table;
/* Reserve a sequential group of tags for exclusive use. The number of
tags to be reserved is specified by the <number_of_tags> parameter.
This routine returns the first tag ID for a sequential list of
available tags and marks them as reserved. The reserved group
of tags is in the range starting from the returned tag through
the returned tag + <number_of_tags>-1.
If the number of tags requested exceeds the number of available
sequential tags, then MFC_DMA_TAG_INVALID is returned indicating
that the request could not be serviced. */
unsigned int
__mfc_multi_tag_reserve (unsigned int number_of_tags)
{
vector unsigned int table_copy;
vector unsigned int one = (vector unsigned int)
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
vector unsigned int count_busy, is_valid;
vector unsigned int count_total;
vector unsigned int count_avail = (vector unsigned int) { 0, 0, 0, 0 };
vector unsigned int index = (vector unsigned int) { 0, 0, 0, 0 };
table_copy = __mfc_tag_table;
/* count_busy: number of consecutive busy tags
count_avail: number of consecutive free tags
table_copy: temporary copy of the tag table
count_total: sum of count_busy and count_avail
index: index of the current working tag */
do
{
table_copy = spu_sl (table_copy, count_avail);
count_busy = spu_cntlz (table_copy);
table_copy = spu_sl (table_copy, count_busy);
count_avail = spu_cntlz (spu_xor(table_copy, -1));
count_total = spu_add (count_busy, count_avail);
index = spu_add (index, count_total);
}
while (spu_extract (count_avail, 0) < number_of_tags
&& spu_extract (table_copy, 0) != 0);
index = spu_sub (index, count_avail);
/* is_valid is set to 0xFFFFFFFF if table_copy == 0, 0 otherwise. */
is_valid = spu_cmpeq (table_copy, 0);
index = spu_sel (index, is_valid, is_valid);
/* Now I need to actually mark the tags as used. */
table_copy = spu_sl (one, number_of_tags);
table_copy = spu_rl (table_copy, -number_of_tags - spu_extract (index, 0));
table_copy = spu_sel (table_copy, __mfc_tag_table, table_copy);
__mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_valid);
return spu_extract (index, 0);
}

View File

@ -0,0 +1,64 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include <spu_mfcio.h>
extern vector unsigned int __mfc_tag_table;
/* Release the specified DMA tag from exclusive use. Once released, the
tag is available for future reservation. Upon sucessful release,
MFC_DMA_TAG_VALID is returned. If the specified tag is not in the
range 0 to 31, or had not been reserved, no action is taken and
MFC_DMA_TAG_INVALID is returned. */
unsigned int
__mfc_tag_release (unsigned int tag)
{
vector unsigned int is_invalid;
vector unsigned int mask = (vector unsigned int)
{ 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
vector signed int zero = (vector signed int) { 0, 0, 0, 0 };
vector signed int has_been_reserved;
/* Check if the tag is out of range. */
is_invalid = spu_cmpgt (spu_promote (tag, 0), 31);
/* Check whether the tag has been reserved, set to all 1 if has not
been reserved, 0 otherwise. */
has_been_reserved = (vector signed int) spu_rl (__mfc_tag_table, tag);
has_been_reserved = (vector signed int) spu_cmpgt (zero, has_been_reserved);
/* Set invalid. */
is_invalid = spu_or ((vector unsigned int) has_been_reserved, is_invalid);
mask = spu_rlmask (mask, (int)(-tag));
__mfc_tag_table = spu_or (__mfc_tag_table, mask);
return spu_extract(is_invalid, 0);
}

View File

@ -0,0 +1,56 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include <spu_mfcio.h>
extern vector unsigned int __mfc_tag_table;
/* Reserves a DMA tag for exclusive use. This routine returns an available
tag id in the range 0 to 31 and marks the tag as reserved. If no tags
are available, MFC_DMA_TAG_INVALID is returned indicating that all tags
are already reserved. */
unsigned int
__mfc_tag_reserve (void)
{
vector unsigned int mask = (vector unsigned int)
{ 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
vector unsigned int count_zeros, is_valid;
vector signed int count_neg;
count_zeros = spu_cntlz (__mfc_tag_table);
count_neg = spu_sub (0, (vector signed int) count_zeros);
mask = spu_rlmask (mask, (vector signed int) count_neg);
__mfc_tag_table = spu_andc (__mfc_tag_table, mask);
is_valid = spu_cmpeq (count_zeros, 32);
count_zeros = spu_sel (count_zeros, is_valid, is_valid);
return spu_extract (count_zeros, 0);
}

View File

@ -0,0 +1,45 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* The free tag table used by the MFC tag manager, with tag0
reserved for the overlay manager. */
__vector unsigned int
__mfc_tag_table = (__vector unsigned int) { 0x7FFFFFFF, -1, -1, -1 };
/* Arrange to release tag0 if overlays are not present. */
static void __mfc_tag_init (void) __attribute__ ((constructor));
static void
__mfc_tag_init (void)
{
extern void _ovly_table __attribute__ ((weak));
if (&_ovly_table == 0)
__mfc_tag_table = (__vector unsigned int) { -1, -1, -1, -1 };
}

View File

@ -25,7 +25,11 @@
#define __SPU_MFCIO_H__ 1
#include <spu_intrinsics.h>
#ifdef __IN_LIBGCC2
unsigned long long uint64_t;
#else
#include <stdint.h>
#endif
/****************************************************************/
@ -267,4 +271,24 @@ typedef struct mfc_list_element {
#define spu_write_srr0(srr0) spu_writech(SPU_WrSRR0,srr0)
#define spu_read_srr0() spu_readch(SPU_RdSRR0)
/* MFC Tag Manager */
#define MFC_TAG_INVALID 0xFFFFFFFF
#define MFC_TAG_VALID 0x00000000
#define mfc_tag_reserve() \
__mfc_tag_reserve()
#define mfc_tag_release(tag) \
__mfc_tag_release((tag))
#define mfc_multi_tag_reserve(nr_tags) \
__mfc_multi_tag_reserve((nr_tags))
#define mfc_multi_tag_release(tag, nr_tags) \
__mfc_multi_tag_release((tag),(nr_tags))
extern unsigned int __mfc_tag_reserve (void);
extern unsigned int __mfc_tag_release (unsigned int);
extern unsigned int __mfc_multi_tag_reserve (unsigned int);
extern unsigned int __mfc_multi_tag_release (unsigned int, unsigned int);
#endif /* __SPU_MFCIO_H__ */

View File

@ -21,10 +21,15 @@ CROSS_LIBGCC1 =
# On SPU __word__ is TImode which is too inefficient and incomplete for
# implementing libgcc routines.
TARGET_LIBGCC2_CFLAGS = -fPIC -D__word__=SI -mwarn-reloc
TARGET_LIBGCC2_CFLAGS = -fPIC -D__word__=SI -mwarn-reloc -D__IN_LIBGCC2
LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \
$(srcdir)/config/spu/float_unsdidf.c
$(srcdir)/config/spu/float_unsdidf.c \
$(srcdir)/config/spu/mfc_tag_table.c \
$(srcdir)/config/spu/mfc_tag_reserve.c \
$(srcdir)/config/spu/mfc_tag_release.c \
$(srcdir)/config/spu/mfc_multi_tag_reserve.c \
$(srcdir)/config/spu/mfc_multi_tag_release.c
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c

View File

@ -0,0 +1,312 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This file is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* { dg-do run } */
#include <spu_mfcio.h>
/* This test directly accesses the internal table used
by the MFC tag manager. */
extern vector unsigned int __mfc_tag_table;
/* This tag tests invalid tag release. Invalid tag release does
nothing to the tag table. */
void
test_tag_release01 (void)
{
unsigned int copy;
copy = spu_extract (__mfc_tag_table, 0);
mfc_tag_release (35);
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
}
/* More invalid release tests. */
void
test_tag_release_invalid (void)
{
unsigned int copy;
copy = spu_extract (__mfc_tag_table, 0);
if (mfc_tag_release (32) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
if (mfc_tag_release (17) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
}
/* Invalid multiple-tag release tests. */
void
test_tag_group_release_invalid (void)
{
unsigned int copy;
copy = spu_extract (__mfc_tag_table, 0);
if (mfc_multi_tag_release (32, 10) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
if (mfc_multi_tag_release (28, 10) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
if (mfc_multi_tag_release (17, 10) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
if (mfc_multi_tag_release (32, 10) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
}
/* The tag table should be in a pristine mode to run this test. */
void
test_tag_reserve01 (void)
{
unsigned int correct_table[32] =
{
0x80000000, 0xC0000000, 0xE0000000,
0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000,
0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000,
0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000,
0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000,
0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00,
0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0,
0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE,
0xFFFFFFFF
};
unsigned int tag;
unsigned int i;
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve ();
if (tag != i)
abort ();
}
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve ();
if (tag != MFC_TAG_INVALID)
abort ();
}
for (i = 0; i < 32; i++)
{
mfc_tag_release (i);
if (spu_extract (__mfc_tag_table, 0) != correct_table[i])
abort ();
}
}
/* The tag table should be in a pristine mode to run this test. */
void
test_tag_reserve02 (void)
{
unsigned int correct_table[32] =
{
0x80000000, 0xC0000000, 0xA0000000, 0xF0000000,
0xA8000000, 0xFC000000, 0xAA000000, 0xFF000000,
0xAA800000, 0xFFC00000, 0xAAA00000, 0xFFF00000,
0xAAA80000, 0xFFFC0000, 0xAAAA0000, 0xFFFF0000,
0xAAAA8000, 0xFFFFC000, 0xAAAAA000, 0xFFFFF000,
0xAAAAA800, 0xFFFFFC00, 0xAAAAAA00, 0xFFFFFF00,
0xAAAAAA80, 0xFFFFFFC0, 0xAAAAAAA0, 0xFFFFFFF0,
0xAAAAAAA8, 0xFFFFFFFC, 0xAAAAAAAA, 0xFFFFFFFF
};
unsigned int correct_table2[32] =
{
0x80000000, 0xEAAAAAAA, 0xA0000000, 0xFAAAAAAA,
0xA8000000, 0xFEAAAAAA, 0xAA000000, 0xFFAAAAAA,
0xAA800000, 0xFFEAAAAA, 0xAAA00000, 0xFFFAAAAA,
0xAAA80000, 0xFFFEAAAA, 0xAAAA0000, 0xFFFFAAAA,
0xAAAA8000, 0xFFFFEAAA, 0xAAAAA000, 0xFFFFFAAA,
0xAAAAA800, 0xFFFFFEAA, 0xAAAAAA00, 0xFFFFFFAA,
0xAAAAAA80, 0xFFFFFFEA, 0xAAAAAAA0, 0xFFFFFFFA,
0xAAAAAAA8, 0xFFFFFFFE, 0xAAAAAAAA, 0xFFFFFFFF
};
unsigned int tag;
unsigned int i;
/* Reserve all 32 tags. */
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve();
if (tag != i)
abort ();
}
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve();
if (tag != MFC_TAG_INVALID)
abort ();
}
/* Release only 16 tags with a stride of 2. */
for (i = 0; i < 32; i += 2)
{
mfc_tag_release (i);
if (spu_extract (__mfc_tag_table, 0) != correct_table[i])
abort ();
}
/* Release the other 16 tags with a stride of 2. */
for (i = 1; i < 32; i += 2)
{
mfc_tag_release (i);
if (spu_extract (__mfc_tag_table, 0) != correct_table2[i])
abort ();
}
}
/* The tag table should be in a pristine mode to run this test. */
void
test_tag_reserve03 (void)
{
unsigned int tag;
unsigned int i;
/* Reserve all 32 tags. */
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve ();
if (tag != i)
abort ();
}
for (i = 0; i < 32; i++)
{
tag = mfc_tag_reserve ();
if (tag != MFC_TAG_INVALID)
abort ();
}
/* Release only 16 tags with a stride of 2. */
for (i = 0; i < 32; i += 2)
mfc_tag_release (i);
/* Now let's re-reserve those tags. */
for (i = 0; i < 32; i += 2)
{
tag = mfc_tag_reserve ();
if (tag != i)
abort ();
}
/* Release all tags. */
for (i = 0; i < 32; i++)
mfc_tag_release (i);
if (spu_extract (__mfc_tag_table,0) != 0xFFFFFFFF)
abort ();
}
void
test_tag_group_reserve (void)
{
unsigned int tag;
unsigned int i;
unsigned int copy;
/* Reserve all tags. */
for (i = 0; i < 32; i++)
mfc_tag_reserve();
/* Release the first 4. */
for (i = 0; i < 4; i++)
mfc_tag_release (i);
/* Release tag 5 to 7. */
for (i = 5; i < 8; i++)
mfc_tag_release (i);
/* Release tag 9 to 19. */
for (i = 9; i < 20; i++)
mfc_tag_release (i);
/* Tag table should be 0xF77FF000. */
if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000)
abort ();
/* Verify invalid release is detected. */
copy = spu_extract (__mfc_tag_table, 0);
if (mfc_multi_tag_release (1, 5) != MFC_TAG_INVALID)
abort ();
if (copy != spu_extract (__mfc_tag_table, 0))
abort ();
/* Reserve multiple tags. */
tag = mfc_multi_tag_reserve (5);
if (tag != 9)
abort ();
/* Tag table should be 0xF703F000. */
if (spu_extract (__mfc_tag_table, 0) != 0xF703F000)
abort ();
/* Release 5 tags in the group. */
mfc_multi_tag_release (tag, 5);
/* Tag table should be 0xF77FF000. */
if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000)
abort ();
/* This call should not do anything. */
mfc_multi_tag_release (32, 5);
/* Tag table should be 0xF77FF000. */
if (spu_extract (__mfc_tag_table, 0) != 0xF77FF000)
abort ();
}
int
main (void)
{
test_tag_release01 ();
test_tag_release_invalid ();
test_tag_group_release_invalid ();
test_tag_reserve01 ();
test_tag_reserve02 ();
test_tag_reserve03 ();
test_tag_group_reserve ();
return 0;
}