URL
https://opencores.org/ocsvn/ao486/ao486/trunk
Subversion Repositories ao486
[/] [ao486/] [trunk/] [rtl/] [ao486/] [commands/] [CMD_JMP.txt] - Rev 2
Compare with Previous | Blame | View Log
<defines>
`define CMD_JMP #AUTOGEN_NEXT_CMD
`define CMDEX_JMP_Ev_STEP_0 4'd0
`define CMDEX_JMP_Jv_STEP_0 4'd1
`define CMDEX_JMP_Ep_STEP_0 4'd2
`define CMDEX_JMP_Ap_STEP_0 4'd3
`define CMDEX_JMP_Ev_Jv_STEP_1 4'd4
`define CMDEX_JMP_Ep_STEP_1 4'd5
`define CMDEX_JMP_Ap_STEP_1 4'd6
`define CMDEX_JMP_real_v8086_STEP_0 4'd7
`define CMDEX_JMP_real_v8086_STEP_1 4'd8
`define CMDEX_JMP_protected_STEP_0 4'd9
`define CMDEX_JMP_protected_STEP_1 4'd10
`define CMDEX_JMP_protected_seg_STEP_0 4'd11
`define CMDEX_JMP_protected_seg_STEP_1 4'd12
`define CMDEX_JMP_task_switch_STEP_0 4'd13
`define CMDEX_JMP_task_gate_STEP_0 4'd14
`define CMDEX_JMP_task_gate_STEP_1 4'd15
//------------------------------------------------------------------------------
`define CMD_JMP_2 #AUTOGEN_NEXT_CMD
`define CMDEX_JMP_2_call_gate_STEP_0 4'd0
`define CMDEX_JMP_2_call_gate_STEP_1 4'd1
`define CMDEX_JMP_2_call_gate_STEP_2 4'd2
`define CMDEX_JMP_2_call_gate_STEP_3 4'd3
</defines>
<decode>
dec_ready_call_jmp_imm && (decoder[7:0] == 8'hEA || decoder[7:0] == 8'hE9 || decoder[7:0] == 8'hEB)
`CMD_JMP
IF(decoder[0] == 1'b0); SET(dec_cmdex, `CMDEX_JMP_Ap_STEP_0); ELSE(); SET(dec_cmdex, `CMDEX_JMP_Jv_STEP_0); ENDIF();
IF(decoder[3:0] == 4'hB); SET(dec_is_8bit); ENDIF();
SET(consume_call_jmp_imm);
SET(dec_is_complex);
</decode>
<decode>
dec_ready_modregrm_one && decoder[7:0] == 8'hFF && (decoder[13:11] == 3'd4 || decoder[13:11] == 3'd5)
prefix_group_1_lock || (decoder[13:11] == 3'd5 && `DEC_MODREGRM_IS_MOD_11)
`CMD_JMP
IF(decoder[11] == 1'b0); SET(dec_cmdex, `CMDEX_JMP_Ev_STEP_0); ELSE(); SET(dec_cmdex, `CMDEX_JMP_Ep_STEP_0); ENDIF();
SET(consume_modregrm_one);
SET(dec_is_complex);
</decode>
<microcode>
IF(`CMDEX_JMP_Jv_STEP_0);
LOOP(`CMDEX_JMP_Ev_Jv_STEP_1);
ENDIF();
IF(`CMDEX_JMP_Ev_STEP_0);
LOOP(`CMDEX_JMP_Ev_Jv_STEP_1);
ENDIF();
IF(`CMDEX_JMP_Ep_STEP_0);
`CMDEX_JMP_Ep_STEP_1
ENDIF();
IF(`CMDEX_JMP_Ap_STEP_0);
`CMDEX_JMP_Ap_STEP_1
ENDIF();
IF(mc_cmd == `CMD_JMP && (mc_cmdex_last == `CMDEX_JMP_Ep_STEP_1 || mc_cmdex_last == `CMDEX_JMP_Ap_STEP_1) && (real_mode || v8086_mode));
`CMDEX_JMP_real_v8086_STEP_0
CALL(`CMDEX_load_seg_STEP_1);
LOOP(`CMDEX_JMP_real_v8086_STEP_1);
ENDIF();
IF(mc_cmd == `CMD_JMP && (mc_cmdex_last == `CMDEX_JMP_Ep_STEP_1 || mc_cmdex_last == `CMDEX_JMP_Ap_STEP_1) && (protected_mode));
`CMDEX_JMP_protected_STEP_0
`CMDEX_JMP_protected_STEP_1
IF(`CMDEX_JMP_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG]);
`CMDEX_JMP_protected_seg_STEP_0
LOOP(`CMDEX_JMP_protected_seg_STEP_1);
ENDIF();
IF(`CMDEX_JMP_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && (glob_descriptor[`DESC_BITS_TYPE] == `DESC_TSS_AVAIL_386 || glob_descriptor[`DESC_BITS_TYPE] == `DESC_TSS_AVAIL_286));
`CMDEX_JMP_task_switch_STEP_0
//zero length
IF(`CMDEX_JMP_task_switch_STEP_0 && glob_param_3[21:18] == 4'd0);
`CMDEX_JMP_task_switch_STEP_0
ENDIF();
//not zero length, task gate
IF(`CMDEX_JMP_task_switch_STEP_0 && glob_param_3[21:18] != 4'd0);
JMP(`CMDEX_task_switch_STEP_1);
ENDIF();
ENDIF();
IF(`CMDEX_JMP_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && glob_descriptor[`DESC_BITS_TYPE] == `DESC_TASK_GATE);
`CMDEX_JMP_task_gate_STEP_0
`CMDEX_JMP_task_gate_STEP_1
JMP(`CMDEX_task_switch_STEP_1);
ENDIF();
//call gate
IF(`CMDEX_JMP_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && (glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_386 || glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_286));
`CMDEX_JMP_2_call_gate_STEP_0
`CMDEX_JMP_2_call_gate_STEP_1
`CMDEX_JMP_2_call_gate_STEP_2
LOOP(`CMDEX_JMP_2_call_gate_STEP_3);
ENDIF();
ENDIF();
</microcode>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_Jv_STEP_0);
SET(rd_src_is_imm_se);
SET(rd_dst_is_eip);
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_Ap_STEP_1);
SET(rd_extra_wire, rd_decoder[55:24]);
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP_2 && rd_cmdex == `CMDEX_JMP_2_call_gate_STEP_0);
IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- loading glob_param_1
ELSE();
SET(rd_glob_param_1_set);
SET(rd_glob_param_1_value, { 13'd0, `SEGMENT_CS, glob_descriptor[31:16] });
SET(rd_glob_param_2_set);
SET(rd_glob_param_2_value, (glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_386)? { glob_descriptor[63:48], glob_descriptor[15:0] } : { 16'd0, glob_descriptor[15:0] });
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP_2 && rd_cmdex == `CMDEX_JMP_2_call_gate_STEP_1);
IF(glob_param_1[15:2] != 14'd0); // do not load null
SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));
SET(rd_glob_descriptor_set);
SET(rd_glob_descriptor_value, read_8);
SET(read_system_descriptor);
IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_Ev_STEP_0);
IF(rd_modregrm_mod == 2'b11);
SET(rd_src_is_rm);
IF(rd_mutex_busy_modregrm_rm); SET(rd_waiting); ENDIF();
ENDIF();
IF(rd_modregrm_mod != 2'b11);
SET(rd_src_is_memory);
IF(rd_mutex_busy_memory); SET(rd_waiting);
ELSE();
SET(read_virtual);
IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && (rd_cmdex == `CMDEX_JMP_Ep_STEP_0 || rd_cmdex == `CMDEX_JMP_Ep_STEP_1));
IF(rd_cmdex == `CMDEX_JMP_Ep_STEP_1);
SET(address_ea_buffer);
SET(read_length_word);
ENDIF();
SET(rd_src_is_memory);
IF(rd_mutex_busy_memory); SET(rd_waiting);
ELSE();
SET(read_virtual);
IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_Ap_STEP_0);
SET(rd_src_is_imm);
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_protected_STEP_0);
IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- loading glob_param_1
ELSE();
IF(glob_param_1[15:2] != 14'd0); // load null
SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));
SET(rd_glob_descriptor_set);
SET(rd_glob_descriptor_value, read_8);
SET(rd_glob_param_3_set);
SET(rd_glob_param_3_value, 32'd0);
SET(read_system_descriptor);
IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_task_gate_STEP_0);
IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- loading glob_param_1
ELSE();
SET(rd_glob_param_1_set);
SET(rd_glob_param_1_value, { 16'd0, glob_descriptor[31:16] });
ENDIF();
ENDIF();
</read>
<read>
IF(rd_cmd == `CMD_JMP && rd_cmdex == `CMDEX_JMP_task_gate_STEP_1);
//TODO: null not checked
IF(glob_param_1[`SELECTOR_BIT_TI] == 1'b0); // skip if TI set
SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));
SET(rd_glob_descriptor_set);
SET(rd_glob_descriptor_value, read_8);
SET(read_system_descriptor);
IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
ENDIF();
</read>
<execute>
IF(exe_cmd == `CMD_JMP && (exe_cmdex == `CMDEX_JMP_Ev_STEP_0 || exe_cmdex == `CMDEX_JMP_Ep_STEP_0 || exe_cmdex == `CMDEX_JMP_Ap_STEP_0));
IF(exe_operand_32bit);
SET(exe_glob_param_2_set);
SET(exe_glob_param_2_value, src);
ELSE();
SET(exe_glob_param_2_set);
SET(exe_glob_param_2_value, { 16'd0, src[15:0] });
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_Jv_STEP_0);
IF(exe_cmd == `CMD_CALL && exe_mutex_current[`MUTEX_ESP_BIT]); SET(exe_waiting); ENDIF();
IF(exe_operand_32bit);
SET(exe_glob_param_2_set);
SET(exe_glob_param_2_value, exe_arith_add[31:0]);
ELSE();
SET(exe_glob_param_2_set);
SET(exe_glob_param_2_value, { 16'd0, exe_arith_add[15:0] });
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_Ev_Jv_STEP_1);
SET(exe_eip_from_glob_param_2);
IF(glob_param_2 > cs_limit);
SET(exe_waiting);
SET(exe_trigger_gp_fault); //exception GP(0)
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_Ep_STEP_1);
SET(exe_glob_param_1_set);
SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, src[15:0] });
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_Ap_STEP_1);
IF(exe_operand_32bit);
SET(exe_glob_param_1_set);
SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, exe_extra[31:16] });
ELSE();
SET(exe_glob_param_1_set);
SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, exe_extra[15:0] });
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_real_v8086_STEP_0);
IF(glob_param_2 > cs_limit);
SET(exe_waiting);
SET(exe_trigger_gp_fault); //exception GP(0)
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_real_v8086_STEP_1);
SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_protected_seg_STEP_0);
IF(glob_param_2 > glob_desc_limit);
SET(exe_waiting);
SET(exe_trigger_gp_fault); //exception GP(0)
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP && exe_cmdex == `CMDEX_JMP_protected_seg_STEP_1);
SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP_2 && exe_cmdex == `CMDEX_JMP_2_call_gate_STEP_1);
IF(glob_param_1[15:2] == 14'd0 || glob_descriptor[`DESC_BIT_SEG] == `FALSE || `DESC_IS_DATA(glob_descriptor) ||
(`DESC_IS_CODE_NON_CONFORMING(exe_descriptor) && exe_descriptor[`DESC_BITS_DPL] != cpl) ||
(`DESC_IS_CODE_CONFORMING(exe_descriptor) && exe_descriptor[`DESC_BITS_DPL] > cpl)); //check_cs());
SET(exe_waiting);
SET(exe_trigger_gp_fault); //exception GP(val)
SET(exe_error_code, `SELECTOR_FOR_CODE(glob_param_1));
ENDIF();
IF(~(exe_trigger_gp_fault) && exe_descriptor[`DESC_BIT_P] == `FALSE);
SET(exe_waiting);
SET(exe_trigger_np_fault); //exception GP(val)
SET(exe_error_code, `SELECTOR_FOR_CODE(glob_param_1));
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP_2 && exe_cmdex == `CMDEX_JMP_2_call_gate_STEP_2);
IF(glob_param_2 > glob_desc_limit);
SET(exe_waiting);
SET(exe_trigger_gp_fault); //exception GP(0)
ENDIF();
ENDIF();
</execute>
<execute>
IF(exe_cmd == `CMD_JMP_2 && exe_cmdex == `CMDEX_JMP_2_call_gate_STEP_3);
SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>
<write>
IF(wr_cmd == `CMD_JMP && (wr_cmdex == `CMDEX_JMP_Jv_STEP_0 || wr_cmdex == `CMDEX_JMP_Ev_STEP_0));
SET(wr_not_finished);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP && (wr_cmdex == `CMDEX_JMP_Ev_Jv_STEP_1 || wr_cmdex == `CMDEX_JMP_real_v8086_STEP_1));
// clear pipeline
SET(wr_req_reset_pr);
SET(wr_req_reset_dec);
SET(wr_req_reset_micro);
SET(wr_req_reset_rd);
SET(wr_req_reset_exe);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP && (wr_cmdex == `CMDEX_JMP_Ep_STEP_0 || wr_cmdex == `CMDEX_JMP_Ap_STEP_0 || +
wr_cmdex == `CMDEX_JMP_Ep_STEP_1 || wr_cmdex == `CMDEX_JMP_Ap_STEP_1));
SET(wr_not_finished);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP && wr_cmdex == `CMDEX_JMP_real_v8086_STEP_0);
SET(wr_not_finished);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP && wr_cmdex == `CMDEX_JMP_task_switch_STEP_0);
SET(wr_not_finished);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP_2 && wr_cmdex == `CMDEX_JMP_2_call_gate_STEP_0);
SET(wr_not_finished);
ENDIF();
</write>
<write>
IF(wr_cmd == `CMD_JMP_2 && wr_cmdex == `CMDEX_JMP_2_call_gate_STEP_1);
SET(wr_not_finished);
ENDIF();
</write>