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:
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 consecutiveILM
blocks which can be used to produce a singleILI
block. The threshold is simply the number ofILM
words seen in theILM
block(s) from which theILI
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
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) )
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) )
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) ) )
Test validity of shift amount for this machine.
SHIFTOK(x)
((x) >= 0 ? TRUE : FALSE)
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:
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:
Define action name lines of the form:
.DN actionname
actionname
the name of the action to define such as
LSHIFT
.
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.
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.
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 thedtypeinfo
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.
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.
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 thedtypeinfo
array is initialized in the correct order.
Outputs¶
MACHAR produces two output files.
machar.h — contains the C macro definitions for characteristics and actions.
machardf.h — contains the
dtypeinfo
array containing data type size and alignment information.