Tue Aug 19 08:59:12 1997 Fred Fish <fnf@cygnus.com>
[deliverable/binutils-gdb.git] / gas / config / tc-tic80.c
CommitLineData
64556643 1/* tc-tic80.c -- Assemble for the TI TMS320C80 (MV)
414a1069 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
64556643
FF
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 the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21#include "as.h"
22#include "opcode/tic80.h"
23
11e08196
FF
24#define internal_error(what) \
25 as_fatal("internal error:%s:%d: %s\n",__FILE__,__LINE__,what)
26#define internal_error_a(what,arg) \
27 as_fatal("internal error:%s:%d: %s %d\n",__FILE__,__LINE__,what,arg)
28
64556643
FF
29\f
30/* Generic assembler global variables which must be defined by all targets. */
31
32/* Characters which always start a comment. */
33const char comment_chars[] = ";";
34
35/* Characters which start a comment at the beginning of a line. */
64251de5 36const char line_comment_chars[] = ";*#";
64556643 37
16171d71
FF
38/* Characters which may be used to separate multiple commands on a single
39 line. The semicolon is such a character by default and should not be
40 explicitly listed. */
11e08196 41const char line_separator_chars[] = "";
64556643
FF
42
43/* Characters which are used to indicate an exponent in a floating
44 point number. */
45const char EXP_CHARS[] = "eE";
46
47/* Characters which mean that a number is a floating point constant,
1e12595d
FF
48 as in 0f1.0. */
49const char FLT_CHARS[] = "fF";
64556643 50
f1ce6af4
FF
51/* This table describes all the machine specific pseudo-ops the assembler
52 has to support. The fields are:
16171d71 53
f1ce6af4
FF
54 pseudo-op name without dot
55 function to call to execute this pseudo-op
16171d71 56 integer arg to pass to the function */
f1ce6af4 57
1ea52646
FF
58extern void obj_coff_section ();
59
f1ce6af4
FF
60const pseudo_typeS md_pseudo_table[] =
61{
1ea52646
FF
62 { "align", s_align_bytes, 4 }, /* Do byte alignment, default is a 4 byte boundary */
63 { "word", cons, 4 }, /* FIXME: Should this be machine independent? */
015b3352 64 { "bss", s_lcomm_bytes, 1 },
1ea52646
FF
65 { "sect", obj_coff_section, 0}, /* For compatibility with TI tools */
66 { "section", obj_coff_section, 0}, /* Standard COFF .section pseudo-op */
67 { NULL, NULL, 0 }
f1ce6af4
FF
68};
69
70/* Opcode hash table. */
71static struct hash_control *tic80_hash;
72
73static struct tic80_opcode * find_opcode PARAMS ((struct tic80_opcode *, expressionS []));
11e08196 74static void build_insn PARAMS ((struct tic80_opcode *, expressionS *));
f1ce6af4 75static int get_operands PARAMS ((expressionS exp[]));
11e08196 76static int const_overflow PARAMS ((unsigned long num, int bits, int flags));
f1ce6af4 77
64556643 78\f
f1ce6af4
FF
79int
80md_estimate_size_before_relax (fragP, segment_type)
81 fragS *fragP;
82 segT segment_type;
83{
11e08196 84 internal_error ("Relaxation is a luxury we can't afford");
f1ce6af4
FF
85 return (-1);
86}
87
88/* We have no need to default values of symbols. */
89
90/* ARGSUSED */
91symbolS *
92md_undefined_symbol (name)
93 char *name;
94{
95 return 0;
96}
97
98/* Turn a string in input_line_pointer into a floating point constant of type
99 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
100 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
101 */
102
103#define MAX_LITTLENUMS 4
104
105char *
106md_atof (type, litP, sizeP)
107 int type;
108 char *litP;
109 int *sizeP;
110{
111 int prec;
112 LITTLENUM_TYPE words[MAX_LITTLENUMS];
113 LITTLENUM_TYPE *wordP;
114 char *t;
115 char *atof_ieee ();
116
117 switch (type)
118 {
119 case 'f':
120 case 'F':
121 case 's':
122 case 'S':
123 prec = 2;
124 break;
125
126 case 'd':
127 case 'D':
128 case 'r':
129 case 'R':
130 prec = 4;
131 break;
132
133 default:
134 *sizeP = 0;
135 return "bad call to md_atof ()";
136 }
137
138 t = atof_ieee (input_line_pointer, type, words);
139 if (t)
140 {
141 input_line_pointer = t;
142 }
143
144 *sizeP = prec * sizeof (LITTLENUM_TYPE);
145
146 for (wordP = words; prec--;)
147 {
148 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
149 litP += sizeof (LITTLENUM_TYPE);
150 }
151 return (NULL);
152}
153
11e08196
FF
154/* Check to see if the constant value in NUM will fit in a field of
155 width BITS if it has flags FLAGS. */
156
157static int
158const_overflow (num, bits, flags)
159 unsigned long num;
160 int bits;
161 int flags;
162{
163 long min, max;
164 int retval = 0;
165
166 /* Only need to check fields less than 32 bits wide */
167 if (bits < 32)
168 if (flags & TIC80_OPERAND_SIGNED)
169 {
170 max = (1 << (bits - 1)) - 1;
171 min = - (1 << (bits - 1));
172 retval = ((long) num > max) || ((long) num < min);
173 }
174 else
175 {
176 max = (1 << bits) - 1;
177 min = 0;
178 retval = (num > max) || (num < min);
179 }
180 return (retval);
181}
182
f1ce6af4
FF
183/* get_operands() parses a string of operands and fills in a passed array of
184 expressions in EXP.
185
186 Note that we use O_absent expressions to record additional information
187 about the previous non-O_absent expression, such as ":m" or ":s"
188 modifiers or register numbers enclosed in parens like "(r10)".
189
190 Returns the number of expressions that were placed in EXP.
191
192 */
193
194static int
195get_operands (exp)
196 expressionS exp[];
197{
198 char *p = input_line_pointer;
199 int numexp = 0;
200 int mflag = 0;
201 int sflag = 0;
202 int parens = 0;
203
204 while (*p)
205 {
206 /* Skip leading whitespace */
207 while (*p == ' ' || *p == '\t' || *p == ',')
208 {
209 p++;
210 }
211
212 /* Check to see if we have any operands left to parse */
213 if (*p == 0 || *p == '\n' || *p == '\r')
214 {
215 break;
216 }
217
218 /* Notice scaling or direct memory operand modifiers and save them in
219 an O_absent expression after the expression that they modify. */
220
221 if (*p == ':')
222 {
223 p++;
224 exp[numexp].X_op = O_absent;
225 if (*p == 'm')
226 {
227 p++;
f92f247b 228 /* This is a ":m" modifier */
f1ce6af4
FF
229 exp[numexp].X_add_number = TIC80_OPERAND_M_SI | TIC80_OPERAND_M_LI;
230 }
231 else if (*p == 's')
232 {
233 p++;
f92f247b 234 /* This is a ":s" modifier */
f1ce6af4
FF
235 exp[numexp].X_add_number = TIC80_OPERAND_SCALED;
236 }
237 else
238 {
239 as_bad ("':' not followed by 'm' or 's'");
240 }
241 numexp++;
242 continue;
243 }
244
245 /* Handle leading '(' on operands that use them, by recording that we
246 have entered a paren nesting level and then continuing. We complain
247 about multiple nesting. */
248
249 if (*p == '(')
250 {
251 if (++parens != 1)
252 {
253 as_bad ("paren nesting");
254 }
255 p++;
256 continue;
257 }
258
259 /* Handle trailing ')' on operands that use them, by reducing the
260 nesting level and then continuing. We complain if there were too
261 many closures. */
262
263 if (*p == ')')
264 {
265 /* Record that we have left a paren group and continue */
266 if (--parens < 0)
267 {
268 as_bad ("mismatched parenthesis");
269 }
270 p++;
271 continue;
272 }
273
274 /* Begin operand parsing at the current scan point. */
275
276 input_line_pointer = p;
16171d71 277 expression (&exp[numexp]);
f1ce6af4
FF
278
279 if (exp[numexp].X_op == O_illegal)
280 {
281 as_bad ("illegal operand");
282 }
283 else if (exp[numexp].X_op == O_absent)
284 {
285 as_bad ("missing operand");
286 }
287
288 numexp++;
289 p = input_line_pointer;
290 }
291
292 if (parens)
293 {
294 exp[numexp].X_op = O_absent;
295 exp[numexp++].X_add_number = TIC80_OPERAND_PARENS;
296 }
297
11e08196
FF
298 /* Mark the end of the valid operands with an illegal expression. */
299 exp[numexp].X_op = O_illegal;
300
f1ce6af4
FF
301 return (numexp);
302}
303
304/* find_opcode() gets a pointer to the entry in the opcode table that
305 matches the instruction being assembled, or returns NULL if no such match
306 is found.
307
308 First it parses all the operands and save them as expressions. Note that
309 we use O_absent expressions to record additional information about the
310 previous non-O_absent expression, such as ":m" or ":s" modifiers or
311 register numbers enclosed in parens like "(r10)".
312
11e08196 313 It then looks at all opcodes with the same name and uses the operands to
f1ce6af4
FF
314 choose the correct opcode. */
315
f1ce6af4
FF
316static struct tic80_opcode *
317find_opcode (opcode, myops)
318 struct tic80_opcode *opcode;
319 expressionS myops[];
320{
11e08196
FF
321 int numexp; /* Number of expressions from parsing operands */
322 int expi; /* Index of current expression to match */
323 int opi; /* Index of current operand to match */
324 int match = 0; /* Set to 1 when an operand match is found */
325 struct tic80_opcode *opc = opcode; /* Pointer to current opcode table entry */
326 const struct tic80_opcode *end; /* Pointer to end of opcode table */
327
328 /* First parse all the operands so we only have to do it once. There may
329 be more expressions generated than there are operands. */
330
331 numexp = get_operands (myops);
332
333 /* For each opcode with the same name, try to match it against the parsed
334 operands. */
335
336 end = tic80_opcodes + tic80_num_opcodes;
337 while (!match && (opc < end) && (strcmp (opc -> name, opcode -> name) == 0))
338 {
339 /* Start off assuming a match. If we find a mismatch, then this is
340 reset and the operand/expr matching loop terminates with match
341 equal to zero, which allows us to try the next opcode. */
342
343 match = 1;
344
345 /* For each expression, try to match it against the current operand
346 for the current opcode. Upon any mismatch, we abandon further
347 matching for the current opcode table entry. */
f1ce6af4 348
11e08196
FF
349 for (expi = 0, opi = -1; (expi < numexp) && match; expi++)
350 {
351 int bits, flags, X_op, num;
f1ce6af4 352
11e08196
FF
353 X_op = myops[expi].X_op;
354 num = myops[expi].X_add_number;
f92f247b
FF
355
356 /* The O_absent expressions apply to the same operand as the most
357 recent non O_absent expression. So only increment the operand
358 index when the current expression is not one of these special
359 expressions. */
360
11e08196
FF
361 if (X_op != O_absent)
362 {
11e08196
FF
363 opi++;
364 }
f92f247b 365
11e08196
FF
366 flags = tic80_operands[opc -> operands[opi]].flags;
367 bits = tic80_operands[opc -> operands[opi]].bits;
f1ce6af4 368
11e08196
FF
369 switch (X_op)
370 {
371 case O_register:
372 /* Also check that registers that are supposed to be even actually
373 are even. */
374 if (((flags & TIC80_OPERAND_GPR) != (num & TIC80_OPERAND_GPR)) ||
375 ((flags & TIC80_OPERAND_FPA) != (num & TIC80_OPERAND_FPA)) ||
376 ((flags & TIC80_OPERAND_CR) != (num & TIC80_OPERAND_CR)) ||
377 ((flags & TIC80_OPERAND_EVEN) && (num & 1)) ||
378 const_overflow (num & ~TIC80_OPERAND_MASK, bits, flags))
379 {
380 match = 0;
381 }
382 break;
383 case O_constant:
384 if ((flags & TIC80_OPERAND_ENDMASK) && (num == 32))
385 {
386 /* Endmask values of 0 and 32 give identical results */
387 num = 0;
388 }
389 if ((flags & (TIC80_OPERAND_FPA | TIC80_OPERAND_GPR)) ||
390 const_overflow (num, bits, flags))
391 {
392 match = 0;
393 }
394 break;
d160b69e
FF
395 case O_symbol:
396 if ((bits < 32) && (flags & TIC80_OPERAND_PCREL))
397 {
398 /* For now we only allow PC relative relocations in the
399 short immediate fields, like the TI assembler.
400 FIXME: Should be able to choose "best-fit". */
401 }
ec72a266 402 else if ((bits == 32) /* && (flags & TIC80_OPERAND_BASEREL) */)
d160b69e
FF
403 {
404 /* For now we only allow base relative relocations in
405 the long immediate fields, like the TI assembler.
406 FIXME: Should be able to choose "best-fit". */
407 }
408 else
409 {
410 /* Symbols that don't match one of the above cases are
411 rejected as an operand. */
412 match = 0;
413 }
414 break;
11e08196 415 case O_absent:
f92f247b
FF
416 /* If this is an O_absent expression, then it may be an expression that
417 supplies additional information about the operand, such as ":m" or
418 ":s" modifiers. Check to see that the operand matches this requirement. */
419 if (!((num & TIC80_OPERAND_M_SI) && (flags & TIC80_OPERAND_M_SI) ||
420 (num & TIC80_OPERAND_M_LI) && (flags & TIC80_OPERAND_M_LI) ||
421 (num & TIC80_OPERAND_SCALED) && (flags & TIC80_OPERAND_SCALED)))
422 {
423 match = 0;
424 }
425 break;
1e12595d
FF
426 case O_big:
427 if ((num > 0) || !(flags & TIC80_OPERAND_FLOAT))
428 {
429 match = 0;
430 }
431 break;
f92f247b 432 case O_illegal:
11e08196 433 case O_symbol_rva:
11e08196
FF
434 case O_uminus:
435 case O_bit_not:
436 case O_logical_not:
437 case O_multiply:
438 case O_divide:
439 case O_modulus:
440 case O_left_shift:
441 case O_right_shift:
442 case O_bit_inclusive_or:
443 case O_bit_or_not:
444 case O_bit_exclusive_or:
445 case O_bit_and:
446 case O_add:
447 case O_subtract:
448 case O_eq:
449 case O_ne:
450 case O_lt:
451 case O_le:
452 case O_ge:
453 case O_gt:
454 case O_logical_and:
455 case O_logical_or:
456 case O_max:
457 default:
458 internal_error_a ("unhandled expression type", X_op);
459 }
460 }
461 if (!match)
462 {
463 opc++;
464 }
465 }
466
467 return (match ? opc : NULL);
468
469#if 0
f1ce6af4
FF
470
471 /* Now search the opcode table table for one with operands that
472 matches what we've got. */
473
474 while (!match)
475 {
476 match = 1;
477 for (i = 0; opcode -> operands[i]; i++)
478 {
479 int flags = tic80_operands[opcode->operands[i]].flags;
480 int X_op = myops[i].X_op;
481 int num = myops[i].X_add_number;
482
483 if (X_op == 0)
484 {
485 match = 0;
486 break;
487 }
488
11e08196 489 if (flags & (TIC80_OPERAND_GPR | TIC80_OPERAND_FPA | TIC80_OPERAND_CR))
f1ce6af4
FF
490 {
491 if ((X_op != O_register) ||
11e08196
FF
492 ((flags & TIC80_OPERAND_GPR) != (num & TIC80_OPERAND_GPR)) ||
493 ((flags & TIC80_OPERAND_FPA) != (num & TIC80_OPERAND_FPA)) ||
494 ((flags & TIC80_OPERAND_CR) != (num & TIC80_OPERAND_CR)))
f1ce6af4
FF
495 {
496 match=0;
497 break;
498 }
499 }
500
11e08196
FF
501 if (((flags & TIC80_OPERAND_MINUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_MINUS))) ||
502 ((flags & TIC80_OPERAND_PLUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_PLUS))) ||
503 ((flags & TIC80_OPERAND_ATMINUS) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATMINUS))) ||
504 ((flags & TIC80_OPERAND_ATPAR) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATPAR))) ||
505 ((flags & TIC80_OPERAND_ATSIGN) && ((X_op != O_absent) || (num != TIC80_OPERAND_ATSIGN))))
f1ce6af4
FF
506 {
507 match=0;
508 break;
509 }
510 }
511 /* we're only done if the operands matched so far AND there
512 are no more to check */
513 if (match && myops[i].X_op==0)
514 break;
515 else
516 match = 0;
517
518 next_opcode = opcode+1;
519 if (next_opcode->opcode == 0)
520 break;
521 if (strcmp(next_opcode->name, opcode->name))
522 break;
523 opcode = next_opcode;
524 }
525
526 if (!match)
527 {
528 as_bad ("bad opcode or operands");
529 return (0);
530 }
531
532 /* Check that all registers that are required to be even are. */
533 /* Also, if any operands were marked as registers, but were really symbols */
534 /* fix that here. */
535 for (i=0; opcode->operands[i]; i++)
536 {
11e08196 537 if ((tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_EVEN) &&
f1ce6af4 538 (myops[i].X_add_number & 1))
11e08196 539 as_fatal ("Register number must be EVEN");
f1ce6af4
FF
540 if (myops[i].X_op == O_register)
541 {
11e08196 542 if (!(tic80_operands[opcode->operands[i]].flags & TIC80_OPERAND_REG))
f1ce6af4
FF
543 {
544 myops[i].X_op = O_symbol;
545 myops[i].X_add_symbol = symbol_find_or_make ((char *)myops[i].X_op_symbol);
546 myops[i].X_add_number = 0;
547 myops[i].X_op_symbol = NULL;
548 }
549 }
550 }
11e08196
FF
551
552#endif
f1ce6af4
FF
553}
554
555/* build_insn takes a pointer to the opcode entry in the opcode table
e6e676a5
FF
556 and the array of operand expressions and writes out the instruction.
557
558 Note that the opcode word and extended word may be written to different
559 frags, with the opcode at the end of one frag and the extension at the
560 beginning of the next. */
f1ce6af4 561
11e08196
FF
562static void
563build_insn (opcode, opers)
f1ce6af4
FF
564 struct tic80_opcode *opcode;
565 expressionS *opers;
f1ce6af4 566{
11e08196
FF
567 int expi; /* Index of current expression to match */
568 int opi; /* Index of current operand to match */
569 unsigned long insn[2]; /* Instruction and long immediate (if any) */
e6e676a5
FF
570 char *f; /* Pointer to frag location for insn[0] */
571 fragS *ffrag; /* Frag containing location f */
572 char *fx = NULL; /* Pointer to frag location for insn[1] */
573 fragS *fxfrag; /* Frag containing location fx */
11e08196
FF
574
575 /* Start with the raw opcode bits from the opcode table. */
576 insn[0] = opcode -> opcode;
577
d160b69e
FF
578 /* We are going to insert at least one 32 bit opcode so get the
579 frag now. */
580
581 f = frag_more (4);
e6e676a5 582 ffrag = frag_now;
d160b69e 583
11e08196
FF
584 /* For each operand expression, insert the appropriate bits into the
585 instruction . */
586 for (expi = 0, opi = -1; opers[expi].X_op != O_illegal; expi++)
587 {
588 int bits, shift, flags, X_op, num;
589
590 X_op = opers[expi].X_op;
591 num = opers[expi].X_add_number;
f92f247b
FF
592
593 /* The O_absent expressions apply to the same operand as the most
594 recent non O_absent expression. So only increment the operand
595 index when the current expression is not one of these special
596 expressions. */
597
11e08196
FF
598 if (X_op != O_absent)
599 {
11e08196
FF
600 opi++;
601 }
f92f247b 602
11e08196
FF
603 flags = tic80_operands[opcode -> operands[opi]].flags;
604 bits = tic80_operands[opcode -> operands[opi]].bits;
605 shift = tic80_operands[opcode -> operands[opi]].shift;
606
607 switch (X_op)
608 {
609 case O_register:
610 num &= ~TIC80_OPERAND_MASK;
611 insn[0] = insn[0] | (num << shift);
612 break;
613 case O_constant:
614 if ((flags & TIC80_OPERAND_ENDMASK) && (num == 32))
615 {
616 /* Endmask values of 0 and 32 give identical results */
617 num = 0;
618 }
d160b69e
FF
619 else if ((flags & TIC80_OPERAND_BITNUM))
620 {
621 /* BITNUM values are stored in one's complement form */
622 num = (~num & 0x1F);
623 }
11e08196
FF
624 /* Mask off upper bits, just it case it is signed and is negative */
625 if (bits < 32)
626 {
627 num &= (1 << bits) - 1;
628 insn[0] = insn[0] | (num << shift);
629 }
630 else
631 {
e6e676a5
FF
632 fx = frag_more (4);
633 fxfrag = frag_now;
11e08196
FF
634 insn[1] = num;
635 }
636 break;
d160b69e
FF
637 case O_symbol:
638 if (flags & TIC80_OPERAND_PCREL)
639 {
e6e676a5
FF
640 fix_new_exp (ffrag,
641 f - (ffrag -> fr_literal),
d160b69e
FF
642 4, /* FIXME! how is this used? */
643 &opers[expi],
644 1,
645 R_MPPCR);
646 }
ec72a266 647 else if (bits == 32) /* was (flags & TIC80_OPERAND_BASEREL) */
d160b69e 648 {
e6e676a5
FF
649 fx = frag_more (4);
650 fxfrag = frag_now;
e53430c4 651 insn[1] = 0;
e6e676a5
FF
652 fix_new_exp (fxfrag,
653 fx - (fxfrag -> fr_literal),
d160b69e
FF
654 4,
655 &opers[expi],
ec72a266
FF
656 0,
657 R_RELLONGX);
d160b69e
FF
658 }
659 else
660 {
ec72a266 661 internal_error ("symbol reloc that is not PC relative or 32 bits");
d160b69e
FF
662 }
663 break;
11e08196 664 case O_absent:
f92f247b
FF
665 /* Each O_absent expression can indicate exactly one possible modifier. */
666 if ((num & TIC80_OPERAND_M_SI) && (flags & TIC80_OPERAND_M_SI))
667 {
668 insn[0] = insn[0] | (1 << 17);
669 }
670 else if ((num & TIC80_OPERAND_M_LI) && (flags & TIC80_OPERAND_M_LI))
671 {
672 insn[0] = insn[0] | (1 << 15);
673 }
674 else if ((num & TIC80_OPERAND_SCALED) && (flags & TIC80_OPERAND_SCALED))
675 {
676 insn[0] = insn[0] | (1 << 11);
677 }
678 else if ((num & TIC80_OPERAND_PARENS) && (flags & TIC80_OPERAND_PARENS))
679 {
680 /* No code to generate, just accept and discard this expression */
681 }
682 else
683 {
684 internal_error_a ("unhandled operand modifier", opers[expi].X_add_number);
685 }
686 break;
1e12595d 687 case O_big:
e6e676a5
FF
688 fx = frag_more (4);
689 fxfrag = frag_now;
1e12595d 690 {
8ae66b94
FF
691 int precision = 2;
692 long exponent_bits = 8L;
693 LITTLENUM_TYPE words[2];
694 /* Value is still in generic_floating_point_number */
695 gen_to_words (words, precision, exponent_bits);
696 insn[1] = (words[0] << 16) | words[1];
1e12595d
FF
697 }
698 break;
f92f247b 699 case O_illegal:
11e08196 700 case O_symbol_rva:
11e08196
FF
701 case O_uminus:
702 case O_bit_not:
703 case O_logical_not:
704 case O_multiply:
705 case O_divide:
706 case O_modulus:
707 case O_left_shift:
708 case O_right_shift:
709 case O_bit_inclusive_or:
710 case O_bit_or_not:
711 case O_bit_exclusive_or:
712 case O_bit_and:
713 case O_add:
714 case O_subtract:
715 case O_eq:
716 case O_ne:
717 case O_lt:
718 case O_le:
719 case O_ge:
720 case O_gt:
721 case O_logical_and:
722 case O_logical_or:
723 case O_max:
724 default:
725 internal_error_a ("unhandled expression", X_op);
726 break;
727 }
728 }
729
730 /* Write out the instruction, either 4 or 8 bytes. */
731
11e08196 732 md_number_to_chars (f, insn[0], 4);
e6e676a5 733 if (fx != NULL)
11e08196 734 {
e6e676a5 735 md_number_to_chars (fx, insn[1], 4);
11e08196 736 }
f1ce6af4
FF
737}
738
16171d71
FF
739/* This is the main entry point for the machine-dependent assembler. Gas
740 calls this function for each input line which does not contain a
741 pseudoop.
742
743 STR points to a NULL terminated machine dependent instruction. This
744 function is supposed to emit the frags/bytes it assembles to. */
f1ce6af4
FF
745
746void
747md_assemble (str)
748 char *str;
749{
750 char *scan;
751 unsigned char *input_line_save;
752 struct tic80_opcode *opcode;
11e08196 753 expressionS myops[16];
f1ce6af4
FF
754 unsigned long insn;
755
756 /* Ensure there is something there to assemble. */
757 assert (str);
758
759 /* Drop any leading whitespace. */
760 while (isspace (*str))
761 {
762 str++;
763 }
764
765 /* Isolate the mnemonic from the rest of the string by finding the first
766 whitespace character and zapping it to a null byte. */
767 for (scan = str; *scan != '\000' && !isspace (*scan); scan++) {;}
768 if (*scan != '\000')
769 {
770 *scan++ = '\000';
771 }
772
773 /* Try to find this mnemonic in the hash table */
774 if ((opcode = (struct tic80_opcode *) hash_find (tic80_hash, str)) == NULL)
775 {
776 as_bad ("Invalid mnemonic: '%s'", str);
777 return;
778 }
779
780 str = scan;
781 while (isspace (*scan))
782 {
783 scan++;
784 }
785
786 input_line_save = input_line_pointer;
787 input_line_pointer = str;
788
789 opcode = find_opcode (opcode, myops);
790 if (opcode == NULL)
791 {
11e08196 792 as_bad ("Invalid operands: '%s'", input_line_save);
f1ce6af4
FF
793 }
794
795 input_line_pointer = input_line_save;
11e08196 796 build_insn (opcode, myops);
f1ce6af4
FF
797}
798
16171d71
FF
799/* This function is called once at the start of assembly, after the command
800 line arguments have been parsed and all the machine independent
801 initializations have been completed.
802
803 It should set up all the tables, etc., that the machine dependent part of
804 the assembler will need. */
f1ce6af4
FF
805
806void
807md_begin ()
808{
809 char *prev_name = "";
810 register const struct tic80_opcode *op;
811 register const struct tic80_opcode *op_end;
16171d71 812 const struct predefined_symbol *pdsp;
e74539b8 813 extern int coff_flags; /* Defined in obj-coff.c */
f1ce6af4 814
e74539b8
FF
815 /* Set F_AR32WR in coff_flags, which will end up in the file header
816 f_flags field. */
817
818 coff_flags |= F_AR32WR; /* TIc80 is 32 bit little endian */
f1ce6af4
FF
819
820 /* Insert unique names into hash table. The TIc80 instruction set
821 has many identical opcode names that have different opcodes based
822 on the operands. This hash table then provides a quick index to
823 the first opcode with a particular name in the opcode table. */
824
e74539b8 825 tic80_hash = hash_new ();
f1ce6af4
FF
826 op_end = tic80_opcodes + tic80_num_opcodes;
827 for (op = tic80_opcodes; op < op_end; op++)
828 {
829 if (strcmp (prev_name, op -> name) != 0)
830 {
831 prev_name = (char *) op -> name;
832 hash_insert (tic80_hash, op -> name, (char *) op);
833 }
834 }
16171d71
FF
835
836 /* Insert the predefined symbols into the symbol table. We use symbol_create
837 rather than symbol_new so that these symbols don't end up in the object
838 files' symbol table. Note that the values of the predefined symbols include
839 some upper bits that distinguish the type of the symbol (register, bitnum,
840 condition code, etc) and these bits must be masked away before actually
841 inserting the values into the instruction stream. For registers we put
842 these bits in the symbol table since we use them later and there is no
843 question that they aren't part of the register number. For constants we
844 can't do that since the constant can be any value, so they are masked off
845 before putting them into the symbol table. */
846
847 pdsp = NULL;
848 while ((pdsp = tic80_next_predefined_symbol (pdsp)) != NULL)
849 {
850 segT segment;
851 valueT valu;
852 int symtype;
853
854 symtype = PDS_VALUE (pdsp) & TIC80_OPERAND_MASK;
855 switch (symtype)
856 {
857 case TIC80_OPERAND_GPR:
858 case TIC80_OPERAND_FPA:
859 case TIC80_OPERAND_CR:
860 segment = reg_section;
861 valu = PDS_VALUE (pdsp);
862 break;
863 case TIC80_OPERAND_CC:
864 case TIC80_OPERAND_BITNUM:
865 segment = absolute_section;
866 valu = PDS_VALUE (pdsp) & ~TIC80_OPERAND_MASK;
867 break;
868 default:
869 internal_error_a ("unhandled predefined symbol bits", symtype);
870 break;
871 }
872 symbol_table_insert (symbol_create (PDS_NAME (pdsp), segment, valu,
873 &zero_address_frag));
874 }
f1ce6af4
FF
875}
876
877\f
878
16171d71
FF
879/* The assembler adds md_shortopts to the string passed to getopt. */
880
f1ce6af4
FF
881CONST char *md_shortopts = "";
882
16171d71
FF
883/* The assembler adds md_longopts to the machine independent long options
884 that are passed to getopt. */
885
f1ce6af4
FF
886struct option md_longopts[] = {
887 {NULL, no_argument, NULL, 0}
888};
889
890size_t md_longopts_size = sizeof(md_longopts);
891
16171d71
FF
892/* The md_parse_option function will be called whenever getopt returns an
893 unrecognized code, presumably indicating a special code value which
894 appears in md_longopts for machine specific command line options. */
f1ce6af4
FF
895
896int
897md_parse_option (c, arg)
898 int c;
899 char *arg;
900{
901 return (0);
902}
903
16171d71
FF
904/* The md_show_usage function will be called whenever a usage message is
905 printed. It should print a description of the machine specific options
906 found in md_longopts. */
f1ce6af4
FF
907
908void
909md_show_usage (stream)
910 FILE *stream;
911{
912}
913
914\f
915/* Attempt to simplify or even eliminate a fixup. The return value is
916 ignored; perhaps it was once meaningful, but now it is historical.
917 To indicate that a fixup has been eliminated, set fixP->fx_done.
918 */
919
920void
921md_apply_fix (fixP, val)
922 fixS *fixP;
923 long val;
924{
d160b69e 925 char *dest = fixP -> fx_frag -> fr_literal + fixP -> fx_where;
7b02bacd 926 int overflow;
d160b69e
FF
927
928 switch (fixP -> fx_r_type)
929 {
930 case R_RELLONGX:
931 md_number_to_chars (dest, (valueT) val, 4);
932 break;
933 case R_MPPCR:
af942f1d 934 overflow = (val < -65536) || (val > 65532);
7b02bacd
FF
935 if (overflow)
936 {
937 as_bad_where (fixP -> fx_file, fixP -> fx_line, "PC relative target out of range");
938 }
939 else
940 {
941 val >>= 2;
942 *dest++ = val & 0xFF;
943 val >>= 8;
944 *dest = (*dest & 0x80) | (val & 0x7F);
945 }
d160b69e 946 break;
b16a8c8e
FF
947 case R_ABS:
948 md_number_to_chars (dest, (valueT) val, fixP -> fx_size);
949 break;
d160b69e
FF
950 default:
951 internal_error_a ("unhandled relocation type in fixup", fixP -> fx_r_type);
952 break;
953 }
f1ce6af4
FF
954}
955
956\f
957/* Functions concerning relocs. */
958
959/* The location from which a PC relative jump should be calculated,
d160b69e
FF
960 given a PC relative reloc.
961
962 For the TIc80, this is the address of the 32 bit opcode containing
963 the PC relative field. */
f1ce6af4
FF
964
965long
966md_pcrel_from (fixP)
967 fixS *fixP;
968{
d160b69e 969 return (fixP -> fx_frag -> fr_address + fixP -> fx_where) ;
f1ce6af4
FF
970}
971
972/*
973 * Called after relax() is finished.
974 * In: Address of frag.
975 * fr_type == rs_machine_dependent.
976 * fr_subtype is what the address relaxed to.
977 *
978 * Out: Any fixSs and constants are set up.
979 * Caller will turn frag into a ".space 0".
980 */
981
982void
983md_convert_frag (headers, seg, fragP)
984 object_headers *headers;
985 segT seg;
986 fragS *fragP;
987{
11e08196 988 internal_error ("md_convert_frag() not implemented yet");
f1ce6af4
FF
989 abort ();
990}
991
992\f
993/*ARGSUSED*/
994void
995tc_coff_symbol_emit_hook (ignore)
996 symbolS *ignore;
997{
998}
999
1000#if defined OBJ_COFF
1001
1002short
1003tc_coff_fix2rtype (fixP)
1004 fixS *fixP;
1005{
d160b69e 1006 return (fixP -> fx_r_type);
f1ce6af4
FF
1007}
1008
1009#endif /* OBJ_COFF */
1010
64556643 1011/* end of tc-tic80.c */
This page took 0.100423 seconds and 4 git commands to generate.