@@ -9,79 +9,59 @@ import (
99 "alon.kr/x/usm/gen"
1010)
1111
12- type BaseAdd struct {
13- NonBranchingInstruction
12+ type Add struct {
13+ gen. NonBranchingInstruction
1414}
1515
16- func (BaseAdd ) Operator () string {
17- return "add"
18- }
19-
20- type AddReg struct {
21- BaseAdd
22- instructions.AddShiftedRegister
23- }
24-
25- func (i AddReg ) Generate (
26- * aarch64codegen.InstructionCodegenContext ,
27- ) (instructions.Instruction , core.ResultList ) {
28- return i , core.ResultList {}
29- }
30-
31- type AddImm struct {
32- BaseAdd
33- instructions.AddImmediate
16+ func NewAddInstruction () gen.InstructionDefinition {
17+ return Add {}
3418}
3519
36- func (i AddImm ) Generate (
37- * aarch64codegen.InstructionCodegenContext ,
38- ) (instructions.Instruction , core.ResultList ) {
39- return i , core.ResultList {}
20+ func (Add ) Operator (* gen.InstructionInfo ) string {
21+ return "add"
4022}
4123
42- type AddDefinition struct {}
43-
44- func (d AddDefinition ) buildRegisterVariant (
24+ func (add Add ) codegenRegisterVariant (
4525 info * gen.InstructionInfo ,
46- ) (gen. BaseInstruction , core.ResultList ) {
26+ ) (instructions. Instruction , core.ResultList ) {
4727 Xd , Xn , Xm , results := aarch64translation .BinaryInstructionToAarch64 (info )
4828 if ! results .IsEmpty () {
4929 return nil , results
5030 }
5131
52- return AddReg {
53- AddShiftedRegister : instructions .NewAddShiftedRegister (Xd , Xn , Xm ),
54- }, core.ResultList {}
32+ inst := instructions .NewAddShiftedRegister (Xd , Xn , Xm )
33+ return inst , core.ResultList {}
5534}
5635
57- func (AddDefinition ) buildImmediateVariant (
36+ func (add Add ) codegenImmediateVariant (
5837 info * gen.InstructionInfo ,
59- ) (gen. BaseInstruction , core.ResultList ) {
38+ ) (instructions. Instruction , core.ResultList ) {
6039 Xd , Xn , imm , results := aarch64translation .Immediate12InstructionToAarch64 (info )
6140 if ! results .IsEmpty () {
6241 return nil , results
6342 }
6443
65- return AddImm {
66- AddImmediate : instructions .NewAddImmediate (Xd , Xn , imm ),
67- }, core.ResultList {}
44+ inst := instructions .NewAddImmediate (Xd , Xn , imm )
45+ return inst , core.ResultList {}
6846}
6947
70- func (d AddDefinition ) BuildInstruction (
71- info * gen.InstructionInfo ,
72- ) (gen.BaseInstruction , core.ResultList ) {
48+ func (add Add ) Codegen (
49+ ctx * aarch64codegen.InstructionCodegenContext ,
50+ ) (instructions.Instruction , core.ResultList ) {
51+ // TODO: this implementation is very similar to the one in adds.go, and possibly
52+ // other binary arithmetic instructions. Consider refactoring this.
53+
54+ info := ctx .InstructionInfo
7355 results := aarch64translation .ValidateBinaryInstruction (info )
7456 if ! results .IsEmpty () {
7557 return nil , results
7658 }
7759
7860 switch info .Arguments [1 ].(type ) {
7961 case * gen.RegisterArgumentInfo :
80- return d .buildRegisterVariant (info )
81-
62+ return add .codegenRegisterVariant (info )
8263 case * gen.ImmediateInfo :
83- return d .buildImmediateVariant (info )
84-
64+ return add .codegenImmediateVariant (info )
8565 default :
8666 return nil , list .FromSingle (core.Result {
8767 {
@@ -93,6 +73,13 @@ func (d AddDefinition) BuildInstruction(
9373 }
9474}
9575
96- func NewAddInstructionDefinition () gen.InstructionDefinition {
97- return AddDefinition {}
76+ func (add Add ) Validate (
77+ info * gen.InstructionInfo ,
78+ ) core.ResultList {
79+ // TODO: this is a pretty hacky way to validate the instruction: we create
80+ // a "mock" generation context, and then try to generate the binary
81+ // representation of the instruction.
82+ ctx := aarch64codegen.InstructionCodegenContext {InstructionInfo : info }
83+ _ , results := add .Codegen (& ctx )
84+ return results
9885}
0 commit comments