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 segT seg_of_operand
; /* segment as returned by expression()*/
35 expressionS exp_of_operand
; /* The expression as parsed by expression()*/
37 byte top_dispsize
; /* Number of bytes in the displacement if we
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)
46 #define TAHOE_REG_DISP (0xE0)
47 #define TAHOE_REG_DISP_DEFERRED (0xF0)
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)
55 #define TAHOE_DISPLACED_RELATIVE (0xEF)
56 #define TAHOE_DISP_REL_DEFERRED (0xFF)
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] */
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 ':'
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)
82 struct tit
/* get it out of the sewer, it stands for
83 tahoe instruction tree (Geeze!) */
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 */
91 /* end: tahoe-inst.h */
93 /* tahoe.c - tahoe-specific -
97 #include "opcode/tahoe.h"
99 /* This is the number to put at the beginning of the a.out file */
100 long omagic
= OMAGIC
;
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
[] = "#;";
106 /* These chars only start a comment at the beginning of a line. */
107 const char line_comment_chars
[] = "#";
109 /* Chars that can be used to separate mant from exp in floating point nums */
110 const char EXP_CHARS
[] = "eE";
112 /* Chars that mean this number is a floating point constant
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";
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.)
125 static struct tit t
; /* A tahoe instruction after decoding. */
128 /* A table of pseudo ops (sans .), the function called, and an integer op
129 that the function is called with. */
131 const pseudo_typeS md_pseudo_table
[] =
133 {"dfloat", float_cons
, 'd'},
134 {"ffloat", float_cons
, 'f'},
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:
144 * 4 3 2 1 0 bit number
145 * ---/ /--+-------+-------+-------+-------+-------+
146 * | what state ? | how long ? |
147 * ---/ /--+-------+-------+-------+-------+-------+
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.
157 States for Tahoe address relaxing.
158 1. TAHOE_WIDTH_ALWAYS_JUMP (-)
160 Tahoe opcodes are: (Hex)
164 Always, 1 byte opcode, then displacement/absolute.
165 If word or longword, change opcode to brw or jmp.
168 2. TAHOE_WIDTH_CONDITIONAL_JUMP (?)
169 J<cond> where <cond> is a simple flag test.
171 Tahoe opcodes are: (Hex)
184 Always, you complement 4th bit to reverse the condition.
185 Always, 1-byte opcode, then 1-byte displacement.
187 3. TAHOE_WIDTH_BIG_REV_JUMP (!)
188 Jbc/Jbs where cond tests a memory bit.
190 Tahoe opcodes are: (Hex)
193 Always, you complement 4th bit to reverse the condition.
194 Always, 1-byte opcde, longword, longword-address, 1-word-displacement
196 4. TAHOE_WIDTH_BIG_NON_REV_JUMP (:)
199 Tahoe opcodes are: (Hex)
205 Always, we cannot reverse the sense of the branch; we have a word
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
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.) */
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))
222 The first letter is Byte, Word.
223 2nd letter is Forward, Backward. */
226 #define WF (2+ 32767)
227 #define WB (2+-32768)
228 /* Dont need LF, LB because they always reach. [They are coded as 0.] */
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)
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)
242 #define STATE_BYTE (0)
243 #define STATE_WORD (1)
244 #define STATE_LONG (2)
245 #define STATE_UNDF (3) /* Symbol undefined in pass1 */
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. */
255 }, /* error sentinel 0,0 */
265 /* Unconditional branch cases "jrb"
266 The relax part is the actual displacement */
269 }, /* brb B`foo 1,0 */
272 }, /* brw W`foo 1,1 */
275 }, /* Jmp L`foo 1,2 */
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
284 }, /* b<cond> B`foo 2,0 */
286 WF
+ 2, WB
+ 2, 4, C (2, 2)
287 }, /* brev over, brw W`foo, over: 2,1 */
290 }, /* brev over, jmp L`foo, over: 2,2 */
294 /* Another type of reversable branch. But this only has a word
301 }, /* jbX W`foo 3,1 */
304 }, /* jrevX over, jmp L`foo, over: 3,2 */
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
318 }, /* aobl_ W`foo 4,1 */
321 }, /*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/
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. */
329 BF
+ 1, BB
+ 1, 2, C (5, 1)
332 WF
+ 1, WB
+ 1, 3, C (5, 2)
347 /* End relax stuff */
349 static struct hash_control
*op_hash
= NULL
; /* handle of the OPCODE hash table
350 NULL means any use before md_begin() will
353 /* Init function. Build the hash table. */
359 int synthetic_too
= 1; /* If 0, just use real opcodes. */
361 if ((op_hash
= hash_new ()))
363 for (tP
= totstrs
; *tP
->name
&& !*errorval
; tP
++)
365 errorval
= hash_insert (op_hash
, tP
->name
, &tP
->detail
);
369 for (tP
= synthetic_totstrs
; *tP
->name
&& !*errorval
; tP
++)
371 errorval
= hash_insert (op_hash
, tP
->name
, &tP
->detail
);
377 errorval
= "Virtual memory exceeded";
389 md_parse_option (argP
, cntP
, vecP
)
394 char *temp_name
; /* name for -t or -d options */
400 as_warn ("The -a option doesn't exits. (Dispite what the man page says!");
403 as_warn ("JUMPIFY (-J) not implemented, use psuedo ops instead.");
407 as_warn ("SYMBOL TABLE not implemented");
408 break; /* SYMBOL TABLE not implemented */
411 as_warn ("TOKEN TRACE not implemented");
412 break; /* TOKEN TRACE not implemented */
418 { /* Rest of argument is filename. */
428 temp_name
= *++(*vecP
);
429 **vecP
= NULL
; /* Remember this is not a file-name. */
433 as_warn ("I expected a filename after -%c.", opt
);
434 temp_name
= "{absent}";
438 as_warn ("Displacement length %s ignored!", temp_name
);
440 as_warn ("I don't need or use temp. file \"%s\".", temp_name
);
444 as_warn ("I don't use an interpass file! -V ignored");
454 /* The functions in this section take numbers in the machine format, and
455 munges them into Tahoe byte order.
456 They exist primarily for cross assembly purpose. */
457 void /* Knows about order of bytes in address. */
458 md_number_to_chars (con
, value
, nbytes
)
459 char con
[]; /* Return 'nbytes' of chars here. */
460 valueT value
; /* The value of the bits. */
461 int nbytes
; /* Number of bytes in the output. */
466 con
+= nbytes
- 1; /* Tahoes is (Bleah!) big endian */
469 *con
-- = value
; /* Lint wants & MASK_CHAR. */
470 value
>>= BITS_PER_CHAR
;
472 /* XXX line number probably botched for this warning message. */
473 if (value
!= 0 && value
!= -1)
474 as_warn ("Displacement (%ld) long for instruction field length (%d).", v
, n
);
478 void /* Knows about order of bytes in address. */
479 md_number_to_imm (con
, value
, nbytes
)
480 char con
[]; /* Return 'nbytes' of chars here. */
481 long int value
; /* The value of the bits. */
482 int nbytes
; /* Number of bytes in the output. */
484 md_number_to_chars (con
, value
, nbytes
);
490 tc_apply_fix (fixP
, val
)
494 /* char *place = fixP->fx_where + fixP->fx_frag->fr_literal; */
495 /* should never be called */
498 } /* tc_apply_fix() */
500 void /* Knows about order of bytes in address. */
501 md_number_to_disp (con
, value
, nbytes
)
502 char con
[]; /* Return 'nbytes' of chars here. */
503 long int value
; /* The value of the bits. */
504 int nbytes
; /* Number of bytes in the output. */
506 md_number_to_chars (con
, value
, nbytes
);
509 void /* Knows about order of bytes in address. */
510 md_number_to_field (con
, value
, nbytes
)
511 char con
[]; /* Return 'nbytes' of chars here. */
512 long int value
; /* The value of the bits. */
513 int nbytes
; /* Number of bytes in the output. */
515 md_number_to_chars (con
, value
, nbytes
);
518 /* Put the bits in an order that a tahoe will understand, despite the ordering
519 of the native machine.
520 On Tahoe: first 4 bytes are normal unsigned big endian long,
521 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
522 The last byte is broken up with bit 7 as pcrel,
523 bits 6 & 5 as length,
524 bit 4 as extern and the last nibble as 'undefined'. */
528 md_ri_to_chars (ri_p
, ri
)
529 struct relocation_info
*ri_p
, ri
;
531 byte the_bytes
[sizeof (struct relocation_info
)];
532 /* The reason I can't just encode these directly into ri_p is that
533 ri_p may point to ri. */
536 md_number_to_chars (the_bytes
, ri
.r_address
, sizeof (ri
.r_address
));
538 /* now the fun stuff */
539 the_bytes
[4] = (ri
.r_symbolnum
>> 16) & 0x0ff;
540 the_bytes
[5] = (ri
.r_symbolnum
>> 8) & 0x0ff;
541 the_bytes
[6] = ri
.r_symbolnum
& 0x0ff;
542 the_bytes
[7] = (((ri
.r_extern
<< 4) & 0x10) | ((ri
.r_length
<< 5) & 0x60) |
543 ((ri
.r_pcrel
<< 7) & 0x80)) & 0xf0;
545 bcopy (the_bytes
, (char *) ri_p
, sizeof (struct relocation_info
));
550 /* Put the bits in an order that a tahoe will understand, despite the ordering
551 of the native machine.
552 On Tahoe: first 4 bytes are normal unsigned big endian long,
553 next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).
554 The last byte is broken up with bit 7 as pcrel,
555 bits 6 & 5 as length,
556 bit 4 as extern and the last nibble as 'undefined'. */
559 tc_aout_fix_to_chars (where
, fixP
, segment_address_in_file
)
562 relax_addressT segment_address_in_file
;
566 know (fixP
->fx_addsy
!= NULL
);
568 md_number_to_chars (where
,
569 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
572 r_symbolnum
= (S_IS_DEFINED (fixP
->fx_addsy
)
573 ? S_GET_TYPE (fixP
->fx_addsy
)
574 : fixP
->fx_addsy
->sy_number
);
576 where
[4] = (r_symbolnum
>> 16) & 0x0ff;
577 where
[5] = (r_symbolnum
>> 8) & 0x0ff;
578 where
[6] = r_symbolnum
& 0x0ff;
579 where
[7] = (((is_pcrel (fixP
) << 7) & 0x80)
580 | ((((fixP
->fx_type
== FX_8
|| fixP
->fx_type
== FX_PCREL8
582 : (fixP
->fx_type
== FX_16
|| fixP
->fx_type
== FX_PCREL16
584 : (fixP
->fx_type
== FX_32
|| fixP
->fx_type
== FX_PCREL32
586 : 42)))) << 5) & 0x60)
587 | ((!S_IS_DEFINED (fixP
->fx_addsy
) << 4) & 0x10));
590 } /* tc_aout_fix_to_chars() */
592 /* Relocate byte stuff */
594 /* This is for broken word. */
595 const int md_short_jump_size
= 3;
598 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
600 addressT from_addr
, to_addr
;
606 offset
= to_addr
- (from_addr
+ 1);
608 md_number_to_chars (ptr
, offset
, 2);
611 const int md_long_jump_size
= 6;
612 const int md_reloc_size
= 8; /* Size of relocation record */
615 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
617 addressT from_addr
, to_addr
;
623 offset
= to_addr
- (from_addr
+ 4);
625 *ptr
++ = TAHOE_PC_REL_LONG
;
626 md_number_to_chars (ptr
, offset
, 4);
630 * md_estimate_size_before_relax()
632 * Called just before relax().
633 * Any symbol that is now undefined will not become defined, so we assumed
634 * that it will be resolved by the linker.
635 * Return the correct fr_subtype in the frag, for relax()
636 * Return the initial "guess for fr_var" to caller. (How big I think this
638 * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
639 * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
640 * Although it may not be explicit in the frag, pretend fr_var starts with a
644 md_estimate_size_before_relax (fragP
, segment_type
)
645 register fragS
*fragP
;
646 segT segment_type
; /* N_DATA or N_TEXT. */
649 register int old_fr_fix
;
650 /* int pc_rel; FIXME: remove this */
652 old_fr_fix
= fragP
->fr_fix
;
653 switch (fragP
->fr_subtype
)
655 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_UNDF
):
656 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
658 /* The symbol was in the same segment as the opcode, and it's
659 a real pc_rel case so it's a relaxable case. */
660 fragP
->fr_subtype
= ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
);
664 /* This case is still undefined, so asume it's a long word for the
666 p
= fragP
->fr_literal
+ old_fr_fix
;
667 *p
|= TAHOE_PC_OR_LONG
;
668 /* We now know how big it will be, one long word. */
669 fragP
->fr_fix
+= 1 + 4;
670 fix_new (fragP
, old_fr_fix
+ 1, fragP
->fr_symbol
,
671 fragP
->fr_offset
, FX_PCREL32
, NULL
);
676 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_UNDF
):
677 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
679 fragP
->fr_subtype
= ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
);
683 p
= fragP
->fr_literal
+ old_fr_fix
;
684 *fragP
->fr_opcode
^= 0x10; /* Reverse sense of branch. */
687 *p
++ = TAHOE_PC_REL_LONG
;
688 fragP
->fr_fix
+= 1 + 1 + 1 + 4;
689 fix_new (fragP
, old_fr_fix
+ 3, fragP
->fr_symbol
,
690 fragP
->fr_offset
, FX_PCREL32
, NULL
);
695 case ENCODE_RELAX (STATE_BIG_REV_BRANCH
, STATE_UNDF
):
696 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
699 ENCODE_RELAX (STATE_BIG_REV_BRANCH
, STATE_WORD
);
703 p
= fragP
->fr_literal
+ old_fr_fix
;
704 *fragP
->fr_opcode
^= 0x10; /* Reverse sense of branch. */
708 *p
++ = TAHOE_PC_REL_LONG
;
709 fragP
->fr_fix
+= 2 + 2 + 4;
710 fix_new (fragP
, old_fr_fix
+ 4, fragP
->fr_symbol
,
711 fragP
->fr_offset
, FX_PCREL32
, NULL
);
716 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH
, STATE_UNDF
):
717 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
719 fragP
->fr_subtype
= ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH
, STATE_WORD
);
723 p
= fragP
->fr_literal
+ old_fr_fix
;
729 *p
++ = TAHOE_PC_REL_LONG
;
730 fragP
->fr_fix
+= 2 + 2 + 2 + 4;
731 fix_new (fragP
, old_fr_fix
+ 6, fragP
->fr_symbol
,
732 fragP
->fr_offset
, FX_PCREL32
, NULL
);
737 case ENCODE_RELAX (STATE_ALWAYS_BRANCH
, STATE_UNDF
):
738 if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
)
740 fragP
->fr_subtype
= ENCODE_RELAX (STATE_ALWAYS_BRANCH
, STATE_BYTE
);
744 p
= fragP
->fr_literal
+ old_fr_fix
;
745 *fragP
->fr_opcode
= TAHOE_JMP
;
746 *p
++ = TAHOE_PC_REL_LONG
;
747 fragP
->fr_fix
+= 1 + 4;
748 fix_new (fragP
, old_fr_fix
+ 1, fragP
->fr_symbol
,
749 fragP
->fr_offset
, FX_PCREL32
, NULL
);
757 return (fragP
->fr_var
+ fragP
->fr_fix
- old_fr_fix
);
758 } /* md_estimate_size_before_relax() */
763 * Called after relax() is finished.
764 * In: Address of frag.
765 * fr_type == rs_machine_dependent.
766 * fr_subtype is what the address relaxed to.
768 * Out: Any fixSs and constants are set up.
769 * Caller will turn frag into a ".space 0".
772 md_convert_frag (headers
, fragP
)
773 object_headers
*headers
;
774 register fragS
*fragP
;
776 register char *addressP
; /* -> _var to change. */
777 register char *opcodeP
; /* -> opcode char(s) to change. */
778 register short int length_code
; /* 2=long 1=word 0=byte */
779 register short int extension
= 0; /* Size of relaxed address.
780 Added to fr_fix: incl. ALL var chars. */
781 register symbolS
*symbolP
;
782 register long int where
;
783 register long int address_of_var
;
784 /* Where, in file space, is _var of *fragP? */
785 register long int target_address
;
786 /* Where, in file space, does addr point? */
788 know (fragP
->fr_type
== rs_machine_dependent
);
789 length_code
= RELAX_LENGTH (fragP
->fr_subtype
);
790 know (length_code
>= 0 && length_code
< 3);
791 where
= fragP
->fr_fix
;
792 addressP
= fragP
->fr_literal
+ where
;
793 opcodeP
= fragP
->fr_opcode
;
794 symbolP
= fragP
->fr_symbol
;
796 target_address
= S_GET_VALUE (symbolP
) + fragP
->fr_offset
;
797 address_of_var
= fragP
->fr_address
+ where
;
798 switch (fragP
->fr_subtype
)
800 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_BYTE
):
801 /* *addressP holds the registers number, plus 0x10, if it's deferred
802 mode. To set up the right mode, just OR the size of this displacement */
803 /* Byte displacement. */
804 *addressP
++ |= TAHOE_PC_OR_BYTE
;
805 *addressP
= target_address
- (address_of_var
+ 2);
809 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_WORD
):
810 /* Word displacement. */
811 *addressP
++ |= TAHOE_PC_OR_WORD
;
812 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 3), 2);
816 case ENCODE_RELAX (STATE_PC_RELATIVE
, STATE_LONG
):
817 /* Long word displacement. */
818 *addressP
++ |= TAHOE_PC_OR_LONG
;
819 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 5), 4);
823 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_BYTE
):
824 *addressP
= target_address
- (address_of_var
+ 1);
828 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_WORD
):
829 *opcodeP
^= 0x10; /* Reverse sense of test. */
830 *addressP
++ = 3; /* Jump over word branch */
831 *addressP
++ = TAHOE_BRW
;
832 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 4), 2);
836 case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
, STATE_LONG
):
837 *opcodeP
^= 0x10; /* Reverse sense of test. */
839 *addressP
++ = TAHOE_JMP
;
840 *addressP
++ = TAHOE_PC_REL_LONG
;
841 md_number_to_chars (addressP
, target_address
, 4);
845 case ENCODE_RELAX (STATE_ALWAYS_BRANCH
, STATE_BYTE
):
846 *addressP
= target_address
- (address_of_var
+ 1);
850 case ENCODE_RELAX (STATE_ALWAYS_BRANCH
, STATE_WORD
):
851 *opcodeP
= TAHOE_BRW
;
852 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 2), 2);
856 case ENCODE_RELAX (STATE_ALWAYS_BRANCH
, STATE_LONG
):
857 *opcodeP
= TAHOE_JMP
;
858 *addressP
++ = TAHOE_PC_REL_LONG
;
859 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 5), 4);
863 case ENCODE_RELAX (STATE_BIG_REV_BRANCH
, STATE_WORD
):
864 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 2), 2);
868 case ENCODE_RELAX (STATE_BIG_REV_BRANCH
, STATE_LONG
):
872 *addressP
++ = TAHOE_JMP
;
873 *addressP
++ = TAHOE_PC_REL_LONG
;
874 md_number_to_chars (addressP
, target_address
, 4);
878 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH
, STATE_WORD
):
879 md_number_to_chars (addressP
, target_address
- (address_of_var
+ 2), 2);
883 case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH
, STATE_LONG
):
886 *addressP
++ = TAHOE_BRB
;
888 *addressP
++ = TAHOE_JMP
;
889 *addressP
++ = TAHOE_PC_REL_LONG
;
890 md_number_to_chars (addressP
, target_address
, 4);
895 BAD_CASE (fragP
->fr_subtype
);
898 fragP
->fr_fix
+= extension
;
899 } /* md_convert_frag */
902 /* This is the stuff for md_assemble. */
906 #define BIGGESTREG PC_REG
909 * Parse the string pointed to by START
910 * If it represents a valid register, point START to the character after
911 * the last valid register char, and return the register number (0-15).
912 * If invalid, leave START alone, return -1.
913 * The format has to be exact. I don't do things like eat leading zeros
915 * Note: This doesn't check for the next character in the string making
916 * this invalid. Ex: R123 would return 12, it's the callers job to check
917 * what start is point to apon return.
919 * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15)
920 * Case doesn't matter.
923 tahoe_reg_parse (start
)
924 char **start
; /* A pointer to the string to parse. */
926 register char *regpoint
= *start
;
927 register int regnum
= -1;
931 case '%': /* Registers can start with a %,
932 R or r, and then a number. */
935 if (isdigit (*regpoint
))
937 /* Got the first digit. */
938 regnum
= *regpoint
++ - '0';
939 if ((regnum
== 1) && isdigit (*regpoint
))
941 /* Its a two digit number. */
942 regnum
= 10 + (*regpoint
++ - '0');
943 if (regnum
> BIGGESTREG
)
944 { /* Number too big? */
950 case 'F': /* Is it the FP */
959 case 's': /* How about the SP */
968 case 'p': /* OR the PC even */
980 { /* No error, so move string pointer */
983 return regnum
; /* Return results */
984 } /* tahoe_reg_parse */
987 * This chops up an operand and figures out its modes and stuff.
988 * It's a little touchy about extra characters.
989 * Optex to start with one extra character so it can be overwritten for
990 * the backward part of the parsing.
991 * You can't put a bunch of extra characters in side to
992 * make the command look cute. ie: * foo ( r1 ) [ r0 ]
993 * If you like doing a lot of typing, try COBOL!
994 * Actually, this parser is a little weak all around. It's designed to be
995 * used with compliers, so I emphisise correct decoding of valid code quickly
996 * rather that catching every possable error.
997 * Note: This uses the expression function, so save input_line_pointer before
1000 * Sperry defines the semantics of address modes (and values)
1001 * by a two-letter code, explained here.
1003 * letter 1: access type
1005 * a address calculation - no data access, registers forbidden
1006 * b branch displacement
1007 * m read - let go of bus - write back "modify"
1010 * v bit field address: like 'a' but registers are OK
1012 * letter 2: data type (i.e. width, alignment)
1017 * q quadword (Even regs < 14 allowed) (if 12, you get a warning)
1018 * - unconditional synthetic jbr operand
1019 * ? simple synthetic reversable branch operand
1020 * ! complex synthetic reversable branch operand
1021 * : complex synthetic non-reversable branch operand
1023 * The '-?!:' letter 2's are not for external consumption. They are used
1024 * by GAS for psuedo ops relaxing code.
1026 * After parsing topP has:
1028 * top_ndx: -1, or the index register. eg 7=[R7]
1029 * top_reg: -1, or register number. eg 7 = R7 or (R7)
1030 * top_mode: The addressing mode byte. This byte, defines which of
1031 * the 11 modes opcode is.
1032 * top_access: Access type wanted for this opperand 'b'branch ' '
1033 * no-instruction 'amrvw'
1034 * top_width: Operand width expected, one of "bwlq?-:!"
1035 * exp_of_operand: The expression as parsed by expression()
1036 * top_dispsize: Number of bytes in the displacement if we can figure it
1037 * out and it's relavent.
1039 * Need syntax checks built.
1043 tip_op (optex
, topP
)
1044 char *optex
; /* The users text input, with one leading character */
1045 struct top
*topP
; /* The tahoe instruction with some fields already set:
1047 out: ndx, reg, mode, error, dispsize */
1050 int mode
= 0; /* This operand's mode. */
1051 char segfault
= *optex
; /* To keep the back parsing from freaking. */
1052 char *point
= optex
+ 1; /* Parsing from front to back. */
1053 char *end
; /* Parsing from back to front. */
1054 int reg
= -1; /* major register, -1 means absent */
1055 int imreg
= -1; /* Major register in immediate mode */
1056 int ndx
= -1; /* index register number, -1 means absent */
1057 char dec_inc
= ' '; /* Is the SP auto-incremented '+' or
1058 auto-decremented '-' or neither ' '. */
1059 int immediate
= 0; /* 1 if '$' immediate mode */
1060 int call_width
= 0; /* If the caller casts the displacement */
1061 int abs_width
= 0; /* The width of the absolute displacment */
1062 int com_width
= 0; /* Displacement width required by branch */
1063 int deferred
= 0; /* 1 if '*' deferral is used */
1064 byte disp_size
= 0; /* How big is this operand. 0 == don't know */
1065 char *op_bad
= ""; /* Bad operand error */
1067 char *tp
, *temp
, c
; /* Temporary holders */
1069 char access
= topP
->top_access
; /* Save on a deref. */
1070 char width
= topP
->top_width
;
1072 int really_none
= 0; /* Empty expressions evaluate to 0
1073 but I need to know if it's there or not */
1074 expressionS
*expP
; /* -> expression values for this operand */
1076 /* Does this command restrict the displacement size. */
1078 com_width
= (width
== 'b' ? 1 :
1080 (width
== 'l' ? 4 : 0)));
1082 *optex
= '\0'; /* This is kind of a back stop for all
1083 the searches to fail on if needed.*/
1085 { /* A dereference? */
1090 /* Force words into a certain mode */
1091 /* Bitch, Bitch, Bitch! */
1093 * Using the ^ operator is ambigous. If I have an absolute label
1094 * called 'w' set to, say 2, and I have the expression 'w^1', do I get
1095 * 1, forced to be in word displacement mode, or do I get the value of
1096 * 'w' or'ed with 1 (3 in this case).
1097 * The default is 'w' as an offset, so that's what I use.
1098 * Stick with `, it does the same, and isn't ambig.
1101 if (*point
!= '\0' && ((point
[1] == '^') || (point
[1] == '`')))
1111 as_warn ("Casting a branch displacement is bad form, and is ignored.");
1114 c
= (isupper (*point
) ? tolower (*point
) : *point
);
1115 call_width
= ((c
== 'b') ? 1 :
1116 ((c
== 'w') ? 2 : 4));
1122 /* Setting immediate mode */
1130 * I've pulled off all the easy stuff off the front, move to the end and
1134 for (end
= point
; *end
!= '\0'; end
++) /* Move to the end. */
1137 if (end
!= point
) /* Null string? */
1140 if (end
> point
&& *end
== ' ' && end
[-1] != '\'')
1141 end
--; /* Hop white space */
1143 /* Is this an index reg. */
1144 if ((*end
== ']') && (end
[-1] != '\''))
1148 /* Find opening brace. */
1149 for (--end
; (*end
!= '[' && end
!= point
); end
--)
1152 /* If I found the opening brace, get the index register number. */
1155 tp
= end
+ 1; /* tp should point to the start of a reg. */
1156 ndx
= tahoe_reg_parse (&tp
);
1158 { /* Reg. parse error. */
1163 end
--; /* Found it, move past brace. */
1167 op_bad
= "Couldn't parse the [index] in this operand.";
1168 end
= point
; /* Force all the rest of the tests to fail. */
1173 op_bad
= "Couldn't find the opening '[' for the index of this operand.";
1174 end
= point
; /* Force all the rest of the tests to fail. */
1178 /* Post increment? */
1186 /* register in parens? */
1187 if ((*end
== ')') && (end
[-1] != '\''))
1191 /* Find opening paren. */
1192 for (--end
; (*end
!= '(' && end
!= point
); end
--)
1195 /* If I found the opening paren, get the register number. */
1199 reg
= tahoe_reg_parse (&tp
);
1202 /* Not a register, but could be part of the expression. */
1204 end
= temp
; /* Rest the pointer back */
1208 end
--; /* Found the reg. move before opening paren. */
1213 op_bad
= "Couldn't find the opening '(' for the deref of this operand.";
1214 end
= point
; /* Force all the rest of the tests to fail. */
1218 /* Pre decrement? */
1223 op_bad
= "Operand can't be both pre-inc and post-dec.";
1235 * Everything between point and end is the 'expression', unless it's
1243 imreg
= tahoe_reg_parse (&point
); /* Get the immediate register
1247 /* If there is junk after point, then the it's not immediate reg. */
1252 if (imreg
!= -1 && reg
!= -1)
1253 op_bad
= "I parsed 2 registers in this operand.";
1256 * Evaluate whats left of the expression to see if it's valid.
1257 * Note again: This assumes that the calling expression has saved
1258 * input_line_pointer. (Nag, nag, nag!)
1261 if (*op_bad
== '\0')
1263 /* statement has no syntax goofs yet: lets sniff the expression */
1264 input_line_pointer
= point
;
1265 expP
= &(topP
->exp_of_operand
);
1266 topP
->seg_of_operand
= expression (expP
);
1270 /* No expression. For BSD4.2 compatibility, missing expression is
1272 expP
->X_op
= O_constant
;
1273 expP
->X_add_number
= 0;
1276 /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol,
1277 X_add_symbol to any particular value. */
1278 /* But, we will program defensively. Since this situation occurs
1279 rarely so it costs us little to do so. */
1280 expP
->X_add_symbol
= NULL
;
1281 expP
->X_op_symbol
= NULL
;
1282 /* How many bytes are needed to express this abs value? */
1284 ((((expP
->X_add_number
& 0xFFFFFF80) == 0) ||
1285 ((expP
->X_add_number
& 0xFFFFFF80) == 0xFFFFFF80)) ? 1 :
1286 (((expP
->X_add_number
& 0xFFFF8000) == 0) ||
1287 ((expP
->X_add_number
& 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4);
1294 * Major bug. We can't handle the case of a operator
1295 * expression in a synthetic opcode variable-length
1296 * instruction. We don't have a frag type that is smart
1297 * enough to relax a operator, and so we just force all
1298 * operators to behave like SEG_PASS1s. Clearly, if there is
1299 * a demand we can invent a new or modified frag type and
1300 * then coding up a frag for this case will be easy.
1303 op_bad
= "Can't relocate expression error.";
1307 /* This is an error. Tahoe doesn't allow any expressions
1308 bigger that a 32 bit long word. Any bigger has to be referenced
1310 op_bad
= "Expression is too large for a 32 bits.";
1313 if (*input_line_pointer
!= '\0')
1315 op_bad
= "Junk at end of expression.";
1321 /* I'm done, so restore optex */
1326 * At this point in the game, we (in theory) have all the components of
1327 * the operand at least parsed. Now it's time to check for syntax/semantic
1328 * errors, and build the mode.
1329 * This is what I have:
1330 * deferred = 1 if '*'
1331 * call_width = 0,1,2,4
1332 * abs_width = 0,1,2,4
1333 * com_width = 0,1,2,4
1334 * immediate = 1 if '$'
1335 * ndx = -1 or reg num
1336 * dec_inc = '-' or '+' or ' '
1337 * reg = -1 or reg num
1338 * imreg = -1 or reg num
1339 * topP->exp_of_operand
1342 /* Is there a displacement size? */
1343 disp_size
= (call_width
? call_width
:
1344 (com_width
? com_width
:
1345 abs_width
? abs_width
: 0));
1347 if (*op_bad
== '\0')
1352 mode
= TAHOE_DIRECT_REG
;
1353 if (deferred
|| immediate
|| (dec_inc
!= ' ') ||
1354 (reg
!= -1) || !really_none
)
1355 op_bad
= "Syntax error in direct register mode.";
1357 op_bad
= "You can't index a register in direct register mode.";
1358 else if (imreg
== SP_REG
&& access
== 'r')
1360 "SP can't be the source operand with direct register addressing.";
1361 else if (access
== 'a')
1362 op_bad
= "Can't take the address of a register.";
1363 else if (access
== 'b')
1364 op_bad
= "Direct Register can't be used in a branch.";
1365 else if (width
== 'q' && ((imreg
% 2) || (imreg
> 13)))
1366 op_bad
= "For quad access, the register must be even and < 14.";
1367 else if (call_width
)
1368 op_bad
= "You can't cast a direct register.";
1370 if (*op_bad
== '\0')
1372 /* No errors, check for warnings */
1373 if (width
== 'q' && imreg
== 12)
1374 as_warn ("Using reg 14 for quadwords can tromp the FP register.");
1379 /* We know: imm = -1 */
1381 else if (dec_inc
== '-')
1384 mode
= TAHOE_AUTO_DEC
;
1385 if (deferred
|| immediate
|| !really_none
)
1386 op_bad
= "Syntax error in auto-dec mode.";
1388 op_bad
= "You can't have an index auto dec mode.";
1389 else if (access
== 'r')
1390 op_bad
= "Auto dec mode cant be used for reading.";
1391 else if (reg
!= SP_REG
)
1392 op_bad
= "Auto dec only works of the SP register.";
1393 else if (access
== 'b')
1394 op_bad
= "Auto dec can't be used in a branch.";
1395 else if (width
== 'q')
1396 op_bad
= "Auto dec won't work with quadwords.";
1398 /* We know: imm = -1, dec_inc != '-' */
1400 else if (dec_inc
== '+')
1402 if (immediate
|| !really_none
)
1403 op_bad
= "Syntax error in one of the auto-inc modes.";
1407 mode
= TAHOE_AUTO_INC_DEFERRED
;
1409 op_bad
= "Auto inc deferred only works of the SP register.";
1411 op_bad
= "You can't have an index auto inc deferred mode.";
1412 else if (access
== 'b')
1413 op_bad
= "Auto inc can't be used in a branch.";
1418 mode
= TAHOE_AUTO_INC
;
1419 if (access
== 'm' || access
== 'w')
1420 op_bad
= "You can't write to an auto inc register.";
1421 else if (reg
!= SP_REG
)
1422 op_bad
= "Auto inc only works of the SP register.";
1423 else if (access
== 'b')
1424 op_bad
= "Auto inc can't be used in a branch.";
1425 else if (width
== 'q')
1426 op_bad
= "Auto inc won't work with quadwords.";
1428 op_bad
= "You can't have an index in auto inc mode.";
1431 /* We know: imm = -1, dec_inc == ' ' */
1435 if ((ndx
!= -1) && (reg
== SP_REG
))
1436 op_bad
= "You can't index the sp register.";
1440 mode
= TAHOE_REG_DISP_DEFERRED
;
1442 op_bad
= "Syntax error in register displaced mode.";
1444 else if (really_none
)
1447 mode
= TAHOE_REG_DEFERRED
;
1448 /* if reg = SP then cant be indexed */
1453 mode
= TAHOE_REG_DISP
;
1456 /* We know: imm = -1, dec_inc == ' ', Reg = -1 */
1461 op_bad
= "An offest is needed for this operand.";
1462 if (deferred
&& immediate
)
1465 mode
= TAHOE_ABSOLUTE_ADDR
;
1471 mode
= TAHOE_IMMEDIATE
;
1473 op_bad
= "You can't index a register in immediate mode.";
1475 op_bad
= "Immediate access can't be used as an address.";
1476 /* ponder the wisdom of a cast because it doesn't do any good. */
1481 mode
= TAHOE_DISP_REL_DEFERRED
;
1486 mode
= TAHOE_DISPLACED_RELATIVE
;
1492 * At this point, all the errors we can do have be checked for.
1493 * We can build the 'top'. */
1495 topP
->top_ndx
= ndx
;
1496 topP
->top_reg
= reg
;
1497 topP
->top_mode
= mode
;
1498 topP
->top_error
= op_bad
;
1499 topP
->top_dispsize
= disp_size
;
1505 * This converts a string into a tahoe instruction.
1506 * The string must be a bare single instruction in tahoe (with BSD4 frobs)
1508 * It provides at most one fatal error message (which stops the scan)
1509 * some warning messages as it finds them.
1510 * The tahoe instruction is returned in exploded form.
1512 * The exploded instruction is returned to a struct tit of your choice.
1513 * #include "tahoe-inst.h" to know what a struct tit is.
1518 tip (titP
, instring
)
1519 struct tit
*titP
; /* We build an exploded instruction here. */
1520 char *instring
; /* Text of a vax instruction: we modify. */
1522 register struct tot_wot
*twP
= NULL
; /* How to bit-encode this opcode. */
1523 register char *p
; /* 1/skip whitespace.2/scan vot_how */
1524 register char *q
; /* */
1525 register unsigned char count
; /* counts number of operands seen */
1526 register struct top
*operandp
;/* scan operands in struct tit */
1527 register char *alloperr
= ""; /* error over all operands */
1528 register char c
; /* Remember char, (we clobber it
1529 with '\0' temporarily). */
1530 char *save_input_line_pointer
;
1532 if (*instring
== ' ')
1533 ++instring
; /* Skip leading whitespace. */
1534 for (p
= instring
; *p
&& *p
!= ' '; p
++)
1535 ; /* MUST end in end-of-string or
1537 /* Scanned up to end of operation-code. */
1538 /* Operation-code is ended with whitespace. */
1541 titP
->tit_error
= "No operator";
1543 titP
->tit_opcode
= 0;
1550 * Here with instring pointing to what better be an op-name, and p
1551 * pointing to character just past that.
1552 * We trust instring points to an op-name, with no whitespace.
1554 twP
= (struct tot_wot
*) hash_find (op_hash
, instring
);
1555 *p
= c
; /* Restore char after op-code. */
1558 titP
->tit_error
= "Unknown operator";
1560 titP
->tit_opcode
= 0;
1565 * We found a match! So lets pick up as many operands as the
1566 * instruction wants, and even gripe if there are too many.
1567 * We expect comma to seperate each operand.
1568 * We let instring track the text, while p tracks a part of the
1572 count
= 0; /* no operands seen yet */
1573 instring
= p
+ (*p
!= '\0'); /* point past the operation code */
1574 /* tip_op() screws with the input_line_pointer, so save it before
1576 save_input_line_pointer
= input_line_pointer
;
1577 for (p
= twP
->args
, operandp
= titP
->tit_operand
;
1582 * Here to parse one operand. Leave instring pointing just
1583 * past any one ',' that marks the end of this operand.
1586 as_fatal ("Compiler bug: ODD number of bytes in arg structure %s.",
1590 for (q
= instring
; (*q
!= ',' && *q
!= '\0'); q
++)
1592 if (*q
== '\'' && q
[1] != '\0') /* Jump quoted characters */
1597 * Q points to ',' or '\0' that ends argument. C is that
1601 operandp
->top_access
= p
[0];
1602 operandp
->top_width
= p
[1];
1603 tip_op (instring
- 1, operandp
);
1604 *q
= c
; /* Restore input text. */
1605 if (*(operandp
->top_error
))
1607 alloperr
= operandp
->top_error
;
1609 instring
= q
+ (c
? 1 : 0); /* next operand (if any) */
1610 count
++; /* won another argument, may have an operr */
1613 alloperr
= "Not enough operands";
1615 /* Restore the pointer. */
1616 input_line_pointer
= save_input_line_pointer
;
1620 if (*instring
== ' ')
1621 instring
++; /* Skip whitespace. */
1623 alloperr
= "Too many operands";
1625 titP
->tit_error
= alloperr
;
1629 titP
->tit_opcode
= twP
->code
; /* The op-code. */
1630 titP
->tit_operands
= count
;
1633 /* md_assemble() emit frags for 1 instruction */
1635 md_assemble (instruction_string
)
1636 char *instruction_string
; /* A string: assemble 1 instruction. */
1639 register struct top
*operandP
;/* An operand. Scans all operands. */
1640 /* char c_save; fixme: remove this line *//* What used to live after an expression. */
1641 /* struct frag *fragP; fixme: remove this line *//* Fragment of code we just made. */
1642 /* register struct top *end_operandP; fixme: remove this line *//* -> slot just after last operand
1643 Limit of the for (each operand). */
1644 register expressionS
*expP
; /* -> expression values for this operand */
1646 /* These refer to an instruction operand expression. */
1647 segT to_seg
; /* Target segment of the address. */
1649 register valueT this_add_number
;
1650 register struct symbol
*this_add_symbol
; /* +ve (minuend) symbol. */
1652 /* tahoe_opcodeT opcode_as_number; fixme: remove this line *//* The opcode as a number. */
1653 char *opcodeP
; /* Where it is in a frag. */
1654 /* char *opmodeP; fixme: remove this line *//* Where opcode type is, in a frag. */
1656 int dispsize
; /* From top_dispsize: tahoe_operand_width
1658 int is_undefined
; /* 1 if operand expression's
1659 segment not known yet. */
1660 int pc_rel
; /* Is this operand pc relative? */
1662 /* Decode the operand. */
1663 tip (&t
, instruction_string
);
1666 * Check to see if this operand decode properly.
1667 * Notice that we haven't made any frags yet.
1668 * If it goofed, then this instruction will wedge in any pass,
1669 * and we can safely flush it, without causing interpass symbol phase
1670 * errors. That is, without changing label values in different passes.
1674 as_warn ("Ignoring statement due to \"%s\"", t
.tit_error
);
1678 /* We saw no errors in any operands - try to make frag(s) */
1680 /* Remember where it is, in case we want to modify the op-code later. */
1681 opcodeP
= frag_more (1);
1682 *opcodeP
= t
.tit_opcode
;
1683 /* Now do each operand. */
1684 for (operandP
= t
.tit_operand
;
1685 operandP
< t
.tit_operand
+ t
.tit_operands
;
1687 { /* for each operand */
1688 expP
= &(operandP
->exp_of_operand
);
1689 if (operandP
->top_ndx
>= 0)
1691 /* Indexed addressing byte
1692 Legality of indexed mode already checked: it is OK */
1693 FRAG_APPEND_1_CHAR (0x40 + operandP
->top_ndx
);
1694 } /* if(top_ndx>=0) */
1696 /* Here to make main operand frag(s). */
1697 this_add_number
= expP
->X_add_number
;
1698 this_add_symbol
= expP
->X_add_symbol
;
1699 to_seg
= operandP
->seg_of_operand
;
1700 know (to_seg
== SEG_UNKNOWN
|| \
1701 to_seg
== SEG_ABSOLUTE
|| \
1702 to_seg
== SEG_DATA
|| \
1703 to_seg
== SEG_TEXT
|| \
1705 is_undefined
= (to_seg
== SEG_UNKNOWN
);
1706 /* Do we know how big this opperand is? */
1707 dispsize
= operandP
->top_dispsize
;
1709 /* Deal with the branch possabilities. (Note, this doesn't include
1711 if (operandP
->top_access
== 'b')
1713 /* Branches must be expressions. A psuedo branch can also jump to
1714 an absolute address. */
1715 if (to_seg
== now_seg
|| is_undefined
)
1717 /* If is_undefined, then it might BECOME now_seg by relax time. */
1720 /* I know how big the branch is supposed to be (it's a normal
1721 branch), so I set up the frag, and let GAS do the rest. */
1722 p
= frag_more (dispsize
);
1723 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1724 this_add_symbol
, this_add_number
,
1725 size_to_fx (dispsize
, 1),
1730 /* (to_seg==now_seg || to_seg == SEG_UNKNOWN) && dispsize==0 */
1731 /* If we don't know how big it is, then its a synthetic branch,
1732 so we set up a simple relax state. */
1733 switch (operandP
->top_width
)
1735 case TAHOE_WIDTH_CONDITIONAL_JUMP
:
1736 /* Simple (conditional) jump. I may have to reverse the
1737 condition of opcodeP, and then jump to my destination.
1738 I set 1 byte aside for the branch off set, and could need 6
1739 more bytes for the pc_rel jump */
1740 frag_var (rs_machine_dependent
, 7, 1,
1741 ENCODE_RELAX (STATE_CONDITIONAL_BRANCH
,
1742 is_undefined
? STATE_UNDF
: STATE_BYTE
),
1743 this_add_symbol
, this_add_number
, opcodeP
);
1745 case TAHOE_WIDTH_ALWAYS_JUMP
:
1746 /* Simple (unconditional) jump. I may have to convert this to
1747 a word branch, or an absolute jump. */
1748 frag_var (rs_machine_dependent
, 5, 1,
1749 ENCODE_RELAX (STATE_ALWAYS_BRANCH
,
1750 is_undefined
? STATE_UNDF
: STATE_BYTE
),
1751 this_add_symbol
, this_add_number
, opcodeP
);
1753 /* The smallest size for the next 2 cases is word. */
1754 case TAHOE_WIDTH_BIG_REV_JUMP
:
1755 frag_var (rs_machine_dependent
, 8, 2,
1756 ENCODE_RELAX (STATE_BIG_REV_BRANCH
,
1757 is_undefined
? STATE_UNDF
: STATE_WORD
),
1758 this_add_symbol
, this_add_number
,
1761 case TAHOE_WIDTH_BIG_NON_REV_JUMP
:
1762 frag_var (rs_machine_dependent
, 10, 2,
1763 ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH
,
1764 is_undefined
? STATE_UNDF
: STATE_WORD
),
1765 this_add_symbol
, this_add_number
,
1769 as_fatal ("Compliler bug: Got a case (%d) I wasn't expecting.",
1770 operandP
->top_width
);
1776 /* to_seg != now_seg && to_seg != seg_unknown (still in branch)
1777 In other words, I'm jumping out of my segment so extend the
1778 branches to jumps, and let GAS fix them. */
1780 /* These are "branches" what will always be branches around a jump
1781 to the correct addresss in real life.
1782 If to_seg is SEG_ABSOLUTE, just encode the branch in,
1783 else let GAS fix the address. */
1785 switch (operandP
->top_width
)
1788 For SEG_ABSOLUTE, then mode is ABSOLUTE_ADDR, jump
1789 to that addresss (not pc_rel).
1790 For other segs, address is a long word PC rel jump. */
1791 case TAHOE_WIDTH_CONDITIONAL_JUMP
:
1793 /* To reverse the condition in a TAHOE branch,
1799 *p
++ = (operandP
->top_mode
==
1800 TAHOE_ABSOLUTE_ADDR
? TAHOE_ABSOLUTE_ADDR
:
1802 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1803 this_add_symbol
, this_add_number
,
1804 (to_seg
!= SEG_ABSOLUTE
) ? FX_PCREL32
: FX_32
, NULL
);
1811 case TAHOE_WIDTH_ALWAYS_JUMP
:
1812 /* br, just turn it into a jump */
1813 *opcodeP
= TAHOE_JMP
;
1815 *p
++ = (operandP
->top_mode
==
1816 TAHOE_ABSOLUTE_ADDR
? TAHOE_ABSOLUTE_ADDR
:
1818 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1819 this_add_symbol
, this_add_number
,
1820 (to_seg
!= SEG_ABSOLUTE
) ? FX_PCREL32
: FX_32
, NULL
);
1821 /* Now (eg) JMP foo */
1823 case TAHOE_WIDTH_BIG_REV_JUMP
:
1829 *p
++ = (operandP
->top_mode
==
1830 TAHOE_ABSOLUTE_ADDR
? TAHOE_ABSOLUTE_ADDR
:
1832 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1833 this_add_symbol
, this_add_number
,
1834 (to_seg
!= SEG_ABSOLUTE
) ? FX_PCREL32
: FX_32
, NULL
);
1841 case TAHOE_WIDTH_BIG_NON_REV_JUMP
:
1848 *p
++ = (operandP
->top_mode
==
1849 TAHOE_ABSOLUTE_ADDR
? TAHOE_ABSOLUTE_ADDR
:
1851 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1852 this_add_symbol
, this_add_number
,
1853 (to_seg
!= SEG_ABSOLUTE
) ? FX_PCREL32
: FX_32
, NULL
);
1855 * Now (eg) xOBxxx 1f
1863 as_warn ("Real branch displacements must be expressions.");
1866 as_fatal ("Complier error: I got an unknown synthetic branch :%c",
1867 operandP
->top_width
);
1874 /* It ain't a branch operand. */
1875 switch (operandP
->top_mode
)
1877 /* Auto-foo access, only works for one reg (SP)
1878 so the only thing needed is the mode. */
1879 case TAHOE_AUTO_DEC
:
1880 case TAHOE_AUTO_INC
:
1881 case TAHOE_AUTO_INC_DEFERRED
:
1882 FRAG_APPEND_1_CHAR (operandP
->top_mode
);
1885 /* Numbered Register only access. Only thing needed is the
1886 mode + Register number */
1887 case TAHOE_DIRECT_REG
:
1888 case TAHOE_REG_DEFERRED
:
1889 FRAG_APPEND_1_CHAR (operandP
->top_mode
+ operandP
->top_reg
);
1892 /* An absolute address. It's size is always 5 bytes.
1893 (mode_type + 4 byte address). */
1894 case TAHOE_ABSOLUTE_ADDR
:
1895 know ((this_add_symbol
== NULL
));
1897 *p
= TAHOE_ABSOLUTE_ADDR
;
1898 md_number_to_chars (p
+ 1, this_add_number
, 4);
1901 /* Immediate data. If the size isn't known, then it's an address
1902 + and offset, which is 4 bytes big. */
1903 case TAHOE_IMMEDIATE
:
1904 if (this_add_symbol
!= NULL
)
1907 *p
++ = TAHOE_IMMEDIATE_LONGWORD
;
1908 fix_new (frag_now
, p
- frag_now
->fr_literal
,
1909 this_add_symbol
, this_add_number
,
1914 /* It's a integer, and I know it's size. */
1915 if ((unsigned) this_add_number
< 0x40)
1917 /* Will it fit in a literal? */
1918 FRAG_APPEND_1_CHAR ((byte
) this_add_number
);
1922 p
= frag_more (dispsize
+ 1);
1926 *p
++ = TAHOE_IMMEDIATE_BYTE
;
1927 *p
= (byte
) this_add_number
;
1930 *p
++ = TAHOE_IMMEDIATE_WORD
;
1931 md_number_to_chars (p
, this_add_number
, 2);
1934 *p
++ = TAHOE_IMMEDIATE_LONGWORD
;
1935 md_number_to_chars (p
, this_add_number
, 4);
1942 /* Distance from the PC. If the size isn't known, we have to relax
1943 into it. The difference between this and disp(sp) is that
1944 this offset is pc_rel, and disp(sp) isn't.
1945 Note the drop through code. */
1947 case TAHOE_DISPLACED_RELATIVE
:
1948 case TAHOE_DISP_REL_DEFERRED
:
1949 operandP
->top_reg
= PC_REG
;
1952 /* Register, plus a displacement mode. Save the register number,
1953 and weather its deffered or not, and relax the size if it isn't
1955 case TAHOE_REG_DISP
:
1956 case TAHOE_REG_DISP_DEFERRED
:
1957 if (operandP
->top_mode
== TAHOE_DISP_REL_DEFERRED
||
1958 operandP
->top_mode
== TAHOE_REG_DISP_DEFERRED
)
1959 operandP
->top_reg
+= 0x10; /* deffered mode is always 0x10 higher
1960 than it's non-deffered sibling. */
1962 /* Is this a value out of this segment?
1963 The first part of this conditional is a cludge to make gas
1964 produce the same output as 'as' when there is a lable, in
1965 the current segment, displaceing a register. It's strange,
1966 and no one in their right mind would do it, but it's easy
1968 if ((dispsize
== 0 && !pc_rel
) ||
1969 (to_seg
!= now_seg
&& !is_undefined
&& to_seg
!= SEG_ABSOLUTE
))
1975 * We have a SEG_UNKNOWN symbol, or the size isn't cast.
1976 * It might turn out to be in the same segment as
1977 * the instruction, permitting relaxation.
1979 p
= frag_var (rs_machine_dependent
, 5, 2,
1980 ENCODE_RELAX (STATE_PC_RELATIVE
,
1981 is_undefined
? STATE_UNDF
: STATE_BYTE
),
1982 this_add_symbol
, this_add_number
, 0);
1983 *p
= operandP
->top_reg
;
1987 /* Either this is an abs, or a cast. */
1988 p
= frag_more (dispsize
+ 1);
1992 *p
= TAHOE_PC_OR_BYTE
+ operandP
->top_reg
;
1995 *p
= TAHOE_PC_OR_WORD
+ operandP
->top_reg
;
1998 *p
= TAHOE_PC_OR_LONG
+ operandP
->top_reg
;
2001 fix_new (frag_now
, p
+ 1 - frag_now
->fr_literal
,
2002 this_add_symbol
, this_add_number
,
2003 size_to_fx (dispsize
, pc_rel
), NULL
);
2007 as_fatal ("Barf, bad mode %x\n", operandP
->top_mode
);
2010 } /* for(operandP) */
2011 } /* if(!need_pass_2 && !goofed) */
2012 } /* tahoe_assemble() */
2015 /* We have no need to default values of symbols. */
2019 md_undefined_symbol (name
)
2023 } /* md_undefined_symbol() */
2025 /* Parse an operand that is machine-specific.
2026 We just return without modifying the expression if we have nothing
2031 md_operand (expressionP
)
2032 expressionS
*expressionP
;
2034 } /* md_operand() */
2036 /* Round up a section size to the appropriate boundary. */
2038 md_section_align (segment
, size
)
2042 return ((size
+ 7) & ~7); /* Round all sects to multiple of 8 */
2043 } /* md_section_align() */
2045 /* Exactly what point is a PC-relative offset relative TO?
2046 On the sparc, they're relative to the address of the offset, plus
2047 its size. This gets us to the following instruction.
2048 (??? Is this right? FIXME-SOON) */
2050 md_pcrel_from (fixP
)
2053 return (((fixP
->fx_type
== FX_8
2054 || fixP
->fx_type
== FX_PCREL8
)
2056 : ((fixP
->fx_type
== FX_16
2057 || fixP
->fx_type
== FX_PCREL16
)
2059 : ((fixP
->fx_type
== FX_32
2060 || fixP
->fx_type
== FX_PCREL32
)
2062 : 0))) + fixP
->fx_where
+ fixP
->fx_frag
->fr_address
);
2063 } /* md_pcrel_from() */
2069 /* should never be called */
2072 } /* tc_is_pcrel() */
2074 /* end of tc-tahoe.c */