@@ -43,31 +43,46 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
43
43
// "value": 1
44
44
// "result": &dest,
45
45
// })
46
+ // collectInlineAsmRegisters extracts register values from the map referrers,
47
+ // stopping when it encounters the AsmFull call itself to avoid processing
48
+ // MapUpdate operations that happen after the call.
49
+ func (b * builder ) collectInlineAsmRegisters (instr * ssa.CallCommon , registerMap * ssa.MakeMap ) (map [string ]llvm.Value , error ) {
50
+ registers := map [string ]llvm.Value {}
51
+
52
+ for _ , r := range * registerMap .Referrers () {
53
+ switch r := r .(type ) {
54
+ case * ssa.DebugRef :
55
+ // ignore
56
+ case * ssa.MapUpdate :
57
+ if r .Block () != registerMap .Block () {
58
+ return nil , b .makeError (instr .Pos (), "register value map must be created in the same basic block" )
59
+ }
60
+ key := constant .StringVal (r .Key .(* ssa.Const ).Value )
61
+ registers [key ] = b .getValue (r .Value .(* ssa.MakeInterface ).X , getPos (instr ))
62
+ case * ssa.Call :
63
+ if r .Common () == instr {
64
+ // Stop processing when we encounter the AsmFull call itself
65
+ // to avoid including MapUpdate operations that happen after the call
66
+ return registers , nil
67
+ }
68
+ default :
69
+ return nil , b .makeError (instr .Pos (), "don't know how to handle argument to inline assembly: " + r .String ())
70
+ }
71
+ }
72
+
73
+ return registers , nil
74
+ }
75
+
46
76
func (b * builder ) createInlineAsmFull (instr * ssa.CallCommon ) (llvm.Value , error ) {
47
77
asmString := constant .StringVal (instr .Args [0 ].(* ssa.Const ).Value )
48
78
registers := map [string ]llvm.Value {}
79
+
49
80
if registerMap , ok := instr .Args [1 ].(* ssa.MakeMap ); ok {
50
- for _ , r := range * registerMap .Referrers () {
51
- switch r := r .(type ) {
52
- case * ssa.DebugRef :
53
- // ignore
54
- case * ssa.MapUpdate :
55
- if r .Block () != registerMap .Block () {
56
- return llvm.Value {}, b .makeError (instr .Pos (), "register value map must be created in the same basic block" )
57
- }
58
- key := constant .StringVal (r .Key .(* ssa.Const ).Value )
59
- registers [key ] = b .getValue (r .Value .(* ssa.MakeInterface ).X , getPos (instr ))
60
- case * ssa.Call :
61
- if r .Common () == instr {
62
- // Stop processing when we encounter the AsmFull call itself
63
- // to avoid including MapUpdate operations that happen after the call
64
- goto done
65
- }
66
- default :
67
- return llvm.Value {}, b .makeError (instr .Pos (), "don't know how to handle argument to inline assembly: " + r .String ())
68
- }
81
+ var err error
82
+ registers , err = b .collectInlineAsmRegisters (instr , registerMap )
83
+ if err != nil {
84
+ return llvm.Value {}, err
69
85
}
70
- done:
71
86
}
72
87
// TODO: handle dollar signs in asm string
73
88
registerNumbers := map [string ]int {}
0 commit comments