Skip to content

Commit fa7af34

Browse files
committed
builder/createInlineAsm:with independant logic to avoid goto operate
1 parent 633688c commit fa7af34

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

compiler/inlineasm.go

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,31 +43,46 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
4343
// "value": 1
4444
// "result": &dest,
4545
// })
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+
4676
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
4777
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
4878
registers := map[string]llvm.Value{}
79+
4980
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
6985
}
70-
done:
7186
}
7287
// TODO: handle dollar signs in asm string
7388
registerNumbers := map[string]int{}

0 commit comments

Comments
 (0)