This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] tic4x update
- From: "Svein E. Seldal" <Svein dot Seldal at solidas dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 05 Nov 2002 17:43:19 +0100
- Subject: [patch] tic4x update
Hi,
While I'm waiting on getting maintainer access, can someone please
approve and apply this patch... It contains a lot of
changes/enhancements for tic4x-gas.
Svein
include/ChangeLog:
2002-11-05 Svein E. Seldal <Svein.Seldal@solidas.com>
* opcode/tic4x.h: Added new opcodes and corrected some bugs.
Add support for new DSP types.
gas/ChangeLog:
2002-11-05 Svein E. Seldal <Svein.Seldal@solidas.com>
* Makefile.am: Added tic4x dependecy
* config/tc-tic4x.c: Declare as many functions as possible
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.
Index: include/opcode/tic4x.h
===================================================================
RCS file: /prosjekt/gnu/src/src/include/opcode/tic4x.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 tic4x.h
*** include/opcode/tic4x.h 28 Aug 2002 10:38:49 -0000 1.1
--- include/opcode/tic4x.h 5 Nov 2002 16:35:07 -0000
*************** static const c4x_inst_t c3x_insts[] =
*** 304,311 ****
--- 304,313 ----
{ "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 },
*************** static const c4x_inst_t c3x_insts[] =
*** 390,395 ****
--- 392,399 ----
{ "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 },
*************** static const c4x_inst_t c3x_insts[] =
*** 402,407 ****
--- 406,412 ----
{ "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 */
*************** static const c4x_inst_t c3x_insts[] =
*** 417,422 ****
--- 422,428 ----
{ "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 },
*************** static const c4x_inst_t c3x_insts[] =
*** 1007,1015 ****
{ "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 */
/* Dummy entry, not included in c3x_num_insts. This
lets code examine entry i + 1 without checking
--- 1013,1021 ----
{ "xor3", 0x38000000, 0xffe00000, T_rJr }, /* C4x */
{ "xor3", 0x38200000, 0xffe00000, T_rRr }, /* C4x */
{ "xor3", 0x38200000, 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
*************** static const c4x_inst_t c4x_insts[] =
*** 1025,1030 ****
--- 1031,1038 ----
/* 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" },
*************** static const c4x_inst_t c4x_insts[] =
*** 1038,1049 ****
{ "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 },
--- 1046,1055 ----
Index: gas/config/tc-tic4x.c
===================================================================
RCS file: /prosjekt/gnu/src/src/gas/config/tc-tic4x.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 tc-tic4x.c
*** gas/config/tc-tic4x.c 17 Sep 2002 08:35:10 -0000 1.2
--- gas/config/tc-tic4x.c 5 Nov 2002 16:35:07 -0000
***************
*** 19,37 ****
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. */
! /* Things not currently implemented:
! > .usect if has symbol on previous line
! > .sym, .eos, .stag, .etag, .member
! > Evaluation of constant floating point expressions (expr.c needs work!)
! > Warnings issued if parallel load of same register
! Note that this is primarily designed to handle the code generated
! by GCC. Anything else is a bonus! */
#include <stdio.h>
#include <ctype.h>
--- 19,53 ----
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)
! 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.
! o .usect if has symbol on previous line not implemented
! o .sym, .eos, .stag, .etag, .member not implemented
! o Evaluation of constant floating point expressions (expr.c needs work!)
! 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>
*************** c4x_insn_t;
*** 101,248 ****
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 void c4x_insert_reg
! PARAMS ((char *, int ));
static void c4x_insert_sym
! PARAMS ((char *, int ));
static char *c4x_expression
! PARAMS ((char *, expressionS *));
static char *c4x_expression_abs
! PARAMS ((char *, int *));
static void c4x_emit_char
! PARAMS ((char));
static void c4x_seg_alloc
! PARAMS ((char *, segT, int, symbolS *));
static void c4x_asg
! PARAMS ((int));
static void c4x_bss
! PARAMS ((int));
! void c4x_globl
! PARAMS ((int));
static void c4x_cons
! PARAMS ((int));
static void c4x_eval
! PARAMS ((int));
static void c4x_newblock
! PARAMS ((int));
static void c4x_sect
! PARAMS ((int));
static void c4x_set
! PARAMS ((int));
static void c4x_usect
! PARAMS ((int));
static void c4x_version
! PARAMS ((int));
static void c4x_pseudo_ignore
! PARAMS ((int));
static void c4x_init_regtable
! PARAMS ((void));
static void c4x_init_symbols
! PARAMS ((void));
static int c4x_inst_insert
! PARAMS ((c4x_inst_t *));
static c4x_inst_t *c4x_inst_make
! PARAMS ((char *, unsigned long, char *));
static int c4x_inst_add
! PARAMS ((c4x_inst_t *));
void md_begin
! PARAMS ((void));
void c4x_end
! PARAMS ((void));
static int c4x_indirect_parse
! PARAMS ((c4x_operand_t *, const c4x_indirect_t *));
! 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 ));
void md_assemble
! PARAMS ((char *));
void c4x_cleanup
! PARAMS ((void));
char *md_atof
! PARAMS ((int, char *, int *));
void md_apply_fix3
! PARAMS ((fixS *, valueT *, segT ));
void md_convert_frag
! PARAMS ((bfd *, segT, fragS *));
void md_create_short_jump
! PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
void md_create_long_jump
! PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
int md_estimate_size_before_relax
! PARAMS ((register fragS *, segT));
int md_parse_option
! PARAMS ((int, char *));
void md_show_usage
! PARAMS ((FILE *));
int c4x_unrecognized_line
! PARAMS ((int));
symbolS *md_undefined_symbol
! PARAMS ((char *));
void md_operand
! PARAMS ((expressionS *));
valueT md_section_align
! PARAMS ((segT, valueT));
static int c4x_pc_offset
! PARAMS ((unsigned int));
long md_pcrel_from
! PARAMS ((fixS *));
int c4x_do_align
! PARAMS ((int, const char *, int, int));
void c4x_start_line
! PARAMS ((void));
arelent *tc_gen_reloc
! PARAMS ((asection *, fixS *));
const pseudo_typeS
md_pseudo_table[] =
{
{"align", s_align_bytes, 32},
! {"ascii", c4x_cons, 1},
! {"asciz", c4x_pseudo_ignore, 0},
{"asg", c4x_asg, 0},
! {"asect", c4x_pseudo_ignore, 0}, /* Absolute named section. */
! {"block", s_space, 0},
{"byte", c4x_cons, 1},
{"bss", c4x_bss, 0},
! {"comm", c4x_bss, 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},
{"newblock", c4x_newblock, 0},
! {"ref", s_ignore, 0}, /* All undefined treated as external. */
{"set", c4x_set, 0},
! {"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. */
{"version", c4x_version, 0},
! {"width", c4x_pseudo_ignore, 0},
! {"word", c4x_cons, 4}, /* .word allocates 4 bytes. */
{"xdef", c4x_globl, 0},
{NULL, 0, 0},
};
--- 117,255 ----
static c4x_insn_t the_insn; /* Info about our instruction. */
static c4x_insn_t *insn = &the_insn;
! 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 ));
static void c4x_insert_sym
! PARAMS ((char *, int ));
static char *c4x_expression
! PARAMS ((char *, expressionS *));
static char *c4x_expression_abs
! PARAMS ((char *, int *));
static void c4x_emit_char
! PARAMS ((char, int));
static void c4x_seg_alloc
! PARAMS ((char *, segT, int, symbolS *));
static void c4x_asg
! PARAMS ((int));
static void c4x_bss
! PARAMS ((int));
! static void c4x_globl
! PARAMS ((int));
static void c4x_cons
! PARAMS ((int));
! static void c4x_stringer
! PARAMS ((int));
static void c4x_eval
! PARAMS ((int));
static void c4x_newblock
! PARAMS ((int));
static void c4x_sect
! PARAMS ((int));
static void c4x_set
! PARAMS ((int));
static void c4x_usect
! PARAMS ((int));
static void c4x_version
! PARAMS ((int));
static void c4x_pseudo_ignore
! PARAMS ((int));
static void c4x_init_regtable
! PARAMS ((void));
static void c4x_init_symbols
! PARAMS ((void));
static int c4x_inst_insert
! PARAMS ((c4x_inst_t *));
static c4x_inst_t *c4x_inst_make
! PARAMS ((char *, unsigned long, char *));
static int c4x_inst_add
! PARAMS ((c4x_inst_t *));
void md_begin
! PARAMS ((void));
void c4x_end
! PARAMS ((void));
static int c4x_indirect_parse
! 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 *));
! 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 *));
void c4x_cleanup
! PARAMS ((void));
char *md_atof
! PARAMS ((int, char *, int *));
void md_apply_fix3
! PARAMS ((fixS *, valueT *, segT ));
void md_convert_frag
! PARAMS ((bfd *, segT, fragS *));
void md_create_short_jump
! PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
void md_create_long_jump
! PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
int md_estimate_size_before_relax
! PARAMS ((register fragS *, segT));
int md_parse_option
! PARAMS ((int, char *));
void md_show_usage
! PARAMS ((FILE *));
int c4x_unrecognized_line
! PARAMS ((int));
symbolS *md_undefined_symbol
! PARAMS ((char *));
void md_operand
! PARAMS ((expressionS *));
valueT md_section_align
! PARAMS ((segT, valueT));
static int c4x_pc_offset
! PARAMS ((unsigned int));
long md_pcrel_from
! PARAMS ((fixS *));
int c4x_do_align
! PARAMS ((int, const char *, int, int));
void c4x_start_line
! PARAMS ((void));
arelent *tc_gen_reloc
! PARAMS ((asection *, fixS *));
const pseudo_typeS
md_pseudo_table[] =
{
{"align", s_align_bytes, 32},
! {"ascii", c4x_stringer, 1},
! {"asciz", c4x_stringer, 0},
{"asg", c4x_asg, 0},
! {"block", s_space, 4},
{"byte", c4x_cons, 1},
{"bss", c4x_bss, 0},
! {"copy", s_include, 0},
{"def", c4x_globl, 0},
{"equ", c4x_set, 0},
{"eval", c4x_eval, 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. */
! {"ldouble", float_cons, 'e'},
{"newblock", c4x_newblock, 0},
! {"ref", s_ignore, 0}, /* All undefined treated as external. */
{"set", c4x_set, 0},
! {"sect", c4x_sect, 1}, /* Define named section. */
{"space", s_space, 4},
! {"string", c4x_stringer, 0},
! {"usect", c4x_usect, 0}, /* Reserve space in uninit. named sect. */
{"version", c4x_version, 0},
! {"word", c4x_cons, 4}, /* .word allocates 4 bytes. */
{"xdef", c4x_globl, 0},
{NULL, 0, 0},
};
*************** const char FLT_CHARS[] = "fFilsS";
*** 288,301 ****
extern FLONUM_TYPE generic_floating_point_number;
/* Precision in LittleNums. */
! #define MAX_PRECISION (2)
#define S_PRECISION (1) /* Short float constants 16-bit. */
#define F_PRECISION (2) /* Float and double types 32-bit. */
#define GUARD (2)
-
/* Turn generic_floating_point_number into a real short/float/double. */
! int
c4x_gen_to_words (flonum, words, precision)
FLONUM_TYPE flonum;
LITTLENUM_TYPE *words;
--- 295,309 ----
extern FLONUM_TYPE generic_floating_point_number;
/* Precision in LittleNums. */
! #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. */
! static int
c4x_gen_to_words (flonum, words, precision)
FLONUM_TYPE flonum;
LITTLENUM_TYPE *words;
*************** c4x_gen_to_words (flonum, words, precisi
*** 310,318 ****
unsigned int sfract; /* Scaled fraction. */
unsigned int smant; /* Scaled mantissa. */
unsigned int tmp;
int shift; /* Shift count. */
! /* 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.
--- 318,334 ----
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. */
! /* 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.
*************** c4x_gen_to_words (flonum, words, precisi
*** 440,470 ****
if (precision != S_PRECISION)
words[1] = 0x0000;
! /* 0.0e0 seen. */
! if (flonum.low > flonum.leader)
{
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')
{
/* +INF: Replace with maximum float. */
if (precision == S_PRECISION)
words[0] = 0x77ff;
! else
{
words[0] = 0x7f7f;
words[1] = 0xffff;
}
return return_value;
}
else if (flonum.sign == 'N')
--- 456,489 ----
if (precision != S_PRECISION)
words[1] = 0x0000;
+ if (precision == E_PRECISION)
+ words[2] = words[3] = 0x0000;
! /* 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;
}
! if (flonum.sign == 'P')
{
/* +INF: Replace with maximum float. */
if (precision == S_PRECISION)
words[0] = 0x77ff;
! 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')
*************** c4x_gen_to_words (flonum, words, precisi
*** 472,479 ****
/* -INF: Replace with maximum float. */
if (precision == S_PRECISION)
words[0] = 0x7800;
! else
! words[0] = 0x7f80;
return return_value;
}
--- 491,500 ----
/* -INF: Replace with maximum float. */
if (precision == S_PRECISION)
words[0] = 0x7800;
! else
! words[0] = 0x7f80;
! if (precision == E_PRECISION)
! words[2] = 0x8000;
return return_value;
}
*************** c4x_gen_to_words (flonum, words, precisi
*** 489,531 ****
if (precision == S_PRECISION) /* Allow 1 rounding bit. */
{
exponent_bits = 4;
! mantissa_bits = 12; /* Include suppr. bit but not rounding bit. */
}
! else
{
exponent_bits = 8;
! mantissa_bits = 24;
}
shift = mantissa_bits - shift;
smant = 0;
for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
{
tmp = shift >= 0 ? *p << shift : *p >> -shift;
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;
/* The number may be unnormalised so renormalise it... */
! if (smant >> mantissa_bits)
{
smant >>= 1;
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. */
- sone = (1 << (mantissa_bits - 1));
if (flonum.sign == '+')
sfract = smant - sone; /* smant - 1.0. */
else
--- 510,573 ----
if (precision == S_PRECISION) /* Allow 1 rounding bit. */
{
exponent_bits = 4;
! mantissa_bits = 11;
}
! else if(precision == F_PRECISION)
! {
! exponent_bits = 8;
! 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 */
! 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(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 (!(sone&smant))
! abort (); /* Ooops. */
if (flonum.sign == '+')
sfract = smant - sone; /* smant - 1.0. */
else
*************** c4x_gen_to_words (flonum, words, precisi
*** 537,543 ****
sfract = 0;
}
else
! sfract = (sone << 1) - smant; /* 2.0 - smant. */
sfract |= sone; /* Insert sign bit. */
}
--- 579,587 ----
sfract = 0;
}
else
! {
! sfract = -smant & (sone-1); /* 2.0 - smant. */
! }
sfract |= sone; /* Insert sign bit. */
}
*************** c4x_gen_to_words (flonum, words, precisi
*** 546,566 ****
/* Force exponent to fit in desired field width. */
exponent &= (1 << (exponent_bits)) - 1;
- sfract |= exponent << mantissa_bits;
! 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 *
c4x_atof (str, what_kind, words)
char *str;
char what_kind;
--- 590,626 ----
/* Force exponent to fit in desired field width. */
exponent &= (1 << (exponent_bits)) - 1;
! 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
{
! /* 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. */
! static char *
c4x_atof (str, what_kind, words)
char *str;
char what_kind;
*************** c4x_atof (str, what_kind, words)
*** 606,611 ****
--- 666,676 ----
precision = F_PRECISION;
break;
+ case 'E':
+ case 'e':
+ precision = E_PRECISION;
+ break;
+
default:
as_bad ("Invalid floating point number");
return (NULL);
*************** c4x_expression_abs (str, value)
*** 695,708 ****
}
static void
! c4x_emit_char (c)
char c;
{
expressionS exp;
exp.X_op = O_constant;
exp.X_add_number = c;
! emit_expr (&exp, 4);
}
static void
--- 760,774 ----
}
static void
! c4x_emit_char (c,b)
char c;
+ int b;
{
expressionS exp;
exp.X_op = O_constant;
exp.X_add_number = c;
! emit_expr (&exp, b);
}
static void
*************** c4x_bss (x)
*** 824,830 ****
demand_empty_rest_of_line ();
}
! void
c4x_globl (ignore)
int ignore ATTRIBUTE_UNUSED;
{
--- 890,896 ----
demand_empty_rest_of_line ();
}
! static void
c4x_globl (ignore)
int ignore ATTRIBUTE_UNUSED;
{
*************** c4x_cons (bytes)
*** 866,872 ****
{
input_line_pointer++;
while (is_a_char (c = next_char_of_string ()))
! c4x_emit_char (c);
know (input_line_pointer[-1] == '\"');
}
else
--- 932,938 ----
{
input_line_pointer++;
while (is_a_char (c = next_char_of_string ()))
! c4x_emit_char (c, 4);
know (input_line_pointer[-1] == '\"');
}
else
*************** c4x_cons (bytes)
*** 897,902 ****
--- 963,1022 ----
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)
*************** c4x_version (x)
*** 1120,1135 ****
}
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 ()
{
unsigned int i;
--- 1240,1245 ----
*************** c4x_init_symbols ()
*** 1182,1198 ****
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 (".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 (".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 (".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);
--- 1292,1310 ----
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_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_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);
*************** c4x_indirect_parse (operand, indirect)
*** 1465,1471 ****
return 1;
}
! char *
c4x_operand_parse (s, operand)
char *s;
c4x_operand_t *operand;
--- 1577,1583 ----
return 1;
}
! static char *
c4x_operand_parse (s, operand)
char *s;
c4x_operand_t *operand;
*************** c4x_operands_match (inst, insn)
*** 2188,2194 ****
}
}
! void
c4x_insn_output (insn)
c4x_insn_t *insn;
{
--- 2300,2306 ----
}
}
! static void
c4x_insn_output (insn)
c4x_insn_t *insn;
{
*************** md_atof (type, litP, sizeP)
*** 2380,2392 ****
break;
case 'i': /* .ieee */
prec = 2;
ieee = 1;
break;
! case 'l': /* .ldouble */
prec = 4; /* 2 32-bit words */
! ieee = 1;
break;
default:
--- 2492,2507 ----
break;
case 'i': /* .ieee */
+ case 'I':
prec = 2;
ieee = 1;
+ type = 'f'; /* Rewrite type to be usable by atof_ieee() */
break;
! case 'e': /* .ldouble */
! case 'E':
prec = 4; /* 2 32-bit words */
! ieee = 0;
break;
default:
*************** md_atof (type, litP, sizeP)
*** 2404,2413 ****
t = litP;
/* This loops outputs the LITTLENUMs in REVERSE order; in accord with
little endian byte order. */
! for (wordP = words + prec - 1; prec--;)
! {
! md_number_to_chars (litP, (valueT) (*wordP--),
! sizeof (LITTLENUM_TYPE));
litP += sizeof (LITTLENUM_TYPE);
}
return 0;
--- 2519,2539 ----
t = litP;
/* This loops outputs the LITTLENUMs in REVERSE order; in accord with
little endian byte order. */
! /* 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)
! {
! 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;
*************** md_show_usage (stream)
*** 2550,2556 ****
{
fputs ("\
C[34]x options:\n\
! -m30 | -m31 | -m32 | -m40 | -m44\n\
specify variant of architecture\n\
-b big memory model\n\
-p pass arguments on stack\n\
--- 2676,2682 ----
{
fputs ("\
C[34]x options:\n\
! -m30 | -m31 | -m32 | -m33 | -m40 | -m44\n\
specify variant of architecture\n\
-b big memory model\n\
-p pass arguments on stack\n\
*************** md_pcrel_from (fixP)
*** 2720,2727 ****
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. */
int
c4x_do_align (alignment, fill, len, max)
int alignment ATTRIBUTE_UNUSED;
--- 2846,2853 ----
c4x_pc_offset (op);
}
! /* 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;
*************** c4x_do_align (alignment, fill, len, max)
*** 2729,2741 ****
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);
!
! /* We could use frag_align_pattern (n, nop_pattern, sizeof (nop_pattern));
! to fill with our 32-bit nop opcode. */
return 1;
}
--- 2855,2882 ----
int len ATTRIBUTE_UNUSED;
int max ATTRIBUTE_UNUSED;
{
! unsigned long nop = 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;
}
Index: gas/config/tc-tic4x.h
===================================================================
RCS file: /prosjekt/gnu/src/src/gas/config/tc-tic4x.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 tc-tic4x.h
*** gas/config/tc-tic4x.h 28 Aug 2002 10:38:48 -0000 1.1
--- gas/config/tc-tic4x.h 5 Nov 2002 16:35:07 -0000
***************
*** 65,70 ****
--- 65,72 ----
#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
*************** extern int c4x_unrecognized_line PARAMS
*** 84,90 ****
#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
/* Start of line hook to remove parallel instruction operator || */
extern void c4x_start_line PARAMS ((void));
--- 86,92 ----
#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,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));