diff options
Diffstat (limited to 'gas/subsegs.c')
-rw-r--r-- | gas/subsegs.c | 448 |
1 files changed, 238 insertions, 210 deletions
diff --git a/gas/subsegs.c b/gas/subsegs.c index 00937ea..e872a83 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -1,23 +1,21 @@ /* subsegs.c - subsegments - Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc. - -This file is part of GAS, the GNU Assembler. - -GAS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -GAS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GAS; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* static const char rcsid[] = "$Id$"; */ + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Segments & sub-segments. @@ -28,65 +26,90 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "subsegs.h" #include "obstack.h" +#ifdef MANY_SEGMENTS +segment_info_type segment_info[SEG_MAXIMUM_ORDINAL]; + frchainS* frchain_root, - * frchain_now, /* Commented in "subsegs.h". */ - * data0_frchainP; + * frchain_now; +#else +frchainS* frchain_root, + * frchain_now, /* Commented in "subsegs.h". */ + * data0_frchainP; +#endif char * const /* in: segT out: char* */ -seg_name[] = { - "absolute", - "text", - "data", - "bss", - "unknown", - "absent", - "pass1", - "ASSEMBLER-INTERNAL-LOGIC-ERROR!", - "bignum/flonum", - "difference", - "debug", - "transfert vector preload", - "transfert vector postload", - "register", - "", -}; /* Used by error reporters, dumpers etc. */ + seg_name[] = { + "absolute", +#ifdef MANY_SEGMENTS + "e0","e1","e2","e3","e4","e5","e6","e7","e8","e9", +#else + "text", + "data", + "bss", +#endif + "unknown", + "absent", + "pass1", + "ASSEMBLER-INTERNAL-LOGIC-ERROR!", + "bignum/flonum", + "difference", + "debug", + "transfert vector preload", + "transfert vector postload", + "register", + "", + }; /* Used by error reporters, dumpers etc. */ void -subsegs_begin() + subsegs_begin() { - /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */ - know( SEG_ABSOLUTE == 0 ); - know( SEG_TEXT == 1 ); - know( SEG_DATA == 2 ); - know( SEG_BSS == 3 ); - know( SEG_UNKNOWN == 4 ); - know( SEG_ABSENT == 5 ); - know( SEG_PASS1 == 6 ); - know( SEG_GOOF == 7 ); - know( SEG_BIG == 8 ); - know( SEG_DIFFERENCE == 9 ); - know( SEG_DEBUG == 10 ); - know( SEG_NTV == 11 ); - know( SEG_PTV == 12 ); - know( SEG_REGISTER == 13 ); - know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER ); - know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 ); - - obstack_begin( &frags, 5000); - frchain_root = NULL; - frchain_now = NULL; /* Warn new_subseg() that we are booting. */ - /* Fake up 1st frag. */ - /* It won't be used=> is ok if obstack... */ - /* pads the end of it for alignment. */ - frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); - /* obstack_1blank( &frags, SIZEOF_STRUCT_FRAG, & frag_now ); */ - /* This 1st frag will not be in any frchain. */ - /* We simply give subseg_new somewhere to scribble. */ - now_subseg = 42; /* Lie for 1st call to subseg_new. */ - subseg_new (SEG_DATA, 0); /* .data 0 */ - data0_frchainP = frchain_now; + /* Check table(s) seg_name[], seg_N_TYPE[] is in correct order */ +#ifdef MANY_SEGMENTS +#else + know( SEG_ABSOLUTE == 0 ); + know( SEG_TEXT == 1 ); + know( SEG_DATA == 2 ); + know( SEG_BSS == 3 ); + know( SEG_UNKNOWN == 4 ); + know( SEG_ABSENT == 5 ); + know( SEG_PASS1 == 6 ); + know( SEG_GOOF == 7 ); + know( SEG_BIG == 8 ); + know( SEG_DIFFERENCE == 9 ); + know( SEG_DEBUG == 10 ); + know( SEG_NTV == 11 ); + know( SEG_PTV == 12 ); + know( SEG_REGISTER == 13 ); + know( SEG_MAXIMUM_ORDINAL == SEG_REGISTER ); + /* know( segment_name (SEG_MAXIMUM_ORDINAL + 1) [0] == 0 );*/ +#endif + + obstack_begin( &frags, 5000); + frchain_root = NULL; + frchain_now = NULL; /* Warn new_subseg() that we are booting. */ + /* Fake up 1st frag. */ + /* It won't be used=> is ok if obstack... */ + /* pads the end of it for alignment. */ + frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); + memset(frag_now, SIZEOF_STRUCT_FRAG, 0); + /* This 1st frag will not be in any frchain. */ + /* We simply give subseg_new somewhere to scribble. */ + now_subseg = 42; /* Lie for 1st call to subseg_new. */ +#ifdef MANY_SEGMENTS + { + int i; + for (i = SEG_E0; i < SEG_UNKNOWN; i++) { + subseg_new(i, 0); + segment_info[i].frchainP = frchain_now; + } + } +#else + subseg_new (SEG_DATA, 0); /* .data 0 */ + data0_frchainP = frchain_now; +#endif + } /* @@ -100,23 +123,28 @@ subsegs_begin() * segment context correct. */ void -subseg_change (seg, subseg) - register segT seg; - register int subseg; + subseg_change (seg, subseg) +register segT seg; +register int subseg; { - now_seg = seg; - now_subseg = subseg; - if (seg == SEG_DATA) - { - seg_fix_rootP = & data_fix_root; - seg_fix_tailP = & data_fix_tail; - } - else - { - know (seg == SEG_TEXT); - seg_fix_rootP = & text_fix_root; - seg_fix_tailP = & text_fix_tail; - } + now_seg = seg; + now_subseg = subseg; +#ifdef MANY_SEGMENTS + seg_fix_rootP = & segment_info[seg].fix_root; + seg_fix_tailP = & segment_info[seg].fix_tail; +#else + if (seg == SEG_DATA) + { + seg_fix_rootP = & data_fix_root; + seg_fix_tailP = & data_fix_tail; + } + else + { + know (seg == SEG_TEXT); + seg_fix_rootP = & text_fix_root; + seg_fix_tailP = & text_fix_tail; + } +#endif } /* @@ -136,137 +164,137 @@ subseg_change (seg, subseg) */ void -subseg_new (seg, subseg) /* begin assembly for a new sub-segment */ - register segT seg; /* SEG_DATA or SEG_TEXT */ - register subsegT subseg; + subseg_new (seg, subseg) /* begin assembly for a new sub-segment */ +register segT seg; /* SEG_DATA or SEG_TEXT */ +register subsegT subseg; { - long tmp; /* JF for obstack alignment hacking */ - - know( seg == SEG_DATA || seg == SEG_TEXT ); - - if (seg != now_seg || subseg != now_subseg) - { /* we just changed sub-segments */ - register frchainS * frcP; /* crawl frchain chain */ - register frchainS** lastPP; /* address of last pointer */ - frchainS * newP; /* address of new frchain */ - register fragS * former_last_fragP; - register fragS * new_fragP; - - if (frag_now) /* If not bootstrapping. */ - { - frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal; - frag_wane(frag_now); /* Close off any frag in old subseg. */ - } -/* - * It would be nice to keep an obstack for each subsegment, if we swap - * subsegments a lot. Hence we would have much fewer frag_wanes(). - */ - { - - obstack_finish( &frags); - /* - * If we don't do the above, the next object we put on obstack frags - * will appear to start at the fr_literal of the current frag. - * Also, above ensures that the next object will begin on a - * address that is aligned correctly for the engine that runs - * this program. - */ - } - subseg_change (seg, (int)subseg); - /* - * Attempt to find or make a frchain for that sub seg. - * Crawl along chain of frchainSs, begins @ frchain_root. - * If we need to make a frchainS, link it into correct - * position of chain rooted in frchain_root. - */ - for (frcP = * (lastPP = & frchain_root); - frcP - && (int)(frcP -> frch_seg) <= (int)seg; - frcP = * ( lastPP = & frcP -> frch_next) - ) - { - if ( (int)(frcP -> frch_seg) == (int)seg - && frcP -> frch_subseg >= subseg) - { - break; - } - } - /* - * frcP: Address of the 1st frchainS in correct segment with - * frch_subseg >= subseg. - * We want to either use this frchainS, or we want - * to insert a new frchainS just before it. - * - * If frcP==NULL, then we are at the end of the chain - * of frchainS-s. A NULL frcP means we fell off the end - * of the chain looking for a - * frch_subseg >= subseg, so we - * must make a new frchainS. - * - * If we ever maintain a pointer to - * the last frchainS in the chain, we change that pointer - * ONLY when frcP==NULL. - * - * lastPP: Address of the pointer with value frcP; - * Never NULL. - * May point to frchain_root. - * - */ - if ( ! frcP - || ( (int)(frcP -> frch_seg) > (int)seg - || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ - { - /* - * This should be the only code that creates a frchainS. - */ - newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS)); - /* obstack_1blank( &frags, sizeof(frchainS), &newP); */ + long tmp; /* JF for obstack alignment hacking */ +#ifndef MANY_SEGMENTS + know( seg == SEG_DATA || seg == SEG_TEXT ); +#endif + if (seg != now_seg || subseg != now_subseg) + { /* we just changed sub-segments */ + register frchainS * frcP; /* crawl frchain chain */ + register frchainS** lastPP; /* address of last pointer */ + frchainS * newP; /* address of new frchain */ + register fragS * former_last_fragP; + register fragS * new_fragP; + + if (frag_now) /* If not bootstrapping. */ + { + frag_now -> fr_fix = obstack_next_free(& frags) - frag_now -> fr_literal; + frag_wane(frag_now); /* Close off any frag in old subseg. */ + } + /* + * It would be nice to keep an obstack for each subsegment, if we swap + * subsegments a lot. Hence we would have much fewer frag_wanes(). + */ + { + + obstack_finish( &frags); + /* + * If we don't do the above, the next object we put on obstack frags + * will appear to start at the fr_literal of the current frag. + * Also, above ensures that the next object will begin on a + * address that is aligned correctly for the engine that runs + * this program. + */ + } + subseg_change (seg, (int)subseg); + /* + * Attempt to find or make a frchain for that sub seg. + * Crawl along chain of frchainSs, begins @ frchain_root. + * If we need to make a frchainS, link it into correct + * position of chain rooted in frchain_root. + */ + for (frcP = * (lastPP = & frchain_root); + frcP + && (int)(frcP -> frch_seg) <= (int)seg; + frcP = * ( lastPP = & frcP -> frch_next) + ) + { + if ( (int)(frcP -> frch_seg) == (int)seg + && frcP -> frch_subseg >= subseg) + { + break; + } + } + /* + * frcP: Address of the 1st frchainS in correct segment with + * frch_subseg >= subseg. + * We want to either use this frchainS, or we want + * to insert a new frchainS just before it. + * + * If frcP==NULL, then we are at the end of the chain + * of frchainS-s. A NULL frcP means we fell off the end + * of the chain looking for a + * frch_subseg >= subseg, so we + * must make a new frchainS. + * + * If we ever maintain a pointer to + * the last frchainS in the chain, we change that pointer + * ONLY when frcP==NULL. + * + * lastPP: Address of the pointer with value frcP; + * Never NULL. + * May point to frchain_root. + * + */ + if ( ! frcP + || ( (int)(frcP -> frch_seg) > (int)seg + || frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */ + { + /* + * This should be the only code that creates a frchainS. + */ + newP=(frchainS *)obstack_alloc(&frags,sizeof(frchainS)); + memset(newP, sizeof(frchainS), 0); /* This begines on a good boundary */ /* because a obstack_done() preceeded it. */ /* It implies an obstack_done(), so we */ /* expect the next object allocated to */ /* begin on a correct boundary. */ - *lastPP = newP; - newP -> frch_next = frcP; /* perhaps NULL */ - (frcP = newP) -> frch_subseg = subseg; - newP -> frch_seg = seg; - newP -> frch_last = NULL; - } - /* - * Here with frcP ->ing to the frchainS for subseg. - */ - frchain_now = frcP; - /* - * Make a fresh frag for the subsegment. - */ - /* We expect this to happen on a correct */ - /* boundary since it was proceeded by a */ - /* obstack_done(). */ - tmp=obstack_alignment_mask(&frags); /* JF disable alignment */ - obstack_alignment_mask(&frags)=0; - frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); - obstack_alignment_mask(&frags)=tmp; - /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */ - /* But we want any more chars to come */ - /* immediately after the structure we just made. */ - new_fragP = frag_now; - new_fragP -> fr_next = NULL; - /* - * Append new frag to current frchain. - */ - former_last_fragP = frcP -> frch_last; - if (former_last_fragP) - { - know( former_last_fragP -> fr_next == NULL ); - know( frchain_now -> frch_root ); - former_last_fragP -> fr_next = new_fragP; - } - else - { - frcP -> frch_root = new_fragP; - } - frcP -> frch_last = new_fragP; - } /* if (changing subsegments) */ + *lastPP = newP; + newP -> frch_next = frcP; /* perhaps NULL */ + (frcP = newP) -> frch_subseg = subseg; + newP -> frch_seg = seg; + newP -> frch_last = NULL; + } + /* + * Here with frcP ->ing to the frchainS for subseg. + */ + frchain_now = frcP; + /* + * Make a fresh frag for the subsegment. + */ + /* We expect this to happen on a correct */ + /* boundary since it was proceeded by a */ + /* obstack_done(). */ + tmp=obstack_alignment_mask(&frags); /* JF disable alignment */ + obstack_alignment_mask(&frags)=0; + frag_now=(fragS *)obstack_alloc(&frags,SIZEOF_STRUCT_FRAG); + obstack_alignment_mask(&frags)=tmp; + /* know( frags . obstack_c_next_free == frag_now -> fr_literal ); */ + /* But we want any more chars to come */ + /* immediately after the structure we just made. */ + new_fragP = frag_now; + new_fragP -> fr_next = NULL; + /* + * Append new frag to current frchain. + */ + former_last_fragP = frcP -> frch_last; + if (former_last_fragP) + { + know( former_last_fragP -> fr_next == NULL ); + know( frchain_now -> frch_root ); + former_last_fragP -> fr_next = new_fragP; + } + else + { + frcP -> frch_root = new_fragP; + } + frcP -> frch_last = new_fragP; + } /* if (changing subsegments) */ } /* subseg_new() */ /* |