The SVCall function call is lowered to an inline "svc" instruction. The
first parameter *must* be a constant number.
Этот коммит содержится в:
Ayke van Laethem 2018-11-21 17:06:56 +01:00
родитель ce0ad1daa2
коммит d887d645f7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
2 изменённых файлов: 42 добавлений и 0 удалений

Просмотреть файл

@ -1972,6 +1972,36 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon, parentHandle l
return c.builder.CreateCall(target, nil, ""), nil
}
if strings.HasPrefix(fn.RelString(nil), "device/arm.SVCall") {
// Magic function: inline this call as a SVC instruction.
num, _ := constant.Uint64Val(instr.Args[0].(*ssa.Const).Value)
args := []llvm.Value{}
argTypes := []llvm.Type{}
asm := "svc #" + strconv.FormatUint(num, 10)
constraints := "={r0}"
for i, arg := range instr.Args[1:] {
arg = arg.(*ssa.MakeInterface).X
if i == 0 {
constraints += ",0"
} else {
constraints += ",{r" + strconv.Itoa(i) + "}"
}
llvmValue, err := c.parseExpr(frame, arg)
if err != nil {
return llvm.Value{}, err
}
args = append(args, llvmValue)
argTypes = append(argTypes, llvmValue.Type())
}
// Implement the ARM calling convention by marking r1-r3 as
// clobbered. r0 is used as an output register so doesn't have to be
// marked as clobbered.
constraints += ",~{r1},~{r2},~{r3}"
fnType := llvm.FunctionType(c.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0)
return c.builder.CreateCall(target, args, ""), nil
}
if fn.RelString(nil) == "device/arm.AsmFull" || fn.RelString(nil) == "device/avr.AsmFull" {
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
registers := map[string]llvm.Value{}

Просмотреть файл

@ -54,6 +54,18 @@ func AsmFull(asm string, regs map[string]interface{})
// must be a processor register, reachable with the "mov" instruction.
func ReadRegister(name string) uintptr
// Run the following system call (SVCall) with 1 argument.
func SVCall1(num uintptr, a1 interface{}) uintptr
// Run the following system call (SVCall) with 2 arguments.
func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// Run the following system call (SVCall) with 3 arguments.
func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// Run the following system call (SVCall) with 4 arguments.
func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
//go:volatile
type RegValue uint32