Appendix III - Target Machine

Introduction

This appendix defines the idiosyncracies of the target machine architecture: presence of divide instructions, byte ordering, size requirements of data types, how shifts are done, etc. The target machine characteristics are defined using C macros and structures. These are included by the compiler so that it can test for the presence of a characteristic or determine how an action is to be performed on the target machine for constant folding. Those machine characteristics that cannot be implemented with C macros are implemented in code.

There are two classes of macros that can be defined; characteristic macros and action macros. Characteristic macros are used as simple boolean flags that indicate the presence or absence of a particular machine capability. For example, there would be a characteristic macro defined for the integer divide capability. If the target machine did not have that capability then a characteristic macro would not be defined for that capability.

Action macros communicate to the compiler a value or how an operation is to be performed for constant folding. An example of a value is the threshold for breaking blocks. An example of an operation is the shift operation. The compiler needs to know what code it must execute when constant folding a shift operation.

The following table lists the possible characteristic macros. Those characteristics that are present for this target machine are indicated in the activated column.

Characteristic Macros

Macro Name

Description

Activated

TM_BIG_ENDIAN

big endian byte order

no

TM_UIDIV

unsigned integer divide instruction

no

TM_IDIV

integer divide instruction

no

TM_UIMOD

unsigned integer mod instruction

no

TM_IMOD

integer mod instruction

no

TM_IDIV2

divide by power of 2 instruction

no

TM_FDIV

single precision divide instruction

no

TM_DDIV

double precision divide instruction

no

TM_FRCP

single precision Newton’s reciprocal

no

TM_DRCP

double precision Newton’s reciprocal

no

TM_UICMP

unsigned integer compare instruction

yes

TM_SQRT

square root instruction

no

TM_FIELD_INST

bit field support instructions

no

TM_64BIT

64 bit stack, pointer, long

yes

TM_LPCNT

loop counter instruction

yes

TM_LPCMP

loop compare & branch instructions

no

TM_LPSIGN

loop counter is a signed quantity

yes

TM_REVERSE_SHIFT

shift of negative reverses direction

no

TM_PREFER_SIGNED

signed byte/halfwd loads vs. unsigned

yes

TM_AUTOINC_IR

auto increment when addressing ints/pointers

no

TM_AUTOINC_FP

auto increment when addressing single/double

yes

TM_FCMPZ

single precision compare with zero

yes

TM_DCMPZ

double precision compare with zero

yes

TM_QCMPZ

quad precision compare with zero

yes

TM_FCJMPZ

single precision compare with zero and jump

yes

TM_DCJMPZ

double precision compare with zero and jump

yes

TM_QCJMPZ

quad precision compare with zero and jump

yes

TM_REAL8

default real size is 8

no

The list of code macros used by this compiler and machine architecture are:

  1. For certain targets, it’s advantageous for both compile and execution time to limit the size of the ILI blocks produced by the front-end. Block breaking is performed by limiting the number of consecutive ILM blocks which can be used to produce a single ILI block. The threshold is simply the number of ILM words seen in the ILM block(s) from which the ILI were generated. If block breaking is not needed, this value should be a large 32-bit integer where the expression value + value/2 does not overflow.

    TM_ILM_THRESH

    1024

  2. Constant fold shift per target machine; operand which is shifted is a signed quantity.

    LSHIFT(x,y)

    ( (x) << ((y)&31) )

    RSHIFT(x,y)

    ( (x) >> ((y)&31) )

  3. Constant fold shift per target machine; operand which is shifted is an unsigned quantity.

    ULSHIFT(x,y)

    ( (x) << ((y)&31) )

    URSHIFT(x,y)

    ( (unsigned int)(x) >> ((y)&31) )

  4. Arithmetic right shift.

    ARSHIFT(x,y)

    ( ((y)&31) == 0 ? (x) : ( (x) & 0x80000000 ? ( (unsigned int)(x) >> ((y)&31) ) | ( ((unsigned int)-1) << (32-((y)&31)) ) : (x) >> ((y)&31) ) )

  5. Test validity of shift amount for this machine.

    SHIFTOK(x)

    ((x) >= 0 ? TRUE : FALSE)

  6. Correct shift count if it fails SHIFTOK.

    SHIFT_FIX(x)

    ((x)&31)

Also, specific to a particular machine architecture is the size and alignment requirements of the various data types in the language. The structure dtypeinfo is indexed by the data type to determine the size and alignment requirements for that data type.

For code maintenance simplicity, there are 5 tables, one for each target machine; the actual table used at compile time is determined by XBIT values.

The first table is for machine 0 which is the default, a x86-64 machine.

The data types, their sizes, and alignment requirements for this compiler and target machine are listed in the following table.

Data Type Information

Data Type

Size

Align

Bits

Scale

Fval

Tname

print name

kind

TY_WORD

4

3

32

0

reg0

Unsigned Integer

TY_DWORD

8

7

32

0

reg3

Unsigned Integer

TY_BINT

1

0

8

0

reg0

Byte Integer

byte

1

TY_SINT

2

1

16

0

reg0

Short Integer

integer*2

2

TY_INT

4

3

32

0

reg0

Integer

integer

4

TY_INT8

8

7

64

0

reg2

Integer*8

integer*8

8

TY_HALF

2

1

16

0

reg1

Floating Point Half

real

2

TY_REAL

4

3

32

0

reg1

Floating Point Real

real

4

TY_DBLE

8

7

64

0

reg2

Double Precision Real

double precision

8

TY_QUAD

16

15

128

0

reg2

Quad Precision Real

real*16

16

TY_HCMPLX

4

1

32

0

reg2

Half Complex

half complex

2

TY_CMPLX

8

3

64

0

reg2

Complex

complex

4

TY_DCMPLX

16

7

128

0

reg3

Double Precision Complex

double complex

8

TY_QCMPLX

16

7

128

0

reg3

Quad Precision Complex

complex*32

16

TY_BLOG

1

0

8

0

reg0

Byte Logical

logical*1

1

TY_SLOG

2

1

16

0

reg0

Short Logical

logical*2

2

TY_LOG

4

3

32

0

reg0

Logical

logical

4

TY_LOG8

8

7

64

0

reg2

Logical*8

logical*8

8

TY_CHAR

1

0

8

0

mem2

Character

character

1

TY_PTR

8

7

64

0

reg0

Address of

TY_NCHAR

2

1

16

0

mem2

Kanji Character String

ncharacter

2

TY_128

16

15

128

0

reg2

128-bit

128_bit

TY_256

32

31

256

0

reg2

256-bit

256_bit

TY_INT128

16

15

128

0

reg2

Quad Integer

integer(16)

16

TY_LOG128

16

15

128

0

reg2

Quad Logical

logical(16)

16

TY_FLOAT128

16

15

128

0

reg2

Quad Precision Real

real(16)

16

TY_CMPLX128

32

15

256

0

reg3

Quad Precision Complex

complex(32)

16

The second table is for machine 1 which is a T3E, byte-addressible 8-byte integer/pointer machine.

The data types, their sizes, and alignment requirements for this compiler and target machine are listed in the following table.

Data Type Information

Data Type

Size

Align

Bits

Scale

Fval

Tname

print name

kind

TY_WORD

4

3

32

0

reg0

Unsigned Integer

TY_DWORD

8

7

64

0

reg3

Unsigned Integer

TY_BINT

4

3

8

0

reg0

Byte Integer

integer*1

1

TY_SINT

4

3

16

0

reg0

Short Integer

integer*2

2

TY_INT

4

3

32

0

reg0

Integer

integer*4

4

TY_INT8

8

7

64

0

reg2

Integer*8

integer*8

8

TY_HALF

2

1

16

0

reg1

Floating Point Half

real

2

TY_REAL

4

3

32

0

reg1

Floating Point Real

real*4

4

TY_DBLE

8

7

64

0

reg2

Double Precision Real

real*8

8

TY_QUAD

16

15

128

0

reg2

Quad Precision Real

real*16

16

TY_HCMPLX

4

1

32

0

reg2

Half Complex

half complex

2

TY_CMPLX

8

3

64

0

reg3

Complex

complex*8

4

TY_DCMPLX

16

7

128

0

reg3

Double Precision Complex

complex*16

8

TY_QCMPLX

32

15

256

0

reg3

Quad Precision Complex

complex*32

16

TY_BLOG

4

3

8

0

reg0

Byte Logical

logical*1

1

TY_SLOG

4

3

16

0

reg0

Short Logical

logical*2

2

TY_LOG

4

3

32

0

reg0

Logical

logical*4

4

TY_LOG8

8

7

64

0

reg2

Logical*8

logical*8

8

TY_CHAR

1

0

8

0

mem2

Character

character

1

TY_PTR

8

7

64

0

reg0

Address of

TY_NCHAR

2

1

16

0

mem2

Kanji Character String

ncharacter

2

The third table is for machine 2 which is a C90, word-addressible 8-byte integer/pointer machine.

The data types, their sizes, and alignment requirements for this compiler and target machine are listed in the following table.

Data Type Information

Data Type

Size

Align

Bits

Scale

Fval

Tname

print name

kind

TY_WORD

8

7

64

0

reg0

Unsigned Integer

TY_DWORD

8

7

64

0

reg3

Unsigned Integer

TY_BINT

8

7

64

0

reg0

Byte Integer

integer

8

TY_SINT

8

7

64

0

reg0

Short Integer

integer

8

TY_INT

8

7

64

0

reg0

Integer

integer

8

TY_INT8

8

7

64

0

reg2

Integer*8

integer

8

TY_HALF

2

1

16

0

reg1

Floating Point Half

real

2

TY_REAL

8

7

64

0

reg1

Floating Point Real

real

8

TY_DBLE

8

7

64

0

reg2

Double Precision Real

real

8

TY_QUAD

16

15

128

0

reg2

Quad Precision Real

real

16

TY_HCMPLX

4

1

32

0

reg2

Half Complex

half complex

2

TY_CMPLX

16

7

64

0

reg3

Complex

complex

8

TY_DCMPLX

16

7

128

0

reg3

Double Precision Complex

complex

8

TY_QCMPLX

32

15

256

0

reg3

Quad Precision Complex

double complex

16

TY_BLOG

8

7

64

0

reg0

Byte Logical

logical

1

TY_SLOG

8

7

64

0

reg0

Short Logical

logical

2

TY_LOG

8

7

64

0

reg0

Logical

logical

4

TY_LOG8

8

7

64

0

reg2

Logical*8

logical

8

TY_CHAR

1

0

8

0

mem2

Character

character

1

TY_PTR

8

7

64

0

reg0

Address of

TY_NCHAR

8

7

64

0

mem2

Kanji Character String

ncharacter

2

The fourth table is for machine 3 which is a Fortran-90 target with integer kinds (1), (2), (4), and (8), real kinds (4), (8), and (16), and complex kinds (4), (8) and (16), and with 8-byte pointers, e.g. AArch64.

The data types, their sizes, and alignment requirements for this compiler and target machine are listed in the following table.

Data Type Information

Data Type

Size

Align

Bits

Scale

Fval

Tname

print name

kind

TY_WORD

4

3

32

0

reg0

Unsigned Integer

TY_DWORD

8

7

32

0

reg3

Unsigned Integer

TY_BINT

1

0

8

0

reg0

Byte Integer

integer(1)

1

TY_SINT

2

1

16

0

reg0

Short Integer

integer(2)

2

TY_INT

4

3

32

0

reg0

Integer

integer

4

TY_INT8

8

7

64

0

reg2

Integer*8

integer(8)

8

TY_HALF

2

1

16

0

reg1

Half Precision Real

real(2)

2

TY_REAL

4

3

32

0

reg1

Single Precision Real

real

4

TY_DBLE

8

7

64

0

reg2

Double Precision Real

real(8)

8

TY_QUAD

16

15

128

0

reg2

Quad Precision Real

real(16)

16

TY_HCMPLX

4

1

32

0

reg2

Half Precision Complex

half complex

2

TY_CMPLX

8

3

64

0

reg2

Single Precision Complex

complex

4

TY_DCMPLX

16

7

128

0

reg3

Double Precision Complex

complex(8)

8

TY_QCMPLX

32

15

256

0

reg3

Quad Precision Complex

complex(16)

16

TY_BLOG

1

0

8

0

reg0

Byte Logical

logical(1)

1

TY_SLOG

2

1

16

0

reg0

Short Logical

logical(2)

2

TY_LOG

4

3

32

0

reg0

Logical

logical

4

TY_LOG8

8

7

64

0

reg2

Logical*8

logical(8)

8

TY_CHAR

1

0

8

0

mem2

Character

character

1

TY_PTR

8

7

64

0

reg0

Address of

TY_NCHAR

2

1

16

0

mem2

Kanji Character String

ncharacter

2

The fifth table is for machine 4 which is a Fortran-90 target which has the following data types: logical(4) and (8), integer(4) and (8), real(4), (8) and (16), and complex(4), (8) and (16), and with 8-byte pointers, e.g. the NEC SX/4.

The data types, their sizes, and alignment requirements for this compiler and target machine are listed in the following table.

Data Type Information

Data Type

Size

Align

Bits

Scale

Fval

Tname

print name

kind

TY_WORD

4

3

32

0

reg0

Unsigned Integer

TY_DWORD

8

7

64

0

reg3

Unsigned Integer

TY_BINT

4

3

32

0

reg0

Byte Integer

integer

4

TY_SINT

4

3

32

0

reg0

Short Integer

integer

4

TY_INT

4

3

32

0

reg0

Integer

integer

4

TY_INT8

8

7

64

0

reg2

Integer*8

integer(8)

8

TY_HALF

2

1

16

0

reg1

Floating Point Half

real

2

TY_REAL

4

3

32

0

reg1

Floating Point Real

real

4

TY_DBLE

8

7

64

0

reg2

Double Precision Real

double precision

8

TY_QUAD

16

15

128

0

reg2

Quad Precision Real

real(16)

16

TY_HCMPLX

4

1

32

0

reg2

Half Complex

half complex

2

TY_CMPLX

8

3

64

0

reg2

Complex

complex

4

TY_DCMPLX

16

7

128

0

reg3

Double Precision Complex

complex(8)

8

TY_QCMPLX

32

15

256

0

reg3

Quad Precision Complex

complex(16)

16

TY_BLOG

4

3

32

0

reg0

Byte Logical

logical

4

TY_SLOG

4

3

32

0

reg0

Short Logical

logical

4

TY_LOG

4

3

32

0

reg0

Logical

logical

4

TY_LOG8

8

7

64

0

reg2

Logical*8

logical(8)

8

TY_CHAR

1

0

8

0

mem2

Character

character

1

TY_PTR

8

7

64

0

reg2

Address of

TY_NCHAR

2

1

16

0

mem2

Kanji Character String

ncharacter

2

Target Machine Characteristics Utility (MACHAR)

MACHAR reads the nroff source for this appendix and extracts information to build the C include files containing the macro definitions for the target machine characteristics, actions, and data type information. MACHAR also reads symtab.h for a specific compiler to determine what the list of data types are. If either of the input files change then MACHAR must be rerun.

Inputs

MACHAR reads two input files:

  1. machar.n — Target machine characteristics file. Defines the target machine characteristics. This file contains the nroff source for this appendix so that this appendix as well as the C macro files can be generated from the same source file. It contains nroff macros and tbl commands that are also recognized as directives to MACHAR. The following kinds of directive lines are used:

    1. Define action name lines of the form:

      .DN actionname
      
      actionname

      the name of the action to define such as LSHIFT.

    2. Define action lines of the form:

      .DA "action"
      
      action

      the C macro code the compiler uses to perform the action given by actionname. Action must be enclosed in double quotes. One or more .DA lines must be specified for a macro containing macro code. The .DA line(s) are associated with the most recently encountered actionname. More than one .DA line may be required to express very large macro definitions. C continuation characters are not required on multiple action lines.

    3. Define characteristic lines:

      %TM_char%description%present
      
      TM_char

      the target machine characteristic to define. For example, TM_UIDIV.

      description

      a short description of what the characteristic is.

      present

      a value of yes or no indicating whether this macro is defined for this architecture.

    4. Define data type size and alignment lines:

      %TY_type%size%align%bits%scale%fval%description
      
      TY_type

      the data type to be specified. For example, TY_DBLE. The possible values for type are listed above.

      size

      the number of bytes required for datatype.

      align

      the number of bytes required to align datatype properly. This value is added to the current byte address to ensure that the desired data type starts on an address consistent with its alignment requirements. For example, byte integers’ value would be zero since they need only start on byte boundaries. Data types requiring alignment on 2-byte boundaries would use a value of one.

      bits

      the number of bits required for datatype.

      scale

      the scaling factor allowed for datatype. An architecture may allow an index (subscript) to be scaled when involved in an effective address calculation. This value indicates the scaling factor which can be applied to a subscript instead of multiplying the subscript by the datatype’s size. This value is the number of bits the subscript is scaled (shifted left). For example, a double could have a scaling factor of 3 (the subscript is shifted left 3 positions). Note that a value of 0 implies either a byte datatype or that the architecture does not allow scaling of subscripts.

      fval

      indicates how the value of a function of this type is returned and also indicates the return group to which the function belongs (i.e., certain function return types are returned in the same register). The possible values are ‘reg<d>’ (value is returned in a register), ‘mem<d>’ (value is returned in a temporary and its address is an implicit argument to the function), and ‘na’ (not applicable). <d> is a digit (0, 1, 2, etc.) indicating the group. These values are stored in the dtypeinfo array. A value of -1 indicates ‘na’. Otherwise, the value is divided into two fields: the rightmost 2 bits indicate ‘reg’ or ‘mem’ (0, 1, respectively). The remaining bits represent the group value (0, 1, etc.).

      description

      a textual description of the data type.

    5. Support for multiple types of machines; this is used for the pghpf translator, for which the source files are identical, but the word sizes are different. A line of the form

      .NM 5
      

      is used to tell the utility to generate datatype initializations for five machines. A line of the form

      .MA number
      

      before the TY_type table tells the utility that the following table is for the given machine number, where number must be less than the number given in the NM directive.

    1. symtab.h — the output file produced by the SYMINI utility. This file is scanned for data type definitions, for example TY_INT to determine their numeric value. This is done to guarantee that the dtypeinfo array is initialized in the correct order.

Outputs

MACHAR produces two output files.

  1. machar.h — contains the C macro definitions for characteristics and actions.

  2. machardf.h — contains the dtypeinfo array containing data type size and alignment information.