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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [commands/] [CMD_Arith.txt] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log


<defines>
`define CMD_Arith   #AUTOGEN_NEXT_CMD_MOD8
`define CMD_ADD     #AUTOGEN_NEXT_CMD_LIKE_PREV
`define CMD_OR      #AUTOGEN_NEXT_CMD
`define CMD_ADC     #AUTOGEN_NEXT_CMD
`define CMD_SBB     #AUTOGEN_NEXT_CMD
`define CMD_AND     #AUTOGEN_NEXT_CMD
`define CMD_SUB     #AUTOGEN_NEXT_CMD
`define CMD_XOR     #AUTOGEN_NEXT_CMD
`define CMD_CMP     #AUTOGEN_NEXT_CMD

`define CMDEX_Arith_immediate       4'd0
`define CMDEX_Arith_modregrm        4'd1
`define CMDEX_Arith_modregrm_imm    4'd2
</defines>

<decode>
dec_ready_one_imm && decoder[7:6] == 2'b00 && decoder[2:1] == 2'b10
{`CMD_Arith | { 4'd0, decoder[5:3] } }
SET(dec_cmdex, `CMDEX_Arith_immediate);
IF(decoder[0] == 1'b0); SET(dec_is_8bit); ENDIF();
SET(consume_one_imm);
</decode>

<decode>
dec_ready_modregrm_one && decoder[7:6] == 2'b00 && decoder[2] == 1'b0
prefix_group_1_lock && (decoder[1] == 1'b1 || `DEC_MODREGRM_IS_MOD_11 || decoder[5:3] == 3'b111)
{`CMD_Arith | { 4'd0, decoder[5:3] } }
SET(dec_cmdex, `CMDEX_Arith_modregrm);
IF(decoder[0] == 1'b0); SET(dec_is_8bit); ENDIF();
SET(consume_modregrm_one);
</decode>

<decode>
dec_ready_modregrm_imm && { decoder[7:2], 2'b00 } == 8'h80
prefix_group_1_lock && (decoder[13:11] == 3'b111 || `DEC_MODREGRM_IS_MOD_11)
{`CMD_Arith | { 4'd0, decoder[13:11] } }
SET(dec_cmdex, `CMDEX_Arith_modregrm_imm);
IF(decoder[0] == 1'b0); SET(dec_is_8bit); ENDIF();
SET(consume_modregrm_imm);
</decode>

<read_local>
wire rd_arith_modregrm_to_rm;
wire rd_arith_modregrm_to_reg;

assign rd_arith_modregrm_to_rm = ~(rd_decoder[1]);
assign rd_arith_modregrm_to_reg= rd_decoder[1];
</read_local>

<read>
IF({ rd_cmd[6:3], 3'd0 } == `CMD_Arith && rd_cmdex == `CMDEX_Arith_modregrm);

    SET(rd_src_is_reg,  rd_arith_modregrm_to_rm);
    SET(rd_dst_is_reg,  rd_arith_modregrm_to_reg);
    
    SET(rd_req_eflags);
    
    // dst: reg, src: reg
    IF(rd_modregrm_mod == 2'b11);
        
        // reg, reg
        SET(rd_dst_is_rm,   rd_arith_modregrm_to_rm);
        SET(rd_src_is_rm,   rd_arith_modregrm_to_reg);

        IF(rd_decoder[5:3] != 3'b111); // not CMP
            SET(rd_req_reg, rd_arith_modregrm_to_reg);
            SET(rd_req_rm,  rd_arith_modregrm_to_rm);
        ENDIF();
    
        IF(rd_mutex_busy_modregrm_reg || rd_mutex_busy_modregrm_rm); SET(rd_waiting); ENDIF();
    ENDIF();

    // dst: memory, src: reg;
    // dst: reg,    src: memory
    IF(rd_modregrm_mod != 2'b11);
        
        SET(rd_src_is_memory,   rd_arith_modregrm_to_reg);
        SET(rd_dst_is_memory,   rd_arith_modregrm_to_rm);
        
        IF(rd_decoder[5:3] != 3'b111 && rd_arith_modregrm_to_rm);   SET(rd_req_memory); ENDIF(); // not CMP and dst: memory
        IF(rd_decoder[5:3] != 3'b111 && rd_arith_modregrm_to_reg);  SET(rd_req_reg);    ENDIF(); // dst: reg
        
        IF(rd_mutex_busy_memory || rd_mutex_busy_modregrm_reg); SET(rd_waiting);
        ELSE();

            IF(rd_decoder[5:3] != 3'b111 && rd_arith_modregrm_to_rm);   SET(read_rmw_virtual); // not CMP and dst: memory
            ELSE();                                                     SET(read_virtual);     // CMP
            ENDIF();
            
            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF({ rd_cmd[6:3], 3'd0 } == `CMD_Arith && rd_cmdex == `CMDEX_Arith_modregrm_imm);

    SET(rd_req_eflags);

    // dst: reg, src: imm
    IF(rd_modregrm_mod == 2'b11);
    
        // reg, reg
        IF(rd_decoder[1:0] == 2'b11);   SET(rd_src_is_modregrm_imm_se);
        ELSE();                         SET(rd_src_is_modregrm_imm);
        ENDIF();
        
        SET(rd_dst_is_rm);
        
        IF(rd_decoder[13:11] != 3'b111); SET(rd_req_rm); ENDIF(); //CMP
    
        IF(rd_mutex_busy_modregrm_rm); SET(rd_waiting); ENDIF();
    ENDIF();

    // dst: memory, src: imm
    IF(rd_modregrm_mod != 2'b11);
        
        IF(rd_decoder[1:0] == 2'b11);    SET(rd_src_is_modregrm_imm_se);
        ELSE();                          SET(rd_src_is_modregrm_imm);
        ENDIF();
        
        SET(rd_dst_is_memory);
        
        IF(rd_decoder[13:11] != 3'b111); SET(rd_req_memory); ENDIF(); // not CMP
        
        IF(rd_mutex_busy_memory); SET(rd_waiting);
        ELSE();

            IF(rd_decoder[13:11] != 3'b111); SET(read_rmw_virtual); // not CMP 
            ELSE();                          SET(read_virtual);     // CMP
            ENDIF();
            
            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF({ rd_cmd[6:3], 3'd0 } == `CMD_Arith && rd_cmdex == `CMDEX_Arith_immediate);
    
    SET(rd_src_is_imm);
    SET(rd_dst_is_eax);
        
    SET(rd_req_eflags);
    IF(rd_decoder[5:3] != 3'b111); SET(rd_req_eax); ENDIF(); //not CMP

    // dst: eAX, src: imm
    IF(rd_mutex_busy_eax); SET(rd_waiting); ENDIF();
ENDIF();
</read>

<execute>
IF({ exe_cmd[6:3], 3'd0 } == `CMD_Arith);
            
    SET(exe_arith_index, {`TRUE, exe_cmd[2:0]});

    SET(exe_result, ({ 1'b0, exe_cmd[2:0] } == `ARITH_ADD)?   exe_arith_add[31:0] :
                    ({ 1'b0, exe_cmd[2:0] } == `ARITH_OR)?    exe_arith_or :
                    ({ 1'b0, exe_cmd[2:0] } == `ARITH_ADC)?   exe_arith_adc[31:0] :
                    ({ 1'b0, exe_cmd[2:0] } == `ARITH_SBB)?   exe_arith_sbb[31:0] :
                    ({ 1'b0, exe_cmd[2:0] } == `ARITH_AND)?   exe_arith_and :
                    ({ 1'b0, exe_cmd[2:0] } == `ARITH_XOR)?   exe_arith_xor :
                                                              exe_arith_sub[31:0]);
        
    IF(exe_cmd[2:1] == 2'b01 && exe_mutex_current[`MUTEX_EFLAGS_BIT]); SET(exe_waiting); ENDIF(); // ADC,SBB -- wait for mutex_eflags       
ENDIF();
</execute>

<write>
IF({ wr_cmd[6:3], 3'd0 } == `CMD_Arith);
    
    IF(wr_cmd[2:0] != 3'b111 && wr_dst_is_memory && ~(write_for_wr_ready)); SET(wr_waiting); ENDIF(); //not CMP
    
    IF(wr_cmd[2:0] != 3'b111); // writeback not for CMP
        SET(write_rmw_virtual,  wr_dst_is_memory);
        SET(write_regrm,        wr_dst_is_reg || wr_dst_is_rm);  
        SET(write_eax,          wr_dst_is_eax);
    ENDIF();

    SAVE(zflag, zflag_result);
    SAVE(sflag, sflag_result);
    SAVE(pflag, pflag_result);

    SAVE(aflag, aflag_arith);
    SAVE(cflag, cflag_arith);
    SAVE(oflag, oflag_arith);
ENDIF();  
</write>

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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