2 (** This module defines the abstract syntax tree of [RTL]. *)
4 (* Adapted from Pottiers's Pseudo-Pascal pedagogical compiler *)
6 (* This is the definition of the abstract syntax for the Explicit
7 Register Transfer Language (ERTL).
9 This language is very much like RTL, except the calling convention
10 has been made explicit. That is, functions and procedures no longer
11 accept parameters and return results via a high-level mechanism;
12 instead, they do so via either hardware registers or stack
15 Functions and procedures no longer magically return to their caller: instead,
16 a new [St_return] instruction appears, whose semantics is to transfer control
17 to the address stored in the return address registers.
19 Functions and procedures are no longer explicitly distinguished: functions
20 are simply procedures that happen to write the hardware register. There only
21 remains a distinction at [St_return] instructions (see below).
23 Two new instructions, [St_newframe] and [St_delframe], appear in order to
24 allocate and release stack frames. They will be translated, in the final
25 assembly code, to arithmetic on the stack pointer registers. *)
27 (* Stack organization.
29 The stack is going from top to bottom. Below is a schema of the stack
30 organization viewed by the function being executed.
32 formal parameters (the first parameter is at the top)
33 spilled variables (the first spilled variable is a the top)
34 local variables (the first local variable is at the bottom)
38 type registers = Register.t list
42 (* The empty statement. *)
46 | St_comment of string * Label.t
48 (* Emit a cost label. *)
49 | St_cost of CostLabel.t * Label.t
51 (* Assign the content of a hardware register to a pseudo register. Parameters
52 are the destination pseudo register, the source hardware register, and the
53 label of the next statement. *)
54 | St_get_hdw of Register.t * I8051.register * Label.t
56 (* Assign the content of a pseudo register to a hardware register. Parameters
57 are the destination hardware register, the source pseudo register, and the
58 label of the next statement. *)
59 | St_set_hdw of I8051.register * Register.t * Label.t
61 (* Assign the content of a hardware register to a hardware
62 register. Parameters are the destination register, the source register, and
63 the label of the next statement. Only used to save the return value before
64 the epilogue and restore it right before leaving the function. *)
65 | St_hdw_to_hdw of I8051.register * I8051.register * Label.t
67 (* Allocate required space on the stack for the function. Parameter is the
68 label of the next statement. *)
69 | St_newframe of Label.t
71 (* Deallocate required space on the stack for the function. Parameter is the
72 label of the next statement. *)
73 | St_delframe of Label.t
75 (* Assign the frame size to a register. Parameters are the destination
76 register, and the label of the next statement. *)
77 | St_framesize of Register.t * Label.t
79 (* Pop a value from the IRAM to a register. Parameter are the destination
80 register, and the label of the next statement. *)
81 | St_pop of Register.t * Label.t
83 (* Push a value from a register to the IRAM. Parameter are the source
84 register, and the label of the next statement. *)
85 | St_push of Register.t * Label.t
87 (* Assign the most significant bits of the address of a symbol to a
88 register. Parameters are the destination register, the symbol and the label
89 of the next statement. *)
90 | St_addrH of Register.t * AST.ident * Label.t
92 (* Assign the least significant bits of the address of a symbol to a
93 register. Parameters are the destination register, the symbol and the label
94 of the next statement. *)
95 | St_addrL of Register.t * AST.ident * Label.t
97 (* Assign an integer constant to a register. Parameters are the destination
98 register, the integer and the label of the next statement. *)
99 | St_int of Register.t * int * Label.t
101 (* Move the content of a register to another. Parameters are the destination
102 register, the source register, and the label of the next statement. *)
103 | St_move of Register.t * Register.t * Label.t
105 (* Apply a binary operation that will later be translated in an operation on
106 the accumulators, keeping only the result in ACC. Parameters are the
107 operation, the destination register, the source registers, and the label of
108 the next statement. *)
109 | St_opaccsA of I8051.opaccs * Register.t * Register.t * Register.t * Label.t
111 (* Apply a binary operation that will later be translated in an operation on
112 the accumulators, keeping only the result in BACC. Parameters are the
113 operation, the destination register, the source registers, and the label of
114 the next statement. *)
115 | St_opaccsB of I8051.opaccs * Register.t * Register.t * Register.t * Label.t
117 (* Apply an unary operation. Parameters are the operation, the destination
118 register, the source register, and the label of the next statement. *)
119 | St_op1 of I8051.op1 * Register.t * Register.t * Label.t
121 (* Apply a binary operation. Parameters are the operation, the destination
122 register, the source registers, and the label of the next statement. *)
123 | St_op2 of I8051.op2 * Register.t * Register.t * Register.t * Label.t
125 (* Set the carry flag to zero. Parameter is the label of the next
127 | St_clear_carry of Label.t
129 (* Set the carry flag to 1. Parameter is the label of the next statement. *)
130 | St_set_carry of Label.t
132 (* Load from external memory. Parameters are the destination register, the
133 address registers (low bytes first), and the label of the next
135 | St_load of Register.t * Register.t * Register.t * Label.t
137 (* Store to external memory. Parameters are the address registers (low bytes
138 first), the source register, and the label of the next statement. *)
139 | St_store of Register.t * Register.t * Register.t * Label.t
141 (* Call to a function given its name. Parameters are the name of the function,
142 the number of arguments of the function, and the label of the next
144 | St_call_id of AST.ident * int * Label.t
146 (* Call to a function given its address. Parameters are the registers holding
147 the address of the function, the number of arguments of the function, and
148 the label of the next statement. *)
149 | St_call_ptr of Register.t * Register.t * int * Label.t
152 (* Tail call to a function given its name. Parameters are the name of the
153 function, and the number of arguments of the function. *)
154 | St_tailcall_id of AST.ident * int
156 (* Tail call to a function given its address. Parameters are registers holding
157 the address of the function, and the arguments of the function. *)
158 | St_tailcall_ptr of registers * register list
161 (* Branch. Parameters are the register holding the value for the branching,
162 the label to go to when the value is not 0, and the label to go to when the
164 | St_cond of Register.t * Label.t * Label.t
166 (* Transfer control to the address stored in the return address registers. *)
167 | St_return of registers
169 type graph = statement Label.Map.t
171 type internal_function =
172 { f_luniverse : Label.Gen.universe ;
173 f_runiverse : Register.universe ;
175 f_locals : Register.Set.t ;
182 | F_int of internal_function
183 | F_ext of AST.external_function
185 (* A program is a list of global variables and their reserved space, a list of
186 function names and their definition, and the name of the main function. *)
189 { vars : (AST.ident * int (* size *)) list ;
190 functs : (AST.ident * function_def) list ;
191 main : AST.ident option }