4 * (C) Copyright 1989-1995
12 * - outsym: show s_id as string rather than array [NCPS]
13 * - Added outr11 to support 8051's 11 bit destination address
24 * The module asout.c contains all the functions used to
25 * generate the .REL assembler output file.
28 * The assemblers' output object file is an ascii file containing
29 * the information needed by the linker to bind multiple object
30 * modules into a complete loadable memory image.
32 * The object module contains the following designators:
39 * H Most significant byte first
40 * L Least significant byte first
47 * R Relocation information
48 * P Paging information
53 * The first line of an object module contains the [XDQ][HL]
54 * format specifier (i.e. XH indicates a hexadecimal file with
55 * most significant byte first) for the following designators.
60 * H aa areas gg global symbols
62 * The header line specifies the number of areas(aa) and the
63 * number of global symbols(gg) defined or referenced in this ob-
64 * ject module segment.
71 * The module line specifies the module name from which this
72 * header segment was assembled. The module line will not appear
73 * if the .module directive was not used in the source program.
84 * The symbol line defines (Def) or references (Ref) the symbol
85 * 'string' with the value nnnn. The defined value is relative to
86 * the current area base address. References to constants and ex-
87 * ternal global symbols will always appear before the first area
88 * definition. References to external symbols will have a value of
94 * A label size ss flags ff
96 * The area line defines the area label, the size (ss) of the
97 * area in bytes, and the area flags (ff). The area flags specify
98 * the ABS, REL, CON, OVR, and PAG parameters:
100 * OVR/CON (0x04/0x00 i.e. bit position 2)
102 * ABS/REL (0x08/0x00 i.e. bit position 3)
104 * PAG (0x10 i.e. bit position 4)
109 * T xx xx nn nn nn nn nn ...
111 * The T line contains the assembled code output by the assem-
112 * bler with xx xx being the offset address from the current area
113 * base address and nn being the assembled instructions and data in
119 * R 0 0 nn nn n1 n2 xx xx ...
121 * The R line provides the relocation information to the linker.
122 * The nn nn value is the current area index, i.e. which area the
123 * current values were assembled. Relocation information is en-
124 * coded in groups of 4 bytes:
126 * 1. n1 is the relocation mode and object format
127 * 1. bit 0 word(0x00)/byte(0x01)
128 * 2. bit 1 relocatable area(0x00)/symbol(0x02)
129 * 3. bit 2 normal(0x00)/PC relative(0x04) relocation
130 * 4. bit 3 1-byte(0x00)/2-byte(0x08) object format for
132 * 5. bit 4 signed(0x00)/unsigned(0x10) byte data
133 * 6. bit 5 normal(0x00)/page '0'(0x20) reference
134 * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference
135 * 8. bit 7 normal(0x00)/MSB of value
137 * 2. n2 is a byte index into the corresponding (i.e. pre-
138 * ceeding) T line data (i.e. a pointer to the data to be
139 * updated by the relocation). The T line data may be
140 * 1-byte or 2-byte byte data format or 2-byte word
143 * 3. xx xx is the area/symbol index for the area/symbol be-
144 * ing referenced. the corresponding area/symbol is found
145 * in the header area/symbol lists.
148 * The groups of 4 bytes are repeated for each item requiring relo-
149 * cation in the preceeding T line.
154 * P 0 0 nn nn n1 n2 xx xx
156 * The P line provides the paging information to the linker as
157 * specified by a .setdp directive. The format of the relocation
158 * information is identical to that of the R line. The correspond-
159 * ing T line has the following information:
160 * T xx xx aa aa bb bb
162 * Where aa aa is the area reference number which specifies the
163 * selected page area and bb bb is the base address of the page.
164 * bb bb will require relocation processing if the 'n1 n2 xx xx' is
165 * specified in the P line. The linker will verify that the base
166 * address is on a 256 byte boundary and that the page length of an
167 * area defined with the PAG type is not larger than 256 bytes.
169 * The linker defaults any direct page references to the first
170 * area defined in the input REL file. All ASxxxx assemblers will
171 * specify the _CODE area first, making this the default page area.
174 * asout.c contains the following functions:
195 * The module asout.c contains the following local variables:
196 * int rel[] relocation data for code/data array
197 * int * relp pointer to rel array
198 * int txt[] assembled code/data array
199 * int * txtp pointer to txt array
208 char *txtp = { &txt[0] };
209 char *relp = { &rel[0] };
211 /*)Function VOID outab(b)
213 * int b assembler data word
215 * The function outab() processes a single word of
216 * assembled data in absolute format.
219 * int * txtp pointer to data word
222 * int oflag -o, generate relocatable output flag
223 * int pass assembler pass number
226 * VOID outchk() asout.c
227 * VOID out_lb() asout.c
230 * The current assembly address is incremented by 1.
246 /*)Function VOID outaw(w)
248 * int w assembler data word
250 * The function outaw() processes a single word of
251 * assembled data in absolute format.
254 * int * txtp pointer to data word
257 * int oflag -o, generate relocatable output flag
258 * int pass assembler pass number
261 * VOID outchk() asout.c
262 * VOID out_lw() asout.c
265 * The current assembly address is incremented by 2.
281 /*)Function VOID write_rmode(r)
283 * int r relocation mode
285 * write_rmode puts the passed relocation mode into the
286 * output relp buffer, escaping it if necessary.
289 * int * relp pointer to rel array
292 * VOID rerr() assubr.c
295 * relp is incremented appropriately.
300 /* We need to escape the relocation mode if it is greater
301 * than a byte, or if it happens to look like an escape.
302 * (I don't think that the latter case is legal, but
303 * better safe than sorry).
305 if ((r > 0xff) || ((r & R_ESCAPE_MASK) == R_ESCAPE_MASK))
307 /* Hack in up to an extra 4 bits of flags with escape. */
310 /* uh-oh.. we have more than 4 extra bits. */
312 "Internal error: relocation mode 0x%X too big.\n",
316 /* printf("escaping relocation mode\n"); */
317 *relp++ = R_ESCAPE_MASK | (r >> 8);
326 /*)Function VOID outrb(esp, r)
328 * expr * esp pointer to expr structure
329 * int r relocation mode
331 * The function outrb() processes a byte of generated code
332 * in either absolute or relocatable format dependent upon
333 * the data contained in the expr structure esp. If the
334 * .REL output is enabled then the appropriate information
335 * is loaded into the txt and rel buffers.
338 * int n symbol/area reference number
339 * int * relp pointer to rel array
340 * int * txtp pointer to txt array
343 * sym dot defined as sym[0]
344 * int oflag -o, generate relocatable output flag
345 * int pass assembler pass number
348 * VOID aerr() assubr.c
349 * VOID outchk() asout.c
350 * VOID out_lb() asout.c
351 * VOID out_rb() asout.c
352 * VOID out_tb() asout.c
355 * The current assembly address is incremented by 1.
359 outrb(struct expr *esp, int r)
364 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
365 /* This is a constant; simply write the
366 * const byte to the T line and don't
367 * generate any relocation info.
369 out_lb(lobyte(esp->e_addr),0);
372 *txtp++ = lobyte(esp->e_addr);
375 /* We are generating a single byte of relocatable
378 * In 8051 mode, we generate a 16 bit address. The
379 * linker will later select a single byte based on
380 * whether R_MSB is set.
382 * In flat24 mode, we generate a 24 bit address. The
383 * linker will select a single byte based on
384 * whether R_MSB or R_HIB is set.
388 r |= R_BYTE | R_BYT2 | esp->e_rlcf;
390 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
392 out_lb(lobyte(esp->e_addr),r|R_RELOC);
398 n = esp->e_base.e_sp->s_ref;
401 n = esp->e_base.e_ap->a_ref;
404 *relp++ = txtp - txt - 2;
411 r |= R_BYTE | R_BYT3 | esp->e_rlcf;
414 /* Probably should mark this differently in the
417 out_lb(byte3(esp->e_addr),r|R_RELOC|R_HIGH);
419 else if (r & R_MSB) {
420 out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
422 out_lb(lobyte(esp->e_addr),r|R_RELOC);
426 out_t24(esp->e_addr);
428 n = esp->e_base.e_sp->s_ref;
431 n = esp->e_base.e_ap->a_ref;
434 *relp++ = txtp - txt - 3;
443 /*)Function VOID outrw(esp, r)
445 * expr * esp pointer to expr structure
446 * int r relocation mode
448 * The function outrw() processes a word of generated code
449 * in either absolute or relocatable format dependent upon
450 * the data contained in the expr structure esp. If the
451 * .REL output is enabled then the appropriate information
452 * is loaded into the txt and rel buffers.
455 * int n symbol/area reference number
456 * int * relp pointer to rel array
457 * int * txtp pointer to txt array
460 * sym dot defined as sym[0]
461 * int oflag -o, generate relocatable output flag
462 * int pass assembler pass number
465 * VOID aerr() assubr.c
466 * VOID outchk() asout.c
467 * VOID out_lw() asout.c
468 * VOID out_rw() asout.c
469 * VOID out_tw() asout.c
472 * The current assembly address is incremented by 2.
476 outrw(struct expr *esp, int r)
482 if (esp->e_addr > 0xffff)
486 "large constant 0x%x truncated to 16 bits\n",
489 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
490 out_lw(esp->e_addr,0);
496 r |= R_WORD | esp->e_rlcf;
500 out_lw(hibyte(esp->e_addr),r|R_RELOC);
502 out_lw(lobyte(esp->e_addr),r|R_RELOC);
505 out_lw(esp->e_addr,r|R_RELOC);
511 n = esp->e_base.e_sp->s_ref;
514 n = esp->e_base.e_ap->a_ref;
519 /* If this happens, the linker will
520 * attempt to process this 16 bit field
521 * as 24 bits. That would be bad.
524 "***Internal error: C24 out in "
529 *relp++ = txtp - txt - 2;
537 /*)Function VOID outr24(esp, r)
539 * expr * esp pointer to expr structure
540 * int r relocation mode
542 * The function outr24() processes 24 bits of generated code
543 * in either absolute or relocatable format dependent upon
544 * the data contained in the expr structure esp. If the
545 * .REL output is enabled then the appropriate information
546 * is loaded into the txt and rel buffers.
549 * int n symbol/area reference number
550 * int * relp pointer to rel array
551 * int * txtp pointer to txt array
554 * sym dot defined as sym[0]
555 * int oflag -o, generate relocatable output flag
556 * int pass assembler pass number
559 * VOID aerr() assubr.c
560 * VOID outchk() asout.c
561 * VOID out_l24() asout.c
562 * VOID out_rw() asout.c
563 * VOID out_t24() asout.c
566 * The current assembly address is incremented by 3.
570 outr24(struct expr *esp, int r)
575 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
576 /* This is a constant expression. */
577 out_l24(esp->e_addr,0);
580 out_t24(esp->e_addr);
583 /* This is a symbol. */
584 r |= R_WORD | esp->e_rlcf;
586 /* I have no idea what this case is. */
589 out_lw(hibyte(esp->e_addr),r|R_RELOC);
591 out_lw(lobyte(esp->e_addr),r|R_RELOC);
594 out_l24(esp->e_addr,r|R_RELOC);
598 out_t24(esp->e_addr);
600 n = esp->e_base.e_sp->s_ref;
603 n = esp->e_base.e_ap->a_ref;
608 /* If this occurs, we cannot properly
609 * code the relocation data with the
610 * R_C24 flag. This means the linker
611 * will fail to do the 24 bit relocation.
615 "***Internal error: BYTE out in 24 "
616 "bit flat mode unexpected.\n");
620 write_rmode(r | R_C24);
621 *relp++ = txtp - txt - 3;
629 /*)Function VOID outdp(carea, esp)
631 * area * carea pointer to current area strcuture
632 * expr * esp pointer to expr structure
634 * The function outdp() flushes the output buffer and
635 * outputs paging information to the .REL file.
638 * int n symbol/area reference number
639 * int r relocation mode
640 * int * relp pointer to rel array
641 * int * txtp pointer to txt array
644 * int oflag -o, generate relocatable output flag
645 * int pass assembler pass number
648 * VOID outbuf() asout.c
649 * VOID outchk() asout.c
650 * VOID out_rw() asout.c
651 * VOID out_tw() asout.c
654 * Output buffer flushed to .REL fiel.
655 * Paging information dumped to .REL file.
659 outdp(register struct area *carea, register struct expr *esp)
663 if (oflag && pass==2) {
665 out_tw(carea->a_ref);
667 if (esp->e_flag || esp->e_base.e_ap!=NULL) {
670 n = esp->e_base.e_sp->s_ref;
673 n = esp->e_base.e_ap->a_ref;
676 *relp++ = txtp - txt - 2;
683 /*)Function VOID outall()
685 * The function outall() will output any bufferred assembled
686 * data and relocation information (during pass 2 if the .REL
687 * output has been enabled).
693 * int oflag -o, generate relocatable output flag
694 * int pass assembler pass number
697 * VOID outbuf() asout.c
700 * assembled data and relocation buffers will be cleared.
706 if (oflag && pass==2)
710 /*)Function VOID outdot()
712 * The function outdot() outputs information about the
713 * current program counter value (during pass 2 if the .REL
714 * output has been enabled).
720 * int oflag -o, generate relocatable output flag
721 * int pass assembler pass number
724 * int fprintf() c_library
728 * assembled data and relocation buffers will be cleared.
734 if (oflag && pass==2) {
736 out(txt,(int) (txtp-txt));
739 out(rel,(int) (relp-rel));
746 /*)Function outchk(nt, nr)
748 * int nr number of additional relocation words
749 * int nt number of additional data words
751 * The function outchk() checks the data and relocation buffers
752 * for space to insert the nt data words and nr relocation words.
753 * If space is not available then output the current data and
754 * initialize the data buffers to receive the new data.
757 * area * ap pointer to an area structure
758 * int * relp pointer to rel array
759 * int * txtp pointer to txt array
762 * sym dot defined as sym[0]
765 * VOID outbuf() asout.c
768 * Data and relocation buffers may be emptied and initialized.
772 outchk(int nt, int nr)
774 register struct area *ap;
776 if (txtp+nt > &txt[NTXT] || relp+nr > &rel[NREL]) {
781 if ((ap = dot.s_area) != NULL) {
782 write_rmode(R_WORD|R_AREA);
789 /*)Function VOID outbuf()
791 * The function outbuf() will output any bufferred data
792 * and relocation information to the .REL file. The output
793 * buffer pointers and counters are initialized.
796 * int rel[] relocation data for code/data array
797 * int * relp pointer to rel array
798 * int txt[] assembled code/data array
799 * int * txtp pointer to txt array
802 * FILE * ofp relocation output file handle
808 * All bufferred data written to .REL file and
809 * buffer pointers and counters initialized.
815 if (txtp > &txt[2]) {
817 out(txt,(int) (txtp-txt));
819 fprintf(ofp, "%s", s);
820 out(rel,(int) (relp-rel));
827 /*)Function VOID outgsd()
829 * The function outgsd() performs the following:
830 * (1) outputs the .REL file radix
831 * (2) outputs the header specifying the number
832 * of areas and global symbols
833 * (3) outputs the module name
834 * (4) set the reference number and output a symbol line
835 * for all external global variables and absolutes
836 * (5) output an area name, set reference number and output
837 * a symbol line for all global relocatables in the area.
838 * Repeat this proceedure for all areas.
841 * area * ap pointer to an area structure
842 * sym * sp pointer to a sym structure
845 * int c string character value
846 * int narea number of code areas
847 * char * ptr string pointer
848 * int nglob number of global symbols
849 * int rn symbol reference number
852 * area * areap pointer to an area structure
853 * char module[] module name string
854 * sym * symhash[] array of pointers to NHASH
855 * linked symbol lists
856 * int xflag -x, listing radix flag
859 * int fprintf() c_library
860 * VOID outarea() asout.c
861 * VOID outsym() asout.c
862 * int putc() c_library
865 * All symbols are given reference numbers, all symbol
866 * and area information is output to the .REL file.
872 register struct area *ap;
873 register struct sym *sp;
876 int c, narea, nglob, rn;
881 narea = areap->a_ref + 1;
884 * Number of global references/absolutes
887 for (i = 0; i < NHASH; ++i) {
890 if (sp->s_flag&S_GBL)
897 * Output Radix and number of areas and symbols
900 fprintf(ofp, "X%c\n", hilo ? 'H' : 'L');
901 fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob);
904 fprintf(ofp, "Q%c\n", hilo ? 'H' : 'L');
905 fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob);
908 fprintf(ofp, "D%c\n", hilo ? 'H' : 'L');
909 fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob);
918 while (ptr < &module[NCPS]) {
919 if ((c = *ptr++) != 0)
926 * Sdcc compile options
928 if (strlen(optsdcc)) fprintf(ofp, "O %s\n", optsdcc);
931 * Global references and absolutes.
934 for (i=0; i<NHASH; ++i) {
937 if (sp->s_area==NULL && sp->s_flag&S_GBL) {
946 * Global relocatables.
948 for (i=0; i<narea; ++i) {
950 while (ap->a_ref != i)
953 for (j=0; j<NHASH; ++j) {
956 if (sp->s_area==ap && sp->s_flag&S_GBL) {
966 /*)Function VOID outarea(ap)
968 * area * ap pointer to an area structure
970 * The function outarea() outputs the A line to the .REL
971 * file. The A line contains the area's name, size, and
975 * char * ptr pointer to area id string
976 * int c character value
979 * FILE * ofp relocation output file handle
980 * int xflag -x, listing radix flag
983 * int fprintf() c_library
984 * int putc() c_library
987 * The A line is sent to the .REL file.
991 outarea(register struct area *ap)
998 while (ptr < &ap->a_id[NCPS]) {
999 if ((c = *ptr++) != 0)
1003 fprintf(ofp, " size %X flags %X addr %X\n", ap->a_size, ap->a_flag, ap->a_addr);
1006 fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag);
1009 fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag);
1013 /*)Function VOID outsym(sp)
1015 * sym * sp pointer to a sym structure
1017 * The function outsym() outputs the S line to the .REL
1018 * file. The S line contains the symbols name and whether the
1019 * the symbol is defined or referenced.
1022 * char * ptr pointer to symbol id string
1023 * int c character value
1026 * FILE * ofp relocation output file handle
1027 * int xflag -x, listing radix flag
1030 * int fprintf() c_library
1031 * int putc() c_library
1034 * The S line is sent to the .REL file.
1038 outsym(register struct sym *sp)
1044 fprintf(ofp, "%s", ptr );
1045 fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def");
1047 fprintf(ofp, "%04X\n", sp->s_addr);
1050 fprintf(ofp, "%06o\n", sp->s_addr);
1053 fprintf(ofp, "%05u\n", sp->s_addr);
1057 /*)Function VOID out(p, n)
1059 * int n number of words to output
1060 * int * p pointer to data words
1062 * The function out() outputs the data words to the .REL file
1063 * int the specified radix.
1069 * FILE * ofp relocation output file handle
1070 * int xflag -x, listing radix flag
1073 * int fprintf() c_library
1076 * Data is sent to the .REL file.
1084 fprintf(ofp, " %02X", (*p++)&0xff);
1087 fprintf(ofp, " %03o", (*p++)&0xff);
1090 fprintf(ofp, " %03u", (*p++)&0xff);
1095 /*)Function VOID out_lb(b, t)
1097 * int b assembled data
1098 * int t relocation type
1100 * The function out_lb() copies the assembled data and
1101 * its relocation type to the list data buffers.
1107 * int * cp pointer to assembler output array cb[]
1108 * int * cpt pointer to assembler relocation type
1109 * output array cbt[]
1115 * Pointers to data and relocation buffers incremented by 1.
1119 out_lb(register int b, register int t)
1121 if (cp < &cb[NCODE]) {
1127 /*)Function VOID out_lw(n, t)
1129 * int n assembled data
1130 * int t relocation type
1132 * The function out_lw() copies the assembled data and
1133 * its relocation type to the list data buffers.
1139 * int * cp pointer to assembler output array cb[]
1140 * int * cpt pointer to assembler relocation type
1141 * output array cbt[]
1147 * Pointers to data and relocation buffers incremented by 2.
1151 out_lw(register int n, register int t)
1154 out_lb(hibyte(n),t ? t|R_HIGH : 0);
1155 out_lb(lobyte(n),t);
1157 out_lb(lobyte(n),t);
1158 out_lb(hibyte(n),t ? t|R_HIGH : 0);
1162 /*)Function VOID out_l24(n, t)
1164 * int n assembled data
1165 * int t relocation type
1167 * The function out_l24() copies the assembled data and
1168 * its relocation type to the list data buffers.
1174 * int * cp pointer to assembler output array cb[]
1175 * int * cpt pointer to assembler relocation type
1176 * output array cbt[]
1182 * Pointers to data and relocation buffers incremented by 3.
1186 out_l24(int n, int t)
1189 out_lb(byte3(n),t ? t|R_HIGH : 0);
1190 out_lb(hibyte(n),t);
1191 out_lb(lobyte(n),t);
1193 out_lb(lobyte(n),t);
1194 out_lb(hibyte(n),t);
1195 out_lb(byte3(n),t ? t|R_HIGH : 0);
1199 /*)Function VOID out_rw(n)
1203 * The function out_rw() outputs the relocation (R)
1204 * data word as two bytes ordered according to hilo.
1207 * int * relp pointer to rel array
1213 * int lobyte() asout.c
1214 * int hibyte() asout.c
1217 * Pointer to relocation buffer incremented by 2.
1221 out_rw(register int n)
1224 *relp++ = hibyte(n);
1225 *relp++ = lobyte(n);
1227 *relp++ = lobyte(n);
1228 *relp++ = hibyte(n);
1232 /*)Function VOID out_tw(n)
1236 * The function out_tw() outputs the text (T)
1237 * data word as two bytes ordered according to hilo.
1240 * int * txtp pointer to txt array
1246 * int lobyte() asout.c
1247 * int hibyte() asout.c
1250 * Pointer to relocation buffer incremented by 2.
1254 out_tw(register int n)
1257 *txtp++ = hibyte(n);
1258 *txtp++ = lobyte(n);
1260 *txtp++ = lobyte(n);
1261 *txtp++ = hibyte(n);
1265 /*)Function VOID out_t24(n)
1269 * The function out_t24() outputs the text (T)
1270 * data word as three bytes ordered according to hilo.
1273 * int * txtp pointer to txt array
1279 * int lobyte() asout.c
1280 * int hibyte() asout.c
1283 * Pointer to relocation buffer incremented by 3.
1291 *txtp++ = hibyte(n);
1292 *txtp++ = lobyte(n);
1294 *txtp++ = lobyte(n);
1295 *txtp++ = hibyte(n);
1300 /*)Function int lobyte(n)
1304 * The function lobyte() returns the lower byte of
1326 /*)Function int hibyte(n)
1330 * The function hibyte() returns the higher byte of
1349 return ((n>>8)&0377);
1352 /*)Function int byte3(n)
1356 * The function byte3() returns the MSB of the
1374 return ((n >> 16) & 0xff);
1378 * JLH: Output relocatable 11 bit jump/call
1380 * This function is derived from outrw(), adding the parameter for the
1381 * 11 bit address. This form of address is used only on the 8051 and 8048.
1384 outr11(register struct expr *esp, int op, int r)
1389 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1390 /* Absolute destination.
1391 * Listing shows only the address.
1393 out_lw(esp->e_addr,0);
1396 out_tw(esp->e_addr);
1400 *relp++ = txtp - txt - 3;
1404 /* Relocatable destination. Build THREE
1405 * byte output: relocatable word, followed
1406 * by op-code. Linker will combine them.
1407 * Listing shows only the address.
1409 r |= R_WORD | esp->e_rlcf;
1410 out_lw(esp->e_addr,r|R_RELOC);
1413 out_tw(esp->e_addr);
1417 n = esp->e_base.e_sp->s_ref;
1420 n = esp->e_base.e_ap->a_ref;
1423 *relp++ = txtp - txt - 3;
1432 * Output relocatable 19 bit jump/call
1434 * This function is derived from outrw(), adding the parameter for the
1435 * 19 bit address. This form of address is used only in the DS80C390
1439 outr19(struct expr * esp, int op, int r)
1444 if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
1445 /* Absolute destination.
1446 * Listing shows only the address.
1448 out_lw(esp->e_addr,0);
1451 out_t24(esp->e_addr);
1455 *relp++ = txtp - txt - 4;
1459 /* Relocatable destination. Build FOUR
1460 * byte output: relocatable 24-bit entity, followed
1461 * by op-code. Linker will combine them.
1462 * Listing shows only the address.
1464 r |= R_WORD | esp->e_rlcf;
1465 out_l24(esp->e_addr,r|R_RELOC);
1468 out_t24(esp->e_addr);
1472 n = esp->e_base.e_sp->s_ref;
1475 n = esp->e_base.e_ap->a_ref;
1478 *relp++ = txtp - txt - 4;