|
<< Click to Display Table of Contents >> Navigation: ASA-EMulatR Reference Guide > Introduction > Architecture Overview > Chapter 3 - Pipeline Architecture > 3.16 Grain System |
The grain system provides the instruction abstraction layer that bridges raw 32-bit instruction words to executable behavior.
The GrainResolver is a singleton that decodes raw instructions and resolves them to InstructionGrain objects. Resolution extracts the 6-bit opcode and the function code (format-dependent), then looks up the corresponding grain in the InstructionGrainRegistry. For PAL hardware opcodes (0x19, 0x1B, 0x1D, 0x1E, 0x1F), the function code is treated as an operand (IPR index), not a grain selector — these instructions share a single grain per opcode.
inline InstructionGrain* ResolveGrain(quint32 rawBits) {
const quint8 opcode = (rawBits >> 26) & 0x3F;
quint16 func;
if (isPalHardwareOpcode(opcode))
func = 0x0000; // IPR index is operand, not grain selector
else
func = extractFunctionCode(rawBits, opcode);
return InstructionGrainRegistry::instance().lookup(opcode, func);
}
Decoding occurs once per unique instruction pattern (opcode + function code). The resolved grain is cached in the InstructionGrainRegistry and reused on subsequent fetches of the same pattern. This avoids redundant decode work — execution may occur thousands of times from a single decode operation.
Each InstructionGrain carries:
•flags (GrainFlags) — format classification: OperateFormat, MemoryFormat, BranchFormat, PALFormat, CanDualIssue, NeedsStall
•latency and throughput — cycle counts for scheduling
•Virtual methods: execute(PipelineSlot&), mnemonic(), opcode(), functionCode(), grainType()
The execute() method is the single dispatch point — it is called by stage_EX() and contains the instruction's complete architectural behavior.
The GrainMaster.tsv file is the master opcode table (616 entries) that defines every instruction the emulator supports. Each row specifies the opcode, function code, mnemonic, description, instruction type, and target Box. The Python tooling (generate_all_grains.py) reads this TSV and generates C++ registration code that populates the InstructionGrainRegistry at startup.
The GrainResolver classifies instructions into formats for pipeline routing:
Operate — integer operate (non-barrier)
Memory — normal LD/ST/LDA/LDAH
Branch — BR/BSR/BEQ and conditional branches
Pal — CALL_PAL instructions
Float — FP arithmetic and FP compare
MemoryMB — memory-with-function: FETCH/FETCH_M/WH64/MB/WMB
JMP_JSR_Format — JMP, JSR, RET, JSR_COROUTINE
See Also: grainFactoryLib/GrainResolver.h; grainFactoryLib/InstructionGrain.h; grainFactoryLib/GrainMaster.tsv; Python/generate_all_grains.py.