Merge branch 'rvc18'

Adds support for the updated RVC extension. The spec is not final yet, but the
compiler already supports and uses it. This update makes it possible to use
the most up-to-date compiler version.
This commit is contained in:
Sven Stucki 2015-09-25 13:19:41 +02:00
commit 3a992372d6

View file

@ -52,26 +52,28 @@ module compressed_decoder
unique case (instr_i[15:13])
3'b000: begin
if (instr_i[12] == 1'b0) begin
// c.mv -> add rd, x0, rs2
// c.mv -> add rd/rs1, x0, rs2
instr_o = {7'b0, instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `OPCODE_OP};
if (instr_i[6:2] == 5'b0) begin
// c.jr -> jalr x0, rd/rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, `OPCODE_JALR};
end
end else begin
// c.add -> add rd, rd, rs2
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], `OPCODE_OP};
end
if (instr_i[11:7] == 5'b0) begin
if (instr_i[6:2] == 5'b0)
instr_o = {32'h00_10_00_73}; // EBREAK
else
illegal_instr_o = 1'b1;
end
end
3'b001: begin
// c.srai -> srai rd, rd, shamt
instr_o = {2'b01, 5'b0, instr_i[6:2], instr_i[11:7], 3'b101, instr_i[11:7], `OPCODE_OPIMM};
if (instr_i[12] != 1'b0) illegal_instr_o = 1'b1;
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
if (instr_i[11:7] == 5'b0) begin
// c.ebreak -> ebreak
instr_o = {32'h00_10_00_73};
if (instr_i[6:2] != 5'b0)
illegal_instr_o = 1'b1;
end else if (instr_i[6:2] == 5'b0) begin
// c.jalr -> jalr x1, rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, `OPCODE_JALR};
end
end
end
3'b010: begin
@ -79,57 +81,9 @@ module compressed_decoder
instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, `OPCODE_STORE};
end
3'b011: begin
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b0, 2'b01, instr_i[9:7], `OPCODE_OP};
unique case ({instr_i[12:10], instr_i[6:5]})
// c.xor -> xor rd', rd', rs2'
5'b00000: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.sll -> sll rd', rd', rs2'
5'b00100: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b001, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.srl -> srl rd', rd', rs2'
5'b00101: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.sra -> sra rd', rd', rs2'
5'b00001: instr_o = {7'b010_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.sltu -> sltu rd', rd', rs2'
5'b00111: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b011, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.sllr -> sll rd', rs1', rd'
5'b01100: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b001, 2'b01, instr_i[4:2], `OPCODE_OP};
// c.srlr -> srl rd', rs1', rd'
5'b01101: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[4:2], `OPCODE_OP};
// c.sltur -> sltu rd', rs1', rd'
5'b01111: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b011, 2'b01, instr_i[4:2], `OPCODE_OP};
// c.slt -> slt rd', rd', rs2'
5'b00110: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[9:7], `OPCODE_OP};
// c.sltr -> slt rd', rs1', rd'
5'b01110: instr_o = {7'b000_0000, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], `OPCODE_OP};
default: illegal_instr_o = 1'b1;
endcase
end
3'b100: begin
// c.sub -> sub rd, rd rs2
instr_o = {2'b01, 5'b0, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], `OPCODE_OP};
if (instr_i[12] != 1'b0) illegal_instr_o = 1'b1;
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end
3'b101: begin
unique case (instr_i[6:5])
// c.add3 -> add rd', rs1', rs2'
2'b00: instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[12:10], `OPCODE_OP};
// c.sub3 -> sub rd', rs1', rs2'
2'b01: instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[12:10], `OPCODE_OP};
// c.or3 -> or rd'1, rs1', rs2'
2'b10: instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[12:10], `OPCODE_OP};
// c.and3 -> and rd', rs1', rs2'
2'b11: instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[12:10], `OPCODE_OP};
endcase
// c.addi4spn -> addi rd', x2, imm
instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
end
3'b110: begin
@ -153,54 +107,17 @@ module compressed_decoder
if (instr_i[12] == 1'b1 || instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
end
3'b001: begin
// c.srli -> srli rd, rd, shamt
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b101, instr_i[11:7], `OPCODE_OPIMM};
if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1;
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end
3'b010: begin
// c.swsp -> sw rs2, imm(x2)
instr_o = {4'b0, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, `OPCODE_STORE};
end
3'b011: begin
// c.bltz -> blt rs1', x0, imm
instr_o = {{3 {instr_i[12]}}, instr_i[12:10], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 3'b100, instr_i[6:3], instr_i[12], `OPCODE_BRANCH};
end
3'b100: begin
unique case (instr_i[6:5])
// c.addin -> addi rd', rs1', imm
2'b00: instr_o = {{9 {instr_i[12]}}, instr_i[12:10], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
// c.xorin -> xori rd', rs1', imm
2'b01: instr_o = {{9 {instr_i[12]}}, instr_i[12:10], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
// c.orin -> ori rd', rs1', imm
2'b10: instr_o = {{9 {instr_i[12]}}, instr_i[12:10], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
// c.andin -> andi rd', rs1', imm
2'b11: instr_o = {{9 {instr_i[12]}}, instr_i[12:10], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
endcase
if (instr_i[12:10] == 3'b0) illegal_instr_o = 1'b1;
end
3'b101: begin
// c.addi4spn -> addi rd', x2, imm
instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
end
3'b110: begin
// c.lwsp -> lw rd, imm(x2)
instr_o = {4'b0, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], `OPCODE_LOAD};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end
3'b111: begin
// c.bgez -> bge rs1', x0, imm
instr_o = {{3 {instr_i[12]}}, instr_i[12:10], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 3'b101, instr_i[6:3], instr_i[12], `OPCODE_BRANCH};
end
default: begin
illegal_instr_o = 1'b1;
end
@ -223,44 +140,28 @@ module compressed_decoder
end
3'b100: begin
if ({instr_i[12], instr_i[6:2]} == 6'b0) begin
// c.jr -> jalr x0, rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, `OPCODE_JALR};
end else begin
// c.li -> addi rd, x0, nzimm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `OPCODE_OPIMM};
end
// c.li -> addi rd, x0, nzimm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `OPCODE_OPIMM};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end
3'b101: begin
if ({instr_i[12], instr_i[6:2]} == 6'b0) begin
// c.jalr -> jalr x1, rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, `OPCODE_JALR};
end else begin
// c.lui -> lui rd, imm
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], `OPCODE_LUI};
// c.lui -> lui rd, imm
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], `OPCODE_LUI};
if (instr_i[11:7] == 5'b0) begin
// c.addi16sp -> addi x2, x2, nzimm
instr_o = {{3 {instr_i[12]}}, instr_i[4:2], instr_i[5], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, `OPCODE_OPIMM};
end
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
end
3'b110: begin
if (instr_i[11:7] == 5'b0) begin
// c.addi16sp -> addi x2, x2, nzimm
// c.nop
instr_o = {{3 {instr_i[12]}}, instr_i[4:2], instr_i[5], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, `OPCODE_OPIMM};
end else begin
// c.addi -> addi rd, rd, nzimm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `OPCODE_OPIMM};
if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
end
end
3'b111: begin
// c.andi -> andi rd, rd, nzimm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b111, instr_i[11:7], `OPCODE_OPIMM};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
// c.addi -> addi rd, rd, nzimm
// c.nop
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `OPCODE_OPIMM};
end
default: begin