-- (C) Copyright International Business Machines Corporation 23 January 
-- 1990.  All Rights Reserved. 
--  
-- See the file USERAGREEMENT distributed with this software for full 
-- terms and conditions of use. 
-- File: cginit.pp
-- Author: Andy Lowry
-- SCCS Info: @(#)cginit.pp	1.42 3/15/90

-- This function loads code for other functions that will be needed by
-- the code generator, and initializes various "global" tables.

#include "typemark.h"
#include "codegen.h"

cgInit: using (interpform, common, cgInternal, cgInit, LIStuff)

process (Q: cgInitQ)

declare
  empty: empty;
  shutQ: signalQ;
  args: cgInit;
  -- signal ports that will cause the servers started by cgInit to
  -- shut down
  stmtShut: signalPort;
  directStmtShut: signalPort;
  typedStmtShut: signalPort;
  typeDefShut: signalPort;
  compOffsetsShut: signalPort;
begin
  receive args from Q;

  -- Establish 'shutdown' signal connection
  new shutQ;
  connect args.finish to shutQ;

  -- Fill in the auxiliary data record
  new args.cgData.Aux;
  block declare
    poly: polymorph;
  begin
    poly <- polymorph#(args.loadobj(S("opmap.obj")));
    unwrap args.cgData.Aux.opMap from poly {init};
  end block;

  -- Load all the functions and fill them in 
  new FNS;
  FNS.optimize <-optimizeFn#(PROCEDURE(args.load(S("optimize"))));
  FNS.cgProcess <- cgProcessFn#(PROCEDURE(args.load(S("cgprocess"))));
  FNS.cgProcInit <- cgProcInitFn#(PROCEDURE(args.load(S("cgprocinit"))));
  FNS.cgClause <- cgClauseFn#(PROCEDURE(args.load(S("cgclause"))));
  FNS.BBAssemble <- BBAssembleFn#(PROCEDURE(args.load(S("bbassemble"))));

  -- Server-style statement translators
  stmtShut <- signalPort#(
      (cgStmtInitFn#(PROCESS(args.load(S("cgstmt")))))
          (FNS.cgStmt));
  directStmtShut <- signalPort#(
      (cgStmtInitFn#(PROCESS(args.load(S("cgdirectstmt")))))
          (FNS.cgDirectStmt));
  typedStmtShut <- signalPort#(
      (cgStmtInitFn#(PROCESS(args.load(S("cgtypedstmt")))))
	  (FNS.cgTypedStmt));

  --  Utility functions
  FNS.LIStuff <- LIStuffFn#(PROCEDURE(args.load(S("listuff"))));
  FNS.breakSelector <-
      breakSelectorFn#(PROCEDURE(args.load(S("breakselector"))));
  FNS.cgSelector <- cgSelectorFn#(PROCEDURE(args.load(S("cgselector"))));
  FNS.newTableInfo <- newTableInfoFn#(PROCEDURE(args.load(S("newtableinfo"))));
  FNS.atoi <- atoiFn#(PROCEDURE(args.load(S("cgatoi"))));
--  FNS.ator <- atorFn#(PROCEDURE(args.load(S("ator"))));
  FNS.clauseUsesObj <-
      clauseUsesObjFn#(PROCEDURE(args.load(S("clauseusesobj"))));
  FNS.lkupType <- lkupTypeFn#(PROCEDURE(args.load(S("lkuptype"))));
  FNS.objAddrInit <- objAddrInitFn#(PROCEDURE(args.load(S("objaddr"))));
  FNS.varCaseID <- varCaseIDFn#(PROCEDURE(args.load(S("varcaseid"))));

  -- Utility servers that need to be initialized with cgData
  typeDefShut <- signalPort#(
      (typeDefInitFn#(PROCESS(args.load(S("typedef")))))
	  (args.cgData.Prog,FNS.typeDef));
  compOffsetsShut <- signalPort#(
      (compOffsetsInitFn#(PROCESS(args.load(S("compoffsets")))))
	  (args.cgData.Prog,FNS.typeDef,FNS.compOffsets));

  -- following macro builds and installs an instruction template with
  -- no operands.
# define MKTPLT(name,code,qtype,qval) \
  block declare op: interpform!operation; begin \
    new op; op.opcode <- interpform!opcode@TYPEMARK@'code'; \
    new op.operands; \
    unite op.qualifier.qtype from qval; \
    args.cgData.Tplt.name <- op; \
  end block

  -- fill in instruction templates
  new args.cgData.Tplt;
  MKTPLT(boolF,boolean,boolean,FALSE);
  MKTPLT(boolT,boolean,boolean,TRUE);
  MKTPLT(noop,noop,empty,empty);
  MKTPLT(endblock,endblock,empty,empty);
  MKTPLT(endprocess,endprocess,empty,empty);
  MKTPLT(discard,discard,empty,empty);

  -- Initialize scratchpad information as needed
  new args.cgData.scratch;
  new args.cgData.scratch.selInfo;

  return args;			-- all done

  -- Now wait for the shutdown signal, and when it comes, shut down
  -- all the servers we started
  select
  event shutQ
    send empty to stmtShut;
    send empty to directStmtShut;
    send empty to typedStmtShut;
    send empty to typeDefShut;
    send empty to compOffsetsShut;
  otherwise
    exit cantHappen;
  end select;

on exit(cantHappen)
  print S("CantHappen exit taken in cginit");
end process
