From: Svein Seldal Date: Mon, 11 Nov 2002 14:29:01 +0000 (+0000) Subject: gas tic4x target enhancements (long list - see gas/ChangeLog and X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=247b1fe61092651808c546345912ad8a36e55b8f;p=binutils-gdb.git gas tic4x target enhancements (long list - see gas/ChangeLog and include/ChangeLog) --- diff --git a/gas/ChangeLog b/gas/ChangeLog index e4e95b532bb..91ac46f813f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,20 @@ +2002-11-11 Svein E. Seldal + + * config/tc-tic4x.c: Declare as many functions as possible as + static. Maintenance on the general indenting. Removed unnecessary + pseudo-ops and added new ones. Removed obsoleted c4x_pseudo_ignore + function. Add support for new DSP, TMS320VC33. Fix bug for + converting flonum constants. + (c4x_do_align): Add proper align handling. Setup align to insert + NOP's. + (c4x_gen_to_words): Support for extended TI type floats. + (md_atof): Proper dumping of multiple-word littlenums. + (c4x_atof): Added support for extended TI type floats. + (c4x_stringer): Added new function to handle compact strings. + (c4x_emit_char): Added new function argument to handle custom + length inserts, like single-byte strings. + * config/tc-tic4x.h: Add proper align handling with NOP's. + 2002-11-11 Hans-Peter Nilsson * macro.c (get_any_string): Correct logic for not going beyond end diff --git a/gas/config/tc-tic4x.c b/gas/config/tc-tic4x.c index 0ca9e5a305a..37d9aef5328 100644 --- a/gas/config/tc-tic4x.c +++ b/gas/config/tc-tic4x.c @@ -19,19 +19,35 @@ along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* + TODOs: + ------ + + o .align cannot handle fill-data larger than 0xFF/8-bits + o .align fills all section with NOP's when used regardless if has + been used in .text or .data. (However the .align is primarely + intended used in .text sections. If you require something else, + use .align ,0x00) -/* Things not currently implemented: - > .usect if has symbol on previous line + o .align: Implement a 'bu' insn if the number of nop's exeeds 4 within + the align frag. if(fragsize>4words) insert bu fragend+1 first. - > .sym, .eos, .stag, .etag, .member + o .usect if has symbol on previous line not implemented - > Evaluation of constant floating point expressions (expr.c needs work!) + o .sym, .eos, .stag, .etag, .member not implemented - > Warnings issued if parallel load of same register + o Evaluation of constant floating point expressions (expr.c needs work!) - Note that this is primarily designed to handle the code generated - by GCC. Anything else is a bonus! */ + o Warnings issued if parallel load of same register + + o Support 'abc' constants? + + o Support new opcodes and implement a silicon version switch (maybe -mpg) + + o Disallow non-float registers in float instructions. Make as require + 'fx' notation on floats, while 'rx' on the rest +*/ #include #include @@ -101,148 +117,139 @@ c4x_insn_t; static c4x_insn_t the_insn; /* Info about our instruction. */ static c4x_insn_t *insn = &the_insn; -int c4x_gen_to_words - PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int )); -char *c4x_atof - PARAMS ((char *, char, LITTLENUM_TYPE * )); +static int c4x_gen_to_words + PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int )); +static char *c4x_atof + PARAMS ((char *, char, LITTLENUM_TYPE * )); static void c4x_insert_reg - PARAMS ((char *, int )); + PARAMS ((char *, int )); static void c4x_insert_sym - PARAMS ((char *, int )); + PARAMS ((char *, int )); static char *c4x_expression - PARAMS ((char *, expressionS *)); + PARAMS ((char *, expressionS *)); static char *c4x_expression_abs - PARAMS ((char *, int *)); + PARAMS ((char *, int *)); static void c4x_emit_char - PARAMS ((char)); + PARAMS ((char, int)); static void c4x_seg_alloc - PARAMS ((char *, segT, int, symbolS *)); + PARAMS ((char *, segT, int, symbolS *)); static void c4x_asg - PARAMS ((int)); + PARAMS ((int)); static void c4x_bss - PARAMS ((int)); -void c4x_globl - PARAMS ((int)); + PARAMS ((int)); +static void c4x_globl + PARAMS ((int)); static void c4x_cons - PARAMS ((int)); + PARAMS ((int)); +static void c4x_stringer + PARAMS ((int)); static void c4x_eval - PARAMS ((int)); + PARAMS ((int)); static void c4x_newblock - PARAMS ((int)); + PARAMS ((int)); static void c4x_sect - PARAMS ((int)); + PARAMS ((int)); static void c4x_set - PARAMS ((int)); + PARAMS ((int)); static void c4x_usect - PARAMS ((int)); + PARAMS ((int)); static void c4x_version - PARAMS ((int)); + PARAMS ((int)); static void c4x_pseudo_ignore - PARAMS ((int)); + PARAMS ((int)); static void c4x_init_regtable - PARAMS ((void)); + PARAMS ((void)); static void c4x_init_symbols - PARAMS ((void)); + PARAMS ((void)); static int c4x_inst_insert - PARAMS ((c4x_inst_t *)); + PARAMS ((c4x_inst_t *)); static c4x_inst_t *c4x_inst_make - PARAMS ((char *, unsigned long, char *)); + PARAMS ((char *, unsigned long, char *)); static int c4x_inst_add - PARAMS ((c4x_inst_t *)); + PARAMS ((c4x_inst_t *)); void md_begin - PARAMS ((void)); + PARAMS ((void)); void c4x_end - PARAMS ((void)); + PARAMS ((void)); static int c4x_indirect_parse - PARAMS ((c4x_operand_t *, const c4x_indirect_t *)); -char *c4x_operand_parse - PARAMS ((char *, c4x_operand_t *)); + PARAMS ((c4x_operand_t *, const c4x_indirect_t *)); +static char *c4x_operand_parse + PARAMS ((char *, c4x_operand_t *)); static int c4x_operands_match - PARAMS ((c4x_inst_t *, c4x_insn_t *)); -void c4x_insn_output - PARAMS ((c4x_insn_t *)); -int c4x_operands_parse - PARAMS ((char *, c4x_operand_t *, int )); + PARAMS ((c4x_inst_t *, c4x_insn_t *)); +static void c4x_insn_output + PARAMS ((c4x_insn_t *)); +static int c4x_operands_parse + PARAMS ((char *, c4x_operand_t *, int )); void md_assemble - PARAMS ((char *)); + PARAMS ((char *)); void c4x_cleanup - PARAMS ((void)); + PARAMS ((void)); char *md_atof - PARAMS ((int, char *, int *)); + PARAMS ((int, char *, int *)); void md_apply_fix3 - PARAMS ((fixS *, valueT *, segT )); + PARAMS ((fixS *, valueT *, segT )); void md_convert_frag - PARAMS ((bfd *, segT, fragS *)); + PARAMS ((bfd *, segT, fragS *)); void md_create_short_jump - PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); + PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); void md_create_long_jump - PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); + PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); int md_estimate_size_before_relax - PARAMS ((register fragS *, segT)); + PARAMS ((register fragS *, segT)); int md_parse_option - PARAMS ((int, char *)); + PARAMS ((int, char *)); void md_show_usage - PARAMS ((FILE *)); + PARAMS ((FILE *)); int c4x_unrecognized_line - PARAMS ((int)); + PARAMS ((int)); symbolS *md_undefined_symbol - PARAMS ((char *)); + PARAMS ((char *)); void md_operand - PARAMS ((expressionS *)); + PARAMS ((expressionS *)); valueT md_section_align - PARAMS ((segT, valueT)); + PARAMS ((segT, valueT)); static int c4x_pc_offset - PARAMS ((unsigned int)); + PARAMS ((unsigned int)); long md_pcrel_from - PARAMS ((fixS *)); + PARAMS ((fixS *)); int c4x_do_align - PARAMS ((int, const char *, int, int)); + PARAMS ((int, const char *, int, int)); void c4x_start_line - PARAMS ((void)); + PARAMS ((void)); arelent *tc_gen_reloc - PARAMS ((asection *, fixS *)); + PARAMS ((asection *, fixS *)); const pseudo_typeS md_pseudo_table[] = { {"align", s_align_bytes, 32}, - {"ascii", c4x_cons, 1}, - {"asciz", c4x_pseudo_ignore, 0}, + {"ascii", c4x_stringer, 1}, + {"asciz", c4x_stringer, 0}, {"asg", c4x_asg, 0}, - {"asect", c4x_pseudo_ignore, 0}, /* Absolute named section. */ - {"block", s_space, 0}, + {"block", s_space, 4}, {"byte", c4x_cons, 1}, {"bss", c4x_bss, 0}, - {"comm", c4x_bss, 0}, + {"copy", s_include, 0}, {"def", c4x_globl, 0}, - {"endfunc", c4x_pseudo_ignore, 0}, - {"eos", c4x_pseudo_ignore, 0}, - {"etag", c4x_pseudo_ignore, 0}, {"equ", c4x_set, 0}, {"eval", c4x_eval, 0}, - {"exitm", s_mexit, 0}, - {"func", c4x_pseudo_ignore, 0}, {"global", c4x_globl, 0}, {"globl", c4x_globl, 0}, {"hword", c4x_cons, 2}, {"ieee", float_cons, 'i'}, - {"int", c4x_cons, 4}, /* .int allocates 4 bytes. */ - {"length", c4x_pseudo_ignore, 0}, - {"ldouble", float_cons, 'l'}, - {"member", c4x_pseudo_ignore, 0}, + {"int", c4x_cons, 4}, /* .int allocates 4 bytes. */ + {"ldouble", float_cons, 'e'}, {"newblock", c4x_newblock, 0}, - {"ref", s_ignore, 0}, /* All undefined treated as external. */ + {"ref", s_ignore, 0}, /* All undefined treated as external. */ {"set", c4x_set, 0}, - {"sect", c4x_sect, 1}, /* Define named section. */ + {"sect", c4x_sect, 1}, /* Define named section. */ {"space", s_space, 4}, - {"stag", c4x_pseudo_ignore, 0}, - {"string", c4x_pseudo_ignore, 0}, - {"sym", c4x_pseudo_ignore, 0}, - {"usect", c4x_usect, 0}, /* Reserve space in uninit. named sect. */ + {"string", c4x_stringer, 0}, + {"usect", c4x_usect, 0}, /* Reserve space in uninit. named sect. */ {"version", c4x_version, 0}, - {"width", c4x_pseudo_ignore, 0}, - {"word", c4x_cons, 4}, /* .word allocates 4 bytes. */ + {"word", c4x_cons, 4}, /* .word allocates 4 bytes. */ {"xdef", c4x_globl, 0}, {NULL, 0, 0}, }; @@ -288,14 +295,15 @@ const char FLT_CHARS[] = "fFilsS"; extern FLONUM_TYPE generic_floating_point_number; /* Precision in LittleNums. */ -#define MAX_PRECISION (2) +#define MAX_PRECISION (4) /* Its a bit overkill for us, but the code + reqires it... */ #define S_PRECISION (1) /* Short float constants 16-bit. */ #define F_PRECISION (2) /* Float and double types 32-bit. */ +#define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */ #define GUARD (2) - /* Turn generic_floating_point_number into a real short/float/double. */ -int +static int c4x_gen_to_words (flonum, words, precision) FLONUM_TYPE flonum; LITTLENUM_TYPE *words; @@ -310,9 +318,17 @@ c4x_gen_to_words (flonum, words, precision) unsigned int sfract; /* Scaled fraction. */ unsigned int smant; /* Scaled mantissa. */ unsigned int tmp; + unsigned int mover; /* Mantissa overflow bits */ + unsigned int rbit; /* Round bit. */ int shift; /* Shift count. */ - /* Here is how a generic floating point number is stored using + /* NOTE: Svein Seldal + The code in this function is altered slightly to support floats + with 31-bits mantissas, thus the documentation below may be a + little bit inaccurate. + + By Michael P. Hayes + Here is how a generic floating point number is stored using flonums (an extension of bignums) where p is a pointer to an array of LITTLENUMs. @@ -440,31 +456,34 @@ c4x_gen_to_words (flonum, words, precision) if (precision != S_PRECISION) words[1] = 0x0000; + if (precision == E_PRECISION) + words[2] = words[3] = 0x0000; - /* 0.0e0 seen. */ - if (flonum.low > flonum.leader) + /* 0.0e0 or NaN seen. */ + if (flonum.low > flonum.leader /* = 0.0e0 */ + || flonum.sign == 0) /* = NaN */ { + if(flonum.sign == 0) + as_bad ("Nan, using zero."); words[0] = 0x8000; return return_value; } - /* NaN: We can't do much... */ - if (flonum.sign == 0) - { - as_bad ("Nan, using zero."); - words[0] = 0x8000; - return return_value; - } - else if (flonum.sign == 'P') + if (flonum.sign == 'P') { /* +INF: Replace with maximum float. */ if (precision == S_PRECISION) words[0] = 0x77ff; - else + else { words[0] = 0x7f7f; words[1] = 0xffff; } + if (precision == E_PRECISION) + { + words[2] = 0x7fff; + words[3] = 0xffff; + } return return_value; } else if (flonum.sign == 'N') @@ -472,8 +491,10 @@ c4x_gen_to_words (flonum, words, precision) /* -INF: Replace with maximum float. */ if (precision == S_PRECISION) words[0] = 0x7800; - else - words[0] = 0x7f80; + else + words[0] = 0x7f80; + if (precision == E_PRECISION) + words[2] = 0x8000; return return_value; } @@ -489,43 +510,64 @@ c4x_gen_to_words (flonum, words, precision) if (precision == S_PRECISION) /* Allow 1 rounding bit. */ { exponent_bits = 4; - mantissa_bits = 12; /* Include suppr. bit but not rounding bit. */ + mantissa_bits = 11; } - else + else if(precision == F_PRECISION) + { + exponent_bits = 8; + mantissa_bits = 23; + } + else /* E_PRECISION */ { exponent_bits = 8; - mantissa_bits = 24; + mantissa_bits = 31; } shift = mantissa_bits - shift; smant = 0; + mover = 0; + rbit = 0; + /* Store the mantissa data into smant and the roundbit into rbit */ for (p = flonum.leader; p >= flonum.low && shift > -16; p--) { tmp = shift >= 0 ? *p << shift : *p >> -shift; + rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0; smant |= tmp; shift -= 16; } - /* OK, we've got our scaled mantissa so let's round it up - and drop the rounding bit. */ - smant++; - smant >>= 1; + /* OK, we've got our scaled mantissa so let's round it up */ + if(rbit) + { + /* If the mantissa is going to overflow when added, lets store + the extra bit in mover. -- A special case exists when + mantissa_bits is 31 (E_PRECISION). Then the first test cannot + be trusted, as result is host-dependent, thus the second + test. */ + if( smant == ((unsigned)(1<<(mantissa_bits+1))-1) + || smant == (unsigned)-1 ) /* This is to catch E_PRECISION cases */ + mover=1; + smant++; + } + + /* Get the scaled one value */ + sone = (1 << (mantissa_bits)); /* The number may be unnormalised so renormalise it... */ - if (smant >> mantissa_bits) + if(mover) { smant >>= 1; + smant |= sone; /* Insert the bit from mover into smant */ exponent++; } /* The binary point is now between bit positions 11 and 10 or 23 and 22, i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the bit at mantissa_bits - 1 should be set. */ - if (!(smant >> (mantissa_bits - 1))) - abort (); /* Ooops. */ + if (!(sone&smant)) + abort (); /* Ooops. */ - sone = (1 << (mantissa_bits - 1)); if (flonum.sign == '+') sfract = smant - sone; /* smant - 1.0. */ else @@ -537,7 +579,9 @@ c4x_gen_to_words (flonum, words, precision) sfract = 0; } else - sfract = (sone << 1) - smant; /* 2.0 - smant. */ + { + sfract = -smant & (sone-1); /* 2.0 - smant. */ + } sfract |= sone; /* Insert sign bit. */ } @@ -546,21 +590,37 @@ c4x_gen_to_words (flonum, words, precision) /* Force exponent to fit in desired field width. */ exponent &= (1 << (exponent_bits)) - 1; - sfract |= exponent << mantissa_bits; - if (precision == S_PRECISION) - words[0] = sfract; + if (precision == E_PRECISION) + { + /* Map the float part first (100% equal format as F_PRECISION) */ + words[0] = exponent << (mantissa_bits+1-24); + words[0] |= sfract >> 24; + words[1] = sfract >> 8; + + /* Map the mantissa in the next */ + words[2] = sfract >> 16; + words[3] = sfract & 0xffff; + } else { - words[0] = sfract >> 16; - words[1] = sfract & 0xffff; + /* Insert the exponent data into the word */ + sfract |= exponent << (mantissa_bits+1); + + if (precision == S_PRECISION) + words[0] = sfract; + else + { + words[0] = sfract >> 16; + words[1] = sfract & 0xffff; + } } return return_value; } /* Returns pointer past text consumed. */ -char * +static char * c4x_atof (str, what_kind, words) char *str; char what_kind; @@ -606,6 +666,11 @@ c4x_atof (str, what_kind, words) precision = F_PRECISION; break; + case 'E': + case 'e': + precision = E_PRECISION; + break; + default: as_bad ("Invalid floating point number"); return (NULL); @@ -695,14 +760,15 @@ c4x_expression_abs (str, value) } static void -c4x_emit_char (c) +c4x_emit_char (c,b) char c; + int b; { expressionS exp; exp.X_op = O_constant; exp.X_add_number = c; - emit_expr (&exp, 4); + emit_expr (&exp, b); } static void @@ -824,7 +890,7 @@ c4x_bss (x) demand_empty_rest_of_line (); } -void +static void c4x_globl (ignore) int ignore ATTRIBUTE_UNUSED; { @@ -866,7 +932,7 @@ c4x_cons (bytes) { input_line_pointer++; while (is_a_char (c = next_char_of_string ())) - c4x_emit_char (c); + c4x_emit_char (c, 4); know (input_line_pointer[-1] == '\"'); } else @@ -897,6 +963,60 @@ c4x_cons (bytes) demand_empty_rest_of_line (); } +/* Handle .ascii, .asciz, .string */ +static void +c4x_stringer (append_zero) + int append_zero; /*ex: bytes */ +{ + int bytes; + register unsigned int c; + + bytes = 0; + do + { + SKIP_WHITESPACE (); + if (*input_line_pointer == '"') + { + input_line_pointer++; + while (is_a_char (c = next_char_of_string ())) + { + c4x_emit_char (c, 1); + bytes++; + } + + if (append_zero) + { + c4x_emit_char (c, 1); + bytes++; + } + + know (input_line_pointer[-1] == '\"'); + } + else + { + expressionS exp; + + input_line_pointer = c4x_expression (input_line_pointer, &exp); + if (exp.X_op != O_constant) + { + as_bad("Non-constant symbols not allowed\n"); + return; + } + exp.X_add_number &= 255; /* Limit numeber to 8-bit */ + emit_expr (&exp, 1); + bytes++; + } + } + while (*input_line_pointer++ == ','); + + /* Fill out the rest of the expression with 0's to fill up a full word */ + if ( bytes&0x3 ) + c4x_emit_char (0, 4-(bytes&0x3)); + + input_line_pointer--; /* Put terminator back into stream. */ + demand_empty_rest_of_line (); +} + /* .eval expression, symbol */ static void c4x_eval (x) @@ -1119,16 +1239,6 @@ c4x_version (x) demand_empty_rest_of_line (); } -static void -c4x_pseudo_ignore (x) - int x ATTRIBUTE_UNUSED; -{ - /* We could print warning message here... */ - - /* Ignore everything until end of line. */ - while (!is_end_of_line[(unsigned char) *input_line_pointer++]); -} - static void c4x_init_regtable () { @@ -1182,17 +1292,19 @@ c4x_init_symbols () c4x_insert_sym (".BIGMODEL", c4x_big_model); c4x_insert_sym (".C30INTERRUPT", 0); c4x_insert_sym (".TMS320xx", c4x_cpu == 0 ? 40 : c4x_cpu); - c4x_insert_sym (".C3X", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32); - c4x_insert_sym (".C3x", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32); + c4x_insert_sym (".C3X", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32 || c4x_cpu == 33); + c4x_insert_sym (".C3x", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32 || c4x_cpu == 33); c4x_insert_sym (".C4X", c4x_cpu == 0 || c4x_cpu == 40 || c4x_cpu == 44); c4x_insert_sym (".C4x", c4x_cpu == 0 || c4x_cpu == 40 || c4x_cpu == 44); /* Do we need to have the following symbols also in lower case? */ - c4x_insert_sym (".TMS320C30", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32); - c4x_insert_sym (".tms320C30", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32); + c4x_insert_sym (".TMS320C30", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32 || c4x_cpu == 33); + c4x_insert_sym (".tms320C30", c4x_cpu == 30 || c4x_cpu == 31 || c4x_cpu == 32 || c4x_cpu == 33); c4x_insert_sym (".TMS320C31", c4x_cpu == 31); c4x_insert_sym (".tms320C31", c4x_cpu == 31); c4x_insert_sym (".TMS320C32", c4x_cpu == 32); c4x_insert_sym (".tms320C32", c4x_cpu == 32); + c4x_insert_sym (".TMS320C33", c4x_cpu == 33); + c4x_insert_sym (".tms320C33", c4x_cpu == 33); c4x_insert_sym (".TMS320C40", c4x_cpu == 40 || c4x_cpu == 44 || c4x_cpu == 0); c4x_insert_sym (".tms320C40", c4x_cpu == 40 || c4x_cpu == 44 || c4x_cpu == 0); c4x_insert_sym (".TMS320C44", c4x_cpu == 44); @@ -1465,7 +1577,7 @@ c4x_indirect_parse (operand, indirect) return 1; } -char * +static char * c4x_operand_parse (s, operand) char *s; c4x_operand_t *operand; @@ -2188,7 +2300,7 @@ c4x_operands_match (inst, insn) } } -void +static void c4x_insn_output (insn) c4x_insn_t *insn; { @@ -2380,13 +2492,16 @@ md_atof (type, litP, sizeP) break; case 'i': /* .ieee */ + case 'I': prec = 2; ieee = 1; + type = 'f'; /* Rewrite type to be usable by atof_ieee() */ break; - case 'l': /* .ldouble */ + case 'e': /* .ldouble */ + case 'E': prec = 4; /* 2 32-bit words */ - ieee = 1; + ieee = 0; break; default: @@ -2404,10 +2519,21 @@ md_atof (type, litP, sizeP) t = litP; /* This loops outputs the LITTLENUMs in REVERSE order; in accord with little endian byte order. */ - for (wordP = words + prec - 1; prec--;) + /* SES: However it is required to put the words (32-bits) out in the + correct order, hence we write 2 and 2 littlenums in little endian + order, while we keep the original order on successive words. */ + for(wordP = words; wordP<(words+prec) ; wordP+=2) { - md_number_to_chars (litP, (valueT) (*wordP--), - sizeof (LITTLENUM_TYPE)); + if (wordP<(words+prec-1)) /* Dump wordP[1] (if we have one) */ + { + md_number_to_chars (litP, (valueT) (wordP[1]), + sizeof (LITTLENUM_TYPE)); + litP += sizeof (LITTLENUM_TYPE); + } + + /* Dump wordP[0] */ + md_number_to_chars (litP, (valueT) (wordP[0]), + sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0; @@ -2550,7 +2676,7 @@ md_show_usage (stream) { fputs ("\ C[34]x options:\n\ --m30 | -m31 | -m32 | -m40 | -m44\n\ +-m30 | -m31 | -m32 | -m33 | -m40 | -m44\n\ specify variant of architecture\n\ -b big memory model\n\ -p pass arguments on stack\n\ @@ -2720,8 +2846,8 @@ md_pcrel_from (fixP) c4x_pc_offset (op); } -/* This is probably not necessary, if we have played our cards right, - since everything should be already aligned on a 4-byte boundary. */ +/* Fill the alignment area with NOP's on .text, unless fill-data + was specified. */ int c4x_do_align (alignment, fill, len, max) int alignment ATTRIBUTE_UNUSED; @@ -2729,13 +2855,28 @@ c4x_do_align (alignment, fill, len, max) int len ATTRIBUTE_UNUSED; int max ATTRIBUTE_UNUSED; { - char *p; - - p = frag_var (rs_align, 1, 1, (relax_substateT) 0, - (symbolS *) 0, (long) 2, (char *) 0); + unsigned long nop = NOP_OPCODE; - /* We could use frag_align_pattern (n, nop_pattern, sizeof (nop_pattern)); - to fill with our 32-bit nop opcode. */ + /* Because we are talking lwords, not bytes, adjust aligment to do words */ + alignment += 2; + + if (alignment != 0 && !need_pass_2) + { + if (fill == NULL) + { + /*if (subseg_text_p (now_seg))*/ /* FIXME: doesnt work for .text for some reason */ + frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max); + return 1; + /*else + frag_align (alignment, 0, max);*/ + } + else if (len <= 1) + frag_align (alignment, *fill, max); + else + frag_align_pattern (alignment, fill, len, max); + } + + /* Return 1 to skip the default aligment function */ return 1; } diff --git a/gas/config/tc-tic4x.h b/gas/config/tc-tic4x.h index 185886a0e0f..b9dd0e55081 100644 --- a/gas/config/tc-tic4x.h +++ b/gas/config/tc-tic4x.h @@ -65,6 +65,8 @@ #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep (frag) #define NEED_FX_R_TYPE +#define NOP_OPCODE 0x0c800000 + #define reloc_type int #define NO_RELOC 0 @@ -84,7 +86,7 @@ extern int c4x_unrecognized_line PARAMS ((int)); #define md_number_to_chars number_to_chars_littleendian extern int c4x_do_align PARAMS ((int, const char *, int, int)); -#define md_do_align(n,fill,len,max,l) if (c4x_do_align (n,fill,len,max)) goto l +#define md_do_align(n,fill,len,max,label) if( c4x_do_align (n,fill,len,max) ) goto label; /* Start of line hook to remove parallel instruction operator || */ extern void c4x_start_line PARAMS ((void)); diff --git a/include/ChangeLog b/include/ChangeLog index 8efd9a3cd0b..425f3db54cd 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2002-11-11 Svein E. Seldal + + * opcode/tic4x.h: Added new opcodes and corrected some bugs. Add + support for new DSP types. + 2002-10-26 Roger Sayle * partition.h: Close the extern "C" scope when compiling with C++. diff --git a/include/opcode/tic4x.h b/include/opcode/tic4x.h index 68d186d1d0e..18df7f19c8a 100644 --- a/include/opcode/tic4x.h +++ b/include/opcode/tic4x.h @@ -304,8 +304,10 @@ static const c4x_inst_t c3x_insts[] = { "addi_mpyi", 0x89000000, 0xff000000, Q_rSr_rSr }, { "addi_mpyi", 0x8a000000, 0xff000000, Q_SSr_rrr }, { "addi_mpyi", 0x8b000000, 0xff000000, Q_Srr_Srr }, + { "addi_mpyi", 0x8b000000, 0xff000000, Q_Srr_rSr }, { "addi3_mpyi3", 0x88000000, 0xff000000, Q_rrr_SSr }, { "addi3_mpyi3", 0x89000000, 0xff000000, Q_rSr_Srr }, + { "addi3_mpyi3", 0x89000000, 0xff000000, Q_rSr_rSr }, { "addi3_mpyi3", 0x8a000000, 0xff000000, Q_SSr_rrr }, { "addi3_mpyi3", 0x8b000000, 0xff000000, Q_Srr_Srr }, { "addi3_mpyi3", 0x8b000000, 0xff000000, Q_Srr_rSr }, @@ -390,6 +392,8 @@ static const c4x_inst_t c3x_insts[] = { "negf_stf", 0xe2000000, 0xfe000000, P_Sr_rS }, { "negi_sti", 0xe4000000, 0xfe000000, P_Sr_rS }, { "not_sti", 0xe6000000, 0xfe000000, P_Sr_rS }, + { "or_sti", 0xe8000000, 0xfe000000, P_Srr_rS }, + { "or_sti", 0xe8000000, 0xfe000000, P_rSr_rS }, { "or3_sti", 0xe8000000, 0xfe000000, P_Srr_rS }, { "or3_sti", 0xe8000000, 0xfe000000, P_rSr_rS }, { "stf_absf", 0xc8000000, 0xfe000000, Q_rS_Sr }, @@ -402,6 +406,7 @@ static const c4x_inst_t c3x_insts[] = { "stf_mpyf", 0xde000000, 0xfe000000, Q_rS_rSr }, { "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_Srr }, { "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_rSr }, + { "stf_ldf", 0xd8000000, 0xfe000000, Q_rS_Sr }, { "stf_negf", 0xe2000000, 0xfe000000, Q_rS_Sr }, { "stf_stf", 0xc0000000, 0xfe000000, P_rS_rS }, { "stf1_stf2", 0xc0000000, 0xfe000000, Q_rS_rS }, /* synonym */ @@ -417,6 +422,7 @@ static const c4x_inst_t c3x_insts[] = { "sti_and", 0xd0000000, 0xfe000000, Q_rS_rSr }, { "sti_and3", 0xd0000000, 0xfe000000, Q_rS_Srr }, { "sti_and3", 0xd0000000, 0xfe000000, Q_rS_rSr }, + { "sti_ash", 0xd2000000, 0xfe000000, Q_rS_rSr }, { "sti_ash3", 0xd2000000, 0xfe000000, Q_rS_rSr }, { "sti_fix", 0xd4000000, 0xfe000000, Q_rS_Sr }, { "sti_ldi", 0xda000000, 0xfe000000, Q_rS_Sr }, @@ -1007,9 +1013,9 @@ static const c4x_inst_t c3x_insts[] = { "xor3", 0x38000000, 0xffe00000, T_rJr }, /* C4x */ { "xor3", 0x38200000, 0xffe00000, T_rRr }, /* C4x */ { "xor3", 0x38200000, 0xffe00000, T_Rrr }, /* C4x */ - { "xor3", 0x3c400000, 0xffe00000, T_JRr }, /* C4x */ - { "xor3", 0x3c400000, 0xffe00000, T_RJr }, /* C4x */ - { "xor3", 0x3c600000, 0xffe00000, T_RRr }, /* C4x */ + { "xor3", 0x38400000, 0xffe00000, T_JRr }, /* C4x */ + { "xor3", 0x38400000, 0xffe00000, T_RJr }, /* C4x */ + { "xor3", 0x38600000, 0xffe00000, T_RRr }, /* C4x */ /* Dummy entry, not included in c3x_num_insts. This lets code examine entry i + 1 without checking @@ -1025,6 +1031,8 @@ static const c4x_inst_t c4x_insts[] = /* Parallel instructions. */ { "frieee_stf", 0xf2000000, 0xfe000000, P_Sr_rS }, { "toieee_stf", 0xf0000000, 0xfe000000, P_Sr_rS }, + { "stf_frieee", 0xf2000000, 0xfe000000, Q_rS_Sr }, + { "stf_toieee", 0xf0000000, 0xfe000000, Q_rS_Sr }, { "bBaf", 0x68a00000, 0xffe00000, "Q" }, { "bBaf", 0x6aa00000, 0xffe00000, "P" }, @@ -1038,12 +1046,10 @@ static const c4x_inst_t c4x_insts[] = { "lajB", 0x70200000, 0xffe00000, "Q" }, { "lajB", 0x72200000, 0xffe00000, "P" }, { "latB", 0x74800000, 0xffe00000, "V" }, - { "frieee", 0x1c000000, 0xffe00000, G_r_r }, { "frieee", 0x1c200000, 0xffe00000, G_T_r }, { "frieee", 0x1c400000, 0xffe00000, G_Q_r }, { "frieee", 0x1c600000, 0xffe00000, G_F_r }, - { "lb0", 0xb0000000, 0xffe00000, G_r_r }, { "lb0", 0xb0200000, 0xffe00000, G_T_r }, { "lb0", 0xb0400000, 0xffe00000, G_Q_r },