-- (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: cgtypedstmt.pp
-- Author: Andy Lowry
-- SCCS Info: @(#)cgtypedstmt.pp	1.14 3/13/90

-- This process translates statements whose opcodes depend only on the
-- absprog operator and the type of the destination operand.  None of
-- these cases requires a qualifier, so there is no operator-specific
-- code, as there is in the case of the direct-mapped operators

-- This process operates as a statement translation server throughout
-- the life of a single codegen invocation, so startup overhead is not
-- repeated.

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

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

process (initQ: cgStmtInitQ)

declare
  initArgs: cgStmtInit;
  shutQ: signalQ;
  Q: cgStmtQ;
  args: cgStmt;
  op: interpform!operation;
  emptyQual: interpform!qualifier;
  empty: empty;
begin
  receive initArgs from initQ;

  -- Establish connections for services and shutdown
  new Q;
  connect initArgs.cgStmt to Q;
  new shutQ;
  connect initArgs.shutdown to shutQ;
  return initArgs;

  -- Allocate an 'absent' LI qualifier so we can do a single 'copy'
  -- operation rather than a 'new' and a 'unite' for each translated
  -- statement
  unite emptyQual.empty from empty;

  -- Now keep performing translation requests until we get a shutdown
  -- message.
  while TRUE repeat
    select
    event shutQ
      exit done;		-- shut down when we're told to
    event Q
      receive args from Q;	-- stmt translation request

      new op;			-- allocate a new LI instruction

      block declare
	tname: typename;
	tdef: type_definition;
	primtype: primitive_types;
      begin
	-- Extract the primitive type of the first source operand
	inspect AREF(op1,args.stmt.operands,ONE) begin
	  tname <- typename#(args.cgData.Proc.objType(op1));
	  tdef <- type_definition#(FNS.typeDef(tname));
	  primtype := primitive_types#(case of tdef.specification);
	end inspect;

	-- Find LI opcode from the opcode map
	inspect entry in args.cgData.Aux.opMap[args.stmt.operator] begin
	  reveal entry.mapInfo.typed;
	  inspect tentry in entry.mapInfo.typed[primtype] begin
	    op.opcode := tentry.liOp;
	  end inspect;
	end inspect;
      end block;

      -- Translate all the operands into offset lists
      new op.operands;
      for operand in args.stmt.operands[] inspect
	insert interpform!operand#(args.cgData.Proc.objAddr(operand))
	    into op.operands;
      end for;

      -- Set an empty qualifier for each of these instructions
      op.qualifier := emptyQual;

      -- The instruction is complete... add it to the current BB
      ADDINSTR(op);

    otherwise
      exit cantHappen;

    end select;			-- end of event dispatcher

    return args;

  end while;


on exit(done)
  -- Branch here to terminate

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