(** This module defines the abstract syntax tree of [LTL]. *) (** The main difference with ERTL is that only physical registers are present in LTL (no more pseudo-registers). Pseudo-registers are associated either a physical register or a location on the stack. This is done by a coloring algorithm. Actually, this coloring algorithm relies on the result of a liveness analysis that will also allow to remove dead code. *) type statement = (* The empty statement. *) | St_skip of Label.t (* Comment. *) | St_comment of string * Label.t (* Emit a cost label. *) | St_cost of CostLabel.t * Label.t (* Assign an integer constant to a register. Parameters are the destination register, the integer and the label of the next statement. *) | St_int of I8051.register * int * Label.t (* Pop a value from the IRAM to the accumulator. Parameter is the label of the next statement. *) | St_pop of Label.t (* Push a value from the accumulator to the IRAM. Parameter is the label of the next statement. *) | St_push of Label.t (* Assign the address of a symbol to a DPTR. Parameters are the symbol, and the label of the next statement. *) | St_addr of AST.ident * Label.t (* Move the content of the accumulator to a register. Parameters are the destination register, and the label of the next statement. *) | St_from_acc of I8051.register * Label.t (* Move the content of a register to the accumulator. Parameters are the source register, and the label of the next statement. *) | St_to_acc of I8051.register * Label.t (* Apply an operation on the accumulators. Parameters are the operation, and the label of the next statement. *) | St_opaccs of I8051.opaccs * Label.t (* Apply an unary operation on the A accumulator. Parameters are the operation, and the label of the next statement. *) | St_op1 of I8051.op1 * Label.t (* Apply a binary operation on the A accumulator. Parameters are the operation, the other source register, and the label of the next statement. *) | St_op2 of I8051.op2 * I8051.register * Label.t (* Set the carry flag to zero. Parameter is the label of the next statement. *) | St_clear_carry of Label.t (* Set the carry flag to 1. Parameter is the label of the next statement. *) | St_set_carry of Label.t (* Load from external memory (address in DPTR) to the accumulator. Parameter is the label of the next statement. *) | St_load of Label.t (* Store to external memory (address in DPTR) from the accumulator. Parameter is the label of the next statement. *) | St_store of Label.t (* Call to a function given its name. Parameters are the name of the function, and the label of the next statement. *) | St_call_id of AST.ident * Label.t (* Call to a function given its address in DPTR. Parameter is the label of the next statement. *) | St_call_ptr of Label.t (* Branch on A accumulator. Parameters are the label to go to when the A accumulator is not 0, and the label to go to when the A accumulator is 0. *) | St_condacc of Label.t * Label.t (* Transfer control to the address stored in the return address registers. *) | St_return type graph = statement Label.Map.t type internal_function = { f_luniverse : Label.Gen.universe ; f_stacksize : int ; f_graph : graph ; f_entry : Label.t ; f_exit : Label.t } type function_def = | F_int of internal_function | F_ext of AST.external_function (* A program is a list of global variables and their reserved space, a list of function names and their definition, and the name of the main function. *) type program = { vars : (AST.ident * int (* size *)) list ; functs : (AST.ident * function_def) list ; main : AST.ident option }