123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- /*
- * Andrea Di Biagio
- * Politecnico di Milano, 2007
- *
- * axe_gencode.c
- * Formal Languages & Compilers Machine, 2007/2008
- *
- */
- #include "axe_gencode.h"
- #include "axe_errors.h"
- static t_axe_instruction * gen_unary_instruction (t_program_infos *program
- , int opcode, int r_dest, t_axe_label *label, int addr);
- static t_axe_instruction * gen_binary_instruction (t_program_infos *program
- , int opcode, int r_dest, int r_source1, int immediate);
- static t_axe_instruction * gen_ternary_instruction (t_program_infos *program
- , int opcode, int r_dest, int r_source1, int r_source2, int flags);
- static t_axe_instruction * gen_jump_instruction (t_program_infos *program
- , int opcode, t_axe_label *label, int addr);
- t_axe_instruction * gen_bt_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BT, label, addr);
- }
- t_axe_instruction * gen_bf_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BF, label, addr);
- }
- t_axe_instruction * gen_bhi_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BHI, label, addr);
- }
-
- t_axe_instruction * gen_bls_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BLS, label, addr);
- }
- t_axe_instruction * gen_bcc_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BCC, label, addr);
- }
- t_axe_instruction * gen_bcs_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BCS, label, addr);
- }
- t_axe_instruction * gen_bne_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BNE, label, addr);
- }
- t_axe_instruction * gen_beq_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BEQ, label, addr);
- }
- t_axe_instruction * gen_bvc_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BVC, label, addr);
- }
- t_axe_instruction * gen_bvs_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BVS, label, addr);
- }
- t_axe_instruction * gen_bpl_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BPL, label, addr);
- }
- t_axe_instruction * gen_bmi_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BMI, label, addr);
- }
- t_axe_instruction * gen_bge_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BGE, label, addr);
- }
- t_axe_instruction * gen_blt_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BLT, label, addr);
- }
- t_axe_instruction * gen_bgt_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BGT, label, addr);
- }
- t_axe_instruction * gen_ble_instruction
- (t_program_infos *program, t_axe_label *label, int addr)
- {
- return gen_jump_instruction (program, BLE, label, addr);
- }
- t_axe_instruction * gen_add_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, ADD, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_sub_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, SUB, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_andl_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, ANDL, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_orl_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, ORL, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_eorl_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, EORL, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_andb_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, ANDB, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_orb_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, ORB, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_eorb_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, EORB, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_mul_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, MUL, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_div_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, DIV, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_shl_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- /* The SHL operational semantic is: source2 << source1. Because of this we
- * need to put the value to shift in source2, and the shift-amount in source1
- */
- return gen_ternary_instruction
- (program, SHL, r_dest, r_source2, r_source1, flags);
- }
- t_axe_instruction * gen_shr_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- /* The SHR operational semantic is: source2 >> source1. Because of this we
- * need to put the value to shift in source2, and the shift-amount in source1
- */
- return gen_ternary_instruction
- (program, SHR, r_dest, r_source2, r_source1, flags);
- }
- t_axe_instruction * gen_neg_instruction (t_program_infos *program
- , int r_dest, int r_source, int flags)
- {
- return gen_ternary_instruction
- (program, SUB, r_dest, REG_0, r_source, flags);
- }
- t_axe_instruction * gen_spcl_instruction (t_program_infos *program
- , int r_dest, int r_source1, int r_source2, int flags)
- {
- return gen_ternary_instruction
- (program, SPCL, r_dest, r_source1, r_source2, flags);
- }
- t_axe_instruction * gen_addi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, ADDI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_subi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, SUBI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_andli_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, ANDLI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_orli_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, ORLI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_eorli_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, EORLI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_andbi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, ANDBI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_muli_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, MULI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_orbi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, ORBI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_eorbi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, EORBI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_divi_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, DIVI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_shli_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, SHLI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_shri_instruction
- (t_program_infos *program, int r_dest, int r_source1, int immediate)
- {
- return gen_binary_instruction(program, SHRI
- , r_dest, r_source1, immediate);
- }
- t_axe_instruction * gen_notl_instruction
- (t_program_infos *program, int r_dest, int r_source1)
- {
- return gen_binary_instruction(program, NOTL
- , r_dest, r_source1, 0);
- }
- t_axe_instruction * gen_notb_instruction
- (t_program_infos *program, int r_dest, int r_source1)
- {
- return gen_binary_instruction(program, NOTB
- , r_dest, r_source1, 0);
- }
- t_axe_instruction * gen_read_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, AXE_READ, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_write_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, AXE_WRITE, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_load_instruction
- (t_program_infos *program, int r_dest, t_axe_label *label, int address)
- {
- return gen_unary_instruction(program, LOAD, r_dest, label, address);
- }
- t_axe_instruction * gen_store_instruction
- (t_program_infos *program, int r_dest, t_axe_label *label, int address)
- {
- return gen_unary_instruction(program, STORE, r_dest, label, address);
- }
- t_axe_instruction * gen_mova_instruction
- (t_program_infos *program, int r_dest, t_axe_label *label, int address)
- {
- return gen_unary_instruction(program, MOVA, r_dest, label, address);
- }
- t_axe_instruction * gen_sge_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SGE, r_dest, NULL, 0);
- }
-
- t_axe_instruction * gen_seq_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SEQ, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_sgt_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SGT, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_sle_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SLE, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_slt_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SLT, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_sne_instruction
- (t_program_infos *program, int r_dest)
- {
- return gen_unary_instruction(program, SNE, r_dest, NULL, 0);
- }
- t_axe_instruction * gen_halt_instruction
- (t_program_infos *program)
- {
- t_axe_instruction *instr;
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
-
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(HALT);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
- t_axe_instruction * gen_nop_instruction(t_program_infos *program)
- {
- t_axe_instruction *instr;
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
-
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(NOP);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
- t_axe_instruction * gen_unary_instruction (t_program_infos *program
- , int opcode, int r_dest, t_axe_label *label, int addr)
- {
- t_axe_instruction *instr;
- t_axe_register *reg;
- t_axe_address *address;
- int addressType;
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
- if (r_dest == REG_INVALID)
- notifyError(AXE_INVALID_REGISTER_INFO);
-
- /* test if value is correctly initialized */
- if (label != NULL)
- {
- if (label->labelID == LABEL_UNSPECIFIED)
- {
- notifyError(AXE_INVALID_LABEL);
- }
- /* address type is a label type */
- addressType = LABEL_TYPE;
- }
- else
- {
- if (addr < 0)
- notifyError(AXE_INVALID_ADDRESS);
- /* address type is a label type */
- addressType = ADDRESS_TYPE;
- }
- /* test if the opcode is a valid opcode */
- if (opcode == INVALID_OPCODE)
- notifyError(AXE_INVALID_OPCODE);
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(opcode);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* initialize a register info */
- reg = alloc_register(r_dest, 0);
- if (reg == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
-
- /* update the reg_1 info */
- instr->reg_1 = reg;
- /* initialize an address info */
- address = alloc_address(addressType, addr, label);
-
- if (address == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the instruction address info */
- instr->address = address;
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
- t_axe_instruction * gen_binary_instruction (t_program_infos *program
- , int opcode, int r_dest, int r_source1, int immediate)
- {
- t_axe_instruction *instr;
- t_axe_register *reg_dest;
- t_axe_register *reg_source1;
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
- /* test if value is correctly initialized */
- if ( (r_dest == REG_INVALID)
- || (r_source1 == REG_INVALID) )
- {
- notifyError(AXE_INVALID_REGISTER_INFO);
- }
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(opcode);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* initialize a register info */
- reg_dest = alloc_register(r_dest, 0);
- if (reg_dest == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the reg_1 info */
- instr->reg_1 = reg_dest;
- reg_source1 = alloc_register(r_source1, 0);
- if (reg_source1 == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- return NULL;
- }
- /* update the reg_1 info */
- instr->reg_2 = reg_source1;
- /* assign an immediate value */
- instr->immediate = immediate;
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
- t_axe_instruction * gen_ternary_instruction (t_program_infos *program
- , int opcode, int r_dest, int r_source1, int r_source2, int flags)
- {
- t_axe_instruction *instr;
- t_axe_register *reg_dest;
- t_axe_register *reg_source1;
- t_axe_register *reg_source2;
-
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
- /* test if value is correctly initialized */
- if ( (r_dest == REG_INVALID)
- || (r_source1 == REG_INVALID)
- || (r_source2 == REG_INVALID))
- {
- notifyError(AXE_INVALID_REGISTER_INFO);
- }
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(opcode);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* initialize a register info */
- reg_dest = alloc_register(r_dest, ((flags & CG_INDIRECT_DEST)? 1 : 0) );
- if (reg_dest == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the reg_1 info */
- instr->reg_1 = reg_dest;
- reg_source1 = alloc_register(r_source1, 0);
- if (reg_source1 == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the reg_2 info */
- instr->reg_2 = reg_source1;
- reg_source2 = alloc_register(r_source2, ((flags & CG_INDIRECT_SOURCE)? 1 : 0));
- if (reg_source1 == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the reg_3 info */
- instr->reg_3 = reg_source2;
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
- t_axe_instruction * gen_jump_instruction (t_program_infos *program
- , int opcode, t_axe_label *label, int addr)
- {
- t_axe_instruction *instr;
- t_axe_address * address;
- int addressType;
- /* test if program is initialized */
- if (program == NULL)
- notifyError(AXE_PROGRAM_NOT_INITIALIZED);
- /* test if value is correctly initialized */
- if (label != NULL)
- {
- if (label->labelID == LABEL_UNSPECIFIED)
- notifyError(AXE_INVALID_LABEL);
- addressType = LABEL_TYPE;
- }
- else
- {
- if (addr < 0)
- notifyError(AXE_INVALID_ADDRESS);
- addressType = ADDRESS_TYPE;
- }
- /* test if the opcode is a valid opcode */
- if (opcode == INVALID_OPCODE)
- notifyError(AXE_INVALID_OPCODE);
- /* create an instance of `t_axe_instruction' */
- instr = alloc_instruction(opcode);
- if (instr == NULL)
- notifyError(AXE_OUT_OF_MEMORY);
- /* initialize an address info */
- address = alloc_address(addressType, addr, label);
-
- if (address == NULL)
- {
- free_Instruction(instr);
- notifyError(AXE_OUT_OF_MEMORY);
- }
- /* update the instruction address info */
- instr->address = address;
- /* add the newly created instruction to the current program */
- addInstruction(program, instr);
- /* return the load instruction */
- return instr;
- }
|