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

-- This module transates 'position_of_element' statements.  Either a
-- 'position' or 'scan_position' is used, depending on whether a
-- scan-style lookup was used for the selector corresponding to the
-- source operand.  The 'position' instruction is used if so, and is
-- efficient since the current position is stored in the corresponding
-- selector frame.  Otherwise, the 'scan_position' instruction must be
-- used to scan through the table and search for the current element.

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

cgPosOfElt: using (cgInternal, interpform)

process (Q: cgStmtQ)
  
declare
  args: cgStmt;
  op: interpform!operation;
  eltobj: objectname;
  empty: empty;
begin
  receive args from Q;
  
  -- Locate the selector info record stored for the selector
  -- corresponding to the source operand
  eltobj := objectname#(AREF(tmp,args.stmt.operands,ONE));
  inspect si in args.cgData.scratch.selInfo[eltobj.root] begin
    -- Generate the appropriate instruction
    new op;
    -- Dest and source operands translated directly
    new op.operands;
    insert interpform!operand#(args.cgData.Proc.objAddr(objectname#
	    (AREF(tmp,args.stmt.operands,ZERO)))) into op.operands;
    insert interpform!operand#(args.cgData.Proc.objAddr(eltObj))
	into op.operands;
    if B(si.lkup = lookupType#'scan') then
      -- scan style lookup... use the quick version
      op.opcode <- interpform!opcode#'position';
    else
      -- non-scan lookup... use the longer form, and add the table
      -- address as a second source operand
      op.opcode <- interpform!opcode#'scan_position';
      insert interpform!operand#(copy of si.tblAddr) into op.operands;
    end if;
    unite op.qualifier.empty from empty;
    ADDINSTR(op);
  end inspect;
  
  return args;
  
end process
      
