1195098Sed/* Copyright (C) 2007-2019 Free Software Foundation, Inc.
2195098Sed
3195098SedThis file is part of GCC.
4195098Sed
5195098SedGCC is free software; you can redistribute it and/or modify it under
6195098Sedthe terms of the GNU General Public License as published by the Free
7195098SedSoftware Foundation; either version 3, or (at your option) any later
8195098Sedversion.
9195098Sed
10195098SedGCC is distributed in the hope that it will be useful, but WITHOUT ANY
11205218SrdivackyWARRANTY; without even the implied warranty of MERCHANTABILITY or
12207618SrdivackyFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13207618Srdivackyfor more details.
14208599Srdivacky
15195098SedUnder Section 7 of GPL version 3, you are granted additional
16208599Srdivackypermissions described in the GCC Runtime Library Exception, version
17212904Sdim3.1, as published by the Free Software Foundation.
18218893Sdim
19198396SrdivackyYou should have received a copy of the GNU General Public License and
20198396Srdivackya copy of the GCC Runtime Library Exception along with this program;
21218893Sdimsee the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22195098Sed<http://www.gnu.org/licenses/>.  */
23195098Sed
24207618Srdivacky#include <spu_mfcio.h>
25207618Srdivackyextern vector unsigned int __mfc_tag_table;
26208599Srdivacky
27207618Srdivacky/* Release a sequential group of tags from exclusive use. The sequential
28207618Srdivacky   group of tags is the range starting from <first_tag> through
29218893Sdim   <first_tag>+<number_of_tags>-1. Upon successful release, MFC_DMA_TAG_VALID
30218893Sdim   is returned and the tags become available for future reservation.
31218893Sdim
32207618Srdivacky   If the specified tags were not previously reserved, no action is
33207618Srdivacky   taken and MFC_DMA_TAG_INVALID is returned.  */
34208599Srdivacky
35210299Sedunsigned int
36210299Sed__mfc_multi_tag_release (unsigned int first_tag, unsigned int number_of_tags)
37210299Sed{
38210299Sed  vector unsigned int table_copy, tmp, tmp1;
39212904Sdim  vector unsigned int one = (vector unsigned int)
40212904Sdim        { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
41195098Sed  vector unsigned int is_invalid;
42195098Sed  unsigned int last_tag;
43195098Sed  vector unsigned int has_been_reserved;
44207618Srdivacky
45198090Srdivacky  last_tag = first_tag + number_of_tags;
46218893Sdim
47207618Srdivacky  table_copy = spu_sl (one, number_of_tags);
48207618Srdivacky  table_copy = spu_rl (table_copy, -last_tag);
49207618Srdivacky  table_copy = spu_xor (table_copy, -1);
50208599Srdivacky
51210299Sed  /* Make sure the tags are in range and valid.  */
52210299Sed  tmp = spu_cmpgt (spu_promote(last_tag, 0), 32);
53210299Sed  tmp1 = spu_cmpgt (spu_promote(number_of_tags, 0), 32);
54218893Sdim  is_invalid =  spu_cmpgt (spu_promote(first_tag, 0), 31);
55218893Sdim
56195098Sed  /* All bits are set to 1 if invalid, 0 if valid.  */
57195098Sed  is_invalid = spu_or (tmp, is_invalid);
58207618Srdivacky  is_invalid = spu_or (tmp1, is_invalid);
59207618Srdivacky
60207618Srdivacky  /* check whether these tags have been reserved */
61207618Srdivacky  tmp = spu_rlmask (one, (int)-number_of_tags);
62206083Srdivacky  tmp1 = spu_sl (__mfc_tag_table, first_tag);
63204961Srdivacky  has_been_reserved = spu_cmpgt(tmp1, tmp);
64218893Sdim
65205218Srdivacky  is_invalid = spu_or (has_been_reserved, is_invalid);
66205218Srdivacky
67205218Srdivacky  table_copy = spu_sel (__mfc_tag_table, table_copy, table_copy);
68218893Sdim  __mfc_tag_table = spu_sel (table_copy, __mfc_tag_table, is_invalid);
69195098Sed
70218893Sdim  return spu_extract (is_invalid, 0);
71218893Sdim}
72218893Sdim
73218893Sdim