Skip to content

Commit 0999f28

Browse files
committed
Refactored base instruction types
1 parent 5be2b9c commit 0999f28

File tree

9 files changed

+63
-60
lines changed

9 files changed

+63
-60
lines changed

aarch64/codegen/instruction.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
)
1212

1313
type Instruction interface {
14-
gen.BaseInstruction
14+
gen.InstructionDefinition
1515

1616
// Converts the abstract instruction representation into a concrete binary
1717
// instruction.
18-
Generate(
19-
*InstructionCodegenContext,
18+
Codegen(
19+
ctx *InstructionCodegenContext,
2020
) (instructions.Instruction, core.ResultList)
2121
}
2222

@@ -34,7 +34,7 @@ func (ctx *InstructionCodegenContext) InstructionOffsetInFile() uint64 {
3434
func (ctx *InstructionCodegenContext) Codegen(
3535
buffer *bytes.Buffer,
3636
) core.ResultList {
37-
instruction, ok := ctx.Instruction.(Instruction)
37+
instruction, ok := ctx.InstructionInfo.Instruction.(Instruction)
3838
if !ok {
3939
return list.FromSingle(core.Result{
4040
{
@@ -45,7 +45,7 @@ func (ctx *InstructionCodegenContext) Codegen(
4545
})
4646
}
4747

48-
binaryInst, results := instruction.Generate(ctx)
48+
binaryInst, results := instruction.Codegen(ctx)
4949
if !results.IsEmpty() {
5050
return results
5151
}

aarch64/isa/base.go

Lines changed: 0 additions & 12 deletions
This file was deleted.

gen/function_generator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (g *FunctionGenerator) getInstructionBranchingDestinations(
144144
info *InstructionInfo,
145145
labels functionLabelData,
146146
) ([]int, core.ResultList) {
147-
steps, results := info.Instruction.PossibleNextSteps()
147+
steps, results := info.Instruction.PossibleNextSteps(info)
148148
if !results.IsEmpty() {
149149
return nil, results
150150
}
@@ -286,7 +286,7 @@ func (g *FunctionGenerator) generateBasicBlocks(
286286
basicBlockLength := len(currentBasicBlock.Instructions)
287287
lastInstruction := currentBasicBlock.Instructions[basicBlockLength-1]
288288

289-
steps, results := lastInstruction.Instruction.PossibleNextSteps()
289+
steps, results := lastInstruction.Instruction.PossibleNextSteps(lastInstruction)
290290
if !results.IsEmpty() {
291291
return results
292292
}

gen/instruction_definition.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,31 @@ import (
44
"alon.kr/x/usm/core"
55
)
66

7-
type BaseInstruction interface {
7+
type InstructionDefinition interface {
88
// This method is usd by the USM engine to generate the internal control
99
// flow graph representation.
1010
//
1111
// Should return a non-empty slice. If the instruction does not have any
1212
// consecutive steps in the function (for example, a return statement),
1313
// then a special dedicated return step should be returned.
14-
PossibleNextSteps() (StepInfo, core.ResultList)
14+
PossibleNextSteps(*InstructionInfo) (StepInfo, core.ResultList)
1515

1616
// Returns the string that represents the operator of the instruction.
1717
// For example, for the add instruction this method would return "ADD".
1818
//
1919
// This is required because some instructions may be generated automatically,
2020
// and we want to be able to display them in a human-readable format.
21-
Operator() string
21+
Operator(*InstructionInfo) string
22+
23+
// Validate the instruction information structure, according to the
24+
// expected arguments, targets, and other related information.
25+
Validate(*InstructionInfo) core.ResultList
2226
}
2327

24-
// A basic instruction definition. This defines the logic that converts the
25-
// generic, architecture / instruction set independent instruction AST nodes
26-
// into a format instruction which is part of a specific instruction set.
27-
type InstructionDefinition interface {
28-
// Build an instruction from the provided instruction information.
29-
BuildInstruction(info *InstructionInfo) (BaseInstruction, core.ResultList)
28+
type NonBranchingInstruction struct{}
29+
30+
func (NonBranchingInstruction) PossibleNextSteps(*InstructionInfo) (StepInfo, core.ResultList) {
31+
return StepInfo{
32+
PossibleContinue: true,
33+
}, core.ResultList{}
3034
}

gen/instruction_generator.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,12 @@ func (g *InstructionGenerator) Generate(
137137
instCtx.InstructionInfo.AppendTarget(targets...)
138138
instCtx.InstructionInfo.AppendArgument(arguments...)
139139

140-
instruction, results := instDef.BuildInstruction(instCtx.InstructionInfo)
140+
instCtx.InstructionInfo.SetInstruction(instDef)
141+
142+
results = instDef.Validate(instCtx.InstructionInfo)
141143
if !results.IsEmpty() {
142144
return nil, results
143145
}
144146

145-
instCtx.InstructionInfo.Instruction = instruction
146147
return instCtx.InstructionInfo, core.ResultList{}
147148
}

gen/instruction_generator_test.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@ import (
1616

1717
type AddInstruction struct{}
1818

19-
func (i *AddInstruction) PossibleNextSteps() (gen.StepInfo, core.ResultList) {
19+
func (AddInstruction) PossibleNextSteps(*gen.InstructionInfo) (gen.StepInfo, core.ResultList) {
2020
return gen.StepInfo{PossibleContinue: true}, core.ResultList{}
2121
}
2222

23-
func (i *AddInstruction) Operator() string {
23+
func (AddInstruction) Operator(*gen.InstructionInfo) string {
2424
return "ADD"
2525
}
2626

27+
func (AddInstruction) Validate(info *gen.InstructionInfo) core.ResultList {
28+
return core.ResultList{}
29+
}
30+
2731
type AddInstructionDefinition struct{}
2832

2933
func (AddInstructionDefinition) BuildInstruction(
3034
info *gen.InstructionInfo,
31-
) (gen.BaseInstruction, core.ResultList) {
32-
return gen.BaseInstruction(&AddInstruction{}), core.ResultList{}
35+
) (gen.InstructionDefinition, core.ResultList) {
36+
return gen.InstructionDefinition(AddInstruction{}), core.ResultList{}
3337
}
3438

3539
func (AddInstructionDefinition) InferTargetTypes(
@@ -71,20 +75,24 @@ func (AddInstructionDefinition) InferTargetTypes(
7175

7276
type RetInstruction struct{}
7377

74-
func (i *RetInstruction) PossibleNextSteps() (gen.StepInfo, core.ResultList) {
78+
func (RetInstruction) PossibleNextSteps(*gen.InstructionInfo) (gen.StepInfo, core.ResultList) {
7579
return gen.StepInfo{PossibleReturn: true}, core.ResultList{}
7680
}
7781

78-
func (i *RetInstruction) Operator() string {
82+
func (RetInstruction) Operator(*gen.InstructionInfo) string {
7983
return "RET"
8084
}
8185

86+
func (RetInstruction) Validate(*gen.InstructionInfo) core.ResultList {
87+
return core.ResultList{}
88+
}
89+
8290
type RetInstructionDefinition struct{}
8391

8492
func (RetInstructionDefinition) BuildInstruction(
8593
info *gen.InstructionInfo,
86-
) (gen.BaseInstruction, core.ResultList) {
87-
return gen.BaseInstruction(&RetInstruction{}), core.ResultList{}
94+
) (gen.InstructionDefinition, core.ResultList) {
95+
return gen.InstructionDefinition(RetInstruction{}), core.ResultList{}
8896
}
8997

9098
func (RetInstructionDefinition) InferTargetTypes(
@@ -97,28 +105,30 @@ func (RetInstructionDefinition) InferTargetTypes(
97105

98106
// MARK: Jump
99107

100-
type JumpInstruction struct {
101-
*gen.InstructionInfo
102-
}
108+
type JumpInstruction struct{}
103109

104-
func (i *JumpInstruction) PossibleNextSteps() (gen.StepInfo, core.ResultList) {
110+
func (JumpInstruction) PossibleNextSteps(i *gen.InstructionInfo) (gen.StepInfo, core.ResultList) {
105111
return gen.StepInfo{
106112
PossibleBranches: []*gen.LabelInfo{
107113
i.Arguments[0].(*gen.LabelArgumentInfo).Label,
108114
},
109115
}, core.ResultList{}
110116
}
111117

112-
func (i *JumpInstruction) Operator() string {
118+
func (JumpInstruction) Operator(*gen.InstructionInfo) string {
113119
return "JMP"
114120
}
115121

122+
func (JumpInstruction) Validate(info *gen.InstructionInfo) core.ResultList {
123+
return core.ResultList{}
124+
}
125+
116126
type JumpInstructionDefinition struct{}
117127

118128
func (JumpInstructionDefinition) BuildInstruction(
119129
info *gen.InstructionInfo,
120-
) (gen.BaseInstruction, core.ResultList) {
121-
return gen.BaseInstruction(&JumpInstruction{info}), core.ResultList{}
130+
) (gen.InstructionDefinition, core.ResultList) {
131+
return gen.InstructionDefinition(JumpInstruction{}), core.ResultList{}
122132
}
123133

124134
func (JumpInstructionDefinition) InferTargetTypes(
@@ -132,28 +142,30 @@ func (JumpInstructionDefinition) InferTargetTypes(
132142
// MARK: Jump Zero
133143

134144
// JZ %condition .label
135-
type JumpZeroInstruction struct {
136-
*gen.InstructionInfo
137-
}
145+
type JumpZeroInstruction struct{}
138146

139-
func (i *JumpZeroInstruction) PossibleNextSteps() (gen.StepInfo, core.ResultList) {
147+
func (JumpZeroInstruction) PossibleNextSteps(i *gen.InstructionInfo) (gen.StepInfo, core.ResultList) {
140148
label := i.Arguments[1].(*gen.LabelArgumentInfo).Label
141149
return gen.StepInfo{
142150
PossibleBranches: []*gen.LabelInfo{label},
143151
PossibleContinue: true,
144152
}, core.ResultList{}
145153
}
146154

147-
func (i *JumpZeroInstruction) Operator() string {
155+
func (JumpZeroInstruction) Operator(*gen.InstructionInfo) string {
148156
return "JZ"
149157
}
150158

159+
func (JumpZeroInstruction) Validate(info *gen.InstructionInfo) core.ResultList {
160+
return core.ResultList{}
161+
}
162+
151163
type JumpZeroInstructionDefinition struct{}
152164

153165
func (JumpZeroInstructionDefinition) BuildInstruction(
154166
info *gen.InstructionInfo,
155-
) (gen.BaseInstruction, core.ResultList) {
156-
return gen.BaseInstruction(&JumpZeroInstruction{info}), core.ResultList{}
167+
) (gen.InstructionDefinition, core.ResultList) {
168+
return gen.InstructionDefinition(JumpZeroInstruction{}), core.ResultList{}
157169
}
158170

159171
func (JumpZeroInstructionDefinition) InferTargetTypes(
@@ -172,15 +184,15 @@ func (m *InstructionMap) GetInstructionDefinition(
172184
name string,
173185
node parse.InstructionNode,
174186
) (gen.InstructionDefinition, core.ResultList) {
175-
instDef, ok := (*m)[name]
187+
inst, ok := (*m)[name]
176188
if !ok {
177189
return nil, list.FromSingle(core.Result{{
178190
Type: core.ErrorResult,
179191
Message: "undefined instruction",
180192
Location: &node.Operator,
181193
}})
182194
}
183-
return instDef, core.ResultList{}
195+
return inst, core.ResultList{}
184196
}
185197

186198
func PrepareTestForInstructionGeneration(

gen/instruction_info.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type InstructionInfo struct {
1313
Arguments []ArgumentInfo
1414

1515
// The actual instruction information, which is ISA specific.
16-
Instruction BaseInstruction
16+
Instruction InstructionDefinition
1717

1818
// The location in which the instruction was defined in the source code.
1919
// Can be nil if the instruction was defined internally, for example,
@@ -61,13 +61,13 @@ func (i *InstructionInfo) AppendArgument(arguments ...ArgumentInfo) {
6161
// This can be used to update the instruction, but keep the same arguments and
6262
// targets, for example, as an optimization to a more specific operation which
6363
// accepts the same arguments in certain cases.
64-
func (i *InstructionInfo) SetBaseInstruction(instruction BaseInstruction) {
64+
func (i *InstructionInfo) SetInstruction(instruction InstructionDefinition) {
6565
i.Instruction = instruction
6666
}
6767

6868
func (i *InstructionInfo) String() string {
6969
s := ""
70-
operator := i.Instruction.Operator()
70+
operator := i.Instruction.Operator(i)
7171

7272
if len(i.Targets) > 0 {
7373
for _, target := range i.Targets {

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
alon.kr/x/aarch64codegen v0.0.0-20250423211537-52c2f85d1367 h1:l+WdERkNIO4GVBHvcqs0PJSELEkr3A0CGbwSTL3/6pE=
22
alon.kr/x/aarch64codegen v0.0.0-20250423211537-52c2f85d1367/go.mod h1:WAdZYqOdp9KwoBjWamrMDAphahR5oXkPSICj3+tLIyQ=
3-
alon.kr/x/faststringmap v0.0.0-20250425112818-35d6525968e3 h1:i2q4NANxEeSzGiWidH8lodMM/fZ3eCxfZdvA4WDKC9I=
4-
alon.kr/x/faststringmap v0.0.0-20250425112818-35d6525968e3/go.mod h1:dPORoTvAFIehHRaI/lfJV3eT6PL5tY7fpAtxzz7rQVw=
53
alon.kr/x/faststringmap v0.0.0-20250503134653-20d6364c2c94 h1:EdG6bQh5IT5MZ76MY85/GK4Ma7zoJ4zcFqd2fpxK6NI=
64
alon.kr/x/faststringmap v0.0.0-20250503134653-20d6364c2c94/go.mod h1:dPORoTvAFIehHRaI/lfJV3eT6PL5tY7fpAtxzz7rQVw=
75
alon.kr/x/graph v0.0.0-20250319212444-dd67d0281ab7 h1:0d/oLvPQWc1B38ZfWfJ5UQXeHx9JT8gmp3K0AOOG8aQ=

usm64/ssa/ssa_construction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (s *ConstructionScheme) NewPhiInstruction(
2929
target := gen.NewTargetInfo(register)
3030
info.AppendTarget(&target)
3131
instruction, results := usm64isa.NewPhiInstruction(info)
32-
info.SetBaseInstruction(instruction)
32+
info.SetInstruction(instruction)
3333
block.PrependInstruction(info)
3434
return ssa.PhiInstruction(instruction), results
3535
}

0 commit comments

Comments
 (0)