$A Escape = '/' /a page=58 /a just=1; mark=2 /a top=6; bottom=3 /a pageno=1 /a tab=2,8,16,19,22 /a left=8; line=68 /b8 /l3m I-code V1.3 Working-Notes Peter S. Robertson 1 October 1984 /l0 1 Philosophy 2 Definitions 3 Conventions 4 Instructions Appendix 1 Encodings Appendix 2 Instructions which set the condition-code Appendix 3 Instructions which test the condition-code Note: This document in not intended to be a complete formal description of I-code Copyright (c) 1984 Lattice Logic Limited 9, Wemyss Place Edinburgh EH3 6DH Scotland /n /Lm 1 Philosophy /b I-code is an intermediate code used to provide an interface between the machine-independent and machine-dependent sections of a compiler. /b Most intermediate codes in use today describe the execution of an abstract machine which performs the desired computation. For example, the intermediate code for a statement of the form: X/ =/ Y+Z would describe the operations of the abstract machine which would compute the value of Y+Z and assign it to X. Using this sort of code the machine-dependent section of the compiler has to map the abstract machine onto the real target machine. /b I-code uses a fundamentally different model. It describes the execution of an abstract compiler which generates target code to perform the desired computation; it does not describe an abstract machine which will perform that computation. It is vital to understand that it does not describe the function of the program directly but describes it indirectly via the abstract compiler. It is this indirection which gives I-code the power to be machine-independent without sacrificing efficiency in the executable programs which it can be used to generate. /b There are two important corollaries of this. Firstly the structures and operations associated with the abstract compiler need have no counterparts in the object program. For example the target machine need have no hardware or software stack and neither need it have a true condition code. Secondly the code assumes that the operations it describes will be performed by the abstract compiler in the order specified with no omissions. In particular the control transfer instructions do not transfer control in the abstract compiler but indicate changes of control flow in the program which is being compiled. This also does not mean that any of the operations need have counterparts in the object program nor that the order of the generated code need correspond to the order of the I-code. /b For example the Algol-60 statement: A := if B then C else D; could not be encoded in the seemingly obvious way: /l0i Stack A Stack B; Test-Boolean; BF 1 Stack C; Forward 2 Label 1 Stack D Label 2 Assign-Value /b0 as this would assign D to C, the last two objects stacked prior to the Assign-Value instruction, and leave A on the stack. /n /Lm 2 Definitions /a indent=3 /b/t1 byte-order /t3 All multi-byte values are specified with the least-significant byte first. /b/t1 unsigned /t3 a natural binary number. /b/t1 signed /t3 a 2's complement binary number. /b/t1 /t3 A one-byte unsigned number. /b/t1 /t3 A four-byte signed integer number. /b/t1