summaryrefslogtreecommitdiff
path: root/rtl/core/decode/data.sv
blob: f7449722ecde56a616c01a3b4a718ac89ec4e65c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
`include "core/decode/isa.sv"
`include "core/uarch.sv"

module core_decode_data
(
	input  word        insn,

	output data_decode decode,
	output logic       snd_is_imm,
	                   snd_shift_by_reg_if_reg,
	                   writeback,
	                   conditional,
	                   update_flags,
	                   restore_spsr
);

	alu_op op;
	reg_num rn, rd;
	logic uses_rn;

	assign decode.op = op;
	assign decode.rn = rn;
	assign decode.rd = rd;
	assign decode.uses_rn = uses_rn;

	assign rn = insn `FIELD_DATA_RN;
	assign rd = insn `FIELD_DATA_RD;
	assign op = insn `FIELD_DATA_OPCODE;

	assign snd_is_imm = insn `FIELD_DATA_IMM;
	assign snd_shift_by_reg_if_reg = insn `FIELD_DATA_REGSHIFT;

	always_comb begin
		unique case(op)
			`ALU_ADC, `ALU_SBC, `ALU_RSC:
				conditional = 1;

			default:
				conditional = 0;
		endcase

		unique case(op)
			`ALU_CMP, `ALU_CMN, `ALU_TST, `ALU_TEQ:
				writeback = 0;

			default:
				writeback = 1;
		endcase

		unique case(op)
			`ALU_MOV, `ALU_MVN:
				uses_rn = 0;

			default:
				uses_rn = 1;
		endcase

		update_flags = insn `FIELD_DATA_S;
		restore_spsr = (rd == `R15) & update_flags;

		if(restore_spsr)
			update_flags = 0;
	end

endmodule