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