/* -------------------------------------------------------------------------- * Code generator * * Copyright (c) The University of Nottingham and Yale University, 1994-1997. * All rights reserved. See NOTICE for details and conditions of use etc... * Hugs version 1.4, December 1997 * * $RCSfile: codegen.c,v $ * $Revision: 1.8 $ * $Date: 1999/07/06 15:24:36 $ * ------------------------------------------------------------------------*/ #include "prelude.h" #include "storage.h" #include "backend.h" #include "connect.h" #include "errors.h" #include "Assembler.h" #include "link.h" #include "Rts.h" /* IF_DEBUG */ #include "RtsFlags.h" /* -------------------------------------------------------------------------- * Local function prototypes: * ------------------------------------------------------------------------*/ #define getPos(v) intOf(stgVarInfo(v)) #define setPos(v,sp) stgVarInfo(v) = mkInt(sp) #define getObj(v) ptrOf(stgVarInfo(v)) #define setObj(v,obj) stgVarInfo(v) = mkPtr(obj) #define repOf(x) charOf(stgVarRep(x)) static void cgBind ( AsmBCO bco, StgVar v ); static Void pushVar ( AsmBCO bco, StgVar v ); static Void pushAtom ( AsmBCO bco, StgAtom atom ); static Void alloc ( AsmBCO bco, StgRhs rhs ); static Void build ( AsmBCO bco, StgRhs rhs ); static Void cgExpr ( AsmBCO bco, AsmSp root, StgExpr e ); static AsmBCO cgAlts ( AsmSp root, AsmSp sp, List alts ); static void testPrimPats ( AsmBCO bco, AsmSp root, List pats, StgExpr e ); //static void cgPrimAlt ( AsmBCO bco, AsmSp root, List vs, StgExpr e ); static AsmBCO cgLambda ( StgExpr e ); static AsmBCO cgRhs ( StgRhs rhs ); static void beginTop ( StgVar v ); static void endTop ( StgVar v ); static StgVar currentTop; /* -------------------------------------------------------------------------- * * ------------------------------------------------------------------------*/ static Cell cptrFromName ( Name n ) { char buf[1000]; void* p; Module m = name(n).mod; Text mt = module(m).text; sprintf(buf,"%s_%s_closure", textToStr(mt), textToStr(name(n).text) ); p = lookupOTabName ( m, buf ); if (!p) { ERRMSG(0) "Can't find object symbol %s", buf EEND; } return mkCPtr(p); } static Bool varHasClosure( StgVar v ) { return asmObjectHasClosure((AsmClosure*)ptrOf(stgVarInfo(v))); } /* should be AsmClosure* */ void* closureOfVar( StgVar v ) { return asmClosureOfObject((AsmClosure*)ptrOf(stgVarInfo(v))); } char* lookupHugsName( void* closure ) { extern Name nameHw; Name nm; for( nm=NAMEMIN; nm length(args); fprintf ( stderr, "nativeCall: name %s, arity %d, args %d\n", nameFromOPtr(cptrOf(fun)), name(fun0).arity, length(args) ); } else { itsaPAP = FALSE; if (nonNull(stgVarBody(fun)) && whatIs(stgVarBody(fun)) == LAMBDA && length(stgLambdaArgs(stgVarBody(fun))) > length(args) ) itsaPAP = TRUE; } if (itsaPAP) { AsmSp start = asmBeginMkPAP(bco); map1Proc(pushAtom,bco,reverse(args)); pushAtom(bco,fun); asmEndMkPAP(bco,getPos(v),start); /* optimisation */ } else { AsmSp start = asmBeginMkAP(bco); map1Proc(pushAtom,bco,reverse(args)); pushAtom(bco,fun); asmEndMkAP(bco,getPos(v),start); } return; } case LAMBDA: /* optimisation */ doNothing(); /* already pushed in alloc */ break; /* These two cases look almost identical to the default but they're really * special cases of STGAPP. The essential thing here is that we can't call * cgRhs(rhs) because that expects the rhs to have no free variables when, * in fact, the rhs is _always_ a free variable. * * ToDo: a simple optimiser would eliminate all examples * of this except "let x = x in ..." */ case NAME: rhs = name(rhs).stgVar; case STGVAR: { AsmSp start = asmBeginMkAP(bco); pushAtom(bco,rhs); asmEndMkAP(bco,getPos(v),start); } return; default: { AsmSp start = asmBeginMkAP(bco); /* make it updateable! */ asmClosure(bco,cgRhs(rhs)); asmEndMkAP(bco,getPos(v),start); return; } } } /* -------------------------------------------------------------------------- * Top level variables * * ToDo: these should be handled by allocating a dynamic unentered CAF * for each top level variable - this should be simpler! * ------------------------------------------------------------------------*/ #if 0 /* appears to be unused */ static void cgAddVar( AsmObject obj, StgAtom v ) { if (isName(v)) { v = name(v).stgVar; } assert(isStgVar(v)); asmAddPtr(obj,getObj(v)); } #endif /* allocate AsmObject for top level variables * any change requires a corresponding change in endTop */ static void beginTop( StgVar v ) { StgRhs rhs; assert(isStgVar(v)); currentTop = v; rhs = stgVarBody(v); switch (whatIs(rhs)) { case STGCON: { //List as = stgConArgs(rhs); setObj(v,asmBeginCon(stgConInfo(stgConCon(rhs)))); break; } case LAMBDA: #ifdef CRUDE_PROFILING setObj(v,asmBeginBCO(currentTop)); #else setObj(v,asmBeginBCO(rhs)); #endif break; default: setObj(v,asmBeginCAF()); break; } } static void endTop( StgVar v ) { StgRhs rhs = stgVarBody(v); currentTop = v; switch (whatIs(rhs)) { case STGCON: { List as = stgConArgs(rhs); AsmCon con = (AsmCon)getObj(v); for( ; nonNull(as); as=tl(as)) { StgAtom a = hd(as); switch (whatIs(a)) { case STGVAR: /* should be a delayed combinator! */ asmAddPtr(con,(AsmObject)getObj(a)); break; case NAME: { StgVar var = name(a).stgVar; assert(var); asmAddPtr(con,(AsmObject)getObj(a)); break; } #if !USE_ADDR_FOR_STRINGS case STRCELL: asmAddPtr(con,asmStringObj(textToStr(textOf(a)))); break; #endif default: /* asmAddPtr(con,??); */ assert(0); break; } } asmEndCon(con); break; } case LAMBDA: /* optimisation */ { /* ToDo: merge this code with cgLambda */ AsmBCO bco = (AsmBCO)getObj(v); AsmSp root = asmBeginArgCheck(bco); map1Proc(cgBind,bco,reverse(stgLambdaArgs(rhs))); asmEndArgCheck(bco,root); cgExpr(bco,root,stgLambdaBody(rhs)); asmEndBCO(bco); break; } default: /* updateable caf */ { AsmCAF caf = (AsmCAF)getObj(v); asmEndCAF(caf,cgRhs(rhs)); break; } } } static void zap( StgVar v ) { // ToDo: reinstate // stgVarBody(v) = NIL; } /* external entry point */ Void cgBinds( List binds ) { List b; int i; #if 0 if (lastModule() != modulePrelude) { printf("\n\ncgBinds: before ll\n\n" ); for (b=binds; nonNull(b); b=tl(b)) { printStg ( stdout, hd(b) ); printf("\n\n"); } } #endif binds = liftBinds(binds); #if 0 if (lastModule() != modulePrelude) { printf("\n\ncgBinds: after ll\n\n" ); for (b=binds; nonNull(b); b=tl(b)) { printStg ( stdout, hd(b) ); printf("\n\n"); } } #endif for (b=binds,i=0; nonNull(b); b=tl(b),i++) { beginTop(hd(b)); } for (b=binds,i=0; nonNull(b); b=tl(b),i++) { //printf("endTop %s\n", maybeName(hd(b))); endTop(hd(b)); } //mapProc(zap,binds); } /* -------------------------------------------------------------------------- * Code Generator control: * ------------------------------------------------------------------------*/ Void codegen(what) Int what; { switch (what) { case INSTALL: /* deliberate fall though */ case RESET: break; case MARK: break; } liftControl(what); } /*-------------------------------------------------------------------------*/