5 static void I(segment
)(int n
) {
10 case CODE
: print("code\n"); return;
11 case DATA
: print("data\n"); return;
12 case BSS
: print("bss\n"); return;
13 case LIT
: print("lit\n"); return;
18 static void I(address
)(Symbol q
, Symbol p
, long n
) {
19 q
->x
.name
= stringf("%s%s%D", p
->x
.name
, n
> 0 ? "+" : "", n
);
22 static void I(defaddress
)(Symbol p
) {
23 print("address %s\n", p
->x
.name
);
26 static void I(defconst
)(int suffix
, int size
, Value v
) {
29 if (size
> sizeof (int))
30 print("byte %d %D\n", size
, v
.i
);
32 print("byte %d %d\n", size
, v
.i
);
35 if (size
> sizeof (unsigned))
36 print("byte %d %U\n", size
, v
.u
);
38 print("byte %d %u\n", size
, v
.u
);
40 case P
: print("byte %d %U\n", size
, (unsigned long)v
.p
); return;
45 print("byte 4 %u\n", fi
.ui
);
47 unsigned *p
= (unsigned *)&v
.d
;
48 print("byte 4 %u\n", p
[swap
]);
49 print("byte 4 %u\n", p
[1 - swap
]);
56 static void I(defstring
)(int len
, char *str
) {
59 for (s
= str
; s
< str
+ len
; s
++)
60 print("byte 1 %d\n", (*s
)&0377);
63 static void I(defsymbol
)(Symbol p
) {
64 if (p
->scope
== CONSTANTS
)
65 switch (optype(ttob(p
->type
))) {
66 case I
: p
->x
.name
= stringf("%D", p
->u
.c
.v
.i
); break;
67 case U
: p
->x
.name
= stringf("%U", p
->u
.c
.v
.u
); break;
68 case P
: p
->x
.name
= stringf("%U", p
->u
.c
.v
.p
); break;
70 { // JDC: added this to get inline floats
74 p
->x
.name
= stringf("%U", temp
.ui
);
76 break;// JDC: added this
79 else if (p
->scope
>= LOCAL
&& p
->sclass
== STATIC
)
80 p
->x
.name
= stringf("$%d", genlabel(1));
81 else if (p
->scope
== LABELS
|| p
->generated
)
82 p
->x
.name
= stringf("$%s", p
->name
);
87 static void dumptree(Node p
) {
88 switch (specific(p
->op
)) {
95 print("%s %d\n", opname(p
->op
), p
->syms
[0]->u
.c
.v
.u
);
100 print("%s\n", opname(p
->op
));
103 switch (generic(p
->op
)) {
104 case CNST
: case ADDRG
: case ADDRF
: case ADDRL
: case LABEL
:
107 assert(p
->syms
[0] && p
->syms
[0]->x
.name
);
108 print("%s %s\n", opname(p
->op
), p
->syms
[0]->x
.name
);
110 case CVF
: case CVI
: case CVP
: case CVU
:
114 dumptree(p
->kids
[0]);
115 print("%s %d\n", opname(p
->op
), p
->syms
[0]->u
.c
.v
.i
);
117 case ARG
: case BCOM
: case NEG
: case INDIR
: case JUMP
: case RET
:
120 dumptree(p
->kids
[0]);
121 print("%s\n", opname(p
->op
));
126 assert(optype(p
->op
) != B
);
127 dumptree(p
->kids
[0]);
128 print("%s\n", opname(p
->op
));
129 if ( !p
->count
) { printf("pop\n"); }; // JDC
131 case ASGN
: case BOR
: case BAND
: case BXOR
: case RSH
: case LSH
:
132 case ADD
: case SUB
: case DIV
: case MUL
: case MOD
:
135 dumptree(p
->kids
[0]);
136 dumptree(p
->kids
[1]);
137 print("%s\n", opname(p
->op
));
139 case EQ
: case NE
: case GT
: case GE
: case LE
: case LT
:
143 assert(p
->syms
[0]->x
.name
);
144 dumptree(p
->kids
[0]);
145 dumptree(p
->kids
[1]);
146 print("%s %s\n", opname(p
->op
), p
->syms
[0]->x
.name
);
152 static void I(emit
)(Node p
) {
153 for (; p
; p
= p
->link
)
157 static void I(export
)(Symbol p
) {
158 print("export %s\n", p
->x
.name
);
161 static void I(function
)(Symbol f
, Symbol caller
[], Symbol callee
[], int ncalls
) {
164 (*IR
->segment
)(CODE
);
166 for (i
= 0; caller
[i
] && callee
[i
]; i
++) {
167 offset
= roundup(offset
, caller
[i
]->type
->align
);
168 caller
[i
]->x
.name
= callee
[i
]->x
.name
= stringf("%d", offset
);
169 caller
[i
]->x
.offset
= callee
[i
]->x
.offset
= offset
;
170 offset
+= caller
[i
]->type
->size
;
172 maxargoffset
= maxoffset
= argoffset
= offset
= 0;
173 gencode(caller
, callee
);
174 print("proc %s %d %d\n", f
->x
.name
, maxoffset
, maxargoffset
);
176 print("endproc %s %d %d\n", f
->x
.name
, maxoffset
, maxargoffset
);
180 static void gen02(Node p
) {
182 if (generic(p
->op
) == ARG
) {
184 argoffset
+= (p
->syms
[0]->u
.c
.v
.i
< 4 ? 4 : p
->syms
[0]->u
.c
.v
.i
);
185 } else if (generic(p
->op
) == CALL
) {
186 maxargoffset
= (argoffset
> maxargoffset
? argoffset
: maxargoffset
);
191 static void gen01(Node p
) {
199 static Node
I(gen
)(Node p
) {
203 for (q
= p
; q
; q
= q
->link
)
208 static void I(global
)(Symbol p
) {
209 print("align %d\n", p
->type
->align
> 4 ? 4 : p
->type
->align
);
210 print("LABELV %s\n", p
->x
.name
);
213 static void I(import
)(Symbol p
) {
214 print("import %s\n", p
->x
.name
);
217 static void I(local
)(Symbol p
) {
218 offset
= roundup(offset
, p
->type
->align
);
219 p
->x
.name
= stringf("%d", offset
);
220 p
->x
.offset
= offset
;
221 offset
+= p
->type
->size
;
224 static void I(progbeg
)(int argc
, char *argv
[]) {}
226 static void I(progend
)(void) {}
228 static void I(space
)(int n
) {
229 print("skip %d\n", n
);
232 //========================================================
234 // JDC: hacked up to get interleaved source lines in asm code
235 static char *sourceFile
;
236 static char *sourcePtr
;
237 static int sourceLine
;
239 static int filelength( FILE *f
) {
244 fseek (f
, 0, SEEK_END
);
246 fseek (f
, pos
, SEEK_SET
);
251 static void LoadSourceFile( const char *filename
) {
255 f
= fopen( filename
, "r" );
257 print( ";couldn't open %s\n", filename
);
261 length
= filelength( f
);
262 sourceFile
= malloc( length
+ 1 );
264 fread( sourceFile
, length
, 1, f
);
265 sourceFile
[length
] = 0;
270 sourcePtr
= sourceFile
;
273 static void PrintToSourceLine( int line
) {
279 while ( sourceLine
<= line
) {
282 for ( i
= 0 ; sourcePtr
[i
] && sourcePtr
[i
] != '\n' ; i
++ ) {
288 print( ";%d:%s\n", sourceLine
, sourcePtr
);
290 sourcePtr
+= i
; // end of file
298 static void I(stabline
)(Coordinate
*cp
) {
299 static char *prevfile
;
302 if (cp
->file
&& (prevfile
== NULL
|| strcmp(prevfile
, cp
->file
) != 0)) {
303 print("file \"%s\"\n", prevfile
= cp
->file
);
309 // load the new source file
310 LoadSourceFile( cp
->file
);
312 if (cp
->y
!= prevline
) {
313 print("line %d\n", prevline
= cp
->y
);
314 PrintToSourceLine( cp
->y
);
318 //========================================================
320 #define b_blockbeg blockbeg
321 #define b_blockend blockend
323 Interface bytecodeIR
= {
324 {1, 1, 0}, /* char */
325 {2, 2, 0}, /* short */
327 {4, 4, 0}, /* long */
328 {4, 4, 0}, /* long long */
329 {4, 4, 0}, /* float */ // JDC: use inline floats
330 {4, 4, 0}, /* double */ // JDC: don't ever emit 8 byte double code
331 {4, 4, 0}, /* long double */ // JDC: don't ever emit 8 byte double code
333 {0, 4, 0}, /* struct */
334 0, /* little_endian */
335 0, /* mulops_calls */
338 1, /* left_to_right */
340 0, /* unsigned_char */
359 0, /* I(stabblock) */