1 /* tc-a29k.c -- Assemble for the AMD 29000.
2 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 /* John Gilmore has reorganized this module somewhat, to make it easier
23 to convert it to new machines' assemblers as desired. There was too
24 much bloody rewriting required before. There still probably is. */
28 #include "opcode/a29k.h"
30 /* Make it easier to clone this machine desc into another one. */
31 #define machine_opcode a29k_opcode
32 #define machine_opcodes a29k_opcodes
33 #define machine_ip a29k_ip
34 #define machine_it a29k_it
36 const relax_typeS md_relax_table
[] = { 0 };
38 #define IMMEDIATE_BIT 0x01000000 /* Turns RB into Immediate */
39 #define ABSOLUTE_BIT 0x01000000 /* Turns PC-relative to Absolute */
40 #define CE_BIT 0x00800000 /* Coprocessor enable in LOAD */
41 #define UI_BIT 0x00000080 /* Unsigned integer in CONVERT */
43 /* handle of the OPCODE hash table */
44 static struct hash_control
*op_hash
= NULL
;
52 int reloc_offset
; /* Offset of reloc within insn */
53 enum reloc_type reloc
;
58 /* static int getExpression(char *str); */
59 static void machine_ip(char *str
);
60 /* static void print_insn(struct machine_it *insn); */
61 static void s_data1(void);
62 static void s_use(void);
66 /* static int getExpression(); */
67 static void machine_ip();
68 /* static void print_insn(); */
69 static void s_data1();
76 { "align", s_align_bytes
, 4 },
77 { "block", s_space
, 0 },
78 { "cputype", s_ignore
, 0 }, /* CPU as 29000 or 29050 */
79 { "reg", s_lsym
, 0 }, /* Register equate, same as equ */
80 { "space", s_ignore
, 0 }, /* Listing control */
81 { "sect", s_ignore
, 0 }, /* Creation of coff sections */
87 int md_short_jump_size
= 4;
88 int md_long_jump_size
= 4;
89 #if defined(BFD_HEADERS)
91 int md_reloc_size
= RELSZ
; /* Coff headers */
93 int md_reloc_size
= 12; /* something else headers */
96 int md_reloc_size
= 12; /* Not bfdized*/
99 /* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101 char comment_chars
[] = ";";
103 /* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106 /* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
108 #NO_APP at the beginning of its output. */
109 /* Also note that comments like this one will always work */
110 char line_comment_chars
[] = "#";
112 /* We needed an unused char for line separation to work around the
113 lack of macros, using sed and such. */
114 char line_separator_chars
[] = "@";
116 /* Chars that can be used to separate mant from exp in floating point nums */
117 char EXP_CHARS
[] = "eE";
119 /* Chars that mean this number is a floating point constant */
122 char FLT_CHARS
[] = "rRsSfFdDxXpP";
124 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
125 changed in read.c . Ideally it shouldn't have to know about it at all,
126 but nothing is ideal around here.
129 static unsigned char octal
[256];
130 #define isoctal(c) octal[c]
131 static unsigned char toHex
[256];
134 * anull bit - causes the branch delay slot instructions to not be executed
136 #define ANNUL (1 << 29)
142 if (strncmp(input_line_pointer
, ".text", 5) == 0) {
143 input_line_pointer
+= 5;
147 if (strncmp(input_line_pointer
, ".data", 5) == 0) {
148 input_line_pointer
+= 5;
152 if (strncmp(input_line_pointer
, ".data1", 6) == 0) {
153 input_line_pointer
+= 6;
157 /* Literals can't go in the text segment because you can't read
158 from instruction memory on some 29k's. So, into initialized data. */
159 if (strncmp(input_line_pointer
, ".lit", 4) == 0) {
160 input_line_pointer
+= 4;
161 subseg_new(SEG_DATA
, 200);
162 demand_empty_rest_of_line();
166 as_bad("Unknown segment type");
167 demand_empty_rest_of_line();
174 subseg_new(SEG_DATA
, 1);
175 demand_empty_rest_of_line();
179 /* Install symbol definition that maps REGNAME to REGNO.
180 FIXME-SOON: These are not recognized in mixed case. */
183 insert_sreg (regname
, regnum
)
187 /* FIXME-SOON, put something in these syms so they won't be output to the symbol
188 table of the resulting object file. */
190 /* Must be large enough to hold the names of the special registers. */
194 symbol_table_insert(symbol_new(regname
, SEG_REGISTER
, regnum
, &zero_address_frag
));
195 for (i
= 0; regname
[i
]; i
++)
196 buf
[i
] = islower (regname
[i
]) ? toupper (regname
[i
]) : regname
[i
];
199 symbol_table_insert(symbol_new(buf
, SEG_REGISTER
, regnum
, &zero_address_frag
));
200 } /* insert_sreg() */
202 /* Install symbol definitions for assorted special registers.
203 See ASM29K Ref page 2-9. */
205 void define_some_regs() {
208 /* Protected special-purpose register names */
209 insert_sreg ("vab", SREG
+0);
210 insert_sreg ("ops", SREG
+1);
211 insert_sreg ("cps", SREG
+2);
212 insert_sreg ("cfg", SREG
+3);
213 insert_sreg ("cha", SREG
+4);
214 insert_sreg ("chd", SREG
+5);
215 insert_sreg ("chc", SREG
+6);
216 insert_sreg ("rbp", SREG
+7);
217 insert_sreg ("tmc", SREG
+8);
218 insert_sreg ("tmr", SREG
+9);
219 insert_sreg ("pc0", SREG
+10);
220 insert_sreg ("pc1", SREG
+11);
221 insert_sreg ("pc2", SREG
+12);
222 insert_sreg ("mmu", SREG
+13);
223 insert_sreg ("lru", SREG
+14);
225 /* Unprotected special-purpose register names */
226 insert_sreg ("ipc", SREG
+128);
227 insert_sreg ("ipa", SREG
+129);
228 insert_sreg ("ipb", SREG
+130);
229 insert_sreg ("q", SREG
+131);
230 insert_sreg ("alu", SREG
+132);
231 insert_sreg ("bp", SREG
+133);
232 insert_sreg ("fc", SREG
+134);
233 insert_sreg ("cr", SREG
+135);
234 insert_sreg ("fpe", SREG
+160);
235 insert_sreg ("inte",SREG
+161);
236 insert_sreg ("fps", SREG
+162);
237 /* "", SREG+163); Reserved */
238 insert_sreg ("exop",SREG
+164);
239 } /* define_some_regs() */
241 /* This function is called once, at assembler startup time. It should
242 set up all the tables, etc. that the MD part of the assembler will need. */
246 register char *retval
= NULL
;
248 register int skipnext
= 0;
249 register unsigned int i
;
250 register char *strend
, *strend2
;
252 /* Hash up all the opcodes for fast use later. */
254 op_hash
= hash_new();
256 as_fatal("Virtual memory exhausted");
258 for (i
= 0; i
< num_opcodes
; i
++)
260 const char *name
= machine_opcodes
[i
].name
;
267 /* Hack to avoid multiple opcode entries. We pre-locate all the
268 variations (b/i field and P/A field) and handle them. */
270 if (!strcmp (name
, machine_opcodes
[i
+1].name
)) {
271 if ((machine_opcodes
[i
].opcode
^ machine_opcodes
[i
+1].opcode
)
274 strend
= machine_opcodes
[i
].args
+strlen(machine_opcodes
[i
].args
)-1;
275 strend2
= machine_opcodes
[i
+1].args
+strlen(machine_opcodes
[i
+1].args
)-1;
278 if (*strend2
!= 'i') goto bad_table
;
281 if (*strend2
!= 'b') goto bad_table
;
284 if (*strend2
!= 'A') goto bad_table
;
287 if (*strend2
!= 'P') goto bad_table
;
291 fprintf (stderr
, "internal error: can't handle opcode %s\n", name
);
295 /* OK, this is an i/b or A/P pair. We skip the higher-valued one,
296 and let the code for operand checking handle OR-ing in the bit. */
297 if (machine_opcodes
[i
].opcode
& 1)
303 retval
= hash_insert (op_hash
, name
, &machine_opcodes
[i
]);
304 if (retval
!= NULL
&& *retval
!= '\0')
306 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
307 machine_opcodes
[i
].name
, retval
);
313 as_fatal("Broken assembler. No assembly attempted.");
315 for (i
= '0'; i
< '8'; ++i
)
317 for (i
= '0'; i
<= '9'; ++i
)
319 for (i
= 'a'; i
<= 'f'; ++i
)
320 toHex
[i
] = i
+ 10 - 'a';
321 for (i
= 'A'; i
<= 'F'; ++i
)
322 toHex
[i
] = i
+ 10 - 'A';
331 /* Assemble a single instruction. Its label has already been handled
332 by the generic front end. We just parse opcode and operands, and
333 produce the bytes of data and relocation. */
335 void md_assemble(str
)
344 /* put out the opcode */
345 md_number_to_chars(toP
, the_insn
.opcode
, 4);
347 /* put out the symbol-dependent stuff */
348 if (the_insn
.reloc
!= NO_RELOC
) {
350 frag_now
, /* which frag */
351 (toP
- frag_now
->fr_literal
+ the_insn
.reloc_offset
), /* where */
353 the_insn
.exp
.X_add_symbol
,
354 the_insn
.exp
.X_subtract_symbol
,
355 the_insn
.exp
.X_add_number
,
363 parse_operand (s
, operandp
)
365 expressionS
*operandp
;
367 char *save
= input_line_pointer
;
371 input_line_pointer
= s
;
372 seg
= expr (0, operandp
);
373 new = input_line_pointer
;
374 input_line_pointer
= save
;
388 as_bad("Missing operand");
392 as_bad("Don't understand operand of type %s", segment_name (seg
));
397 /* Instruction parsing. Takes a string containing the opcode.
398 Operands are at input_line_pointer. Output is in the_insn.
399 Warnings or errors are generated. */
408 /* !!!! unsigned long i; */
409 struct machine_opcode
*insn
;
411 unsigned long opcode
;
412 /* !!!! unsigned int mask; */
413 expressionS the_operand
;
414 expressionS
*operand
= &the_operand
;
417 /* Must handle `div0' opcode. */
420 for (; isalnum(*s
); ++s
)
428 case ' ': /* FIXME-SOMEDAY more whitespace */
433 as_bad("Unknown opcode: `%s'", str
);
436 if ((insn
= (struct machine_opcode
*) hash_find(op_hash
, str
)) == NULL
) {
437 as_bad("Unknown opcode `%s'.", str
);
441 opcode
= insn
->opcode
;
442 bzero(&the_insn
, sizeof(the_insn
));
443 the_insn
.reloc
= NO_RELOC
;
446 * Build the opcode, checking as we go to make
447 * sure that the operands match.
449 * If an operand matches, we modify the_insn or opcode appropriately,
450 * and do a "continue". If an operand fails to match, we "break".
452 if (insn
->args
[0] != '\0')
453 s
= parse_operand (s
, operand
); /* Prime the pump */
455 for (args
= insn
->args
; ; ++args
) {
458 case '\0': /* end of args */
460 /* We are truly done. */
461 the_insn
.opcode
= opcode
;
464 as_bad("Too many operands: %s", s
);
467 case ',': /* Must match a comma */
469 s
= parse_operand (s
, operand
); /* Parse next opnd */
474 case 'v': /* Trap numbers (immediate field) */
475 if (operand
->X_seg
== SEG_ABSOLUTE
) {
476 if (operand
->X_add_number
< 256) {
477 opcode
|= (operand
->X_add_number
<< 16);
480 as_bad("Immediate value of %d is too large",
481 operand
->X_add_number
);
485 the_insn
.reloc
= RELOC_8
;
486 the_insn
.reloc_offset
= 1; /* BIG-ENDIAN Byte 1 of insn */
487 the_insn
.exp
= *operand
;
490 case 'b': /* A general register or 8-bit immediate */
492 /* We treat the two cases identically since we mashed
493 them together in the opcode table. */
494 if (operand
->X_seg
== SEG_REGISTER
)
497 opcode
|= IMMEDIATE_BIT
;
498 if (operand
->X_seg
== SEG_ABSOLUTE
) {
499 if (operand
->X_add_number
< 256) {
500 opcode
|= operand
->X_add_number
;
503 as_bad("Immediate value of %d is too large",
504 operand
->X_add_number
);
508 the_insn
.reloc
= RELOC_8
;
509 the_insn
.reloc_offset
= 3; /* BIG-ENDIAN Byte 3 of insn */
510 the_insn
.exp
= *operand
;
513 case 'a': /* next operand must be a register */
516 /* lrNNN or grNNN or %%expr or a user-def register name */
517 if (operand
->X_seg
!= SEG_REGISTER
)
518 break; /* Only registers */
519 know (operand
->X_add_symbol
== 0);
520 know (operand
->X_subtract_symbol
== 0);
521 reg
= operand
->X_add_number
;
523 break; /* No special registers */
526 * Got the register, now figure out where
527 * it goes in the opcode.
543 as_fatal("failed sanity check.");
546 case 'x': /* 16 bit constant, zero-extended */
547 case 'X': /* 16 bit constant, one-extended */
548 if (operand
->X_seg
== SEG_ABSOLUTE
) {
549 opcode
|= (operand
->X_add_number
& 0xFF) << 0 |
550 ((operand
->X_add_number
& 0xFF00) << 8);
553 the_insn
.reloc
= RELOC_CONST
;
554 the_insn
.exp
= *operand
;
558 if (operand
->X_seg
== SEG_ABSOLUTE
) {
559 opcode
|= (operand
->X_add_number
& 0x00FF0000) >> 16 |
560 (((unsigned long)operand
->X_add_number
561 /* avoid sign ext */ & 0xFF000000) >> 8);
564 the_insn
.reloc
= RELOC_CONSTH
;
565 the_insn
.exp
= *operand
;
568 case 'P': /* PC-relative jump address */
569 case 'A': /* Absolute jump address */
570 /* These two are treated together since we folded the
571 opcode table entries together. */
572 if (operand
->X_seg
== SEG_ABSOLUTE
) {
573 opcode
|= ABSOLUTE_BIT
|
574 (operand
->X_add_number
& 0x0003FC00) << 6 |
575 ((operand
->X_add_number
& 0x000003FC) >> 2);
578 the_insn
.reloc
= RELOC_JUMPTARG
;
579 the_insn
.exp
= *operand
;
580 the_insn
.pcrel
= 1; /* Assume PC-relative jump */
581 /* FIXME-SOON, Do we figure out whether abs later, after know sym val? */
584 case 'e': /* Coprocessor enable bit for LOAD/STORE insn */
585 if (operand
->X_seg
== SEG_ABSOLUTE
) {
586 if (operand
->X_add_number
== 0)
588 if (operand
->X_add_number
== 1) {
595 case 'n': /* Control bits for LOAD/STORE instructions */
596 if (operand
->X_seg
== SEG_ABSOLUTE
&&
597 operand
->X_add_number
< 128) {
598 opcode
|= (operand
->X_add_number
<< 16);
603 case 's': /* Special register number */
604 if (operand
->X_seg
!= SEG_REGISTER
)
605 break; /* Only registers */
606 if (operand
->X_add_number
< SREG
)
607 break; /* Not a special register */
608 opcode
|= (operand
->X_add_number
& 0xFF) << 8;
611 case 'u': /* UI bit of CONVERT */
612 if (operand
->X_seg
== SEG_ABSOLUTE
) {
613 if (operand
->X_add_number
== 0)
615 if (operand
->X_add_number
== 1) {
622 case 'r': /* RND bits of CONVERT */
623 if (operand
->X_seg
== SEG_ABSOLUTE
&&
624 operand
->X_add_number
< 8) {
625 opcode
|= operand
->X_add_number
<< 4;
630 case 'd': /* FD bits of CONVERT */
631 if (operand
->X_seg
== SEG_ABSOLUTE
&&
632 operand
->X_add_number
< 4) {
633 opcode
|= operand
->X_add_number
<< 2;
639 case 'f': /* FS bits of CONVERT */
640 if (operand
->X_seg
== SEG_ABSOLUTE
&&
641 operand
->X_add_number
< 4) {
642 opcode
|= operand
->X_add_number
<< 0;
648 if (operand
->X_seg
== SEG_ABSOLUTE
&&
649 operand
->X_add_number
< 4) {
650 opcode
|= operand
->X_add_number
<< 16;
656 if (operand
->X_seg
== SEG_ABSOLUTE
&&
657 operand
->X_add_number
< 16) {
658 opcode
|= operand
->X_add_number
<< 18;
666 /* Types or values of args don't match. */
667 as_bad("Invalid operands");
673 This is identical to the md_atof in m68k.c. I think this is right,
676 Turn a string in input_line_pointer into a floating point constant of type
677 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
678 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
681 /* Equal to MAX_PRECISION in atof-ieee.c */
682 #define MAX_LITTLENUMS 6
685 md_atof(type
,litP
,sizeP
)
691 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
692 LITTLENUM_TYPE
*wordP
;
723 return "Bad call to MD_ATOF()";
725 t
=atof_ieee(input_line_pointer
,type
,words
);
727 input_line_pointer
=t
;
728 *sizeP
=prec
* sizeof(LITTLENUM_TYPE
);
729 for(wordP
=words
;prec
--;) {
730 md_number_to_chars(litP
,(long)(*wordP
++),sizeof(LITTLENUM_TYPE
));
731 litP
+=sizeof(LITTLENUM_TYPE
);
733 return ""; /* Someone should teach Dean about null pointers */
737 * Write out big-endian.
740 md_number_to_chars(buf
,val
,n
)
758 as_fatal("failed sanity check.");
763 void md_apply_fix(fixP
, val
)
767 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
769 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
772 know(fixP
->fx_size
== 4);
773 know(fixP
->fx_r_type
< NO_RELOC
);
776 * This is a hack. There should be a better way to
779 if (fixP
->fx_r_type
== RELOC_WDISP30
&& fixP
->fx_addsy
) {
780 val
+= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
783 switch (fixP
->fx_r_type
) {
797 val
= (val
>>= 2) + 1;
798 buf
[0] |= (val
>> 24) & 0x3f;
805 buf
[1] |= (val
>> 26) & 0x3f;
811 buf
[2] |= (val
>> 8) & 0x03;
816 buf
[2] |= (val
>> 8) & 0x1f;
821 val
= (val
>>= 2) + 1;
824 buf
[1] |= (val
>> 16) & 0x3f;
838 case RELOC_JUMPTARG
: /* 00XX00XX pattern in a word */
839 buf
[1] = val
>> 10; /* Holds bits 0003FFFC of address */
843 case RELOC_CONST
: /* 00XX00XX pattern in a word */
844 buf
[1] = val
>> 8; /* Holds bits 0000XXXX */
848 case RELOC_CONSTH
: /* 00XX00XX pattern in a word */
849 buf
[1] = val
>> 24; /* Holds bits XXXX0000 */
855 as_bad("bad relocation type: 0x%02x", fixP
->fx_r_type
);
862 short tc_coff_fix2rtype(fixP
)
866 /* FIXME-NOW: relocation type handling is not yet written for
870 switch (fixP
->fx_r_type
) {
871 case RELOC_32
: return(R_WORD
);
872 case RELOC_8
: return(R_BYTE
);
873 case RELOC_CONST
: return (R_ILOHALF
);
874 case RELOC_CONSTH
: return (R_IHIHALF
);
875 case RELOC_JUMPTARG
: return (R_IREL
);
876 default: printf("need %o3\n", fixP
->fx_r_type
);
878 } /* switch on type */
881 } /* tc_coff_fix2rtype() */
882 #endif /* OBJ_COFF */
884 /* should never be called for sparc */
885 void md_create_short_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
887 long from_addr
, to_addr
;
891 as_fatal("a29k_create_short_jmp\n");
894 /* should never be called for 29k */
895 void md_convert_frag(headers
, fragP
)
896 object_headers
*headers
;
897 register fragS
*fragP
;
899 as_fatal("sparc_convert_frag\n");
902 /* should never be called for 29k */
903 void md_create_long_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
910 as_fatal("sparc_create_long_jump\n");
913 /* should never be called for sparc */
914 int md_estimate_size_before_relax(fragP
, segtype
)
915 register fragS
*fragP
;
918 as_fatal("sparc_estimate_size_before_relax\n");
922 /* for debugging only */
925 struct machine_it
*insn
;
956 fprintf(stderr
, "ERROR: %s\n");
958 fprintf(stderr
, "opcode=0x%08x\n", insn
->opcode
);
959 fprintf(stderr
, "reloc = %s\n", Reloc
[insn
->reloc
]);
960 fprintf(stderr
, "exp = {\n");
961 fprintf(stderr
, "\t\tX_add_symbol = %s\n",
962 insn
->exp
.X_add_symbol
?
963 (S_GET_NAME(insn
->exp
.X_add_symbol
) ?
964 S_GET_NAME(insn
->exp
.X_add_symbol
) : "???") : "0");
965 fprintf(stderr
, "\t\tX_sub_symbol = %s\n",
966 insn
->exp
.X_subtract_symbol
?
967 (S_GET_NAME(insn
->exp
.X_subtract_symbol
) ?
968 S_GET_NAME(insn
->exp
.X_subtract_symbol
) : "???") : "0");
969 fprintf(stderr
, "\t\tX_add_number = %d\n",
970 insn
->exp
.X_add_number
);
971 fprintf(stderr
, "}\n");
976 /* Translate internal representation of relocation info to target format.
978 On sparc/29k: first 4 bytes are normal unsigned long address, next three
979 bytes are index, most sig. byte first. Byte 7 is broken up with
980 bit 7 as external, bits 6 & 5 unused, and the lower
981 five bits as relocation type. Next 4 bytes are long addend. */
982 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
986 void tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
989 relax_addressT segment_address_in_file
;
993 know(fixP
->fx_r_type
< NO_RELOC
);
994 know(fixP
->fx_addsy
!= NULL
);
996 r_index
= (S_IS_DEFINED(fixP
->fx_addsy
)
997 ? S_GET_TYPE(fixP
->fx_addsy
)
998 : fixP
->fx_addsy
->sy_number
);
1001 md_number_to_chars(where
,
1002 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1005 /* now the fun stuff */
1006 where
[4] = (r_index
>> 16) & 0x0ff;
1007 where
[5] = (r_index
>> 8) & 0x0ff;
1008 where
[6] = r_index
& 0x0ff;
1009 where
[7] = (((!S_IS_DEFINED(fixP
->fx_addsy
)) << 7) & 0x80) | (0 & 0x60) | (fixP
->fx_r_type
& 0x1F);
1011 md_number_to_chars(&where
[8], fixP
->fx_addnumber
, 4);
1014 } /* tc_aout_fix_to_chars() */
1016 #endif /* OBJ_AOUT */
1019 md_parse_option(argP
,cntP
,vecP
)
1028 /* Default the values of symbols known that should be "predefined". We
1029 don't bother to predefine them unless you actually use one, since there
1030 are a lot of them. */
1032 symbolS
*md_undefined_symbol (name
)
1036 char testbuf
[5+ /*SLOP*/ 5];
1038 if (name
[0] == 'g' || name
[0] == 'G' || name
[0] == 'l' || name
[0] == 'L')
1040 /* Perhaps a global or local register name */
1041 if (name
[1] == 'r' || name
[1] == 'R')
1043 /* Parse the number, make sure it has no extra zeroes or trailing
1045 regnum
= atol(&name
[2]);
1048 sprintf(testbuf
, "%ld", regnum
);
1049 if (strcmp (testbuf
, &name
[2]) != 0)
1050 return 0; /* gr007 or lr7foo or whatever */
1052 /* We have a wiener! Define and return a new symbol for it. */
1053 if (name
[0] == 'l' || name
[0] == 'L')
1055 return(symbol_new(name
, SEG_REGISTER
, regnum
, &zero_address_frag
));
1062 /* Parse an operand that is machine-specific. */
1064 void md_operand(expressionP
)
1065 expressionS
*expressionP
;
1068 if (input_line_pointer
[0] == '%' && input_line_pointer
[1] == '%')
1070 /* We have a numeric register expression. No biggy. */
1071 input_line_pointer
+= 2; /* Skip %% */
1072 (void)expression (expressionP
);
1073 if (expressionP
->X_seg
!= SEG_ABSOLUTE
1074 || expressionP
->X_add_number
> 255)
1075 as_bad("Invalid expression after %%%%\n");
1076 expressionP
->X_seg
= SEG_REGISTER
;
1078 else if (input_line_pointer
[0] == '&')
1080 /* We are taking the 'address' of a register...this one is not
1081 in the manual, but it *is* in traps/fpsymbol.h! What they
1082 seem to want is the register number, as an absolute number. */
1083 input_line_pointer
++; /* Skip & */
1084 (void)expression (expressionP
);
1085 if (expressionP
->X_seg
!= SEG_REGISTER
)
1086 as_bad("Invalid register in & expression");
1088 expressionP
->X_seg
= SEG_ABSOLUTE
;
1092 /* Round up a section size to the appropriate boundary. */
1094 md_section_align (segment
, size
)
1098 return size
; /* Byte alignment is fine */
1101 /* Exactly what point is a PC-relative offset relative TO?
1102 On the 29000, they're relative to the address of the instruction,
1103 which we have set up as the address of the fixup too. */
1104 long md_pcrel_from (fixP
)
1107 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1116 /* end of tc-a29k.c */