* as.c (main): Only invoke md_end if it's defined as a macro.
[binutils-gdb.git] / gas / config / tc-tahoe.c
1 /* tc-tahoe.c
2 Not part of GAS yet. */
3
4 #include "as.h"
5 #include "obstack.h"
6
7 /* this bit glommed from tahoe-inst.h */
8
9 typedef unsigned char byte;
10 typedef byte tahoe_opcodeT;
11
12 /*
13 * This is part of tahoe-ins-parse.c & friends.
14 * We want to parse a tahoe instruction text into a tree defined here.
15 */
16
17 #define TIT_MAX_OPERANDS (4) /* maximum number of operands in one
18 single tahoe instruction */
19
20 struct top /* tahoe instruction operand */
21 {
22 int top_ndx; /* -1, or index register. eg 7=[R7] */
23 int top_reg; /* -1, or register number. eg 7 = R7 or (R7) */
24 byte top_mode; /* Addressing mode byte. This byte, defines
25 which of the 11 modes opcode is. */
26
27 char top_access; /* Access type wanted for this opperand
28 'b'branch ' 'no-instruction 'amrvw' */
29 char top_width; /* Operand width expected, one of "bwlq?-:!" */
30
31 char *top_error; /* Say if operand is inappropriate */
32
33 segT seg_of_operand; /* segment as returned by expression()*/
34
35 expressionS exp_of_operand; /* The expression as parsed by expression()*/
36
37 byte top_dispsize; /* Number of bytes in the displacement if we
38 can figure it out */
39 };
40
41 /* The addressing modes for an operand. These numbers are the acutal values
42 for certain modes, so be carefull if you screw with them. */
43 #define TAHOE_DIRECT_REG (0x50)
44 #define TAHOE_REG_DEFERRED (0x60)
45
46 #define TAHOE_REG_DISP (0xE0)
47 #define TAHOE_REG_DISP_DEFERRED (0xF0)
48
49 #define TAHOE_IMMEDIATE (0x8F)
50 #define TAHOE_IMMEDIATE_BYTE (0x88)
51 #define TAHOE_IMMEDIATE_WORD (0x89)
52 #define TAHOE_IMMEDIATE_LONGWORD (0x8F)
53 #define TAHOE_ABSOLUTE_ADDR (0x9F)
54
55 #define TAHOE_DISPLACED_RELATIVE (0xEF)
56 #define TAHOE_DISP_REL_DEFERRED (0xFF)
57
58 #define TAHOE_AUTO_DEC (0x7E)
59 #define TAHOE_AUTO_INC (0x8E)
60 #define TAHOE_AUTO_INC_DEFERRED (0x9E)
61 /* INDEXED_REG is decided by the existance or lack of a [reg] */
62
63 /* These are encoded into top_width when top_access=='b'
64 and it's a psuedo op.*/
65 #define TAHOE_WIDTH_ALWAYS_JUMP '-'
66 #define TAHOE_WIDTH_CONDITIONAL_JUMP '?'
67 #define TAHOE_WIDTH_BIG_REV_JUMP '!'
68 #define TAHOE_WIDTH_BIG_NON_REV_JUMP ':'
69
70 /* The hex code for certain tahoe commands and modes.
71 This is just for readability. */
72 #define TAHOE_JMP (0x71)
73 #define TAHOE_PC_REL_LONG (0xEF)
74 #define TAHOE_BRB (0x11)
75 #define TAHOE_BRW (0x13)
76 /* These, when 'ored' with, or added to, a register number,
77 set up the number for the displacement mode. */
78 #define TAHOE_PC_OR_BYTE (0xA0)
79 #define TAHOE_PC_OR_WORD (0xC0)
80 #define TAHOE_PC_OR_LONG (0xE0)
81
82 struct tit /* get it out of the sewer, it stands for
83 tahoe instruction tree (Geeze!) */
84 {
85 tahoe_opcodeT tit_opcode; /* The opcode. */
86 byte tit_operands; /* How many operands are here. */
87 struct top tit_operand[TIT_MAX_OPERANDS]; /* Operands */
88 char *tit_error; /* "" or fatal error text */
89 };
90
91 /* end: tahoe-inst.h */
92
93 /* tahoe.c - tahoe-specific -
94 Not part of gas yet.
95 */
96
97 #include "opcode/tahoe.h"
98
99 /* This is the number to put at the beginning of the a.out file */
100 long omagic = OMAGIC;
101
102 /* These chars start a comment anywhere in a source file (except inside
103 another comment or a quoted string. */
104 const char comment_chars[] = "#;";
105
106 /* These chars only start a comment at the beginning of a line. */
107 const char line_comment_chars[] = "#";
108
109 /* Chars that can be used to separate mant from exp in floating point nums */
110 const char EXP_CHARS[] = "eE";
111
112 /* Chars that mean this number is a floating point constant
113 as in 0f123.456
114 or 0d1.234E-12 (see exp chars above)
115 Note: The Tahoe port doesn't support floating point constants. This is
116 consistant with 'as' If it's needed, I can always add it later. */
117 const char FLT_CHARS[] = "df";
118
119 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
120 changed in read.c . Ideally it shouldn't have to know about it at all,
121 but nothing is ideal around here.
122 (The tahoe has plenty of room, so the change currently isn't needed.)
123 */
124
125 static struct tit t; /* A tahoe instruction after decoding. */
126
127 void float_cons ();
128 /* A table of pseudo ops (sans .), the function called, and an integer op
129 that the function is called with. */
130
131 const pseudo_typeS md_pseudo_table[] =
132 {
133 {"dfloat", float_cons, 'd'},
134 {"ffloat", float_cons, 'f'},
135 {0}
136 };
137 \f
138 /*
139 * For Tahoe, relative addresses of "just the right length" are pretty easy.
140 * The branch displacement is always the last operand, even in
141 * synthetic instructions.
142 * For Tahoe, we encode the relax_substateTs (in e.g. fr_substate) as:
143 *
144 * 4 3 2 1 0 bit number
145 * ---/ /--+-------+-------+-------+-------+-------+
146 * | what state ? | how long ? |
147 * ---/ /--+-------+-------+-------+-------+-------+
148 *
149 * The "how long" bits are 00=byte, 01=word, 10=long.
150 * This is a Un*x convention.
151 * Not all lengths are legit for a given value of (what state).
152 * The four states are listed below.
153 * The "how long" refers merely to the displacement length.
154 * The address usually has some constant bytes in it as well.
155 *
156
157 States for Tahoe address relaxing.
158 1. TAHOE_WIDTH_ALWAYS_JUMP (-)
159 Format: "b-"
160 Tahoe opcodes are: (Hex)
161 jr 11
162 jbr 11
163 Simple branch.
164 Always, 1 byte opcode, then displacement/absolute.
165 If word or longword, change opcode to brw or jmp.
166
167
168 2. TAHOE_WIDTH_CONDITIONAL_JUMP (?)
169 J<cond> where <cond> is a simple flag test.
170 Format: "b?"
171 Tahoe opcodes are: (Hex)
172 jneq/jnequ 21
173 jeql/jeqlu 31
174 jgtr 41
175 jleq 51
176 jgeq 81
177 jlss 91
178 jgtru a1
179 jlequ b1
180 jvc c1
181 jvs d1
182 jlssu/jcs e1
183 jgequ/jcc f1
184 Always, you complement 4th bit to reverse the condition.
185 Always, 1-byte opcode, then 1-byte displacement.
186
187 3. TAHOE_WIDTH_BIG_REV_JUMP (!)
188 Jbc/Jbs where cond tests a memory bit.
189 Format: "rlvlb!"
190 Tahoe opcodes are: (Hex)
191 jbs 0e
192 jbc 1e
193 Always, you complement 4th bit to reverse the condition.
194 Always, 1-byte opcde, longword, longword-address, 1-word-displacement
195
196 4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:)
197 JaoblXX/Jbssi
198 Format: "rlmlb:"
199 Tahoe opcodes are: (Hex)
200 aojlss 2f
201 jaoblss 2f
202 aojleq 3f
203 jaobleq 3f
204 jbssi 5f
205 Always, we cannot reverse the sense of the branch; we have a word
206 displacement.
207
208 We need to modify the opcode is for class 1, 2 and 3 instructions.
209 After relax() we may complement the 4th bit of 2 or 3 to reverse sense of
210 branch.
211
212 We sometimes store context in the operand literal. This way we can figure out
213 after relax() what the original addressing mode was. (Was is pc_rel, or
214 pc_rel_disp? That sort of thing.) */
215 \f
216 /* These displacements are relative to the START address of the
217 displacement which is at the start of the displacement, not the end of
218 the instruction. The hardware pc_rel is at the end of the instructions.
219 That's why all the displacements have the length of the displacement added
220 to them. (WF + length(word))
221
222 The first letter is Byte, Word.
223 2nd letter is Forward, Backward. */
224 #define BF (1+ 127)
225 #define BB (1+-128)
226 #define WF (2+ 32767)
227 #define WB (2+-32768)
228 /* Dont need LF, LB because they always reach. [They are coded as 0.] */
229
230 #define C(a,b) ENCODE_RELAX(a,b)
231 /* This macro has no side-effects. */
232 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
233 #define RELAX_STATE(what) ((what) >> 2)
234 #define RELAX_LENGTH(length) ((length) && 3)
235
236 #define STATE_ALWAYS_BRANCH (1)
237 #define STATE_CONDITIONAL_BRANCH (2)
238 #define STATE_BIG_REV_BRANCH (3)
239 #define STATE_BIG_NON_REV_BRANCH (4)
240 #define STATE_PC_RELATIVE (5)
241
242 #define STATE_BYTE (0)
243 #define STATE_WORD (1)
244 #define STATE_LONG (2)
245 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
246
247 /* This is the table used by gas to figure out relaxing modes. The fields are
248 forward_branch reach, backward_branch reach, number of bytes it would take,
249 where the next biggest branch is. */
250 const relax_typeS
251 md_relax_table[] =
252 {
253 {
254 1, 1, 0, 0
255 }, /* error sentinel 0,0 */
256 {
257 1, 1, 0, 0
258 }, /* unused 0,1 */
259 {
260 1, 1, 0, 0
261 }, /* unused 0,2 */
262 {
263 1, 1, 0, 0
264 }, /* unused 0,3 */
265 /* Unconditional branch cases "jrb"
266 The relax part is the actual displacement */
267 {
268 BF, BB, 1, C (1, 1)
269 }, /* brb B`foo 1,0 */
270 {
271 WF, WB, 2, C (1, 2)
272 }, /* brw W`foo 1,1 */
273 {
274 0, 0, 5, 0
275 }, /* Jmp L`foo 1,2 */
276 {
277 1, 1, 0, 0
278 }, /* unused 1,3 */
279 /* Reversible Conditional Branch. If the branch won't reach, reverse
280 it, and jump over a brw or a jmp that will reach. The relax part is the
281 actual address. */
282 {
283 BF, BB, 1, C (2, 1)
284 }, /* b<cond> B`foo 2,0 */
285 {
286 WF + 2, WB + 2, 4, C (2, 2)
287 }, /* brev over, brw W`foo, over: 2,1 */
288 {
289 0, 0, 7, 0
290 }, /* brev over, jmp L`foo, over: 2,2 */
291 {
292 1, 1, 0, 0
293 }, /* unused 2,3 */
294 /* Another type of reversable branch. But this only has a word
295 displacement. */
296 {
297 1, 1, 0, 0
298 }, /* unused 3,0 */
299 {
300 WF, WB, 2, C (3, 2)
301 }, /* jbX W`foo 3,1 */
302 {
303 0, 0, 8, 0
304 }, /* jrevX over, jmp L`foo, over: 3,2 */
305 {
306 1, 1, 0, 0
307 }, /* unused 3,3 */
308 /* These are the non reversable branches, all of which have a word
309 displacement. If I can't reach, branch over a byte branch, to a
310 jump that will reach. The jumped branch jumps over the reaching
311 branch, to continue with the flow of the program. It's like playing
312 leap frog. */
313 {
314 1, 1, 0, 0
315 }, /* unused 4,0 */
316 {
317 WF, WB, 2, C (4, 2)
318 }, /* aobl_ W`foo 4,1 */
319 {
320 0, 0, 10, 0
321 }, /*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/
322 {
323 1, 1, 0, 0
324 }, /* unused 4,3 */
325 /* Normal displacement mode, no jumping or anything like that.
326 The relax points to one byte before the address, thats why all
327 the numbers are up by one. */
328 {
329 BF + 1, BB + 1, 2, C (5, 1)
330 }, /* B^"foo" 5,0 */
331 {
332 WF + 1, WB + 1, 3, C (5, 2)
333 }, /* W^"foo" 5,1 */
334 {
335 0, 0, 5, 0
336 }, /* L^"foo" 5,2 */
337 {
338 1, 1, 0, 0
339 }, /* unused 5,3 */
340 };
341
342 #undef C
343 #undef BF
344 #undef BB
345 #undef WF
346 #undef WB
347 /* End relax stuff */
348 \f
349 /* Handle of the OPCODE hash table. NULL means any use before
350 md_begin() will crash. */
351 static struct hash_control *op_hash;
352
353 /* Init function. Build the hash table. */
354 void
355 md_begin ()
356 {
357 struct tot *tP;
358 char *errorval = 0;
359 int synthetic_too = 1; /* If 0, just use real opcodes. */
360
361 op_hash = hash_new ();
362
363 for (tP = totstrs; *tP->name && !errorval; tP++)
364 errorval = hash_insert (op_hash, tP->name, &tP->detail);
365
366 if (synthetic_too)
367 for (tP = synthetic_totstrs; *tP->name && !errorval; tP++)
368 errorval = hash_insert (op_hash, tP->name, &tP->detail);
369
370 if (errorval)
371 as_fatal (errorval);
372 }
373 \f
374 int
375 md_parse_option (argP, cntP, vecP)
376 char **argP;
377 int *cntP;
378 char ***vecP;
379 {
380 char *temp_name; /* name for -t or -d options */
381 char opt;
382
383 switch (**argP)
384 {
385 case 'a':
386 as_warn ("The -a option doesn't exits. (Dispite what the man page says!");
387
388 case 'J':
389 as_warn ("JUMPIFY (-J) not implemented, use psuedo ops instead.");
390 break;
391
392 case 'S':
393 as_warn ("SYMBOL TABLE not implemented");
394 break; /* SYMBOL TABLE not implemented */
395
396 case 'T':
397 as_warn ("TOKEN TRACE not implemented");
398 break; /* TOKEN TRACE not implemented */
399
400 case 'd':
401 case 't':
402 opt = **argP;
403 if (**argP)
404 { /* Rest of argument is filename. */
405 temp_name = *argP;
406 while (**argP)
407 (*argP)++;
408 }
409 else if (*cntP)
410 {
411 while (**argP)
412 (*argP)++;
413 --(*cntP);
414 temp_name = *++(*vecP);
415 **vecP = NULL; /* Remember this is not a file-name. */
416 }
417 else
418 {
419 as_warn ("I expected a filename after -%c.", opt);
420 temp_name = "{absent}";
421 }
422
423 if (opt == 'd')
424 as_warn ("Displacement length %s ignored!", temp_name);
425 else
426 as_warn ("I don't need or use temp. file \"%s\".", temp_name);
427 break;
428
429 case 'V':
430 as_warn ("I don't use an interpass file! -V ignored");
431 break;
432
433 default:
434 return 0;
435
436 }
437 return 1;
438 }
439 \f
440 /* The functions in this section take numbers in the machine format, and
441 munges them into Tahoe byte order.
442 They exist primarily for cross assembly purpose. */
443 void /* Knows about order of bytes in address. */
444 md_number_to_chars (con, value, nbytes)
445 char con[]; /* Return 'nbytes' of chars here. */
446 valueT value; /* The value of the bits. */
447 int nbytes; /* Number of bytes in the output. */
448 {
449 number_to_chars_bigendian (con, value, nbytes);
450 }
451
452 #ifdef comment
453 void /* Knows about order of bytes in address. */
454 md_number_to_imm (con, value, nbytes)
455 char con[]; /* Return 'nbytes' of chars here. */
456 long int value; /* The value of the bits. */
457 int nbytes; /* Number of bytes in the output. */
458 {
459 md_number_to_chars (con, value, nbytes);
460 }
461
462 #endif /* comment */
463
464 void
465 tc_apply_fix (fixP, val)
466 fixS *fixP;
467 long val;
468 {
469 /* should never be called */
470 know (0);
471 }
472
473 void /* Knows about order of bytes in address. */
474 md_number_to_disp (con, value, nbytes)
475 char con[]; /* Return 'nbytes' of chars here. */
476 long int value; /* The value of the bits. */
477 int nbytes; /* Number of bytes in the output. */
478 {
479 md_number_to_chars (con, value, nbytes);
480 }
481
482 void /* Knows about order of bytes in address. */
483 md_number_to_field (con, value, nbytes)
484 char con[]; /* Return 'nbytes' of chars here. */
485 long int value; /* The value of the bits. */
486 int nbytes; /* Number of bytes in the output. */
487 {
488 md_number_to_chars (con, value, nbytes);
489 }
490
491 /* Put the bits in an order that a tahoe will understand, despite the ordering
492 of the native machine.
493 On Tahoe: first 4 bytes are normal unsigned big endian long,
494 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
495 The last byte is broken up with bit 7 as pcrel,
496 bits 6 & 5 as length,
497 bit 4 as extern and the last nibble as 'undefined'. */
498
499 #if comment
500 void
501 md_ri_to_chars (ri_p, ri)
502 struct relocation_info *ri_p, ri;
503 {
504 byte the_bytes[sizeof (struct relocation_info)];
505 /* The reason I can't just encode these directly into ri_p is that
506 ri_p may point to ri. */
507
508 /* This is easy */
509 md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
510
511 /* now the fun stuff */
512 the_bytes[4] = (ri.r_symbolnum >> 16) & 0x0ff;
513 the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
514 the_bytes[6] = ri.r_symbolnum & 0x0ff;
515 the_bytes[7] = (((ri.r_extern << 4) & 0x10) | ((ri.r_length << 5) & 0x60) |
516 ((ri.r_pcrel << 7) & 0x80)) & 0xf0;
517
518 bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));
519 }
520
521 #endif /* comment */
522
523 /* Put the bits in an order that a tahoe will understand, despite the ordering
524 of the native machine.
525 On Tahoe: first 4 bytes are normal unsigned big endian long,
526 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
527 The last byte is broken up with bit 7 as pcrel,
528 bits 6 & 5 as length,
529 bit 4 as extern and the last nibble as 'undefined'. */
530
531 void
532 tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
533 char *where;
534 fixS *fixP;
535 relax_addressT segment_address_in_file;
536 {
537 long r_symbolnum;
538
539 know (fixP->fx_addsy != NULL);
540
541 md_number_to_chars (where,
542 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
543 4);
544
545 r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
546 ? S_GET_TYPE (fixP->fx_addsy)
547 : fixP->fx_addsy->sy_number);
548
549 where[4] = (r_symbolnum >> 16) & 0x0ff;
550 where[5] = (r_symbolnum >> 8) & 0x0ff;
551 where[6] = r_symbolnum & 0x0ff;
552 where[7] = (((is_pcrel (fixP) << 7) & 0x80)
553 | ((((fixP->fx_type == FX_8 || fixP->fx_type == FX_PCREL8
554 ? 0
555 : (fixP->fx_type == FX_16 || fixP->fx_type == FX_PCREL16
556 ? 1
557 : (fixP->fx_type == FX_32 || fixP->fx_type == FX_PCREL32
558 ? 2
559 : 42)))) << 5) & 0x60)
560 | ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10));
561 }
562
563 /* Relocate byte stuff */
564 \f
565 /* This is for broken word. */
566 const int md_short_jump_size = 3;
567
568 void
569 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
570 char *ptr;
571 addressT from_addr, to_addr;
572 fragS *frag;
573 symbolS *to_symbol;
574 {
575 valueT offset;
576
577 offset = to_addr - (from_addr + 1);
578 *ptr++ = TAHOE_BRW;
579 md_number_to_chars (ptr, offset, 2);
580 }
581
582 const int md_long_jump_size = 6;
583 const int md_reloc_size = 8; /* Size of relocation record */
584
585 void
586 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
587 char *ptr;
588 addressT from_addr, to_addr;
589 fragS *frag;
590 symbolS *to_symbol;
591 {
592 valueT offset;
593
594 offset = to_addr - (from_addr + 4);
595 *ptr++ = TAHOE_JMP;
596 *ptr++ = TAHOE_PC_REL_LONG;
597 md_number_to_chars (ptr, offset, 4);
598 }
599 \f
600 /*
601 * md_estimate_size_before_relax()
602 *
603 * Called just before relax().
604 * Any symbol that is now undefined will not become defined, so we assumed
605 * that it will be resolved by the linker.
606 * Return the correct fr_subtype in the frag, for relax()
607 * Return the initial "guess for fr_var" to caller. (How big I think this
608 * will be.)
609 * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
610 * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
611 * Although it may not be explicit in the frag, pretend fr_var starts with a
612 * 0 value.
613 */
614 int
615 md_estimate_size_before_relax (fragP, segment_type)
616 register fragS *fragP;
617 segT segment_type; /* N_DATA or N_TEXT. */
618 {
619 register char *p;
620 register int old_fr_fix;
621 /* int pc_rel; FIXME: remove this */
622
623 old_fr_fix = fragP->fr_fix;
624 switch (fragP->fr_subtype)
625 {
626 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
627 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
628 {
629 /* The symbol was in the same segment as the opcode, and it's
630 a real pc_rel case so it's a relaxable case. */
631 fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
632 }
633 else
634 {
635 /* This case is still undefined, so asume it's a long word for the
636 linker to fix. */
637 p = fragP->fr_literal + old_fr_fix;
638 *p |= TAHOE_PC_OR_LONG;
639 /* We now know how big it will be, one long word. */
640 fragP->fr_fix += 1 + 4;
641 fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
642 fragP->fr_offset, FX_PCREL32, NULL);
643 frag_wane (fragP);
644 }
645 break;
646
647 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
648 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
649 {
650 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
651 }
652 else
653 {
654 p = fragP->fr_literal + old_fr_fix;
655 *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
656 *p++ = 6;
657 *p++ = TAHOE_JMP;
658 *p++ = TAHOE_PC_REL_LONG;
659 fragP->fr_fix += 1 + 1 + 1 + 4;
660 fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol,
661 fragP->fr_offset, FX_PCREL32, NULL);
662 frag_wane (fragP);
663 }
664 break;
665
666 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_UNDF):
667 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
668 {
669 fragP->fr_subtype =
670 ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);
671 }
672 else
673 {
674 p = fragP->fr_literal + old_fr_fix;
675 *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
676 *p++ = 0;
677 *p++ = 6;
678 *p++ = TAHOE_JMP;
679 *p++ = TAHOE_PC_REL_LONG;
680 fragP->fr_fix += 2 + 2 + 4;
681 fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol,
682 fragP->fr_offset, FX_PCREL32, NULL);
683 frag_wane (fragP);
684 }
685 break;
686
687 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_UNDF):
688 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
689 {
690 fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD);
691 }
692 else
693 {
694 p = fragP->fr_literal + old_fr_fix;
695 *p++ = 2;
696 *p++ = 0;
697 *p++ = TAHOE_BRB;
698 *p++ = 6;
699 *p++ = TAHOE_JMP;
700 *p++ = TAHOE_PC_REL_LONG;
701 fragP->fr_fix += 2 + 2 + 2 + 4;
702 fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol,
703 fragP->fr_offset, FX_PCREL32, NULL);
704 frag_wane (fragP);
705 }
706 break;
707
708 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
709 if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
710 {
711 fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
712 }
713 else
714 {
715 p = fragP->fr_literal + old_fr_fix;
716 *fragP->fr_opcode = TAHOE_JMP;
717 *p++ = TAHOE_PC_REL_LONG;
718 fragP->fr_fix += 1 + 4;
719 fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,
720 fragP->fr_offset, FX_PCREL32, NULL);
721 frag_wane (fragP);
722 }
723 break;
724
725 default:
726 break;
727 }
728 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
729 } /* md_estimate_size_before_relax() */
730 \f
731 /*
732 * md_convert_frag();
733 *
734 * Called after relax() is finished.
735 * In: Address of frag.
736 * fr_type == rs_machine_dependent.
737 * fr_subtype is what the address relaxed to.
738 *
739 * Out: Any fixSs and constants are set up.
740 * Caller will turn frag into a ".space 0".
741 */
742 void
743 md_convert_frag (headers, fragP)
744 object_headers *headers;
745 register fragS *fragP;
746 {
747 register char *addressP; /* -> _var to change. */
748 register char *opcodeP; /* -> opcode char(s) to change. */
749 register short int length_code; /* 2=long 1=word 0=byte */
750 register short int extension = 0; /* Size of relaxed address.
751 Added to fr_fix: incl. ALL var chars. */
752 register symbolS *symbolP;
753 register long int where;
754 register long int address_of_var;
755 /* Where, in file space, is _var of *fragP? */
756 register long int target_address;
757 /* Where, in file space, does addr point? */
758
759 know (fragP->fr_type == rs_machine_dependent);
760 length_code = RELAX_LENGTH (fragP->fr_subtype);
761 know (length_code >= 0 && length_code < 3);
762 where = fragP->fr_fix;
763 addressP = fragP->fr_literal + where;
764 opcodeP = fragP->fr_opcode;
765 symbolP = fragP->fr_symbol;
766 know (symbolP);
767 target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;
768 address_of_var = fragP->fr_address + where;
769 switch (fragP->fr_subtype)
770 {
771 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
772 /* *addressP holds the registers number, plus 0x10, if it's deferred
773 mode. To set up the right mode, just OR the size of this displacement */
774 /* Byte displacement. */
775 *addressP++ |= TAHOE_PC_OR_BYTE;
776 *addressP = target_address - (address_of_var + 2);
777 extension = 2;
778 break;
779
780 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
781 /* Word displacement. */
782 *addressP++ |= TAHOE_PC_OR_WORD;
783 md_number_to_chars (addressP, target_address - (address_of_var + 3), 2);
784 extension = 3;
785 break;
786
787 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
788 /* Long word displacement. */
789 *addressP++ |= TAHOE_PC_OR_LONG;
790 md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);
791 extension = 5;
792 break;
793
794 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
795 *addressP = target_address - (address_of_var + 1);
796 extension = 1;
797 break;
798
799 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
800 *opcodeP ^= 0x10; /* Reverse sense of test. */
801 *addressP++ = 3; /* Jump over word branch */
802 *addressP++ = TAHOE_BRW;
803 md_number_to_chars (addressP, target_address - (address_of_var + 4), 2);
804 extension = 4;
805 break;
806
807 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
808 *opcodeP ^= 0x10; /* Reverse sense of test. */
809 *addressP++ = 6;
810 *addressP++ = TAHOE_JMP;
811 *addressP++ = TAHOE_PC_REL_LONG;
812 md_number_to_chars (addressP, target_address, 4);
813 extension = 7;
814 break;
815
816 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
817 *addressP = target_address - (address_of_var + 1);
818 extension = 1;
819 break;
820
821 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
822 *opcodeP = TAHOE_BRW;
823 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
824 extension = 2;
825 break;
826
827 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
828 *opcodeP = TAHOE_JMP;
829 *addressP++ = TAHOE_PC_REL_LONG;
830 md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);
831 extension = 5;
832 break;
833
834 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD):
835 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
836 extension = 2;
837 break;
838
839 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_LONG):
840 *opcodeP ^= 0x10;
841 *addressP++ = 0;
842 *addressP++ = 6;
843 *addressP++ = TAHOE_JMP;
844 *addressP++ = TAHOE_PC_REL_LONG;
845 md_number_to_chars (addressP, target_address, 4);
846 extension = 8;
847 break;
848
849 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD):
850 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
851 extension = 2;
852 break;
853
854 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_LONG):
855 *addressP++ = 0;
856 *addressP++ = 2;
857 *addressP++ = TAHOE_BRB;
858 *addressP++ = 6;
859 *addressP++ = TAHOE_JMP;
860 *addressP++ = TAHOE_PC_REL_LONG;
861 md_number_to_chars (addressP, target_address, 4);
862 extension = 10;
863 break;
864
865 default:
866 BAD_CASE (fragP->fr_subtype);
867 break;
868 }
869 fragP->fr_fix += extension;
870 } /* md_convert_frag */
871 \f
872
873 /* This is the stuff for md_assemble. */
874 #define FP_REG 13
875 #define SP_REG 14
876 #define PC_REG 15
877 #define BIGGESTREG PC_REG
878
879 /*
880 * Parse the string pointed to by START
881 * If it represents a valid register, point START to the character after
882 * the last valid register char, and return the register number (0-15).
883 * If invalid, leave START alone, return -1.
884 * The format has to be exact. I don't do things like eat leading zeros
885 * or the like.
886 * Note: This doesn't check for the next character in the string making
887 * this invalid. Ex: R123 would return 12, it's the callers job to check
888 * what start is point to apon return.
889 *
890 * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15)
891 * Case doesn't matter.
892 */
893 int
894 tahoe_reg_parse (start)
895 char **start; /* A pointer to the string to parse. */
896 {
897 register char *regpoint = *start;
898 register int regnum = -1;
899
900 switch (*regpoint++)
901 {
902 case '%': /* Registers can start with a %,
903 R or r, and then a number. */
904 case 'R':
905 case 'r':
906 if (isdigit (*regpoint))
907 {
908 /* Got the first digit. */
909 regnum = *regpoint++ - '0';
910 if ((regnum == 1) && isdigit (*regpoint))
911 {
912 /* Its a two digit number. */
913 regnum = 10 + (*regpoint++ - '0');
914 if (regnum > BIGGESTREG)
915 { /* Number too big? */
916 regnum = -1;
917 }
918 }
919 }
920 break;
921 case 'F': /* Is it the FP */
922 case 'f':
923 switch (*regpoint++)
924 {
925 case 'p':
926 case 'P':
927 regnum = FP_REG;
928 }
929 break;
930 case 's': /* How about the SP */
931 case 'S':
932 switch (*regpoint++)
933 {
934 case 'p':
935 case 'P':
936 regnum = SP_REG;
937 }
938 break;
939 case 'p': /* OR the PC even */
940 case 'P':
941 switch (*regpoint++)
942 {
943 case 'c':
944 case 'C':
945 regnum = PC_REG;
946 }
947 break;
948 }
949
950 if (regnum != -1)
951 { /* No error, so move string pointer */
952 *start = regpoint;
953 }
954 return regnum; /* Return results */
955 } /* tahoe_reg_parse */
956 \f
957 /*
958 * This chops up an operand and figures out its modes and stuff.
959 * It's a little touchy about extra characters.
960 * Optex to start with one extra character so it can be overwritten for
961 * the backward part of the parsing.
962 * You can't put a bunch of extra characters in side to
963 * make the command look cute. ie: * foo ( r1 ) [ r0 ]
964 * If you like doing a lot of typing, try COBOL!
965 * Actually, this parser is a little weak all around. It's designed to be
966 * used with compliers, so I emphisise correct decoding of valid code quickly
967 * rather that catching every possable error.
968 * Note: This uses the expression function, so save input_line_pointer before
969 * calling.
970 *
971 * Sperry defines the semantics of address modes (and values)
972 * by a two-letter code, explained here.
973 *
974 * letter 1: access type
975 *
976 * a address calculation - no data access, registers forbidden
977 * b branch displacement
978 * m read - let go of bus - write back "modify"
979 * r read
980 * w write
981 * v bit field address: like 'a' but registers are OK
982 *
983 * letter 2: data type (i.e. width, alignment)
984 *
985 * b byte
986 * w word
987 * l longword
988 * q quadword (Even regs < 14 allowed) (if 12, you get a warning)
989 * - unconditional synthetic jbr operand
990 * ? simple synthetic reversable branch operand
991 * ! complex synthetic reversable branch operand
992 * : complex synthetic non-reversable branch operand
993 *
994 * The '-?!:' letter 2's are not for external consumption. They are used
995 * by GAS for psuedo ops relaxing code.
996 *
997 * After parsing topP has:
998 *
999 * top_ndx: -1, or the index register. eg 7=[R7]
1000 * top_reg: -1, or register number. eg 7 = R7 or (R7)
1001 * top_mode: The addressing mode byte. This byte, defines which of
1002 * the 11 modes opcode is.
1003 * top_access: Access type wanted for this opperand 'b'branch ' '
1004 * no-instruction 'amrvw'
1005 * top_width: Operand width expected, one of "bwlq?-:!"
1006 * exp_of_operand: The expression as parsed by expression()
1007 * top_dispsize: Number of bytes in the displacement if we can figure it
1008 * out and it's relavent.
1009 *
1010 * Need syntax checks built.
1011 */
1012
1013 void
1014 tip_op (optex, topP)
1015 char *optex; /* The users text input, with one leading character */
1016 struct top *topP; /* The tahoe instruction with some fields already set:
1017 in: access, width
1018 out: ndx, reg, mode, error, dispsize */
1019
1020 {
1021 int mode = 0; /* This operand's mode. */
1022 char segfault = *optex; /* To keep the back parsing from freaking. */
1023 char *point = optex + 1; /* Parsing from front to back. */
1024 char *end; /* Parsing from back to front. */
1025 int reg = -1; /* major register, -1 means absent */
1026 int imreg = -1; /* Major register in immediate mode */
1027 int ndx = -1; /* index register number, -1 means absent */
1028 char dec_inc = ' '; /* Is the SP auto-incremented '+' or
1029 auto-decremented '-' or neither ' '. */
1030 int immediate = 0; /* 1 if '$' immediate mode */
1031 int call_width = 0; /* If the caller casts the displacement */
1032 int abs_width = 0; /* The width of the absolute displacment */
1033 int com_width = 0; /* Displacement width required by branch */
1034 int deferred = 0; /* 1 if '*' deferral is used */
1035 byte disp_size = 0; /* How big is this operand. 0 == don't know */
1036 char *op_bad = ""; /* Bad operand error */
1037
1038 char *tp, *temp, c; /* Temporary holders */
1039
1040 char access = topP->top_access; /* Save on a deref. */
1041 char width = topP->top_width;
1042
1043 int really_none = 0; /* Empty expressions evaluate to 0
1044 but I need to know if it's there or not */
1045 expressionS *expP; /* -> expression values for this operand */
1046
1047 /* Does this command restrict the displacement size. */
1048 if (access == 'b')
1049 com_width = (width == 'b' ? 1 :
1050 (width == 'w' ? 2 :
1051 (width == 'l' ? 4 : 0)));
1052
1053 *optex = '\0'; /* This is kind of a back stop for all
1054 the searches to fail on if needed.*/
1055 if (*point == '*')
1056 { /* A dereference? */
1057 deferred = 1;
1058 point++;
1059 }
1060
1061 /* Force words into a certain mode */
1062 /* Bitch, Bitch, Bitch! */
1063 /*
1064 * Using the ^ operator is ambigous. If I have an absolute label
1065 * called 'w' set to, say 2, and I have the expression 'w^1', do I get
1066 * 1, forced to be in word displacement mode, or do I get the value of
1067 * 'w' or'ed with 1 (3 in this case).
1068 * The default is 'w' as an offset, so that's what I use.
1069 * Stick with `, it does the same, and isn't ambig.
1070 */
1071
1072 if (*point != '\0' && ((point[1] == '^') || (point[1] == '`')))
1073 switch (*point)
1074 {
1075 case 'b':
1076 case 'B':
1077 case 'w':
1078 case 'W':
1079 case 'l':
1080 case 'L':
1081 if (com_width)
1082 as_warn ("Casting a branch displacement is bad form, and is ignored.");
1083 else
1084 {
1085 c = (isupper (*point) ? tolower (*point) : *point);
1086 call_width = ((c == 'b') ? 1 :
1087 ((c == 'w') ? 2 : 4));
1088 }
1089 point += 2;
1090 break;
1091 }
1092
1093 /* Setting immediate mode */
1094 if (*point == '$')
1095 {
1096 immediate = 1;
1097 point++;
1098 }
1099
1100 /*
1101 * I've pulled off all the easy stuff off the front, move to the end and
1102 * yank.
1103 */
1104
1105 for (end = point; *end != '\0'; end++) /* Move to the end. */
1106 ;
1107
1108 if (end != point) /* Null string? */
1109 end--;
1110
1111 if (end > point && *end == ' ' && end[-1] != '\'')
1112 end--; /* Hop white space */
1113
1114 /* Is this an index reg. */
1115 if ((*end == ']') && (end[-1] != '\''))
1116 {
1117 temp = end;
1118
1119 /* Find opening brace. */
1120 for (--end; (*end != '[' && end != point); end--)
1121 ;
1122
1123 /* If I found the opening brace, get the index register number. */
1124 if (*end == '[')
1125 {
1126 tp = end + 1; /* tp should point to the start of a reg. */
1127 ndx = tahoe_reg_parse (&tp);
1128 if (tp != temp)
1129 { /* Reg. parse error. */
1130 ndx = -1;
1131 }
1132 else
1133 {
1134 end--; /* Found it, move past brace. */
1135 }
1136 if (ndx == -1)
1137 {
1138 op_bad = "Couldn't parse the [index] in this operand.";
1139 end = point; /* Force all the rest of the tests to fail. */
1140 }
1141 }
1142 else
1143 {
1144 op_bad = "Couldn't find the opening '[' for the index of this operand.";
1145 end = point; /* Force all the rest of the tests to fail. */
1146 }
1147 }
1148
1149 /* Post increment? */
1150 if (*end == '+')
1151 {
1152 dec_inc = '+';
1153 /* was: *end--; */
1154 end--;
1155 }
1156
1157 /* register in parens? */
1158 if ((*end == ')') && (end[-1] != '\''))
1159 {
1160 temp = end;
1161
1162 /* Find opening paren. */
1163 for (--end; (*end != '(' && end != point); end--)
1164 ;
1165
1166 /* If I found the opening paren, get the register number. */
1167 if (*end == '(')
1168 {
1169 tp = end + 1;
1170 reg = tahoe_reg_parse (&tp);
1171 if (tp != temp)
1172 {
1173 /* Not a register, but could be part of the expression. */
1174 reg = -1;
1175 end = temp; /* Rest the pointer back */
1176 }
1177 else
1178 {
1179 end--; /* Found the reg. move before opening paren. */
1180 }
1181 }
1182 else
1183 {
1184 op_bad = "Couldn't find the opening '(' for the deref of this operand.";
1185 end = point; /* Force all the rest of the tests to fail. */
1186 }
1187 }
1188
1189 /* Pre decrement? */
1190 if (*end == '-')
1191 {
1192 if (dec_inc != ' ')
1193 {
1194 op_bad = "Operand can't be both pre-inc and post-dec.";
1195 end = point;
1196 }
1197 else
1198 {
1199 dec_inc = '-';
1200 /* was: *end--; */
1201 end--;
1202 }
1203 }
1204
1205 /*
1206 * Everything between point and end is the 'expression', unless it's
1207 * a register name.
1208 */
1209
1210 c = end[1];
1211 end[1] = '\0';
1212
1213 tp = point;
1214 imreg = tahoe_reg_parse (&point); /* Get the immediate register
1215 if it is there.*/
1216 if (*point != '\0')
1217 {
1218 /* If there is junk after point, then the it's not immediate reg. */
1219 point = tp;
1220 imreg = -1;
1221 }
1222
1223 if (imreg != -1 && reg != -1)
1224 op_bad = "I parsed 2 registers in this operand.";
1225
1226 /*
1227 * Evaluate whats left of the expression to see if it's valid.
1228 * Note again: This assumes that the calling expression has saved
1229 * input_line_pointer. (Nag, nag, nag!)
1230 */
1231
1232 if (*op_bad == '\0')
1233 {
1234 /* statement has no syntax goofs yet: lets sniff the expression */
1235 input_line_pointer = point;
1236 expP = &(topP->exp_of_operand);
1237 topP->seg_of_operand = expression (expP);
1238 switch (expP->X_op)
1239 {
1240 case O_absent:
1241 /* No expression. For BSD4.2 compatibility, missing expression is
1242 absolute 0 */
1243 expP->X_op = O_constant;
1244 expP->X_add_number = 0;
1245 really_none = 1;
1246 case O_constant:
1247 /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol,
1248 X_add_symbol to any particular value. */
1249 /* But, we will program defensively. Since this situation occurs
1250 rarely so it costs us little to do so. */
1251 expP->X_add_symbol = NULL;
1252 expP->X_op_symbol = NULL;
1253 /* How many bytes are needed to express this abs value? */
1254 abs_width =
1255 ((((expP->X_add_number & 0xFFFFFF80) == 0) ||
1256 ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 :
1257 (((expP->X_add_number & 0xFFFF8000) == 0) ||
1258 ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4);
1259
1260 case O_symbol:
1261 break;
1262
1263 default:
1264 /*
1265 * Major bug. We can't handle the case of a operator
1266 * expression in a synthetic opcode variable-length
1267 * instruction. We don't have a frag type that is smart
1268 * enough to relax a operator, and so we just force all
1269 * operators to behave like SEG_PASS1s. Clearly, if there is
1270 * a demand we can invent a new or modified frag type and
1271 * then coding up a frag for this case will be easy.
1272 */
1273 need_pass_2 = 1;
1274 op_bad = "Can't relocate expression error.";
1275 break;
1276
1277 case O_big:
1278 /* This is an error. Tahoe doesn't allow any expressions
1279 bigger that a 32 bit long word. Any bigger has to be referenced
1280 by address. */
1281 op_bad = "Expression is too large for a 32 bits.";
1282 break;
1283 }
1284 if (*input_line_pointer != '\0')
1285 {
1286 op_bad = "Junk at end of expression.";
1287 }
1288 }
1289
1290 end[1] = c;
1291
1292 /* I'm done, so restore optex */
1293 *optex = segfault;
1294
1295
1296 /*
1297 * At this point in the game, we (in theory) have all the components of
1298 * the operand at least parsed. Now it's time to check for syntax/semantic
1299 * errors, and build the mode.
1300 * This is what I have:
1301 * deferred = 1 if '*'
1302 * call_width = 0,1,2,4
1303 * abs_width = 0,1,2,4
1304 * com_width = 0,1,2,4
1305 * immediate = 1 if '$'
1306 * ndx = -1 or reg num
1307 * dec_inc = '-' or '+' or ' '
1308 * reg = -1 or reg num
1309 * imreg = -1 or reg num
1310 * topP->exp_of_operand
1311 * really_none
1312 */
1313 /* Is there a displacement size? */
1314 disp_size = (call_width ? call_width :
1315 (com_width ? com_width :
1316 abs_width ? abs_width : 0));
1317
1318 if (*op_bad == '\0')
1319 {
1320 if (imreg != -1)
1321 {
1322 /* Rn */
1323 mode = TAHOE_DIRECT_REG;
1324 if (deferred || immediate || (dec_inc != ' ') ||
1325 (reg != -1) || !really_none)
1326 op_bad = "Syntax error in direct register mode.";
1327 else if (ndx != -1)
1328 op_bad = "You can't index a register in direct register mode.";
1329 else if (imreg == SP_REG && access == 'r')
1330 op_bad =
1331 "SP can't be the source operand with direct register addressing.";
1332 else if (access == 'a')
1333 op_bad = "Can't take the address of a register.";
1334 else if (access == 'b')
1335 op_bad = "Direct Register can't be used in a branch.";
1336 else if (width == 'q' && ((imreg % 2) || (imreg > 13)))
1337 op_bad = "For quad access, the register must be even and < 14.";
1338 else if (call_width)
1339 op_bad = "You can't cast a direct register.";
1340
1341 if (*op_bad == '\0')
1342 {
1343 /* No errors, check for warnings */
1344 if (width == 'q' && imreg == 12)
1345 as_warn ("Using reg 14 for quadwords can tromp the FP register.");
1346
1347 reg = imreg;
1348 }
1349
1350 /* We know: imm = -1 */
1351 }
1352 else if (dec_inc == '-')
1353 {
1354 /* -(SP) */
1355 mode = TAHOE_AUTO_DEC;
1356 if (deferred || immediate || !really_none)
1357 op_bad = "Syntax error in auto-dec mode.";
1358 else if (ndx != -1)
1359 op_bad = "You can't have an index auto dec mode.";
1360 else if (access == 'r')
1361 op_bad = "Auto dec mode cant be used for reading.";
1362 else if (reg != SP_REG)
1363 op_bad = "Auto dec only works of the SP register.";
1364 else if (access == 'b')
1365 op_bad = "Auto dec can't be used in a branch.";
1366 else if (width == 'q')
1367 op_bad = "Auto dec won't work with quadwords.";
1368
1369 /* We know: imm = -1, dec_inc != '-' */
1370 }
1371 else if (dec_inc == '+')
1372 {
1373 if (immediate || !really_none)
1374 op_bad = "Syntax error in one of the auto-inc modes.";
1375 else if (deferred)
1376 {
1377 /* *(SP)+ */
1378 mode = TAHOE_AUTO_INC_DEFERRED;
1379 if (reg != SP_REG)
1380 op_bad = "Auto inc deferred only works of the SP register.";
1381 else if (ndx != -1)
1382 op_bad = "You can't have an index auto inc deferred mode.";
1383 else if (access == 'b')
1384 op_bad = "Auto inc can't be used in a branch.";
1385 }
1386 else
1387 {
1388 /* (SP)+ */
1389 mode = TAHOE_AUTO_INC;
1390 if (access == 'm' || access == 'w')
1391 op_bad = "You can't write to an auto inc register.";
1392 else if (reg != SP_REG)
1393 op_bad = "Auto inc only works of the SP register.";
1394 else if (access == 'b')
1395 op_bad = "Auto inc can't be used in a branch.";
1396 else if (width == 'q')
1397 op_bad = "Auto inc won't work with quadwords.";
1398 else if (ndx != -1)
1399 op_bad = "You can't have an index in auto inc mode.";
1400 }
1401
1402 /* We know: imm = -1, dec_inc == ' ' */
1403 }
1404 else if (reg != -1)
1405 {
1406 if ((ndx != -1) && (reg == SP_REG))
1407 op_bad = "You can't index the sp register.";
1408 if (deferred)
1409 {
1410 /* *<disp>(Rn) */
1411 mode = TAHOE_REG_DISP_DEFERRED;
1412 if (immediate)
1413 op_bad = "Syntax error in register displaced mode.";
1414 }
1415 else if (really_none)
1416 {
1417 /* (Rn) */
1418 mode = TAHOE_REG_DEFERRED;
1419 /* if reg = SP then cant be indexed */
1420 }
1421 else
1422 {
1423 /* <disp>(Rn) */
1424 mode = TAHOE_REG_DISP;
1425 }
1426
1427 /* We know: imm = -1, dec_inc == ' ', Reg = -1 */
1428 }
1429 else
1430 {
1431 if (really_none)
1432 op_bad = "An offest is needed for this operand.";
1433 if (deferred && immediate)
1434 {
1435 /* *$<ADDR> */
1436 mode = TAHOE_ABSOLUTE_ADDR;
1437 disp_size = 4;
1438 }
1439 else if (immediate)
1440 {
1441 /* $<disp> */
1442 mode = TAHOE_IMMEDIATE;
1443 if (ndx != -1)
1444 op_bad = "You can't index a register in immediate mode.";
1445 if (access == 'a')
1446 op_bad = "Immediate access can't be used as an address.";
1447 /* ponder the wisdom of a cast because it doesn't do any good. */
1448 }
1449 else if (deferred)
1450 {
1451 /* *<disp> */
1452 mode = TAHOE_DISP_REL_DEFERRED;
1453 }
1454 else
1455 {
1456 /* <disp> */
1457 mode = TAHOE_DISPLACED_RELATIVE;
1458 }
1459 }
1460 }
1461
1462 /*
1463 * At this point, all the errors we can do have be checked for.
1464 * We can build the 'top'. */
1465
1466 topP->top_ndx = ndx;
1467 topP->top_reg = reg;
1468 topP->top_mode = mode;
1469 topP->top_error = op_bad;
1470 topP->top_dispsize = disp_size;
1471 } /* tip_op */
1472 \f
1473 /*
1474 * t i p ( )
1475 *
1476 * This converts a string into a tahoe instruction.
1477 * The string must be a bare single instruction in tahoe (with BSD4 frobs)
1478 * format.
1479 * It provides at most one fatal error message (which stops the scan)
1480 * some warning messages as it finds them.
1481 * The tahoe instruction is returned in exploded form.
1482 *
1483 * The exploded instruction is returned to a struct tit of your choice.
1484 * #include "tahoe-inst.h" to know what a struct tit is.
1485 *
1486 */
1487
1488 static void
1489 tip (titP, instring)
1490 struct tit *titP; /* We build an exploded instruction here. */
1491 char *instring; /* Text of a vax instruction: we modify. */
1492 {
1493 register struct tot_wot *twP = NULL; /* How to bit-encode this opcode. */
1494 register char *p; /* 1/skip whitespace.2/scan vot_how */
1495 register char *q; /* */
1496 register unsigned char count; /* counts number of operands seen */
1497 register struct top *operandp;/* scan operands in struct tit */
1498 register char *alloperr = ""; /* error over all operands */
1499 register char c; /* Remember char, (we clobber it
1500 with '\0' temporarily). */
1501 char *save_input_line_pointer;
1502
1503 if (*instring == ' ')
1504 ++instring; /* Skip leading whitespace. */
1505 for (p = instring; *p && *p != ' '; p++)
1506 ; /* MUST end in end-of-string or
1507 exactly 1 space. */
1508 /* Scanned up to end of operation-code. */
1509 /* Operation-code is ended with whitespace. */
1510 if (p == instring)
1511 {
1512 titP->tit_error = "No operator";
1513 count = 0;
1514 titP->tit_opcode = 0;
1515 }
1516 else
1517 {
1518 c = *p;
1519 *p = '\0';
1520 /*
1521 * Here with instring pointing to what better be an op-name, and p
1522 * pointing to character just past that.
1523 * We trust instring points to an op-name, with no whitespace.
1524 */
1525 twP = (struct tot_wot *) hash_find (op_hash, instring);
1526 *p = c; /* Restore char after op-code. */
1527 if (twP == 0)
1528 {
1529 titP->tit_error = "Unknown operator";
1530 count = 0;
1531 titP->tit_opcode = 0;
1532 }
1533 else
1534 {
1535 /*
1536 * We found a match! So lets pick up as many operands as the
1537 * instruction wants, and even gripe if there are too many.
1538 * We expect comma to seperate each operand.
1539 * We let instring track the text, while p tracks a part of the
1540 * struct tot.
1541 */
1542
1543 count = 0; /* no operands seen yet */
1544 instring = p + (*p != '\0'); /* point past the operation code */
1545 /* tip_op() screws with the input_line_pointer, so save it before
1546 I jump in */
1547 save_input_line_pointer = input_line_pointer;
1548 for (p = twP->args, operandp = titP->tit_operand;
1549 !*alloperr && *p;
1550 operandp++, p += 2)
1551 {
1552 /*
1553 * Here to parse one operand. Leave instring pointing just
1554 * past any one ',' that marks the end of this operand.
1555 */
1556 if (!p[1])
1557 as_fatal ("Compiler bug: ODD number of bytes in arg structure %s.",
1558 twP->args);
1559 else if (*instring)
1560 {
1561 for (q = instring; (*q != ',' && *q != '\0'); q++)
1562 {
1563 if (*q == '\'' && q[1] != '\0') /* Jump quoted characters */
1564 q++;
1565 }
1566 c = *q;
1567 /*
1568 * Q points to ',' or '\0' that ends argument. C is that
1569 * character.
1570 */
1571 *q = '\0';
1572 operandp->top_access = p[0];
1573 operandp->top_width = p[1];
1574 tip_op (instring - 1, operandp);
1575 *q = c; /* Restore input text. */
1576 if (*(operandp->top_error))
1577 {
1578 alloperr = operandp->top_error;
1579 }
1580 instring = q + (c ? 1 : 0); /* next operand (if any) */
1581 count++; /* won another argument, may have an operr */
1582 }
1583 else
1584 alloperr = "Not enough operands";
1585 }
1586 /* Restore the pointer. */
1587 input_line_pointer = save_input_line_pointer;
1588
1589 if (!*alloperr)
1590 {
1591 if (*instring == ' ')
1592 instring++; /* Skip whitespace. */
1593 if (*instring)
1594 alloperr = "Too many operands";
1595 }
1596 titP->tit_error = alloperr;
1597 }
1598 }
1599
1600 titP->tit_opcode = twP->code; /* The op-code. */
1601 titP->tit_operands = count;
1602 } /* tip */
1603 \f
1604 /* md_assemble() emit frags for 1 instruction */
1605 void
1606 md_assemble (instruction_string)
1607 char *instruction_string; /* A string: assemble 1 instruction. */
1608 {
1609 char *p;
1610 register struct top *operandP;/* An operand. Scans all operands. */
1611 /* char c_save; fixme: remove this line *//* What used to live after an expression. */
1612 /* struct frag *fragP; fixme: remove this line *//* Fragment of code we just made. */
1613 /* register struct top *end_operandP; fixme: remove this line *//* -> slot just after last operand
1614 Limit of the for (each operand). */
1615 register expressionS *expP; /* -> expression values for this operand */
1616
1617 /* These refer to an instruction operand expression. */
1618 segT to_seg; /* Target segment of the address. */
1619
1620 register valueT this_add_number;
1621 register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */
1622
1623 /* tahoe_opcodeT opcode_as_number; fixme: remove this line *//* The opcode as a number. */
1624 char *opcodeP; /* Where it is in a frag. */
1625 /* char *opmodeP; fixme: remove this line *//* Where opcode type is, in a frag. */
1626
1627 int dispsize; /* From top_dispsize: tahoe_operand_width
1628 (in bytes) */
1629 int is_undefined; /* 1 if operand expression's
1630 segment not known yet. */
1631 int pc_rel; /* Is this operand pc relative? */
1632
1633 /* Decode the operand. */
1634 tip (&t, instruction_string);
1635
1636 /*
1637 * Check to see if this operand decode properly.
1638 * Notice that we haven't made any frags yet.
1639 * If it goofed, then this instruction will wedge in any pass,
1640 * and we can safely flush it, without causing interpass symbol phase
1641 * errors. That is, without changing label values in different passes.
1642 */
1643 if (*t.tit_error)
1644 {
1645 as_warn ("Ignoring statement due to \"%s\"", t.tit_error);
1646 }
1647 else
1648 {
1649 /* We saw no errors in any operands - try to make frag(s) */
1650 /* Emit op-code. */
1651 /* Remember where it is, in case we want to modify the op-code later. */
1652 opcodeP = frag_more (1);
1653 *opcodeP = t.tit_opcode;
1654 /* Now do each operand. */
1655 for (operandP = t.tit_operand;
1656 operandP < t.tit_operand + t.tit_operands;
1657 operandP++)
1658 { /* for each operand */
1659 expP = &(operandP->exp_of_operand);
1660 if (operandP->top_ndx >= 0)
1661 {
1662 /* Indexed addressing byte
1663 Legality of indexed mode already checked: it is OK */
1664 FRAG_APPEND_1_CHAR (0x40 + operandP->top_ndx);
1665 } /* if(top_ndx>=0) */
1666
1667 /* Here to make main operand frag(s). */
1668 this_add_number = expP->X_add_number;
1669 this_add_symbol = expP->X_add_symbol;
1670 to_seg = operandP->seg_of_operand;
1671 know (to_seg == SEG_UNKNOWN || \
1672 to_seg == SEG_ABSOLUTE || \
1673 to_seg == SEG_DATA || \
1674 to_seg == SEG_TEXT || \
1675 to_seg == SEG_BSS);
1676 is_undefined = (to_seg == SEG_UNKNOWN);
1677 /* Do we know how big this opperand is? */
1678 dispsize = operandP->top_dispsize;
1679 pc_rel = 0;
1680 /* Deal with the branch possabilities. (Note, this doesn't include
1681 jumps.)*/
1682 if (operandP->top_access == 'b')
1683 {
1684 /* Branches must be expressions. A psuedo branch can also jump to
1685 an absolute address. */
1686 if (to_seg == now_seg || is_undefined)
1687 {
1688 /* If is_undefined, then it might BECOME now_seg by relax time. */
1689 if (dispsize)
1690 {
1691 /* I know how big the branch is supposed to be (it's a normal
1692 branch), so I set up the frag, and let GAS do the rest. */
1693 p = frag_more (dispsize);
1694 fix_new (frag_now, p - frag_now->fr_literal,
1695 this_add_symbol, this_add_number,
1696 size_to_fx (dispsize, 1),
1697 NULL);
1698 }
1699 else
1700 {
1701 /* (to_seg==now_seg || to_seg == SEG_UNKNOWN) && dispsize==0 */
1702 /* If we don't know how big it is, then its a synthetic branch,
1703 so we set up a simple relax state. */
1704 switch (operandP->top_width)
1705 {
1706 case TAHOE_WIDTH_CONDITIONAL_JUMP:
1707 /* Simple (conditional) jump. I may have to reverse the
1708 condition of opcodeP, and then jump to my destination.
1709 I set 1 byte aside for the branch off set, and could need 6
1710 more bytes for the pc_rel jump */
1711 frag_var (rs_machine_dependent, 7, 1,
1712 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
1713 is_undefined ? STATE_UNDF : STATE_BYTE),
1714 this_add_symbol, this_add_number, opcodeP);
1715 break;
1716 case TAHOE_WIDTH_ALWAYS_JUMP:
1717 /* Simple (unconditional) jump. I may have to convert this to
1718 a word branch, or an absolute jump. */
1719 frag_var (rs_machine_dependent, 5, 1,
1720 ENCODE_RELAX (STATE_ALWAYS_BRANCH,
1721 is_undefined ? STATE_UNDF : STATE_BYTE),
1722 this_add_symbol, this_add_number, opcodeP);
1723 break;
1724 /* The smallest size for the next 2 cases is word. */
1725 case TAHOE_WIDTH_BIG_REV_JUMP:
1726 frag_var (rs_machine_dependent, 8, 2,
1727 ENCODE_RELAX (STATE_BIG_REV_BRANCH,
1728 is_undefined ? STATE_UNDF : STATE_WORD),
1729 this_add_symbol, this_add_number,
1730 opcodeP);
1731 break;
1732 case TAHOE_WIDTH_BIG_NON_REV_JUMP:
1733 frag_var (rs_machine_dependent, 10, 2,
1734 ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH,
1735 is_undefined ? STATE_UNDF : STATE_WORD),
1736 this_add_symbol, this_add_number,
1737 opcodeP);
1738 break;
1739 default:
1740 as_fatal ("Compliler bug: Got a case (%d) I wasn't expecting.",
1741 operandP->top_width);
1742 }
1743 }
1744 }
1745 else
1746 {
1747 /* to_seg != now_seg && to_seg != seg_unknown (still in branch)
1748 In other words, I'm jumping out of my segment so extend the
1749 branches to jumps, and let GAS fix them. */
1750
1751 /* These are "branches" what will always be branches around a jump
1752 to the correct addresss in real life.
1753 If to_seg is SEG_ABSOLUTE, just encode the branch in,
1754 else let GAS fix the address. */
1755
1756 switch (operandP->top_width)
1757 {
1758 /* The theory:
1759 For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump
1760 to that addresss (not pc_rel).
1761 For other segs, address is a long word PC rel jump. */
1762 case TAHOE_WIDTH_CONDITIONAL_JUMP:
1763 /* b<cond> */
1764 /* To reverse the condition in a TAHOE branch,
1765 complement bit 4 */
1766 *opcodeP ^= 0x10;
1767 p = frag_more (7);
1768 *p++ = 6;
1769 *p++ = TAHOE_JMP;
1770 *p++ = (operandP->top_mode ==
1771 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1772 TAHOE_PC_REL_LONG);
1773 fix_new (frag_now, p - frag_now->fr_literal,
1774 this_add_symbol, this_add_number,
1775 (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
1776 /*
1777 * Now (eg) BLEQ 1f
1778 * JMP foo
1779 * 1:
1780 */
1781 break;
1782 case TAHOE_WIDTH_ALWAYS_JUMP:
1783 /* br, just turn it into a jump */
1784 *opcodeP = TAHOE_JMP;
1785 p = frag_more (5);
1786 *p++ = (operandP->top_mode ==
1787 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1788 TAHOE_PC_REL_LONG);
1789 fix_new (frag_now, p - frag_now->fr_literal,
1790 this_add_symbol, this_add_number,
1791 (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
1792 /* Now (eg) JMP foo */
1793 break;
1794 case TAHOE_WIDTH_BIG_REV_JUMP:
1795 p = frag_more (8);
1796 *opcodeP ^= 0x10;
1797 *p++ = 0;
1798 *p++ = 6;
1799 *p++ = TAHOE_JMP;
1800 *p++ = (operandP->top_mode ==
1801 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1802 TAHOE_PC_REL_LONG);
1803 fix_new (frag_now, p - frag_now->fr_literal,
1804 this_add_symbol, this_add_number,
1805 (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
1806 /*
1807 * Now (eg) ACBx 1f
1808 * JMP foo
1809 * 1:
1810 */
1811 break;
1812 case TAHOE_WIDTH_BIG_NON_REV_JUMP:
1813 p = frag_more (10);
1814 *p++ = 0;
1815 *p++ = 2;
1816 *p++ = TAHOE_BRB;
1817 *p++ = 6;
1818 *p++ = TAHOE_JMP;
1819 *p++ = (operandP->top_mode ==
1820 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1821 TAHOE_PC_REL_LONG);
1822 fix_new (frag_now, p - frag_now->fr_literal,
1823 this_add_symbol, this_add_number,
1824 (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL);
1825 /*
1826 * Now (eg) xOBxxx 1f
1827 * BRB 2f
1828 * 1: JMP @#foo
1829 * 2:
1830 */
1831 break;
1832 case 'b':
1833 case 'w':
1834 as_warn ("Real branch displacements must be expressions.");
1835 break;
1836 default:
1837 as_fatal ("Complier error: I got an unknown synthetic branch :%c",
1838 operandP->top_width);
1839 break;
1840 }
1841 }
1842 }
1843 else
1844 {
1845 /* It ain't a branch operand. */
1846 switch (operandP->top_mode)
1847 {
1848 /* Auto-foo access, only works for one reg (SP)
1849 so the only thing needed is the mode. */
1850 case TAHOE_AUTO_DEC:
1851 case TAHOE_AUTO_INC:
1852 case TAHOE_AUTO_INC_DEFERRED:
1853 FRAG_APPEND_1_CHAR (operandP->top_mode);
1854 break;
1855
1856 /* Numbered Register only access. Only thing needed is the
1857 mode + Register number */
1858 case TAHOE_DIRECT_REG:
1859 case TAHOE_REG_DEFERRED:
1860 FRAG_APPEND_1_CHAR (operandP->top_mode + operandP->top_reg);
1861 break;
1862
1863 /* An absolute address. It's size is always 5 bytes.
1864 (mode_type + 4 byte address). */
1865 case TAHOE_ABSOLUTE_ADDR:
1866 know ((this_add_symbol == NULL));
1867 p = frag_more (5);
1868 *p = TAHOE_ABSOLUTE_ADDR;
1869 md_number_to_chars (p + 1, this_add_number, 4);
1870 break;
1871
1872 /* Immediate data. If the size isn't known, then it's an address
1873 + and offset, which is 4 bytes big. */
1874 case TAHOE_IMMEDIATE:
1875 if (this_add_symbol != NULL)
1876 {
1877 p = frag_more (5);
1878 *p++ = TAHOE_IMMEDIATE_LONGWORD;
1879 fix_new (frag_now, p - frag_now->fr_literal,
1880 this_add_symbol, this_add_number,
1881 FX_32, NULL);
1882 }
1883 else
1884 {
1885 /* It's a integer, and I know it's size. */
1886 if ((unsigned) this_add_number < 0x40)
1887 {
1888 /* Will it fit in a literal? */
1889 FRAG_APPEND_1_CHAR ((byte) this_add_number);
1890 }
1891 else
1892 {
1893 p = frag_more (dispsize + 1);
1894 switch (dispsize)
1895 {
1896 case 1:
1897 *p++ = TAHOE_IMMEDIATE_BYTE;
1898 *p = (byte) this_add_number;
1899 break;
1900 case 2:
1901 *p++ = TAHOE_IMMEDIATE_WORD;
1902 md_number_to_chars (p, this_add_number, 2);
1903 break;
1904 case 4:
1905 *p++ = TAHOE_IMMEDIATE_LONGWORD;
1906 md_number_to_chars (p, this_add_number, 4);
1907 break;
1908 }
1909 }
1910 }
1911 break;
1912
1913 /* Distance from the PC. If the size isn't known, we have to relax
1914 into it. The difference between this and disp(sp) is that
1915 this offset is pc_rel, and disp(sp) isn't.
1916 Note the drop through code. */
1917
1918 case TAHOE_DISPLACED_RELATIVE:
1919 case TAHOE_DISP_REL_DEFERRED:
1920 operandP->top_reg = PC_REG;
1921 pc_rel = 1;
1922
1923 /* Register, plus a displacement mode. Save the register number,
1924 and weather its deffered or not, and relax the size if it isn't
1925 known. */
1926 case TAHOE_REG_DISP:
1927 case TAHOE_REG_DISP_DEFERRED:
1928 if (operandP->top_mode == TAHOE_DISP_REL_DEFERRED ||
1929 operandP->top_mode == TAHOE_REG_DISP_DEFERRED)
1930 operandP->top_reg += 0x10; /* deffered mode is always 0x10 higher
1931 than it's non-deffered sibling. */
1932
1933 /* Is this a value out of this segment?
1934 The first part of this conditional is a cludge to make gas
1935 produce the same output as 'as' when there is a lable, in
1936 the current segment, displaceing a register. It's strange,
1937 and no one in their right mind would do it, but it's easy
1938 to cludge. */
1939 if ((dispsize == 0 && !pc_rel) ||
1940 (to_seg != now_seg && !is_undefined && to_seg != SEG_ABSOLUTE))
1941 dispsize = 4;
1942
1943 if (dispsize == 0)
1944 {
1945 /*
1946 * We have a SEG_UNKNOWN symbol, or the size isn't cast.
1947 * It might turn out to be in the same segment as
1948 * the instruction, permitting relaxation.
1949 */
1950 p = frag_var (rs_machine_dependent, 5, 2,
1951 ENCODE_RELAX (STATE_PC_RELATIVE,
1952 is_undefined ? STATE_UNDF : STATE_BYTE),
1953 this_add_symbol, this_add_number, 0);
1954 *p = operandP->top_reg;
1955 }
1956 else
1957 {
1958 /* Either this is an abs, or a cast. */
1959 p = frag_more (dispsize + 1);
1960 switch (dispsize)
1961 {
1962 case 1:
1963 *p = TAHOE_PC_OR_BYTE + operandP->top_reg;
1964 break;
1965 case 2:
1966 *p = TAHOE_PC_OR_WORD + operandP->top_reg;
1967 break;
1968 case 4:
1969 *p = TAHOE_PC_OR_LONG + operandP->top_reg;
1970 break;
1971 };
1972 fix_new (frag_now, p + 1 - frag_now->fr_literal,
1973 this_add_symbol, this_add_number,
1974 size_to_fx (dispsize, pc_rel), NULL);
1975 }
1976 break;
1977 default:
1978 as_fatal ("Barf, bad mode %x\n", operandP->top_mode);
1979 }
1980 }
1981 } /* for(operandP) */
1982 } /* if(!need_pass_2 && !goofed) */
1983 } /* tahoe_assemble() */
1984
1985
1986 /* We have no need to default values of symbols. */
1987
1988 /* ARGSUSED */
1989 symbolS *
1990 md_undefined_symbol (name)
1991 char *name;
1992 {
1993 return 0;
1994 } /* md_undefined_symbol() */
1995
1996 /* Parse an operand that is machine-specific.
1997 We just return without modifying the expression if we have nothing
1998 to do. */
1999
2000 /* ARGSUSED */
2001 void
2002 md_operand (expressionP)
2003 expressionS *expressionP;
2004 {
2005 } /* md_operand() */
2006
2007 /* Round up a section size to the appropriate boundary. */
2008 valueT
2009 md_section_align (segment, size)
2010 segT segment;
2011 valueT size;
2012 {
2013 return ((size + 7) & ~7); /* Round all sects to multiple of 8 */
2014 } /* md_section_align() */
2015
2016 /* Exactly what point is a PC-relative offset relative TO?
2017 On the sparc, they're relative to the address of the offset, plus
2018 its size. This gets us to the following instruction.
2019 (??? Is this right? FIXME-SOON) */
2020 long
2021 md_pcrel_from (fixP)
2022 fixS *fixP;
2023 {
2024 return (((fixP->fx_type == FX_8
2025 || fixP->fx_type == FX_PCREL8)
2026 ? 1
2027 : ((fixP->fx_type == FX_16
2028 || fixP->fx_type == FX_PCREL16)
2029 ? 2
2030 : ((fixP->fx_type == FX_32
2031 || fixP->fx_type == FX_PCREL32)
2032 ? 4
2033 : 0))) + fixP->fx_where + fixP->fx_frag->fr_address);
2034 } /* md_pcrel_from() */
2035
2036 int
2037 tc_is_pcrel (fixP)
2038 fixS *fixP;
2039 {
2040 /* should never be called */
2041 know (0);
2042 return (0);
2043 } /* tc_is_pcrel() */
2044
2045 /* end of tc-tahoe.c */