gas tic4x target enhancements (long list - see gas/ChangeLog and

include/ChangeLog)
This commit is contained in:
Svein Seldal 2002-11-11 14:29:01 +00:00
parent b7b0b72964
commit 247b1fe610
5 changed files with 331 additions and 160 deletions

View file

@ -1,3 +1,20 @@
2002-11-11 Svein E. Seldal <Svein.Seldal@solidas.com>
* 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 <hp@bitrange.com> 2002-11-11 Hans-Peter Nilsson <hp@bitrange.com>
* macro.c (get_any_string): Correct logic for not going beyond end * macro.c (get_any_string): Correct logic for not going beyond end

View file

@ -19,19 +19,35 @@
along with GAS; see the file COPYING. If not, write to along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ Boston, MA 02111-1307, USA. */
/*
TODOs:
------
o .align cannot handle fill-data larger than 0xFF/8-bits
/* Things not currently implemented: o .align fills all section with NOP's when used regardless if has
> .usect if has symbol on previous line been used in .text or .data. (However the .align is primarely
intended used in .text sections. If you require something else,
use .align <size>,0x00)
> .sym, .eos, .stag, .etag, .member 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.
> Evaluation of constant floating point expressions (expr.c needs work!) o .usect if has symbol on previous line not implemented
> Warnings issued if parallel load of same register o .sym, .eos, .stag, .etag, .member not implemented
Note that this is primarily designed to handle the code generated o Evaluation of constant floating point expressions (expr.c needs work!)
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 <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
@ -101,148 +117,139 @@ c4x_insn_t;
static c4x_insn_t the_insn; /* Info about our instruction. */ static c4x_insn_t the_insn; /* Info about our instruction. */
static c4x_insn_t *insn = &the_insn; static c4x_insn_t *insn = &the_insn;
int c4x_gen_to_words static int c4x_gen_to_words
PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int )); PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int ));
char *c4x_atof static char *c4x_atof
PARAMS ((char *, char, LITTLENUM_TYPE * )); PARAMS ((char *, char, LITTLENUM_TYPE * ));
static void c4x_insert_reg static void c4x_insert_reg
PARAMS ((char *, int )); PARAMS ((char *, int ));
static void c4x_insert_sym static void c4x_insert_sym
PARAMS ((char *, int )); PARAMS ((char *, int ));
static char *c4x_expression static char *c4x_expression
PARAMS ((char *, expressionS *)); PARAMS ((char *, expressionS *));
static char *c4x_expression_abs static char *c4x_expression_abs
PARAMS ((char *, int *)); PARAMS ((char *, int *));
static void c4x_emit_char static void c4x_emit_char
PARAMS ((char)); PARAMS ((char, int));
static void c4x_seg_alloc static void c4x_seg_alloc
PARAMS ((char *, segT, int, symbolS *)); PARAMS ((char *, segT, int, symbolS *));
static void c4x_asg static void c4x_asg
PARAMS ((int)); PARAMS ((int));
static void c4x_bss static void c4x_bss
PARAMS ((int)); PARAMS ((int));
void c4x_globl static void c4x_globl
PARAMS ((int)); PARAMS ((int));
static void c4x_cons static void c4x_cons
PARAMS ((int)); PARAMS ((int));
static void c4x_stringer
PARAMS ((int));
static void c4x_eval static void c4x_eval
PARAMS ((int)); PARAMS ((int));
static void c4x_newblock static void c4x_newblock
PARAMS ((int)); PARAMS ((int));
static void c4x_sect static void c4x_sect
PARAMS ((int)); PARAMS ((int));
static void c4x_set static void c4x_set
PARAMS ((int)); PARAMS ((int));
static void c4x_usect static void c4x_usect
PARAMS ((int)); PARAMS ((int));
static void c4x_version static void c4x_version
PARAMS ((int)); PARAMS ((int));
static void c4x_pseudo_ignore static void c4x_pseudo_ignore
PARAMS ((int)); PARAMS ((int));
static void c4x_init_regtable static void c4x_init_regtable
PARAMS ((void)); PARAMS ((void));
static void c4x_init_symbols static void c4x_init_symbols
PARAMS ((void)); PARAMS ((void));
static int c4x_inst_insert static int c4x_inst_insert
PARAMS ((c4x_inst_t *)); PARAMS ((c4x_inst_t *));
static c4x_inst_t *c4x_inst_make static c4x_inst_t *c4x_inst_make
PARAMS ((char *, unsigned long, char *)); PARAMS ((char *, unsigned long, char *));
static int c4x_inst_add static int c4x_inst_add
PARAMS ((c4x_inst_t *)); PARAMS ((c4x_inst_t *));
void md_begin void md_begin
PARAMS ((void)); PARAMS ((void));
void c4x_end void c4x_end
PARAMS ((void)); PARAMS ((void));
static int c4x_indirect_parse static int c4x_indirect_parse
PARAMS ((c4x_operand_t *, const c4x_indirect_t *)); PARAMS ((c4x_operand_t *, const c4x_indirect_t *));
char *c4x_operand_parse static char *c4x_operand_parse
PARAMS ((char *, c4x_operand_t *)); PARAMS ((char *, c4x_operand_t *));
static int c4x_operands_match static int c4x_operands_match
PARAMS ((c4x_inst_t *, c4x_insn_t *)); PARAMS ((c4x_inst_t *, c4x_insn_t *));
void c4x_insn_output static void c4x_insn_output
PARAMS ((c4x_insn_t *)); PARAMS ((c4x_insn_t *));
int c4x_operands_parse static int c4x_operands_parse
PARAMS ((char *, c4x_operand_t *, int )); PARAMS ((char *, c4x_operand_t *, int ));
void md_assemble void md_assemble
PARAMS ((char *)); PARAMS ((char *));
void c4x_cleanup void c4x_cleanup
PARAMS ((void)); PARAMS ((void));
char *md_atof char *md_atof
PARAMS ((int, char *, int *)); PARAMS ((int, char *, int *));
void md_apply_fix3 void md_apply_fix3
PARAMS ((fixS *, valueT *, segT )); PARAMS ((fixS *, valueT *, segT ));
void md_convert_frag void md_convert_frag
PARAMS ((bfd *, segT, fragS *)); PARAMS ((bfd *, segT, fragS *));
void md_create_short_jump void md_create_short_jump
PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
void md_create_long_jump void md_create_long_jump
PARAMS ((char *, addressT, addressT, fragS *, symbolS *)); PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
int md_estimate_size_before_relax int md_estimate_size_before_relax
PARAMS ((register fragS *, segT)); PARAMS ((register fragS *, segT));
int md_parse_option int md_parse_option
PARAMS ((int, char *)); PARAMS ((int, char *));
void md_show_usage void md_show_usage
PARAMS ((FILE *)); PARAMS ((FILE *));
int c4x_unrecognized_line int c4x_unrecognized_line
PARAMS ((int)); PARAMS ((int));
symbolS *md_undefined_symbol symbolS *md_undefined_symbol
PARAMS ((char *)); PARAMS ((char *));
void md_operand void md_operand
PARAMS ((expressionS *)); PARAMS ((expressionS *));
valueT md_section_align valueT md_section_align
PARAMS ((segT, valueT)); PARAMS ((segT, valueT));
static int c4x_pc_offset static int c4x_pc_offset
PARAMS ((unsigned int)); PARAMS ((unsigned int));
long md_pcrel_from long md_pcrel_from
PARAMS ((fixS *)); PARAMS ((fixS *));
int c4x_do_align int c4x_do_align
PARAMS ((int, const char *, int, int)); PARAMS ((int, const char *, int, int));
void c4x_start_line void c4x_start_line
PARAMS ((void)); PARAMS ((void));
arelent *tc_gen_reloc arelent *tc_gen_reloc
PARAMS ((asection *, fixS *)); PARAMS ((asection *, fixS *));
const pseudo_typeS const pseudo_typeS
md_pseudo_table[] = md_pseudo_table[] =
{ {
{"align", s_align_bytes, 32}, {"align", s_align_bytes, 32},
{"ascii", c4x_cons, 1}, {"ascii", c4x_stringer, 1},
{"asciz", c4x_pseudo_ignore, 0}, {"asciz", c4x_stringer, 0},
{"asg", c4x_asg, 0}, {"asg", c4x_asg, 0},
{"asect", c4x_pseudo_ignore, 0}, /* Absolute named section. */ {"block", s_space, 4},
{"block", s_space, 0},
{"byte", c4x_cons, 1}, {"byte", c4x_cons, 1},
{"bss", c4x_bss, 0}, {"bss", c4x_bss, 0},
{"comm", c4x_bss, 0}, {"copy", s_include, 0},
{"def", c4x_globl, 0}, {"def", c4x_globl, 0},
{"endfunc", c4x_pseudo_ignore, 0},
{"eos", c4x_pseudo_ignore, 0},
{"etag", c4x_pseudo_ignore, 0},
{"equ", c4x_set, 0}, {"equ", c4x_set, 0},
{"eval", c4x_eval, 0}, {"eval", c4x_eval, 0},
{"exitm", s_mexit, 0},
{"func", c4x_pseudo_ignore, 0},
{"global", c4x_globl, 0}, {"global", c4x_globl, 0},
{"globl", c4x_globl, 0}, {"globl", c4x_globl, 0},
{"hword", c4x_cons, 2}, {"hword", c4x_cons, 2},
{"ieee", float_cons, 'i'}, {"ieee", float_cons, 'i'},
{"int", c4x_cons, 4}, /* .int allocates 4 bytes. */ {"int", c4x_cons, 4}, /* .int allocates 4 bytes. */
{"length", c4x_pseudo_ignore, 0}, {"ldouble", float_cons, 'e'},
{"ldouble", float_cons, 'l'},
{"member", c4x_pseudo_ignore, 0},
{"newblock", c4x_newblock, 0}, {"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}, {"set", c4x_set, 0},
{"sect", c4x_sect, 1}, /* Define named section. */ {"sect", c4x_sect, 1}, /* Define named section. */
{"space", s_space, 4}, {"space", s_space, 4},
{"stag", c4x_pseudo_ignore, 0}, {"string", c4x_stringer, 0},
{"string", c4x_pseudo_ignore, 0}, {"usect", c4x_usect, 0}, /* Reserve space in uninit. named sect. */
{"sym", c4x_pseudo_ignore, 0},
{"usect", c4x_usect, 0}, /* Reserve space in uninit. named sect. */
{"version", c4x_version, 0}, {"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}, {"xdef", c4x_globl, 0},
{NULL, 0, 0}, {NULL, 0, 0},
}; };
@ -288,14 +295,15 @@ const char FLT_CHARS[] = "fFilsS";
extern FLONUM_TYPE generic_floating_point_number; extern FLONUM_TYPE generic_floating_point_number;
/* Precision in LittleNums. */ /* 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 S_PRECISION (1) /* Short float constants 16-bit. */
#define F_PRECISION (2) /* Float and double types 32-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) #define GUARD (2)
/* Turn generic_floating_point_number into a real short/float/double. */ /* Turn generic_floating_point_number into a real short/float/double. */
int static int
c4x_gen_to_words (flonum, words, precision) c4x_gen_to_words (flonum, words, precision)
FLONUM_TYPE flonum; FLONUM_TYPE flonum;
LITTLENUM_TYPE *words; LITTLENUM_TYPE *words;
@ -310,9 +318,17 @@ c4x_gen_to_words (flonum, words, precision)
unsigned int sfract; /* Scaled fraction. */ unsigned int sfract; /* Scaled fraction. */
unsigned int smant; /* Scaled mantissa. */ unsigned int smant; /* Scaled mantissa. */
unsigned int tmp; unsigned int tmp;
unsigned int mover; /* Mantissa overflow bits */
unsigned int rbit; /* Round bit. */
int shift; /* Shift count. */ int shift; /* Shift count. */
/* Here is how a generic floating point number is stored using /* NOTE: Svein Seldal <Svein.Seldal@solidas.com>
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 <m.hayes@elec.canterbury.ac.nz>
Here is how a generic floating point number is stored using
flonums (an extension of bignums) where p is a pointer to an flonums (an extension of bignums) where p is a pointer to an
array of LITTLENUMs. array of LITTLENUMs.
@ -440,22 +456,20 @@ c4x_gen_to_words (flonum, words, precision)
if (precision != S_PRECISION) if (precision != S_PRECISION)
words[1] = 0x0000; words[1] = 0x0000;
if (precision == E_PRECISION)
words[2] = words[3] = 0x0000;
/* 0.0e0 seen. */ /* 0.0e0 or NaN seen. */
if (flonum.low > flonum.leader) if (flonum.low > flonum.leader /* = 0.0e0 */
|| flonum.sign == 0) /* = NaN */
{ {
if(flonum.sign == 0)
as_bad ("Nan, using zero.");
words[0] = 0x8000; words[0] = 0x8000;
return return_value; return return_value;
} }
/* NaN: We can't do much... */ if (flonum.sign == 'P')
if (flonum.sign == 0)
{
as_bad ("Nan, using zero.");
words[0] = 0x8000;
return return_value;
}
else if (flonum.sign == 'P')
{ {
/* +INF: Replace with maximum float. */ /* +INF: Replace with maximum float. */
if (precision == S_PRECISION) if (precision == S_PRECISION)
@ -465,6 +479,11 @@ c4x_gen_to_words (flonum, words, precision)
words[0] = 0x7f7f; words[0] = 0x7f7f;
words[1] = 0xffff; words[1] = 0xffff;
} }
if (precision == E_PRECISION)
{
words[2] = 0x7fff;
words[3] = 0xffff;
}
return return_value; return return_value;
} }
else if (flonum.sign == 'N') else if (flonum.sign == 'N')
@ -473,7 +492,9 @@ c4x_gen_to_words (flonum, words, precision)
if (precision == S_PRECISION) if (precision == S_PRECISION)
words[0] = 0x7800; words[0] = 0x7800;
else else
words[0] = 0x7f80; words[0] = 0x7f80;
if (precision == E_PRECISION)
words[2] = 0x8000;
return return_value; return return_value;
} }
@ -489,43 +510,64 @@ c4x_gen_to_words (flonum, words, precision)
if (precision == S_PRECISION) /* Allow 1 rounding bit. */ if (precision == S_PRECISION) /* Allow 1 rounding bit. */
{ {
exponent_bits = 4; 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; exponent_bits = 8;
mantissa_bits = 24; mantissa_bits = 23;
}
else /* E_PRECISION */
{
exponent_bits = 8;
mantissa_bits = 31;
} }
shift = mantissa_bits - shift; shift = mantissa_bits - shift;
smant = 0; 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--) for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
{ {
tmp = shift >= 0 ? *p << shift : *p >> -shift; tmp = shift >= 0 ? *p << shift : *p >> -shift;
rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
smant |= tmp; smant |= tmp;
shift -= 16; shift -= 16;
} }
/* OK, we've got our scaled mantissa so let's round it up /* OK, we've got our scaled mantissa so let's round it up */
and drop the rounding bit. */ if(rbit)
smant++; {
smant >>= 1; /* 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... */ /* The number may be unnormalised so renormalise it... */
if (smant >> mantissa_bits) if(mover)
{ {
smant >>= 1; smant >>= 1;
smant |= sone; /* Insert the bit from mover into smant */
exponent++; exponent++;
} }
/* The binary point is now between bit positions 11 and 10 or 23 and 22, /* 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 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
bit at mantissa_bits - 1 should be set. */ bit at mantissa_bits - 1 should be set. */
if (!(smant >> (mantissa_bits - 1))) if (!(sone&smant))
abort (); /* Ooops. */ abort (); /* Ooops. */
sone = (1 << (mantissa_bits - 1));
if (flonum.sign == '+') if (flonum.sign == '+')
sfract = smant - sone; /* smant - 1.0. */ sfract = smant - sone; /* smant - 1.0. */
else else
@ -537,7 +579,9 @@ c4x_gen_to_words (flonum, words, precision)
sfract = 0; sfract = 0;
} }
else else
sfract = (sone << 1) - smant; /* 2.0 - smant. */ {
sfract = -smant & (sone-1); /* 2.0 - smant. */
}
sfract |= sone; /* Insert sign bit. */ sfract |= sone; /* Insert sign bit. */
} }
@ -546,21 +590,37 @@ c4x_gen_to_words (flonum, words, precision)
/* Force exponent to fit in desired field width. */ /* Force exponent to fit in desired field width. */
exponent &= (1 << (exponent_bits)) - 1; exponent &= (1 << (exponent_bits)) - 1;
sfract |= exponent << mantissa_bits;
if (precision == S_PRECISION) if (precision == E_PRECISION)
words[0] = sfract; {
/* 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 else
{ {
words[0] = sfract >> 16; /* Insert the exponent data into the word */
words[1] = sfract & 0xffff; sfract |= exponent << (mantissa_bits+1);
if (precision == S_PRECISION)
words[0] = sfract;
else
{
words[0] = sfract >> 16;
words[1] = sfract & 0xffff;
}
} }
return return_value; return return_value;
} }
/* Returns pointer past text consumed. */ /* Returns pointer past text consumed. */
char * static char *
c4x_atof (str, what_kind, words) c4x_atof (str, what_kind, words)
char *str; char *str;
char what_kind; char what_kind;
@ -606,6 +666,11 @@ c4x_atof (str, what_kind, words)
precision = F_PRECISION; precision = F_PRECISION;
break; break;
case 'E':
case 'e':
precision = E_PRECISION;
break;
default: default:
as_bad ("Invalid floating point number"); as_bad ("Invalid floating point number");
return (NULL); return (NULL);
@ -695,14 +760,15 @@ c4x_expression_abs (str, value)
} }
static void static void
c4x_emit_char (c) c4x_emit_char (c,b)
char c; char c;
int b;
{ {
expressionS exp; expressionS exp;
exp.X_op = O_constant; exp.X_op = O_constant;
exp.X_add_number = c; exp.X_add_number = c;
emit_expr (&exp, 4); emit_expr (&exp, b);
} }
static void static void
@ -824,7 +890,7 @@ c4x_bss (x)
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} }
void static void
c4x_globl (ignore) c4x_globl (ignore)
int ignore ATTRIBUTE_UNUSED; int ignore ATTRIBUTE_UNUSED;
{ {
@ -866,7 +932,7 @@ c4x_cons (bytes)
{ {
input_line_pointer++; input_line_pointer++;
while (is_a_char (c = next_char_of_string ())) while (is_a_char (c = next_char_of_string ()))
c4x_emit_char (c); c4x_emit_char (c, 4);
know (input_line_pointer[-1] == '\"'); know (input_line_pointer[-1] == '\"');
} }
else else
@ -897,6 +963,60 @@ c4x_cons (bytes)
demand_empty_rest_of_line (); 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 */ /* .eval expression, symbol */
static void static void
c4x_eval (x) c4x_eval (x)
@ -1119,16 +1239,6 @@ c4x_version (x)
demand_empty_rest_of_line (); 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 static void
c4x_init_regtable () c4x_init_regtable ()
{ {
@ -1182,17 +1292,19 @@ c4x_init_symbols ()
c4x_insert_sym (".BIGMODEL", c4x_big_model); c4x_insert_sym (".BIGMODEL", c4x_big_model);
c4x_insert_sym (".C30INTERRUPT", 0); c4x_insert_sym (".C30INTERRUPT", 0);
c4x_insert_sym (".TMS320xx", c4x_cpu == 0 ? 40 : c4x_cpu); 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_cpu == 33);
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 (".C4X", c4x_cpu == 0 || c4x_cpu == 40 || c4x_cpu == 44); 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); 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? */ /* 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_cpu == 33);
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 (".TMS320C31", c4x_cpu == 31); c4x_insert_sym (".TMS320C31", c4x_cpu == 31);
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 (".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 (".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); c4x_insert_sym (".TMS320C44", c4x_cpu == 44);
@ -1465,7 +1577,7 @@ c4x_indirect_parse (operand, indirect)
return 1; return 1;
} }
char * static char *
c4x_operand_parse (s, operand) c4x_operand_parse (s, operand)
char *s; char *s;
c4x_operand_t *operand; c4x_operand_t *operand;
@ -2188,7 +2300,7 @@ c4x_operands_match (inst, insn)
} }
} }
void static void
c4x_insn_output (insn) c4x_insn_output (insn)
c4x_insn_t *insn; c4x_insn_t *insn;
{ {
@ -2380,13 +2492,16 @@ md_atof (type, litP, sizeP)
break; break;
case 'i': /* .ieee */ case 'i': /* .ieee */
case 'I':
prec = 2; prec = 2;
ieee = 1; ieee = 1;
type = 'f'; /* Rewrite type to be usable by atof_ieee() */
break; break;
case 'l': /* .ldouble */ case 'e': /* .ldouble */
case 'E':
prec = 4; /* 2 32-bit words */ prec = 4; /* 2 32-bit words */
ieee = 1; ieee = 0;
break; break;
default: default:
@ -2404,10 +2519,21 @@ md_atof (type, litP, sizeP)
t = litP; t = litP;
/* This loops outputs the LITTLENUMs in REVERSE order; in accord with /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
little endian byte order. */ 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--), if (wordP<(words+prec-1)) /* Dump wordP[1] (if we have one) */
sizeof (LITTLENUM_TYPE)); {
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); litP += sizeof (LITTLENUM_TYPE);
} }
return 0; return 0;
@ -2550,7 +2676,7 @@ md_show_usage (stream)
{ {
fputs ("\ fputs ("\
C[34]x options:\n\ C[34]x options:\n\
-m30 | -m31 | -m32 | -m40 | -m44\n\ -m30 | -m31 | -m32 | -m33 | -m40 | -m44\n\
specify variant of architecture\n\ specify variant of architecture\n\
-b big memory model\n\ -b big memory model\n\
-p pass arguments on stack\n\ -p pass arguments on stack\n\
@ -2720,8 +2846,8 @@ md_pcrel_from (fixP)
c4x_pc_offset (op); c4x_pc_offset (op);
} }
/* This is probably not necessary, if we have played our cards right, /* Fill the alignment area with NOP's on .text, unless fill-data
since everything should be already aligned on a 4-byte boundary. */ was specified. */
int int
c4x_do_align (alignment, fill, len, max) c4x_do_align (alignment, fill, len, max)
int alignment ATTRIBUTE_UNUSED; int alignment ATTRIBUTE_UNUSED;
@ -2729,13 +2855,28 @@ c4x_do_align (alignment, fill, len, max)
int len ATTRIBUTE_UNUSED; int len ATTRIBUTE_UNUSED;
int max ATTRIBUTE_UNUSED; int max ATTRIBUTE_UNUSED;
{ {
char *p; unsigned long nop = NOP_OPCODE;
p = frag_var (rs_align, 1, 1, (relax_substateT) 0, /* Because we are talking lwords, not bytes, adjust aligment to do words */
(symbolS *) 0, (long) 2, (char *) 0); alignment += 2;
/* We could use frag_align_pattern (n, nop_pattern, sizeof (nop_pattern)); if (alignment != 0 && !need_pass_2)
to fill with our 32-bit nop opcode. */ {
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; return 1;
} }

View file

@ -65,6 +65,8 @@
#define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep (frag) #define TC_COFF_SIZEMACHDEP(frag) tc_coff_sizemachdep (frag)
#define NEED_FX_R_TYPE #define NEED_FX_R_TYPE
#define NOP_OPCODE 0x0c800000
#define reloc_type int #define reloc_type int
#define NO_RELOC 0 #define NO_RELOC 0
@ -84,7 +86,7 @@ extern int c4x_unrecognized_line PARAMS ((int));
#define md_number_to_chars number_to_chars_littleendian #define md_number_to_chars number_to_chars_littleendian
extern int c4x_do_align PARAMS ((int, const char *, int, int)); 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 || */ /* Start of line hook to remove parallel instruction operator || */
extern void c4x_start_line PARAMS ((void)); extern void c4x_start_line PARAMS ((void));

View file

@ -1,3 +1,8 @@
2002-11-11 Svein E. Seldal <Svein.Seldal@solidas.com>
* opcode/tic4x.h: Added new opcodes and corrected some bugs. Add
support for new DSP types.
2002-10-26 Roger Sayle <roger@eyesopen.com> 2002-10-26 Roger Sayle <roger@eyesopen.com>
* partition.h: Close the extern "C" scope when compiling with C++. * partition.h: Close the extern "C" scope when compiling with C++.

View file

@ -304,8 +304,10 @@ static const c4x_inst_t c3x_insts[] =
{ "addi_mpyi", 0x89000000, 0xff000000, Q_rSr_rSr }, { "addi_mpyi", 0x89000000, 0xff000000, Q_rSr_rSr },
{ "addi_mpyi", 0x8a000000, 0xff000000, Q_SSr_rrr }, { "addi_mpyi", 0x8a000000, 0xff000000, Q_SSr_rrr },
{ "addi_mpyi", 0x8b000000, 0xff000000, Q_Srr_Srr }, { "addi_mpyi", 0x8b000000, 0xff000000, Q_Srr_Srr },
{ "addi_mpyi", 0x8b000000, 0xff000000, Q_Srr_rSr },
{ "addi3_mpyi3", 0x88000000, 0xff000000, Q_rrr_SSr }, { "addi3_mpyi3", 0x88000000, 0xff000000, Q_rrr_SSr },
{ "addi3_mpyi3", 0x89000000, 0xff000000, Q_rSr_Srr }, { "addi3_mpyi3", 0x89000000, 0xff000000, Q_rSr_Srr },
{ "addi3_mpyi3", 0x89000000, 0xff000000, Q_rSr_rSr },
{ "addi3_mpyi3", 0x8a000000, 0xff000000, Q_SSr_rrr }, { "addi3_mpyi3", 0x8a000000, 0xff000000, Q_SSr_rrr },
{ "addi3_mpyi3", 0x8b000000, 0xff000000, Q_Srr_Srr }, { "addi3_mpyi3", 0x8b000000, 0xff000000, Q_Srr_Srr },
{ "addi3_mpyi3", 0x8b000000, 0xff000000, Q_Srr_rSr }, { "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 }, { "negf_stf", 0xe2000000, 0xfe000000, P_Sr_rS },
{ "negi_sti", 0xe4000000, 0xfe000000, P_Sr_rS }, { "negi_sti", 0xe4000000, 0xfe000000, P_Sr_rS },
{ "not_sti", 0xe6000000, 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_Srr_rS },
{ "or3_sti", 0xe8000000, 0xfe000000, P_rSr_rS }, { "or3_sti", 0xe8000000, 0xfe000000, P_rSr_rS },
{ "stf_absf", 0xc8000000, 0xfe000000, Q_rS_Sr }, { "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_mpyf", 0xde000000, 0xfe000000, Q_rS_rSr },
{ "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_Srr }, { "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_Srr },
{ "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_rSr }, { "stf_mpyf3", 0xde000000, 0xfe000000, Q_rS_rSr },
{ "stf_ldf", 0xd8000000, 0xfe000000, Q_rS_Sr },
{ "stf_negf", 0xe2000000, 0xfe000000, Q_rS_Sr }, { "stf_negf", 0xe2000000, 0xfe000000, Q_rS_Sr },
{ "stf_stf", 0xc0000000, 0xfe000000, P_rS_rS }, { "stf_stf", 0xc0000000, 0xfe000000, P_rS_rS },
{ "stf1_stf2", 0xc0000000, 0xfe000000, Q_rS_rS }, /* synonym */ { "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_and", 0xd0000000, 0xfe000000, Q_rS_rSr },
{ "sti_and3", 0xd0000000, 0xfe000000, Q_rS_Srr }, { "sti_and3", 0xd0000000, 0xfe000000, Q_rS_Srr },
{ "sti_and3", 0xd0000000, 0xfe000000, Q_rS_rSr }, { "sti_and3", 0xd0000000, 0xfe000000, Q_rS_rSr },
{ "sti_ash", 0xd2000000, 0xfe000000, Q_rS_rSr },
{ "sti_ash3", 0xd2000000, 0xfe000000, Q_rS_rSr }, { "sti_ash3", 0xd2000000, 0xfe000000, Q_rS_rSr },
{ "sti_fix", 0xd4000000, 0xfe000000, Q_rS_Sr }, { "sti_fix", 0xd4000000, 0xfe000000, Q_rS_Sr },
{ "sti_ldi", 0xda000000, 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", 0x38000000, 0xffe00000, T_rJr }, /* C4x */
{ "xor3", 0x38200000, 0xffe00000, T_rRr }, /* C4x */ { "xor3", 0x38200000, 0xffe00000, T_rRr }, /* C4x */
{ "xor3", 0x38200000, 0xffe00000, T_Rrr }, /* C4x */ { "xor3", 0x38200000, 0xffe00000, T_Rrr }, /* C4x */
{ "xor3", 0x3c400000, 0xffe00000, T_JRr }, /* C4x */ { "xor3", 0x38400000, 0xffe00000, T_JRr }, /* C4x */
{ "xor3", 0x3c400000, 0xffe00000, T_RJr }, /* C4x */ { "xor3", 0x38400000, 0xffe00000, T_RJr }, /* C4x */
{ "xor3", 0x3c600000, 0xffe00000, T_RRr }, /* C4x */ { "xor3", 0x38600000, 0xffe00000, T_RRr }, /* C4x */
/* Dummy entry, not included in c3x_num_insts. This /* Dummy entry, not included in c3x_num_insts. This
lets code examine entry i + 1 without checking lets code examine entry i + 1 without checking
@ -1025,6 +1031,8 @@ static const c4x_inst_t c4x_insts[] =
/* Parallel instructions. */ /* Parallel instructions. */
{ "frieee_stf", 0xf2000000, 0xfe000000, P_Sr_rS }, { "frieee_stf", 0xf2000000, 0xfe000000, P_Sr_rS },
{ "toieee_stf", 0xf0000000, 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", 0x68a00000, 0xffe00000, "Q" },
{ "bBaf", 0x6aa00000, 0xffe00000, "P" }, { "bBaf", 0x6aa00000, 0xffe00000, "P" },
@ -1038,12 +1046,10 @@ static const c4x_inst_t c4x_insts[] =
{ "lajB", 0x70200000, 0xffe00000, "Q" }, { "lajB", 0x70200000, 0xffe00000, "Q" },
{ "lajB", 0x72200000, 0xffe00000, "P" }, { "lajB", 0x72200000, 0xffe00000, "P" },
{ "latB", 0x74800000, 0xffe00000, "V" }, { "latB", 0x74800000, 0xffe00000, "V" },
{ "frieee", 0x1c000000, 0xffe00000, G_r_r }, { "frieee", 0x1c000000, 0xffe00000, G_r_r },
{ "frieee", 0x1c200000, 0xffe00000, G_T_r }, { "frieee", 0x1c200000, 0xffe00000, G_T_r },
{ "frieee", 0x1c400000, 0xffe00000, G_Q_r }, { "frieee", 0x1c400000, 0xffe00000, G_Q_r },
{ "frieee", 0x1c600000, 0xffe00000, G_F_r }, { "frieee", 0x1c600000, 0xffe00000, G_F_r },
{ "lb0", 0xb0000000, 0xffe00000, G_r_r }, { "lb0", 0xb0000000, 0xffe00000, G_r_r },
{ "lb0", 0xb0200000, 0xffe00000, G_T_r }, { "lb0", 0xb0200000, 0xffe00000, G_T_r },
{ "lb0", 0xb0400000, 0xffe00000, G_Q_r }, { "lb0", 0xb0400000, 0xffe00000, G_Q_r },