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/bench/rom.vhd
File deleted
/trunk/miniMIPS/bench/ram.vhd
File deleted
/trunk/miniMIPS/bench/bench_minimips.vhd
File deleted
/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 ##