1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file imports.c
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Standard C library function wrappers.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Imports are services which the device driver or window system or
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operating system provides to the core renderer.  The core renderer (Mesa)
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will call these functions in order to do memory allocation, simple I/O,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * etc.
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some drivers will want to override/replace this file with something
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * specialized, but that'll be rare.
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Eventually, I want to move roll the glheader.h file into this.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \todo Functions still needed:
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - scanf
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - qsort
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - rand and RAND_MAX
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version:  7.1
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software.
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "imports.h"
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "context.h"
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "mtypes.h"
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "version.h"
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef _GNU_SOURCE
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <locale.h>
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __APPLE__
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xlocale.h>
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef WIN32
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define vsnprintf _vsnprintf
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(__IBMC__) || defined(__IBMCPP__) || ( defined(__VMS) && __CRTL_VER < 70312000 )
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __VMS
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vsnprintf.c"
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Memory */
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate aligned memory.
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param bytes number of bytes to allocate.
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param alignment alignment (must be greater than zero).
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocates extra memory to accommodate rounding up the address for
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * alignment and to record the real malloc address.
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \sa _mesa_align_free().
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_malloc(size_t bytes, unsigned long alignment)
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN)
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mem;
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int err = posix_memalign(& mem, alignment, bytes);
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (err)
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return mem;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER)
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _aligned_malloc(bytes, alignment);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uintptr_t ptr, buf;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT( alignment > 0 );
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ptr = (uintptr_t) malloc(bytes + alignment + sizeof(void *));
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ptr)
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *(uintptr_t *)(buf - sizeof(void *)) = ptr;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* mark the non-aligned area */
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while ( ptr < buf - sizeof(void *) ) {
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *(unsigned long *)ptr = 0xcdcdcdcd;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr += sizeof(unsigned long);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (void *) buf;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Same as _mesa_align_malloc(), but using calloc(1, ) instead of
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * malloc()
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_calloc(size_t bytes, unsigned long alignment)
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN)
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mem;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mem = _mesa_align_malloc(bytes, alignment);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mem != NULL) {
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void) memset(mem, 0, bytes);
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return mem;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER)
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mem;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   mem = _aligned_malloc(bytes, alignment);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (mem != NULL) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void) memset(mem, 0, bytes);
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return mem;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uintptr_t ptr, buf;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ASSERT( alignment > 0 );
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ptr = (uintptr_t) calloc(1, bytes + alignment + sizeof(void *));
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ptr)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buf = (ptr + alignment + sizeof(void *)) & ~(uintptr_t)(alignment - 1);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *(uintptr_t *)(buf - sizeof(void *)) = ptr;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* mark the non-aligned area */
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while ( ptr < buf - sizeof(void *) ) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *(unsigned long *)ptr = 0xcdcdcdcd;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ptr += sizeof(unsigned long);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (void *)buf;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free memory which was allocated with either _mesa_align_malloc()
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or _mesa_align_calloc().
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ptr pointer to the memory to be freed.
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The actual address to free is stored in the word immediately before the
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * address the client sees.
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_free(void *ptr)
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(HAVE_POSIX_MEMALIGN)
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(ptr);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_WIN32) && defined(_MSC_VER)
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   _aligned_free(ptr);
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *realAddr = *cubbyHole;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   free(realAddr);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* defined(HAVE_POSIX_MEMALIGN) */
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Reallocate memory, with alignment.
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    unsigned long alignment)
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_WIN32) && defined(_MSC_VER)
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) oldSize;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return _aligned_realloc(oldBuffer, newSize, alignment);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *newBuf = _mesa_align_malloc(newSize, alignment);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (newBuf && oldBuffer && copySize > 0) {
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(newBuf, oldBuffer, copySize);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (oldBuffer)
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      _mesa_align_free(oldBuffer);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return newBuf;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Reallocate memory */
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_realloc(void *oldBuffer, size_t oldSize, size_t newSize)
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const size_t copySize = (oldSize < newSize) ? oldSize : newSize;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *newBuffer = malloc(newSize);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (newBuffer && oldBuffer && copySize > 0)
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memcpy(newBuffer, oldBuffer, copySize);
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (oldBuffer)
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      free(oldBuffer);
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return newBuffer;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Math */
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef __GNUC__
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find the first bit set in a word.
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgffs(int i)
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   register int bit = 0;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (i != 0) {
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((i & 0xffff) == 0) {
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bit += 16;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i >>= 16;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((i & 0xff) == 0) {
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bit += 8;
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i >>= 8;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((i & 0xf) == 0) {
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bit += 4;
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i >>= 4;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      while ((i & 1) == 0) {
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         bit++;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         i >>= 1;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bit++;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return bit;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find position of first bit set in given value.
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX Warning: this function can only be used on 64-bit systems!
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return  position of least-significant bit set, starting at 1, return zero
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *          if no bits set.
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgffsll(long long int val)
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int bit;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(sizeof(val) == 8);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bit = ffs((int) val);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bit != 0)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bit;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bit = ffs((int) (val >> 32));
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (bit != 0)
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return 32 + bit;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 0;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* __GNUC__ */
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if !defined(__GNUC__) ||\
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in given GLuint.
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bitcount(unsigned int n)
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int bits;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (bits = 0; n > 0; n = n >> 1) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits += (n & 1);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return bits;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return number of bits set in given 64-bit uint.
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bitcount_64(uint64_t n)
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int bits;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (bits = 0; n > 0; n = n >> 1) {
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bits += (n & 1);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return bits;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a 4-byte float to a 2-byte half float.
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on code from:
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLhalfARB
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_float_to_half(float val)
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const fi_type fi = {val};
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int flt_m = fi.i & 0x7fffff;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int flt_e = (fi.i >> 23) & 0xff;
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int flt_s = (fi.i >> 31) & 0x1;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int s, e, m = 0;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   GLhalfARB result;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sign bit */
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   s = flt_s;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* handle special cases */
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((flt_e == 0) && (flt_m == 0)) {
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* zero */
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* m = 0; - already set */
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      e = 0;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((flt_e == 0) && (flt_m != 0)) {
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* denorm -- denorm float maps to 0 half */
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* m = 0; - already set */
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      e = 0;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((flt_e == 0xff) && (flt_m == 0)) {
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* infinity */
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* m = 0; - already set */
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      e = 31;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((flt_e == 0xff) && (flt_m != 0)) {
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* NaN */
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      m = 1;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      e = 31;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* regular number */
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const int new_exp = flt_e - 127;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (new_exp < -24) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* this maps to 0 */
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* m = 0; - already set */
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         e = 0;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (new_exp < -14) {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* this maps to a denorm */
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         e = 0;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         switch (exp_val) {
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 0:
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               _mesa_warning(NULL,
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   "float_to_half: logical error in denorm creation!\n");
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* m = 0; - already set */
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 1: m = 512 + (flt_m >> 14); break;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 2: m = 256 + (flt_m >> 15); break;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 3: m = 128 + (flt_m >> 16); break;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 4: m = 64 + (flt_m >> 17); break;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 5: m = 32 + (flt_m >> 18); break;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 6: m = 16 + (flt_m >> 19); break;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 7: m = 8 + (flt_m >> 20); break;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 8: m = 4 + (flt_m >> 21); break;
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 9: m = 2 + (flt_m >> 22); break;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case 10: m = 1; break;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (new_exp > 15) {
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* map this value to infinity */
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* m = 0; - already set */
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         e = 31;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* regular */
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         e = new_exp + 15;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         m = flt_m >> 13;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result = (s << 15) | (e << 10) | m;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a 2-byte half float to a 4-byte float.
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on code from:
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_half_to_float(GLhalfARB val)
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX could also use a 64K-entry lookup table */
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int m = val & 0x3ff;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int e = (val >> 10) & 0x1f;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int s = (val >> 15) & 0x1;
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int flt_m, flt_e, flt_s;
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi_type fi;
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float result;
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* sign bit */
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   flt_s = s;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* handle special cases */
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((e == 0) && (m == 0)) {
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* zero */
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_m = 0;
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_e = 0;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((e == 0) && (m != 0)) {
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* denorm -- denorm half will fit in non-denorm single */
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const float half_denorm = 1.0f / 16384.0f; /* 2^-14 */
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      float mantissa = ((float) (m)) / 1024.0f;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      float sign = s ? -1.0f : 1.0f;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return sign * mantissa * half_denorm;
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((e == 31) && (m == 0)) {
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* infinity */
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_e = 0xff;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_m = 0;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else if ((e == 31) && (m != 0)) {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* NaN */
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_e = 0xff;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_m = 1;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* regular */
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_e = e + 112;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flt_m = m << 13;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi.i = (flt_s << 31) | (flt_e << 23) | flt_m;
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result = fi.f;
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Sort & Search */
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper for bsearch().
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_bsearch( const void *key, const void *base, size_t nmemb, size_t size,
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               int (*compar)(const void *, const void *) )
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_WIN32_WCE)
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *mid;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int cmp;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (nmemb) {
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nmemb >>= 1;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mid = (char *)base + nmemb * size;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cmp = (*compar)(key, mid);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cmp == 0)
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return mid;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (cmp > 0) {
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 base = (char *)mid + size;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 --nmemb;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return bsearch(key, base, nmemb, size, compar);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name Environment vars */
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Wrapper for getenv().
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar *
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_getenv( const char *var )
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_XBOX) || defined(_WIN32_WCE)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return getenv(var);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************************/
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** \name String */
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@{*/
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Implemented using malloc() and strcpy.
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that NULL is handled accordingly.
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar *
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_strdup( const char *s )
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (s) {
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      size_t l = strlen(s);
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      char *s2 = (char *) malloc(l + 1);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (s2)
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         strcpy(s2, s);
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return s2;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Wrapper around strtof() */
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfloat
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_strtof( const char *s, char **end )
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   !defined(ANDROID) && !defined(__HAIKU__) && !defined(__UCLIBC__)
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static locale_t loc = NULL;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!loc) {
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      loc = newlocale(LC_CTYPE_MASK, "C", NULL);
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return strtof_l(s, end, loc);
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(_ISOC99_SOURCE) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return strtof(s, end);
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (float)strtod(s, end);
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Compute simple checksum/hash for a string */
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_str_checksum(const char *str)
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This could probably be much better */
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int sum, i;
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const char *c;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sum = i = 1;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (c = str; *c; c++, i++)
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sum += *c * (i % 100);
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return sum + i;
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*@}*/
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Needed due to #ifdef's, above. */
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args)
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return vsnprintf( str, size, fmt, args);
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Wrapper around vsnprintf() */
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_snprintf( char *str, size_t size, const char *fmt, ... )
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int r;
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_list args;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_start( args, fmt );
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   r = vsnprintf( str, size, fmt, args );
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   va_end( args );
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return r;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
595