Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / sdas / asxxsrc / asout.c
blobdb03696b4fab84eacbb9b5b6e0600ac16a6931c5
1 /* asout.c */
3 /*
4 * Copyright (C) 1989-2021 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
27 * 28-Oct-97 JLH:
28 * - outsym: show s_id as string rather than array [NCPS]
29 * - Added outr11 to support 8051's 11 bit destination address
32 #include "sdas.h"
33 #include "asxxxx.h"
36 /*)Module asout.c
38 * The module asout.c contains all the functions used to
39 * generate the .REL assembler output file.
42 * The assemblers' output object file is an ascii file containing
43 * the information needed by the linker to bind multiple object
44 * modules into a complete loadable memory image.
46 * The object module contains the following designators:
48 * [XDQ][HL][234]
49 * X Hexadecimal radix
50 * D Decimal radix
51 * Q Octal radix
53 * H Most significant byte first
54 * L Least significant byte first
56 * 2 16-Bit Relocatable Addresses/Data
57 * 3 24-Bit Relocatable Addresses/Data
58 * 4 32-Bit Relocatable Addresses/Data
60 * H Header
61 * M Module
62 * A Area
63 * S Symbol
64 * T Object code
65 * R Relocation information
66 * P Paging information
69 * (1) Radix Line
71 * The first line of an object module contains the [XDQ][HL][234]
72 * format specifier (i.e. XH2 indicates a hexadecimal file with
73 * most significant byte first and 16-bit addresses) for the
74 * following designators.
77 * (2) Header Line
79 * H aa areas gg global symbols
81 * The header line specifies the number of areas(aa) and the
82 * number of global symbols(gg) defined or referenced in this ob-
83 * ject module segment.
86 * (3) Module Line
88 * M name
90 * The module line specifies the module name from which this
91 * header segment was assembled. The module line will not appear
92 * if the .module directive was not used in the source program.
95 * (4) Symbol Line
97 * S string Defnnnn
99 * or
101 * S string Refnnnn
103 * The symbol line defines (Def) or references (Ref) the symbol
104 * 'string' with the value nnnn. The defined value is relative to
105 * the current area base address. References to constants and ex-
106 * ternal global symbols will always appear before the first area
107 * definition. References to external symbols will have a value of
108 * zero.
111 * (5) Area Line
113 * A label size ss flags ff
115 * The area line defines the area label, the size (ss) of the
116 * area in bytes, and the area flags (ff). The area flags
117 * specify the area properties:
119 * OVR/CON (0x04/0x00 i.e. bit position 2)
120 * ABS/REL (0x08/0x00 i.e. bit position 3)
121 * PAG (0x10 i.e. bit position 4)
124 * (6) T Line
126 * T xx xx nn nn nn nn nn ...
128 * The T line contains the assembled code output by the assem-
129 * bler with xx xx being the offset address from the current area
130 * base address and nn being the assembled instructions and data in
131 * byte format.
134 * (7) R Line
136 * R 0 0 nn nn n1 n2 xx xx ...
138 * The R line provides the relocation information to the linker.
139 * The nn nn value is the current area index, i.e. which area the
140 * current values were assembled. Relocation information is en-
141 * coded in groups of 4 bytes:
143 * 1. n1 is the relocation mode and object format
144 * 1. bit 0 word(0x00)/byte(0x01)
145 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
146 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
147 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
148 * byte data
149 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
150 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
151 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
152 * 8. bit 7 normal(0x00)/MSB of value
154 * 2. n2 is a byte index into the corresponding
155 * (i.e. preceeding) T line data (i.e. a pointer to
156 * the data to be updated by the relocation).
157 * The T line data may be 1-byte or 2-byte byte data
158 * format or 2-byte word format.
160 * 3. xx xx is the area/symbol index for the area/symbol be-
161 * ing referenced. the corresponding area/symbol is found
162 * in the header area/symbol lists.
165 * The groups of 4 bytes are repeated for each item requiring relo-
166 * cation in the preceeding T line.
169 * (8) P Line
171 * P 0 0 nn nn n1 n2 xx xx
173 * The P line provides the paging information to the linker as
174 * specified by a .setdp directive. The format of the relocation
175 * information is identical to that of the R line. The correspond-
176 * ing T line has the following information:
177 * T xx xx aa aa bb bb
179 * Where aa aa is the area reference number which specifies the
180 * selected page area and bb bb is the base address of the page.
181 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
182 * specified in the P line. The linker will verify that the base
183 * address is on a 256 byte boundary and that the page length of an
184 * area defined with the PAG type is not larger than 256 bytes.
186 * The linker defaults any direct page references to the first
187 * area defined in the input REL file. All ASxxxx assemblers will
188 * specify the _CODE area first, making this the default page area.
191 * asout.c contains the following functions:
192 * int lobyte()
193 * int hibyte()
194 * int thrdbyte()
195 * int frthbyte()
196 * VOID out()
197 * VOID outall()
198 * VOID outarea()
199 * VOID outbuf()
200 * VOID outchk()
201 * VOID outdp()
202 * VOID outdot()
203 * VOID outgsd()
204 * VOID outsym()
205 * VOID outab()
206 * VOID outaw()
207 * VOID outa3b()
208 * VOID outa4b()
209 * VOID outaxb()
210 * VOID outatxb()
211 * VOID outrb()
212 * VOID outrw()
213 * VOID outr11()
214 * VOID out_lb()
215 * VOID out_lw()
216 * VOID out_l3b()
217 * VOID out_l4b()
218 * VOID out_lxb()
219 * VOID out_txb()
222 /*)Function VOID outab(v)
223 *)Function VOID outaw(v)
224 *)Function VOID outa3b(v)
225 *)Function VOID outa4b(v)
227 * a_uint v assembler data
229 * Dispatch to output routine of 1 to 4 absolute bytes.
231 * local variables:
232 * none
234 * global variables:
235 * none
237 * functions called:
238 * VOID outaxb() asout.c
240 * side effects:
241 * Absolute data is processed.
244 VOID
245 outab(a_uint v)
247 outaxb(1, v);
250 VOID
251 outaw(a_uint v)
253 outaxb(2, v);
256 VOID
257 outa3b(a_uint v)
259 outaxb(3, v);
262 VOID
263 outa4b(a_uint v)
265 outaxb(4, v);
268 /*)Function VOID outaxb(i, v)
270 * int i output byte count
271 * a_uint v assembler data
273 * The function outaxb() processes 1 to 4 bytes of
274 * assembled data in absolute format.
276 * local variables:
277 * int p_bytes
279 * global variables:
280 * sym dot defined as sym[0]
281 * int oflag -o, generate relocatable output flag
282 * int pass assembler pass number
284 * functions called:
285 * VOID outatxb() asout.c
286 * VOID outchk() asout.c
287 * VOID out_lxb() asout.c
289 * side effects:
290 * The current assembly address is incremented by i.
293 VOID
294 outaxb(int i, a_uint v)
296 int p_bytes;
298 if (pass == 2) {
299 out_lxb(i, v, 0);
300 if (oflag) {
301 outchk(i, 0);
302 outatxb(i, v);
306 * Update the Program Counter
308 p_bytes = 1;
309 dot.s_addr += (i/p_bytes) + (i % p_bytes ? 1 : 0);
312 /* sdas specific */
313 /*)Function VOID write_rmode(r, n)
315 * int r relocation mode
316 * int n byte index
318 * write_rmode puts the passed relocation mode into the
319 * output relp buffer, escaping it if necessary.
321 * global variables:
322 * char * relp Pointer to R Line Values
324 * functions called:
325 * VOID rerr() assubr.c
327 * side effects:
328 * relp is incremented appropriately.
330 VOID
331 write_rmode(int r, int n)
333 /* We need to escape the relocation mode if it is greater
334 * than a byte, or if it happens to look like an escape.
335 * (I don't think that the latter case is legal, but
336 * better safe than sorry).
338 if ((r > 0xff) || ((r & R_ESCAPE_MASK) == R_ESCAPE_MASK))
340 /* Hack in up to an extra 4 bits of flags with escape. */
341 if (r > 0xfff)
343 /* uh-oh.. we have more than 4 extra bits. */
344 fprintf(stderr,
345 "Internal error: relocation mode 0x%X too big.\n",
347 rerr();
349 /* printf("escaping relocation mode\n"); */
350 *relp++ = R_ESCAPE_MASK | (r >> 8);
351 *relp++ = r & 0xff;
353 else
355 *relp++ = r;
357 *relp++ = n;
359 /* end sdas specific */
361 /*)Function VOID outatxb(i, v)
363 * int i number of bytes to process
364 * a_uint v assembler data
366 * The function outatxb() outputs i bytes
368 * local variables:
369 * none
371 * global variables:
372 * int hilo byte order
373 * char * txtp Pointer to T Line Values
375 * functions called:
376 * int lobyte() asout.c
377 * int hibyte() asout.c
378 * int thrdbyte() asout.c
379 * int frthbyte() asout.c
381 * side effects:
382 * i bytes are placed into the T Line Buffer.
385 VOID
386 outatxb(int i, a_uint v)
388 if ((int) hilo) {
389 if (i >= 4) *txtp++ = frthbyte(v);
390 if (i >= 3) *txtp++ = thrdbyte(v);
391 if (i >= 2) *txtp++ = hibyte(v);
392 if (i >= 1) *txtp++ = lobyte(v);
393 } else {
394 if (i >= 1) *txtp++ = lobyte(v);
395 if (i >= 2) *txtp++ = hibyte(v);
396 if (i >= 3) *txtp++ = thrdbyte(v);
397 if (i >= 4) *txtp++ = frthbyte(v);
401 /*)Function VOID outrb(esp, r)
403 * expr * esp pointer to expr structure
404 * int r relocation mode
406 * Dispatch functions for processing relocatable data.
408 * local variables:
409 * none
411 * global variables:
412 * none
414 * functions called:
415 * int outrxb() asout.c
417 * side effects:
418 * relocatable data processed
421 VOID
422 outrb(struct expr *esp, int r)
424 outrxb(1, esp, r);
428 /*)Function VOID outrxb(i, esp, r)
430 * int i output byte count
431 * expr * esp pointer to expr structure
432 * int r relocation mode
434 * The function outrxb() processes 1 to 4 bytes of generated code
435 * in either absolute or relocatable format dependent upon
436 * the data contained in the expr structure esp. If the
437 * .REL output is enabled then the appropriate information
438 * is loaded into the txt and rel buffers.
440 * local variables:
441 * int m signed value mask
442 * int n unsigned value mask
443 * symbol/area reference number
445 * global variables:
446 * int a_bytes T Line byte count
447 * sym dot defined as sym[0]
448 * int oflag -o, generate relocatable output flag
449 * int pass assembler pass number
450 * char * relp Pointer to R Line Values
451 * char * txtp Pointer to T Line Values
453 * functions called:
454 * VOID outchk() asout.c
455 * VOID out_lb() asout.c
456 * VOID out_rb() asout.c
457 * VOID out_tb() asout.c
459 * side effects:
460 * R and T Lines updated. Listing updated.
461 * The current assembly address is incremented by i.
464 VOID
465 outrxb(int i, struct expr *esp, int r)
467 a_uint m, n;
468 int p_bytes;
470 if (pass == 2) {
471 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
472 /* This is a constant; simply write the
473 * const byte to the T line and don't
474 * generate any relocation info.
477 * Mask Value Selection
479 #ifdef LONGINT
480 switch(i) {
481 default:
482 case 1: m = (a_uint) ~0x0000007Fl; n = (a_uint) ~0x000000FFl; break; /* 1 byte */
483 case 2: m = (a_uint) ~0x00007FFFl; n = (a_uint) ~0x0000FFFFl; break; /* 2 bytes */
484 case 3: m = (a_uint) ~0x007FFFFFl; n = (a_uint) ~0x00FFFFFFl; break; /* 3 bytes */
485 case 4: m = (a_uint) ~0x7FFFFFFFl; n = (a_uint) ~0xFFFFFFFFl; break; /* 4 bytes */
487 #else
488 switch(i) {
489 default:
490 case 1: m = (a_uint) ~0x0000007F; n = (a_uint) ~0x000000FF; break; /* 1 byte */
491 case 2: m = (a_uint) ~0x00007FFF; n = (a_uint) ~0x0000FFFF; break; /* 2 bytes */
492 case 3: m = (a_uint) ~0x007FFFFF; n = (a_uint) ~0x00FFFFFF; break; /* 3 bytes */
493 case 4: m = (a_uint) ~0x7FFFFFFF; n = (a_uint) ~0xFFFFFFFF; break; /* 4 bytes */
495 #endif
497 * Signed Range Check
499 (void)m; //temporary fix warning
502 * Page0 Range Check
504 if (((r & (R_SGND | R_USGN | R_PAGX | R_PCR)) == R_PAG0) &&
505 ((n & esp->e_addr) != 0))
506 xerr('d', "Page 0 Address Error.");
508 out_lxb(i,esp->e_addr,0);
509 if (oflag) {
510 outchk(i,0);
511 outatxb(i,esp->e_addr);
513 } else {
514 if ((i == 1) && (!is_sdas() || !(is_sdas_target_8051_like() || is_sdas_target_stm8()))) {
515 r |= R_BYTE | R_BYTX | esp->e_rlcf;
516 if (r & R_MSB) {
517 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
518 } else {
519 out_lb(lobyte(esp->e_addr),r|R_RELOC);
521 if (oflag) {
522 outchk(a_bytes, 4);
523 out_txb(a_bytes, esp->e_addr);
524 if (esp->e_flag) {
525 n = esp->e_base.e_sp->s_ref;
526 r |= R_SYM;
527 } else {
528 n = esp->e_base.e_ap->a_ref;
530 *relp++ = r;
531 *relp++ = txtp - txt - a_bytes;
532 out_rw(n);
534 } else {
535 /* sdas mcs51 specific */
536 /* We are generating a single byte of relocatable
537 * info.
539 * We generate a 24 bit address. The linker will
540 * select a single byte based on whether R_MSB or
541 * R_HIB is set.
543 /* 24 bit mode. */
544 r |= R_BYTE | R_BYT3 | esp->e_rlcf;
545 if (r & R_HIB)
547 /* Probably should mark this differently in the
548 * listing file.
550 out_lb(thrdbyte(esp->e_addr),r|R_RELOC|R_HIGH);
552 else if (r & R_MSB) {
553 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
554 } else {
555 out_lb(lobyte(esp->e_addr),r|R_RELOC);
557 if (oflag) {
558 outchk(a_bytes, 5);
559 out_txb(a_bytes, esp->e_addr);
560 if (esp->e_flag) {
561 n = esp->e_base.e_sp->s_ref;
562 r |= R_SYM;
563 } else {
564 n = esp->e_base.e_ap->a_ref;
566 write_rmode(r, txtp - txt - a_bytes);
567 out_rw(n);
569 /* end sdas mcs51 specific */
574 * Update the Program Counter
576 p_bytes = 1;
577 dot.s_addr += (i/p_bytes) + (i % p_bytes ? 1 : 0);
580 /*)Function VOID outrw(esp, r)
582 * expr * esp pointer to expr structure
583 * int r relocation mode
585 * The function outrw() processes a word of generated code
586 * in either absolute or relocatable format dependent upon
587 * the data contained in the expr structure esp. If the
588 * .REL output is enabled then the appropriate information
589 * is loaded into the txt and rel buffers.
591 * local variables:
592 * int n symbol/area reference number
594 * global variables:
595 * sym dot defined as sym[0]
596 * int oflag -o, generate relocatable output flag
597 * int pass assembler pass number
598 * char * relp Pointer to R Line Values
599 * char * txtp Pointer to T Line Values
601 * functions called:
602 * VOID outchk() asout.c
603 * VOID out_lw() asout.c
604 * VOID out_rw() asout.c
605 * VOID out_txb() asout.c
607 * side effects:
608 * The current assembly address is incremented by 2.
611 VOID
612 outrw(struct expr *esp, int r)
614 int n;
616 if (pass == 2) {
617 /* sdas specific */
618 if (is_sdas() && is_sdas_target_8051_like() && esp->e_addr > 0xffff) {
619 warnBanner();
620 fprintf(stderr,
621 "large constant 0x%x truncated to 16 bits\n",
622 esp->e_addr);
624 /* end sdas specific */
625 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
626 out_lxb(2,esp->e_addr,0);
627 if (oflag) {
628 outchk(2,0);
629 out_txb(2,esp->e_addr);
631 } else {
632 r |= R_WORD | esp->e_rlcf;
633 if (r & R_BYTX) {
634 rerr();
635 if (r & R_MSB) {
636 out_lw(hibyte(esp->e_addr),r|R_RELOC);
637 } else {
638 out_lw(lobyte(esp->e_addr),r|R_RELOC);
640 } else {
641 out_lw(esp->e_addr,r|R_RELOC);
643 if (oflag) {
644 if (!is_sdas() || !(is_sdas_target_8051_like() || is_sdas_target_stm8())) {
645 outchk(2, 4);
646 out_txb(2, esp->e_addr);
647 if (esp->e_flag) {
648 n = esp->e_base.e_sp->s_ref;
649 r |= R_SYM;
650 } else {
651 n = esp->e_base.e_ap->a_ref;
653 *relp++ = r;
654 *relp++ = txtp - txt - 2;
655 out_rw(n);
656 } else {
657 outchk(2, 5);
658 out_txb(2, esp->e_addr);
659 if (esp->e_flag) {
660 n = esp->e_base.e_sp->s_ref;
661 r |= R_SYM;
662 } else {
663 n = esp->e_base.e_ap->a_ref;
666 if (IS_C24(r))
668 /* If this happens, the linker will
669 * attempt to process this 16 bit field
670 * as 24 bits. That would be bad.
672 fprintf(stderr,
673 "***Internal error: C24 out in "
674 "outrw()\n");
675 rerr();
677 write_rmode(r, txtp - txt - 2);
678 out_rw(n);
683 dot.s_addr += 2;
686 /*)Function VOID outr3b(esp, r)
688 * expr * esp pointer to expr structure
689 * int r relocation mode
691 * The function outr3b() processes 24 bits of generated code
692 * in either absolute or relocatable format dependent upon
693 * the data contained in the expr structure esp. If the
694 * .REL output is enabled then the appropriate information
695 * is loaded into the txt and rel buffers.
697 * local variables:
698 * int n symbol/area reference number
699 * int esprv merged value
700 * int p_bytes program counter update temporary
702 * global variables:
703 * int a_bytes T Line byte count
704 * sym dot defined as sym[0]
705 * int oflag -o, generate relocatable output flag
706 * int pass assembler pass number
707 * char * relp Pointer to R Line Values
708 * char * txtp Pointer to T Line Values
710 * functions called:
711 * VOID outchk() asout.c
712 * VOID out_lxb() asout.c
713 * VOID out_rw() asout.c
714 * VOID out_txb() asout.c
716 * side effects:
717 * R and T Lines updated. Listing updated.
718 * The current assembly address is incremented by i.
721 VOID
722 outr3b(struct expr *esp, int r)
724 int i = 3;
725 a_uint esprv;
726 int n, p_bytes;
728 if (pass == 2) {
729 esprv = esp->e_addr;
730 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
731 /* This is a constant expression. */
732 out_lxb(i,esprv,0);
733 if (oflag) {
734 outchk(i,0);
735 out_txb(i,esprv);
737 } else {
738 /* This is a symbol. */
739 r |= R_WORD | esp->e_rlcf;
740 if (r & R_BYTX) {
741 /* I have no idea what this case is. */
742 rerr();
743 if (r & R_MSB) {
744 out_lw(hibyte(esprv),r|R_RELOC);
745 } else {
746 out_lw(lobyte(esprv),r|R_RELOC);
748 } else {
749 out_lxb(i,esprv,r|R_RELOC);
751 if (oflag) {
752 outchk(2*a_bytes, 5);
753 out_txb(a_bytes, esp->e_addr);
754 if (esp->e_flag) {
755 n = esp->e_base.e_sp->s_ref;
756 r |= R_SYM;
757 } else {
758 n = esp->e_base.e_ap->a_ref;
761 if (r & R_BYTE)
763 /* If this occurs, we cannot properly
764 * code the relocation data with the
765 * R_C24 flag. This means the linker
766 * will fail to do the 24 bit relocation.
767 * Which will suck.
769 fprintf(stderr,
770 "***Internal error: BYTE out in 24 "
771 "bit flat mode unexpected.\n");
772 rerr();
775 write_rmode(r | R_C24, txtp - txt - a_bytes);
777 out_rw(n);
782 * Update the Program Counter
784 p_bytes = 1;
785 dot.s_addr += (i/p_bytes) + (i % p_bytes ? 1 : 0);
789 /*)Function VOID outdp(carea, esp, r)
791 * area * carea pointer to current area structure
792 * expr * esp pointer to expr structure
793 * int r optional PAGX relocation coding
795 * The function outdp() flushes the output buffer and
796 * outputs paging information to the .REL file.
798 * local variables:
799 * int n symbol/area reference number
801 * global variables:
802 * int a_bytes T Line byte count
803 * int oflag -o, generate relocatable output flag
804 * int pass assembler pass number
805 * char * relp Pointer to R Line Values
806 * char * txtp Pointer to T Line Values
808 * functions called:
809 * VOID outbuf() asout.c
810 * VOID outchk() asout.c
811 * VOID out_rw() asout.c
812 * VOID out_txb() asout.c
814 * side effects:
815 * Output buffer flushed to .REL file.
816 * Paging information dumped to .REL file.
819 VOID
820 outdp(struct area *carea, struct expr *esp, int r)
822 a_uint n;
824 if (oflag && pass==2) {
825 outchk(ASXHUGE, ASXHUGE);
826 out_txb(a_bytes, carea->a_ref);
827 out_txb(a_bytes, esp->e_addr);
828 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
829 if (esp->e_base.e_ap == NULL) {
830 n = area[1].a_ref;
831 r |= R_AREA;
832 fprintf(stderr, "?ASxxxx-OUTDP-NULL-POINTER error.\n\n");
833 } else
834 if (esp->e_flag) {
835 n = esp->e_base.e_sp->s_ref;
836 r |= R_SYM;
837 } else {
838 n = esp->e_base.e_ap->a_ref;
839 r |= R_AREA;
841 write_rmode(r, txtp - txt - a_bytes);
842 out_rw(n);
844 outbuf("P");
848 /*)Function VOID outall()
850 * The function outall() will output any bufferred assembled
851 * data and relocation information (during pass 2 if the .REL
852 * output has been enabled).
854 * local variables:
855 * none
857 * global variables:
858 * int oflag -o, generate relocatable output flag
859 * int pass assembler pass number
861 * functions called:
862 * VOID outbuf() asout.c
864 * side effects:
865 * assembled data and relocation buffers will be cleared.
868 VOID
869 outall(void)
871 if (oflag && pass==2)
872 outbuf("R");
875 /*)Function VOID outdot()
877 * The function outdot() outputs information about the
878 * current program counter value (during pass 2 if the .REL
879 * output has been enabled).
881 * local variables:
882 * none
884 * global variables:
885 * int oflag -o, generate relocatable output flag
886 * int pass assembler pass number
887 * char rel[] relocation data for code/data array
888 * char * relp Pointer to R Line Values
889 * char txt[] assembled code/data array
890 * char * txtp Pointer to T Line Values
892 * functions called:
893 * int fprintf() c_library
894 * VOID out() asout.c
896 * side effects:
897 * assembled data and relocation buffers will be cleared.
900 VOID
901 outdot(void)
903 if (oflag && pass==2) {
904 fprintf(ofp, "T");
905 out(txt,(int) (txtp-txt));
906 fprintf(ofp, "\n");
907 fprintf(ofp, "R");
908 out(rel,(int) (relp-rel));
909 fprintf(ofp, "\n");
910 txtp = txt;
911 relp = rel;
915 /*)Function outchk(nt, nr)
917 * int nr number of additional relocation words
918 * int nt number of additional data words
920 * The function outchk() checks the data and relocation buffers
921 * for space to insert the nt data words and nr relocation words.
922 * If space is not available then output the current data and
923 * initialize the data buffers to receive the new data.
925 * local variables:
926 * area * ap pointer to an area structure
928 * global variables:
929 * int a_bytes T Line byte count
930 * sym dot defined as sym[0]
931 * char rel[] relocation data for code/data array
932 * char * relp Pointer to R Line Values
933 * char txt[] assembled code/data array
934 * char * txtp Pointer to T Line Values
936 * functions called:
937 * VOID outbuf() asout.c
938 * VOID out_rw() asout.c
939 * VOID out_txb() asout.c
941 * side effects:
942 * Data and relocation buffers may be emptied and initialized.
945 VOID
946 outchk(int nt, int nr)
948 struct area *ap;
950 if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
951 outbuf("R");
953 if (txtp == txt) {
954 out_txb(a_bytes, dot.s_addr);
955 if ((ap = dot.s_area) != NULL) {
956 write_rmode(R_WORD|R_AREA, 0);
957 out_rw(ap->a_ref);
962 /*)Function VOID outbuf(s)
964 * char * s "R" or "P" or ("I" illegal)
966 * The function outbuf() will output any bufferred data
967 * and relocation information to the .REL file. The output
968 * buffer pointers and counters are initialized.
970 * local variables:
971 * none
973 * global variables:
974 * int a_bytes T Line byte count
975 * FILE * ofp relocation output file handle
976 * char rel[] relocation data for code/data array
977 * char * relp Pointer to R Line Values
978 * char txt[] assembled code/data array
979 * char * txtp Pointer to T Line Values
981 * functions called:
982 * int fprintf() c_library
983 * VOID out() asout.c
985 * side effects:
986 * All bufferred data written to .REL file and
987 * buffer pointers and counters initialized.
990 VOID
991 outbuf(char *s)
993 if (txtp > &txt[a_bytes]) {
994 fprintf(ofp, "T");
995 out(txt,(int) (txtp-txt));
996 fprintf(ofp, "\n");
997 fprintf(ofp, "%s", s);
998 out(rel,(int) (relp-rel));
999 fprintf(ofp, "\n");
1001 txtp = txt;
1002 relp = rel;
1005 VOID
1006 outradix()
1008 if (pass < 2)
1009 return;
1012 * Output Radix
1014 if (xflag == 0) {
1015 fprintf(ofp, "X%c%d\n", (int) hilo ? 'H' : 'L', a_bytes);
1016 } else
1017 if (xflag == 1) {
1018 fprintf(ofp, "Q%c%d\n", (int) hilo ? 'H' : 'L', a_bytes);
1019 } else
1020 if (xflag == 2) {
1021 fprintf(ofp, "D%c%d\n", (int) hilo ? 'H' : 'L', a_bytes);
1025 /*)Function VOID outgsd()
1027 * The function outgsd() performs the following:
1028 * (1) outputs the .REL file radix
1029 * (2) outputs the header specifying the number
1030 * of areas and global symbols
1031 * (3) outputs the module name
1032 * (4) set the reference number and output a symbol line
1033 * for all external global variables and absolutes
1034 * (5) output an area name, set reference number and output
1035 * a symbol line for all global relocatables in the area.
1036 * Repeat this proceedure for all areas.
1038 * local variables:
1039 * area * ap pointer to an area structure
1040 * sym * sp pointer to a sym structure
1041 * int i loop counter
1042 * int j loop counter
1043 * int c string character value
1044 * int narea number of code areas
1045 * int nglob number of global symbols
1046 * char * ptr string pointer
1047 * int rn symbol reference number
1049 * global variables:
1050 * int a_bytes T Line byte count
1051 * area * areap pointer to an area structure
1052 * int hilo byte order
1053 * char module[] module name string
1054 * sym * symhash[] array of pointers to NHASH
1055 * linked symbol lists
1056 * int xflag -x, listing radix flag
1058 * functions called:
1059 * int fprintf() c_library
1060 * VOID outarea() asout.c
1061 * VOID outsym() asout.c
1063 * side effects:
1064 * All symbols are given reference numbers, all symbol
1065 * and area information is output to the .REL file.
1068 VOID
1069 outgsd(void)
1071 struct area *ap;
1072 struct sym *sp;
1073 int i, j;
1074 char *ptr;
1075 int narea, nglob, rn;
1078 * Number of areas
1080 narea = areap->a_ref + 1;
1083 * Number of global references/absolutes
1085 nglob = 0;
1086 for (i = 0; i < NHASH; ++i) {
1087 sp = symhash[i];
1088 while (sp) {
1089 if (sp->s_flag&S_GBL)
1090 nglob += 1;
1091 sp = sp->s_sp;
1095 outradix();
1098 * Output number of areas and symbols
1100 if (xflag == 0) {
1101 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
1102 } else
1103 if (xflag == 1) {
1104 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
1105 } else
1106 if (xflag == 2) {
1107 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
1111 * Module name
1113 if (module[0]) {
1114 fprintf(ofp, "M ");
1115 ptr = &module[0];
1116 fprintf(ofp, "%s\n", ptr);
1119 /* sdas specific */
1121 * Sdcc compile options
1123 if (is_sdas() && NULL != optsdcc) fprintf(ofp, "O %s\n", optsdcc);
1124 /* end sdas specific */
1127 * Global references and absolutes.
1129 rn = 0;
1130 for (i=0; i<NHASH; ++i) {
1131 sp = symhash[i];
1132 while (sp) {
1133 if (sp->s_area==NULL && sp->s_flag&S_GBL) {
1134 sp->s_ref = rn++;
1135 outsym(sp);
1137 sp = sp->s_sp;
1142 * Global relocatables.
1144 for (i=0; i<narea; ++i) {
1145 ap = areap;
1146 while (ap->a_ref != i)
1147 ap = ap->a_ap;
1148 outarea(ap);
1149 for (j=0; j<NHASH; ++j) {
1150 sp = symhash[j];
1151 while (sp) {
1152 if (sp->s_area==ap && sp->s_flag&S_GBL) {
1153 sp->s_ref = rn++;
1154 outsym(sp);
1156 sp = sp->s_sp;
1162 /*)Function VOID outarea(ap)
1164 * area * ap pointer to an area structure
1166 * The function outarea() outputs the A line to the .REL
1167 * file. The A line contains the area's name, size,
1168 * and attributes.
1170 * local variables:
1171 * char * frmt pointer to format string
1173 * global variables:
1174 * FILE * ofp relocation output file handle
1175 * int xflag -x, listing radix flag
1177 * functions called:
1178 * int fprintf() c_library
1180 * side effects:
1181 * The A line is sent to the .REL file.
1184 VOID
1185 outarea(struct area *ap)
1187 char * frmt;
1189 fprintf(ofp, "A ");
1190 fprintf(ofp, "%s", &ap->a_id[0]);
1192 switch(xflag) {
1193 default:
1194 case 0: frmt = " size %X flags %X"; break;
1195 case 1: frmt = " size %o flags %o"; break;
1196 case 2: frmt = " size %u flags %u"; break;
1199 fprintf(ofp, frmt, ap->a_size, ap->a_flag);
1200 if (is_sdas()) {
1201 /* sdas specific */
1202 if (xflag == 0) {
1203 fprintf(ofp, " addr %X", ap->a_addr);
1204 } else
1205 if (xflag == 1) {
1206 fprintf(ofp, " addr %o", ap->a_addr);
1207 } else
1208 if (xflag == 2) {
1209 fprintf(ofp, " addr %u", ap->a_addr);
1211 /* end sdas specific */
1213 fprintf(ofp, "\n");
1216 /*)Function VOID outsym(sp)
1218 * sym * sp pointer to a sym structure
1220 * The function outsym() outputs the S line to the .REL
1221 * file. The S line contains the symbols name and whether the
1222 * the symbol is defined or referenced.
1224 * local variables:
1225 * char * frmt pointer to format string
1226 * int s_addr (int) truncated to 2-bytes
1228 * global variables:
1229 * int a_bytes argument size in bytes
1230 * FILE * ofp relocation output file handle
1231 * int xflag -x, listing radix flag
1233 * functions called:
1234 * int fprintf() c_library
1236 * side effects:
1237 * The S line is sent to the .REL file.
1240 VOID
1241 outsym(struct sym *sp)
1243 char *frmt;
1244 a_uint s_addr;
1246 s_addr = sp->s_addr;
1248 fprintf(ofp, "S ");
1249 fprintf(ofp, "%s", &sp->s_id[0]);
1250 fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
1252 #ifdef LONGINT
1253 switch(xflag) {
1254 default:
1255 case 0:
1256 switch(a_bytes) {
1257 default:
1258 case 2: frmt = "%04lX\n"; break;
1259 case 3: frmt = "%06lX\n"; break;
1260 case 4: frmt = "%08lX\n"; break;
1262 break;
1264 case 1:
1265 switch(a_bytes) {
1266 default:
1267 case 2: frmt = "%06lo\n"; break;
1268 case 3: frmt = "%08lo\n"; break;
1269 case 4: frmt = "%011lo\n"; break;
1271 break;
1273 case 2:
1274 switch(a_bytes) {
1275 default:
1276 case 2: frmt = "%05lu\n"; break;
1277 case 3: frmt = "%08lu\n"; break;
1278 case 4: frmt = "%010lu\n"; break;
1280 break;
1282 #else
1283 switch(xflag) {
1284 default:
1285 case 0:
1286 switch(a_bytes) {
1287 default:
1288 case 2: frmt = "%04X\n"; break;
1289 case 3: frmt = "%06X\n"; break;
1290 case 4: frmt = "%08X\n"; break;
1292 break;
1294 case 1:
1295 switch(a_bytes) {
1296 default:
1297 case 2: frmt = "%06o\n"; break;
1298 case 3: frmt = "%08o\n"; break;
1299 case 4: frmt = "%011o\n"; break;
1301 break;
1303 case 2:
1304 switch(a_bytes) {
1305 default:
1306 case 2: frmt = "%05u\n"; break;
1307 case 3: frmt = "%08u\n"; break;
1308 case 4: frmt = "%010u\n"; break;
1310 break;
1312 #endif
1314 fprintf(ofp, frmt, s_addr);
1317 /*)Function VOID out(p, n)
1319 * int n number of words to output
1320 * int * p pointer to data words
1322 * The function out() outputs the data words to the .REL file
1323 * in the specified radix.
1325 * local variables:
1326 * none
1328 * global variables:
1329 * FILE * ofp relocation output file handle
1330 * int xflag -x, listing radix flag
1332 * functions called:
1333 * int fprintf() c_library
1335 * side effects:
1336 * Data is sent to the .REL file.
1339 VOID
1340 out(char *p, int n)
1342 while (n--) {
1343 if (xflag == 0) {
1344 fprintf(ofp, " %02X", (*p++)&0377);
1345 } else
1346 if (xflag == 1) {
1347 fprintf(ofp, " %03o", (*p++)&0377);
1348 } else
1349 if (xflag == 2) {
1350 fprintf(ofp, " %03u", (*p++)&0377);
1355 /*)Function VOID out_lb(v, t)
1357 * a_uint v assembled data
1358 * int t relocation type
1360 * The function out_lb() copies the assembled data and
1361 * its relocation type to the list data buffers.
1363 * local variables:
1364 * none
1366 * global variables:
1367 * int * cp pointer to assembler output array cb[]
1368 * int * cpt pointer to assembler relocation type
1369 * output array cbt[]
1371 * functions called:
1372 * none
1374 * side effects:
1375 * Pointers to data and relocation buffers incremented by 1.
1378 VOID
1379 out_lb(a_uint v, int t)
1381 if (cp < &cb[NCODE]) {
1382 *cp++ = (char) v;
1383 *cpt++ = t;
1387 /*)Function VOID out_lw(v, t)
1388 *)Function VOID out_l3b(v, t)
1389 *)Function VOID out_l4b(v, t)
1391 * a_uint v assembled data
1392 * int t relocation type
1394 * Dispatch functions for processing listing data.
1396 * local variables:
1397 * none
1399 * global variables:
1400 * none
1402 * functions called:
1403 * none
1405 * side effects:
1406 * Listing data processed.
1409 VOID
1410 out_lw(a_uint v, int t)
1412 out_lxb(2, v, t);
1415 VOID
1416 out_l3b(a_uint v, int t)
1418 out_lxb(3, v, t);
1421 VOID
1422 out_l4b(a_uint v, int t)
1424 out_lxb(4, v, t);
1427 /*)Function VOID out_lxb(i, v, t)
1429 * int i output byte count
1430 * a_uint v assembled data
1431 * int t relocation type
1433 * Dispatch function for list processing.
1435 * local variables:
1436 * none
1438 * global variables:
1439 * int hilo byte order
1441 * functions called:
1442 * VOID out_lb() asout.c
1444 * side effects:
1445 * i list bytes are processed.
1448 VOID
1449 out_lxb(int i, a_uint v, int t)
1451 if ((int) hilo) {
1452 if (i >= 3) out_lb(thrdbyte(v),t ? t|R_HIGH : 0);
1453 if (i >= 2) out_lb(hibyte(v),t);
1454 if (i >= 1) out_lb(lobyte(v),t);
1455 } else {
1456 if (i >= 1) out_lb(lobyte(v),t);
1457 if (i >= 2) out_lb(hibyte(v),t);
1458 if (i >= 3) out_lb(thrdbyte(v),t ? t|R_HIGH : 0);
1462 /*)Function VOID out_rw(v)
1464 * a_uint v assembled data
1466 * The function out_rw() outputs the relocation (R)
1467 * data word as two bytes ordered according to hilo.
1469 * local variables:
1470 * none
1472 * global variables:
1473 * int hilo byte order
1474 * char * relp Pointer to R Line Values
1476 * functions called:
1477 * int lobyte() asout.c
1478 * int hibyte() asout.c
1480 * side effects:
1481 * Pointer to relocation buffer incremented by 2.
1484 VOID
1485 out_rw(a_uint v)
1487 if ((int) hilo) {
1488 *relp++ = hibyte(v);
1489 *relp++ = lobyte(v);
1490 } else {
1491 *relp++ = lobyte(v);
1492 *relp++ = hibyte(v);
1496 /*)Function VOID out_txb(i, v)
1498 * int i T Line byte count
1499 * a_uint v data word
1501 * The function out_txb() outputs the text (T)
1502 * data word as i bytes ordered according to hilo.
1504 * local variables:
1506 * global variables:
1507 * int hilo byte order
1508 * char * txtp Pointer to T Line Values
1510 * functions called:
1511 * int lobyte() asout.c
1512 * int hibyte() asout.c
1513 * int thrdbyte() asout.c
1514 * int frthbyte() asout.c
1516 * side effects:
1517 * T Line buffer updated.
1520 VOID
1521 out_txb(int i, a_uint v)
1523 if ((int) hilo) {
1524 if (i >= 4) *txtp++ = frthbyte(v);
1525 if (i >= 3) *txtp++ = thrdbyte(v);
1526 if (i >= 2) *txtp++ = hibyte(v);
1527 if (i >= 1) *txtp++ = lobyte(v);
1528 } else {
1529 if (i >= 1) *txtp++ = lobyte(v);
1530 if (i >= 2) *txtp++ = hibyte(v);
1531 if (i >= 3) *txtp++ = thrdbyte(v);
1532 if (i >= 4) *txtp++ = frthbyte(v);
1536 /*)Function int lobyte(v)
1537 *)Function int hibyte(v)
1538 *)Function int thrdbyte(v)
1539 *)Function int frthbyte(v)
1541 * a_uint v assembled data
1543 * These functions return the 1st, 2nd, 3rd, or 4th byte
1544 * of integer v.
1546 * local variables:
1547 * none
1549 * global variables:
1550 * none
1552 * functions called:
1553 * none
1555 * side effects:
1556 * none
1560 lobyte(a_uint v)
1562 return ((int) (v&0377));
1566 hibyte(a_uint v)
1568 return ((int) ((v>>8)&0377));
1572 thrdbyte(a_uint v)
1574 return ((int) ((v>>16)&0377));
1578 frthbyte(a_uint v)
1580 return ((int) ((v>>24)&0377));
1584 * JLH: Output relocatable 11 bit jump/call
1586 * This function is derived from outrw(), adding the parameter for the
1587 * 11 bit address. This form of address is used only on the 8051 and 8048.
1589 /*)Function VOID outrwm(esp, r, v)
1591 * expr * esp pointer to expr structure
1592 * int r relocation mode
1593 * int v opcode
1595 * The function outrwm() processes a word of generated code
1596 * in either absolute or relocatable format dependent upon
1597 * the data contained in the expr structure esp. If the
1598 * .REL output is enabled then the appropriate information
1599 * is loaded into the txt and rel buffers. The code is output
1600 * in a special format to the linker to allow relocation and
1601 * merging of the opcode and an 11 bit paged address as required
1602 * by the 8051 architecture.
1604 * This function based on code by
1605 * John L. Hartman
1606 * jhartman@compuserve.com
1608 * local variables:
1609 * int n symbol/area reference number
1611 * global variables:
1612 * sym dot defined as sym[0]
1613 * int oflag -o, generate relocatable output flag
1614 * int pass assembler pass number
1615 * char * relp Pointer to R Line Values
1616 * char * txtp Pointer to T Line Values
1618 * functions called:
1619 * VOID outchk() asout.c
1620 * VOID out_lw() asout.c
1621 * VOID out_rw() asout.c
1622 * VOID out_txb() asout.c
1624 * side effects:
1625 * The current assembly address is incremented by 2.
1627 VOID
1628 outrwm(struct expr *esp, int r, a_uint v)
1630 int n;
1632 if (pass == 2) {
1633 if (!is_sdas() || !is_sdas_target_8051_like()) {
1634 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1636 * Absolute Destination
1638 * Use the global symbol '.__.ABS.'
1639 * of value zero and force the assembler
1640 * to use this absolute constant as the
1641 * base value for the relocation.
1643 esp->e_flag = 1;
1644 esp->e_base.e_sp = &sym[1];
1647 * Relocatable Destination. Build THREE
1648 * byte output: relocatable word, followed
1649 * by op-code. Linker will combine them.
1651 r |= R_WORD | esp->e_rlcf;
1652 n = ((esp->e_addr & 0x0700) >> 3) | v;
1653 n = (n << 8) | (esp->e_addr & 0xFF);
1654 out_lw(n,r|R_RELOC);
1655 if (oflag) {
1656 outchk(3, 4);
1657 out_txb(2, esp->e_addr);
1658 *txtp++ = v;
1660 if (esp->e_flag) {
1661 n = esp->e_base.e_sp->s_ref;
1662 r |= R_SYM;
1663 } else {
1664 n = esp->e_base.e_ap->a_ref;
1666 *relp++ = r;
1667 *relp++ = txtp - txt - 3;
1668 out_rw(n);
1670 } else {
1671 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1672 /* Absolute destination.
1673 * Listing shows only the address.
1675 out_lw(esp->e_addr,0);
1676 if (oflag) {
1677 outchk(3, 0);
1678 out_txb(2, esp->e_addr);
1679 *txtp++ = v;
1681 write_rmode(r, txtp - txt - 3);
1682 out_rw(0xFFFF);
1684 } else {
1685 /* Relocatable destination. Build THREE
1686 * byte output: relocatable word, followed
1687 * by op-code. Linker will combine them.
1688 * Listing shows only the address.
1690 r |= R_WORD | esp->e_rlcf;
1691 out_lw(esp->e_addr,r|R_RELOC);
1692 if (oflag) {
1693 outchk(3, 5);
1694 out_txb(2, esp->e_addr);
1695 *txtp++ = v;
1697 if (esp->e_flag) {
1698 n = esp->e_base.e_sp->s_ref;
1699 r |= R_SYM;
1700 } else {
1701 n = esp->e_base.e_ap->a_ref;
1703 write_rmode(r, txtp - txt - 3);
1704 out_rw(n);
1709 dot.s_addr += 2;
1713 * Output relocatable 19 bit jump/call
1715 * This function is derived from outrw(), adding the parameter for the
1716 * 19 bit address. This form of address is used only in the DS80C390.
1718 VOID
1719 outr3bm(struct expr * esp, int r, a_uint v)
1721 int n;
1723 if (pass == 2) {
1724 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1725 /* Absolute destination.
1726 * Listing shows only the address.
1728 out_lw(esp->e_addr,0);
1729 if (oflag) {
1730 outchk(4, 0);
1731 out_txb(3, esp->e_addr);
1732 *txtp++ = v;
1734 write_rmode(r, txtp - txt - 4);
1735 out_rw(0xFFFF);
1737 } else {
1738 /* Relocatable destination. Build FOUR
1739 * byte output: relocatable 24-bit entity, followed
1740 * by op-code. Linker will combine them.
1741 * Listing shows only the address.
1743 r |= R_WORD | esp->e_rlcf;
1744 out_l3b(esp->e_addr,r|R_RELOC);
1745 if (oflag) {
1746 outchk(4, 5);
1747 out_txb(3, esp->e_addr);
1748 *txtp++ = v;
1750 if (esp->e_flag) {
1751 n = esp->e_base.e_sp->s_ref;
1752 r |= R_SYM;
1753 } else {
1754 n = esp->e_base.e_ap->a_ref;
1756 write_rmode(r, txtp - txt - 4);
1757 out_rw(n);
1761 dot.s_addr += 3;
1765 * PDK: Output relocatable 11 bit goto/call
1767 * This function is derived from outrw(), adding the parameter for the
1768 * 11 bit address. This form of address is used only on the pdk.
1770 /*)Function VOID outrwp(esp, op, mask, jump)
1772 * expr * esp pointer to expr structure
1773 * a_uint op opcode
1774 * a_uint mask address mask
1775 * int jump call/goto relocation data
1777 * The function outrwp() processes a word of generated code
1778 * in either absolute or relocatable format dependent upon
1779 * the data contained in the expr structure esp. If the
1780 * .REL output is enabled then the appropriate information
1781 * is loaded into the txt and rel buffers. The code is output
1782 * in a special format to the linker to allow relocation and
1783 * merging of the opcode.
1785 * This function based on code by
1786 * John L. Hartman
1787 * jhartman@compuserve.com
1789 * local variables:
1790 * int n symbol/area reference number
1791 * int r relocation information
1793 * global variables:
1794 * sym dot defined as sym[0]
1795 * int oflag -o, generate relocatable output flag
1796 * int pass assembler pass number
1797 * char * relp Pointer to R Line Values
1798 * char * txtp Pointer to T Line Values
1800 * functions called:
1801 * VOID outchk() asout.c
1802 * VOID out_lw() asout.c
1803 * VOID out_rw() asout.c
1804 * VOID out_txb() asout.c
1806 * side effects:
1807 * The current assembly address is incremented by 2.
1809 VOID
1810 outrwp(struct expr *esp, a_uint op, a_uint mask, int jump)
1812 int n, r = R_J11;
1814 if (pass == 2) {
1815 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1817 * Absolute Destination
1819 * Use the global symbol '.__.ABS.'
1820 * of value zero and force the assembler
1821 * to use this absolute constant as the
1822 * base value for the relocation.
1824 esp->e_flag = 1;
1825 esp->e_base.e_sp = &sym[1];
1828 /* We need to select either the MSB or LSB of the address.
1829 * Reset relocation marker so that the linker knows what to do
1830 * with it.
1832 if (esp->e_rlcf & R_BYTX) {
1833 r |= R_BYTE;
1834 /* We might select the MSB/LSB of an address in RAM. In
1835 * that case the linker should not convert the address
1836 * to words.
1838 if (!esp->e_flag && !memcmp(esp->e_base.e_ap->a_id, "DATA", 4)) {
1839 r |= R_USGN;
1841 } else {
1842 r |= R_WORD;
1845 /* Some (address) marker bits might have been shifted out of
1846 * range. Revert this and put them back where they belong.
1848 if (esp->e_addr & ~0xFFFF) {
1849 int marker = esp->e_addr & 0x10000;
1850 esp->e_addr &= ~0x10000;
1851 esp->e_addr |= marker >> 1;
1855 * Relocatable Destination. Build FOUR
1856 * byte output: relocatable word, followed
1857 * by op-code. Linker will combine them.
1859 r |= esp->e_rlcf;
1860 n = op | (esp->e_addr & mask);
1861 out_lw(n,r|R_RELOC);
1862 if (oflag) {
1863 outchk(5, 4);
1864 out_txb(2, esp->e_addr);
1865 out_txb(2, op);
1866 out_txb(1, (int)get_sdas_target());
1868 if (esp->e_flag) {
1869 n = esp->e_base.e_sp->s_ref;
1870 r |= R_SYM;
1871 } else {
1872 n = esp->e_base.e_ap->a_ref;
1874 *relp++ = r;
1875 *relp++ = txtp - txt - 5;
1876 out_rw(n);
1879 dot.s_addr += 2;