Updated Vietnamese translation.
[deliverable/binutils-gdb.git] / gas / config / tc-w65.c
CommitLineData
252b5132 1/* tc-w65.c -- Assemble code for the W65816
2132e3a3
AM
2 Copyright 1995, 1998, 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
8098403c 22/* Written By Steve Chamberlain <sac@cygnus.com>. */
252b5132
RH
23
24#include <stdio.h>
25#include "as.h"
26#include "bfd.h"
27#include "subsegs.h"
28#define DEFINE_TABLE
29#include "../opcodes/w65-opc.h"
252b5132
RH
30
31const char comment_chars[] = "!";
5a38dc70 32const char line_separator_chars[] = ";";
252b5132
RH
33const char line_comment_chars[] = "!#";
34
35/* This table describes all the machine specific pseudo-ops the assembler
36 has to support. The fields are:
8098403c 37
252b5132
RH
38 pseudo-op name without dot
39 function to call to execute this pseudo-op
8098403c 40 Integer arg to pass to the function */
252b5132
RH
41
42#define OP_BCC 0x90
43#define OP_BCS 0xB0
44#define OP_BEQ 0xF0
45#define OP_BMI 0x30
46#define OP_BNE 0xD0
47#define OP_BPL 0x10
48#define OP_BRA 0x80
49#define OP_BRL 0x82
50#define OP_BVC 0x50
51#define OP_BVS 0x70
52
6297c1fe
AM
53static void s_longa PARAMS ((int));
54static char *parse_exp PARAMS ((char *));
55static char *get_operands PARAMS ((const struct opinfo *, char *));
56static const struct opinfo *get_specific PARAMS ((const struct opinfo *));
57static void build_Mytes PARAMS ((const struct opinfo *));
58
19d63e5d
KH
59
60const pseudo_typeS md_pseudo_table[] = {
252b5132
RH
61 {"int", cons, 2},
62 {"word", cons, 2},
63 {"longa", s_longa, 0},
64 {"longi", s_longa, 1},
65 {0, 0, 0}
66};
67
252b5132
RH
68const char EXP_CHARS[] = "eE";
69
19d63e5d 70/* Chars that mean this number is a floating point constant. */
252b5132
RH
71/* As in 0f12.456 */
72/* or 0d1.2345e12 */
73const char FLT_CHARS[] = "rRsSfFdDxXpP";
74
19d63e5d
KH
75/* Opcode mnemonics */
76static struct hash_control *opcode_hash_control;
252b5132
RH
77
78int M; /* M flag */
79int X; /* X flag */
80
252b5132
RH
81#define C(a,b) ENCODE_RELAX(a,b)
82#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
83
84#define GET_WHAT(x) ((x>>2))
85
86#define BYTE_DISP 1
87#define WORD_DISP 2
88#define UNDEF_BYTE_DISP 0
89#define UNDEF_WORD_DISP 3
90
91#define COND_BRANCH 1
92#define UNCOND_BRANCH 2
93#define END 3
94
95#define BYTE_F 127 /* How far we can branch forwards */
96#define BYTE_B -126 /* How far we can branch backwards */
97#define WORD_F 32767
98#define WORD_B 32768
99
e66457fb
AM
100relax_typeS md_relax_table[C (END, 0)] = {
101 { 0, 0, 0, 0 },
102 { 0, 0, 0, 0 },
103 { 0, 0, 0, 0 },
104 { 0, 0, 0, 0 },
105
106 /* COND_BRANCH */
107 { 0, 0, 0, 0 }, /* UNDEF_BYTE_DISP */
108 { BYTE_F, BYTE_B, 2, C (COND_BRANCH, WORD_DISP) }, /* BYTE_DISP */
109 { WORD_F, WORD_B, 5, 0 }, /* WORD_DISP */
110 { 0, 0, 5, 0 }, /* UNDEF_WORD_DISP */
111
112 /* UNCOND_BRANCH */
113 { 0, 0, 0, 0 }, /* UNDEF_BYTE_DISP */
114 { BYTE_F, BYTE_B, 2, C (UNCOND_BRANCH, WORD_DISP) }, /* BYTE_DISP */
115 { WORD_F, WORD_B, 3, 0 }, /* WORD_DISP */
116 { 0, 0, 3, 0 } /* UNDEF_WORD_DISP */
117
118};
252b5132 119
8098403c
NC
120/* This function is called once, at assembler startup time. This
121 should set up all the tables, etc that the MD part of the assembler
122 needs. */
252b5132 123
6297c1fe 124static void
252b5132 125s_longa (xmode)
6297c1fe 126 int xmode;
252b5132
RH
127{
128 int *p = xmode ? &X : &M;
129 while (*input_line_pointer == ' ')
130 input_line_pointer++;
131 if (strncmp (input_line_pointer, "on", 2) == 0)
132 {
133 input_line_pointer += 2;
134 *p = 0;
135 }
136 else if (strncmp (input_line_pointer, "off", 3) == 0)
137 {
138 *p = 1;
139 input_line_pointer += 3;
140 }
141 else
142 as_bad (_("need on or off."));
143 demand_empty_rest_of_line ();
144}
8098403c 145
252b5132
RH
146void
147md_begin ()
148{
6297c1fe 149 const struct opinfo *opcode;
252b5132
RH
150 char *prev_name = "";
151
152 opcode_hash_control = hash_new ();
153
8098403c 154 /* Insert unique names into hash table. */
252b5132
RH
155 for (opcode = optable; opcode->name; opcode++)
156 {
157 if (strcmp (prev_name, opcode->name))
158 {
159 prev_name = opcode->name;
160 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
161 }
252b5132
RH
162 }
163
252b5132
RH
164 flag_signed_overflow_ok = 1;
165}
166
167static expressionS immediate; /* absolute expression */
168static expressionS immediate1; /* absolute expression */
252b5132
RH
169int expr_size;
170int expr_shift;
171int tc_cons_reloc;
8098403c 172
252b5132 173void
6297c1fe 174w65_expression (dest)
252b5132 175 expressionS *dest;
252b5132
RH
176{
177 expr_size = 0;
178 expr_shift = 0;
179 tc_cons_reloc = 0;
180 while (*input_line_pointer == ' ')
181 input_line_pointer++;
182
183 if (*input_line_pointer == '<')
184 {
185 expr_size = 1;
186 input_line_pointer++;
187 }
188 else if (*input_line_pointer == '>')
189 {
190 expr_shift = 1;
191 input_line_pointer++;
192 }
193 else if (*input_line_pointer == '^')
194 {
195 expr_shift = 2;
196 input_line_pointer++;
197 }
198
199 expr (0, dest);
200}
201
202int amode;
8098403c
NC
203
204static char *
6297c1fe 205parse_exp (s)
252b5132 206 char *s;
252b5132
RH
207{
208 char *save;
209 char *new;
210
211 save = input_line_pointer;
212 input_line_pointer = s;
6297c1fe 213 w65_expression (&immediate);
252b5132
RH
214 if (immediate.X_op == O_absent)
215 as_bad (_("missing operand"));
216 new = input_line_pointer;
217 input_line_pointer = save;
218 return new;
219}
220
8098403c 221static char *
252b5132 222get_operands (info, ptr)
6297c1fe 223 const struct opinfo *info;
252b5132
RH
224 char *ptr;
225{
226 register int override_len = 0;
227 register int bytes = 0;
8098403c 228
252b5132
RH
229 while (*ptr == ' ')
230 ptr++;
231
232 if (ptr[0] == '#')
233 {
234 ptr++;
235 switch (info->amode)
236 {
237 case ADDR_IMMTOI:
238 bytes = X ? 1 : 2;
239 amode = ADDR_IMMTOI;
240 break;
241 case ADDR_IMMTOA:
242 bytes = M ? 1 : 2;
243 amode = ADDR_IMMTOA;
244 break;
245 case ADDR_IMMCOP:
246 bytes = 1;
247 amode = ADDR_IMMCOP;
248 break;
249 case ADDR_DIR:
250 bytes = 2;
251 amode = ADDR_ABS;
252 break;
253 default:
254 abort ();
255 break;
256 }
257 ptr = parse_exp (ptr);
258 }
259 else if (ptr[0] == '!')
260 {
261 ptr = parse_exp (ptr + 1);
262 if (ptr[0] == ',')
263 {
264 if (ptr[1] == 'y')
265 {
266 amode = ADDR_ABS_IDX_Y;
267 bytes = 2;
268 ptr += 2;
269 }
270 else if (ptr[1] == 'x')
271 {
272 amode = ADDR_ABS_IDX_X;
273 bytes = 2;
274 ptr += 2;
275 }
276 else
277 {
278 as_bad (_("syntax error after <exp"));
279 }
280 }
281 else
282 {
283 amode = ADDR_ABS;
284 bytes = 2;
285 }
286 }
287 else if (ptr[0] == '>')
288 {
289 ptr = parse_exp (ptr + 1);
290 if (ptr[0] == ',' && ptr[1] == 'x')
291 {
292 amode = ADDR_ABS_LONG_IDX_X;
293 bytes = 3;
294 ptr += 2;
295 }
296 else
297 {
298 amode = ADDR_ABS_LONG;
299 bytes = 3;
300 }
301 }
302 else if (ptr[0] == '<')
303 {
304 ptr = parse_exp (ptr + 1);
305 if (ptr[0] == ',')
306 {
307 if (ptr[1] == 'y')
308 {
309 amode = ADDR_DIR_IDX_Y;
310 ptr += 2;
311 bytes = 2;
312 }
313 else if (ptr[1] == 'x')
314 {
315 amode = ADDR_DIR_IDX_X;
316 ptr += 2;
317 bytes = 2;
318 }
319 else
320 {
321 as_bad (_("syntax error after <exp"));
322 }
323 }
324 else
325 {
326 amode = ADDR_DIR;
327 bytes = 1;
328 }
329 }
330 else if (ptr[0] == 'a')
331 {
332 amode = ADDR_ACC;
333 }
334 else if (ptr[0] == '(')
335 {
336 /* Look for (exp),y
337 (<exp),y
338 (exp,x)
339 (<exp,x)
340 (exp)
341 (!exp)
342 (exp)
343 (<exp)
344 (exp,x)
345 (!exp,x)
346 (exp,s)
347 (exp,s),y */
348
349 ptr++;
350 if (ptr[0] == '<')
351 {
352 override_len = 1;
353 ptr++;
354 }
355 else if (ptr[0] == '!')
356 {
357 override_len = 2;
358 ptr++;
359 }
360 else if (ptr[0] == '>')
361 {
362 override_len = 3;
363 ptr++;
364 }
365 else
366 {
367 override_len = 0;
368 }
369 ptr = parse_exp (ptr);
370
371 if (ptr[0] == ',')
372 {
373 ptr++;
374 if (ptr[0] == 'x' && ptr[1] == ')')
375 {
376 ptr += 2;
377
378 if (override_len == 1)
379 {
380 amode = ADDR_DIR_IDX_IND_X;
381 bytes = 2;
382 }
383 else
384 {
385 amode = ADDR_ABS_IND_IDX;
386 bytes = 2;
387 }
388 }
8098403c
NC
389 else if (ptr[0] == 's' && ptr[1] == ')'
390 && ptr[2] == ',' && ptr[3] == 'y')
252b5132
RH
391 {
392 amode = ADDR_STACK_REL_INDX_IDX;
393 bytes = 1;
394 ptr += 4;
395 }
396 }
397 else if (ptr[0] == ')')
398 {
399 if (ptr[1] == ',' && ptr[2] == 'y')
400 {
401 amode = ADDR_DIR_IND_IDX_Y;
402 ptr += 3;
403 bytes = 2;
404 }
405 else
406 {
407 if (override_len == 1)
408 {
409 amode = ADDR_DIR_IND;
410 bytes = 1;
411 }
412 else
413 {
414 amode = ADDR_ABS_IND;
415 bytes = 2;
416 }
417 ptr++;
418
419 }
420 }
252b5132
RH
421 }
422 else if (ptr[0] == '[')
423 {
424 ptr = parse_exp (ptr + 1);
425 if (ptr[0] == ']')
426 {
427 ptr++;
428 if (ptr[0] == ',' && ptr[1] == 'y')
429 {
430 bytes = 1;
431 amode = ADDR_DIR_IND_IDX_Y_LONG;
432 ptr += 2;
433 }
434 else
435 {
8098403c 436 if (info->code == O_jmp)
252b5132 437 {
8098403c
NC
438 bytes = 2;
439 amode = ADDR_ABS_IND_LONG;
440 }
441 else
442 {
443 bytes = 1;
444 amode = ADDR_DIR_IND_LONG;
445 }
252b5132
RH
446 }
447 }
448 }
449 else
450 {
6297c1fe 451 ptr = parse_exp (ptr);
252b5132
RH
452 if (ptr[0] == ',')
453 {
454 if (ptr[1] == 'y')
455 {
456 if (override_len == 1)
457 {
458 bytes = 1;
459 amode = ADDR_DIR_IDX_Y;
460 }
461 else
462 {
463 amode = ADDR_ABS_IDX_Y;
464 bytes = 2;
465 }
466 ptr += 2;
467 }
468 else if (ptr[1] == 'x')
469 {
470 if (override_len == 1)
471 {
472 amode = ADDR_DIR_IDX_X;
473 bytes = 1;
474 }
475 else
476 {
477 amode = ADDR_ABS_IDX_X;
478 bytes = 2;
479 }
480 ptr += 2;
481 }
482 else if (ptr[1] == 's')
483 {
484 bytes = 1;
485 amode = ADDR_STACK_REL;
486 ptr += 2;
487 }
488 else
489 {
490 bytes = 1;
491 immediate1 = immediate;
492 ptr = parse_exp (ptr + 1);
493 amode = ADDR_BLOCK_MOVE;
494 }
495 }
496 else
497 {
498 switch (info->amode)
499 {
500 case ADDR_PC_REL:
501 amode = ADDR_PC_REL;
502 bytes = 1;
503 break;
504 case ADDR_PC_REL_LONG:
505 amode = ADDR_PC_REL_LONG;
506 bytes = 2;
507 break;
508 default:
509 if (override_len == 1)
510 {
511 amode = ADDR_DIR;
512 bytes = 1;
513 }
514 else if (override_len == 3)
515 {
516 bytes = 3;
517 amode = ADDR_ABS_LONG;
518 }
519 else
520 {
521 amode = ADDR_ABS;
522 bytes = 2;
523 }
524 }
525 }
526 }
527
528 switch (bytes)
529 {
530 case 1:
531 switch (expr_shift)
532 {
533 case 0:
534 if (amode == ADDR_DIR)
8098403c 535 tc_cons_reloc = R_W65_DP;
252b5132 536 else
8098403c 537 tc_cons_reloc = R_W65_ABS8;
252b5132
RH
538 break;
539 case 1:
540 tc_cons_reloc = R_W65_ABS8S8;
541 break;
542 case 2:
543 tc_cons_reloc = R_W65_ABS8S16;
544 break;
545 }
546 break;
547 case 2:
548 switch (expr_shift)
549 {
550 case 0:
551 tc_cons_reloc = R_W65_ABS16;
552 break;
553 case 1:
554 tc_cons_reloc = R_W65_ABS16S8;
555 break;
556 case 2:
557 tc_cons_reloc = R_W65_ABS16S16;
558 break;
559 }
560 }
561 return ptr;
562}
563
564/* Passed a pointer to a list of opcodes which use different
565 addressing modes, return the opcode which matches the opcodes
8098403c 566 provided. */
252b5132 567
6297c1fe 568static const struct opinfo *
252b5132 569get_specific (opcode)
6297c1fe 570 const struct opinfo *opcode;
252b5132
RH
571{
572 int ocode = opcode->code;
573
574 for (; opcode->code == ocode; opcode++)
575 {
576 if (opcode->amode == amode)
577 return opcode;
578 }
579 return 0;
580}
581
1994a7c7 582/* Now we know what sort of opcodes it is, let's build the bytes. */
8098403c 583
252b5132
RH
584static void
585build_Mytes (opcode)
6297c1fe 586 const struct opinfo *opcode;
252b5132
RH
587{
588 int size;
589 int type;
590 int pcrel;
591 char *output;
592
593 if (opcode->amode == ADDR_IMPLIED)
594 {
595 output = frag_more (1);
596 }
597 else if (opcode->amode == ADDR_PC_REL)
598 {
599 int type;
8098403c
NC
600
601 /* This is a relaxable insn, so we do some special handling. */
252b5132
RH
602 type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH;
603 output = frag_var (rs_machine_dependent,
604 md_relax_table[C (type, WORD_DISP)].rlx_length,
605 md_relax_table[C (type, BYTE_DISP)].rlx_length,
606 C (type, UNDEF_BYTE_DISP),
607 immediate.X_add_symbol,
608 immediate.X_add_number,
609 0);
610 }
611 else
612 {
613 switch (opcode->amode)
614 {
615 GETINFO (size, type, pcrel);
6297c1fe
AM
616 default:
617 abort ();
252b5132
RH
618 }
619
8098403c
NC
620 /* If something special was done in the expression modify the
621 reloc type. */
252b5132 622 if (tc_cons_reloc)
8098403c 623 type = tc_cons_reloc;
252b5132 624
8098403c 625 /* 1 byte for the opcode + the bytes for the addrmode. */
252b5132
RH
626 output = frag_more (size + 1);
627
628 if (opcode->amode == ADDR_BLOCK_MOVE)
629 {
8098403c 630 /* Two relocs for this one. */
252b5132
RH
631 fix_new_exp (frag_now,
632 output + 1 - frag_now->fr_literal,
633 1,
634 &immediate,
635 0,
636 R_W65_ABS8S16);
637
638 fix_new_exp (frag_now,
639 output + 2 - frag_now->fr_literal,
640 1,
641 &immediate1,
642 0,
643 R_W65_ABS8S16);
644 }
645 else if (type >= 0
646 && opcode->amode != ADDR_IMPLIED
647 && opcode->amode != ADDR_ACC
648 && opcode->amode != ADDR_STACK)
649 {
650 fix_new_exp (frag_now,
651 output + 1 - frag_now->fr_literal,
652 size,
653 &immediate,
654 pcrel,
655 type);
656 }
657 }
658 output[0] = opcode->val;
659}
660
8098403c
NC
661/* This is the guts of the machine-dependent assembler. STR points to
662 a machine dependent instruction. This function is supposed to emit
663 the frags/bytes it assembles to. */
252b5132
RH
664
665void
666md_assemble (str)
667 char *str;
668{
6297c1fe 669 const struct opinfo *opcode;
252b5132 670 char name[20];
252b5132
RH
671
672 /* Drop leading whitespace */
673 while (*str == ' ')
674 str++;
675
676 /* all opcodes are three letters */
677 name[0] = str[0];
678 name[1] = str[1];
679 name[2] = str[2];
680 name[3] = 0;
681
682 tc_cons_reloc = 0;
683 str += 3;
684 opcode = (struct opinfo *) hash_find (opcode_hash_control, name);
685
686 if (opcode == NULL)
687 {
688 as_bad (_("unknown opcode"));
689 return;
690 }
691
692 if (opcode->amode != ADDR_IMPLIED
693 && opcode->amode != ADDR_STACK)
694 {
695 get_operands (opcode, str);
696 opcode = get_specific (opcode);
697 }
698
699 if (opcode == 0)
700 {
8098403c 701 /* Couldn't find an opcode which matched the operands. */
252b5132
RH
702
703 char *where = frag_more (1);
704
705 where[0] = 0x0;
706 where[1] = 0x0;
707 as_bad (_("invalid operands for opcode"));
708 return;
709 }
710
711 build_Mytes (opcode);
712}
713
252b5132 714symbolS *
c0fecd35 715md_undefined_symbol (name)
6297c1fe 716 char *name ATTRIBUTE_UNUSED;
252b5132
RH
717{
718 return 0;
719}
720
8098403c
NC
721/* Various routines to kill one day. */
722/* Equal to MAX_PRECISION in atof-ieee.c. */
252b5132
RH
723#define MAX_LITTLENUMS 6
724
8098403c
NC
725/* Turn a string in input_line_pointer into a floating point constant
726 of type TYPE, and store the appropriate bytes in *LITP. The number
727 of LITTLENUMS emitted is stored in *SIZEP. An error message is
728 returned, or NULL on OK. */
729
252b5132
RH
730char *
731md_atof (type, litP, sizeP)
732 char type;
733 char *litP;
734 int *sizeP;
735{
736 int prec;
737 LITTLENUM_TYPE words[MAX_LITTLENUMS];
738 LITTLENUM_TYPE *wordP;
739 char *t;
252b5132
RH
740
741 switch (type)
742 {
743 case 'f':
744 case 'F':
745 case 's':
746 case 'S':
747 prec = 2;
748 break;
749
750 case 'd':
751 case 'D':
752 case 'r':
753 case 'R':
754 prec = 4;
755 break;
756
757 case 'x':
758 case 'X':
759 prec = 6;
760 break;
761
762 case 'p':
763 case 'P':
764 prec = 6;
765 break;
766
767 default:
768 *sizeP = 0;
769 return _("Bad call to MD_NTOF()");
770 }
771 t = atof_ieee (input_line_pointer, type, words);
772 if (t)
773 input_line_pointer = t;
774
775 *sizeP = prec * sizeof (LITTLENUM_TYPE);
776 for (wordP = words + prec - 1; prec--;)
777 {
778 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
779 litP += sizeof (LITTLENUM_TYPE);
780 }
781 return 0;
782}
783
784int
8098403c 785md_parse_option (c, a)
6297c1fe
AM
786 int c ATTRIBUTE_UNUSED;
787 char *a ATTRIBUTE_UNUSED;
252b5132 788{
a2199cc1 789 return 0;
252b5132
RH
790}
791
8098403c
NC
792/* Called after relaxing, change the frags so they know how big they
793 are. */
794
252b5132
RH
795void
796md_convert_frag (headers, seg, fragP)
6297c1fe
AM
797 object_headers *headers ATTRIBUTE_UNUSED;
798 segT seg ATTRIBUTE_UNUSED;
252b5132
RH
799 fragS *fragP;
800{
801 int disp_size = 0;
802 int inst_size = 0;
8098403c
NC
803 unsigned char *buffer =
804 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
252b5132
RH
805
806 switch (fragP->fr_subtype)
807 {
808 case C (COND_BRANCH, BYTE_DISP):
809 case C (UNCOND_BRANCH, BYTE_DISP):
810 disp_size = 1;
811 inst_size = 1;
812 break;
813
8098403c 814 /* Conditional branches to a known 16 bit displacement. */
252b5132
RH
815 case C (COND_BRANCH, WORD_DISP):
816 switch (buffer[0])
817 {
818 case OP_BCC:
819 case OP_BCS:
820 case OP_BEQ:
821 case OP_BMI:
822 case OP_BNE:
823 case OP_BPL:
824 case OP_BVS:
825 case OP_BVC:
826 /* Invert the sense of the test */
827 buffer[0] ^= 0x20;
828 buffer[1] = 3; /* Jump over following brl */
829 buffer[2] = OP_BRL;
830 buffer[3] = 0;
831 buffer[4] = 0;
832 disp_size = 2;
833 inst_size = 3;
834 break;
835 default:
836 abort ();
837 }
838 break;
839 case C (UNCOND_BRANCH, WORD_DISP):
8098403c 840 /* Unconditional branches to a known 16 bit displacement. */
252b5132
RH
841
842 switch (buffer[0])
843 {
844 case OP_BRA:
845 buffer[0] = OP_BRL;
846 disp_size = 2;
847 inst_size = 1;
848 break;
849 default:
850 abort ();
851 }
852 break;
8098403c 853 /* Got to create a branch over a reloc here. */
252b5132
RH
854 case C (COND_BRANCH, UNDEF_WORD_DISP):
855 buffer[0] ^= 0x20; /* invert test */
856 buffer[1] = 3;
857 buffer[2] = OP_BRL;
858 buffer[3] = 0;
859 buffer[4] = 0;
860 fix_new (fragP,
861 fragP->fr_fix + 3,
862 4,
863 fragP->fr_symbol,
864 fragP->fr_offset,
865 0,
866 R_W65_PCR16);
867
868 fragP->fr_fix += disp_size + inst_size;
869 fragP->fr_var = 0;
870 break;
871 case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
872 buffer[0] = OP_BRL;
873 buffer[1] = 0;
874 buffer[2] = 0;
875 fix_new (fragP,
876 fragP->fr_fix + 1,
877 4,
878 fragP->fr_symbol,
879 fragP->fr_offset,
880 0,
881 R_W65_PCR16);
882
883 fragP->fr_fix += disp_size + inst_size;
884 fragP->fr_var = 0;
885 break;
886 default:
887 abort ();
888 }
889 if (inst_size)
890 {
8098403c
NC
891 /* Get the address of the end of the instruction. */
892 int next_inst = (fragP->fr_fix + fragP->fr_address
893 + disp_size + inst_size);
252b5132
RH
894 int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
895 fragP->fr_offset);
896 int disp = targ_addr - next_inst;
897
2132e3a3 898 md_number_to_chars ((char *) buffer + inst_size, disp, disp_size);
252b5132
RH
899 fragP->fr_fix += disp_size + inst_size;
900 fragP->fr_var = 0;
901 }
902}
903
252b5132 904valueT
c0fecd35
AM
905md_section_align (seg, size)
906 segT seg;
907 valueT size;
252b5132
RH
908{
909 return ((size + (1 << section_alignment[(int) seg]) - 1)
910 & (-1 << section_alignment[(int) seg]));
252b5132
RH
911}
912
913void
94f592af 914md_apply_fix3 (fixP, valP, seg)
252b5132 915 fixS *fixP;
a2199cc1 916 valueT * valP;
94f592af 917 segT seg ATTRIBUTE_UNUSED;
252b5132 918{
94f592af 919 long val = * (long *) valP;
252b5132
RH
920 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
921 int addr = fixP->fx_frag->fr_address + fixP->fx_where;
922
923 if (fixP->fx_r_type == 0)
924 {
925 if (fixP->fx_size == 1)
926 fixP->fx_r_type = R_W65_ABS8;
927 else
928 fixP->fx_r_type = R_W65_ABS16;
929 }
930
931 switch (fixP->fx_r_type)
932 {
933 case R_W65_ABS8S16:
934 val >>= 8;
935 case R_W65_ABS8S8:
936 val >>= 8;
937 case R_W65_ABS8:
938 *buf++ = val;
939 break;
940 case R_W65_ABS16S16:
941 val >>= 8;
942 case R_W65_ABS16S8:
943 val >>= 8;
944 case R_W65_ABS16:
945 *buf++ = val >> 0;
946 *buf++ = val >> 8;
947 break;
948 case R_W65_ABS24:
949 *buf++ = val >> 0;
950 *buf++ = val >> 8;
951 *buf++ = val >> 16;
952 break;
953 case R_W65_PCR8:
954 *buf++ = val - addr - 1;
955 break;
956 case R_W65_PCR16:
957 val = val - addr - 1;
958 *buf++ = val;
959 *buf++ = val >> 8;
960 break;
961 case R_W65_DP:
962 *buf++ = val;
963 break;
964
965 default:
966 abort ();
967 }
94f592af
NC
968
969 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
970 fixP->fx_done = 1;
252b5132
RH
971}
972
94f592af 973/* Put number into target byte order. */
252b5132
RH
974
975void
976md_number_to_chars (ptr, use, nbytes)
977 char *ptr;
978 valueT use;
979 int nbytes;
980{
981 number_to_chars_littleendian (ptr, use, nbytes);
982}
983
984long
985md_pcrel_from (fixP)
986 fixS *fixP;
987{
988 int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1;
989 return gap;
990}
991
992void
993tc_coff_symbol_emit_hook (x)
6297c1fe 994 symbolS *x ATTRIBUTE_UNUSED;
252b5132
RH
995{
996}
997
998short
999tc_coff_fix2rtype (fix_ptr)
1000 fixS *fix_ptr;
1001{
1002 return fix_ptr->fx_r_type;
1003}
1004
1005void
1006tc_reloc_mangle (fix_ptr, intr, base)
1007 fixS *fix_ptr;
1008 struct internal_reloc *intr;
1009 bfd_vma base;
1010
1011{
1012 symbolS *symbol_ptr;
1013
1014 symbol_ptr = fix_ptr->fx_addsy;
1015
1016 /* If this relocation is attached to a symbol then it's ok
1017 to output it */
1018 if (fix_ptr->fx_r_type == RELOC_32)
1019 {
1020 /* cons likes to create reloc32's whatever the size of the reloc..
1021 */
1022 switch (fix_ptr->fx_size)
1023 {
1024 case 2:
1025 intr->r_type = R_IMM16;
1026 break;
1027 case 1:
1028 intr->r_type = R_IMM8;
1029 break;
1030 default:
1031 abort ();
1032 }
1033 }
1034 else
1035 {
1036 if (fix_ptr->fx_size == 4)
1037 intr->r_type = R_W65_ABS24;
1038 else
1039 intr->r_type = fix_ptr->fx_r_type;
1040 }
1041
1042 intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
1043 intr->r_offset = fix_ptr->fx_offset;
1044
1045 /* Turn the segment of the symbol into an offset. */
1046 if (symbol_ptr)
1047 {
1048 symbolS *dot;
1049
1050 dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
1051 if (dot)
1052 {
1053 intr->r_offset += S_GET_VALUE (symbol_ptr);
1054 intr->r_symndx = dot->sy_number;
1055 }
1056 else
1057 {
1058 intr->r_symndx = symbol_ptr->sy_number;
1059 }
1060 }
1061 else
1062 {
1063 intr->r_symndx = -1;
1064 }
1065}
1066
1067int
1068tc_coff_sizemachdep (frag)
1069 fragS *frag;
1070{
1071 return md_relax_table[frag->fr_subtype].rlx_length;
1072}
1073
8098403c
NC
1074/* Called just before address relaxation, return the length by which a
1075 fragment must grow to reach it's destination. */
252b5132 1076
252b5132
RH
1077int
1078md_estimate_size_before_relax (fragP, segment_type)
1079 register fragS *fragP;
1080 register segT segment_type;
1081{
e66457fb 1082 int what;
252b5132
RH
1083
1084 switch (fragP->fr_subtype)
1085 {
1086 default:
1087 abort ();
93c2a809 1088
252b5132
RH
1089 case C (COND_BRANCH, UNDEF_BYTE_DISP):
1090 case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):
e66457fb 1091 what = GET_WHAT (fragP->fr_subtype);
8098403c 1092 /* Used to be a branch to somewhere which was unknown. */
252b5132
RH
1093 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
1094 {
1095 /* Got a symbol and it's defined in this segment, become byte
8098403c 1096 sized - maybe it will fix up. */
252b5132 1097 fragP->fr_subtype = C (what, BYTE_DISP);
252b5132
RH
1098 }
1099 else
1100 {
8098403c
NC
1101 /* Its got a segment, but its not ours, so it will always be
1102 long. */
252b5132 1103 fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
252b5132 1104 }
93c2a809
AM
1105 break;
1106
1107 case C (COND_BRANCH, BYTE_DISP):
1108 case C (COND_BRANCH, WORD_DISP):
e66457fb 1109 case C (COND_BRANCH, UNDEF_WORD_DISP):
93c2a809
AM
1110 case C (UNCOND_BRANCH, BYTE_DISP):
1111 case C (UNCOND_BRANCH, WORD_DISP):
e66457fb 1112 case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
93c2a809 1113 /* When relaxing a section for the second time, we don't need to
e66457fb 1114 do anything besides return the current size. */
93c2a809 1115 break;
252b5132 1116 }
e66457fb
AM
1117
1118 fragP->fr_var = md_relax_table[fragP->fr_subtype].rlx_length;
252b5132
RH
1119 return fragP->fr_var;
1120}
1121
5a38dc70 1122const char *md_shortopts = "";
252b5132
RH
1123struct option md_longopts[] = {
1124#define OPTION_RELAX (OPTION_MD_BASE)
1125 {NULL, no_argument, NULL, 0}
1126};
1127
1128void
1129md_show_usage (stream)
6297c1fe 1130 FILE *stream ATTRIBUTE_UNUSED;
252b5132 1131{
252b5132
RH
1132}
1133
8098403c 1134size_t md_longopts_size = sizeof (md_longopts);
This page took 0.379738 seconds and 4 git commands to generate.