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>
* 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
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 <size>,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 <stdio.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 *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 <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
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 = 24;
mantissa_bits = 23;
}
else /* E_PRECISION */
{
exponent_bits = 8;
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;
unsigned long nop = NOP_OPCODE;
p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
(symbolS *) 0, (long) 2, (char *) 0);
/* 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;
}

View file

@ -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));

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>
* 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", 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 },