Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)

* expr.c(expr): allow SEG_REGISTER in expressions.
	* read.c(pseudo_set): register expressions can be the source of a
	set.
	* subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to
	goto SEG_TEXT (if a.out)
	* write.c (write_object_file): If a.out don't use the old way for
	-R.
	* config/obj-a.out (s_sect): complain if the user tries to use a
	subsegment with a value which might interfere with out -R hackery.
	* config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table
	rather than use ugly if tree. (init_regtable): insert register
	names into symbol table.
This commit is contained in:
Steve Chamberlain 1992-06-04 19:21:58 +00:00
parent f4a0f42d8a
commit f8701a3ff8
6 changed files with 4684 additions and 4543 deletions

View file

@ -1,3 +1,18 @@
Thu Jun 4 11:59:13 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* expr.c(expr): allow SEG_REGISTER in expressions.
* read.c(pseudo_set): register expressions can be the source of a
set.
* subsegs.c (subseg_new): Now -R forces all changes to SEG_DATA to
goto SEG_TEXT (if a.out)
* write.c (write_object_file): If a.out don't use the old way for
-R.
* config/obj-a.out (s_sect): complain if the user tries to use a
subsegment with a value which might interfere with out -R hackery.
* config/tc-m68k.c (m68k_reg_parse): lookup names in symbol table
rather than use ugly if tree. (init_regtable): insert register
names into symbol table.
Tue Jun 2 16:47:09 1992 Steve Chamberlain (sac@cygnus.com)
* write.c (write_object_file): keep the fix_tail clean, which

View file

@ -20,7 +20,7 @@
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ctype.h>
#define NO_RELOC 0
#include "as.h"
#include "obstack.h"
@ -540,252 +540,29 @@ static char alt_notend_table[256];
enum _register m68k_reg_parse(ccp)
register char **ccp;
{
#ifndef MAX_REG_NAME_LEN
#define MAX_REG_NAME_LEN (6)
#endif /* MAX_REG_NAME_LEN */
register char c[MAX_REG_NAME_LEN];
char *p, *q;
register int n = 0,
ret = FAIL;
char *start = *ccp;
c[0] = mklower(ccp[0][0]);
#ifdef REGISTER_PREFIX
if (c[0] != REGISTER_PREFIX) {
return(FAIL);
} /* need prefix */
#endif
if (isalpha(*start) && is_name_beginner(*start))
{
char c;
char *p = start;
symbolS *symbolP;
for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
{
if (*q == 0)
{
*p = 0;
break;
}
else
*p = mklower(*q);
} /* downcase */
while (is_part_of_name(c = *p++))
;
* -- p = 0;
symbolP = symbol_find(start);
*p = c;
switch(c[0]) {
case 'a':
if(c[1]>='0' && c[1]<='7') {
n=2;
ret=ADDR+c[1]-'0';
}
#ifndef NO_68851
else if (c[1] == 'c') {
n = 2;
ret = AC;
}
#endif
break;
#ifndef NO_68851
case 'b':
if (c[1] == 'a') {
if (c[2] == 'd') {
if (c[3] >= '0' && c[3] <= '7') {
n = 4;
ret = BAD + c[3] - '0';
}
} /* BAD */
if (c[2] == 'c') {
if (c[3] >= '0' && c[3] <= '7') {
n = 4;
ret = BAC + c[3] - '0';
}
} /* BAC */
} else if (c[1] == 'c') {
n = 2;
ret = BC;
} /* BC */
break;
#endif
case 'c':
#ifndef NO_68851
if (c[1] == 'a' && c[2] == 'l') {
n = 3;
ret = CAL;
} else
#endif
/* This supports both CCR and CC as the ccr reg. */
if(c[1]=='c' && c[2]=='r') {
n=3;
ret = CCR;
} else if(c[1]=='c') {
n=2;
ret = CCR;
} else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') {
n=4;
ret = c[2]=='a' ? CAAR : CACR;
}
#ifndef NO_68851
else if (c[1] == 'r' && c[2] == 'p') {
n = 3;
ret = (CRP);
}
#endif
break;
case 'd':
if (c[1] >= '0' && c[1] <= '7') {
n = 2;
ret = DATA + c[1] - '0';
} else if (c[1] == 'f' && c[2] == 'c') {
n = 3;
ret = DFC;
} else if (c[1] == 'c') {
n = 2;
ret = DC;
} else if (c[1] == 't' && c[2] == 't') {
if ('0' <= c[3] && c[3] <= '1') {
n = 4;
ret = DTT0 + (c[3] - '0');
} /* DTT[01] */
}
#ifndef NO_68851
else if (c[1] == 'r' && c[2] == 'p') {
n = 3;
ret = (DRP);
}
#endif
break;
case 'f':
if(c[1]=='p') {
if(c[2]>='0' && c[2]<='7') {
n=3;
ret = FPREG+c[2]-'0';
if(c[3]==':')
ccp[0][3]=',';
} else if(c[2]=='i') {
n=3;
ret = FPI;
} else if(c[2]=='s') {
n= (c[3] == 'r' ? 4 : 3);
ret = FPS;
} else if(c[2]=='c') {
n= (c[3] == 'r' ? 4 : 3);
ret = FPC;
}
}
break;
case 'i':
if (c[1] == 's' && c[2] == 'p') {
n = 3;
ret = ISP;
} else if (c[1] == 'c') {
n = 2;
ret = IC;
} else if (c[1] == 't' && c[2] == 't') {
if ('0' <= c[3] && c[3] <= '1') {
n = 4;
ret = ITT0 + (c[3] - '0');
} /* ITT[01] */
}
break;
case 'm':
if (c[1] == 's' && c[2] == 'p') {
n = 3;
ret = MSP;
} else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') {
n = 5;
ret = MMUSR;
}
break;
case 'n':
if (c[1] == 'c') {
n = 2;
ret = NC;
}
break;
case 'p':
if(c[1]=='c') {
#ifndef NO_68851
if(c[2] == 's' && c[3]=='r') {
n=4;
ret = (PCSR);
} else
#endif
if (symbolP && S_GET_SEGMENT(symbolP) == SEG_REGISTER)
{
n=2;
ret = PC;
*ccp = p;
return S_GET_VALUE(symbolP);
}
}
#ifndef NO_68851
else if (c[1] == 's' && c[2] == 'r') {
n = 3;
ret = (PSR);
}
#endif
break;
case 's':
#ifndef NO_68851
if (c[1] == 'c' && c[2] == 'c') {
n = 3;
ret = (SCC);
} else
#endif
if (c[1] == 'r') {
if (c[2] == 'p') {
n = 3;
ret = SRP;
} else {
n = 2;
ret = SR;
} /* srp else sr */
} else if (c[1] == 'p') {
n = 2;
ret = SP;
} else if (c[1] == 'f' && c[2] == 'c') {
n = 3;
ret = SFC;
}
break;
case 't':
if (c[1] == 'c') {
n = 2;
ret = TC;
}
break;
case 'u':
if (c[1] == 's' && c[2] == 'p') {
n=3;
ret = USP;
} else if (c[1] == 'r' && c[2] == 'p') {
n = 3;
ret = URP;
}
break;
case 'v':
#ifndef NO_68851
if (c[1] == 'a' && c[2] == 'l') {
n = 3;
ret = (VAL);
} else
#endif
if(c[1]=='b' && c[2]=='r') {
n=3;
ret = VBR;
}
break;
case 'z':
if(c[1]=='p' && c[2]=='c') {
n=3;
ret = ZPC;
}
break;
default:
break;
}
if(n) {
#ifdef REGISTER_PREFIX
n++;
#endif
if(isalnum(ccp[0][n]) || ccp[0][n]=='_')
ret=FAIL;
else
ccp[0]+=n;
} else
ret = FAIL;
return ret;
return FAIL;
}
#define SKIP_WHITE() { str++; if(*str==' ') str++;}
@ -1136,7 +913,7 @@ main()
for(;;) {
if(!gets(buf))
break;
bzero(&thark,sizeof(thark));
memset(&thark, '\0', sizeof(thark));
if(!m68k_ip_op(buf,&thark)) printf("FAIL:");
if(thark.error)
printf("op1 error %s in %s\n",thark.error,buf);
@ -1259,8 +1036,8 @@ void m68k_ip (instring)
for(n=opsfound;n>0;--n)
the_ins.operands[n]=the_ins.operands[n-1];
/* bcopy((char *)(&the_ins.operands[0]),(char *)(&the_ins.operands[1]),opsfound*sizeof(the_ins.operands[0])); */
bzero((char *)(&the_ins.operands[0]),sizeof(the_ins.operands[0]));
/* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
the_ins.operands[0].mode=MSCR;
the_ins.operands[0].reg=COPNUM; /* COP #1 */
opsfound++;
@ -2676,7 +2453,7 @@ char *str;
);
} /* default current_architecture */
bzero((char *)(&the_ins),sizeof(the_ins)); /* JF for paranoia sake */
memset((char *)(&the_ins), '\0', sizeof(the_ins)); /* JF for paranoia sake */
m68k_ip(str);
er=the_ins.error;
if(!er) {
@ -2806,6 +2583,140 @@ char *str;
/* This function is called once, at assembler startup time. This should
set up all the tables, etc that the MD part of the assembler needs
*/
void
insert_reg(regname, regnum)
char *regname;
int regnum;
{
char buf[100];
int i;
symbol_table_insert(symbol_new(regname, SEG_REGISTER, regnum, &zero_address_frag));
for (i = 0; regname[i]; i++)
buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
buf[i] = '\0';
symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag));
}
static struct {
char *name;
int number;
} init_table[] =
{
"d0", DATA0,
"d1", DATA1,
"d2", DATA2,
"d3", DATA3,
"d4", DATA4,
"d5", DATA5,
"d6", DATA6,
"d7", DATA7,
"a0", ADDR0,
"a1", ADDR1,
"a2", ADDR2,
"a3", ADDR3,
"a4", ADDR4,
"a5", ADDR5,
"a6", ADDR6,
"fp", ADDR6,
"a7", ADDR7,
"sp", ADDR7,
"fp0", FP0,
"fp1", FP1,
"fp2", FP2,
"fp3", FP3,
"fp4", FP4,
"fp5", FP5,
"fp6", FP6,
"fp7", FP7,
"fpi", FPI,
"fps", FPS,
"fpc", FPC,
"cop0", COP0,
"cop1", COP1,
"cop2", COP2,
"cop3", COP3,
"cop4", COP4,
"cop5", COP5,
"cop6", COP6,
"cop7", COP7,
"pc", PC,
"zpc", ZPC,
"sr", SR,
"ccr", CCR,
"cc", CCR,
"usp", USP,
"isp", ISP,
"sfc", SFC,
"dfc", DFC,
"cacr", CACR,
"caar", CAAR,
"vbr", VBR,
"msp", MSP,
"itt0", ITT0,
"itt1", ITT1,
"dtt0", DTT0,
"dtt1", DTT1,
"mmusr", MMUSR,
"tc", TC,
"srp", SRP,
"urp", URP,
#ifndef NO_68851
"ac", AC,
"bc", BC,
"cal", CAL,
"crp", CRP,
"drp", DRP,
"pcsr", PCSR,
"psr", PSR,
"scc", SCC,
"val", VAL,
"bad0", BAD0,
"bad1", BAD1,
"bad2", BAD2,
"bad3", BAD3,
"bad4", BAD4,
"bad5", BAD5,
"bad6", BAD6,
"bad7", BAD7,
"bac0", BAC0,
"bac1", BAC1,
"bac2", BAC2,
"bac3", BAC3,
"bac4", BAC4,
"bac5", BAC5,
"bac6", BAC6,
"bac7", BAC7,
#endif
"ic", IC,
"dc", DC,
"nc", NC,
0,
};
void
init_regtable()
{
int i;
for (i = 0; init_table[i].name; i++)
{
insert_reg(init_table[i].name, init_table[i].number);
}
}
void
md_begin()
{
@ -2877,6 +2788,8 @@ void
#ifdef REGISTER_PREFIX
alt_notend_table[REGISTER_PREFIX] = 1;
#endif
init_regtable();
}
#if 0
@ -3414,29 +3327,23 @@ void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
*/
static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
long r_extern;
long r_symbolnum;
/* this is easy */
know(fixP->fx_addsy != NULL);
md_number_to_chars(where,
fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
4);
/* now the fun stuff */
if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) {
r_extern = 1;
r_symbolnum = fixP->fx_addsy->sy_number;
} else {
r_extern = 0;
r_symbolnum = S_GET_TYPE(fixP->fx_addsy);
}
r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
? S_GET_TYPE(fixP->fx_addsy)
: fixP->fx_addsy->sy_number);
where[4] = (r_symbolnum >> 16) & 0x0ff;
where[5] = (r_symbolnum >> 8) & 0x0ff;
where[6] = r_symbolnum & 0x0ff;
where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) |
((r_extern << 4) & 0x10));
(((!S_IS_DEFINED(fixP->fx_addsy)) << 4) & 0x10));
return;
} /* tc_aout_fix_to_chars() */
@ -3839,7 +3746,7 @@ main()
*cp=' ';
if(is_label(buf))
continue;
bzero(&the_ins,sizeof(the_ins));
memset(&the_ins, '\0', sizeof(the_ins));
m68k_ip(&the_ins,buf);
if(the_ins.error) {
printf("Error %s in %s\n",the_ins.error,buf);
@ -3909,23 +3816,6 @@ abort()
exit(12);
}
char *index(s,c)
char *s;
{
while(*s!=c) {
if(!*s) return 0;
s++;
}
return s;
}
bzero(s,n)
char *s;
{
while(n--)
*s++=0;
}
print_frags()
{
fragS *fragP;
@ -3991,7 +3881,7 @@ long
md_pcrel_from (fixP)
fixS *fixP;
{
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
return(fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
}
/*

View file

@ -39,10 +39,6 @@ static void clean_up_expression(); /* Internal. */
extern const char EXP_CHARS[]; /* JF hide MD floating pt stuff all the same place */
extern const char FLT_CHARS[];
#ifdef LOCAL_LABELS_DOLLAR
extern int local_label_defined[];
#endif
/*
* Build any floating-point literal here.
* Also build any bignum literal here.
@ -101,8 +97,6 @@ expressionS *expressionP;
integer_constant(radix, expressionP)
int radix;
expressionS *expressionP;
{
register char * digit_2; /*->2nd digit of number. */
char c;
@ -217,25 +211,18 @@ expressionS *expressionP;
number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
}
}
if (small)
{
if (small) {
/*
* here with number, in correct radix. c is the next char.
* note that unlike un*x, we allow "011f" "0x9f" to
* both mean the same as the (conventional) "9f". this is simply easier
* than checking for strict canonical form. syntax sux!
*/
if (number<10)
{
if (0
switch (c) {
#ifdef LOCAL_LABELS_FB
|| c=='b'
#endif
#ifdef LOCAL_LABELS_DOLLAR
|| (c=='$' && local_label_defined[number])
#endif
)
{
case 'b': {
/*
* backward ref to local label.
* because it is backward, expect it to be defined.
@ -243,45 +230,37 @@ expressionS *expressionP;
/*
* construct a local label.
*/
name = local_label_name ((int)number, 0);
if (((symbolP = symbol_find(name)) != NULL) /* seen before */
&& (S_IS_DEFINED(symbolP))) /* symbol is defined: ok */
{ /* expected path: symbol defined. */
name = fb_label_name((int) number, 0);
/* seen before, or symbol is defined: ok */
symbolP = symbol_find(name);
if ((symbolP != NULL) && (S_IS_DEFINED(symbolP))) {
/* local labels are never absolute. don't waste time checking absoluteness. */
know(SEG_NORMAL(S_GET_SEGMENT(symbolP)));
expressionP->X_add_symbol = symbolP;
expressionP->X_add_number = 0;
expressionP->X_seg = S_GET_SEGMENT(symbolP);
}
else
{ /* either not seen or not defined. */
as_bad("backw. ref to unknown label \"%d:\", 0 assumed.",
number);
expressionP->X_add_number = 0;
} else { /* either not seen or not defined. */
as_bad("backw. ref to unknown label \"%d:\", 0 assumed.", number);
expressionP->X_seg = SEG_ABSOLUTE;
}
}
else
{
if (0
#ifdef LOCAL_LABELS_FB
|| c == 'f'
#endif
#ifdef LOCAL_LABELS_DOLLAR
|| (c=='$' && !local_label_defined[number])
#endif
)
{
expressionP->X_add_number = 0;
break;
} /* case 'b' */
case 'f': {
/*
* forward reference. expect symbol to be undefined or
* unknown. undefined: seen it before. unknown: never seen
* it in this pass.
* it before.
* construct a local label name, then an undefined symbol.
* don't create a xseg frag for it: caller may do that.
* just return it as never seen before.
*/
name = local_label_name((int)number, 1);
name = fb_label_name((int) number, 1);
symbolP = symbol_find_or_make(name);
/* we have no need to check symbol properties. */
#ifndef many_segments
@ -293,29 +272,54 @@ expressionS *expressionP;
expressionP->X_seg = SEG_UNKNOWN;
expressionP->X_subtract_symbol = NULL;
expressionP->X_add_number = 0;
break;
} /* case 'f' */
#endif /* LOCAL_LABELS_FB */
#ifdef LOCAL_LABELS_DOLLAR
case '$': {
/* if the dollar label is *currently* defined, then this is just another
reference to it. If it is not *currently* defined, then this is a
fresh instantiation of that number, so create it. */
if (dollar_label_defined(number)) {
name = dollar_label_name(number, 0);
symbolP = symbol_find(name);
know(symbolP != NULL);
} else {
name = dollar_label_name(number, 1);
symbolP = symbol_find_or_make(name);
}
else
{ /* really a number, not a local label. */
expressionP->X_add_symbol = symbolP;
expressionP->X_add_number = 0;
expressionP->X_seg = S_GET_SEGMENT(symbolP);
break;
} /* case '$' */
#endif /* LOCAL_LABELS_DOLLAR */
default: {
expressionP->X_add_number = number;
expressionP->X_seg = SEG_ABSOLUTE;
input_line_pointer--; /* restore following character. */
} /* if (c=='f') */
} /* if (c=='b') */
}
else
{ /* really a number. */
expressionP->X_add_number = number;
expressionP->X_seg = SEG_ABSOLUTE;
input_line_pointer --; /* restore following character. */
} /* if (number<10) */
}
else
{
break;
} /* really just a number */
} /* switch on char following the number */
} else { /* not a small number */
expressionP->X_add_number = number;
expressionP->X_seg = SEG_BIG;
input_line_pointer --; /*->char following number. */
} /* if (small) */
}
} /* integer_constant() */
/*
@ -390,10 +394,21 @@ operand (expressionP)
{
default:
if (c && strchr(FLT_CHARS,c))
{
input_line_pointer++;
floating_constant(expressionP);
}
else
{
/* The string was only zero */
expressionP->X_add_symbol = 0;
expressionP->X_add_number = 0;
expressionP->X_seg = SEG_ABSOLUTE;
}
break;
case 'x':
@ -435,7 +450,7 @@ operand (expressionP)
case 'd':
case 'D':
case 'F':
case 'r':
case 'e':
case 'E':
case 'g':
@ -459,7 +474,7 @@ operand (expressionP)
}
/* here with input_line_pointer->char after "(...)" */
}
return;
return expressionP->X_seg;
case '\'':
@ -931,7 +946,9 @@ register expressionS *resultP; /* Deliver result here. */
segT seg1;
segT seg2;
#ifndef MANY_SEGMENTS
know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1);
know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg ==
SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1
|| resultP->X_seg == SEG_REGISTER);
know(right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1);
#endif
clean_up_expression (& right);

View file

@ -1,6 +1,5 @@
/* read.c - read a source file -
Copyright (C) 1986, 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -36,12 +35,9 @@
#include "as.h"
#include "obstack.h"
#include "listing.h"
char *input_line_pointer; /*->next char of source file to parse. */
#ifndef NOP_OPCODE
# define NOP_OPCODE 0x00
#endif
#if BITS_PER_CHAR != 8
The following table is indexed by [ (char) ] and will break if
@ -123,7 +119,7 @@ struct broken_word *broken_words;
int new_broken_words = 0;
#endif
#if __STDC__ == 1
#ifdef __STDC__
static char *demand_copy_string(int *lenP);
int is_it_end_of_statement(void);
@ -143,7 +139,7 @@ static void grow_bignum();
static void pobegin();
void stringer();
#endif /* not __STDC__ */
#endif /* __STDC__ */
extern int listing;
@ -174,6 +170,11 @@ void
struct hash_control *
po_hash = NULL; /* use before set up: NULL->address error */
#ifdef DONTDEF
void s_gdbline(), s_gdblinetab();
void s_gdbbeg(), s_gdbblock(), s_gdbend(), s_gdbsym();
#endif
static const pseudo_typeS
potable[] =
{
@ -183,17 +184,12 @@ static const pseudo_typeS
{ "asciz", stringer, 1 },
/* block */
{ "byte", cons, 1 },
{ "bss", s_bss, 0 },
{ "comm", s_comm, 0 },
{ "data", s_data, 0 },
/* dim */
{ "double", float_cons, 'd' },
/* dsect */
#ifdef NO_LISTING
{ "eject", s_ignore, 0 }, /* Formfeed listing */
#else
{ "eject", listing_eject, 0 }, /* Formfeed listing */
#endif /* NO_LISTING */
{ "else", s_else, 0 },
{ "end", s_end, 0 },
{ "endif", s_endif, 0 },
@ -206,6 +202,14 @@ static const pseudo_typeS
{ "file", s_app_file, 0 },
{ "fill", s_fill, 0 },
{ "float", float_cons, 'f' },
#ifdef DONTDEF
{ "gdbbeg", s_gdbbeg, 0 },
{ "gdbblock", s_gdbblock, 0 },
{ "gdbend", s_gdbend, 0 },
{ "gdbsym", s_gdbsym, 0 },
{ "gdbline", s_gdbline, 0 },
{ "gdblinetab",s_gdblinetab, 0 },
#endif
{ "global", s_globl, 0 },
{ "globl", s_globl, 0 },
{ "hword", cons, 2 },
@ -218,34 +222,17 @@ static const pseudo_typeS
{ "include", s_include, 0 },
{ "int", cons, 4 },
{ "lcomm", s_lcomm, 0 },
#ifdef NO_LISTING
{ "lflags", s_ignore, 0 }, /* Listing flags */
{ "list", s_ignore, 1 }, /* Turn listing on */
#else
{ "lflags", listing_flags, 0 }, /* Listing flags */
{ "list", listing_list, 1 }, /* Turn listing on */
#endif /* NO_LISTING */
{ "long", cons, 4 },
{ "lsym", s_lsym, 0 },
#ifdef NO_LISTING
{ "nolist", s_ignore, 0 }, /* Turn listing off */
#else
{ "nolist", listing_list, 0 }, /* Turn listing off */
#endif /* NO_LISTING */
{ "octa", big_cons, 16 },
{ "org", s_org, 0 },
#ifdef NO_LISTING
{ "psize", s_ignore, 0 }, /* set paper size */
#else
{ "psize", listing_psize, 0 }, /* set paper size */
#endif /* NO_LISTING */
/* print */
{ "quad", big_cons, 8 },
#ifdef NO_LISTING
{ "sbttl", s_ignore, 1 }, /* Subtitle of listing */
#else
{ "sbttl", listing_title, 1 }, /* Subtitle of listing */
#endif /* NO_LISTING */
/* scl */
/* sect */
{ "set", s_set, 0 },
@ -255,11 +242,7 @@ static const pseudo_typeS
{ "space", s_space, 0 },
/* tag */
{ "text", s_text, 0 },
#ifdef NO_LISTING
{ "title", s_ignore, 0 }, /* Listing title */
#else
{ "title", listing_title, 0 }, /* Listing title */
#endif /* NO_LISTING */
/* type */
/* use */
/* val */
@ -337,6 +320,12 @@ char *name;
register int temp;
/* register struct frag * fragP; JF unused */ /* a frag we just made */
pseudo_typeS *pop;
#ifdef DONTDEF
void gdb_block_beg();
void gdb_block_position();
void gdb_block_end();
void gdb_symbols_fixup();
#endif
buffer = input_scrub_new_file(name);
@ -356,10 +345,26 @@ char *name;
*/
if (input_line_pointer[-1] == '\n') {
bump_line_counters();
#ifdef MRI
/* Text at the start of a line must be a label, we run down and stick a colon in */
if (is_name_beginner(*input_line_pointer))
{
char *line_start = input_line_pointer;
char c = get_symbol_end();
colon(line_start);
*input_line_pointer = c;
if (c == ':')
input_line_pointer++;
}
#endif
} /* just passed a newline */
/*
* We are at the begining of a line, or similar place.
* We expect a well-formed assembler statement.
@ -406,6 +411,10 @@ char *name;
equals(s);
demand_empty_rest_of_line();
} else { /* expect pseudo-op or machine instruction */
#ifdef MRI
if(!done_pseudo(s))
#else
if (*s == '.') {
/*
* PSEUDO - OP.
@ -443,17 +452,23 @@ char *name;
} else {
(*pop->poc_handler)(pop->poc_val);
} /* if we have one */
} else { /* machine instruction */
} else
#endif
{ /* machine instruction */
/* WARNING: c has char, which may be end-of-line. */
/* Also: input_line_pointer->`\0` where c was. */
* input_line_pointer = c;
while (!is_end_of_line[*input_line_pointer]) {
input_line_pointer++;
}
c = *input_line_pointer;
*input_line_pointer = '\0';
md_assemble(s); /* Assemble 1 instruction. */
*input_line_pointer++ = c;
/* We resume loop AFTER the end-of-line from this instruction */
} /* if (*s=='.') */
@ -467,26 +482,45 @@ char *name;
} /* empty statement */
#if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
if (isdigit(c)) { /* local label ("4:") */
char *backup = input_line_pointer;
HANDLE_CONDITIONAL_ASSEMBLY ();
temp = c - '0';
while (isdigit(*input_line_pointer)) {
temp = (temp * 10) + *input_line_pointer - '0';
++input_line_pointer;
} /* read the whole number */
#ifdef LOCAL_LABELS_DOLLAR
if (*input_line_pointer=='$')
input_line_pointer++;
#endif
if (* input_line_pointer ++ == ':')
{
local_colon (temp);
}
else
{
as_bad("Spurious digit %d.", temp);
input_line_pointer -- ;
ignore_rest_of_line();
if (*input_line_pointer == '$'
&& *(input_line_pointer + 1) == ':') {
input_line_pointer += 2;
if (dollar_label_defined(temp)) {
as_fatal("label \"%d$\" redefined", temp);
}
define_dollar_label(temp);
colon(dollar_label_name(temp, 0));
continue;
}
#endif /* LOCAL_LABELS_DOLLAR */
#ifdef LOCAL_LABELS_FB
if (*input_line_pointer++ == ':') {
fb_label_instance_inc(temp);
colon(fb_label_name(temp, 0));
continue;
}
#endif /* LOCAL_LABELS_FB */
input_line_pointer = backup;
} /* local label ("4:") */
#endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
if (c && strchr(line_comment_chars,c)) { /* Its a comment. Better say APP or NO_APP */
char *ends;
@ -514,7 +548,7 @@ char *name;
guarentee it. . . */
tmp_len=buffer_limit-s;
tmp_buf=xmalloc(tmp_len);
memcpy(tmp_buf, s, tmp_len);
bcopy(s,tmp_buf,tmp_len);
do {
new_tmp = input_scrub_next_buffer(&buffer);
if (!new_tmp)
@ -529,7 +563,7 @@ char *name;
num=buffer_limit-buffer;
tmp_buf = xrealloc(tmp_buf, tmp_len + num);
memcpy(tmp_buf + tmp_len, buffer, num);
bcopy(buffer,tmp_buf+tmp_len,num);
tmp_len+=num;
} while(!ends);
@ -630,7 +664,7 @@ int arg;
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else {
temp_fill = NOP_OPCODE;
temp_fill = 0;
}
/* Only make a frag if we HAVE to. . . */
if (temp && ! need_pass_2)
@ -656,7 +690,7 @@ void s_align_ptwo() {
input_line_pointer ++;
temp_fill = get_absolute_expression ();
} else
temp_fill = NOP_OPCODE;
temp_fill = 0;
/* Only make a frag if we HAVE to. . . */
if (temp && ! need_pass_2)
frag_align (temp, (int)temp_fill);
@ -666,17 +700,6 @@ void s_align_ptwo() {
demand_empty_rest_of_line();
} /* s_align_ptwo() */
void s_bss()
{
register int temp;
temp = get_absolute_expression ();
subseg_new (SEG_BSS, (subsegT)temp);
demand_empty_rest_of_line();
}
void s_comm() {
register char *name;
register char c;
@ -794,7 +817,7 @@ void s_fill() {
temp_fill = get_absolute_expression ();
if (temp_size && !need_pass_2) {
p = frag_var(rs_fill, (int)temp_size, (int)temp_size, (relax_substateT)0, (symbolS *)0, temp_repeat, (char *)0);
memset(p, '\0', (int) temp_size);
bzero (p, (int)temp_size);
/*
* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
* The following bizzare behaviour is to be compatible with above.
@ -812,6 +835,118 @@ void s_fill() {
demand_empty_rest_of_line();
}
#ifdef DONTDEF
void
s_gdbbeg()
{
register int temp;
temp = get_absolute_expression ();
if (temp < 0)
as_warn("Block number <0. Ignored.");
else if (flagseen ['G'])
gdb_block_beg ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
demand_empty_rest_of_line ();
}
void
s_gdbblock()
{
register int position;
int temp;
if (get_absolute_expression_and_terminator (&temp) != ',') {
as_bad("expected comma before position in .gdbblock");
--input_line_pointer;
ignore_rest_of_line ();
return;
}
position = get_absolute_expression ();
if (flagseen ['G'])
gdb_block_position ((long) temp, (long) position);
demand_empty_rest_of_line ();
}
void
s_gdbend()
{
register int temp;
temp = get_absolute_expression ();
if (temp < 0)
as_warn("Block number <0. Ignored.");
else if (flagseen ['G'])
gdb_block_end ((long) temp, frag_now, (long)(obstack_next_free(& frags) - frag_now->fr_literal));
demand_empty_rest_of_line ();
}
void
s_gdbsym()
{
register char *name,
*p;
register char c;
register symbolS * symbolP;
register int temp;
name = input_line_pointer;
c = get_symbol_end();
p = input_line_pointer;
symbolP = symbol_find_or_make(name);
*p = c;
SKIP_WHITESPACE();
if (* input_line_pointer != ',') {
as_bad("Expected comma after name");
ignore_rest_of_line();
return;
}
input_line_pointer ++;
if ((temp = get_absolute_expression ()) < 0) {
as_bad("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
ignore_rest_of_line();
return;
}
if (flagseen ['G'])
gdb_symbols_fixup (symbolP, (long)temp);
demand_empty_rest_of_line ();
}
void
s_gdbline()
{
int file_number,
lineno;
if (get_absolute_expression_and_terminator(&file_number) != ',') {
as_bad("expected comman after filenum in .gdbline");
ignore_rest_of_line();
return;
}
lineno=get_absolute_expression();
if (flagseen['G'])
gdb_line(file_number,lineno);
demand_empty_rest_of_line();
}
void
s_gdblinetab()
{
int file_number,
offset;
if (get_absolute_expression_and_terminator(&file_number) != ',') {
as_bad("expected comma after filenum in .gdblinetab");
ignore_rest_of_line();
return;
}
offset=get_absolute_expression();
if (flagseen['G'])
gdb_line_tab(file_number,offset);
demand_empty_rest_of_line();
}
#endif
void s_globl() {
register char *name;
register int c;
@ -1229,6 +1364,12 @@ symbolS * symbolP;
switch (segment)
{
case SEG_REGISTER:
S_SET_SEGMENT(symbolP, SEG_REGISTER);
S_SET_VALUE(symbolP, exp.X_add_number);
symbolP->sy_frag = & zero_address_frag;
break;
case SEG_BIG:
as_bad("%s number invalid. Absolute 0 assumed.",
exp . X_add_number > 0 ? "Bignum" : "Floating-Point");
@ -1283,6 +1424,7 @@ symbolS * symbolP;
case SEG_DATA: S_SET_SEGMENT(symbolP, SEG_DATA); break;
case SEG_TEXT: S_SET_SEGMENT(symbolP, SEG_TEXT); break;
case SEG_BSS: S_SET_SEGMENT(symbolP, SEG_BSS); break;
default: as_fatal("failed sanity check.");
} /* switch on segment */
#endif
@ -1386,7 +1528,53 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
/* used for error messages and rescanning */
char *hold = input_line_pointer;
#endif /* WANT_BITFIELDS */
#ifdef MRI
if (*input_line_pointer == '\'')
{
/* An MRI style string, cut into as many bytes as will fit
into a nbyte chunk, left justify if necessary, and sepatate
with commas so we can try again later */
int scan = 0;
unsigned int result = 0;
input_line_pointer++;
for (scan = 0; scan < nbytes; scan++)
{
if (*input_line_pointer == '\'')
{
if (input_line_pointer[1] == '\'')
{
input_line_pointer++;
}
else
break;
}
result = (result << 8) | (*input_line_pointer++);
}
/* Left justify */
while (scan < nbytes)
{
result <<=8;
scan++;
}
/* Create correct expression */
exp.X_add_symbol = 0;
exp.X_add_number = result;
exp.X_seg = segment = SEG_ABSOLUTE;
/* Fake it so that we can read the next char too */
if (input_line_pointer[0] != '\'' ||
(input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
{
input_line_pointer-=2;
input_line_pointer[0] = ',';
input_line_pointer[1] = '\'';
}
else
input_line_pointer++;
}
else
#endif
/* At least scan over the expression. */
segment = expression(&exp);
@ -1558,9 +1746,23 @@ register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
exp . X_add_symbol, exp . X_subtract_symbol,
exp . X_add_number, 0, 0, 2, 0, 0);
#else
# if defined(TC_SPARC) || defined(TC_A29K)
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
exp . X_add_symbol, exp . X_subtract_symbol,
exp . X_add_number, 0, RELOC_32);
# else
# if defined(TC_H8300)
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
exp . X_add_symbol, exp . X_subtract_symbol,
exp . X_add_number, 0, R_RELWORD);
# else
fix_new (frag_now, p - frag_now->fr_literal, nbytes,
exp . X_add_symbol, exp . X_subtract_symbol,
exp . X_add_number, 0, 0);
# endif /* tc_h8300 */
# endif /* tc_sparc|tc_a29k */
#endif /* TC_NS32K */
break;
} /* switch(segment) */
@ -1693,7 +1895,7 @@ register int nbytes;
if (! need_pass_2)
{
p = frag_more (nbytes);
memcpy(p, bignum_low, (int) nbytes);
bcopy (bignum_low, p, (int)nbytes);
}
/* C contains character after number. */
SKIP_WHITESPACE();
@ -1763,7 +1965,8 @@ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
{
c = ','; /* Do loop. */
}
while (c == ',') {
while (c == ',')
{
/* input_line_pointer->1st char of a flonum (we hope!). */
SKIP_WHITESPACE();
/* Skip any 0{letter} that may be present. Don't even check if the
@ -1778,15 +1981,19 @@ register int float_type; /* 'f':.ffloat ... 'F':.float ... */
err = md_atof (float_type, temp, &length);
know(length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
know(length > 0);
if (* err) {
if (* err)
{
as_bad("Bad floating literal: %s", err);
ignore_rest_of_line();
/* Input_line_pointer->just after end-of-line. */
c = 0; /* Break out of loop. */
} else {
if (! need_pass_2) {
}
else
{
if (! need_pass_2)
{
p = frag_more (length);
memcpy(p, temp, length);
bcopy (temp, p, length);
}
SKIP_WHITESPACE();
c = * input_line_pointer ++;
@ -1811,7 +2018,12 @@ void stringer(append_zero ) /* Worker to do .ascii etc statements. */
/* Checks end-of-line. */
register int append_zero; /* 0: don't append '\0', else 1 */
{
unsigned int c;
/* register char * p; JF unused */
/* register int length; JF unused */ /* Length of string we read, excluding */
/* trailing '\0' implied by closing quote. */
/* register char * where; JF unused */
/* register fragS * fragP; JF unused */
register unsigned int c;
/*
* The following awkward logic is to parse ZERO or more strings,
@ -1821,13 +2033,15 @@ register int append_zero; /* 0: don't append '\0', else 1 */
* a 1st, expression. We keep demanding expressions for each
* ','.
*/
if (is_it_end_of_statement()) {
if (is_it_end_of_statement())
{
c = 0; /* Skip loop. */
++ input_line_pointer; /* Compensate for end of loop. */
} else {
}
else
{
c = ','; /* Do loop. */
}
while (c == ',' || c == '<' || c == '"' ) {
SKIP_WHITESPACE();
switch (*input_line_pointer) {

View file

@ -35,8 +35,7 @@ frchainS* frchain_root,
#else
frchainS* frchain_root,
* frchain_now, /* Commented in "subsegs.h". */
* data0_frchainP,
* bss0_frchainP;
* data0_frchainP;
#endif
char * const /* in: segT out: char* */
@ -109,8 +108,6 @@ void
#else
subseg_new (SEG_DATA, 0); /* .data 0 */
data0_frchainP = frchain_now;
subseg_new (SEG_BSS, 0);
bss0_frchainP = frchain_now;
#endif
}
@ -136,12 +133,7 @@ register int subseg;
seg_fix_rootP = & segment_info[seg].fix_root;
seg_fix_tailP = & segment_info[seg].fix_tail;
#else
if (seg == SEG_BSS)
{
seg_fix_rootP = & bss_fix_root;
seg_fix_tailP = & bss_fix_tail;
}
else if (seg == SEG_DATA)
if (seg == SEG_DATA)
{
seg_fix_rootP = & data_fix_root;
seg_fix_tailP = & data_fix_tail;
@ -173,13 +165,25 @@ register int subseg;
void
subseg_new (seg, subseg) /* begin assembly for a new sub-segment */
register segT seg; /* SEG_DATA or SEG_TEXT or SEG_BSS */
register segT seg; /* SEG_DATA or SEG_TEXT */
register subsegT subseg;
{
long tmp; /* JF for obstack alignment hacking */
#ifndef MANY_SEGMENTS
know( seg == SEG_DATA || seg == SEG_TEXT || seg == SEG_BSS);
know(seg == SEG_DATA || seg == SEG_TEXT);
#endif
#ifdef OBJ_AOUT
/* If -R specifed, always put stuff into the data section */
if (flagseen['R'])
{
if (seg == SEG_DATA)
{
subseg += 1000;
seg = SEG_TEXT;
}
}
#endif
if (seg != now_seg || subseg != now_subseg)
{ /* we just changed sub-segments */
register frchainS * frcP; /* crawl frchain chain */

View file

@ -215,6 +215,7 @@ void write_object_file()
* data frags into the text segment. Do this before relaxing so
* we know to take advantage of -R and make shorter addresses.
*/
#ifndef OBJ_AOUT
if (flagseen[ 'R' ]) {
fixS *tmp;
@ -230,7 +231,7 @@ void write_object_file()
text_fix_root=data_fix_root;
data_fix_root=NULL;
}
#endif
relax_segment(text_frag_root, SEG_TEXT);
relax_segment(data_frag_root, SEG_DATA);
/*