diff options
author | Ian Lance Taylor <ian@airs.com> | 1992-09-09 18:38:16 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1992-09-09 18:38:16 +0000 |
commit | 3ad9ec6a7b491be1e1224861f31b351720fa1df0 (patch) | |
tree | 90c69136274493011976f4b512a566a8aecb0ab2 /gas/config/tc-m68k.c | |
parent | b53ccaacae4537af9cdc9b037f49f16467f84ea4 (diff) | |
download | gdb-3ad9ec6a7b491be1e1224861f31b351720fa1df0.zip gdb-3ad9ec6a7b491be1e1224861f31b351720fa1df0.tar.gz gdb-3ad9ec6a7b491be1e1224861f31b351720fa1df0.tar.bz2 |
Wed Sep 9 11:10:24 1992 Ian Lance Taylor (ian@cygnus.com)
* tc-m68k.c (m68k_ip, m68k_ip_op, get_num, try_moto_index): merge
Motorola and MIT syntax; gas can now assemble either type of
file.
tc-m68kmote.c, tc-m68kmote.h: removed now superfluous files.
From Steve Chamberlain:
m68kcoff.mt: for m68k COFF.
obj-coffbfd.c: (fixup_mdeps) added
(size_section) removed bad sanity check
(fill_section) added rs_machine_dependent case
(write_object_file) call fixup_mdeps
(fixup_segment) set fx_subsy to 0.
obj-coffbfd.h: define WORKING_DOT_WORD (too hard to support) and
handle m68k.
tc-m68k.c, config/tc-m68k.h: added m68k COFF support and Motorala
pseudo ops.
Diffstat (limited to 'gas/config/tc-m68k.c')
-rw-r--r-- | gas/config/tc-m68k.c | 695 |
1 files changed, 556 insertions, 139 deletions
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index e243362..0342624 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -22,11 +22,13 @@ #include <ctype.h> #define NO_RELOC 0 #include "as.h" +#include "read.h" #include "obstack.h" /* note that this file includes real declarations and thus can only be included by one source file per executable. */ #include "opcode/m68k.h" + #ifdef TE_SUN /* This variable contains the value to write out at the beginning of the a.out file. The 2<<16 means that this is a 68020 file instead @@ -76,8 +78,8 @@ static struct obstack robyn; #define SHORT 1 #define LONG 2 #define SZ_UNDEF 3 - -#define BRANCH 1 +#undef BRANCH +#define ABRANCH 1 #define FBRANCH 2 #define PCREL 3 #define BCC68000 4 @@ -383,6 +385,8 @@ struct m68k_incant { struct m68k_incant *m_next; }; + + #define getone(x) ((((x)->m_opcode)>>16)&0xffff) #define gettwo(x) (((x)->m_opcode)&0xffff) @@ -397,7 +401,7 @@ static int reverse_8_bits(int in); static int try_index(char **s, struct m68k_op *opP); static void install_gen_operand(int mode, int val); static void install_operand(int mode, int val); - void s_bss(void); +static void s_bss(void); static void s_data1(void); static void s_data2(void); static void s_even(void); @@ -413,7 +417,7 @@ static int reverse_8_bits(); static int try_index(); static void install_gen_operand(); static void install_operand(); -void s_bss(); +static void s_bss(); void s_align_bytes(); static void s_data1(); static void s_data2(); @@ -446,8 +450,8 @@ const relax_typeS { 1, 1, 0, 0 }, /* that the VAX doesn't either */ { 1, 1, 0, 0 }, - { (127), (-128), 0, TAB(BRANCH,SHORT)}, - { (32767), (-32768), 2, TAB(BRANCH,LONG) }, + { (127), (-128), 0, TAB(ABRANCH,SHORT)}, + { (32767), (-32768), 2, TAB(ABRANCH,LONG) }, { 0, 0, 4, 0 }, { 1, 1, 0, 0 }, @@ -503,6 +507,33 @@ const pseudo_typeS md_pseudo_table[] = { }; +/* The mote pseudo ops are put into the opcode table, since they + don't start with a . they look like opcodes to gas. + */ +extern void obj_coff_section(); + +const pseudo_typeS mote_pseudo_table[] = +{ + + { "dc.l", cons,4}, + { "dc", cons,2}, + { "dc.w", cons,2}, + { "dc.b", cons,1}, + + { "ds.l", s_space,4}, + { "ds", s_space,2}, + { "ds.w", s_space,2}, + { "ds.b", s_space,1}, + + { "xdef", s_globl, 0}, + { "align", s_align_ptwo, 0}, +#ifdef M68KCOFF + { "sect", obj_coff_section,0}, + { "section", obj_coff_section,0}, +#endif + 0, +}; + /* #define isbyte(x) ((x)>=-128 && (x)<=127) */ /* #define isword(x) ((x)>=-32768 && (x)<=32767) */ @@ -557,7 +588,12 @@ register char **ccp; char *p = start; symbolS *symbolP; - while (is_part_of_name(c = *p++)) + c = *p++; + while (isalpha(c) || isdigit(c)) + { + c = *p++; + } + ; * -- p = 0; symbolP = symbol_find(start); @@ -575,18 +611,175 @@ register char **ccp; } #define SKIP_WHITE() { str++; if(*str==' ') str++;} +#define SKIP_W() { ss++; if(*ss==' ') ss++;} + +/* Parse an index specification using Motorola syntax. */ + +static int +try_moto_index(s,opP) +char **s; +struct m68k_op *opP; +{ + register int i; + char *ss; + + ss= *s; + /* SKIP_W(); */ + if(*ss==' ') ss++; + i=m68k_reg_parse(&ss); + if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ + opP->error="Invalid index register"; + *s=ss; + return FAIL; + } + opP->ireg=i; + /* SKIP_W(); */ + if(*ss==')') { + opP->isiz=0; + opP->imul=1; + SKIP_W(); + *s=ss; + return OK; + } + if(*ss!='.') { + opP->error="Missing . in index register"; + *s=ss; + return FAIL; + } + SKIP_W(); + if(mklower(*ss)=='w') opP->isiz=2; + else if(mklower(*ss)=='l') opP->isiz=3; + else { + opP->error="Size spec not .W or .L"; + *s=ss; + return FAIL; + } + SKIP_W(); + if(*ss=='.' || *ss=='*') { + SKIP_W(); + switch(*ss) { + case '1': + case '2': + case '4': + case '8': + opP->imul= *ss-'0'; + break; + default: + opP->error="index multiplier not 1, 2, 4 or 8"; + *s=ss; + return FAIL; + } + SKIP_W(); + } else opP->imul=1; + if(*ss!=')') { + opP->error="Missing )"; + *s=ss; + return FAIL; + } + SKIP_W(); + *s=ss; + return OK; +} /* - * m68k_ip_op := '#' + <anything> - * | <register> + range_sep + get_regs + * + * try_index := data_or_address_register + ')' + SKIP_W + * | data_or_address_register + ':' + SKIP_W + size_spec + SKIP_W + multiplier + ')' + SKIP_W + * + * multiplier := <empty> + * | ':' + multiplier_number * ; * - * range_sep := '/' | '-' ; + * multiplier_number := '1' | '2' | '4' | '8' ; * - * SKIP_WHITE := <empty> | ' ' ; + * size_spec := 'l' | 'L' | 'w' | 'W' ; + * + * SKIP_W := <empty> | ' ' ; * */ +static int try_index(s,opP) +char **s; +struct m68k_op *opP; +{ + register int i; + char *ss; + + ss= *s; + /* SKIP_W(); */ + i=m68k_reg_parse(&ss); + if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ + *s=ss; + return FAIL; + } + opP->ireg=i; + /* SKIP_W(); */ + if(*ss==')') { + opP->isiz=0; + opP->imul=1; + SKIP_W(); + *s=ss; + return OK; + } + if(*ss!=':') { + opP->error="Missing : in index register"; + *s=ss; + return FAIL; + } + SKIP_W(); + switch(*ss) { + case 'w': + case 'W': + opP->isiz=2; + break; + case 'l': + case 'L': + opP->isiz=3; + break; + default: + opP->error="Index register size spec not :w or :l"; + *s=ss; + return FAIL; + } + SKIP_W(); + if(*ss==':') { + SKIP_W(); + switch(*ss) { + case '1': + case '2': + case '4': + case '8': + if (cpu_of_arch(current_architecture) < m68020) { + opP->error="no index scaling in pre-68020's"; + *s=ss; + return FAIL; + } + opP->imul= *ss-'0'; + break; + default: + opP->error="index multiplier not 1, 2, 4 or 8"; + *s=ss; + return FAIL; + } + SKIP_W(); + } else opP->imul=1; + if(*ss!=')') { + opP->error="Missing )"; + *s=ss; + return FAIL; + } + SKIP_W(); + *s=ss; + return OK; +} /* try_index() */ + +/* Ian Taylor expanded this function to accept both MIT and Motorola + syntax. I removed the old comment, since it was wrong. The syntax + this accepted even before my changes was complex and undocumented. + I mainly added a large case when the operand string does not + contain an '@', since the Motorola syntax does not use the '@' + character. */ + int m68k_ip_op(str,opP) char *str; @@ -596,6 +789,7 @@ register struct m68k_op *opP; long i; char *parse_index(); int needp; + if (*str==' ') { str++; } /* Find the beginning of the string */ @@ -605,8 +799,8 @@ register struct m68k_op *opP; return FAIL; } /* Out of gas */ - for(strend = str; *strend; strend++) ;; - + for(strend = str; *strend; strend++) + ; --strend; if(*str=='#') { @@ -618,16 +812,29 @@ register struct m68k_op *opP; i = m68k_reg_parse(&str); - /* is a register, is exactly a register, and is followed by '@' */ + if (i!=FAIL) { + if(*str=='/' || *str=='-') { + /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */ + opP->mode=REGLST; + return get_regs(i,str,opP); + } + if(*str=='\0') { + opP->reg=i; + /* "Rn" Register Direct mode */ + if(i>=DATA+0 && i<=DATA+7) + opP->mode=DREG; + else if(i>=ADDR+0 && i<=ADDR+7) + opP->mode=AREG; + else + opP->mode=MSCR; + return OK; + } + } - if((i==FAIL || *str!='\0') && *str!='@') { + if (*str!='@') { char *stmp; - if(i!=FAIL && (*str=='/' || *str=='-')) { - opP->mode=REGLST; - return(get_regs(i,str,opP)); - } - if ((stmp=strchr(str,'@')) != '\0') { + if ((stmp=strchr(str,'@')) != 0) { opP->con1=add_exp(str,stmp-1); if(stmp==strend) { opP->mode=AINDX; @@ -653,22 +860,233 @@ register struct m68k_op *opP; } return(OK); } /* if there's an '@' */ - opP->mode = ABSL; - opP->con1 = add_exp(str,strend); - return(OK); - } /* not a register, not exactly a register, or no '@' */ - opP->reg=i; +#ifndef MIT_SYNTAX_ONLY + /* The operand has no '@'. Try to parse it using + Motorola syntax. */ + /* Logic of the parsing switch(*str): + case opP->mode = + ---- ----------- + #anything IMMED 1 + REG AREG or DREG or MSCR 3 or 2 or 13 + REG- or REG/ REGLST 14 + (REG) AINDR 4 + (REG)+ AINC 6 + (REG,INDX) AINDX 8 + (EXPR,REG) AOFF 7 + (EXPR,REG,INDX) AINDX 8 + -(REG) ADEC 5 + EXP2(REG) AOFF 7 + EXP2(REG,INDX) AINDX 8 + EXP2 ABSL 12 + + REG means truth(m68k_reg_parse(&str)) + INDX means truth(try_moto_index(&str,opP)) + EXPR means not REG + EXP2 means not REG and not '(' and not '-(' + */ + + if(*str=='(') { + str++; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) + && (i<DATA+0 || i>DATA+7 + || *str != ')' || str[1] != '0') + && i!=PC && i!=ZPC && i!=FAIL) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + str++; + if(*str=='\0') { + /* "(An)" Address Register Indirect mode + or "(Dn)" for cas2. */ + if (i>=DATA+0 && i<=DATA+7) + opP->mode=DINDR; + else + opP->mode=AINDR; + return OK; + } + if(*str=='+') { + if(str[1]=='\0') { + /* "(An)+" Register Indirect w Postincrement */ + opP->mode=AINC; + return OK; + } + } + opP->error="Junk after indirect"; + return FAIL; + } + if(*str==',') { + str++; + i=try_moto_index(&str,opP); + if(i==FAIL) return FAIL; + /* "(An,Rn)" Register Indirect with Index mode*/ + opP->mode=AINDX; + return OK; + } + else { + opP->error="Bad indirect syntax"; + return FAIL; + } + } + else { + /* "(EXPR,..." , a displacement */ + char *stmp; + char *index(); + + if(stmp=index(str,',')) { + opP->con1=add_exp(str,stmp-1); + str=stmp; + SKIP_WHITE(); + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + /* "(d,An)" Register Indirect w Displacement */ + opP->mode=AOFF; + return OK; + } + if(*str==',') { + str++; + i=try_moto_index(&str,opP); + if(i==FAIL) return FAIL; + /* "(d,An,Rn)" Register Indirect with Index */ + opP->mode=AINDX; + return OK; + } + else { + opP->error="Bad indirect syntax"; + return FAIL; + } + } + else { + opP->error="Invalid register"; + return FAIL; + } + } + else { + opP->mode = ABSL; + opP->con1 = add_exp(str-1,strend); + return OK; + } + } + } - if (*str=='\0') { - if(i>=DATA+0 && i<=DATA+7) - opP->mode=DREG; - else if(i>=ADDR+0 && i<=ADDR+7) - opP->mode=AREG; - else - opP->mode=MSCR; + if(*str=='-') { + if(str[1]=='(') { + str = str+2; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + str++; + if(*str=='\0') { + /* "-(An)" Register Indirect with Predecrement */ + opP->mode=ADEC; + return OK; + } + opP->error="Junk after indirect"; + return FAIL; + } + opP->error="Bad indirect syntax"; + return FAIL; + } + opP->mode = ABSL; + opP->con1 = add_exp(str-2,strend); + return OK; + } + /* if '-' but not "-(', do nothing */ + } + + /* whether *str=='-' or not */ + { + /* "EXP2" or "EXP2(REG..." */ + char *stmp; + char *index(); + if(stmp=index(str,'(')) { + char *ostr=str; + + opP->con1=add_exp(str,stmp-1); + str=stmp+1; + i=m68k_reg_parse(&str); + if((i<ADDR+0 || i>ADDR+7) && i!=PC + && i!=ZPC && i!=FAIL) { + /* Can't indirect off non address regs */ + opP->error="Invalid indirect register"; + return FAIL; + } + if(i!=FAIL) { + opP->reg=i; + if(*str==')') { + /* "d(An)" Register Indirect w Displacement */ + opP->mode=AOFF; + return OK; + } + if(*str==',') { + str++; + i=try_moto_index(&str,opP); + if(i==FAIL) return FAIL; + /* "d(An,Rn)" Register Indirect with Index */ + opP->mode=AINDX; + return OK; + } + else { + opP->error="Bad indirect syntax"; + return FAIL; + } + } + else { + opP->mode = ABSL; + opP->con1 = add_exp(ostr,strend); + return OK; + } + } + else { + /* "EXP2" Absolute */ + opP->mode=ABSL; + opP->isiz=0; + if(strend[-1]=='.' || strend[-1]==':') { + /* mode ==foo.[wl] */ + switch(*strend) { + case 'w': + case 'W': + opP->isiz=2; + strend-=2; + break; + case 'l': + case 'L': + opP->isiz=3; + strend-=2; + break; + } + } + opP->con1=add_exp(str,strend); + return OK; + } + } + /*NOTREACHED*/ +#else /* defined (MIT_SYNTAX_ONLY) */ + opP->mode=ABSL; + opP->con1=add_exp(str,strend); return OK; - } +#endif /* defined (MIT_SYNTAX_ONLY) */ + } + + opP->reg=i; /* Can't indirect off non address regs, but Dx@ is OK for cas2 */ if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL @@ -681,7 +1099,7 @@ register struct m68k_op *opP; str++; switch(*str) { case '\0': - if (i < DATA + 0 || i > DATA + 7) + if (i<DATA+0 || i>DATA+7) opP->mode=AINDR; else opP->mode=DINDR; @@ -837,98 +1255,24 @@ register struct m68k_op *opP; return(OK); } /* m68k_ip_op() */ -/* - * - * try_index := data_or_address_register + ')' + SKIP_W - * | data_or_address_register + ':' + SKIP_W + size_spec + SKIP_W + multiplier + ')' + SKIP_W - * - * multiplier := <empty> - * | ':' + multiplier_number - * ; - * - * multiplier_number := '1' | '2' | '4' | '8' ; - * - * size_spec := 'l' | 'L' | 'w' | 'W' ; - * - * SKIP_W := <empty> | ' ' ; - * - */ -static int try_index(s,opP) -char **s; -struct m68k_op *opP; +#ifdef M68KCOFF + +short tc_coff_fix2rtype(fixP) +fixS *fixP; { - register int i; - char *ss; -#define SKIP_W() { ss++; if (*ss==' ') ss++;} + return (fixP->fx_pcrel ? + (fixP->fx_size == 1 ? R_PCRBYTE : + fixP->fx_size == 2 ? R_PCRWORD : + R_PCRLONG): + (fixP->fx_size == 1 ? R_RELBYTE : + fixP->fx_size == 2 ? R_RELWORD : + R_RELLONG)); - ss= *s; - /* SKIP_W(); */ - i=m68k_reg_parse(&ss); - if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */ - *s=ss; - return FAIL; - } - opP->ireg=i; - /* SKIP_W(); */ - if(*ss==')') { - opP->isiz=0; - opP->imul=1; - SKIP_W(); - *s=ss; - return OK; - } - if(*ss!=':') { - opP->error="Missing : in index register"; - *s=ss; - return FAIL; - } - SKIP_W(); - switch(*ss) { - case 'w': - case 'W': - opP->isiz=2; - break; - case 'l': - case 'L': - opP->isiz=3; - break; - default: - opP->error="Index register size spec not :w or :l"; - *s=ss; - return FAIL; - } - SKIP_W(); - if(*ss==':') { - SKIP_W(); - switch(*ss) { - case '1': - case '2': - case '4': - case '8': - if (cpu_of_arch(current_architecture) < m68020) { - opP->error="no index scaling in pre-68020's"; - *s=ss; - return FAIL; - } - opP->imul= *ss-'0'; - break; - default: - opP->error="index multiplier not 1, 2, 4 or 8"; - *s=ss; - return FAIL; - } - SKIP_W(); - } else opP->imul=1; - if(*ss!=')') { - opP->error="Missing )"; - *s=ss; - return FAIL; - } - SKIP_W(); - *s=ss; - return OK; -} /* try_index() */ + +} + +#endif #ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */ main() @@ -995,6 +1339,7 @@ void m68k_ip (instring) register struct m68k_incant *opcode; register char *s; register int tmpreg = 0, baseo = 0, outro = 0, nextword; + char *pdot, *pdotmove; int siz1, siz2; char c; int losing; @@ -1009,10 +1354,13 @@ void m68k_ip (instring) /* Scan up to end of operation-code, which MUST end in end-of-string or exactly 1 space. */ - for (p = instring; *p != '\0'; p++) + pdot = 0; + for (p = instring; *p != '\0'; p++) { if (*p == ' ') break; - + if (*p == '.') + pdot = p; + } if (p == instring) { the_ins.error = "No operator"; @@ -1023,12 +1371,26 @@ void m68k_ip (instring) /* p now points to the end of the opcode name, probably whitespace. make sure the name is null terminated by clobbering the whitespace, - look it up in the hash table, then fix it back. */ + look it up in the hash table, then fix it back. + Remove a dot, first, since the opcode tables have none. */ + if (pdot != NULL) { + for (pdotmove=pdot; pdotmove<p; pdotmove++) + *pdotmove=pdotmove[1]; + p--; + } + c = *p; *p = '\0'; opcode = (struct m68k_incant *)hash_find (op_hash, instring); *p = c; + if (pdot != NULL) { + for (pdotmove=p; pdotmove>pdot; pdotmove--) + *pdotmove=pdotmove[-1]; + *pdot='.'; + ++p; + } + if (opcode == NULL) { the_ins.error = "Unknown operator"; the_ins.opcode[0] = NULL; @@ -1039,6 +1401,20 @@ void m68k_ip (instring) /* found a legitimate opcode, start matching operands */ while (*p == ' ') ++p; + + if (opcode->m_operands == 0) { + char *old = input_line_pointer; + *old = '\n'; + input_line_pointer = p; + /* Ahh - it's a motorola style psuedo op */ + mote_pseudo_table[opcode->m_opnum].poc_handler + ( mote_pseudo_table[opcode->m_opnum].poc_val); + input_line_pointer = old; + *old = 0; + + return; + } + for(opP = &the_ins.operands[0]; *p; opP++) { p = crack_operand(p, opP); @@ -1959,7 +2335,7 @@ void m68k_ip (instring) && (the_ins.opcode[0] <= 0x6f00)) { add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF)); } else { - add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF)); + add_frag(adds(opP->con1),offs(opP->con1),TAB(ABRANCH,SZ_UNDEF)); } break; case 'w': @@ -2280,6 +2656,7 @@ void m68k_ip (instring) s[0], __LINE__, __FILE__); } } + /* By the time whe get here (FINALLY) the_ins contains the complete instruction, ready to be emitted. . . */ } /* m68k_ip() */ @@ -2899,8 +3276,6 @@ md_assemble(str) - - void md_begin() { @@ -2949,7 +3324,7 @@ void retval = hash_insert (op_hash, ins->name,(char *)hack); /* Didn't his mommy tell him about null pointers? */ if(retval && *retval) - as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval); + as_bad("Internal Error: Can't hash %s: %s",ins->name,retval); } for (i = 0; i < sizeof(mklower_table) ; i++) @@ -2973,6 +3348,24 @@ void alt_notend_table[REGISTER_PREFIX] = 1; #endif +#ifndef MIT_SYNTAX_ONLY + /* Insert pseudo ops, these have to go into the opcode table since + gas expects pseudo ops to start with a dot */ + { + int n = 0; + while (mote_pseudo_table[n].poc_name) + { + hack=(struct m68k_incant *) + obstack_alloc(&robyn,sizeof(struct m68k_incant)); + hash_insert(op_hash, + mote_pseudo_table[n].poc_name, (char *)hack); + hack->m_operands = 0; + hack->m_opnum = n; + n++; + } + } +#endif + init_regtable(); } @@ -3142,7 +3535,7 @@ register fragS *fragP; switch(fragP->fr_subtype) { case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): + case TAB(ABRANCH,BYTE): know(issbyte(disp)); if(disp==0) as_bad("short branch with zero offset: use :w"); @@ -3154,12 +3547,12 @@ register fragS *fragP; ext=2; break; case TAB(BCC68000,SHORT): - case TAB(BRANCH,SHORT): + case TAB(ABRANCH,SHORT): know(issword(disp)); fragP->fr_opcode[1]=0x00; ext=2; break; - case TAB(BRANCH,LONG): + case TAB(ABRANCH,LONG): if (cpu_of_arch(current_architecture) < m68020) { if (fragP->fr_opcode[0]==0x61) { fragP->fr_opcode[0]= 0x4E; @@ -3304,7 +3697,7 @@ segT segment; /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */ switch (fragP->fr_subtype) { - case TAB(BRANCH,SZ_UNDEF): { + case TAB(ABRANCH,SZ_UNDEF): { if((fragP->fr_symbol != NULL) /* Not absolute */ && S_GET_SEGMENT(fragP->fr_symbol) == segment) { fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE); @@ -3341,7 +3734,7 @@ segT segment; } break; - } /* case TAB(BRANCH,SZ_UNDEF) */ + } /* case TAB(ABRANCH,SZ_UNDEF) */ case TAB(FBRANCH,SZ_UNDEF): { if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) { @@ -3459,7 +3852,7 @@ segT segment; /* now that SZ_UNDEF are taken care of, check others */ switch (fragP->fr_subtype) { case TAB(BCC68000,BYTE): - case TAB(BRANCH,BYTE): + case TAB(ABRANCH,BYTE): /* We can't do a short jump to the next instruction, so we force word mode. */ if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 && @@ -3630,26 +4023,31 @@ int ok; } exp->e_siz=0; - if(/* ok!=80 && */exp->e_end[-1]==':' && (exp->e_end-exp->e_beg)>=2) { + if(/* ok!=80 && */ (exp->e_end[-1]==':' || exp->e_end[-1]=='.') + && (exp->e_end-exp->e_beg)>=2) { switch(exp->e_end[0]) { case 's': case 'S': case 'b': case 'B': exp->e_siz=1; + exp->e_end-=2; break; case 'w': case 'W': exp->e_siz=2; + exp->e_end-=2; break; case 'l': case 'L': exp->e_siz=3; + exp->e_end-=2; break; default: - as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); + if (exp->e_end[-1] == ':') + as_bad("Unknown size for expression \"%c\"",exp->e_end[0]); + break; } - exp->e_end-=2; } c_save=exp->e_end[1]; exp->e_end[1]='\0'; @@ -4081,6 +4479,24 @@ fixS *fixP; return(fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address); } +void +tc_coff_symbol_emit_hook () +{ +} + +int +tc_coff_sizemachdep(frag) +fragS *frag; +{ + switch (frag->fr_subtype & 0x3) + { + case BYTE: return 1; + case SHORT: return 2; + case LONG: return 4; + default: abort(); + } + +} /* * Local Variables: * comment-column: 0 @@ -4089,3 +4505,4 @@ fixS *fixP; */ /* end of tc-m68k.c */ + |