1package riscv23// Predecode: the image is turned into fields once, at load, and the dispatch4// loop only indexes arrays.5//6// Two measurements forced this shape, both in switchcost_test.gno:7//8
Functions
not supported for pure packages by the node (vm/qfuncs)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
// - The GnoVM scans switch cases in source order. Reaching case 47 of a
9// 48-case switch costs 13,358 gas against 292 for case 0, a measured 278
10// gas per case skipped. So the internal opcodes below are ordered by how
11// often compiled code actually executes them, and that ordering is a
12// performance decision, not a stylistic one. Do not sort this list.
13// - An elementary operation costs on the order of 280 gas. Fetching four
14// bytes and reassembling them is fourteen of those, on every instruction,
15// forever. Doing it once per word instead is the single largest saving
16// available to an interpreter here.
17//
18// The decoders in decode.gno are used verbatim below rather than inlined,
19// because predecode runs once per word in the image and not once per executed
20// instruction. That is the point: the expensive, readable code moved off the
21// hot path instead of being duplicated onto it.
22
23// Internal opcodes, ordered by expected dynamic frequency in compiled code.
24// The first dozen are what a loop nest and a function prologue are made of.
25const (
26 iADDI uint8 = iota
27 iLW
28 iSW
29 iADD
30 iBNE
31 iBEQ
32 iJAL
33 iJALR
34 iLUI
35 iSLLI
36 iSRLI
37 iANDI
38 iSUB
39 iORI
40 iXORI
41 iBLT
42 iBGE
43 iBLTU
44 iBGEU
45 iSRAI
46 iSLL
47 iSRL
48 iSRA
49 iAND
50 iOR
51 iXOR
52 iLBU
53 iLB
54 iLH
55 iLHU
56 iSB
57 iSH
58 iAUIPC
59 iSLT
60 iSLTU
61 iSLTI
62 iSLTIU
63 iMUL
64 iMULH
65 iMULHSU
66 iMULHU
67 iDIV
68 iDIVU
69 iREM
70 iREMU
71 iECALL
72 iEBREAK
73 iFENCE
74 iILLEGAL
75)
76
77// code is an image with its fields already pulled apart. Parallel arrays, not
78// a slice of structs: an arm reads three or four fields, and paying for the
79// ones it does not read is the cost this whole file exists to avoid.
80type code struct {
81 base uint32// the address word 0 sits at
82 words uint32// how many instructions the text segment holds
83 end uint32// base + 4*words, the first address past the text
84 op []uint8
85 rd []uint8
86 rs1 []uint8
87 rs2 []uint8
88 imm []uint32
89}
90
91// predecode walks an image and records, for every word, what it is and what
92// its operands are. A word that is not an instruction becomes iILLEGAL and
93// traps only if it is ever executed, which is what keeps a constant pool in