2 Not part of GAS yet. */
7 /* this bit glommed from tahoe-inst.h */
9 typedef unsigned char byte;
10 typedef byte tahoe_opcodeT;
13 * This is part of tahoe-ins-parse.c & friends.
14 * We want to parse a tahoe instruction text into a tree defined here.
17 #define TIT_MAX_OPERANDS (4) /* maximum number of operands in one
18 single tahoe instruction */
20 struct top /* tahoe instruction operand */
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. */
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?-:!" */
31 char *top_error; /* Say if operand is inappropriate */
33 expressionS exp_of_operand; /* The expression as parsed by expression()*/
35 byte top_dispsize; /* Number of bytes in the displacement if we
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)
44 #define TAHOE_REG_DISP (0xE0)
45 #define TAHOE_REG_DISP_DEFERRED (0xF0)
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)
53 #define TAHOE_DISPLACED_RELATIVE (0xEF)
54 #define TAHOE_DISP_REL_DEFERRED (0xFF)
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] */
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 ':'
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)
80 struct tit /* get it out of the sewer, it stands for
81 tahoe instruction tree (Geeze!) */
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 */
89 /* end: tahoe-inst.h */
91 /* tahoe.c - tahoe-specific -
95 #include "opcode/tahoe.h"
97 /* This is the number to put at the beginning of the a.out file */
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[] = "#;";
104 /* These chars only start a comment at the beginning of a line. */
105 const char line_comment_chars[] = "#";
107 /* Chars that can be used to separate mant from exp in floating point nums */
108 const char EXP_CHARS[] = "eE";
110 /* Chars that mean this number is a floating point constant
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";
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.)
123 static struct tit t; /* A tahoe instruction after decoding. */
126 /* A table of pseudo ops (sans .), the function called, and an integer op
127 that the function is called with. */
129 const pseudo_typeS md_pseudo_table[] =
131 {"dfloat", float_cons, 'd'},
132 {"ffloat", float_cons, 'f'},
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:
142 * 4 3 2 1 0 bit number
143 * ---/ /--+-------+-------+-------+-------+-------+
144 * | what state ? | how long ? |
145 * ---/ /--+-------+-------+-------+-------+-------+
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.
155 States for Tahoe address relaxing.
156 1. TAHOE_WIDTH_ALWAYS_JUMP (-)
158 Tahoe opcodes are: (Hex)
162 Always, 1 byte opcode, then displacement/absolute.
163 If word or longword, change opcode to brw or jmp.
166 2. TAHOE_WIDTH_CONDITIONAL_JUMP (?)
167 J<cond> where <cond> is a simple flag test.
169 Tahoe opcodes are: (Hex)
182 Always, you complement 4th bit to reverse the condition.
183 Always, 1-byte opcode, then 1-byte displacement.
185 3. TAHOE_WIDTH_BIG_REV_JUMP (!)
186 Jbc/Jbs where cond tests a memory bit.
188 Tahoe opcodes are: (Hex)
191 Always, you complement 4th bit to reverse the condition.
192 Always, 1-byte opcde, longword, longword-address, 1-word-displacement
194 4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:)
197 Tahoe opcodes are: (Hex)
203 Always, we cannot reverse the sense of the branch; we have a word
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
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.) */
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))
220 The first letter is Byte, Word.
221 2nd letter is Forward, Backward. */
224 #define WF (2+ 32767)
225 #define WB (2+-32768)
226 /* Dont need LF, LB because they always reach. [They are coded as 0.] */
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)
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)
240 #define STATE_BYTE (0)
241 #define STATE_WORD (1)
242 #define STATE_LONG (2)
243 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
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. */
253 }, /* error sentinel 0,0 */
263 /* Unconditional branch cases "jrb"
264 The relax part is the actual displacement */
267 }, /* brb B`foo 1,0 */
270 }, /* brw W`foo 1,1 */
273 }, /* Jmp L`foo 1,2 */
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
282 }, /* b<cond> B`foo 2,0 */
284 WF + 2, WB + 2, 4, C (2, 2)
285 }, /* brev over, brw W`foo, over: 2,1 */
288 }, /* brev over, jmp L`foo, over: 2,2 */
292 /* Another type of reversable branch. But this only has a word
299 }, /* jbX W`foo 3,1 */
302 }, /* jrevX over, jmp L`foo, over: 3,2 */
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
316 }, /* aobl_ W`foo 4,1 */
319 }, /*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/
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. */
327 BF + 1, BB + 1, 2, C (5, 1)
330 WF + 1, WB + 1, 3, C (5, 2)
345 /* End relax stuff */
347 static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table
348 NULL means any use before md_begin() will
351 /* Init function. Build the hash table. */
357 int synthetic_too = 1; /* If 0, just use real opcodes. */
359 if ((op_hash = hash_new())){
360 for (tP= totstrs; *tP->name && !*errorval; tP++){
361 errorval = hash_insert (op_hash, tP->name, &tP->detail);
364 for (tP = synthetic_totstrs; *tP->name && !*errorval; tP++){
365 errorval = hash_insert (op_hash, tP->name, &tP->detail);
369 errorval = "Virtual memory exceeded";
381 md_parse_option (argP, cntP, vecP)
386 char *temp_name; /* name for -t or -d options */
391 as_warn("The -a option doesn't exits. (Dispite what the man page says!");
394 as_warn("JUMPIFY (-J) not implemented, use psuedo ops instead.");
398 as_warn ("SYMBOL TABLE not implemented");
399 break; /* SYMBOL TABLE not implemented */
402 as_warn ("TOKEN TRACE not implemented");
403 break; /* TOKEN TRACE not implemented */
408 if (**argP){ /* Rest of argument is filename. */
416 temp_name = *++(*vecP);
417 **vecP = NULL; /* Remember this is not a file-name. */
419 as_warn ("I expected a filename after -%c.",opt);
420 temp_name = "{absent}";
424 as_warn ("Displacement length %s ignored!", temp_name);
426 as_warn ("I don't need or use temp. file \"%s\".", temp_name);
430 as_warn ("I don't use an interpass file! -V ignored");
440 /* The functions in this section take numbers in the machine format, and
441 munges them into Tahoe byte order.
442 They exist primarily for cross assembly purpose. */
443 void /* Knows about order of bytes in address. */
444 md_number_to_chars (con, value, nbytes)
445 char con[]; /* Return 'nbytes' of chars here. */
446 long int value; /* The value of the bits. */
447 int nbytes; /* Number of bytes in the output. */
452 con += nbytes - 1; /* Tahoes is (Bleah!) big endian */
454 *con-- = value; /* Lint wants & MASK_CHAR. */
455 value >>= BITS_PER_CHAR;
457 /* XXX line number probably botched for this warning message. */
458 if (value != 0 && value != -1)
459 as_warn ("Displacement (%ld) long for instruction field length (%d).",v,n);
463 void /* Knows about order of bytes in address. */
464 md_number_to_imm (con, value, nbytes)
465 char con[]; /* Return 'nbytes' of chars here. */
466 long int value; /* The value of the bits. */
467 int nbytes; /* Number of bytes in the output. */
469 md_number_to_chars(con, value, nbytes);
474 md_apply_fix(fixP, val)
478 char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
479 md_number_to_chars(place, val, fixP->fx_size);
481 } /* md_apply_fix() */
483 void /* Knows about order of bytes in address. */
484 md_number_to_disp (con, value, nbytes)
485 char con[]; /* Return 'nbytes' of chars here. */
486 long int value; /* The value of the bits. */
487 int nbytes; /* Number of bytes in the output. */
489 md_number_to_chars(con, value, nbytes);
492 void /* Knows about order of bytes in address. */
493 md_number_to_field (con, value, nbytes)
494 char con[]; /* Return 'nbytes' of chars here. */
495 long int value; /* The value of the bits. */
496 int nbytes; /* Number of bytes in the output. */
498 md_number_to_chars(con, value, nbytes);
501 /* Put the bits in an order that a tahoe will understand, despite the ordering
502 of the native machine.
503 On Tahoe: first 4 bytes are normal unsigned big endian long,
504 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
505 The last byte is broken up with bit 7 as pcrel,
506 bits 6 & 5 as length,
507 bit 4 as extern and the last nibble as 'undefined'. */
511 md_ri_to_chars (ri_p, ri)
512 struct relocation_info *ri_p, ri;
514 byte the_bytes[sizeof(struct relocation_info)];
515 /* The reason I can't just encode these directly into ri_p is that
516 ri_p may point to ri. */
519 md_number_to_chars (the_bytes, ri.r_address, sizeof(ri.r_address));
521 /* now the fun stuff */
522 the_bytes[4] = (ri.r_symbolnum >> 16) & 0x0ff;
523 the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
524 the_bytes[6] = ri.r_symbolnum & 0x0ff;
525 the_bytes[7] = (((ri.r_extern << 4) & 0x10) | ((ri.r_length << 5) & 0x60) |
526 ((ri.r_pcrel << 7) & 0x80)) & 0xf0;
528 bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));
532 /* Put the bits in an order that a tahoe will understand, despite the ordering
533 of the native machine.
534 On Tahoe: first 4 bytes are normal unsigned big endian long,
535 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
536 The last byte is broken up with bit 7 as pcrel,
537 bits 6 & 5 as length,
538 bit 4 as extern and the last nibble as 'undefined'. */
540 void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
543 relax_addressT segment_address_in_file;
546 * In: length of relocation (or of address) in chars: 1, 2 or 4.
547 * Out: GNU LD relocation length code: 0, 1, or 2.
550 static unsigned char nbytes_r_length[] = { 42, 0, 1, 42, 2 };
553 know(fixP->fx_addsy != NULL);
555 md_number_to_chars(where,
556 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
559 r_symbolnum = (S_IS_DEFINED(fixP->fx_addsy)
560 ? S_GET_TYPE(fixP->fx_addsy)
561 : fixP->fx_addsy->sy_number);
563 where[4] = (r_symbolnum >> 16) & 0x0ff;
564 where[5] = (r_symbolnum >> 8) & 0x0ff;
565 where[6] = r_symbolnum & 0x0ff;
566 where[7] = (((fixP->fx_pcrel << 7) & 0x80)
567 | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60)
568 | ((!S_IS_DEFINED(fixP->fx_addsy) << 4) & 0x10));
571 } /* tc_aout_fix_to_chars() */
573 /* Relocate byte stuff */
575 /* This is for broken word. */
576 const int md_short_jump_size = 3;
579 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
581 long from_addr, to_addr;
587 offset = to_addr - (from_addr + 1);
589 md_number_to_chars (ptr, offset, 2);
592 const int md_long_jump_size = 6;
593 const int md_reloc_size = 8; /* Size of relocation record */
596 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
598 long from_addr, to_addr;
604 offset = to_addr - (from_addr + 4);
606 *ptr++ = TAHOE_PC_REL_LONG;
607 md_number_to_chars (ptr, offset, 4);
611 * md_estimate_size_before_relax()
613 * Called just before relax().
614 * Any symbol that is now undefined will not become defined, so we assumed
615 * that it will be resolved by the linker.
616 * Return the correct fr_subtype in the frag, for relax()
617 * Return the initial "guess for fr_var" to caller. (How big I think this
619 * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
620 * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
621 * Although it may not be explicit in the frag, pretend fr_var starts with a
625 md_estimate_size_before_relax (fragP, segment_type)
626 register fragS *fragP;
627 segT segment_type; /* N_DATA or N_TEXT. */
630 register int old_fr_fix;
631 /* int pc_rel; FIXME: remove this */
633 old_fr_fix = fragP->fr_fix;
634 switch (fragP->fr_subtype){
635 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
636 if (S_GET_SEGMENT(fragP->fr_symbol) == segment_type) {
637 /* The symbol was in the same segment as the opcode, and it's
638 a real pc_rel case so it's a relaxable case. */
639 fragP->fr_subtype = ENCODE_RELAX(STATE_PC_RELATIVE, STATE_BYTE);
641 /* This case is still undefined, so asume it's a long word for the
643 p = fragP->fr_literal + old_fr_fix;
644 *p |= TAHOE_PC_OR_LONG;
645 /* We now know how big it will be, one long word. */
646 fragP->fr_fix += 1 + 4;
647 fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,
648 fragP->fr_offset, 1, NO_RELOC);
653 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
654 if (S_GET_SEGMENT(fragP->fr_symbol) == segment_type){
655 fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
657 p = fragP->fr_literal + old_fr_fix;
658 *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
661 *p++ = TAHOE_PC_REL_LONG;
662 fragP->fr_fix += 1 + 1 + 1 + 4;
663 fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol, 0,
664 fragP->fr_offset, 1, NO_RELOC);
669 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_UNDF):
670 if (S_GET_SEGMENT(fragP->fr_symbol) == segment_type){
672 ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);
674 p = fragP->fr_literal + old_fr_fix;
675 *fragP->fr_opcode ^= 0x10; /* Reverse sense of branch. */
679 *p++ = TAHOE_PC_REL_LONG;
680 fragP->fr_fix += 2 + 2 + 4;
681 fix_new (fragP, old_fr_fix + 4, 4, fragP->fr_symbol, 0,
682 fragP->fr_offset, 1, NO_RELOC);
687 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_UNDF):
688 if (S_GET_SEGMENT(fragP->fr_symbol) == segment_type){
689 fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD);
691 p = fragP->fr_literal + old_fr_fix;
697 *p++ = TAHOE_PC_REL_LONG;
698 fragP->fr_fix += 2 + 2 + 2 + 4;
699 fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol, 0,
700 fragP->fr_offset, 1, NO_RELOC);
705 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
706 if (S_GET_SEGMENT(fragP->fr_symbol) == segment_type){
707 fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
709 p = fragP->fr_literal + old_fr_fix;
710 *fragP->fr_opcode = TAHOE_JMP;
711 *p++ = TAHOE_PC_REL_LONG;
712 fragP->fr_fix += 1 + 4;
713 fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,
714 fragP->fr_offset, 1, NO_RELOC);
722 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
723 } /* md_estimate_size_before_relax() */
728 * Called after relax() is finished.
729 * In: Address of frag.
730 * fr_type == rs_machine_dependent.
731 * fr_subtype is what the address relaxed to.
733 * Out: Any fixSs and constants are set up.
734 * Caller will turn frag into a ".space 0".
737 md_convert_frag (headers, fragP)
738 object_headers *headers;
739 register fragS *fragP;
741 register char *addressP; /* -> _var to change. */
742 register char *opcodeP; /* -> opcode char(s) to change. */
743 register short int length_code; /* 2=long 1=word 0=byte */
744 register short int extension = 0; /* Size of relaxed address.
745 Added to fr_fix: incl. ALL var chars. */
746 register symbolS *symbolP;
747 register long int where;
748 register long int address_of_var;
749 /* Where, in file space, is _var of *fragP? */
750 register long int target_address;
751 /* Where, in file space, does addr point? */
753 know (fragP->fr_type == rs_machine_dependent);
754 length_code = RELAX_LENGTH(fragP->fr_subtype);
755 know (length_code >= 0 && length_code < 3);
756 where = fragP->fr_fix;
757 addressP = fragP->fr_literal + where;
758 opcodeP = fragP->fr_opcode;
759 symbolP = fragP->fr_symbol;
761 target_address = S_GET_VALUE(symbolP) + fragP->fr_offset;
762 address_of_var = fragP->fr_address + where;
763 switch (fragP->fr_subtype){
764 case ENCODE_RELAX(STATE_PC_RELATIVE, STATE_BYTE):
765 /* *addressP holds the registers number, plus 0x10, if it's deferred
766 mode. To set up the right mode, just OR the size of this displacement */
767 /* Byte displacement. */
768 *addressP++ |= TAHOE_PC_OR_BYTE;
769 *addressP = target_address - (address_of_var + 2);
773 case ENCODE_RELAX(STATE_PC_RELATIVE, STATE_WORD):
774 /* Word displacement. */
775 *addressP++ |= TAHOE_PC_OR_WORD;
776 md_number_to_chars(addressP, target_address - (address_of_var + 3), 2);
780 case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
781 /* Long word displacement. */
782 *addressP++ |= TAHOE_PC_OR_LONG;
783 md_number_to_chars(addressP, target_address - (address_of_var + 5), 4);
787 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
788 *addressP = target_address - (address_of_var + 1);
792 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
793 *opcodeP ^= 0x10; /* Reverse sense of test. */
794 *addressP++ = 3; /* Jump over word branch */
795 *addressP++ = TAHOE_BRW;
796 md_number_to_chars (addressP, target_address - (address_of_var + 4), 2);
800 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
801 *opcodeP ^= 0x10; /* Reverse sense of test. */
803 *addressP++ = TAHOE_JMP;
804 *addressP++ = TAHOE_PC_REL_LONG;
805 md_number_to_chars (addressP, target_address, 4);
809 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
810 *addressP = target_address - (address_of_var + 1);
814 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
815 *opcodeP = TAHOE_BRW;
816 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
820 case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
821 *opcodeP = TAHOE_JMP;
822 *addressP++ = TAHOE_PC_REL_LONG;
823 md_number_to_chars(addressP, target_address - (address_of_var + 5), 4);
827 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD):
828 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
832 case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_LONG):
836 *addressP++ = TAHOE_JMP;
837 *addressP++ = TAHOE_PC_REL_LONG;
838 md_number_to_chars (addressP, target_address, 4);
842 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD):
843 md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
847 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_LONG):
850 *addressP++ = TAHOE_BRB;
852 *addressP++ = TAHOE_JMP;
853 *addressP++ = TAHOE_PC_REL_LONG;
854 md_number_to_chars (addressP, target_address, 4);
859 BAD_CASE (fragP->fr_subtype);
862 fragP->fr_fix += extension;
863 } /* md_convert_frag */
866 /* This is the stuff for md_assemble. */
870 #define BIGGESTREG PC_REG
873 * Parse the string pointed to by START
874 * If it represents a valid register, point START to the character after
875 * the last valid register char, and return the register number (0-15).
876 * If invalid, leave START alone, return -1.
877 * The format has to be exact. I don't do things like eat leading zeros
879 * Note: This doesn't check for the next character in the string making
880 * this invalid. Ex: R123 would return 12, it's the callers job to check
881 * what start is point to apon return.
883 * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15)
884 * Case doesn't matter.
887 tahoe_reg_parse(start)
888 char **start; /* A pointer to the string to parse. */
890 register char *regpoint = *start;
891 register int regnum = -1;
894 case '%': /* Registers can start with a %,
895 R or r, and then a number. */
898 if (isdigit(*regpoint)){
899 /* Got the first digit. */
900 regnum = *regpoint++ - '0';
901 if ((regnum == 1) && isdigit(*regpoint)){
902 /* Its a two digit number. */
903 regnum = 10 + (*regpoint++ - '0');
904 if (regnum > BIGGESTREG){ /* Number too big? */
910 case 'F': /* Is it the FP */
918 case 's': /* How about the SP */
926 case 'p': /* OR the PC even */
936 if (regnum != -1){ /* No error, so move string pointer */
939 return regnum; /* Return results */
940 } /* tahoe_reg_parse */
943 * This chops up an operand and figures out its modes and stuff.
944 * It's a little touchy about extra characters.
945 * Optex to start with one extra character so it can be overwritten for
946 * the backward part of the parsing.
947 * You can't put a bunch of extra characters in side to
948 * make the command look cute. ie: * foo ( r1 ) [ r0 ]
949 * If you like doing a lot of typing, try COBOL!
950 * Actually, this parser is a little weak all around. It's designed to be
951 * used with compliers, so I emphisise correct decoding of valid code quickly
952 * rather that catching every possable error.
953 * Note: This uses the expression function, so save input_line_pointer before
956 * Sperry defines the semantics of address modes (and values)
957 * by a two-letter code, explained here.
959 * letter 1: access type
961 * a address calculation - no data access, registers forbidden
962 * b branch displacement
963 * m read - let go of bus - write back "modify"
966 * v bit field address: like 'a' but registers are OK
968 * letter 2: data type (i.e. width, alignment)
973 * q quadword (Even regs < 14 allowed) (if 12, you get a warning)
974 * - unconditional synthetic jbr operand
975 * ? simple synthetic reversable branch operand
976 * ! complex synthetic reversable branch operand
977 * : complex synthetic non-reversable branch operand
979 * The '-?!:' letter 2's are not for external consumption. They are used
980 * by GAS for psuedo ops relaxing code.
982 * After parsing topP has:
984 * top_ndx: -1, or the index register. eg 7=[R7]
985 * top_reg: -1, or register number. eg 7 = R7 or (R7)
986 * top_mode: The addressing mode byte. This byte, defines which of
987 * the 11 modes opcode is.
988 * top_access: Access type wanted for this opperand 'b'branch ' '
989 * no-instruction 'amrvw'
990 * top_width: Operand width expected, one of "bwlq?-:!"
991 * exp_of_operand: The expression as parsed by expression()
992 * top_dispsize: Number of bytes in the displacement if we can figure it
993 * out and it's relavent.
995 * Need syntax checks built.
1000 char *optex; /* The users text input, with one leading character */
1001 struct top *topP;/* The tahoe instruction with some fields already set:
1003 out: ndx, reg, mode, error, dispsize */
1006 int mode = 0; /* This operand's mode. */
1007 char segfault = *optex; /* To keep the back parsing from freaking. */
1008 char *point = optex+1; /* Parsing from front to back. */
1009 char *end; /* Parsing from back to front. */
1010 int reg = -1; /* major register, -1 means absent */
1011 int imreg = -1; /* Major register in immediate mode */
1012 int ndx = -1; /* index register number, -1 means absent */
1013 char dec_inc = ' '; /* Is the SP auto-incremented '+' or
1014 auto-decremented '-' or neither ' '. */
1015 int immediate = 0; /* 1 if '$' immediate mode */
1016 int call_width = 0; /* If the caller casts the displacement */
1017 int abs_width = 0; /* The width of the absolute displacment */
1018 int com_width = 0; /* Displacement width required by branch */
1019 int deferred = 0; /* 1 if '*' deferral is used */
1020 byte disp_size = 0; /* How big is this operand. 0 == don't know */
1021 char *op_bad = ""; /* Bad operand error */
1023 char *tp, *temp, c; /* Temporary holders */
1025 char access = topP->top_access; /* Save on a deref. */
1026 char width = topP->top_width;
1028 int really_none = 0; /* Empty expressions evaluate to 0
1029 but I need to know if it's there or not */
1030 expressionS *expP; /* -> expression values for this operand */
1032 /* Does this command restrict the displacement size. */
1034 com_width = (width == 'b' ? 1 :
1036 (width == 'l' ? 4 : 0)));
1038 *optex = '\0'; /* This is kind of a back stop for all
1039 the searches to fail on if needed.*/
1040 if (*point == '*') { /* A dereference? */
1045 /* Force words into a certain mode */
1046 /* Bitch, Bitch, Bitch! */
1048 * Using the ^ operator is ambigous. If I have an absolute label
1049 * called 'w' set to, say 2, and I have the expression 'w^1', do I get
1050 * 1, forced to be in word displacement mode, or do I get the value of
1051 * 'w' or'ed with 1 (3 in this case).
1052 * The default is 'w' as an offset, so that's what I use.
1053 * Stick with `, it does the same, and isn't ambig.
1056 if (*point != '\0' && ((point[1] == '^') || (point[1] == '`')))
1065 as_warn("Casting a branch displacement is bad form, and is ignored.");
1067 c = (isupper(*point) ? tolower(*point) : *point);
1068 call_width = ((c == 'b') ? 1 :
1069 ((c == 'w') ? 2 : 4));
1075 /* Setting immediate mode */
1082 * I've pulled off all the easy stuff off the front, move to the end and
1086 for(end = point;*end != '\0';end++) /* Move to the end. */
1089 if(end != point) /* Null string? */
1092 if (end > point && *end == ' ' && end[-1] != '\'')
1093 end--; /* Hop white space */
1095 /* Is this an index reg. */
1096 if ((*end == ']') && (end[-1] != '\'')){
1099 /* Find opening brace. */
1100 for(--end;(*end != '[' && end != point);end--)
1103 /* If I found the opening brace, get the index register number. */
1105 tp = end + 1; /* tp should point to the start of a reg. */
1106 ndx = tahoe_reg_parse(&tp);
1107 if (tp != temp){ /* Reg. parse error. */
1110 end--; /* Found it, move past brace. */
1113 op_bad = "Couldn't parse the [index] in this operand.";
1114 end = point; /* Force all the rest of the tests to fail. */
1117 op_bad = "Couldn't find the opening '[' for the index of this operand.";
1118 end = point; /* Force all the rest of the tests to fail. */
1122 /* Post increment? */
1129 /* register in parens? */
1130 if ((*end == ')') && (end[-1] != '\'')){
1133 /* Find opening paren. */
1134 for(--end;(*end != '(' && end != point);end--)
1137 /* If I found the opening paren, get the register number. */
1140 reg = tahoe_reg_parse(&tp);
1142 /* Not a register, but could be part of the expression. */
1144 end = temp; /* Rest the pointer back */
1146 end--; /* Found the reg. move before opening paren. */
1149 op_bad = "Couldn't find the opening '(' for the deref of this operand.";
1150 end = point; /* Force all the rest of the tests to fail. */
1154 /* Pre decrement? */
1156 if (dec_inc != ' '){
1157 op_bad = "Operand can't be both pre-inc and post-dec.";
1167 * Everything between point and end is the 'expression', unless it's
1175 imreg = tahoe_reg_parse(&point); /* Get the immediate register
1177 if (*point != '\0'){
1178 /* If there is junk after point, then the it's not immediate reg. */
1183 if (imreg != -1 && reg != -1)
1184 op_bad = "I parsed 2 registers in this operand.";
1187 * Evaluate whats left of the expression to see if it's valid.
1188 * Note again: This assumes that the calling expression has saved
1189 * input_line_pointer. (Nag, nag, nag!)
1192 if (*op_bad == '\0'){
1193 /* statement has no syntax goofs yet: lets sniff the expression */
1194 input_line_pointer = point;
1195 expP = &(topP->exp_of_operand);
1196 switch (expression (expP)){
1197 /* If expression == SEG_PASS1, expression() will have set
1200 /* No expression. For BSD4.2 compatibility, missing expression is
1202 expP->X_seg = SEG_ABSOLUTE;
1203 expP->X_add_number = 0;
1206 /* for SEG_ABSOLUTE, we shouldnt need to set X_subtract_symbol,
1207 X_add_symbol to any particular value. */
1208 /* But, we will program defensively. Since this situation occurs
1209 rarely so it costs us little to do so. */
1210 expP->X_add_symbol = NULL;
1211 expP->X_subtract_symbol = NULL;
1212 /* How many bytes are needed to express this abs value? */
1214 ((((expP->X_add_number & 0xFFFFFF80) == 0) ||
1215 ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 :
1216 (((expP->X_add_number & 0xFFFF8000) == 0) ||
1217 ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4);
1224 case SEG_DIFFERENCE:
1226 * Major bug. We can't handle the case of a
1227 * SEG_DIFFERENCE expression in a synthetic opcode
1228 * variable-length instruction.
1229 * We don't have a frag type that is smart enough to
1230 * relax a SEG_DIFFERENCE, and so we just force all
1231 * SEG_DIFFERENCEs to behave like SEG_PASS1s.
1232 * Clearly, if there is a demand we can invent a new or
1233 * modified frag type and then coding up a frag for this
1234 * case will be easy. SEG_DIFFERENCE was invented for the
1235 * .words after a CASE opcode, and was never intended for
1236 * instruction operands.
1240 op_bad = "Can't relocate expression error.";
1244 /* This is an error. Tahoe doesn't allow any expressions
1245 bigger that a 32 bit long word. Any bigger has to be referenced
1247 op_bad = "Expression is too large for a 32 bits.";
1251 as_fatal("Complier Bug: I got segment %d in tip_op.",expP->X_seg);
1254 if (*input_line_pointer != '\0'){
1255 op_bad = "Junk at end of expression.";
1261 /* I'm done, so restore optex */
1266 * At this point in the game, we (in theory) have all the components of
1267 * the operand at least parsed. Now it's time to check for syntax/semantic
1268 * errors, and build the mode.
1269 * This is what I have:
1270 * deferred = 1 if '*'
1271 * call_width = 0,1,2,4
1272 * abs_width = 0,1,2,4
1273 * com_width = 0,1,2,4
1274 * immediate = 1 if '$'
1275 * ndx = -1 or reg num
1276 * dec_inc = '-' or '+' or ' '
1277 * reg = -1 or reg num
1278 * imreg = -1 or reg num
1279 * topP->exp_of_operand
1282 /* Is there a displacement size? */
1283 disp_size = (call_width ? call_width :
1284 (com_width ? com_width :
1285 abs_width ? abs_width : 0));
1287 if (*op_bad == '\0'){
1290 mode = TAHOE_DIRECT_REG;
1291 if (deferred || immediate || (dec_inc != ' ') ||
1292 (reg != -1) || !really_none)
1293 op_bad = "Syntax error in direct register mode.";
1295 op_bad = "You can't index a register in direct register mode.";
1296 else if (imreg == SP_REG && access == 'r')
1298 "SP can't be the source operand with direct register addressing.";
1299 else if (access == 'a')
1300 op_bad = "Can't take the address of a register.";
1301 else if (access == 'b')
1302 op_bad = "Direct Register can't be used in a branch.";
1303 else if (width == 'q' && ((imreg % 2) || (imreg > 13)))
1304 op_bad = "For quad access, the register must be even and < 14.";
1305 else if (call_width)
1306 op_bad = "You can't cast a direct register.";
1308 if (*op_bad == '\0'){
1309 /* No errors, check for warnings */
1310 if (width == 'q' && imreg == 12)
1311 as_warn("Using reg 14 for quadwords can tromp the FP register.");
1316 /* We know: imm = -1 */
1317 }else if (dec_inc == '-'){
1319 mode = TAHOE_AUTO_DEC;
1320 if (deferred || immediate || !really_none)
1321 op_bad = "Syntax error in auto-dec mode.";
1323 op_bad = "You can't have an index auto dec mode.";
1324 else if (access == 'r')
1325 op_bad = "Auto dec mode cant be used for reading.";
1326 else if (reg != SP_REG)
1327 op_bad = "Auto dec only works of the SP register.";
1328 else if (access == 'b')
1329 op_bad = "Auto dec can't be used in a branch.";
1330 else if (width == 'q')
1331 op_bad = "Auto dec won't work with quadwords.";
1333 /* We know: imm = -1, dec_inc != '-' */
1334 }else if (dec_inc == '+'){
1335 if (immediate || !really_none)
1336 op_bad = "Syntax error in one of the auto-inc modes.";
1339 mode = TAHOE_AUTO_INC_DEFERRED;
1341 op_bad = "Auto inc deferred only works of the SP register.";
1343 op_bad = "You can't have an index auto inc deferred mode.";
1344 else if (access == 'b')
1345 op_bad = "Auto inc can't be used in a branch.";
1348 mode = TAHOE_AUTO_INC;
1349 if (access == 'm' || access == 'w')
1350 op_bad = "You can't write to an auto inc register.";
1351 else if (reg != SP_REG)
1352 op_bad = "Auto inc only works of the SP register.";
1353 else if (access == 'b')
1354 op_bad = "Auto inc can't be used in a branch.";
1355 else if (width == 'q')
1356 op_bad = "Auto inc won't work with quadwords.";
1358 op_bad = "You can't have an index in auto inc mode.";
1361 /* We know: imm = -1, dec_inc == ' ' */
1362 }else if (reg != -1){
1363 if ((ndx != -1) && (reg == SP_REG))
1364 op_bad = "You can't index the sp register.";
1367 mode = TAHOE_REG_DISP_DEFERRED;
1369 op_bad = "Syntax error in register displaced mode.";
1370 }else if (really_none){
1372 mode = TAHOE_REG_DEFERRED;
1373 /* if reg = SP then cant be indexed */
1376 mode = TAHOE_REG_DISP;
1379 /* We know: imm = -1, dec_inc == ' ', Reg = -1 */
1382 op_bad = "An offest is needed for this operand.";
1383 if (deferred && immediate){
1385 mode = TAHOE_ABSOLUTE_ADDR;
1387 }else if (immediate){
1389 mode = TAHOE_IMMEDIATE;
1391 op_bad = "You can't index a register in immediate mode.";
1393 op_bad = "Immediate access can't be used as an address.";
1394 /* ponder the wisdom of a cast because it doesn't do any good. */
1395 }else if (deferred){
1397 mode = TAHOE_DISP_REL_DEFERRED;
1400 mode = TAHOE_DISPLACED_RELATIVE;
1406 * At this point, all the errors we can do have be checked for.
1407 * We can build the 'top'. */
1409 topP->top_ndx = ndx;
1410 topP->top_reg = reg;
1411 topP->top_mode = mode;
1412 topP->top_error = op_bad;
1413 topP->top_dispsize = disp_size;
1419 * This converts a string into a tahoe instruction.
1420 * The string must be a bare single instruction in tahoe (with BSD4 frobs)
1422 * It provides at most one fatal error message (which stops the scan)
1423 * some warning messages as it finds them.
1424 * The tahoe instruction is returned in exploded form.
1426 * The exploded instruction is returned to a struct tit of your choice.
1427 * #include "tahoe-inst.h" to know what a struct tit is.
1432 tip (titP, instring)
1433 struct tit *titP; /* We build an exploded instruction here. */
1434 char *instring; /* Text of a vax instruction: we modify. */
1436 register struct tot_wot *twP = NULL; /* How to bit-encode this opcode. */
1437 register char *p; /* 1/skip whitespace.2/scan vot_how */
1438 register char *q; /* */
1439 register unsigned char count; /* counts number of operands seen */
1440 register struct top *operandp;/* scan operands in struct tit */
1441 register char *alloperr = ""; /* error over all operands */
1442 register char c; /* Remember char, (we clobber it
1443 with '\0' temporarily). */
1444 char *save_input_line_pointer;
1446 if (*instring == ' ')
1447 ++instring; /* Skip leading whitespace. */
1448 for (p = instring; *p && *p != ' '; p++)
1449 ; /* MUST end in end-of-string or
1451 /* Scanned up to end of operation-code. */
1452 /* Operation-code is ended with whitespace. */
1454 titP->tit_error = "No operator";
1456 titP->tit_opcode = 0;
1461 * Here with instring pointing to what better be an op-name, and p
1462 * pointing to character just past that.
1463 * We trust instring points to an op-name, with no whitespace.
1465 twP = (struct tot_wot *) hash_find(op_hash, instring);
1466 *p = c; /* Restore char after op-code. */
1468 titP->tit_error = "Unknown operator";
1470 titP->tit_opcode = 0;
1473 * We found a match! So lets pick up as many operands as the
1474 * instruction wants, and even gripe if there are too many.
1475 * We expect comma to seperate each operand.
1476 * We let instring track the text, while p tracks a part of the
1480 count = 0; /* no operands seen yet */
1481 instring = p+(*p!='\0'); /* point past the operation code */
1482 /* tip_op() screws with the input_line_pointer, so save it before
1484 save_input_line_pointer = input_line_pointer;
1485 for (p = twP->args, operandp = titP->tit_operand;
1487 operandp++, p += 2){
1489 * Here to parse one operand. Leave instring pointing just
1490 * past any one ',' that marks the end of this operand.
1493 as_fatal("Compiler bug: ODD number of bytes in arg structure %s.",
1495 else if (*instring){
1496 for (q = instring; (*q != ',' && *q != '\0'); q++){
1497 if (*q == '\'' && q[1] != '\0') /* Jump quoted characters */
1502 * Q points to ',' or '\0' that ends argument. C is that
1506 operandp->top_access = p[0];
1507 operandp->top_width = p[1];
1508 tip_op(instring-1, operandp);
1509 *q = c; /* Restore input text. */
1510 if (*(operandp->top_error)){
1511 alloperr = operandp->top_error;
1513 instring = q + (c ? 1 : 0); /* next operand (if any) */
1514 count++; /* won another argument, may have an operr */
1516 alloperr = "Not enough operands";
1518 /* Restore the pointer. */
1519 input_line_pointer = save_input_line_pointer;
1522 if (*instring == ' ')
1523 instring++; /* Skip whitespace. */
1525 alloperr = "Too many operands";
1527 titP->tit_error = alloperr;
1531 titP->tit_opcode = twP->code; /* The op-code. */
1532 titP->tit_operands = count;
1535 /* md_assemble() emit frags for 1 instruction */
1537 md_assemble (instruction_string)
1538 char *instruction_string; /* A string: assemble 1 instruction. */
1541 register struct top *operandP; /* An operand. Scans all operands. */
1542 /* char c_save; fixme: remove this line */ /* What used to live after an expression. */
1543 /* struct frag *fragP; fixme: remove this line */ /* Fragment of code we just made. */
1544 /* register struct top *end_operandP; fixme: remove this line */ /* -> slot just after last operand
1545 Limit of the for (each operand). */
1546 register expressionS *expP; /* -> expression values for this operand */
1548 /* These refer to an instruction operand expression. */
1549 segT to_seg; /* Target segment of the address. */
1551 register valueT this_add_number;
1552 register struct symbol *this_add_symbol; /* +ve (minuend) symbol. */
1554 /* tahoe_opcodeT opcode_as_number; fixme: remove this line */ /* The opcode as a number. */
1555 char *opcodeP; /* Where it is in a frag. */
1556 /* char *opmodeP; fixme: remove this line */ /* Where opcode type is, in a frag. */
1558 int dispsize; /* From top_dispsize: tahoe_operand_width
1560 int is_undefined; /* 1 if operand expression's
1561 segment not known yet. */
1562 int pc_rel; /* Is this operand pc relative? */
1564 /* Decode the operand. */
1565 tip(&t, instruction_string);
1568 * Check to see if this operand decode properly.
1569 * Notice that we haven't made any frags yet.
1570 * If it goofed, then this instruction will wedge in any pass,
1571 * and we can safely flush it, without causing interpass symbol phase
1572 * errors. That is, without changing label values in different passes.
1575 as_warn("Ignoring statement due to \"%s\"", t.tit_error);
1577 /* We saw no errors in any operands - try to make frag(s) */
1579 /* Remember where it is, in case we want to modify the op-code later. */
1580 opcodeP = frag_more(1);
1581 *opcodeP = t.tit_opcode;
1582 /* Now do each operand. */
1583 for (operandP = t.tit_operand;
1584 operandP < t.tit_operand + t.tit_operands;
1585 operandP++){ /* for each operand */
1586 expP = &(operandP->exp_of_operand);
1587 if (operandP->top_ndx >= 0){
1588 /* Indexed addressing byte
1589 Legality of indexed mode already checked: it is OK */
1590 FRAG_APPEND_1_CHAR(0x40 + operandP->top_ndx);
1591 } /* if(top_ndx>=0) */
1593 /* Here to make main operand frag(s). */
1594 this_add_number = expP->X_add_number;
1595 this_add_symbol = expP->X_add_symbol;
1596 to_seg = expP->X_seg;
1597 know (to_seg == SEG_UNKNOWN||\
1598 to_seg == SEG_ABSOLUTE||\
1599 to_seg == SEG_DATA||\
1600 to_seg == SEG_TEXT||\
1602 is_undefined = (to_seg == SEG_UNKNOWN);
1603 /* Do we know how big this opperand is? */
1604 dispsize = operandP->top_dispsize;
1606 /* Deal with the branch possabilities. (Note, this doesn't include
1608 if (operandP->top_access == 'b'){
1609 /* Branches must be expressions. A psuedo branch can also jump to
1610 an absolute address. */
1611 if (to_seg == now_seg || is_undefined){
1612 /* If is_undefined, then it might BECOME now_seg by relax time. */
1614 /* I know how big the branch is supposed to be (it's a normal
1615 branch), so I set up the frag, and let GAS do the rest. */
1616 p = frag_more (dispsize);
1617 fix_new (frag_now, p - frag_now->fr_literal, dispsize,
1618 this_add_symbol, 0, this_add_number, 1, NO_RELOC);
1620 /* (to_seg==now_seg || to_seg == SEG_UNKNOWN) && dispsize==0 */
1621 /* If we don't know how big it is, then its a synthetic branch,
1622 so we set up a simple relax state. */
1623 switch (operandP->top_width){
1624 case TAHOE_WIDTH_CONDITIONAL_JUMP:
1625 /* Simple (conditional) jump. I may have to reverse the
1626 condition of opcodeP, and then jump to my destination.
1627 I set 1 byte aside for the branch off set, and could need 6
1628 more bytes for the pc_rel jump */
1629 frag_var (rs_machine_dependent, 7, 1,
1630 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH,
1631 is_undefined ? STATE_UNDF : STATE_BYTE),
1632 this_add_symbol, this_add_number, opcodeP);
1634 case TAHOE_WIDTH_ALWAYS_JUMP:
1635 /* Simple (unconditional) jump. I may have to convert this to
1636 a word branch, or an absolute jump. */
1637 frag_var (rs_machine_dependent, 5, 1,
1638 ENCODE_RELAX (STATE_ALWAYS_BRANCH,
1639 is_undefined ? STATE_UNDF : STATE_BYTE),
1640 this_add_symbol, this_add_number, opcodeP);
1642 /* The smallest size for the next 2 cases is word. */
1643 case TAHOE_WIDTH_BIG_REV_JUMP:
1644 frag_var (rs_machine_dependent, 8, 2,
1645 ENCODE_RELAX (STATE_BIG_REV_BRANCH,
1646 is_undefined ? STATE_UNDF : STATE_WORD),
1647 this_add_symbol, this_add_number,
1650 case TAHOE_WIDTH_BIG_NON_REV_JUMP:
1651 frag_var (rs_machine_dependent, 10, 2,
1652 ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH,
1653 is_undefined ? STATE_UNDF : STATE_WORD),
1654 this_add_symbol, this_add_number,
1658 as_fatal("Compliler bug: Got a case (%d) I wasn't expecting.",
1659 operandP->top_width);
1663 /* to_seg != now_seg && to_seg != seg_unknown (still in branch)
1664 In other words, I'm jumping out of my segment so extend the
1665 branches to jumps, and let GAS fix them. */
1667 /* These are "branches" what will always be branches around a jump
1668 to the correct addresss in real life.
1669 If to_seg is SEG_ABSOLUTE, just encode the branch in,
1670 else let GAS fix the address. */
1672 switch (operandP->top_width){
1674 For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump
1675 to that addresss (not pc_rel).
1676 For other segs, address is a long word PC rel jump. */
1677 case TAHOE_WIDTH_CONDITIONAL_JUMP:
1679 /* To reverse the condition in a TAHOE branch,
1685 *p++ = (operandP->top_mode ==
1686 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1688 fix_new (frag_now, p - frag_now->fr_literal, 4,
1689 this_add_symbol, 0, this_add_number,
1690 (to_seg != SEG_ABSOLUTE), NO_RELOC);
1697 case TAHOE_WIDTH_ALWAYS_JUMP:
1698 /* br, just turn it into a jump */
1699 *opcodeP = TAHOE_JMP;
1701 *p++ = (operandP->top_mode ==
1702 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1704 fix_new (frag_now, p - frag_now->fr_literal, 4,
1705 this_add_symbol, 0, this_add_number,
1706 (to_seg != SEG_ABSOLUTE), NO_RELOC);
1707 /* Now (eg) JMP foo */
1709 case TAHOE_WIDTH_BIG_REV_JUMP:
1715 *p++ = (operandP->top_mode ==
1716 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1718 fix_new (frag_now, p - frag_now->fr_literal, 4,
1719 this_add_symbol, 0, this_add_number,
1720 (to_seg != SEG_ABSOLUTE), NO_RELOC);
1727 case TAHOE_WIDTH_BIG_NON_REV_JUMP:
1734 *p++ = (operandP->top_mode ==
1735 TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR :
1737 fix_new (frag_now, p - frag_now->fr_literal, 4,
1738 this_add_symbol, 0, this_add_number,
1739 (to_seg != SEG_ABSOLUTE), NO_RELOC);
1741 * Now (eg) xOBxxx 1f
1749 as_warn("Real branch displacements must be expressions.");
1752 as_fatal("Complier error: I got an unknown synthetic branch :%c",
1753 operandP->top_width);
1758 /* It ain't a branch operand. */
1759 switch (operandP->top_mode){
1760 /* Auto-foo access, only works for one reg (SP)
1761 so the only thing needed is the mode. */
1762 case TAHOE_AUTO_DEC:
1763 case TAHOE_AUTO_INC:
1764 case TAHOE_AUTO_INC_DEFERRED:
1765 FRAG_APPEND_1_CHAR(operandP->top_mode);
1768 /* Numbered Register only access. Only thing needed is the
1769 mode + Register number */
1770 case TAHOE_DIRECT_REG:
1771 case TAHOE_REG_DEFERRED:
1772 FRAG_APPEND_1_CHAR(operandP->top_mode + operandP->top_reg);
1775 /* An absolute address. It's size is always 5 bytes.
1776 (mode_type + 4 byte address). */
1777 case TAHOE_ABSOLUTE_ADDR:
1778 know((this_add_symbol == NULL));
1780 *p = TAHOE_ABSOLUTE_ADDR;
1781 md_number_to_chars(p+1,this_add_number,4);
1784 /* Immediate data. If the size isn't known, then it's an address
1785 + and offset, which is 4 bytes big. */
1786 case TAHOE_IMMEDIATE:
1787 if (this_add_symbol != NULL){
1789 *p++ = TAHOE_IMMEDIATE_LONGWORD;
1790 fix_new (frag_now, p - frag_now->fr_literal,
1791 4, this_add_symbol,0,this_add_number,
1794 /* It's a integer, and I know it's size. */
1795 if ((unsigned) this_add_number < 0x40){
1796 /* Will it fit in a literal? */
1797 FRAG_APPEND_1_CHAR((byte) this_add_number);
1799 p = frag_more(dispsize+1);
1802 *p++ = TAHOE_IMMEDIATE_BYTE;
1803 *p = (byte) this_add_number;
1806 *p++ = TAHOE_IMMEDIATE_WORD;
1807 md_number_to_chars(p,this_add_number,2);
1810 *p++ = TAHOE_IMMEDIATE_LONGWORD;
1811 md_number_to_chars(p,this_add_number,4);
1818 /* Distance from the PC. If the size isn't known, we have to relax
1819 into it. The difference between this and disp(sp) is that
1820 this offset is pc_rel, and disp(sp) isn't.
1821 Note the drop through code. */
1823 case TAHOE_DISPLACED_RELATIVE:
1824 case TAHOE_DISP_REL_DEFERRED:
1825 operandP->top_reg = PC_REG;
1828 /* Register, plus a displacement mode. Save the register number,
1829 and weather its deffered or not, and relax the size if it isn't
1831 case TAHOE_REG_DISP:
1832 case TAHOE_REG_DISP_DEFERRED:
1833 if (operandP->top_mode == TAHOE_DISP_REL_DEFERRED ||
1834 operandP->top_mode == TAHOE_REG_DISP_DEFERRED)
1835 operandP->top_reg += 0x10; /* deffered mode is always 0x10 higher
1836 than it's non-deffered sibling. */
1838 /* Is this a value out of this segment?
1839 The first part of this conditional is a cludge to make gas
1840 produce the same output as 'as' when there is a lable, in
1841 the current segment, displaceing a register. It's strange,
1842 and no one in their right mind would do it, but it's easy
1844 if ((dispsize == 0 && !pc_rel) ||
1845 (to_seg != now_seg && !is_undefined && to_seg != SEG_ABSOLUTE))
1850 * We have a SEG_UNKNOWN symbol, or the size isn't cast.
1851 * It might turn out to be in the same segment as
1852 * the instruction, permitting relaxation.
1854 p = frag_var(rs_machine_dependent, 5, 2,
1855 ENCODE_RELAX(STATE_PC_RELATIVE,
1856 is_undefined ? STATE_UNDF:STATE_BYTE),
1857 this_add_symbol, this_add_number,0);
1858 *p = operandP->top_reg;
1860 /* Either this is an abs, or a cast. */
1861 p = frag_more (dispsize + 1);
1864 *p = TAHOE_PC_OR_BYTE + operandP->top_reg;
1867 *p = TAHOE_PC_OR_WORD + operandP->top_reg;
1870 *p = TAHOE_PC_OR_LONG + operandP->top_reg;
1873 fix_new (frag_now, p + 1 - frag_now->fr_literal,
1874 dispsize, this_add_symbol,0,this_add_number,
1879 as_fatal("Barf, bad mode %x\n",operandP->top_mode);
1882 } /* for(operandP) */
1883 } /* if(!need_pass_2 && !goofed) */
1884 } /* tahoe_assemble() */
1887 /* We have no need to default values of symbols. */
1890 symbolS *md_undefined_symbol(name)
1894 } /* md_undefined_symbol() */
1896 /* Parse an operand that is machine-specific.
1897 We just return without modifying the expression if we have nothing
1901 void md_operand(expressionP)
1902 expressionS *expressionP;
1904 } /* md_operand() */
1906 /* Round up a section size to the appropriate boundary. */
1907 long md_section_align(segment, size)
1911 return((size + 7) & ~7); /* Round all sects to multiple of 8 */
1912 } /* md_section_align() */
1914 /* Exactly what point is a PC-relative offset relative TO?
1915 On the sparc, they're relative to the address of the offset, plus
1916 its size. This gets us to the following instruction.
1917 (??? Is this right? FIXME-SOON) */
1918 long md_pcrel_from(fixP)
1921 return(fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
1922 } /* md_pcrel_from() */
1924 /* end of tc-tahoe.c */