func IsARM64STLXR(op obj.As) bool {
switch op {
case arm64.ASTLXRB, arm64.ASTLXRH, arm64.ASTLXRW, arm64.ASTLXR,
- arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR:
+ arm64.ASTXRB, arm64.ASTXRH, arm64.ASTXRW, arm64.ASTXR,
+ arm64.ASTXP, arm64.ASTXPW, arm64.ASTLXP, arm64.ASTLXPW:
return true
}
return false
// {
// outcode($1, &$2, &$4, &$6);
// }
- LDAXRW (R0), R2
- STLXRW R1, (R0), R3
+ LDARB (R25), R2 // 22ffdf08
+ LDARH (R5), R7 // a7fcdf48
+ LDAXPW (R10), (R20, R16) // 54c17f88
+ LDAXP (R25), (R30, R11) // 3eaf7fc8
+ LDAXRW (R0), R2 // 02fc5f88
+ LDXPW (R24), (R23, R11) // 172f7f88
+ LDXP (R0), (R16, R13) // 10347fc8
+ STLRB R11, (R22) // cbfe9f08
+ STLRH R16, (R23) // f0fe9f48
+ STLXP (R6, R3), (R10), R2 // 468d22c8
+ STLXPW (R6, R11), (R22), R21 // c6ae3588
+ STLXRW R1, (R0), R3 // 01fc0388
+ STXP (R1, R2), (R3), R10 // 61082ac8
+ STXP (R1, R2), (RSP), R10 // e10b2ac8
+ STXPW (R1, R2), (R3), R10 // 61082a88
+ STXPW (R1, R2), (RSP), R10 // e10b2a88
// RET
//
LDARW (R30), R22 // d6ffdf88
LDARW (RSP), R22 // f6ffdf88
LDAR (R27), R22 // 76ffdfc8
- //TODO LDARB (R25), R2 // 22ffdf08
- //TODO LDARH (R5), R7 // a7fcdf48
- //TODO LDAXPW (R10), R16, R20 // 54c17f88
- //TODO LDAXP (R25), R11, R30 // 3eaf7fc8
+ LDARB (R25), R2 // 22ffdf08
+ LDARH (R5), R7 // a7fcdf48
+ //TODO LDAXPW (R10), (R20, R16) // 54c17f88
+ //TODO LDAXP (R25), (R30, R11) // 3eaf7fc8
LDAXRW (R15), R2 // e2fd5f88
LDAXR (R15), R21 // f5fd5fc8
LDAXRB (R19), R16 // 70fe5f08
//TODO LDURSH -0x49(R11), R28 // 7c71db78
//TODO LDURSH -0x1f(R0), R29 // 1d109e78
//TODO LDURSW 0x48(R6), R20 // d48084b8
- LDXPW (R24), R11, R23 // 172f7f88
- LDXP (R0), R13, R16 // 10347fc8
+ //TODO LDXPW (R24), (R23, R11) // 172f7f88
+ //TODO LDXP (R0), (R16, R13) // 10347fc8
LDXRW (RSP), R30 // fe7f5f88
LDXR (R27), R12 // 6c7f5fc8
LDXRB (R0), R4 // 047c5f08
STLXRW R13, (R15), R14 // edfd0e88
STLXRB R24, (R23), R8 // f8fe0808
STLXRH R19, (R27), R11 // 73ff0b48
- //TODO STLXPW (R22), R11, R6, R21 // c6ae3588
- //TODO STLXP (R22), LR, R6, R2 // c6fa22c8
+ //TODO STLXP (R6, R3), (R10), R2 // 468d22c8
+ //TODO STLXPW (R6, R11), (R22), R21 // c6ae3588
//TODO STNPW 44(R1), R3, R10 // 2a8c0528
//TODO STNP 0x108(R3), ZR, R7 // 67fc10a8
LDP.P -384(R3), (R22, R26) // 7668e8a8
//TODO STTR 124(R5), R25 // b9c807f8
//TODO STTRB -28(R23), R16 // f04a1e38
//TODO STTRH 9(R10), R18 // 52990078
- //TODO STXP (R20), R18, R5, ZR // 854a3f88
- //TODO STXP (R22), R9, R17, R0 // d12620c8
+ //TODO STXP (R1, R2), (R3), R10 // 61082ac8
+ //TODO STXP (R1, R2), (RSP), R10 // e10b2ac8
+ //TODO STXPW (R1, R2), (R3), R10 // 61082a88
+ //TODO STXPW (R1, R2), (RSP), R10 // e10b2a88
STXRW R2, (R19), R18 // 627e1288
STXR R15, (R21), R13 // af7e0dc8
STXRB R7, (R9), R24 // 277d1808
{ALDAR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
{ALDXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
{ALDAXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
- {ALDXP, C_ZOREG, C_REG, C_REG, 58, 4, 0, 0, 0},
+ {ALDXP, C_ZOREG, C_NONE, C_PAIR, 58, 4, 0, 0, 0},
{ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_NONE
{ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
{ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
-
- // { ASTXP, C_REG, C_NONE, C_ZOREG, 59, 4, 0 , 0}, // TODO(aram):
-
+ {ASTXP, C_PAIR, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},
{AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0}, // for compatibility with old code
{AAESD, C_ARNG, C_NONE, C_ARNG, 29, 4, 0, 0, 0}, // recommend using the new one for better readability
{ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0},
case ALDAR:
oprangeset(ALDARW, t)
+ oprangeset(ALDARB, t)
+ oprangeset(ALDARH, t)
fallthrough
case ALDXR:
case ALDXP:
oprangeset(ALDXPW, t)
+ oprangeset(ALDAXP, t)
+ oprangeset(ALDAXPW, t)
case ASTLR:
+ oprangeset(ASTLRB, t)
+ oprangeset(ASTLRH, t)
oprangeset(ASTLRW, t)
case ASTXR:
oprangeset(ASTLXRW, t)
case ASTXP:
+ oprangeset(ASTLXP, t)
+ oprangeset(ASTLXPW, t)
oprangeset(ASTXPW, t)
case AVADDP:
rt := int(p.GetFrom3().Reg)
o1 |= uint32(rf&31)<<16 | uint32(cond&15)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
- case 58: /* ldar/ldxr/ldaxr */
+ case 58: /* ldar/ldarb/ldarh/ldaxp/ldxp/ldaxr/ldxr */
o1 = c.opload(p, p.As)
o1 |= 0x1F << 16
o1 |= uint32(p.From.Reg&31) << 5
- if p.Reg != 0 {
- o1 |= uint32(p.Reg&31) << 10
+ if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW {
+ o1 |= uint32(p.To.Offset&31) << 10
} else {
o1 |= 0x1F << 10
}
o1 |= uint32(p.To.Reg & 31)
- case 59: /* stxr/stlxr */
+ case 59: /* stxr/stlxr/stxp/stlxp */
o1 = c.opstore(p, p.As)
if p.RegTo2 != obj.REG_NONE {
} else {
o1 |= 0x1F << 16
}
-
- // TODO(aram): add support for STXP
- o1 |= uint32(p.To.Reg&31) << 5
-
- o1 |= uint32(p.From.Reg & 31)
+ if p.As == ASTXP || p.As == ASTXPW || p.As == ASTLXP || p.As == ASTLXPW {
+ o1 |= uint32(p.From.Offset&31) << 10
+ }
+ o1 |= uint32(p.To.Reg&31) << 5 | uint32(p.From.Reg & 31)
case 60: /* adrp label,r */
d := c.brdist(p, 12, 21, 0)
return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10
case ASTLXP:
- return LDSTX(2, 0, 0, 1, 1)
+ return LDSTX(3, 0, 0, 1, 1)
case ASTLXPW:
- return LDSTX(3, 0, 0, 1, 1)
+ return LDSTX(2, 0, 0, 1, 1)
case ASTLXR:
return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10
PRFM imm(Rn), $imm
$imm prefetch operation is encoded as an immediate.
+ LDARB: Load-Acquire Register Byte
+ LDARB (<Rn>), <Rd>
+ Loads a byte from memory, zero-extends it and writes it to Rd.
+
+ LDARH: Load-Acquire Register Halfword
+ LDARH (<Rn>), <Rd>
+ Loads a halfword from memory, zero-extends it and writes it to Rd.
+
+ LDAXP: Load-Acquire Exclusive Pair of Registers
+ LDAXP (<Rn>), (<Rt1>, <Rt2>)
+ Loads two 64-bit doublewords from memory, and writes them to Rt1 and Rt2.
+
+ LDAXPW: Load-Acquire Exclusive Pair of Registers
+ LDAXPW (<Rn>), (<Rt1>, <Rt2>)
+ Loads two 32-bit words from memory, and writes them to Rt1 and Rt2.
+
+ LDXP: 64-bit Load Exclusive Pair of Registers
+ LDXP (<Rn>), (<Rt1>, <Rt2>)
+ Loads two 64-bit doublewords from memory, and writes them to Rt1 and Rt2.
+
+ LDXPW: 32-bit Load Exclusive Pair of Registers
+ LDXPW (<Rn>), (<Rt1>, <Rt2>)
+ Loads two 32-bit words from memory, and writes them to Rt1 and Rt2.
+
+ STLRB: Store-Release Register Byte
+ STLRB <Rd>, (<Rn>)
+ Stores a byte from Rd to a memory location from Rn.
+
+ STLRH: Store-Release Register Halfword
+ STLRH <Rd>, (<Rn>)
+ Stores a halfword from Rd to a memory location from Rn.
+
+ STLXP: 64-bit Store-Release Exclusive Pair of registers
+ STLXP (<Rt1>, <Rt2>), (<Rn>), <Rs>
+ Stores two 64-bit doublewords from Rt1 and Rt2 to a memory location from Rn,
+ and returns in Rs a status value of 0 if the store was successful, or of 1 if
+ no store was performed.
+
+ STLXPW: 32-bit Store-Release Exclusive Pair of registers
+ STLXPW (<Rt1>, <Rt2>), (<Rn>), <Rs>
+ Stores two 32-bit words from Rt1 and Rt2 to a memory location from Rn, and
+ returns in Rs a status value of 0 if the store was successful, or of 1 if no
+ store was performed.
+
+ STXP: 64-bit Store Exclusive Pair of registers
+ STXP (<Rt1>, <Rt2>), (<Rn>), <Rs>
+ Stores two 64-bit doublewords from Rt1 and Rt2 to a memory location from Rn,
+ and returns in Rs a status value of 0 if the store was successful, or of 1 if
+ no store was performed.
+
+ STXPW: 32-bit Store Exclusive Pair of registers
+ STXPW (<Rt1>, <Rt2>), (<Rn>), <Rs>
+ Stores two 32-bit words from Rt1 and Rt2 to a memory location from Rn, and returns in
+ a Rs a status value of 0 if the store was successful, or of 1 if no store was performed.
+
2. Alphabetical list of float-point instructions
// TODO
VADD: Add (vector).
VADD <Vm>.T, <Vn>.<T>, <Vd>.<T>
<T> Is an arrangement specifier and can have the following values:
- 8B, 16B, H4, H8, S2, S4, D2
+ B8, B16, H4, H8, S2, S4, D2
VADDP: Add Pairwise (vector)
VADDP <Vm>.<T>, <Vn>.<T>, <Vd>.<T>