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