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