github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/obj/arm64/doc.go (about) 1 // Copyright 2018 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 /* 6 Package arm64 implements an ARM64 assembler. Go assembly syntax is different from GNU ARM64 7 syntax, but we can still follow the general rules to map between them. 8 9 Instructions mnemonics mapping rules 10 11 1. Most instructions use width suffixes of instruction names to indicate operand width rather than 12 using different register names. 13 14 Examples: 15 ADC R24, R14, R12 <=> adc x12, x24 16 ADDW R26->24, R21, R15 <=> add w15, w21, w26, asr #24 17 FCMPS F2, F3 <=> fcmp s3, s2 18 FCMPD F2, F3 <=> fcmp d3, d2 19 FCVTDH F2, F3 <=> fcvt h3, d2 20 21 2. Go uses .P and .W suffixes to indicate post-increment and pre-increment. 22 23 Examples: 24 MOVD.P -8(R10), R8 <=> ldr x8, [x10],#-8 25 MOVB.W 16(R16), R10 <=> ldr x10, [x16,#16]! 26 27 3. Go uses a series of MOV instructions as load and store. 28 29 64-bit variant ldr, str, stur => MOVD; 30 32-bit variant str, stur, ldrsw => MOVW; 31 32-bit variant ldr => MOVWU; 32 ldrb => MOVBU; ldrh => MOVHU; 33 ldrsb, sturb, strb => MOVB; 34 ldrsh, sturh, strh => MOVH. 35 36 4. Go moves conditions into opcode suffix, like BLT. 37 38 5. Go adds a V prefix for most floating-point and SIMD instructions, except cryptographic extension 39 instructions and floating-point(scalar) instructions. 40 41 Examples: 42 VADD V5.H8, V18.H8, V9.H8 <=> add v9.8h, v18.8h, v5.8h 43 VLD1.P (R6)(R11), [V31.D1] <=> ld1 {v31.1d}, [x6], x11 44 VFMLA V29.S2, V20.S2, V14.S2 <=> fmla v14.2s, v20.2s, v29.2s 45 AESD V22.B16, V19.B16 <=> aesd v19.16b, v22.16b 46 SCVTFWS R3, F16 <=> scvtf s17, w6 47 48 Special Cases. 49 50 (1) umov is written as VMOV. 51 52 (2) br is renamed JMP, blr is renamed CALL. 53 54 (3) No need to add "W" suffix: LDARB, LDARH, LDAXRB, LDAXRH, LDTRH, LDXRB, LDXRH. 55 56 (4) In Go assembly syntax, NOP is a zero-width pseudo-instruction serves generic purpose, nothing 57 related to real ARM64 instruction. NOOP serves for the hardware nop instruction. NOOP is an alias of 58 HINT $0. 59 60 Examples: 61 VMOV V13.B[1], R20 <=> mov x20, v13.b[1] 62 VMOV V13.H[1], R20 <=> mov w20, v13.h[1] 63 JMP (R3) <=> br x3 64 CALL (R17) <=> blr x17 65 LDAXRB (R19), R16 <=> ldaxrb w16, [x19] 66 NOOP <=> nop 67 68 69 Register mapping rules 70 71 1. All basic register names are written as Rn. 72 73 2. Go uses ZR as the zero register and RSP as the stack pointer. 74 75 3. Bn, Hn, Dn, Sn and Qn instructions are written as Fn in floating-point instructions and as Vn 76 in SIMD instructions. 77 78 79 Argument mapping rules 80 81 1. The operands appear in left-to-right assignment order. 82 83 Go reverses the arguments of most instructions. 84 85 Examples: 86 ADD R11.SXTB<<1, RSP, R25 <=> add x25, sp, w11, sxtb #1 87 VADD V16, V19, V14 <=> add d14, d19, d16 88 89 Special Cases. 90 91 (1) Argument order is the same as in the GNU ARM64 syntax: cbz, cbnz and some store instructions, 92 such as str, stur, strb, sturb, strh, sturh stlr, stlrb. stlrh, st1. 93 94 Examples: 95 MOVD R29, 384(R19) <=> str x29, [x19,#384] 96 MOVB.P R30, 30(R4) <=> strb w30, [x4],#30 97 STLRH R21, (R19) <=> stlrh w21, [x19] 98 99 (2) MADD, MADDW, MSUB, MSUBW, SMADDL, SMSUBL, UMADDL, UMSUBL <Rm>, <Ra>, <Rn>, <Rd> 100 101 Examples: 102 MADD R2, R30, R22, R6 <=> madd x6, x22, x2, x30 103 SMSUBL R10, R3, R17, R27 <=> smsubl x27, w17, w10, x3 104 105 (3) FMADDD, FMADDS, FMSUBD, FMSUBS, FNMADDD, FNMADDS, FNMSUBD, FNMSUBS <Fm>, <Fa>, <Fn>, <Fd> 106 107 Examples: 108 FMADDD F30, F20, F3, F29 <=> fmadd d29, d3, d30, d20 109 FNMSUBS F7, F25, F7, F22 <=> fnmsub s22, s7, s7, s25 110 111 (4) BFI, BFXIL, SBFIZ, SBFX, UBFIZ, UBFX $<lsb>, <Rn>, $<width>, <Rd> 112 113 Examples: 114 BFIW $16, R20, $6, R0 <=> bfi w0, w20, #16, #6 115 UBFIZ $34, R26, $5, R20 <=> ubfiz x20, x26, #34, #5 116 117 (5) FCCMPD, FCCMPS, FCCMPED, FCCMPES <cond>, Fm. Fn, $<nzcv> 118 119 Examples: 120 FCCMPD AL, F8, F26, $0 <=> fccmp d26, d8, #0x0, al 121 FCCMPS VS, F29, F4, $4 <=> fccmp s4, s29, #0x4, vs 122 FCCMPED LE, F20, F5, $13 <=> fccmpe d5, d20, #0xd, le 123 FCCMPES NE, F26, F10, $0 <=> fccmpe s10, s26, #0x0, ne 124 125 (6) CCMN, CCMNW, CCMP, CCMPW <cond>, <Rn>, $<imm>, $<nzcv> 126 127 Examples: 128 CCMP MI, R22, $12, $13 <=> ccmp x22, #0xc, #0xd, mi 129 CCMNW AL, R1, $11, $8 <=> ccmn w1, #0xb, #0x8, al 130 131 (7) CCMN, CCMNW, CCMP, CCMPW <cond>, <Rn>, <Rm>, $<nzcv> 132 133 Examples: 134 CCMN VS, R13, R22, $10 <=> ccmn x13, x22, #0xa, vs 135 CCMPW HS, R19, R14, $11 <=> ccmp w19, w14, #0xb, cs 136 137 (9) CSEL, CSELW, CSNEG, CSNEGW, CSINC, CSINCW <cond>, <Rn>, <Rm>, <Rd> ; 138 FCSELD, FCSELS <cond>, <Fn>, <Fm>, <Fd> 139 140 Examples: 141 CSEL GT, R0, R19, R1 <=> csel x1, x0, x19, gt 142 CSNEGW GT, R7, R17, R8 <=> csneg w8, w7, w17, gt 143 FCSELD EQ, F15, F18, F16 <=> fcsel d16, d15, d18, eq 144 145 (10) TBNZ, TBZ $<imm>, <Rt>, <label> 146 147 148 (11) STLXR, STLXRW, STXR, STXRW, STLXRB, STLXRH, STXRB, STXRH <Rf>, (<Rn|RSP>), <Rs> 149 150 Examples: 151 STLXR ZR, (R15), R16 <=> stlxr w16, xzr, [x15] 152 STXRB R9, (R21), R19 <=> stxrb w19, w9, [x21] 153 154 (12) STLXP, STLXPW, STXP, STXPW (<Rf1>, <Rf2>), (<Rn|RSP>), <Rs> 155 156 Examples: 157 STLXP (R17, R19), (R4), R5 <=> stlxp w5, x17, x19, [x4] 158 STXPW (R30, R25), (R22), R13 <=> stxp w13, w30, w25, [x22] 159 160 2. Expressions for special arguments. 161 162 #<immediate> is written as $<immediate>. 163 164 Optionally-shifted immediate. 165 166 Examples: 167 ADD $(3151<<12), R14, R20 <=> add x20, x14, #0xc4f, lsl #12 168 ADDW $1864, R25, R6 <=> add w6, w25, #0x748 169 170 Optionally-shifted registers are written as <Rm>{<shift><amount>}. 171 The <shift> can be <<(lsl), >>(lsr), ->(asr), @>(ror). 172 173 Examples: 174 ADD R19>>30, R10, R24 <=> add x24, x10, x19, lsr #30 175 ADDW R26->24, R21, R15 <=> add w15, w21, w26, asr #24 176 177 Extended registers are written as <Rm>{.<extend>{<<<amount>}}. 178 <extend> can be UXTB, UXTH, UXTW, UXTX, SXTB, SXTH, SXTW or SXTX. 179 180 Examples: 181 ADDS R19.UXTB<<4, R9, R26 <=> adds x26, x9, w19, uxtb #4 182 ADDSW R14.SXTX, R14, R6 <=> adds w6, w14, w14, sxtx 183 184 Memory references: [<Xn|SP>{,#0}] is written as (Rn|RSP), a base register and an immediate 185 offset is written as imm(Rn|RSP), a base register and an offset register is written as (Rn|RSP)(Rm). 186 187 Examples: 188 LDAR (R22), R9 <=> ldar x9, [x22] 189 LDP 28(R17), (R15, R23) <=> ldp x15, x23, [x17,#28] 190 MOVWU (R4)(R12<<2), R8 <=> ldr w8, [x4, x12, lsl #2] 191 MOVD (R7)(R11.UXTW<<3), R25 <=> ldr x25, [x7,w11,uxtw #3] 192 MOVBU (R27)(R23), R14 <=> ldrb w14, [x27,x23] 193 194 Register pairs are written as (Rt1, Rt2). 195 196 Examples: 197 LDP.P -240(R11), (R12, R26) <=> ldp x12, x26, [x11],#-240 198 199 Register with arrangement and register with arrangement and index. 200 201 Examples: 202 VADD V5.H8, V18.H8, V9.H8 <=> add v9.8h, v18.8h, v5.8h 203 VLD1 (R2), [V21.B16] <=> ld1 {v21.16b}, [x2] 204 VST1.P V9.S[1], (R16)(R21) <=> st1 {v9.s}[1], [x16], x28 205 VST1.P [V13.H8, V14.H8, V15.H8], (R3)(R14) <=> st1 {v13.8h-v15.8h}, [x3], x14 206 VST1.P [V14.D1, V15.D1], (R7)(R23) <=> st1 {v14.1d, v15.1d}, [x7], x23 207 */ 208 package arm64