1
/* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
2
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009
3
Free Software Foundation, Inc.
4
Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
6
This file is part of GAS, the GNU Assembler.
8
GAS is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
13
GAS is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with GAS; see the file COPYING. If not, write to the Free
20
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23
/* Texas Instruments TMS320C30 machine specific gas.
24
Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
25
Bugs & suggestions are completely welcome. This is free software.
26
Please help us make it better. */
29
#include "safe-ctype.h"
30
#include "opcode/tic30.h"
32
/* Put here all non-digit non-letter characters that may occur in an
34
static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
35
static char *ordinal_names[] =
37
N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
40
const char comment_chars[] = ";";
41
const char line_comment_chars[] = "*";
42
const char line_separator_chars[] = "";
44
const char *md_shortopts = "";
45
struct option md_longopts[] =
47
{NULL, no_argument, NULL, 0}
50
size_t md_longopts_size = sizeof (md_longopts);
52
/* Chars that mean this number is a floating point constant.
55
const char FLT_CHARS[] = "fFdDxX";
57
/* Chars that can be used to separate mant from exp in floating point
59
const char EXP_CHARS[] = "eE";
61
/* Tables for lexical analysis. */
62
static char opcode_chars[256];
63
static char register_chars[256];
64
static char operand_chars[256];
65
static char space_chars[256];
66
static char identifier_chars[256];
67
static char digit_chars[256];
70
#define is_opcode_char(x) (opcode_chars [(unsigned char) x])
71
#define is_operand_char(x) (operand_chars [(unsigned char) x])
72
#define is_register_char(x) (register_chars [(unsigned char) x])
73
#define is_space_char(x) (space_chars [(unsigned char) x])
74
#define is_identifier_char(x) (identifier_chars [(unsigned char) x])
75
#define is_digit_char(x) (digit_chars [(unsigned char) x])
77
const pseudo_typeS md_pseudo_table[] =
82
static int ATTRIBUTE_PRINTF_1
83
debug (const char *string, ...)
89
VA_OPEN (argptr, string);
90
VA_FIXEDARG (argptr, const char *, string);
91
vsprintf (str, string, argptr);
95
fputs (str, USE_STDOUT ? stdout : stderr);
102
/* Hash table for opcode lookup. */
103
static struct hash_control *op_hash;
104
/* Hash table for parallel opcode lookup. */
105
static struct hash_control *parop_hash;
106
/* Hash table for register lookup. */
107
static struct hash_control *reg_hash;
108
/* Hash table for indirect addressing lookup. */
109
static struct hash_control *ind_hash;
114
const char *hash_err;
116
debug ("In md_begin()\n");
117
op_hash = hash_new ();
120
const insn_template *current_optab = tic30_optab;
122
for (; current_optab < tic30_optab_end; current_optab++)
124
hash_err = hash_insert (op_hash, current_optab->name,
125
(char *) current_optab);
127
as_fatal ("Internal Error: Can't Hash %s: %s",
128
current_optab->name, hash_err);
132
parop_hash = hash_new ();
135
const partemplate *current_parop = tic30_paroptab;
137
for (; current_parop < tic30_paroptab_end; current_parop++)
139
hash_err = hash_insert (parop_hash, current_parop->name,
140
(char *) current_parop);
142
as_fatal ("Internal Error: Can't Hash %s: %s",
143
current_parop->name, hash_err);
147
reg_hash = hash_new ();
150
const reg *current_reg = tic30_regtab;
152
for (; current_reg < tic30_regtab_end; current_reg++)
154
hash_err = hash_insert (reg_hash, current_reg->name,
155
(char *) current_reg);
157
as_fatal ("Internal Error: Can't Hash %s: %s",
158
current_reg->name, hash_err);
162
ind_hash = hash_new ();
165
const ind_addr_type *current_ind = tic30_indaddr_tab;
167
for (; current_ind < tic30_indaddrtab_end; current_ind++)
169
hash_err = hash_insert (ind_hash, current_ind->syntax,
170
(char *) current_ind);
172
as_fatal ("Internal Error: Can't Hash %s: %s",
173
current_ind->syntax, hash_err);
177
/* Fill in lexical tables: opcode_chars, operand_chars, space_chars. */
182
for (c = 0; c < 256; c++)
184
if (ISLOWER (c) || ISDIGIT (c))
187
register_chars[c] = c;
189
else if (ISUPPER (c))
191
opcode_chars[c] = TOLOWER (c);
192
register_chars[c] = opcode_chars[c];
194
else if (c == ')' || c == '(')
195
register_chars[c] = c;
197
if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
198
operand_chars[c] = c;
200
if (ISDIGIT (c) || c == '-')
203
if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
204
identifier_chars[c] = c;
206
if (c == ' ' || c == '\t')
212
for (p = operand_special_chars; *p != '\0'; p++)
213
operand_chars[(unsigned char) *p] = *p;
217
/* Address Mode OR values. */
218
#define AM_Register 0x00000000
219
#define AM_Direct 0x00200000
220
#define AM_Indirect 0x00400000
221
#define AM_Immediate 0x00600000
222
#define AM_NotReq 0xFFFFFFFF
224
/* PC Relative OR values. */
225
#define PC_Register 0x00000000
226
#define PC_Relative 0x02000000
236
expressionS direct_expr;
254
unsigned int u_number;
256
expressionS imm_expr;
260
insn_template *opcode;
264
insn_template *tm; /* Template of current instruction. */
265
unsigned opcode; /* Final opcode. */
266
unsigned int operands; /* Number of given operands. */
267
/* Type of operand given in instruction. */
268
operand *operand_type[MAX_OPERANDS];
269
unsigned addressing_mode; /* Final addressing mode of instruction. */
272
struct tic30_insn insn;
273
static int found_parallel_insn;
275
static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
278
output_invalid (char c)
281
snprintf (output_invalid_buf, sizeof (output_invalid_buf),
284
snprintf (output_invalid_buf, sizeof (output_invalid_buf),
285
"(0x%x)", (unsigned char) c);
286
return output_invalid_buf;
289
/* next_line points to the next line after the current instruction
290
(current_line). Search for the parallel bars, and if found, merge two
291
lines into internal syntax for a parallel instruction:
292
q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
293
By this stage, all comments are scrubbed, and only the bare lines are
297
#define START_OPCODE 1
299
#define START_OPERANDS 3
300
#define END_OPERANDS 4
303
tic30_find_parallel_insn (char *current_line, char *next_line)
305
int found_parallel = 0;
306
char first_opcode[256];
307
char second_opcode[256];
308
char first_operands[256];
309
char second_operands[256];
312
debug ("In tic30_find_parallel_insn()\n");
313
while (!is_end_of_line[(unsigned char) *next_line])
315
if (*next_line == PARALLEL_SEPARATOR
316
&& *(next_line + 1) == PARALLEL_SEPARATOR)
326
debug ("Found a parallel instruction\n");
330
char *op, *operands, *line;
332
for (i = 0; i < 2; i++)
336
op = &first_opcode[0];
337
operands = &first_operands[0];
342
op = &second_opcode[0];
343
operands = &second_operands[0];
348
int search_status = NONE;
352
while (!is_end_of_line[(unsigned char) (c = *line)])
354
if (is_opcode_char (c) && search_status == NONE)
356
op[char_ptr++] = TOLOWER (c);
357
search_status = START_OPCODE;
359
else if (is_opcode_char (c) && search_status == START_OPCODE)
360
op[char_ptr++] = TOLOWER (c);
361
else if (!is_opcode_char (c) && search_status == START_OPCODE)
365
search_status = END_OPCODE;
367
else if (is_operand_char (c) && search_status == START_OPERANDS)
368
operands[char_ptr++] = c;
370
if (is_operand_char (c) && search_status == END_OPCODE)
372
operands[char_ptr++] = c;
373
search_status = START_OPERANDS;
378
if (search_status != START_OPERANDS)
380
operands[char_ptr] = '\0';
384
parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
385
+ strlen (second_opcode) + strlen (second_operands) + 8);
386
sprintf (parallel_insn, "q_%s_%s %s | %s",
387
first_opcode, second_opcode,
388
first_operands, second_operands);
389
debug ("parallel insn = %s\n", parallel_insn);
390
return parallel_insn;
396
#undef START_OPERANDS
400
tic30_operand (char *token)
403
char ind_buffer[strlen (token)];
406
debug ("In tic30_operand with %s\n", token);
407
current_op = malloc (sizeof (* current_op));
408
memset (current_op, '\0', sizeof (operand));
410
if (*token == DIRECT_REFERENCE)
412
char *token_posn = token + 1;
413
int direct_label = 0;
415
debug ("Found direct reference\n");
418
if (!is_digit_char (*token_posn))
425
char *save_input_line_pointer;
428
debug ("Direct reference is a label\n");
429
current_op->direct.label = token + 1;
430
save_input_line_pointer = input_line_pointer;
431
input_line_pointer = token + 1;
432
debug ("Current input_line_pointer: %s\n", input_line_pointer);
433
retval = expression (¤t_op->direct.direct_expr);
435
debug ("Expression type: %d\n",
436
current_op->direct.direct_expr.X_op);
437
debug ("Expression addnum: %ld\n",
438
(long) current_op->direct.direct_expr.X_add_number);
439
debug ("Segment: %p\n", retval);
441
input_line_pointer = save_input_line_pointer;
443
if (current_op->direct.direct_expr.X_op == O_constant)
445
current_op->direct.address =
446
current_op->direct.direct_expr.X_add_number;
447
current_op->direct.resolved = 1;
452
debug ("Direct reference is a number\n");
453
current_op->direct.address = atoi (token + 1);
454
current_op->direct.resolved = 1;
456
current_op->op_type = Direct;
458
else if (*token == INDIRECT_REFERENCE)
460
/* Indirect reference operand. */
466
ind_addr_type *ind_addr_op;
468
debug ("Found indirect reference\n");
469
ind_buffer[0] = *token;
471
for (count = 1; count < strlen (token); count++)
474
ind_buffer[buffer_posn] = TOLOWER (*(token + count));
476
if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
477
&& (*(token + count) == 'r' || *(token + count) == 'R'))
479
/* AR reference is found, so get its number and remove
480
it from the buffer so it can pass through hash_find(). */
483
as_bad (_("More than one AR register found in indirect reference"));
486
if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
488
as_bad (_("Illegal AR register in indirect reference"));
491
ar_number = *(token + count + 1) - '0';
496
if (*(token + count) == '(')
498
/* Parenthesis found, so check if a displacement value is
499
inside. If so, get the value and remove it from the
501
if (is_digit_char (*(token + count + 1)))
508
as_bad (_("More than one displacement found in indirect reference"));
512
while (*(token + count) != ')')
514
if (!is_digit_char (*(token + count)))
516
as_bad (_("Invalid displacement in indirect reference"));
519
disp[disp_posn++] = *(token + (count++));
521
disp[disp_posn] = '\0';
522
disp_number = atoi (disp);
530
ind_buffer[buffer_posn] = '\0';
533
as_bad (_("AR register not found in indirect reference"));
537
ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
540
debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
541
if (ind_addr_op->displacement == IMPLIED_DISP)
546
else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
548
/* Maybe an implied displacement of 1 again. */
549
as_bad (_("required displacement wasn't given in indirect reference"));
555
as_bad (_("illegal indirect reference"));
559
if (found_disp && (disp_number < 0 || disp_number > 255))
561
as_bad (_("displacement must be an unsigned 8-bit number"));
565
current_op->indirect.mod = ind_addr_op->modfield;
566
current_op->indirect.disp = disp_number;
567
current_op->indirect.ARnum = ar_number;
568
current_op->op_type = Indirect;
572
reg *regop = (reg *) hash_find (reg_hash, token);
576
debug ("Found register operand: %s\n", regop->name);
577
if (regop->regtype == REG_ARn)
578
current_op->op_type = ARn;
579
else if (regop->regtype == REG_Rn)
580
current_op->op_type = Rn;
581
else if (regop->regtype == REG_DP)
582
current_op->op_type = DPReg;
584
current_op->op_type = OtherReg;
585
current_op->reg.opcode = regop->opcode;
589
if (!is_digit_char (*token)
590
|| *(token + 1) == 'x'
591
|| strchr (token, 'h'))
593
char *save_input_line_pointer;
596
debug ("Probably a label: %s\n", token);
597
current_op->immediate.label = malloc (strlen (token) + 1);
598
strcpy (current_op->immediate.label, token);
599
current_op->immediate.label[strlen (token)] = '\0';
600
save_input_line_pointer = input_line_pointer;
601
input_line_pointer = token;
603
debug ("Current input_line_pointer: %s\n", input_line_pointer);
604
retval = expression (¤t_op->immediate.imm_expr);
605
debug ("Expression type: %d\n",
606
current_op->immediate.imm_expr.X_op);
607
debug ("Expression addnum: %ld\n",
608
(long) current_op->immediate.imm_expr.X_add_number);
609
debug ("Segment: %p\n", retval);
610
input_line_pointer = save_input_line_pointer;
612
if (current_op->immediate.imm_expr.X_op == O_constant)
614
current_op->immediate.s_number
615
= current_op->immediate.imm_expr.X_add_number;
616
current_op->immediate.u_number
617
= (unsigned int) current_op->immediate.imm_expr.X_add_number;
618
current_op->immediate.resolved = 1;
623
debug ("Found a number or displacement\n");
624
for (count = 0; count < strlen (token); count++)
625
if (*(token + count) == '.')
626
current_op->immediate.decimal_found = 1;
627
current_op->immediate.label = malloc (strlen (token) + 1);
628
strcpy (current_op->immediate.label, token);
629
current_op->immediate.label[strlen (token)] = '\0';
630
current_op->immediate.f_number = (float) atof (token);
631
current_op->immediate.s_number = (int) atoi (token);
632
current_op->immediate.u_number = (unsigned int) atoi (token);
633
current_op->immediate.resolved = 1;
635
current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
636
if (current_op->immediate.u_number <= 31)
637
current_op->op_type |= IVector;
643
struct tic30_par_insn
645
partemplate *tm; /* Template of current parallel instruction. */
646
unsigned operands[2]; /* Number of given operands for each insn. */
647
/* Type of operand given in instruction. */
648
operand *operand_type[2][MAX_OPERANDS];
649
int swap_operands; /* Whether to swap operands around. */
650
unsigned p_field; /* Value of p field in multiply add/sub instructions. */
651
unsigned opcode; /* Final opcode. */
654
struct tic30_par_insn p_insn;
657
tic30_parallel_insn (char *token)
659
static partemplate *p_opcode;
660
char *current_posn = token;
664
debug ("In tic30_parallel_insn with %s\n", token);
665
memset (&p_insn, '\0', sizeof (p_insn));
667
while (is_opcode_char (*current_posn))
670
/* Find instruction. */
671
save_char = *current_posn;
672
*current_posn = '\0';
673
p_opcode = (partemplate *) hash_find (parop_hash, token);
676
debug ("Found instruction %s\n", p_opcode->name);
677
p_insn.tm = p_opcode;
681
char first_opcode[6] = {0};
682
char second_opcode[6] = {0};
684
int current_opcode = -1;
687
for (i = 0; i < strlen (token); i++)
689
char ch = *(token + i);
691
if (ch == '_' && current_opcode == -1)
697
if (ch == '_' && current_opcode == 0)
704
switch (current_opcode)
707
first_opcode[char_ptr++] = ch;
710
second_opcode[char_ptr++] = ch;
715
debug ("first_opcode = %s\n", first_opcode);
716
debug ("second_opcode = %s\n", second_opcode);
717
sprintf (token, "q_%s_%s", second_opcode, first_opcode);
718
p_opcode = (partemplate *) hash_find (parop_hash, token);
722
debug ("Found instruction %s\n", p_opcode->name);
723
p_insn.tm = p_opcode;
724
p_insn.swap_operands = 1;
729
*current_posn = save_char;
734
int paren_not_balanced;
735
int expecting_operand = 0;
736
int found_separator = 0;
740
/* Skip optional white space before operand. */
741
while (!is_operand_char (*current_posn)
742
&& *current_posn != END_OF_INSN)
744
if (!is_space_char (*current_posn)
745
&& *current_posn != PARALLEL_SEPARATOR)
747
as_bad (_("Invalid character %s before %s operand"),
748
output_invalid (*current_posn),
749
ordinal_names[insn.operands]);
752
if (*current_posn == PARALLEL_SEPARATOR)
757
token_start = current_posn;
758
paren_not_balanced = 0;
760
while (paren_not_balanced || *current_posn != ',')
762
if (*current_posn == END_OF_INSN)
764
if (paren_not_balanced)
766
as_bad (_("Unbalanced parenthesis in %s operand."),
767
ordinal_names[insn.operands]);
773
else if (*current_posn == PARALLEL_SEPARATOR)
775
while (is_space_char (*(current_posn - 1)))
779
else if (!is_operand_char (*current_posn)
780
&& !is_space_char (*current_posn))
782
as_bad (_("Invalid character %s in %s operand"),
783
output_invalid (*current_posn),
784
ordinal_names[insn.operands]);
788
if (*current_posn == '(')
789
++paren_not_balanced;
790
if (*current_posn == ')')
791
--paren_not_balanced;
795
if (current_posn != token_start)
797
/* Yes, we've read in another operand. */
798
p_insn.operands[found_separator]++;
799
if (p_insn.operands[found_separator] > MAX_OPERANDS)
801
as_bad (_("Spurious operands; (%d operands/instruction max)"),
806
/* Now parse operand adding info to 'insn' as we go along. */
807
save_char = *current_posn;
808
*current_posn = '\0';
809
p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
810
tic30_operand (token_start);
811
*current_posn = save_char;
812
if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
817
if (expecting_operand)
819
as_bad (_("Expecting operand after ','; got nothing"));
822
if (*current_posn == ',')
824
as_bad (_("Expecting operand before ','; got nothing"));
829
/* Now *current_posn must be either ',' or END_OF_INSN. */
830
if (*current_posn == ',')
832
if (*++current_posn == END_OF_INSN)
834
/* Just skip it, if it's \n complain. */
835
as_bad (_("Expecting operand after ','; got nothing"));
838
expecting_operand = 1;
841
while (*current_posn != END_OF_INSN);
844
if (p_insn.swap_operands)
849
temp_num = p_insn.operands[0];
850
p_insn.operands[0] = p_insn.operands[1];
851
p_insn.operands[1] = temp_num;
852
for (i = 0; i < MAX_OPERANDS; i++)
854
temp_op = p_insn.operand_type[0][i];
855
p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
856
p_insn.operand_type[1][i] = temp_op;
860
if (p_insn.operands[0] != p_insn.tm->operands_1)
862
as_bad (_("incorrect number of operands given in the first instruction"));
866
if (p_insn.operands[1] != p_insn.tm->operands_2)
868
as_bad (_("incorrect number of operands given in the second instruction"));
872
debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
873
debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
876
/* Now check if operands are correct. */
881
for (count = 0; count < 2; count++)
884
for (i = 0; i < p_insn.operands[count]; i++)
886
if ((p_insn.operand_type[count][i]->op_type &
887
p_insn.tm->operand_types[count][i]) == 0)
889
as_bad (_("%s instruction, operand %d doesn't match"),
890
ordinal_names[count], i + 1);
894
/* Get number of R register and indirect reference contained
895
within the first two operands of each instruction. This is
896
required for the multiply parallel instructions which require
897
two R registers and two indirect references, but not in any
899
if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
901
else if ((p_insn.operand_type[count][i]->op_type & Indirect)
907
if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
910
/* Check for the multiply instructions. */
913
as_bad (_("incorrect format for multiply parallel instruction"));
919
/* Shouldn't get here. */
920
as_bad (_("incorrect format for multiply parallel instruction"));
924
if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
925
&& (p_insn.operand_type[0][2]->reg.opcode != 0x01))
927
as_bad (_("destination for multiply can only be R0 or R1"));
931
if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
932
&& (p_insn.operand_type[1][2]->reg.opcode != 0x03))
934
as_bad (_("destination for add/subtract can only be R2 or R3"));
938
/* Now determine the P field for the instruction. */
939
if (p_insn.operand_type[0][0]->op_type & Indirect)
941
if (p_insn.operand_type[0][1]->op_type & Indirect)
942
p_insn.p_field = 0x00000000; /* Ind * Ind, Rn +/- Rn. */
943
else if (p_insn.operand_type[1][0]->op_type & Indirect)
944
p_insn.p_field = 0x01000000; /* Ind * Rn, Ind +/- Rn. */
946
p_insn.p_field = 0x03000000; /* Ind * Rn, Rn +/- Ind. */
950
if (p_insn.operand_type[0][1]->op_type & Rn)
951
p_insn.p_field = 0x02000000; /* Rn * Rn, Ind +/- Ind. */
952
else if (p_insn.operand_type[1][0]->op_type & Indirect)
955
p_insn.p_field = 0x01000000; /* Rn * Ind, Ind +/- Rn. */
956
/* Need to swap the two multiply operands around so that
957
everything is in its place for the opcode makeup.
958
ie so Ind * Rn, Ind +/- Rn. */
959
temp = p_insn.operand_type[0][0];
960
p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
961
p_insn.operand_type[0][1] = temp;
966
p_insn.p_field = 0x03000000; /* Rn * Ind, Rn +/- Ind. */
967
temp = p_insn.operand_type[0][0];
968
p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
969
p_insn.operand_type[0][1] = temp;
975
debug ("P field: %08X\n", p_insn.p_field);
977
/* Finalise opcode. This is easier for parallel instructions as they have
978
to be fully resolved, there are no memory addresses allowed, except
979
through indirect addressing, so there are no labels to resolve. */
980
p_insn.opcode = p_insn.tm->base_opcode;
982
switch (p_insn.tm->oporder)
985
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
986
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
987
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
988
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
989
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
990
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
994
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
995
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
996
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
997
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
998
p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
999
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
1000
if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
1001
as_warn (_("loading the same register in parallel operation"));
1005
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1006
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1007
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1008
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1009
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1010
p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
1014
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
1015
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
1016
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1017
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1018
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1019
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1020
p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1024
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1025
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1026
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
1027
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
1028
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1029
p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1030
p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
1034
p_insn.opcode |= p_insn.p_field;
1035
if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
1036
p_insn.opcode |= 0x00800000;
1037
if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
1038
p_insn.opcode |= 0x00400000;
1040
switch (p_insn.p_field)
1043
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
1044
p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
1045
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1046
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1047
p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1048
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
1051
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
1052
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
1053
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1054
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1055
p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
1056
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1059
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1060
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1061
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
1062
p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
1063
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
1064
p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
1067
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
1068
p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
1069
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
1070
p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
1071
p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
1072
p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
1081
p = frag_more (INSN_SIZE);
1082
md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
1088
for (i = 0; i < 2; i++)
1089
for (j = 0; j < p_insn.operands[i]; j++)
1090
free (p_insn.operand_type[i][j]);
1093
debug ("Final opcode: %08X\n", p_insn.opcode);
1099
/* In order to get gas to ignore any | chars at the start of a line,
1100
this function returns true if a | is found in a line. */
1103
tic30_unrecognized_line (int c)
1105
debug ("In tc_unrecognized_line\n");
1106
return (c == PARALLEL_SEPARATOR);
1110
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
1111
segT segment ATTRIBUTE_UNUSED)
1113
debug ("In md_estimate_size_before_relax()\n");
1118
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1119
segT sec ATTRIBUTE_UNUSED,
1120
register fragS *fragP ATTRIBUTE_UNUSED)
1122
debug ("In md_convert_frag()\n");
1126
md_apply_fix (fixS *fixP,
1128
segT seg ATTRIBUTE_UNUSED)
1130
valueT value = *valP;
1132
debug ("In md_apply_fix() with value = %ld\n", (long) value);
1133
debug ("Values in fixP\n");
1134
debug ("fx_size = %d\n", fixP->fx_size);
1135
debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
1136
debug ("fx_where = %ld\n", fixP->fx_where);
1137
debug ("fx_offset = %d\n", (int) fixP->fx_offset);
1139
char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1142
if (fixP->fx_size == 1)
1143
/* Special fix for LDP instruction. */
1144
value = (value & 0x00FF0000) >> 16;
1146
debug ("new value = %ld\n", (long) value);
1147
md_number_to_chars (buf, value, fixP->fx_size);
1150
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
1155
md_parse_option (int c ATTRIBUTE_UNUSED,
1156
char *arg ATTRIBUTE_UNUSED)
1158
debug ("In md_parse_option()\n");
1163
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1165
debug ("In md_show_usage()\n");
1169
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1171
debug ("In md_undefined_symbol()\n");
1172
return (symbolS *) 0;
1176
md_section_align (segT segment, valueT size)
1178
debug ("In md_section_align() segment = %p and size = %lu\n",
1179
segment, (unsigned long) size);
1180
size = (size + 3) / 4;
1182
debug ("New size value = %lu\n", (unsigned long) size);
1187
md_pcrel_from (fixS *fixP)
1191
debug ("In md_pcrel_from()\n");
1192
debug ("fx_where = %ld\n", fixP->fx_where);
1193
debug ("fx_size = %d\n", fixP->fx_size);
1194
/* Find the opcode that represents the current instruction in the
1195
fr_literal storage area, and check bit 21. Bit 21 contains whether the
1196
current instruction is a delayed one or not, and then set the offset
1197
value appropriately. */
1198
if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
1202
debug ("offset = %d\n", offset);
1203
/* PC Relative instructions have a format:
1204
displacement = Label - (PC + offset)
1205
This function returns PC + offset where:
1206
fx_where - fx_size = PC
1207
INSN_SIZE * offset = offset number of instructions. */
1208
return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
1212
md_atof (int what_statement_type,
1219
unsigned long value;
1222
debug ("In md_atof()\n");
1223
debug ("precision = %c\n", what_statement_type);
1224
debug ("literal = %s\n", literalP);
1226
token = input_line_pointer;
1227
while (!is_end_of_line[(unsigned char) *input_line_pointer]
1228
&& (*input_line_pointer != ','))
1230
debug ("%c", *input_line_pointer);
1231
input_line_pointer++;
1234
keepval = *input_line_pointer;
1235
*input_line_pointer = '\0';
1237
float_value = (float) atof (token);
1238
*input_line_pointer = keepval;
1239
debug ("float_value = %f\n", float_value);
1241
switch (what_statement_type)
1259
return _("Unrecognized or unsupported floating point constant");
1262
if (float_value == 0.0)
1263
value = (prec == 2) ? 0x00008000L : 0x80000000L;
1266
unsigned long exp, sign, mant, tmsfloat;
1274
converter.f = float_value;
1275
tmsfloat = converter.l;
1276
sign = tmsfloat & 0x80000000;
1277
mant = tmsfloat & 0x007FFFFF;
1278
exp = tmsfloat & 0x7F800000;
1280
if (exp == 0xFF000000)
1294
mant = mant & 0x007FFFFF;
1296
mant = mant & 0x00FFFFFF;
1300
exp = (long) exp - 0x01000000;
1303
tmsfloat = exp | mant;
1310
if (tmsfloat == 0x80000000)
1315
expon = (tmsfloat & 0xFF000000);
1317
mantis = tmsfloat & 0x007FFFFF;
1318
if (tmsfloat & 0x00800000)
1320
mantis |= 0xFF000000;
1321
mantis += 0x00000800;
1323
mantis |= 0x00000800;
1330
mantis |= 0x00800000;
1331
mantis += 0x00000800;
1332
expon += (mantis >> 24);
1342
mantis = (expon << 12) | mantis;
1343
value = mantis & 0xFFFF;
1348
md_number_to_chars (literalP, value, prec);
1354
md_number_to_chars (char *buf, valueT val, int n)
1356
debug ("In md_number_to_chars()\n");
1357
number_to_chars_bigendian (buf, val, n);
1360
#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
1361
#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
1364
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
1367
bfd_reloc_code_real_type code = 0;
1369
debug ("In tc_gen_reloc()\n");
1370
debug ("fixP.size = %d\n", fixP->fx_size);
1371
debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
1372
debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
1374
switch (F (fixP->fx_size, fixP->fx_pcrel))
1376
MAP (1, 0, BFD_RELOC_TIC30_LDP);
1377
MAP (2, 0, BFD_RELOC_16);
1378
MAP (3, 0, BFD_RELOC_24);
1379
MAP (2, 1, BFD_RELOC_16_PCREL);
1380
MAP (4, 0, BFD_RELOC_32);
1382
as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
1383
fixP->fx_pcrel ? _("pc-relative ") : "");
1388
rel = xmalloc (sizeof (* rel));
1389
gas_assert (rel != 0);
1390
rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1391
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1392
rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
1394
rel->howto = bfd_reloc_type_lookup (stdoutput, code);
1399
name = S_GET_NAME (fixP->fx_addsy);
1402
as_fatal ("Cannot generate relocation type for symbol %s, code %s",
1403
name, bfd_get_reloc_code_name (code));
1409
md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
1411
debug ("In md_operand()\n");
1415
md_assemble (char *line)
1423
debug ("In md_assemble() with argument %s\n", line);
1424
memset (&insn, '\0', sizeof (insn));
1425
if (found_parallel_insn)
1427
debug ("Line is second part of parallel instruction\n\n");
1428
found_parallel_insn = 0;
1432
tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
1433
current_posn = line;
1435
found_parallel_insn = 1;
1437
while (is_space_char (*current_posn))
1440
token_start = current_posn;
1442
if (!is_opcode_char (*current_posn))
1444
as_bad (_("Invalid character %s in opcode"),
1445
output_invalid (*current_posn));
1448
/* Check if instruction is a parallel instruction
1449
by seeing if the first character is a q. */
1450
if (*token_start == 'q')
1452
if (tic30_parallel_insn (token_start))
1454
if (found_parallel_insn)
1459
while (is_opcode_char (*current_posn))
1462
/* Find instruction. */
1463
save_char = *current_posn;
1464
*current_posn = '\0';
1465
op = (insn_template *) hash_find (op_hash, token_start);
1468
debug ("Found instruction %s\n", op->name);
1473
debug ("Didn't find insn\n");
1474
as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
1477
*current_posn = save_char;
1480
if (*current_posn != END_OF_INSN)
1482
/* Find operands. */
1483
int paren_not_balanced;
1484
int expecting_operand = 0;
1488
/* Skip optional white space before operand. */
1489
while (!is_operand_char (*current_posn)
1490
&& *current_posn != END_OF_INSN)
1492
if (!is_space_char (*current_posn))
1494
as_bad (_("Invalid character %s before %s operand"),
1495
output_invalid (*current_posn),
1496
ordinal_names[insn.operands]);
1501
token_start = current_posn;
1502
paren_not_balanced = 0;
1503
while (paren_not_balanced || *current_posn != ',')
1505
if (*current_posn == END_OF_INSN)
1507
if (paren_not_balanced)
1509
as_bad (_("Unbalanced parenthesis in %s operand."),
1510
ordinal_names[insn.operands]);
1516
else if (!is_operand_char (*current_posn)
1517
&& !is_space_char (*current_posn))
1519
as_bad (_("Invalid character %s in %s operand"),
1520
output_invalid (*current_posn),
1521
ordinal_names[insn.operands]);
1524
if (*current_posn == '(')
1525
++paren_not_balanced;
1526
if (*current_posn == ')')
1527
--paren_not_balanced;
1530
if (current_posn != token_start)
1532
/* Yes, we've read in another operand. */
1533
this_operand = insn.operands++;
1534
if (insn.operands > MAX_OPERANDS)
1536
as_bad (_("Spurious operands; (%d operands/instruction max)"),
1541
/* Now parse operand adding info to 'insn' as we go along. */
1542
save_char = *current_posn;
1543
*current_posn = '\0';
1544
insn.operand_type[this_operand] = tic30_operand (token_start);
1545
*current_posn = save_char;
1546
if (insn.operand_type[this_operand] == NULL)
1551
if (expecting_operand)
1553
as_bad (_("Expecting operand after ','; got nothing"));
1556
if (*current_posn == ',')
1558
as_bad (_("Expecting operand before ','; got nothing"));
1563
/* Now *current_posn must be either ',' or END_OF_INSN. */
1564
if (*current_posn == ',')
1566
if (*++current_posn == END_OF_INSN)
1568
/* Just skip it, if it's \n complain. */
1569
as_bad (_("Expecting operand after ','; got nothing"));
1572
expecting_operand = 1;
1575
while (*current_posn != END_OF_INSN);
1578
debug ("Number of operands found: %d\n", insn.operands);
1580
/* Check that number of operands is correct. */
1581
if (insn.operands != insn.tm->operands)
1584
unsigned int numops = insn.tm->operands;
1586
/* If operands are not the same, then see if any of the operands are
1587
not required. Then recheck with number of given operands. If they
1588
are still not the same, then give an error, otherwise carry on. */
1589
for (i = 0; i < insn.tm->operands; i++)
1590
if (insn.tm->operand_types[i] & NotReq)
1592
if (insn.operands != numops)
1594
as_bad (_("Incorrect number of operands given"));
1598
insn.addressing_mode = AM_NotReq;
1599
for (count = 0; count < insn.operands; count++)
1601
if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
1603
debug ("Operand %d matches\n", count + 1);
1604
/* If instruction has two operands and has an AddressMode
1605
modifier then set addressing mode type for instruction. */
1606
if (insn.tm->opcode_modifier == AddressMode)
1609
/* Store instruction uses the second
1610
operand for the address mode. */
1611
if ((insn.tm->operand_types[1] & (Indirect | Direct))
1612
== (Indirect | Direct))
1615
if (insn.operand_type[addr_insn]->op_type & (AllReg))
1616
insn.addressing_mode = AM_Register;
1617
else if (insn.operand_type[addr_insn]->op_type & Direct)
1618
insn.addressing_mode = AM_Direct;
1619
else if (insn.operand_type[addr_insn]->op_type & Indirect)
1620
insn.addressing_mode = AM_Indirect;
1622
insn.addressing_mode = AM_Immediate;
1627
as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
1632
/* Now set the addressing mode for 3 operand instructions. */
1633
if ((insn.tm->operand_types[0] & op3T1)
1634
&& (insn.tm->operand_types[1] & op3T2))
1636
/* Set the addressing mode to the values used for 2 operand
1637
instructions in the G addressing field of the opcode. */
1639
switch (insn.operand_type[0]->op_type)
1645
if (insn.operand_type[1]->op_type & (AllReg))
1646
insn.addressing_mode = AM_Register;
1647
else if (insn.operand_type[1]->op_type & Indirect)
1648
insn.addressing_mode = AM_Direct;
1651
/* Shouldn't make it to this stage. */
1652
as_bad (_("Incompatible first and second operands in instruction"));
1657
if (insn.operand_type[1]->op_type & (AllReg))
1658
insn.addressing_mode = AM_Indirect;
1659
else if (insn.operand_type[1]->op_type & Indirect)
1660
insn.addressing_mode = AM_Immediate;
1663
/* Shouldn't make it to this stage. */
1664
as_bad (_("Incompatible first and second operands in instruction"));
1669
/* Now make up the opcode for the 3 operand instructions. As in
1670
parallel instructions, there will be no unresolved values, so they
1671
can be fully formed and added to the frag table. */
1672
insn.opcode = insn.tm->base_opcode;
1673
if (insn.operand_type[0]->op_type & Indirect)
1675
insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
1676
insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
1679
insn.opcode |= (insn.operand_type[0]->reg.opcode);
1681
if (insn.operand_type[1]->op_type & Indirect)
1683
insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
1684
insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
1687
insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
1689
if (insn.operands == 3)
1690
insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
1692
insn.opcode |= insn.addressing_mode;
1693
p = frag_more (INSN_SIZE);
1694
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1698
/* Not a three operand instruction. */
1701
insn.opcode = insn.tm->base_opcode;
1702
/* Create frag for instruction - all instructions are 4 bytes long. */
1703
p = frag_more (INSN_SIZE);
1704
if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
1706
insn.opcode |= insn.addressing_mode;
1707
if (insn.addressing_mode == AM_Indirect)
1709
/* Determine which operand gives the addressing mode. */
1710
if (insn.operand_type[0]->op_type & Indirect)
1712
if ((insn.operands > 1)
1713
&& (insn.operand_type[1]->op_type & Indirect))
1715
insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
1716
insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
1717
insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
1718
if (insn.operands > 1)
1719
insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
1720
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1722
else if (insn.addressing_mode == AM_Register)
1724
insn.opcode |= (insn.operand_type[0]->reg.opcode);
1725
if (insn.operands > 1)
1726
insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1727
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1729
else if (insn.addressing_mode == AM_Direct)
1731
if (insn.operand_type[0]->op_type & Direct)
1733
if ((insn.operands > 1)
1734
&& (insn.operand_type[1]->op_type & Direct))
1736
if (insn.operands > 1)
1738
(insn.operand_type[! am_insn]->reg.opcode << 16);
1739
if (insn.operand_type[am_insn]->direct.resolved == 1)
1741
/* Resolved values can be placed straight
1742
into instruction word, and output. */
1744
(insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
1745
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1749
/* Unresolved direct addressing mode instruction. */
1750
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1751
fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1752
& insn.operand_type[am_insn]->direct.direct_expr,
1756
else if (insn.addressing_mode == AM_Immediate)
1758
if (insn.operand_type[0]->immediate.resolved == 1)
1763
if (insn.operands > 1)
1764
insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1766
switch (insn.tm->imm_arg_type)
1769
debug ("Floating point first operand\n");
1770
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1772
keeploc = input_line_pointer;
1773
input_line_pointer =
1774
insn.operand_type[0]->immediate.label;
1776
if (md_atof ('f', p + 2, & size) != 0)
1778
as_bad (_("invalid short form floating point immediate operand"));
1782
input_line_pointer = keeploc;
1786
debug ("Unsigned int first operand\n");
1787
if (insn.operand_type[0]->immediate.decimal_found)
1788
as_warn (_("rounding down first operand float to unsigned int"));
1789
if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
1790
as_warn (_("only lower 16-bits of first operand are used"));
1792
(insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
1793
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1797
debug ("Int first operand\n");
1799
if (insn.operand_type[0]->immediate.decimal_found)
1800
as_warn (_("rounding down first operand float to signed int"));
1802
if (insn.operand_type[0]->immediate.s_number < -32768 ||
1803
insn.operand_type[0]->immediate.s_number > 32767)
1805
as_bad (_("first operand is too large for 16-bit signed int"));
1809
(insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
1810
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1816
/* Unresolved immediate label. */
1817
if (insn.operands > 1)
1818
insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
1819
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1820
fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
1821
& insn.operand_type[0]->immediate.imm_expr,
1826
else if (insn.tm->opcode_modifier == PCRel)
1828
/* Conditional Branch and Call instructions. */
1829
if ((insn.tm->operand_types[0] & (AllReg | Disp))
1832
if (insn.operand_type[0]->op_type & (AllReg))
1834
insn.opcode |= (insn.operand_type[0]->reg.opcode);
1835
insn.opcode |= PC_Register;
1836
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1840
insn.opcode |= PC_Relative;
1841
if (insn.operand_type[0]->immediate.resolved == 1)
1844
(insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
1845
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1849
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1850
fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
1851
2, & insn.operand_type[0]->immediate.imm_expr,
1856
else if ((insn.tm->operand_types[0] & ARn) == ARn)
1858
/* Decrement and Branch instructions. */
1859
insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
1860
if (insn.operand_type[1]->op_type & (AllReg))
1862
insn.opcode |= (insn.operand_type[1]->reg.opcode);
1863
insn.opcode |= PC_Register;
1864
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1866
else if (insn.operand_type[1]->immediate.resolved == 1)
1868
if (insn.operand_type[0]->immediate.decimal_found)
1870
as_bad (_("first operand is floating point"));
1873
if (insn.operand_type[0]->immediate.s_number < -32768 ||
1874
insn.operand_type[0]->immediate.s_number > 32767)
1876
as_bad (_("first operand is too large for 16-bit signed int"));
1879
insn.opcode |= (insn.operand_type[1]->immediate.s_number);
1880
insn.opcode |= PC_Relative;
1881
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1885
insn.opcode |= PC_Relative;
1886
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1887
fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
1888
& insn.operand_type[1]->immediate.imm_expr,
1893
else if (insn.tm->operand_types[0] == IVector)
1895
/* Trap instructions. */
1896
if (insn.operand_type[0]->op_type & IVector)
1897
insn.opcode |= (insn.operand_type[0]->immediate.u_number);
1900
/* Shouldn't get here. */
1901
as_bad (_("interrupt vector for trap instruction out of range"));
1904
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1906
else if (insn.tm->opcode_modifier == StackOp
1907
|| insn.tm->opcode_modifier == Rotate)
1909
/* Push, Pop and Rotate instructions. */
1910
insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
1911
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1913
else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
1914
== (Abs24 | Direct))
1916
/* LDP Instruction needs to be tested
1917
for before the next section. */
1918
if (insn.operand_type[0]->op_type & Direct)
1920
if (insn.operand_type[0]->direct.resolved == 1)
1922
/* Direct addressing uses lower 8 bits of direct address. */
1924
(insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
1925
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1931
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1932
fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1933
1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
1934
/* Ensure that the assembler doesn't complain
1935
about fitting a 24-bit address into 8 bits. */
1936
fix->fx_no_overflow = 1;
1941
if (insn.operand_type[0]->immediate.resolved == 1)
1943
/* Immediate addressing uses upper 8 bits of address. */
1944
if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1946
as_bad (_("LDP instruction needs a 24-bit operand"));
1950
((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
1951
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1956
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1957
fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
1958
1, &insn.operand_type[0]->immediate.imm_expr,
1960
fix->fx_no_overflow = 1;
1964
else if (insn.tm->operand_types[0] & (Imm24))
1966
/* Unconditional Branch and Call instructions. */
1967
if (insn.operand_type[0]->immediate.resolved == 1)
1969
if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
1970
as_warn (_("first operand is too large for a 24-bit displacement"));
1972
(insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
1973
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1977
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1978
fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
1979
& insn.operand_type[0]->immediate.imm_expr, 0, 0);
1982
else if (insn.tm->operand_types[0] & NotReq)
1983
/* Check for NOP instruction without arguments. */
1984
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1986
else if (insn.tm->operands == 0)
1987
/* Check for instructions without operands. */
1988
md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
1990
debug ("Addressing mode: %08X\n", insn.addressing_mode);
1994
for (i = 0; i < insn.operands; i++)
1996
if (insn.operand_type[i]->immediate.label)
1997
free (insn.operand_type[i]->immediate.label);
1998
free (insn.operand_type[i]);
2001
debug ("Final opcode: %08X\n", insn.opcode);