From 05b4b0e70c8f7563fd092dcb7fb94f08faeb0f0d Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Tue, 26 Nov 1991 02:16:59 +0000 Subject: [PATCH] obj-coff-bfd: bfd support gets deeper into gas *h8* fixed numerous bugs in instruction encoding --- gas/config/.Sanitize | 9 +- gas/config/h8300.mt | 3 +- gas/config/tc-h8300.c | 624 +++++++++++++++++++++++++----------------- gas/config/tc-h8300.h | 9 + 4 files changed, 394 insertions(+), 251 deletions(-) create mode 100644 gas/config/tc-h8300.h diff --git a/gas/config/.Sanitize b/gas/config/.Sanitize index 7ab77901ddf..79867a227bb 100644 --- a/gas/config/.Sanitize +++ b/gas/config/.Sanitize @@ -51,7 +51,6 @@ mh-cygnus mh-i386 mt-ebmon29k mt-h8300 -mt-h8300hds mt-m68k mt-mips obj-aout.c @@ -124,7 +123,13 @@ echo Done in `pwd`. # # # $Log$ -# Revision 1.9 1991/11/11 23:36:39 sac +# Revision 1.10 1991/11/26 02:16:55 sac +# obj-coff-bfd: +# bfd support gets deeper into gas +# *h8* +# fixed numerous bugs in instruction encoding +# +# Revision 1.9 1991/11/11 23:36:39 sac # Added tc-sparc.c # # Revision 1.8 1991/11/06 11:53:16 sac diff --git a/gas/config/h8300.mt b/gas/config/h8300.mt index 1e6eb3c8dc9..f58ab63ec41 100644 --- a/gas/config/h8300.mt +++ b/gas/config/h8300.mt @@ -1,4 +1,5 @@ TARG_CPU_DEPENDENTS=$(srcdir)/../include/h8300-opcode.h LOCAL_LOADLIBES=$(srcdir)/../bfd/$(srcdir)/libbfd.a -TDEFINES=-DBFD -DMANY_SEGMENTS +TDEFINES=-DBFD_HEADERS -DMANY_SEGMENTS -DBFD +CC=gcc diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index b68307d1522..83065c2df24 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written By Steve Chamberlain + steve@cygnus.com */ @@ -70,7 +71,7 @@ reloc_howto_type *r8pcrel; void md_begin () { - bfd_arch_info_struct_type *ai; + bfd_arch_info_type *ai; const struct h8_opcode *opcode; opcode_hash_control = hash_new(); @@ -96,7 +97,7 @@ struct h8_exp { }; struct h8_op { -op_enum_type mode; +op_type mode; unsigned reg; expressionS exp; }; @@ -114,15 +115,15 @@ op_enum_type mode; */ -op_enum_type r8_sord[] = {RS8, RD8}; -op_enum_type r16_sord[] = {RS16, RD16}; -op_enum_type rind_sord[] = {RSIND, RDIND}; -op_enum_type abs_sord[2] = {ABS16SRC, ABS16DST}; -op_enum_type disp_sord[] = {DISPSRC, DISPDST}; +op_type r8_sord[] = {RS8, RD8}; +op_type r16_sord[] = {RS16, RD16}; +op_type rind_sord[] = {RSIND, RDIND}; +op_type abs_sord[2] = {ABS16SRC, ABS16DST}; +op_type disp_sord[] = {DISPSRC, DISPDST}; /* try and parse a reg name, returns number of chars consumed */ int DEFUN(parse_reg,(src, mode, reg, dst), char *src AND - op_enum_type *mode AND + op_type *mode AND unsigned int *reg AND int dst) { @@ -199,7 +200,7 @@ DEFUN(get_operand,(ptr, op, dst), unsigned int dst) { char *src = *ptr; - op_enum_type mode; + op_type mode; unsigned int num; unsigned int len; op->mode = E; @@ -309,280 +310,291 @@ DEFUN(md_assemble,(str), { char *op_start; char *op_end; + unsigned int i; + struct h8_opcode * opcode; /* Drop leading whitespace */ while (*str == ' ') - str++; + str++; /* find the op code end */ for (op_start = op_end = str; *op_end != 0 && *op_end != ' '; op_end ++) - ; + ; if (op_end == op_start) { - as_bad("can't find opcode "); - } + as_bad("can't find opcode "); + } *op_end = 0; opcode = (struct h8_opcode *) hash_find(opcode_hash_control, op_start); if (opcode == NULL) { - as_bad("unknown opcode"); - return; - } + as_bad("unknown opcode"); + return; + } - { - int ok = 1; - int j,i; - int dispreg = 0; - struct h8_op operand[2]; - char *ptr = op_end+1; - if (opcode->noperands) - get_operand(& ptr, &operand[0],0); - else operand[0].mode = 0; - if (opcode->noperands==2) { - if (*ptr == ',') ptr++; - get_operand(& ptr, &operand[1], 1); - } - else operand[1].mode = 0; - - - - { - struct h8_opcode *this_try ; - int found = 0; - for (j = 0; j < opcode->nopcodes && !found; j++) { - this_try = opcode + j; - for (i = 0; i < opcode->noperands; i++) { - op_enum_type op = (this_try->args.nib[i]) & ~(B30|B31); - switch (op) { - case Hex0: - case Hex1: - case Hex2: - case Hex3: - case Hex4: - case Hex5: - case Hex6: - case Hex7: - case Hex8: - case Hex9: - case HexA: - case HexB: - case HexC: - case HexD: - case HexE: - case HexF: - break; - case DISPSRC: - case DISPDST: - dispreg = operand[i].reg; - case RD8: - case RS8: - case RDIND: - case RSIND: - case RD16: - case RS16: - case CCR: - case RSINC: - case RDDEC: - if (operand[i].mode != op) goto fail; - break; - case KBIT: - case IMM8: - case IMM16: - case IMM3: - if (operand[i].mode != IMM16) goto fail; - break; - case ABS16SRC: - case ABS8SRC: - if (operand[i].mode != ABS16SRC) goto fail; - break; - case ABS16DST: - case ABS8DST: - if (operand[i].mode != ABS16DST) goto fail; +{ + int ok = 1; + int j,i; + int dispreg = 0; + struct h8_op operand[2]; + char *ptr = op_end+1; + if (opcode->noperands) + get_operand(& ptr, &operand[0],0); + else operand[0].mode = 0; + if (opcode->noperands==2) { + if (*ptr == ',') ptr++; + get_operand(& ptr, &operand[1], 1); + } + else operand[1].mode = 0; + + + +{ + struct h8_opcode *this_try ; + int found = 0; + for (j = 0; j < opcode->nopcodes && !found; j++) { + this_try = opcode + j; + for (i = 0; i < opcode->noperands; i++) { + op_type op = (this_try->args.nib[i]) & ~(B30|B31); + switch (op) { + case Hex0: + case Hex1: + case Hex2: + case Hex3: + case Hex4: + case Hex5: + case Hex6: + case Hex7: + case Hex8: + case Hex9: + case HexA: + case HexB: + case HexC: + case HexD: + case HexE: + case HexF: + break; + case DISPSRC: + case DISPDST: + dispreg = operand[i].reg; + case RD8: + case RS8: + case RDIND: + case RSIND: + case RD16: + case RS16: + case CCR: + case RSINC: + case RDDEC: + if (operand[i].mode != op) goto fail; + break; + case IMM8: + /* We have an expression, called IMM16, but we know we + want an 8 bit value here */ + if (operand[i].mode != IMM16) goto fail; + operand[i].mode = IMM8; + break; + case KBIT: + case IMM16: + case IMM3: + if (operand[i].mode != IMM16) goto fail; + break; + case ABS16SRC: + case ABS8SRC: + if (operand[i].mode != ABS16SRC) goto fail; + break; + case ABS16DST: + case ABS8DST: + if (operand[i].mode != ABS16DST) goto fail; - break; - } + break; } - found =1; - fail: ; - } - if (found == 0) - as_bad("illegal operands for opcode"); + } + found =1; + fail: ; + } + if (found == 0) + as_bad("illegal operands for opcode"); - /* Now we know what sort of opcodes etc, lets build the bytes - - actually we know how big the instruction will be too. So we - can get - */ - { - char *output = frag_more(this_try->length); - char *output_ptr = output; - op_enum_type *nibble_ptr = this_try->data.nib; - char part; - op_enum_type c; - char high; - int nib; - top: ; - while (*nibble_ptr != E) { + /* Now we know what sort of opcodes etc, lets build the bytes - + actually we know how big the instruction will be too. So we + can get + */ +{ + char *output = frag_more(this_try->length); + char *output_ptr = output; + op_type *nibble_ptr = this_try->data.nib; + char part; + op_type c; + char high; + int nib; + top: ; + while (*nibble_ptr != E) { int nibble; for (nibble = 0; nibble <2; nibble++) { - c = *nibble_ptr & ~(B30|B31); - switch (c) { - default: - abort(); - - case 0: - case 1: - case 2: case 3: case 4: case 5: case 6: - case 7: case 8: case 9: case 10: case 11: - case 12: case 13: case 14: case 15: - nib = c; - break; - case DISPREG: - nib = dispreg; - break; - case IMM8: - /* if no symbol then put value in place */ - if (operand[0].exp.X_add_symbol == 0) { - operand[0].mode = 0; /* stop it making a fix */ - *output_ptr++ = (operand[0].exp.X_add_number); - nibble_ptr += 2; - goto top; - } - nib = 0; - break; - - case DISPDST: - /* if no symbol then put value in place */ - if (operand[1].exp.X_add_symbol == 0) { - operand[1].mode = 0; /* stop it making a fix */ - *output_ptr++ =(operand[1].exp.X_add_number)>>8; - *output_ptr++ = (operand[1].exp.X_add_number); - nibble_ptr += 4; - goto top; - } - - nib = 0; - break; - case IMM3: - - if (operand[0].exp.X_add_symbol == 0) { - operand[0].mode = 0; /* stop it making a fix */ - nib = (operand[0].exp.X_add_number); - } - else as_bad("can't have symbol for bit number"); - break; - - case DISPSRC: - case IMM16: - /* if no symbol then put value in place */ - if (operand[0].exp.X_add_symbol == 0) { - operand[0].mode = 0; /* stop it making a fix */ - *output_ptr++ =(operand[0].exp.X_add_number)>>8; - *output_ptr++ = (operand[0].exp.X_add_number); - nibble_ptr += 4; - goto top; - } - - - case ABS16SRC: - case ABS16DST: - - case ABS8DST: - case ABS8SRC: - case IGNORE: - - - nib = 0; - break; - case DISP8: - nib = 0; - break; + c = *nibble_ptr & ~(B30|B31); + switch (c) { + default: + abort(); + case KBIT: + switch (operand[0].exp.X_add_number) { + case 1: + nib = 0; + break; + case 2: + nib = 8; + break; + default: + as_bad("Need #1 or #2 here"); + break; + } + /* stop it making a fix */ + operand[0].mode = 0; + break; + case 0: + case 1: + case 2: case 3: case 4: case 5: case 6: + case 7: case 8: case 9: case 10: case 11: + case 12: case 13: case 14: case 15: + nib = c; + break; + case DISPREG: + nib = dispreg; + break; + case IMM8: + nib = 0; + break; + + case DISPDST: + nib = 0; + break; + case IMM3: + if (operand[0].exp.X_add_symbol == 0) { + operand[0].mode = 0; /* stop it making a fix */ + nib = (operand[0].exp.X_add_number); + } + else as_bad("can't have symbol for bit number"); + break; + + case ABS16DST: + nib = 0; + break; + case DISPSRC: + case ABS16SRC: + case IMM16: + nib=0; + break; + + + case ABS8DST: + case ABS8SRC: + case IGNORE: + + + nib = 0; + break; + case DISP8: + nib = 0; + break; - case RS8: - case RS16: - case RSIND: - case RSINC: - case RDIND: - nib= operand[0].reg; - break; - case RD8: - case RD16: - case RDDEC: - nib = operand[1].reg; - - break; - case E: - abort(); - break; - } - if (*nibble_ptr & B31) nib|=0x8; - if (nibble == 0) { - *output_ptr = nib << 4; - } - else { - *output_ptr |= nib; - output_ptr++; - } - nibble_ptr++; + case RS8: + case RS16: + case RSIND: + case RSINC: + + nib= operand[0].reg; + break; + case RD8: + case RD16: + case RDDEC: + case RDIND: + nib = operand[1].reg; + + break; + case E: + abort(); + break; + } + if (*nibble_ptr & B31) nib|=0x8; + if (nibble == 0) { + *output_ptr = nib << 4; + } + else { + *output_ptr |= nib; + output_ptr++; + } + nibble_ptr++; } - } + } - /* output any fixes */ - { - int i; - for (i = 0; i < 2; i++) { + /* output any fixes */ + for (i = 0; i < 2; i++) + { switch (operand[i].mode) { case 0: - break; + break; case DISP8: - fix_new(frag_now, - output+1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - (int)r8pcrel); - break; + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number -1, + 1, + (int)r8pcrel); + break; + case IMM8: + fix_new(frag_now, + output - frag_now->fr_literal + 1, + 1, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + 0); + break; + case ABS16SRC: case ABS16DST: case IMM16: case DISPSRC: case DISPDST: - fix_new(frag_now, - output+2, - 2, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - (int)r16); - break; + fix_new(frag_now, + output - frag_now->fr_literal + 2, + 2, + operand[i].exp.X_add_symbol, + operand[i].exp.X_subtract_symbol, + operand[i].exp.X_add_number, + 0, + (int)r16); + break; case RS8: case RD8: case RS16: case RD16: case RDDEC: + case KBIT: case RSINC: case RDIND: case RSIND: - break; + break; default: - abort(); + abort(); } - } - } - } - } - } + + +} +} +} } void @@ -610,17 +622,105 @@ DEFUN_VOID(md_end) } /* Various routines to kill one day */ +/* Equal to MAX_PRECISION in atof-ieee.c */ +#define MAX_LITTLENUMS 6 + +/* Turn a string in input_line_pointer into a floating point constant of type + type, and store the appropriate bytes in *litP. The number of LITTLENUMS + emitted is stored in *sizeP . An error message is returned, or NULL on OK. + */ +char * +md_atof(type,litP,sizeP) +char type; +char *litP; +int *sizeP; +{ + int prec; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + LITTLENUM_TYPE *wordP; + char *t; + char *atof_ieee(); + + switch(type) { + case 'f': + case 'F': + case 's': + case 'S': + prec = 2; + break; + + case 'd': + case 'D': + case 'r': + case 'R': + prec = 4; + break; -char *md_atof () { printf("call to md_atof \n"); abort(); } -int md_parse_option () { printf("call to md_parse_option \n"); abort(); } + case 'x': + case 'X': + prec = 6; + break; + + case 'p': + case 'P': + prec = 6; + break; + + default: + *sizeP=0; + return "Bad call to MD_ATOF()"; + } + t=atof_ieee(input_line_pointer,type,words); + if(t) + input_line_pointer=t; + + *sizeP=prec * sizeof(LITTLENUM_TYPE); + for(wordP=words;prec--;) { + md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE)); + litP+=sizeof(LITTLENUM_TYPE); + } + return ""; /* Someone should teach Dean about null pointers */ +} + +int +md_parse_option(argP, cntP, vecP) + char **argP; + int *cntP; + char ***vecP; + + {abort(); + } int md_short_jump_size; void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \n"); abort(); } -void md_create_long_jump () { printf("call to md_create_long_jump \n"); - abort(); } -void md_convert_frag () { printf("call to md_convert_frag \n"); abort(); } +void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol) +char *ptr; +long from_addr; +long to_addr; +fragS *frag; +symbolS *to_symbol; +{ + as_fatal("failed sanity check."); + } + +void +md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol) + char *ptr; + long from_addr, to_addr; + fragS *frag; + symbolS *to_symbol; +{ + as_fatal("failed sanity check."); +} + +void +md_convert_frag(headers, fragP) +object_headers *headers; + fragS * fragP; + + { printf("call to md_convert_frag \n"); abort(); } long DEFUN(md_section_align,(seg, size), @@ -631,18 +731,48 @@ DEFUN(md_section_align,(seg, size), } -void md_apply_fix () { printf("call to md_apply_fix \n"); abort(); } +void +md_apply_fix(fixP, val) + fixS *fixP; + long val; +{ + char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; + + switch(fixP->fx_size) { + case 1: + *buf++=val; + break; + case 2: + *buf++=(val>>8); + *buf++=val; + break; + case 4: + *buf++=(val>>24); + *buf++=(val>>16); + *buf++=(val>>8); + *buf++=val; + break; + default: + abort(); + + } +} void DEFUN(md_operand, (expressionP),expressionS *expressionP) { } int md_long_jump_size; -int md_estimate_size_before_relax () { printf("call tomd_estimate_size_before_relax \n"); abort(); } +int +md_estimate_size_before_relax(fragP, segment_type) + register fragS *fragP; + register segT segment_type; +{ printf("call tomd_estimate_size_before_relax \n"); abort(); } /* Put number into target byte order */ + void DEFUN(md_number_to_chars,(ptr, use, nbytes), char *ptr AND - int use AND - unsigned int nbytes) + long use AND + int nbytes) { switch (nbytes) { case 4: *ptr++ = (use >> 24) & 0xff; @@ -654,9 +784,7 @@ void DEFUN(md_number_to_chars,(ptr, use, nbytes), abort(); } } - -long md_pcrel_from () { printf("call to md_pcrel_from \n"); abort(); } -void md_create_short_jump () { printf("call to md_create_short_jump \n"); - abort(); } +long md_pcrel_from(fixP) +fixS *fixP; { abort(); } void tc_coff_symbol_emit_hook() { } diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h new file mode 100644 index 00000000000..2e02b40e0b5 --- /dev/null +++ b/gas/config/tc-h8300.h @@ -0,0 +1,9 @@ + +#define TC_H8300 + +/* This macro translates between an internal fix and an coff reloc type */ +#define TC_COFF_FIX2RTYPE(fixP) \ + (fixP->fx_pcrel ? (fixP->fx_size == 1 ? R_PCRBYTE : R_PCRWORD ) : \ + (fixP->fx_size == 1 ? R_RELBYTE : R_RELWORD )) + + -- 2.30.2