diff options
Diffstat (limited to 'gnu/usr.bin/as/config/tc-h8300.c')
-rw-r--r-- | gnu/usr.bin/as/config/tc-h8300.c | 1295 |
1 files changed, 1295 insertions, 0 deletions
diff --git a/gnu/usr.bin/as/config/tc-h8300.c b/gnu/usr.bin/as/config/tc-h8300.c new file mode 100644 index 0000000..db4786b --- /dev/null +++ b/gnu/usr.bin/as/config/tc-h8300.c @@ -0,0 +1,1295 @@ +/* tc-h8300.c -- Assemble code for the Hitachi H8/300 + Copyright (C) 1991, 1992 Free Software Foundation. + + 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. */ + + +/* + Written By Steve Chamberlain + sac@cygnus.com + */ + +#include <stdio.h> +#include "as.h" +#include "bfd.h" +#include "opcode/h8300.h" +#include <ctype.h> +#include "listing.h" + +char comment_chars[] = { ';',0 }; +char line_separator_chars[] = { '$' ,0}; + +/* This table describes all the machine specific pseudo-ops the assembler + has to support. The fields are: + pseudo-op name without dot + function to call to execute this pseudo-op + Integer arg to pass to the function + */ + +void cons(); + +const pseudo_typeS md_pseudo_table[] = { + { "int", cons, 2 }, + { 0,0,0 } +}; + +int md_reloc_size ; + +const char EXP_CHARS[] = "eE"; + +/* Chars that mean this number is a floating point constant */ +/* As in 0f12.456 */ +/* or 0d1.2345e12 */ +char FLT_CHARS[] = "rRsSfFdDxXpP"; + + +const relax_typeS md_relax_table[1]; + + +static struct hash_control *opcode_hash_control; /* Opcode mnemonics */ + + +/* + 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 + */ +#if 0 +/* encode the size and number into the number field + xxnnnn + 00 8 bit + 01 16 bit + 10 ccr + nnnnreg number + */ +#define WORD_REG 0x10 +#define BYTE_REG 0x00 +#define CCR_REG 0x20 +struct reg_entry +{ + char *name; + char number; +}; + +struct reg_entry reg_list[] = { + "r0",WORD_REG +0, + "r1",WORD_REG +1, + "r2",WORD_REG +2, + "r3",WORD_REG +3, + "r4",WORD_REG +4, + "r5",WORD_REG +5, + "r6",WORD_REG +6, + "r7",WORD_REG +7, + "fp",WORD_REG +6, + "sp",WORD_REG +7, + "r0h",BYTE_REG + 0, + "r0l",BYTE_REG + 1, + "r1h",BYTE_REG + 2, + "r1l",BYTE_REG + 3, + "r2h",BYTE_REG + 4, + "r2l",BYTE_REG + 5, + "r3h",BYTE_REG + 6, + "r3l",BYTE_REG + 7, + "r4h",BYTE_REG + 8, + "r4l",BYTE_REG + 9, + "r5h",BYTE_REG + 10, + "r5l",BYTE_REG + 11, + "r6h",BYTE_REG + 12, + "r6l",BYTE_REG + 13, + "r7h",BYTE_REG + 14, + "r7l",BYTE_REG + 15, + "ccr",CCR_REG, + 0,0 + } +; + + +#endif + + +void md_begin () +{ + struct h8_opcode *opcode; + const struct reg_entry *reg; + char prev_buffer[100]; + int idx = 0; + + opcode_hash_control = hash_new(); + prev_buffer[0] = 0; + + for (opcode = h8_opcodes; opcode->name; opcode++) + { + /* Strip off any . part when inserting the opcode and only enter + unique codes into the hash table + */ + char *src= opcode->name; + unsigned int len = strlen(src); + char *dst = malloc(len+1); + char *buffer = dst; + opcode->size = 0; + while (*src) { + if (*src == '.') { + *dst++ = 0; + src++; + opcode->size = *src; + break; + } + *dst++ = *src++; + } + if (strcmp(buffer, prev_buffer)) + { + hash_insert(opcode_hash_control, buffer, (char *)opcode); + strcpy(prev_buffer, buffer); + idx++; + } + opcode->idx = idx; + + + /* Find the number of operands */ + opcode->noperands = 0; + while (opcode->args.nib[opcode->noperands] != E) + opcode->noperands ++; + /* Find the length of the opcode in bytes */ + opcode->length =0; + while (opcode->data.nib[opcode->length*2] != E) + opcode->length++; + } + +} + + +struct h8_exp { + char *e_beg; + char *e_end; + expressionS e_exp; +}; +struct h8_op +{ + unsigned int dispreg; + op_type mode; + unsigned reg; + expressionS exp; +}; + + + +/* + parse operands + WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp + r0l,r0h,..r7l,r7h + @WREG + @WREG+ + @-WREG + #const + + */ + +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_type *mode AND + unsigned int *reg AND + int dst) +{ + if (src[0] == 's' && src[1] == 'p') + { + *mode = r16_sord[dst]; + *reg = 7; + return 2; + } + if (src[0] == 'c' && src[1] == 'c' && src[2] == 'r') + { + *mode = CCR; + *reg = 0; + return 3; + } + if (src[0] == 'f' && src[1] == 'p') + { + *mode = r16_sord[dst]; + *reg = 6; + return 2; + } + if (src[0] == 'r') + { + if (src[1] >= '0' && src[1] <= '7') + { + if (src[2] == 'l') + { + *mode = r8_sord[dst]; + *reg = (src[1] - '0') + 8; + return 3; + } + if (src[2] == 'h') + { + *mode = r8_sord[dst]; + *reg = (src[1] - '0') ; + return 3; + } + *mode = r16_sord[dst]; + *reg = (src[1] - '0'); + return 2; + } + } + return 0; +} + +char * + DEFUN(parse_exp,(s, op), + char *s AND + expressionS *op) +{ + char *save = input_line_pointer; + char *new; + segT seg; + input_line_pointer = s; + seg = expr(0,op); + new = input_line_pointer; + input_line_pointer = save; + if (SEG_NORMAL(seg)) + return new; + switch (seg) { + case SEG_ABSOLUTE: + case SEG_UNKNOWN: + case SEG_DIFFERENCE: + case SEG_BIG: + case SEG_REGISTER: + return new; + case SEG_ABSENT: + as_bad("Missing operand"); + return new; + default: + as_bad("Don't understand operand of type %s", segment_name (seg)); + return new; + } +} + +static char * + DEFUN(skip_colonthing,(ptr), + char *ptr) +{ + if (*ptr == ':') { + ptr++; + while (isdigit(*ptr)) + ptr++; + + } + return ptr; +} + +/* The many forms of operand: + + Rn Register direct + @Rn Register indirect + @(exp[:16], Rn) Register indirect with displacement + @Rn+ + @-Rn + @aa:8 absolute 8 bit + @aa:16 absolute 16 bit + @aa absolute 16 bit + + #xx[:size] immediate data + @(exp:[8], pc) pc rel + @@aa[:8] memory indirect + + */ + +static void + DEFUN(get_operand,(ptr, op, dst), + char **ptr AND + struct h8_op *op AND + unsigned int dst) +{ + char *src = *ptr; + op_type mode; + unsigned int num; + unsigned int len; + unsigned int size; + op->mode = E; + + len = parse_reg(src, &op->mode, &op->reg, dst); + if (len) { + *ptr = src + len; + return ; + } + + if (*src == '@') + { + src++; + if (*src == '@') + { + src++; + src = parse_exp(src,&op->exp); + src = skip_colonthing(src); + + *ptr = src; + + op->mode = MEMIND; + return; + + } + + + if (*src == '-') + { + src++; + len = parse_reg(src, &mode, &num, dst); + if (len == 0) + { + /* Oops, not a reg after all, must be ordinary exp */ + src--; + /* must be a symbol */ + op->mode = abs_sord[dst]; + *ptr = skip_colonthing(parse_exp(src, &op->exp)); + + return; + + + } + + if (mode != r16_sord[dst]) + { + as_bad("@- needs word register"); + } + op->mode = RDDEC; + op->reg = num; + *ptr = src + len; + return; + } + if (*src == '(' && ')') + { + /* Disp */ + src++; + src = parse_exp(src, &op->exp); + + if (*src == ')') + { + src++; + op->mode = abs_sord[dst]; + *ptr = src; + return; + } + src = skip_colonthing(src); + + if (*src != ',') + { + as_bad("expected @(exp, reg16)"); + } + src++; + len = parse_reg(src, &mode, &op->reg, dst); + if (len == 0 || mode != r16_sord[dst]) + { + as_bad("expected @(exp, reg16)"); + } + op->mode = disp_sord[dst]; + src += len; + src = skip_colonthing(src); + + if (*src != ')' && '(') + { + as_bad("expected @(exp, reg16)"); + + } + *ptr = src +1; + + return; + } + len = parse_reg(src, &mode, &num, dst); + + if (len) { + src += len; + if (*src == '+') + { + src++; + if (mode != RS16) + { + as_bad("@Rn+ needs src word register"); + } + op->mode = RSINC; + op->reg = num; + *ptr = src; + return; + } + if (mode != r16_sord[dst]) + { + as_bad("@Rn needs word register"); + } + op->mode =rind_sord[dst]; + op->reg = num; + *ptr = src; + return; + } + else + { + /* must be a symbol */ + op->mode = abs_sord[dst]; + *ptr = skip_colonthing(parse_exp(src, &op->exp)); + + return; + } + } + + + if (*src == '#') { + src++; + op->mode = IMM16; + src = parse_exp(src, &op->exp); + *ptr= skip_colonthing(src); + + return; + } + else { + *ptr = parse_exp(src, &op->exp); + op->mode = DISP8; + } +} + + +static + char * + DEFUN(get_operands,(noperands,op_end, operand), + unsigned int noperands AND + char *op_end AND + struct h8_op *operand) +{ + char *ptr = op_end; + switch (noperands) + { + case 0: + operand[0].mode = 0; + operand[1].mode = 0; + break; + + case 1: + ptr++; + get_operand(& ptr, operand +0,0); + operand[1].mode =0; + break; + + case 2: + ptr++; + get_operand(& ptr, operand +0,0); + if (*ptr == ',') ptr++; + get_operand(& ptr, operand +1, 1); + break; + + default: + abort(); + } + + + return ptr; +} + +/* Passed a pointer to a list of opcodes which use different + addressing modes, return the opcode which matches the opcodes + provided + */ +static + struct h8_opcode * + DEFUN(get_specific,(opcode, operands), + struct h8_opcode *opcode AND + struct h8_op *operands) + +{ + struct h8_opcode *this_try = opcode ; + int found = 0; + unsigned int noperands = opcode->noperands; + + unsigned int dispreg; + unsigned int this_index = opcode->idx; + while (this_index == opcode->idx && !found) + { + unsigned int i; + + this_try = opcode ++; + for (i = 0; i < 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: + operands[0].dispreg = operands[i].reg; + case RD8: + case RS8: + case RDIND: + case RSIND: + case RD16: + case RS16: + case CCR: + case RSINC: + case RDDEC: + if (operands[i].mode != op) goto fail; + break; + case KBIT: + case IMM16: + case IMM3: + case IMM8: + if (operands[i].mode != IMM16) goto fail; + break; + case MEMIND: + if (operands[i].mode != MEMIND) goto fail; + break; + case ABS16SRC: + case ABS8SRC: + case ABS16OR8SRC: + case ABS16ORREL8SRC: + + if (operands[i].mode != ABS16SRC) goto fail; + break; + case ABS16OR8DST: + case ABS16DST: + case ABS8DST: + if (operands[i].mode != ABS16DST) goto fail; + break; + } + } + found =1; + fail: ; + } + if (found) + return this_try; + else + return 0; +} + +static void + DEFUN(check_operand,(operand, width, string), + struct h8_op *operand AND + unsigned int width AND + char *string) +{ + if (operand->exp.X_add_symbol == 0 + && operand->exp.X_subtract_symbol == 0) + { + + /* No symbol involved, let's look at offset, it's dangerous if any of + the high bits are not 0 or ff's, find out by oring or anding with + the width and seeing if the answer is 0 or all fs*/ + if ((operand->exp.X_add_number | width) != ~0 && + (operand->exp.X_add_number & ~width) != 0) + { + as_warn("operand %s0x%x out of range.", string, operand->exp.X_add_number); + } + } + +} + +/* Now we know what sort of opcodes it is, lets build the bytes - + */ +static void + DEFUN (build_bytes,(this_try, operand), + struct h8_opcode *this_try AND + struct h8_op *operand) + +{ + unsigned int i; + + 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 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 = operand[0].dispreg; + break; + case IMM8: + operand[0].mode = 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"); + if (nib < 0 || nib > 7) + { + as_bad("Bit number out of range %d", nib); + } + + break; + + case ABS16DST: + nib = 0; + break; + case ABS8DST: + operand[1].mode = ABS8DST; + nib = 0; + break; + case ABS8SRC: + operand[0].mode = ABS8SRC; + nib = 0; + break; + case ABS16OR8DST: + operand[1].mode = c; + + nib = 0; + + break; + + case ABS16ORREL8SRC: + operand[0].mode = c; + nib=0; + break; + + case ABS16OR8SRC: + operand[0].mode = ABS16OR8SRC; + nib = 0; + break; + case DISPSRC: + operand[0].mode = ABS16SRC; + nib = 0; + break; + + case DISP8: + operand[0].mode = DISP8; + nib = 0; + break; + + case ABS16SRC: + case IMM16: + case IGNORE: + case MEMIND: + + nib=0; + break; + 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 */ + for (i = 0; i < 2; i++) + { + switch (operand[i].mode) { + case 0: + break; + + case DISP8: + check_operand(operand+i, 0x7f,"@"); + + 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, + R_PCRBYTE); + break; + case IMM8: + check_operand(operand+i, 0xff,"#"); + /* If there is nothing else going on we can safely + reloc in place */ + if (operand[i].exp.X_add_symbol == 0) + { + output[1] = operand[i].exp.X_add_number; + } + else + { + 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, + R_RELBYTE); + } + + break; + case MEMIND: + check_operand(operand+i, 0xff,"@@"); + 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, + R_RELBYTE); + break; + case ABS8DST: + case ABS8SRC: + check_operand(operand+i, 0xff,"@"); + 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, + R_RELBYTE); + break; + + case ABS16OR8SRC: + case ABS16OR8DST: + check_operand(operand+i, 0xffff,"@"); + + 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, + R_MOVB1); + break; + + case ABS16ORREL8SRC: + check_operand(operand+i, 0xffff,"@"); + + 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, + R_JMP1); + break; + + + case ABS16SRC: + case ABS16DST: + case IMM16: + case DISPSRC: + case DISPDST: + check_operand(operand+i, 0xffff,"@"); + if (operand[i].exp.X_add_symbol == 0) + { + /* This should be done with bfd */ + output[3] = operand[i].exp.X_add_number & 0xff; + output[2] = operand[i].exp.X_add_number >> 8; + + } + else + { + + 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, + R_RELWORD); + } + + break; + case RS8: + case RD8: + case RS16: + case RD16: + case RDDEC: + case KBIT: + case RSINC: + case RDIND: + case RSIND: + case CCR: + + break; + default: + abort(); + } + } + +} +/* + try and give an intelligent error message for common and simple to + detect errors + */ + +static void + DEFUN(clever_message, (opcode, operand), + struct h8_opcode *opcode AND + struct h8_op *operand) +{ + struct h8_opcode *scan = opcode; + + /* Find out if there was more than one possible opccode */ + + if ((opcode+1)->idx != opcode->idx) + { + unsigned int argn; + + /* Only one opcode of this flavour, try and guess which operand + didn't match */ + for (argn = 0; argn < opcode->noperands; argn++) + { + switch (opcode->args.nib[argn]) + { + case RD16: + if (operand[argn].mode != RD16) + { + as_bad("destination operand must be 16 bit register"); + } + return; + case RS8: + + if (operand[argn].mode != RS8) + { + as_bad("source operand must be 8 bit register"); + } + return; + case ABS16DST: + if (operand[argn].mode != ABS16DST) + { + as_bad("destination operand must be 16bit absolute address"); + return; + } + + case RD8: + if (operand[argn].mode != RD8) + { + as_bad("destination operand must be 8 bit register"); + } + return; + + case ABS16SRC: + if (operand[argn].mode != ABS16SRC) + { + as_bad("source operand must be 16bit absolute address"); + return; + } + } + } + } + as_bad("invalid operands"); +} + +/* This is the guts of the machine-dependent assembler. STR points to a + machine dependent instruction. This funciton is supposed to emit + the frags/bytes it assembles to. + */ + + + +void + DEFUN(md_assemble,(str), + char *str) +{ + char *op_start; + char *op_end; + unsigned int i; + struct h8_op operand[2]; + struct h8_opcode * opcode; + struct h8_opcode * prev_opcode; + + char *dot = 0; + char c; + /* Drop leading whitespace */ + while (*str == ' ') + str++; + + /* find the op code end */ + for (op_start = op_end = str; + *op_end != 0 && *op_end != ' '; + op_end ++) + { + if (*op_end == '.') { + dot = op_end+1; + *op_end = 0; + op_end+=2; + break; + } + } + + ; + + if (op_end == op_start) + { + as_bad("can't find opcode "); + } + c = *op_end; + + *op_end = 0; + + opcode = (struct h8_opcode *) hash_find(opcode_hash_control, + op_start); + + if (opcode == NULL) + { + as_bad("unknown opcode"); + return; + } + + + input_line_pointer = get_operands(opcode->noperands, op_end, + operand); + *op_end = c; + prev_opcode = opcode; + + opcode = get_specific(opcode, operand); + + if (opcode == 0) + { + /* Couldn't find an opcode which matched the operands */ + char *where =frag_more(2); + where[0] = 0x0; + where[1] = 0x0; + clever_message(prev_opcode, operand); + + return; + } + if (opcode->size && dot) + { + if (opcode->size != *dot) + { + as_warn("mismatch between opcode size and operand size"); + } + } + + build_bytes(opcode, operand); + +} + +void + DEFUN(tc_crawl_symbol_chain, (headers), + object_headers *headers) +{ + printf("call to tc_crawl_symbol_chain \n"); +} + +symbolS *DEFUN(md_undefined_symbol,(name), + char *name) +{ + return 0; +} + +void + DEFUN(tc_headers_hook,(headers), + object_headers *headers) +{ + printf("call to tc_headers_hook \n"); +} +void + 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; + + 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; + +{ + return 0; + +} + +int md_short_jump_size; + +void tc_aout_fix_to_chars () { printf("call to tc_aout_fix_to_chars \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), + segT seg AND + long size) +{ + return((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg])); + +} + +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(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 + long use AND + int nbytes) +{ + switch (nbytes) { + case 4: *ptr++ = (use >> 24) & 0xff; + case 3: *ptr++ = (use >> 16) & 0xff; + case 2: *ptr++ = (use >> 8) & 0xff; + case 1: *ptr++ = (use >> 0) & 0xff; + break; + default: + abort(); + } +} +long md_pcrel_from(fixP) +fixS *fixP; { abort(); } + +void tc_coff_symbol_emit_hook() { } + + +void tc_reloc_mangle(fix_ptr, intr, base) +fixS *fix_ptr; +struct internal_reloc *intr; +bfd_vma base; + +{ + symbolS *symbol_ptr; + + symbol_ptr = fix_ptr->fx_addsy; + + /* If this relocation is attached to a symbol then it's ok + to output it */ + if (fix_ptr->fx_r_type == RELOC_32) { + /* cons likes to create reloc32's whatever the size of the reloc.. + */ + switch (fix_ptr->fx_size) + { + + case 2: + intr->r_type = R_RELWORD; + break; + case 1: + intr->r_type = R_RELBYTE; + break; + default: + abort(); + + } + + } + else { + intr->r_type = fix_ptr->fx_r_type; + } + + intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where +base; + intr->r_offset = fix_ptr->fx_offset; + + if (symbol_ptr) + intr->r_symndx = symbol_ptr->sy_number; + else + intr->r_symndx = -1; + + +} + +/* end of tc-h8300.c */ |