arm: implement SVCall
The SVCall function call is lowered to an inline "svc" instruction. The first parameter *must* be a constant number.
Этот коммит содержится в:
родитель
ce0ad1daa2
коммит
d887d645f7
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
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче