RIP gzip, we found a nicer playmate.
[dragonfly.git] / gnu / usr.bin / as / config / tc-i860.c
1 /* tc-i860.c -- Assemble for the I860
2    Copyright (C) 1989, 1992 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "as.h"
21
22 #include "opcode/i860.h"
23
24 void md_begin();
25 void md_end();
26 void md_number_to_chars();
27 void md_assemble();
28 char *md_atof();
29 void md_convert_frag();
30 void md_create_short_jump();
31 void md_create_long_jump();
32 int  md_estimate_size_before_relax();
33 void md_number_to_imm();
34 void md_number_to_disp();
35 void md_number_to_field();
36 void md_ri_to_chars();
37 static void i860_ip();
38
39 const relax_typeS md_relax_table[] = { 0 };
40
41 /* handle of the OPCODE hash table */
42 static struct hash_control *op_hash = NULL;
43
44 static void s_dual(), s_enddual();
45 static void s_atmp();
46
47 const pseudo_typeS
48     md_pseudo_table[] = {
49             { "dual",       s_dual,     4 },
50             { "enddual",    s_enddual,  4 },
51             { "atmp",       s_atmp,     4 },
52             { NULL,         0,          0 },
53     };
54
55 int md_short_jump_size = 4;
56 int md_long_jump_size = 4;
57
58 /* This array holds the chars that always start a comment.  If the
59    pre-processor is disabled, these aren't very useful */
60 char comment_chars[] = "!/";    /* JF removed '|' from comment_chars */
61
62 /* This array holds the chars that only start a comment at the beginning of
63    a line.  If the line seems to have the form '# 123 filename'
64    .line and .file directives will appear in the pre-processed output */
65 /* Note that input_file.c hand checks for '#' at the beginning of the
66    first line of the input file.  This is because the compiler outputs
67    #NO_APP at the beginning of its output. */
68 /* Also note that comments like this one will always work. */
69 char line_comment_chars[] = "#/";
70
71 /* Chars that can be used to separate mant from exp in floating point nums */
72 char EXP_CHARS[] = "eE";
73
74 /* Chars that mean this number is a floating point constant */
75 /* As in 0f12.456 */
76 /* or    0d1.2345e12 */
77 char FLT_CHARS[] = "rRsSfFdDxXpP";
78
79 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
80    changed in read.c. Ideally it shouldn't have to know about it at all,
81    but nothing is ideal around here.
82    */
83 int size_reloc_info = sizeof(struct relocation_info);
84
85 static unsigned char octal[256];
86 #define isoctal(c)  octal[c]
87     static unsigned char toHex[256];
88
89 struct i860_it {
90         char    *error;
91         unsigned long opcode;
92         struct nlist *nlistp;
93         expressionS exp;
94         int pcrel;
95         enum expand_type expand;
96         enum highlow_type highlow;
97         enum reloc_type reloc;
98 } the_insn;
99
100 #if __STDC__ == 1
101
102 #ifdef comment
103 static void print_insn(struct i860_it *insn);
104 #endif /* comment */
105
106 static int getExpression(char *str);
107
108 #else /* not __STDC__ */
109
110 #ifdef comment
111 static void print_insn();
112 #endif /* comment */
113
114 static int getExpression();
115
116 #endif /* not __STDC__ */
117
118 static char *expr_end;
119 static char last_expand;        /* error if expansion after branch */
120
121 enum dual
122 {
123         DUAL_OFF = 0, DUAL_ON, DUAL_DDOT, DUAL_ONDDOT,
124 };
125 static enum dual dual_mode = DUAL_OFF;  /* dual-instruction mode */
126
127 static void
128     s_dual()    /* floating point instructions have dual set */
129 {
130         dual_mode = DUAL_ON;
131 }
132
133 static void
134     s_enddual() /* floating point instructions have dual set */
135 {
136         dual_mode = DUAL_OFF;
137 }
138
139 static int atmp = 31; /* temporary register for pseudo's */
140
141 static void
142     s_atmp()
143 {
144         register int temp;
145         if (strncmp(input_line_pointer, "sp", 2) == 0) {
146                 input_line_pointer += 2;
147                 atmp = 2;
148         }
149         else if (strncmp(input_line_pointer, "fp", 2) == 0) {
150                 input_line_pointer += 2;
151                 atmp = 3;
152         }
153         else if (strncmp(input_line_pointer, "r", 1) == 0) {
154                 input_line_pointer += 1;
155                 temp = get_absolute_expression();
156                 if (temp >= 0 && temp <= 31)
157                     atmp = temp;
158                 else
159                     as_bad("Unknown temporary pseudo register");
160         }
161         else {
162                 as_bad("Unknown temporary pseudo register");
163         }
164         demand_empty_rest_of_line();
165         return;
166 }
167
168 /* This function is called once, at assembler startup time.  It should
169    set up all the tables, etc. that the MD part of the assembler will need.  */
170 void
171     md_begin()
172 {
173         register char *retval = NULL;
174         int lose = 0;
175         register unsigned int i = 0;
176
177         op_hash = hash_new();
178         if (op_hash == NULL)
179             as_fatal("Virtual memory exhausted");
180
181         while (i < NUMOPCODES)
182             {
183                     const char *name = i860_opcodes[i].name;
184                     retval = hash_insert(op_hash, name, &i860_opcodes[i]);
185                     if (retval != NULL && *retval != '\0')
186                         {
187                                 fprintf (stderr, "internal error: can't hash `%s': %s\n",
188                                          i860_opcodes[i].name, retval);
189                                 lose = 1;
190                         }
191                     do
192                         {
193                                 if (i860_opcodes[i].match & i860_opcodes[i].lose)
194                                     {
195                                             fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
196                                                      i860_opcodes[i].name, i860_opcodes[i].args);
197                                             lose = 1;
198                                     }
199                                 ++i;
200                         } while (i < NUMOPCODES
201                                  && !strcmp(i860_opcodes[i].name, name));
202             }
203
204         if (lose)
205             as_fatal("Broken assembler.  No assembly attempted.");
206
207         for (i = '0'; i < '8'; ++i)
208             octal[i] = 1;
209         for (i = '0'; i <= '9'; ++i)
210             toHex[i] = i - '0';
211         for (i = 'a'; i <= 'f'; ++i)
212             toHex[i] = i + 10 - 'a';
213         for (i = 'A'; i <= 'F'; ++i)
214             toHex[i] = i + 10 - 'A';
215 }
216
217 void
218     md_end()
219 {
220         return;
221 }
222
223 void
224     md_assemble(str)
225 char *str;
226 {
227         char *toP;
228 /*      int rsd; FIXME: remove this line. */
229         int no_opcodes = 1;
230         int i;
231         struct i860_it pseudo[3];
232
233         assert(str);
234         i860_ip(str);
235
236         /* check for expandable flag to produce pseudo-instructions */
237         if (the_insn.expand != 0 && the_insn.highlow == NO_SPEC) {
238                 for (i = 0; i < 3; i++)
239                     pseudo[i] = the_insn;
240
241                 switch (the_insn.expand) {
242
243                 case E_DELAY:
244                         no_opcodes = 1;
245                         break;
246
247                 case E_MOV:
248                         if (the_insn.exp.X_add_symbol == NULL &&
249                             the_insn.exp.X_subtract_symbol == NULL &&
250                             (the_insn.exp.X_add_number < (1 << 15) &&
251                              the_insn.exp.X_add_number >= -(1 << 15)))
252                             break;
253                         /* or l%const,r0,ireg_dest */
254                         pseudo[0].opcode = (the_insn.opcode & 0x001f0000) | 0xe4000000;
255                         pseudo[0].highlow = PAIR;
256                         /* orh h%const,ireg_dest,ireg_dest */
257                         pseudo[1].opcode = (the_insn.opcode & 0x03ffffff) | 0xec000000 |
258                             ((the_insn.opcode & 0x001f0000) << 5);
259                         pseudo[1].highlow = HIGH;
260                         no_opcodes = 2;
261                         break;
262
263                 case E_ADDR:
264                         if (the_insn.exp.X_add_symbol == NULL &&
265                             the_insn.exp.X_subtract_symbol == NULL)
266                             break;
267                         /* orh ha%addr_expr,r0,r31 */
268                         pseudo[0].opcode = 0xec000000 | (atmp<<16);
269                         pseudo[0].highlow = HIGHADJ;
270                         pseudo[0].reloc = LOW0; /* must overwrite */
271                         /* l%addr_expr(r31),ireg_dest */
272                         pseudo[1].opcode = (the_insn.opcode & ~0x003e0000) | (atmp << 21);
273                         pseudo[1].highlow = PAIR;
274                         no_opcodes = 2;
275                         break;
276
277                 case E_U32:     /* 2nd version emulates Intel as, not doc. */
278                         if (the_insn.exp.X_add_symbol == NULL &&
279                             the_insn.exp.X_subtract_symbol == NULL &&
280                             (the_insn.exp.X_add_number < (1 << 16) &&
281                              the_insn.exp.X_add_number >= 0))
282                             break;
283                         /* $(opcode)h h%const,ireg_src2,ireg_dest
284                            pseudo[0].opcode = (the_insn.opcode & 0xf3ffffff) | 0x0c000000; */
285                         /* $(opcode)h h%const,ireg_src2,r31 */
286                         pseudo[0].opcode = (the_insn.opcode & 0xf3e0ffff) | 0x0c000000 |
287                             (atmp << 16);
288                         pseudo[0].highlow = HIGH;
289                         /* $(opcode) l%const,ireg_dest,ireg_dest
290                            pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
291                            ((the_insn.opcode & 0x001f0000) << 5); */
292                         /* $(opcode) l%const,r31,ireg_dest */
293                         pseudo[1].opcode = (the_insn.opcode & 0xf01f0000) | 0x04000000 |
294                             (atmp << 21);
295                         pseudo[1].highlow = PAIR;
296                         no_opcodes = 2;
297                         break;
298
299                 case E_AND:     /* 2nd version emulates Intel as, not doc. */
300                         if (the_insn.exp.X_add_symbol == NULL &&
301                             the_insn.exp.X_subtract_symbol == NULL &&
302                             (the_insn.exp.X_add_number < (1 << 16) &&
303                              the_insn.exp.X_add_number >= 0))
304                             break;
305                         /* andnot h%const,ireg_src2,ireg_dest
306                            pseudo[0].opcode = (the_insn.opcode & 0x03ffffff) | 0xd4000000; */
307                         /* andnot h%const,ireg_src2,r31 */
308                         pseudo[0].opcode = (the_insn.opcode & 0x03e0ffff) | 0xd4000000 |
309                             (atmp << 16);
310                         pseudo[0].highlow = HIGH;
311                         pseudo[0].exp.X_add_number = -1 - the_insn.exp.X_add_number;
312                         /* andnot l%const,ireg_dest,ireg_dest
313                            pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
314                            ((the_insn.opcode & 0x001f0000) << 5); */
315                         /* andnot l%const,r31,ireg_dest */
316                         pseudo[1].opcode = (the_insn.opcode & 0x001f0000) | 0xd4000000 |
317                             (atmp << 21);
318                         pseudo[1].highlow = PAIR;
319                         pseudo[1].exp.X_add_number = -1 - the_insn.exp.X_add_number;
320                         no_opcodes = 2;
321                         break;
322
323                 case E_S32:
324                         if (the_insn.exp.X_add_symbol == NULL &&
325                             the_insn.exp.X_subtract_symbol == NULL &&
326                             (the_insn.exp.X_add_number < (1 << 15) &&
327                              the_insn.exp.X_add_number >= -(1 << 15)))
328                             break;
329                         /* orh h%const,r0,r31 */
330                         pseudo[0].opcode = 0xec000000 | (atmp << 16);
331                         pseudo[0].highlow = HIGH;
332                         /* or l%const,r31,r31 */
333                         pseudo[1].opcode = 0xe4000000 | (atmp << 21) | (atmp << 16);
334                         pseudo[1].highlow = PAIR;
335                         /* r31,ireg_src2,ireg_dest */
336                         pseudo[2].opcode = (the_insn.opcode & ~0x0400ffff) | (atmp << 11);
337                         pseudo[2].reloc = NO_RELOC;
338                         no_opcodes = 3;
339                         break;
340
341                 default:
342                         as_fatal("failed sanity check.");
343                 }
344
345                 the_insn = pseudo[0];
346                 /* check for expanded opcode after branch or in dual */
347                 if (no_opcodes > 1 && last_expand == 1)
348                     as_warn("Expanded opcode after delayed branch: `%s'", str);
349                 if (no_opcodes > 1 && dual_mode != DUAL_OFF)
350                     as_warn("Expanded opcode in dual mode: `%s'", str);
351         }
352
353         i = 0;
354         do {    /* always produce at least one opcode */
355                 toP = frag_more(4);
356                 /* put out the opcode */
357                 md_number_to_chars(toP, the_insn.opcode, 4);
358
359                 /* check for expanded opcode after branch or in dual */
360                 last_expand = the_insn.pcrel;
361
362                 /* put out the symbol-dependent stuff */
363                 if (the_insn.reloc != NO_RELOC) {
364                         fix_new(frag_now, /* which frag */
365                                 (toP - frag_now->fr_literal), /* where */
366                                 4, /* size */
367                                 the_insn.exp.X_add_symbol,
368                                 the_insn.exp.X_subtract_symbol,
369                                 the_insn.exp.X_add_number,
370                                 the_insn.pcrel,
371                                 /* merge bit fields into one argument */
372                                 (int)(((the_insn.highlow & 0x3) << 4) | (the_insn.reloc & 0xf)));
373                 }
374                 the_insn = pseudo[++i];
375         } while (--no_opcodes > 0);
376
377 }
378
379 static void
380     i860_ip(str)
381 char *str;
382 {
383         char *s;
384         const char *args;
385         char c;
386 /*      unsigned long i; FIXME: remove this line. */
387         struct i860_opcode *insn;
388         char *argsStart;
389         unsigned long opcode;
390         unsigned int mask;
391         int match = 0;
392         int comma = 0;
393
394
395         for (s = str; islower(*s) || *s == '.' || *s == '3'; ++s)
396             ;
397         switch (*s) {
398
399         case '\0':
400                 break;
401
402         case ',':
403                 comma = 1;
404
405                 /*FALLTHROUGH*/
406
407         case ' ':
408                 *s++ = '\0';
409                 break;
410
411         default:
412                 as_bad("Unknown opcode: `%s'", str);
413                 exit(1);
414         }
415
416         if (strncmp(str, "d.", 2) == 0) {       /* check for d. opcode prefix */
417                 if (dual_mode == DUAL_ON)
418                     dual_mode = DUAL_ONDDOT;
419                 else
420                     dual_mode = DUAL_DDOT;
421                 str += 2;
422         }
423
424         if ((insn = (struct i860_opcode *) hash_find(op_hash, str)) == NULL) {
425                 if (dual_mode == DUAL_DDOT || dual_mode == DUAL_ONDDOT)
426                     str -= 2;
427                 as_bad("Unknown opcode: `%s'", str);
428                 return;
429         }
430         if (comma) {
431                 *--s = ',';
432         }
433         argsStart = s;
434         for (;;) {
435                 opcode = insn->match;
436                 memset(&the_insn, '\0', sizeof(the_insn));
437                 the_insn.reloc = NO_RELOC;
438
439                 /*
440                  * Build the opcode, checking as we go to make
441                  * sure that the operands match
442                  */
443                 for (args = insn->args; ; ++args) {
444                         switch (*args) {
445
446                         case '\0':  /* end of args */
447                                 if (*s == '\0') {
448                                         match = 1;
449                                 }
450                                 break;
451
452                         case '+':
453                         case '(':   /* these must match exactly */
454                         case ')':
455                         case ',':
456                         case ' ':
457                                 if (*s++ == *args)
458                                     continue;
459                                 break;
460
461                         case '#':   /* must be at least one digit */
462                                 if (isdigit(*s++)) {
463                                         while (isdigit(*s)) {
464                                                 ++s;
465                                         }
466                                         continue;
467                                 }
468                                 break;
469
470                         case '1':   /* next operand must be a register */
471                         case '2':
472                         case 'd':
473                                 switch (*s) {
474
475                                 case 'f':   /* frame pointer */
476                                         s++;
477                                         if (*s++ == 'p') {
478                                                 mask = 0x3;
479                                                 break;
480                                         }
481                                         goto error;
482
483                                 case 's':   /* stack pointer */
484                                         s++;
485                                         if (*s++ == 'p') {
486                                                 mask= 0x2;
487                                                 break;
488                                         }
489                                         goto error;
490
491                                 case 'r': /* any register */
492                                         s++;
493                                         if (!isdigit(c = *s++)) {
494                                                 goto error;
495                                         }
496                                         if (isdigit(*s)) {
497                                                 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
498                                                         goto error;
499                                                 }
500                                         } else {
501                                                 c -= '0';
502                                         }
503                                         mask= c;
504                                         break;
505
506                                 default:        /* not this opcode */
507                                         goto error;
508                                 }
509                                 /*
510                                  * Got the register, now figure out where
511                                  * it goes in the opcode.
512                                  */
513                                 switch (*args) {
514
515                                 case '1':
516                                         opcode |= mask << 11;
517                                         continue;
518
519                                 case '2':
520                                         opcode |= mask << 21;
521                                         continue;
522
523                                 case 'd':
524                                         opcode |= mask << 16;
525                                         continue;
526
527                                 }
528                                 break;
529
530                         case 'e':    /* next operand is a floating point register */
531                         case 'f':
532                         case 'g':
533                                 if (*s++ == 'f' && isdigit(*s)) {
534                                         mask = *s++;
535                                         if (isdigit(*s)) {
536                                                 mask = 10 * (mask - '0') + (*s++ - '0');
537                                                 if (mask >= 32) {
538                                                         break;
539                                                 }
540                                         } else {
541                                                 mask -= '0';
542                                         }
543                                         switch (*args) {
544
545                                         case 'e':
546                                                 opcode |= mask << 11;
547                                                 continue;
548
549                                         case 'f':
550                                                 opcode |= mask << 21;
551                                                 continue;
552
553                                         case 'g':
554                                                 opcode |= mask << 16;
555                                                 if (dual_mode != DUAL_OFF)
556                                                     opcode |= (1 << 9); /* dual mode instruction */
557                                                 if (dual_mode == DUAL_DDOT)
558                                                     dual_mode = DUAL_OFF;
559                                                 if (dual_mode == DUAL_ONDDOT)
560                                                     dual_mode = DUAL_ON;
561                                                 if ((opcode & (1 << 10)) && (mask == ((opcode >> 11) & 0x1f)))
562                                                     as_warn("Fsr1 equals fdest with Pipelining");
563                                                 continue;
564                                         }
565                                 }
566                                 break;
567
568                         case 'c': /* next operand must be a control register */
569                                 if (strncmp(s, "fir", 3) == 0) {
570                                         opcode |= 0x0 << 21;
571                                         s += 3;
572                                         continue;
573                                 }
574                                 if (strncmp(s, "psr", 3) == 0) {
575                                         opcode |= 0x1 << 21;
576                                         s += 3;
577                                         continue;
578                                 }
579                                 if (strncmp(s, "dirbase", 7) == 0) {
580                                         opcode |= 0x2 << 21;
581                                         s += 7;
582                                         continue;
583                                 }
584                                 if (strncmp(s, "db", 2) == 0) {
585                                         opcode |= 0x3 << 21;
586                                         s += 2;
587                                         continue;
588                                 }
589                                 if (strncmp(s, "fsr", 3) == 0) {
590                                         opcode |= 0x4 << 21;
591                                         s += 3;
592                                         continue;
593                                 }
594                                 if (strncmp(s, "epsr", 4) == 0) {
595                                         opcode |= 0x5 << 21;
596                                         s += 4;
597                                         continue;
598                                 }
599                                 break;
600
601                         case '5':   /* 5 bit immediate in src1 */
602                                 memset(&the_insn, '\0', sizeof(the_insn));
603                                 if ( !getExpression(s)) {
604                                         s = expr_end;
605                                         if (the_insn.exp.X_add_number & ~0x1f)
606                                             as_bad("5-bit immediate too large");
607                                         opcode |= (the_insn.exp.X_add_number & 0x1f) << 11;
608                                         memset(&the_insn, '\0', sizeof(the_insn));
609                                         the_insn.reloc = NO_RELOC;
610                                         continue;
611                                 }
612                                 break;
613
614                         case 'l':   /* 26 bit immediate, relative branch */
615                                 the_insn.reloc = BRADDR;
616                                 the_insn.pcrel = 1;
617                                 goto immediate;
618
619                         case 's':   /* 16 bit immediate, split relative branch */
620                                 /* upper 5 bits of offset in dest field */
621                                 the_insn.pcrel = 1;
622                                 the_insn.reloc = SPLIT0;
623                                 goto immediate;
624
625                         case 'S':   /* 16 bit immediate, split (st), aligned */
626                                 if (opcode & (1 << 28))
627                                     if (opcode & 0x1)
628                                         the_insn.reloc = SPLIT2;
629                                     else
630                                         the_insn.reloc = SPLIT1;
631                                 else
632                                     the_insn.reloc = SPLIT0;
633                                 goto immediate;
634
635                         case 'I':   /* 16 bit immediate, aligned */
636                                 if (opcode & (1 << 28))
637                                     if (opcode & 0x1)
638                                         the_insn.reloc = LOW2;
639                                     else
640                                         the_insn.reloc = LOW1;
641                                 else
642                                     the_insn.reloc = LOW0;
643                                 goto immediate;
644
645                         case 'i':   /* 16 bit immediate */
646                                 the_insn.reloc = LOW0;
647
648                                 /*FALLTHROUGH*/
649
650                         immediate:
651                                 if (*s == ' ')
652                                     s++;
653                                 if (strncmp(s, "ha%", 3) == 0) {
654                                         the_insn.highlow = HIGHADJ;
655                                         s += 3;
656                                 } else if (strncmp(s, "h%", 2) == 0) {
657                                         the_insn.highlow = HIGH;
658                                         s += 2;
659                                 } else if (strncmp(s, "l%", 2) == 0) {
660                                         the_insn.highlow = PAIR;
661                                         s += 2;
662                                 }
663                                 the_insn.expand = insn->expand;
664
665                                 /* Note that if the getExpression() fails, we will still have
666                                    created U entries in the symbol table for the 'symbols'
667                                    in the input string.  Try not to create U symbols for
668                                    registers, etc. */
669
670                                 if ( !getExpression(s)) {
671                                         s = expr_end;
672                                         continue;
673                                 }
674                                 break;
675
676                         default:
677                                 as_fatal("failed sanity check.");
678                         }
679                         break;
680                 }
681         error:
682                 if (match == 0)
683                     {
684                             /* Args don't match.  */
685                             if (&insn[1] - i860_opcodes < NUMOPCODES
686                                 && !strcmp(insn->name, insn[1].name))
687                                 {
688                                         ++insn;
689                                         s = argsStart;
690                                         continue;
691                                 }
692                             else
693                                 {
694                                         as_bad("Illegal operands");
695                                         return;
696                                 }
697                     }
698                 break;
699         }
700
701         the_insn.opcode = opcode;
702         return;
703 }
704
705 static int
706     getExpression(str)
707 char *str;
708 {
709         char *save_in;
710         segT seg;
711
712         save_in = input_line_pointer;
713         input_line_pointer = str;
714         switch (seg = expression(&the_insn.exp)) {
715
716         case SEG_ABSOLUTE:
717         case SEG_TEXT:
718         case SEG_DATA:
719         case SEG_BSS:
720         case SEG_UNKNOWN:
721         case SEG_DIFFERENCE:
722         case SEG_BIG:
723         case SEG_ABSENT:
724                 break;
725
726         default:
727                 the_insn.error = "bad segment";
728                 expr_end = input_line_pointer;
729                 input_line_pointer=save_in;
730                 return 1;
731         }
732         expr_end = input_line_pointer;
733         input_line_pointer = save_in;
734         return 0;
735 }
736
737
738 /*
739   This is identical to the md_atof in m68k.c.  I think this is right,
740   but I'm not sure.
741
742   Turn a string in input_line_pointer into a floating point constant of type
743   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
744   emitted is stored in *sizeP. An error message is returned, or NULL on OK.
745   */
746
747 /* Equal to MAX_PRECISION in atof-ieee.c */
748 #define MAX_LITTLENUMS 6
749
750 char *
751     md_atof(type,litP,sizeP)
752 char type;
753 char *litP;
754 int *sizeP;
755 {
756         int     prec;
757         LITTLENUM_TYPE words[MAX_LITTLENUMS];
758         LITTLENUM_TYPE *wordP;
759         char    *t;
760         char    *atof_ieee();
761
762         switch (type) {
763
764         case 'f':
765         case 'F':
766         case 's':
767         case 'S':
768                 prec = 2;
769                 break;
770
771         case 'd':
772         case 'D':
773         case 'r':
774         case 'R':
775                 prec = 4;
776                 break;
777
778         case 'x':
779         case 'X':
780                 prec = 6;
781                 break;
782
783         case 'p':
784         case 'P':
785                 prec = 6;
786                 break;
787
788         default:
789                 *sizeP=0;
790                 return "Bad call to MD_ATOF()";
791         }
792         t=atof_ieee(input_line_pointer,type,words);
793         if (t)
794             input_line_pointer=t;
795         *sizeP=prec * sizeof(LITTLENUM_TYPE);
796         for (wordP=words;prec--;) {
797                 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
798                 litP+=sizeof(LITTLENUM_TYPE);
799         }
800         return "";      /* Someone should teach Dean about null pointers */
801 }
802
803 /*
804  * Write out big-endian.
805  */
806 void
807     md_number_to_chars(buf, val, n)
808 char *buf;
809 long val;
810 int n;
811 {
812         switch (n) {
813
814         case 4:
815                 *buf++ = val >> 24;
816                 *buf++ = val >> 16;
817         case 2:
818                 *buf++ = val >> 8;
819         case 1:
820                 *buf = val;
821                 break;
822
823         default:
824                 as_fatal("failed sanity check.");
825         }
826         return;
827 }
828
829 void md_number_to_imm(buf, val, n, fixP)
830 char *buf;
831 long val;
832 int n;
833 fixS *fixP;
834 {
835         enum reloc_type reloc = fixP->fx_r_type & 0xf;
836         enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3;
837
838         assert(buf);
839         assert(n == 4); /* always on i860 */
840
841         switch (highlow) {
842
843         case HIGHADJ:   /* adjusts the high-order 16-bits */
844                 if (val & (1 << 15))
845                     val += (1 << 16);
846
847                 /*FALLTHROUGH*/
848
849         case HIGH:      /* selects the high-order 16-bits */
850                 val >>= 16;
851                 break;
852
853         case PAIR:      /* selects the low-order 16-bits */
854                 val = val & 0xffff;
855                 break;
856
857         default:
858                 break;
859         }
860
861         switch (reloc) {
862
863         case BRADDR:    /* br, call, bc, bc.t, bnc, bnc.t w/26-bit immediate */
864                 if (fixP->fx_pcrel != 1)
865                     as_bad("26-bit branch w/o pc relative set: 0x%08x", val);
866                 val >>= 2;      /* align pcrel offset, see manual */
867
868                 if (val >= (1 << 25) || val < -(1 << 25))       /* check for overflow */
869                     as_bad("26-bit branch offset overflow: 0x%08x", val);
870                 buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3);
871                 buf[1] = val >> 16;
872                 buf[2] = val >> 8;
873                 buf[3] = val;
874                 break;
875
876         case SPLIT2:    /* 16 bit immediate, 4-byte aligned */
877                 if (val & 0x3)
878                     as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val);
879                 val &= ~0x3;    /* 4-byte align value */
880                 /*FALLTHROUGH*/
881         case SPLIT1:    /* 16 bit immediate, 2-byte aligned */
882                 if (val & 0x1)
883                     as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val);
884                 val &= ~0x1;    /* 2-byte align value */
885                 /*FALLTHROUGH*/
886         case SPLIT0:    /* st,bla,bte,btne w/16-bit immediate */
887                 if (fixP->fx_pcrel == 1)
888                     val >>= 2;  /* align pcrel offset, see manual */
889                 /* check for bounds */
890                 if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
891                     as_bad("16-bit branch offset overflow: 0x%08x", val);
892                 buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f);
893                 buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7);
894                 buf[3] |= val;  /* perserve bottom opcode bits */
895                 break;
896
897         case LOW4:      /* fld,pfld,pst,flush 16-byte aligned */
898                 if (val & 0xf)
899                     as_bad("16-bit immediate 16-byte alignment error: 0x%08x", val);
900                 val &= ~0xf;    /* 16-byte align value */
901                 /*FALLTHROUGH*/
902         case LOW3:      /* fld,pfld,pst,flush 8-byte aligned */
903                 if (val & 0x7)
904                     as_bad("16-bit immediate 8-byte alignment error: 0x%08x", val);
905                 val &= ~0x7;    /* 8-byte align value */
906                 /*FALLTHROUGH*/
907         case LOW2:      /* 16 bit immediate, 4-byte aligned */
908                 if (val & 0x3)
909                     as_bad("16-bit immediate 4-byte alignment error: 0x%08x", val);
910                 val &= ~0x3;    /* 4-byte align value */
911                 /*FALLTHROUGH*/
912         case LOW1:      /* 16 bit immediate, 2-byte aligned */
913                 if (val & 0x1)
914                     as_bad("16-bit immediate 2-byte alignment error: 0x%08x", val);
915                 val &= ~0x1;    /* 2-byte align value */
916                 /*FALLTHROUGH*/
917         case LOW0:      /* 16 bit immediate, byte aligned */
918                 /* check for bounds */
919                 if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))
920                     as_bad("16-bit immediate overflow: 0x%08x", val);
921                 buf[2] = val >> 8;
922                 buf[3] |= val;  /* perserve bottom opcode bits */
923                 break;
924
925         case RELOC_32:
926                 md_number_to_chars(buf, val, 4);
927                 break;
928
929         case NO_RELOC:
930         default:
931                 as_bad("bad relocation type: 0x%02x", reloc);
932                 break;
933         }
934         return;
935 }
936
937 /* should never be called for i860 */
938 void
939     md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
940 char *ptr;
941 long from_addr, to_addr;
942 fragS *frag;
943 symbolS *to_symbol;
944 {
945         as_fatal("i860_create_short_jmp\n");
946 }
947
948 /* should never be called for i860 */
949 void
950     md_number_to_disp(buf, val, n)
951 char *buf;
952 long val;
953 int n;
954 {
955         as_fatal("md_number_to_disp\n");
956 }
957
958 /* should never be called for i860 */
959 void
960     md_number_to_field(buf,val,fix)
961 char *buf;
962 long val;
963 void *fix;
964 {
965         as_fatal("i860_number_to_field\n");
966 }
967
968 /* the bit-field entries in the relocation_info struct plays hell
969    with the byte-order problems of cross-assembly.  So as a hack,
970    I added this mach. dependent ri twiddler.  Ugly, but it gets
971    you there. -KWK */
972 /* on i860: first 4 bytes are normal unsigned long address, next three
973    bytes are index, most sig. byte first.  Byte 7 is broken up with
974    bit 7 as pcrel, bit 6 as extern, and the lower six bits as
975    relocation type (highlow 5-4).  Next 4 bytes are long addend. */
976 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
977 void
978     md_ri_to_chars(ri_p, ri)
979 struct relocation_info *ri_p, ri;
980 {
981 #if 0
982         unsigned char the_bytes[sizeof(*ri_p)];
983
984         /* this is easy */
985         md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));
986         /* now the fun stuff */
987         the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
988         the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
989         the_bytes[6] = ri.r_index & 0x0ff;
990         the_bytes[7] = ((ri.r_extern << 7)  & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
991         /* Also easy */
992         md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend));
993         /* now put it back where you found it, Junior... */
994         memcpy((char *) ri_p, the_bytes, sizeof(*ri_p));
995 #endif
996 }
997
998 /* should never be called for i860 */
999 void
1000     md_convert_frag(headers, fragP)
1001 object_headers *headers;
1002 register fragS *fragP;
1003 {
1004         as_fatal("i860_convert_frag\n");
1005 }
1006
1007 /* should never be called for i860 */
1008 void
1009     md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
1010 char    *ptr;
1011 long    from_addr,
1012     to_addr;
1013 fragS   *frag;
1014 symbolS *to_symbol;
1015 {
1016         as_fatal("i860_create_long_jump\n");
1017 }
1018
1019 /* should never be called for i860 */
1020 int
1021     md_estimate_size_before_relax(fragP, segtype)
1022 register fragS *fragP;
1023 segT segtype;
1024 {
1025         as_fatal("i860_estimate_size_before_relax\n");
1026         return(0);
1027 }
1028
1029 #ifdef comment
1030 /* for debugging only, must match enum reloc_type */
1031 static char *Reloc[] = {
1032         "NO_RELOC",
1033         "BRADDR",
1034         "LOW0",
1035         "LOW1",
1036         "LOW2",
1037         "LOW3",
1038         "LOW4",
1039         "SPLIT0",
1040         "SPLIT1",
1041         "SPLIT2",
1042         "RELOC_32",
1043 };
1044 static char *Highlow[] = {
1045         "NO_SPEC",
1046         "PAIR",
1047         "HIGH",
1048         "HIGHADJ",
1049 };
1050
1051 static void
1052     print_insn(insn)
1053 struct i860_it *insn;
1054 {
1055         if (insn->error) {
1056                 fprintf(stderr, "ERROR: %s\n", insn->error);
1057         }
1058         fprintf(stderr, "opcode=0x%08x\t", insn->opcode);
1059         fprintf(stderr, "expand=0x%08x\t", insn->expand);
1060         fprintf(stderr, "reloc = %s\t", Reloc[insn->reloc]);
1061         fprintf(stderr, "highlow = %s\n", Highlow[insn->highlow]);
1062         fprintf(stderr, "exp =  {\n");
1063         fprintf(stderr, "\t\tX_add_symbol = %s\n",
1064                 insn->exp.X_add_symbol ?
1065                 (S_GET_NAME(insn->exp.X_add_symbol) ?
1066                  S_GET_NAME(insn->exp.X_add_symbol) : "???") : "0");
1067         fprintf(stderr, "\t\tX_sub_symbol = %s\n",
1068                 insn->exp.X_subtract_symbol ?
1069                 (S_GET_NAME(insn->exp.X_subtract_symbol) ?
1070                  S_GET_NAME(insn->exp.X_subtract_symbol) : "???") : "0");
1071         fprintf(stderr, "\t\tX_add_number = %d\n",
1072                 insn->exp.X_add_number);
1073         fprintf(stderr, "}\n");
1074         return;
1075 }
1076 #endif /* comment */
1077
1078 int
1079     md_parse_option(argP,cntP,vecP)
1080 char **argP;
1081 int *cntP;
1082 char ***vecP;
1083 {
1084         return 0;
1085 }
1086
1087 #ifdef comment
1088 /*
1089  * I860 relocations are completely different, so it needs
1090  * this machine dependent routine to emit them.
1091  */
1092 void
1093     emit_machine_reloc(fixP, segment_address_in_file)
1094 register fixS *fixP;
1095 relax_addressT segment_address_in_file;
1096 {
1097         struct reloc_info_i860 ri;
1098         register symbolS *symbolP;
1099         extern char *next_object_file_charP;
1100         long add_number;
1101
1102         memset((char *) &ri, '\0', sizeof(ri));
1103         for (; fixP; fixP = fixP->fx_next) {
1104
1105                 if (fixP->fx_r_type & ~0x3f) {
1106                         as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type);
1107                 }
1108                 ri.r_pcrel = fixP->fx_pcrel;
1109                 ri.r_type = fixP->fx_r_type;
1110
1111                 if ((symbolP = fixP->fx_addsy) != NULL) {
1112                         ri.r_address = fixP->fx_frag->fr_address +
1113                             fixP->fx_where - segment_address_in_file;
1114                         if (!S_IS_DEFINED(symbolP)) {
1115                                 ri.r_extern = 1;
1116                                 ri.r_symbolnum = symbolP->sy_number;
1117                         } else {
1118                                 ri.r_extern = 0;
1119                                 ri.r_symbolnum = S_GET_TYPE(symbolP);
1120                         }
1121                         if (symbolP && symbolP->sy_frag) {
1122                                 ri.r_addend = symbolP->sy_frag->fr_address;
1123                         }
1124                         ri.r_type = fixP->fx_r_type;
1125                         if (fixP->fx_pcrel) {
1126                                 /* preserve actual offset vs. pc + 4 */
1127                                 ri.r_addend -= (ri.r_address + 4);
1128                         } else {
1129                                 ri.r_addend = fixP->fx_addnumber;
1130                         }
1131
1132                         md_ri_to_chars((char *) &ri, ri);
1133                         append(&next_object_file_charP, (char *)& ri, sizeof(ri));
1134                 }
1135         }
1136         return;
1137 }
1138 #endif /* comment */
1139
1140 #ifdef OBJ_AOUT
1141
1142 /* on i860: first 4 bytes are normal unsigned long address, next three
1143    bytes are index, most sig. byte first.  Byte 7 is broken up with
1144    bit 7 as pcrel, bit 6 as extern, and the lower six bits as
1145    relocation type (highlow 5-4).  Next 4 bytes are long addend.
1146
1147    ie,
1148
1149    struct reloc_info_i860 {
1150        unsigned long r_address;
1151        unsigned int r_symbolnum : 24;
1152        unsigned int r_pcrel : 1;
1153        unsigned int r_extern : 1;
1154        unsigned int r_type : 6;
1155        long r_addend;
1156    }
1157
1158  */
1159
1160 const int md_reloc_size = 12;
1161
1162 void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1163 char *where;
1164 fixS *fixP;
1165 relax_addressT segment_address_in_file;
1166 {
1167         long r_index;
1168         long r_extern;
1169         long r_addend = 0;
1170         long r_address;
1171
1172         know(fixP->fx_addsy);
1173         know(!(fixP->fx_r_type & ~0x3f));
1174
1175         if (!S_IS_DEFINED(fixP->fx_addsy)) {
1176                 r_extern = 1;
1177                 r_index = fixP->fx_addsy->sy_number;
1178         } else {
1179                 r_extern = 0;
1180                 r_index = S_GET_TYPE(fixP->fx_addsy);
1181         }
1182
1183         md_number_to_chars(where,
1184                            r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1185                            4);
1186
1187         where[4] = (r_index >> 16) & 0x0ff;
1188         where[5] = (r_index >> 8) & 0x0ff;
1189         where[6] = r_index & 0x0ff;
1190         where[7] = (((fixP->fx_pcrel << 7) & 0x80)
1191                     | ((r_extern << 6)  & 0x40)
1192                     | (fixP->fx_r_type & 0x3F));
1193
1194         if (fixP->fx_addsy->sy_frag) {
1195                 r_addend = fixP->fx_addsy->sy_frag->fr_address;
1196         }
1197
1198         if (fixP->fx_pcrel) {
1199                 /* preserve actual offset vs. pc + 4 */
1200                 r_addend -= (r_address + 4);
1201         } else {
1202                 r_addend = fixP->fx_addnumber;
1203         }
1204
1205         md_number_to_chars(&where[8], r_addend, 4);
1206
1207         return;
1208 } /* tc_aout_fix_to_chars() */
1209
1210 #endif /* OBJ_AOUT */
1211
1212 /* Parse an operand that is machine-specific.
1213    We just return without modifying the expression if we have nothing
1214    to do.  */
1215
1216 /* ARGSUSED */
1217 void
1218     md_operand (expressionP)
1219 expressionS *expressionP;
1220 {
1221 }
1222
1223 /* We have no need to default values of symbols.  */
1224
1225 /* ARGSUSED */
1226 symbolS *
1227     md_undefined_symbol (name)
1228 char *name;
1229 {
1230         return 0;
1231 }
1232
1233 /* Round up a section size to the appropriate boundary.  */
1234 long
1235     md_section_align (segment, size)
1236 segT segment;
1237 long size;
1238 {
1239         return size;            /* Byte alignment is fine */
1240 }
1241
1242 /* Exactly what point is a PC-relative offset relative TO?
1243    On the i860, they're relative to the address of the offset, plus
1244    its size. (??? Is this right?  FIXME-SOON!) */
1245 long
1246     md_pcrel_from (fixP)
1247 fixS *fixP;
1248 {
1249         return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1250 }
1251
1252 void
1253     md_apply_fix(fixP, val)
1254 fixS *fixP;
1255 long val;
1256 {
1257         char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
1258
1259         /* fixme-soon: looks to me like i860 never has bit fixes. Let's see. xoxorich. */
1260         know(fixP->fx_bit_fixP == NULL);
1261         if (!fixP->fx_bit_fixP) {
1262
1263                 /* fixme-soon: also looks like fx_im_disp is always 0.  Let's see.  xoxorich. */
1264                 know(fixP->fx_im_disp == 0);
1265                 switch (fixP->fx_im_disp) {
1266                 case 0:
1267                         fixP->fx_addnumber = val;
1268                         md_number_to_imm(place, val, fixP->fx_size, fixP);
1269                         break;
1270                 case 1:
1271                         md_number_to_disp(place,
1272                                            fixP->fx_pcrel ? val + fixP->fx_pcrel_adjust : val,
1273                                            fixP->fx_size);
1274                         break;
1275                 case 2: /* fix requested for .long .word etc */
1276                         md_number_to_chars(place, val, fixP->fx_size);
1277                         break;
1278                 default:
1279                         as_fatal("Internal error in md_apply_fix() in file \"%s\"", __FILE__);
1280                 } /* OVE: maybe one ought to put _imm _disp _chars in one md-func */
1281         } else {
1282                 md_number_to_field(place, val, fixP->fx_bit_fixP);
1283         }
1284
1285         return;
1286 } /* md_apply_fix() */
1287
1288 /*
1289  * Local Variables:
1290  * fill-column: 131
1291  * comment-column: 0
1292  * End:
1293  */
1294
1295 /* end of tc-i860.c */