nasm/rdoff/segtab.c

143 lines
3.2 KiB
C
Raw Normal View History

#include "compiler.h"
2002-05-01 04:58:18 +08:00
#include <stdio.h>
#include <stdlib.h>
#include "segtab.h"
struct segtabnode {
int localseg;
int destseg;
int32_t offset;
2002-05-01 04:58:18 +08:00
2005-01-16 06:15:51 +08:00
struct segtabnode *left;
struct segtabnode *right;
/*
2002-05-01 04:58:18 +08:00
* counts of how many are left or right, for use in reorganising
* the tree
*/
int leftcount;
int rightcount;
};
/*
* init_seglocations()
* add_seglocation()
* get_seglocation()
* done_seglocation()
*
* functions used by write_output() to manipulate associations
* between segment numbers and locations (which are built up on a per
* module basis, but we only need one module at a time...)
*
* implementation: we build a binary tree.
*/
void init_seglocations(segtab * root)
{
*root = NULL;
}
2005-01-16 06:15:51 +08:00
void descend_tree_add(struct segtabnode **node,
int localseg, int destseg, int32_t offset)
2002-05-01 04:58:18 +08:00
{
2005-01-16 06:15:51 +08:00
struct segtabnode *n;
2002-05-01 04:58:18 +08:00
if (*node == NULL) {
2005-01-16 06:15:51 +08:00
*node = malloc(sizeof(**node));
if (!*node) {
fprintf(stderr, "segment table: out of memory\n");
exit(1);
}
(*node)->localseg = localseg;
(*node)->offset = offset;
(*node)->left = NULL;
(*node)->leftcount = 0;
(*node)->right = NULL;
(*node)->rightcount = 0;
(*node)->destseg = destseg;
return;
2002-05-01 04:58:18 +08:00
}
2005-01-16 06:15:51 +08:00
if (localseg < (*node)->localseg) {
(*node)->leftcount++;
descend_tree_add(&(*node)->left, localseg, destseg, offset);
if ((*node)->leftcount > (*node)->rightcount + 2) {
n = *node;
*node = n->left;
n->left = (*node)->right;
n->leftcount = (*node)->rightcount;
(*node)->right = n;
(*node)->rightcount = n->leftcount + n->rightcount + 1;
}
} else {
(*node)->rightcount++;
descend_tree_add(&(*node)->right, localseg, destseg, offset);
if ((*node)->rightcount > (*node)->leftcount + 2) {
n = *node;
*node = n->right;
n->right = (*node)->left;
n->rightcount = (*node)->leftcount;
(*node)->left = n;
(*node)->leftcount = n->leftcount + n->rightcount + 1;
}
2002-05-01 04:58:18 +08:00
}
}
void add_seglocation(segtab * root, int localseg, int destseg, int32_t offset)
2002-05-01 04:58:18 +08:00
{
2005-01-16 06:15:51 +08:00
descend_tree_add((struct segtabnode **)root, localseg, destseg,
offset);
2002-05-01 04:58:18 +08:00
}
2005-01-16 06:15:51 +08:00
int get_seglocation(segtab * root, int localseg, int *destseg,
int32_t *offset)
2002-05-01 04:58:18 +08:00
{
2005-01-16 06:15:51 +08:00
struct segtabnode *n = (struct segtabnode *)*root;
while (n && n->localseg != localseg) {
if (localseg < n->localseg)
n = n->left;
else
n = n->right;
2002-05-01 04:58:18 +08:00
}
if (n) {
2005-01-16 06:15:51 +08:00
*destseg = n->destseg;
*offset = n->offset;
return 1;
} else
return 0;
2002-05-01 04:58:18 +08:00
}
2005-01-16 06:15:51 +08:00
void freenode(struct segtabnode *n)
2002-05-01 04:58:18 +08:00
{
2005-01-16 06:15:51 +08:00
if (!n)
return;
freenode(n->left);
freenode(n->right);
2002-05-01 04:58:18 +08:00
free(n);
}
void done_seglocations(segtab * root)
{
freenode(*root);
*root = NULL;
}
#if 0
2005-01-16 06:15:51 +08:00
void printnode(int i, struct segtabnode *n)
2002-05-01 04:58:18 +08:00
{
2005-01-16 06:15:51 +08:00
if (!n)
return;
2002-05-01 04:58:18 +08:00
printnode(i + 1, n->left);
2005-01-16 06:15:51 +08:00
printf("%*s%d %d %ld\n", i, "", n->localseg, n->destseg, n->offset);
2002-05-01 04:58:18 +08:00
printnode(i + 1, n->right);
}
void printtable()
{
2005-01-16 06:15:51 +08:00
printnode(0, root);
2002-05-01 04:58:18 +08:00
}
#endif