OpenCores
URL https://opencores.org/ocsvn/minimips/minimips/trunk

Subversion Repositories minimips

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 13 to Rev 14
    Reverse comparison

Rev 13 → Rev 14

/trunk/miniMIPS/doc/doc_pps_ei.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/miniMIPS/doc/doc_pps_ei.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/miniMIPS/doc/doc_pps_pf.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/miniMIPS/doc/doc_pps_pf.pdf =================================================================== --- trunk/miniMIPS/doc/doc_pps_pf.pdf (revision 13) +++ trunk/miniMIPS/doc/doc_pps_pf.pdf (nonexistent)
trunk/miniMIPS/doc/doc_pps_pf.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/miniMIPS/doc/doc_predict.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/miniMIPS/doc/doc_predict.pdf =================================================================== --- trunk/miniMIPS/doc/doc_predict.pdf (revision 13) +++ trunk/miniMIPS/doc/doc_predict.pdf (nonexistent)
trunk/miniMIPS/doc/doc_predict.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/miniMIPS/doc/doc_pps_di.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/miniMIPS/doc/doc_pps_di.pdf =================================================================== --- trunk/miniMIPS/doc/doc_pps_di.pdf (revision 13) +++ trunk/miniMIPS/doc/doc_pps_di.pdf (nonexistent)
trunk/miniMIPS/doc/doc_pps_di.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf =================================================================== --- trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf (revision 13) +++ trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf (nonexistent)
trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/miniMIPS/src/predict.vhd =================================================================== --- trunk/miniMIPS/src/predict.vhd (revision 13) +++ trunk/miniMIPS/src/predict.vhd (nonexistent) @@ -1,227 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Branch prediction -- --- -- --- -- --- -- --- Author : Olivier Schneider -- --- -- --- june 2004 -- --------------------------------------------------------------------------- - - - -library ieee; -use ieee.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - - -entity predict is -generic ( - nb_record : integer := 3 -); -port ( - - clock : in std_logic; - reset : in std_logic; - - -- Datas from PF pipeline stage - PF_pc : in std_logic_vector(31 downto 0); -- PC of the current instruction extracted - - -- Datas from DI pipeline stage - DI_bra : in std_logic; -- Branch detected - DI_adr : in std_logic_vector(31 downto 0); -- Address of the branch - - -- Datas from EX pipeline stage - EX_bra_confirm : in std_logic; -- Confirm if the branch test is ok - EX_adr : in std_logic_vector(31 downto 0); -- Address of the branch - EX_adresse : in std_logic_vector(31 downto 0); -- Result of the branch - EX_uncleared : in std_logic; -- Define if the EX stage is cleared - - -- Outputs to PF pipeline stage - PR_bra_cmd : out std_logic; -- Defined a branch - PR_bra_bad : out std_logic; -- Defined a branch to restore from a bad prediction - PR_bra_adr : out std_logic_vector(31 downto 0); -- New PC - - -- Clear the three pipeline stage : EI, DI, EX - PR_clear : out std_logic -); -end entity; - - -architecture rtl of predict is - - -- Record contained in the table of prediction - type pred_type is - record - is_affected : std_logic; -- Check if the record is affected - last_bra : std_logic; -- The last branch confirmation result - code_adr : std_logic_vector(31 downto 0); -- Branch instruction address - bra_adr : std_logic_vector(31 downto 0); -- Branch result - end record; - - type pred_tab_type is array(1 to nb_record) of pred_type; - - -- Table of predictions - signal pred_tab : pred_tab_type; - signal pre_pred_tab : pred_tab_type; - - signal next_out : integer range 1 to nb_record := 1; -- Next record to be erased in the table - signal add_record : std_logic; - -begin - - -- Do the predictions - process(reset, PF_pc, DI_bra, DI_adr, EX_adr, EX_adresse, EX_bra_confirm, pred_tab) - - variable index : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address - variable index2 : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address - variable index3 : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address - - variable bad_pred : std_logic; -- Flag of bad prediction - - begin - - -- Default signal affectations - index := 0; - index2 := 0; - index3 := 0; - pre_pred_tab <= pred_tab; -- No modification in table of prediction by default - PR_bra_cmd <= '0'; - PR_bra_bad <= '0'; - PR_bra_adr <= (others => '0'); - PR_clear <= '0'; - bad_pred := '0'; - add_record <= '0'; - - -- Check a match in the table - for i in 1 to nb_record loop - if pred_tab(i).is_affected = '1' then - if PF_pc = pred_tab(i).code_adr then - index3 := i; - end if; - if DI_adr = pred_tab(i).code_adr then - index := i; - end if; - if EX_adr = pred_tab(i).code_adr then - index2 := i; - end if; - end if; - end loop; - - -- Branch prediciton - if index3 /= 0 then - PR_bra_cmd <= '1'; - PR_bra_adr <= pred_tab(index3).bra_adr; - end if; - - -- Check if the prediction is ok - if EX_uncleared = '1' then - if index2 /= 0 then - if pred_tab(index2).last_bra /= EX_bra_confirm then -- Bad test result prediction - - if EX_bra_confirm = '1' then - pre_pred_tab(index2).last_bra <= '1'; - pre_pred_tab(index2).bra_adr <= EX_adresse; - else - pre_pred_tab(index2).last_bra <= '0'; - pre_pred_tab(index2).bra_adr <= std_logic_vector(unsigned(pred_tab(index2).code_adr)+4); - end if; - - bad_pred := '1'; - - elsif pred_tab(index2).bra_adr /= EX_adresse then -- Bad adress result prediction - - pre_pred_tab(index2).bra_adr <= EX_adresse; - bad_pred := '1'; - - end if; - end if; - end if; - - -- Clear the pipeline and branch to the new instruction - if bad_pred = '1' then - PR_bra_bad <= '1'; - PR_bra_adr <= pre_pred_tab(index2).bra_adr; - PR_clear <= '1'; - end if; - - -- Add a record in the table - if DI_bra = '1' then - if index = 0 then - add_record <= '1'; - pre_pred_tab(next_out).is_affected <= '1'; -- The record is affected - pre_pred_tab(next_out).last_bra <= '0'; -- Can't predict the branch the first time - pre_pred_tab(next_out).code_adr <= DI_adr; -- Save the branch address - pre_pred_tab(next_out).bra_adr <= std_logic_vector(unsigned(DI_adr)+4); -- Branch result - end if; - end if; - - end process; - - -- Update the table of prediction - process(clock, reset) - begin - if reset = '1' then - - next_out <= 1; -- At the beginning the first record must be chosen to be filled - - for i in 1 to nb_record loop - pred_tab(i).is_affected <= '0'; - end loop; - - elsif rising_edge(clock) then - - pred_tab <= pre_pred_tab; - - if add_record = '1' then - if next_out = nb_record then - next_out <= 1; - else - next_out <= next_out+1; -- Next record to be erased - end if; - end if; - - end if; - end process; -end rtl; - Index: trunk/miniMIPS/src/bus_ctrl.vhd =================================================================== --- trunk/miniMIPS/src/bus_ctrl.vhd (revision 13) +++ trunk/miniMIPS/src/bus_ctrl.vhd (nonexistent) @@ -1,206 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : bus controler -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity bus_ctrl is -port -( - clock : std_logic; - reset : std_logic; - - -- Interruption in the pipeline - interrupt : in std_logic; - - -- Interface for the Instruction Extraction Stage - adr_from_ei : in bus32; -- The address of the data to read - instr_to_ei : out bus32; -- Instruction from the memory - - -- Interface with the MEMory Stage - req_from_mem : in std_logic; -- Request to access the ram - r_w_from_mem : in std_logic; -- Read/Write request - adr_from_mem : in bus32; -- Address in ram - data_from_mem : in bus32; -- Data to write in ram - data_to_mem : out bus32; -- Data from the ram to the MEMory stage - - -- RAM interface signals - req_to_ram : out std_logic; -- Request to ram - adr_to_ram : out bus32; -- Address of the data to read or write - r_w_to_ram : out std_logic; -- Read/Write request - ack_from_ram : in std_logic; -- Acknowledge from the memory - data_inout_ram : inout bus32; -- Data from/to the memory - - -- Pipeline progress control signal - stop_all : out std_logic -); -end bus_ctrl; - - -architecture rtl of bus_ctrl is - - type ctrl_state is ( ST1, ST2 ); - signal cs, ns : ctrl_state; - signal ei_buffer : bus32; -- Buffer storing the data for EI - - signal r_w : std_logic; -- Current utilisation of the tristate bus - signal data_in : bus32; -- Data read on the tristate bus - signal req_allowed : std_logic; - -begin - - -- Read/write on the tristate bus - process (r_w, data_from_mem, data_inout_ram) - begin - r_w_to_ram <= r_w; - if r_w='0' then -- Reads bus - data_inout_ram <= (others => 'Z'); - data_in <= data_inout_ram; - else -- Writing of the data from the MEM stage - data_inout_ram <= data_from_mem; - data_in <= (others => '0'); - end if; - end process; - - process (clock) - begin - if clock='1' and clock'event then - if reset='1' then - cs <= ST1; - ei_buffer <= (others => '0'); - else - if cs=ST1 then - -- Storing of the data to send to EI stage - ei_buffer <= data_in; - end if; - - cs <= ns; - end if; - end if; - end process; - - process (clock, ack_from_ram) - begin - if ack_from_ram = '0' then - req_allowed <= '0'; - elsif clock='1' and clock'event then - if ack_from_ram = '1' then - req_allowed <= '1'; - end if; - end if; - end process; - - process (req_allowed, ack_from_ram) - begin - if req_allowed = '1' then - req_to_ram <= '1'; - elsif ack_from_ram = '0' then - req_to_ram <= '1'; - else - req_to_ram <= '0'; - end if; - end process; - - process (cs, interrupt, adr_from_ei, req_from_mem, r_w_from_mem, adr_from_mem, ack_from_ram) - begin - if interrupt = '1' then -- An interruption is detected - ns <= ST1; -- Get back to the reading request - stop_all <= '0'; -- The pipeline is unlock for taking in account the interruption - adr_to_ram <= adr_from_ei; - r_w <= '0'; - else - case cs is - - when ST1 => -- First step the reading for EI - adr_to_ram <= adr_from_ei; - r_w <= '0'; - - if ack_from_ram='1' then - - if req_from_mem='1' then - -- If request from MEM, then step 2 - ns <= ST2; - stop_all <= '1'; - else - -- else next reading for EI - ns <= ST1; - stop_all <= '0'; - end if; - else - -- Wait the end of the reading - ns <= ST1; - stop_all <= '1'; - end if; - - when ST2 => -- Treat the request from the MEM stage - adr_to_ram <= adr_from_mem; - r_w <= r_w_from_mem; - - -- Wait the acknowledge from the RAM - if ack_from_ram='1' then - ns <= ST1; - stop_all <= '0'; - else - ns <= ST2; - stop_all <= '1'; - end if; - - end case; - end if; - end process; - - data_to_mem <= data_in; - instr_to_ei <= ei_buffer when cs=ST2 else data_in; - -end rtl; Index: trunk/miniMIPS/src/pps_di.vhd =================================================================== --- trunk/miniMIPS/src/pps_di.vhd (revision 13) +++ trunk/miniMIPS/src/pps_di.vhd (nonexistent) @@ -1,429 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- Processor miniMIPS : Instruction decoding stage -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity pps_di is -port ( - clock : in std_logic; - reset : in std_logic; - stop_all : in std_logic; -- Unconditionnal locking of the outputs - clear : in std_logic; -- Clear the pipeline stage (nop in the outputs) - - -- Asynchronous connexion with the register management and data bypass unit - adr_reg1 : out adr_reg_type; -- Address of the first register operand - adr_reg2 : out adr_reg_type; -- Address of the second register operand - use1 : out std_logic; -- Effective use of operand 1 - use2 : out std_logic; -- Effective use of operand 2 - - stop_di : in std_logic; -- Unresolved detected : send nop in the pipeline - data1 : in bus32; -- Operand register 1 - data2 : in bus32; -- Operand register 2 - - -- Datas from EI stage - EI_adr : in bus32; -- Address of the instruction - EI_instr : in bus32; -- The instruction to decode - EI_it_ok : in std_logic; -- Allow hardware interruptions - - -- Synchronous output to EX stage - DI_bra : out std_logic; -- Branch decoded - DI_link : out std_logic; -- A link for that instruction - DI_op1 : out bus32; -- operand 1 for alu - DI_op2 : out bus32; -- operand 2 for alu - DI_code_ual : out alu_ctrl_type; -- Alu operation - DI_offset : out bus32; -- Offset for the address calculation - DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result - DI_ecr_reg : out std_logic; -- Effective writing of the result - DI_mode : out std_logic; -- Address mode (relative to pc or indexed to a register) - DI_op_mem : out std_logic; -- Memory operation request - DI_r_w : out std_logic; -- Type of memory operation (reading or writing) - DI_adr : out bus32; -- Address of the decoded instruction - DI_exc_cause : out bus32; -- Potential exception detected - DI_level : out level_type; -- Availability of the result for the data bypass - DI_it_ok : out std_logic -- Allow hardware interruptions -); -end entity; - - -architecture rtl of pps_di is - - -- Enumeration type used for the micro-code of the instruction - type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0); -- selection du mode de l'instruction - type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT); -- selection de la valeur de l'offset - type rdest_type is ( D_RT, D_RD, D_31, D_00); -- selection du registre destination - - -- Record type containg the micro-code of an instruction - type micro_instr_type is - record - op_mode : op_mode_type; -- Instruction codop mode - op_code : bus6; -- Instruction codop - bra : std_logic; -- Branch instruction - link : std_logic; -- Branch with link : the return address is saved in a register - code_ual : alu_ctrl_type; -- Operation code for the alu - op_mem : std_logic; -- Memory operation needed - r_w : std_logic; -- Read/Write selection in memory - mode : std_logic; -- Address calculation from the current pc ('1') or the alu operand 1 ('0') - off_sel : off_sel_type; -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm) - exc_cause : bus32; -- Unconditionnal exception cause to generate - cop_org1 : std_logic; -- Source register 1 : general register if 0, coprocessor register if 1 - cop_org2 : std_logic; -- Source register 2 : general register if 0, coprocessor register if 1 - cs_imm1 : std_logic; -- Use of immediat operand 1 instead of register bank - cs_imm2 : std_logic; -- Use of immediat operand 2 instead of register bank - imm1_sel : std_logic; -- Origine of immediat operand 1 - imm2_sel : std_logic; -- Origine of immediat operand 2 - level : level_type; -- Data availability stage for the bypass - ecr_reg : std_logic; -- Writing the result in a register - bank_des : std_logic; -- Register bank selection : GPR if 0, coprocessor system if 1 - des_sel : rdest_type ; -- Destination register address : Rt, Rd, $31, $0 - end record; - - type micro_code_type is array (natural range <>) of micro_instr_type; - - constant micro_code : micro_code_type := -( -- Instruction decoding in micro-instructions table -(OP_SPECIAL, "100000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADD -(OP_NORMAL , "001000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- ADDI -(OP_NORMAL , "001001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ADDIU -(OP_SPECIAL, "100001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADDU -(OP_SPECIAL, "100100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- AND -(OP_NORMAL , "001100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ANDI -(OP_NORMAL , "000100", '1', '0', OP_EQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BEQ -(OP_REGIMM , "000001", '1', '0', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGEZ -(OP_REGIMM , "010001", '1', '1', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BGEZAL -(OP_NORMAL , "000111", '1', '0', OP_SPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGTZ -(OP_NORMAL , "000110", '1', '0', OP_LNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLEZ -(OP_REGIMM , "000000", '1', '0', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLTZ -(OP_REGIMM , "010000", '1', '1', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BLTZAL -(OP_NORMAL , "000101", '1', '0', OP_NEQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BNE -(OP_SPECIAL, "001101", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_BREAK, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BREAK -(OP_COP0 , "000001", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '1', '1', D_00), -- COP0 -(OP_NORMAL , "000010", '1', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- J -(OP_NORMAL , "000011", '1', '1', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_31), -- JAL -(OP_SPECIAL, "001001", '1', '1', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- JALR -(OP_SPECIAL, "001000", '1', '0', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- JR -(OP_NORMAL , "001111", '0', '0', OP_LUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- LUI -(OP_NORMAL , "100011", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '0', D_RT), -- LW -(OP_NORMAL , "110000", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '1', D_RT), -- LWC0 -(OP_COP0 , "000000", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '1', '1', '0', '0', '0', LVL_DI , '1', '0', D_RD), -- MFC0 -(OP_SPECIAL, "010000", '0', '0', OP_MFHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFHI -(OP_SPECIAL, "010010", '0', '0', OP_MFLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFLO -(OP_COP0 , "000100", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '0', '0', LVL_DI , '1', '1', D_RD), -- MTC0 -(OP_SPECIAL, "010001", '0', '0', OP_MTHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTHI -(OP_SPECIAL, "010011", '0', '0', OP_MTLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTLO -(OP_SPECIAL, "011000", '0', '0', OP_MULT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT -(OP_SPECIAL, "011001", '0', '0', OP_MULTU, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT -(OP_SPECIAL, "100111", '0', '0', OP_NOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- NOR -(OP_SPECIAL, "100101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- OR -(OP_NORMAL , "001101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ORI -(OP_SPECIAL, "000000", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SLL -(OP_SPECIAL, "000100", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLLV -(OP_SPECIAL, "101010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLT -(OP_NORMAL , "001010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTI -(OP_NORMAL , "001011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTIU -(OP_SPECIAL, "101011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLTU -(OP_SPECIAL, "000011", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRA -(OP_SPECIAL, "000111", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRAV -(OP_SPECIAL, "000010", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRL -(OP_SPECIAL, "000110", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRLV -(OP_SPECIAL, "100010", '0', '0', OP_SUB , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUB -(OP_SPECIAL, "100011", '0', '0', OP_SUBU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUBU -(OP_NORMAL , "101011", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SW -(OP_NORMAL , "111000", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '1', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SWC0 -(OP_SPECIAL, "001100", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_SCALL, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- SYSC -(OP_SPECIAL, "100110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- XOR -(OP_NORMAL , "001110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT) -- XORI -); - - -- Preparation of the synchronous outputs - signal PRE_bra : std_logic; -- Branch operation - signal PRE_link : std_logic; -- Branch with link - signal PRE_op1 : bus32; -- operand 1 of the ual - signal PRE_op2 : bus32; -- operand 2 of the ual - signal PRE_code_ual : alu_ctrl_type; -- Alu operation - signal PRE_offset : bus32; -- Address offset for calculation - signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result - signal PRE_ecr_reg : std_logic; -- Writing of result in the bank register - signal PRE_mode : std_logic; -- Address calculation with current pc - signal PRE_op_mem : std_logic; -- Memory access operation instruction - signal PRE_r_w : std_logic; -- Read/write selection in memory - signal PRE_exc_cause : bus32; -- Potential exception cause - signal PRE_level : level_type; -- Result availability stage for bypass - -begin - - - -- Instruction decoding - process (EI_instr, EI_adr, data1, data2) - variable op_code : bus6; -- Effective codop of the instruction - variable op_mode : op_mode_type; -- Instruction mode - variable flag : boolean; -- Is true if valid instruction - variable instr : integer; -- Current micro-instruction adress - - -- Instruction fields - variable rs : bus5; - variable rt : bus5; - variable rd : bus5; - variable shamt : bus5; - variable imm : bus16; - variable address : bus26; - begin - - -- Selection of the instruction codop and its mode - case EI_instr(31 downto 26) is - when "000000" => -- special mode - op_mode := OP_SPECIAL; - op_code := EI_instr(5 downto 0); - when "000001" => -- regimm mode - op_mode := OP_REGIMM; - op_code := '0' & EI_instr(20 downto 16); - when "010000" => -- cop0 mode - op_mode := OP_COP0; - op_code := '0' & EI_instr(25 downto 21); - when others => -- normal mode - op_mode := OP_NORMAL; - op_code := EI_instr(31 downto 26); - end case; - - - -- Search the current instruction in the micro-code table - flag := false; - instr := 0; - for i in micro_code'range loop - if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then - flag := true; -- The instruction exists - instr := i; -- Index memorisation - end if; - end loop; - - -- Read the instruction field - rs := EI_instr(25 downto 21); - rt := EI_instr(20 downto 16); - rd := EI_instr(15 downto 11); - shamt := EI_instr(10 downto 6); - imm := EI_instr(15 downto 0); - address := EI_instr(25 downto 0); - - if not flag then -- Unknown instruction - - -- Synchronous output preparation - PRE_bra <= '0'; -- Branch operation - PRE_link <= '0'; -- Branch with link - PRE_op1 <= (others => '0'); -- operand 1 of the ual - PRE_op2 <= (others => '0'); -- operand 2 of the ual - PRE_code_ual <= OP_OUI; -- Alu operation - PRE_offset <= (others => '0'); -- Address offset for calculation - PRE_adr_reg_dest <= (others => '0'); -- Destination register adress for result - PRE_ecr_reg <= '0'; -- Writing of result in the bank register - PRE_mode <= '0'; -- Address calculation with current pc - PRE_op_mem <= '0'; -- Memory access operation instruction - PRE_r_w <= '0'; -- Read/write selection in memory - PRE_exc_cause <= IT_ERINS; -- Potential exception cause - PRE_level <= LVL_DI; -- Result availability stage for bypass - - -- Set asynchronous outputs - adr_reg1 <= (others => '0'); -- First operand register - adr_reg2 <= (others => '0'); -- Second operand register - use1 <= '0'; -- Effective use of operand 1 - use2 <= '0'; -- Effective use of operand 2 - - else -- Valid instruction - - -- Offset signal preparation - case micro_code(instr).off_sel is - when OFS_PCRL => -- PC(31..28) & Adresse & 00 - PRE_offset <= EI_adr(31 downto 28) & address & "00"; - when OFS_NULL => -- 0 - PRE_offset <= (others => '0'); - when OFS_SESH => -- sgn_ext(Imm) & 00 - if imm(15)='1' then - PRE_offset <= "11111111111111" & imm & "00"; - else - PRE_offset <= "00000000000000" & imm & "00"; - end if; - when OFS_SEXT => -- sgn_ext(Imm) - if imm(15)='1' then - PRE_offset <= "1111111111111111" & imm; - else - PRE_offset <= "0000000000000000" & imm; - end if; - end case; - - - -- Alu operand preparation - if micro_code(instr).cs_imm1='0' then - -- Datas from register banks - PRE_op1 <= data1; - else - -- Immediate datas - if micro_code(instr).imm1_sel='0' then - PRE_op1 <= (others => '0'); -- Immediate operand = 0 - else - PRE_op1 <= X"000000" & "000" & shamt; -- Immediate operand = shamt - end if; - end if; - - - if micro_code(instr).cs_imm2='0' then - -- Datas from register banks - PRE_op2 <= data2; - else - -- Immediate datas - if micro_code(instr).imm2_sel='0' then - PRE_op2 <= X"0000" & imm; -- Immediate operand = imm - else - if imm(15)='1' then -- Immediate operand = sgn_ext(imm) - PRE_op2 <= X"FFFF" & imm; - else - PRE_op2 <= X"0000" & imm; - end if; - end if; - end if; - - -- Selection of destination register address - case micro_code(instr).des_sel is - when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt; - when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd; - when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111"; - when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000"; - end case; - - -- Command signal affectation - PRE_bra <= micro_code(instr).bra; -- Branch operation - PRE_link <= micro_code(instr).link; -- Branch with link - PRE_code_ual <= micro_code(instr).code_ual; -- Alu operation - PRE_ecr_reg <= micro_code(instr).ecr_reg; -- Writing the result in a bank register - PRE_mode <= micro_code(instr).mode; -- Type of calculation for the address with current pc - PRE_op_mem <= micro_code(instr).op_mem; -- Memory operation needed - PRE_r_w <= micro_code(instr).r_w; -- Read/Write in memory selection - PRE_exc_cause <= micro_code(instr).exc_cause; -- Potential cause exception - PRE_level <= micro_code(instr).level; - - -- Set asynchronous outputs - adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address - adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address - use1 <= not micro_code(instr).cs_imm1; -- Effective use of operande 1 - use2 <= not micro_code(instr).cs_imm2; -- Effective use of operande 2 - end if; - - end process; - - - - -- Set the synchronous outputs - process (clock) - begin - if clock='1' and clock'event then - if reset='1' then - DI_bra <= '0'; - DI_link <= '0'; - DI_op1 <= (others => '0'); - DI_op2 <= (others => '0'); - DI_code_ual <= OP_OUI; - DI_offset <= (others => '0'); - DI_adr_reg_dest <= (others => '0'); - DI_ecr_reg <= '0'; - DI_mode <= '0'; - DI_op_mem <= '0'; - DI_r_w <= '0'; - DI_adr <= (others => '0'); - DI_exc_cause <= IT_NOEXC; - DI_level <= LVL_DI; - DI_it_ok <= '0'; - elsif stop_all='0' then - if clear='1' or stop_di='1' then - -- Nop instruction - DI_bra <= '0'; - DI_link <= '0'; - DI_op1 <= (others => '0'); - DI_op2 <= (others => '0'); - DI_code_ual <= OP_OUI; - DI_offset <= (others => '0'); - DI_adr_reg_dest <= (others => '0'); - DI_ecr_reg <= '0'; - DI_mode <= '0'; - DI_op_mem <= '0'; - DI_r_w <= '0'; - DI_adr <= EI_adr; - DI_exc_cause <= IT_NOEXC; - DI_level <= LVL_DI; - if clear='1' then - DI_it_ok <= '0'; - else - DI_it_ok <= EI_it_ok; - end if; - else -- Noraml step - DI_bra <= PRE_bra; - DI_link <= PRE_link; - DI_op1 <= PRE_op1; - DI_op2 <= PRE_op2; - DI_code_ual <= PRE_code_ual; - DI_offset <= PRE_offset; - DI_adr_reg_dest <= PRE_adr_reg_dest; - DI_ecr_reg <= PRE_ecr_reg; - DI_mode <= PRE_mode; - DI_op_mem <= PRE_op_mem; - DI_r_w <= PRE_r_w; - DI_adr <= EI_adr; - DI_exc_cause <= PRE_exc_cause; - DI_level <= PRE_level; - DI_it_ok <= EI_it_ok; - end if; - end if; - end if; - end process; - -end rtl; - - Index: trunk/miniMIPS/src/pps_ex.vhd =================================================================== --- trunk/miniMIPS/src/pps_ex.vhd (revision 13) +++ trunk/miniMIPS/src/pps_ex.vhd (nonexistent) @@ -1,184 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- Processor miniMIPS : Execution stage -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; -use work.alu; - -entity pps_ex is -port( - clock : in std_logic; - reset : in std_logic; - stop_all : in std_logic; -- Unconditionnal locking of outputs - clear : in std_logic; -- Clear the pipeline stage - - -- Datas from DI stage - DI_bra : in std_logic; -- Branch instruction - DI_link : in std_logic; -- Branch with link - DI_op1 : in bus32; -- Operand 1 for alu - DI_op2 : in bus32; -- Operand 2 for alu - DI_code_ual : in alu_ctrl_type; -- Alu operation - DI_offset : in bus32; -- Offset for address calculation - DI_adr_reg_dest : in adr_reg_type; -- Destination register address for the result - DI_ecr_reg : in std_logic; -- Effective writing of the result - DI_mode : in std_logic; -- Address mode (relative to pc ou index by a register) - DI_op_mem : in std_logic; -- Memory operation - DI_r_w : in std_logic; -- Type of memory operation (read or write) - DI_adr : in bus32; -- Instruction address - DI_exc_cause : in bus32; -- Potential cause exception - DI_level : in level_type; -- Availability stage of the result for bypassing - DI_it_ok : in std_logic; -- Allow hardware interruptions - - -- Synchronous outputs to MEM stage - EX_adr : out bus32; -- Instruction address - EX_bra_confirm : out std_logic; -- Branch execution confirmation - EX_data_ual : out bus32; -- Ual result - EX_adresse : out bus32; -- Address calculation result - EX_adr_reg_dest : out adr_reg_type; -- Destination register for the result - EX_ecr_reg : out std_logic; -- Effective writing of the result - EX_op_mem : out std_logic; -- Memory operation needed - EX_r_w : out std_logic; -- Type of memory operation (read or write) - EX_exc_cause : out bus32; -- Potential cause exception - EX_level : out level_type; -- Availability stage of result for bypassing - EX_it_ok : out std_logic -- Allow hardware interruptions -); -end entity; - - -architecture rtl of pps_ex is - -component alu - port ( - clock : in bus1; - reset : in bus1; - op1 : in bus32; -- Operand 1 - op2 : in bus32; -- Operand 2 - ctrl : in alu_ctrl_type; -- Operation - - res : out bus32; -- Result - overflow : out bus1 -- Overflow - ); - end component; - - signal res_ual : bus32; -- Alu result output - signal base_adr : bus32; -- Output of the address mode mux selection - - signal pre_ecr_reg : std_logic; -- Output of mux selection for writing command to register - signal pre_data_ual : bus32; -- Mux selection of the data to write - signal pre_bra_confirm : std_logic; -- Result of the test in alu when branch instruction - signal pre_exc_cause : bus32; -- Preparation of the exception detection signal - signal overflow_ual : std_logic; -- Dectection of the alu overflow - -begin - - -- Alu instantiation - U1_alu : alu port map (clock => clock, reset => reset, op1=>DI_op1, op2=>DI_op2, ctrl=>DI_code_ual, - res=>res_ual, overflow=>overflow_ual); - - -- Calculation of the future outputs - base_adr <= DI_op1 when DI_mode='0' else DI_adr; - pre_ecr_reg <= DI_ecr_reg when DI_link='0' else pre_bra_confirm; - pre_data_ual <= res_ual when DI_link='0' else bus32(unsigned(DI_adr) + 4); - pre_bra_confirm <= DI_bra and res_ual(0); - pre_exc_cause <= DI_exc_cause when DI_exc_cause/=IT_NOEXC else - IT_OVERF when overflow_ual='1' else - IT_NOEXC; - - -- Set the synchronous outputs - process(clock) is - begin - if clock='1' and clock'event then - if reset='1' then - EX_adr <= (others => '0'); - EX_bra_confirm <= '0'; - EX_data_ual <= (others => '0'); - EX_adresse <= (others => '0'); - EX_adr_reg_dest <= (others => '0'); - EX_ecr_reg <= '0'; - EX_op_mem <= '0'; - EX_r_w <= '0'; - EX_exc_cause <= IT_NOEXC; - EX_level <= LVL_DI; - EX_it_ok <= '0'; - elsif stop_all = '0' then - if clear = '1' then -- Clear the stage - EX_adr <= DI_adr; - EX_bra_confirm <= '0'; - EX_data_ual <= (others => '0'); - EX_adresse <= (others => '0'); - EX_adr_reg_dest <= (others => '0'); - EX_ecr_reg <= '0'; - EX_op_mem <= '0'; - EX_r_w <= '0'; - EX_exc_cause <= IT_NOEXC; - EX_level <= LVL_DI; - EX_it_ok <= '0'; - else -- Normal evolution - EX_adr <= DI_adr; - EX_bra_confirm <= pre_bra_confirm; - EX_data_ual <= pre_data_ual; - EX_adr_reg_dest <= DI_adr_reg_dest; - EX_ecr_reg <= pre_ecr_reg; - EX_op_mem <= DI_op_mem; - EX_r_w <= DI_r_w; - EX_exc_cause <= pre_exc_cause; - EX_level <= DI_level; - EX_it_ok <= DI_it_ok; - EX_adresse <= bus32(unsigned(DI_offset) + unsigned(base_adr)); - end if; - end if; - end if; - end process; - -end architecture; Index: trunk/miniMIPS/src/pps_ei.vhd =================================================================== --- trunk/miniMIPS/src/pps_ei.vhd (revision 13) +++ trunk/miniMIPS/src/pps_ei.vhd (nonexistent) @@ -1,109 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Instruction extraction stage -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity pps_ei is -port ( - clock : in std_logic; - reset : in std_logic; - clear : in std_logic; -- Clear the pipeline stage - stop_all : in std_logic; -- Evolution locking signal - - -- Asynchronous inputs - stop_ei : in std_logic; -- Lock the EI_adr and Ei_instr registers - - -- Bus controler interface - CTE_instr : in bus32; -- Instruction from the memory - ETC_adr : out bus32; -- Address to read in memory - - -- Synchronous inputs from PF stage - PF_pc : in bus32; -- Current value of the pc - - -- Synchronous outputs to DI stage - EI_instr : out bus32; -- Read interface - EI_adr : out bus32; -- Address from the read instruction - EI_it_ok : out std_logic -- Allow hardware interruptions -); -end pps_ei; - -architecture rtl of pps_ei is -begin - - ETC_adr <= PF_pc; -- Connexion of the PC to the memory address bus - - -- Set the results - process (clock) - begin - if (clock='1' and clock'event) then - if reset='1' then - EI_instr <= INS_NOP; - EI_adr <= (others => '0'); - EI_it_ok <= '0'; - elsif stop_all='0' then - if clear='1' then - -- Clear the stage - EI_instr <= INS_NOP; - EI_it_ok <= '0'; - elsif stop_ei='0' then - -- Normal evolution - EI_adr <= PF_pc; - EI_instr <= CTE_instr; - EI_it_ok <= '1'; - end if; - end if; - end if; - end process; -end rtl; Index: trunk/miniMIPS/src/pps_mem.vhd =================================================================== --- trunk/miniMIPS/src/pps_mem.vhd (revision 13) +++ trunk/miniMIPS/src/pps_mem.vhd (nonexistent) @@ -1,149 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- Processor miniMIPS : Memory access stage -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - - - -library IEEE; -use IEEE.std_logic_1164.all; - -library work; -use work.pack_mips.all; - -entity pps_mem is -port -( - clock : in std_logic; - reset : in std_logic; - stop_all : in std_logic; -- Unconditionnal locking of the outputs - clear : in std_logic; -- Clear the pipeline stage - - -- Interface with the control bus - MTC_data : out bus32; -- Data to write in memory - MTC_adr : out bus32; -- Address for memory - MTC_r_w : out std_logic; -- Read/Write in memory - MTC_req : out std_logic; -- Request access to memory - CTM_data : in bus32; -- Data from memory - - -- Datas from Execution stage - EX_adr : in bus32; -- Instruction address - EX_data_ual : in bus32; -- Result of alu operation - EX_adresse : in bus32; -- Result of the calculation of the address - EX_adr_reg_dest : in adr_reg_type; -- Destination register address for the result - EX_ecr_reg : in std_logic; -- Effective writing of the result - EX_op_mem : in std_logic; -- Memory operation needed - EX_r_w : in std_logic; -- Type of memory operation (read or write) - EX_exc_cause : in bus32; -- Potential exception cause - EX_level : in level_type; -- Availability stage for the result for bypassing - EX_it_ok : in std_logic; -- Allow hardware interruptions - - -- Synchronous outputs for bypass unit - MEM_adr : out bus32; -- Instruction address - MEM_adr_reg_dest : out adr_reg_type; -- Destination register address - MEM_ecr_reg : out std_logic; -- Writing of the destination register - MEM_data_ecr : out bus32; -- Data to write (from alu or memory) - MEM_exc_cause : out bus32; -- Potential exception cause - MEM_level : out level_type; -- Availability stage for the result for bypassing - MEM_it_ok : out std_logic -- Allow hardware interruptions -); -end pps_mem; - - -architecture rtl of pps_mem is - - signal tmp_data_ecr : bus32; -- Selection of the data source (memory or alu) - -begin - - -- Bus controler connexions - MTC_adr <= EX_adresse; -- Connexion of the address - MTC_r_w <= EX_r_w; -- Connexion of R/W - MTC_data <= EX_data_ual; -- Connexion of the data bus - MTC_req <= EX_op_mem and not clear; -- Connexion of the request (if there is no clearing of the pipeline) - - - -- Preselection of the data source for the outputs - tmp_data_ecr <= CTM_data when EX_op_mem = '1' else EX_data_ual; - - - -- Set the synchronous outputs - process (clock) - begin - if clock = '1' and clock'event then - if reset = '1' then - MEM_adr <= (others => '0'); - MEM_adr_reg_dest <= (others => '0'); - MEM_ecr_reg <= '0'; - MEM_data_ecr <= (others => '0'); - MEM_exc_cause <= IT_NOEXC; - MEM_level <= LVL_DI; - MEM_it_ok <= '0'; - elsif stop_all = '0' then - if clear = '1' then -- Clear the stage - MEM_adr <= EX_adr; - MEM_adr_reg_dest <= (others => '0'); - MEM_ecr_reg <= '0'; - MEM_data_ecr <= (others => '0'); - MEM_exc_cause <= IT_NOEXC; - MEM_level <= LVL_DI; - MEM_it_ok <= '0'; - else -- Normal evolution - MEM_adr <= EX_adr; - MEM_adr_reg_dest <= EX_adr_reg_dest; - MEM_ecr_reg <= EX_ecr_reg; - MEM_data_ecr <= tmp_data_ecr; - MEM_exc_cause <= EX_exc_cause; - MEM_level <= EX_level; - MEM_it_ok <= EX_it_ok; - end if; - end if; - end if; - end process; - -end rtl; Index: trunk/miniMIPS/src/syscop.vhd =================================================================== --- trunk/miniMIPS/src/syscop.vhd (revision 13) +++ trunk/miniMIPS/src/syscop.vhd (nonexistent) @@ -1,203 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Coprocessor system (cop0) -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - - -library ieee; -use ieee.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - --- By convention in the commentary, the term interruption means hardware interruptions and software exceptions - -entity syscop is -port -( - clock : in std_logic; - reset : in std_logic; - - -- Datas from the pipeline - MEM_adr : in bus32; -- Address of the current instruction in the pipeline end -> responsible of the exception - MEM_exc_cause : in bus32; -- Potential cause exception of that instruction - MEM_it_ok : in std_logic; -- Allow hardware interruptions - - -- Hardware interruption - it_mat : in std_logic; -- Hardware interruption detected - - -- Interruption controls - interrupt : out std_logic; -- Interruption to take into account - vecteur_it : out bus32; -- Interruption vector - - -- Writing request in register bank - write_data : in bus32; -- Data to write - write_adr : in bus5; -- Address of the register to write - write_SCP : in std_logic; -- Writing request - - -- Reading request in register bank - read_adr1 : in bus5; -- Address of the first register - read_adr2 : in bus5; -- Address of the second register - read_data1 : out bus32; -- Value of register 1 - read_data2 : out bus32 -- Value of register 2 -); -end syscop; - - -architecture rtl of syscop is - - subtype adr_scp_reg is integer range 12 to 15; - - type scp_reg_type is array (integer range adr_scp_reg'low to adr_scp_reg'high) of bus32; - - -- Constants to define the coprocessor registers - constant COMMAND : integer := 0; -- False register to command the coprocessor system - constant STATUS : adr_scp_reg := 12; -- Registre 12 of the coprocessor system - constant CAUSE : adr_scp_reg := 13; -- Registre 13 of the coprocessor system - constant ADRESSE : adr_scp_reg := 14; -- Registre 14 of the coprocessor system - constant VECTIT : adr_scp_reg := 15; -- Registre 15 of the coprocessor system - - signal scp_reg : scp_reg_type; -- Internal register bank - signal pre_reg : scp_reg_type; -- Register bank preparation - - signal adr_src1 : integer range 0 to 31; - signal adr_src2 : integer range 0 to 31; - signal adr_dest : integer range 0 to 31; - - signal exception : std_logic; -- Set to '1' when exception detected - signal interruption : std_logic; -- Set to '1' when interruption detected - signal cmd_itret : std_logic; -- Set to '1' when interruption return command is detected - - signal save_msk : std_logic; -- Save the mask state when an interruption occurs - -begin - - -- Detection of the interruptions - exception <= '1' when MEM_exc_cause/=IT_NOEXC else '0'; - interruption <= '1' when it_mat='1' and scp_reg(STATUS)(0)='1' and MEM_it_ok='1' else '0'; - - -- Update asynchronous outputs - interrupt <= exception or interruption; -- Detection of interruptions - vecteur_it <= scp_reg(ADRESSE) when cmd_itret = '1' else -- Send the return adress when a return instruction appears - scp_reg(VECTIT); -- Send the interruption vector in other cases - - - -- Decode the address of the registers - adr_src1 <= to_integer(unsigned(read_adr1)); - adr_src2 <= to_integer(unsigned(read_adr2)); - adr_dest <= to_integer(unsigned(write_adr)); - - -- Read the two registers - read_data1 <= (others => '0') when (adr_src1scp_reg'high) else - scp_reg(adr_src1); - read_data2 <= (others => '0') when adr_src2scp_reg'high else - scp_reg(adr_src2); - - -- Define the pre_reg signal, next value for the registers - process (scp_reg, adr_dest, write_SCP, write_data, interruption, - exception, MEM_exc_cause, MEM_adr, reset) - begin - pre_reg <= scp_reg; - cmd_itret <= '0'; -- No IT return in most cases - - -- Potential writing in a register - if (write_SCP='1' and adr_dest>=pre_reg'low and adr_dest<=pre_reg'high) then - pre_reg(adr_dest) <= write_data; - end if; - - -- Command from the core - if write_SCP='1' and adr_dest=COMMAND then - case write_data is -- Different operations - when SYS_UNMASK => pre_reg(STATUS)(0) <= '1'; -- Unamsk command - when SYS_MASK => pre_reg(STATUS)(0) <= '0'; -- Mask command - when SYS_ITRET => -- Interruption return command - pre_reg(STATUS)(0) <= save_msk; -- Restore the mask before the interruption - cmd_itret <= '1'; -- False interruption request (to clear the pipeline) - when others => null; - end case; - end if; - - -- Modifications from the interruptions - if interruption='1' then - pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions - pre_reg(CAUSE) <= IT_ITMAT; -- Save the interruption cause - pre_reg(ADRESSE) <= MEM_adr; -- Save the return address - end if; - - -- Modifications from the exceptions - if exception='1' then - pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions - pre_reg(CAUSE) <= MEM_exc_cause; -- Save the exception cause - pre_reg(ADRESSE) <= MEM_adr; -- Save the return address - end if; - - -- The reset has the priority on the other cuases - if reset='1' then - pre_reg <= (others => (others => '0')); - -- NB : The processor is masked after a reset - -- The exception handler is set at address 0 - end if; - end process; - - -- Memorisation of the modifications in the register bank - process(clock) - begin - if clock='1' and clock'event then - - -- Save the mask when an interruption appears - if (exception='1') or (interruption='1') then - save_msk <= scp_reg(STATUS)(0); - end if; - - scp_reg <= pre_reg; - - end if; - end process; - -end rtl; Index: trunk/miniMIPS/src/alu.vhd =================================================================== --- trunk/miniMIPS/src/alu.vhd (revision 13) +++ trunk/miniMIPS/src/alu.vhd (nonexistent) @@ -1,191 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Arithmetical and logical unit -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity alu is -port -( - clock : in bus1; - reset : in bus1; - op1 : in bus32; -- Operand 1 - op2 : in bus32; -- Operand 2 - ctrl : in alu_ctrl_type; -- Opearator control - - res : out bus32; -- The result is 32 bit long - overflow : out bus1 -- Overflow of the result -); -end alu; - - -architecture rtl of alu is - - -- Signals to pre-process the operands - signal efct_op1, efct_op2 : bus33; -- Effective operands of the adder (33 bits) - signal comp_op2 : bus1; -- Select the opposite of operand 2 - signal igno_op2 : bus1; -- Ignore op 2 (put zeros) - signal sign_op1 : bus1; -- High bit of op 1 - signal sign_op2 : bus1; -- High bit of op 2 - signal signe : bus1; -- Signed operation (bit sign extension) - signal shift_val : natural range 0 to 31; -- Value of the shift - - -- Signals for internal results - signal res_shl, res_shr : bus32; -- Results of left and right shifter - signal res_lui : bus32; -- Result of Load Upper Immediate - signal res_add : bus33; -- Result of the adder - signal carry : bus33; -- Carry for the adder - signal nul : bus1; -- Check if the adder result is zero - signal hilo : bus64; -- Internal registers to store the multiplication operation - signal tmp_hilo : bus64; -- Internal registers to store the multiplication operation (synchronised) - -begin - - -- Process if the operation is signed compliant - signe <= '1' when (ctrl=OP_ADD or ctrl=OP_SUB or ctrl=OP_SLT or ctrl=OP_SNEG or ctrl=OP_SPOS or ctrl=OP_LNEG or ctrl=OP_LPOS) - else - '0'; - - sign_op1 <= signe and op1(31); - sign_op2 <= signe and op2(31); - - -- Selection of the value of the second operand : op2 or -op2 (ie not op2 + 1) - comp_op2 <= '1' when -- The opposite of op2 is used - (ctrl=OP_SUB or ctrl=OP_SUBU) -- Opposite of the operand 2 to obtain a substraction - or (ctrl=OP_SLT or ctrl=OP_SLTU) -- Process the difference to check the lesser than operation for the operands - or (ctrl=OP_EQU or ctrl=OP_NEQU) -- Process the difference to check the equality of the operands - else - '0'; -- by default, op2 is used - - igno_op2 <= '1' when -- Op 2 will be zero (when comp_op2='0') - (ctrl=OP_SPOS or ctrl=OP_LNEG) -- Process if the op1 is nul with op1+0 - else - '0'; - - -- Effective signals for the adder - efct_op2 <= not (sign_op2 & op2) when (comp_op2='1') else -- We take the opposite of op2 to get -op2 (we will add 1 with the carry) - (others => '0') when (igno_op2='1') else -- Op2 is zero - (sign_op2 & op2); -- by default we use op2 (33 bits long) - - efct_op1 <= sign_op1 & op1; - - -- Execution of the addition - carry <= X"00000000" & comp_op2; -- Carry to one when -op2 is needed - res_add <= std_logic_vector(unsigned(efct_op1) + unsigned(efct_op2) + unsigned(carry)); - - nul <= '1' when (res_add(31 downto 0)=X"00000000") else '0'; -- Check the nullity of the result - - -- Value of the shift for the programmable shifter - shift_val <= to_integer(unsigned(op1(4 downto 0))); - - res_shl <= bus32(shift_left(unsigned(op2), shift_val)); - res_shr <= not bus32(shift_right(unsigned(not op2) , shift_val)) when (ctrl=OP_SRA and op2(31)='1') else - bus32(shift_right(unsigned(op2), shift_val)); - res_lui <= op2(15 downto 0) & X"0000"; - - -- Affectation of the hilo register if necessary - tmp_hilo <= std_logic_vector(signed(op1)*signed(op2)) when (ctrl=OP_MULT) else - std_logic_vector(unsigned(op1)*unsigned(op2)) when (ctrl=OP_MULTU) else - op1 & hilo(31 downto 0) when (ctrl=OP_MTHI) else - hilo(63 downto 32) & op1 when (ctrl=OP_MTLO) else - (others => '0'); - - -- Check the overflows - overflow <= '1' when ((ctrl=OP_ADD and op1(31)=efct_op2(31) and op1(31)/=res_add(31)) - or (ctrl=OP_SUB and op1(31)/=op2(31) and op1(31)/=res_add(31))) else - '0'; -- Only ADD and SUB can overflow - - -- Result affectation - res <= - -- Arithmetical operations - res_add(31 downto 0) when (ctrl=OP_ADD or ctrl=OP_ADDU or ctrl=OP_SUB or ctrl=OP_SUBU) else - -- Logical operations - op1 and op2 when (ctrl=OP_AND) else - op1 or op2 when (ctrl=OP_OR) else - op1 nor op2 when (ctrl=OP_NOR) else - op1 xor op2 when (ctrl=OP_XOR) else - -- Different tests : the result is one when the test is succesful - (0 => res_add(32), others=>'0') when (ctrl=OP_SLTU or ctrl=OP_SLT) else - (0 => nul, others=>'0') when (ctrl=OP_EQU) else - (0 => not nul, others=>'0') when (ctrl=OP_NEQU) else - (0 => op1(31), others=>'0') when (ctrl=OP_SNEG) else - (0 => not (op1(31) or nul), others=>'0') when (ctrl=OP_SPOS) else - (0 => (op1(31) or nul), others=>'0') when (ctrl=OP_LNEG) else - (0 => not op1(31), others=>'0') when (ctrl=OP_LPOS) else - -- Shifts - res_shl when (ctrl=OP_SLL) else - res_shr when (ctrl=OP_SRL or ctrl=OP_SRA) else - res_lui when (ctrl=OP_LUI) else - -- Internal registers - hilo(63 downto 32) when (ctrl=OP_MFHI) else - hilo(31 downto 0) when (ctrl=OP_MFLO or ctrl=OP_MULT or ctrl=OP_MULTU) else - op1 when (ctrl=OP_MTHI or ctrl=OP_MTLO) else - op2 when (ctrl=OP_OP2) else - -- Always true - X"00000001" when (ctrl=OP_OUI) else - -- Unknown operation or nul result desired - (others => '0'); - - -- Save the hilo register - process (clock) - begin - if clock = '1' and clock'event then - if reset = '1' then - hilo <= (others => '0'); - elsif (ctrl = OP_MULT) or (ctrl = OP_MULTU) or (ctrl = OP_MTLO) or (ctrl = OP_MTHI) then - hilo <= tmp_hilo; - end if; - end if; - end process; -end rtl; Index: trunk/miniMIPS/src/renvoi.vhd =================================================================== --- trunk/miniMIPS/src/renvoi.vhd (revision 13) +++ trunk/miniMIPS/src/renvoi.vhd (nonexistent) @@ -1,176 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Bypass unit -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity renvoi is -port ( - -- Register access signals - adr1 : in adr_reg_type; -- Operand 1 address - adr2 : in adr_reg_type; -- Operand 2 address - use1 : in std_logic; -- Operand 1 utilisation - use2 : in std_logic; -- Operand 2 utilisation - - data1 : out bus32; -- First register value - data2 : out bus32; -- Second register value - alea : out std_logic; -- Unresolved hazards detected - - -- Bypass signals of the intermediary datas - DI_level : in level_type; -- Availability level of the data - DI_adr : in adr_reg_type; -- Register destination of the result - DI_ecr : in std_logic; -- Writing register request - DI_data : in bus32; -- Data to used - - EX_level : in level_type; -- Availability level of the data - EX_adr : in adr_reg_type; -- Register destination of the result - EX_ecr : in std_logic; -- Writing register request - EX_data : in bus32; -- Data to used - - MEM_level : in level_type; -- Availability level of the data - MEM_adr : in adr_reg_type; -- Register destination of the result - MEM_ecr : in std_logic; -- Writing register request - MEM_data : in bus32; -- Data to used - - interrupt : in std_logic; -- Exceptions or interruptions - - -- Connexion to the differents bank of register - - -- Writing commands for writing in the registers - write_data : out bus32; -- Data to write - write_adr : out bus5; -- Address of the register to write - write_GPR : out std_logic; -- Selection in the internal registers - write_SCP : out std_logic; -- Selection in the coprocessor system registers - - -- Reading commands for Reading in the registers - read_adr1 : out bus5; -- Address of the first register to read - read_adr2 : out bus5; -- Address of the second register to read - read_data1_GPR : in bus32; -- Value of operand 1 from the internal registers - read_data2_GPR : in bus32; -- Value of operand 2 from the internal registers - read_data1_SCP : in bus32; -- Value of operand 1 from the coprocessor system registers - read_data2_SCP : in bus32 -- Value of operand 2 from the coprocessor system registers -); -end renvoi; - -architecture rtl of renvoi is - signal dep_r1 : level_type; -- Dependency level for operand 1 - signal dep_r2 : level_type; -- Dependency level for operand 2 - signal read_data1 : bus32; -- Data contained in the register asked by operand 1 - signal read_data2 : bus32; -- Data contained in the register asked by operand 2 - signal res_reg, res_mem, res_ex, res_di : std_logic; - signal resolution : bus4; -- Verification of the resolved hazards - - signal idx1, idx2 : integer range 0 to 3; -begin - - -- Connexion of the writing command signals - write_data <= MEM_data; - write_adr <= MEM_adr(4 downto 0); - write_GPR <= not MEM_adr(5) and MEM_ecr when interrupt = '0' else -- The high bit to 0 selects the internal registers - '0'; - write_SCP <= MEM_adr(5) and MEM_ecr; -- The high bit to 1 selects the coprocessor system registers - - -- Connexion of the writing command signals - read_adr1 <= adr1(4 downto 0); -- Connexion of the significative address bits - read_adr2 <= adr2(4 downto 0); -- Connexion of the significative address bits - - -- Evaluation of the level of dependencies - dep_r1 <= LVL_REG when adr1(4 downto 0)="00000" or use1='0' else -- No dependency with register 0 - LVL_DI when adr1=DI_adr and DI_ecr ='1' else -- Dependency with DI stage - LVL_EX when adr1=EX_adr and EX_ecr ='1' else -- Dependency with DI stage - LVL_MEM when adr1=MEM_adr and MEM_ecr='1' else -- Dependency with DI stage - LVL_REG; -- No dependency detected - - dep_r2 <= LVL_REG when adr2(4 downto 0)="00000" or use2='0' else -- No dependency with register 0 - LVL_DI when adr2=DI_adr and DI_ecr ='1' else -- Dependency with DI stage - LVL_EX when adr2=EX_adr and EX_ecr ='1' else -- Dependency with DI stage - LVL_MEM when adr2=MEM_adr and MEM_ecr='1' else -- Dependency with DI stage - LVL_REG; -- No dependency detected - - -- Elaboration of the signals with the datas form the bank registers - read_data1 <= read_data1_GPR when adr1(5)='0' else -- Selection of the internal registers - read_data1_SCP when adr1(5)='1' else -- Selection of the coprocessor registers - (others => '0'); - - read_data2 <= read_data2_GPR when adr2(5)='0' else -- Selection of the internal registers - read_data2_SCP when adr2(5)='1' else -- Selection of the coprocessor registers - (others => '0'); - - -- Bypass the datas (the validity is tested later when detecting the hazards) - data1 <= read_data1 when dep_r1=LVL_REG else - MEM_data when dep_r1=LVL_MEM else - EX_data when dep_r1=LVL_EX else - DI_data; - - data2 <= read_data2 when dep_r2=LVL_REG else - MEM_data when dep_r2=LVL_MEM else - EX_data when dep_r2=LVL_EX else - DI_data; - - -- Detection of a potential unresolved hazard - res_reg <= '1'; -- This hazard is always resolved - res_mem <= '1' when MEM_level>=LVL_MEM else '0'; - res_ex <= '1' when EX_level >=LVL_EX else '0'; - res_di <= '1' when DI_level >=LVL_DI else '0'; - - -- Table defining the resolved hazard for each stage - resolution <= res_di & res_ex & res_mem & res_reg; - - -- Verification of the validity of the transmitted datas (test the good resolution of the hazards) - idx1 <= to_integer(unsigned(dep_r1(1 downto 0))); - idx2 <= to_integer(unsigned(dep_r2(1 downto 0))); - alea <= not resolution(idx1) or not resolution(idx2); - -end rtl; Index: trunk/miniMIPS/src/banc.vhd =================================================================== --- trunk/miniMIPS/src/banc.vhd (revision 13) +++ trunk/miniMIPS/src/banc.vhd (nonexistent) @@ -1,115 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Register bank -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity banc is -port ( - clock : in bus1; - reset : in bus1; - - -- Register addresses to read - reg_src1 : in bus5; - reg_src2 : in bus5; - - -- Register address to write and its data - reg_dest : in bus5; - donnee : in bus32; - - -- Write signal - cmd_ecr : in bus1; - - -- Bank outputs - data_src1 : out bus32; - data_src2 : out bus32 - ); -end banc; - - -architecture rtl of banc is - - -- The register bank - type tab_reg is array (1 to 31) of bus32; - signal registres : tab_reg; - signal adr_src1 : integer range 0 to 31; - signal adr_src2 : integer range 0 to 31; - signal adr_dest : integer range 0 to 31; -begin - - adr_src1 <= to_integer(unsigned(reg_src1)); - adr_src2 <= to_integer(unsigned(reg_src2)); - adr_dest <= to_integer(unsigned(reg_dest)); - - - data_src1 <= (others => '0') when adr_src1=0 else - registres(adr_src1); - data_src2 <= (others => '0') when adr_src2=0 else - registres(adr_src2); - - process(clock) - begin - if clock = '1' and clock'event then - if reset='1' then - for i in 1 to 31 loop - registres(i) <= (others => '0'); - end loop; - elsif cmd_ecr = '1' and adr_dest /= 0 then - -- The data is saved - registres(adr_dest) <= donnee; - end if; - end if; - end process; - -end rtl; Index: trunk/miniMIPS/src/minimips.vhd =================================================================== --- trunk/miniMIPS/src/minimips.vhd (revision 13) +++ trunk/miniMIPS/src/minimips.vhd (nonexistent) @@ -1,496 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : miniMIPS processor -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2004 -- --------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -library work; -use work.pack_mips.all; - -entity minimips is -port ( - clock : in std_logic; - reset : in std_logic; - - -- Ram connexion - ram_req : out std_logic; - ram_adr : out bus32; - ram_r_w : out std_logic; - ram_data : inout bus32; - ram_ack : in std_logic; - - -- Hardware interruption - it_mat : in std_logic -); -end minimips; - -architecture rtl of minimips is - - -- General signals - signal stop_all : std_logic; -- Lock the pipeline evolution - signal it_mat_clk : std_logic; -- Synchronised hardware interruption - - -- interface PF - EI - signal PF_pc : bus32; -- PC value - - -- interface Controler - EI - signal CTE_instr : bus32; -- Instruction from the memory - signal ETC_adr : bus32; -- Address to read in memory - - -- interface EI - DI - signal EI_instr : bus32; -- Read interface - signal EI_adr : bus32; -- Address from the read instruction - signal EI_it_ok : std_logic; -- Allow hardware interruptions - - -- Asynchronous connexion with the bypass unit - signal adr_reg1 : adr_reg_type; -- Operand 1 address - signal adr_reg2 : adr_reg_type; -- Operand 2 address - signal use1 : std_logic; -- Operand 1 utilisation - signal use2 : std_logic; -- Operand 2 utilisation - signal data1 : bus32; -- First register value - signal data2 : bus32; -- Second register value - signal alea : std_logic; -- Unresolved hazards detected - - - -- interface DI - EX - signal DI_bra : std_logic; -- Branch decoded - signal DI_link : std_logic; -- A link for that instruction - signal DI_op1 : bus32; -- operand 1 for alu - signal DI_op2 : bus32; -- operand 2 for alu - signal DI_code_ual : alu_ctrl_type; -- Alu operation - signal DI_offset : bus32; -- Offset for the address calculation - signal DI_adr_reg_dest : adr_reg_type; -- Address of the destination register of the result - signal DI_ecr_reg : std_logic; -- Effective writing of the result - signal DI_mode : std_logic; -- Address mode (relative to pc or indexed to a register) - signal DI_op_mem : std_logic; -- Memory operation request - signal DI_r_w : std_logic; -- Type of memory operation (reading or writing) - signal DI_adr : bus32; -- Address of the decoded instruction - signal DI_exc_cause : bus32; -- Potential exception detected - signal DI_level : level_type; -- Availability of the result for the data bypass - signal DI_it_ok : std_logic; -- Allow hardware interruptions - - -- interface EX - MEM - signal EX_adr : bus32; -- Instruction address - signal EX_bra_confirm : std_logic; -- Branch execution confirmation - signal EX_data_ual : bus32; -- Ual result - signal EX_adresse : bus32; -- Address calculation result - signal EX_adr_reg_dest : adr_reg_type; -- Destination register for the result - signal EX_ecr_reg : std_logic; -- Effective writing of the result - signal EX_op_mem : std_logic; -- Memory operation needed - signal EX_r_w : std_logic; -- Type of memory operation (read or write) - signal EX_exc_cause : bus32; -- Potential cause exception - signal EX_level : level_type; -- Availability stage of result for bypassing - signal EX_it_ok : std_logic; -- Allow hardware interruptions - - -- interface Controler - MEM - signal MTC_data : bus32; -- Data to write in memory - signal MTC_adr : bus32; -- Address for memory - signal MTC_r_w : std_logic; -- Read/Write in memory - signal MTC_req : std_logic; -- Request access to memory - signal CTM_data : bus32; -- Data from memory - - -- interface MEM - REG - signal MEM_adr : bus32; -- Instruction address - signal MEM_adr_reg_dest : adr_reg_type; -- Destination register address - signal MEM_ecr_reg : std_logic; -- Writing of the destination register - signal MEM_data_ecr : bus32; -- Data to write (from alu or memory) - signal MEM_exc_cause : bus32; -- Potential exception cause - signal MEM_level : level_type; -- Availability stage for the result for bypassing - signal MEM_it_ok : std_logic; -- Allow hardware interruptions - - -- connexion to the register banks - - -- Writing commands in the register banks - signal write_data : bus32; -- Data to write - signal write_adr : bus5; -- Address of the register to write - signal write_GPR : std_logic; -- Selection in the internal registers - signal write_SCP : std_logic; -- Selection in the coprocessor system registers - - -- Reading commands for Reading in the registers - signal read_adr1 : bus5; -- Address of the first register to read - signal read_adr2 : bus5; -- Address of the second register to read - signal read_data1_GPR : bus32; -- Value of operand 1 from the internal registers - signal read_data1_SCP : bus32; -- Value of operand 2 from the internal registers - signal read_data2_GPR : bus32; -- Value of operand 1 from the coprocessor system registers - signal read_data2_SCP : bus32; -- Value of operand 2 from the coprocessor system registers - - -- Interruption controls - signal interrupt : std_logic; -- Interruption to take into account - signal vecteur_it : bus32; -- Interruption vector - - -- Connexion with predict - signal PR_bra_cmd : std_logic; -- Defined a branch - signal PR_bra_bad : std_logic; -- Defined a branch to restore from a bad prediction - signal PR_bra_adr : std_logic_vector(31 downto 0); -- New PC - signal PR_clear : std_logic; -- Clear the three pipeline stage : EI, DI, EX - - -- Clear asserted when interrupt or PR_clear are asserted - signal clear : std_logic; - -begin - - clear <= interrupt or PR_clear; - - -- Take into account the hardware interruption on rising edge - process (clock) - begin - if clock='1' and clock'event then - it_mat_clk <= it_mat; - end if; - end process; - - U1_pf : pps_pf port map ( - clock => clock, - reset => reset, - stop_all => stop_all, -- Unconditionnal locking of the pipeline stage - - -- entrees asynchrones - bra_adr => PR_bra_adr, -- Branch - bra_cmd => PR_bra_cmd, -- Address to load when an effective branch - bra_cmd_pr => PR_bra_bad, -- Branch which have a priority on stop_pf (bad prediction branch) - exch_adr => vecteur_it, -- Exception branch - exch_cmd => interrupt, -- Exception vector - -- Lock the stage - stop_pf => alea, - - -- Synchronous output to EI stage - PF_pc => PF_pc -- PC value - ); - - - U2_ei : pps_ei port map ( - clock => clock, - reset => reset, - clear => clear, -- Clear the pipeline stage - stop_all => stop_all, -- Evolution locking signal - - -- Asynchronous inputs - stop_ei => alea, -- Lock the EI_adr and Ei_instr registers - - -- interface Controler - EI - CTE_instr => CTE_instr, -- Instruction from the memory - ETC_adr => ETC_adr, -- Address to read in memory - - -- Synchronous inputs from PF stage - PF_pc => PF_pc, -- Current value of the pc - - -- Synchronous outputs to DI stage - EI_instr => EI_instr, -- Read interface - EI_adr => EI_adr, -- Address from the read instruction - EI_it_ok => EI_it_ok -- Allow hardware interruptions - ); - - - U3_di : pps_di port map ( - clock => clock, - reset => reset, - stop_all => stop_all, -- Unconditionnal locking of the outputs - clear => clear, -- Clear the pipeline stage (nop in the outputs) - - -- Asynchronous connexion with the register management and data bypass unit - adr_reg1 => adr_reg1, -- Address of the first register operand - adr_reg2 => adr_reg2, -- Address of the second register operand - use1 => use1, -- Effective use of operand 1 - use2 => use2, -- Effective use of operand 2 - - stop_di => alea, -- Unresolved detected : send nop in the pipeline - data1 => data1, -- Operand register 1 - data2 => data2, -- Operand register 2 - - -- Datas from EI stage - EI_adr => EI_adr, -- Address of the instruction - EI_instr => EI_instr, -- The instruction to decode - EI_it_ok => EI_it_ok, -- Allow hardware interruptions - - -- Synchronous output to EX stage - DI_bra => DI_bra, -- Branch decoded - DI_link => DI_link, -- A link for that instruction - DI_op1 => DI_op1, -- operand 1 for alu - DI_op2 => DI_op2, -- operand 2 for alu - DI_code_ual => DI_code_ual, -- Alu operation - DI_offset => DI_offset, -- Offset for the address calculation - DI_adr_reg_dest => DI_adr_reg_dest, -- Address of the destination register of the result - DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result - DI_mode => DI_mode, -- Address mode (relative to pc or indexed to a register) - DI_op_mem => DI_op_mem, -- Memory operation request - DI_r_w => DI_r_w, -- Type of memory operation (reading or writing) - DI_adr => DI_adr, -- Address of the decoded instruction - DI_exc_cause => DI_exc_cause, -- Potential exception detected - DI_level => DI_level, -- Availability of the result for the data bypass - DI_it_ok => DI_it_ok -- Allow hardware interruptions - ); - - - U4_ex : pps_ex port map ( - clock => clock, - reset => reset, - stop_all => stop_all, -- Unconditionnal locking of outputs - clear => clear, -- Clear the pipeline stage - - -- Datas from DI stage - DI_bra => DI_bra, -- Branch instruction - DI_link => DI_link, -- Branch with link - DI_op1 => DI_op1, -- Operand 1 for alu - DI_op2 => DI_op2, -- Operand 2 for alu - DI_code_ual => DI_code_ual, -- Alu operation - DI_offset => DI_offset, -- Offset for address calculation - DI_adr_reg_dest => DI_adr_reg_dest, -- Destination register address for the result - DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result - DI_mode => DI_mode, -- Address mode (relative to pc ou index by a register) - DI_op_mem => DI_op_mem, -- Memory operation - DI_r_w => DI_r_w, -- Type of memory operation (read or write) - DI_adr => DI_adr, -- Instruction address - DI_exc_cause => DI_exc_cause, -- Potential cause exception - DI_level => DI_level, -- Availability stage of the result for bypassing - DI_it_ok => DI_it_ok, -- Allow hardware interruptions - - -- Synchronous outputs to MEM stage - EX_adr => EX_adr, -- Instruction address - EX_bra_confirm => EX_bra_confirm, -- Branch execution confirmation - EX_data_ual => EX_data_ual, -- Ual result - EX_adresse => EX_adresse, -- Address calculation result - EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register for the result - EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result - EX_op_mem => EX_op_mem, -- Memory operation needed - EX_r_w => EX_r_w, -- Type of memory operation (read or write) - EX_exc_cause => EX_exc_cause, -- Potential cause exception - EX_level => EX_level, -- Availability stage of result for bypassing - EX_it_ok => EX_it_ok -- Allow hardware interruptions - ); - - - U5_mem : pps_mem port map ( - clock => clock, - reset => reset, - stop_all => stop_all, -- Unconditionnal locking of the outputs - clear => interrupt, -- Clear the pipeline stage - - -- Interface with the control bus - MTC_data => MTC_data, -- Data to write in memory - MTC_adr => MTC_adr, -- Address for memory - MTC_r_w => MTC_r_w, -- Read/Write in memory - MTC_req => MTC_req, -- Request access to memory - CTM_data => CTM_data, -- Data from memory - - -- Datas from Execution stage - EX_adr => EX_adr, -- Instruction address - EX_data_ual => EX_data_ual, -- Result of alu operation - EX_adresse => EX_adresse, -- Result of the calculation of the address - EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register address for the result - EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result - EX_op_mem => EX_op_mem, -- Memory operation needed - EX_r_w => EX_r_w, -- Type of memory operation (read or write) - EX_exc_cause => EX_exc_cause, -- Potential exception cause - EX_level => EX_level, -- Availability stage for the result for bypassing - EX_it_ok => EX_it_ok, -- Allow hardware interruptions - - -- Synchronous outputs for bypass unit - MEM_adr => MEM_adr, -- Instruction address - MEM_adr_reg_dest=>MEM_adr_reg_dest, -- Destination register address - MEM_ecr_reg => MEM_ecr_reg, -- Writing of the destination register - MEM_data_ecr => MEM_data_ecr, -- Data to write (from alu or memory) - MEM_exc_cause => MEM_exc_cause, -- Potential exception cause - MEM_level => MEM_level, -- Availability stage for the result for bypassing - MEM_it_ok => MEM_it_ok -- Allow hardware interruptions - ); - - - U6_renvoi : renvoi port map ( - -- Register access signals - adr1 => adr_reg1, -- Operand 1 address - adr2 => adr_reg2, -- Operand 2 address - use1 => use1, -- Operand 1 utilisation - use2 => use2, -- Operand 2 utilisation - - data1 => data1, -- First register value - data2 => data2, -- Second register value - alea => alea, -- Unresolved hazards detected - - -- Bypass signals of the intermediary datas - DI_level => DI_level, -- Availability level of the data - DI_adr => DI_adr_reg_dest, -- Register destination of the result - DI_ecr => DI_ecr_reg, -- Writing register request - DI_data => DI_op2, -- Data to used - - EX_level => EX_level, -- Availability level of the data - EX_adr => EX_adr_reg_dest, -- Register destination of the result - EX_ecr => EX_ecr_reg, -- Writing register request - EX_data => EX_data_ual, -- Data to used - - MEM_level => MEM_level, -- Availability level of the data - MEM_adr => MEM_adr_reg_dest, -- Register destination of the result - MEM_ecr => MEM_ecr_reg, -- Writing register request - MEM_data => MEM_data_ecr, -- Data to used - - interrupt => interrupt, -- Exceptions or interruptions - - -- Connexion to the differents bank of register - - -- Writing commands for writing in the registers - write_data => write_data, -- Data to write - write_adr => write_adr, -- Address of the register to write - write_GPR => write_GPR, -- Selection in the internal registers - write_SCP => write_SCP, -- Selection in the coprocessor system registers - - -- Reading commands for Reading in the registers - read_adr1 => read_adr1, -- Address of the first register to read - read_adr2 => read_adr2, -- Address of the second register to read - read_data1_GPR => read_data1_GPR, -- Value of operand 1 from the internal registers - read_data1_SCP => read_data1_SCP, -- Value of operand 2 from the internal registers - read_data2_GPR => read_data2_GPR, -- Value of operand 1 from the coprocessor system registers - read_data2_SCP => read_data2_SCP -- Value of operand 2 from the coprocessor system registers - ); - - - U7_banc : banc port map( - clock => clock, - reset => reset, - - -- Register addresses to read - reg_src1 => read_adr1, - reg_src2 => read_adr2, - - -- Register address to write and its data - reg_dest => write_adr, - donnee => write_data, - - -- Write signal - cmd_ecr => write_GPR, - - -- Bank outputs - data_src1 => read_data1_GPR, - data_src2 => read_data2_GPR - ); - - - U8_syscop : syscop port map ( - clock => clock, - reset => reset, - - -- Datas from the pipeline - MEM_adr => MEM_adr, -- Address of the current instruction in the pipeline end -> responsible of the exception - MEM_exc_cause => MEM_exc_cause, -- Potential cause exception of that instruction - MEM_it_ok => MEM_it_ok, -- Allow hardware interruptions - - -- Hardware interruption - it_mat => it_mat_clk, -- Hardware interruption detected - - -- Interruption controls - interrupt => interrupt, -- Interruption to take into account - vecteur_it => vecteur_it, -- Interruption vector - - -- Writing request in register bank - write_data => write_data, -- Data to write - write_adr => write_adr, -- Address of the register to write - write_SCP => write_SCP, -- Writing request - - -- Reading request in register bank - read_adr1 => read_adr1, -- Address of the first register - read_adr2 => read_adr2, -- Address of the second register - read_data1 => read_data1_SCP, -- Value of register 1 - read_data2 => read_data2_SCP -- Value of register 2 - ); - - - U9_bus_ctrl : bus_ctrl port map ( - clock => clock, - reset => reset, - - -- Interruption in the pipeline - interrupt => interrupt, - - -- Interface for the Instruction Extraction Stage - adr_from_ei => ETC_adr, -- The address of the data to read - instr_to_ei => CTE_instr, -- Instruction from the memory - - -- Interface with the MEMory Stage - req_from_mem => MTC_req, -- Request to access the ram - r_w_from_mem => MTC_r_w, -- Read/Write request - adr_from_mem => MTC_adr, -- Address in ram - data_from_mem => MTC_data, -- Data to write in ram - data_to_mem => CTM_data, -- Data from the ram to the MEMory stage - - -- RAM interface signals - req_to_ram => ram_req, -- Request to ram - adr_to_ram => ram_adr, -- Address of the data to read or write - r_w_to_ram => ram_r_w, -- Read/Write request - ack_from_ram => ram_ack, -- Acknowledge from the memory - data_inout_ram => ram_data, -- Data from/to the memory - - -- Pipeline progress control signal - stop_all => stop_all - ); - - U10_predict : predict port map ( - clock => clock, - reset => reset, - - -- Datas from PF pipeline stage - PF_pc => PF_pc, -- PC of the current instruction extracted - - -- Datas from DI pipeline stage - DI_bra => DI_bra, -- Branch detected - DI_adr => DI_adr, -- Address of the branch - - -- Datas from EX pipeline stage - EX_bra_confirm => EX_bra_confirm, -- Confirm if the branch test is ok - EX_adr => EX_adr, -- Address of the branch - EX_adresse => EX_adresse, -- Result of the branch - EX_uncleared => EX_it_ok, -- Define if the EX stage is cleared - - -- Outputs to PF pipeline stage - PR_bra_cmd => PR_bra_cmd, -- Defined a branch - PR_bra_bad => PR_bra_bad, -- Defined a branch to restore from a bad prediction - PR_bra_adr => PR_bra_adr, -- New PC - - -- Clear the three pipeline stage : EI, DI, EX - PR_clear => PR_clear - ); - -end rtl; Index: trunk/miniMIPS/src/pack_mips.vhd =================================================================== --- trunk/miniMIPS/src/pack_mips.vhd (revision 13) +++ trunk/miniMIPS/src/pack_mips.vhd (nonexistent) @@ -1,471 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- Processor miniMIPS : Enumerations and components declarations -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - - -library ieee; -use ieee.std_logic_1164.all; - -package pack_mips is - - -- Type signal on n bits - subtype bus64 is std_logic_vector(63 downto 0); - subtype bus33 is std_logic_vector(32 downto 0); - subtype bus32 is std_logic_vector(31 downto 0); - subtype bus31 is std_logic_vector(30 downto 0); - subtype bus26 is std_logic_vector(25 downto 0); - subtype bus24 is std_logic_vector(23 downto 0); - subtype bus16 is std_logic_vector(15 downto 0); - subtype bus8 is std_logic_vector(7 downto 0); - subtype bus6 is std_logic_vector(5 downto 0); - subtype bus5 is std_logic_vector(4 downto 0); - subtype bus4 is std_logic_vector(3 downto 0); - subtype bus2 is std_logic_vector(1 downto 0); - subtype bus1 is std_logic; - - -- Address of a register type - subtype adr_reg_type is std_logic_vector(5 downto 0); - - -- Coding of the level of data availability for UR - subtype level_type is std_logic_vector(1 downto 0); - constant LVL_DI : level_type := "11"; -- Data available from the op2 of DI stage - constant LVL_EX : level_type := "10"; -- Data available from the data_ual register of EX stage - constant LVL_MEM : level_type := "01"; -- Data available from the data_ecr register of MEM stage - constant LVL_REG : level_type := "00"; -- Data available only in the register bank - - -- Different values of cause exceptions - constant IT_NOEXC : bus32 := X"00000000"; - constant IT_ITMAT : bus32 := X"00000001"; - constant IT_OVERF : bus32 := X"00000002"; - constant IT_ERINS : bus32 := X"00000004"; - constant IT_BREAK : bus32 := X"00000008"; - constant IT_SCALL : bus32 := X"00000010"; - - - -- Operation type of the coprocessor system (only the low 16 bits are valid) - constant SYS_NOP : bus32 := X"0000_0000"; - constant SYS_MASK : bus32 := X"0000_0001"; - constant SYS_UNMASK : bus32 := X"0000_0002"; - constant SYS_ITRET : bus32 := X"0000_0004"; - - -- Type for the alu control - subtype alu_ctrl_type is std_logic_vector(27 downto 0); - - -- Arithmetical operations - constant OP_ADD : alu_ctrl_type := "1000000000000000000000000000"; -- op1 + op2 sign‰ - constant OP_ADDU : alu_ctrl_type := "0100000000000000000000000000"; -- op1 + op2 non sign‰ - constant OP_SUB : alu_ctrl_type := "0010000000000000000000000000"; -- op1 - op2 sign‰ - constant OP_SUBU : alu_ctrl_type := "0001000000000000000000000000"; -- op1 - op2 non sign‰e - -- Logical operations - constant OP_AND : alu_ctrl_type := "0000100000000000000000000000"; -- et logique - constant OP_OR : alu_ctrl_type := "0000010000000000000000000000"; -- ou logique - constant OP_XOR : alu_ctrl_type := "0000001000000000000000000000"; -- ou exclusif logique - constant OP_NOR : alu_ctrl_type := "0000000100000000000000000000"; -- non ou logique - -- Tests : result to one if ok - constant OP_SLT : alu_ctrl_type := "0000000010000000000000000000"; -- op1 < op2 (sign‰) - constant OP_SLTU : alu_ctrl_type := "0000000001000000000000000000"; -- op1 < op2 (non sign‰) - constant OP_EQU : alu_ctrl_type := "0000000000100000000000000000"; -- op1 = op2 - constant OP_NEQU : alu_ctrl_type := "0000000000010000000000000000"; -- op1 /= op2 - constant OP_SNEG : alu_ctrl_type := "0000000000001000000000000000"; -- op1 < 0 - constant OP_SPOS : alu_ctrl_type := "0000000000000100000000000000"; -- op1 > 0 - constant OP_LNEG : alu_ctrl_type := "0000000000000010000000000000"; -- op1 <= 0 - constant OP_LPOS : alu_ctrl_type := "0000000000000001000000000000"; -- op1 >= 0 - -- Multiplications - constant OP_MULT : alu_ctrl_type := "0000000000000000100000000000"; -- op1 * op2 sign‰ (chargement des poids faibles) - constant OP_MULTU : alu_ctrl_type := "0000000000000000010000000000"; -- op1 * op2 non sign‰ (chargement des poids faibles) - -- Shifts - constant OP_SLL : alu_ctrl_type := "0000000000000000001000000000"; -- decallage logique a gauche - constant OP_SRL : alu_ctrl_type := "0000000000000000000100000000"; -- decallage logique a droite - constant OP_SRA : alu_ctrl_type := "0000000000000000000010000000"; -- decallage arithmetique a droite - constant OP_LUI : alu_ctrl_type := "0000000000000000000001000000"; -- met en poids fort la valeur immediate - -- Access to internal registers - constant OP_MFHI : alu_ctrl_type := "0000000000000000000000100000"; -- lecture des poids forts - constant OP_MFLO : alu_ctrl_type := "0000000000000000000000010000"; -- lecture des poids faibles - constant OP_MTHI : alu_ctrl_type := "0000000000000000000000001000"; -- ecriture des poids forts - constant OP_MTLO : alu_ctrl_type := "0000000000000000000000000100"; -- ecriture des poids faibles - -- Operations which do nothing but are useful - constant OP_OUI : alu_ctrl_type := "0000000000000000000000000010"; -- met a 1 le bit de poids faible en sortie - constant OP_OP2 : alu_ctrl_type := "0000000000000000000000000001"; -- recopie l'operande 2 en sortie - - - - -- Starting boot address (after reset) - constant ADR_INIT : bus32 := X"00000000"; - constant INS_NOP : bus32 := X"00000000"; - - - -- Internal component of the pipeline stage - - component alu - port ( - clock : in bus1; - reset : in bus1; - op1 : in bus32; - op2 : in bus32; - ctrl : in alu_ctrl_type; - - res : out bus32; - overflow : out bus1 - ); - end component; - - -- Pipeline stage components - - component pps_pf - port ( - clock : in bus1; - reset : in bus1; - stop_all : in bus1; - - bra_cmd : in bus1; - bra_cmd_pr : in bus1; - bra_adr : in bus32; - exch_cmd : in bus1; - exch_adr : in bus32; - - stop_pf : in bus1; - - PF_pc : out bus32 - ); - end component; - - - component pps_ei - port ( - clock : in bus1; - reset : in bus1; - clear : in bus1; - stop_all : in bus1; - - stop_ei : in bus1; - - CTE_instr : in bus32; - ETC_adr : out bus32; - - PF_pc : in bus32; - - EI_instr : out bus32; - EI_adr : out bus32; - EI_it_ok : out bus1 - ); - end component; - - - component pps_di - port ( - clock : in bus1; - reset : in bus1; - stop_all : in bus1; - clear : in bus1; - - adr_reg1 : out adr_reg_type; - adr_reg2 : out adr_reg_type; - use1 : out bus1; - use2 : out bus1; - - stop_di : in bus1; - data1 : in bus32; - data2 : in bus32; - - EI_adr : in bus32; - EI_instr : in bus32; - EI_it_ok : in bus1; - - DI_bra : out bus1; - DI_link : out bus1; - DI_op1 : out bus32; - DI_op2 : out bus32; - DI_code_ual : out alu_ctrl_type; - DI_offset : out bus32; - DI_adr_reg_dest : out adr_reg_type; - DI_ecr_reg : out bus1; - DI_mode : out bus1; - DI_op_mem : out bus1; - DI_r_w : out bus1; - DI_adr : out bus32; - DI_exc_cause : out bus32; - DI_level : out level_type; - DI_it_ok : out bus1 - ); - end component; - - - component pps_ex - port ( - clock : in bus1; - reset : in bus1; - stop_all : in bus1; - clear : in bus1; - - DI_bra : in bus1; - DI_link : in bus1; - DI_op1 : in bus32; - DI_op2 : in bus32; - DI_code_ual : in alu_ctrl_type; - DI_offset : in bus32; - DI_adr_reg_dest : in adr_reg_type; - DI_ecr_reg : in bus1; - DI_mode : in bus1; - DI_op_mem : in bus1; - DI_r_w : in bus1; - DI_adr : in bus32; - DI_exc_cause : in bus32; - DI_level : in level_type; - DI_it_ok : in bus1; - - EX_adr : out bus32; - EX_bra_confirm : out bus1; - EX_data_ual : out bus32; - EX_adresse : out bus32; - EX_adr_reg_dest : out adr_reg_type; - EX_ecr_reg : out bus1; - EX_op_mem : out bus1; - EX_r_w : out bus1; - EX_exc_cause : out bus32; - EX_level : out level_type; - EX_it_ok : out bus1 - ); - end component; - - - component pps_mem - port ( - clock : in bus1; - reset : in bus1; - stop_all : in bus1; - clear : in bus1; - - MTC_data : out bus32; - MTC_adr : out bus32; - MTC_r_w : out bus1; - MTC_req : out bus1; - CTM_data : in bus32; - - EX_adr : in bus32; - EX_data_ual : in bus32; - EX_adresse : in bus32; - EX_adr_reg_dest : in adr_reg_type; - EX_ecr_reg : in bus1; - EX_op_mem : in bus1; - EX_r_w : in bus1; - EX_exc_cause : in bus32; - EX_level : in level_type; - EX_it_ok : in bus1; - - MEM_adr : out bus32; - MEM_adr_reg_dest : out adr_reg_type; - MEM_ecr_reg : out bus1; - MEM_data_ecr : out bus32; - MEM_exc_cause : out bus32; - MEM_level : out level_type; - MEM_it_ok : out bus1 - ); - end component; - - - component renvoi - port ( - adr1 : in adr_reg_type; - adr2 : in adr_reg_type; - use1 : in bus1; - use2 : in bus1; - - data1 : out bus32; - data2 : out bus32; - alea : out bus1; - - DI_level : in level_type; - DI_adr : in adr_reg_type; - DI_ecr : in bus1; - DI_data : in bus32; - - EX_level : in level_type; - EX_adr : in adr_reg_type; - EX_ecr : in bus1; - EX_data : in bus32; - - MEM_level : in level_type; - MEM_adr : in adr_reg_type; - MEM_ecr : in bus1; - MEM_data : in bus32; - - interrupt : in bus1; - - write_data : out bus32; - write_adr : out bus5; - write_GPR : out bus1; - write_SCP : out bus1; - - read_adr1 : out bus5; - read_adr2 : out bus5; - read_data1_GPR : in bus32; - read_data1_SCP : in bus32; - read_data2_GPR : in bus32; - read_data2_SCP : in bus32 - ); - end component; - - - component banc - port ( - clock : in bus1; - reset : bus1; - - reg_src1 : in bus5; - reg_src2 : in bus5; - - reg_dest : in bus5; - donnee : in bus32; - - cmd_ecr : in bus1; - - data_src1 : out bus32; - data_src2 : out bus32 - ); - end component; - - - component bus_ctrl - port - ( - clock : bus1; - reset : bus1; - - interrupt : in std_logic; - - adr_from_ei : in bus32; - instr_to_ei : out bus32; - - req_from_mem : in bus1; - r_w_from_mem : in bus1; - adr_from_mem : in bus32; - data_from_mem : in bus32; - data_to_mem : out bus32; - - req_to_ram : out std_logic; - adr_to_ram : out bus32; - r_w_to_ram : out bus1; - ack_from_ram : in bus1; - data_inout_ram : inout bus32; - - stop_all : out bus1 - ); - end component; - - - component syscop - port - ( - clock : in bus1; - reset : in bus1; - - MEM_adr : in bus32; - MEM_exc_cause : in bus32; - MEM_it_ok : in bus1; - - it_mat : in bus1; - - interrupt : out bus1; - vecteur_it : out bus32; - - write_data : in bus32; - write_adr : in bus5; - write_SCP : in bus1; - - read_adr1 : in bus5; - read_adr2 : in bus5; - read_data1 : out bus32; - read_data2 : out bus32 - ); - end component; - - component predict - generic ( - nb_record : integer := 3 - ); - port ( - - clock : in std_logic; - reset : in std_logic; - - PF_pc : in std_logic_vector(31 downto 0); - - DI_bra : in std_logic; - DI_adr : in std_logic_vector(31 downto 0); - - EX_bra_confirm : in std_logic; - EX_adr : in std_logic_vector(31 downto 0); - EX_adresse : in std_logic_vector(31 downto 0); - EX_uncleared : in std_logic; - - PR_bra_cmd : out std_logic; - PR_bra_bad : out std_logic; - PR_bra_adr : out std_logic_vector(31 downto 0); - - PR_clear : out std_logic - ); - end component; - - - component minimips - port ( - clock : in bus1; - reset : in bus1; - - ram_req : out bus1; - ram_adr : out bus32; - ram_r_w : out bus1; - ram_data : inout bus32; - ram_ack : in bus1; - - it_mat : in bus1 - ); - end component; - -end pack_mips; Index: trunk/miniMIPS/src/pps_pf.vhd =================================================================== --- trunk/miniMIPS/src/pps_pf.vhd (revision 13) +++ trunk/miniMIPS/src/pps_pf.vhd (nonexistent) @@ -1,115 +0,0 @@ ------------------------------------------------------------------------------------- --- -- --- Copyright (c) 2004, Hangouet Samuel -- --- , Jan Sebastien -- --- , Mouton Louis-Marie -- --- , Schneider Olivier all rights reserved -- --- -- --- This file is part of miniMIPS. -- --- -- --- miniMIPS is free software; you can redistribute it and/or modify -- --- it under the terms of the GNU Lesser General Public License as published by -- --- the Free Software Foundation; either version 2.1 of the License, or -- --- (at your option) any later version. -- --- -- --- miniMIPS is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of -- --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- --- GNU Lesser General Public License for more details. -- --- -- --- You should have received a copy of the GNU Lesser General Public License -- --- along with miniMIPS; if not, write to the Free Software -- --- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- --- -- ------------------------------------------------------------------------------------- - - --- If you encountered any problem, please contact : --- --- lmouton@enserg.fr --- oschneid@enserg.fr --- shangoue@enserg.fr --- - - - --------------------------------------------------------------------------- --- -- --- -- --- miniMIPS Processor : Address calculation stage -- --- -- --- -- --- -- --- Authors : Hangouet Samuel -- --- Jan Sébastien -- --- Mouton Louis-Marie -- --- Schneider Olivier -- --- -- --- june 2003 -- --------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library work; -use work.pack_mips.all; - -entity pps_pf is -port ( - clock : in bus1; - reset : in bus1; - stop_all : in bus1; -- Unconditionnal locking of the pipeline stage - - -- Asynchronous inputs - bra_cmd : in bus1; -- Branch - bra_cmd_pr : in bus1; -- Branch which have a priority on stop_pf (bad prediction branch) - bra_adr : in bus32; -- Address to load when an effective branch - exch_cmd : in bus1; -- Exception branch - exch_adr : in bus32; -- Exception vector - stop_pf : in bus1; -- Lock the stage - - -- Synchronous output to EI stage - PF_pc : out bus32 -- PC value -); -end pps_pf; - -architecture rtl of pps_pf is - - signal suivant : bus32; -- Preparation of the future pc - signal pc_interne : bus32; -- Value of the pc output, needed for an internal reading - signal lock : bus1; -- Specify the authorization of the pc evolution - -begin - - -- Connexion the pc to the internal pc - PF_pc <= pc_interne; - - -- Elaboration of an potential future pc - suivant <= exch_adr when exch_cmd='1' else - bra_adr when bra_cmd_pr='1' else - bra_adr when bra_cmd='1' else - bus32(unsigned(pc_interne) + 4); - - lock <= '1' when stop_all='1' else -- Lock this stage when all the pipeline is locked - '0' when exch_cmd='1' else -- Exception - '0' when bra_cmd_pr='1' else -- Bad prediction restoration - '1' when stop_pf='1' else -- Wait for the data hazard - '0' when bra_cmd='1' else -- Branch - '0'; -- Normal evolution - - -- Synchronous evolution of the pc - process(clock) - begin - if clock='1' and clock'event then - if reset='1' then - -- PC reinitialisation with the boot address - pc_interne <= ADR_INIT; - elsif lock='0' then - -- PC not locked - pc_interne <= suivant; - end if; - end if; - end process; - -end rtl; Index: trunk/gasm/main.c =================================================================== --- trunk/gasm/main.c (revision 13) +++ trunk/gasm/main.c (nonexistent) @@ -1,220 +0,0 @@ -/**********************************************************************************/ -/* */ -/* Copyright (c) 2003, Hangouet Samuel, Mouton Louis-Marie all rights reserved */ -/* */ -/* This file is part of gasm. */ -/* */ -/* gasm is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* gasm is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with gasm; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* */ -/**********************************************************************************/ - - -/* If you encountered any problem, please contact : */ -/* */ -/* lmouton@enserg.fr */ -/* shangoue@enserg.fr */ -/* */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static char nom_source[MAX_LONG_ALPHA+1]=""; -static char nom_syntaxe[MAX_LONG_ALPHA+1]="Syntaxe"; -static char nom_macro[MAX_LONG_ALPHA+1]=""; -static char nom_liste[MAX_LONG_ALPHA+1]="a.lst"; -static char nom_obj[MAX_LONG_ALPHA+1]="a.bin"; - -int gere_args(int argc, char * argv[]) -{ - int i; - char * cur_arg; - nom_source[MAX_LONG_ALPHA]=nom_syntaxe[MAX_LONG_ALPHA]=nom_macro[MAX_LONG_ALPHA]='\0'; - for(i=1; i=argc) - { - DIALOGUE(cur_arg, 0, W_ARG_INC); - break; - } - strncpy(nom_syntaxe,argv[i+1],MAX_LONG_ALPHA); - i++; - break; - case 'm': /* Nom du fichier macro par défaut. */ - if (cur_arg[1]!='\0' || i+1>=argc) - { - DIALOGUE(cur_arg, 0, W_ARG_INC); - break; - } - strncpy(nom_macro,argv[i+1],MAX_LONG_ALPHA); - i++; - break; - case 'l': /* Nom du fichier liste d'assemblage. */ - if (cur_arg[1]!='\0' || i+1>=argc) - { - DIALOGUE(cur_arg, 0, W_ARG_INC); - break; - } - strncpy(nom_liste,argv[i+1],MAX_LONG_ALPHA); - i++; - break; - case 'o': /* Nom du fichier objet. */ - if (cur_arg[1]!='\0' || i+1>=argc) - { - DIALOGUE(cur_arg, 0, W_ARG_INC); - break; - } - strncpy(nom_obj,argv[i+1],MAX_LONG_ALPHA); - i++; - break; - case '?': - case 'h': /* Aide en ligne. */ - display_help(); - return 0; - break; - case 'p': /* Utilise la sortie standard */ - nom_obj[0]='\0'; - break; - default: - DIALOGUE(cur_arg, 0, W_ARG_INC); - break; - } - } - else - { - if (*nom_source!='\0') DIALOGUE(cur_arg, 0, W_ARG_INC) - else strncpy(nom_source,cur_arg,MAX_LONG_ALPHA); - } - } - return 1; -} - -int main(int argc, char * argv[]) -{ - FILE * f_lst=NULL, * f_obj=NULL, * f_srceff=NULL; - int err1, err2; - int dst_std=0; - type_lexeme * ptr_lex; - - if (!gere_args(argc, argv)) return 0; /* Détection du paramètre d'aide. */ - - /* Initialisation de la syntaxe de l'assembleur. */ - DIALOGUE(NULL, 0, B_INIT_SYNTAX); - init_arbre(nom_syntaxe); - - /* Initialisation des macros génériques (pseudo-instructions). */ - DIALOGUE(NULL, 0, B_INIT_MACRO); - /* Si le nom du fichier de macros n'est pas spécifié en paramètre, on récupère le */ - /* nom par défaut défini dans le fichier syntaxe. */ - if (nom_macro[0]=='\0' && fich_macro_def) - strcpy(nom_macro, fich_macro_def); /* nom_macro est assez long ! */ - if (nom_macro[0]!='\0') - { - if (init_preprocesseur(nom_macro)) DIALOGUE(NULL, 0, W_FICH_DEF_MACRO); - } - else DIALOGUE(NULL, 0, W_MACRO_MANQ); - /* Vidange du fichier de définition des macros par défaut avant de poursuivre */ - while ((ptr_lex=pop_lexeme())!=NULL) FREE_LEX(ptr_lex); - - /* Initialisation du préprocesseur avec le fichier asm donné en paramètre */ - if (init_preprocesseur(nom_source)) DIALOGUE(nom_source, 0, F_ERR_OUV); - - /* Exécution de l'analyse. */ - DIALOGUE(NULL, 0, B_ANA); - err1=analyse(); - if (verbose) liste_table_macro(stderr); - clear_preprocesseur(); /* Nettoyage du préprocesseur. */ - - /* Exécution de la synthèse. */ - DIALOGUE(NULL, 0, B_SYN); - err2=synthese(); - - /* Ouverture du flux de sortie. */ - if (nom_obj[0]!='\0') - { - f_obj=fopen(nom_obj, "wb"); - if (f_obj==NULL) DIALOGUE(nom_obj, 0, F_ERR_OUV); - } - else - { /* Ecriture dans le stdout. */ - f_obj=stdout; - strcpy(nom_obj, "stdout"); - dst_std=1; - } - - /* Ecriture du fichier objet. */ - DIALOGUE(NULL, 0, B_STR_OBJ); - write_objet(f_obj); - - if (!dst_std) fclose(f_obj); /* Fermeture du flux objet. */ - - if (active_list) - { /* Création de la liste d'assemblage. */ - /* Ouverture du flux source effectif et du flux de la liste si besoin est. */ - f_srceff=fopen(nom_source, "rb"); - if (f_srceff==NULL) DIALOGUE(nom_source, 0, F_ERR_OUV); - f_lst=fopen(nom_liste, "wb"); - if (f_lst==NULL) DIALOGUE(nom_liste, 0, F_ERR_OUV); - DIALOGUE(NULL, 0, B_STR_LST); /* Ecriture de la lsite d'assemblage. */ - write_liste(f_lst, f_srceff); - /* Fermeture des différents flux ouverts. */ - fclose(f_srceff); - fclose(f_lst); - } - - if (verbose) - { /* Affichage du nombre d'erreurs détectées aux cours des deux passes. */ - char str_nbr[MAX_LONG_ALPHA]; - DIALOGUE(NULL, 0, B_ERR_REP); - sprintf(str_nbr, "%d", err1); - DIALOGUE(str_nbr, 0, B_NBR_ERR_ANA); - sprintf(str_nbr, "%d", err2); - DIALOGUE(str_nbr, 0, B_NBR_ERR_SYN); - } - - /* Libération de l'espace réservé lors de l'initialisation des différents modules. */ - clear_preparateur(); - clear_adaptateur(); - clear_analyseur(); - - -#ifdef DEBUG - /* Affichage des informations de debuging : */ - print_mem(stderr); -#endif - - return 0; -} Index: trunk/gasm/src/preprocesseur.c =================================================================== --- trunk/gasm/src/preprocesseur.c (revision 13) +++ trunk/gasm/src/preprocesseur.c (nonexistent) @@ -1,839 +0,0 @@ -/********************************************************************************************* - * * - * MODULE PREPROCESSEUR * - * * - * Ce module a pour but de fournir sur demande les lexemes correspondant au code * - * du fichiers .ASM avec lequel il a été initialisé. * - * * - * Il gere aussi l'inclusion de fichiers et l'expansion des macros. * - * * - * Points d'entrée : les fonctions push_lexemes() et pop_lexeme() * - * * - *********************************************************************************************/ - -/* Déclarations des symbols de ce module */ -#include "preprocesseur.h" - -/* Inclusion de la bibliothèque standard */ -#include -#include -#include -#include - -/* Inclusion des modules du projet utilisés */ -#include -#include -#include -#include - -#define SYNTAX_ERROR(CODE)\ - {\ - char * msg;\ - msg=gen_orig_msg();\ - DIALOGUE(msg, ligne_courante(), CODE);\ - free(msg);\ - } - -/********************************************************************************************* - * * - * Types spécifiques à ce module * - * * - *********************************************************************************************/ - -typedef struct type_pdf_tmp -{ - FILE * flux; - unsigned int ligne; /* numéro de la ligne en cours de lecture dans ce flux */ - char * nom_fich; /* nom du fichier en cours de lecture */ - char * nom_macro; /* nom de la macro si c'en est une pour eviter l'autoappel */ - struct type_pdf_tmp * prec; /* Flux entassé */ -} type_pdf; - -typedef struct type_pdm_tmp -{ - char * nom_macro; /* Lexeme dont la rencontre entraine une expansion */ - long def_pos; /* Position dans le fichier de définition */ - struct type_pdm_tmp * suiv; -} type_pdm; - -/********************************************************************************************* - * * - * Variables spécifiques à ce module * - * * - *********************************************************************************************/ - -/* Le pointeur vers l'élément en cours de lecture de la pile de flux */ -static type_pdf * ptr_pdf=NULL; - -/* La file de lexèmes où sont empilés les lexèmes "recrachés" par push_lex apres un pop_lex */ -static type_file_lexeme * ptr_pdl=NULL; - -/* Pointeur vers la fonction strcmp ou strcasecmp selon la casse_sens */ -static int (*fcmp)()=NULL; -#define CAR_EQ(a, b) ( casse_sens ? (a==b) : (tolower(a)==tolower(b)) ) - -/* Le pointeur vers le début de la pile de macros */ -static type_pdm * ptr_pdm=NULL; - -/* Fichier temporaire, contiendra toutes les définitions de macro du code ASM */ -FILE * fich_macro=NULL; - -/********************************************************************************************* - * * - * Fonctions non exportées * - * * - *********************************************************************************************/ - -static void empile_flux(char * nom_fich, char * nom_macro); -static void depile_flux(); -static type_pdm * is_macro(char *); -static type_lexeme * read_lexeme(); -static type_lexeme * get_true_lexeme(FILE * fich); -static void expanse_macro(type_pdm * ptr); - -void empile_flux(char * nom_fich, char * nom_macro) -{ - type_pdf * ptr; - char errmsg[]="preprocesseur(empile_flux)"; - - /* Vérifications anti-inclusions circulaires de macros et de fichiers */ - ptr=ptr_pdf; - while(ptr!=NULL) - { - if (nom_fich) - if (strcmp(nom_fich, ptr->nom_fich)==0) - { - SYNTAX_ERROR(S_CIRCULAR_FILE) - return; - } - if (nom_macro) - if (ptr->nom_macro && (*fcmp)(nom_macro, ptr->nom_macro)==0) - { - SYNTAX_ERROR(S_CIRCULAR_MACRO) - return; - } - ptr=ptr->prec; - } - - /* Allocation de la structure */ - ptr=(type_pdf *) malloc(sizeof(type_pdf)); - if (!ptr) DIALOGUE(errmsg, 0, F_ERR_MEM); - - /* Initialisation des champs */ - ptr->flux=NULL; - ptr->ligne=1; - ptr->nom_fich=NULL; - ptr->nom_macro=NULL; - ptr->prec=NULL; - - /* Ouverture du fichier */ - if (nom_fich) - { - ptr->flux=fopen(nom_fich, "rb"); - if (!ptr->flux) - { - char * msg; - msg=gen_orig_msg(); - DIALOGUE(msg, ptr_pdf->ligne, S_FICH_NON_TROUVE); - free(msg); - free(ptr); - return; - } - - /* Recopie des chaines transmises en parametres */ - ptr->nom_fich=(char *) malloc(strlen(nom_fich)); - if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); - strcpy(ptr->nom_fich, nom_fich); - } - if (nom_macro) - { - ptr->nom_macro=(char *) malloc(strlen(nom_macro)); - if (!ptr->nom_macro) DIALOGUE(errmsg, 0, F_ERR_MEM); - strcpy(ptr->nom_macro, nom_macro); - } - - /* Empilement */ - ptr->prec=ptr_pdf; - ptr_pdf=ptr; -} - -void depile_flux() -{ - type_pdf * ptr_sav; - ptr_sav=ptr_pdf->prec; - fclose(ptr_pdf->flux); - if (ptr_pdf->nom_macro) - free(ptr_pdf->nom_macro); - else - free(ptr_pdf->nom_fich); - free(ptr_pdf); - ptr_pdf=ptr_sav; -} - -/* Cette fonction cherche et retourne la position d'une macro dans la table. */ -type_pdm * is_macro(char * lex_alpha) -{ - type_pdm * ptr_mac; - for( ptr_mac=ptr_pdm; - ptr_mac && (*fcmp)(ptr_mac->nom_macro, lex_alpha); - ptr_mac=ptr_mac->suiv) - ; - return ptr_mac; -} - -/* Cette fonction renvoie le prochain lexeme valide disponible dans la pile de flux, * - * ou NULL, mais uniquement si plus auncun flux n'est ouvert (analyse terminée). * - * Elle s'occupe d'empiler les flux en cas d'inclusion, les dépile quand elle intercepte un * - * lexème EOF (qu'elle ne renvoie jamais). Enfin, elle détecte les macros et leur défs. */ -type_lexeme * read_lexeme() -{ - type_lexeme * ptr_lex; - static int germac=1; /* Permet de ne pas expansionner * - * certains bouts de code... */ - static int last_is_NL=0; /* On considère les NL en fin de ligne, * - * pas en début de ligne suivante... */ - - /* Aucun fichier ouvert => NULL */ - if (ptr_pdf==NULL) return NULL; - - if (last_is_NL) - { - last_is_NL=0; - ptr_pdf->ligne++; - } - - /* Retourne un lexème en filtrant les erreurs du formateurs */ - ptr_lex=get_true_lexeme(ptr_pdf->flux); - - /* Traitement des macros et sous-typage */ - if (TYPE_IS(ptr_lex, ALPHA)) /* si macro expansion, sinon sous-typage */ - { - int i; - char * p_regle, * p_alpha; - type_pdm * ptr_mac; - if (germac && (ptr_mac=is_macro(ptr_lex->valeur.alpha))!=NULL) - { - FREE_LEX(ptr_lex); - expanse_macro(ptr_mac); - ptr_lex=read_lexeme(); - } - else /* Test si c'est sous-typable */ - for(i=0; ivaleur.alpha; - while((*p_regle)!='\0') - { - if ((*p_regle)=='?') /* Remplacmt par un caractère */ - { /* les 2 car suiv sont les bornes */ - if ((*p_alpha)<*(++p_regle) || (*p_alpha)>*(++p_regle)) - break; - } - else if (!CAR_EQ(*p_regle, *p_alpha)) break; - p_regle++; - p_alpha++; - } - /* Si le lexème match la règle, on sous-type... */ - if ((*p_regle)=='\0' && (*p_alpha)=='\0') - { - /* La valeur du lexème n'est pas modifiée */ - ptr_lex->type = POS_MPV(regle_typage[i].code); - break; - } - } - } - - else - - /* Traitment des directives, des sauts de ligne et des fin de flux */ - if (TYPE_IS(ptr_lex, OP)) /* Traitements spéciaux */ - switch(ptr_lex->valeur.op) - { - case NL: /* Fin de ligne */ - last_is_NL=1; - break; - case EOF: /* Fin de fichier : on ne retourne pas de lexemes */ - FREE_LEX(ptr_lex) - depile_flux(); - ptr_lex=read_lexeme(); - break; - case DIR: /* Directive de Préprocesseur */ - { - type_lexeme * ptr_sauv_lex; - int pas_dir=1; /* Drapeau soupconneux */ - ptr_sauv_lex=ptr_lex; - germac=0; - ptr_lex=read_lexeme(); - if (TYPE_IS(ptr_lex, ALPHA)) - { - if (define_str && - (*fcmp)(ptr_lex->valeur.alpha, define_str)==0) - { /* Ajout d'1 macro */ - pas_dir=0; - FREE_LEX(ptr_lex); - ptr_lex=read_lexeme(); - if (!TYPE_IS(ptr_lex, ALPHA)) - SYNTAX_ERROR(S_NOM_MAC_INVALID) - else - ajoute_macro(ptr_lex->valeur.alpha - , ptr_pdf->flux); - } - else if (include_str && - (*fcmp)(ptr_lex->valeur.alpha,include_str)==0) - { /* Empliement d'un fichier */ - pas_dir=0; - FREE_LEX(ptr_lex); - ptr_lex=read_lexeme(); - if (!TYPE_IS(ptr_lex, ALPHA)) - SYNTAX_ERROR(S_NOM_INCFICH_INVALID) - else - empile_flux(ptr_lex->valeur.alpha - ,NULL); - } - else if (undef_str && - (*fcmp)(ptr_lex->valeur.alpha,undef_str)==0) - { /* Empliement d'un fichier */ - pas_dir=0; - FREE_LEX(ptr_lex); - ptr_lex=read_lexeme(); - if (!TYPE_IS(ptr_lex, ALPHA)) - SYNTAX_ERROR(S_NOM_MAC_INVALID) - else - suppress_macro(ptr_lex->valeur.alpha); - } - } - germac=1; - if (pas_dir) /* Si, en fait, ce n'était pas une dir */ - { - push_lexeme(ptr_lex); /* on sauve le lexème testé */ - ptr_lex=ptr_sauv_lex; /* on renvoie le lexème DIR */ - } - else - { - FREE_LEX(ptr_sauv_lex); - FREE_LEX(ptr_lex); - ptr_lex=read_lexeme(); - } - } - } - - return ptr_lex; -} - -/* Cette fonction sert d'interface entre le préprocesseur et le formateur. * - * Elle se charge d'afficher ses messages d'erreur et de lire le lexème suivant quand ce * - * dernier renvoie NULL. */ -type_lexeme * get_true_lexeme(FILE * fich) -{ - type_lexeme * p; - p=get_lexeme(fich); - if (p==NULL) - { - SYNTAX_ERROR(err_code) - p=get_true_lexeme(fich); - } - return p; -} - -/* Vide le flux jusqu'a la prochaine accolade ouvrante comprise, * - * Elle renvoie 0 si tout s'est bien passé, 1 si EOF est rencontré */ -int next_ACO(FILE * flux) -{ - int drap=0; - type_lexeme * p; - do - { - p=get_true_lexeme(flux); - if (TYPE_IS(p, OP)) - { - if (p->valeur.op==EOF) - { - FREE_LEX(p) - err_code=S_DEF_MACRO_EOF; - return 1; - } - if (p->valeur.op==ACO) drap=1; - } - FREE_LEX(p); - } - while(!drap); - return 0; -} - -/* Retourne le lexème suivant du flux, ou NULL s'il s'agit d'une accolade fermante ou d'EOF. * - * Il faut alors testé la variable err_code pour savoir s'il s'agit d'un e erreur ou pas. */ -type_lexeme * read_all_but_ACF(FILE * flux) -{ - type_lexeme * p; - p=get_true_lexeme(flux); - if (TYPE_IS(p,OP)) - { - if (p->valeur.op==EOF) - { - FREE_LEX(p) - err_code=S_DEF_MACRO_EOF; - return NULL; - } - if (p->valeur.op==ACF) - { - FREE_LEX(p) - err_code=NO_ERR; - return NULL; - } - } - return p; -} - -/* Fonction assurant le controle de la validité de la définition de la macro, son expansion * - * dans un nouveau buffer qu'elle empile avant de rendre la main. */ -void expanse_macro(type_pdm * ptr_mac) -#define FREE_TABLE\ - while(table)\ - {\ - parcourt_table=table->suiv;\ - FREE_LEX(table->nom_param);\ - if (table->val_param) FREE_LEX(table->val_param)\ - free(table);\ - table=parcourt_table;\ - } -{ - /* Structure servant au stockage temporaire des paramètres formels de la macro. */ - typedef struct type_file_param_tmp - { - type_lexeme * nom_param; - type_lexeme * val_param; - struct type_file_param_tmp * suiv; - } type_file_param; - - type_file_param * table=NULL, * parcourt_table=NULL, * ptr_new=NULL; - type_lexeme * ptr_lex=NULL, * ptr_lex_asm=NULL; - FILE * ftemp; - - /* Positionnement au début de la définition de la macro */ - fseek(fich_macro, ptr_mac->def_pos, SEEK_SET); - - /* Recherche du début du bloc de paramètres */ - if (next_ACO(fich_macro)) - { - SYNTAX_ERROR(err_code) - return; - } - - /* Lecture des paramètres et placement dans la table jusqu'à l'accolade fermante */ - while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) - { - /* Placement à la fin de la table */ - ptr_new=(type_file_param *) malloc(sizeof(type_file_param)); - if (!ptr_new) DIALOGUE("preprocesseur(expanse_macro)", 0, F_ERR_MEM); - ptr_new->nom_param=ptr_lex; - ptr_new->val_param=NULL; - ptr_new->suiv=NULL; - if (parcourt_table) - parcourt_table=parcourt_table->suiv=ptr_new; - else - table=parcourt_table=ptr_new; - /* Attention, pas de FREE_LEX car placement dans la table */ - } - if (err_code!=NO_ERR) - { - SYNTAX_ERROR(err_code) - FREE_TABLE - return; - } - - /* Recherche du début du bloc de syntaxe */ - if (next_ACO(fich_macro)) - { - SYNTAX_ERROR(err_code) - return; - } - - /* Parcourt la syntaxe macro, la valide, mémorise la valeur des paramètres */ - while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) - { - /* Parcourt de l'utilisation de la macro */ - ptr_lex_asm=get_true_lexeme(ptr_pdf->flux); - /* Recherche s'il s'agit d'un paramètre */ - for( parcourt_table=table; - parcourt_table!=NULL - && !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); - parcourt_table=parcourt_table->suiv); - /* Si c'est le cas, on mémorise sa valeur */ - if (parcourt_table) parcourt_table->val_param=ptr_lex_asm; - else - { - if (!id_lexeme(ptr_lex, ptr_lex_asm, casse_sens)) - { - err_code=S_MAC_NO_MATCH; - FREE_LEX(ptr_lex) - FREE_LEX(ptr_lex_asm) - break; /* La syntaxe n'est pas respectée */ - } - FREE_LEX(ptr_lex_asm) - } - FREE_LEX(ptr_lex) - } - if (err_code!=NO_ERR) - { - SYNTAX_ERROR(err_code) - FREE_TABLE - return; - } - - /* On controle que tous les paramètres ont une valeur, à présent */ - for( parcourt_table=table; - parcourt_table; - parcourt_table=parcourt_table->suiv) - if (parcourt_table->val_param==NULL) - { - SYNTAX_ERROR(S_MAC_TROP_PARAM) - FREE_TABLE - return; - } - - /* Positionnement au début de la séquence de remplacement */ - if (next_ACO(fich_macro)) - { - SYNTAX_ERROR(err_code) - FREE_TABLE - return; - } - - /* On expanse dans un buffer temporaire */ - ftemp=tmpfile(); - - /* Recopie de cette séquence en remplaçant les paramètres */ - while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) - { - /* Est-ce un paramètre ? */ - for( parcourt_table=table; - parcourt_table - && !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); - parcourt_table=parcourt_table->suiv); - if (parcourt_table==NULL) /* Si ce n'en est pas un */ - fprint_lexeme(ftemp, ptr_lex); - else - fprint_lexeme(ftemp, parcourt_table->val_param); - fputc(' ', ftemp); - FREE_LEX(ptr_lex); - } - - /* Nous n'avons à présent plus besoin de la table... */ - FREE_TABLE - if (err_code!=NO_ERR) - { - fclose(ftemp); - SYNTAX_ERROR(err_code) - return; - } - - /* Ouf ! Expansion réussie... */ - empile_flux(NULL, ptr_mac->nom_macro); - ptr_pdf->flux=ftemp; - rewind(ftemp); -} - -/********************************************************************************************* - * * - * Fonctions exportées * - * * - *********************************************************************************************/ - -/* Cette fonction empile le fichier spécifié après avoir testé son existence. * - * Elle prépare l'exécution du préprocesseur à travers pop_lexeme. * - * Elle renvoie 0 si le fichier a bien été empilé, 1 sinon. */ -int init_preprocesseur(char * fichinit) -{ - FILE * ftest; - char errmsg[]="preprocesseur(init_preprocesseur)"; - int i; - - /* Pointeur sur la fonction de comparaison adéquate */ - fcmp=casse_sens ? (void *) &strcmp : (void *) &strcasecmp; - - /* On test l'existence des directives */ - if (include_str!=NULL && active_list) - { - DIALOGUE(NULL, 0, W_NO_LIST_INC) - active_list=0; /* Liste d'assemblage non prévue pour fonctionner en cas */ - /* inclusions de fichiers. */ - } - - /* Controle de validité des regles de sous-typage une fois pour toutes. * - * La règle invalide est supprimée. */ - for(i=0; iflux=stdin; - ptr->ligne=1; - ptr->nom_macro=NULL; - ptr->prec=NULL; - - /* Recopie des chaines transmises en parametres */ - ptr->nom_fich=(char *) malloc(6); - if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); - strcpy(ptr->nom_fich, "stdin"); - - /* Empilement */ - ptr->prec=ptr_pdf; - ptr_pdf=ptr; - - if (active_list) - { - DIALOGUE(NULL, 0, W_NO_LIST_STDIN); - active_list=0; /* Liste d'assemblage non prévue pour fonctionner * - * en cas d'utilisation du stdin. */ - } - } - else - { - if ((ftest=fopen(fichinit, "rb"))==NULL) return 1; - fclose(ftest); - empile_flux(fichinit, NULL); - } - return 0; -} - -/* Cette fonction libère de la mémoire toutes les allocations du préprocesseur */ -void clear_preprocesseur() -{ - while(ptr_pdf) depile_flux(); - while(ptr_pdl) FREE_LEX(pop_lexeme()); - while(ptr_pdm) - { - type_pdm * p; - p=ptr_pdm->suiv; - free(ptr_pdm->nom_macro); - free(ptr_pdm); - ptr_pdm=p; - } -} - -/* Cette fonction renvoie le prochain lexeme valide disponible. Elle regarde d'abord dans la * - * pile de lexèmes. Si celle-ci est vide elle le prend dans la pile de flux, en appelant * - * read_lexeme(). * - * Un ptr NULL est renvoyé uniquement si plus auncun flux n'est ouvert (analyse terminée). */ -type_lexeme * pop_lexeme() -{ - if (ptr_pdl==NULL) /* Pas de lexemes stockés */ - { - return read_lexeme(); - } - else /* On dépile le lexème du tampon */ - { - type_file_lexeme * ptr_sav; - type_lexeme * ptr_lex; - - ptr_sav = ptr_pdl->suivant; - ptr_lex = ptr_pdl->lexeme; - free(ptr_pdl); - ptr_pdl=ptr_sav; - return ptr_lex; - } -} - -/* Sauvegarde des lexèmes qui ont déjà été extraits des flux */ -void push_lexeme(type_lexeme * ptr_recrach) -{ - type_file_lexeme * ptr_sav; - - ptr_sav = ptr_pdl; - ptr_pdl = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); - if (!ptr_pdl) DIALOGUE("preprocesseur(push_lexeme)", 0, F_ERR_MEM); - ptr_pdl->suivant=ptr_sav; - ptr_pdl->lexeme=ptr_recrach; -} - -/* Retourne la ligne où a été lu le dernier lexème ou 0 si pas de fichiers ouverts */ -int ligne_courante() -{ - type_pdf * p=ptr_pdf; - while(p && p->nom_macro) p=p->prec; - if (p==NULL) return 0; - return p->ligne; -} - -/* Indique les noms successifs des fichiers d'origine du lexème. * - * Ne pas oublier de faire free sur le pointeur renvoyé !!! */ -char * gen_orig_msg() -{ - char * text; - type_pdf * ptr; - int t_src=0, t_dest=MAX_LONG_ALPHA, t_sep; - - t_sep=strlen(sep_fich_inclus); - text=(char *) malloc(t_dest); - text[0]=0; - for(ptr=ptr_pdf; ptr; ptr=ptr->prec) - { - if (ptr->nom_macro) continue; - t_src+=strlen(ptr->nom_fich)+t_sep; - if (t_src >= t_dest) - { - t_dest=t_src+1; - text=(char *) realloc(text, t_dest); - } - strcat(text, ptr->nom_fich); - if (ptr->prec) strcat(text, sep_fich_inclus); - } - return text; -} - -/* La macro est supprimée de la table, mais pas du buffer contenant sa définition. */ -void suppress_macro(char * nom_macro) -{ - type_pdm * ptr_mac, * ptr_mac_prec; - - ptr_mac_prec=NULL; /* On sauvegarde le maillon où il faudra raccrocher les * - * macros en aval du maillon à supprimer. */ - for( ptr_mac=ptr_pdm; - ptr_mac && (*fcmp)(ptr_mac->nom_macro, nom_macro); - ptr_mac=ptr_mac->suiv) - ptr_mac_prec=ptr_mac; - - if (ptr_mac) - { - type_pdm * psav; - psav=ptr_mac->suiv; - free(ptr_mac->nom_macro); - free(ptr_mac); - if (ptr_mac_prec) - ptr_mac_prec->suiv=psav; - else - ptr_pdm=psav; - } - else - SYNTAX_ERROR(W_UNDEF_NOMAC) -} - -/* Ajoute une macro à la pile des macros */ -void ajoute_macro(char * nom_macro, FILE * flux_def) -{ - int c,i; - long pos; - char * org_msg = "preprocesseur(ajoute_macro)"; - - if (is_macro(nom_macro)) /* Cas d'une redéfinition */ - { - SYNTAX_ERROR(W_REDEF_MAC) - suppress_macro(nom_macro); - } - - fseek(fich_macro, 0L, SEEK_END); - pos=ftell(fich_macro); - - /* Recopie de la définition de la macro */ - for(i=0; i<3; c==ACF ? i++ : i) - { - if ((c=fgetc(flux_def))==EOF) - { - if (feof(flux_def)) - SYNTAX_ERROR(S_DEF_MACRO_EOF) - else - DIALOGUE(org_msg, 0, F_ERR_LECT); - break; - } - fputc(c, fich_macro); - if (c==NL && flux_def==ptr_pdf->flux) ptr_pdf->ligne++; - } - - /* Si la copie s'est bien passée... */ - if (i==3) - { - type_pdm * ptr; - ptr=(type_pdm *) malloc(sizeof(type_pdm)); - if (!ptr) DIALOGUE(org_msg, 0, F_ERR_MEM); - ptr->nom_macro=(char *) malloc(strlen(nom_macro)); - strcpy(ptr->nom_macro,nom_macro); - ptr->def_pos=pos; - ptr->suiv=NULL; - if (ptr_pdm) /* Ajout à la fin de la pile */ - { - type_pdm * ptr_fin; - ptr_fin=ptr_pdm; - while (ptr_fin->suiv) ptr_fin=ptr_fin->suiv; - ptr_fin->suiv=ptr; - } - else - ptr_pdm=ptr; - } -} - -/* Petite fonction utile pour consulter (dans le stderr) la liste des macros disponibles */ -void liste_table_macro(FILE * f) -{ - type_pdm * p; - type_lexeme * ptr_lex; - if (ptr_pdm) - err_code=B_MACRO_DISPO; - else - err_code=B_NO_MACRO; - fprintf(f, "-- %s\n", search_msg()); - - for(p=ptr_pdm; p!=NULL; p=p->suiv) - { - fprintf(f,"-- \t%s ",p->nom_macro); - fseek(fich_macro, p->def_pos, SEEK_SET); - /* Ecriture de la syntaxe */ - if (next_ACO(fich_macro) || next_ACO(fich_macro)) - { - SYNTAX_ERROR(err_code) - continue; - } - while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) - { - fprint_lexeme(f, ptr_lex); - FREE_LEX(ptr_lex) - } - if (err_code!=NO_ERR) - { - SYNTAX_ERROR(err_code) - continue; - } - fprintf(f, "\t\t"); - /* Ecriture de la séquence de remplacement */ - if (next_ACO(fich_macro)) - { - SYNTAX_ERROR(err_code) - continue; - } - while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) - { - fprint_lexeme(f, ptr_lex); - fputc(' ', f); - FREE_LEX(ptr_lex) - } - if (err_code!=NO_ERR) - { - SYNTAX_ERROR(err_code) - continue; - } - fprintf(f, "\n"); - } -} Index: trunk/gasm/src/parametres.c =================================================================== --- trunk/gasm/src/parametres.c (revision 13) +++ trunk/gasm/src/parametres.c (nonexistent) @@ -1,20 +0,0 @@ -#include "parametres.h" - -#include - -#include -#include - -/* Variables d'environnement. */ -int active_list=1; /* Activation de la lsite d'assemblage. */ -int pco=0; /* Définition du pseudo compteur ordinal. */ - -/* Variables positionnées par le préparateur à la lecture du fichier syntaxe. */ -int casse_sens = 1; /* Sensibilité de la syntaxe à la casse. */ -char * fich_macro_def=NULL; /* Nom du fichier de macros par défaut. */ -char * define_str=NULL; /* Chaine de caractères pour la déclaration de macros. */ -char * include_str=NULL; /* Chaine de caractères pour la directive d'inclusion. */ -char * undef_str=NULL; /* Chaine de caractères pour la suppression de macros. */ -type_lexeme * seplex=NULL; /* Lexème séparateur entre les différentes instructions. */ -int nbr_sous_types=0; /* Nombre de sous types admis par la syntaxe. */ -type_paire *regle_typage=NULL; /* Table des règles et des codes de chaque sous-type. */ Index: trunk/gasm/src/analyseur.c =================================================================== --- trunk/gasm/src/analyseur.c (revision 13) +++ trunk/gasm/src/analyseur.c (nonexistent) @@ -1,257 +0,0 @@ -/*********************************************************************************************/ -/* MODULE ANALYSEUR */ -/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ -/* du code source avec la syntaxe acceptée par le langage. La lecture se fait lexème par */ -/* lexème en utilisant le préprocesseur. */ -/* Il se charge de générer la pile de précode qu sera utilisée par le syntéthiseur pour */ -/* générer le code final. */ -/*********************************************************************************************/ - -#include "analyseur.h" - -/* Inclusion des autres modules du projet utilisés. */ -#include -#include -#include -#include -#include -#include - -type_precode * file_precode=NULL, * fin_file_precode=NULL; - -int nprc_alloc=0; /* Compteur du nombre de précodes alloués. */ - -/* fonctions de filtrage et de comparaison des lexèmes (sensibles ou non à la casse). */ -#define filtre(l, filtre) filtre_lexeme(l, filtre, casse_sens) -#define compare_lexeme(l1, l2) (casse_sens ? lexid(l1, l2) : lexcaseid(l1,l2)) - -/* Pointeur sur la file de lexèmes composant l'argument courant. */ -static type_file_lexeme * ptr_arg=NULL; - -/* ajoute le lexème sur la pile de lexèmes locale (instruction en cours). */ -void push_local(type_lexeme * l) -{ - type_file_lexeme * nouv; - - nouv = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); - if (nouv==NULL) DIALOGUE("analyseur(push_local)", 0, F_ERR_MEM); - - nouv->suivant=ptr_arg; - nouv->lexeme=l; - ptr_arg=nouv; -} - -/* Fonction récursive d'analyse du code assembleur. */ -type_feuille * analyse_rec(type_noeud * n_cour) -{ - type_lexeme * l_cour; - type_noeud * fils_cour; - - l_cour=pop_lexeme(); /* Lecture d'un lexème par le préprocesseur. */ - fils_cour=n_cour->ptr_fils; - - while (fils_cour!=NULL && l_cour!=NULL) - { - if (filtre(l_cour, &(fils_cour->lexeme))) - { /* Les lexèmes sont compatibles. */ - type_feuille * rescur; - rescur=analyse_rec(fils_cour); - if (rescur!=NULL) - { /* Validation de la transition. */ - push_local(l_cour); /* Ajout dans la file locale. */ - return rescur; - } - } - /* La transition n'est pas validée. */ - fils_cour=fils_cour->ptr_frere; /* On passe à la transition suivante. */ - } - - push_lexeme(l_cour); /* Le lexème est rendu au préprocesseur. */ - return (n_cour->ptr_feuille); /* Si la feuille est valide, l'instruction l'est. */ -} - -/*********************************************************************************************/ -/* */ -/* Point d'entrée principal du module, fonction d'analyse. Les données analysées sont celles */ -/* fournies par le préprocesseur qui doit être préalablement initialisé. */ -/* */ -/*********************************************************************************************/ - -/* Macro d'initialisation d'un nouveau précode. */ -#define INIT_PRECODE(precode) \ -{\ - ALLOC_PREC(precode)\ - precode->fichier_orig=f_orig;\ - precode->ligne_orig=l_orig;\ - precode->pco=pco;\ -} - -/* Macro d'ajout d'un précode en queue de la file. */ -#define EMPILE_PRECODE(precode) \ -{\ - if (file_precode==NULL)\ - {\ - file_precode=precode;\ - fin_file_precode=precode;\ - }\ - else\ - {\ - fin_file_precode->suivant=precode;\ - fin_file_precode=precode;\ - }\ -} - -int analyse() -{ - int err=0; - char * msg_orig = "analyseur(analyse)"; - type_lexeme * lex; - - pco = 0; /* Initialisation du pseudo compteur ordinal. */ - - if (seplex == NULL) - { /* Utilisation du séparateur par défaut. */ - DIALOGUE(NULL, 0, W_SEPLEX_INIT); - seplex=(type_lexeme *) malloc(sizeof(type_lexeme)); - if (seplex==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM); - seplex->type = POS_MPV(OP); - seplex->valeur.op = NL; - } - - while ((lex = pop_lexeme())!=NULL) /* Analyse jusqu'à la fin du fichier. */ - { - int l_orig = ligne_courante(); /* On conserve la ligne de l'instruction. */ - char * f_orig = gen_orig_msg(); /* On conserve le fichier d'origine. */ - type_feuille * feuille; - - push_lexeme(lex); /* On rend le lexème au prépreocesseur. */ - feuille = analyse_rec(root); /* Analyse de l'instruction suivante. */ - - if (feuille==NULL) - { /* L'instruction n'a pas été reconnue. */ - type_lexeme * lex_depile; - type_precode * err_pcd; - INIT_PRECODE(err_pcd); - err++; /* Détection d'une erreur de syntaxe. */ - err_pcd->erreur=S_SYN_ERR; /* Mise à jour du code d'erreur. */ - EMPILE_PRECODE(err_pcd); /* Empilage du lexème erreur. */ - - DIALOGUE(f_orig, l_orig, S_SYN_ERR); - - while ((lex_depile=pop_lexeme())!=NULL - && !compare_lexeme(lex_depile, seplex)) - { /* On recherche le prochain lexème de séparation. */ - FREE_LEX(lex_depile); - } - if (lex_depile!=NULL) FREE_LEX(lex_depile); /* Efface le "seplex". */ - } - else - { /* L'instruction a été validée. Génération du précode. */ - type_precode * pcd; - int p2f[MAX_FONCTIONS]; /* tableau des fonctions de seconde passe. */ - int i; - INIT_PRECODE(pcd); - - /* Recopie de la file des lexèmes ayant validé l'instruction. */ - pcd->param = ptr_arg; - - /* Recopie du masque de la feuille. */ - if (feuille->mask_primaire==NULL) pcd->mask=NULL; - else - { - ALLOC_MASK(pcd->mask); - if (pcd->mask==NULL) - DIALOGUE(msg_orig, 0, F_ERR_MEM); - pcd->mask->valeur=feuille->mask_primaire->valeur; - pcd->mask->taille=feuille->mask_primaire->taille; - } - - for (i=0 ; inbr_func ; i++) - { /* Tentative d'application des fonctions de l'adaptateur. */ - type_mask * res = (feuille->ptr_func)[i](ptr_arg); - - /* Différents cas de réponse de l'adaptateur. */ - switch (eval_code) - { - case EVAL_REUSSIE : /* Evalutation réussie. */ - if (pcd->mask==NULL) - { - pcd->mask=res; /* Pas encore de masque. */ - res=NULL; /* Evite que le masque soit vidé. */ - break; - } - if (res==NULL) break; /* Rien à faire. */ - if (res->taille==pcd->mask->taille) - { /* On ajoute le nouveau masque. */ - pcd->mask->valeur|=res->valeur; - break; - } - /* Le masque retourné est incompatible. */ - DIALOGUE(f_orig, l_orig, S_FUN_ERR); - CLEAR_PRECODE(pcd); /* Le précode est une erreur. */ - pcd->erreur=S_FUN_ERR; - err++; - break; - case EVAL_IMPOSSIBLE : /* Fonction de seconde passe. */ - p2f[(int)(pcd->nbr_func)++]=i; - break; - case EVAL_ERREUR : /* Erreur de l'adaptateur/Syntaxe. */ - affiche_message(f_orig, l_orig); - err++; - CLEAR_PRECODE(pcd); /* Le précode est une erreur. */ - pcd->erreur=err_code; - break; - default : /* Erreur de l'adaptateur. */ - DIALOGUE(f_orig, l_orig, S_ADAP_ERR); - CLEAR_PRECODE(pcd); - pcd->erreur=S_ADAP_ERR; - err++; - break; - } - if (res!=NULL) FREE_MASK(res); /* Suppression du masque. */ - } - - if (pcd->nbr_func!=0) /* Recopie des pointeurs vers les p2f. */ - { /* Il reste des fonctions de seconde passe. */ - pcd->func=(type_ptr_fgm*) /* On crée le tableau. */ - malloc((pcd->nbr_func)*sizeof(type_ptr_fgm)); - for (i=0; inbr_func; i++) - { /* On recopie les fonctions de seconde passe. */ - (pcd->func)[i]=(feuille->ptr_func)[p2f[i]]; - } - } - else - { /* Plus de fonctions de seconde passe, effacement des arguments. */ - pcd->func = NULL; - FREE_ARGS(pcd->param); - } - - if ((pcd->mask==NULL || pcd->mask->taille==0) && pcd->func==NULL - && pcd->erreur==NO_ERR) - { /* On supprime le précode s'il est vide. */ - FREE_PRECODE(pcd); - } - else - { - EMPILE_PRECODE(pcd); - if (pcd->mask!=NULL) pco+=pcd->mask->taille; - } - - ptr_arg=NULL; /* Réinitialisation du pointeur de file de lexèmes. */ - } - } - return err; -} - -/* Cette fonction libère les structures de précode allouées lors de l'analyse. Les données */ -/* non écrites par le synthétiseur seront perdues. */ -void clear_analyseur() -{ - while (file_precode!=NULL) - { - type_precode * pcd=file_precode; - file_precode=pcd->suivant; - FREE_PRECODE(pcd); - } - fin_file_precode=NULL; -} Index: trunk/gasm/src/formateur.c =================================================================== --- trunk/gasm/src/formateur.c (revision 13) +++ trunk/gasm/src/formateur.c (nonexistent) @@ -1,453 +0,0 @@ -#include "formateur.h" - -/* Autres modules utilises */ - -#include -#include - -/* Modules de la bibliotheque standard */ - -#include -#include -#include -#include - -/*********************************************************************************************/ -/* COMPOSITION DES ENSEMBLES DE CARACTERES */ -/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ -/* sa lecture. */ -/*********************************************************************************************/ - - -/* D‰finition de constantes pour la taille de chaque ensemble existant. */ -int taille_ensemble[NBR_ENS] = {taille_lettre, taille_chiffre, taille_prefixe, - taille_sep_explicite, taille_sep_invisible, taille_commentaire}; - -/* D‰finition des ensembles */ - -int ens_lettre[taille_lettre] = - { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', - 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '_', '.', '?', '$' - }; - -int ens_chiffre[taille_chiffre] = - { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', - 'b', 'c', 'd', 'e', 'f' - }; - -int ens_prefixe[taille_prefixe] = - { - '@', '%', '&', '+', '-', '\'' - }; - -int ens_sep_explicite[taille_sep_explicite] = - { - ACF, ACO, NL, DP, PF, PO, PS, MS, DIR, VIR, EOF - }; - -int ens_sep_invisible[taille_sep_invisible] = - { - '\t', ' ', '\r' - }; - -int ens_commentaire[taille_commentaire] = - { - ';', '\n' - }; - -/* D‰finition du tableau regroupant tous les ensembles qui est export‰. */ -int *ensemble[NBR_ENS] = {ens_lettre, ens_chiffre, ens_prefixe, - ens_sep_explicite, ens_sep_invisible, ens_commentaire}; - -/* D‰finition de la table des correspondances des caractˆres d'‰chappement. */ -char car_ech[] = "nt\\"; -char seq_ech[] = "\n\t\\"; - - -/*********************************************************************************************/ -/* MACROS DE TRAVAIL SUR LES ENSEMBLES */ -/* Pour ne pas avoir utiliser de r‰f‰rence directe aux ensembles de caractˆres, on y accˆde */ -/* au travers de macros d‰finies ici. En cas de changement, le code des autres modules */ -/* n'aura donc pas € Štre modifi‰. */ -/*********************************************************************************************/ - -/* G‰nˆre le masque caract‰ristique de l'ensemble */ -#define MASK_ENSEMBLE(ensbl) (1<= '0') && (car <= '9')) ? (car - '0') :\ - ((car >= 'a') && (car <= 'f')) ? (10 + car - 'a') :\ - ((car >= 'A') && (car <= 'F')) ? (10 + car - 'A') :\ - 0) - -/* Macro de d‰finition des bases des entiers en fonction de leur pr‰fixe. */ -#define VAL_BASE(prefixe) (\ - (prefixe == '\'') ? 0 :\ - (prefixe == '@') ? 16 :\ - (prefixe == '%') ? 2 :\ - (prefixe == '&') ? 8 :\ - 10\ - ) - -/* Macro de d‰finition du signe des entiers en fonction de leur pr‰fixe. */ -#define SGN_INIT(prefixe) (\ - (prefixe == '-') ? -1 :\ - 1\ - ) - - -/*********************************************************************************************/ -/* FONCTIONS DE TRAVAIL SUR LES ENSEMBLES */ -/* Fonctions publi‰es pour simplifier le traitement des ensembles. */ -/*********************************************************************************************/ - -char type_car(int c) -/* Cette fonction recherche dans tous les ensembles le caractˆre c et positionne un bit pour */ -/* chaque ensemble auquel il appartient. */ -{ - char type=0; - int i, j, flag; - - for(i=0; itype=POS_MPV(ALPHA); - (ptr_lex->valeur).alpha=(char*) malloc(i+1); - strcpy((ptr_lex->valeur).alpha, memo_string); - return ptr_lex; - } - else - { - err_code=S_ALPHA_INVALID; - return NULL; - } - } - - - if (typ & (MASK_ENSEMBLE(chiffre) | MASK_ENSEMBLE(prefixe))) - { /* Caractere numerique (‰ventuellement pr‰fixe, signe, etc.) */ - int val, sgn, base, car_in, typ_in, err_sel = 0; - - /* On m‰morise la valeur et le type du caractˆre en entr‰e pour le cas o· ce */ - /* choix ne serait pas le bon. */ - car_in = car; - typ_in = typ; - - val = CAR_TO_NUM(car); /* Initialisation de la valeur de l'entier. */ - sgn = SGN_INIT(car); /* initialistaion du signe de l'entier. */ - base = VAL_BASE(car); /* initialisation de la base d'aprˆs le pr‰fixe. */ - - if (car==CAR_ENC) /* Cas d'un entier de type caractˆre. */ - { - long pos=ftell(f); - char * car_trouve; - int err_ech=0; - LIT_CAR; - if (car=='\\') /* D‰but de s‰quence d'‰chappement. */ - { - LIT_CAR; - if ((car_trouve=strchr(car_ech, car))!=NULL) - car=*(seq_ech+(car_trouve-car_ech)); - else err_ech=1; - } - val=car; - LIT_CAR; - if (err_ech || car!=CAR_ENC) - { - err_sel=1; - car=car_in; - typ=typ_in; - fseek(f,pos-ftell(f),SEEK_CUR); - } - else - { - ALLOC_LEX(ptr_lex); - if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); - ptr_lex->type=POS_MPV(NUM); - (ptr_lex->valeur).num=val; - return ptr_lex; - } - } - - if (typ & MASK_ENSEMBLE(prefixe)) - { /* Si on a affaire € un pr‰fixe, le chargement du premier chiffre est */ - /* obligatoire mais il peut Štre s‰par‰ du chiffre par des s‰parateurs */ - /* invisibles. */ - LIT_SIGNIFICATIF; - val = CAR_TO_NUM(car); - if (!((typ & MASK_ENSEMBLE(chiffre)) && (val < base))) - { /* Erreur de format ou de s‰lection, caractˆre n'est pas un pr‰fixe */ - ungetc(car, f); - car = car_in; - typ = typ_in; - err_sel = 1; - } - } - - if (!err_sel) /* Uniquement s'il n'y a pas eu d'erreur de s‰lection. */ - { - LIT_CAR; - while (typ & MASK_ENSEMBLE(chiffre)) - { - int chiffre_val = CAR_TO_NUM(car); - if (chiffre_val >= base) - { - err_code=S_INT_INVALID; - return NULL; /* chiffre valide ? */ - } - val *= base; - val += chiffre_val; - LIT_CAR; - } - - /* Si le dernier caractˆre ‰tait un s‰parateur ou d‰but commentaire. */ - if ((typ & (MASK_ENSEMBLE(sep_explicite)|MASK_ENSEMBLE(sep_invisible))) - || (car == DEBUT_COM)) - { - ungetc(car, f); - ALLOC_LEX(ptr_lex); - if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); - ptr_lex->type=POS_MPV(NUM); - (ptr_lex->valeur).num=val*sgn; - return ptr_lex; - } - else - { - err_code=S_INT_INVALID; - return NULL; - } - } - } - - - if (typ & MASK_ENSEMBLE(sep_explicite)) - { /* Lire lexeme operateur. */ - ALLOC_LEX(ptr_lex); - if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); - ptr_lex->type=POS_MPV(OP); - (ptr_lex->valeur).op=car; - return ptr_lex; - } - - - if (car == DEBUT_COM) - { /* Epuiser le commentaire. */ - do - { - LIT_CAR; - } - while(car!=FIN_COM && car!=EOF); - if (!IGNORE_FIN_COMMENT) ungetc(car, f); - return get_lexeme(f); - } - - /* Le caractˆre rencontr‰ n'‰tait pas dans le bon contexte, erreur. */ - err_code=S_ERR_FORMAT; - return NULL; -} - - -/* Renvoie 1 si l est compatible avec filtre */ -int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse) -{ - int (* compare)(); - int v_comp=0; - - compare = casse ? (void *) &strcmp : (void *) &strcasecmp; - - /* Si les lexˆmes n'ont pas le mŠme type de base le filtre ne passe pas. */ - if (BASE_TYPE(l) != BASE_TYPE(filtre)) return 0; - /* Si l n'est pas du mŠme sous type que filtre le filtre ne passe pas. */ - if (SOUS_TYPE(filtre)!=0 && SOUS_TYPE(l)!=SOUS_TYPE(filtre)) return 0; - - if (!LIT_MPV(l->type) || !LIT_MPV(filtre->type)) v_comp=0; - else switch (BASE_TYPE(l)) - { - case ALPHA : if ((*compare) (l->valeur.alpha, - filtre->valeur.alpha)) - v_comp=0; - else v_comp=1; - break; - case NUM : if (l->valeur.num != filtre->valeur.num) - v_comp=0; - else v_comp=1; - break; - case OP : if (l->valeur.op != filtre->valeur.op) - v_comp=0; - else v_comp=1; - break; - default : v_comp=0; - break; - } - - /* Si les deux lexˆmes n'ont pas la mŠme valeur le filtre ne passe pas. */ - if (LIT_MPV(filtre->type) && (!LIT_MPV(l->type) || !v_comp)) return 0; - return 1; -} - -/* Renvoie 1 si les 2 lexˆmes sont ‰gaux */ -int id_lexeme(type_lexeme * l1, type_lexeme * l2, int casse) -{ - int (* compare)(); - - if (l1->type != l2->type) return 0; /* Lexˆmes de type, sstype ou bit de val diff. */ - if (!LIT_MPV(l1->type) && !LIT_MPV(l2->type)) return 1; /* Aucun lexˆme n'a de val. */ - - compare = casse ? (void *) &strcmp : (void *) &strcasecmp; - - switch BASE_TYPE(l1) - { - case ALPHA : if (!(*compare)(l1->valeur.alpha, l2->valeur.alpha)) - return 1; - break; - case NUM : if (l1->valeur.num == l2->valeur.num) - return 1; - break; - case OP : if (l1->valeur.op == l2->valeur.op) - return 1; - break; - default : return 0; - break; - } - return 0; -} - - -/*********************************************************************************************/ -/* */ -/* POINT D'ENTREE SECONDAIRE DU MODULE */ -/* */ -/* void print_lexeme(type_lexeme * l) */ -/* */ -/* Cette fonction affiche un lexˆme € l'‰cran avec formatage suivant son type et la pr‰sence */ -/* ‰ventuelle d'une valeur. */ -/* */ -/*********************************************************************************************/ - -int fprint_lexeme(FILE * f, type_lexeme * l) -{ -#define ALPHA_VAL (l->valeur.alpha) -#define NUM_VAL (l->valeur.num) -#define OP_VAL (l->valeur.op) - long int pos=ftell(f); - - switch (BASE_TYPE(l)) - { - case ALPHA : if (LIT_MPV(l->type)) fprintf(f, "%s", ALPHA_VAL); - break; - case NUM : if (LIT_MPV(l->type)) fprintf(f, "%d", NUM_VAL); - break; - case OP : if (LIT_MPV(l->type)) fprintf(f, "%c", OP_VAL); - break; - } - return ftell(f)-pos; -} - -/********************************************************************************************* - * * - * POINT D'ENTREE SECONDAIRE DU MODULE * - * * - * int strcasecmp(const char *, const char *) * - * * - * Redefinit cette fonction car elle n'est pas posix. * - * * - * Renvoie un nombre (<, =, >) € z‰ro si s1 est (<, =, >) € s2. * - * * - *********************************************************************************************/ - -int strcasecmp(char * s1, char * s2) -{ - for(; tolower(*s1)==tolower(*s2); s1++, s2++) - if (*s1=='\0') return 0; - return (*s1-*s2); -} - Index: trunk/gasm/src/synthetiseur.c =================================================================== --- trunk/gasm/src/synthetiseur.c (revision 13) +++ trunk/gasm/src/synthetiseur.c (nonexistent) @@ -1,270 +0,0 @@ -#include "synthetiseur.h" - -/* Autres modules utilisés par le synthétiseur. */ -#include -#include -#include -#include -#include -#include - -/* Cette fonction convertit un masque en talbeau de char équivalent. */ -/* La chaine étant allouée dynamiquement, il conviendra de la libérer après utilisation. */ -char * cnv_mask_str(type_mask * m) -{ - char * res; - int i; - type_valeur_mask v; - if (m==NULL) return NULL; - res = malloc((m->taille)*sizeof(char)); - if (res==NULL) DIALOGUE("synthetiseur(cnv_mask_str)", 0, F_ERR_MEM); - v=m->valeur; - for (i=m->taille-1 ; i>=0 ; i--) - { - res[i]= (v & 0xFF); - v>>=8; - } - return res; -} - -/* numéro de la colonne où l'on écrit le texte du code source dans la liste d'assemblage. */ -#define COL_TEXT (2*sizeof(type_valeur_mask)+10) - -/* Cette fonction recopie le flux srce dans dest jusqu'à la ligne fin exclue, sachant que le */ -/* flux source est supposé positionné à la ligne debut. */ -/* Le flux srce sera positionné au début de la ligne fin après l'exécution de la fonction. */ -/* La fonction retourne le numéro de la ligne à laquelle se trouve effectivement le flux. */ -/* Au début de chaque ligne, la fonction écrit son numéro puis \t suivi de COL_TEXT espaces. */ -int recopie(FILE * srce, FILE * dest, int debut, int fin) -{ - while (debutsuivant ) - { - int i; - - pco=pcd->pco; - - for (i=0 ; inbr_func ; i++) - { - type_mask * res; - res = (pcd->func)[i](pcd->param); - - switch (eval_code) - { /* Application du masque généré par la fonction de seconde passe. */ - case EVAL_REUSSIE : - if (res==NULL || res->taille==0) break; - if (pcd->mask==NULL || res->taille!=pcd->mask->taille) - { /* On a défini un nouveau masque incompatible. */ - DIALOGUE(pcd->fichier_orig, - pcd->ligne_orig, S_FUN_ERR); - /* On remplace le précode par une erreur. */ - CLEAR_PRECODE(pcd); - pcd->erreur=S_FUN_ERR; - err++; - break; - } - /* Le nouveau masque est ajouté. */ - pcd->mask->valeur|=res->valeur; - break; - case EVAL_IMPOSSIBLE : /* En seconde passe, erreur. */ - case EVAL_ERREUR : - affiche_message(pcd->fichier_orig, pcd->ligne_orig); - err++; - /* On remplace le précode par une erreur. */ - CLEAR_PRECODE(pcd); - pcd->erreur=err_code; - break; - default : - DIALOGUE(pcd->fichier_orig, - pcd->ligne_orig, S_ADAP_ERR); - CLEAR_PRECODE(pcd); - pcd->erreur=S_ADAP_ERR; - err++; - break; - } - if (res!=NULL) FREE_MASK(res); - } - /* On libère l'espace alloué pour le tableau des fonctions de seconde passe. */ - if (pcd->func!=NULL) free(pcd->func); - pcd->func=NULL; - pcd->nbr_func=0; - } - return err; -} - - -/* Cette fonction est utilisée pour écrire dans un flux le code binaire généré et */ -/* actuellement enregistré dans la pile de précode. Il faut au préalable exécuter la seconde */ -/* passe faute de quoi le code sera incomplet. */ -void write_objet(FILE * f_obj) -{ - type_precode * pcd; - int i; - int local_pco=-1; - long c_head=-5; /* Utilisé pour mémoriser la position de l'entête du bloc courant. */ - long n_head; /* Position du nouvel entête de bloc. */ - int addimp; - int taille; - - if (f_obj==NULL) DIALOGUE("synthetiseur(write_objet)", 0, F_FLUX_NULL); - - for (pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant) - { - if (pcd->erreur==NO_ERR && pcd->mask!=NULL) - { /* On ne s'occupe ici que des précodes générant du code. */ - char * code_bin; - - if (pcd->pco!=local_pco) - { /* Ecriture d'un nouvel entête de bloc en complétion du précédent. */ - n_head=ftell(f_obj); - addimp=pcd->pco; - if (c_head!=-5) /* Il ne s'agit pas du premier bloc. */ - { /* Ecriture de la taille du bloc que l'on ferme. */ - /* Calcul de la taille du bloc terminé. */ - taille=n_head-c_head-4; - /* Ecriture de la taille au bon emplacement. */ - fseek(f_obj, c_head+2, SEEK_SET); - for (i=1 ; i>=0 ; i--) - fputc((taille>>(8*i)) & 0xFF, f_obj); - /* Retour au nouveau bloc. */ - fseek(f_obj, n_head, SEEK_SET); - } - /* Ecriture de l'adresse d'implantation. */ - for (i=1 ; i>=0 ; i--) fputc((addimp>>(8*i)) & 0xFF , f_obj); - /* Ecriture de 0 pour la taille du prochain bloc. */ - for (i=0; i<2; i++) fputc(0, f_obj); - c_head=n_head; - local_pco=pcd->pco; - } - - /* On écrit le masque du précode courant dans le fichier. */ - code_bin=cnv_mask_str(pcd->mask); /* Conversion du masque. */ - /* Insertion des caractères dans le fichier objet. */ - for (i=0 ; imask->taille ; i++) fputc(code_bin[i], f_obj); - free(code_bin); /* On libère la chaine allouée. */ - - local_pco+=pcd->mask->taille; /* Avancement du pco. */ - } - } - - /* Ecriture de la taille du dernier bloc. */ - n_head=ftell(f_obj); - /* Calcul de la taille du bloc terminé. */ - taille=n_head-c_head-4; - /* Ecriture de la taille au bon emplacement. */ - fseek(f_obj, c_head+2, SEEK_SET); - for (i=1 ; i>=0 ; i--) fputc((taille>>(8*i)) & 0xFF, f_obj); - /* Retour au nouveau bloc, en fin de fichier. */ - fseek(f_obj, n_head, SEEK_SET); -} - - -/* Cette fonction est utilisée pour écrire dans un flux la liste d'assemblage correspondant */ -/* aux données enregistrée dans la pile de précode. Il faut au préalable exécuter la seconde */ -/* passe faute de quoi le code sera incomplet. */ -void write_liste(FILE * f_lst, FILE * f_src) -{ - int ligne=1; /* Ligne courante dans le fichier source. */ - type_precode * pcd_cour=file_precode; - - if (f_lst==NULL) DIALOGUE("synthetiseur(write_liste)", 0, F_FLUX_NULL); - - while (pcd_cour!=NULL) - { - int lbloc; /* Numéro de ligne de l'instruction que l'on va traiter. */ - int pco_ecrit=0; /* Drapeau de controle de l'écriture du pco. */ - long col=0; /* Colonne courante dans la ligne actuelle du fichier. */ - type_precode * pcd; - - lbloc=pcd_cour->ligne_orig; /* Ligne courante dans la source. */ - - /* On recopie la portion de code jusqu'à la ligne ayant généré le précode. */ - ligne=recopie(f_src, f_lst, ligne, lbloc); - - if (ligne!=lbloc) - { /* Le fichier source a changé par rapport aux lignes mémorisées. */ - DIALOGUE(NULL, 0, W_SRCE_MOD); - return; - } - - fprintf(f_lst, "%d\t", ligne); /* Ecriture du numéro de la ligne en cours. */ - col=ftell(f_lst); /* On mémorise la colonne de départ. */ - - for (pcd=pcd_cour ; pcd!=NULL && pcd->ligne_orig==lbloc ; pcd=pcd->suivant) - { /* On parcourt tous les précodes de la ligne. */ - if (pcd->erreur==NO_ERR && pcd->mask!=NULL) - { - char str[3*sizeof(type_taille_mask)+3]; - - if (!pco_ecrit) /* Le pco n'est écrit que sur les lignes */ - { /* générant du code et ce une seule fois. */ - fprintf(f_lst, "%04X ", pcd->pco); - pco_ecrit=1; - } - - sprintf(str, "%%0%dX", pcd->mask->taille*2); - fprintf(f_lst, str, pcd->mask->valeur); - } - } - - /* On complète avec des espaces pour aligner le code source. */ - for ( col=ftell(f_lst)-col ; colligne_orig==lbloc) - { /* Ecriture des éventuelles erreurs du bloc. */ - if (pcd_cour->erreur!=NO_ERR) - { /* On affiche le message d'erreur dans la liste d'assemblage. */ - int i; - err_code=pcd_cour->erreur; - fputc('\t', f_lst); - for (i=0; isuivant; - } - } - - /* Recopie de la fin du fichier source dans la liste d'assemblage. */ - while (!feof(f_src)) - { - int i; - fprintf(f_lst, "%d\t", ligne++); - for (i=0; i -#include - -#include - -int err_code=0; - -int verbose=0; - -/* Texte de l'aide en ligne. */ -char help[]="\n\ -Assembleur pour le microprocesseur miniMIPS version 1.0\n\ -Utilisation : asmips [options] [fichier]\n\ -\n\ - Exemple : asmips -vo a.obj -l a.lst source.asm\n\ -\n\ -Options disponibles :\n\ -\n\ - -v active le mode verbeux\n\ -\n\ - -n désactive la liste d'assemblage\n\ -\n\ - -o nom_fichier nom du fichier de sortie, par défaut a.obj\n\ -\n\ - -p assemble vers la sortie standard\n\ -\n\ - -l nom_fichier nom du fichier pour la liste d'assemblage\n\ - par défaut, a.lst est utilisé\n\ -\n\ - -s nom_fichier nom du fichier de syntaxe, par défaut \'Syntaxe\'\n\ -\n\ - -m nom_fichier nom du fichier de macros par défaut, contenant les\n\ - pseudo-instructions de l'assembleur\n\ -\n\ -Notes d'utilisation :\n\ -\n\ - Si aucun fichier d'entrée n'est spécifié, asmips tente d'assembler\n\ - l'entrée standard. Ce mode n'est pas encore compatible avec la liste\n\ - d'assemblage qui sera donc automatiquement désactivée.\n\ -\n\ - La sélection du fichier de macro en ligne de commande est prioritaire\n\ - par rapport au fichier spécifié par la syntaxe qui sera donc ignoré.\n\ -\n\ -Merci de signaler les éventuels bugs à :\n\ -\n\ - shangoue@enserg.fr\n\ - lmouton@enserg.fr\n\ -"; - - -typedef struct -{ - int code; - char * chaine; -} type_paire_msg; - -static type_paire_msg message[] = - -{{ NO_ERR, "Pas d'erreur trouvée" } -/* Erreurs génériques : */ -,{ F_FLUX_NULL, "Tentative de lecture/écriture dans un flux NULL" } -,{ F_ERR_LECT, "Erreur de lecture imprévisible dans le flux" } -,{ F_ERR_OUV, "Erreur d'ouverture du fichier" } -,{ F_ERR_MEM, "Erreur d'allocation (mémoire insuffisante ?)" } -/* Erreurs du formateur : */ -,{ S_ERR_FORMAT, "Mauvaise utilisation d'un caractère" } -,{ S_CAR_INVALID, "Caractère non reconnu" } -,{ S_ALPHA_LONG, "Lexème de type ALPHA trop long" } -,{ S_ALPHA_INVALID, "Caractère non valide dans l'identificateur" } -,{ S_INT_INVALID, "Caractère non valide dans l'entier" } -/* Erreurs du préprocesseur : */ -,{ S_CIRCULAR_FILE, "Inclusion circulaire de fichier(s)" } -,{ S_CIRCULAR_MACRO, "Inclusion circulaire de macro" } -,{ S_FICH_NON_TROUVE, "Impossible d'ouvrir le fichier indiqué" } -,{ S_DEF_MACRO_EOF, "Fin du fichier inattendue lors de la définition de macro" } -,{ S_USE_MACRO_EOF, "Fin du fichier inattendue lors de l'utlisation d'une macro" } -,{ S_NOM_MAC_INVALID, "Nom de la macro dans sa déclaration invalide" } -,{ S_NOM_INCFICH_INVALID, "Nom du fichier à inclure invalide" } -,{ S_MAC_NO_MATCH , "L'utilisation de la macro est incompatible avec sa définition" } -,{ S_MAC_TROP_PARAM, "Paramètre(s) non utlisé(s) dans la macro" } -/* Erreurs du préparateur : */ -,{ S_ERR_DCL, "Déclaration incorrecte" } -,{ S_DCL_VIDE, "Déclaration d'instruction vide" } -,{ S_DCL_NON_TERM, "Déclaration d'instruction non terminée '}' manquante" } -,{ S_REDEF_INS, "Instruction déjà existante, la nouvelle déclaration sera ignorée" } -,{ S_BAD_PROP, "Propriété incorrecte" } -,{ S_BAD_VAL, "Valeur de la propriété incorrecte" } -,{ S_BAD_FUN, "Fonction non définie" } -,{ S_BAD_ARG, "Mauvais argument pour la commande SET" } -,{ S_BAD_SST_DEC, "Déclaration du nombre de sous-types absente ou insuffisante" } -,{ S_DEP_FUNC_NB, "Dépassement de la capacité d'enregistrement des fonctions" } -,{ S_DEP_SST, "Dépassement de la capacité de codage des sous-types" } -,{ S_SEC_SST_DEC, "Répétition de la commande SSTNUM non autorisée" } -/* Erreurs de l'analyseur : */ -,{ S_SYN_ERR, "Erreur de syntaxe" } -,{ S_FUN_ERR, "Masques incompatibles dans la définition d'une instruction" } -,{ S_ADAP_ERR, "Erreur dans la valeur de retour d'une fonction de l'adaptateur" } -/* Erreurs de l'adaptateur : */ -,{ S_FUN_INAP, "Fonction génératrice de masque inapplicable" } -,{ S_ARG_INCOMP, "Inadéquation des arguments avec une fonction de l'adaptateur" } -,{ S_SIGNED_TL, "Entier trop long pour le codage signé sur les bits disponibles" } -,{ S_UNSIGNED_TL, "Entier trop long pour le codage non signé sur les bits disponibles" } -,{ S_UNSIGNED_EXPECTED, "Entier non signé attendu" } -,{ S_REDEF_ETIQ, "Redéfinition d'étiquette non prise en compte" } -,{ S_BAD_ETIQ, "Etiquette inexistante" } -,{ S_ADR_INCONNUE, "L'adresse d'implantation est indéterminée" } -,{ S_BAD_ALIGN, "Saut à une étiquette non alignée sur 32 bits" } -,{ S_TOO_FAR, "Saut à une adresse n'appartenant pas à la région courante de 256 Mo" } -/* Erreurs du synthetiseur. */ - -/* Warnings : */ -,{ W_SEPLEX_INIT, "Valeur du séparateur d'instruction non initialisé dans fichier Syntaxe" } -,{ W_REGLE_TYPAGE, "Regle de sous-typage invalide dans le fichier Syntaxe; elle est ignorée" } -,{ W_ARG_INC, "Argument incorrect" } -,{ W_FICH_DEF_MACRO, "Le fichier des macros par défaut n'a pas été trouvé" } -,{ W_MACRO_MANQ, "Auncun fichier des macros par défaut chargé" } -,{ W_NO_LIST_INC, "L'utilisation des inclusions désactive la liste d'assemblage" } -,{ W_NO_LIST_STDIN, "La lecture dans le flux standard interdit la liste d'assemblage" } -,{ W_NO_SYNTAX, "Pas de fichier de syntaxe" } -,{ W_SRCE_MOD, "Flux source modifié. Echec de la création de la liste d'assemblage" } -,{ W_REDEF_MAC, "Redéfinition d'une macro" } -,{ W_UNDEF_NOMAC, "Tentative de suppression d'une macro non définie" } -,{ W_REDEF_CODE, "Réutilisation du code, les sous-types seront confondus" } -,{ W_REDEF_SST, "Nom de sous-type existant, seule la première définition sera accessible" } - -/* Commentaires */ - -/* Main */ -,{ B_INIT_SYNTAX, "Initialisation de la syntaxe de l'assembleur..." } -,{ B_INIT_MACRO, "Chargement des pseudo-instructions..." } -,{ B_LECT_SRC, "Lecture des sources..." } -,{ B_STR_OBJ, "Enregistrement du fichier objet..." } -,{ B_STR_LST, "Creation de la liste d'assemblage..." } -,{ B_ERR_REP, "Rapport d'erreurs :" } -,{ B_NBR_ERR_SYN, "\tErreurs détectées lors de la synthèse :" } -,{ B_NBR_ERR_ANA, "\tErreurs détectées lors de l'analyse :" } -,{ B_SYN, "Synthèse..." } -,{ B_ANA, "Analyse du code..." } -/* Preparateur */ -,{ B_CASSE, "Basculement en mode sensible à la casse" } -,{ B_NOCASSE, "Basculement en mode insensible à la casse" } -,{ B_MAC_DEF, "Détection d'un fichier de pseudo-instructions par défaut dans la syntaxe" } -,{ B_INIT_D, "Activation du support des macros" } -,{ B_INIT_U, "Activation du support de la supression de macros" } -,{ B_INIT_I, "Activation du support de l'inclusion de fichiers" } -,{ B_INIT_SEP, "Initialisation du séparateur d'instructions" } -,{ B_PREP_SST, "Préparation pour l'ajout de sous-types" } -,{ B_ADD_SST, "Nouveau sous-type détecté" } -/* Preprocesseur */ -,{ B_NO_MACRO, "Aucune macro définie." } -,{ B_MACRO_DISPO, "Macros disponibles :" } -/* Adaptateur */ -,{ B_TABLAB, "Table des étiquettes :" } - -/* Terminateur de la table, ne pas supprimer ! */ -,{ 0, NULL } -}; - -char sep_fich_inclus[] = " inclus depuis "; - -char * search_msg() -{ - type_paire_msg * pmsg=message; - while(pmsg->chaine!=NULL) - { - if (pmsg->code==err_code) return pmsg->chaine; - pmsg++; - } - return message->chaine; -} - -void affiche_message(char * origine, int ligne) -{ - if (err_code>=1000) /* Warning */ - { - if (origine && ligne) - fprintf(stderr, "Attention ! \'%s\' : %d : %s.\n" - , origine, ligne, search_msg()); - else if (origine) - fprintf(stderr, "Attention ! \'%s\' : %s.\n", origine, search_msg()); - else - fprintf(stderr, "Attention ! %s.\n", search_msg()); - } - else if (err_code < 0) /* Commentaire */ - { - if (verbose) - { - if (origine && ligne) - fprintf(stderr, "-- \'%s\' : %d : %s\n" - , origine, ligne, search_msg()); - else if (origine) - fprintf(stderr, "-- %s %s\n", search_msg(), origine); - else - fprintf(stderr, "-- %s\n", search_msg()); - } - } - else if (err_code<100) /* Fatal Error */ - { - if (origine && ligne) - fprintf(stderr, "Erreur fatale ! \'%s\' : %d : %s.\n" - , origine, ligne, search_msg()); - else if (origine) - fprintf(stderr, "Erreur fatale ! \'%s\' : %s.\n" - , origine, search_msg()); - else - fprintf(stderr, "Erreur fatale ! %s.\n", search_msg()); - exit(err_code); - } - else /* Erreur de Syntaxe */ - { - if (origine && ligne) - fprintf(stderr, "\'%s\' : %d : %s.\n" - , origine, ligne, search_msg()); - else if (origine) - fprintf(stderr, "\'%s\' : %s.\n", origine, search_msg()); - else - fprintf(stderr, "%s.\n", search_msg()); - } -} - -void display_help() -{ /* fonction d'affichage de l'aide en ligne. */ - fprintf(stderr, help); -} Index: trunk/gasm/src/preparateur.c =================================================================== --- trunk/gasm/src/preparateur.c (revision 13) +++ trunk/gasm/src/preparateur.c (nonexistent) @@ -1,786 +0,0 @@ -/*********************************************************************************************/ -/* MODULE PREPARATEUR */ -/* ce module a pour but de lire le fichier Syntaxe du programme et de générer l'arbre des */ -/* lexèmes qui lui correspond. */ -/* */ -/* Le seul point d'accès de ce module est la fonction init_arbre qui reçoit le nom du */ -/* fichier Syntaxe à utiliser. */ -/* */ -/*********************************************************************************************/ - -#include "preparateur.h" - -/* Inclusion des modules de la bibliothèque standard. */ -#include -#include - -/* Inclusion des autres modules utilisés du projet. */ -#include -#include -#include -#include -#include - -/* Ces macros sont utilisées pour les comparaisons de chaines. Leur valeur détermine la */ -/* sensibilité ou non du préparateur à la casse lors de la lecture du fichier Syntaxe. */ -#define string_comp strcasecmp -#define lexeme_comp lexcaseid - -type_noeud *root = NULL; /* Définition de la racine de l'arbre des lexèmes. */ - -/* Numéro de ligne et fichier Syntaxe courant. */ -static int ligne=1; -static char * n_fich; -static FILE * f_syn; - -/*********************************************************************************************/ -/* */ -/* Définition des objets décrivant la syntaxe et l'organisation du fichier Syntaxe. On */ -/* trouve : */ -/* */ -/* la table des mots clefs, qui contient les valeurs spécifiant un type de lexème. */ -/* la table des propriétés, regroupant le nom des différentes propriétés. */ -/* la table des fonctions qui peuvent être exécutées à la lecture du fichier Syntaxe. */ -/* */ -/*********************************************************************************************/ - - -/* TABLES DES MOTS CLEF */ -typedef struct -{ - char * nom; - type_type_lex code; -} type_table; - -/* Table statique des mots clefs correspondant aux types de base. */ -#define NUM_KEYWORD 2 /* Nombre de mots clef reconnus par le préparateur. */ -static type_table table_clef_base[NUM_KEYWORD] = - { { "alpha" , ALPHA} - , { "int" , NUM} - }; - -/* Table dynamique des mots clefs correspondant aux sous types. */ -static type_table * table_clef_sst=NULL; - - -/* TABLE DES PROPRIETES */ -#define NUM_PROP 3 -static char *prop_table[NUM_PROP] = - { "TMO" - , "MSK" - , "FUN" - }; -enum {TMO, MSK, FUN}; /* Codes symboliques pour les différentes propriétés. */ - - -/* TABLE DES FONCTIONS */ -/* Définition des fonctions de paramétrage du preparateur. Elles seront exécutées à la */ -/* demande du fichier Syntaxe lors de la rencontre de l'instruction SET. */ - -/* En cas d'erreur, ces fonctions renvoient 1 et positionnent la variable errcode du module */ -/* erreur. La fonction appelante se charge de l'affichage de l'erreur. */ - -int casse() -{ - casse_sens = 1; - DIALOGUE(NULL, 0, B_CASSE); - return 0; -} - -int nocasse() -{ - casse_sens = 0; - DIALOGUE(NULL, 0, B_NOCASSE); - return 0; -} - -int macrofile() /* Cette fonction lit le nom du fichier macro par défaut et l'enregistre. */ -{ - long pos=ftell(f_syn); - type_lexeme * l; - - DIALOGUE(NULL, 0, B_MAC_DEF); - - l=get_lexeme(f_syn); - if (l==NULL) - { - err_code=S_BAD_ARG; - return 1; - } - if (!TYPE_IS(l, ALPHA) || !LIT_MPV(l->type)) - { - FREE_LEX(l); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - - if (fich_macro_def!=NULL) free(fich_macro_def); - fich_macro_def=l->valeur.alpha; - /* On supprime la valeur du lexème pour que la chaine ne soit pas libérée. */ - l->type=RET_MPV(l->type); - FREE_LEX(l); - - err_code = NO_ERR; - return 0; -} - -int setdefine() -{ - long pos=ftell(f_syn); - type_lexeme * lex; - - DIALOGUE(NULL, 0, B_INIT_D); - - lex=get_lexeme(f_syn); - if (lex==NULL) - { /* Erreur de lecture de l'argument. */ - err_code=S_BAD_ARG; - return 1; - } - if (!TYPE_IS(lex,ALPHA)) - { /* L'argument n'a pas le bon type. */ - FREE_LEX(lex); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - if (define_str!=NULL) free(define_str); - define_str=malloc(strlen(lex->valeur.alpha)+1); - strcpy(define_str, lex->valeur.alpha); - FREE_LEX(lex); - - err_code = NO_ERR; - return 0; -} - -int setundef() -{ - long pos=ftell(f_syn); - type_lexeme * lex; - - DIALOGUE(NULL, 0, B_INIT_U); - - lex=get_lexeme(f_syn); - if (lex==NULL) - { /* Erreur de lecture de l'argument. */ - err_code=S_BAD_ARG; - return 1; - } - if (!TYPE_IS(lex,ALPHA)) - { /* L'argument n'a pas le bon type. */ - FREE_LEX(lex); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - if (undef_str!=NULL) free(undef_str); - undef_str=malloc(strlen(lex->valeur.alpha)+1); - strcpy(undef_str, lex->valeur.alpha); - FREE_LEX(lex); - - err_code = NO_ERR; - return 0; -} - -int setinclude() -{ - long pos=ftell(f_syn); - type_lexeme * lex; - - DIALOGUE(NULL, 0, B_INIT_I); - - lex=get_lexeme(f_syn); - if (lex==NULL) - { - err_code=S_BAD_ARG; - return 1; /* Erreur de lecture de l'argument. */ - } - if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ - { - FREE_LEX(lex); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - - if (include_str!=NULL) free(include_str); - include_str=malloc(strlen(lex->valeur.alpha)+1); - strcpy(include_str, lex->valeur.alpha); - FREE_LEX(lex); - - err_code = NO_ERR; - return 0; -} - -int setsep() -{ - type_lexeme * lex; - lex=get_lexeme(f_syn); - - DIALOGUE(NULL, 0, B_INIT_SEP); - - if (lex==NULL) - { - err_code=S_BAD_ARG; - return 1; - } - if (seplex!=NULL) FREE_LEX(seplex); - if (TYPE_IS(lex, OP) && lex->valeur.op==NL) ligne++; - seplex=lex; - - err_code = NO_ERR; - return 0; -} - -int sst_max=0; /* Nombre maximal de sous-types réservés dans la table. */ - -int setnumsst() -{ - long pos=ftell(f_syn); - type_lexeme * lex; - - DIALOGUE(NULL, 0, B_PREP_SST); - - if (table_clef_sst!=NULL) /* Réutilisation de SSTNUM. */ - { - err_code = S_SEC_SST_DEC; - return 1; - } - - lex=get_lexeme(f_syn); - if (lex==NULL) - { /* Erreur de lecture de l'argument. */ - err_code=S_BAD_ARG; - return 1; - } - if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ - { - FREE_LEX(lex); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - sst_max=lex->valeur.num; - - FREE_LEX(lex); - /* Allocation des tables locales et globale des sous types. */ - regle_typage = (type_paire *) malloc(sst_max*sizeof(type_paire)); - if (regle_typage==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); - table_clef_sst = (type_table*) malloc(sst_max*sizeof(type_table)); - if (table_clef_sst==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); - - err_code = NO_ERR; - return 0; -} - -int setnewsst() -{ - long pos=ftell(f_syn); - type_lexeme * lex; - char * nom, *filtre; - type_type_lex code; - int i, bk=0; - - DIALOGUE(NULL, 0, B_ADD_SST); - - /* Vérification que la déclaration du nombre de sous-types est valide. */ - if (regle_typage==NULL || table_clef_sst==NULL || nbr_sous_types>=sst_max) - { - err_code=S_BAD_SST_DEC; - return 1; - } - - /* Lecture du mot clef correspondant au sous-type. */ - lex=get_lexeme(f_syn); - if (lex==NULL) - { - err_code=S_BAD_ARG; - return 1; /* Erreur de lecture de l'argument. */ - } - if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ - { - FREE_LEX(lex); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - /* Ajout du mot clef. */ - nom = lex->valeur.alpha; - /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX. */ - lex->type=RET_MPV(lex->type); - FREE_LEX(lex); - - - /* Lecture de la règle de typage correspondant au sous-type. */ - lex=get_lexeme(f_syn); - if (lex==NULL) - { - err_code=S_BAD_ARG; - return 1; /* Erreur de lecture de l'argument. */ - } - if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ - { - FREE_LEX(lex); - free(nom); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - /* Ajout de la règle à la table. */ - filtre=lex->valeur.alpha; - /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX. */ - lex->type=RET_MPV(lex->type); - FREE_LEX(lex); - - /* Lecture du code correspondant au sous-type. */ - lex=get_lexeme(f_syn); - if (lex==NULL) - { - err_code=S_BAD_ARG; - return 1; /* Erreur de lecture de l'argument. */ - } - if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ - { - FREE_LEX(lex); - free(nom); - free(filtre); - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - err_code=S_BAD_ARG; - return 1; - } - /* Vérification de la valeur du code demandé. */ - if (lex->valeur.num<0 || lex->valeur.num>MAX_SOUS_TYPES) - { /* Le nombre de sous-types codables est limité... */ - FREE_LEX(lex); - free(nom); - free(filtre); - err_code=S_DEP_SST; - fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ - return 1; - } - code=CODE_TYPE(lex->valeur.num); - FREE_LEX(lex); - - for (i=0 ; i0 ; nbr_sous_types--)\ - free(regle_typage[nbr_sous_types-1].chaine);\ - free(regle_typage);\ - regle_typage=NULL;\ - }\ - casse_sens=1;\ - sst_max=0;\ - nbr_sous_types=0;\ -} - - -/*********************************************************************************************/ -/* FONCTION place_lexeme */ -/* */ -/* type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) */ -/* */ -/* Cette fonction reçoit un lexème et un noeud. Elle recherche le lexème dans les fils du */ -/* noeud et si elle le trouve, elle renvoie un pointeur sur lui, sinon elle le crée et */ -/* renvoie ce nouveau pointeur. */ -/* */ -/*********************************************************************************************/ - -type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) -{ - char * msg_orig="préparateur(place_lexeme)"; - type_noeud * cur_fils = (cur_root->ptr_fils); - - while (cur_fils != NULL) - { - if (lexeme_comp(l, &(cur_fils->lexeme))) return cur_fils; - cur_fils = cur_fils->ptr_frere; - } - ALLOC_NOEUD(cur_fils); - cur_fils->ptr_frere = cur_root->ptr_fils; - LEX_COPY(l, &(cur_fils->lexeme)); - cur_root->ptr_fils = cur_fils; - return cur_fils; -} - - -/*********************************************************************************************/ -/* FONCTION lit_feuille */ -/* */ -/* type_feuille * lit_feuille(FILE * f_syn) */ -/* */ -/* Cette fonction reçoit le fichier Syntaxe ouvert à la bonne position et lit les */ -/* différentes propriétés qui s'y trouve. A partir de cette lecture, elle crée une feuille */ -/* pour les enregistrer et renvoie un pointeur vers celle-ci. En cas d'erreur, un pointeur */ -/* NULL est retourné et le fichier est laissé à la position de l'erreur. */ -/* */ -/*********************************************************************************************/ - -#define OPERATEUR (TYPE_IS(lex, OP)) -#define VAL_OP ((lex->valeur).op) -#define VAL_ALPHA ((lex->valeur).alpha) - -#define ERR_LF(val) {\ - if (lex!=NULL) FREE_LEX(lex);\ - if (mask_ptr!=NULL) FREE_MASK(mask_ptr);\ - DIALOGUE(n_fich, ligne, val);\ - return NULL;\ - } -/* Comme la lecture d'une feuille n'est pas sensible a la présence de sauts de ligne, la */ -/* macro suivante se charge de les éliminer. La terminaison est assurée par EOF. */ -/* La macro commence par libérer l'espace du lexème précédent sauf si celui-ci est NULL. */ -#define LIT_LEXEME {\ - do\ - {\ - if (lex!=NULL) FREE_LEX(lex);\ - lex=get_lexeme(f_syn);\ - if (lex==NULL) ERR_LF(err_code)\ - if (OPERATEUR && VAL_OP==NL) ligne++;\ - }\ - while (OPERATEUR && VAL_OP==NL);\ - } - -#define INIT_MASK {\ - if (mask_ptr==NULL)\ - {\ - ALLOC_MASK(mask_ptr);\ - mask_ptr->taille=0;\ - mask_ptr->valeur=0;\ - }\ - if (mask_ptr==NULL)\ - DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM);\ - } - -type_feuille * lit_feuille() -{ - char * msg_orig="preparateur(lit_feuille)"; - int i, c, tmo_lu=0, i_fun=0; - type_valeur_mask tmp_msk=0; - type_lexeme * lex=NULL; - type_ptr_fgm fun_ptr[MAX_FONCTIONS]; - type_mask * mask_ptr=NULL; - type_feuille * tmp_feuille; - - LIT_LEXEME /* Lit le premier lexème différent de NL. */ - while (!OPERATEUR || (VAL_OP!=EOF && VAL_OP!=ACO)) - { - if (!TYPE_IS(lex, ALPHA)) ERR_LF(S_BAD_PROP); - /* Détermination de la propriété. */ - i=-1; - while (++itaille=(lex->valeur).num; - break; - case MSK : LIT_LEXEME; - if (!TYPE_IS(lex,ALPHA)||VAL_ALPHA[0]!='_') - ERR_LF(S_BAD_VAL); - INIT_MASK; - i=1; tmp_msk=0; - while ((c=VAL_ALPHA[i++])!='\0') - { - if (c!='0' && c!='1') - { - if (c!='_') ERR_LF(S_BAD_VAL); - } - else - { - tmp_msk<<=1; - tmp_msk+=(c-'0'); - } - } - (mask_ptr->valeur)|=tmp_msk; - break; - case FUN : if (i_fun==MAX_FONCTIONS) ERR_LF(S_DEP_FUNC_NB); - LIT_LEXEME; - if (!TYPE_IS(lex,ALPHA)) ERR_LF(S_BAD_VAL); - fun_ptr[i_fun]=alias(VAL_ALPHA); - if (fun_ptr[i_fun]==NULL) - { /* Fonction inexistante. */ - ERR_LF(S_BAD_FUN); - } - i_fun++; - break; - default : return NULL; - } - LIT_LEXEME; - } - - FREE_LEX(lex); - ALLOC_FEUILLE(tmp_feuille); - if (!tmo_lu && mask_ptr!=NULL) - { /* On ignore le masque si il n'a pas de taille spécifiée. */ - FREE_MASK(mask_ptr); - mask_ptr=NULL; - } - tmp_feuille->mask_primaire=mask_ptr; - - /* Recopie de la liste des fonctions de génération de masque. */ - tmp_feuille->nbr_func=i_fun; - if (i_fun) - { - tmp_feuille->ptr_func=(type_ptr_fgm *) (malloc(i_fun*sizeof(type_ptr_fgm))); - if (tmp_feuille->ptr_func==NULL) - DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM); - while ((i_fun--)>0) - { - tmp_feuille->ptr_func[i_fun] = fun_ptr[i_fun]; - } - } - else tmp_feuille->ptr_func=NULL; - - return tmp_feuille; -} - - -/*********************************************************************************************/ -/* FONCTION init_arbre */ -/* */ -/* int init_arbre(char * fichier_syntaxe) */ -/* */ -/* Cette fonction reçoit le nom du fichier Syntaxe, l'ouvre et y lit les informations. Elle */ -/* les utilise pour mettre à jour l'arbre des lexèmes défini dans le commun (root). Les */ -/* erreurs de format sont signalées. */ -/* La valeur de retour est le nombre d'erreurs rencontrées. */ -/* */ -/*********************************************************************************************/ - -int init_arbre(char * fichier_syntaxe) - - -#define ERREUR(val) {\ - DIALOGUE(fichier_syntaxe, ligne, val);\ - err=1;\ - } -/* Lecture d'un lexème non NULL, au pire EOF, tout en comptant les lignes. */ -/* Le lexème précédent est libéré sauf s'il est NULL. */ -#define LIT_VALIDE {\ - if (lex!=NULL) FREE_LEX(lex);\ - while ((lex=get_lexeme(f_syn))==NULL)\ - {\ - err=1;\ - ERREUR(err_code);\ - }\ - if (OPERATEUR && VAL_OP==NL) ligne++;\ - } -/* Recherche de la prochaine accolade ouvrante (instruction suivante) */ -#define ACO_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF)) -#define LIGNE_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=NL && VAL_OP!=EOF)) - -{ - char * msg_orig="preparateur(init_arbre)"; - type_lexeme * lex=NULL; - int err=0,gblerr=0; /* err est vrai lors d'une erreur, gblerr s'il y a eu une erreur */ - type_noeud * courant; - type_feuille * feuille=NULL; - - /* Réinitialisation des différentes variables locales et globales. */ - REINIT; - ALLOC_NOEUD(root); - - f_syn=fopen(fichier_syntaxe, "rb"); /* ouverture du fichier Syntaxe. */ - if (f_syn==NULL) - { - DIALOGUE(NULL, 0, W_NO_SYNTAX); - return 0; - } - - n_fich = fichier_syntaxe; /* Positionne la variable commune au module. */ - ligne=1; /* Initialisation du numéro de ligne au début du fichier. */ - - do /* Lecture du fichier Syntaxe jusqu'à la première accolade ouvrante. */ - { - LIT_VALIDE; - if (TYPE_IS(lex, ALPHA) && !string_comp(VAL_ALPHA, SET)) - { /* On a rencontré une commande SET, lecture des arguments. */ - int i=-1; - LIT_VALIDE; - if (!TYPE_IS(lex, ALPHA)) - { - ERREUR(S_BAD_ARG); - gblerr++; - LIGNE_SUIV; - } - else - { - while (++itype) && TYPE_IS(lex, ALPHA)) - { /* Si on a un mot clef, on ajuste le type (on supprime la valeur) */ - int i, key=0; - /* Recherche dans les mots clef de base. */ - for (i=0 ; itype=table_clef_base[i].code; - key=1; - } - /* Recherche dans les mots clef des sous-types. */ - for (i=0 ; itype=table_clef_sst[i].code; - key=1; - } - if (key) free(lex->valeur.alpha); - } - courant = place_lexeme(lex, courant); - LIT_VALIDE; - if (OPERATEUR && VAL_OP==EOF) ERREUR(S_DCL_NON_TERM); - } - - /* Redéfinition d'une instruction déjà lue. */ - if (courant->ptr_feuille!=NULL) ERREUR(S_REDEF_INS); - - if (!err) feuille=lit_feuille(); /* Lecture de la feuille. */ - if (feuille==NULL) err=1; /* Le message d'erreur est géré à la lecture. */ - - /* Si la lecture est réussie, il faut mémoriser la nouvelle instruction. */ - if (!err) courant->ptr_feuille=feuille; - else ACO_SUIV; /* Erreur de lecture, on passe à l'instruction suivante. */ - gblerr+=(err==1); /* Le code d'erreur est uniquement 1. */ - } - while (!OPERATEUR || VAL_OP!=EOF); - FREE_LEX(lex); - fclose(f_syn); - return gblerr; -} - -/* Fonction de libération des structures contenues dans un arbre. */ -void free_arbre(type_noeud * courant) -{ - type_noeud * fils_courant; - - if (courant==NULL) return; - fils_courant=courant->ptr_fils; - while (fils_courant!=NULL) - { /* On efface récursivement tous les sous arbres. */ - free_arbre(fils_courant); - fils_courant=fils_courant->ptr_frere; - } - /* On efface le champ valeur des lexèmes ALPHA. */ - if (TYPE_IS(&(courant->lexeme), ALPHA) && LIT_MPV(courant->lexeme.type) - && (courant->lexeme.valeur.alpha!=NULL)) - free(courant->lexeme.valeur.alpha); - FREE_NOEUD(courant); -} - -/* Fonction de libération des structures crées par init_arbre. */ -void clear_preparateur() -{ - free_arbre(root); - root=NULL; /* root a été libéré par la fonction free_arbre. */ - REINIT; -} - Index: trunk/gasm/src/adaptateur.c =================================================================== --- trunk/gasm/src/adaptateur.c (revision 13) +++ trunk/gasm/src/adaptateur.c (nonexistent) @@ -1,795 +0,0 @@ -/* Module adaptateur */ -#include "adaptateur.h" - -/* Autres modules du projet utilisés. */ -#include -#include -#include -#include -#include - -/* Autres modules de la bibliothèque standard. */ -#include -#include - - -/*********************************************************************************************/ -/* */ -/* POINT D'ENTRÉE PRINCIPAL DU MODULE : RETOURNE LES POINTEURS VERS LES FGM. */ -/* */ -/*********************************************************************************************/ - -/* Type utilisé pour enregistrer les paires fonction, pointeur. */ -typedef struct -{ - char * nom; - type_mask *(*fun)(); -} type_paire_fonction; - -/* Variable contenant les paires nom de fonction , pointeur. */ -extern type_paire_fonction index_nf[]; - -/* Cette fonction retourne le pointeur sur la fonction correspondant au nom. */ -type_mask *(*alias(char * nom_fonction))() -{ - type_paire_fonction * courant; - - for (courant=index_nf ; courant->nom!=NULL ; courant++) - if (!strcasecmp(courant->nom, nom_fonction)) return courant->fun; - return NULL; -} - -/* Fonctions de l'adaptateur utiles pour la "fermeture" de adaptateur. */ -void fprint_lablist(FILE * flux); /* fonction d'écriture de la liste des labels. */ -void clear_lablist(); /* fonction de nettoyage de la liste des labels. */ - -/* Cette fonction sera appelée à la fin de la synthèse du code assembleur. */ -/* Elle peut écrire dans la liste d'asemblage. */ -void write_data(FILE * f_lst) -{ /* Attention, le flux peut être NULL. */ - if (f_lst!=NULL) fprint_lablist(f_lst); -} - -/* Cette fonction doit libérer les variables allouées dynamiquement par l'adaptateur. */ -void clear_adaptateur() -{ - clear_lablist(); -} - -/* Drapeau pour le résultat de l'évaluation d'une fonction génératrice de masque. */ -/* Ce drapeau peut prendre trois valeur selon le résultat de l'évaluation : */ -/* EVAL_REUSSIE : l'évaluation a aboutit. */ -/* EVAL_IMPOSSIBLE : l'évaluation n'est pas possible dans les conditions actuelles. */ -/* EVAL_ERREUR : la fonction n'est pas applicable dans ce contexte. */ -/* En plus de positionner ce drapeau, les fgm doivent spécifier le code de l'erreur dans la */ -/* variable err_code du module erreur. */ -int eval_code; - - -/*********************************************************************************************/ -/* */ -/* FONCTIONS AUXILLIAIRES SPÉCIFIQUES A LA SYNTAXE. */ -/* */ -/*********************************************************************************************/ - -/* Définition des sous-types spécifiés dans le fichier Syntaxe. */ -#define REG (CODE_TYPE(1)) - -/* Macro de comparaison de chaine sensible ou non à la casse. */ -#define compare_chaine(c1, c2) (casse_sens ? strcmp(c1,c2):strcasecmp(c1,c2)) - -/* Définition de la liste des étiquettes. */ -typedef struct tmp_file_lbl -{ - char * label; - int valeur; - struct tmp_file_lbl * suivant; -} type_file_lbl; - -/* Initialisation de la liste des étiquettes. */ -type_file_lbl * label=NULL; - -/* Retourne le nième élément de la liste des arguments ou NULL s'il n'existe pas. */ -type_lexeme * argn(type_file_lexeme * args, int n) -{ - if (n<0) return NULL; - while (args!=NULL) - { - if (n==0) return args->lexeme; - args = args->suivant; - n--; - } - return NULL; -} - -/* Cette fonction ajoute l'étiquette dans la liste. */ -/* Si l'étiquette existe déjà, l'ajout est impossible et le code 0 est retourné. */ -/* En cas de succès, la fonction renvoie 1. */ -int add_label(char * nom) -{ - type_file_lbl * nlbl; - type_file_lbl * courant; - - /* On vérifie que l'étiquette n'est pas déjà présente dans la liste. */ - for (courant = label ; courant!=NULL ; courant=courant->suivant) - if (!compare_chaine(courant->label, nom)) return 0; - - /* Allocation d'un nouveau maillon pour enregistrer la nouvellle étiquette. */ - nlbl = (type_file_lbl *) malloc(sizeof(type_file_lbl)); - if (nlbl==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); - (nlbl->label) = (char *) malloc(strlen(nom)*sizeof(char)); - if (nlbl->label==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); - /* Ajout de l'étiquette à la pile d'étiquettes. */ - strcpy(nlbl->label, nom); - nlbl->suivant=label; - nlbl->valeur=pco; - label=nlbl; - return 1; -} - -/* Fonction de recherche d'une étiquette dans la liste. */ -/* Si l'étiquette n'existe pas, le code -1 est retourné, sinon on renvoie sa valeur. */ -int find_address_label(char * nom) -{ - type_file_lbl * courant=label; - while (courant!=NULL) - { - if (!compare_chaine(courant->label, nom)) - return courant->valeur; - courant = courant->suivant; - } - return -1; -} - -/* Fonction d'écriture de la liste des étiquettes dans un flux. */ -void fprint_lablist(FILE * flux) -{ - type_file_lbl * courant; - if (flux==NULL) DIALOGUE("adaptateur(fprint_lablist)", 0, F_FLUX_NULL); - err_code=B_TABLAB; - fprintf(flux, "%s\n", search_msg()); - for (courant=label ; courant!=NULL ; courant=courant->suivant) - fprintf(flux, "%s\t%04X\n", courant->label, courant->valeur); -} - -/* Fonction de nettoyage de la liste des étiquettes. */ -void clear_lablist() -{ - type_file_lbl * courant=label; - while (courant!=NULL) - { - type_file_lbl * tmp=courant; - courant=courant->suivant; - free(tmp->label); - free(tmp); - } -} - -/* Fonctions de recodage des entiers sur un nombre quelconque de bits. */ - -/* Entiers signés. */ -/* La valeur signée est prise dans l'entier r et le masque généré retourné. */ -/* n spécifie le nombre de bits à utiliser pour coder l'entier. */ -/* En cas de dépassement de la capacité sur n bits signés, le err_code est positionné. */ -type_valeur_mask code_signed(int r, int n) -{ - long int max_taille=0; - int i; - - /* Crée un masque contenant n-1 1 : 0..01..1 */ - for (i=0; imax_taille) - { - err_code=S_SIGNED_TL; - return 0; - } - max_taille=(max_taille<<1)+1; /* On inclut le bit de signe dans le masque */ - r&=max_taille; /* On tronque le nombre. */ - err_code=NO_ERR; - return (type_valeur_mask) r; -} - -/* Entiers non signés. */ -/* La valeur signée est prise dans l'entier r et le masque généré retourné. */ -/* n spécifie le nombre de bits à utiliser pour coder l'entier. */ -/* En cas de dépassement de la capacité sur n bits non signés, le err_code est positionné. */ -type_valeur_mask code_unsigned(unsigned int r, int n) -{ - long unsigned int max_taille=0; - int i; - - /* Crée un masque contenant n 1 : 0..01..1 */ - for (i=0; imax_taille) - { - err_code=S_UNSIGNED_TL; - return 0; - } - r&=max_taille; /* On tronque. */ - err_code=NO_ERR; - return (type_valeur_mask) r; -} - - -/* Cette fonction crée un masque avec les 5 bits codant l'argument i (numéro de registre) */ -/* et les positionne à la position j dans le masque de taille tmo. */ -type_mask * rij(type_file_lexeme * args, int i, int j, type_taille_mask tmo) -{ - type_lexeme * l; - type_mask * res; - type_valeur_mask msk; - - l=argn(args, i); - /* test de la cohérence du type de l'opérande */ - if (l==NULL || !TYPE_IS(l, ALPHA) || !SOUS_TYPE_IS(l, REG) || !LIT_MPV(l->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - msk = l->valeur.alpha[1]-'0'; - if (strlen(l->valeur.alpha)==3) - { - msk*=10; - msk+=l->valeur.alpha[2]-'0'; - } - msk<<=j; - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(rij)",0, F_ERR_MEM); - res->valeur=msk; - res->taille=tmo; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -/* Cette fonction crée un masque avec les 5 bits codant l'argument i (valeur immédiate) */ -/* et les positionne à la position 6 dans le masque de taille tmo. */ -type_mask * shamt(type_file_lexeme * args, int i) -{ - type_lexeme * l; - type_mask * res; - type_valeur_mask v; - - l=argn(args, i); - /* test de la cohérence du type de l'opérande */ - if (l==NULL || !TYPE_IS(l, NUM) || !LIT_MPV(l->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - v=code_unsigned(l->valeur.num, 5); - - if (err_code!=NO_ERR) - { - eval_code=EVAL_ERREUR; - return NULL; - } - - v<<=6; - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(shamt)",0, F_ERR_MEM); - res->valeur=v; - res->taille=4; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -/*********************************************************************************************/ -/* */ -/* DEFINITION DES FONCTIONS GENERATIRCES DE MASQUE ET EXPORTATION DES POINTEURS. */ -/* */ -/*********************************************************************************************/ - -/* Fonctions de codage des numéros de registre dans différentes conditions. */ -/* err_code est positionné par la fonction rij. */ -type_mask * r1s(type_file_lexeme * args) -{ return rij(args, 1, 21, 4); } -type_mask * r3s(type_file_lexeme * args) -{ return rij(args, 3, 21, 4); } -type_mask * r5s(type_file_lexeme * args) -{ return rij(args, 5, 21, 4); } -type_mask * r1t(type_file_lexeme * args) -{ return rij(args, 1, 16, 4); } -type_mask * r3t(type_file_lexeme * args) -{ return rij(args, 3, 16, 4); } -type_mask * r5t(type_file_lexeme * args) -{ return rij(args, 5, 16, 4); } -type_mask * r1d(type_file_lexeme * args) -{ return rij(args, 1, 11, 4); } -type_mask * r3d(type_file_lexeme * args) -{ return rij(args, 3, 11, 4); } -type_mask * r5d(type_file_lexeme * args) -{ return rij(args, 5, 11, 4); } - -/* Codage du shift amount lu à la position 5 de la liste d'args */ -type_mask * sa5(type_file_lexeme * args) -{ return shamt(args, 5); } - -/* Fonction d'ajout d'une étiquette dans la table (déclaration). */ -type_mask * ajoute_etiquette(type_file_lexeme * args) -{ - type_lexeme * lex=argn(args, 0); - /* Si le lexème n'est pas un ALPHA ou s'il n'a pas de valeur. */ - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { /* Argument incorrect. */ - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - if (!add_label(lex->valeur.alpha)) - { /* L'étiquette existe déjà dans la liste. Impossible de l'ajouter. */ - err_code=S_REDEF_ETIQ; - eval_code=EVAL_ERREUR; - return NULL; - } - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return NULL; -} - - -/* Fonction de création d'un masque de zéros pour atteindre un adresse congrue à 4. */ -type_mask * complete_zeros(type_file_lexeme * args) -{ - type_mask * res; - int n=pco%4; - /* Calcule le nombre de zéros manquants pour s'aligner sur une adresse congrue à 4. */ - if (n==0) n=4; - n=4-n; - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(complete_zeros)", 0, F_ERR_MEM); - res->taille=n; - res->valeur=0; - - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - - -type_mask * org_int(type_file_lexeme * args) -{ - type_lexeme * p; - - p=argn(args, 1); - if (p==NULL || !TYPE_IS(p, NUM)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - pco=p->valeur.num; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return NULL; -} - - -type_mask * org_label(type_file_lexeme * args) -{ - type_lexeme * p; - int adr; - - p=argn(args, 1); - if (p==NULL || !TYPE_IS(p, ALPHA)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - adr=find_address_label(p->valeur.alpha); - - if (adr==-1) - { /* Tentative d'implantation à une adresse inconnue. */ - err_code=S_ADR_INCONNUE; - eval_code=EVAL_ERREUR; - return NULL; - } - - pco=adr; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return NULL; -} - - -type_mask * add_equ(type_file_lexeme * args) -{ - FILE * f; - type_lexeme * p1, * p2; - - p1=argn(args, 0); - p2=argn(args, 2); - if (p1==NULL || p2==NULL || !TYPE_IS(p1, ALPHA) - || (!TYPE_IS(p2, ALPHA) && !TYPE_IS(p2, NUM))) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - f=tmpfile(); - if (f==NULL) DIALOGUE("adaptateur(add_equ)",0, F_FLUX_NULL); - - if (TYPE_IS(p2, ALPHA)) - { - fprintf(f, " {} {} { %s } ", p2->valeur.alpha); - } - else - { - fprintf(f, " {} {} { %d } ", p2->valeur.num); - } - - rewind(f); - ajoute_macro(p1->valeur.alpha, f); - fclose(f); - - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return NULL; -} - -/* Codage de l'entier de rang i dans la liste d'arguments dans les 16 bits de poids faible. */ -type_mask * immediate16(type_file_lexeme * args, int i) -{ - type_lexeme * lex; - type_mask * res; - type_valeur_mask v; - - lex=argn(args, i); - - if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - if (lex->valeur.num<0) v=code_signed(lex->valeur.num, 16); - else v=code_unsigned(lex->valeur.num, 16); - - if (err_code!=NO_ERR) - { - eval_code=EVAL_ERREUR; - return NULL; - } - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(cimm)", 0, F_ERR_MEM); - res->taille=4; - res->valeur=v; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -/* Acquisistion de la valeur immediate de l'instruction */ -type_mask * imm1(type_file_lexeme * args) -{ return immediate16(args, 1); } -type_mask * imm3(type_file_lexeme * args) -{ return immediate16(args, 3); } -type_mask * imm5(type_file_lexeme * args) -{ return immediate16(args, 5); } - -/* retourne le masque contenant la valeur val sur n octets. */ -type_mask * dc(int val, int n) -{ - type_mask * res; - type_valeur_mask v; - - if (val<0) v=code_signed(val, n*8); - else v=code_unsigned(val, n*8); - - if (err_code!=NO_ERR) - { - eval_code=EVAL_ERREUR; - return NULL; - } - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(dcb)", 0, F_ERR_MEM); - res->taille=n; - res->valeur=v; - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -/* Retourne le masque pour un entier sur 8 bits en premier argument (numérique) */ -type_mask * dcb_int(type_file_lexeme * args) -{ - type_lexeme * lex; - - lex=argn(args, 1); - if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - return dc(lex->valeur.num, 1); -} - -/* Retourne le masque pour un entier sur 8 bits en premier argument (étiquette) */ -type_mask * dcb_alpha(type_file_lexeme * args) -{ - type_lexeme * lex; - int adr; /* Adresse correspondant à l'étiquette. */ - - lex=argn(args, 1); - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - adr = find_address_label(lex->valeur.alpha); - - if (adr==-1) - { - err_code=S_BAD_ETIQ; - eval_code=EVAL_IMPOSSIBLE; - return NULL; - } - - return dc(adr, 1); -} - - -/* Retourne le masque pour un entier sur 32 bits en premier argument (numérique) */ -type_mask * dcw_int(type_file_lexeme * args) -{ - type_lexeme * lex; - - lex=argn(args, 1); - if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - return dc(lex->valeur.num, 4); -} - -/* Retourne le masque pour un entier sur 32 bits en premier argument (étiquette) */ -type_mask * dcw_alpha(type_file_lexeme * args) -{ - type_lexeme * lex; - int adr; /* Adresse correspondant à l'étiquette. */ - - lex=argn(args, 1); - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - adr = find_address_label(lex->valeur.alpha); - - if (adr==-1) - { - err_code=S_BAD_ETIQ; - eval_code=EVAL_IMPOSSIBLE; - return NULL; - } - - return dc(adr, 4); -} - -/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible - * contiennent l'offset signé tenant sur 18 bits correspondant au lexème étiquette de rang i - * dans la liste de paramètres mais donc les 2 bits de poids faible ont été tronqués. */ -type_mask * offset(type_file_lexeme * args, int i) -{ - type_valeur_mask valres; - int diff; - type_mask * res; - type_lexeme * lex; - - lex = argn(args, i); - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - diff=find_address_label(lex->valeur.alpha); - if (diff==-1) - { - err_code=S_BAD_ETIQ; - eval_code=EVAL_IMPOSSIBLE; - return NULL; - } - diff=diff-(pco); /* Le PCO ne tient pas encore compte des 4 octets du masque */ - if (diff & 3) /* Vérif que l'étiquette est bien aligné sur 32 bits */ - { - err_code=S_BAD_ALIGN; - eval_code=EVAL_ERREUR; - return NULL; - } - - valres=code_signed(diff>>2, 16); - if (err_code!=NO_ERR) /* Si le déplacement est sur plus de 16 bits... */ - { - eval_code=EVAL_ERREUR; - return NULL; - } - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); - res->taille=4; - res->valeur=valres; - - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -type_mask * offset3(type_file_lexeme * args) -{ return offset(args, 3); } -type_mask * offset5(type_file_lexeme * args) -{ return offset(args, 5); } - -/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible - * contiennent la valeur signée tenant sur 16 bits correspondant au lexème étiquette de rang i - * dans la liste de paramètres. */ -type_mask * val_etiq(type_file_lexeme * args, int i) -{ - type_valeur_mask valres; - int diff; - type_mask * res; - type_lexeme * lex; - - lex = argn(args, i); - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - diff=find_address_label(lex->valeur.alpha); - if (diff==-1) - { - err_code=S_BAD_ETIQ; - eval_code=EVAL_IMPOSSIBLE; - return NULL; - } - - valres=code_unsigned(diff, 16); - if (err_code!=NO_ERR) /* Si le déplacement est sur plus de 16 bits... */ - { - eval_code=EVAL_ERREUR; - return NULL; - } - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); - res->taille=4; - res->valeur=valres; - - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -type_mask * val_etiq3(type_file_lexeme * args) -{ return val_etiq(args, 3); } -type_mask * val_etiq5(type_file_lexeme * args) -{ return val_etiq(args, 5); } - -/* Fonction de création d'un masque de 32 bits dont les 26 bits de poids faible - * contiennent l'adresse dans la région courante de 256 Mo tenant sur 28 bits correspondant - * au lexème étiquette de rang i dans la liste de paramètres mais donc les 2 bits de poids - * faible ont été tronqués. */ -type_mask * absolu(type_file_lexeme * args, int i) -{ - type_valeur_mask valres; - int diff; - type_mask * res; - type_lexeme * lex; - - lex = argn(args, i); - if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) - { - err_code=S_ARG_INCOMP; - eval_code=EVAL_ERREUR; - return NULL; - } - - diff=find_address_label(lex->valeur.alpha); - if (diff==-1) - { - err_code=S_BAD_ETIQ; - eval_code=EVAL_IMPOSSIBLE; - return NULL; - } - if ((pco >> 26) != (diff >> 26)) /* Test que le saut ne change pas de région */ - { - err_code=S_TOO_FAR; - eval_code=EVAL_ERREUR; - return NULL; - } - diff=diff & 0xFFFFFFF; /* On ne conserve que les 28 bits de poids faible */ - if (diff & 3) /* Vérif que l'étiquette est bien aligné sur 32 bits */ - { - err_code=S_BAD_ALIGN; - eval_code=EVAL_ERREUR; - return NULL; - } - valres=code_signed(diff>>2, 26); /* L'offset est codé sur 26 bits */ - if (err_code!=NO_ERR) - { - eval_code=EVAL_ERREUR; - return NULL; - } - - ALLOC_MASK(res); - if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); - res->taille=4; - res->valeur=valres; - - err_code=NO_ERR; - eval_code=EVAL_REUSSIE; - return res; -} - -type_mask * absolu1(type_file_lexeme * args) -{ return absolu(args, 1); } - -/*********************************************************************************************/ -/* Définition du tableau des correspondances entre nom et fonction de génération de masque. */ -/*********************************************************************************************/ - -type_paire_fonction index_nf[] = - { {"R1S" , &r1s } /* Codage des opérandes */ - , {"R3S" , &r3s } - , {"R5S" , &r5s } - , {"R1T" , &r1t } - , {"R3T" , &r3t } - , {"R5T" , &r5t } - , {"R1D" , &r1d } - , {"R3D" , &r3d } - , {"R5D" , &r5d } - , {"IMM1" , &imm1 } - , {"IMM3" , &imm3 } - , {"IMM5" , &imm5 } - , {"ETIQ3" , &val_etiq3 } - , {"ETIQ5" , &val_etiq5 } - , {"SA5" , &sa5 } - - , {"OFFSET3" , &offset3 } /* Création des masques d'adresse */ - , {"OFFSET5" , &offset5 } - , {"ABSOLU1" , &absolu1 } - - , {"Ajoute_Etiquette" , &ajoute_etiquette } /* Ajoute éiquette */ - - , {"Complete_Zeros" , &complete_zeros } /* Gestion des directives */ - , {"AddEqu" , &add_equ } - , {"Dcb_Int" , &dcb_int } - , {"Dcb_Alpha" , &dcb_alpha } - , {"Dcw_Int" , &dcw_int } - , {"Dcw_Alpha" , &dcw_alpha } - , {"Org_Int" , &org_int } - , {"Org_Label" , &org_label } - - , {NULL , NULL } - }; - Index: trunk/gasm/readme.txt =================================================================== --- trunk/gasm/readme.txt (revision 13) +++ trunk/gasm/readme.txt (nonexistent) @@ -1,2 +0,0 @@ -1 - To generate the asmips assemblee, run make -2 - The files Syntaxe and psd_instr.sx must be in the same repository than your assemblee code Index: trunk/gasm/Syntaxe =================================================================== --- trunk/gasm/Syntaxe (revision 13) +++ trunk/gasm/Syntaxe (nonexistent) @@ -1,522 +0,0 @@ -; This file is part of gasm. -; -; -; If you encountered any problem, please contact : -; -; lmouton@enserg.fr -; shangoue@enserg.fr -; - - - -;===============================================================================; -; ; -; ; -; Fichier de donnees sur la syntaxe de l'assembleur du microprocesseur miniMIPS ; -; ; -; ; -;===============================================================================; - -; Les instructions SET s'adressant au preparateur doivent se trouver avant la première accolade. - - -SET MACROFILE psd_instr.sx ; Fichier macro par défaut (pseudo instructions). -SET NOCASSE ; L'assembleur MIPS n'est pas sensible à la casse - -SET DEFINESTR D ; Chaine de définition de macro -SET UNDEFSTR U ; Chaine de supression de macro - -; Il est également possible d'activer l'inclusion de fichier mais dans ce cas la liste -; d'assemblage sera interdite... -; SET INCLUDESTR I ; Chaine d'inclusion de fichier - -; Définition du séparateur d'instructions (ici, NL) -; Le séparateur est utilisé lors de la détection d'une erreur par l'analyseur pour déterminer -; à partir de quel endroit poursuivre l'assemblage. Il effectue la recherche du prochain séparateur -; puis se place juste après et continue l'analyse. -SET SEP - -; Définition des sous-types que l'on utilise dans la syntaxe de l'assembleur. -; Le nombre de sous-types pouvant actuellement être référencés est de 16. -SET NUMSST 3 ; Déclaration de deux sous types du type ALPHA - -; Le troisième champ correspond au code du sous-type. Si plusieurs sont identiques, -; ils seront confondus par l'assembleur. On peut utiliser cette propriété pour -; définir plusieurs motifs définissant le même type. -; Codage des registres R0 à R31 (la notation R02 est autorisée) : -SET NEWSST Reg $?09 1 -SET NEWSST Reg $?02?09 1 -SET NEWSST Reg $3?01 1 - -; Mots clefs autorisées dans la déclaration de la syntaxe d'une instruction : Int, Alpha, Reg -; Mots clefs autorisés dans les propriétés de l'instruction : TMO, MSK, FUN -; Les masques doivent commencer par - et peuvent contenir - le caractère '_' - -; Autorise les lignes vides -{ -} - -; Déclaration d'étiquette -{ Alpha: } - FUN Ajoute_Etiquette ; Ajoute une étiquette dans la table - -; DÉFINITION DES DIRECTIVES - -; Directives de définition des équivalences -{ Alpha EQU Alpha } - FUN AddEqu - -{ Alpha EQU Int } - FUN AddEqu - -; Directive d'alignement sur adresse congrue à 4 -{ ALIGN4 } - FUN Complete_zeros - -; Directives d'inclusion de données dans le code -{ DCB Int } - TMO 1 - MSK _0000_0000_ - FUN Dcb_Int -{ DCB Alpha } - TMO 1 - MSK _0000_0000_ - FUN Dcb_Alpha -{ DCW Int } - TMO 4 - MSK _0000_0000_0000_0000__0000_0000_0000_0000_ - FUN Dcw_Int -{ DCW Alpha } - TMO 2 - MSK _0000_0000_0000_0000__0000_0000_0000_0000_ - FUN Dcw_Alpha - -; Directives de positionnement de l'adresse d'implantation -{ ORG Int } - FUN Org_Int - -{ ORG Alpha } - FUN Org_Label - -; DEFINITION DES INSTRUCTIONS - -; Instruction ADD -{ ADD Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100000 - FUN R1D - FUN R3S - FUN R5T - -; Instruction ADDI -{ ADDI Reg, Reg, Int } - TMO 4 - MSK _001000_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ ADDI Reg, Reg, Alpha } - TMO 4 - MSK _001000_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 - -; Instruction ADDIU -{ ADDIU Reg, Reg, Int } - TMO 4 - MSK _001001_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 - -; Instruction ADDU -{ ADDU Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100001 - FUN R1D - FUN R3S - FUN R5T - -; Instruction AND -{ AND Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100100 - FUN R1D - FUN R3S - FUN R5T - -; Instruction ANDI -{ ANDI Reg, Reg, Int } - TMO 4 - MSK _001100_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ ANDI Reg, Reg, Alpha } - TMO 4 - MSK _001100_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 - -; Instruction BEQ -{ BEQ Reg, Reg, Alpha } - TMO 4 - MSK _000100_00000_00000__0000_0000_0000_0000 - FUN R1S - FUN R3T - FUN OFFSET5 - -; Instruction BGEZ -{ BGEZ Reg, Alpha } - TMO 4 - MSK _000001_00000_00001__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BGEZAL -{ BGEZAL Reg, Alpha } - TMO 4 - MSK _000001_00000_10001__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BGTZ -{ BGTZ Reg, Alpha } - TMO 4 - MSK _000111_00000_00000__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BLEZ -{ BLEZ Reg, Alpha } - TMO 4 - MSK _000110_00000_00000__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BLTZ -{ BLTZ Reg, Alpha } - TMO 4 - MSK _000001_00000_00000__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BLTZAL -{ BLTZAL Reg, Alpha } - TMO 4 - MSK _000001_00000_10000__00000000_00000000 - FUN R1S - FUN OFFSET3 - -; Instruction BNE -{ BNE Reg, Reg, Alpha } - TMO 4 - MSK _000101_00000_00000__00000000_00000000 - FUN R1S - FUN R3T - FUN OFFSET5 - -; Instruction BREAK -{ BREAK } - TMO 4 - MSK _000000__00000_00000_00000_00000__001101 - -; Instruction COP0 -{ COP0 Int } - TMO 4 - MSK _010000_00001_00000_0000_0000_0000_0000 - FUN IMM1 - -; Instruction J -{ J Alpha } - TMO 4 - MSK _000010__00_0000_0000_0000_0000_0000_0000 - FUN ABSOLU1 - -; Instruction JAL -{ JAL Alpha } - TMO 4 - MSK _000011__00_0000_0000_0000_0000_0000_0000 - FUN ABSOLU1 - -; Instruction JALR -{ JAL Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_001001 - FUN R1D - FUN R3S - -; Instruction JALR avec rd=$31 implicite -{ JAL Reg } - TMO 4 - MSK _000000_00000_00000_11111_00000_001001 - FUN R1S - -; Instruction JR -{ JR Reg } - TMO 4 - MSK _000000_00000__000_0000_0000_0000__001000 - FUN R1S - -; Instruction LUI -{ LUI Reg, Int } - TMO 4 - MSK _001111_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN IMM3 -{ LUI Reg, Alpha } - TMO 4 - MSK _001111_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN ETIQ3 - -; Instruction LW -{ LW Reg, Int(Reg) } - TMO 4 - MSK _100011_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN IMM3 - FUN R5S - -; Instruction LWC0 -{ LWC0 Reg, Int(Reg) } - TMO 4 - MSK _110000_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN IMM3 - FUN R5S - -; Instruction MFC0 -{ MFC0 Reg, Reg } - TMO 4 - MSK _010000_00000_00000_00000__000000_00000 - FUN R1D - FUN R3T - -; Instruction MFHI -{ MFHI Reg } - TMO 4 - MSK _000000_0000000000_00000_00000_010000 - FUN R1D - -; Instruction MFLO -{ MFLO Reg } - TMO 4 - MSK _000000_0000000000_00000_00000_010010 - FUN R1D - -; Instruction MTC0 -{ MTC0 Reg, Reg } - TMO 4 - MSK _010000_00100_00000_00000__000000_00000 - FUN R1T - FUN R3D - -; Instruction MTHI -{ MTHI Reg } - TMO 4 - MSK _000000_00000__0_0000_0000_0000_00__010001 - FUN R1S - -; Instruction MTLO -{ MTLO Reg } - TMO 4 - MSK _000000_00000__0_0000_0000_0000_00__010011 - FUN R1S - -; Instruction MULT -{ MULT Reg, Reg } - TMO 4 - MSK _000000_00000_00000__0000_0000_00__011000 - FUN R1S - FUN R3T - -; Instruction MULTU -{ MULTU Reg, Reg } - TMO 4 - MSK _000000_00000_00000__0000_0000_00__011001 - FUN R1S - FUN R3T - -; Instruction NOR -{ NOR Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100111 - FUN R1D - FUN R3S - FUN R5T - -; Instruction OR -{ OR Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100101 - FUN R1D - FUN R3S - FUN R5T - -; Instruction ORI -{ ORI Reg, Reg, Int } - TMO 4 - MSK _001101_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ ORI Reg, Reg, Alpha } - TMO 4 - MSK _001101_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 - -; Instruction SLL -{ SLL Reg, Reg, Int } - TMO 4 - MSK _000000_00000_00000_00000_00000_000000 - FUN R1D - FUN R3T - FUN SA5 - -; Instruction SLLV -{ SLLV Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_000100 - FUN R1D - FUN R3T - FUN R5S - -; Instruction SLT -{ SLT Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_101010 - FUN R1D - FUN R3S - FUN R5T - -; Instruction SLTI -{ SLTI Reg, Reg, Int } - TMO 4 - MSK _001010_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ SLTI Reg, Reg, Alpha } - TMO 4 - MSK _001010_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 - -; Instruction SLTIU -{ SLTIU Reg, Reg, Int } - TMO 4 - MSK _001010_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ SLTIU Reg, Reg, Alpha } - TMO 4 - MSK _001010_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 - -; Instruction SLTU -{ SLTU Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_101011 - FUN R1D - FUN R3S - FUN R5T - -; Instruction SRA -{ SRA Reg, Reg, Int } - TMO 4 - MSK _000000_00000_00000_00000_00000_000011 - FUN R1D - FUN R3T - FUN SA5 - -; Instruction SRAV -{ SRAV Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_000111 - FUN R1D - FUN R3T - FUN R5S - -; Instruction SRL -{ SRL Reg, Reg, Int } - TMO 4 - MSK _000000_00000_00000_00000_00000_000010 - FUN R1D - FUN R3T - FUN SA5 - -; Instruction SRLV -{ SRLV Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_000110 - FUN R1D - FUN R3T - FUN R5S - -; Instruction SUB -{ SUB Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100010 - FUN R1D - FUN R3S - FUN R5T - -; Instruction SUBU -{ SUBU Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100011 - FUN R1D - FUN R3S - FUN R5T - -; Instruction SW -{ SW Reg, Int(Reg) } - TMO 4 - MSK _101011_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN IMM3 - FUN R5S - -; Instruction SWC0 -{ SWC0 Reg, Int(Reg) } - TMO 4 - MSK _111000_00000_00000__0000_0000_0000_0000 - FUN R1T - FUN IMM3 - FUN R5S - -; Instruction SYSCALL -{ SYSCALL } - TMO 4 - MSK _000000__00000_00000_00000_00000__001100 - -; Instruction XOR -{ XOR Reg, Reg, Reg } - TMO 4 - MSK _000000_00000_00000_00000_00000_100110 - FUN R1D - FUN R3S - FUN R5T - -; Instruction XORI -{ XORI Reg, Reg, Int } - TMO 4 - MSK _001110_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN IMM5 -{ XORI Reg, Reg, Alpha } - TMO 4 - MSK _001110_00000_00000__00000000_00000000 - FUN R1T - FUN R3S - FUN ETIQ5 Index: trunk/gasm/Makefile =================================================================== --- trunk/gasm/Makefile (revision 13) +++ trunk/gasm/Makefile (nonexistent) @@ -1,75 +0,0 @@ -# This file is part of gasm. -# -# -# If you encountered any problem, please contact : -# -# lmouton@enserg.fr -# shangoue@enserg.fr -# - - -# Makefile de type compilation du projet -# -# Cibles possibles : -# -# project, all, asmica Compile l'assembleur avec main.c et tous les modules en les recompilant au besoin -# info Informe sur l'état d'avancement du projet -# nom_module Recompile le module indiqué -# menage Fait le menage des fichiers generes -# exec Executer le programme -# save[fichier_tar] Archivage du projet dans sav/ - -COMP_OPT = -I$(INCLUDE_PATH) -O2 -Wall -ansi -pipe -s - -# Repertoires du projet -# SOUS_REP est défini dans le Makefile appelant -LIB_PATH = lib -INCLUDE_PATH = include -SRC_PATH = src - -# inclusion de la définition des dépendances -include Makefile.dep - -VPATH = $(LIB_PATH) : $(INCLUDE_PATH) : $(SRC_PATH) - -# modules du projet dans l'ordre des dépandances -MODS_OBJ = $(addsuffix .o, $(strip $(ALL))) -MODS_SRC = $(addsuffix .c, $(strip $(ALL))) - -# Compilateur utilisé et options de compilation d'édition de liens -CC = gcc -LINK_OPT = - -.SILENT : menage exec $(MODS_OBJ) info -.PHONY : all project exec menage - -all project : asmips - -asmips : main.c $(MODS_OBJ) - $(CC) $(COMP_OPT) $(LINK_OPT) $< $(addprefix $(LIB_PATH)/, $(MODS_OBJ)) -o $@ - -$(MODS_OBJ) : %.o : %.c $(addsuffix .h, $(%_DEP)) - @echo Compilation du module $* - $(CC) $(COMP_OPT) -o $(LIB_PATH)/$*.o -c $< - -menage : - @echo Menage des fichiers principaux du projet - rm -f *.o - rm -f core.* - rm -f *~ - rm -f asmips - rm -f a.obj a.lst - rm -f $(LIB_PATH)/*.o - -exec : - $(MAKE) -s project - clear - ./asmips - -save[%] : - @tar -jvcf ../sav/$*.tbz2 * - -info : - @echo Modules installés : - ls $(LIB_PATH) - Index: trunk/gasm/psd_instr.sx =================================================================== --- trunk/gasm/psd_instr.sx (revision 13) +++ trunk/gasm/psd_instr.sx (nonexistent) @@ -1,110 +0,0 @@ -; This file is part of gasm. -; -; -; If you encountered any problem, please contact : -; -; lmouton@enserg.fr -; shangoue@enserg.fr -; - - -; Ce fichier contient les d‰finitions des macros du langage. -; Il s'agit des pseudo-instructions ainsi que des ‰quivalences de base. - -; Il est € noter que les instructions ‰ventuelles ne seront pas trait‰es -; seules les directives de pr‰processeur sont prises en compte. - -;================================= Surnoms des registres ================================== - -#D $ZERO {} {} { $0 } - -#D $AT {} {} { $1 } - -#D $V0 {} {} { $2 } -#D $V1 {} {} { $3 } - -#D $A0 {} {} { $4 } -#D $A1 {} {} { $5 } -#D $A2 {} {} { $6 } -#D $A3 {} {} { $7 } - -#D $T0 {} {} { $8 } -#D $T1 {} {} { $9 } -#D $T2 {} {} { $10 } -#D $T3 {} {} { $11 } -#D $T4 {} {} { $12 } -#D $T5 {} {} { $13 } -#D $T6 {} {} { $14 } -#D $T7 {} {} { $15 } - -#D $S1 {} {} { $16 } -#D $S2 {} {} { $17 } -#D $S3 {} {} { $18 } -#D $S4 {} {} { $19 } -#D $S5 {} {} { $20 } -#D $S6 {} {} { $21 } -#D $S7 {} {} { $22 } -#D $S8 {} {} { $23 } - -#D $T8 {} {} { $24 } -#D $T9 {} {} { $25 } - -#D $K0 {} {} { $26 } -#D $K1 {} {} { $27 } - -#D $GP {} {} { $28 } - -#D $SP {} {} { $29 } - -#D $FP {} {} { $30 } - -#D $RA {} {} { $31 } - -; Registres internes du coprocesseur systeme - -#D STATUS {} {} { $12 } -#D CAUSE {} {} { $13 } -#D EPC {} {} { $14 } -#D VECTIT {} {} { $15 } - - -;============= Fonctions du coprocesseur systeme pour l'instruction COP0 ================ - -#D MASK {} {} { 1 } -#D UNMASK {} {} { 2 } -#D ITRET {} {} { 4 } ; Retour d'interruption - - -;================================== Pseudo-instructions =================================== - -#D NOP {} {} { SLL $0, $0, 0 } - -#D BLT {r o a} {r, o, a} { SLT $1,r, o ;/ Justifie le registre at ($1) - BNE $1, $0, a } ;/ reserve par l'assembleur. - -#D MOVE { Rt Rs } {Rt, Rs} { ADDU Rt, $0, Rs} ;/ addition 'unsigned' avec zero -#D LI { Rt Int } {Rt, Int}{ ORI Rt, $ZERO, Int} ;/ Chargement de valeur immediate - -#D INC { R } { R } { ADDI R, R, 1 } -#D DEC { R } { R } { ADDI R, R, -1 } -#D INCW { R } { R } { ADDI R, R, 4 } -#D DECW { R } { R } { ADDI R, R, -4 } -#D STOP { etq } { etq } { etq: J etq } -#D RETURN {} {} { JR $31 } -#D RIT {} {} { COP0 ITRET } - -#D LOCK {} {} { LI $K0, @FFFF LW $ZERO, 0($K0) } ;/ plantage du processeur - -; Utilisation d'une pile - -#D INIT_SP { adresse } { adresse } { ADDI $SP, $0, adresse } -#D PUSH { reg } { reg } { DECW $SP SW reg, 0($SP) } -#D PULL { reg } { reg } { LW reg, 0($SP) INCW $SP } - -#D FOR { boucle reg max } - { reg from max downto 0 DO boucle } - { boucle: LI reg, max } -#D NEXT { reg boucle } - { reg, boucle } - { DEC reg BGEZ reg, boucle } - Index: trunk/gasm/include/formateur.h =================================================================== --- trunk/gasm/include/formateur.h (revision 13) +++ trunk/gasm/include/formateur.h (nonexistent) @@ -1,168 +0,0 @@ -#ifndef M_FORMATEUR_FLAG -#define M_FORMATEUR_FLAG - -/* Modules de la bibliotheque standard */ - -#include -#include - -/* Autres modules utilises */ - -#include - - -/*********************************************************************************************/ -/* COMPOSITION DES ENSEMBLES DE CARACTERES */ -/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ -/* sa lecture. */ -/*********************************************************************************************/ - -/* D‰finition d'un code pour chaque ensemble existant */ -#define NBR_ENS 6 /* Nombre d'ensembles existant. */ -enum {lettre, chiffre, prefixe, sep_explicite, sep_invisible, commentaire}; - -/* D‰finition de constantes pour la taille de chaque ensemble existant. */ -#define taille_lettre 56 -#define taille_chiffre 22 -#define taille_prefixe 6 -#define taille_sep_explicite 11 -#define taille_sep_invisible 3 -#define taille_commentaire 2 - -/* D‰claration du tableau regroupant tous ces ensembles. */ -extern int *ensemble[NBR_ENS]; - -/* D‰finition de constantes pour les valeurs des operateurs (S‰parateur explicites). */ -#define ACF '}' -#define ACO '{' -#define NL '\n' -#define DP ':' -#define PF ')' -#define PO '(' -#define PS '+' -#define MS '-' -#define DIR '#' -#define VIR ',' - -/*********************************************************************************************/ -/* DEFINITION DES LEXEMES */ -/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ -/*********************************************************************************************/ - -/* D‰claration des diff‰rents types de lexemes possibles. Ces valeurs rempliront le champ */ -/* type de la structure lexeme. */ -#define ALPHA 2 -#define NUM 4 -#define OP 8 - -/* Le type des lexˆmes sera cod‰ sur 8 bits donc 1 pour la pr‰sence de valeur, 3 pour les */ -/* trois types de base et 4 pour coder les 15 sous-types possibles. */ -typedef unsigned char type_type_lex; - -/* Definition du type lexeme. */ -/* le type int sera utilis‰ pour coder la valeur d'un lexˆme de type op‰rateur. */ -/* Comme celui-ci peut ‰ventuellement Štre EOF, on doit utiliser un type entier, mŠme si */ -/* dans tous les autres cas un char aurait suffit. */ -typedef struct -{ - type_type_lex type; - union - { - char * alpha; /* champ pour coder la valeur d'un ALPHA */ - int num; /* champ pour coder la valeur d'un NUM */ - int op; /* champ pour coder la valeur d'un op‰rateur */ - } valeur; -} type_lexeme; - -/*********************************************************************************************/ -/* MACROS DE TRAVAIL SUR LES LEXEMES */ -/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ -/*********************************************************************************************/ - -/* Le bit 1 du type sert a indiquer la presence d'une valeur. Pour le positionner, on */ -/* utilise le masque d‰fini ci-dessous. */ -#define MASK_PRESENCE_VALEUR 1 -/* Les trois macros suivantes permettent respectivement de positionner, de lire et de retire */ -/* le masque de pr‰sence de valeur € un type de lexˆme */ -#define POS_MPV(type) ((type) | MASK_PRESENCE_VALEUR) -#define LIT_MPV(type) ((type) & MASK_PRESENCE_VALEUR) -#define RET_MPV(type) ((type) & ~MASK_PRESENCE_VALEUR) -/* Macros de lecture du type de base et du sous-type. */ -#define BASE_TYPE(ptrlex) (((ptrlex)->type) & 0x0E) /* Masque par 00001110 */ -#define SOUS_TYPE(ptrlex) (((ptrlex)->type) & 0xF0) /* Masque par 11110000 */ -/* Ces macros v‰rifient si le type (ou sous type) de lexeme est bien tp (ou stp). */ -#define TYPE_IS(ptrlex, tp) (((ptrlex)->type) & tp) -#define SOUS_TYPE_IS(ptrlex, stp) (SOUS_TYPE(ptrlex)==((stp) & 0xF0)) -/* Cette macro prend le sous-type et g‰nˆre le code complet correspondant. */ -#define CODE_TYPE(sst) (ALPHA | ((sst)<<4)) - -/* Comme l'allocation de lexˆmes sera une op‰ration trˆs fr‰quente, on pourra utiliser les */ -/* macros suivantes pour simplifier le code. */ - -#define ALLOC_LEX(lex) {\ - lex=((type_lexeme *) malloc(sizeof(type_lexeme)));\ - } - -#define FREE_LEX(lex) {\ - if (TYPE_IS((lex), ALPHA) && LIT_MPV((lex)->type))\ - free(((lex)->valeur).alpha);\ - free(lex);\ - } - -/* MŠme si le type lexˆme n'a pas de limite pour son champ valeur.alpha, certaines fonctions */ -/* peuvent avoir besoin d'allouer une taille maximale pour celui-ci, notament par exemple */ -/* lors de la lecture dans un fichier du lexˆme. Dans tous les cas, le tableau vers lequel */ -/* pointera le champ du lexˆme sera ajust‰ € sa longueur. */ -#define MAX_LONG_ALPHA 128 - -/* Macro de recopie d'un lexˆme vers un autre. */ -#define LEX_COPY(ptrl1, ptrl2) \ -{\ - (ptrl2)->type = (ptrl1)->type;\ - if (LIT_MPV((ptrl1)->type)) switch BASE_TYPE(ptrl1)\ - {\ - case ALPHA :\ - (ptrl2)->valeur.alpha=malloc(strlen((ptrl1)->valeur.alpha));\ - strcpy((ptrl2)->valeur.alpha, (ptrl1)->valeur.alpha);\ - break;\ - case NUM :\ - (ptrl2)->valeur.num=(ptrl1)->valeur.num;\ - break;\ - case OP :\ - (ptrl2)->valeur.op=(ptrl1)->valeur.op;\ - break;\ - }\ - else (ptrl2)->valeur.alpha=NULL;\ -} - -/*********************************************************************************************/ -/* TYPES DERIVES DU TYPE LEXEME */ -/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ -/*********************************************************************************************/ - -/* D‰finition du type file de lexeme. */ -typedef struct file_lexeme_tmp -{ - struct file_lexeme_tmp * suivant ; - type_lexeme * lexeme ; -} type_file_lexeme ; - -/*********************************************************************************************/ -/* */ -/* EXPORTATION DES POINTS D'ENTRÐE DU MODULE */ -/* */ -/*********************************************************************************************/ - -int fprint_lexeme(FILE * f, type_lexeme * l); -type_lexeme * get_lexeme(FILE *); -int strcasecmp(char * s1, char * s2); -int id_lexeme(type_lexeme *, type_lexeme *, int casse); -int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse); - - -#define lexcaseid(l1, l2) id_lexeme(l1, l2, 0) -#define lexid(l1, l2) id_lexeme(l1, l2, 1) -#define lexcaseftr(l, filtre) filtre_lexeme(l1, filtre, 0) -#define lexftr(l, filtre) filtre_lexeme(l, filtre, 1) - -#endif Index: trunk/gasm/include/synthetiseur.h =================================================================== --- trunk/gasm/include/synthetiseur.h (revision 13) +++ trunk/gasm/include/synthetiseur.h (nonexistent) @@ -1,10 +0,0 @@ -#ifndef M_SYNTHETISEUR_FLAG -#define M_SYNTHETISEUR_FLAG - -#include - -int synthese(); -void write_objet(FILE * f_obj); -void write_liste(FILE * f_lst, FILE * f_src); - -#endif Index: trunk/gasm/include/dialogue.h =================================================================== --- trunk/gasm/include/dialogue.h (revision 13) +++ trunk/gasm/include/dialogue.h (nonexistent) @@ -1,151 +0,0 @@ -/*********************************************************************************************/ -/* MODULE DIALOGUE */ -/* ce module a pour but d'afficher les erreurs rencontrées lors de l'exécution du programme. */ -/* Il peut s'agir d'erreurs fatales, correspondant à un plantage, ou d'erreurs de syntaxe */ -/* correspondant à une erreur de l'utilisateur, par exemple dans un fichier source. */ -/* Sont également gérés les avertissements et les indications en mode verbose. */ -/* */ -/* Le module exporte des noms symboliques pour tous les codes d'erreurs et dispose de deux */ -/* points d'entrées pour les deux types d'erreurs */ -/* */ -/*********************************************************************************************/ - -#ifndef M_ERREUR_FLAG -#define M_ERREUR_FLAG - -/********************************************************************************************* - * Identification de l'erreur * - *********************************************************************************************/ - -/* Ce drapeau doit etre positionné à chaque erreur rencontrée */ -extern int err_code; - -/* Il faut garder à l'esprit que rien n'empeche un module d'utiliser les codes d'erreurs * - * qui ont à l'origine été créés pour un autre module. */ - -#define NO_ERR 0 /* Pas d'erreur détectée. */ - -/* Erreurs fatales */ -#define F_FLUX_NULL 1 /* Tentative de lecture dans un flux NULL */ -#define F_ERR_LECT 2 /* Erreur de lecture imprévisible */ -#define F_ERR_OUV 3 /* Erreur d'ouverture de fichier imprévisible */ -#define F_ERR_MEM 4 /* Erreur d'allocation, mémoire insuffisante ? */ - -/* Erreurs plutot du formateur */ -#define S_ERR_FORMAT 301 -#define S_INT_INVALID 302 /* Entier invalide */ -#define S_ALPHA_LONG 303 /* Alpha trop long */ -#define S_ALPHA_INVALID 304 -#define S_CAR_INVALID 305 - -/* Erreurs plutot du préprocesseur */ -#define S_CIRCULAR_FILE 401 /* Inclusion circulaire de fichiers */ -#define S_CIRCULAR_MACRO 402 /* Appel circulaire de macros */ -#define S_FICH_NON_TROUVE 403 /* Fichier spécifié en argument introuvable */ -#define S_DEF_MACRO_EOF 404 /* Troisème accolade fermante non rencontrée */ -#define S_USE_MACRO_EOF 405 /* Troisème accolade fermante non rencontrée */ -#define S_NOM_MAC_INVALID 406 /* Nom de la macro dans sa déclaration invalide */ -#define S_NOM_INCFICH_INVALID 407 /* Nom du fichier à inclure invalide */ -#define S_MAC_NO_MATCH 408 /* Macro incompatible avec sa définition */ -#define S_MAC_TROP_PARAM 409 /* Paramètres non utlisés par la macro */ - -/* Erreurs plutot du du preparateur */ -#define S_ERR_DCL 501 -#define S_DCL_VIDE 502 -#define S_DCL_NON_TERM 503 -#define S_BAD_PROP 504 -#define S_BAD_VAL 505 -#define S_BAD_FUN 506 -#define S_BAD_ARG 507 -#define S_DEP_SST 508 /* Dépassement de la capacité des sous-types. */ -#define S_DEP_FUNC_NB 510 /* Dépassement du nombre maximal de fonctions allouables. */ -#define S_BAD_SST_DEC 511 /* Déclaration du nb de sous-type manquante ou insuffisante. */ -#define S_SEC_SST_DEC 512 /* Second appel à la commande SET SSTNUM non autorisé. */ -#define S_REDEF_INS 513 /* Une instruction est redéfinie dans le fichier Syntaxe. */ - -/* Erreurs pultot de l'analyseur */ -#define S_SYN_ERR 601 /* Erreur de syntaxe dans le fichier source. */ -#define S_FUN_ERR 602 /* Erreur lors de l'application des fonctions de l'adapt. */ -#define S_ADAP_ERR 603 /* Erreur de positionnement du eval_code par l'adaptateur. */ - -/* Erreurs plutot de l'adaptateur. */ -#define S_FUN_INAP 701 /* Erreur, fonction non applicable. */ -#define S_ARG_INCOMP 702 /* Args incompatbiles, erreur dans fichier Syntaxe. */ -#define S_SIGNED_TL 703 /* Entier trop long pour un codage signé */ -#define S_UNSIGNED_TL 704 /* Entier trop long pour le codage non-signé */ -#define S_REDEF_ETIQ 705 /* Etiquette déjà exisante. */ -#define S_BAD_ETIQ 706 /* L'étiquette n'existe pas dans la table. */ -#define S_ADR_INCONNUE 707 /* L'adresse d'implantation est indéterminée. */ -#define S_UNSIGNED_EXPECTED 708 /* Entier non signé attendu */ -#define S_BAD_ALIGN 709 /* Saut à une étiquette non alignée sur 32 bits */ -#define S_TOO_FAR 710 /* Saut à une adresse trop éloignée */ - -/* Erreurs plutot du synthetiseur. */ - -/* Warnings */ -#define W_REGLE_TYPAGE 4001 /* Règle invalide, ignorée */ -#define W_NO_LIST_INC 4002 /* La fonctionalité include désactive la liste */ -#define W_NO_LIST_STDIN 4003 /* La lecture dans le flux standard aussi */ -#define W_REDEF_MAC 4004 /* Redéfinition d'une macro */ -#define W_UNDEF_NOMAC 4005 /* Tentative de suppression d'une macro non définie */ -#define W_REDEF_CODE 5001 /* Réutilisation du code, les sst seront les mêmes */ -#define W_REDEF_SST 5002 /* Réutilisation du nom de sous-type */ -#define W_NO_SYNTAX 5004 /* Pas de fichier Syntax trouvé */ -#define W_SEPLEX_INIT 6001 /* seplex non initialisé dans fichier Syntaxe */ -#define W_SRCE_MOD 8001 /* Le flux source a été modifié */ -#define W_ARG_INC 9001 /* Mauvaise utilisation des arguments */ -#define W_FICH_DEF_MACRO 9002 /* Fichier macro principal non ouvert */ -#define W_MACRO_MANQ 9003 /* Auncun fichier des macros par défaut chargé */ - -/* Commentaires. */ - -/* Main */ -#define B_INIT_SYNTAX -901 /* Initialisation de la syntaxe de l'assembleur */ -#define B_INIT_MACRO -902 /* Initialisation des macros par défaut */ -#define B_LECT_SRC -903 /* Lecture des sources.. */ -#define B_STR_OBJ -904 /* Enregistrement du fichier objet... */ -#define B_STR_LST -905 /* Creation de la liste d'assemblage... */ -#define B_ERR_REP -906 /* Rapport d'erreurs : */ -#define B_NBR_ERR_SYN -907 /* erreurs détectées lors de la synthèse */ -#define B_NBR_ERR_ANA -908 /* erreurs détectées lors de l'analyse */ -#define B_SYN -909 /* Analyse du code.. */ -#define B_ANA -910 /* Synthèse.. */ - -/* Preparateur */ -#define B_CASSE -600 /* Basculement en mode sensible à la casse */ -#define B_NOCASSE -601 /* Basculement en mode insensible à la casse */ -#define B_MAC_DEF -602 /* Détection d'un fichier de pseudo-instructions */ -#define B_INIT_D -603 /* Activation du support des macros */ -#define B_INIT_U -604 /* Activation du support de la supression de macros */ -#define B_INIT_I -605 /* Activation du support de l'inclusion de fichiers */ -#define B_INIT_SEP -606 /* Initialisation du séparateur d'instructions */ -#define B_PREP_SST -607 /* Préparation pour l'ajout de sous-types */ -#define B_ADD_SST -608 /* Nouveau sous-type détecté */ - -/* Adaptateur */ -#define B_TABLAB -700 /* Table des étiquettes */ - -/* Preprocesseur */ -#define B_NO_MACRO -401 /* Aucune macro définie */ -#define B_MACRO_DISPO -402 /* Voici la liste des macros disponibles */ - -/********************************************************************************************* - * Génération des messages d'erreur * - *********************************************************************************************/ - -/* Exportation du controleur de blabla. */ -extern int verbose; - -extern char sep_fich_inclus[]; /* "Inclus depuis" */ -char * search_msg(); /* Fonction de recherche du message correspondant au code d'erreur. */ -void display_help(); /* Fonction d'affichage de l'aide en ligne. */ - -void affiche_message(char * orig, int ligne); - -#define DIALOGUE(ptr_org, ligne, code)\ -{\ - err_code=code;\ - affiche_message(ptr_org, ligne);\ -} - -#endif Index: trunk/gasm/include/preparateur.h =================================================================== --- trunk/gasm/include/preparateur.h (revision 13) +++ trunk/gasm/include/preparateur.h (nonexistent) @@ -1,85 +0,0 @@ -/*********************************************************************************************/ -/* MODULE PREPARATEUR */ -/* ce module a pour but de lire le fichier Syntaxe du programme et de générer l'arbre des */ -/* lexèmes qui lui correspond. */ -/* */ -/* Le seul point d'accès de ce module est la fonction init_arbre qui reçoit le nom du */ -/* fichier Syntaxe à utiliser. */ -/* */ -/*********************************************************************************************/ - -#ifndef M_PREPA_FLAG -#define M_PREPA_FLAG - -#include -#include -#include - -/*********************************************************************************************/ -/* DEFINITION DE L'ARBRE DE LEXEMES */ -/* Définition de l'arbre de lexèmes généré par le préparateur et des autres types auquels il */ -/* se rapporte. */ -/*********************************************************************************************/ - -/* Définition de la feuille de l'arbre. */ -typedef struct -{ - type_mask * mask_primaire; /* masque primaire du codage. */ - char nbr_func; /* nombre de fonctions. */ - type_ptr_fgm * ptr_func; /* adresse du début du tableau des fonctions. */ -} type_feuille; - -/* Définition de la structure arbre elle-même. */ -typedef struct noeud_arbre -{ - type_lexeme lexeme; - struct noeud_arbre * ptr_fils; - struct noeud_arbre * ptr_frere; - type_feuille * ptr_feuille; -} type_noeud; - -#define ALLOC_FEUILLE(feuille) \ -{\ - feuille=(type_feuille *) malloc(sizeof(type_feuille));\ - if (feuille==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ - feuille->mask_primaire=NULL;\ - feuille->nbr_func=0;\ - feuille->ptr_func=NULL;\ -} - -#define FREE_FEUILLE(feuille) \ -{\ - if (feuille->mask_primaire!=NULL) FREE_MASK(feuille->mask_primaire);\ - if (feuille->ptr_func!=NULL) free(feuille->ptr_func);\ - free(feuille);\ -} - -#define ALLOC_NOEUD(noeud) \ -{\ - noeud=(type_noeud *) malloc(sizeof(type_noeud));\ - if (noeud==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ - noeud->lexeme.type=0;\ - noeud->lexeme.valeur.op=0;\ - noeud->ptr_fils=NULL;\ - noeud->ptr_frere=NULL;\ - noeud->ptr_feuille=NULL;\ -} - -#define FREE_NOEUD(noeud) \ -{\ - if (noeud->ptr_feuille!=NULL) FREE_FEUILLE(noeud->ptr_feuille);\ - free(noeud);\ -} - - -/* Exportation de la racine de l'arbre des lexèmes. */ -extern type_noeud * root; - - -/* Nombre maximal de fonctions pour une instruction dans le fichier Syntaxe. */ -#define MAX_FONCTIONS 16 - -int init_arbre(char * fichier_syntaxe); -void clear_preparateur(); - -#endif Index: trunk/gasm/include/adaptateur.h =================================================================== --- trunk/gasm/include/adaptateur.h (revision 13) +++ trunk/gasm/include/adaptateur.h (nonexistent) @@ -1,50 +0,0 @@ -/* Module adaptateur */ -#ifndef M_ADAPTATEUR_FLAG -#define M_ADAPTATEUR_FLAG - -/* Autres modules du projet utilisés. */ -#include -#include - -/*********************************************************************************************/ -/* DEFINITION DU TYPE MASQUE */ -/* Définition du type mask */ -/*********************************************************************************************/ - -typedef short int type_taille_mask; -typedef unsigned long type_valeur_mask; -typedef struct -{ - type_taille_mask taille; /* taille du masque en octets. */ - type_valeur_mask valeur; /* valeur du masque sur 64 bits. */ -} type_mask; - -/* Comme l'allocation de masques sera une opération très fréquente, on pourra utiliser la */ -/* macro suivante pour simplifier le code. */ -#define ALLOC_MASK(msk) {\ - msk = ((type_mask *) malloc(sizeof(type_mask)));\ - } - -#define FREE_MASK(msk) {\ - free(msk);\ - } - -/*********************************************************************************************/ -/* EXPORTATION DES FONCTIONS DE L'ADAPTATEUR */ -/*********************************************************************************************/ - -/* Définition du type pointeur vers une fonction génératrice de masque. */ -typedef type_mask *((*type_ptr_fgm)()); - -type_ptr_fgm alias(char *); /* Retourne le pointeur sur la fonction à partir du nom. */ -void clear_adaptateur(); /* Fonction de cloture de l'adaptateur. */ -void write_data(FILE * f_lst); /* Ecriture d'informations dans la lsite. */ - -extern int eval_code; /* Drapeau pour le résultat de l'évaluation d'une fgm. */ - -/* Définition des différents types d'erreur d'évaluation. */ -#define EVAL_REUSSIE 0 /* Evaluation réussie. */ -#define EVAL_IMPOSSIBLE 1 /* Evaluation impossible (fonction de seconde passe ?) */ -#define EVAL_ERREUR 2 /* Erreur lors de l'évaluation (fichier Syntaxe incorrect ?) */ - -#endif Index: trunk/gasm/include/preprocesseur.h =================================================================== --- trunk/gasm/include/preprocesseur.h (revision 13) +++ trunk/gasm/include/preprocesseur.h (nonexistent) @@ -1,33 +0,0 @@ -#ifndef M_PREPROCESSEUR_FLAG -#define M_PREPROCESSEUR_FLAG - -#include -#include - -/******************************************************************************************** - * POINTS D'ENTREE * - ********************************************************************************************/ -void push_lexeme(type_lexeme * ptr_recrach); -type_lexeme * pop_lexeme(); - -/* ATTENTION !!! les lexemes rendu avec push_lexeme ne seront pas à nouveau traités lors de * - * l'appel au prochain pop_lexeme. Ainsi, les macro ajoutées ne s'appliquent qu'à partir * - * du prochain lexème lu pour la première fois, c'est-à-dire quand la pile est vide. De * - * meme, la ligne et la chaine d'origine fournie coincident avec le dernier lexème non issu * - * de la pile. Les push et pop ne constituent qu'un outil surpeficiel à manier avec soin. */ - -int init_preprocesseur(char * main_asm); -void clear_preprocesseur(); -void suppress_macro(char * nom_macro); -void ajoute_macro(char * nom_macro, FILE * flux_def); -void liste_table_macro(FILE *); - -/******************************************************************************************** - * GENERATION DE L'ORIGINE DES LEXEMES POUR LA LOCALISATION D'ERREUR * - * * - * Attention, ne pas oublier de faire free() sur le pointeur renvoyé ! * - ********************************************************************************************/ -int ligne_courante(); -char * gen_orig_msg(); - -#endif Index: trunk/gasm/include/debogueur.h =================================================================== --- trunk/gasm/include/debogueur.h (revision 13) +++ trunk/gasm/include/debogueur.h (nonexistent) @@ -1,29 +0,0 @@ -#ifdef DEBUG -#ifndef M_DEBUG_FLAG -#define M_DEBUG_FLAG - -/* La bibliothèque standard doit être incluse avant de déffinir les macros de remplacement */ -/* de malloc et free sinon leurs déclarations deviennt fausses. */ -#include -#include - -/* "Surcharge" des fonctions malloc et free. */ -#define malloc(taille) alloc_debug(taille, __LINE__, __FILE__) -#define free(ptr) free_debug(ptr, __LINE__, __FILE__) - -void * alloc_debug(int size, int lg, char * fc); -void free_debug(void * ptr, int lg, char * fc); -void print_mem(FILE * f); -extern int nalloc; - -/* Définition d'une macro pour l'enregistrement des pointeurs dans un fichier. */ -#define FPRINT_MALLOC \ -{\ - FILE * f;\ - f=fopen("malloc.debug", "wb");\ - print_mem(f);\ - fclose(f);\ -} - -#endif -#endif Index: trunk/gasm/include/analyseur.h =================================================================== --- trunk/gasm/include/analyseur.h (revision 13) +++ trunk/gasm/include/analyseur.h (nonexistent) @@ -1,100 +0,0 @@ -/*********************************************************************************************/ -/* MODULE ANALYSEUR */ -/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ -/* du code source avec la syntaxe acceptée par le langage. La lecture se fait lexème par */ -/* lexème en utilisant le préprocesseur. */ -/* Il se charge de générer la pile de précode qu sera utilisée par le syntéthiseur pour */ -/* générer le code final. */ -/*********************************************************************************************/ -#ifndef M_ANALYSEUR_FLAG -#define M_ANALYSEUR_FLAG - -#include -#include -#include - -typedef struct file_pcd_tmp -{ - type_mask * mask; /* Masque déjà généré à la première passe. */ - char nbr_func; /* Nombre de fonctions restant à appliquer. */ - type_ptr_fgm * func; /* Tableau des pointeurs vers ces fonctions. */ - type_file_lexeme * param; /* File de lexèmes ayant validé l'intruction. */ - char * fichier_orig; /* Nom du fichier d'origine de l'instruction. */ - int ligne_orig; /* Numéro de la ligne de l'instruction. */ - struct file_pcd_tmp * suivant; /* Pointeur vers la suite de la file de precode. */ - int erreur; /* Code d'erreur rencontré. */ - int pco; /* Adresse d'implantation. */ -} type_precode; - - -extern type_precode * file_precode; /* Pointeur vers la file de précode générée. */ - -int analyse(); /* Point d'entrée principal du module. */ -void clear_analyseur(); /* Fonction de nettoyage/réinitialisation du module. */ - -/* Macro d'allocation et d'initialisation d'un précode. */ -#define ALLOC_PREC(prec) \ -{\ - prec = (type_precode *) malloc(sizeof(type_precode));\ - if (prec==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ - prec->fichier_orig=NULL;\ - prec->ligne_orig=0;\ - prec->mask=NULL;\ - prec->nbr_func=0;\ - prec->func=NULL;\ - prec->param=NULL;\ - prec->suivant=NULL;\ - prec->erreur=NO_ERR;\ -} - -/* Cette macro libère l'espace alloué pour une file de lexèmes. */ -#define FREE_ARGS(args) \ -{\ - type_file_lexeme * courant=args, * suivant;\ - while (courant!=NULL)\ - {\ - suivant=courant->suivant;\ - FREE_LEX(courant->lexeme);\ - free(courant);\ - courant=suivant;\ - }\ - args=NULL;\ -} - -/* Cette macro libère l'espace alloué pour un précode. */ -#define FREE_PRECODE(precode) \ -{\ - if (precode->mask) FREE_MASK(precode->mask);\ - if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ - FREE_ARGS(precode->param);\ - if (precode->fichier_orig) free(precode->fichier_orig);\ - if (precode->func) free(precode->func);\ - free(precode);\ -} - -/* Cette macro efface et libère le contenu d'un précode mais pas la structure elle_même. */ -/* On conserve toutefois les informations sur l'origine. */ -#define CLEAR_PRECODE(precode) \ -{\ - if (precode->mask) FREE_MASK(precode->mask);\ - precode->mask=NULL;\ - if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ - precode->func=NULL;\ - FREE_ARGS(precode->param);\ - precode->param=NULL;\ - precode->nbr_func=0;\ -} - - -/* Cette macro peut être utilisée pour écrire un masque sous forme "lisible". */ -#define FPRINT_BIN(f, ptrmask) \ -{\ - int i;\ - if (ptrmask)\ - {\ - for (i=8*ptrmask->taille-1;i>=0;i--)\ - fprintf(f, "%c",((ptrmask->valeur>>i) % 2) ? '1' : '0');\ - }\ -} - -#endif Index: trunk/gasm/include/parametres.h =================================================================== --- trunk/gasm/include/parametres.h (revision 13) +++ trunk/gasm/include/parametres.h (nonexistent) @@ -1,48 +0,0 @@ -#ifndef M_PARAMETRES_FLAG -#define M_PARAMETRES_FLAG - -#include - -/*********************************************************************************************/ -/* MODULE CONTENANT LES VARIABLES D'ENVIRONNEMENT */ -/*********************************************************************************************/ - -/* Déclaration de variables globales concernant la syntaxe de l'assembleur */ - -/* Sous-typage des lexèmes ALPHA : */ -typedef struct -{ - type_type_lex code; - char * chaine; -} type_paire; - -extern type_paire * regle_typage; - -#define MAX_SOUS_TYPES 15 /* Nombre maximum de sous types codables. */ - -/* Sensibilité à la casse (oui par défaut) */ -extern int casse_sens; - -/* Nom du fichier de macro à inclure par défaut en début de code */ -extern char * fich_macro_def; - -/* Chaines de caractères pour les directives préprocesseur. */ -extern char * include_str; -extern char * define_str; -extern char * undef_str; - -/* Variables pour la définition des sous-types. */ -extern int nbr_sous_types; - -/* Lexème séparateur d'instructions. */ -extern type_lexeme * seplex; - -/* Variables globales utilisées par le programme. */ - -/* Exportation du pseudo compteur ordinal. */ -extern int pco; - -/* Activation de la lsite d'assemblage. */ -extern int active_list; - -#endif Index: trunk/gasm/Makefile.dep =================================================================== --- trunk/gasm/Makefile.dep (revision 13) +++ trunk/gasm/Makefile.dep (nonexistent) @@ -1,23 +0,0 @@ -# This file is part of gasm. -# -# -# If you encountered any problem, please contact : -# -# lmouton@enserg.fr -# shangoue@enserg.fr -# - - - -# Définition des dépendances - -dialogue_DEP = -formateur_DEP = dialogue -parametres_DEP = formateur -preprocesseur_DEP = dialogue formateur parametres -adaptateur_DEP = dialogue formateur parametres preprocesseur -preparateur_DEP = dialogue formateur parametres adaptateur -analyseur_DEP = dialogue formateur parametres preprocesseur adaptateur preparateur -synthetiseur_DEP = dialogue formateur parametres adaptateur analyseur - -ALL = dialogue formateur parametres preprocesseur adaptateur preparateur analyseur synthetiseur Index: trunk/COPYING =================================================================== --- trunk/COPYING (revision 13) +++ trunk/COPYING (nonexistent) @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. Index: trunk/LGPL.txt =================================================================== --- trunk/LGPL.txt (revision 13) +++ trunk/LGPL.txt (nonexistent) @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - Index: minimips/trunk/gasm/include/dialogue.h =================================================================== --- minimips/trunk/gasm/include/dialogue.h (nonexistent) +++ minimips/trunk/gasm/include/dialogue.h (revision 14) @@ -0,0 +1,151 @@ +/*********************************************************************************************/ +/* MODULE DIALOGUE */ +/* ce module a pour but d'afficher les erreurs rencontrées lors de l'exécution du programme. */ +/* Il peut s'agir d'erreurs fatales, correspondant à un plantage, ou d'erreurs de syntaxe */ +/* correspondant à une erreur de l'utilisateur, par exemple dans un fichier source. */ +/* Sont également gérés les avertissements et les indications en mode verbose. */ +/* */ +/* Le module exporte des noms symboliques pour tous les codes d'erreurs et dispose de deux */ +/* points d'entrées pour les deux types d'erreurs */ +/* */ +/*********************************************************************************************/ + +#ifndef M_ERREUR_FLAG +#define M_ERREUR_FLAG + +/********************************************************************************************* + * Identification de l'erreur * + *********************************************************************************************/ + +/* Ce drapeau doit etre positionné à chaque erreur rencontrée */ +extern int err_code; + +/* Il faut garder à l'esprit que rien n'empeche un module d'utiliser les codes d'erreurs * + * qui ont à l'origine été créés pour un autre module. */ + +#define NO_ERR 0 /* Pas d'erreur détectée. */ + +/* Erreurs fatales */ +#define F_FLUX_NULL 1 /* Tentative de lecture dans un flux NULL */ +#define F_ERR_LECT 2 /* Erreur de lecture imprévisible */ +#define F_ERR_OUV 3 /* Erreur d'ouverture de fichier imprévisible */ +#define F_ERR_MEM 4 /* Erreur d'allocation, mémoire insuffisante ? */ + +/* Erreurs plutot du formateur */ +#define S_ERR_FORMAT 301 +#define S_INT_INVALID 302 /* Entier invalide */ +#define S_ALPHA_LONG 303 /* Alpha trop long */ +#define S_ALPHA_INVALID 304 +#define S_CAR_INVALID 305 + +/* Erreurs plutot du préprocesseur */ +#define S_CIRCULAR_FILE 401 /* Inclusion circulaire de fichiers */ +#define S_CIRCULAR_MACRO 402 /* Appel circulaire de macros */ +#define S_FICH_NON_TROUVE 403 /* Fichier spécifié en argument introuvable */ +#define S_DEF_MACRO_EOF 404 /* Troisème accolade fermante non rencontrée */ +#define S_USE_MACRO_EOF 405 /* Troisème accolade fermante non rencontrée */ +#define S_NOM_MAC_INVALID 406 /* Nom de la macro dans sa déclaration invalide */ +#define S_NOM_INCFICH_INVALID 407 /* Nom du fichier à inclure invalide */ +#define S_MAC_NO_MATCH 408 /* Macro incompatible avec sa définition */ +#define S_MAC_TROP_PARAM 409 /* Paramètres non utlisés par la macro */ + +/* Erreurs plutot du du preparateur */ +#define S_ERR_DCL 501 +#define S_DCL_VIDE 502 +#define S_DCL_NON_TERM 503 +#define S_BAD_PROP 504 +#define S_BAD_VAL 505 +#define S_BAD_FUN 506 +#define S_BAD_ARG 507 +#define S_DEP_SST 508 /* Dépassement de la capacité des sous-types. */ +#define S_DEP_FUNC_NB 510 /* Dépassement du nombre maximal de fonctions allouables. */ +#define S_BAD_SST_DEC 511 /* Déclaration du nb de sous-type manquante ou insuffisante. */ +#define S_SEC_SST_DEC 512 /* Second appel à la commande SET SSTNUM non autorisé. */ +#define S_REDEF_INS 513 /* Une instruction est redéfinie dans le fichier Syntaxe. */ + +/* Erreurs pultot de l'analyseur */ +#define S_SYN_ERR 601 /* Erreur de syntaxe dans le fichier source. */ +#define S_FUN_ERR 602 /* Erreur lors de l'application des fonctions de l'adapt. */ +#define S_ADAP_ERR 603 /* Erreur de positionnement du eval_code par l'adaptateur. */ + +/* Erreurs plutot de l'adaptateur. */ +#define S_FUN_INAP 701 /* Erreur, fonction non applicable. */ +#define S_ARG_INCOMP 702 /* Args incompatbiles, erreur dans fichier Syntaxe. */ +#define S_SIGNED_TL 703 /* Entier trop long pour un codage signé */ +#define S_UNSIGNED_TL 704 /* Entier trop long pour le codage non-signé */ +#define S_REDEF_ETIQ 705 /* Etiquette déjà exisante. */ +#define S_BAD_ETIQ 706 /* L'étiquette n'existe pas dans la table. */ +#define S_ADR_INCONNUE 707 /* L'adresse d'implantation est indéterminée. */ +#define S_UNSIGNED_EXPECTED 708 /* Entier non signé attendu */ +#define S_BAD_ALIGN 709 /* Saut à une étiquette non alignée sur 32 bits */ +#define S_TOO_FAR 710 /* Saut à une adresse trop éloignée */ + +/* Erreurs plutot du synthetiseur. */ + +/* Warnings */ +#define W_REGLE_TYPAGE 4001 /* Règle invalide, ignorée */ +#define W_NO_LIST_INC 4002 /* La fonctionalité include désactive la liste */ +#define W_NO_LIST_STDIN 4003 /* La lecture dans le flux standard aussi */ +#define W_REDEF_MAC 4004 /* Redéfinition d'une macro */ +#define W_UNDEF_NOMAC 4005 /* Tentative de suppression d'une macro non définie */ +#define W_REDEF_CODE 5001 /* Réutilisation du code, les sst seront les mêmes */ +#define W_REDEF_SST 5002 /* Réutilisation du nom de sous-type */ +#define W_NO_SYNTAX 5004 /* Pas de fichier Syntax trouvé */ +#define W_SEPLEX_INIT 6001 /* seplex non initialisé dans fichier Syntaxe */ +#define W_SRCE_MOD 8001 /* Le flux source a été modifié */ +#define W_ARG_INC 9001 /* Mauvaise utilisation des arguments */ +#define W_FICH_DEF_MACRO 9002 /* Fichier macro principal non ouvert */ +#define W_MACRO_MANQ 9003 /* Auncun fichier des macros par défaut chargé */ + +/* Commentaires. */ + +/* Main */ +#define B_INIT_SYNTAX -901 /* Initialisation de la syntaxe de l'assembleur */ +#define B_INIT_MACRO -902 /* Initialisation des macros par défaut */ +#define B_LECT_SRC -903 /* Lecture des sources.. */ +#define B_STR_OBJ -904 /* Enregistrement du fichier objet... */ +#define B_STR_LST -905 /* Creation de la liste d'assemblage... */ +#define B_ERR_REP -906 /* Rapport d'erreurs : */ +#define B_NBR_ERR_SYN -907 /* erreurs détectées lors de la synthèse */ +#define B_NBR_ERR_ANA -908 /* erreurs détectées lors de l'analyse */ +#define B_SYN -909 /* Analyse du code.. */ +#define B_ANA -910 /* Synthèse.. */ + +/* Preparateur */ +#define B_CASSE -600 /* Basculement en mode sensible à la casse */ +#define B_NOCASSE -601 /* Basculement en mode insensible à la casse */ +#define B_MAC_DEF -602 /* Détection d'un fichier de pseudo-instructions */ +#define B_INIT_D -603 /* Activation du support des macros */ +#define B_INIT_U -604 /* Activation du support de la supression de macros */ +#define B_INIT_I -605 /* Activation du support de l'inclusion de fichiers */ +#define B_INIT_SEP -606 /* Initialisation du séparateur d'instructions */ +#define B_PREP_SST -607 /* Préparation pour l'ajout de sous-types */ +#define B_ADD_SST -608 /* Nouveau sous-type détecté */ + +/* Adaptateur */ +#define B_TABLAB -700 /* Table des étiquettes */ + +/* Preprocesseur */ +#define B_NO_MACRO -401 /* Aucune macro définie */ +#define B_MACRO_DISPO -402 /* Voici la liste des macros disponibles */ + +/********************************************************************************************* + * Génération des messages d'erreur * + *********************************************************************************************/ + +/* Exportation du controleur de blabla. */ +extern int verbose; + +extern char sep_fich_inclus[]; /* "Inclus depuis" */ +char * search_msg(); /* Fonction de recherche du message correspondant au code d'erreur. */ +void display_help(); /* Fonction d'affichage de l'aide en ligne. */ + +void affiche_message(char * orig, int ligne); + +#define DIALOGUE(ptr_org, ligne, code)\ +{\ + err_code=code;\ + affiche_message(ptr_org, ligne);\ +} + +#endif Index: minimips/trunk/gasm/include/adaptateur.h =================================================================== --- minimips/trunk/gasm/include/adaptateur.h (nonexistent) +++ minimips/trunk/gasm/include/adaptateur.h (revision 14) @@ -0,0 +1,50 @@ +/* Module adaptateur */ +#ifndef M_ADAPTATEUR_FLAG +#define M_ADAPTATEUR_FLAG + +/* Autres modules du projet utilisés. */ +#include +#include + +/*********************************************************************************************/ +/* DEFINITION DU TYPE MASQUE */ +/* Définition du type mask */ +/*********************************************************************************************/ + +typedef short int type_taille_mask; +typedef unsigned long type_valeur_mask; +typedef struct +{ + type_taille_mask taille; /* taille du masque en octets. */ + type_valeur_mask valeur; /* valeur du masque sur 64 bits. */ +} type_mask; + +/* Comme l'allocation de masques sera une opération très fréquente, on pourra utiliser la */ +/* macro suivante pour simplifier le code. */ +#define ALLOC_MASK(msk) {\ + msk = ((type_mask *) malloc(sizeof(type_mask)));\ + } + +#define FREE_MASK(msk) {\ + free(msk);\ + } + +/*********************************************************************************************/ +/* EXPORTATION DES FONCTIONS DE L'ADAPTATEUR */ +/*********************************************************************************************/ + +/* Définition du type pointeur vers une fonction génératrice de masque. */ +typedef type_mask *((*type_ptr_fgm)()); + +type_ptr_fgm alias(char *); /* Retourne le pointeur sur la fonction à partir du nom. */ +void clear_adaptateur(); /* Fonction de cloture de l'adaptateur. */ +void write_data(FILE * f_lst); /* Ecriture d'informations dans la lsite. */ + +extern int eval_code; /* Drapeau pour le résultat de l'évaluation d'une fgm. */ + +/* Définition des différents types d'erreur d'évaluation. */ +#define EVAL_REUSSIE 0 /* Evaluation réussie. */ +#define EVAL_IMPOSSIBLE 1 /* Evaluation impossible (fonction de seconde passe ?) */ +#define EVAL_ERREUR 2 /* Erreur lors de l'évaluation (fichier Syntaxe incorrect ?) */ + +#endif Index: minimips/trunk/gasm/include/preparateur.h =================================================================== --- minimips/trunk/gasm/include/preparateur.h (nonexistent) +++ minimips/trunk/gasm/include/preparateur.h (revision 14) @@ -0,0 +1,85 @@ +/*********************************************************************************************/ +/* MODULE PREPARATEUR */ +/* ce module a pour but de lire le fichier Syntaxe du programme et de générer l'arbre des */ +/* lexèmes qui lui correspond. */ +/* */ +/* Le seul point d'accès de ce module est la fonction init_arbre qui reçoit le nom du */ +/* fichier Syntaxe à utiliser. */ +/* */ +/*********************************************************************************************/ + +#ifndef M_PREPA_FLAG +#define M_PREPA_FLAG + +#include +#include +#include + +/*********************************************************************************************/ +/* DEFINITION DE L'ARBRE DE LEXEMES */ +/* Définition de l'arbre de lexèmes généré par le préparateur et des autres types auquels il */ +/* se rapporte. */ +/*********************************************************************************************/ + +/* Définition de la feuille de l'arbre. */ +typedef struct +{ + type_mask * mask_primaire; /* masque primaire du codage. */ + char nbr_func; /* nombre de fonctions. */ + type_ptr_fgm * ptr_func; /* adresse du début du tableau des fonctions. */ +} type_feuille; + +/* Définition de la structure arbre elle-même. */ +typedef struct noeud_arbre +{ + type_lexeme lexeme; + struct noeud_arbre * ptr_fils; + struct noeud_arbre * ptr_frere; + type_feuille * ptr_feuille; +} type_noeud; + +#define ALLOC_FEUILLE(feuille) \ +{\ + feuille=(type_feuille *) malloc(sizeof(type_feuille));\ + if (feuille==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ + feuille->mask_primaire=NULL;\ + feuille->nbr_func=0;\ + feuille->ptr_func=NULL;\ +} + +#define FREE_FEUILLE(feuille) \ +{\ + if (feuille->mask_primaire!=NULL) FREE_MASK(feuille->mask_primaire);\ + if (feuille->ptr_func!=NULL) free(feuille->ptr_func);\ + free(feuille);\ +} + +#define ALLOC_NOEUD(noeud) \ +{\ + noeud=(type_noeud *) malloc(sizeof(type_noeud));\ + if (noeud==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ + noeud->lexeme.type=0;\ + noeud->lexeme.valeur.op=0;\ + noeud->ptr_fils=NULL;\ + noeud->ptr_frere=NULL;\ + noeud->ptr_feuille=NULL;\ +} + +#define FREE_NOEUD(noeud) \ +{\ + if (noeud->ptr_feuille!=NULL) FREE_FEUILLE(noeud->ptr_feuille);\ + free(noeud);\ +} + + +/* Exportation de la racine de l'arbre des lexèmes. */ +extern type_noeud * root; + + +/* Nombre maximal de fonctions pour une instruction dans le fichier Syntaxe. */ +#define MAX_FONCTIONS 16 + +int init_arbre(char * fichier_syntaxe); +void clear_preparateur(); + +#endif Index: minimips/trunk/gasm/include/debogueur.h =================================================================== --- minimips/trunk/gasm/include/debogueur.h (nonexistent) +++ minimips/trunk/gasm/include/debogueur.h (revision 14) @@ -0,0 +1,29 @@ +#ifdef DEBUG +#ifndef M_DEBUG_FLAG +#define M_DEBUG_FLAG + +/* La bibliothèque standard doit être incluse avant de déffinir les macros de remplacement */ +/* de malloc et free sinon leurs déclarations deviennt fausses. */ +#include +#include + +/* "Surcharge" des fonctions malloc et free. */ +#define malloc(taille) alloc_debug(taille, __LINE__, __FILE__) +#define free(ptr) free_debug(ptr, __LINE__, __FILE__) + +void * alloc_debug(int size, int lg, char * fc); +void free_debug(void * ptr, int lg, char * fc); +void print_mem(FILE * f); +extern int nalloc; + +/* Définition d'une macro pour l'enregistrement des pointeurs dans un fichier. */ +#define FPRINT_MALLOC \ +{\ + FILE * f;\ + f=fopen("malloc.debug", "wb");\ + print_mem(f);\ + fclose(f);\ +} + +#endif +#endif Index: minimips/trunk/gasm/include/preprocesseur.h =================================================================== --- minimips/trunk/gasm/include/preprocesseur.h (nonexistent) +++ minimips/trunk/gasm/include/preprocesseur.h (revision 14) @@ -0,0 +1,33 @@ +#ifndef M_PREPROCESSEUR_FLAG +#define M_PREPROCESSEUR_FLAG + +#include +#include + +/******************************************************************************************** + * POINTS D'ENTREE * + ********************************************************************************************/ +void push_lexeme(type_lexeme * ptr_recrach); +type_lexeme * pop_lexeme(); + +/* ATTENTION !!! les lexemes rendu avec push_lexeme ne seront pas à nouveau traités lors de * + * l'appel au prochain pop_lexeme. Ainsi, les macro ajoutées ne s'appliquent qu'à partir * + * du prochain lexème lu pour la première fois, c'est-à-dire quand la pile est vide. De * + * meme, la ligne et la chaine d'origine fournie coincident avec le dernier lexème non issu * + * de la pile. Les push et pop ne constituent qu'un outil surpeficiel à manier avec soin. */ + +int init_preprocesseur(char * main_asm); +void clear_preprocesseur(); +void suppress_macro(char * nom_macro); +void ajoute_macro(char * nom_macro, FILE * flux_def); +void liste_table_macro(FILE *); + +/******************************************************************************************** + * GENERATION DE L'ORIGINE DES LEXEMES POUR LA LOCALISATION D'ERREUR * + * * + * Attention, ne pas oublier de faire free() sur le pointeur renvoyé ! * + ********************************************************************************************/ +int ligne_courante(); +char * gen_orig_msg(); + +#endif Index: minimips/trunk/gasm/include/analyseur.h =================================================================== --- minimips/trunk/gasm/include/analyseur.h (nonexistent) +++ minimips/trunk/gasm/include/analyseur.h (revision 14) @@ -0,0 +1,100 @@ +/*********************************************************************************************/ +/* MODULE ANALYSEUR */ +/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ +/* du code source avec la syntaxe acceptée par le langage. La lecture se fait lexème par */ +/* lexème en utilisant le préprocesseur. */ +/* Il se charge de générer la pile de précode qu sera utilisée par le syntéthiseur pour */ +/* générer le code final. */ +/*********************************************************************************************/ +#ifndef M_ANALYSEUR_FLAG +#define M_ANALYSEUR_FLAG + +#include +#include +#include + +typedef struct file_pcd_tmp +{ + type_mask * mask; /* Masque déjà généré à la première passe. */ + char nbr_func; /* Nombre de fonctions restant à appliquer. */ + type_ptr_fgm * func; /* Tableau des pointeurs vers ces fonctions. */ + type_file_lexeme * param; /* File de lexèmes ayant validé l'intruction. */ + char * fichier_orig; /* Nom du fichier d'origine de l'instruction. */ + int ligne_orig; /* Numéro de la ligne de l'instruction. */ + struct file_pcd_tmp * suivant; /* Pointeur vers la suite de la file de precode. */ + int erreur; /* Code d'erreur rencontré. */ + int pco; /* Adresse d'implantation. */ +} type_precode; + + +extern type_precode * file_precode; /* Pointeur vers la file de précode générée. */ + +int analyse(); /* Point d'entrée principal du module. */ +void clear_analyseur(); /* Fonction de nettoyage/réinitialisation du module. */ + +/* Macro d'allocation et d'initialisation d'un précode. */ +#define ALLOC_PREC(prec) \ +{\ + prec = (type_precode *) malloc(sizeof(type_precode));\ + if (prec==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM);\ + prec->fichier_orig=NULL;\ + prec->ligne_orig=0;\ + prec->mask=NULL;\ + prec->nbr_func=0;\ + prec->func=NULL;\ + prec->param=NULL;\ + prec->suivant=NULL;\ + prec->erreur=NO_ERR;\ +} + +/* Cette macro libère l'espace alloué pour une file de lexèmes. */ +#define FREE_ARGS(args) \ +{\ + type_file_lexeme * courant=args, * suivant;\ + while (courant!=NULL)\ + {\ + suivant=courant->suivant;\ + FREE_LEX(courant->lexeme);\ + free(courant);\ + courant=suivant;\ + }\ + args=NULL;\ +} + +/* Cette macro libère l'espace alloué pour un précode. */ +#define FREE_PRECODE(precode) \ +{\ + if (precode->mask) FREE_MASK(precode->mask);\ + if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ + FREE_ARGS(precode->param);\ + if (precode->fichier_orig) free(precode->fichier_orig);\ + if (precode->func) free(precode->func);\ + free(precode);\ +} + +/* Cette macro efface et libère le contenu d'un précode mais pas la structure elle_même. */ +/* On conserve toutefois les informations sur l'origine. */ +#define CLEAR_PRECODE(precode) \ +{\ + if (precode->mask) FREE_MASK(precode->mask);\ + precode->mask=NULL;\ + if (precode->nbr_func!=0 && precode->func!=NULL) free(precode->func);\ + precode->func=NULL;\ + FREE_ARGS(precode->param);\ + precode->param=NULL;\ + precode->nbr_func=0;\ +} + + +/* Cette macro peut être utilisée pour écrire un masque sous forme "lisible". */ +#define FPRINT_BIN(f, ptrmask) \ +{\ + int i;\ + if (ptrmask)\ + {\ + for (i=8*ptrmask->taille-1;i>=0;i--)\ + fprintf(f, "%c",((ptrmask->valeur>>i) % 2) ? '1' : '0');\ + }\ +} + +#endif Index: minimips/trunk/gasm/include/parametres.h =================================================================== --- minimips/trunk/gasm/include/parametres.h (nonexistent) +++ minimips/trunk/gasm/include/parametres.h (revision 14) @@ -0,0 +1,48 @@ +#ifndef M_PARAMETRES_FLAG +#define M_PARAMETRES_FLAG + +#include + +/*********************************************************************************************/ +/* MODULE CONTENANT LES VARIABLES D'ENVIRONNEMENT */ +/*********************************************************************************************/ + +/* Déclaration de variables globales concernant la syntaxe de l'assembleur */ + +/* Sous-typage des lexèmes ALPHA : */ +typedef struct +{ + type_type_lex code; + char * chaine; +} type_paire; + +extern type_paire * regle_typage; + +#define MAX_SOUS_TYPES 15 /* Nombre maximum de sous types codables. */ + +/* Sensibilité à la casse (oui par défaut) */ +extern int casse_sens; + +/* Nom du fichier de macro à inclure par défaut en début de code */ +extern char * fich_macro_def; + +/* Chaines de caractères pour les directives préprocesseur. */ +extern char * include_str; +extern char * define_str; +extern char * undef_str; + +/* Variables pour la définition des sous-types. */ +extern int nbr_sous_types; + +/* Lexème séparateur d'instructions. */ +extern type_lexeme * seplex; + +/* Variables globales utilisées par le programme. */ + +/* Exportation du pseudo compteur ordinal. */ +extern int pco; + +/* Activation de la lsite d'assemblage. */ +extern int active_list; + +#endif Index: minimips/trunk/gasm/include/formateur.h =================================================================== --- minimips/trunk/gasm/include/formateur.h (nonexistent) +++ minimips/trunk/gasm/include/formateur.h (revision 14) @@ -0,0 +1,168 @@ +#ifndef M_FORMATEUR_FLAG +#define M_FORMATEUR_FLAG + +/* Modules de la bibliotheque standard */ + +#include +#include + +/* Autres modules utilises */ + +#include + + +/*********************************************************************************************/ +/* COMPOSITION DES ENSEMBLES DE CARACTERES */ +/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ +/* sa lecture. */ +/*********************************************************************************************/ + +/* D‰finition d'un code pour chaque ensemble existant */ +#define NBR_ENS 6 /* Nombre d'ensembles existant. */ +enum {lettre, chiffre, prefixe, sep_explicite, sep_invisible, commentaire}; + +/* D‰finition de constantes pour la taille de chaque ensemble existant. */ +#define taille_lettre 56 +#define taille_chiffre 22 +#define taille_prefixe 6 +#define taille_sep_explicite 11 +#define taille_sep_invisible 3 +#define taille_commentaire 2 + +/* D‰claration du tableau regroupant tous ces ensembles. */ +extern int *ensemble[NBR_ENS]; + +/* D‰finition de constantes pour les valeurs des operateurs (S‰parateur explicites). */ +#define ACF '}' +#define ACO '{' +#define NL '\n' +#define DP ':' +#define PF ')' +#define PO '(' +#define PS '+' +#define MS '-' +#define DIR '#' +#define VIR ',' + +/*********************************************************************************************/ +/* DEFINITION DES LEXEMES */ +/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ +/*********************************************************************************************/ + +/* D‰claration des diff‰rents types de lexemes possibles. Ces valeurs rempliront le champ */ +/* type de la structure lexeme. */ +#define ALPHA 2 +#define NUM 4 +#define OP 8 + +/* Le type des lexˆmes sera cod‰ sur 8 bits donc 1 pour la pr‰sence de valeur, 3 pour les */ +/* trois types de base et 4 pour coder les 15 sous-types possibles. */ +typedef unsigned char type_type_lex; + +/* Definition du type lexeme. */ +/* le type int sera utilis‰ pour coder la valeur d'un lexˆme de type op‰rateur. */ +/* Comme celui-ci peut ‰ventuellement Štre EOF, on doit utiliser un type entier, mŠme si */ +/* dans tous les autres cas un char aurait suffit. */ +typedef struct +{ + type_type_lex type; + union + { + char * alpha; /* champ pour coder la valeur d'un ALPHA */ + int num; /* champ pour coder la valeur d'un NUM */ + int op; /* champ pour coder la valeur d'un op‰rateur */ + } valeur; +} type_lexeme; + +/*********************************************************************************************/ +/* MACROS DE TRAVAIL SUR LES LEXEMES */ +/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ +/*********************************************************************************************/ + +/* Le bit 1 du type sert a indiquer la presence d'une valeur. Pour le positionner, on */ +/* utilise le masque d‰fini ci-dessous. */ +#define MASK_PRESENCE_VALEUR 1 +/* Les trois macros suivantes permettent respectivement de positionner, de lire et de retire */ +/* le masque de pr‰sence de valeur € un type de lexˆme */ +#define POS_MPV(type) ((type) | MASK_PRESENCE_VALEUR) +#define LIT_MPV(type) ((type) & MASK_PRESENCE_VALEUR) +#define RET_MPV(type) ((type) & ~MASK_PRESENCE_VALEUR) +/* Macros de lecture du type de base et du sous-type. */ +#define BASE_TYPE(ptrlex) (((ptrlex)->type) & 0x0E) /* Masque par 00001110 */ +#define SOUS_TYPE(ptrlex) (((ptrlex)->type) & 0xF0) /* Masque par 11110000 */ +/* Ces macros v‰rifient si le type (ou sous type) de lexeme est bien tp (ou stp). */ +#define TYPE_IS(ptrlex, tp) (((ptrlex)->type) & tp) +#define SOUS_TYPE_IS(ptrlex, stp) (SOUS_TYPE(ptrlex)==((stp) & 0xF0)) +/* Cette macro prend le sous-type et g‰nˆre le code complet correspondant. */ +#define CODE_TYPE(sst) (ALPHA | ((sst)<<4)) + +/* Comme l'allocation de lexˆmes sera une op‰ration trˆs fr‰quente, on pourra utiliser les */ +/* macros suivantes pour simplifier le code. */ + +#define ALLOC_LEX(lex) {\ + lex=((type_lexeme *) malloc(sizeof(type_lexeme)));\ + } + +#define FREE_LEX(lex) {\ + if (TYPE_IS((lex), ALPHA) && LIT_MPV((lex)->type))\ + free(((lex)->valeur).alpha);\ + free(lex);\ + } + +/* MŠme si le type lexˆme n'a pas de limite pour son champ valeur.alpha, certaines fonctions */ +/* peuvent avoir besoin d'allouer une taille maximale pour celui-ci, notament par exemple */ +/* lors de la lecture dans un fichier du lexˆme. Dans tous les cas, le tableau vers lequel */ +/* pointera le champ du lexˆme sera ajust‰ € sa longueur. */ +#define MAX_LONG_ALPHA 128 + +/* Macro de recopie d'un lexˆme vers un autre. */ +#define LEX_COPY(ptrl1, ptrl2) \ +{\ + (ptrl2)->type = (ptrl1)->type;\ + if (LIT_MPV((ptrl1)->type)) switch BASE_TYPE(ptrl1)\ + {\ + case ALPHA :\ + (ptrl2)->valeur.alpha=malloc(strlen((ptrl1)->valeur.alpha));\ + strcpy((ptrl2)->valeur.alpha, (ptrl1)->valeur.alpha);\ + break;\ + case NUM :\ + (ptrl2)->valeur.num=(ptrl1)->valeur.num;\ + break;\ + case OP :\ + (ptrl2)->valeur.op=(ptrl1)->valeur.op;\ + break;\ + }\ + else (ptrl2)->valeur.alpha=NULL;\ +} + +/*********************************************************************************************/ +/* TYPES DERIVES DU TYPE LEXEME */ +/* D‰finition du type lexˆme et des constantes qui s'y rapportent. */ +/*********************************************************************************************/ + +/* D‰finition du type file de lexeme. */ +typedef struct file_lexeme_tmp +{ + struct file_lexeme_tmp * suivant ; + type_lexeme * lexeme ; +} type_file_lexeme ; + +/*********************************************************************************************/ +/* */ +/* EXPORTATION DES POINTS D'ENTRÐE DU MODULE */ +/* */ +/*********************************************************************************************/ + +int fprint_lexeme(FILE * f, type_lexeme * l); +type_lexeme * get_lexeme(FILE *); +int strcasecmp(char * s1, char * s2); +int id_lexeme(type_lexeme *, type_lexeme *, int casse); +int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse); + + +#define lexcaseid(l1, l2) id_lexeme(l1, l2, 0) +#define lexid(l1, l2) id_lexeme(l1, l2, 1) +#define lexcaseftr(l, filtre) filtre_lexeme(l1, filtre, 0) +#define lexftr(l, filtre) filtre_lexeme(l, filtre, 1) + +#endif Index: minimips/trunk/gasm/include/synthetiseur.h =================================================================== --- minimips/trunk/gasm/include/synthetiseur.h (nonexistent) +++ minimips/trunk/gasm/include/synthetiseur.h (revision 14) @@ -0,0 +1,10 @@ +#ifndef M_SYNTHETISEUR_FLAG +#define M_SYNTHETISEUR_FLAG + +#include + +int synthese(); +void write_objet(FILE * f_obj); +void write_liste(FILE * f_lst, FILE * f_src); + +#endif Index: minimips/trunk/gasm/src/preprocesseur.c =================================================================== --- minimips/trunk/gasm/src/preprocesseur.c (nonexistent) +++ minimips/trunk/gasm/src/preprocesseur.c (revision 14) @@ -0,0 +1,839 @@ +/********************************************************************************************* + * * + * MODULE PREPROCESSEUR * + * * + * Ce module a pour but de fournir sur demande les lexemes correspondant au code * + * du fichiers .ASM avec lequel il a été initialisé. * + * * + * Il gere aussi l'inclusion de fichiers et l'expansion des macros. * + * * + * Points d'entrée : les fonctions push_lexemes() et pop_lexeme() * + * * + *********************************************************************************************/ + +/* Déclarations des symbols de ce module */ +#include "preprocesseur.h" + +/* Inclusion de la bibliothèque standard */ +#include +#include +#include +#include + +/* Inclusion des modules du projet utilisés */ +#include +#include +#include +#include + +#define SYNTAX_ERROR(CODE)\ + {\ + char * msg;\ + msg=gen_orig_msg();\ + DIALOGUE(msg, ligne_courante(), CODE);\ + free(msg);\ + } + +/********************************************************************************************* + * * + * Types spécifiques à ce module * + * * + *********************************************************************************************/ + +typedef struct type_pdf_tmp +{ + FILE * flux; + unsigned int ligne; /* numéro de la ligne en cours de lecture dans ce flux */ + char * nom_fich; /* nom du fichier en cours de lecture */ + char * nom_macro; /* nom de la macro si c'en est une pour eviter l'autoappel */ + struct type_pdf_tmp * prec; /* Flux entassé */ +} type_pdf; + +typedef struct type_pdm_tmp +{ + char * nom_macro; /* Lexeme dont la rencontre entraine une expansion */ + long def_pos; /* Position dans le fichier de définition */ + struct type_pdm_tmp * suiv; +} type_pdm; + +/********************************************************************************************* + * * + * Variables spécifiques à ce module * + * * + *********************************************************************************************/ + +/* Le pointeur vers l'élément en cours de lecture de la pile de flux */ +static type_pdf * ptr_pdf=NULL; + +/* La file de lexèmes où sont empilés les lexèmes "recrachés" par push_lex apres un pop_lex */ +static type_file_lexeme * ptr_pdl=NULL; + +/* Pointeur vers la fonction strcmp ou strcasecmp selon la casse_sens */ +static int (*fcmp)()=NULL; +#define CAR_EQ(a, b) ( casse_sens ? (a==b) : (tolower(a)==tolower(b)) ) + +/* Le pointeur vers le début de la pile de macros */ +static type_pdm * ptr_pdm=NULL; + +/* Fichier temporaire, contiendra toutes les définitions de macro du code ASM */ +FILE * fich_macro=NULL; + +/********************************************************************************************* + * * + * Fonctions non exportées * + * * + *********************************************************************************************/ + +static void empile_flux(char * nom_fich, char * nom_macro); +static void depile_flux(); +static type_pdm * is_macro(char *); +static type_lexeme * read_lexeme(); +static type_lexeme * get_true_lexeme(FILE * fich); +static void expanse_macro(type_pdm * ptr); + +void empile_flux(char * nom_fich, char * nom_macro) +{ + type_pdf * ptr; + char errmsg[]="preprocesseur(empile_flux)"; + + /* Vérifications anti-inclusions circulaires de macros et de fichiers */ + ptr=ptr_pdf; + while(ptr!=NULL) + { + if (nom_fich) + if (strcmp(nom_fich, ptr->nom_fich)==0) + { + SYNTAX_ERROR(S_CIRCULAR_FILE) + return; + } + if (nom_macro) + if (ptr->nom_macro && (*fcmp)(nom_macro, ptr->nom_macro)==0) + { + SYNTAX_ERROR(S_CIRCULAR_MACRO) + return; + } + ptr=ptr->prec; + } + + /* Allocation de la structure */ + ptr=(type_pdf *) malloc(sizeof(type_pdf)); + if (!ptr) DIALOGUE(errmsg, 0, F_ERR_MEM); + + /* Initialisation des champs */ + ptr->flux=NULL; + ptr->ligne=1; + ptr->nom_fich=NULL; + ptr->nom_macro=NULL; + ptr->prec=NULL; + + /* Ouverture du fichier */ + if (nom_fich) + { + ptr->flux=fopen(nom_fich, "rb"); + if (!ptr->flux) + { + char * msg; + msg=gen_orig_msg(); + DIALOGUE(msg, ptr_pdf->ligne, S_FICH_NON_TROUVE); + free(msg); + free(ptr); + return; + } + + /* Recopie des chaines transmises en parametres */ + ptr->nom_fich=(char *) malloc(strlen(nom_fich)); + if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); + strcpy(ptr->nom_fich, nom_fich); + } + if (nom_macro) + { + ptr->nom_macro=(char *) malloc(strlen(nom_macro)); + if (!ptr->nom_macro) DIALOGUE(errmsg, 0, F_ERR_MEM); + strcpy(ptr->nom_macro, nom_macro); + } + + /* Empilement */ + ptr->prec=ptr_pdf; + ptr_pdf=ptr; +} + +void depile_flux() +{ + type_pdf * ptr_sav; + ptr_sav=ptr_pdf->prec; + fclose(ptr_pdf->flux); + if (ptr_pdf->nom_macro) + free(ptr_pdf->nom_macro); + else + free(ptr_pdf->nom_fich); + free(ptr_pdf); + ptr_pdf=ptr_sav; +} + +/* Cette fonction cherche et retourne la position d'une macro dans la table. */ +type_pdm * is_macro(char * lex_alpha) +{ + type_pdm * ptr_mac; + for( ptr_mac=ptr_pdm; + ptr_mac && (*fcmp)(ptr_mac->nom_macro, lex_alpha); + ptr_mac=ptr_mac->suiv) + ; + return ptr_mac; +} + +/* Cette fonction renvoie le prochain lexeme valide disponible dans la pile de flux, * + * ou NULL, mais uniquement si plus auncun flux n'est ouvert (analyse terminée). * + * Elle s'occupe d'empiler les flux en cas d'inclusion, les dépile quand elle intercepte un * + * lexème EOF (qu'elle ne renvoie jamais). Enfin, elle détecte les macros et leur défs. */ +type_lexeme * read_lexeme() +{ + type_lexeme * ptr_lex; + static int germac=1; /* Permet de ne pas expansionner * + * certains bouts de code... */ + static int last_is_NL=0; /* On considère les NL en fin de ligne, * + * pas en début de ligne suivante... */ + + /* Aucun fichier ouvert => NULL */ + if (ptr_pdf==NULL) return NULL; + + if (last_is_NL) + { + last_is_NL=0; + ptr_pdf->ligne++; + } + + /* Retourne un lexème en filtrant les erreurs du formateurs */ + ptr_lex=get_true_lexeme(ptr_pdf->flux); + + /* Traitement des macros et sous-typage */ + if (TYPE_IS(ptr_lex, ALPHA)) /* si macro expansion, sinon sous-typage */ + { + int i; + char * p_regle, * p_alpha; + type_pdm * ptr_mac; + if (germac && (ptr_mac=is_macro(ptr_lex->valeur.alpha))!=NULL) + { + FREE_LEX(ptr_lex); + expanse_macro(ptr_mac); + ptr_lex=read_lexeme(); + } + else /* Test si c'est sous-typable */ + for(i=0; ivaleur.alpha; + while((*p_regle)!='\0') + { + if ((*p_regle)=='?') /* Remplacmt par un caractère */ + { /* les 2 car suiv sont les bornes */ + if ((*p_alpha)<*(++p_regle) || (*p_alpha)>*(++p_regle)) + break; + } + else if (!CAR_EQ(*p_regle, *p_alpha)) break; + p_regle++; + p_alpha++; + } + /* Si le lexème match la règle, on sous-type... */ + if ((*p_regle)=='\0' && (*p_alpha)=='\0') + { + /* La valeur du lexème n'est pas modifiée */ + ptr_lex->type = POS_MPV(regle_typage[i].code); + break; + } + } + } + + else + + /* Traitment des directives, des sauts de ligne et des fin de flux */ + if (TYPE_IS(ptr_lex, OP)) /* Traitements spéciaux */ + switch(ptr_lex->valeur.op) + { + case NL: /* Fin de ligne */ + last_is_NL=1; + break; + case EOF: /* Fin de fichier : on ne retourne pas de lexemes */ + FREE_LEX(ptr_lex) + depile_flux(); + ptr_lex=read_lexeme(); + break; + case DIR: /* Directive de Préprocesseur */ + { + type_lexeme * ptr_sauv_lex; + int pas_dir=1; /* Drapeau soupconneux */ + ptr_sauv_lex=ptr_lex; + germac=0; + ptr_lex=read_lexeme(); + if (TYPE_IS(ptr_lex, ALPHA)) + { + if (define_str && + (*fcmp)(ptr_lex->valeur.alpha, define_str)==0) + { /* Ajout d'1 macro */ + pas_dir=0; + FREE_LEX(ptr_lex); + ptr_lex=read_lexeme(); + if (!TYPE_IS(ptr_lex, ALPHA)) + SYNTAX_ERROR(S_NOM_MAC_INVALID) + else + ajoute_macro(ptr_lex->valeur.alpha + , ptr_pdf->flux); + } + else if (include_str && + (*fcmp)(ptr_lex->valeur.alpha,include_str)==0) + { /* Empliement d'un fichier */ + pas_dir=0; + FREE_LEX(ptr_lex); + ptr_lex=read_lexeme(); + if (!TYPE_IS(ptr_lex, ALPHA)) + SYNTAX_ERROR(S_NOM_INCFICH_INVALID) + else + empile_flux(ptr_lex->valeur.alpha + ,NULL); + } + else if (undef_str && + (*fcmp)(ptr_lex->valeur.alpha,undef_str)==0) + { /* Empliement d'un fichier */ + pas_dir=0; + FREE_LEX(ptr_lex); + ptr_lex=read_lexeme(); + if (!TYPE_IS(ptr_lex, ALPHA)) + SYNTAX_ERROR(S_NOM_MAC_INVALID) + else + suppress_macro(ptr_lex->valeur.alpha); + } + } + germac=1; + if (pas_dir) /* Si, en fait, ce n'était pas une dir */ + { + push_lexeme(ptr_lex); /* on sauve le lexème testé */ + ptr_lex=ptr_sauv_lex; /* on renvoie le lexème DIR */ + } + else + { + FREE_LEX(ptr_sauv_lex); + FREE_LEX(ptr_lex); + ptr_lex=read_lexeme(); + } + } + } + + return ptr_lex; +} + +/* Cette fonction sert d'interface entre le préprocesseur et le formateur. * + * Elle se charge d'afficher ses messages d'erreur et de lire le lexème suivant quand ce * + * dernier renvoie NULL. */ +type_lexeme * get_true_lexeme(FILE * fich) +{ + type_lexeme * p; + p=get_lexeme(fich); + if (p==NULL) + { + SYNTAX_ERROR(err_code) + p=get_true_lexeme(fich); + } + return p; +} + +/* Vide le flux jusqu'a la prochaine accolade ouvrante comprise, * + * Elle renvoie 0 si tout s'est bien passé, 1 si EOF est rencontré */ +int next_ACO(FILE * flux) +{ + int drap=0; + type_lexeme * p; + do + { + p=get_true_lexeme(flux); + if (TYPE_IS(p, OP)) + { + if (p->valeur.op==EOF) + { + FREE_LEX(p) + err_code=S_DEF_MACRO_EOF; + return 1; + } + if (p->valeur.op==ACO) drap=1; + } + FREE_LEX(p); + } + while(!drap); + return 0; +} + +/* Retourne le lexème suivant du flux, ou NULL s'il s'agit d'une accolade fermante ou d'EOF. * + * Il faut alors testé la variable err_code pour savoir s'il s'agit d'un e erreur ou pas. */ +type_lexeme * read_all_but_ACF(FILE * flux) +{ + type_lexeme * p; + p=get_true_lexeme(flux); + if (TYPE_IS(p,OP)) + { + if (p->valeur.op==EOF) + { + FREE_LEX(p) + err_code=S_DEF_MACRO_EOF; + return NULL; + } + if (p->valeur.op==ACF) + { + FREE_LEX(p) + err_code=NO_ERR; + return NULL; + } + } + return p; +} + +/* Fonction assurant le controle de la validité de la définition de la macro, son expansion * + * dans un nouveau buffer qu'elle empile avant de rendre la main. */ +void expanse_macro(type_pdm * ptr_mac) +#define FREE_TABLE\ + while(table)\ + {\ + parcourt_table=table->suiv;\ + FREE_LEX(table->nom_param);\ + if (table->val_param) FREE_LEX(table->val_param)\ + free(table);\ + table=parcourt_table;\ + } +{ + /* Structure servant au stockage temporaire des paramètres formels de la macro. */ + typedef struct type_file_param_tmp + { + type_lexeme * nom_param; + type_lexeme * val_param; + struct type_file_param_tmp * suiv; + } type_file_param; + + type_file_param * table=NULL, * parcourt_table=NULL, * ptr_new=NULL; + type_lexeme * ptr_lex=NULL, * ptr_lex_asm=NULL; + FILE * ftemp; + + /* Positionnement au début de la définition de la macro */ + fseek(fich_macro, ptr_mac->def_pos, SEEK_SET); + + /* Recherche du début du bloc de paramètres */ + if (next_ACO(fich_macro)) + { + SYNTAX_ERROR(err_code) + return; + } + + /* Lecture des paramètres et placement dans la table jusqu'à l'accolade fermante */ + while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) + { + /* Placement à la fin de la table */ + ptr_new=(type_file_param *) malloc(sizeof(type_file_param)); + if (!ptr_new) DIALOGUE("preprocesseur(expanse_macro)", 0, F_ERR_MEM); + ptr_new->nom_param=ptr_lex; + ptr_new->val_param=NULL; + ptr_new->suiv=NULL; + if (parcourt_table) + parcourt_table=parcourt_table->suiv=ptr_new; + else + table=parcourt_table=ptr_new; + /* Attention, pas de FREE_LEX car placement dans la table */ + } + if (err_code!=NO_ERR) + { + SYNTAX_ERROR(err_code) + FREE_TABLE + return; + } + + /* Recherche du début du bloc de syntaxe */ + if (next_ACO(fich_macro)) + { + SYNTAX_ERROR(err_code) + return; + } + + /* Parcourt la syntaxe macro, la valide, mémorise la valeur des paramètres */ + while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) + { + /* Parcourt de l'utilisation de la macro */ + ptr_lex_asm=get_true_lexeme(ptr_pdf->flux); + /* Recherche s'il s'agit d'un paramètre */ + for( parcourt_table=table; + parcourt_table!=NULL + && !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); + parcourt_table=parcourt_table->suiv); + /* Si c'est le cas, on mémorise sa valeur */ + if (parcourt_table) parcourt_table->val_param=ptr_lex_asm; + else + { + if (!id_lexeme(ptr_lex, ptr_lex_asm, casse_sens)) + { + err_code=S_MAC_NO_MATCH; + FREE_LEX(ptr_lex) + FREE_LEX(ptr_lex_asm) + break; /* La syntaxe n'est pas respectée */ + } + FREE_LEX(ptr_lex_asm) + } + FREE_LEX(ptr_lex) + } + if (err_code!=NO_ERR) + { + SYNTAX_ERROR(err_code) + FREE_TABLE + return; + } + + /* On controle que tous les paramètres ont une valeur, à présent */ + for( parcourt_table=table; + parcourt_table; + parcourt_table=parcourt_table->suiv) + if (parcourt_table->val_param==NULL) + { + SYNTAX_ERROR(S_MAC_TROP_PARAM) + FREE_TABLE + return; + } + + /* Positionnement au début de la séquence de remplacement */ + if (next_ACO(fich_macro)) + { + SYNTAX_ERROR(err_code) + FREE_TABLE + return; + } + + /* On expanse dans un buffer temporaire */ + ftemp=tmpfile(); + + /* Recopie de cette séquence en remplaçant les paramètres */ + while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) + { + /* Est-ce un paramètre ? */ + for( parcourt_table=table; + parcourt_table + && !id_lexeme(parcourt_table->nom_param, ptr_lex, casse_sens); + parcourt_table=parcourt_table->suiv); + if (parcourt_table==NULL) /* Si ce n'en est pas un */ + fprint_lexeme(ftemp, ptr_lex); + else + fprint_lexeme(ftemp, parcourt_table->val_param); + fputc(' ', ftemp); + FREE_LEX(ptr_lex); + } + + /* Nous n'avons à présent plus besoin de la table... */ + FREE_TABLE + if (err_code!=NO_ERR) + { + fclose(ftemp); + SYNTAX_ERROR(err_code) + return; + } + + /* Ouf ! Expansion réussie... */ + empile_flux(NULL, ptr_mac->nom_macro); + ptr_pdf->flux=ftemp; + rewind(ftemp); +} + +/********************************************************************************************* + * * + * Fonctions exportées * + * * + *********************************************************************************************/ + +/* Cette fonction empile le fichier spécifié après avoir testé son existence. * + * Elle prépare l'exécution du préprocesseur à travers pop_lexeme. * + * Elle renvoie 0 si le fichier a bien été empilé, 1 sinon. */ +int init_preprocesseur(char * fichinit) +{ + FILE * ftest; + char errmsg[]="preprocesseur(init_preprocesseur)"; + int i; + + /* Pointeur sur la fonction de comparaison adéquate */ + fcmp=casse_sens ? (void *) &strcmp : (void *) &strcasecmp; + + /* On test l'existence des directives */ + if (include_str!=NULL && active_list) + { + DIALOGUE(NULL, 0, W_NO_LIST_INC) + active_list=0; /* Liste d'assemblage non prévue pour fonctionner en cas */ + /* inclusions de fichiers. */ + } + + /* Controle de validité des regles de sous-typage une fois pour toutes. * + * La règle invalide est supprimée. */ + for(i=0; iflux=stdin; + ptr->ligne=1; + ptr->nom_macro=NULL; + ptr->prec=NULL; + + /* Recopie des chaines transmises en parametres */ + ptr->nom_fich=(char *) malloc(6); + if (!ptr->nom_fich) DIALOGUE(errmsg, 0, F_ERR_MEM); + strcpy(ptr->nom_fich, "stdin"); + + /* Empilement */ + ptr->prec=ptr_pdf; + ptr_pdf=ptr; + + if (active_list) + { + DIALOGUE(NULL, 0, W_NO_LIST_STDIN); + active_list=0; /* Liste d'assemblage non prévue pour fonctionner * + * en cas d'utilisation du stdin. */ + } + } + else + { + if ((ftest=fopen(fichinit, "rb"))==NULL) return 1; + fclose(ftest); + empile_flux(fichinit, NULL); + } + return 0; +} + +/* Cette fonction libère de la mémoire toutes les allocations du préprocesseur */ +void clear_preprocesseur() +{ + while(ptr_pdf) depile_flux(); + while(ptr_pdl) FREE_LEX(pop_lexeme()); + while(ptr_pdm) + { + type_pdm * p; + p=ptr_pdm->suiv; + free(ptr_pdm->nom_macro); + free(ptr_pdm); + ptr_pdm=p; + } +} + +/* Cette fonction renvoie le prochain lexeme valide disponible. Elle regarde d'abord dans la * + * pile de lexèmes. Si celle-ci est vide elle le prend dans la pile de flux, en appelant * + * read_lexeme(). * + * Un ptr NULL est renvoyé uniquement si plus auncun flux n'est ouvert (analyse terminée). */ +type_lexeme * pop_lexeme() +{ + if (ptr_pdl==NULL) /* Pas de lexemes stockés */ + { + return read_lexeme(); + } + else /* On dépile le lexème du tampon */ + { + type_file_lexeme * ptr_sav; + type_lexeme * ptr_lex; + + ptr_sav = ptr_pdl->suivant; + ptr_lex = ptr_pdl->lexeme; + free(ptr_pdl); + ptr_pdl=ptr_sav; + return ptr_lex; + } +} + +/* Sauvegarde des lexèmes qui ont déjà été extraits des flux */ +void push_lexeme(type_lexeme * ptr_recrach) +{ + type_file_lexeme * ptr_sav; + + ptr_sav = ptr_pdl; + ptr_pdl = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); + if (!ptr_pdl) DIALOGUE("preprocesseur(push_lexeme)", 0, F_ERR_MEM); + ptr_pdl->suivant=ptr_sav; + ptr_pdl->lexeme=ptr_recrach; +} + +/* Retourne la ligne où a été lu le dernier lexème ou 0 si pas de fichiers ouverts */ +int ligne_courante() +{ + type_pdf * p=ptr_pdf; + while(p && p->nom_macro) p=p->prec; + if (p==NULL) return 0; + return p->ligne; +} + +/* Indique les noms successifs des fichiers d'origine du lexème. * + * Ne pas oublier de faire free sur le pointeur renvoyé !!! */ +char * gen_orig_msg() +{ + char * text; + type_pdf * ptr; + int t_src=0, t_dest=MAX_LONG_ALPHA, t_sep; + + t_sep=strlen(sep_fich_inclus); + text=(char *) malloc(t_dest); + text[0]=0; + for(ptr=ptr_pdf; ptr; ptr=ptr->prec) + { + if (ptr->nom_macro) continue; + t_src+=strlen(ptr->nom_fich)+t_sep; + if (t_src >= t_dest) + { + t_dest=t_src+1; + text=(char *) realloc(text, t_dest); + } + strcat(text, ptr->nom_fich); + if (ptr->prec) strcat(text, sep_fich_inclus); + } + return text; +} + +/* La macro est supprimée de la table, mais pas du buffer contenant sa définition. */ +void suppress_macro(char * nom_macro) +{ + type_pdm * ptr_mac, * ptr_mac_prec; + + ptr_mac_prec=NULL; /* On sauvegarde le maillon où il faudra raccrocher les * + * macros en aval du maillon à supprimer. */ + for( ptr_mac=ptr_pdm; + ptr_mac && (*fcmp)(ptr_mac->nom_macro, nom_macro); + ptr_mac=ptr_mac->suiv) + ptr_mac_prec=ptr_mac; + + if (ptr_mac) + { + type_pdm * psav; + psav=ptr_mac->suiv; + free(ptr_mac->nom_macro); + free(ptr_mac); + if (ptr_mac_prec) + ptr_mac_prec->suiv=psav; + else + ptr_pdm=psav; + } + else + SYNTAX_ERROR(W_UNDEF_NOMAC) +} + +/* Ajoute une macro à la pile des macros */ +void ajoute_macro(char * nom_macro, FILE * flux_def) +{ + int c,i; + long pos; + char * org_msg = "preprocesseur(ajoute_macro)"; + + if (is_macro(nom_macro)) /* Cas d'une redéfinition */ + { + SYNTAX_ERROR(W_REDEF_MAC) + suppress_macro(nom_macro); + } + + fseek(fich_macro, 0L, SEEK_END); + pos=ftell(fich_macro); + + /* Recopie de la définition de la macro */ + for(i=0; i<3; c==ACF ? i++ : i) + { + if ((c=fgetc(flux_def))==EOF) + { + if (feof(flux_def)) + SYNTAX_ERROR(S_DEF_MACRO_EOF) + else + DIALOGUE(org_msg, 0, F_ERR_LECT); + break; + } + fputc(c, fich_macro); + if (c==NL && flux_def==ptr_pdf->flux) ptr_pdf->ligne++; + } + + /* Si la copie s'est bien passée... */ + if (i==3) + { + type_pdm * ptr; + ptr=(type_pdm *) malloc(sizeof(type_pdm)); + if (!ptr) DIALOGUE(org_msg, 0, F_ERR_MEM); + ptr->nom_macro=(char *) malloc(strlen(nom_macro)); + strcpy(ptr->nom_macro,nom_macro); + ptr->def_pos=pos; + ptr->suiv=NULL; + if (ptr_pdm) /* Ajout à la fin de la pile */ + { + type_pdm * ptr_fin; + ptr_fin=ptr_pdm; + while (ptr_fin->suiv) ptr_fin=ptr_fin->suiv; + ptr_fin->suiv=ptr; + } + else + ptr_pdm=ptr; + } +} + +/* Petite fonction utile pour consulter (dans le stderr) la liste des macros disponibles */ +void liste_table_macro(FILE * f) +{ + type_pdm * p; + type_lexeme * ptr_lex; + if (ptr_pdm) + err_code=B_MACRO_DISPO; + else + err_code=B_NO_MACRO; + fprintf(f, "-- %s\n", search_msg()); + + for(p=ptr_pdm; p!=NULL; p=p->suiv) + { + fprintf(f,"-- \t%s ",p->nom_macro); + fseek(fich_macro, p->def_pos, SEEK_SET); + /* Ecriture de la syntaxe */ + if (next_ACO(fich_macro) || next_ACO(fich_macro)) + { + SYNTAX_ERROR(err_code) + continue; + } + while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) + { + fprint_lexeme(f, ptr_lex); + FREE_LEX(ptr_lex) + } + if (err_code!=NO_ERR) + { + SYNTAX_ERROR(err_code) + continue; + } + fprintf(f, "\t\t"); + /* Ecriture de la séquence de remplacement */ + if (next_ACO(fich_macro)) + { + SYNTAX_ERROR(err_code) + continue; + } + while((ptr_lex=read_all_but_ACF(fich_macro))!=NULL) + { + fprint_lexeme(f, ptr_lex); + fputc(' ', f); + FREE_LEX(ptr_lex) + } + if (err_code!=NO_ERR) + { + SYNTAX_ERROR(err_code) + continue; + } + fprintf(f, "\n"); + } +} Index: minimips/trunk/gasm/src/analyseur.c =================================================================== --- minimips/trunk/gasm/src/analyseur.c (nonexistent) +++ minimips/trunk/gasm/src/analyseur.c (revision 14) @@ -0,0 +1,257 @@ +/*********************************************************************************************/ +/* MODULE ANALYSEUR */ +/* Ce module a pour but de parcourir le fichier assembleur en effectuant la correspondance */ +/* du code source avec la syntaxe acceptée par le langage. La lecture se fait lexème par */ +/* lexème en utilisant le préprocesseur. */ +/* Il se charge de générer la pile de précode qu sera utilisée par le syntéthiseur pour */ +/* générer le code final. */ +/*********************************************************************************************/ + +#include "analyseur.h" + +/* Inclusion des autres modules du projet utilisés. */ +#include +#include +#include +#include +#include +#include + +type_precode * file_precode=NULL, * fin_file_precode=NULL; + +int nprc_alloc=0; /* Compteur du nombre de précodes alloués. */ + +/* fonctions de filtrage et de comparaison des lexèmes (sensibles ou non à la casse). */ +#define filtre(l, filtre) filtre_lexeme(l, filtre, casse_sens) +#define compare_lexeme(l1, l2) (casse_sens ? lexid(l1, l2) : lexcaseid(l1,l2)) + +/* Pointeur sur la file de lexèmes composant l'argument courant. */ +static type_file_lexeme * ptr_arg=NULL; + +/* ajoute le lexème sur la pile de lexèmes locale (instruction en cours). */ +void push_local(type_lexeme * l) +{ + type_file_lexeme * nouv; + + nouv = (type_file_lexeme *) malloc(sizeof(type_file_lexeme)); + if (nouv==NULL) DIALOGUE("analyseur(push_local)", 0, F_ERR_MEM); + + nouv->suivant=ptr_arg; + nouv->lexeme=l; + ptr_arg=nouv; +} + +/* Fonction récursive d'analyse du code assembleur. */ +type_feuille * analyse_rec(type_noeud * n_cour) +{ + type_lexeme * l_cour; + type_noeud * fils_cour; + + l_cour=pop_lexeme(); /* Lecture d'un lexème par le préprocesseur. */ + fils_cour=n_cour->ptr_fils; + + while (fils_cour!=NULL && l_cour!=NULL) + { + if (filtre(l_cour, &(fils_cour->lexeme))) + { /* Les lexèmes sont compatibles. */ + type_feuille * rescur; + rescur=analyse_rec(fils_cour); + if (rescur!=NULL) + { /* Validation de la transition. */ + push_local(l_cour); /* Ajout dans la file locale. */ + return rescur; + } + } + /* La transition n'est pas validée. */ + fils_cour=fils_cour->ptr_frere; /* On passe à la transition suivante. */ + } + + push_lexeme(l_cour); /* Le lexème est rendu au préprocesseur. */ + return (n_cour->ptr_feuille); /* Si la feuille est valide, l'instruction l'est. */ +} + +/*********************************************************************************************/ +/* */ +/* Point d'entrée principal du module, fonction d'analyse. Les données analysées sont celles */ +/* fournies par le préprocesseur qui doit être préalablement initialisé. */ +/* */ +/*********************************************************************************************/ + +/* Macro d'initialisation d'un nouveau précode. */ +#define INIT_PRECODE(precode) \ +{\ + ALLOC_PREC(precode)\ + precode->fichier_orig=f_orig;\ + precode->ligne_orig=l_orig;\ + precode->pco=pco;\ +} + +/* Macro d'ajout d'un précode en queue de la file. */ +#define EMPILE_PRECODE(precode) \ +{\ + if (file_precode==NULL)\ + {\ + file_precode=precode;\ + fin_file_precode=precode;\ + }\ + else\ + {\ + fin_file_precode->suivant=precode;\ + fin_file_precode=precode;\ + }\ +} + +int analyse() +{ + int err=0; + char * msg_orig = "analyseur(analyse)"; + type_lexeme * lex; + + pco = 0; /* Initialisation du pseudo compteur ordinal. */ + + if (seplex == NULL) + { /* Utilisation du séparateur par défaut. */ + DIALOGUE(NULL, 0, W_SEPLEX_INIT); + seplex=(type_lexeme *) malloc(sizeof(type_lexeme)); + if (seplex==NULL) DIALOGUE(msg_orig, 0, F_ERR_MEM); + seplex->type = POS_MPV(OP); + seplex->valeur.op = NL; + } + + while ((lex = pop_lexeme())!=NULL) /* Analyse jusqu'à la fin du fichier. */ + { + int l_orig = ligne_courante(); /* On conserve la ligne de l'instruction. */ + char * f_orig = gen_orig_msg(); /* On conserve le fichier d'origine. */ + type_feuille * feuille; + + push_lexeme(lex); /* On rend le lexème au prépreocesseur. */ + feuille = analyse_rec(root); /* Analyse de l'instruction suivante. */ + + if (feuille==NULL) + { /* L'instruction n'a pas été reconnue. */ + type_lexeme * lex_depile; + type_precode * err_pcd; + INIT_PRECODE(err_pcd); + err++; /* Détection d'une erreur de syntaxe. */ + err_pcd->erreur=S_SYN_ERR; /* Mise à jour du code d'erreur. */ + EMPILE_PRECODE(err_pcd); /* Empilage du lexème erreur. */ + + DIALOGUE(f_orig, l_orig, S_SYN_ERR); + + while ((lex_depile=pop_lexeme())!=NULL + && !compare_lexeme(lex_depile, seplex)) + { /* On recherche le prochain lexème de séparation. */ + FREE_LEX(lex_depile); + } + if (lex_depile!=NULL) FREE_LEX(lex_depile); /* Efface le "seplex". */ + } + else + { /* L'instruction a été validée. Génération du précode. */ + type_precode * pcd; + int p2f[MAX_FONCTIONS]; /* tableau des fonctions de seconde passe. */ + int i; + INIT_PRECODE(pcd); + + /* Recopie de la file des lexèmes ayant validé l'instruction. */ + pcd->param = ptr_arg; + + /* Recopie du masque de la feuille. */ + if (feuille->mask_primaire==NULL) pcd->mask=NULL; + else + { + ALLOC_MASK(pcd->mask); + if (pcd->mask==NULL) + DIALOGUE(msg_orig, 0, F_ERR_MEM); + pcd->mask->valeur=feuille->mask_primaire->valeur; + pcd->mask->taille=feuille->mask_primaire->taille; + } + + for (i=0 ; inbr_func ; i++) + { /* Tentative d'application des fonctions de l'adaptateur. */ + type_mask * res = (feuille->ptr_func)[i](ptr_arg); + + /* Différents cas de réponse de l'adaptateur. */ + switch (eval_code) + { + case EVAL_REUSSIE : /* Evalutation réussie. */ + if (pcd->mask==NULL) + { + pcd->mask=res; /* Pas encore de masque. */ + res=NULL; /* Evite que le masque soit vidé. */ + break; + } + if (res==NULL) break; /* Rien à faire. */ + if (res->taille==pcd->mask->taille) + { /* On ajoute le nouveau masque. */ + pcd->mask->valeur|=res->valeur; + break; + } + /* Le masque retourné est incompatible. */ + DIALOGUE(f_orig, l_orig, S_FUN_ERR); + CLEAR_PRECODE(pcd); /* Le précode est une erreur. */ + pcd->erreur=S_FUN_ERR; + err++; + break; + case EVAL_IMPOSSIBLE : /* Fonction de seconde passe. */ + p2f[(int)(pcd->nbr_func)++]=i; + break; + case EVAL_ERREUR : /* Erreur de l'adaptateur/Syntaxe. */ + affiche_message(f_orig, l_orig); + err++; + CLEAR_PRECODE(pcd); /* Le précode est une erreur. */ + pcd->erreur=err_code; + break; + default : /* Erreur de l'adaptateur. */ + DIALOGUE(f_orig, l_orig, S_ADAP_ERR); + CLEAR_PRECODE(pcd); + pcd->erreur=S_ADAP_ERR; + err++; + break; + } + if (res!=NULL) FREE_MASK(res); /* Suppression du masque. */ + } + + if (pcd->nbr_func!=0) /* Recopie des pointeurs vers les p2f. */ + { /* Il reste des fonctions de seconde passe. */ + pcd->func=(type_ptr_fgm*) /* On crée le tableau. */ + malloc((pcd->nbr_func)*sizeof(type_ptr_fgm)); + for (i=0; inbr_func; i++) + { /* On recopie les fonctions de seconde passe. */ + (pcd->func)[i]=(feuille->ptr_func)[p2f[i]]; + } + } + else + { /* Plus de fonctions de seconde passe, effacement des arguments. */ + pcd->func = NULL; + FREE_ARGS(pcd->param); + } + + if ((pcd->mask==NULL || pcd->mask->taille==0) && pcd->func==NULL + && pcd->erreur==NO_ERR) + { /* On supprime le précode s'il est vide. */ + FREE_PRECODE(pcd); + } + else + { + EMPILE_PRECODE(pcd); + if (pcd->mask!=NULL) pco+=pcd->mask->taille; + } + + ptr_arg=NULL; /* Réinitialisation du pointeur de file de lexèmes. */ + } + } + return err; +} + +/* Cette fonction libère les structures de précode allouées lors de l'analyse. Les données */ +/* non écrites par le synthétiseur seront perdues. */ +void clear_analyseur() +{ + while (file_precode!=NULL) + { + type_precode * pcd=file_precode; + file_precode=pcd->suivant; + FREE_PRECODE(pcd); + } + fin_file_precode=NULL; +} Index: minimips/trunk/gasm/src/parametres.c =================================================================== --- minimips/trunk/gasm/src/parametres.c (nonexistent) +++ minimips/trunk/gasm/src/parametres.c (revision 14) @@ -0,0 +1,20 @@ +#include "parametres.h" + +#include + +#include +#include + +/* Variables d'environnement. */ +int active_list=1; /* Activation de la lsite d'assemblage. */ +int pco=0; /* Définition du pseudo compteur ordinal. */ + +/* Variables positionnées par le préparateur à la lecture du fichier syntaxe. */ +int casse_sens = 1; /* Sensibilité de la syntaxe à la casse. */ +char * fich_macro_def=NULL; /* Nom du fichier de macros par défaut. */ +char * define_str=NULL; /* Chaine de caractères pour la déclaration de macros. */ +char * include_str=NULL; /* Chaine de caractères pour la directive d'inclusion. */ +char * undef_str=NULL; /* Chaine de caractères pour la suppression de macros. */ +type_lexeme * seplex=NULL; /* Lexème séparateur entre les différentes instructions. */ +int nbr_sous_types=0; /* Nombre de sous types admis par la syntaxe. */ +type_paire *regle_typage=NULL; /* Table des règles et des codes de chaque sous-type. */ Index: minimips/trunk/gasm/src/formateur.c =================================================================== --- minimips/trunk/gasm/src/formateur.c (nonexistent) +++ minimips/trunk/gasm/src/formateur.c (revision 14) @@ -0,0 +1,453 @@ +#include "formateur.h" + +/* Autres modules utilises */ + +#include +#include + +/* Modules de la bibliotheque standard */ + +#include +#include +#include +#include + +/*********************************************************************************************/ +/* COMPOSITION DES ENSEMBLES DE CARACTERES */ +/* Tout autre caractere rencontre dans la source sera inconnu et renverra une erreur lors de */ +/* sa lecture. */ +/*********************************************************************************************/ + + +/* D‰finition de constantes pour la taille de chaque ensemble existant. */ +int taille_ensemble[NBR_ENS] = {taille_lettre, taille_chiffre, taille_prefixe, + taille_sep_explicite, taille_sep_invisible, taille_commentaire}; + +/* D‰finition des ensembles */ + +int ens_lettre[taille_lettre] = + { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', + 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '_', '.', '?', '$' + }; + +int ens_chiffre[taille_chiffre] = + { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', + 'b', 'c', 'd', 'e', 'f' + }; + +int ens_prefixe[taille_prefixe] = + { + '@', '%', '&', '+', '-', '\'' + }; + +int ens_sep_explicite[taille_sep_explicite] = + { + ACF, ACO, NL, DP, PF, PO, PS, MS, DIR, VIR, EOF + }; + +int ens_sep_invisible[taille_sep_invisible] = + { + '\t', ' ', '\r' + }; + +int ens_commentaire[taille_commentaire] = + { + ';', '\n' + }; + +/* D‰finition du tableau regroupant tous les ensembles qui est export‰. */ +int *ensemble[NBR_ENS] = {ens_lettre, ens_chiffre, ens_prefixe, + ens_sep_explicite, ens_sep_invisible, ens_commentaire}; + +/* D‰finition de la table des correspondances des caractˆres d'‰chappement. */ +char car_ech[] = "nt\\"; +char seq_ech[] = "\n\t\\"; + + +/*********************************************************************************************/ +/* MACROS DE TRAVAIL SUR LES ENSEMBLES */ +/* Pour ne pas avoir utiliser de r‰f‰rence directe aux ensembles de caractˆres, on y accˆde */ +/* au travers de macros d‰finies ici. En cas de changement, le code des autres modules */ +/* n'aura donc pas € Štre modifi‰. */ +/*********************************************************************************************/ + +/* G‰nˆre le masque caract‰ristique de l'ensemble */ +#define MASK_ENSEMBLE(ensbl) (1<= '0') && (car <= '9')) ? (car - '0') :\ + ((car >= 'a') && (car <= 'f')) ? (10 + car - 'a') :\ + ((car >= 'A') && (car <= 'F')) ? (10 + car - 'A') :\ + 0) + +/* Macro de d‰finition des bases des entiers en fonction de leur pr‰fixe. */ +#define VAL_BASE(prefixe) (\ + (prefixe == '\'') ? 0 :\ + (prefixe == '@') ? 16 :\ + (prefixe == '%') ? 2 :\ + (prefixe == '&') ? 8 :\ + 10\ + ) + +/* Macro de d‰finition du signe des entiers en fonction de leur pr‰fixe. */ +#define SGN_INIT(prefixe) (\ + (prefixe == '-') ? -1 :\ + 1\ + ) + + +/*********************************************************************************************/ +/* FONCTIONS DE TRAVAIL SUR LES ENSEMBLES */ +/* Fonctions publi‰es pour simplifier le traitement des ensembles. */ +/*********************************************************************************************/ + +char type_car(int c) +/* Cette fonction recherche dans tous les ensembles le caractˆre c et positionne un bit pour */ +/* chaque ensemble auquel il appartient. */ +{ + char type=0; + int i, j, flag; + + for(i=0; itype=POS_MPV(ALPHA); + (ptr_lex->valeur).alpha=(char*) malloc(i+1); + strcpy((ptr_lex->valeur).alpha, memo_string); + return ptr_lex; + } + else + { + err_code=S_ALPHA_INVALID; + return NULL; + } + } + + + if (typ & (MASK_ENSEMBLE(chiffre) | MASK_ENSEMBLE(prefixe))) + { /* Caractere numerique (‰ventuellement pr‰fixe, signe, etc.) */ + int val, sgn, base, car_in, typ_in, err_sel = 0; + + /* On m‰morise la valeur et le type du caractˆre en entr‰e pour le cas o· ce */ + /* choix ne serait pas le bon. */ + car_in = car; + typ_in = typ; + + val = CAR_TO_NUM(car); /* Initialisation de la valeur de l'entier. */ + sgn = SGN_INIT(car); /* initialistaion du signe de l'entier. */ + base = VAL_BASE(car); /* initialisation de la base d'aprˆs le pr‰fixe. */ + + if (car==CAR_ENC) /* Cas d'un entier de type caractˆre. */ + { + long pos=ftell(f); + char * car_trouve; + int err_ech=0; + LIT_CAR; + if (car=='\\') /* D‰but de s‰quence d'‰chappement. */ + { + LIT_CAR; + if ((car_trouve=strchr(car_ech, car))!=NULL) + car=*(seq_ech+(car_trouve-car_ech)); + else err_ech=1; + } + val=car; + LIT_CAR; + if (err_ech || car!=CAR_ENC) + { + err_sel=1; + car=car_in; + typ=typ_in; + fseek(f,pos-ftell(f),SEEK_CUR); + } + else + { + ALLOC_LEX(ptr_lex); + if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); + ptr_lex->type=POS_MPV(NUM); + (ptr_lex->valeur).num=val; + return ptr_lex; + } + } + + if (typ & MASK_ENSEMBLE(prefixe)) + { /* Si on a affaire € un pr‰fixe, le chargement du premier chiffre est */ + /* obligatoire mais il peut Štre s‰par‰ du chiffre par des s‰parateurs */ + /* invisibles. */ + LIT_SIGNIFICATIF; + val = CAR_TO_NUM(car); + if (!((typ & MASK_ENSEMBLE(chiffre)) && (val < base))) + { /* Erreur de format ou de s‰lection, caractˆre n'est pas un pr‰fixe */ + ungetc(car, f); + car = car_in; + typ = typ_in; + err_sel = 1; + } + } + + if (!err_sel) /* Uniquement s'il n'y a pas eu d'erreur de s‰lection. */ + { + LIT_CAR; + while (typ & MASK_ENSEMBLE(chiffre)) + { + int chiffre_val = CAR_TO_NUM(car); + if (chiffre_val >= base) + { + err_code=S_INT_INVALID; + return NULL; /* chiffre valide ? */ + } + val *= base; + val += chiffre_val; + LIT_CAR; + } + + /* Si le dernier caractˆre ‰tait un s‰parateur ou d‰but commentaire. */ + if ((typ & (MASK_ENSEMBLE(sep_explicite)|MASK_ENSEMBLE(sep_invisible))) + || (car == DEBUT_COM)) + { + ungetc(car, f); + ALLOC_LEX(ptr_lex); + if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); + ptr_lex->type=POS_MPV(NUM); + (ptr_lex->valeur).num=val*sgn; + return ptr_lex; + } + else + { + err_code=S_INT_INVALID; + return NULL; + } + } + } + + + if (typ & MASK_ENSEMBLE(sep_explicite)) + { /* Lire lexeme operateur. */ + ALLOC_LEX(ptr_lex); + if (ptr_lex==NULL) DIALOGUE("formateur(get_lexeme)", 0, F_ERR_MEM); + ptr_lex->type=POS_MPV(OP); + (ptr_lex->valeur).op=car; + return ptr_lex; + } + + + if (car == DEBUT_COM) + { /* Epuiser le commentaire. */ + do + { + LIT_CAR; + } + while(car!=FIN_COM && car!=EOF); + if (!IGNORE_FIN_COMMENT) ungetc(car, f); + return get_lexeme(f); + } + + /* Le caractˆre rencontr‰ n'‰tait pas dans le bon contexte, erreur. */ + err_code=S_ERR_FORMAT; + return NULL; +} + + +/* Renvoie 1 si l est compatible avec filtre */ +int filtre_lexeme(type_lexeme * l, type_lexeme * filtre, int casse) +{ + int (* compare)(); + int v_comp=0; + + compare = casse ? (void *) &strcmp : (void *) &strcasecmp; + + /* Si les lexˆmes n'ont pas le mŠme type de base le filtre ne passe pas. */ + if (BASE_TYPE(l) != BASE_TYPE(filtre)) return 0; + /* Si l n'est pas du mŠme sous type que filtre le filtre ne passe pas. */ + if (SOUS_TYPE(filtre)!=0 && SOUS_TYPE(l)!=SOUS_TYPE(filtre)) return 0; + + if (!LIT_MPV(l->type) || !LIT_MPV(filtre->type)) v_comp=0; + else switch (BASE_TYPE(l)) + { + case ALPHA : if ((*compare) (l->valeur.alpha, + filtre->valeur.alpha)) + v_comp=0; + else v_comp=1; + break; + case NUM : if (l->valeur.num != filtre->valeur.num) + v_comp=0; + else v_comp=1; + break; + case OP : if (l->valeur.op != filtre->valeur.op) + v_comp=0; + else v_comp=1; + break; + default : v_comp=0; + break; + } + + /* Si les deux lexˆmes n'ont pas la mŠme valeur le filtre ne passe pas. */ + if (LIT_MPV(filtre->type) && (!LIT_MPV(l->type) || !v_comp)) return 0; + return 1; +} + +/* Renvoie 1 si les 2 lexˆmes sont ‰gaux */ +int id_lexeme(type_lexeme * l1, type_lexeme * l2, int casse) +{ + int (* compare)(); + + if (l1->type != l2->type) return 0; /* Lexˆmes de type, sstype ou bit de val diff. */ + if (!LIT_MPV(l1->type) && !LIT_MPV(l2->type)) return 1; /* Aucun lexˆme n'a de val. */ + + compare = casse ? (void *) &strcmp : (void *) &strcasecmp; + + switch BASE_TYPE(l1) + { + case ALPHA : if (!(*compare)(l1->valeur.alpha, l2->valeur.alpha)) + return 1; + break; + case NUM : if (l1->valeur.num == l2->valeur.num) + return 1; + break; + case OP : if (l1->valeur.op == l2->valeur.op) + return 1; + break; + default : return 0; + break; + } + return 0; +} + + +/*********************************************************************************************/ +/* */ +/* POINT D'ENTREE SECONDAIRE DU MODULE */ +/* */ +/* void print_lexeme(type_lexeme * l) */ +/* */ +/* Cette fonction affiche un lexˆme € l'‰cran avec formatage suivant son type et la pr‰sence */ +/* ‰ventuelle d'une valeur. */ +/* */ +/*********************************************************************************************/ + +int fprint_lexeme(FILE * f, type_lexeme * l) +{ +#define ALPHA_VAL (l->valeur.alpha) +#define NUM_VAL (l->valeur.num) +#define OP_VAL (l->valeur.op) + long int pos=ftell(f); + + switch (BASE_TYPE(l)) + { + case ALPHA : if (LIT_MPV(l->type)) fprintf(f, "%s", ALPHA_VAL); + break; + case NUM : if (LIT_MPV(l->type)) fprintf(f, "%d", NUM_VAL); + break; + case OP : if (LIT_MPV(l->type)) fprintf(f, "%c", OP_VAL); + break; + } + return ftell(f)-pos; +} + +/********************************************************************************************* + * * + * POINT D'ENTREE SECONDAIRE DU MODULE * + * * + * int strcasecmp(const char *, const char *) * + * * + * Redefinit cette fonction car elle n'est pas posix. * + * * + * Renvoie un nombre (<, =, >) € z‰ro si s1 est (<, =, >) € s2. * + * * + *********************************************************************************************/ + +int strcasecmp(char * s1, char * s2) +{ + for(; tolower(*s1)==tolower(*s2); s1++, s2++) + if (*s1=='\0') return 0; + return (*s1-*s2); +} + Index: minimips/trunk/gasm/src/synthetiseur.c =================================================================== --- minimips/trunk/gasm/src/synthetiseur.c (nonexistent) +++ minimips/trunk/gasm/src/synthetiseur.c (revision 14) @@ -0,0 +1,270 @@ +#include "synthetiseur.h" + +/* Autres modules utilisés par le synthétiseur. */ +#include +#include +#include +#include +#include +#include + +/* Cette fonction convertit un masque en talbeau de char équivalent. */ +/* La chaine étant allouée dynamiquement, il conviendra de la libérer après utilisation. */ +char * cnv_mask_str(type_mask * m) +{ + char * res; + int i; + type_valeur_mask v; + if (m==NULL) return NULL; + res = malloc((m->taille)*sizeof(char)); + if (res==NULL) DIALOGUE("synthetiseur(cnv_mask_str)", 0, F_ERR_MEM); + v=m->valeur; + for (i=m->taille-1 ; i>=0 ; i--) + { + res[i]= (v & 0xFF); + v>>=8; + } + return res; +} + +/* numéro de la colonne où l'on écrit le texte du code source dans la liste d'assemblage. */ +#define COL_TEXT (2*sizeof(type_valeur_mask)+10) + +/* Cette fonction recopie le flux srce dans dest jusqu'à la ligne fin exclue, sachant que le */ +/* flux source est supposé positionné à la ligne debut. */ +/* Le flux srce sera positionné au début de la ligne fin après l'exécution de la fonction. */ +/* La fonction retourne le numéro de la ligne à laquelle se trouve effectivement le flux. */ +/* Au début de chaque ligne, la fonction écrit son numéro puis \t suivi de COL_TEXT espaces. */ +int recopie(FILE * srce, FILE * dest, int debut, int fin) +{ + while (debutsuivant ) + { + int i; + + pco=pcd->pco; + + for (i=0 ; inbr_func ; i++) + { + type_mask * res; + res = (pcd->func)[i](pcd->param); + + switch (eval_code) + { /* Application du masque généré par la fonction de seconde passe. */ + case EVAL_REUSSIE : + if (res==NULL || res->taille==0) break; + if (pcd->mask==NULL || res->taille!=pcd->mask->taille) + { /* On a défini un nouveau masque incompatible. */ + DIALOGUE(pcd->fichier_orig, + pcd->ligne_orig, S_FUN_ERR); + /* On remplace le précode par une erreur. */ + CLEAR_PRECODE(pcd); + pcd->erreur=S_FUN_ERR; + err++; + break; + } + /* Le nouveau masque est ajouté. */ + pcd->mask->valeur|=res->valeur; + break; + case EVAL_IMPOSSIBLE : /* En seconde passe, erreur. */ + case EVAL_ERREUR : + affiche_message(pcd->fichier_orig, pcd->ligne_orig); + err++; + /* On remplace le précode par une erreur. */ + CLEAR_PRECODE(pcd); + pcd->erreur=err_code; + break; + default : + DIALOGUE(pcd->fichier_orig, + pcd->ligne_orig, S_ADAP_ERR); + CLEAR_PRECODE(pcd); + pcd->erreur=S_ADAP_ERR; + err++; + break; + } + if (res!=NULL) FREE_MASK(res); + } + /* On libère l'espace alloué pour le tableau des fonctions de seconde passe. */ + if (pcd->func!=NULL) free(pcd->func); + pcd->func=NULL; + pcd->nbr_func=0; + } + return err; +} + + +/* Cette fonction est utilisée pour écrire dans un flux le code binaire généré et */ +/* actuellement enregistré dans la pile de précode. Il faut au préalable exécuter la seconde */ +/* passe faute de quoi le code sera incomplet. */ +void write_objet(FILE * f_obj) +{ + type_precode * pcd; + int i; + int local_pco=-1; + long c_head=-5; /* Utilisé pour mémoriser la position de l'entête du bloc courant. */ + long n_head; /* Position du nouvel entête de bloc. */ + int addimp; + int taille; + + if (f_obj==NULL) DIALOGUE("synthetiseur(write_objet)", 0, F_FLUX_NULL); + + for (pcd=file_precode ; pcd!=NULL ; pcd=pcd->suivant) + { + if (pcd->erreur==NO_ERR && pcd->mask!=NULL) + { /* On ne s'occupe ici que des précodes générant du code. */ + char * code_bin; + + if (pcd->pco!=local_pco) + { /* Ecriture d'un nouvel entête de bloc en complétion du précédent. */ + n_head=ftell(f_obj); + addimp=pcd->pco; + if (c_head!=-5) /* Il ne s'agit pas du premier bloc. */ + { /* Ecriture de la taille du bloc que l'on ferme. */ + /* Calcul de la taille du bloc terminé. */ + taille=n_head-c_head-4; + /* Ecriture de la taille au bon emplacement. */ + fseek(f_obj, c_head+2, SEEK_SET); + for (i=1 ; i>=0 ; i--) + fputc((taille>>(8*i)) & 0xFF, f_obj); + /* Retour au nouveau bloc. */ + fseek(f_obj, n_head, SEEK_SET); + } + /* Ecriture de l'adresse d'implantation. */ + for (i=1 ; i>=0 ; i--) fputc((addimp>>(8*i)) & 0xFF , f_obj); + /* Ecriture de 0 pour la taille du prochain bloc. */ + for (i=0; i<2; i++) fputc(0, f_obj); + c_head=n_head; + local_pco=pcd->pco; + } + + /* On écrit le masque du précode courant dans le fichier. */ + code_bin=cnv_mask_str(pcd->mask); /* Conversion du masque. */ + /* Insertion des caractères dans le fichier objet. */ + for (i=0 ; imask->taille ; i++) fputc(code_bin[i], f_obj); + free(code_bin); /* On libère la chaine allouée. */ + + local_pco+=pcd->mask->taille; /* Avancement du pco. */ + } + } + + /* Ecriture de la taille du dernier bloc. */ + n_head=ftell(f_obj); + /* Calcul de la taille du bloc terminé. */ + taille=n_head-c_head-4; + /* Ecriture de la taille au bon emplacement. */ + fseek(f_obj, c_head+2, SEEK_SET); + for (i=1 ; i>=0 ; i--) fputc((taille>>(8*i)) & 0xFF, f_obj); + /* Retour au nouveau bloc, en fin de fichier. */ + fseek(f_obj, n_head, SEEK_SET); +} + + +/* Cette fonction est utilisée pour écrire dans un flux la liste d'assemblage correspondant */ +/* aux données enregistrée dans la pile de précode. Il faut au préalable exécuter la seconde */ +/* passe faute de quoi le code sera incomplet. */ +void write_liste(FILE * f_lst, FILE * f_src) +{ + int ligne=1; /* Ligne courante dans le fichier source. */ + type_precode * pcd_cour=file_precode; + + if (f_lst==NULL) DIALOGUE("synthetiseur(write_liste)", 0, F_FLUX_NULL); + + while (pcd_cour!=NULL) + { + int lbloc; /* Numéro de ligne de l'instruction que l'on va traiter. */ + int pco_ecrit=0; /* Drapeau de controle de l'écriture du pco. */ + long col=0; /* Colonne courante dans la ligne actuelle du fichier. */ + type_precode * pcd; + + lbloc=pcd_cour->ligne_orig; /* Ligne courante dans la source. */ + + /* On recopie la portion de code jusqu'à la ligne ayant généré le précode. */ + ligne=recopie(f_src, f_lst, ligne, lbloc); + + if (ligne!=lbloc) + { /* Le fichier source a changé par rapport aux lignes mémorisées. */ + DIALOGUE(NULL, 0, W_SRCE_MOD); + return; + } + + fprintf(f_lst, "%d\t", ligne); /* Ecriture du numéro de la ligne en cours. */ + col=ftell(f_lst); /* On mémorise la colonne de départ. */ + + for (pcd=pcd_cour ; pcd!=NULL && pcd->ligne_orig==lbloc ; pcd=pcd->suivant) + { /* On parcourt tous les précodes de la ligne. */ + if (pcd->erreur==NO_ERR && pcd->mask!=NULL) + { + char str[3*sizeof(type_taille_mask)+3]; + + if (!pco_ecrit) /* Le pco n'est écrit que sur les lignes */ + { /* générant du code et ce une seule fois. */ + fprintf(f_lst, "%04X ", pcd->pco); + pco_ecrit=1; + } + + sprintf(str, "%%0%dX", pcd->mask->taille*2); + fprintf(f_lst, str, pcd->mask->valeur); + } + } + + /* On complète avec des espaces pour aligner le code source. */ + for ( col=ftell(f_lst)-col ; colligne_orig==lbloc) + { /* Ecriture des éventuelles erreurs du bloc. */ + if (pcd_cour->erreur!=NO_ERR) + { /* On affiche le message d'erreur dans la liste d'assemblage. */ + int i; + err_code=pcd_cour->erreur; + fputc('\t', f_lst); + for (i=0; isuivant; + } + } + + /* Recopie de la fin du fichier source dans la liste d'assemblage. */ + while (!feof(f_src)) + { + int i; + fprintf(f_lst, "%d\t", ligne++); + for (i=0; i +#include + +#include + +int err_code=0; + +int verbose=0; + +/* Texte de l'aide en ligne. */ +char help[]="\n\ +Assembleur pour le microprocesseur miniMIPS version 1.0\n\ +Utilisation : asmips [options] [fichier]\n\ +\n\ + Exemple : asmips -vo a.obj -l a.lst source.asm\n\ +\n\ +Options disponibles :\n\ +\n\ + -v active le mode verbeux\n\ +\n\ + -n désactive la liste d'assemblage\n\ +\n\ + -o nom_fichier nom du fichier de sortie, par défaut a.obj\n\ +\n\ + -p assemble vers la sortie standard\n\ +\n\ + -l nom_fichier nom du fichier pour la liste d'assemblage\n\ + par défaut, a.lst est utilisé\n\ +\n\ + -s nom_fichier nom du fichier de syntaxe, par défaut \'Syntaxe\'\n\ +\n\ + -m nom_fichier nom du fichier de macros par défaut, contenant les\n\ + pseudo-instructions de l'assembleur\n\ +\n\ +Notes d'utilisation :\n\ +\n\ + Si aucun fichier d'entrée n'est spécifié, asmips tente d'assembler\n\ + l'entrée standard. Ce mode n'est pas encore compatible avec la liste\n\ + d'assemblage qui sera donc automatiquement désactivée.\n\ +\n\ + La sélection du fichier de macro en ligne de commande est prioritaire\n\ + par rapport au fichier spécifié par la syntaxe qui sera donc ignoré.\n\ +\n\ +Merci de signaler les éventuels bugs à :\n\ +\n\ + shangoue@enserg.fr\n\ + lmouton@enserg.fr\n\ +"; + + +typedef struct +{ + int code; + char * chaine; +} type_paire_msg; + +static type_paire_msg message[] = + +{{ NO_ERR, "Pas d'erreur trouvée" } +/* Erreurs génériques : */ +,{ F_FLUX_NULL, "Tentative de lecture/écriture dans un flux NULL" } +,{ F_ERR_LECT, "Erreur de lecture imprévisible dans le flux" } +,{ F_ERR_OUV, "Erreur d'ouverture du fichier" } +,{ F_ERR_MEM, "Erreur d'allocation (mémoire insuffisante ?)" } +/* Erreurs du formateur : */ +,{ S_ERR_FORMAT, "Mauvaise utilisation d'un caractère" } +,{ S_CAR_INVALID, "Caractère non reconnu" } +,{ S_ALPHA_LONG, "Lexème de type ALPHA trop long" } +,{ S_ALPHA_INVALID, "Caractère non valide dans l'identificateur" } +,{ S_INT_INVALID, "Caractère non valide dans l'entier" } +/* Erreurs du préprocesseur : */ +,{ S_CIRCULAR_FILE, "Inclusion circulaire de fichier(s)" } +,{ S_CIRCULAR_MACRO, "Inclusion circulaire de macro" } +,{ S_FICH_NON_TROUVE, "Impossible d'ouvrir le fichier indiqué" } +,{ S_DEF_MACRO_EOF, "Fin du fichier inattendue lors de la définition de macro" } +,{ S_USE_MACRO_EOF, "Fin du fichier inattendue lors de l'utlisation d'une macro" } +,{ S_NOM_MAC_INVALID, "Nom de la macro dans sa déclaration invalide" } +,{ S_NOM_INCFICH_INVALID, "Nom du fichier à inclure invalide" } +,{ S_MAC_NO_MATCH , "L'utilisation de la macro est incompatible avec sa définition" } +,{ S_MAC_TROP_PARAM, "Paramètre(s) non utlisé(s) dans la macro" } +/* Erreurs du préparateur : */ +,{ S_ERR_DCL, "Déclaration incorrecte" } +,{ S_DCL_VIDE, "Déclaration d'instruction vide" } +,{ S_DCL_NON_TERM, "Déclaration d'instruction non terminée '}' manquante" } +,{ S_REDEF_INS, "Instruction déjà existante, la nouvelle déclaration sera ignorée" } +,{ S_BAD_PROP, "Propriété incorrecte" } +,{ S_BAD_VAL, "Valeur de la propriété incorrecte" } +,{ S_BAD_FUN, "Fonction non définie" } +,{ S_BAD_ARG, "Mauvais argument pour la commande SET" } +,{ S_BAD_SST_DEC, "Déclaration du nombre de sous-types absente ou insuffisante" } +,{ S_DEP_FUNC_NB, "Dépassement de la capacité d'enregistrement des fonctions" } +,{ S_DEP_SST, "Dépassement de la capacité de codage des sous-types" } +,{ S_SEC_SST_DEC, "Répétition de la commande SSTNUM non autorisée" } +/* Erreurs de l'analyseur : */ +,{ S_SYN_ERR, "Erreur de syntaxe" } +,{ S_FUN_ERR, "Masques incompatibles dans la définition d'une instruction" } +,{ S_ADAP_ERR, "Erreur dans la valeur de retour d'une fonction de l'adaptateur" } +/* Erreurs de l'adaptateur : */ +,{ S_FUN_INAP, "Fonction génératrice de masque inapplicable" } +,{ S_ARG_INCOMP, "Inadéquation des arguments avec une fonction de l'adaptateur" } +,{ S_SIGNED_TL, "Entier trop long pour le codage signé sur les bits disponibles" } +,{ S_UNSIGNED_TL, "Entier trop long pour le codage non signé sur les bits disponibles" } +,{ S_UNSIGNED_EXPECTED, "Entier non signé attendu" } +,{ S_REDEF_ETIQ, "Redéfinition d'étiquette non prise en compte" } +,{ S_BAD_ETIQ, "Etiquette inexistante" } +,{ S_ADR_INCONNUE, "L'adresse d'implantation est indéterminée" } +,{ S_BAD_ALIGN, "Saut à une étiquette non alignée sur 32 bits" } +,{ S_TOO_FAR, "Saut à une adresse n'appartenant pas à la région courante de 256 Mo" } +/* Erreurs du synthetiseur. */ + +/* Warnings : */ +,{ W_SEPLEX_INIT, "Valeur du séparateur d'instruction non initialisé dans fichier Syntaxe" } +,{ W_REGLE_TYPAGE, "Regle de sous-typage invalide dans le fichier Syntaxe; elle est ignorée" } +,{ W_ARG_INC, "Argument incorrect" } +,{ W_FICH_DEF_MACRO, "Le fichier des macros par défaut n'a pas été trouvé" } +,{ W_MACRO_MANQ, "Auncun fichier des macros par défaut chargé" } +,{ W_NO_LIST_INC, "L'utilisation des inclusions désactive la liste d'assemblage" } +,{ W_NO_LIST_STDIN, "La lecture dans le flux standard interdit la liste d'assemblage" } +,{ W_NO_SYNTAX, "Pas de fichier de syntaxe" } +,{ W_SRCE_MOD, "Flux source modifié. Echec de la création de la liste d'assemblage" } +,{ W_REDEF_MAC, "Redéfinition d'une macro" } +,{ W_UNDEF_NOMAC, "Tentative de suppression d'une macro non définie" } +,{ W_REDEF_CODE, "Réutilisation du code, les sous-types seront confondus" } +,{ W_REDEF_SST, "Nom de sous-type existant, seule la première définition sera accessible" } + +/* Commentaires */ + +/* Main */ +,{ B_INIT_SYNTAX, "Initialisation de la syntaxe de l'assembleur..." } +,{ B_INIT_MACRO, "Chargement des pseudo-instructions..." } +,{ B_LECT_SRC, "Lecture des sources..." } +,{ B_STR_OBJ, "Enregistrement du fichier objet..." } +,{ B_STR_LST, "Creation de la liste d'assemblage..." } +,{ B_ERR_REP, "Rapport d'erreurs :" } +,{ B_NBR_ERR_SYN, "\tErreurs détectées lors de la synthèse :" } +,{ B_NBR_ERR_ANA, "\tErreurs détectées lors de l'analyse :" } +,{ B_SYN, "Synthèse..." } +,{ B_ANA, "Analyse du code..." } +/* Preparateur */ +,{ B_CASSE, "Basculement en mode sensible à la casse" } +,{ B_NOCASSE, "Basculement en mode insensible à la casse" } +,{ B_MAC_DEF, "Détection d'un fichier de pseudo-instructions par défaut dans la syntaxe" } +,{ B_INIT_D, "Activation du support des macros" } +,{ B_INIT_U, "Activation du support de la supression de macros" } +,{ B_INIT_I, "Activation du support de l'inclusion de fichiers" } +,{ B_INIT_SEP, "Initialisation du séparateur d'instructions" } +,{ B_PREP_SST, "Préparation pour l'ajout de sous-types" } +,{ B_ADD_SST, "Nouveau sous-type détecté" } +/* Preprocesseur */ +,{ B_NO_MACRO, "Aucune macro définie." } +,{ B_MACRO_DISPO, "Macros disponibles :" } +/* Adaptateur */ +,{ B_TABLAB, "Table des étiquettes :" } + +/* Terminateur de la table, ne pas supprimer ! */ +,{ 0, NULL } +}; + +char sep_fich_inclus[] = " inclus depuis "; + +char * search_msg() +{ + type_paire_msg * pmsg=message; + while(pmsg->chaine!=NULL) + { + if (pmsg->code==err_code) return pmsg->chaine; + pmsg++; + } + return message->chaine; +} + +void affiche_message(char * origine, int ligne) +{ + if (err_code>=1000) /* Warning */ + { + if (origine && ligne) + fprintf(stderr, "Attention ! \'%s\' : %d : %s.\n" + , origine, ligne, search_msg()); + else if (origine) + fprintf(stderr, "Attention ! \'%s\' : %s.\n", origine, search_msg()); + else + fprintf(stderr, "Attention ! %s.\n", search_msg()); + } + else if (err_code < 0) /* Commentaire */ + { + if (verbose) + { + if (origine && ligne) + fprintf(stderr, "-- \'%s\' : %d : %s\n" + , origine, ligne, search_msg()); + else if (origine) + fprintf(stderr, "-- %s %s\n", search_msg(), origine); + else + fprintf(stderr, "-- %s\n", search_msg()); + } + } + else if (err_code<100) /* Fatal Error */ + { + if (origine && ligne) + fprintf(stderr, "Erreur fatale ! \'%s\' : %d : %s.\n" + , origine, ligne, search_msg()); + else if (origine) + fprintf(stderr, "Erreur fatale ! \'%s\' : %s.\n" + , origine, search_msg()); + else + fprintf(stderr, "Erreur fatale ! %s.\n", search_msg()); + exit(err_code); + } + else /* Erreur de Syntaxe */ + { + if (origine && ligne) + fprintf(stderr, "\'%s\' : %d : %s.\n" + , origine, ligne, search_msg()); + else if (origine) + fprintf(stderr, "\'%s\' : %s.\n", origine, search_msg()); + else + fprintf(stderr, "%s.\n", search_msg()); + } +} + +void display_help() +{ /* fonction d'affichage de l'aide en ligne. */ + fprintf(stderr, help); +} Index: minimips/trunk/gasm/src/adaptateur.c =================================================================== --- minimips/trunk/gasm/src/adaptateur.c (nonexistent) +++ minimips/trunk/gasm/src/adaptateur.c (revision 14) @@ -0,0 +1,795 @@ +/* Module adaptateur */ +#include "adaptateur.h" + +/* Autres modules du projet utilisés. */ +#include +#include +#include +#include +#include + +/* Autres modules de la bibliothèque standard. */ +#include +#include + + +/*********************************************************************************************/ +/* */ +/* POINT D'ENTRÉE PRINCIPAL DU MODULE : RETOURNE LES POINTEURS VERS LES FGM. */ +/* */ +/*********************************************************************************************/ + +/* Type utilisé pour enregistrer les paires fonction, pointeur. */ +typedef struct +{ + char * nom; + type_mask *(*fun)(); +} type_paire_fonction; + +/* Variable contenant les paires nom de fonction , pointeur. */ +extern type_paire_fonction index_nf[]; + +/* Cette fonction retourne le pointeur sur la fonction correspondant au nom. */ +type_mask *(*alias(char * nom_fonction))() +{ + type_paire_fonction * courant; + + for (courant=index_nf ; courant->nom!=NULL ; courant++) + if (!strcasecmp(courant->nom, nom_fonction)) return courant->fun; + return NULL; +} + +/* Fonctions de l'adaptateur utiles pour la "fermeture" de adaptateur. */ +void fprint_lablist(FILE * flux); /* fonction d'écriture de la liste des labels. */ +void clear_lablist(); /* fonction de nettoyage de la liste des labels. */ + +/* Cette fonction sera appelée à la fin de la synthèse du code assembleur. */ +/* Elle peut écrire dans la liste d'asemblage. */ +void write_data(FILE * f_lst) +{ /* Attention, le flux peut être NULL. */ + if (f_lst!=NULL) fprint_lablist(f_lst); +} + +/* Cette fonction doit libérer les variables allouées dynamiquement par l'adaptateur. */ +void clear_adaptateur() +{ + clear_lablist(); +} + +/* Drapeau pour le résultat de l'évaluation d'une fonction génératrice de masque. */ +/* Ce drapeau peut prendre trois valeur selon le résultat de l'évaluation : */ +/* EVAL_REUSSIE : l'évaluation a aboutit. */ +/* EVAL_IMPOSSIBLE : l'évaluation n'est pas possible dans les conditions actuelles. */ +/* EVAL_ERREUR : la fonction n'est pas applicable dans ce contexte. */ +/* En plus de positionner ce drapeau, les fgm doivent spécifier le code de l'erreur dans la */ +/* variable err_code du module erreur. */ +int eval_code; + + +/*********************************************************************************************/ +/* */ +/* FONCTIONS AUXILLIAIRES SPÉCIFIQUES A LA SYNTAXE. */ +/* */ +/*********************************************************************************************/ + +/* Définition des sous-types spécifiés dans le fichier Syntaxe. */ +#define REG (CODE_TYPE(1)) + +/* Macro de comparaison de chaine sensible ou non à la casse. */ +#define compare_chaine(c1, c2) (casse_sens ? strcmp(c1,c2):strcasecmp(c1,c2)) + +/* Définition de la liste des étiquettes. */ +typedef struct tmp_file_lbl +{ + char * label; + int valeur; + struct tmp_file_lbl * suivant; +} type_file_lbl; + +/* Initialisation de la liste des étiquettes. */ +type_file_lbl * label=NULL; + +/* Retourne le nième élément de la liste des arguments ou NULL s'il n'existe pas. */ +type_lexeme * argn(type_file_lexeme * args, int n) +{ + if (n<0) return NULL; + while (args!=NULL) + { + if (n==0) return args->lexeme; + args = args->suivant; + n--; + } + return NULL; +} + +/* Cette fonction ajoute l'étiquette dans la liste. */ +/* Si l'étiquette existe déjà, l'ajout est impossible et le code 0 est retourné. */ +/* En cas de succès, la fonction renvoie 1. */ +int add_label(char * nom) +{ + type_file_lbl * nlbl; + type_file_lbl * courant; + + /* On vérifie que l'étiquette n'est pas déjà présente dans la liste. */ + for (courant = label ; courant!=NULL ; courant=courant->suivant) + if (!compare_chaine(courant->label, nom)) return 0; + + /* Allocation d'un nouveau maillon pour enregistrer la nouvellle étiquette. */ + nlbl = (type_file_lbl *) malloc(sizeof(type_file_lbl)); + if (nlbl==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); + (nlbl->label) = (char *) malloc(strlen(nom)*sizeof(char)); + if (nlbl->label==NULL) DIALOGUE("adaptateur(add_label)", 0, F_ERR_MEM); + /* Ajout de l'étiquette à la pile d'étiquettes. */ + strcpy(nlbl->label, nom); + nlbl->suivant=label; + nlbl->valeur=pco; + label=nlbl; + return 1; +} + +/* Fonction de recherche d'une étiquette dans la liste. */ +/* Si l'étiquette n'existe pas, le code -1 est retourné, sinon on renvoie sa valeur. */ +int find_address_label(char * nom) +{ + type_file_lbl * courant=label; + while (courant!=NULL) + { + if (!compare_chaine(courant->label, nom)) + return courant->valeur; + courant = courant->suivant; + } + return -1; +} + +/* Fonction d'écriture de la liste des étiquettes dans un flux. */ +void fprint_lablist(FILE * flux) +{ + type_file_lbl * courant; + if (flux==NULL) DIALOGUE("adaptateur(fprint_lablist)", 0, F_FLUX_NULL); + err_code=B_TABLAB; + fprintf(flux, "%s\n", search_msg()); + for (courant=label ; courant!=NULL ; courant=courant->suivant) + fprintf(flux, "%s\t%04X\n", courant->label, courant->valeur); +} + +/* Fonction de nettoyage de la liste des étiquettes. */ +void clear_lablist() +{ + type_file_lbl * courant=label; + while (courant!=NULL) + { + type_file_lbl * tmp=courant; + courant=courant->suivant; + free(tmp->label); + free(tmp); + } +} + +/* Fonctions de recodage des entiers sur un nombre quelconque de bits. */ + +/* Entiers signés. */ +/* La valeur signée est prise dans l'entier r et le masque généré retourné. */ +/* n spécifie le nombre de bits à utiliser pour coder l'entier. */ +/* En cas de dépassement de la capacité sur n bits signés, le err_code est positionné. */ +type_valeur_mask code_signed(int r, int n) +{ + long int max_taille=0; + int i; + + /* Crée un masque contenant n-1 1 : 0..01..1 */ + for (i=0; imax_taille) + { + err_code=S_SIGNED_TL; + return 0; + } + max_taille=(max_taille<<1)+1; /* On inclut le bit de signe dans le masque */ + r&=max_taille; /* On tronque le nombre. */ + err_code=NO_ERR; + return (type_valeur_mask) r; +} + +/* Entiers non signés. */ +/* La valeur signée est prise dans l'entier r et le masque généré retourné. */ +/* n spécifie le nombre de bits à utiliser pour coder l'entier. */ +/* En cas de dépassement de la capacité sur n bits non signés, le err_code est positionné. */ +type_valeur_mask code_unsigned(unsigned int r, int n) +{ + long unsigned int max_taille=0; + int i; + + /* Crée un masque contenant n 1 : 0..01..1 */ + for (i=0; imax_taille) + { + err_code=S_UNSIGNED_TL; + return 0; + } + r&=max_taille; /* On tronque. */ + err_code=NO_ERR; + return (type_valeur_mask) r; +} + + +/* Cette fonction crée un masque avec les 5 bits codant l'argument i (numéro de registre) */ +/* et les positionne à la position j dans le masque de taille tmo. */ +type_mask * rij(type_file_lexeme * args, int i, int j, type_taille_mask tmo) +{ + type_lexeme * l; + type_mask * res; + type_valeur_mask msk; + + l=argn(args, i); + /* test de la cohérence du type de l'opérande */ + if (l==NULL || !TYPE_IS(l, ALPHA) || !SOUS_TYPE_IS(l, REG) || !LIT_MPV(l->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + msk = l->valeur.alpha[1]-'0'; + if (strlen(l->valeur.alpha)==3) + { + msk*=10; + msk+=l->valeur.alpha[2]-'0'; + } + msk<<=j; + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(rij)",0, F_ERR_MEM); + res->valeur=msk; + res->taille=tmo; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +/* Cette fonction crée un masque avec les 5 bits codant l'argument i (valeur immédiate) */ +/* et les positionne à la position 6 dans le masque de taille tmo. */ +type_mask * shamt(type_file_lexeme * args, int i) +{ + type_lexeme * l; + type_mask * res; + type_valeur_mask v; + + l=argn(args, i); + /* test de la cohérence du type de l'opérande */ + if (l==NULL || !TYPE_IS(l, NUM) || !LIT_MPV(l->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + v=code_unsigned(l->valeur.num, 5); + + if (err_code!=NO_ERR) + { + eval_code=EVAL_ERREUR; + return NULL; + } + + v<<=6; + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(shamt)",0, F_ERR_MEM); + res->valeur=v; + res->taille=4; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +/*********************************************************************************************/ +/* */ +/* DEFINITION DES FONCTIONS GENERATIRCES DE MASQUE ET EXPORTATION DES POINTEURS. */ +/* */ +/*********************************************************************************************/ + +/* Fonctions de codage des numéros de registre dans différentes conditions. */ +/* err_code est positionné par la fonction rij. */ +type_mask * r1s(type_file_lexeme * args) +{ return rij(args, 1, 21, 4); } +type_mask * r3s(type_file_lexeme * args) +{ return rij(args, 3, 21, 4); } +type_mask * r5s(type_file_lexeme * args) +{ return rij(args, 5, 21, 4); } +type_mask * r1t(type_file_lexeme * args) +{ return rij(args, 1, 16, 4); } +type_mask * r3t(type_file_lexeme * args) +{ return rij(args, 3, 16, 4); } +type_mask * r5t(type_file_lexeme * args) +{ return rij(args, 5, 16, 4); } +type_mask * r1d(type_file_lexeme * args) +{ return rij(args, 1, 11, 4); } +type_mask * r3d(type_file_lexeme * args) +{ return rij(args, 3, 11, 4); } +type_mask * r5d(type_file_lexeme * args) +{ return rij(args, 5, 11, 4); } + +/* Codage du shift amount lu à la position 5 de la liste d'args */ +type_mask * sa5(type_file_lexeme * args) +{ return shamt(args, 5); } + +/* Fonction d'ajout d'une étiquette dans la table (déclaration). */ +type_mask * ajoute_etiquette(type_file_lexeme * args) +{ + type_lexeme * lex=argn(args, 0); + /* Si le lexème n'est pas un ALPHA ou s'il n'a pas de valeur. */ + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { /* Argument incorrect. */ + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + if (!add_label(lex->valeur.alpha)) + { /* L'étiquette existe déjà dans la liste. Impossible de l'ajouter. */ + err_code=S_REDEF_ETIQ; + eval_code=EVAL_ERREUR; + return NULL; + } + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return NULL; +} + + +/* Fonction de création d'un masque de zéros pour atteindre un adresse congrue à 4. */ +type_mask * complete_zeros(type_file_lexeme * args) +{ + type_mask * res; + int n=pco%4; + /* Calcule le nombre de zéros manquants pour s'aligner sur une adresse congrue à 4. */ + if (n==0) n=4; + n=4-n; + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(complete_zeros)", 0, F_ERR_MEM); + res->taille=n; + res->valeur=0; + + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + + +type_mask * org_int(type_file_lexeme * args) +{ + type_lexeme * p; + + p=argn(args, 1); + if (p==NULL || !TYPE_IS(p, NUM)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + pco=p->valeur.num; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return NULL; +} + + +type_mask * org_label(type_file_lexeme * args) +{ + type_lexeme * p; + int adr; + + p=argn(args, 1); + if (p==NULL || !TYPE_IS(p, ALPHA)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + adr=find_address_label(p->valeur.alpha); + + if (adr==-1) + { /* Tentative d'implantation à une adresse inconnue. */ + err_code=S_ADR_INCONNUE; + eval_code=EVAL_ERREUR; + return NULL; + } + + pco=adr; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return NULL; +} + + +type_mask * add_equ(type_file_lexeme * args) +{ + FILE * f; + type_lexeme * p1, * p2; + + p1=argn(args, 0); + p2=argn(args, 2); + if (p1==NULL || p2==NULL || !TYPE_IS(p1, ALPHA) + || (!TYPE_IS(p2, ALPHA) && !TYPE_IS(p2, NUM))) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + f=tmpfile(); + if (f==NULL) DIALOGUE("adaptateur(add_equ)",0, F_FLUX_NULL); + + if (TYPE_IS(p2, ALPHA)) + { + fprintf(f, " {} {} { %s } ", p2->valeur.alpha); + } + else + { + fprintf(f, " {} {} { %d } ", p2->valeur.num); + } + + rewind(f); + ajoute_macro(p1->valeur.alpha, f); + fclose(f); + + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return NULL; +} + +/* Codage de l'entier de rang i dans la liste d'arguments dans les 16 bits de poids faible. */ +type_mask * immediate16(type_file_lexeme * args, int i) +{ + type_lexeme * lex; + type_mask * res; + type_valeur_mask v; + + lex=argn(args, i); + + if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + if (lex->valeur.num<0) v=code_signed(lex->valeur.num, 16); + else v=code_unsigned(lex->valeur.num, 16); + + if (err_code!=NO_ERR) + { + eval_code=EVAL_ERREUR; + return NULL; + } + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(cimm)", 0, F_ERR_MEM); + res->taille=4; + res->valeur=v; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +/* Acquisistion de la valeur immediate de l'instruction */ +type_mask * imm1(type_file_lexeme * args) +{ return immediate16(args, 1); } +type_mask * imm3(type_file_lexeme * args) +{ return immediate16(args, 3); } +type_mask * imm5(type_file_lexeme * args) +{ return immediate16(args, 5); } + +/* retourne le masque contenant la valeur val sur n octets. */ +type_mask * dc(int val, int n) +{ + type_mask * res; + type_valeur_mask v; + + if (val<0) v=code_signed(val, n*8); + else v=code_unsigned(val, n*8); + + if (err_code!=NO_ERR) + { + eval_code=EVAL_ERREUR; + return NULL; + } + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(dcb)", 0, F_ERR_MEM); + res->taille=n; + res->valeur=v; + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +/* Retourne le masque pour un entier sur 8 bits en premier argument (numérique) */ +type_mask * dcb_int(type_file_lexeme * args) +{ + type_lexeme * lex; + + lex=argn(args, 1); + if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + return dc(lex->valeur.num, 1); +} + +/* Retourne le masque pour un entier sur 8 bits en premier argument (étiquette) */ +type_mask * dcb_alpha(type_file_lexeme * args) +{ + type_lexeme * lex; + int adr; /* Adresse correspondant à l'étiquette. */ + + lex=argn(args, 1); + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + adr = find_address_label(lex->valeur.alpha); + + if (adr==-1) + { + err_code=S_BAD_ETIQ; + eval_code=EVAL_IMPOSSIBLE; + return NULL; + } + + return dc(adr, 1); +} + + +/* Retourne le masque pour un entier sur 32 bits en premier argument (numérique) */ +type_mask * dcw_int(type_file_lexeme * args) +{ + type_lexeme * lex; + + lex=argn(args, 1); + if (lex==NULL || !TYPE_IS(lex, NUM) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + return dc(lex->valeur.num, 4); +} + +/* Retourne le masque pour un entier sur 32 bits en premier argument (étiquette) */ +type_mask * dcw_alpha(type_file_lexeme * args) +{ + type_lexeme * lex; + int adr; /* Adresse correspondant à l'étiquette. */ + + lex=argn(args, 1); + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + adr = find_address_label(lex->valeur.alpha); + + if (adr==-1) + { + err_code=S_BAD_ETIQ; + eval_code=EVAL_IMPOSSIBLE; + return NULL; + } + + return dc(adr, 4); +} + +/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible + * contiennent l'offset signé tenant sur 18 bits correspondant au lexème étiquette de rang i + * dans la liste de paramètres mais donc les 2 bits de poids faible ont été tronqués. */ +type_mask * offset(type_file_lexeme * args, int i) +{ + type_valeur_mask valres; + int diff; + type_mask * res; + type_lexeme * lex; + + lex = argn(args, i); + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + diff=find_address_label(lex->valeur.alpha); + if (diff==-1) + { + err_code=S_BAD_ETIQ; + eval_code=EVAL_IMPOSSIBLE; + return NULL; + } + diff=diff-(pco); /* Le PCO ne tient pas encore compte des 4 octets du masque */ + if (diff & 3) /* Vérif que l'étiquette est bien aligné sur 32 bits */ + { + err_code=S_BAD_ALIGN; + eval_code=EVAL_ERREUR; + return NULL; + } + + valres=code_signed(diff>>2, 16); + if (err_code!=NO_ERR) /* Si le déplacement est sur plus de 16 bits... */ + { + eval_code=EVAL_ERREUR; + return NULL; + } + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); + res->taille=4; + res->valeur=valres; + + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +type_mask * offset3(type_file_lexeme * args) +{ return offset(args, 3); } +type_mask * offset5(type_file_lexeme * args) +{ return offset(args, 5); } + +/* Fonction de création d'un masque de 32 bits dont les 16 bits de poids faible + * contiennent la valeur signée tenant sur 16 bits correspondant au lexème étiquette de rang i + * dans la liste de paramètres. */ +type_mask * val_etiq(type_file_lexeme * args, int i) +{ + type_valeur_mask valres; + int diff; + type_mask * res; + type_lexeme * lex; + + lex = argn(args, i); + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + diff=find_address_label(lex->valeur.alpha); + if (diff==-1) + { + err_code=S_BAD_ETIQ; + eval_code=EVAL_IMPOSSIBLE; + return NULL; + } + + valres=code_unsigned(diff, 16); + if (err_code!=NO_ERR) /* Si le déplacement est sur plus de 16 bits... */ + { + eval_code=EVAL_ERREUR; + return NULL; + } + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); + res->taille=4; + res->valeur=valres; + + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +type_mask * val_etiq3(type_file_lexeme * args) +{ return val_etiq(args, 3); } +type_mask * val_etiq5(type_file_lexeme * args) +{ return val_etiq(args, 5); } + +/* Fonction de création d'un masque de 32 bits dont les 26 bits de poids faible + * contiennent l'adresse dans la région courante de 256 Mo tenant sur 28 bits correspondant + * au lexème étiquette de rang i dans la liste de paramètres mais donc les 2 bits de poids + * faible ont été tronqués. */ +type_mask * absolu(type_file_lexeme * args, int i) +{ + type_valeur_mask valres; + int diff; + type_mask * res; + type_lexeme * lex; + + lex = argn(args, i); + if (lex==NULL || !TYPE_IS(lex, ALPHA) || !LIT_MPV(lex->type)) + { + err_code=S_ARG_INCOMP; + eval_code=EVAL_ERREUR; + return NULL; + } + + diff=find_address_label(lex->valeur.alpha); + if (diff==-1) + { + err_code=S_BAD_ETIQ; + eval_code=EVAL_IMPOSSIBLE; + return NULL; + } + if ((pco >> 26) != (diff >> 26)) /* Test que le saut ne change pas de région */ + { + err_code=S_TOO_FAR; + eval_code=EVAL_ERREUR; + return NULL; + } + diff=diff & 0xFFFFFFF; /* On ne conserve que les 28 bits de poids faible */ + if (diff & 3) /* Vérif que l'étiquette est bien aligné sur 32 bits */ + { + err_code=S_BAD_ALIGN; + eval_code=EVAL_ERREUR; + return NULL; + } + valres=code_signed(diff>>2, 26); /* L'offset est codé sur 26 bits */ + if (err_code!=NO_ERR) + { + eval_code=EVAL_ERREUR; + return NULL; + } + + ALLOC_MASK(res); + if (res==NULL) DIALOGUE("adaptateur(offset)", 0, F_ERR_MEM); + res->taille=4; + res->valeur=valres; + + err_code=NO_ERR; + eval_code=EVAL_REUSSIE; + return res; +} + +type_mask * absolu1(type_file_lexeme * args) +{ return absolu(args, 1); } + +/*********************************************************************************************/ +/* Définition du tableau des correspondances entre nom et fonction de génération de masque. */ +/*********************************************************************************************/ + +type_paire_fonction index_nf[] = + { {"R1S" , &r1s } /* Codage des opérandes */ + , {"R3S" , &r3s } + , {"R5S" , &r5s } + , {"R1T" , &r1t } + , {"R3T" , &r3t } + , {"R5T" , &r5t } + , {"R1D" , &r1d } + , {"R3D" , &r3d } + , {"R5D" , &r5d } + , {"IMM1" , &imm1 } + , {"IMM3" , &imm3 } + , {"IMM5" , &imm5 } + , {"ETIQ3" , &val_etiq3 } + , {"ETIQ5" , &val_etiq5 } + , {"SA5" , &sa5 } + + , {"OFFSET3" , &offset3 } /* Création des masques d'adresse */ + , {"OFFSET5" , &offset5 } + , {"ABSOLU1" , &absolu1 } + + , {"Ajoute_Etiquette" , &ajoute_etiquette } /* Ajoute éiquette */ + + , {"Complete_Zeros" , &complete_zeros } /* Gestion des directives */ + , {"AddEqu" , &add_equ } + , {"Dcb_Int" , &dcb_int } + , {"Dcb_Alpha" , &dcb_alpha } + , {"Dcw_Int" , &dcw_int } + , {"Dcw_Alpha" , &dcw_alpha } + , {"Org_Int" , &org_int } + , {"Org_Label" , &org_label } + + , {NULL , NULL } + }; + Index: minimips/trunk/gasm/src/preparateur.c =================================================================== --- minimips/trunk/gasm/src/preparateur.c (nonexistent) +++ minimips/trunk/gasm/src/preparateur.c (revision 14) @@ -0,0 +1,786 @@ +/*********************************************************************************************/ +/* MODULE PREPARATEUR */ +/* ce module a pour but de lire le fichier Syntaxe du programme et de générer l'arbre des */ +/* lexèmes qui lui correspond. */ +/* */ +/* Le seul point d'accès de ce module est la fonction init_arbre qui reçoit le nom du */ +/* fichier Syntaxe à utiliser. */ +/* */ +/*********************************************************************************************/ + +#include "preparateur.h" + +/* Inclusion des modules de la bibliothèque standard. */ +#include +#include + +/* Inclusion des autres modules utilisés du projet. */ +#include +#include +#include +#include +#include + +/* Ces macros sont utilisées pour les comparaisons de chaines. Leur valeur détermine la */ +/* sensibilité ou non du préparateur à la casse lors de la lecture du fichier Syntaxe. */ +#define string_comp strcasecmp +#define lexeme_comp lexcaseid + +type_noeud *root = NULL; /* Définition de la racine de l'arbre des lexèmes. */ + +/* Numéro de ligne et fichier Syntaxe courant. */ +static int ligne=1; +static char * n_fich; +static FILE * f_syn; + +/*********************************************************************************************/ +/* */ +/* Définition des objets décrivant la syntaxe et l'organisation du fichier Syntaxe. On */ +/* trouve : */ +/* */ +/* la table des mots clefs, qui contient les valeurs spécifiant un type de lexème. */ +/* la table des propriétés, regroupant le nom des différentes propriétés. */ +/* la table des fonctions qui peuvent être exécutées à la lecture du fichier Syntaxe. */ +/* */ +/*********************************************************************************************/ + + +/* TABLES DES MOTS CLEF */ +typedef struct +{ + char * nom; + type_type_lex code; +} type_table; + +/* Table statique des mots clefs correspondant aux types de base. */ +#define NUM_KEYWORD 2 /* Nombre de mots clef reconnus par le préparateur. */ +static type_table table_clef_base[NUM_KEYWORD] = + { { "alpha" , ALPHA} + , { "int" , NUM} + }; + +/* Table dynamique des mots clefs correspondant aux sous types. */ +static type_table * table_clef_sst=NULL; + + +/* TABLE DES PROPRIETES */ +#define NUM_PROP 3 +static char *prop_table[NUM_PROP] = + { "TMO" + , "MSK" + , "FUN" + }; +enum {TMO, MSK, FUN}; /* Codes symboliques pour les différentes propriétés. */ + + +/* TABLE DES FONCTIONS */ +/* Définition des fonctions de paramétrage du preparateur. Elles seront exécutées à la */ +/* demande du fichier Syntaxe lors de la rencontre de l'instruction SET. */ + +/* En cas d'erreur, ces fonctions renvoient 1 et positionnent la variable errcode du module */ +/* erreur. La fonction appelante se charge de l'affichage de l'erreur. */ + +int casse() +{ + casse_sens = 1; + DIALOGUE(NULL, 0, B_CASSE); + return 0; +} + +int nocasse() +{ + casse_sens = 0; + DIALOGUE(NULL, 0, B_NOCASSE); + return 0; +} + +int macrofile() /* Cette fonction lit le nom du fichier macro par défaut et l'enregistre. */ +{ + long pos=ftell(f_syn); + type_lexeme * l; + + DIALOGUE(NULL, 0, B_MAC_DEF); + + l=get_lexeme(f_syn); + if (l==NULL) + { + err_code=S_BAD_ARG; + return 1; + } + if (!TYPE_IS(l, ALPHA) || !LIT_MPV(l->type)) + { + FREE_LEX(l); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + + if (fich_macro_def!=NULL) free(fich_macro_def); + fich_macro_def=l->valeur.alpha; + /* On supprime la valeur du lexème pour que la chaine ne soit pas libérée. */ + l->type=RET_MPV(l->type); + FREE_LEX(l); + + err_code = NO_ERR; + return 0; +} + +int setdefine() +{ + long pos=ftell(f_syn); + type_lexeme * lex; + + DIALOGUE(NULL, 0, B_INIT_D); + + lex=get_lexeme(f_syn); + if (lex==NULL) + { /* Erreur de lecture de l'argument. */ + err_code=S_BAD_ARG; + return 1; + } + if (!TYPE_IS(lex,ALPHA)) + { /* L'argument n'a pas le bon type. */ + FREE_LEX(lex); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + if (define_str!=NULL) free(define_str); + define_str=malloc(strlen(lex->valeur.alpha)+1); + strcpy(define_str, lex->valeur.alpha); + FREE_LEX(lex); + + err_code = NO_ERR; + return 0; +} + +int setundef() +{ + long pos=ftell(f_syn); + type_lexeme * lex; + + DIALOGUE(NULL, 0, B_INIT_U); + + lex=get_lexeme(f_syn); + if (lex==NULL) + { /* Erreur de lecture de l'argument. */ + err_code=S_BAD_ARG; + return 1; + } + if (!TYPE_IS(lex,ALPHA)) + { /* L'argument n'a pas le bon type. */ + FREE_LEX(lex); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + if (undef_str!=NULL) free(undef_str); + undef_str=malloc(strlen(lex->valeur.alpha)+1); + strcpy(undef_str, lex->valeur.alpha); + FREE_LEX(lex); + + err_code = NO_ERR; + return 0; +} + +int setinclude() +{ + long pos=ftell(f_syn); + type_lexeme * lex; + + DIALOGUE(NULL, 0, B_INIT_I); + + lex=get_lexeme(f_syn); + if (lex==NULL) + { + err_code=S_BAD_ARG; + return 1; /* Erreur de lecture de l'argument. */ + } + if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ + { + FREE_LEX(lex); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + + if (include_str!=NULL) free(include_str); + include_str=malloc(strlen(lex->valeur.alpha)+1); + strcpy(include_str, lex->valeur.alpha); + FREE_LEX(lex); + + err_code = NO_ERR; + return 0; +} + +int setsep() +{ + type_lexeme * lex; + lex=get_lexeme(f_syn); + + DIALOGUE(NULL, 0, B_INIT_SEP); + + if (lex==NULL) + { + err_code=S_BAD_ARG; + return 1; + } + if (seplex!=NULL) FREE_LEX(seplex); + if (TYPE_IS(lex, OP) && lex->valeur.op==NL) ligne++; + seplex=lex; + + err_code = NO_ERR; + return 0; +} + +int sst_max=0; /* Nombre maximal de sous-types réservés dans la table. */ + +int setnumsst() +{ + long pos=ftell(f_syn); + type_lexeme * lex; + + DIALOGUE(NULL, 0, B_PREP_SST); + + if (table_clef_sst!=NULL) /* Réutilisation de SSTNUM. */ + { + err_code = S_SEC_SST_DEC; + return 1; + } + + lex=get_lexeme(f_syn); + if (lex==NULL) + { /* Erreur de lecture de l'argument. */ + err_code=S_BAD_ARG; + return 1; + } + if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ + { + FREE_LEX(lex); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + sst_max=lex->valeur.num; + + FREE_LEX(lex); + /* Allocation des tables locales et globale des sous types. */ + regle_typage = (type_paire *) malloc(sst_max*sizeof(type_paire)); + if (regle_typage==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); + table_clef_sst = (type_table*) malloc(sst_max*sizeof(type_table)); + if (table_clef_sst==NULL) DIALOGUE("preparateur(setnumsst)", 0, F_ERR_MEM); + + err_code = NO_ERR; + return 0; +} + +int setnewsst() +{ + long pos=ftell(f_syn); + type_lexeme * lex; + char * nom, *filtre; + type_type_lex code; + int i, bk=0; + + DIALOGUE(NULL, 0, B_ADD_SST); + + /* Vérification que la déclaration du nombre de sous-types est valide. */ + if (regle_typage==NULL || table_clef_sst==NULL || nbr_sous_types>=sst_max) + { + err_code=S_BAD_SST_DEC; + return 1; + } + + /* Lecture du mot clef correspondant au sous-type. */ + lex=get_lexeme(f_syn); + if (lex==NULL) + { + err_code=S_BAD_ARG; + return 1; /* Erreur de lecture de l'argument. */ + } + if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ + { + FREE_LEX(lex); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + /* Ajout du mot clef. */ + nom = lex->valeur.alpha; + /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX. */ + lex->type=RET_MPV(lex->type); + FREE_LEX(lex); + + + /* Lecture de la règle de typage correspondant au sous-type. */ + lex=get_lexeme(f_syn); + if (lex==NULL) + { + err_code=S_BAD_ARG; + return 1; /* Erreur de lecture de l'argument. */ + } + if (!TYPE_IS(lex,ALPHA)) /* L'argument n'a pas le bon type. */ + { + FREE_LEX(lex); + free(nom); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + /* Ajout de la règle à la table. */ + filtre=lex->valeur.alpha; + /* On supprime la valeur pour qu'elle ne soit pas libérée par FREE_LEX. */ + lex->type=RET_MPV(lex->type); + FREE_LEX(lex); + + /* Lecture du code correspondant au sous-type. */ + lex=get_lexeme(f_syn); + if (lex==NULL) + { + err_code=S_BAD_ARG; + return 1; /* Erreur de lecture de l'argument. */ + } + if (!TYPE_IS(lex,NUM)) /* L'argument n'a pas le bon type. */ + { + FREE_LEX(lex); + free(nom); + free(filtre); + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + err_code=S_BAD_ARG; + return 1; + } + /* Vérification de la valeur du code demandé. */ + if (lex->valeur.num<0 || lex->valeur.num>MAX_SOUS_TYPES) + { /* Le nombre de sous-types codables est limité... */ + FREE_LEX(lex); + free(nom); + free(filtre); + err_code=S_DEP_SST; + fseek(f_syn,pos-ftell(f_syn),SEEK_CUR); /* On "remet" le lexème. */ + return 1; + } + code=CODE_TYPE(lex->valeur.num); + FREE_LEX(lex); + + for (i=0 ; i0 ; nbr_sous_types--)\ + free(regle_typage[nbr_sous_types-1].chaine);\ + free(regle_typage);\ + regle_typage=NULL;\ + }\ + casse_sens=1;\ + sst_max=0;\ + nbr_sous_types=0;\ +} + + +/*********************************************************************************************/ +/* FONCTION place_lexeme */ +/* */ +/* type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) */ +/* */ +/* Cette fonction reçoit un lexème et un noeud. Elle recherche le lexème dans les fils du */ +/* noeud et si elle le trouve, elle renvoie un pointeur sur lui, sinon elle le crée et */ +/* renvoie ce nouveau pointeur. */ +/* */ +/*********************************************************************************************/ + +type_noeud * place_lexeme(type_lexeme * l, type_noeud * cur_root) +{ + char * msg_orig="préparateur(place_lexeme)"; + type_noeud * cur_fils = (cur_root->ptr_fils); + + while (cur_fils != NULL) + { + if (lexeme_comp(l, &(cur_fils->lexeme))) return cur_fils; + cur_fils = cur_fils->ptr_frere; + } + ALLOC_NOEUD(cur_fils); + cur_fils->ptr_frere = cur_root->ptr_fils; + LEX_COPY(l, &(cur_fils->lexeme)); + cur_root->ptr_fils = cur_fils; + return cur_fils; +} + + +/*********************************************************************************************/ +/* FONCTION lit_feuille */ +/* */ +/* type_feuille * lit_feuille(FILE * f_syn) */ +/* */ +/* Cette fonction reçoit le fichier Syntaxe ouvert à la bonne position et lit les */ +/* différentes propriétés qui s'y trouve. A partir de cette lecture, elle crée une feuille */ +/* pour les enregistrer et renvoie un pointeur vers celle-ci. En cas d'erreur, un pointeur */ +/* NULL est retourné et le fichier est laissé à la position de l'erreur. */ +/* */ +/*********************************************************************************************/ + +#define OPERATEUR (TYPE_IS(lex, OP)) +#define VAL_OP ((lex->valeur).op) +#define VAL_ALPHA ((lex->valeur).alpha) + +#define ERR_LF(val) {\ + if (lex!=NULL) FREE_LEX(lex);\ + if (mask_ptr!=NULL) FREE_MASK(mask_ptr);\ + DIALOGUE(n_fich, ligne, val);\ + return NULL;\ + } +/* Comme la lecture d'une feuille n'est pas sensible a la présence de sauts de ligne, la */ +/* macro suivante se charge de les éliminer. La terminaison est assurée par EOF. */ +/* La macro commence par libérer l'espace du lexème précédent sauf si celui-ci est NULL. */ +#define LIT_LEXEME {\ + do\ + {\ + if (lex!=NULL) FREE_LEX(lex);\ + lex=get_lexeme(f_syn);\ + if (lex==NULL) ERR_LF(err_code)\ + if (OPERATEUR && VAL_OP==NL) ligne++;\ + }\ + while (OPERATEUR && VAL_OP==NL);\ + } + +#define INIT_MASK {\ + if (mask_ptr==NULL)\ + {\ + ALLOC_MASK(mask_ptr);\ + mask_ptr->taille=0;\ + mask_ptr->valeur=0;\ + }\ + if (mask_ptr==NULL)\ + DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM);\ + } + +type_feuille * lit_feuille() +{ + char * msg_orig="preparateur(lit_feuille)"; + int i, c, tmo_lu=0, i_fun=0; + type_valeur_mask tmp_msk=0; + type_lexeme * lex=NULL; + type_ptr_fgm fun_ptr[MAX_FONCTIONS]; + type_mask * mask_ptr=NULL; + type_feuille * tmp_feuille; + + LIT_LEXEME /* Lit le premier lexème différent de NL. */ + while (!OPERATEUR || (VAL_OP!=EOF && VAL_OP!=ACO)) + { + if (!TYPE_IS(lex, ALPHA)) ERR_LF(S_BAD_PROP); + /* Détermination de la propriété. */ + i=-1; + while (++itaille=(lex->valeur).num; + break; + case MSK : LIT_LEXEME; + if (!TYPE_IS(lex,ALPHA)||VAL_ALPHA[0]!='_') + ERR_LF(S_BAD_VAL); + INIT_MASK; + i=1; tmp_msk=0; + while ((c=VAL_ALPHA[i++])!='\0') + { + if (c!='0' && c!='1') + { + if (c!='_') ERR_LF(S_BAD_VAL); + } + else + { + tmp_msk<<=1; + tmp_msk+=(c-'0'); + } + } + (mask_ptr->valeur)|=tmp_msk; + break; + case FUN : if (i_fun==MAX_FONCTIONS) ERR_LF(S_DEP_FUNC_NB); + LIT_LEXEME; + if (!TYPE_IS(lex,ALPHA)) ERR_LF(S_BAD_VAL); + fun_ptr[i_fun]=alias(VAL_ALPHA); + if (fun_ptr[i_fun]==NULL) + { /* Fonction inexistante. */ + ERR_LF(S_BAD_FUN); + } + i_fun++; + break; + default : return NULL; + } + LIT_LEXEME; + } + + FREE_LEX(lex); + ALLOC_FEUILLE(tmp_feuille); + if (!tmo_lu && mask_ptr!=NULL) + { /* On ignore le masque si il n'a pas de taille spécifiée. */ + FREE_MASK(mask_ptr); + mask_ptr=NULL; + } + tmp_feuille->mask_primaire=mask_ptr; + + /* Recopie de la liste des fonctions de génération de masque. */ + tmp_feuille->nbr_func=i_fun; + if (i_fun) + { + tmp_feuille->ptr_func=(type_ptr_fgm *) (malloc(i_fun*sizeof(type_ptr_fgm))); + if (tmp_feuille->ptr_func==NULL) + DIALOGUE("préparateur(lit_feuille)", 0, F_ERR_MEM); + while ((i_fun--)>0) + { + tmp_feuille->ptr_func[i_fun] = fun_ptr[i_fun]; + } + } + else tmp_feuille->ptr_func=NULL; + + return tmp_feuille; +} + + +/*********************************************************************************************/ +/* FONCTION init_arbre */ +/* */ +/* int init_arbre(char * fichier_syntaxe) */ +/* */ +/* Cette fonction reçoit le nom du fichier Syntaxe, l'ouvre et y lit les informations. Elle */ +/* les utilise pour mettre à jour l'arbre des lexèmes défini dans le commun (root). Les */ +/* erreurs de format sont signalées. */ +/* La valeur de retour est le nombre d'erreurs rencontrées. */ +/* */ +/*********************************************************************************************/ + +int init_arbre(char * fichier_syntaxe) + + +#define ERREUR(val) {\ + DIALOGUE(fichier_syntaxe, ligne, val);\ + err=1;\ + } +/* Lecture d'un lexème non NULL, au pire EOF, tout en comptant les lignes. */ +/* Le lexème précédent est libéré sauf s'il est NULL. */ +#define LIT_VALIDE {\ + if (lex!=NULL) FREE_LEX(lex);\ + while ((lex=get_lexeme(f_syn))==NULL)\ + {\ + err=1;\ + ERREUR(err_code);\ + }\ + if (OPERATEUR && VAL_OP==NL) ligne++;\ + } +/* Recherche de la prochaine accolade ouvrante (instruction suivante) */ +#define ACO_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=ACO && VAL_OP!=EOF)) +#define LIGNE_SUIV do LIT_VALIDE while (!OPERATEUR || (VAL_OP!=NL && VAL_OP!=EOF)) + +{ + char * msg_orig="preparateur(init_arbre)"; + type_lexeme * lex=NULL; + int err=0,gblerr=0; /* err est vrai lors d'une erreur, gblerr s'il y a eu une erreur */ + type_noeud * courant; + type_feuille * feuille=NULL; + + /* Réinitialisation des différentes variables locales et globales. */ + REINIT; + ALLOC_NOEUD(root); + + f_syn=fopen(fichier_syntaxe, "rb"); /* ouverture du fichier Syntaxe. */ + if (f_syn==NULL) + { + DIALOGUE(NULL, 0, W_NO_SYNTAX); + return 0; + } + + n_fich = fichier_syntaxe; /* Positionne la variable commune au module. */ + ligne=1; /* Initialisation du numéro de ligne au début du fichier. */ + + do /* Lecture du fichier Syntaxe jusqu'à la première accolade ouvrante. */ + { + LIT_VALIDE; + if (TYPE_IS(lex, ALPHA) && !string_comp(VAL_ALPHA, SET)) + { /* On a rencontré une commande SET, lecture des arguments. */ + int i=-1; + LIT_VALIDE; + if (!TYPE_IS(lex, ALPHA)) + { + ERREUR(S_BAD_ARG); + gblerr++; + LIGNE_SUIV; + } + else + { + while (++itype) && TYPE_IS(lex, ALPHA)) + { /* Si on a un mot clef, on ajuste le type (on supprime la valeur) */ + int i, key=0; + /* Recherche dans les mots clef de base. */ + for (i=0 ; itype=table_clef_base[i].code; + key=1; + } + /* Recherche dans les mots clef des sous-types. */ + for (i=0 ; itype=table_clef_sst[i].code; + key=1; + } + if (key) free(lex->valeur.alpha); + } + courant = place_lexeme(lex, courant); + LIT_VALIDE; + if (OPERATEUR && VAL_OP==EOF) ERREUR(S_DCL_NON_TERM); + } + + /* Redéfinition d'une instruction déjà lue. */ + if (courant->ptr_feuille!=NULL) ERREUR(S_REDEF_INS); + + if (!err) feuille=lit_feuille(); /* Lecture de la feuille. */ + if (feuille==NULL) err=1; /* Le message d'erreur est géré à la lecture. */ + + /* Si la lecture est réussie, il faut mémoriser la nouvelle instruction. */ + if (!err) courant->ptr_feuille=feuille; + else ACO_SUIV; /* Erreur de lecture, on passe à l'instruction suivante. */ + gblerr+=(err==1); /* Le code d'erreur est uniquement 1. */ + } + while (!OPERATEUR || VAL_OP!=EOF); + FREE_LEX(lex); + fclose(f_syn); + return gblerr; +} + +/* Fonction de libération des structures contenues dans un arbre. */ +void free_arbre(type_noeud * courant) +{ + type_noeud * fils_courant; + + if (courant==NULL) return; + fils_courant=courant->ptr_fils; + while (fils_courant!=NULL) + { /* On efface récursivement tous les sous arbres. */ + free_arbre(fils_courant); + fils_courant=fils_courant->ptr_frere; + } + /* On efface le champ valeur des lexèmes ALPHA. */ + if (TYPE_IS(&(courant->lexeme), ALPHA) && LIT_MPV(courant->lexeme.type) + && (courant->lexeme.valeur.alpha!=NULL)) + free(courant->lexeme.valeur.alpha); + FREE_NOEUD(courant); +} + +/* Fonction de libération des structures crées par init_arbre. */ +void clear_preparateur() +{ + free_arbre(root); + root=NULL; /* root a été libéré par la fonction free_arbre. */ + REINIT; +} + Index: minimips/trunk/gasm/Makefile.dep =================================================================== --- minimips/trunk/gasm/Makefile.dep (nonexistent) +++ minimips/trunk/gasm/Makefile.dep (revision 14) @@ -0,0 +1,23 @@ +# This file is part of gasm. +# +# +# If you encountered any problem, please contact : +# +# lmouton@enserg.fr +# shangoue@enserg.fr +# + + + +# Définition des dépendances + +dialogue_DEP = +formateur_DEP = dialogue +parametres_DEP = formateur +preprocesseur_DEP = dialogue formateur parametres +adaptateur_DEP = dialogue formateur parametres preprocesseur +preparateur_DEP = dialogue formateur parametres adaptateur +analyseur_DEP = dialogue formateur parametres preprocesseur adaptateur preparateur +synthetiseur_DEP = dialogue formateur parametres adaptateur analyseur + +ALL = dialogue formateur parametres preprocesseur adaptateur preparateur analyseur synthetiseur Index: minimips/trunk/gasm/main.c =================================================================== --- minimips/trunk/gasm/main.c (nonexistent) +++ minimips/trunk/gasm/main.c (revision 14) @@ -0,0 +1,220 @@ +/**********************************************************************************/ +/* */ +/* Copyright (c) 2003, Hangouet Samuel, Mouton Louis-Marie all rights reserved */ +/* */ +/* This file is part of gasm. */ +/* */ +/* gasm is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* gasm is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with gasm; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* */ +/**********************************************************************************/ + + +/* If you encountered any problem, please contact : */ +/* */ +/* lmouton@enserg.fr */ +/* shangoue@enserg.fr */ +/* */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static char nom_source[MAX_LONG_ALPHA+1]=""; +static char nom_syntaxe[MAX_LONG_ALPHA+1]="Syntaxe"; +static char nom_macro[MAX_LONG_ALPHA+1]=""; +static char nom_liste[MAX_LONG_ALPHA+1]="a.lst"; +static char nom_obj[MAX_LONG_ALPHA+1]="a.bin"; + +int gere_args(int argc, char * argv[]) +{ + int i; + char * cur_arg; + nom_source[MAX_LONG_ALPHA]=nom_syntaxe[MAX_LONG_ALPHA]=nom_macro[MAX_LONG_ALPHA]='\0'; + for(i=1; i=argc) + { + DIALOGUE(cur_arg, 0, W_ARG_INC); + break; + } + strncpy(nom_syntaxe,argv[i+1],MAX_LONG_ALPHA); + i++; + break; + case 'm': /* Nom du fichier macro par défaut. */ + if (cur_arg[1]!='\0' || i+1>=argc) + { + DIALOGUE(cur_arg, 0, W_ARG_INC); + break; + } + strncpy(nom_macro,argv[i+1],MAX_LONG_ALPHA); + i++; + break; + case 'l': /* Nom du fichier liste d'assemblage. */ + if (cur_arg[1]!='\0' || i+1>=argc) + { + DIALOGUE(cur_arg, 0, W_ARG_INC); + break; + } + strncpy(nom_liste,argv[i+1],MAX_LONG_ALPHA); + i++; + break; + case 'o': /* Nom du fichier objet. */ + if (cur_arg[1]!='\0' || i+1>=argc) + { + DIALOGUE(cur_arg, 0, W_ARG_INC); + break; + } + strncpy(nom_obj,argv[i+1],MAX_LONG_ALPHA); + i++; + break; + case '?': + case 'h': /* Aide en ligne. */ + display_help(); + return 0; + break; + case 'p': /* Utilise la sortie standard */ + nom_obj[0]='\0'; + break; + default: + DIALOGUE(cur_arg, 0, W_ARG_INC); + break; + } + } + else + { + if (*nom_source!='\0') DIALOGUE(cur_arg, 0, W_ARG_INC) + else strncpy(nom_source,cur_arg,MAX_LONG_ALPHA); + } + } + return 1; +} + +int main(int argc, char * argv[]) +{ + FILE * f_lst=NULL, * f_obj=NULL, * f_srceff=NULL; + int err1, err2; + int dst_std=0; + type_lexeme * ptr_lex; + + if (!gere_args(argc, argv)) return 0; /* Détection du paramètre d'aide. */ + + /* Initialisation de la syntaxe de l'assembleur. */ + DIALOGUE(NULL, 0, B_INIT_SYNTAX); + init_arbre(nom_syntaxe); + + /* Initialisation des macros génériques (pseudo-instructions). */ + DIALOGUE(NULL, 0, B_INIT_MACRO); + /* Si le nom du fichier de macros n'est pas spécifié en paramètre, on récupère le */ + /* nom par défaut défini dans le fichier syntaxe. */ + if (nom_macro[0]=='\0' && fich_macro_def) + strcpy(nom_macro, fich_macro_def); /* nom_macro est assez long ! */ + if (nom_macro[0]!='\0') + { + if (init_preprocesseur(nom_macro)) DIALOGUE(NULL, 0, W_FICH_DEF_MACRO); + } + else DIALOGUE(NULL, 0, W_MACRO_MANQ); + /* Vidange du fichier de définition des macros par défaut avant de poursuivre */ + while ((ptr_lex=pop_lexeme())!=NULL) FREE_LEX(ptr_lex); + + /* Initialisation du préprocesseur avec le fichier asm donné en paramètre */ + if (init_preprocesseur(nom_source)) DIALOGUE(nom_source, 0, F_ERR_OUV); + + /* Exécution de l'analyse. */ + DIALOGUE(NULL, 0, B_ANA); + err1=analyse(); + if (verbose) liste_table_macro(stderr); + clear_preprocesseur(); /* Nettoyage du préprocesseur. */ + + /* Exécution de la synthèse. */ + DIALOGUE(NULL, 0, B_SYN); + err2=synthese(); + + /* Ouverture du flux de sortie. */ + if (nom_obj[0]!='\0') + { + f_obj=fopen(nom_obj, "wb"); + if (f_obj==NULL) DIALOGUE(nom_obj, 0, F_ERR_OUV); + } + else + { /* Ecriture dans le stdout. */ + f_obj=stdout; + strcpy(nom_obj, "stdout"); + dst_std=1; + } + + /* Ecriture du fichier objet. */ + DIALOGUE(NULL, 0, B_STR_OBJ); + write_objet(f_obj); + + if (!dst_std) fclose(f_obj); /* Fermeture du flux objet. */ + + if (active_list) + { /* Création de la liste d'assemblage. */ + /* Ouverture du flux source effectif et du flux de la liste si besoin est. */ + f_srceff=fopen(nom_source, "rb"); + if (f_srceff==NULL) DIALOGUE(nom_source, 0, F_ERR_OUV); + f_lst=fopen(nom_liste, "wb"); + if (f_lst==NULL) DIALOGUE(nom_liste, 0, F_ERR_OUV); + DIALOGUE(NULL, 0, B_STR_LST); /* Ecriture de la lsite d'assemblage. */ + write_liste(f_lst, f_srceff); + /* Fermeture des différents flux ouverts. */ + fclose(f_srceff); + fclose(f_lst); + } + + if (verbose) + { /* Affichage du nombre d'erreurs détectées aux cours des deux passes. */ + char str_nbr[MAX_LONG_ALPHA]; + DIALOGUE(NULL, 0, B_ERR_REP); + sprintf(str_nbr, "%d", err1); + DIALOGUE(str_nbr, 0, B_NBR_ERR_ANA); + sprintf(str_nbr, "%d", err2); + DIALOGUE(str_nbr, 0, B_NBR_ERR_SYN); + } + + /* Libération de l'espace réservé lors de l'initialisation des différents modules. */ + clear_preparateur(); + clear_adaptateur(); + clear_analyseur(); + + +#ifdef DEBUG + /* Affichage des informations de debuging : */ + print_mem(stderr); +#endif + + return 0; +} Index: minimips/trunk/gasm/Syntaxe =================================================================== --- minimips/trunk/gasm/Syntaxe (nonexistent) +++ minimips/trunk/gasm/Syntaxe (revision 14) @@ -0,0 +1,522 @@ +; This file is part of gasm. +; +; +; If you encountered any problem, please contact : +; +; lmouton@enserg.fr +; shangoue@enserg.fr +; + + + +;===============================================================================; +; ; +; ; +; Fichier de donnees sur la syntaxe de l'assembleur du microprocesseur miniMIPS ; +; ; +; ; +;===============================================================================; + +; Les instructions SET s'adressant au preparateur doivent se trouver avant la première accolade. + + +SET MACROFILE psd_instr.sx ; Fichier macro par défaut (pseudo instructions). +SET NOCASSE ; L'assembleur MIPS n'est pas sensible à la casse + +SET DEFINESTR D ; Chaine de définition de macro +SET UNDEFSTR U ; Chaine de supression de macro + +; Il est également possible d'activer l'inclusion de fichier mais dans ce cas la liste +; d'assemblage sera interdite... +; SET INCLUDESTR I ; Chaine d'inclusion de fichier + +; Définition du séparateur d'instructions (ici, NL) +; Le séparateur est utilisé lors de la détection d'une erreur par l'analyseur pour déterminer +; à partir de quel endroit poursuivre l'assemblage. Il effectue la recherche du prochain séparateur +; puis se place juste après et continue l'analyse. +SET SEP + +; Définition des sous-types que l'on utilise dans la syntaxe de l'assembleur. +; Le nombre de sous-types pouvant actuellement être référencés est de 16. +SET NUMSST 3 ; Déclaration de deux sous types du type ALPHA + +; Le troisième champ correspond au code du sous-type. Si plusieurs sont identiques, +; ils seront confondus par l'assembleur. On peut utiliser cette propriété pour +; définir plusieurs motifs définissant le même type. +; Codage des registres R0 à R31 (la notation R02 est autorisée) : +SET NEWSST Reg $?09 1 +SET NEWSST Reg $?02?09 1 +SET NEWSST Reg $3?01 1 + +; Mots clefs autorisées dans la déclaration de la syntaxe d'une instruction : Int, Alpha, Reg +; Mots clefs autorisés dans les propriétés de l'instruction : TMO, MSK, FUN +; Les masques doivent commencer par - et peuvent contenir - le caractère '_' + +; Autorise les lignes vides +{ +} + +; Déclaration d'étiquette +{ Alpha: } + FUN Ajoute_Etiquette ; Ajoute une étiquette dans la table + +; DÉFINITION DES DIRECTIVES + +; Directives de définition des équivalences +{ Alpha EQU Alpha } + FUN AddEqu + +{ Alpha EQU Int } + FUN AddEqu + +; Directive d'alignement sur adresse congrue à 4 +{ ALIGN4 } + FUN Complete_zeros + +; Directives d'inclusion de données dans le code +{ DCB Int } + TMO 1 + MSK _0000_0000_ + FUN Dcb_Int +{ DCB Alpha } + TMO 1 + MSK _0000_0000_ + FUN Dcb_Alpha +{ DCW Int } + TMO 4 + MSK _0000_0000_0000_0000__0000_0000_0000_0000_ + FUN Dcw_Int +{ DCW Alpha } + TMO 2 + MSK _0000_0000_0000_0000__0000_0000_0000_0000_ + FUN Dcw_Alpha + +; Directives de positionnement de l'adresse d'implantation +{ ORG Int } + FUN Org_Int + +{ ORG Alpha } + FUN Org_Label + +; DEFINITION DES INSTRUCTIONS + +; Instruction ADD +{ ADD Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100000 + FUN R1D + FUN R3S + FUN R5T + +; Instruction ADDI +{ ADDI Reg, Reg, Int } + TMO 4 + MSK _001000_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ ADDI Reg, Reg, Alpha } + TMO 4 + MSK _001000_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 + +; Instruction ADDIU +{ ADDIU Reg, Reg, Int } + TMO 4 + MSK _001001_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 + +; Instruction ADDU +{ ADDU Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100001 + FUN R1D + FUN R3S + FUN R5T + +; Instruction AND +{ AND Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100100 + FUN R1D + FUN R3S + FUN R5T + +; Instruction ANDI +{ ANDI Reg, Reg, Int } + TMO 4 + MSK _001100_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ ANDI Reg, Reg, Alpha } + TMO 4 + MSK _001100_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 + +; Instruction BEQ +{ BEQ Reg, Reg, Alpha } + TMO 4 + MSK _000100_00000_00000__0000_0000_0000_0000 + FUN R1S + FUN R3T + FUN OFFSET5 + +; Instruction BGEZ +{ BGEZ Reg, Alpha } + TMO 4 + MSK _000001_00000_00001__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BGEZAL +{ BGEZAL Reg, Alpha } + TMO 4 + MSK _000001_00000_10001__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BGTZ +{ BGTZ Reg, Alpha } + TMO 4 + MSK _000111_00000_00000__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BLEZ +{ BLEZ Reg, Alpha } + TMO 4 + MSK _000110_00000_00000__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BLTZ +{ BLTZ Reg, Alpha } + TMO 4 + MSK _000001_00000_00000__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BLTZAL +{ BLTZAL Reg, Alpha } + TMO 4 + MSK _000001_00000_10000__00000000_00000000 + FUN R1S + FUN OFFSET3 + +; Instruction BNE +{ BNE Reg, Reg, Alpha } + TMO 4 + MSK _000101_00000_00000__00000000_00000000 + FUN R1S + FUN R3T + FUN OFFSET5 + +; Instruction BREAK +{ BREAK } + TMO 4 + MSK _000000__00000_00000_00000_00000__001101 + +; Instruction COP0 +{ COP0 Int } + TMO 4 + MSK _010000_00001_00000_0000_0000_0000_0000 + FUN IMM1 + +; Instruction J +{ J Alpha } + TMO 4 + MSK _000010__00_0000_0000_0000_0000_0000_0000 + FUN ABSOLU1 + +; Instruction JAL +{ JAL Alpha } + TMO 4 + MSK _000011__00_0000_0000_0000_0000_0000_0000 + FUN ABSOLU1 + +; Instruction JALR +{ JAL Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_001001 + FUN R1D + FUN R3S + +; Instruction JALR avec rd=$31 implicite +{ JAL Reg } + TMO 4 + MSK _000000_00000_00000_11111_00000_001001 + FUN R1S + +; Instruction JR +{ JR Reg } + TMO 4 + MSK _000000_00000__000_0000_0000_0000__001000 + FUN R1S + +; Instruction LUI +{ LUI Reg, Int } + TMO 4 + MSK _001111_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN IMM3 +{ LUI Reg, Alpha } + TMO 4 + MSK _001111_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN ETIQ3 + +; Instruction LW +{ LW Reg, Int(Reg) } + TMO 4 + MSK _100011_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN IMM3 + FUN R5S + +; Instruction LWC0 +{ LWC0 Reg, Int(Reg) } + TMO 4 + MSK _110000_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN IMM3 + FUN R5S + +; Instruction MFC0 +{ MFC0 Reg, Reg } + TMO 4 + MSK _010000_00000_00000_00000__000000_00000 + FUN R1D + FUN R3T + +; Instruction MFHI +{ MFHI Reg } + TMO 4 + MSK _000000_0000000000_00000_00000_010000 + FUN R1D + +; Instruction MFLO +{ MFLO Reg } + TMO 4 + MSK _000000_0000000000_00000_00000_010010 + FUN R1D + +; Instruction MTC0 +{ MTC0 Reg, Reg } + TMO 4 + MSK _010000_00100_00000_00000__000000_00000 + FUN R1T + FUN R3D + +; Instruction MTHI +{ MTHI Reg } + TMO 4 + MSK _000000_00000__0_0000_0000_0000_00__010001 + FUN R1S + +; Instruction MTLO +{ MTLO Reg } + TMO 4 + MSK _000000_00000__0_0000_0000_0000_00__010011 + FUN R1S + +; Instruction MULT +{ MULT Reg, Reg } + TMO 4 + MSK _000000_00000_00000__0000_0000_00__011000 + FUN R1S + FUN R3T + +; Instruction MULTU +{ MULTU Reg, Reg } + TMO 4 + MSK _000000_00000_00000__0000_0000_00__011001 + FUN R1S + FUN R3T + +; Instruction NOR +{ NOR Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100111 + FUN R1D + FUN R3S + FUN R5T + +; Instruction OR +{ OR Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100101 + FUN R1D + FUN R3S + FUN R5T + +; Instruction ORI +{ ORI Reg, Reg, Int } + TMO 4 + MSK _001101_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ ORI Reg, Reg, Alpha } + TMO 4 + MSK _001101_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 + +; Instruction SLL +{ SLL Reg, Reg, Int } + TMO 4 + MSK _000000_00000_00000_00000_00000_000000 + FUN R1D + FUN R3T + FUN SA5 + +; Instruction SLLV +{ SLLV Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_000100 + FUN R1D + FUN R3T + FUN R5S + +; Instruction SLT +{ SLT Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_101010 + FUN R1D + FUN R3S + FUN R5T + +; Instruction SLTI +{ SLTI Reg, Reg, Int } + TMO 4 + MSK _001010_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ SLTI Reg, Reg, Alpha } + TMO 4 + MSK _001010_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 + +; Instruction SLTIU +{ SLTIU Reg, Reg, Int } + TMO 4 + MSK _001010_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ SLTIU Reg, Reg, Alpha } + TMO 4 + MSK _001010_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 + +; Instruction SLTU +{ SLTU Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_101011 + FUN R1D + FUN R3S + FUN R5T + +; Instruction SRA +{ SRA Reg, Reg, Int } + TMO 4 + MSK _000000_00000_00000_00000_00000_000011 + FUN R1D + FUN R3T + FUN SA5 + +; Instruction SRAV +{ SRAV Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_000111 + FUN R1D + FUN R3T + FUN R5S + +; Instruction SRL +{ SRL Reg, Reg, Int } + TMO 4 + MSK _000000_00000_00000_00000_00000_000010 + FUN R1D + FUN R3T + FUN SA5 + +; Instruction SRLV +{ SRLV Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_000110 + FUN R1D + FUN R3T + FUN R5S + +; Instruction SUB +{ SUB Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100010 + FUN R1D + FUN R3S + FUN R5T + +; Instruction SUBU +{ SUBU Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100011 + FUN R1D + FUN R3S + FUN R5T + +; Instruction SW +{ SW Reg, Int(Reg) } + TMO 4 + MSK _101011_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN IMM3 + FUN R5S + +; Instruction SWC0 +{ SWC0 Reg, Int(Reg) } + TMO 4 + MSK _111000_00000_00000__0000_0000_0000_0000 + FUN R1T + FUN IMM3 + FUN R5S + +; Instruction SYSCALL +{ SYSCALL } + TMO 4 + MSK _000000__00000_00000_00000_00000__001100 + +; Instruction XOR +{ XOR Reg, Reg, Reg } + TMO 4 + MSK _000000_00000_00000_00000_00000_100110 + FUN R1D + FUN R3S + FUN R5T + +; Instruction XORI +{ XORI Reg, Reg, Int } + TMO 4 + MSK _001110_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN IMM5 +{ XORI Reg, Reg, Alpha } + TMO 4 + MSK _001110_00000_00000__00000000_00000000 + FUN R1T + FUN R3S + FUN ETIQ5 Index: minimips/trunk/gasm/readme.txt =================================================================== --- minimips/trunk/gasm/readme.txt (nonexistent) +++ minimips/trunk/gasm/readme.txt (revision 14) @@ -0,0 +1,2 @@ +1 - To generate the asmips assemblee, run make +2 - The files Syntaxe and psd_instr.sx must be in the same repository than your assemblee code Index: minimips/trunk/gasm/Makefile =================================================================== --- minimips/trunk/gasm/Makefile (nonexistent) +++ minimips/trunk/gasm/Makefile (revision 14) @@ -0,0 +1,75 @@ +# This file is part of gasm. +# +# +# If you encountered any problem, please contact : +# +# lmouton@enserg.fr +# shangoue@enserg.fr +# + + +# Makefile de type compilation du projet +# +# Cibles possibles : +# +# project, all, asmica Compile l'assembleur avec main.c et tous les modules en les recompilant au besoin +# info Informe sur l'état d'avancement du projet +# nom_module Recompile le module indiqué +# menage Fait le menage des fichiers generes +# exec Executer le programme +# save[fichier_tar] Archivage du projet dans sav/ + +COMP_OPT = -I$(INCLUDE_PATH) -O2 -Wall -ansi -pipe -s + +# Repertoires du projet +# SOUS_REP est défini dans le Makefile appelant +LIB_PATH = lib +INCLUDE_PATH = include +SRC_PATH = src + +# inclusion de la définition des dépendances +include Makefile.dep + +VPATH = $(LIB_PATH) : $(INCLUDE_PATH) : $(SRC_PATH) + +# modules du projet dans l'ordre des dépandances +MODS_OBJ = $(addsuffix .o, $(strip $(ALL))) +MODS_SRC = $(addsuffix .c, $(strip $(ALL))) + +# Compilateur utilisé et options de compilation d'édition de liens +CC = gcc +LINK_OPT = + +.SILENT : menage exec $(MODS_OBJ) info +.PHONY : all project exec menage + +all project : asmips + +asmips : main.c $(MODS_OBJ) + $(CC) $(COMP_OPT) $(LINK_OPT) $< $(addprefix $(LIB_PATH)/, $(MODS_OBJ)) -o $@ + +$(MODS_OBJ) : %.o : %.c $(addsuffix .h, $(%_DEP)) + @echo Compilation du module $* + $(CC) $(COMP_OPT) -o $(LIB_PATH)/$*.o -c $< + +menage : + @echo Menage des fichiers principaux du projet + rm -f *.o + rm -f core.* + rm -f *~ + rm -f asmips + rm -f a.obj a.lst + rm -f $(LIB_PATH)/*.o + +exec : + $(MAKE) -s project + clear + ./asmips + +save[%] : + @tar -jvcf ../sav/$*.tbz2 * + +info : + @echo Modules installés : + ls $(LIB_PATH) + Index: minimips/trunk/gasm/psd_instr.sx =================================================================== --- minimips/trunk/gasm/psd_instr.sx (nonexistent) +++ minimips/trunk/gasm/psd_instr.sx (revision 14) @@ -0,0 +1,110 @@ +; This file is part of gasm. +; +; +; If you encountered any problem, please contact : +; +; lmouton@enserg.fr +; shangoue@enserg.fr +; + + +; Ce fichier contient les d‰finitions des macros du langage. +; Il s'agit des pseudo-instructions ainsi que des ‰quivalences de base. + +; Il est € noter que les instructions ‰ventuelles ne seront pas trait‰es +; seules les directives de pr‰processeur sont prises en compte. + +;================================= Surnoms des registres ================================== + +#D $ZERO {} {} { $0 } + +#D $AT {} {} { $1 } + +#D $V0 {} {} { $2 } +#D $V1 {} {} { $3 } + +#D $A0 {} {} { $4 } +#D $A1 {} {} { $5 } +#D $A2 {} {} { $6 } +#D $A3 {} {} { $7 } + +#D $T0 {} {} { $8 } +#D $T1 {} {} { $9 } +#D $T2 {} {} { $10 } +#D $T3 {} {} { $11 } +#D $T4 {} {} { $12 } +#D $T5 {} {} { $13 } +#D $T6 {} {} { $14 } +#D $T7 {} {} { $15 } + +#D $S1 {} {} { $16 } +#D $S2 {} {} { $17 } +#D $S3 {} {} { $18 } +#D $S4 {} {} { $19 } +#D $S5 {} {} { $20 } +#D $S6 {} {} { $21 } +#D $S7 {} {} { $22 } +#D $S8 {} {} { $23 } + +#D $T8 {} {} { $24 } +#D $T9 {} {} { $25 } + +#D $K0 {} {} { $26 } +#D $K1 {} {} { $27 } + +#D $GP {} {} { $28 } + +#D $SP {} {} { $29 } + +#D $FP {} {} { $30 } + +#D $RA {} {} { $31 } + +; Registres internes du coprocesseur systeme + +#D STATUS {} {} { $12 } +#D CAUSE {} {} { $13 } +#D EPC {} {} { $14 } +#D VECTIT {} {} { $15 } + + +;============= Fonctions du coprocesseur systeme pour l'instruction COP0 ================ + +#D MASK {} {} { 1 } +#D UNMASK {} {} { 2 } +#D ITRET {} {} { 4 } ; Retour d'interruption + + +;================================== Pseudo-instructions =================================== + +#D NOP {} {} { SLL $0, $0, 0 } + +#D BLT {r o a} {r, o, a} { SLT $1,r, o ;/ Justifie le registre at ($1) + BNE $1, $0, a } ;/ reserve par l'assembleur. + +#D MOVE { Rt Rs } {Rt, Rs} { ADDU Rt, $0, Rs} ;/ addition 'unsigned' avec zero +#D LI { Rt Int } {Rt, Int}{ ORI Rt, $ZERO, Int} ;/ Chargement de valeur immediate + +#D INC { R } { R } { ADDI R, R, 1 } +#D DEC { R } { R } { ADDI R, R, -1 } +#D INCW { R } { R } { ADDI R, R, 4 } +#D DECW { R } { R } { ADDI R, R, -4 } +#D STOP { etq } { etq } { etq: J etq } +#D RETURN {} {} { JR $31 } +#D RIT {} {} { COP0 ITRET } + +#D LOCK {} {} { LI $K0, @FFFF LW $ZERO, 0($K0) } ;/ plantage du processeur + +; Utilisation d'une pile + +#D INIT_SP { adresse } { adresse } { ADDI $SP, $0, adresse } +#D PUSH { reg } { reg } { DECW $SP SW reg, 0($SP) } +#D PULL { reg } { reg } { LW reg, 0($SP) INCW $SP } + +#D FOR { boucle reg max } + { reg from max downto 0 DO boucle } + { boucle: LI reg, max } +#D NEXT { reg boucle } + { reg, boucle } + { DEC reg BGEZ reg, boucle } + Index: minimips/trunk/miniMIPS/doc/doc_pps_di.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: minimips/trunk/miniMIPS/doc/doc_pps_di.pdf =================================================================== --- minimips/trunk/miniMIPS/doc/doc_pps_di.pdf (nonexistent) +++ minimips/trunk/miniMIPS/doc/doc_pps_di.pdf (revision 14)
minimips/trunk/miniMIPS/doc/doc_pps_di.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: minimips/trunk/miniMIPS/doc/doc_pps_pf.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: minimips/trunk/miniMIPS/doc/doc_pps_pf.pdf =================================================================== --- minimips/trunk/miniMIPS/doc/doc_pps_pf.pdf (nonexistent) +++ minimips/trunk/miniMIPS/doc/doc_pps_pf.pdf (revision 14)
minimips/trunk/miniMIPS/doc/doc_pps_pf.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: minimips/trunk/miniMIPS/doc/doc_predict.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: minimips/trunk/miniMIPS/doc/doc_predict.pdf =================================================================== --- minimips/trunk/miniMIPS/doc/doc_predict.pdf (nonexistent) +++ minimips/trunk/miniMIPS/doc/doc_predict.pdf (revision 14)
minimips/trunk/miniMIPS/doc/doc_predict.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: minimips/trunk/miniMIPS/doc/doc_pps_ei.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: minimips/trunk/miniMIPS/doc/doc_pps_ei.pdf =================================================================== --- minimips/trunk/miniMIPS/doc/doc_pps_ei.pdf (nonexistent) +++ minimips/trunk/miniMIPS/doc/doc_pps_ei.pdf (revision 14)
minimips/trunk/miniMIPS/doc/doc_pps_ei.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: minimips/trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: minimips/trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf =================================================================== --- minimips/trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf (nonexistent) +++ minimips/trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf (revision 14)
minimips/trunk/miniMIPS/doc/miniMIPS Instruction Set.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: minimips/trunk/miniMIPS/bench/ram.vhd =================================================================== --- minimips/trunk/miniMIPS/bench/ram.vhd (nonexistent) +++ minimips/trunk/miniMIPS/bench/ram.vhd (revision 14) @@ -0,0 +1,91 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity ram is + generic (mem_size : natural := 256; -- Size of the memory in words + latency : time := 0 ns); + port( + req : in std_logic; + adr : in bus32; + data_inout : inout bus32; + r_w : in std_logic; + ready : out std_logic + ); +end; + + +architecture bench of ram is + type storage_array is array(natural range 1024 to 1024+4*mem_size - 1) of bus8; + signal storage : storage_array; -- The memory +begin + + + process(adr, data_inout, r_w) + variable inadr : integer; + variable i : natural; + begin + inadr := to_integer(unsigned(adr)); + + if (inadr>=storage'low) and (inadr<=storage'high) then + + ready <= '0', '1' after latency; + if req = '1' then + if r_w /= '1' then -- Reading in memory + for i in 0 to 3 loop + data_inout(8*(i+1)-1 downto 8*i) <= storage(inadr+(3-i)) after latency; + end loop; + else + for i in 0 to 3 loop + storage(inadr+(3-i)) <= data_inout(8*(i+1)-1 downto 8*i) after latency; + end loop; + data_inout <= (others => 'Z'); + end if; + else + data_inout <= (others => 'Z'); + end if; + else + data_inout <= (others => 'Z'); + ready <= 'L'; + end if; + end process; + +end bench; Index: minimips/trunk/miniMIPS/bench/bench_minimips.vhd =================================================================== --- minimips/trunk/miniMIPS/bench/bench_minimips.vhd (nonexistent) +++ minimips/trunk/miniMIPS/bench/bench_minimips.vhd (revision 14) @@ -0,0 +1,175 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + +library IEEE; +use IEEE.std_logic_1164.all; + +library std; +use std.textio.all; + +library work; +use work.pack_mips.all; + +entity sim_minimips is +end; + +architecture bench of sim_minimips is + + component minimips is + port ( + clock : in std_logic; + reset : in std_logic; + + ram_req : out std_logic; + ram_adr : out bus32; + ram_r_w : out std_logic; + ram_data : inout bus32; + ram_ack : in std_logic; + + it_mat : in std_logic + ); + end component; + + + component ram is + generic (mem_size : natural := 256; + latency : time := 10 ns); + port( + req : in std_logic; + adr : in bus32; + data_inout : inout bus32; + r_w : in std_logic; + ready : out std_logic + ); + end component; + + component rom is + generic (mem_size : natural := 256; + start : natural := 0; + latency : time := 10 ns); + port( + adr : in bus32; + donnee : out bus32; + ack : out std_logic; + load : in std_logic; + fname : in string + ); + end component; + + signal clock : std_logic := '0'; + signal reset : std_logic; + + signal it_mat : std_logic := '0'; + + -- Connexion with the code memory + signal load : std_logic; + signal fichier : string(1 to 7); + + -- Connexion with the Ram + signal ram_req : std_logic; + signal ram_adr : bus32; + signal ram_r_w : std_logic; + signal ram_data : bus32; + signal ram_rdy : std_logic; + +begin + + U_minimips : minimips port map ( + clock => clock, + reset => reset, + ram_req => ram_req, + ram_adr => ram_adr, + ram_r_w => ram_r_w, + ram_data => ram_data, + ram_ack => ram_rdy, + it_mat => it_mat + ); + + U_ram : ram port map ( + req => ram_req, + adr => ram_adr, + data_inout => ram_data, + r_w => ram_r_w, + ready => ram_rdy + ); + + U_rom : rom port map ( + adr => ram_adr, + donnee => ram_data, + ack => ram_rdy, + load => load, + fname => fichier + ); + + clock <= not clock after 20 ns; + reset <= '0', '1' after 5 ns, '0' after 70 ns; + ram_data <= (others => 'L'); + + process + variable command : line; + variable nomfichier : string(1 to 3); + begin + write (output, "Enter the filename : "); + readline(input, command); + read(command, nomfichier); + + fichier <= nomfichier & ".bin"; + + load <= '1'; + wait; + end process; + + -- Memory Mapping + -- 0000 - 00FF ROM + + process (ram_adr, ram_r_w, ram_data) + begin -- Emulation of an I/O controller + ram_data <= (others => 'Z'); + + case ram_adr is + when X"00001000" => -- declenche une lecture avec interruption + it_mat <= '1' after 1000 ns; + ram_rdy <= '1' after 5 ns; + when X"00001001" => -- fournit la donnee et lache l'it + it_mat <= '0'; + ram_data <= X"FFFFFFFF"; + ram_rdy <= '1' after 5 ns; + when others => ram_rdy <= 'L'; + end case; + end process; + +end bench; + + + Index: minimips/trunk/miniMIPS/bench/rom.vhd =================================================================== --- minimips/trunk/miniMIPS/bench/rom.vhd (nonexistent) +++ minimips/trunk/miniMIPS/bench/rom.vhd (revision 14) @@ -0,0 +1,183 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + +library work; +use work.pack_mips.all; + +entity rom is + generic (mem_size : natural := 256; -- Size of the memory in words + start : natural := 32768; + latency : time := 0 ns); + port( + adr : in bus32; + donnee : out bus32; + ack : out std_logic; + load : in std_logic; + fname : in string + ); +end; + + +architecture bench of rom is + type storage_array is array(natural range start to start+4*mem_size - 1) of bus8; + signal storage : storage_array := (others => (others => '0')); -- The memory + signal adresse : bus16; + signal taille : bus16; +begin + + + process (load) + -- Variables for loading the memory + -- The reading is done by blocks + type bin is file of integer; -- Binary type file + file load_file : bin; + + variable c : integer ; -- Integer (32 bits) read in the file + variable index : integer range storage'range; -- Index for loading + variable word : bus32; -- Word read in the file + variable taille_bloc : integer; -- Current size of the block to load + variable tmp : bus16; + variable status : file_open_status; + + variable s : line; + variable big_endian : boolean := true; -- Define if the processor (on which we work) is little or big endian + begin + + if load='1' then + + -- Reading of the file de fill the memory at the defined address + file_open(status, load_file, fname, read_mode); + + if status=open_ok then + + while not endfile(load_file) loop + + -- Read the header of the block + read(load_file, c); -- Read a 32 bit long word + word := bus32(to_unsigned(c, 32)); -- Conversion to a bit vector + + if big_endian then + tmp := word(7 downto 0) & word(15 downto 8); + else + tmp := word(31 downto 16); + end if; + + index := to_integer(unsigned(tmp)); + adresse <= tmp; + + if big_endian then + tmp := word(23 downto 16) & word(31 downto 24); + else + tmp := word(15 downto 0); + end if; + + + taille_bloc := to_integer(unsigned(tmp)) / 4; + taille <= tmp; + + -- Load the block in the ROM + for n in 1 to taille_bloc loop + + -- The header file is not correct (block too small, ROM to small ...) + -- The simulation is stopped + assert (not endfile(load_file) and (index<=storage'high)) + report "L'image n'a pas le bon format ou ne rentre pas dans la rom." + severity error; + + if not endfile(load_file) and (index<=storage'high) then + read(load_file, c); + word := bus32(to_unsigned(c, 32)); + if (c < 0) then + word := not(word); + word := std_logic_vector(unsigned(word)+1); + end if; + for i in 0 to 3 loop + + if big_endian then + storage(index+i) <= word(8*(i+1)-1 downto 8*i); + else + storage(index+(3-i)) <= word(8*(i+1)-1 downto 8*i); + end if; + + end loop; + index := index + 4; + end if; + end loop; + + end loop; + + file_close(load_file); + + else + assert false + report "Impossible d'ouvrir le fichier specifie." + severity error; + + end if; + + end if; + + end process; + + + + + process(adr) -- Request for reading the ROM + variable inadr : integer; + variable i : natural; + begin + inadr := to_integer(unsigned(adr)); + + if (inadr>=storage'low) and (inadr<=storage'high) then + for i in 0 to 3 loop + donnee(8*(i+1)-1 downto 8*i) <= storage(inadr+3-i) after latency; + end loop; + ack <= '0', '1' after latency; + else + donnee <= (others => 'Z'); + ack <= 'L'; + end if; + end process; + +end bench; + + + Index: minimips/trunk/miniMIPS/src/pps_ei.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pps_ei.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pps_ei.vhd (revision 14) @@ -0,0 +1,109 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Instruction extraction stage -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity pps_ei is +port ( + clock : in std_logic; + reset : in std_logic; + clear : in std_logic; -- Clear the pipeline stage + stop_all : in std_logic; -- Evolution locking signal + + -- Asynchronous inputs + stop_ei : in std_logic; -- Lock the EI_adr and Ei_instr registers + + -- Bus controler interface + CTE_instr : in bus32; -- Instruction from the memory + ETC_adr : out bus32; -- Address to read in memory + + -- Synchronous inputs from PF stage + PF_pc : in bus32; -- Current value of the pc + + -- Synchronous outputs to DI stage + EI_instr : out bus32; -- Read interface + EI_adr : out bus32; -- Address from the read instruction + EI_it_ok : out std_logic -- Allow hardware interruptions +); +end pps_ei; + +architecture rtl of pps_ei is +begin + + ETC_adr <= PF_pc; -- Connexion of the PC to the memory address bus + + -- Set the results + process (clock) + begin + if (clock='1' and clock'event) then + if reset='1' then + EI_instr <= INS_NOP; + EI_adr <= (others => '0'); + EI_it_ok <= '0'; + elsif stop_all='0' then + if clear='1' then + -- Clear the stage + EI_instr <= INS_NOP; + EI_it_ok <= '0'; + elsif stop_ei='0' then + -- Normal evolution + EI_adr <= PF_pc; + EI_instr <= CTE_instr; + EI_it_ok <= '1'; + end if; + end if; + end if; + end process; +end rtl; Index: minimips/trunk/miniMIPS/src/pps_mem.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pps_mem.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pps_mem.vhd (revision 14) @@ -0,0 +1,149 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- Processor miniMIPS : Memory access stage -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + + + +library IEEE; +use IEEE.std_logic_1164.all; + +library work; +use work.pack_mips.all; + +entity pps_mem is +port +( + clock : in std_logic; + reset : in std_logic; + stop_all : in std_logic; -- Unconditionnal locking of the outputs + clear : in std_logic; -- Clear the pipeline stage + + -- Interface with the control bus + MTC_data : out bus32; -- Data to write in memory + MTC_adr : out bus32; -- Address for memory + MTC_r_w : out std_logic; -- Read/Write in memory + MTC_req : out std_logic; -- Request access to memory + CTM_data : in bus32; -- Data from memory + + -- Datas from Execution stage + EX_adr : in bus32; -- Instruction address + EX_data_ual : in bus32; -- Result of alu operation + EX_adresse : in bus32; -- Result of the calculation of the address + EX_adr_reg_dest : in adr_reg_type; -- Destination register address for the result + EX_ecr_reg : in std_logic; -- Effective writing of the result + EX_op_mem : in std_logic; -- Memory operation needed + EX_r_w : in std_logic; -- Type of memory operation (read or write) + EX_exc_cause : in bus32; -- Potential exception cause + EX_level : in level_type; -- Availability stage for the result for bypassing + EX_it_ok : in std_logic; -- Allow hardware interruptions + + -- Synchronous outputs for bypass unit + MEM_adr : out bus32; -- Instruction address + MEM_adr_reg_dest : out adr_reg_type; -- Destination register address + MEM_ecr_reg : out std_logic; -- Writing of the destination register + MEM_data_ecr : out bus32; -- Data to write (from alu or memory) + MEM_exc_cause : out bus32; -- Potential exception cause + MEM_level : out level_type; -- Availability stage for the result for bypassing + MEM_it_ok : out std_logic -- Allow hardware interruptions +); +end pps_mem; + + +architecture rtl of pps_mem is + + signal tmp_data_ecr : bus32; -- Selection of the data source (memory or alu) + +begin + + -- Bus controler connexions + MTC_adr <= EX_adresse; -- Connexion of the address + MTC_r_w <= EX_r_w; -- Connexion of R/W + MTC_data <= EX_data_ual; -- Connexion of the data bus + MTC_req <= EX_op_mem and not clear; -- Connexion of the request (if there is no clearing of the pipeline) + + + -- Preselection of the data source for the outputs + tmp_data_ecr <= CTM_data when EX_op_mem = '1' else EX_data_ual; + + + -- Set the synchronous outputs + process (clock) + begin + if clock = '1' and clock'event then + if reset = '1' then + MEM_adr <= (others => '0'); + MEM_adr_reg_dest <= (others => '0'); + MEM_ecr_reg <= '0'; + MEM_data_ecr <= (others => '0'); + MEM_exc_cause <= IT_NOEXC; + MEM_level <= LVL_DI; + MEM_it_ok <= '0'; + elsif stop_all = '0' then + if clear = '1' then -- Clear the stage + MEM_adr <= EX_adr; + MEM_adr_reg_dest <= (others => '0'); + MEM_ecr_reg <= '0'; + MEM_data_ecr <= (others => '0'); + MEM_exc_cause <= IT_NOEXC; + MEM_level <= LVL_DI; + MEM_it_ok <= '0'; + else -- Normal evolution + MEM_adr <= EX_adr; + MEM_adr_reg_dest <= EX_adr_reg_dest; + MEM_ecr_reg <= EX_ecr_reg; + MEM_data_ecr <= tmp_data_ecr; + MEM_exc_cause <= EX_exc_cause; + MEM_level <= EX_level; + MEM_it_ok <= EX_it_ok; + end if; + end if; + end if; + end process; + +end rtl; Index: minimips/trunk/miniMIPS/src/syscop.vhd =================================================================== --- minimips/trunk/miniMIPS/src/syscop.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/syscop.vhd (revision 14) @@ -0,0 +1,203 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Coprocessor system (cop0) -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +-- By convention in the commentary, the term interruption means hardware interruptions and software exceptions + +entity syscop is +port +( + clock : in std_logic; + reset : in std_logic; + + -- Datas from the pipeline + MEM_adr : in bus32; -- Address of the current instruction in the pipeline end -> responsible of the exception + MEM_exc_cause : in bus32; -- Potential cause exception of that instruction + MEM_it_ok : in std_logic; -- Allow hardware interruptions + + -- Hardware interruption + it_mat : in std_logic; -- Hardware interruption detected + + -- Interruption controls + interrupt : out std_logic; -- Interruption to take into account + vecteur_it : out bus32; -- Interruption vector + + -- Writing request in register bank + write_data : in bus32; -- Data to write + write_adr : in bus5; -- Address of the register to write + write_SCP : in std_logic; -- Writing request + + -- Reading request in register bank + read_adr1 : in bus5; -- Address of the first register + read_adr2 : in bus5; -- Address of the second register + read_data1 : out bus32; -- Value of register 1 + read_data2 : out bus32 -- Value of register 2 +); +end syscop; + + +architecture rtl of syscop is + + subtype adr_scp_reg is integer range 12 to 15; + + type scp_reg_type is array (integer range adr_scp_reg'low to adr_scp_reg'high) of bus32; + + -- Constants to define the coprocessor registers + constant COMMAND : integer := 0; -- False register to command the coprocessor system + constant STATUS : adr_scp_reg := 12; -- Registre 12 of the coprocessor system + constant CAUSE : adr_scp_reg := 13; -- Registre 13 of the coprocessor system + constant ADRESSE : adr_scp_reg := 14; -- Registre 14 of the coprocessor system + constant VECTIT : adr_scp_reg := 15; -- Registre 15 of the coprocessor system + + signal scp_reg : scp_reg_type; -- Internal register bank + signal pre_reg : scp_reg_type; -- Register bank preparation + + signal adr_src1 : integer range 0 to 31; + signal adr_src2 : integer range 0 to 31; + signal adr_dest : integer range 0 to 31; + + signal exception : std_logic; -- Set to '1' when exception detected + signal interruption : std_logic; -- Set to '1' when interruption detected + signal cmd_itret : std_logic; -- Set to '1' when interruption return command is detected + + signal save_msk : std_logic; -- Save the mask state when an interruption occurs + +begin + + -- Detection of the interruptions + exception <= '1' when MEM_exc_cause/=IT_NOEXC else '0'; + interruption <= '1' when it_mat='1' and scp_reg(STATUS)(0)='1' and MEM_it_ok='1' else '0'; + + -- Update asynchronous outputs + interrupt <= exception or interruption; -- Detection of interruptions + vecteur_it <= scp_reg(ADRESSE) when cmd_itret = '1' else -- Send the return adress when a return instruction appears + scp_reg(VECTIT); -- Send the interruption vector in other cases + + + -- Decode the address of the registers + adr_src1 <= to_integer(unsigned(read_adr1)); + adr_src2 <= to_integer(unsigned(read_adr2)); + adr_dest <= to_integer(unsigned(write_adr)); + + -- Read the two registers + read_data1 <= (others => '0') when (adr_src1scp_reg'high) else + scp_reg(adr_src1); + read_data2 <= (others => '0') when adr_src2scp_reg'high else + scp_reg(adr_src2); + + -- Define the pre_reg signal, next value for the registers + process (scp_reg, adr_dest, write_SCP, write_data, interruption, + exception, MEM_exc_cause, MEM_adr, reset) + begin + pre_reg <= scp_reg; + cmd_itret <= '0'; -- No IT return in most cases + + -- Potential writing in a register + if (write_SCP='1' and adr_dest>=pre_reg'low and adr_dest<=pre_reg'high) then + pre_reg(adr_dest) <= write_data; + end if; + + -- Command from the core + if write_SCP='1' and adr_dest=COMMAND then + case write_data is -- Different operations + when SYS_UNMASK => pre_reg(STATUS)(0) <= '1'; -- Unamsk command + when SYS_MASK => pre_reg(STATUS)(0) <= '0'; -- Mask command + when SYS_ITRET => -- Interruption return command + pre_reg(STATUS)(0) <= save_msk; -- Restore the mask before the interruption + cmd_itret <= '1'; -- False interruption request (to clear the pipeline) + when others => null; + end case; + end if; + + -- Modifications from the interruptions + if interruption='1' then + pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions + pre_reg(CAUSE) <= IT_ITMAT; -- Save the interruption cause + pre_reg(ADRESSE) <= MEM_adr; -- Save the return address + end if; + + -- Modifications from the exceptions + if exception='1' then + pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions + pre_reg(CAUSE) <= MEM_exc_cause; -- Save the exception cause + pre_reg(ADRESSE) <= MEM_adr; -- Save the return address + end if; + + -- The reset has the priority on the other cuases + if reset='1' then + pre_reg <= (others => (others => '0')); + -- NB : The processor is masked after a reset + -- The exception handler is set at address 0 + end if; + end process; + + -- Memorisation of the modifications in the register bank + process(clock) + begin + if clock='1' and clock'event then + + -- Save the mask when an interruption appears + if (exception='1') or (interruption='1') then + save_msk <= scp_reg(STATUS)(0); + end if; + + scp_reg <= pre_reg; + + end if; + end process; + +end rtl; Index: minimips/trunk/miniMIPS/src/alu.vhd =================================================================== --- minimips/trunk/miniMIPS/src/alu.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/alu.vhd (revision 14) @@ -0,0 +1,191 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Arithmetical and logical unit -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity alu is +port +( + clock : in bus1; + reset : in bus1; + op1 : in bus32; -- Operand 1 + op2 : in bus32; -- Operand 2 + ctrl : in alu_ctrl_type; -- Opearator control + + res : out bus32; -- The result is 32 bit long + overflow : out bus1 -- Overflow of the result +); +end alu; + + +architecture rtl of alu is + + -- Signals to pre-process the operands + signal efct_op1, efct_op2 : bus33; -- Effective operands of the adder (33 bits) + signal comp_op2 : bus1; -- Select the opposite of operand 2 + signal igno_op2 : bus1; -- Ignore op 2 (put zeros) + signal sign_op1 : bus1; -- High bit of op 1 + signal sign_op2 : bus1; -- High bit of op 2 + signal signe : bus1; -- Signed operation (bit sign extension) + signal shift_val : natural range 0 to 31; -- Value of the shift + + -- Signals for internal results + signal res_shl, res_shr : bus32; -- Results of left and right shifter + signal res_lui : bus32; -- Result of Load Upper Immediate + signal res_add : bus33; -- Result of the adder + signal carry : bus33; -- Carry for the adder + signal nul : bus1; -- Check if the adder result is zero + signal hilo : bus64; -- Internal registers to store the multiplication operation + signal tmp_hilo : bus64; -- Internal registers to store the multiplication operation (synchronised) + +begin + + -- Process if the operation is signed compliant + signe <= '1' when (ctrl=OP_ADD or ctrl=OP_SUB or ctrl=OP_SLT or ctrl=OP_SNEG or ctrl=OP_SPOS or ctrl=OP_LNEG or ctrl=OP_LPOS) + else + '0'; + + sign_op1 <= signe and op1(31); + sign_op2 <= signe and op2(31); + + -- Selection of the value of the second operand : op2 or -op2 (ie not op2 + 1) + comp_op2 <= '1' when -- The opposite of op2 is used + (ctrl=OP_SUB or ctrl=OP_SUBU) -- Opposite of the operand 2 to obtain a substraction + or (ctrl=OP_SLT or ctrl=OP_SLTU) -- Process the difference to check the lesser than operation for the operands + or (ctrl=OP_EQU or ctrl=OP_NEQU) -- Process the difference to check the equality of the operands + else + '0'; -- by default, op2 is used + + igno_op2 <= '1' when -- Op 2 will be zero (when comp_op2='0') + (ctrl=OP_SPOS or ctrl=OP_LNEG) -- Process if the op1 is nul with op1+0 + else + '0'; + + -- Effective signals for the adder + efct_op2 <= not (sign_op2 & op2) when (comp_op2='1') else -- We take the opposite of op2 to get -op2 (we will add 1 with the carry) + (others => '0') when (igno_op2='1') else -- Op2 is zero + (sign_op2 & op2); -- by default we use op2 (33 bits long) + + efct_op1 <= sign_op1 & op1; + + -- Execution of the addition + carry <= X"00000000" & comp_op2; -- Carry to one when -op2 is needed + res_add <= std_logic_vector(unsigned(efct_op1) + unsigned(efct_op2) + unsigned(carry)); + + nul <= '1' when (res_add(31 downto 0)=X"00000000") else '0'; -- Check the nullity of the result + + -- Value of the shift for the programmable shifter + shift_val <= to_integer(unsigned(op1(4 downto 0))); + + res_shl <= bus32(shift_left(unsigned(op2), shift_val)); + res_shr <= not bus32(shift_right(unsigned(not op2) , shift_val)) when (ctrl=OP_SRA and op2(31)='1') else + bus32(shift_right(unsigned(op2), shift_val)); + res_lui <= op2(15 downto 0) & X"0000"; + + -- Affectation of the hilo register if necessary + tmp_hilo <= std_logic_vector(signed(op1)*signed(op2)) when (ctrl=OP_MULT) else + std_logic_vector(unsigned(op1)*unsigned(op2)) when (ctrl=OP_MULTU) else + op1 & hilo(31 downto 0) when (ctrl=OP_MTHI) else + hilo(63 downto 32) & op1 when (ctrl=OP_MTLO) else + (others => '0'); + + -- Check the overflows + overflow <= '1' when ((ctrl=OP_ADD and op1(31)=efct_op2(31) and op1(31)/=res_add(31)) + or (ctrl=OP_SUB and op1(31)/=op2(31) and op1(31)/=res_add(31))) else + '0'; -- Only ADD and SUB can overflow + + -- Result affectation + res <= + -- Arithmetical operations + res_add(31 downto 0) when (ctrl=OP_ADD or ctrl=OP_ADDU or ctrl=OP_SUB or ctrl=OP_SUBU) else + -- Logical operations + op1 and op2 when (ctrl=OP_AND) else + op1 or op2 when (ctrl=OP_OR) else + op1 nor op2 when (ctrl=OP_NOR) else + op1 xor op2 when (ctrl=OP_XOR) else + -- Different tests : the result is one when the test is succesful + (0 => res_add(32), others=>'0') when (ctrl=OP_SLTU or ctrl=OP_SLT) else + (0 => nul, others=>'0') when (ctrl=OP_EQU) else + (0 => not nul, others=>'0') when (ctrl=OP_NEQU) else + (0 => op1(31), others=>'0') when (ctrl=OP_SNEG) else + (0 => not (op1(31) or nul), others=>'0') when (ctrl=OP_SPOS) else + (0 => (op1(31) or nul), others=>'0') when (ctrl=OP_LNEG) else + (0 => not op1(31), others=>'0') when (ctrl=OP_LPOS) else + -- Shifts + res_shl when (ctrl=OP_SLL) else + res_shr when (ctrl=OP_SRL or ctrl=OP_SRA) else + res_lui when (ctrl=OP_LUI) else + -- Internal registers + hilo(63 downto 32) when (ctrl=OP_MFHI) else + hilo(31 downto 0) when (ctrl=OP_MFLO or ctrl=OP_MULT or ctrl=OP_MULTU) else + op1 when (ctrl=OP_MTHI or ctrl=OP_MTLO) else + op2 when (ctrl=OP_OP2) else + -- Always true + X"00000001" when (ctrl=OP_OUI) else + -- Unknown operation or nul result desired + (others => '0'); + + -- Save the hilo register + process (clock) + begin + if clock = '1' and clock'event then + if reset = '1' then + hilo <= (others => '0'); + elsif (ctrl = OP_MULT) or (ctrl = OP_MULTU) or (ctrl = OP_MTLO) or (ctrl = OP_MTHI) then + hilo <= tmp_hilo; + end if; + end if; + end process; +end rtl; Index: minimips/trunk/miniMIPS/src/renvoi.vhd =================================================================== --- minimips/trunk/miniMIPS/src/renvoi.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/renvoi.vhd (revision 14) @@ -0,0 +1,176 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Bypass unit -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity renvoi is +port ( + -- Register access signals + adr1 : in adr_reg_type; -- Operand 1 address + adr2 : in adr_reg_type; -- Operand 2 address + use1 : in std_logic; -- Operand 1 utilisation + use2 : in std_logic; -- Operand 2 utilisation + + data1 : out bus32; -- First register value + data2 : out bus32; -- Second register value + alea : out std_logic; -- Unresolved hazards detected + + -- Bypass signals of the intermediary datas + DI_level : in level_type; -- Availability level of the data + DI_adr : in adr_reg_type; -- Register destination of the result + DI_ecr : in std_logic; -- Writing register request + DI_data : in bus32; -- Data to used + + EX_level : in level_type; -- Availability level of the data + EX_adr : in adr_reg_type; -- Register destination of the result + EX_ecr : in std_logic; -- Writing register request + EX_data : in bus32; -- Data to used + + MEM_level : in level_type; -- Availability level of the data + MEM_adr : in adr_reg_type; -- Register destination of the result + MEM_ecr : in std_logic; -- Writing register request + MEM_data : in bus32; -- Data to used + + interrupt : in std_logic; -- Exceptions or interruptions + + -- Connexion to the differents bank of register + + -- Writing commands for writing in the registers + write_data : out bus32; -- Data to write + write_adr : out bus5; -- Address of the register to write + write_GPR : out std_logic; -- Selection in the internal registers + write_SCP : out std_logic; -- Selection in the coprocessor system registers + + -- Reading commands for Reading in the registers + read_adr1 : out bus5; -- Address of the first register to read + read_adr2 : out bus5; -- Address of the second register to read + read_data1_GPR : in bus32; -- Value of operand 1 from the internal registers + read_data2_GPR : in bus32; -- Value of operand 2 from the internal registers + read_data1_SCP : in bus32; -- Value of operand 1 from the coprocessor system registers + read_data2_SCP : in bus32 -- Value of operand 2 from the coprocessor system registers +); +end renvoi; + +architecture rtl of renvoi is + signal dep_r1 : level_type; -- Dependency level for operand 1 + signal dep_r2 : level_type; -- Dependency level for operand 2 + signal read_data1 : bus32; -- Data contained in the register asked by operand 1 + signal read_data2 : bus32; -- Data contained in the register asked by operand 2 + signal res_reg, res_mem, res_ex, res_di : std_logic; + signal resolution : bus4; -- Verification of the resolved hazards + + signal idx1, idx2 : integer range 0 to 3; +begin + + -- Connexion of the writing command signals + write_data <= MEM_data; + write_adr <= MEM_adr(4 downto 0); + write_GPR <= not MEM_adr(5) and MEM_ecr when interrupt = '0' else -- The high bit to 0 selects the internal registers + '0'; + write_SCP <= MEM_adr(5) and MEM_ecr; -- The high bit to 1 selects the coprocessor system registers + + -- Connexion of the writing command signals + read_adr1 <= adr1(4 downto 0); -- Connexion of the significative address bits + read_adr2 <= adr2(4 downto 0); -- Connexion of the significative address bits + + -- Evaluation of the level of dependencies + dep_r1 <= LVL_REG when adr1(4 downto 0)="00000" or use1='0' else -- No dependency with register 0 + LVL_DI when adr1=DI_adr and DI_ecr ='1' else -- Dependency with DI stage + LVL_EX when adr1=EX_adr and EX_ecr ='1' else -- Dependency with DI stage + LVL_MEM when adr1=MEM_adr and MEM_ecr='1' else -- Dependency with DI stage + LVL_REG; -- No dependency detected + + dep_r2 <= LVL_REG when adr2(4 downto 0)="00000" or use2='0' else -- No dependency with register 0 + LVL_DI when adr2=DI_adr and DI_ecr ='1' else -- Dependency with DI stage + LVL_EX when adr2=EX_adr and EX_ecr ='1' else -- Dependency with DI stage + LVL_MEM when adr2=MEM_adr and MEM_ecr='1' else -- Dependency with DI stage + LVL_REG; -- No dependency detected + + -- Elaboration of the signals with the datas form the bank registers + read_data1 <= read_data1_GPR when adr1(5)='0' else -- Selection of the internal registers + read_data1_SCP when adr1(5)='1' else -- Selection of the coprocessor registers + (others => '0'); + + read_data2 <= read_data2_GPR when adr2(5)='0' else -- Selection of the internal registers + read_data2_SCP when adr2(5)='1' else -- Selection of the coprocessor registers + (others => '0'); + + -- Bypass the datas (the validity is tested later when detecting the hazards) + data1 <= read_data1 when dep_r1=LVL_REG else + MEM_data when dep_r1=LVL_MEM else + EX_data when dep_r1=LVL_EX else + DI_data; + + data2 <= read_data2 when dep_r2=LVL_REG else + MEM_data when dep_r2=LVL_MEM else + EX_data when dep_r2=LVL_EX else + DI_data; + + -- Detection of a potential unresolved hazard + res_reg <= '1'; -- This hazard is always resolved + res_mem <= '1' when MEM_level>=LVL_MEM else '0'; + res_ex <= '1' when EX_level >=LVL_EX else '0'; + res_di <= '1' when DI_level >=LVL_DI else '0'; + + -- Table defining the resolved hazard for each stage + resolution <= res_di & res_ex & res_mem & res_reg; + + -- Verification of the validity of the transmitted datas (test the good resolution of the hazards) + idx1 <= to_integer(unsigned(dep_r1(1 downto 0))); + idx2 <= to_integer(unsigned(dep_r2(1 downto 0))); + alea <= not resolution(idx1) or not resolution(idx2); + +end rtl; Index: minimips/trunk/miniMIPS/src/banc.vhd =================================================================== --- minimips/trunk/miniMIPS/src/banc.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/banc.vhd (revision 14) @@ -0,0 +1,115 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Register bank -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity banc is +port ( + clock : in bus1; + reset : in bus1; + + -- Register addresses to read + reg_src1 : in bus5; + reg_src2 : in bus5; + + -- Register address to write and its data + reg_dest : in bus5; + donnee : in bus32; + + -- Write signal + cmd_ecr : in bus1; + + -- Bank outputs + data_src1 : out bus32; + data_src2 : out bus32 + ); +end banc; + + +architecture rtl of banc is + + -- The register bank + type tab_reg is array (1 to 31) of bus32; + signal registres : tab_reg; + signal adr_src1 : integer range 0 to 31; + signal adr_src2 : integer range 0 to 31; + signal adr_dest : integer range 0 to 31; +begin + + adr_src1 <= to_integer(unsigned(reg_src1)); + adr_src2 <= to_integer(unsigned(reg_src2)); + adr_dest <= to_integer(unsigned(reg_dest)); + + + data_src1 <= (others => '0') when adr_src1=0 else + registres(adr_src1); + data_src2 <= (others => '0') when adr_src2=0 else + registres(adr_src2); + + process(clock) + begin + if clock = '1' and clock'event then + if reset='1' then + for i in 1 to 31 loop + registres(i) <= (others => '0'); + end loop; + elsif cmd_ecr = '1' and adr_dest /= 0 then + -- The data is saved + registres(adr_dest) <= donnee; + end if; + end if; + end process; + +end rtl; Index: minimips/trunk/miniMIPS/src/minimips.vhd =================================================================== --- minimips/trunk/miniMIPS/src/minimips.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/minimips.vhd (revision 14) @@ -0,0 +1,496 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : miniMIPS processor -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2004 -- +-------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.pack_mips.all; + +entity minimips is +port ( + clock : in std_logic; + reset : in std_logic; + + -- Ram connexion + ram_req : out std_logic; + ram_adr : out bus32; + ram_r_w : out std_logic; + ram_data : inout bus32; + ram_ack : in std_logic; + + -- Hardware interruption + it_mat : in std_logic +); +end minimips; + +architecture rtl of minimips is + + -- General signals + signal stop_all : std_logic; -- Lock the pipeline evolution + signal it_mat_clk : std_logic; -- Synchronised hardware interruption + + -- interface PF - EI + signal PF_pc : bus32; -- PC value + + -- interface Controler - EI + signal CTE_instr : bus32; -- Instruction from the memory + signal ETC_adr : bus32; -- Address to read in memory + + -- interface EI - DI + signal EI_instr : bus32; -- Read interface + signal EI_adr : bus32; -- Address from the read instruction + signal EI_it_ok : std_logic; -- Allow hardware interruptions + + -- Asynchronous connexion with the bypass unit + signal adr_reg1 : adr_reg_type; -- Operand 1 address + signal adr_reg2 : adr_reg_type; -- Operand 2 address + signal use1 : std_logic; -- Operand 1 utilisation + signal use2 : std_logic; -- Operand 2 utilisation + signal data1 : bus32; -- First register value + signal data2 : bus32; -- Second register value + signal alea : std_logic; -- Unresolved hazards detected + + + -- interface DI - EX + signal DI_bra : std_logic; -- Branch decoded + signal DI_link : std_logic; -- A link for that instruction + signal DI_op1 : bus32; -- operand 1 for alu + signal DI_op2 : bus32; -- operand 2 for alu + signal DI_code_ual : alu_ctrl_type; -- Alu operation + signal DI_offset : bus32; -- Offset for the address calculation + signal DI_adr_reg_dest : adr_reg_type; -- Address of the destination register of the result + signal DI_ecr_reg : std_logic; -- Effective writing of the result + signal DI_mode : std_logic; -- Address mode (relative to pc or indexed to a register) + signal DI_op_mem : std_logic; -- Memory operation request + signal DI_r_w : std_logic; -- Type of memory operation (reading or writing) + signal DI_adr : bus32; -- Address of the decoded instruction + signal DI_exc_cause : bus32; -- Potential exception detected + signal DI_level : level_type; -- Availability of the result for the data bypass + signal DI_it_ok : std_logic; -- Allow hardware interruptions + + -- interface EX - MEM + signal EX_adr : bus32; -- Instruction address + signal EX_bra_confirm : std_logic; -- Branch execution confirmation + signal EX_data_ual : bus32; -- Ual result + signal EX_adresse : bus32; -- Address calculation result + signal EX_adr_reg_dest : adr_reg_type; -- Destination register for the result + signal EX_ecr_reg : std_logic; -- Effective writing of the result + signal EX_op_mem : std_logic; -- Memory operation needed + signal EX_r_w : std_logic; -- Type of memory operation (read or write) + signal EX_exc_cause : bus32; -- Potential cause exception + signal EX_level : level_type; -- Availability stage of result for bypassing + signal EX_it_ok : std_logic; -- Allow hardware interruptions + + -- interface Controler - MEM + signal MTC_data : bus32; -- Data to write in memory + signal MTC_adr : bus32; -- Address for memory + signal MTC_r_w : std_logic; -- Read/Write in memory + signal MTC_req : std_logic; -- Request access to memory + signal CTM_data : bus32; -- Data from memory + + -- interface MEM - REG + signal MEM_adr : bus32; -- Instruction address + signal MEM_adr_reg_dest : adr_reg_type; -- Destination register address + signal MEM_ecr_reg : std_logic; -- Writing of the destination register + signal MEM_data_ecr : bus32; -- Data to write (from alu or memory) + signal MEM_exc_cause : bus32; -- Potential exception cause + signal MEM_level : level_type; -- Availability stage for the result for bypassing + signal MEM_it_ok : std_logic; -- Allow hardware interruptions + + -- connexion to the register banks + + -- Writing commands in the register banks + signal write_data : bus32; -- Data to write + signal write_adr : bus5; -- Address of the register to write + signal write_GPR : std_logic; -- Selection in the internal registers + signal write_SCP : std_logic; -- Selection in the coprocessor system registers + + -- Reading commands for Reading in the registers + signal read_adr1 : bus5; -- Address of the first register to read + signal read_adr2 : bus5; -- Address of the second register to read + signal read_data1_GPR : bus32; -- Value of operand 1 from the internal registers + signal read_data1_SCP : bus32; -- Value of operand 2 from the internal registers + signal read_data2_GPR : bus32; -- Value of operand 1 from the coprocessor system registers + signal read_data2_SCP : bus32; -- Value of operand 2 from the coprocessor system registers + + -- Interruption controls + signal interrupt : std_logic; -- Interruption to take into account + signal vecteur_it : bus32; -- Interruption vector + + -- Connexion with predict + signal PR_bra_cmd : std_logic; -- Defined a branch + signal PR_bra_bad : std_logic; -- Defined a branch to restore from a bad prediction + signal PR_bra_adr : std_logic_vector(31 downto 0); -- New PC + signal PR_clear : std_logic; -- Clear the three pipeline stage : EI, DI, EX + + -- Clear asserted when interrupt or PR_clear are asserted + signal clear : std_logic; + +begin + + clear <= interrupt or PR_clear; + + -- Take into account the hardware interruption on rising edge + process (clock) + begin + if clock='1' and clock'event then + it_mat_clk <= it_mat; + end if; + end process; + + U1_pf : pps_pf port map ( + clock => clock, + reset => reset, + stop_all => stop_all, -- Unconditionnal locking of the pipeline stage + + -- entrees asynchrones + bra_adr => PR_bra_adr, -- Branch + bra_cmd => PR_bra_cmd, -- Address to load when an effective branch + bra_cmd_pr => PR_bra_bad, -- Branch which have a priority on stop_pf (bad prediction branch) + exch_adr => vecteur_it, -- Exception branch + exch_cmd => interrupt, -- Exception vector + -- Lock the stage + stop_pf => alea, + + -- Synchronous output to EI stage + PF_pc => PF_pc -- PC value + ); + + + U2_ei : pps_ei port map ( + clock => clock, + reset => reset, + clear => clear, -- Clear the pipeline stage + stop_all => stop_all, -- Evolution locking signal + + -- Asynchronous inputs + stop_ei => alea, -- Lock the EI_adr and Ei_instr registers + + -- interface Controler - EI + CTE_instr => CTE_instr, -- Instruction from the memory + ETC_adr => ETC_adr, -- Address to read in memory + + -- Synchronous inputs from PF stage + PF_pc => PF_pc, -- Current value of the pc + + -- Synchronous outputs to DI stage + EI_instr => EI_instr, -- Read interface + EI_adr => EI_adr, -- Address from the read instruction + EI_it_ok => EI_it_ok -- Allow hardware interruptions + ); + + + U3_di : pps_di port map ( + clock => clock, + reset => reset, + stop_all => stop_all, -- Unconditionnal locking of the outputs + clear => clear, -- Clear the pipeline stage (nop in the outputs) + + -- Asynchronous connexion with the register management and data bypass unit + adr_reg1 => adr_reg1, -- Address of the first register operand + adr_reg2 => adr_reg2, -- Address of the second register operand + use1 => use1, -- Effective use of operand 1 + use2 => use2, -- Effective use of operand 2 + + stop_di => alea, -- Unresolved detected : send nop in the pipeline + data1 => data1, -- Operand register 1 + data2 => data2, -- Operand register 2 + + -- Datas from EI stage + EI_adr => EI_adr, -- Address of the instruction + EI_instr => EI_instr, -- The instruction to decode + EI_it_ok => EI_it_ok, -- Allow hardware interruptions + + -- Synchronous output to EX stage + DI_bra => DI_bra, -- Branch decoded + DI_link => DI_link, -- A link for that instruction + DI_op1 => DI_op1, -- operand 1 for alu + DI_op2 => DI_op2, -- operand 2 for alu + DI_code_ual => DI_code_ual, -- Alu operation + DI_offset => DI_offset, -- Offset for the address calculation + DI_adr_reg_dest => DI_adr_reg_dest, -- Address of the destination register of the result + DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result + DI_mode => DI_mode, -- Address mode (relative to pc or indexed to a register) + DI_op_mem => DI_op_mem, -- Memory operation request + DI_r_w => DI_r_w, -- Type of memory operation (reading or writing) + DI_adr => DI_adr, -- Address of the decoded instruction + DI_exc_cause => DI_exc_cause, -- Potential exception detected + DI_level => DI_level, -- Availability of the result for the data bypass + DI_it_ok => DI_it_ok -- Allow hardware interruptions + ); + + + U4_ex : pps_ex port map ( + clock => clock, + reset => reset, + stop_all => stop_all, -- Unconditionnal locking of outputs + clear => clear, -- Clear the pipeline stage + + -- Datas from DI stage + DI_bra => DI_bra, -- Branch instruction + DI_link => DI_link, -- Branch with link + DI_op1 => DI_op1, -- Operand 1 for alu + DI_op2 => DI_op2, -- Operand 2 for alu + DI_code_ual => DI_code_ual, -- Alu operation + DI_offset => DI_offset, -- Offset for address calculation + DI_adr_reg_dest => DI_adr_reg_dest, -- Destination register address for the result + DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result + DI_mode => DI_mode, -- Address mode (relative to pc ou index by a register) + DI_op_mem => DI_op_mem, -- Memory operation + DI_r_w => DI_r_w, -- Type of memory operation (read or write) + DI_adr => DI_adr, -- Instruction address + DI_exc_cause => DI_exc_cause, -- Potential cause exception + DI_level => DI_level, -- Availability stage of the result for bypassing + DI_it_ok => DI_it_ok, -- Allow hardware interruptions + + -- Synchronous outputs to MEM stage + EX_adr => EX_adr, -- Instruction address + EX_bra_confirm => EX_bra_confirm, -- Branch execution confirmation + EX_data_ual => EX_data_ual, -- Ual result + EX_adresse => EX_adresse, -- Address calculation result + EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register for the result + EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result + EX_op_mem => EX_op_mem, -- Memory operation needed + EX_r_w => EX_r_w, -- Type of memory operation (read or write) + EX_exc_cause => EX_exc_cause, -- Potential cause exception + EX_level => EX_level, -- Availability stage of result for bypassing + EX_it_ok => EX_it_ok -- Allow hardware interruptions + ); + + + U5_mem : pps_mem port map ( + clock => clock, + reset => reset, + stop_all => stop_all, -- Unconditionnal locking of the outputs + clear => interrupt, -- Clear the pipeline stage + + -- Interface with the control bus + MTC_data => MTC_data, -- Data to write in memory + MTC_adr => MTC_adr, -- Address for memory + MTC_r_w => MTC_r_w, -- Read/Write in memory + MTC_req => MTC_req, -- Request access to memory + CTM_data => CTM_data, -- Data from memory + + -- Datas from Execution stage + EX_adr => EX_adr, -- Instruction address + EX_data_ual => EX_data_ual, -- Result of alu operation + EX_adresse => EX_adresse, -- Result of the calculation of the address + EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register address for the result + EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result + EX_op_mem => EX_op_mem, -- Memory operation needed + EX_r_w => EX_r_w, -- Type of memory operation (read or write) + EX_exc_cause => EX_exc_cause, -- Potential exception cause + EX_level => EX_level, -- Availability stage for the result for bypassing + EX_it_ok => EX_it_ok, -- Allow hardware interruptions + + -- Synchronous outputs for bypass unit + MEM_adr => MEM_adr, -- Instruction address + MEM_adr_reg_dest=>MEM_adr_reg_dest, -- Destination register address + MEM_ecr_reg => MEM_ecr_reg, -- Writing of the destination register + MEM_data_ecr => MEM_data_ecr, -- Data to write (from alu or memory) + MEM_exc_cause => MEM_exc_cause, -- Potential exception cause + MEM_level => MEM_level, -- Availability stage for the result for bypassing + MEM_it_ok => MEM_it_ok -- Allow hardware interruptions + ); + + + U6_renvoi : renvoi port map ( + -- Register access signals + adr1 => adr_reg1, -- Operand 1 address + adr2 => adr_reg2, -- Operand 2 address + use1 => use1, -- Operand 1 utilisation + use2 => use2, -- Operand 2 utilisation + + data1 => data1, -- First register value + data2 => data2, -- Second register value + alea => alea, -- Unresolved hazards detected + + -- Bypass signals of the intermediary datas + DI_level => DI_level, -- Availability level of the data + DI_adr => DI_adr_reg_dest, -- Register destination of the result + DI_ecr => DI_ecr_reg, -- Writing register request + DI_data => DI_op2, -- Data to used + + EX_level => EX_level, -- Availability level of the data + EX_adr => EX_adr_reg_dest, -- Register destination of the result + EX_ecr => EX_ecr_reg, -- Writing register request + EX_data => EX_data_ual, -- Data to used + + MEM_level => MEM_level, -- Availability level of the data + MEM_adr => MEM_adr_reg_dest, -- Register destination of the result + MEM_ecr => MEM_ecr_reg, -- Writing register request + MEM_data => MEM_data_ecr, -- Data to used + + interrupt => interrupt, -- Exceptions or interruptions + + -- Connexion to the differents bank of register + + -- Writing commands for writing in the registers + write_data => write_data, -- Data to write + write_adr => write_adr, -- Address of the register to write + write_GPR => write_GPR, -- Selection in the internal registers + write_SCP => write_SCP, -- Selection in the coprocessor system registers + + -- Reading commands for Reading in the registers + read_adr1 => read_adr1, -- Address of the first register to read + read_adr2 => read_adr2, -- Address of the second register to read + read_data1_GPR => read_data1_GPR, -- Value of operand 1 from the internal registers + read_data1_SCP => read_data1_SCP, -- Value of operand 2 from the internal registers + read_data2_GPR => read_data2_GPR, -- Value of operand 1 from the coprocessor system registers + read_data2_SCP => read_data2_SCP -- Value of operand 2 from the coprocessor system registers + ); + + + U7_banc : banc port map( + clock => clock, + reset => reset, + + -- Register addresses to read + reg_src1 => read_adr1, + reg_src2 => read_adr2, + + -- Register address to write and its data + reg_dest => write_adr, + donnee => write_data, + + -- Write signal + cmd_ecr => write_GPR, + + -- Bank outputs + data_src1 => read_data1_GPR, + data_src2 => read_data2_GPR + ); + + + U8_syscop : syscop port map ( + clock => clock, + reset => reset, + + -- Datas from the pipeline + MEM_adr => MEM_adr, -- Address of the current instruction in the pipeline end -> responsible of the exception + MEM_exc_cause => MEM_exc_cause, -- Potential cause exception of that instruction + MEM_it_ok => MEM_it_ok, -- Allow hardware interruptions + + -- Hardware interruption + it_mat => it_mat_clk, -- Hardware interruption detected + + -- Interruption controls + interrupt => interrupt, -- Interruption to take into account + vecteur_it => vecteur_it, -- Interruption vector + + -- Writing request in register bank + write_data => write_data, -- Data to write + write_adr => write_adr, -- Address of the register to write + write_SCP => write_SCP, -- Writing request + + -- Reading request in register bank + read_adr1 => read_adr1, -- Address of the first register + read_adr2 => read_adr2, -- Address of the second register + read_data1 => read_data1_SCP, -- Value of register 1 + read_data2 => read_data2_SCP -- Value of register 2 + ); + + + U9_bus_ctrl : bus_ctrl port map ( + clock => clock, + reset => reset, + + -- Interruption in the pipeline + interrupt => interrupt, + + -- Interface for the Instruction Extraction Stage + adr_from_ei => ETC_adr, -- The address of the data to read + instr_to_ei => CTE_instr, -- Instruction from the memory + + -- Interface with the MEMory Stage + req_from_mem => MTC_req, -- Request to access the ram + r_w_from_mem => MTC_r_w, -- Read/Write request + adr_from_mem => MTC_adr, -- Address in ram + data_from_mem => MTC_data, -- Data to write in ram + data_to_mem => CTM_data, -- Data from the ram to the MEMory stage + + -- RAM interface signals + req_to_ram => ram_req, -- Request to ram + adr_to_ram => ram_adr, -- Address of the data to read or write + r_w_to_ram => ram_r_w, -- Read/Write request + ack_from_ram => ram_ack, -- Acknowledge from the memory + data_inout_ram => ram_data, -- Data from/to the memory + + -- Pipeline progress control signal + stop_all => stop_all + ); + + U10_predict : predict port map ( + clock => clock, + reset => reset, + + -- Datas from PF pipeline stage + PF_pc => PF_pc, -- PC of the current instruction extracted + + -- Datas from DI pipeline stage + DI_bra => DI_bra, -- Branch detected + DI_adr => DI_adr, -- Address of the branch + + -- Datas from EX pipeline stage + EX_bra_confirm => EX_bra_confirm, -- Confirm if the branch test is ok + EX_adr => EX_adr, -- Address of the branch + EX_adresse => EX_adresse, -- Result of the branch + EX_uncleared => EX_it_ok, -- Define if the EX stage is cleared + + -- Outputs to PF pipeline stage + PR_bra_cmd => PR_bra_cmd, -- Defined a branch + PR_bra_bad => PR_bra_bad, -- Defined a branch to restore from a bad prediction + PR_bra_adr => PR_bra_adr, -- New PC + + -- Clear the three pipeline stage : EI, DI, EX + PR_clear => PR_clear + ); + +end rtl; Index: minimips/trunk/miniMIPS/src/pack_mips.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pack_mips.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pack_mips.vhd (revision 14) @@ -0,0 +1,471 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- Processor miniMIPS : Enumerations and components declarations -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; + +package pack_mips is + + -- Type signal on n bits + subtype bus64 is std_logic_vector(63 downto 0); + subtype bus33 is std_logic_vector(32 downto 0); + subtype bus32 is std_logic_vector(31 downto 0); + subtype bus31 is std_logic_vector(30 downto 0); + subtype bus26 is std_logic_vector(25 downto 0); + subtype bus24 is std_logic_vector(23 downto 0); + subtype bus16 is std_logic_vector(15 downto 0); + subtype bus8 is std_logic_vector(7 downto 0); + subtype bus6 is std_logic_vector(5 downto 0); + subtype bus5 is std_logic_vector(4 downto 0); + subtype bus4 is std_logic_vector(3 downto 0); + subtype bus2 is std_logic_vector(1 downto 0); + subtype bus1 is std_logic; + + -- Address of a register type + subtype adr_reg_type is std_logic_vector(5 downto 0); + + -- Coding of the level of data availability for UR + subtype level_type is std_logic_vector(1 downto 0); + constant LVL_DI : level_type := "11"; -- Data available from the op2 of DI stage + constant LVL_EX : level_type := "10"; -- Data available from the data_ual register of EX stage + constant LVL_MEM : level_type := "01"; -- Data available from the data_ecr register of MEM stage + constant LVL_REG : level_type := "00"; -- Data available only in the register bank + + -- Different values of cause exceptions + constant IT_NOEXC : bus32 := X"00000000"; + constant IT_ITMAT : bus32 := X"00000001"; + constant IT_OVERF : bus32 := X"00000002"; + constant IT_ERINS : bus32 := X"00000004"; + constant IT_BREAK : bus32 := X"00000008"; + constant IT_SCALL : bus32 := X"00000010"; + + + -- Operation type of the coprocessor system (only the low 16 bits are valid) + constant SYS_NOP : bus32 := X"0000_0000"; + constant SYS_MASK : bus32 := X"0000_0001"; + constant SYS_UNMASK : bus32 := X"0000_0002"; + constant SYS_ITRET : bus32 := X"0000_0004"; + + -- Type for the alu control + subtype alu_ctrl_type is std_logic_vector(27 downto 0); + + -- Arithmetical operations + constant OP_ADD : alu_ctrl_type := "1000000000000000000000000000"; -- op1 + op2 sign‰ + constant OP_ADDU : alu_ctrl_type := "0100000000000000000000000000"; -- op1 + op2 non sign‰ + constant OP_SUB : alu_ctrl_type := "0010000000000000000000000000"; -- op1 - op2 sign‰ + constant OP_SUBU : alu_ctrl_type := "0001000000000000000000000000"; -- op1 - op2 non sign‰e + -- Logical operations + constant OP_AND : alu_ctrl_type := "0000100000000000000000000000"; -- et logique + constant OP_OR : alu_ctrl_type := "0000010000000000000000000000"; -- ou logique + constant OP_XOR : alu_ctrl_type := "0000001000000000000000000000"; -- ou exclusif logique + constant OP_NOR : alu_ctrl_type := "0000000100000000000000000000"; -- non ou logique + -- Tests : result to one if ok + constant OP_SLT : alu_ctrl_type := "0000000010000000000000000000"; -- op1 < op2 (sign‰) + constant OP_SLTU : alu_ctrl_type := "0000000001000000000000000000"; -- op1 < op2 (non sign‰) + constant OP_EQU : alu_ctrl_type := "0000000000100000000000000000"; -- op1 = op2 + constant OP_NEQU : alu_ctrl_type := "0000000000010000000000000000"; -- op1 /= op2 + constant OP_SNEG : alu_ctrl_type := "0000000000001000000000000000"; -- op1 < 0 + constant OP_SPOS : alu_ctrl_type := "0000000000000100000000000000"; -- op1 > 0 + constant OP_LNEG : alu_ctrl_type := "0000000000000010000000000000"; -- op1 <= 0 + constant OP_LPOS : alu_ctrl_type := "0000000000000001000000000000"; -- op1 >= 0 + -- Multiplications + constant OP_MULT : alu_ctrl_type := "0000000000000000100000000000"; -- op1 * op2 sign‰ (chargement des poids faibles) + constant OP_MULTU : alu_ctrl_type := "0000000000000000010000000000"; -- op1 * op2 non sign‰ (chargement des poids faibles) + -- Shifts + constant OP_SLL : alu_ctrl_type := "0000000000000000001000000000"; -- decallage logique a gauche + constant OP_SRL : alu_ctrl_type := "0000000000000000000100000000"; -- decallage logique a droite + constant OP_SRA : alu_ctrl_type := "0000000000000000000010000000"; -- decallage arithmetique a droite + constant OP_LUI : alu_ctrl_type := "0000000000000000000001000000"; -- met en poids fort la valeur immediate + -- Access to internal registers + constant OP_MFHI : alu_ctrl_type := "0000000000000000000000100000"; -- lecture des poids forts + constant OP_MFLO : alu_ctrl_type := "0000000000000000000000010000"; -- lecture des poids faibles + constant OP_MTHI : alu_ctrl_type := "0000000000000000000000001000"; -- ecriture des poids forts + constant OP_MTLO : alu_ctrl_type := "0000000000000000000000000100"; -- ecriture des poids faibles + -- Operations which do nothing but are useful + constant OP_OUI : alu_ctrl_type := "0000000000000000000000000010"; -- met a 1 le bit de poids faible en sortie + constant OP_OP2 : alu_ctrl_type := "0000000000000000000000000001"; -- recopie l'operande 2 en sortie + + + + -- Starting boot address (after reset) + constant ADR_INIT : bus32 := X"00000000"; + constant INS_NOP : bus32 := X"00000000"; + + + -- Internal component of the pipeline stage + + component alu + port ( + clock : in bus1; + reset : in bus1; + op1 : in bus32; + op2 : in bus32; + ctrl : in alu_ctrl_type; + + res : out bus32; + overflow : out bus1 + ); + end component; + + -- Pipeline stage components + + component pps_pf + port ( + clock : in bus1; + reset : in bus1; + stop_all : in bus1; + + bra_cmd : in bus1; + bra_cmd_pr : in bus1; + bra_adr : in bus32; + exch_cmd : in bus1; + exch_adr : in bus32; + + stop_pf : in bus1; + + PF_pc : out bus32 + ); + end component; + + + component pps_ei + port ( + clock : in bus1; + reset : in bus1; + clear : in bus1; + stop_all : in bus1; + + stop_ei : in bus1; + + CTE_instr : in bus32; + ETC_adr : out bus32; + + PF_pc : in bus32; + + EI_instr : out bus32; + EI_adr : out bus32; + EI_it_ok : out bus1 + ); + end component; + + + component pps_di + port ( + clock : in bus1; + reset : in bus1; + stop_all : in bus1; + clear : in bus1; + + adr_reg1 : out adr_reg_type; + adr_reg2 : out adr_reg_type; + use1 : out bus1; + use2 : out bus1; + + stop_di : in bus1; + data1 : in bus32; + data2 : in bus32; + + EI_adr : in bus32; + EI_instr : in bus32; + EI_it_ok : in bus1; + + DI_bra : out bus1; + DI_link : out bus1; + DI_op1 : out bus32; + DI_op2 : out bus32; + DI_code_ual : out alu_ctrl_type; + DI_offset : out bus32; + DI_adr_reg_dest : out adr_reg_type; + DI_ecr_reg : out bus1; + DI_mode : out bus1; + DI_op_mem : out bus1; + DI_r_w : out bus1; + DI_adr : out bus32; + DI_exc_cause : out bus32; + DI_level : out level_type; + DI_it_ok : out bus1 + ); + end component; + + + component pps_ex + port ( + clock : in bus1; + reset : in bus1; + stop_all : in bus1; + clear : in bus1; + + DI_bra : in bus1; + DI_link : in bus1; + DI_op1 : in bus32; + DI_op2 : in bus32; + DI_code_ual : in alu_ctrl_type; + DI_offset : in bus32; + DI_adr_reg_dest : in adr_reg_type; + DI_ecr_reg : in bus1; + DI_mode : in bus1; + DI_op_mem : in bus1; + DI_r_w : in bus1; + DI_adr : in bus32; + DI_exc_cause : in bus32; + DI_level : in level_type; + DI_it_ok : in bus1; + + EX_adr : out bus32; + EX_bra_confirm : out bus1; + EX_data_ual : out bus32; + EX_adresse : out bus32; + EX_adr_reg_dest : out adr_reg_type; + EX_ecr_reg : out bus1; + EX_op_mem : out bus1; + EX_r_w : out bus1; + EX_exc_cause : out bus32; + EX_level : out level_type; + EX_it_ok : out bus1 + ); + end component; + + + component pps_mem + port ( + clock : in bus1; + reset : in bus1; + stop_all : in bus1; + clear : in bus1; + + MTC_data : out bus32; + MTC_adr : out bus32; + MTC_r_w : out bus1; + MTC_req : out bus1; + CTM_data : in bus32; + + EX_adr : in bus32; + EX_data_ual : in bus32; + EX_adresse : in bus32; + EX_adr_reg_dest : in adr_reg_type; + EX_ecr_reg : in bus1; + EX_op_mem : in bus1; + EX_r_w : in bus1; + EX_exc_cause : in bus32; + EX_level : in level_type; + EX_it_ok : in bus1; + + MEM_adr : out bus32; + MEM_adr_reg_dest : out adr_reg_type; + MEM_ecr_reg : out bus1; + MEM_data_ecr : out bus32; + MEM_exc_cause : out bus32; + MEM_level : out level_type; + MEM_it_ok : out bus1 + ); + end component; + + + component renvoi + port ( + adr1 : in adr_reg_type; + adr2 : in adr_reg_type; + use1 : in bus1; + use2 : in bus1; + + data1 : out bus32; + data2 : out bus32; + alea : out bus1; + + DI_level : in level_type; + DI_adr : in adr_reg_type; + DI_ecr : in bus1; + DI_data : in bus32; + + EX_level : in level_type; + EX_adr : in adr_reg_type; + EX_ecr : in bus1; + EX_data : in bus32; + + MEM_level : in level_type; + MEM_adr : in adr_reg_type; + MEM_ecr : in bus1; + MEM_data : in bus32; + + interrupt : in bus1; + + write_data : out bus32; + write_adr : out bus5; + write_GPR : out bus1; + write_SCP : out bus1; + + read_adr1 : out bus5; + read_adr2 : out bus5; + read_data1_GPR : in bus32; + read_data1_SCP : in bus32; + read_data2_GPR : in bus32; + read_data2_SCP : in bus32 + ); + end component; + + + component banc + port ( + clock : in bus1; + reset : bus1; + + reg_src1 : in bus5; + reg_src2 : in bus5; + + reg_dest : in bus5; + donnee : in bus32; + + cmd_ecr : in bus1; + + data_src1 : out bus32; + data_src2 : out bus32 + ); + end component; + + + component bus_ctrl + port + ( + clock : bus1; + reset : bus1; + + interrupt : in std_logic; + + adr_from_ei : in bus32; + instr_to_ei : out bus32; + + req_from_mem : in bus1; + r_w_from_mem : in bus1; + adr_from_mem : in bus32; + data_from_mem : in bus32; + data_to_mem : out bus32; + + req_to_ram : out std_logic; + adr_to_ram : out bus32; + r_w_to_ram : out bus1; + ack_from_ram : in bus1; + data_inout_ram : inout bus32; + + stop_all : out bus1 + ); + end component; + + + component syscop + port + ( + clock : in bus1; + reset : in bus1; + + MEM_adr : in bus32; + MEM_exc_cause : in bus32; + MEM_it_ok : in bus1; + + it_mat : in bus1; + + interrupt : out bus1; + vecteur_it : out bus32; + + write_data : in bus32; + write_adr : in bus5; + write_SCP : in bus1; + + read_adr1 : in bus5; + read_adr2 : in bus5; + read_data1 : out bus32; + read_data2 : out bus32 + ); + end component; + + component predict + generic ( + nb_record : integer := 3 + ); + port ( + + clock : in std_logic; + reset : in std_logic; + + PF_pc : in std_logic_vector(31 downto 0); + + DI_bra : in std_logic; + DI_adr : in std_logic_vector(31 downto 0); + + EX_bra_confirm : in std_logic; + EX_adr : in std_logic_vector(31 downto 0); + EX_adresse : in std_logic_vector(31 downto 0); + EX_uncleared : in std_logic; + + PR_bra_cmd : out std_logic; + PR_bra_bad : out std_logic; + PR_bra_adr : out std_logic_vector(31 downto 0); + + PR_clear : out std_logic + ); + end component; + + + component minimips + port ( + clock : in bus1; + reset : in bus1; + + ram_req : out bus1; + ram_adr : out bus32; + ram_r_w : out bus1; + ram_data : inout bus32; + ram_ack : in bus1; + + it_mat : in bus1 + ); + end component; + +end pack_mips; Index: minimips/trunk/miniMIPS/src/pps_pf.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pps_pf.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pps_pf.vhd (revision 14) @@ -0,0 +1,115 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Address calculation stage -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity pps_pf is +port ( + clock : in bus1; + reset : in bus1; + stop_all : in bus1; -- Unconditionnal locking of the pipeline stage + + -- Asynchronous inputs + bra_cmd : in bus1; -- Branch + bra_cmd_pr : in bus1; -- Branch which have a priority on stop_pf (bad prediction branch) + bra_adr : in bus32; -- Address to load when an effective branch + exch_cmd : in bus1; -- Exception branch + exch_adr : in bus32; -- Exception vector + stop_pf : in bus1; -- Lock the stage + + -- Synchronous output to EI stage + PF_pc : out bus32 -- PC value +); +end pps_pf; + +architecture rtl of pps_pf is + + signal suivant : bus32; -- Preparation of the future pc + signal pc_interne : bus32; -- Value of the pc output, needed for an internal reading + signal lock : bus1; -- Specify the authorization of the pc evolution + +begin + + -- Connexion the pc to the internal pc + PF_pc <= pc_interne; + + -- Elaboration of an potential future pc + suivant <= exch_adr when exch_cmd='1' else + bra_adr when bra_cmd_pr='1' else + bra_adr when bra_cmd='1' else + bus32(unsigned(pc_interne) + 4); + + lock <= '1' when stop_all='1' else -- Lock this stage when all the pipeline is locked + '0' when exch_cmd='1' else -- Exception + '0' when bra_cmd_pr='1' else -- Bad prediction restoration + '1' when stop_pf='1' else -- Wait for the data hazard + '0' when bra_cmd='1' else -- Branch + '0'; -- Normal evolution + + -- Synchronous evolution of the pc + process(clock) + begin + if clock='1' and clock'event then + if reset='1' then + -- PC reinitialisation with the boot address + pc_interne <= ADR_INIT; + elsif lock='0' then + -- PC not locked + pc_interne <= suivant; + end if; + end if; + end process; + +end rtl; Index: minimips/trunk/miniMIPS/src/predict.vhd =================================================================== --- minimips/trunk/miniMIPS/src/predict.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/predict.vhd (revision 14) @@ -0,0 +1,227 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : Branch prediction -- +-- -- +-- -- +-- -- +-- Author : Olivier Schneider -- +-- -- +-- june 2004 -- +-------------------------------------------------------------------------- + + + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + + +entity predict is +generic ( + nb_record : integer := 3 +); +port ( + + clock : in std_logic; + reset : in std_logic; + + -- Datas from PF pipeline stage + PF_pc : in std_logic_vector(31 downto 0); -- PC of the current instruction extracted + + -- Datas from DI pipeline stage + DI_bra : in std_logic; -- Branch detected + DI_adr : in std_logic_vector(31 downto 0); -- Address of the branch + + -- Datas from EX pipeline stage + EX_bra_confirm : in std_logic; -- Confirm if the branch test is ok + EX_adr : in std_logic_vector(31 downto 0); -- Address of the branch + EX_adresse : in std_logic_vector(31 downto 0); -- Result of the branch + EX_uncleared : in std_logic; -- Define if the EX stage is cleared + + -- Outputs to PF pipeline stage + PR_bra_cmd : out std_logic; -- Defined a branch + PR_bra_bad : out std_logic; -- Defined a branch to restore from a bad prediction + PR_bra_adr : out std_logic_vector(31 downto 0); -- New PC + + -- Clear the three pipeline stage : EI, DI, EX + PR_clear : out std_logic +); +end entity; + + +architecture rtl of predict is + + -- Record contained in the table of prediction + type pred_type is + record + is_affected : std_logic; -- Check if the record is affected + last_bra : std_logic; -- The last branch confirmation result + code_adr : std_logic_vector(31 downto 0); -- Branch instruction address + bra_adr : std_logic_vector(31 downto 0); -- Branch result + end record; + + type pred_tab_type is array(1 to nb_record) of pred_type; + + -- Table of predictions + signal pred_tab : pred_tab_type; + signal pre_pred_tab : pred_tab_type; + + signal next_out : integer range 1 to nb_record := 1; -- Next record to be erased in the table + signal add_record : std_logic; + +begin + + -- Do the predictions + process(reset, PF_pc, DI_bra, DI_adr, EX_adr, EX_adresse, EX_bra_confirm, pred_tab) + + variable index : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address + variable index2 : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address + variable index3 : integer range 0 to nb_record; -- Table index if a code_adr match with an instruction address + + variable bad_pred : std_logic; -- Flag of bad prediction + + begin + + -- Default signal affectations + index := 0; + index2 := 0; + index3 := 0; + pre_pred_tab <= pred_tab; -- No modification in table of prediction by default + PR_bra_cmd <= '0'; + PR_bra_bad <= '0'; + PR_bra_adr <= (others => '0'); + PR_clear <= '0'; + bad_pred := '0'; + add_record <= '0'; + + -- Check a match in the table + for i in 1 to nb_record loop + if pred_tab(i).is_affected = '1' then + if PF_pc = pred_tab(i).code_adr then + index3 := i; + end if; + if DI_adr = pred_tab(i).code_adr then + index := i; + end if; + if EX_adr = pred_tab(i).code_adr then + index2 := i; + end if; + end if; + end loop; + + -- Branch prediciton + if index3 /= 0 then + PR_bra_cmd <= '1'; + PR_bra_adr <= pred_tab(index3).bra_adr; + end if; + + -- Check if the prediction is ok + if EX_uncleared = '1' then + if index2 /= 0 then + if pred_tab(index2).last_bra /= EX_bra_confirm then -- Bad test result prediction + + if EX_bra_confirm = '1' then + pre_pred_tab(index2).last_bra <= '1'; + pre_pred_tab(index2).bra_adr <= EX_adresse; + else + pre_pred_tab(index2).last_bra <= '0'; + pre_pred_tab(index2).bra_adr <= std_logic_vector(unsigned(pred_tab(index2).code_adr)+4); + end if; + + bad_pred := '1'; + + elsif pred_tab(index2).bra_adr /= EX_adresse then -- Bad adress result prediction + + pre_pred_tab(index2).bra_adr <= EX_adresse; + bad_pred := '1'; + + end if; + end if; + end if; + + -- Clear the pipeline and branch to the new instruction + if bad_pred = '1' then + PR_bra_bad <= '1'; + PR_bra_adr <= pre_pred_tab(index2).bra_adr; + PR_clear <= '1'; + end if; + + -- Add a record in the table + if DI_bra = '1' then + if index = 0 then + add_record <= '1'; + pre_pred_tab(next_out).is_affected <= '1'; -- The record is affected + pre_pred_tab(next_out).last_bra <= '0'; -- Can't predict the branch the first time + pre_pred_tab(next_out).code_adr <= DI_adr; -- Save the branch address + pre_pred_tab(next_out).bra_adr <= std_logic_vector(unsigned(DI_adr)+4); -- Branch result + end if; + end if; + + end process; + + -- Update the table of prediction + process(clock, reset) + begin + if reset = '1' then + + next_out <= 1; -- At the beginning the first record must be chosen to be filled + + for i in 1 to nb_record loop + pred_tab(i).is_affected <= '0'; + end loop; + + elsif rising_edge(clock) then + + pred_tab <= pre_pred_tab; + + if add_record = '1' then + if next_out = nb_record then + next_out <= 1; + else + next_out <= next_out+1; -- Next record to be erased + end if; + end if; + + end if; + end process; +end rtl; + Index: minimips/trunk/miniMIPS/src/bus_ctrl.vhd =================================================================== --- minimips/trunk/miniMIPS/src/bus_ctrl.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/bus_ctrl.vhd (revision 14) @@ -0,0 +1,206 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- miniMIPS Processor : bus controler -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity bus_ctrl is +port +( + clock : std_logic; + reset : std_logic; + + -- Interruption in the pipeline + interrupt : in std_logic; + + -- Interface for the Instruction Extraction Stage + adr_from_ei : in bus32; -- The address of the data to read + instr_to_ei : out bus32; -- Instruction from the memory + + -- Interface with the MEMory Stage + req_from_mem : in std_logic; -- Request to access the ram + r_w_from_mem : in std_logic; -- Read/Write request + adr_from_mem : in bus32; -- Address in ram + data_from_mem : in bus32; -- Data to write in ram + data_to_mem : out bus32; -- Data from the ram to the MEMory stage + + -- RAM interface signals + req_to_ram : out std_logic; -- Request to ram + adr_to_ram : out bus32; -- Address of the data to read or write + r_w_to_ram : out std_logic; -- Read/Write request + ack_from_ram : in std_logic; -- Acknowledge from the memory + data_inout_ram : inout bus32; -- Data from/to the memory + + -- Pipeline progress control signal + stop_all : out std_logic +); +end bus_ctrl; + + +architecture rtl of bus_ctrl is + + type ctrl_state is ( ST1, ST2 ); + signal cs, ns : ctrl_state; + signal ei_buffer : bus32; -- Buffer storing the data for EI + + signal r_w : std_logic; -- Current utilisation of the tristate bus + signal data_in : bus32; -- Data read on the tristate bus + signal req_allowed : std_logic; + +begin + + -- Read/write on the tristate bus + process (r_w, data_from_mem, data_inout_ram) + begin + r_w_to_ram <= r_w; + if r_w='0' then -- Reads bus + data_inout_ram <= (others => 'Z'); + data_in <= data_inout_ram; + else -- Writing of the data from the MEM stage + data_inout_ram <= data_from_mem; + data_in <= (others => '0'); + end if; + end process; + + process (clock) + begin + if clock='1' and clock'event then + if reset='1' then + cs <= ST1; + ei_buffer <= (others => '0'); + else + if cs=ST1 then + -- Storing of the data to send to EI stage + ei_buffer <= data_in; + end if; + + cs <= ns; + end if; + end if; + end process; + + process (clock, ack_from_ram) + begin + if ack_from_ram = '0' then + req_allowed <= '0'; + elsif clock='1' and clock'event then + if ack_from_ram = '1' then + req_allowed <= '1'; + end if; + end if; + end process; + + process (req_allowed, ack_from_ram) + begin + if req_allowed = '1' then + req_to_ram <= '1'; + elsif ack_from_ram = '0' then + req_to_ram <= '1'; + else + req_to_ram <= '0'; + end if; + end process; + + process (cs, interrupt, adr_from_ei, req_from_mem, r_w_from_mem, adr_from_mem, ack_from_ram) + begin + if interrupt = '1' then -- An interruption is detected + ns <= ST1; -- Get back to the reading request + stop_all <= '0'; -- The pipeline is unlock for taking in account the interruption + adr_to_ram <= adr_from_ei; + r_w <= '0'; + else + case cs is + + when ST1 => -- First step the reading for EI + adr_to_ram <= adr_from_ei; + r_w <= '0'; + + if ack_from_ram='1' then + + if req_from_mem='1' then + -- If request from MEM, then step 2 + ns <= ST2; + stop_all <= '1'; + else + -- else next reading for EI + ns <= ST1; + stop_all <= '0'; + end if; + else + -- Wait the end of the reading + ns <= ST1; + stop_all <= '1'; + end if; + + when ST2 => -- Treat the request from the MEM stage + adr_to_ram <= adr_from_mem; + r_w <= r_w_from_mem; + + -- Wait the acknowledge from the RAM + if ack_from_ram='1' then + ns <= ST1; + stop_all <= '0'; + else + ns <= ST2; + stop_all <= '1'; + end if; + + end case; + end if; + end process; + + data_to_mem <= data_in; + instr_to_ei <= ei_buffer when cs=ST2 else data_in; + +end rtl; Index: minimips/trunk/miniMIPS/src/pps_di.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pps_di.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pps_di.vhd (revision 14) @@ -0,0 +1,429 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- Processor miniMIPS : Instruction decoding stage -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; + +entity pps_di is +port ( + clock : in std_logic; + reset : in std_logic; + stop_all : in std_logic; -- Unconditionnal locking of the outputs + clear : in std_logic; -- Clear the pipeline stage (nop in the outputs) + + -- Asynchronous connexion with the register management and data bypass unit + adr_reg1 : out adr_reg_type; -- Address of the first register operand + adr_reg2 : out adr_reg_type; -- Address of the second register operand + use1 : out std_logic; -- Effective use of operand 1 + use2 : out std_logic; -- Effective use of operand 2 + + stop_di : in std_logic; -- Unresolved detected : send nop in the pipeline + data1 : in bus32; -- Operand register 1 + data2 : in bus32; -- Operand register 2 + + -- Datas from EI stage + EI_adr : in bus32; -- Address of the instruction + EI_instr : in bus32; -- The instruction to decode + EI_it_ok : in std_logic; -- Allow hardware interruptions + + -- Synchronous output to EX stage + DI_bra : out std_logic; -- Branch decoded + DI_link : out std_logic; -- A link for that instruction + DI_op1 : out bus32; -- operand 1 for alu + DI_op2 : out bus32; -- operand 2 for alu + DI_code_ual : out alu_ctrl_type; -- Alu operation + DI_offset : out bus32; -- Offset for the address calculation + DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result + DI_ecr_reg : out std_logic; -- Effective writing of the result + DI_mode : out std_logic; -- Address mode (relative to pc or indexed to a register) + DI_op_mem : out std_logic; -- Memory operation request + DI_r_w : out std_logic; -- Type of memory operation (reading or writing) + DI_adr : out bus32; -- Address of the decoded instruction + DI_exc_cause : out bus32; -- Potential exception detected + DI_level : out level_type; -- Availability of the result for the data bypass + DI_it_ok : out std_logic -- Allow hardware interruptions +); +end entity; + + +architecture rtl of pps_di is + + -- Enumeration type used for the micro-code of the instruction + type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0); -- selection du mode de l'instruction + type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT); -- selection de la valeur de l'offset + type rdest_type is ( D_RT, D_RD, D_31, D_00); -- selection du registre destination + + -- Record type containg the micro-code of an instruction + type micro_instr_type is + record + op_mode : op_mode_type; -- Instruction codop mode + op_code : bus6; -- Instruction codop + bra : std_logic; -- Branch instruction + link : std_logic; -- Branch with link : the return address is saved in a register + code_ual : alu_ctrl_type; -- Operation code for the alu + op_mem : std_logic; -- Memory operation needed + r_w : std_logic; -- Read/Write selection in memory + mode : std_logic; -- Address calculation from the current pc ('1') or the alu operand 1 ('0') + off_sel : off_sel_type; -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm) + exc_cause : bus32; -- Unconditionnal exception cause to generate + cop_org1 : std_logic; -- Source register 1 : general register if 0, coprocessor register if 1 + cop_org2 : std_logic; -- Source register 2 : general register if 0, coprocessor register if 1 + cs_imm1 : std_logic; -- Use of immediat operand 1 instead of register bank + cs_imm2 : std_logic; -- Use of immediat operand 2 instead of register bank + imm1_sel : std_logic; -- Origine of immediat operand 1 + imm2_sel : std_logic; -- Origine of immediat operand 2 + level : level_type; -- Data availability stage for the bypass + ecr_reg : std_logic; -- Writing the result in a register + bank_des : std_logic; -- Register bank selection : GPR if 0, coprocessor system if 1 + des_sel : rdest_type ; -- Destination register address : Rt, Rd, $31, $0 + end record; + + type micro_code_type is array (natural range <>) of micro_instr_type; + + constant micro_code : micro_code_type := +( -- Instruction decoding in micro-instructions table +(OP_SPECIAL, "100000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADD +(OP_NORMAL , "001000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- ADDI +(OP_NORMAL , "001001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ADDIU +(OP_SPECIAL, "100001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADDU +(OP_SPECIAL, "100100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- AND +(OP_NORMAL , "001100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ANDI +(OP_NORMAL , "000100", '1', '0', OP_EQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BEQ +(OP_REGIMM , "000001", '1', '0', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGEZ +(OP_REGIMM , "010001", '1', '1', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BGEZAL +(OP_NORMAL , "000111", '1', '0', OP_SPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGTZ +(OP_NORMAL , "000110", '1', '0', OP_LNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLEZ +(OP_REGIMM , "000000", '1', '0', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLTZ +(OP_REGIMM , "010000", '1', '1', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BLTZAL +(OP_NORMAL , "000101", '1', '0', OP_NEQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BNE +(OP_SPECIAL, "001101", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_BREAK, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BREAK +(OP_COP0 , "000001", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '1', '1', D_00), -- COP0 +(OP_NORMAL , "000010", '1', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- J +(OP_NORMAL , "000011", '1', '1', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_31), -- JAL +(OP_SPECIAL, "001001", '1', '1', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- JALR +(OP_SPECIAL, "001000", '1', '0', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- JR +(OP_NORMAL , "001111", '0', '0', OP_LUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- LUI +(OP_NORMAL , "100011", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '0', D_RT), -- LW +(OP_NORMAL , "110000", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '1', D_RT), -- LWC0 +(OP_COP0 , "000000", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '1', '1', '0', '0', '0', LVL_DI , '1', '0', D_RD), -- MFC0 +(OP_SPECIAL, "010000", '0', '0', OP_MFHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFHI +(OP_SPECIAL, "010010", '0', '0', OP_MFLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFLO +(OP_COP0 , "000100", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '0', '0', LVL_DI , '1', '1', D_RD), -- MTC0 +(OP_SPECIAL, "010001", '0', '0', OP_MTHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTHI +(OP_SPECIAL, "010011", '0', '0', OP_MTLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTLO +(OP_SPECIAL, "011000", '0', '0', OP_MULT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT +(OP_SPECIAL, "011001", '0', '0', OP_MULTU, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT +(OP_SPECIAL, "100111", '0', '0', OP_NOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- NOR +(OP_SPECIAL, "100101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- OR +(OP_NORMAL , "001101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ORI +(OP_SPECIAL, "000000", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SLL +(OP_SPECIAL, "000100", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLLV +(OP_SPECIAL, "101010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLT +(OP_NORMAL , "001010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTI +(OP_NORMAL , "001011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTIU +(OP_SPECIAL, "101011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLTU +(OP_SPECIAL, "000011", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRA +(OP_SPECIAL, "000111", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRAV +(OP_SPECIAL, "000010", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRL +(OP_SPECIAL, "000110", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRLV +(OP_SPECIAL, "100010", '0', '0', OP_SUB , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUB +(OP_SPECIAL, "100011", '0', '0', OP_SUBU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUBU +(OP_NORMAL , "101011", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SW +(OP_NORMAL , "111000", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '1', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SWC0 +(OP_SPECIAL, "001100", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_SCALL, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- SYSC +(OP_SPECIAL, "100110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- XOR +(OP_NORMAL , "001110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT) -- XORI +); + + -- Preparation of the synchronous outputs + signal PRE_bra : std_logic; -- Branch operation + signal PRE_link : std_logic; -- Branch with link + signal PRE_op1 : bus32; -- operand 1 of the ual + signal PRE_op2 : bus32; -- operand 2 of the ual + signal PRE_code_ual : alu_ctrl_type; -- Alu operation + signal PRE_offset : bus32; -- Address offset for calculation + signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result + signal PRE_ecr_reg : std_logic; -- Writing of result in the bank register + signal PRE_mode : std_logic; -- Address calculation with current pc + signal PRE_op_mem : std_logic; -- Memory access operation instruction + signal PRE_r_w : std_logic; -- Read/write selection in memory + signal PRE_exc_cause : bus32; -- Potential exception cause + signal PRE_level : level_type; -- Result availability stage for bypass + +begin + + + -- Instruction decoding + process (EI_instr, EI_adr, data1, data2) + variable op_code : bus6; -- Effective codop of the instruction + variable op_mode : op_mode_type; -- Instruction mode + variable flag : boolean; -- Is true if valid instruction + variable instr : integer; -- Current micro-instruction adress + + -- Instruction fields + variable rs : bus5; + variable rt : bus5; + variable rd : bus5; + variable shamt : bus5; + variable imm : bus16; + variable address : bus26; + begin + + -- Selection of the instruction codop and its mode + case EI_instr(31 downto 26) is + when "000000" => -- special mode + op_mode := OP_SPECIAL; + op_code := EI_instr(5 downto 0); + when "000001" => -- regimm mode + op_mode := OP_REGIMM; + op_code := '0' & EI_instr(20 downto 16); + when "010000" => -- cop0 mode + op_mode := OP_COP0; + op_code := '0' & EI_instr(25 downto 21); + when others => -- normal mode + op_mode := OP_NORMAL; + op_code := EI_instr(31 downto 26); + end case; + + + -- Search the current instruction in the micro-code table + flag := false; + instr := 0; + for i in micro_code'range loop + if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then + flag := true; -- The instruction exists + instr := i; -- Index memorisation + end if; + end loop; + + -- Read the instruction field + rs := EI_instr(25 downto 21); + rt := EI_instr(20 downto 16); + rd := EI_instr(15 downto 11); + shamt := EI_instr(10 downto 6); + imm := EI_instr(15 downto 0); + address := EI_instr(25 downto 0); + + if not flag then -- Unknown instruction + + -- Synchronous output preparation + PRE_bra <= '0'; -- Branch operation + PRE_link <= '0'; -- Branch with link + PRE_op1 <= (others => '0'); -- operand 1 of the ual + PRE_op2 <= (others => '0'); -- operand 2 of the ual + PRE_code_ual <= OP_OUI; -- Alu operation + PRE_offset <= (others => '0'); -- Address offset for calculation + PRE_adr_reg_dest <= (others => '0'); -- Destination register adress for result + PRE_ecr_reg <= '0'; -- Writing of result in the bank register + PRE_mode <= '0'; -- Address calculation with current pc + PRE_op_mem <= '0'; -- Memory access operation instruction + PRE_r_w <= '0'; -- Read/write selection in memory + PRE_exc_cause <= IT_ERINS; -- Potential exception cause + PRE_level <= LVL_DI; -- Result availability stage for bypass + + -- Set asynchronous outputs + adr_reg1 <= (others => '0'); -- First operand register + adr_reg2 <= (others => '0'); -- Second operand register + use1 <= '0'; -- Effective use of operand 1 + use2 <= '0'; -- Effective use of operand 2 + + else -- Valid instruction + + -- Offset signal preparation + case micro_code(instr).off_sel is + when OFS_PCRL => -- PC(31..28) & Adresse & 00 + PRE_offset <= EI_adr(31 downto 28) & address & "00"; + when OFS_NULL => -- 0 + PRE_offset <= (others => '0'); + when OFS_SESH => -- sgn_ext(Imm) & 00 + if imm(15)='1' then + PRE_offset <= "11111111111111" & imm & "00"; + else + PRE_offset <= "00000000000000" & imm & "00"; + end if; + when OFS_SEXT => -- sgn_ext(Imm) + if imm(15)='1' then + PRE_offset <= "1111111111111111" & imm; + else + PRE_offset <= "0000000000000000" & imm; + end if; + end case; + + + -- Alu operand preparation + if micro_code(instr).cs_imm1='0' then + -- Datas from register banks + PRE_op1 <= data1; + else + -- Immediate datas + if micro_code(instr).imm1_sel='0' then + PRE_op1 <= (others => '0'); -- Immediate operand = 0 + else + PRE_op1 <= X"000000" & "000" & shamt; -- Immediate operand = shamt + end if; + end if; + + + if micro_code(instr).cs_imm2='0' then + -- Datas from register banks + PRE_op2 <= data2; + else + -- Immediate datas + if micro_code(instr).imm2_sel='0' then + PRE_op2 <= X"0000" & imm; -- Immediate operand = imm + else + if imm(15)='1' then -- Immediate operand = sgn_ext(imm) + PRE_op2 <= X"FFFF" & imm; + else + PRE_op2 <= X"0000" & imm; + end if; + end if; + end if; + + -- Selection of destination register address + case micro_code(instr).des_sel is + when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt; + when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd; + when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111"; + when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000"; + end case; + + -- Command signal affectation + PRE_bra <= micro_code(instr).bra; -- Branch operation + PRE_link <= micro_code(instr).link; -- Branch with link + PRE_code_ual <= micro_code(instr).code_ual; -- Alu operation + PRE_ecr_reg <= micro_code(instr).ecr_reg; -- Writing the result in a bank register + PRE_mode <= micro_code(instr).mode; -- Type of calculation for the address with current pc + PRE_op_mem <= micro_code(instr).op_mem; -- Memory operation needed + PRE_r_w <= micro_code(instr).r_w; -- Read/Write in memory selection + PRE_exc_cause <= micro_code(instr).exc_cause; -- Potential cause exception + PRE_level <= micro_code(instr).level; + + -- Set asynchronous outputs + adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address + adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address + use1 <= not micro_code(instr).cs_imm1; -- Effective use of operande 1 + use2 <= not micro_code(instr).cs_imm2; -- Effective use of operande 2 + end if; + + end process; + + + + -- Set the synchronous outputs + process (clock) + begin + if clock='1' and clock'event then + if reset='1' then + DI_bra <= '0'; + DI_link <= '0'; + DI_op1 <= (others => '0'); + DI_op2 <= (others => '0'); + DI_code_ual <= OP_OUI; + DI_offset <= (others => '0'); + DI_adr_reg_dest <= (others => '0'); + DI_ecr_reg <= '0'; + DI_mode <= '0'; + DI_op_mem <= '0'; + DI_r_w <= '0'; + DI_adr <= (others => '0'); + DI_exc_cause <= IT_NOEXC; + DI_level <= LVL_DI; + DI_it_ok <= '0'; + elsif stop_all='0' then + if clear='1' or stop_di='1' then + -- Nop instruction + DI_bra <= '0'; + DI_link <= '0'; + DI_op1 <= (others => '0'); + DI_op2 <= (others => '0'); + DI_code_ual <= OP_OUI; + DI_offset <= (others => '0'); + DI_adr_reg_dest <= (others => '0'); + DI_ecr_reg <= '0'; + DI_mode <= '0'; + DI_op_mem <= '0'; + DI_r_w <= '0'; + DI_adr <= EI_adr; + DI_exc_cause <= IT_NOEXC; + DI_level <= LVL_DI; + if clear='1' then + DI_it_ok <= '0'; + else + DI_it_ok <= EI_it_ok; + end if; + else -- Noraml step + DI_bra <= PRE_bra; + DI_link <= PRE_link; + DI_op1 <= PRE_op1; + DI_op2 <= PRE_op2; + DI_code_ual <= PRE_code_ual; + DI_offset <= PRE_offset; + DI_adr_reg_dest <= PRE_adr_reg_dest; + DI_ecr_reg <= PRE_ecr_reg; + DI_mode <= PRE_mode; + DI_op_mem <= PRE_op_mem; + DI_r_w <= PRE_r_w; + DI_adr <= EI_adr; + DI_exc_cause <= PRE_exc_cause; + DI_level <= PRE_level; + DI_it_ok <= EI_it_ok; + end if; + end if; + end if; + end process; + +end rtl; + + Index: minimips/trunk/miniMIPS/src/pps_ex.vhd =================================================================== --- minimips/trunk/miniMIPS/src/pps_ex.vhd (nonexistent) +++ minimips/trunk/miniMIPS/src/pps_ex.vhd (revision 14) @@ -0,0 +1,184 @@ +------------------------------------------------------------------------------------ +-- -- +-- Copyright (c) 2004, Hangouet Samuel -- +-- , Jan Sebastien -- +-- , Mouton Louis-Marie -- +-- , Schneider Olivier all rights reserved -- +-- -- +-- This file is part of miniMIPS. -- +-- -- +-- miniMIPS is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU Lesser General Public License as published by -- +-- the Free Software Foundation; either version 2.1 of the License, or -- +-- (at your option) any later version. -- +-- -- +-- miniMIPS is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- +-- GNU Lesser General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU Lesser General Public License -- +-- along with miniMIPS; if not, write to the Free Software -- +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- +-- -- +------------------------------------------------------------------------------------ + + +-- If you encountered any problem, please contact : +-- +-- lmouton@enserg.fr +-- oschneid@enserg.fr +-- shangoue@enserg.fr +-- + + + +-------------------------------------------------------------------------- +-- -- +-- -- +-- Processor miniMIPS : Execution stage -- +-- -- +-- -- +-- -- +-- Authors : Hangouet Samuel -- +-- Jan Sébastien -- +-- Mouton Louis-Marie -- +-- Schneider Olivier -- +-- -- +-- june 2003 -- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library work; +use work.pack_mips.all; +use work.alu; + +entity pps_ex is +port( + clock : in std_logic; + reset : in std_logic; + stop_all : in std_logic; -- Unconditionnal locking of outputs + clear : in std_logic; -- Clear the pipeline stage + + -- Datas from DI stage + DI_bra : in std_logic; -- Branch instruction + DI_link : in std_logic; -- Branch with link + DI_op1 : in bus32; -- Operand 1 for alu + DI_op2 : in bus32; -- Operand 2 for alu + DI_code_ual : in alu_ctrl_type; -- Alu operation + DI_offset : in bus32; -- Offset for address calculation + DI_adr_reg_dest : in adr_reg_type; -- Destination register address for the result + DI_ecr_reg : in std_logic; -- Effective writing of the result + DI_mode : in std_logic; -- Address mode (relative to pc ou index by a register) + DI_op_mem : in std_logic; -- Memory operation + DI_r_w : in std_logic; -- Type of memory operation (read or write) + DI_adr : in bus32; -- Instruction address + DI_exc_cause : in bus32; -- Potential cause exception + DI_level : in level_type; -- Availability stage of the result for bypassing + DI_it_ok : in std_logic; -- Allow hardware interruptions + + -- Synchronous outputs to MEM stage + EX_adr : out bus32; -- Instruction address + EX_bra_confirm : out std_logic; -- Branch execution confirmation + EX_data_ual : out bus32; -- Ual result + EX_adresse : out bus32; -- Address calculation result + EX_adr_reg_dest : out adr_reg_type; -- Destination register for the result + EX_ecr_reg : out std_logic; -- Effective writing of the result + EX_op_mem : out std_logic; -- Memory operation needed + EX_r_w : out std_logic; -- Type of memory operation (read or write) + EX_exc_cause : out bus32; -- Potential cause exception + EX_level : out level_type; -- Availability stage of result for bypassing + EX_it_ok : out std_logic -- Allow hardware interruptions +); +end entity; + + +architecture rtl of pps_ex is + +component alu + port ( + clock : in bus1; + reset : in bus1; + op1 : in bus32; -- Operand 1 + op2 : in bus32; -- Operand 2 + ctrl : in alu_ctrl_type; -- Operation + + res : out bus32; -- Result + overflow : out bus1 -- Overflow + ); + end component; + + signal res_ual : bus32; -- Alu result output + signal base_adr : bus32; -- Output of the address mode mux selection + + signal pre_ecr_reg : std_logic; -- Output of mux selection for writing command to register + signal pre_data_ual : bus32; -- Mux selection of the data to write + signal pre_bra_confirm : std_logic; -- Result of the test in alu when branch instruction + signal pre_exc_cause : bus32; -- Preparation of the exception detection signal + signal overflow_ual : std_logic; -- Dectection of the alu overflow + +begin + + -- Alu instantiation + U1_alu : alu port map (clock => clock, reset => reset, op1=>DI_op1, op2=>DI_op2, ctrl=>DI_code_ual, + res=>res_ual, overflow=>overflow_ual); + + -- Calculation of the future outputs + base_adr <= DI_op1 when DI_mode='0' else DI_adr; + pre_ecr_reg <= DI_ecr_reg when DI_link='0' else pre_bra_confirm; + pre_data_ual <= res_ual when DI_link='0' else bus32(unsigned(DI_adr) + 4); + pre_bra_confirm <= DI_bra and res_ual(0); + pre_exc_cause <= DI_exc_cause when DI_exc_cause/=IT_NOEXC else + IT_OVERF when overflow_ual='1' else + IT_NOEXC; + + -- Set the synchronous outputs + process(clock) is + begin + if clock='1' and clock'event then + if reset='1' then + EX_adr <= (others => '0'); + EX_bra_confirm <= '0'; + EX_data_ual <= (others => '0'); + EX_adresse <= (others => '0'); + EX_adr_reg_dest <= (others => '0'); + EX_ecr_reg <= '0'; + EX_op_mem <= '0'; + EX_r_w <= '0'; + EX_exc_cause <= IT_NOEXC; + EX_level <= LVL_DI; + EX_it_ok <= '0'; + elsif stop_all = '0' then + if clear = '1' then -- Clear the stage + EX_adr <= DI_adr; + EX_bra_confirm <= '0'; + EX_data_ual <= (others => '0'); + EX_adresse <= (others => '0'); + EX_adr_reg_dest <= (others => '0'); + EX_ecr_reg <= '0'; + EX_op_mem <= '0'; + EX_r_w <= '0'; + EX_exc_cause <= IT_NOEXC; + EX_level <= LVL_DI; + EX_it_ok <= '0'; + else -- Normal evolution + EX_adr <= DI_adr; + EX_bra_confirm <= pre_bra_confirm; + EX_data_ual <= pre_data_ual; + EX_adr_reg_dest <= DI_adr_reg_dest; + EX_ecr_reg <= pre_ecr_reg; + EX_op_mem <= DI_op_mem; + EX_r_w <= DI_r_w; + EX_exc_cause <= pre_exc_cause; + EX_level <= DI_level; + EX_it_ok <= DI_it_ok; + EX_adresse <= bus32(unsigned(DI_offset) + unsigned(base_adr)); + end if; + end if; + end if; + end process; + +end architecture; Index: minimips/trunk/LGPL.txt =================================================================== --- minimips/trunk/LGPL.txt (nonexistent) +++ minimips/trunk/LGPL.txt (revision 14) @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + Index: minimips/trunk/COPYING =================================================================== --- minimips/trunk/COPYING (nonexistent) +++ minimips/trunk/COPYING (revision 14) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. Index: minimips/trunk =================================================================== --- minimips/trunk (nonexistent) +++ minimips/trunk (revision 14)
minimips/trunk Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: minimips/web_uploads =================================================================== --- minimips/web_uploads (nonexistent) +++ minimips/web_uploads (revision 14)
minimips/web_uploads Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: minimips/branches =================================================================== --- minimips/branches (nonexistent) +++ minimips/branches (revision 14)
minimips/branches Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: minimips/tags =================================================================== --- minimips/tags (nonexistent) +++ minimips/tags (revision 14)
minimips/tags Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.