-
Notifications
You must be signed in to change notification settings - Fork 1
sunzc/Compiler
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Here are the contents of this directory: ICode.l, ICode.y: Flex/Bison files for intermediate code driver.C: Driver program for intermediate code assembler. Makefile: Used to compile the assembler easm: It takes an intermediate code file (e.g., test1.i) as input, translates it into C-code (e.g., test1.c), and then compiles it using gcc to generate an executable (e.g., test1). The assembler program is recompiled if necessary before these steps. erun: Assembles the intermediate code and runs it. It requires at least one command-line argument, which is the name of the intermediate code file (e.g., test1.i). Other command line arguments control some printing options. There is one sample intermediate code file called test1.i included in this directory. The output produced using the following command is also included: ./erun test1.i -dr -df -m 10000000 -dm 9990 10000 > test1.out 2> test1.out < test1.in About the assembler ------------------- The assembler for the intermediate code ("icode") is written using Flex and Bison. Since its input is intended to be generated by a compiler, the assembler does not provide user-friendly syntax error messages --- all you will get is the line number where there is an error. The assembler ensures syntactic and type correctness of icode, and then translates it into C-code, which is in turn compiled using gcc. Currently, this compilation is done without optimization: this way, any optimizations you make will translate to faster performance. (If the -O option to gcc were used, optimizations performed by gcc will likely cause even lousy code to be translated into efficient machine code.) Machine model -------------- The intermediate code is intended to model a very simple instruction set. Complete information about the instruction set can be ontained from the source code files. In particular, note that each icode instruction is translated by the assembler into a macro with the same name. The definitions of these macros appear in E--_RT.c, and should provide you a clear understanding of the instruction set semantics. Icode supports 1000 integer registers (R000 to R999) and 1000 floating point registers (F000 to F999). The size of integers and floating point numbers is the same as the size of int and float respectively on the underlying architecture on which the assembled C-code is compiled. Icode memory starts at address zero, and goes on to a maximum address specified as a command-line option to the C-program generated by the assembler. (The default memory size ia 1M words.) Memory is word-addressed, not byte-addressed. This memory is represented as an array in the C-program. Guard zones are set up on either side of the array to catch out-of-bounds accesses (which will trigger a memory exception). To simplify the organization of memory, we make the assumption that sizeof(int) == sizeof(float). This enables integers and floating point numbers to be both stored in one memory word. Execution of icode starts at the first instruction in the icode file, and execution is stopped when control flows past the last instruction in the file. The instructions can be divided into the following categories. In all cases, destination operands are listed following the source operands. Any instruction can have a label. -- integer arithmetic and bit operations: includes ADD, SUB, DIV, MUL, MOD, NEG, AND, OR and XOR. The last 3 operations are bit-wise operations, appling the specified boolean on corresponding bits of two integer operands. These operations have two source operands (just one source in the case of NEG) that can either be a value or a register, and a destination operand that must be a register. -- floating point arithmetic: includes FADD, FSUB, FDIV, FMUL and FNEG. They have two source operands (one in the case of FNEG) that can be values or registers, and a destination operand that must be a register. -- integer relational operations: includes GT and GE that treat their two operands as signed integers; UGT and UGE that operate on unsigned integers; EQ and NE that operate on integers regardless of size; All operands can be values or registers. NOTE: Relational operators are not stand-alone instructions, but instead, appear as part of a conditional jump instruction. -- floating point relational operations: includes FGT, FGE, FEQ and FNE that operate on floating point operands (values or registers). -- print instructions: include PRTI, PRTS, and PRTF that each take a a single operand. In the case of PRTI, this operand represents the integer value to be printed, or the register that needs to be printed. PRTF is similar, except that it prints a floating point operand. In the case of PRTS, the operand is a string constant (enclosed within double quotes) or a register containing a string constant, i.e., the register was previously initialized by a MOVS <string_constant> <reg>. -- jump instructions: unconditional jump: JMP <loc>, where <loc> is a label. conditional jump: JMPC <cond> <loc>, where <cond> is a relational operator with parameters. Example: JMPC GE R000 R001 <loc> indirect jump: JMPI <reg>, where <reg> is an integer register that has previously been initialized with a label value using a MOVL instruction. conditional indirect jump: Example JMPCI FGE F001 1.0 R010. -- data movement instructions: move label to a register: MOVL <label> <intreg> move string to register: MOVS <stringConstant> <intreg> move integer to register: MOVI <valueOrReg> <intreg> move float to register: MOVF <valueOrReg> <freg> move int to float reg: MOVIF <intreg> <freg> move float to int reg: MOVIF <freg> <intreg> load int reg from mem: LDI <reg> <valuOrReg> load float reg from mem: LDF <reg> <valuOrReg> store int reg to mem: STI <reg> <valuOrReg> store float reg to mem: STF <reg> <valuOrReg> -- input instruction (for reading input data) IN <reg> reads a single byte from input stream and stores it into the specified register. A negative return value indicates an error, with the semantics the same as that of getc. INI <reg>, INF <reg> read an integer (or floating point number) into the specified register. Aborts execution if any errors are encountered.
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published