An intermediate code file consists of:
intermediate‑code‑file | → | compile‑unit‑header type‑declarations? data‑definitions? function‑definitions? metadata‑declarations? |
compile‑unit‑header | → | cu ( compile‑unit‑id , metadata‑ref ) |
compile‑unit‑id | → | hex‑number | number | identifier |
hex‑number | → | hex‑digit+ |
hex‑digit | → | [0-9A-Fa-f] |
number | → | sign? (fractional‑part | digit+) exponent‑part? |
sign | → | + | - |
digit | → | [0-9] |
fractional‑part | → | digit* . digit+ | digit+ . |
exponent‑part | → | (e | E) sign? digit+ |
identifier | → | id‑start id‑cont* |
id‑start | → | 'Unicode characters having ID_Start Property' | _ |
id‑cont | → | 'Unicode characters having ID_Continue Property' | @ | _ |
metadata‑ref | → | ! digit+ |
The types of the intermediate language can be grouped into fundamental and compound types.
The following table contains a summary of fundamental types:
type | kind | signed | unsigned | size | range |
---|---|---|---|---|
void | - | - | - | - |
bool | Boolean | - | 1 byte | true | false |
sbyte | integer | signed | 1 byte | -128...127 |
byte | integer | unsigned | 1 byte | 0...255 |
short | integer | signed | 2 bytes | -32768...32767 |
ushort | integer | unsigned | 2 bytes | 0...65535 |
int | integer | signed | 4 bytes | -2147483648...2147483647 |
uint | integer | unsigned | 4 bytes | 0...4294967295 |
long | integer | signed | 8 bytes | -9223372036854775808...9223372036854775807 |
ulong | integer | unsigned | 8 bytes | 0...18446744073709551615 |
float | floating-point | - | 4 bytes | IEEE single precision floating-point type range |
double | floating-point | - | 8 bytes | IEEE double precision floating-point type range |
The void keyword represents lack of type.
Other fundamental types can be divided into Boolean, integer and floating-point types.
The integer and floating-point types are together called the arithmetic types.
There are four kinds of compound types:
The structured, array and function types used in the intermediate file has to be declared in the type declaration part of the intermediate file.
A structured type consists of a non-empty sequence of fields. Each field has a type identified using a type-ref.
A structured type has to be declared using a structure‑type‑declaration.
An array type consists of a non-empty sequence of elements of the same type. The type of the elements are identified using a a type-ref.
An array type has to be declared using a array‑type‑declaration.
A function type consists of the return type and the types of the parameters of a function. The return type and the types of the parameters are identified using a type-ref.
An function type has to be declared using a function‑type‑declaration.
A pointer type is identified using a type-ref that consists of a prefix that identifies a base type and a suffix consisting of one or more * symbols.
The base type may be fundamental type, a structured type, an array type or a function type.
The value of a pointer type object is a memory address of the pointed-to object.
type‑declarations | → | types { type‑declaration* } |
type‑declaration | → | type‑id = type ( structure‑type‑declaration | array‑type‑declaration | function‑type‑declaration ) |
structure‑type‑declaration | → | { type‑ref ( , type‑ref )* } |
array‑type‑declaration | → | [ array‑size x type‑ref ] |
function‑type‑declaration | → | function return‑type ( ( param‑type (, param‑type)* )? ) |
return‑type | → | type‑ref |
param‑type | → | type‑ref |
type‑ref | → | base‑type ** |
base‑type | → | type‑id | fundamental‑type |
type‑id | → | $T digit+ |
fundamental‑type | → | void | bool | sbyte | byte | short | ushort | int | uint | long | ulong | float | double |
array‑size | → | digit+ |
data‑definitions | → | data { data‑definition* } |
data‑definition | → | type‑ref once? identifier ( ; | = initializer ) |
initializer | → | constant |
The once flag denotes that identical data definitions may occur many times in different translation units. The linker chooses one of them and throws the rest away.
constant | → | bool‑constant | sbyte‑constant | byte‑constant | short‑constant | ushort‑constant | int‑constant | uint‑constant | long‑constant | ulong‑constant | float‑constant | double‑constant | address‑constant | array‑constant | structure‑constant | string‑constant | string‑array‑constant | conversion‑constant | clsid‑constant | symbol‑constant |
bool‑constant | → | bool (true | false) |
sbyte‑constant | → | sbyte number |
byte‑constant | → | byte number |
short‑constant | → | short number |
ushort‑constant | → | ushort number |
int‑constant | → | int number |
uint‑constant | → | uint number |
long‑constant | → | long number |
ulong‑constant | → | ulong number |
float‑constant | → | float number |
double‑constant | → | double number |
address‑constant | → | ptr‑type ( null | identifier ) |
ptr‑type | → | type‑ref |
array‑constant | → | [ (constant (, constant)* )? ] |
structure‑constant | → | { (constant (, constant)* )? } |
string‑constant | → | " [^\r\n]* " |
string‑array‑constant | → | string‑array‑prefix [ (constant (, constant)* )? ] |
string‑array‑prefix | → | u | w | b |
conversion‑constant | → | type‑ref conv ( constant ) |
clsid‑constant | → | type‑ref clsid ( (hex‑digit | -)+ ) |
symbol‑constant | → | type‑ref symbol‑value |
value | → | reg‑value | symbol‑value | literal‑value |
reg‑value | → | $ digit+ |
symbol‑value | → | @ identifier |
literal‑value | → | true | false | null | number | identifier |
ptr-value | → | value |
function‑definitions | → | function‑definition* |
function‑definition | → | function‑header { basic‑block* } |
function‑header | → | function function‑type‑id once? identifier metadata‑ref? |
function‑type‑id | → | type‑id |
basic‑block | → | label instructions |
label | → | @ digit+ |
The once flag denotes that identical function definitions may occur many times in different translation units. The linker chooses one of them and throws the rest away.
add‑instruction | → | add |
The 'add' instruction sets the result to the sum of its operands.
The type of the result and the types of the operands must be the same. The type must be an arithmetic type.
and‑instruction | → | and |
The 'and' instruction sets the result to the bitwise AND of its left and right operands.
The type of the result and the types of the operands must be the same. The type must be an integer or Boolean type.
arg‑instruction | → | arg type‑ref value |
The 'arg' instruction passes a function argument to a following function call, procedure call or trap.
The type of the operand must be an aritmetic, pointer or Boolean type.
bitcast‑instruction | → | bitcast |
The 'bitcast' instruction sets the result to its operand converted to a target type without changing the bits of the operand.
The type of the operand must be an aritmetic, pointer, function or Boolean type. The type of the result must be an arithmetic, pointer, function or Boolean type.
branch‑instruction | → | branch type‑ref value , label , label |
The 'branch' instruction transfers control to the intermediate instruction that has the true-target label if condition is true and to the intermedite instruction that has the false-target label if condition is false.
The type of the operand must be a Boolean type.
function‑call‑instruction | → | call function‑type‑id callee |
function‑type‑id | → | type‑id |
callee | → | value |
The function call 'call' instruction calls the 'callee' function that returns a result.
The type of the 'callee' must be a function or a pointer to function type. The type of the result must be the type returned by the 'callee' function.
procedure‑call‑instruction | → | call procedure‑type‑id callee |
procedure‑type‑id | → | type‑id |
callee | → | value |
The procedure call 'call' instruction calls the void 'callee' function.
The type of the 'callee' must be a function or a pointer to function type.
div‑instruction | → | div |
The 'div' instruction sets the result to the quotient of its left operand divided by its right operand.
The type of the result and the types of the operands must be the same. The type must be an arithmetic type.
elemaddr‑instruction | → | elemaddr operand , operand |
The 'elemaddr' instruction sets the result to an address of an index'th element from an aggregate pointed by ptr.
The type of the 'ptr' must be a a pointer type. The type of the result must be a pointer to the element type.
equal‑instruction | → | equal |
The 'equal' instruction sets the result to true if its left and right operands are equal and false otherwise.
The type of the operands must be the same. The type of the operands must be an arithmetic, pointer of Boolean type. The type of the result must be a Boolean type.
floattoint‑instruction | → | floattoint |
The 'floattoint' instruction sets the result to its floating-point type operand converted to an integer type.
The type of the operand must be a floating-point type. The type of the result must be an integer type.
inttofloat‑instruction | → | inttofloat |
The 'inttofloat' instruction sets the result to its integer type operand converted to a floating-point type.
The type of the operand must be an integer type. The type of the result must be a floating-point type.
inttoptr‑instruction | → | inttoptr |
The 'inttoptr' instruction sets the result to its integer type operand converted to a pointer type.
The type of the operand must be an integer type. The type of the result must be a pointer type.
jmp‑instruction | → | jmp label |
The 'jmp' instruction transfers control to the intermediate instruction that has the given label.
less‑instruction | → | less |
The 'less' instruction sets the result to true if its left operand is less than its right operand and false otherwise.
The type of the operands must be the same. The type of the operands must be an arithmetic or pointer type. The type of the result must be a Boolean type.
load‑instruction | → | load operand |
The 'load' instruction reads from memory.
The type of the operand must be a pointer type. The type of the result must be the type of the value pointed by the 'from' pointer.
local‑instruction | → | local type‑ref |
The 'local' instruction allocates space for a local variable from a function frame.
The type of the result must a pointer to a local variable type.
mod‑instruction | → | mod |
The 'mod' instruction sets the result to the remainder of the division of its left and right operands.
The type of the result and the types of the operands must be the same. The type must be an integer type.
mul‑instruction | → | mul |
The 'mul' instruction sets the result to the product of its operands.
The type of the result and the types of the operands must be the same. The type must be an arithmetic type.
neg‑instruction | → | neg |
The 'neg' instruction sets the result to its operand subtracted from zero.
no‑operation‑instruction | → | nop |
The 'nop' instruction is a no-operation.
not‑instruction | → | not |
If the operand of the 'not' instruction is a Boolean value, the instruction sets a Boolean type result to true if its operand is false and false if its operand is true. If the operand of the 'not' instruction is a an integer value, the instruction sets an integer type result to the bitwise complement of its operand.
The type of the result and the type of the operand must be the same. The type of the operand must be an integer or a Boolean type.
or‑instruction | → | or |
The 'or' instruction sets the result to the bitwise OR of its left and right operands.
The type of the result and the types of the operands must be the same. The type must be an integer or Boolean type.
param‑instruction | → | param |
The 'param' instruction receives a value of a function parameter of a given type.
ptrdiff‑instruction | → | ptrdiff operand , operand |
The 'ptrdiff' instruction sets the result to the number of elements between pointers left-ptr and right-ptr.
The type of the operands must be the same. The type of the operands must be a pointer type. The type of the result must be an integer type.
ptroffset‑instruction | → | ptroffset operand , operand |
The 'ptroffset' instruction sets the result to an address of an element having given offset added to pointer ptr.
The type of the left operand must be a pointer type. The type of the 'offset' must be an integer type. The type of the result must be a pointer type.
ptrtoint‑instruction | → | ptrtoint |
The 'ptrtoint' instruction converts its pointer type operand to an integer type.
The type of the operand must be a pointer type. The type of the result must be an integer type.
ret‑instruction | → | ret (void | type‑ref value) |
The 'ret' instruction has two forms: The first form is used for returning control from a void function, and the second form is used for returning a value from a non-void function.
shl‑instruction | → | shl |
The 'shl' instruction sets the result to its left operand shifted left by the number of bit positions indicated by its right operand.
The type of the result and the types of the operands must be the same. The type must be an integer type.
shr‑instruction | → | shr |
The 'shr' instruction sets the result to its left operand shifted right by the number of bit positions indicated by its right operand.
The type of the result and the types of the operands must be the same. The type must be an integer type.
signextend‑instruction | → | signextend |
The 'signextend' instruction increases the number of bits of its operand while preserving the value of its operand. If the operand is non-negative the vacant most significant bit positions of the result are filled with zero bits, otherwise the vacant most significant bit positions of the result are fillled with one bits.
The type of the result and the type of the operand must be the same. The type must be an aritmetic type.
store‑instruction | → | store type‑ref value , type‑ref ptr‑value |
The 'store' instruction writes a value to the memory location pointed by ptr.
The type of the 'ptr' must be a pointer type.
sub‑instruction | → | sub |
The 'sub' instruction sets the result to the difference of its operands.
The type of the result and the types of the operands must be the same. The type must be an arithmetic type.
switch‑instruction | → | switch type‑ref value label , [ type‑ref value , label (: type‑ref value , label)* ] |
The 'switch' instruction transfers control to an instruction having a label case-target if the condition is equal to the value associated with the case-target. If none of the values associated with case-targets match the condition, control is transfered to the instruction having label default-target.
The type of the 'condition' must be an integer or Boolean type. The type of each case value must be the same as the type of the condition.
trap‑instruction | → | trap type‑ref value , type‑ref value , type‑ref value |
The 'trap' instruction calls a virtual operating system trap. See System X Kernel Traps.
The types of the operands shall be byte. The second byte operand shall contain the number of the virtual operating system trap to be called, the first and the third byte operands shall be zero. The arguments to the trap function shall be passed using the arg instruction.
truncate‑instruction | → | truncate |
The 'truncate' instruction truncates its operand by throwing away the most significant bits of the operand so that it fits the type of the result.
The type of the operand must be an aritmetic type. The type of the result must be an arithmetic or Boolean type.
xor‑instruction | → | xor |
The 'xor' instruction sets the result to the bitwise exclusive OR of its left and right operands.
The type of the result and the types of the operands must be the same. The type must be an integer or Boolean type.
zeroextend‑instruction | → | zeroextend |
The 'zeroextend' instruction increases the number of bits of its operand by adding zero bits to the vacant most significant bit positions of the result.
The type of the operand must be an aritmetic or Boolean type. The type of the result must be an arithmetic type.
metada‑declarations | → | metadata { mdstruct* } |
mdstruct | → | ! digit+ = { (mdfield (, mdfield)*)? } |
mdfield | → | identifier : mditem |
mditem | → | mdbool | mdlong | mdstring | metadata‑ref |
mdbool | → | true | false |
mdlong | → | number |
mdstring | → | string‑constant |