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 "a29k-opcode.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 { "file", s_ignore
, 0 }, /* COFF File name for debug info? */
80 { "line", s_ignore
, 0 }, /* Line number of coff symbol */
81 { "reg", s_lsym
, 0 }, /* Register equate, same as equ */
82 { "space", s_ignore
, 0 }, /* Listing control */
83 { "sect", s_ignore
, 0 }, /* Creation of coff sections */
89 int md_short_jump_size
= 4;
90 int md_long_jump_size
= 4;
91 int md_reloc_size
= 12;
93 /* This array holds the chars that always start a comment. If the
94 pre-processor is disabled, these aren't very useful */
95 char comment_chars
[] = ";";
97 /* This array holds the chars that only start a comment at the beginning of
98 a line. If the line seems to have the form '# 123 filename'
99 .line and .file directives will appear in the pre-processed output */
100 /* Note that input_file.c hand checks for '#' at the beginning of the
101 first line of the input file. This is because the compiler outputs
102 #NO_APP at the beginning of its output. */
103 /* Also note that comments like this one will always work */
104 char line_comment_chars
[] = "#";
106 /* We needed an unused char for line separation to work around the
107 lack of macros, using sed and such. */
108 char line_separator_chars
[] = "@";
110 /* Chars that can be used to separate mant from exp in floating point nums */
111 char EXP_CHARS
[] = "eE";
113 /* Chars that mean this number is a floating point constant */
116 char FLT_CHARS
[] = "rRsSfFdDxXpP";
118 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
119 changed in read.c . Ideally it shouldn't have to know about it at all,
120 but nothing is ideal around here.
123 static unsigned char octal
[256];
124 #define isoctal(c) octal[c]
125 static unsigned char toHex
[256];
128 * anull bit - causes the branch delay slot instructions to not be executed
130 #define ANNUL (1 << 29)
136 if (strncmp(input_line_pointer
, ".text", 5) == 0) {
137 input_line_pointer
+= 5;
141 if (strncmp(input_line_pointer
, ".data", 5) == 0) {
142 input_line_pointer
+= 5;
146 if (strncmp(input_line_pointer
, ".data1", 6) == 0) {
147 input_line_pointer
+= 6;
151 /* Literals can't go in the text segment because you can't read
152 from instruction memory on some 29k's. So, into initialized data. */
153 if (strncmp(input_line_pointer
, ".lit", 4) == 0) {
154 input_line_pointer
+= 4;
155 subseg_new(SEG_DATA
, 200);
156 demand_empty_rest_of_line();
160 as_bad("Unknown segment type");
161 demand_empty_rest_of_line();
168 subseg_new(SEG_DATA
, 1);
169 demand_empty_rest_of_line();
173 /* Install symbol definition that maps REGNAME to REGNO.
174 FIXME-SOON: These are not recognized in mixed case. */
177 insert_sreg (regname
, regnum
)
181 /* FIXME-SOON, put something in these syms so they won't be output to the symbol
182 table of the resulting object file. */
184 /* Must be large enough to hold the names of the special registers. */
188 symbol_table_insert(symbol_new(regname
, SEG_REGISTER
, regnum
, &zero_address_frag
));
189 for (i
= 0; regname
[i
]; i
++)
190 buf
[i
] = islower (regname
[i
]) ? toupper (regname
[i
]) : regname
[i
];
193 symbol_table_insert(symbol_new(buf
, SEG_REGISTER
, regnum
, &zero_address_frag
));
194 } /* insert_sreg() */
196 /* Install symbol definitions for assorted special registers.
197 See ASM29K Ref page 2-9. */
199 void define_some_regs() {
202 /* Protected special-purpose register names */
203 insert_sreg ("vab", SREG
+0);
204 insert_sreg ("ops", SREG
+1);
205 insert_sreg ("cps", SREG
+2);
206 insert_sreg ("cfg", SREG
+3);
207 insert_sreg ("cha", SREG
+4);
208 insert_sreg ("chd", SREG
+5);
209 insert_sreg ("chc", SREG
+6);
210 insert_sreg ("rbp", SREG
+7);
211 insert_sreg ("tmc", SREG
+8);
212 insert_sreg ("tmr", SREG
+9);
213 insert_sreg ("pc0", SREG
+10);
214 insert_sreg ("pc1", SREG
+11);
215 insert_sreg ("pc2", SREG
+12);
216 insert_sreg ("mmu", SREG
+13);
217 insert_sreg ("lru", SREG
+14);
219 /* Unprotected special-purpose register names */
220 insert_sreg ("ipc", SREG
+128);
221 insert_sreg ("ipa", SREG
+129);
222 insert_sreg ("ipb", SREG
+130);
223 insert_sreg ("q", SREG
+131);
224 insert_sreg ("alu", SREG
+132);
225 insert_sreg ("bp", SREG
+133);
226 insert_sreg ("fc", SREG
+134);
227 insert_sreg ("cr", SREG
+135);
228 insert_sreg ("fpe", SREG
+160);
229 insert_sreg ("inte",SREG
+161);
230 insert_sreg ("fps", SREG
+162);
231 /* "", SREG+163); Reserved */
232 insert_sreg ("exop",SREG
+164);
233 } /* define_some_regs() */
235 /* This function is called once, at assembler startup time. It should
236 set up all the tables, etc. that the MD part of the assembler will need. */
240 register char *retval
= NULL
;
242 register int skipnext
= 0;
243 register unsigned int i
;
244 register char *strend
, *strend2
;
246 /* Hash up all the opcodes for fast use later. */
248 op_hash
= hash_new();
250 as_fatal("Virtual memory exhausted");
252 for (i
= 0; i
< num_opcodes
; i
++)
254 const char *name
= machine_opcodes
[i
].name
;
261 /* Hack to avoid multiple opcode entries. We pre-locate all the
262 variations (b/i field and P/A field) and handle them. */
264 if (!strcmp (name
, machine_opcodes
[i
+1].name
)) {
265 if ((machine_opcodes
[i
].opcode
^ machine_opcodes
[i
+1].opcode
)
268 strend
= machine_opcodes
[i
].args
+strlen(machine_opcodes
[i
].args
)-1;
269 strend2
= machine_opcodes
[i
+1].args
+strlen(machine_opcodes
[i
+1].args
)-1;
272 if (*strend2
!= 'i') goto bad_table
;
275 if (*strend2
!= 'b') goto bad_table
;
278 if (*strend2
!= 'A') goto bad_table
;
281 if (*strend2
!= 'P') goto bad_table
;
285 fprintf (stderr
, "internal error: can't handle opcode %s\n", name
);
289 /* OK, this is an i/b or A/P pair. We skip the higher-valued one,
290 and let the code for operand checking handle OR-ing in the bit. */
291 if (machine_opcodes
[i
].opcode
& 1)
297 retval
= hash_insert (op_hash
, name
, &machine_opcodes
[i
]);
298 if (retval
!= NULL
&& *retval
!= '\0')
300 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
301 machine_opcodes
[i
].name
, retval
);
307 as_fatal("Broken assembler. No assembly attempted.");
309 for (i
= '0'; i
< '8'; ++i
)
311 for (i
= '0'; i
<= '9'; ++i
)
313 for (i
= 'a'; i
<= 'f'; ++i
)
314 toHex
[i
] = i
+ 10 - 'a';
315 for (i
= 'A'; i
<= 'F'; ++i
)
316 toHex
[i
] = i
+ 10 - 'A';
325 /* Assemble a single instruction. Its label has already been handled
326 by the generic front end. We just parse opcode and operands, and
327 produce the bytes of data and relocation. */
329 void md_assemble(str
)
338 /* put out the opcode */
339 md_number_to_chars(toP
, the_insn
.opcode
, 4);
341 /* put out the symbol-dependent stuff */
342 if (the_insn
.reloc
!= NO_RELOC
) {
344 frag_now
, /* which frag */
345 (toP
- frag_now
->fr_literal
+ the_insn
.reloc_offset
), /* where */
347 the_insn
.exp
.X_add_symbol
,
348 the_insn
.exp
.X_subtract_symbol
,
349 the_insn
.exp
.X_add_number
,
357 parse_operand (s
, operandp
)
359 expressionS
*operandp
;
361 char *save
= input_line_pointer
;
365 input_line_pointer
= s
;
366 seg
= expr (0, operandp
);
367 new = input_line_pointer
;
368 input_line_pointer
= save
;
382 as_bad("Missing operand");
386 as_bad("Don't understand operand of type %s", segment_name (seg
));
391 /* Instruction parsing. Takes a string containing the opcode.
392 Operands are at input_line_pointer. Output is in the_insn.
393 Warnings or errors are generated. */
402 /* !!!! unsigned long i; */
403 struct machine_opcode
*insn
;
405 unsigned long opcode
;
406 /* !!!! unsigned int mask; */
407 expressionS the_operand
;
408 expressionS
*operand
= &the_operand
;
411 /* Must handle `div0' opcode. */
414 for (; isalnum(*s
); ++s
)
422 case ' ': /* FIXME-SOMEDAY more whitespace */
427 as_bad("Unknown opcode: `%s'", str
);
430 if ((insn
= (struct machine_opcode
*) hash_find(op_hash
, str
)) == NULL
) {
431 as_bad("Unknown opcode `%s'.", str
);
435 opcode
= insn
->opcode
;
436 bzero(&the_insn
, sizeof(the_insn
));
437 the_insn
.reloc
= NO_RELOC
;
440 * Build the opcode, checking as we go to make
441 * sure that the operands match.
443 * If an operand matches, we modify the_insn or opcode appropriately,
444 * and do a "continue". If an operand fails to match, we "break".
446 if (insn
->args
[0] != '\0')
447 s
= parse_operand (s
, operand
); /* Prime the pump */
449 for (args
= insn
->args
; ; ++args
) {
452 case '\0': /* end of args */
454 /* We are truly done. */
455 the_insn
.opcode
= opcode
;
458 as_bad("Too many operands: %s", s
);
461 case ',': /* Must match a comma */
463 s
= parse_operand (s
, operand
); /* Parse next opnd */
468 case 'v': /* Trap numbers (immediate field) */
469 if (operand
->X_seg
== SEG_ABSOLUTE
) {
470 if (operand
->X_add_number
< 256) {
471 opcode
|= (operand
->X_add_number
<< 16);
474 as_bad("Immediate value of %d is too large",
475 operand
->X_add_number
);
479 the_insn
.reloc
= RELOC_8
;
480 the_insn
.reloc_offset
= 1; /* BIG-ENDIAN Byte 1 of insn */
481 the_insn
.exp
= *operand
;
484 case 'b': /* A general register or 8-bit immediate */
486 /* We treat the two cases identically since we mashed
487 them together in the opcode table. */
488 if (operand
->X_seg
== SEG_REGISTER
)
491 opcode
|= IMMEDIATE_BIT
;
492 if (operand
->X_seg
== SEG_ABSOLUTE
) {
493 if (operand
->X_add_number
< 256) {
494 opcode
|= operand
->X_add_number
;
497 as_bad("Immediate value of %d is too large",
498 operand
->X_add_number
);
502 the_insn
.reloc
= RELOC_8
;
503 the_insn
.reloc_offset
= 3; /* BIG-ENDIAN Byte 3 of insn */
504 the_insn
.exp
= *operand
;
507 case 'a': /* next operand must be a register */
510 /* lrNNN or grNNN or %%expr or a user-def register name */
511 if (operand
->X_seg
!= SEG_REGISTER
)
512 break; /* Only registers */
513 know (operand
->X_add_symbol
== 0);
514 know (operand
->X_subtract_symbol
== 0);
515 reg
= operand
->X_add_number
;
517 break; /* No special registers */
520 * Got the register, now figure out where
521 * it goes in the opcode.
537 as_fatal("failed sanity check.");
540 case 'x': /* 16 bit constant, zero-extended */
541 case 'X': /* 16 bit constant, one-extended */
542 if (operand
->X_seg
== SEG_ABSOLUTE
) {
543 opcode
|= (operand
->X_add_number
& 0xFF) << 0 |
544 ((operand
->X_add_number
& 0xFF00) << 8);
547 the_insn
.reloc
= RELOC_CONST
;
548 the_insn
.exp
= *operand
;
552 if (operand
->X_seg
== SEG_ABSOLUTE
) {
553 opcode
|= (operand
->X_add_number
& 0x00FF0000) >> 16 |
554 (((unsigned long)operand
->X_add_number
555 /* avoid sign ext */ & 0xFF000000) >> 8);
558 the_insn
.reloc
= RELOC_CONSTH
;
559 the_insn
.exp
= *operand
;
562 case 'P': /* PC-relative jump address */
563 case 'A': /* Absolute jump address */
564 /* These two are treated together since we folded the
565 opcode table entries together. */
566 if (operand
->X_seg
== SEG_ABSOLUTE
) {
567 opcode
|= ABSOLUTE_BIT
|
568 (operand
->X_add_number
& 0x0003FC00) << 6 |
569 ((operand
->X_add_number
& 0x000003FC) >> 2);
572 the_insn
.reloc
= RELOC_JUMPTARG
;
573 the_insn
.exp
= *operand
;
574 the_insn
.pcrel
= 1; /* Assume PC-relative jump */
575 /* FIXME-SOON, Do we figure out whether abs later, after know sym val? */
578 case 'e': /* Coprocessor enable bit for LOAD/STORE insn */
579 if (operand
->X_seg
== SEG_ABSOLUTE
) {
580 if (operand
->X_add_number
== 0)
582 if (operand
->X_add_number
== 1) {
589 case 'n': /* Control bits for LOAD/STORE instructions */
590 if (operand
->X_seg
== SEG_ABSOLUTE
&&
591 operand
->X_add_number
< 128) {
592 opcode
|= (operand
->X_add_number
<< 16);
597 case 's': /* Special register number */
598 if (operand
->X_seg
!= SEG_REGISTER
)
599 break; /* Only registers */
600 if (operand
->X_add_number
< SREG
)
601 break; /* Not a special register */
602 opcode
|= (operand
->X_add_number
& 0xFF) << 8;
605 case 'u': /* UI bit of CONVERT */
606 if (operand
->X_seg
== SEG_ABSOLUTE
) {
607 if (operand
->X_add_number
== 0)
609 if (operand
->X_add_number
== 1) {
616 case 'r': /* RND bits of CONVERT */
617 if (operand
->X_seg
== SEG_ABSOLUTE
&&
618 operand
->X_add_number
< 8) {
619 opcode
|= operand
->X_add_number
<< 4;
624 case 'd': /* FD bits of CONVERT */
625 if (operand
->X_seg
== SEG_ABSOLUTE
&&
626 operand
->X_add_number
< 4) {
627 opcode
|= operand
->X_add_number
<< 2;
633 case 'f': /* FS bits of CONVERT */
634 if (operand
->X_seg
== SEG_ABSOLUTE
&&
635 operand
->X_add_number
< 4) {
636 opcode
|= operand
->X_add_number
<< 0;
642 if (operand
->X_seg
== SEG_ABSOLUTE
&&
643 operand
->X_add_number
< 4) {
644 opcode
|= operand
->X_add_number
<< 16;
650 if (operand
->X_seg
== SEG_ABSOLUTE
&&
651 operand
->X_add_number
< 16) {
652 opcode
|= operand
->X_add_number
<< 18;
660 /* Types or values of args don't match. */
661 as_bad("Invalid operands");
667 This is identical to the md_atof in m68k.c. I think this is right,
670 Turn a string in input_line_pointer into a floating point constant of type
671 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
672 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
675 /* Equal to MAX_PRECISION in atof-ieee.c */
676 #define MAX_LITTLENUMS 6
679 md_atof(type
,litP
,sizeP
)
685 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
686 LITTLENUM_TYPE
*wordP
;
717 return "Bad call to MD_ATOF()";
719 t
=atof_ieee(input_line_pointer
,type
,words
);
721 input_line_pointer
=t
;
722 *sizeP
=prec
* sizeof(LITTLENUM_TYPE
);
723 for(wordP
=words
;prec
--;) {
724 md_number_to_chars(litP
,(long)(*wordP
++),sizeof(LITTLENUM_TYPE
));
725 litP
+=sizeof(LITTLENUM_TYPE
);
727 return ""; /* Someone should teach Dean about null pointers */
731 * Write out big-endian.
734 md_number_to_chars(buf
,val
,n
)
752 as_fatal("failed sanity check.");
757 void md_apply_fix(fixP
, val
)
761 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
763 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
765 if (fixP
->fx_r_type
== NO_RELOC
) {
766 as_fatal("failed sanity check."); /* FIXME-SOON, if this is never used, remove */
767 switch (fixP
->fx_size
) {
782 as_fatal("failed sanity check.");
787 know(fixP
->fx_size
== 4);
788 know(fixP
->fx_r_type
< NO_RELOC
);
791 * This is a hack. There should be a better way to
794 if (fixP
->fx_r_type
== RELOC_WDISP30
&& fixP
->fx_addsy
) {
795 val
+= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
798 switch (fixP
->fx_r_type
) {
812 val
= (val
>>= 2) + 1;
813 buf
[0] |= (val
>> 24) & 0x3f;
820 buf
[1] |= (val
>> 26) & 0x3f;
826 buf
[2] |= (val
>> 8) & 0x03;
831 buf
[2] |= (val
>> 8) & 0x1f;
836 val
= (val
>>= 2) + 1;
839 buf
[1] |= (val
>> 16) & 0x3f;
853 case RELOC_JUMPTARG
: /* 00XX00XX pattern in a word */
854 buf
[1] = val
>> 10; /* Holds bits 0003FFFC of address */
858 case RELOC_CONST
: /* 00XX00XX pattern in a word */
859 buf
[1] = val
>> 8; /* Holds bits 0000XXXX */
863 case RELOC_CONSTH
: /* 00XX00XX pattern in a word */
864 buf
[1] = val
>> 24; /* Holds bits XXXX0000 */
870 as_bad("bad relocation type: 0x%02x", fixP
->fx_r_type
);
877 short tc_coff_fix2rtype(fixP
)
881 /* FIXME-NOW: relocation type handling is not yet written for
885 switch (fixP
->fx_r_type
) {
886 case RELOC_32
: return(R_WORD
);
887 case RELOC_8
: return(R_BYTE
);
889 } /* switch on type */
892 } /* tc_coff_fix2rtype() */
893 #endif /* OBJ_COFF */
895 /* should never be called for sparc */
896 void md_create_short_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
898 long from_addr
, to_addr
;
902 as_fatal("a29k_create_short_jmp\n");
905 /* should never be called for 29k */
906 void md_convert_frag(headers
, fragP
)
907 object_headers
*headers
;
908 register fragS
*fragP
;
910 as_fatal("sparc_convert_frag\n");
913 /* should never be called for 29k */
914 void md_create_long_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
921 as_fatal("sparc_create_long_jump\n");
924 /* should never be called for sparc */
925 int md_estimate_size_before_relax(fragP
, segtype
)
926 register fragS
*fragP
;
929 as_fatal("sparc_estimate_size_before_relax\n");
933 /* for debugging only */
936 struct machine_it
*insn
;
967 fprintf(stderr
, "ERROR: %s\n");
969 fprintf(stderr
, "opcode=0x%08x\n", insn
->opcode
);
970 fprintf(stderr
, "reloc = %s\n", Reloc
[insn
->reloc
]);
971 fprintf(stderr
, "exp = {\n");
972 fprintf(stderr
, "\t\tX_add_symbol = %s\n",
973 insn
->exp
.X_add_symbol
?
974 (S_GET_NAME(insn
->exp
.X_add_symbol
) ?
975 S_GET_NAME(insn
->exp
.X_add_symbol
) : "???") : "0");
976 fprintf(stderr
, "\t\tX_sub_symbol = %s\n",
977 insn
->exp
.X_subtract_symbol
?
978 (S_GET_NAME(insn
->exp
.X_subtract_symbol
) ?
979 S_GET_NAME(insn
->exp
.X_subtract_symbol
) : "???") : "0");
980 fprintf(stderr
, "\t\tX_add_number = %d\n",
981 insn
->exp
.X_add_number
);
982 fprintf(stderr
, "}\n");
987 /* Translate internal representation of relocation info to target format.
989 On sparc/29k: first 4 bytes are normal unsigned long address, next three
990 bytes are index, most sig. byte first. Byte 7 is broken up with
991 bit 7 as external, bits 6 & 5 unused, and the lower
992 five bits as relocation type. Next 4 bytes are long addend. */
993 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
997 void tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
1000 relax_addressT segment_address_in_file
;
1004 know(fixP
->fx_r_type
< NO_RELOC
);
1005 know(fixP
->fx_addsy
!= NULL
);
1007 r_index
= (S_IS_DEFINED(fixP
->fx_addsy
)
1008 ? S_GET_TYPE(fixP
->fx_addsy
)
1009 : fixP
->fx_addsy
->sy_number
);
1012 md_number_to_chars(where
,
1013 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1016 /* now the fun stuff */
1017 where
[4] = (r_index
>> 16) & 0x0ff;
1018 where
[5] = (r_index
>> 8) & 0x0ff;
1019 where
[6] = r_index
& 0x0ff;
1020 where
[7] = (((!S_IS_DEFINED(fixP
->fx_addsy
)) << 7) & 0x80) | (0 & 0x60) | (fixP
->fx_r_type
& 0x1F);
1022 md_number_to_chars(&where
[8], fixP
->fx_addnumber
, 4);
1025 } /* tc_aout_fix_to_chars() */
1027 #endif /* OBJ_AOUT */
1030 md_parse_option(argP
,cntP
,vecP
)
1039 /* Default the values of symbols known that should be "predefined". We
1040 don't bother to predefine them unless you actually use one, since there
1041 are a lot of them. */
1043 symbolS
*md_undefined_symbol (name
)
1047 char testbuf
[5+ /*SLOP*/ 5];
1049 if (name
[0] == 'g' || name
[0] == 'G' || name
[0] == 'l' || name
[0] == 'L')
1051 /* Perhaps a global or local register name */
1052 if (name
[1] == 'r' || name
[1] == 'R')
1054 /* Parse the number, make sure it has no extra zeroes or trailing
1056 regnum
= atol(&name
[2]);
1059 sprintf(testbuf
, "%ld", regnum
);
1060 if (strcmp (testbuf
, &name
[2]) != 0)
1061 return 0; /* gr007 or lr7foo or whatever */
1063 /* We have a wiener! Define and return a new symbol for it. */
1064 if (name
[0] == 'l' || name
[0] == 'L')
1066 return(symbol_new(name
, SEG_REGISTER
, regnum
, &zero_address_frag
));
1073 /* Parse an operand that is machine-specific. */
1075 void md_operand(expressionP
)
1076 expressionS
*expressionP
;
1079 if (input_line_pointer
[0] == '%' && input_line_pointer
[1] == '%')
1081 /* We have a numeric register expression. No biggy. */
1082 input_line_pointer
+= 2; /* Skip %% */
1083 (void)expression (expressionP
);
1084 if (expressionP
->X_seg
!= SEG_ABSOLUTE
1085 || expressionP
->X_add_number
> 255)
1086 as_bad("Invalid expression after %%%%\n");
1087 expressionP
->X_seg
= SEG_REGISTER
;
1089 else if (input_line_pointer
[0] == '&')
1091 /* We are taking the 'address' of a register...this one is not
1092 in the manual, but it *is* in traps/fpsymbol.h! What they
1093 seem to want is the register number, as an absolute number. */
1094 input_line_pointer
++; /* Skip & */
1095 (void)expression (expressionP
);
1096 if (expressionP
->X_seg
!= SEG_REGISTER
)
1097 as_bad("Invalid register in & expression");
1099 expressionP
->X_seg
= SEG_ABSOLUTE
;
1103 /* Round up a section size to the appropriate boundary. */
1105 md_section_align (segment
, size
)
1109 return size
; /* Byte alignment is fine */
1112 /* Exactly what point is a PC-relative offset relative TO?
1113 On the 29000, they're relative to the address of the instruction,
1114 which we have set up as the address of the fixup too. */
1115 long md_pcrel_from (fixP
)
1118 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1127 /* end of tc-a29k.c */