OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [libsupc++/] [vec.cc] - Blame information for rev 764

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 742 jeremybenn
// New abi Support -*- C++ -*-
2
 
3
// Copyright (C) 2000, 2001, 2003, 2004, 2009, 2011
4
// Free Software Foundation, Inc.
5
//  
6
// This file is part of GCC.
7
//
8
// GCC is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 3, or (at your option)
11
// any later version.
12
 
13
// GCC is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
 
18
// Under Section 7 of GPL version 3, you are granted additional
19
// permissions described in the GCC Runtime Library Exception, version
20
// 3.1, as published by the Free Software Foundation.
21
 
22
// You should have received a copy of the GNU General Public License and
23
// a copy of the GCC Runtime Library Exception along with this program;
24
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25
// <http://www.gnu.org/licenses/>.
26
 
27
// Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
28
 
29
#include <cxxabi.h>
30
#include <new>
31
#include <exception>
32
#include <bits/exception_defines.h>
33
#include "unwind-cxx.h"
34
 
35
namespace __cxxabiv1
36
{
37
  namespace
38
  {
39
    struct uncatch_exception
40
    {
41
      uncatch_exception();
42
      ~uncatch_exception () { __cxa_begin_catch (&p->unwindHeader); }
43
 
44
      __cxa_exception* p;
45
 
46
    private:
47
      uncatch_exception&
48
      operator=(const uncatch_exception&);
49
 
50
      uncatch_exception(const uncatch_exception&);
51
    };
52
 
53
    uncatch_exception::uncatch_exception() : p(0)
54
    {
55
      __cxa_eh_globals *globals = __cxa_get_globals_fast ();
56
 
57
      p = globals->caughtExceptions;
58
      p->handlerCount -= 1;
59
      globals->caughtExceptions = p->nextException;
60
      globals->uncaughtExceptions += 1;
61
    }
62
  }
63
 
64
  // Allocate and construct array.
65
  extern "C" void *
66
  __cxa_vec_new(std::size_t element_count,
67
                std::size_t element_size,
68
                std::size_t padding_size,
69
                __cxa_cdtor_type constructor,
70
                __cxa_cdtor_type destructor)
71
  {
72
    return __cxa_vec_new2(element_count, element_size, padding_size,
73
                           constructor, destructor,
74
                           &operator new[], &operator delete []);
75
  }
76
 
77
  extern "C" void *
78
  __cxa_vec_new2(std::size_t element_count,
79
                 std::size_t element_size,
80
                 std::size_t padding_size,
81
                 __cxa_cdtor_type constructor,
82
                 __cxa_cdtor_type destructor,
83
                 void *(*alloc) (std::size_t),
84
                 void (*dealloc) (void *))
85
  {
86
    std::size_t size = element_count * element_size + padding_size;
87
    char *base = static_cast <char *> (alloc (size));
88
    if (!base)
89
      return base;
90
 
91
    if (padding_size)
92
      {
93
        base += padding_size;
94
        reinterpret_cast <std::size_t *> (base)[-1] = element_count;
95
#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
96
        reinterpret_cast <std::size_t *> (base)[-2] = element_size;
97
#endif
98
      }
99
    __try
100
      {
101
        __cxa_vec_ctor(base, element_count, element_size,
102
                       constructor, destructor);
103
      }
104
    __catch(...)
105
      {
106
        {
107
          uncatch_exception ue;
108
          // Core issue 901 will probably be resolved such that a
109
          // deleted operator delete means not freeing memory here.
110
          if (dealloc)
111
            dealloc(base - padding_size);
112
        }
113
        __throw_exception_again;
114
      }
115
    return base;
116
  }
117
 
118
  extern "C" void *
119
  __cxa_vec_new3(std::size_t element_count,
120
                 std::size_t element_size,
121
                 std::size_t padding_size,
122
                 __cxa_cdtor_type constructor,
123
                 __cxa_cdtor_type destructor,
124
                 void *(*alloc) (std::size_t),
125
                 void (*dealloc) (void *, std::size_t))
126
  {
127
    std::size_t size = element_count * element_size + padding_size;
128
    char *base = static_cast<char *>(alloc (size));
129
    if (!base)
130
      return base;
131
 
132
    if (padding_size)
133
      {
134
        base += padding_size;
135
        reinterpret_cast<std::size_t *>(base)[-1] = element_count;
136
#ifdef _GLIBCXX_ELTSIZE_IN_COOKIE
137
        reinterpret_cast <std::size_t *> (base)[-2] = element_size;
138
#endif
139
      }
140
    __try
141
      {
142
        __cxa_vec_ctor(base, element_count, element_size,
143
                       constructor, destructor);
144
      }
145
    __catch(...)
146
      {
147
        {
148
          uncatch_exception ue;
149
          if (dealloc)
150
            dealloc(base - padding_size, size);
151
        }
152
        __throw_exception_again;
153
      }
154
    return base;
155
  }
156
 
157
  // Construct array.
158
  extern "C" __cxa_vec_ctor_return_type
159
  __cxa_vec_ctor(void *array_address,
160
                 std::size_t element_count,
161
                 std::size_t element_size,
162
                 __cxa_cdtor_type constructor,
163
                 __cxa_cdtor_type destructor)
164
  {
165
    std::size_t ix = 0;
166
    char *ptr = static_cast<char *>(array_address);
167
 
168
    __try
169
      {
170
        if (constructor)
171
          for (; ix != element_count; ix++, ptr += element_size)
172
            constructor(ptr);
173
      }
174
    __catch(...)
175
      {
176
        {
177
          uncatch_exception ue;
178
          __cxa_vec_cleanup(array_address, ix, element_size, destructor);
179
        }
180
        __throw_exception_again;
181
      }
182
    _GLIBCXX_CXA_VEC_CTOR_RETURN (array_address);
183
  }
184
 
185
  // Construct an array by copying.
186
  extern "C" __cxa_vec_ctor_return_type
187
  __cxa_vec_cctor(void *dest_array,
188
                  void *src_array,
189
                  std::size_t element_count,
190
                  std::size_t element_size,
191
                  __cxa_cdtor_return_type (*constructor) (void *, void *),
192
                  __cxa_cdtor_type destructor)
193
  {
194
    std::size_t ix = 0;
195
    char *dest_ptr = static_cast<char *>(dest_array);
196
    char *src_ptr = static_cast<char *>(src_array);
197
 
198
    __try
199
      {
200
        if (constructor)
201
          for (; ix != element_count;
202
               ix++, src_ptr += element_size, dest_ptr += element_size)
203
            constructor(dest_ptr, src_ptr);
204
      }
205
    __catch(...)
206
      {
207
        {
208
          uncatch_exception ue;
209
          __cxa_vec_cleanup(dest_array, ix, element_size, destructor);
210
        }
211
        __throw_exception_again;
212
      }
213
    _GLIBCXX_CXA_VEC_CTOR_RETURN (dest_array);
214
  }
215
 
216
  // Destruct array.
217
  extern "C" void
218
  __cxa_vec_dtor(void *array_address,
219
                 std::size_t element_count,
220
                 std::size_t element_size,
221
                 __cxa_cdtor_type destructor)
222
  {
223
    if (destructor)
224
      {
225
        char *ptr = static_cast<char *>(array_address);
226
        std::size_t ix = element_count;
227
 
228
        ptr += element_count * element_size;
229
 
230
        __try
231
          {
232
            while (ix--)
233
              {
234
                ptr -= element_size;
235
                destructor(ptr);
236
              }
237
          }
238
        __catch(...)
239
          {
240
            {
241
              uncatch_exception ue;
242
              __cxa_vec_cleanup(array_address, ix, element_size, destructor);
243
            }
244
            __throw_exception_again;
245
          }
246
      }
247
  }
248
 
249
  // Destruct array as a result of throwing an exception.
250
  // [except.ctor]/3 If a destructor called during stack unwinding
251
  // exits with an exception, terminate is called.
252
  extern "C" void
253
  __cxa_vec_cleanup(void *array_address,
254
                    std::size_t element_count,
255
                    std::size_t element_size,
256
                    __cxa_cdtor_type destructor) throw()
257
  {
258
    if (destructor)
259
      {
260
        char *ptr = static_cast <char *> (array_address);
261
        std::size_t ix = element_count;
262
 
263
        ptr += element_count * element_size;
264
 
265
        __try
266
          {
267
            while (ix--)
268
              {
269
                ptr -= element_size;
270
                destructor(ptr);
271
              }
272
          }
273
        __catch(...)
274
          {
275
            std::terminate();
276
          }
277
      }
278
  }
279
 
280
  // Destruct and release array.
281
  extern "C" void
282
  __cxa_vec_delete(void *array_address,
283
                   std::size_t element_size,
284
                   std::size_t padding_size,
285
                   __cxa_cdtor_type destructor)
286
  {
287
    __cxa_vec_delete2(array_address, element_size, padding_size,
288
                       destructor,
289
                       &operator delete []);
290
  }
291
 
292
  extern "C" void
293
  __cxa_vec_delete2(void *array_address,
294
                    std::size_t element_size,
295
                    std::size_t padding_size,
296
                    __cxa_cdtor_type destructor,
297
                    void (*dealloc) (void *))
298
  {
299
    if (!array_address)
300
      return;
301
 
302
    char* base = static_cast<char *>(array_address);
303
 
304
    if (padding_size)
305
      {
306
        std::size_t element_count = reinterpret_cast<std::size_t *>(base)[-1];
307
        base -= padding_size;
308
        __try
309
          {
310
            __cxa_vec_dtor(array_address, element_count, element_size,
311
                           destructor);
312
          }
313
        __catch(...)
314
          {
315
            {
316
              uncatch_exception ue;
317
              dealloc(base);
318
            }
319
            __throw_exception_again;
320
          }
321
      }
322
    dealloc(base);
323
  }
324
 
325
  extern "C" void
326
  __cxa_vec_delete3(void *array_address,
327
                    std::size_t element_size,
328
                    std::size_t padding_size,
329
                     __cxa_cdtor_type destructor,
330
                    void (*dealloc) (void *, std::size_t))
331
  {
332
    if (!array_address)
333
      return;
334
 
335
    char* base = static_cast <char *> (array_address);
336
    std::size_t size = 0;
337
 
338
    if (padding_size)
339
      {
340
        std::size_t element_count = reinterpret_cast<std::size_t *> (base)[-1];
341
        base -= padding_size;
342
        size = element_count * element_size + padding_size;
343
        __try
344
          {
345
            __cxa_vec_dtor(array_address, element_count, element_size,
346
                           destructor);
347
          }
348
        __catch(...)
349
          {
350
            {
351
              uncatch_exception ue;
352
              dealloc(base, size);
353
            }
354
            __throw_exception_again;
355
          }
356
      }
357
    dealloc(base, size);
358
  }
359
} // namespace __cxxabiv1
360
 
361
#if defined(__arm__) && defined(__ARM_EABI__)
362
 
363
// The ARM C++ ABI requires that the library provide these additional
364
// helper functions.  There are placed in this file, despite being
365
// architecture-specifier, so that the compiler can inline the __cxa
366
// functions into these functions as appropriate.
367
 
368
namespace __aeabiv1
369
{
370
  extern "C" void *
371
  __aeabi_vec_ctor_nocookie_nodtor (void *array_address,
372
                                    abi::__cxa_cdtor_type constructor,
373
                                    std::size_t element_size,
374
                                    std::size_t element_count)
375
  {
376
    return abi::__cxa_vec_ctor (array_address, element_count, element_size,
377
                                constructor, /*destructor=*/NULL);
378
  }
379
 
380
  extern "C" void *
381
  __aeabi_vec_ctor_cookie_nodtor (void *array_address,
382
                                  abi::__cxa_cdtor_type constructor,
383
                                  std::size_t element_size,
384
                                  std::size_t element_count)
385
  {
386
    if (array_address == NULL)
387
      return NULL;
388
 
389
    array_address = reinterpret_cast<std::size_t *>(array_address) + 2;
390
    reinterpret_cast<std::size_t *>(array_address)[-2] = element_size;
391
    reinterpret_cast<std::size_t *>(array_address)[-1] = element_count;
392
    return abi::__cxa_vec_ctor (array_address,
393
                                element_count, element_size,
394
                                constructor, /*destructor=*/NULL);
395
  }
396
 
397
  extern "C" void *
398
  __aeabi_vec_cctor_nocookie_nodtor (void *dest_array,
399
                                     void *src_array,
400
                                     std::size_t element_size,
401
                                     std::size_t element_count,
402
                                     void *(*constructor) (void *, void *))
403
  {
404
    return abi::__cxa_vec_cctor (dest_array, src_array,
405
                                 element_count, element_size,
406
                                 constructor, NULL);
407
  }
408
 
409
  extern "C" void *
410
  __aeabi_vec_new_cookie_noctor (std::size_t element_size,
411
                                 std::size_t element_count)
412
  {
413
    return abi::__cxa_vec_new(element_count, element_size,
414
                              2 * sizeof (std::size_t),
415
                              /*constructor=*/NULL, /*destructor=*/NULL);
416
  }
417
 
418
  extern "C" void *
419
  __aeabi_vec_new_nocookie (std::size_t element_size,
420
                            std::size_t element_count,
421
                            abi::__cxa_cdtor_type constructor)
422
  {
423
    return abi::__cxa_vec_new (element_count, element_size, 0, constructor,
424
                               NULL);
425
  }
426
 
427
  extern "C" void *
428
  __aeabi_vec_new_cookie_nodtor (std::size_t element_size,
429
                                 std::size_t element_count,
430
                                 abi::__cxa_cdtor_type constructor)
431
  {
432
    return abi::__cxa_vec_new(element_count, element_size,
433
                              2 * sizeof (std::size_t),
434
                              constructor, NULL);
435
  }
436
 
437
  extern "C" void *
438
  __aeabi_vec_new_cookie(std::size_t element_size,
439
                         std::size_t element_count,
440
                         abi::__cxa_cdtor_type constructor,
441
                         abi::__cxa_cdtor_type destructor)
442
  {
443
    return abi::__cxa_vec_new (element_count, element_size,
444
                               2 * sizeof (std::size_t),
445
                               constructor, destructor);
446
  }
447
 
448
 
449
  extern "C" void *
450
  __aeabi_vec_dtor (void *array_address,
451
                    abi::__cxa_cdtor_type destructor,
452
                    std::size_t element_size,
453
                    std::size_t element_count)
454
  {
455
    abi::__cxa_vec_dtor (array_address, element_count, element_size,
456
                         destructor);
457
    return reinterpret_cast<std::size_t*> (array_address) - 2;
458
  }
459
 
460
  extern "C" void *
461
  __aeabi_vec_dtor_cookie (void *array_address,
462
                           abi::__cxa_cdtor_type destructor)
463
  {
464
    if (!array_address)
465
      return NULL;
466
 
467
    abi::__cxa_vec_dtor (array_address,
468
                         reinterpret_cast<std::size_t *>(array_address)[-1],
469
                         reinterpret_cast<std::size_t *>(array_address)[-2],
470
                         destructor);
471
    return reinterpret_cast<std::size_t*> (array_address) - 2;
472
  }
473
 
474
 
475
  extern "C" void
476
  __aeabi_vec_delete (void *array_address,
477
                      abi::__cxa_cdtor_type destructor)
478
  {
479
    if (!array_address)
480
      return;
481
 
482
    abi::__cxa_vec_delete (array_address,
483
                           reinterpret_cast<std::size_t *>(array_address)[-2],
484
                           2 * sizeof (std::size_t),
485
                           destructor);
486
  }
487
 
488
  extern "C" void
489
  __aeabi_vec_delete3 (void *array_address,
490
                       abi::__cxa_cdtor_type destructor,
491
                       void (*dealloc) (void *, std::size_t))
492
  {
493
    if (!array_address)
494
      return;
495
 
496
    abi::__cxa_vec_delete3 (array_address,
497
                            reinterpret_cast<std::size_t *>(array_address)[-2],
498
                            2 * sizeof (std::size_t),
499
                            destructor, dealloc);
500
  }
501
 
502
  extern "C" void
503
  __aeabi_vec_delete3_nodtor (void *array_address,
504
                              void (*dealloc) (void *, std::size_t))
505
  {
506
    if (!array_address)
507
      return;
508
 
509
    abi::__cxa_vec_delete3 (array_address,
510
                            reinterpret_cast<std::size_t *>(array_address)[-2],
511
                            2 * sizeof (std::size_t),
512
                            /*destructor=*/NULL, dealloc);
513
  }
514
} // namespace __aeabiv1
515
 
516
#endif // defined(__arm__) && defined(__ARM_EABI__)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.