home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)emit.c 1.6 1/20/89
- */
- #include "assert.h"
- #include "genutils.h"
- #include "nodes.h"
- #include "builtins.h"
- #include "regdefs.h"
- #include "flags.h"
- #include "trace.h"
- #include "consts.h"
- #include "sequence.h"
-
- Boolean doGenerateCode = 1;
-
- /*VARARGS1*/
- void emit(format, args)
- char *format;
- int args;
- {
- if (doGenerateCode) _doprnt(format, &args, codeFile);
- IFTRACE(emit, 1) _doprnt(format, &args, stdout);
- }
-
- Boolean isPush(d)
- DD d;
- {
- if (d.kind != DD_Address) return(FALSE);
- if (d.value.address.base != regs_sp) return(FALSE);
- return (d.value.address.autoDecrement);
- }
-
- Boolean isMemory(d)
- DD d;
- {
- if (d.kind != DD_Address) return(FALSE);
- return(d.value.address.base != Register);
- }
-
- Boolean isAddressRegister(d)
- DD d;
- {
- #ifdef sun
- static int addressRegs = 0xf033;
- #endif
- #ifdef vax
- static int addressRegs = 0xffff;
- #endif
- if (d.kind != DD_Address) return(FALSE);
- if (d.value.address.base != Register) return(FALSE);
- return(addressRegs & (1 << d.value.address.offset));
- }
-
- Boolean isDataRegister(d)
- DD d;
- {
- #ifdef sun
- static int dataRegs = 0x0fcc;
- #endif
- #ifdef vax
- static int dataRegs = 0xffff;
- #endif
- if (d.kind != DD_Address) return(FALSE);
- if (d.value.address.base != Register) return(FALSE);
- return(dataRegs & (1 << d.value.address.offset));
- }
-
- Boolean isRegisterDD(d)
- DD d;
- {
- if (d.kind != DD_Address) return(FALSE);
- return(d.value.address.base == Register);
- }
-
- Boolean isAppropriateRegister(d, brand)
- DD d;
- Brand brand;
- {
- return ((brand == DataBrand && isDataRegister(d)) ||
- (brand == ODPBrand && isAddressRegister(d)));
- }
-
- Boolean isManifestDD(d)
- DD d;
- {
- return(d.kind == DD_Manifest || d.kind == DD_RealManifest);
- }
-
- static void outDD(d, c)
- DD d;
- char c;
- {
- writeDD(d, c);
- IFTRACE(emitmove, 1) displayDD(stdout, d, c);
- }
-
- /*VARARGS1*/
- static void out0(s)
- char *s;
- {
- emit(s);
- TRACE0(emitmove, 1, s);
- }
-
- /*VARARGS1*/
- static void out1(s, x)
- char *s;
- int x;
- {
- emit(s, x);
- TRACE1(emitmove, 1, s, x);
- }
-
- /*VARARGS1*/
- static void out2(s, x, y)
- char *s;
- int x, y;
- {
- emit(s, x, y);
- TRACE2(emitmove, 1, s, x, y);
- }
-
- /*VARARGS1*/
- static void out3(s, x, y, z)
- char *s;
- int x, y, z;
- {
- emit(s, x, y, z);
- TRACE3(emitmove, 1, s, x, y, z);
- }
-
- void emitMoveAddress(from, to)
- DD from, to;
- {
- assert(!DDNeedsLabel(from));
- assert(from.kind == DD_Address);
- #ifdef vax
- out0("\tmoval\t");
- #endif
- #ifdef sun
- out0("\tlea\t");
- #endif
- outDD(from, ',');
- outDD(to, '\n');
- wroteCode = TRUE;
- }
-
- void emitMove(from, to, size)
- DD from, to;
- char size;
- {
- int trueLabel, endLabel;
- DD intermediate;
-
- if (isSameDD(from, to)) return;
- assert(to.kind == DD_Address);
- if (DDNeedsLabel(from)) {
- currentInstruction = nextLabelNumber++;
- out1("L_%d:\t", currentInstruction);
- } else {
- out0("\t");
- }
-
- if (from.kind == DD_PSLCondition) {
- #ifdef vax
- if (FALSE) {
- #endif
- #ifdef sun
- if (isDataRegister(to) && size == 'l') {
- emit("%ss%s\t", JF(from.value.condition.isFloat),
- JN(from.value.condition.psl));
- writeDD(to, '\n');
- emit("\textbl\t");
- writeDD(to, '\n');
- emit("\tnegl\t");
- writeDD(to, '\n');
- #endif
- } else {
- trueLabel = nextLabelNumber++;
- endLabel = nextLabelNumber++;
- out3("%sb%s\tL_%d\n", JF(from.value.condition.isFloat),
- JN(from.value.condition.psl), trueLabel);
- intermediate.kind = DD_Manifest;
- intermediate.value.manifest = 0;
- emitMove(intermediate, to, size);
- out2("\tj%s\tL_%d\n", JN(ALWAYS), endLabel);
- out1("L_%d:\n", trueLabel);
- intermediate.value.manifest = 1;
- emitMove(intermediate, to, size);
- out1("L_%d:\n", endLabel);
- }
- } else if (from.kind == DD_Self) {
- assert(size == 'l');
- trueLabel = nextLabelNumber++;
- endLabel = nextLabelNumber++;
- emitBranchOnBit(ODTag_global, 's', regs_g, buildLabelDD(trueLabel));
- intermediate = buildRegisterDD(regs_g);
- emitMove(intermediate, to, size);
- emit("\tj%s\tL_%d\n", JN(ALWAYS), endLabel);
- emit("L_%d:\n", trueLabel);
- intermediate = buildRegisterDD(regs_b);
- emitMove(intermediate, to, size);
- emit("L_%d:\n", endLabel);
- #ifdef vax
- } else if (from.kind == DD_Manifest && from.value.manifest == 0) {
- #endif
- #ifdef sun
- } else if (from.kind == DD_Manifest && from.value.manifest == 0 &&
- !isAddressRegister(to)) {
- #endif
- out1("clr%c\t", size);
- outDD(to, '\n');
- #ifdef vax
- } else if (size == 'l' && isPush(to) && from.kind != DD_RealManifest) {
- if (from.kind == DD_Label) {
- /* use pushal */
- out0("pushal\t");
- outDD(from, '\n');
- } else {
- /* use pushl */
- out0("pushl\t");
- outDD(from, '\n');
- }
- #endif
- #ifdef sun
- } else if (size == 'l' && isPush(to) && from.kind == DD_Label) {
- /* use pea */
- out0("pea\t");
- outDD(from, '\n');
- #endif
- } else if (from.kind == DD_RealManifest) {
- assert(size == 'l' || size == 'f');
- #ifdef vax
- out1("movf\t");
- #endif
- #ifdef sun
- out1("movl\t");
- #endif
- outDD(from, ',');
- outDD(to, '\n');
- } else if (from.kind == DD_Label) {
- #ifdef vax
- out1("moval\t");
- outDD(from, ',');
- outDD(to, '\n');
- #endif
- #ifdef sun
- if (isAddressRegister(to)) {
- out0("lea\t");
- outDD(from, ',');
- outDD(to, '\n');
- } else {
- out0("pea\t");
- outDD(from,'\n');
- out0("\tmovl\t");
- outDD(popper, ',');
- outDD(to, '\n');
- }
- #endif
- } else {
- #ifdef sun
- if (from.kind == DD_Manifest && isDataRegister(to) &&
- inRange(from.value.manifest, -128, 127) && size == 'l') {
- out1("moveq\t");
- } else {
- out1("mov%c\t", size);
- }
- #endif
- #ifdef vax
- out1("mov%c\t", size);
- #endif
- outDD(from, ',');
- outDD(to, '\n');
- }
- wroteCode = TRUE;
- }
-
- /*VARARGS1*/
- void Comment(format, args)
- char *format;
- int args;
- {
- if (doGenerateCode) {
- fprintf(codeFile, " %c ", COMMENTCHAR);
- _doprnt(format, &args, codeFile);
- (void) fputc('\n', codeFile);
- }
- IFTRACE(emit, 1) {
- fprintf(stdout, " %c ", COMMENTCHAR);
- _doprnt(format, &args, stdout);
- (void) fputc('\n', stdout);
- }
- }
-
- writeStringData(s)
- char *s;
- {
- int extra;
- extra = 4 - (strlen(s) % 4);
- if (extra == 4) extra = 0;
- emit("\t.ascii\t\""); /* data */
- for (; *s; s++) {
- if (*s == '"') {
- emit("\\\"");
- } else if (*s == '\\') {
- emit("\\\\");
- } else if (*s >= ' ' && *s <= '~') {
- emit("%c",*s);
- } else {
- emit("\\%03o", *s);
- }
- }
- for (; extra; extra--) {
- emit("\\000");
- }
- emit("\"\n");
- }
-
- void emitStringObject(s, labelNumber, extraString, extraNumber)
- register char *s;
- int labelNumber;
- char *extraString;
- int extraNumber;
- {
- ODTag tag;
- tag = BuildTag(LOTag, TRUE);
- tag.gcDoNotCollect = TRUE;
- /* write the codeoid here to facilitate garbage collection */
- writeHexComment(currentCodeOID, "Code OID containing this String");
- if (extraString != NULL) emit("L_%s:\n", extraString);
- emit("L_%d:", labelNumber);
- writeTag(tag); /* tag */
- writeHex((unsigned)0xabcdef01); /* codePtr */
- saveRelocationInfo(labelNumber, 4, AR_OIDToCodePtr,
- OIDOfBuiltin(B_INSTCT, STRINGINDEX), 0);
- writeData(0); /* ownOID */
- writeData(strlen(s)); /* sizeInBytes */
- writeStringData(s);
- }
-
- void emitVectorObject(vector, labelNumber, elementTypeSize, vecCodeOID)
- NodePtr vector;
- int labelNumber, elementTypeSize;
- OID vecCodeOID;
- {
- ODTag tag;
- int nElements, extra;
- Variable v;
- char *labelname;
- NodePtr p;
- tag = BuildTag(LOTag, TRUE);
- tag.gcDoNotCollect = TRUE;
- /* write the codeoid here to facilitate garbage collection */
- writeHexComment(currentCodeOID, "Code OID containing this Vector");
- emit("L_%d:", labelNumber);
- writeTag(tag); /* tag */
- writeHex((unsigned)0xabcdef01); /* codePtr */
- saveRelocationInfo(labelNumber, 4, AR_OIDToCodePtr, vecCodeOID, 0);
- writeData(0); /* ownOID */
- nElements = Sequence_Length(vector->b.vectorlit.exp);
- writeData(nElements - 1); /* upb */
- writeData(nElements * elementTypeSize); /* sizeInBytes */
- extra = 4 - ((nElements * elementTypeSize) % 4);
- if (extra == 4) extra = 0;
- labelname = elementTypeSize == 1 ? ".byte" : ".long";
-
- Sequence_For(p, vector->b.vectorlit.exp)
- vPushValue(p, pusherContext);
- v = vPop();
- switch (v.data.kind) {
- case DD_Manifest:
- emit("\t%s\t%d\n", labelname, v.data.value.manifest);
- break;
- case DD_Label:
- emit("\t%s\tL_%d\n", labelname, v.data.value.label);
- break;
- default:
- assert(FALSE);
- break;
- }
- if (elementTypeSize == 8) {
- writeHex((unsigned)0xabcdef01); /* codePtr */
- saveRelocationInfo(labelNumber, IMVector_data + (z__z * 8) + 4,
- AR_OIDOIDToAbCon, getDDAbstractType(v.abCon),
- getDDConcreteType(v.abCon));
- }
- Sequence_Next
- for (; extra; extra--) {
- emit("\t%s\t0\n", labelname);
- }
- }
-