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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [libstdc++-v3/] [libsupc++/] [vec.cc] - Blame information for rev 826

Details | Compare with Previous | View Log

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