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