aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-h8300.c
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1991-11-26 02:16:59 +0000
committerSteve Chamberlain <sac@cygnus>1991-11-26 02:16:59 +0000
commit05b4b0e70c8f7563fd092dcb7fb94f08faeb0f0d (patch)
tree40746c04592b0e63f11b23fdcc11bb35bc25a800 /gas/config/tc-h8300.c
parent23de7ff6f56bea5d28d7263a62343641a0aa1cbc (diff)
downloadgdb-05b4b0e70c8f7563fd092dcb7fb94f08faeb0f0d.zip
gdb-05b4b0e70c8f7563fd092dcb7fb94f08faeb0f0d.tar.gz
gdb-05b4b0e70c8f7563fd092dcb7fb94f08faeb0f0d.tar.bz2
obj-coff-bfd:
bfd support gets deeper into gas *h8* fixed numerous bugs in instruction encoding
Diffstat (limited to 'gas/config/tc-h8300.c')
-rw-r--r--gas/config/tc-h8300.c624
1 files changed, 376 insertions, 248 deletions
diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c
index b68307d..83065c2 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() { }