Initial vr4111 Sanitization marks.
[deliverable/binutils-gdb.git] / gas / config / tc-mn10300.c
CommitLineData
ae1b99e4 1/* tc-mn10300.c -- Assembler code for the Matsushita 10300
0f91d763 2
590c50d8 3 Copyright (C) 1996, 1997 Free Software Foundation.
0f91d763
JL
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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <ctype.h>
24#include "as.h"
25#include "subsegs.h"
ae1b99e4 26#include "opcode/mn10300.h"
0f91d763
JL
27\f
28/* Structure to hold information about predefined registers. */
29struct reg_name
30{
31 const char *name;
32 int value;
33};
34
35/* Generic assembler global variables which must be defined by all targets. */
36
37/* Characters which always start a comment. */
38const char comment_chars[] = "#";
39
40/* Characters which start a comment at the beginning of a line. */
41const char line_comment_chars[] = ";#";
42
43/* Characters which may be used to separate multiple commands on a
44 single line. */
45const char line_separator_chars[] = ";";
46
47/* Characters which are used to indicate an exponent in a floating
48 point number. */
49const char EXP_CHARS[] = "eE";
50
51/* Characters which mean that a number is a floating point constant,
52 as in 0d1.0. */
53const char FLT_CHARS[] = "dD";
54\f
55
590c50d8
ILT
56const relax_typeS md_relax_table[] = {
57 /* bCC relaxing */
58 {0x7f, -0x80, 2, 1},
59 {0x7fff, -0x8000, 5, 2},
60 {0x7fffffff, -0x80000000, 7, 0},
61
62 /* bCC relaxing (uncommon cases) */
63 {0x7f, -0x80, 3, 4},
64 {0x7fff, -0x8000, 6, 5},
65 {0x7fffffff, -0x80000000, 8, 0},
66
67 /* call relaxing */
68 {0x7fff, -0x8000, 5, 7},
69 {0x7fffffff, -0x80000000, 7, 0},
70
71 /* calls relaxing */
72 {0x7fff, -0x8000, 4, 9},
73 {0x7fffffff, -0x80000000, 6, 0},
74
75 /* jmp relaxing */
76 {0x7f, -0x80, 2, 11},
77 {0x7fff, -0x8000, 3, 12},
78 {0x7fffffff, -0x80000000, 5, 0},
79
80};
81
0f91d763 82/* local functions */
43d695a1
JL
83static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,
84 const struct mn10300_operand *,
85 offsetT, char *, unsigned,
86 unsigned));
87static unsigned long check_operand PARAMS ((unsigned long,
88 const struct mn10300_operand *,
89 offsetT));
0f91d763 90static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
ca82e4eb
JL
91static boolean data_register_name PARAMS ((expressionS *expressionP));
92static boolean address_register_name PARAMS ((expressionS *expressionP));
93static boolean other_register_name PARAMS ((expressionS *expressionP));
0f91d763
JL
94
95
96/* fixups */
97#define MAX_INSN_FIXUPS (5)
ae1b99e4 98struct mn10300_fixup
0f91d763
JL
99{
100 expressionS exp;
101 int opindex;
102 bfd_reloc_code_real_type reloc;
103};
ae1b99e4 104struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
0f91d763
JL
105static int fc;
106\f
107const char *md_shortopts = "";
108struct option md_longopts[] = {
109 {NULL, no_argument, NULL, 0}
110};
111size_t md_longopts_size = sizeof(md_longopts);
112
113/* The target specific pseudo-ops which we support. */
114const pseudo_typeS md_pseudo_table[] =
115{
116 { NULL, NULL, 0 }
117};
118
119/* Opcode hash table. */
ae1b99e4 120static struct hash_control *mn10300_hash;
0f91d763
JL
121
122/* This table is sorted. Suitable for searching by a binary search. */
1217102f 123static const struct reg_name data_registers[] =
0f91d763 124{
ca82e4eb
JL
125 { "d0", 0 },
126 { "d1", 1 },
127 { "d2", 2 },
128 { "d3", 3 },
0f91d763 129};
1217102f 130#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
0f91d763 131
1217102f 132static const struct reg_name address_registers[] =
0f91d763 133{
ca82e4eb
JL
134 { "a0", 0 },
135 { "a1", 1 },
136 { "a2", 2 },
137 { "a3", 3 },
0f91d763 138};
1217102f 139#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
0f91d763 140
1217102f 141static const struct reg_name other_registers[] =
0f91d763 142{
ca82e4eb
JL
143 { "mdr", 0 },
144 { "psw", 0 },
145 { "sp", 0 },
0f91d763 146};
1217102f 147#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
0f91d763
JL
148
149/* reg_name_search does a binary search of the given register table
150 to see if "name" is a valid regiter name. Returns the register
151 number from the array on success, or -1 on failure. */
152
153static int
154reg_name_search (regs, regcount, name)
155 const struct reg_name *regs;
156 int regcount;
157 const char *name;
158{
159 int middle, low, high;
160 int cmp;
161
162 low = 0;
163 high = regcount - 1;
164
165 do
166 {
167 middle = (low + high) / 2;
168 cmp = strcasecmp (name, regs[middle].name);
169 if (cmp < 0)
170 high = middle - 1;
171 else if (cmp > 0)
172 low = middle + 1;
173 else
174 return regs[middle].value;
175 }
176 while (low <= high);
177 return -1;
178}
179
180
181/* Summary of register_name().
182 *
183 * in: Input_line_pointer points to 1st char of operand.
184 *
185 * out: A expressionS.
186 * The operand may have been a register: in this case, X_op == O_register,
187 * X_add_number is set to the register number, and truth is returned.
188 * Input_line_pointer->(next non-blank) char after operand, or is in
189 * its original state.
190 */
191static boolean
1217102f 192data_register_name (expressionP)
0f91d763
JL
193 expressionS *expressionP;
194{
195 int reg_number;
196 char *name;
197 char *start;
198 char c;
199
200 /* Find the spelling of the operand */
201 start = name = input_line_pointer;
202
203 c = get_symbol_end ();
1217102f 204 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
0f91d763
JL
205
206 /* look to see if it's in the register table */
207 if (reg_number >= 0)
208 {
209 expressionP->X_op = O_register;
210 expressionP->X_add_number = reg_number;
211
212 /* make the rest nice */
213 expressionP->X_add_symbol = NULL;
214 expressionP->X_op_symbol = NULL;
215 *input_line_pointer = c; /* put back the delimiting char */
216 return true;
217 }
218 else
219 {
220 /* reset the line as if we had not done anything */
221 *input_line_pointer = c; /* put back the delimiting char */
222 input_line_pointer = start; /* reset input_line pointer */
223 return false;
224 }
225}
226
1217102f 227/* Summary of register_name().
0f91d763
JL
228 *
229 * in: Input_line_pointer points to 1st char of operand.
230 *
231 * out: A expressionS.
232 * The operand may have been a register: in this case, X_op == O_register,
233 * X_add_number is set to the register number, and truth is returned.
234 * Input_line_pointer->(next non-blank) char after operand, or is in
235 * its original state.
236 */
237static boolean
1217102f 238address_register_name (expressionP)
0f91d763
JL
239 expressionS *expressionP;
240{
241 int reg_number;
242 char *name;
243 char *start;
244 char c;
245
246 /* Find the spelling of the operand */
247 start = name = input_line_pointer;
248
249 c = get_symbol_end ();
1217102f 250 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
0f91d763
JL
251
252 /* look to see if it's in the register table */
253 if (reg_number >= 0)
254 {
255 expressionP->X_op = O_register;
256 expressionP->X_add_number = reg_number;
257
258 /* make the rest nice */
259 expressionP->X_add_symbol = NULL;
260 expressionP->X_op_symbol = NULL;
261 *input_line_pointer = c; /* put back the delimiting char */
262 return true;
263 }
264 else
265 {
266 /* reset the line as if we had not done anything */
267 *input_line_pointer = c; /* put back the delimiting char */
268 input_line_pointer = start; /* reset input_line pointer */
269 return false;
270 }
271}
272
1217102f 273/* Summary of register_name().
0f91d763
JL
274 *
275 * in: Input_line_pointer points to 1st char of operand.
276 *
277 * out: A expressionS.
278 * The operand may have been a register: in this case, X_op == O_register,
279 * X_add_number is set to the register number, and truth is returned.
280 * Input_line_pointer->(next non-blank) char after operand, or is in
281 * its original state.
282 */
283static boolean
1217102f 284other_register_name (expressionP)
0f91d763
JL
285 expressionS *expressionP;
286{
287 int reg_number;
288 char *name;
289 char *start;
290 char c;
291
292 /* Find the spelling of the operand */
293 start = name = input_line_pointer;
294
295 c = get_symbol_end ();
1217102f 296 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
0f91d763
JL
297
298 /* look to see if it's in the register table */
299 if (reg_number >= 0)
300 {
1217102f 301 expressionP->X_op = O_register;
0f91d763
JL
302 expressionP->X_add_number = reg_number;
303
304 /* make the rest nice */
305 expressionP->X_add_symbol = NULL;
306 expressionP->X_op_symbol = NULL;
307 *input_line_pointer = c; /* put back the delimiting char */
308 return true;
309 }
310 else
311 {
312 /* reset the line as if we had not done anything */
313 *input_line_pointer = c; /* put back the delimiting char */
314 input_line_pointer = start; /* reset input_line pointer */
315 return false;
316 }
317}
318
319void
320md_show_usage (stream)
321 FILE *stream;
322{
ae1b99e4 323 fprintf(stream, "MN10300 options:\n\
0f91d763
JL
324none yet\n");
325}
326
327int
328md_parse_option (c, arg)
329 int c;
330 char *arg;
331{
332 return 0;
333}
334
335symbolS *
336md_undefined_symbol (name)
337 char *name;
338{
339 return 0;
340}
341
342char *
343md_atof (type, litp, sizep)
344 int type;
345 char *litp;
346 int *sizep;
347{
348 int prec;
349 LITTLENUM_TYPE words[4];
350 char *t;
351 int i;
352
353 switch (type)
354 {
355 case 'f':
356 prec = 2;
357 break;
358
359 case 'd':
360 prec = 4;
361 break;
362
363 default:
364 *sizep = 0;
365 return "bad call to md_atof";
366 }
367
368 t = atof_ieee (input_line_pointer, type, words);
369 if (t)
370 input_line_pointer = t;
371
372 *sizep = prec * 2;
373
374 for (i = prec - 1; i >= 0; i--)
375 {
376 md_number_to_chars (litp, (valueT) words[i], 2);
377 litp += 2;
378 }
379
380 return NULL;
381}
382
383
384void
385md_convert_frag (abfd, sec, fragP)
386 bfd *abfd;
387 asection *sec;
388 fragS *fragP;
389{
590c50d8
ILT
390 static unsigned long label_count = 0;
391 char buf[40];
392
393 subseg_change (sec, 0);
394 if (fragP->fr_subtype == 0)
395 {
396 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
397 fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
398 fragP->fr_var = 0;
399 fragP->fr_fix += 2;
400 }
401 else if (fragP->fr_subtype == 1)
402 {
403 /* Reverse the condition of the first branch. */
404 int offset = fragP->fr_fix;
405 int opcode = fragP->fr_literal[offset] & 0xff;
406
407 switch (opcode)
408 {
409 case 0xc8:
410 opcode = 0xc9;
411 break;
412 case 0xc9:
413 opcode = 0xc8;
414 break;
415 case 0xc0:
416 opcode = 0xc2;
417 break;
418 case 0xc2:
419 opcode = 0xc0;
420 break;
421 case 0xc3:
422 opcode = 0xc1;
423 break;
424 case 0xc1:
425 opcode = 0xc3;
426 break;
427 case 0xc4:
428 opcode = 0xc6;
429 break;
430 case 0xc6:
431 opcode = 0xc4;
432 break;
433 case 0xc7:
434 opcode = 0xc5;
435 break;
436 case 0xc5:
437 opcode = 0xc7;
438 break;
439 default:
440 abort ();
441 }
442 fragP->fr_literal[offset] = opcode;
443
444 /* Create a fixup for the reversed conditional branch. */
445 sprintf (buf, "%s_%d", FAKE_LABEL_NAME, label_count++);
446 fix_new (fragP, fragP->fr_fix + 1, 1,
447 symbol_new (buf, sec, 0, fragP->fr_next),
448 fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
449
450 /* Now create the unconditional branch + fixup to the
451 final target. */
452 fragP->fr_literal[offset + 2] = 0xcc;
453 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
454 fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
455 fragP->fr_var = 0;
456 fragP->fr_fix += 5;
457 }
458 else if (fragP->fr_subtype == 2)
459 {
460 /* Reverse the condition of the first branch. */
461 int offset = fragP->fr_fix;
462 int opcode = fragP->fr_literal[offset] & 0xff;
463
464 switch (opcode)
465 {
466 case 0xc8:
467 opcode = 0xc9;
468 break;
469 case 0xc9:
470 opcode = 0xc8;
471 break;
472 case 0xc0:
473 opcode = 0xc2;
474 break;
475 case 0xc2:
476 opcode = 0xc0;
477 break;
478 case 0xc3:
479 opcode = 0xc1;
480 break;
481 case 0xc1:
482 opcode = 0xc3;
483 break;
484 case 0xc4:
485 opcode = 0xc6;
486 break;
487 case 0xc6:
488 opcode = 0xc4;
489 break;
490 case 0xc7:
491 opcode = 0xc5;
492 break;
493 case 0xc5:
494 opcode = 0xc7;
495 break;
496 default:
497 abort ();
498 }
499 fragP->fr_literal[offset] = opcode;
500
501 /* Create a fixup for the reversed conditional branch. */
502 sprintf (buf, "%s_%d", FAKE_LABEL_NAME, label_count++);
503 fix_new (fragP, fragP->fr_fix + 1, 1,
504 symbol_new (buf, sec, 0, fragP->fr_next),
505 fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
506
507 /* Now create the unconditional branch + fixup to the
508 final target. */
509 fragP->fr_literal[offset + 2] = 0xdc;
510 fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol,
511 fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
512 fragP->fr_var = 0;
513 fragP->fr_fix += 7;
514 }
515 else if (fragP->fr_subtype == 3)
516 {
517 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
518 fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
519 fragP->fr_var = 0;
520 fragP->fr_fix += 3;
521 }
522 else if (fragP->fr_subtype == 4)
523 {
524 /* Reverse the condition of the first branch. */
525 int offset = fragP->fr_fix;
526 int opcode = fragP->fr_literal[offset + 1] & 0xff;
527
528 switch (opcode)
529 {
530 case 0xe8:
531 opcode = 0xe9;
532 break;
533 case 0xe9:
534 opcode = 0xe8;
535 break;
536 case 0xea:
537 opcode = 0xeb;
538 break;
539 case 0xeb:
540 opcode = 0xea;
541 break;
542 default:
543 abort ();
544 }
545 fragP->fr_literal[offset + 1] = opcode;
546
547 /* Create a fixup for the reversed conditional branch. */
548 sprintf (buf, "%s_%d", FAKE_LABEL_NAME, label_count++);
549 fix_new (fragP, fragP->fr_fix + 2, 1,
550 symbol_new (buf, sec, 0, fragP->fr_next),
551 fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
552
553 /* Now create the unconditional branch + fixup to the
554 final target. */
555 fragP->fr_literal[offset + 3] = 0xcc;
556 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
557 fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
558 fragP->fr_var = 0;
559 fragP->fr_fix += 6;
560 }
561 else if (fragP->fr_subtype == 5)
562 {
563 /* Reverse the condition of the first branch. */
564 int offset = fragP->fr_fix;
565 int opcode = fragP->fr_literal[offset + 1] & 0xff;
566
567 switch (opcode)
568 {
569 case 0xe8:
570 opcode = 0xe9;
571 break;
572 case 0xea:
573 opcode = 0xeb;
574 break;
575 case 0xeb:
576 opcode = 0xea;
577 break;
578 default:
579 abort ();
580 }
581 fragP->fr_literal[offset + 1] = opcode;
582
583 /* Create a fixup for the reversed conditional branch. */
584 sprintf (buf, "%s_%d", FAKE_LABEL_NAME, label_count++);
585 fix_new (fragP, fragP->fr_fix + 2, 1,
586 symbol_new (buf, sec, 0, fragP->fr_next),
587 fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
588
589 /* Now create the unconditional branch + fixup to the
590 final target. */
591 fragP->fr_literal[offset + 3] = 0xdc;
592 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
593 fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
594 fragP->fr_var = 0;
595 fragP->fr_fix += 8;
596 }
597 else if (fragP->fr_subtype == 6)
598 {
599 int offset = fragP->fr_fix;
600 fragP->fr_literal[offset] = 0xcd;
601 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
602 fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
603 fragP->fr_var = 0;
604 fragP->fr_fix += 5;
605 }
606 else if (fragP->fr_subtype == 7)
607 {
608 int offset = fragP->fr_fix;
609 fragP->fr_literal[offset] = 0xdd;
610 fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3];
611 fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4];
612
613 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
614 fragP->fr_offset + 2, 1, BFD_RELOC_32_PCREL);
615 fragP->fr_var = 0;
616 fragP->fr_fix += 7;
617 }
618 else if (fragP->fr_subtype == 8)
619 {
620 int offset = fragP->fr_fix;
621 fragP->fr_literal[offset] = 0xfa;
622 fragP->fr_literal[offset + 1] = 0xff;
623 fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
624 fragP->fr_offset + 2, 1, BFD_RELOC_16_PCREL);
625 fragP->fr_var = 0;
626 fragP->fr_fix += 4;
627 }
628 else if (fragP->fr_subtype == 9)
629 {
630 int offset = fragP->fr_fix;
631 fragP->fr_literal[offset] = 0xfc;
632 fragP->fr_literal[offset + 1] = 0xff;
633
634 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
635 fragP->fr_offset + 2, 1, BFD_RELOC_32_PCREL);
636 fragP->fr_var = 0;
637 fragP->fr_fix += 6;
638 }
639 else if (fragP->fr_subtype == 10)
640 {
641 fragP->fr_literal[fragP->fr_fix] = 0xca;
642 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
643 fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
644 fragP->fr_var = 0;
645 fragP->fr_fix += 2;
646 }
647 else if (fragP->fr_subtype == 11)
648 {
649 int offset = fragP->fr_fix;
650 fragP->fr_literal[offset] = 0xcc;
651
652 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
653 fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
654 fragP->fr_var = 0;
655 fragP->fr_fix += 3;
656 }
657 else if (fragP->fr_subtype == 12)
658 {
659 int offset = fragP->fr_fix;
660 fragP->fr_literal[offset] = 0xdc;
661
662 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
663 fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
664 fragP->fr_var = 0;
665 fragP->fr_fix += 5;
666 }
667 else
668 abort ();
0f91d763
JL
669}
670
671valueT
672md_section_align (seg, addr)
673 asection *seg;
674 valueT addr;
675{
676 int align = bfd_get_section_alignment (stdoutput, seg);
677 return ((addr + (1 << align) - 1) & (-1 << align));
678}
679
680void
681md_begin ()
682{
683 char *prev_name = "";
ae1b99e4 684 register const struct mn10300_opcode *op;
0f91d763 685
ae1b99e4 686 mn10300_hash = hash_new();
0f91d763 687
ae1b99e4 688 /* Insert unique names into hash table. The MN10300 instruction set
0f91d763
JL
689 has many identical opcode names that have different opcodes based
690 on the operands. This hash table then provides a quick index to
691 the first opcode with a particular name in the opcode table. */
692
d9a9c18f 693 op = mn10300_opcodes;
0f91d763
JL
694 while (op->name)
695 {
696 if (strcmp (prev_name, op->name))
697 {
698 prev_name = (char *) op->name;
ae1b99e4 699 hash_insert (mn10300_hash, op->name, (char *) op);
0f91d763
JL
700 }
701 op++;
702 }
d9a9c18f
JL
703
704 /* This is both a simplification (we don't have to write md_apply_fix)
705 and support for future optimizations (branch shortening and similar
706 stuff in the linker. */
707 linkrelax = 1;
0f91d763
JL
708}
709
0f91d763
JL
710void
711md_assemble (str)
712 char *str;
713{
714 char *s;
ae1b99e4
JL
715 struct mn10300_opcode *opcode;
716 struct mn10300_opcode *next_opcode;
0f91d763 717 const unsigned char *opindex_ptr;
590c50d8 718 int next_opindex, relaxable;
ca82e4eb 719 unsigned long insn, extension, size = 0;
0f91d763
JL
720 char *f;
721 int i;
722 int match;
0f91d763
JL
723
724 /* Get the opcode. */
725 for (s = str; *s != '\0' && ! isspace (*s); s++)
726 ;
727 if (*s != '\0')
728 *s++ = '\0';
729
730 /* find the first opcode with the proper name */
ae1b99e4 731 opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
0f91d763
JL
732 if (opcode == NULL)
733 {
734 as_bad ("Unrecognized opcode: `%s'", str);
735 return;
736 }
737
738 str = s;
739 while (isspace (*str))
740 ++str;
741
742 input_line_pointer = str;
743
744 for(;;)
745 {
746 const char *errmsg = NULL;
1217102f 747 int op_idx;
1217102f 748 char *hold;
68328dc6 749 int extra_shift = 0;
0f91d763 750
590c50d8 751 relaxable = 0;
0f91d763
JL
752 fc = 0;
753 match = 0;
754 next_opindex = 0;
755 insn = opcode->opcode;
bfe5059c 756 extension = 0;
1217102f
JL
757 for (op_idx = 1, opindex_ptr = opcode->operands;
758 *opindex_ptr != 0;
759 opindex_ptr++, op_idx++)
0f91d763 760 {
ae1b99e4 761 const struct mn10300_operand *operand;
0f91d763
JL
762 expressionS ex;
763
764 if (next_opindex == 0)
765 {
ae1b99e4 766 operand = &mn10300_operands[*opindex_ptr];
0f91d763
JL
767 }
768 else
769 {
ae1b99e4 770 operand = &mn10300_operands[next_opindex];
0f91d763
JL
771 next_opindex = 0;
772 }
773
774 errmsg = NULL;
775
7f02192d 776 while (*str == ' ' || *str == ',')
0f91d763
JL
777 ++str;
778
590c50d8
ILT
779 if (operand->flags & MN10300_OPERAND_RELAX)
780 relaxable = 1;
781
0f91d763
JL
782 /* Gather the operand. */
783 hold = input_line_pointer;
784 input_line_pointer = str;
785
a6be605a
JL
786 if (operand->flags & MN10300_OPERAND_PAREN)
787 {
788 if (*input_line_pointer != ')' && *input_line_pointer != '(')
789 {
790 input_line_pointer = hold;
791 str = hold;
792 goto error;
793 }
1217102f 794 input_line_pointer++;
a6be605a 795 goto keep_going;
1217102f 796 }
1217102f 797 /* See if we can match the operands. */
a6be605a 798 else if (operand->flags & MN10300_OPERAND_DREG)
0f91d763 799 {
1217102f 800 if (!data_register_name (&ex))
0f91d763 801 {
1217102f
JL
802 input_line_pointer = hold;
803 str = hold;
0f91d763
JL
804 goto error;
805 }
1217102f
JL
806 }
807 else if (operand->flags & MN10300_OPERAND_AREG)
808 {
809 if (!address_register_name (&ex))
0f91d763 810 {
1217102f
JL
811 input_line_pointer = hold;
812 str = hold;
813 goto error;
0f91d763 814 }
1217102f
JL
815 }
816 else if (operand->flags & MN10300_OPERAND_SP)
817 {
818 char *start = input_line_pointer;
819 char c = get_symbol_end ();
820
821 if (strcmp (start, "sp") != 0)
822 {
823 *input_line_pointer = c;
824 input_line_pointer = hold;
825 str = hold;
826 goto error;
827 }
828 *input_line_pointer = c;
829 goto keep_going;
830 }
831 else if (operand->flags & MN10300_OPERAND_PSW)
832 {
833 char *start = input_line_pointer;
834 char c = get_symbol_end ();
835
836 if (strcmp (start, "psw") != 0)
0f91d763 837 {
1217102f
JL
838 *input_line_pointer = c;
839 input_line_pointer = hold;
840 str = hold;
841 goto error;
842 }
843 *input_line_pointer = c;
844 goto keep_going;
845 }
846 else if (operand->flags & MN10300_OPERAND_MDR)
847 {
848 char *start = input_line_pointer;
849 char c = get_symbol_end ();
0f91d763 850
1217102f
JL
851 if (strcmp (start, "mdr") != 0)
852 {
853 *input_line_pointer = c;
854 input_line_pointer = hold;
855 str = hold;
856 goto error;
0f91d763 857 }
1217102f
JL
858 *input_line_pointer = c;
859 goto keep_going;
860 }
7f02192d
JL
861 else if (operand->flags & MN10300_OPERAND_REG_LIST)
862 {
863 unsigned int value = 0;
864 if (*input_line_pointer != '[')
865 {
866 input_line_pointer = hold;
867 str = hold;
868 goto error;
869 }
870
871 /* Eat the '['. */
872 input_line_pointer++;
873
874 /* A null register list can not be specified. */
875 if (*input_line_pointer == ']')
876 {
877 input_line_pointer = hold;
878 str = hold;
879 goto error;
880 }
881
882 while (*input_line_pointer != ']')
883 {
884 char *start;
885 char c;
886
887 if (*input_line_pointer == ',')
888 input_line_pointer++;
889
890 start = input_line_pointer;
891 c = get_symbol_end ();
892
ca82e4eb 893 if (strcmp (start, "d2") == 0)
7f02192d
JL
894 {
895 value |= 0x80;
896 *input_line_pointer = c;
897 }
ca82e4eb 898 else if (strcmp (start, "d3") == 0)
7f02192d
JL
899 {
900 value |= 0x40;
901 *input_line_pointer = c;
902 }
ca82e4eb 903 else if (strcmp (start, "a2") == 0)
7f02192d
JL
904 {
905 value |= 0x20;
906 *input_line_pointer = c;
907 }
ca82e4eb 908 else if (strcmp (start, "a3") == 0)
7f02192d
JL
909 {
910 value |= 0x10;
911 *input_line_pointer = c;
912 }
ca82e4eb 913 else if (strcmp (start, "other") == 0)
7f02192d
JL
914 {
915 value |= 0x08;
916 *input_line_pointer = c;
917 }
918 else
919 {
920 input_line_pointer = hold;
921 str = hold;
922 goto error;
923 }
924 }
925 input_line_pointer++;
926 mn10300_insert_operand (&insn, &extension, operand,
927 value, (char *) NULL, 0, 0);
928 goto keep_going;
929
930 }
1217102f
JL
931 else if (data_register_name (&ex))
932 {
933 input_line_pointer = hold;
934 str = hold;
935 goto error;
936 }
937 else if (address_register_name (&ex))
938 {
939 input_line_pointer = hold;
940 str = hold;
941 goto error;
942 }
943 else if (other_register_name (&ex))
944 {
945 input_line_pointer = hold;
946 str = hold;
947 goto error;
0f91d763 948 }
a6be605a
JL
949 else if (*str == ')' || *str == '(')
950 {
951 input_line_pointer = hold;
952 str = hold;
953 goto error;
954 }
0f91d763
JL
955 else
956 {
1217102f
JL
957 expression (&ex);
958 }
959
0f91d763
JL
960 switch (ex.X_op)
961 {
962 case O_illegal:
963 errmsg = "illegal operand";
964 goto error;
965 case O_absent:
966 errmsg = "missing operand";
967 goto error;
968 case O_register:
ca82e4eb
JL
969 if ((operand->flags
970 & (MN10300_OPERAND_DREG | MN10300_OPERAND_AREG)) == 0)
1217102f
JL
971 {
972 input_line_pointer = hold;
973 str = hold;
974 goto error;
975 }
0f91d763 976
68328dc6
JL
977 if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
978 extra_shift = 8;
979 else if (opcode->format == FMT_D2 || opcode->format == FMT_D4
980 || opcode->format == FMT_S2 || opcode->format == FMT_S4
981 || opcode->format == FMT_S6 || opcode->format == FMT_D5)
982 extra_shift = 16;
983 else
984 extra_shift = 0;
985
bfe5059c
JL
986 mn10300_insert_operand (&insn, &extension, operand,
987 ex.X_add_number, (char *) NULL,
988 0, extra_shift);
68328dc6 989
0f91d763
JL
990 break;
991
992 case O_constant:
1217102f
JL
993 /* If this operand can be promoted, and it doesn't
994 fit into the allocated bitfield for this insn,
995 then promote it (ie this opcode does not match). */
590c50d8
ILT
996 if (operand->flags
997 & (MN10300_OPERAND_PROMOTE | MN10300_OPERAND_RELAX)
1217102f
JL
998 && ! check_operand (insn, operand, ex.X_add_number))
999 {
1000 input_line_pointer = hold;
1001 str = hold;
1002 goto error;
1003 }
1004
bfe5059c
JL
1005 mn10300_insert_operand (&insn, &extension, operand,
1006 ex.X_add_number, (char *) NULL,
1007 0, 0);
0f91d763
JL
1008 break;
1009
1010 default:
1217102f
JL
1011 /* If this operand can be promoted, then this opcode didn't
1012 match since we can't know if it needed promotion! */
1013 if (operand->flags & MN10300_OPERAND_PROMOTE)
1014 {
1015 input_line_pointer = hold;
1016 str = hold;
1017 goto error;
1018 }
1019
0f91d763
JL
1020 /* We need to generate a fixup for this expression. */
1021 if (fc >= MAX_INSN_FIXUPS)
1022 as_fatal ("too many fixups");
1023 fixups[fc].exp = ex;
1024 fixups[fc].opindex = *opindex_ptr;
1025 fixups[fc].reloc = BFD_RELOC_UNUSED;
1026 ++fc;
1027 break;
1028 }
1029
1217102f 1030keep_going:
0f91d763
JL
1031 str = input_line_pointer;
1032 input_line_pointer = hold;
1033
7f02192d 1034 while (*str == ' ' || *str == ',')
0f91d763 1035 ++str;
1217102f 1036
1217102f 1037 }
a6be605a
JL
1038
1039 /* Make sure we used all the operands! */
1040 if (*str != ',')
1217102f 1041 match = 1;
0f91d763
JL
1042
1043 error:
1044 if (match == 0)
1045 {
1046 next_opcode = opcode + 1;
42aa2435 1047 if (!strcmp(next_opcode->name, opcode->name))
0f91d763
JL
1048 {
1049 opcode = next_opcode;
1050 continue;
1051 }
1052
1053 as_bad ("%s", errmsg);
1054 return;
1055 }
1056 break;
1057 }
1058
1059 while (isspace (*str))
1060 ++str;
1061
1062 if (*str != '\0')
1063 as_bad ("junk at end of line: `%s'", str);
1064
1065 input_line_pointer = str;
1066
778c521b
JL
1067 /* Determine the size of the instruction. */
1068 if (opcode->format == FMT_S0)
1217102f 1069 size = 1;
0f91d763 1070
778c521b 1071 if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
0f91d763 1072 size = 2;
0f91d763 1073
778c521b 1074 if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
1217102f 1075 size = 3;
0f91d763 1076
778c521b 1077 if (opcode->format == FMT_S4)
1217102f 1078 size = 5;
0f91d763 1079
778c521b 1080 if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
1217102f 1081 size = 7;
0f91d763 1082
778c521b 1083 if (opcode->format == FMT_D2)
1217102f 1084 size = 4;
0f91d763 1085
778c521b 1086 if (opcode->format == FMT_D4)
1217102f
JL
1087 size = 6;
1088
590c50d8 1089 if (relaxable && fc > 0)
8ca71631 1090 {
590c50d8
ILT
1091 int type;
1092
1093 /* bCC */
1094 if (size == 2)
1095 type = 0;
1096 /* call */
1097 else if (size == 5)
1098 type = 6;
1099 /* calls */
1100 else if (size == 4)
1101 type = 8;
1102 /* jmp */
1103 else if (size == 3 && opcode->opcode == 0xcc0000)
1104 type = 10;
1105 /* bCC (uncommon cases) */
1106 else
1107 type = 3;
d9a9c18f 1108
590c50d8
ILT
1109 f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1110 fixups[0].exp.X_add_symbol,
1111 fixups[0].exp.X_add_number,
1112 (char *)fixups[0].opindex);
1113
1114 /* This is pretty hokey. We basically just care about the
1115 opcode, so we have to write out the first word big endian.
1116
1117 The exception is "call", which has two operands that we
1118 care about.
1119
1120 The first operand (the register list) happens to be in the
1121 first instruction word, and will be in the right place if
1122 we output the first word in big endian mode.
1123
1124 The second operand (stack size) is in the extension word,
1125 and we want it to appear as the first character in the extension
1126 word (as it appears in memory). Luckily, writing the extension
1127 word in big endian format will do what we want. */
1128 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1129 if (size > 8)
1130 {
1131 number_to_chars_bigendian (f + 4, extension, 4);
1132 number_to_chars_bigendian (f + 8, 0, size - 8);
1133 }
1134 else if (size > 4)
1135 number_to_chars_bigendian (f + 4, extension, size - 4);
1136 }
1137 else
d9a9c18f 1138 {
590c50d8
ILT
1139 /* Allocate space for the instruction. */
1140 f = frag_more (size);
1141
1142 /* Fill in bytes for the instruction. Note that opcode fields
1143 are written big-endian, 16 & 32bit immediates are written
1144 little endian. Egad. */
1145 if (opcode->format == FMT_S0
1146 || opcode->format == FMT_S1
1147 || opcode->format == FMT_D0
1148 || opcode->format == FMT_D1)
1149 {
1150 number_to_chars_bigendian (f, insn, size);
1151 }
1152 else if (opcode->format == FMT_S2
1153 && opcode->opcode != 0xdf0000
1154 && opcode->opcode != 0xde0000)
1155 {
1156 /* A format S2 instruction that is _not_ "ret" and "retf". */
1157 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1158 number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1159 }
1160 else if (opcode->format == FMT_S2)
1161 {
1162 /* This must be a ret or retf, which is written entirely in
1163 big-endian format. */
1164 number_to_chars_bigendian (f, insn, 3);
1165 }
1166 else if (opcode->format == FMT_S4
1167 && opcode->opcode != 0xdc000000)
1168 {
1169 /* This must be a format S4 "call" instruction. What a pain. */
1170 unsigned long temp = (insn >> 8) & 0xffff;
1171 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1172 number_to_chars_littleendian (f + 1, temp, 2);
1173 number_to_chars_bigendian (f + 3, insn & 0xff, 1);
1174 number_to_chars_bigendian (f + 4, extension & 0xff, 1);
1175 }
1176 else if (opcode->format == FMT_S4)
1177 {
1178 /* This must be a format S4 "jmp" instruction. */
1179 unsigned long temp = ((insn & 0xffffff) << 8) | (extension & 0xff);
1180 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1181 number_to_chars_littleendian (f + 1, temp, 4);
1182 }
1183 else if (opcode->format == FMT_S6)
1184 {
1185 unsigned long temp = ((insn & 0xffffff) << 8)
1186 | ((extension >> 16) & 0xff);
1187 number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1188 number_to_chars_littleendian (f + 1, temp, 4);
1189 number_to_chars_bigendian (f + 5, (extension >> 8) & 0xff, 1);
1190 number_to_chars_bigendian (f + 6, extension & 0xff, 1);
1191 }
1192 else if (opcode->format == FMT_D2
1193 && opcode->opcode != 0xfaf80000
1194 && opcode->opcode != 0xfaf00000
1195 && opcode->opcode != 0xfaf40000)
1196 {
1197 /* A format D2 instruction where the 16bit immediate is
1198 really a single 16bit value, not two 8bit values. */
1199 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1200 number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1201 }
1202 else if (opcode->format == FMT_D2)
1203 {
1204 /* A format D2 instruction where the 16bit immediate
1205 is really two 8bit immediates. */
1206 number_to_chars_bigendian (f, insn, 4);
1207 }
1208 else if (opcode->format == FMT_D4)
1209 {
1210 unsigned long temp = ((insn & 0xffff) << 16) | (extension & 0xffff);
1211 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1212 number_to_chars_littleendian (f + 2, temp, 4);
1213 }
1214 else if (opcode->format == FMT_D5)
1215 {
1216 unsigned long temp = ((insn & 0xffff) << 16)
1217 | ((extension >> 8) & 0xffff);
1218 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1219 number_to_chars_littleendian (f + 2, temp, 4);
1220 number_to_chars_bigendian (f + 6, extension & 0xff, 1);
1221 }
d9a9c18f 1222
590c50d8
ILT
1223 /* Create any fixups. */
1224 for (i = 0; i < fc; i++)
d9a9c18f 1225 {
590c50d8
ILT
1226 const struct mn10300_operand *operand;
1227
1228 operand = &mn10300_operands[fixups[i].opindex];
1229 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1230 {
1231 reloc_howto_type *reloc_howto;
1232 int size;
1233 int offset;
1234 fixS *fixP;
d9a9c18f 1235
590c50d8 1236 reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
d9a9c18f 1237
590c50d8
ILT
1238 if (!reloc_howto)
1239 abort();
d9a9c18f 1240
590c50d8 1241 size = bfd_get_reloc_size (reloc_howto);
d9a9c18f 1242
590c50d8
ILT
1243 if (size < 1 || size > 4)
1244 abort();
d9a9c18f 1245
590c50d8
ILT
1246 offset = 4 - size;
1247 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1248 size, &fixups[i].exp,
1249 reloc_howto->pc_relative,
1250 fixups[i].reloc);
1251 }
d9a9c18f 1252 else
590c50d8
ILT
1253 {
1254 int reloc, pcrel, reloc_size, offset;
1255 fixS *fixP;
1256
1257 reloc = BFD_RELOC_NONE;
1258 /* How big is the reloc? Remember SPLIT relocs are
1259 implicitly 32bits. */
1260 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1261 reloc_size = 32;
1262 else
1263 reloc_size = operand->bits;
1264
1265 /* Is the reloc pc-relative? */
1266 pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
1267
1268 /* Gross. This disgusting hack is to make sure we
1269 get the right offset for the 16/32 bit reloc in
1270 "call" instructions. Basically they're a pain
1271 because the reloc isn't at the end of the instruction. */
1272 if ((size == 5 || size == 7)
1273 && (((insn >> 24) & 0xff) == 0xcd
1274 || ((insn >> 24) & 0xff) == 0xdd))
1275 size -= 2;
1276
1277 /* Similarly for certain bit instructions which don't
1278 hav their 32bit reloc at the tail of the instruction. */
1279 if (size == 7
1280 && (((insn >> 16) & 0xffff) == 0xfe00
1281 || ((insn >> 16) & 0xffff) == 0xfe01
1282 || ((insn >> 16) & 0xffff) == 0xfe02))
1283 size -= 1;
d9a9c18f 1284
590c50d8 1285 offset = size - reloc_size / 8;
d9a9c18f 1286
590c50d8
ILT
1287 /* Choose a proper BFD relocation type. */
1288 if (pcrel)
1289 {
1290 if (reloc_size == 32)
1291 reloc = BFD_RELOC_32_PCREL;
1292 else if (reloc_size == 16)
1293 reloc = BFD_RELOC_16_PCREL;
1294 else if (reloc_size == 8)
1295 reloc = BFD_RELOC_8_PCREL;
1296 else
1297 abort ();
1298 }
d9a9c18f 1299 else
590c50d8
ILT
1300 {
1301 if (reloc_size == 32)
1302 reloc = BFD_RELOC_32;
1303 else if (reloc_size == 16)
1304 reloc = BFD_RELOC_16;
1305 else if (reloc_size == 8)
1306 reloc = BFD_RELOC_8;
1307 else
1308 abort ();
1309 }
1310
1311 /* Convert the size of the reloc into what fix_new_exp wants. */
1312 reloc_size = reloc_size / 8;
1313 if (reloc_size == 8)
1314 reloc_size = 0;
d9a9c18f 1315 else if (reloc_size == 16)
590c50d8
ILT
1316 reloc_size = 1;
1317 else if (reloc_size == 32)
1318 reloc_size = 2;
1319
1320 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1321 reloc_size, &fixups[i].exp, pcrel,
1322 ((bfd_reloc_code_real_type) reloc));
d9a9c18f 1323
590c50d8
ILT
1324 if (pcrel)
1325 fixP->fx_offset += offset;
1326 }
d9a9c18f
JL
1327 }
1328 }
0f91d763
JL
1329}
1330
1331
1332/* if while processing a fixup, a reloc really needs to be created */
1333/* then it is done here */
1334
1335arelent *
1336tc_gen_reloc (seg, fixp)
1337 asection *seg;
1338 fixS *fixp;
1339{
1340 arelent *reloc;
590c50d8 1341 reloc = (arelent *) xmalloc (sizeof (arelent));
a405bb3e 1342
0f91d763
JL
1343 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1344 if (reloc->howto == (reloc_howto_type *) NULL)
1345 {
1346 as_bad_where (fixp->fx_file, fixp->fx_line,
a405bb3e
JL
1347 "reloc %d not supported by object file format",
1348 (int)fixp->fx_r_type);
0f91d763
JL
1349 return NULL;
1350 }
a405bb3e
JL
1351 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1352
1353 if (fixp->fx_addsy && fixp->fx_subsy)
1354 {
1355 reloc->sym_ptr_ptr = &bfd_abs_symbol;
1356 reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
1357 - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
1358 }
1359 else
1360 {
1361 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1362 reloc->addend = fixp->fx_offset;
1363 }
0f91d763
JL
1364 return reloc;
1365}
1366
1367int
1368md_estimate_size_before_relax (fragp, seg)
1369 fragS *fragp;
1370 asection *seg;
1371{
590c50d8
ILT
1372 if (fragp->fr_subtype == 0)
1373 return 2;
1374 if (fragp->fr_subtype == 3)
1375 return 3;
1376 if (fragp->fr_subtype == 6)
1377 {
1378 if (!S_IS_DEFINED (fragp->fr_symbol)
1379 || seg != S_GET_SEGMENT (fragp->fr_symbol))
1380 {
1381 fragp->fr_subtype = 7;
1382 return 7;
1383 }
1384 else
1385 return 5;
1386 }
1387 if (fragp->fr_subtype == 8)
1388 {
1389 if (!S_IS_DEFINED (fragp->fr_symbol)
1390 || seg != S_GET_SEGMENT (fragp->fr_symbol))
1391 {
1392 fragp->fr_subtype = 9;
1393 return 6;
1394 }
1395 else
1396 return 4;
1397 }
1398 if (fragp->fr_subtype == 10)
1399 {
1400 if (!S_IS_DEFINED (fragp->fr_symbol)
1401 || seg != S_GET_SEGMENT (fragp->fr_symbol))
1402 {
1403 fragp->fr_subtype = 12;
1404 return 5;
1405 }
1406 else
1407 return 2;
1408 }
0f91d763
JL
1409}
1410
1411long
1412md_pcrel_from (fixp)
1413 fixS *fixp;
1414{
0671e7f6
JL
1415 return fixp->fx_frag->fr_address;
1416#if 0
0f91d763
JL
1417 if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
1418 {
1419 /* The symbol is undefined. Let the linker figure it out. */
1420 return 0;
1421 }
1422 return fixp->fx_frag->fr_address + fixp->fx_where;
0671e7f6 1423#endif
0f91d763
JL
1424}
1425
1426int
1427md_apply_fix3 (fixp, valuep, seg)
1428 fixS *fixp;
1429 valueT *valuep;
1430 segT seg;
1431{
d9a9c18f
JL
1432 /* We shouldn't ever get here because linkrelax is nonzero. */
1433 abort ();
1217102f
JL
1434 fixp->fx_done = 1;
1435 return 0;
0f91d763
JL
1436}
1437
0f91d763
JL
1438/* Insert an operand value into an instruction. */
1439
bfe5059c
JL
1440static void
1441mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1442 unsigned long *insnp;
1443 unsigned long *extensionp;
ae1b99e4 1444 const struct mn10300_operand *operand;
0f91d763
JL
1445 offsetT val;
1446 char *file;
1447 unsigned int line;
68328dc6 1448 unsigned int shift;
0f91d763 1449{
43d695a1
JL
1450 /* No need to check 32bit operands for a bit. Note that
1451 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
1452 if (operand->bits != 32
1453 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
0f91d763
JL
1454 {
1455 long min, max;
1456 offsetT test;
1457
1217102f
JL
1458 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1459 {
1460 max = (1 << (operand->bits - 1)) - 1;
1461 min = - (1 << (operand->bits - 1));
1462 }
1463 else
0f91d763
JL
1464 {
1465 max = (1 << operand->bits) - 1;
1466 min = 0;
1467 }
1468
1469 test = val;
1470
1471
1472 if (test < (offsetT) min || test > (offsetT) max)
1473 {
1474 const char *err =
1475 "operand out of range (%s not between %ld and %ld)";
1476 char buf[100];
1477
1478 sprint_value (buf, test);
1479 if (file == (char *) NULL)
1480 as_warn (err, buf, min, max);
1481 else
1482 as_warn_where (file, line, err, buf, min, max);
1483 }
1484 }
1485
cdde2f5c
JL
1486 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1487 {
ca82e4eb 1488 *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1);
43d695a1
JL
1489 *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1))
1490 << operand->shift);
cdde2f5c
JL
1491 }
1492 else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
bfe5059c
JL
1493 {
1494 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1495 << (operand->shift + shift));
1496
1497 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1498 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1499 << (operand->shift + shift + 2));
1500 }
1501 else
1502 {
1503 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1504 << (operand->shift + shift));
68328dc6 1505
bfe5059c
JL
1506 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1507 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1508 << (operand->shift + shift + 2));
1509 }
0f91d763 1510}
1217102f
JL
1511
1512static unsigned long
1513check_operand (insn, operand, val)
1514 unsigned long insn;
1515 const struct mn10300_operand *operand;
1516 offsetT val;
1517{
43d695a1
JL
1518 /* No need to check 32bit operands for a bit. Note that
1519 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
1520 if (operand->bits != 32
1521 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
1217102f
JL
1522 {
1523 long min, max;
1524 offsetT test;
1525
1526 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1527 {
1528 max = (1 << (operand->bits - 1)) - 1;
1529 min = - (1 << (operand->bits - 1));
1530 }
1531 else
1532 {
1533 max = (1 << operand->bits) - 1;
1534 min = 0;
1535 }
1536
1537 test = val;
1538
1539
1540 if (test < (offsetT) min || test > (offsetT) max)
1541 return 0;
1542 else
1543 return 1;
1544 }
1545 return 1;
1546}
This page took 0.164304 seconds and 4 git commands to generate.