Home | History | Annotate | Line # | Download | only in ppc
      1 /*  This file is part of the program psim.
      2 
      3     Copyright (C) 1994-1995,1997, Andrew Cagney <cagney (at) highland.com.au>
      4 
      5     This program is free software; you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation; either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program; if not, see <http://www.gnu.org/licenses/>.
     17 
     18     */
     19 
     20 
     21 #ifndef _CAP_C_
     22 #define _CAP_C_
     23 
     24 #include "cap.h"
     25 
     26 typedef struct _cap_mapping cap_mapping;
     27 struct _cap_mapping {
     28   unsigned_cell external;
     29   void *internal;
     30   cap_mapping *next;
     31 };
     32 
     33 struct _cap {
     34   int nr_mappings;
     35   cap_mapping *mappings;
     36 };
     37 
     38 INLINE_CAP\
     39 (cap *)
     40 cap_create(const char *key)
     41 {
     42   return ZALLOC(cap);
     43 }
     44 
     45 INLINE_CAP\
     46 (void)
     47 cap_init(cap *db)
     48 {
     49   cap_mapping *current_map = db->mappings;
     50   if (current_map != NULL) {
     51     db->nr_mappings = db->mappings->external;
     52     /* verify that the mappings that were not removed are in sequence
     53        down to nr 1 */
     54     while (current_map->next != NULL) {
     55       if (current_map->external != current_map->next->external + 1)
     56 	error("cap: cap database possibly corrupt");
     57       current_map = current_map->next;
     58     }
     59     ASSERT(current_map->next == NULL);
     60     if (current_map->external != 1)
     61       error("cap: cap database possibly currupt");
     62   }
     63   else {
     64     db->nr_mappings = 0;
     65   }
     66 }
     67 
     68 INLINE_CAP\
     69 (void *)
     70 cap_internal(cap *db,
     71 	     signed_cell external)
     72 {
     73   cap_mapping *current_map = db->mappings;
     74   while (current_map != NULL) {
     75     if (current_map->external == external)
     76       return current_map->internal;
     77     current_map = current_map->next;
     78   }
     79   return (void*)0;
     80 }
     81 
     82 INLINE_CAP\
     83 (signed_cell)
     84 cap_external(cap *db,
     85 	     void *internal)
     86 {
     87   cap_mapping *current_map = db->mappings;
     88   while (current_map != NULL) {
     89     if (current_map->internal == internal)
     90       return current_map->external;
     91     current_map = current_map->next;
     92   }
     93   return 0;
     94 }
     95 
     96 INLINE_CAP\
     97 (void)
     98 cap_add(cap *db,
     99 	void *internal)
    100 {
    101   if (cap_external(db, internal) != 0) {
    102     error("cap: attempting to add an object already in the data base");
    103   }
    104   else {
    105     /* insert at the front making things in decending order */
    106     cap_mapping *new_map = ZALLOC(cap_mapping);
    107     new_map->next = db->mappings;
    108     new_map->internal = internal;
    109     db->nr_mappings += 1;
    110     new_map->external = db->nr_mappings;
    111     db->mappings = new_map;
    112   }
    113 }
    114 
    115 INLINE_CAP\
    116 (void)
    117 cap_remove(cap *db,
    118 	   void *internal)
    119 {
    120   cap_mapping **current_map = &db->mappings;
    121   while (*current_map != NULL) {
    122     if ((*current_map)->internal == internal) {
    123       cap_mapping *delete = *current_map;
    124       *current_map = delete->next;
    125       free(delete);
    126       return;
    127     }
    128     current_map = &(*current_map)->next;
    129   }
    130   error("cap: attempt to remove nonexistant internal object");
    131 }
    132 
    133 #endif
    134