Files
Digital-Research-Source-Code/ASSEMBLY & COMPILE TOOLS/PLM VAX COMPILER/plmvax/operand.for
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

249 lines
8.0 KiB
Fortran

C***********************************************************************
C
C OPERAND.FOR
C
C
C D I S C L A I M E R N O T I C E
C ------------------- -----------
C
C This document and/or portions of the material and data furnished
C herewith, was developed under sponsorship of the U. S. Government.
C Neither the U.S. nor the U.S.D.O.E., nor the Leland Stanford Junior
C University, nor their employees, nor their respective contractors,
C subcontractors, or their employees, makes any warranty, express or
C implied, or assumes any liability or responsibility for accuracy,
C completeness or usefulness of any information, apparatus, product
C or process disclosed, or represents that its use will not infringe
C privately-owned rights. Mention of any product, its manufacturer,
C or suppliers shall not, nor is it intended to, imply approval, dis-
C approval, or fitness for any particular use. The U. S. and the
C University at all times retain the right to use and disseminate same
C for any purpose whatsoever. Such distribution shall be made by the
C National Energy Software Center at the Argonne National Laboratory
C and only subject to the distributee furnishing satisfactory proof
C that he has a valid license from the Intel Corporation in effect.
C
C
C-----------------------------------------------------------------------
C
C This module of the PL/M-VAX compiler is used to translate a
C code tree operand into a symbolic assembly-language character
C string.
C
C-----------------------------------------------------------------------
C R E V I S I O N H I S T O R Y
C
C 20OCT81 Alex Hunter 1. Added disclaimer notice. (V5.4)
C 2. Generate long-displacement addressing
C for constants in ROM.
C 12NOV81 Alex Hunter 1. Qualify S_STATIC with P_DATA. (V6.1)
C 14NOV81 Alex Hunter 1. Major rewrite to change addressing modes.
C (V6.2)
C 03FEB82 Alex Hunter 1. Fix bug for immediate operands in LARGE
C model. (V6.6)
C
C-----------------------------------------------------------------------
CHARACTER*80 FUNCTION OPERAND(OPND,N)
INCLUDE 'PLMCOM.FOR/NOLIST'
INTEGER*4 IVAL,IFSD,ILSD
CHARACTER*32 VECNIQUE
CHARACTER*14 STRINGG,LITG
CHARACTER*10 LIT,STRING10
CHARACTER*2 DISPL
CHARACTER*3 REGNAME(REG_MIN:REG_MAX)
DATA REGNAME /'R1','R2','R3','R4','R5','R6','R7','R8','R9',
# 'R10','R11','AP','FP','SP','PC','R0'/
INTEGER*2 REGNAME_LENGTH(REG_MIN:REG_MAX)
DATA REGNAME_LENGTH /2,2,2,2,2,2,2,2,2,3,3,2,2,2,2,2/
IF (OPND.GE.REG_MIN.AND.OPND.LE.REG_MAX) THEN
OPERAND=REGNAME(OPND)
N=REGNAME_LENGTH(OPND)
RETURN
ELSEIF (OPND.EQ.ON_STACK) THEN
IF (MODEL.EQ.2 .OR. MODEL.EQ.4) THEN
OPERAND='-(SP)'
N=5
ELSE
OPERAND='-(R10)'
N=6
ENDIF
RETURN
ELSEIF (FIXLIT(OPND)) THEN
IVAL=FIXED_VAL(OPND)
LIT=STRING10(IVAL,IFSD)
OPERAND='#'//LIT(IFSD:10)
N=12-IFSD
RETURN
ELSEIF (FLOATLIT(OPND)) THEN
LITG=STRINGG(FLOAT_VAL(OPND),IFSD,ILSD)
OPERAND='#'//LITG(IFSD:ILSD)
N=ILSD-IFSD+2
RETURN
ENDIF
C -- OPERAND MUST BE A CONSTANT OR AN ATOM.
C
C --- COMPUTE WHICH ADDRESSING SCHEMA TO USE.
C
SCHEMA=1 ! Default schema.
ATMSYM=0 ! In case opnd is a constant.
IF (CONSTANT(OPND)) THEN
IF (ROM_FLAG.OR.MODEL.EQ.4) THEN
SCHEMA=3
ELSEIF (OVERLAY_FLAG) THEN
SCHEMA=7
ELSE
SCHEMA=5
ENDIF
ELSEIF (ATOM(OPND)) THEN
ATMSYM=ATOM_SYM(OPND) ! We'll need this a lot.
IF ((ATOM_FLAGS(OPND).AND.A_VECTOR).NE.0) THEN
SCHEMA=4
ELSEIF (ATOM_BASE(OPND).NE.0) THEN
SCHEMA=2
BASEREG=NODE_REG(ATOM_BASE(OPND))
ELSEIF (ATMSYM.NE.0) THEN
IF (SYMBOL_REF(ATMSYM).EQ.S_STATIC) THEN
IF (SYMBOL_PSECT(ATMSYM).EQ.P_DATA) THEN
IF (OVERLAY_FLAG) THEN
SCHEMA=7
ELSE
SCHEMA=5
ENDIF
ELSEIF (SYMBOL_PSECT(ATMSYM).EQ.P_CONSTANT) THEN
SCHEMA=3
ELSEIF (SYMBOL_PSECT(ATMSYM).EQ.P_MEMORY) THEN
SCHEMA=8
ELSEIF (SYMBOL_PSECT(ATMSYM).GT.P_MEMORY) THEN
SCHEMA=3 ! User common.
ENDIF
ELSEIF (SYMBOL_REF(ATMSYM).EQ.S_EXT) THEN
IF (SYMBOL_PSECT(ATMSYM).EQ.P_DATA) THEN
IF ((SYMBOL_FLAGS(ATMSYM).AND.S_SAME_OVERLAY).NE.0)
# THEN
SCHEMA=7
ELSE
SCHEMA=6
ENDIF
ELSEIF (SYMBOL_PSECT(ATMSYM).EQ.P_CONSTANT) THEN
SCHEMA=3
ELSEIF (SYMBOL_PSECT(ATMSYM).EQ.P_MEMORY) THEN
SCHEMA=8
ELSEIF (SYMBOL_PSECT(ATMSYM).GT.P_MEMORY) THEN
SCHEMA=3 ! User common.
ENDIF
ELSEIF (SYMBOL_REF(ATMSYM).EQ.S_ARG) THEN
SCHEMA=2
BASEREG=PROC_AP(SYMBOL_LINK(ATMSYM))
ELSEIF (SYMBOL_REF(ATMSYM).EQ.S_DYNAMIC) THEN
SCHEMA=2
BASEREG=12
ENDIF
ENDIF
ENDIF
C
C --- COMPUTE THE DISPLACEMENT MODE FIELD.
C
IF (ATOM(OPND).AND.(ATOM_FLAGS(OPND).AND.A_IMMEDIATE).NE.0 .OR.
# ATMSYM.NE.0.AND.SYMBOL_REF(ATMSYM).EQ.S_VALUE) THEN
OPERAND='#'
N=1
ELSEIF (SCHEMA.GE.5.AND.MODEL.NE.4.AND.
# .NOT.(MODEL.EQ.2.AND.SCHEMA.EQ.8)) THEN
OPERAND='W^'
N=2
ELSE
OPERAND=' '
N=0
ENDIF
C
C --- COMPUTE THE SYMBOLIC VALUE FIELD.
C
IF (CONSTANT(OPND)) THEN
OPERAND(N+1:)=LOCAL_LABEL(CONSTANT_LABEL(OPND),N1)
N=N+N1
ELSEIF (SCHEMA.EQ.4) THEN
OPERAND(N+1:)=VECNIQUE(SYMBOL_VAX_ID(ATMSYM))
N=LNB(OPERAND)
ELSE
IF (ATMSYM.NE.0) THEN
OPERAND(N+1:)=SYMBOL_VAX_ID(ATMSYM)
N=LNB(OPERAND)
ENDIF
IF (ATOM_MEM(OPND).NE.0) THEN
OPERAND(N+1:)='+'//MEMBER_VAX_ID(ATOM_MEM(OPND))
N=LNB(OPERAND)
ENDIF
IVAL=ATOM_DISP(OPND)
IF (ATMSYM.NE.0) THEN
IVAL=IVAL+SYMBOL_DISP(ATMSYM)
ENDIF
IF (IVAL.NE.0) THEN
LIT=STRING10(IVAL,IFSD)
IF (IVAL.GE.0) THEN
OPERAND(N+1:)='+'//LIT(IFSD:10)
N=N+12-IFSD
ELSE
OPERAND(N+1:)=LIT(IFSD:10)
N=N+11-IFSD
ENDIF
ENDIF
ENDIF
C
C --- COMPUTE RUNTIME RELOCATION FIELD.
C
IF (SCHEMA.EQ.7.AND.
# (.NOT.ATOM(OPND).OR.(ATOM_FLAGS(OPND).AND.A_CTIM).EQ.0)) THEN
OPERAND(N+1:)='-'//BASEC
N=N+NC+1
ENDIF
C
C --- COMPUTE THE BASE FIELD.
C
IF (SCHEMA.EQ.2) THEN
OPERAND(N+1:)='('//REGNAME(BASEREG)(:REGNAME_LENGTH(BASEREG))
# //')'
N=N+REGNAME_LENGTH(BASEREG)+2
ELSEIF (SCHEMA.EQ.4) THEN
OPERAND(N+1:)='-V.'
N=N+3
ELSEIF (SCHEMA.GE.5.AND.MODEL.NE.4.AND.
# .NOT.(MODEL.EQ.2.AND.SCHEMA.EQ.8)) THEN
IF (.NOT.ATOM(OPND).OR.(ATOM_FLAGS(OPND).AND.A_IMMEDIATE).EQ.0)
# THEN
OPERAND(N+1:)='-K.(R11)'
N=N+8
ENDIF
ELSEIF (SCHEMA.EQ.5.AND.MODEL.EQ.4) THEN
IF (.NOT.ATOM(OPND).OR.(ATOM_FLAGS(OPND).AND.A_IMMEDIATE).EQ.0)
# THEN
OPERAND(N+1:)='(R11)'
N=N+5
ELSE
OPERAND(N+1:)='+M.'
N=N+3
ENDIF
ENDIF
C
C --- COMPUTE THE INDEX FIELD.
C
IF (ATOM(OPND).AND.ATOM_SUB(OPND).NE.NULL) THEN
XREG=NODE_REG(ATOM_SUB(OPND))
OPERAND(N+1:)='['//REGNAME(XREG)(:REGNAME_LENGTH(XREG))//']'
N=N+REGNAME_LENGTH(XREG)+2
ENDIF
RETURN
END