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