diff options
author | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-20 05:12:09 +0000 |
---|---|---|
committer | bje <bje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-11-20 05:12:09 +0000 |
commit | 1ed5a74872c974a7dc86091f4b3d3e0dc689ca75 (patch) | |
tree | e0d18196bca45919182800eb507420f3419a3fd7 /gcc/config/spu | |
parent | 985a329c19cd7b47c16bc82432798c22a8797592 (diff) | |
download | gcc-1ed5a74872c974a7dc86091f4b3d3e0dc689ca75.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130306 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/spu')
-rw-r--r-- | gcc/config/spu/mfc_multi_tag_release.c | 77 | ||||
-rw-r--r-- | gcc/config/spu/mfc_multi_tag_reserve.c | 89 | ||||
-rw-r--r-- | gcc/config/spu/mfc_tag_release.c | 64 | ||||
-rw-r--r-- | gcc/config/spu/mfc_tag_reserve.c | 56 | ||||
-rw-r--r-- | gcc/config/spu/mfc_tag_table.c | 45 | ||||
-rw-r--r-- | gcc/config/spu/spu_mfcio.h | 24 | ||||
-rw-r--r-- | gcc/config/spu/t-spu-elf | 9 |
7 files changed, 362 insertions, 2 deletions
diff --git a/gcc/config/spu/mfc_multi_tag_release.c b/gcc/config/spu/mfc_multi_tag_release.c new file mode 100644 index 00000000000..a809784daa1 --- /dev/null +++ b/gcc/config/spu/mfc_multi_tag_release.c @@ -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); +} + diff --git a/gcc/config/spu/mfc_multi_tag_reserve.c b/gcc/config/spu/mfc_multi_tag_reserve.c new file mode 100644 index 00000000000..ce3b24d000e --- /dev/null +++ b/gcc/config/spu/mfc_multi_tag_reserve.c @@ -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); +} + diff --git a/gcc/config/spu/mfc_tag_release.c b/gcc/config/spu/mfc_tag_release.c new file mode 100644 index 00000000000..0585a3f84c7 --- /dev/null +++ b/gcc/config/spu/mfc_tag_release.c @@ -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); +} + diff --git a/gcc/config/spu/mfc_tag_reserve.c b/gcc/config/spu/mfc_tag_reserve.c new file mode 100644 index 00000000000..cad2810c140 --- /dev/null +++ b/gcc/config/spu/mfc_tag_reserve.c @@ -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); +} + diff --git a/gcc/config/spu/mfc_tag_table.c b/gcc/config/spu/mfc_tag_table.c new file mode 100644 index 00000000000..aea8ffd54fc --- /dev/null +++ b/gcc/config/spu/mfc_tag_table.c @@ -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 }; +} diff --git a/gcc/config/spu/spu_mfcio.h b/gcc/config/spu/spu_mfcio.h index bd651912306..e32132bc12c 100644 --- a/gcc/config/spu/spu_mfcio.h +++ b/gcc/config/spu/spu_mfcio.h @@ -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__ */ diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf index 43fdd8f7fb3..b9550a3d082 100644 --- a/gcc/config/spu/t-spu-elf +++ b/gcc/config/spu/t-spu-elf @@ -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 |