Browse Source

picorv32: fix aliasing of mret = retirq

H. Peter Anvin 3 years ago
parent
commit
ea8bf559a9
1 changed files with 10 additions and 8 deletions
  1. 10 8
      fpga/picorv32.v

+ 10 - 8
fpga/picorv32.v

@@ -853,6 +853,12 @@ module picorv32 #(
 	end
 `endif
 
+	// hpa: allow mret as an alias for retirq, so that
+	// __attribute__((interrupt)) works in gcc
+	wire instr_la_retirq = ENABLE_IRQ &&
+			 ((mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010) ||
+			  (mem_rdata_latched[6:0] == 7'b1110011 && mem_rdata_latched[31:25] == 7'b0011000));
+
 	always @(posedge clk) begin
 		is_lui_auipc_jal <= |{instr_lui, instr_auipc, instr_jal};
 		is_lui_auipc_jal_jalr_addi_add_sub <= |{instr_lui, instr_auipc, instr_jal, instr_jalr, instr_addi, instr_add, instr_sub};
@@ -866,11 +872,7 @@ module picorv32 #(
 			instr_auipc   <= mem_rdata_latched[6:0] == 7'b0010111;
 			instr_jal     <= mem_rdata_latched[6:0] == 7'b1101111;
 			instr_jalr    <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000;
-			// hpa: allow mret as an alias for retirq, so that
-			// __attribute__((interrupt)) works in gcc
-			instr_retirq  <= ENABLE_IRQ &&
-					 ((mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010) ||
-					  (mem_rdata_latched[6:0] == 7'b0000111 && mem_rdata_latched[31:25] == 7'b0011000));
+			instr_retirq  <= instr_la_retirq;
 			instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ;
 
 			is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011;
@@ -888,7 +890,7 @@ module picorv32 #(
 			if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS)
 				decoded_rs1[regindex_bits-1] <= 1; // instr_getq
 
-			if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ)
+			if (instr_la_retirq)
 				decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq
 
 			compressed_instr <= 0;
@@ -1436,7 +1438,7 @@ module picorv32 #(
 			count_instr <= 'bx;
 		end
 
-		next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx;
+		next_irq_pending = ENABLE_IRQ ? (irq_pending & LATCHED_IRQ & ~MASKED_IRQ) : 'bx;
 
 		if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin
 			timer <= timer - 1;
@@ -1680,7 +1682,7 @@ module picorv32 #(
 						`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
 						// hpa: allow rs2 to specify bits to be preserved
 					        `debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, cpuregs_rs2);)
-						irq_mask <= ((irq_mask & ~cpuregs_rs2) ^ cpuregs_rs1) | MASKED_IRQ;
+						irq_mask <= ((irq_mask & cpuregs_rs2) ^ cpuregs_rs1) | MASKED_IRQ;
 						dbg_rs1val <= cpuregs_rs1;
 						dbg_rs1val_valid <= 1;
 						cpu_state <= cpu_state_fetch;