gpcas_isa/instruction.rs
1// Filename: instruction.rs
2// Version: 0.8
3// Date: 18-11-2021 (DD-MM-YYYY)
4// Library: gpcas_isa
5//
6// Copyright (c) 2021 Kai Rese
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Lesser General Public License as
9// published by the Free Software Foundation, either version 3 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU Lesser General Public License for more details.
16//
17// You should have received a copy of the GNU Lesser General Public
18// License along with this program. If not, see
19// <https://www.gnu.org/licenses/>.
20
21//! Contains data structs and enums used by the emulator to send instructions to the simulator.
22
23/// The maximum number of register inputs that is needed by any ISA.
24pub const MAX_INPUTS: usize = 4;
25/// This flag gets set in the register indices. It indicates that the index is for a vector
26/// register and therefore might be using a separate register set.
27pub const IS_VECTOR_REGISTER: u8 = 0x20;
28
29/// An emulated instruction from the program of the simulation.
30///
31/// The emulator frontend sends one `Instruction` for each instruction it emulates. The simulator
32/// backend then uses it to do timing simulation.
33#[derive(Debug, Default, Clone)]
34pub struct Instruction {
35 /// The address of the instruction.
36 pub address: usize,
37 /// Contains the address of the memory operand, if it has one.
38 pub memory_address: usize,
39 /// The target address of the branch, provided the instruction is one.
40 pub branch_address: usize,
41 /// An ID for the instruction class, see `instruction_type` in the gpcas_base crate. Determines
42 /// execution time in the ALU, as well as possible restrictions for execution pipe choice in the
43 /// model.
44 pub instr_type: u16,
45 /// Contains the size of the memory operand in bytes.
46 pub memory_operand_size: u16,
47 /// Bitflags for different properties of the instruction, see [`instruction_flags`].
48 pub flags: u16,
49 /// The register indices of the inputs. The full input count may not be needed by all ISAs.
50 ///
51 /// Registers used as input operands are saved after ones for memory operand calculation.
52 pub inputs: [u8; MAX_INPUTS],
53 /// How many register inputs the instruction uses in total.
54 pub input_register_count: u8,
55 /// How many register inputs are used for memory operand calculation.
56 pub memory_register_count: u8,
57 /// The register index of the output if the instruction has one.
58 pub output: u8,
59 /// Size of the instruction in bytes.
60 pub size: u8,
61}
62
63/// Contains constants for control information for the cpu simulation.
64///
65/// This module contains the flag constants used in [`Instruction::flags`].
66pub mod instruction_flags {
67 /// The branch is taken.
68 ///
69 /// This should only be checked if the branch type is [`BR_TYPE_CONDITIONAL`].
70 pub const BR_TAKEN: u16 = 0x0001;
71 /// The branch is a return from a call.
72 ///
73 /// This should only be checked if the branch type is [`BR_TYPE_CALL`].
74 pub const BR_RETURN: u16 = BR_TAKEN;
75 /// The branch uses registers or a memory operand to determine the target address.
76 ///
77 /// If this is set, the target address might get predicted, but not resolved in the front end of
78 /// the front end of the model pipeline.
79 pub const BR_INDIRECT: u16 = 0x0002;
80 /// The instruction is no branch of any form.
81 pub const BR_TYPE_NONE: u16 = 0x0000;
82 /// The instruction is a unconditional jump.
83 pub const BR_TYPE_JUMP: u16 = 0x0004;
84 /// The instruction is a conditional branch.
85 pub const BR_TYPE_CONDITIONAL: u16 = 0x0008;
86 /// The instruction is either a call or a return instruction.
87 pub const BR_TYPE_CALL: u16 = 0x000C;
88 /// The bitmask for the branch type. Use this to check the type.
89 pub const BR_TYPE_MASK: u16 = 0x000C;
90
91 /// The instruction has a memory input.
92 pub const MEM_IN: u16 = 0x0010;
93 /// The instruction has a memory output.
94 pub const MEM_OUT: u16 = 0x0020;
95 /// The instruction has a register output.
96 pub const REG_OUT: u16 = 0x0040;
97 /// The memory operand is a vector.
98 ///
99 /// This is used for special vector treatment in case it is necessary.
100 pub const MEM_VECTOR: u16 = 0x0080;
101
102 /// The instruction is a micro-operation of a more complex instruction and has another
103 /// micro-operation of the same instruction following after it.
104 pub const HAS_FOLLOW_UP: u16 = 0x0100;
105 /// The instruction switches the execution context, for example when executing a system call.
106 /// This can have different effects on the hardware which could be simulated as flushing the L1
107 /// caches, for example.
108 pub const CONTEXT_CHANGE: u16 = 0x0200;
109 /// The simulator should terminate after this instruction.
110 ///
111 /// Currently there is no difference between a normal exit, a panic or other exceptions.
112 pub const TERMINATE: u16 = 0x8000;
113}