Source file src/math/big/internal/asmgen/arm64.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package asmgen
     6  
     7  var ArchARM64 = &Arch{
     8  	Name:          "arm64",
     9  	WordBits:      64,
    10  	WordBytes:     8,
    11  	CarrySafeLoop: true,
    12  
    13  	regs: []string{
    14  		// R18 is the platform register.
    15  		// R27 is the assembler/linker temporary (which we could potentially use but don't).
    16  		// R28 is g.
    17  		// R29 is FP.
    18  		// R30 is LR.
    19  		"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9",
    20  		"R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R19",
    21  		"R20", "R21", "R22", "R23", "R24", "R25", "R26",
    22  	},
    23  	reg0: "ZR",
    24  
    25  	mov:   "MOVD",
    26  	add:   "ADD",
    27  	adds:  "ADDS",
    28  	adc:   "ADC",
    29  	adcs:  "ADCS",
    30  	sub:   "SUB",
    31  	subs:  "SUBS",
    32  	sbc:   "SBC",
    33  	sbcs:  "SBCS",
    34  	mul:   "MUL",
    35  	mulhi: "UMULH",
    36  	lsh:   "LSL",
    37  	rsh:   "LSR",
    38  	and:   "AND",
    39  	or:    "ORR",
    40  	xor:   "EOR",
    41  
    42  	addWords: "ADD %[1]s<<3, %[2]s, %[3]s",
    43  
    44  	jmpZero:    "CBZ %s, %s",
    45  	jmpNonZero: "CBNZ %s, %s",
    46  
    47  	loadIncN:  arm64LoadIncN,
    48  	loadDecN:  arm64LoadDecN,
    49  	storeIncN: arm64StoreIncN,
    50  	storeDecN: arm64StoreDecN,
    51  }
    52  
    53  func arm64LoadIncN(a *Asm, p RegPtr, regs []Reg) {
    54  	if len(regs) == 1 {
    55  		a.Printf("\tMOVD.P %d(%s), %s\n", a.Arch.WordBytes, p, regs[0])
    56  		return
    57  	}
    58  	a.Printf("\tLDP.P %d(%s), (%s, %s)\n", len(regs)*a.Arch.WordBytes, p, regs[0], regs[1])
    59  	var i int
    60  	for i = 2; i+2 <= len(regs); i += 2 {
    61  		a.Printf("\tLDP %d(%s), (%s, %s)\n", (i-len(regs))*a.Arch.WordBytes, p, regs[i], regs[i+1])
    62  	}
    63  	if i < len(regs) {
    64  		a.Printf("\tMOVD %d(%s), %s\n", -1*a.Arch.WordBytes, p, regs[i])
    65  	}
    66  }
    67  
    68  func arm64LoadDecN(a *Asm, p RegPtr, regs []Reg) {
    69  	if len(regs) == 1 {
    70  		a.Printf("\tMOVD.W -%d(%s), %s\n", a.Arch.WordBytes, p, regs[0])
    71  		return
    72  	}
    73  	a.Printf("\tLDP.W %d(%s), (%s, %s)\n", -len(regs)*a.Arch.WordBytes, p, regs[len(regs)-1], regs[len(regs)-2])
    74  	var i int
    75  	for i = 2; i+2 <= len(regs); i += 2 {
    76  		a.Printf("\tLDP %d(%s), (%s, %s)\n", i*a.Arch.WordBytes, p, regs[len(regs)-1-i], regs[len(regs)-2-i])
    77  	}
    78  	if i < len(regs) {
    79  		a.Printf("\tMOVD %d(%s), %s\n", i*a.Arch.WordBytes, p, regs[0])
    80  	}
    81  }
    82  
    83  func arm64StoreIncN(a *Asm, p RegPtr, regs []Reg) {
    84  	if len(regs) == 1 {
    85  		a.Printf("\tMOVD.P %s, %d(%s)\n", regs[0], a.Arch.WordBytes, p)
    86  		return
    87  	}
    88  	a.Printf("\tSTP.P (%s, %s), %d(%s)\n", regs[0], regs[1], len(regs)*a.Arch.WordBytes, p)
    89  	var i int
    90  	for i = 2; i+2 <= len(regs); i += 2 {
    91  		a.Printf("\tSTP (%s, %s), %d(%s)\n", regs[i], regs[i+1], (i-len(regs))*a.Arch.WordBytes, p)
    92  	}
    93  	if i < len(regs) {
    94  		a.Printf("\tMOVD %s, %d(%s)\n", regs[i], -1*a.Arch.WordBytes, p)
    95  	}
    96  }
    97  
    98  func arm64StoreDecN(a *Asm, p RegPtr, regs []Reg) {
    99  	if len(regs) == 1 {
   100  		a.Printf("\tMOVD.W %s, -%d(%s)\n", regs[0], a.Arch.WordBytes, p)
   101  		return
   102  	}
   103  	a.Printf("\tSTP.W (%s, %s), %d(%s)\n", regs[len(regs)-1], regs[len(regs)-2], -len(regs)*a.Arch.WordBytes, p)
   104  	var i int
   105  	for i = 2; i+2 <= len(regs); i += 2 {
   106  		a.Printf("\tSTP (%s, %s), %d(%s)\n", regs[len(regs)-1-i], regs[len(regs)-2-i], i*a.Arch.WordBytes, p)
   107  	}
   108  	if i < len(regs) {
   109  		a.Printf("\tMOVD %s, %d(%s)\n", regs[0], i*a.Arch.WordBytes, p)
   110  	}
   111  }
   112  

View as plain text