// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package asmgen var ArchARM = &Arch{ Name: "arm", WordBits: 32, WordBytes: 4, CarrySafeLoop: true, regs: []string{ // R10 is g. // R11 is the assembler/linker temporary (but we use it as a regular register). // R13 is SP. // R14 is LR. // R15 is PC. "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R11", "R12", }, regShift: true, mov: "MOVW", add: "ADD", adds: "ADD.S", adc: "ADC", adcs: "ADC.S", sub: "SUB", subs: "SUB.S", sbc: "SBC", sbcs: "SBC.S", rsb: "RSB", and: "AND", or: "ORR", xor: "EOR", mulWideF: armMulWide, addWords: "ADD %s<<2, %s, %s", jmpZero: "TEQ $0, %s; BEQ %s", jmpNonZero: "TEQ $0, %s; BNE %s", loadIncN: armLoadIncN, loadDecN: armLoadDecN, storeIncN: armStoreIncN, storeDecN: armStoreDecN, } func armMulWide(a *Asm, src1, src2, dstlo, dsthi Reg) { a.Printf("\tMULLU %s, %s, (%s, %s)\n", src1, src2, dsthi, dstlo) } func armLoadIncN(a *Asm, p RegPtr, regs []Reg) { for _, r := range regs { a.Printf("\tMOVW.P %d(%s), %s\n", a.Arch.WordBytes, p, r) } } func armLoadDecN(a *Asm, p RegPtr, regs []Reg) { for _, r := range regs { a.Printf("\tMOVW.W %d(%s), %s\n", -a.Arch.WordBytes, p, r) } } func armStoreIncN(a *Asm, p RegPtr, regs []Reg) { for _, r := range regs { a.Printf("\tMOVW.P %s, %d(%s)\n", r, a.Arch.WordBytes, p) } } func armStoreDecN(a *Asm, p RegPtr, regs []Reg) { for _, r := range regs { a.Printf("\tMOVW.W %s, %d(%s)\n", r, -a.Arch.WordBytes, p) } }