OSDN Git Service

gas tic4x target enhancements (long list - see gas/ChangeLog and
authorSvein Seldal <svein@dev.seldal.com>
Mon, 11 Nov 2002 14:29:01 +0000 (14:29 +0000)
committerSvein Seldal <svein@dev.seldal.com>
Mon, 11 Nov 2002 14:29:01 +0000 (14:29 +0000)
include/ChangeLog)

gas/ChangeLog
gas/config/tc-tic4x.c
gas/config/tc-tic4x.h
include/ChangeLog
include/opcode/tic4x.h

index e4e95b5..91ac46f 100644 (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
index 0ca9e5a..37d9aef 100644 (file)
    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 = 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)
@@ -1120,16 +1240,6 @@ c4x_version (x)
 }
 
 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;
@@ -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;
 }
 
index 185886a..b9dd0e5 100644 (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));
index 8efd9a3..425f3db 100644 (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++.
index 68d186d..18df7f1 100644 (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 },