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