From be5d8384812d906e851d6ab51bfda2feb7147ec0 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 16 May 2018 19:45:57 -0400 Subject: [PATCH] [Arm64] Add basic ARMv8.1 Atomics Add cas*, ldadd*, stadd*, and swp* Add atomic emitters Add atomic emitter tests --- src/jit/codegenarm64.cpp | 65 ++++++++++++++++++++++++ src/jit/emitarm64.cpp | 96 +++++++++++++++++++++++++++++++++++- src/jit/emitfmtsarm64.h | 1 + src/jit/instrsarm64.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 287 insertions(+), 1 deletion(-) diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp index 94277d6..ce3ce94 100644 --- a/src/jit/codegenarm64.cpp +++ b/src/jit/codegenarm64.cpp @@ -6240,6 +6240,71 @@ void CodeGen::genArm64EmitterUnitTests() #ifdef ALL_ARM64_EMITTER_UNIT_TESTS // + // ARMv8.1 LSE Atomics + // + genDefineTempLabel(genCreateTempLabel()); + + theEmitter->emitIns_R_R_R(INS_casb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casab, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casalb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_caslb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_cash, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casah, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casalh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_caslh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_cas, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casa, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casal, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casl, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_cas, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casa, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casal, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_casl, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddab, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddalb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddlb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddah, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddalh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddlh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldadd, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldadda, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddal, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddl, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldadd, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldadda, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddal, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_ldaddl, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpab, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpalb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swplb, EA_1BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swph, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpah, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpalh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swplh, EA_2BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swp, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpa, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpal, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpl, EA_4BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swp, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpa, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpal, EA_8BYTE, REG_R8, REG_R9, REG_R10); + theEmitter->emitIns_R_R_R(INS_swpl, EA_8BYTE, REG_R8, REG_R9, REG_R10); + + theEmitter->emitIns_R_R(INS_staddb, EA_1BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_staddlb, EA_1BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_staddh, EA_2BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_staddlh, EA_2BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_stadd, EA_4BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_staddl, EA_4BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_stadd, EA_8BYTE, REG_R8, REG_R10); + theEmitter->emitIns_R_R(INS_staddl, EA_8BYTE, REG_R8, REG_R10); +#endif // ALL_ARM64_EMITTER_UNIT_TESTS + +#ifdef ALL_ARM64_EMITTER_UNIT_TESTS + // // R_R_I_I // diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp index dfca2cd..36e7719 100644 --- a/src/jit/emitarm64.cpp +++ b/src/jit/emitarm64.cpp @@ -278,6 +278,15 @@ void emitter::emitInsSanityCheck(instrDesc* id) assert(insOptsNone(id->idInsOpt())); break; + case IF_LS_3E: // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics + assert(isIntegerRegister(id->idReg1())); + assert(isIntegerRegister(id->idReg2())); + assert(isIntegerRegister(id->idReg3())); + assert(emitGetInsSC(id) == 0); + assert(!id->idIsLclVar()); + assert(insOptsNone(id->idInsOpt())); + break; + case IF_DI_1A: // DI_1A X.......shiiiiii iiiiiinnnnn..... Rn imm(i12,sh) assert(isValidGeneralDatasize(id->idOpSize())); assert(isGeneralRegister(id->idReg1())); @@ -883,6 +892,12 @@ bool emitter::emitInsMayWriteToGCReg(instrDesc* id) return true; } + case IF_LS_3E: // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics + // ARMv8.1 Atomics + assert(emitInsIsStore(ins)); + assert(emitInsIsLoad(ins)); + return true; + default: return false; } @@ -1950,6 +1965,7 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt) case IF_LS_3B: case IF_LS_3C: case IF_LS_3D: + case IF_LS_3E: case IF_DI_1A: case IF_DI_1B: case IF_DI_1C: @@ -4053,6 +4069,25 @@ void emitter::emitIns_R_R( emitIns_R_R_I(ins, attr, reg1, reg2, 0, INS_OPTS_NONE); return; + case INS_staddb: + emitIns_R_R_R(INS_ldaddb, attr, reg1, REG_ZR, reg2); + return; + case INS_staddlb: + emitIns_R_R_R(INS_ldaddlb, attr, reg1, REG_ZR, reg2); + return; + case INS_staddh: + emitIns_R_R_R(INS_ldaddh, attr, reg1, REG_ZR, reg2); + return; + case INS_staddlh: + emitIns_R_R_R(INS_ldaddlh, attr, reg1, REG_ZR, reg2); + return; + case INS_stadd: + emitIns_R_R_R(INS_ldadd, attr, reg1, REG_ZR, reg2); + return; + case INS_staddl: + emitIns_R_R_R(INS_ldaddl, attr, reg1, REG_ZR, reg2); + return; + case INS_fmov: assert(isValidVectorElemsizeFloat(size)); @@ -5388,6 +5423,48 @@ void emitter::emitIns_R_R_R( fmt = IF_LS_3D; break; + case INS_casb: + case INS_casab: + case INS_casalb: + case INS_caslb: + case INS_cash: + case INS_casah: + case INS_casalh: + case INS_caslh: + case INS_cas: + case INS_casa: + case INS_casal: + case INS_casl: + case INS_ldaddb: + case INS_ldaddab: + case INS_ldaddalb: + case INS_ldaddlb: + case INS_ldaddh: + case INS_ldaddah: + case INS_ldaddalh: + case INS_ldaddlh: + case INS_ldadd: + case INS_ldadda: + case INS_ldaddal: + case INS_ldaddl: + case INS_swpb: + case INS_swpab: + case INS_swpalb: + case INS_swplb: + case INS_swph: + case INS_swpah: + case INS_swpalh: + case INS_swplh: + case INS_swp: + case INS_swpa: + case INS_swpal: + case INS_swpl: + assert(isGeneralRegisterOrZR(reg1)); + assert(isGeneralRegisterOrZR(reg2)); + assert(isGeneralRegisterOrSP(reg3)); + fmt = IF_LS_3E; + break; + case INS_sha256h: case INS_sha256h2: case INS_sha256su1: @@ -7789,8 +7866,9 @@ void emitter::emitIns_Call(EmitCallType callType, /*static*/ emitter::code_t emitter::insEncodeDatasizeLS(emitter::code_t code, emitAttr size) { bool exclusive = ((code & 0x35000000) == 0); + bool atomic = ((code & 0x31200C00) == 0x30200000); - if ((code & 0x00800000) && !exclusive) // Is this a sign-extending opcode? (i.e. ldrsw, ldrsh, ldrsb) + if ((code & 0x00800000) && !exclusive && !atomic) // Is this a sign-extending opcode? (i.e. ldrsw, ldrsh, ldrsb) { if ((code & 0x80000000) == 0) // Is it a ldrsh or ldrsb and not ldrsw ? { @@ -9283,6 +9361,15 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutput_Instr(dst, code); break; + case IF_LS_3E: // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics + code = emitInsCode(ins, fmt); + code |= insEncodeDatasizeLS(code, id->idOpSize()); // X + code |= insEncodeReg_Rm(id->idReg1()); // mmmmm + code |= insEncodeReg_Rt(id->idReg2()); // ttttt + code |= insEncodeReg_Rn(id->idReg3()); // nnnnn + dst += emitOutput_Instr(dst, code); + break; + case IF_DI_1A: // DI_1A X.......shiiiiii iiiiiinnnnn..... Rn imm(i12,sh) assert(insOptsNone(id->idInsOpt()) || insOptsLSL12(id->idInsOpt())); imm = emitGetInsSC(id); @@ -10985,6 +11072,13 @@ void emitter::emitDispIns( emitDispAddrRI(id->idReg3(), id->idInsOpt(), 0); break; + case IF_LS_3E: // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics + assert(insOptsNone(id->idInsOpt())); + emitDispReg(id->idReg1(), emitInsTargetRegSize(id), true); + emitDispReg(id->idReg2(), emitInsTargetRegSize(id), true); + emitDispAddrRI(id->idReg3(), id->idInsOpt(), 0); + break; + case IF_DI_1A: // DI_1A X.......shiiiiii iiiiiinnnnn..... Rn imm(i12,sh) emitDispReg(id->idReg1(), size, true); emitDispImmOptsLSL12(emitGetInsSC(id), id->idInsOpt()); diff --git a/src/jit/emitfmtsarm64.h b/src/jit/emitfmtsarm64.h index 891f5b3..dad4bdb 100644 --- a/src/jit/emitfmtsarm64.h +++ b/src/jit/emitfmtsarm64.h @@ -135,6 +135,7 @@ IF_DEF(LS_3A, IS_NONE, NONE) // LS_3A .X.......X.mmmmm xxxS..nnnnnttttt R IF_DEF(LS_3B, IS_NONE, NONE) // LS_3B X............... .aaaaannnnnddddd Rd Ra Rn IF_DEF(LS_3C, IS_NONE, NONE) // LS_3C X.........iiiiii iaaaaannnnnddddd Rd Ra Rn imm(im7,sh) IF_DEF(LS_3D, IS_NONE, NONE) // LS_3D .X.......X.mmmmm ......nnnnnttttt Wm Rt Rn +IF_DEF(LS_3E, IS_NONE, NONE) // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics IF_DEF(DI_1A, IS_NONE, NONE) // DI_1A X.......shiiiiii iiiiiinnnnn..... Rn imm(i12,sh) IF_DEF(DI_1B, IS_NONE, NONE) // DI_1B X........hwiiiii iiiiiiiiiiiddddd Rd imm(i16,hw) diff --git a/src/jit/instrsarm64.h b/src/jit/instrsarm64.h index 8f5971b..c537c4f 100644 --- a/src/jit/instrsarm64.h +++ b/src/jit/instrsarm64.h @@ -708,6 +708,132 @@ INST1(sturb, "sturb", 0,ST, IF_LS_2C, 0x38000000) INST1(sturh, "sturh", 0,ST, IF_LS_2C, 0x78000000) // sturh Rt,[Xn+simm9] LS_2C 01111000000iiiii iiii00nnnnnttttt 7800 0000 [Xn imm(-256..+255)] +INST1(casb, "casb", 0, LD|ST, IF_LS_3E, 0x08A07C00) + // casb Wm, Wt, [Xn] LS_3E 00001000101mmmmm 011111nnnnnttttt 08A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casab, "casab", 0, LD|ST, IF_LS_3E, 0x08E07C00) + // casab Wm, Wt, [Xn] LS_3E 00001000111mmmmm 011111nnnnnttttt 08E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casalb, "casalb", 0, LD|ST, IF_LS_3E, 0x08E0FC00) + // casalb Wm, Wt, [Xn] LS_3E 00001000111mmmmm 111111nnnnnttttt 08E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(caslb, "caslb", 0, LD|ST, IF_LS_3E, 0x08A0FC00) + // caslb Wm, Wt, [Xn] LS_3E 00001000101mmmmm 111111nnnnnttttt 08A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(cash, "cash", 0, LD|ST, IF_LS_3E, 0x48A07C00) + // cash Wm, Wt, [Xn] LS_3E 01001000101mmmmm 011111nnnnnttttt 48A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casah, "casah", 0, LD|ST, IF_LS_3E, 0x48E07C00) + // casah Wm, Wt, [Xn] LS_3E 01001000111mmmmm 011111nnnnnttttt 48E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casalh, "casalh", 0, LD|ST, IF_LS_3E, 0x48E0FC00) + // casalh Wm, Wt, [Xn] LS_3E 01001000111mmmmm 111111nnnnnttttt 48E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(caslh, "caslh", 0, LD|ST, IF_LS_3E, 0x48A0FC00) + // caslh Wm, Wt, [Xn] LS_3E 01001000101mmmmm 111111nnnnnttttt 48A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(cas, "cas", 0, LD|ST, IF_LS_3E, 0x88A07C00) + // cas Rm, Rt, [Xn] LS_3E 1X001000101mmmmm 011111nnnnnttttt 88A0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casa, "casa", 0, LD|ST, IF_LS_3E, 0x88E07C00) + // casa Rm, Rt, [Xn] LS_3E 1X001000111mmmmm 011111nnnnnttttt 88E0 7C00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casal, "casal", 0, LD|ST, IF_LS_3E, 0x88E0FC00) + // casal Rm, Rt, [Xn] LS_3E 1X001000111mmmmm 111111nnnnnttttt 88E0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(casl, "casl", 0, LD|ST, IF_LS_3E, 0x88A0FC00) + // casl Rm, Rt, [Xn] LS_3E 1X001000101mmmmm 111111nnnnnttttt 88A0 FC00 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddb, "ldaddb", 0, LD|ST, IF_LS_3E, 0x38200000) + // ldaddb Wm, Wt, [Xn] LS_3E 00111000001mmmmm 000000nnnnnttttt 3820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddab, "ldaddab", 0, LD|ST, IF_LS_3E, 0x38A00000) + // ldaddab Wm, Wt, [Xn] LS_3E 00111000101mmmmm 000000nnnnnttttt 38A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddalb,"ldaddalb",0, LD|ST, IF_LS_3E, 0x38E00000) + // ldaddalb Wm, Wt, [Xn] LS_3E 00111000111mmmmm 000000nnnnnttttt 38E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddlb, "ldaddlb", 0, LD|ST, IF_LS_3E, 0x38600000) + // ldaddlb Wm, Wt, [Xn] LS_3E 00111000011mmmmm 000000nnnnnttttt 3860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddh, "ldaddh", 0, LD|ST, IF_LS_3E, 0x78200000) + // ldaddh Wm, Wt, [Xn] LS_3E 01111000001mmmmm 000000nnnnnttttt 7820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddah, "ldaddah", 0, LD|ST, IF_LS_3E, 0x78A00000) + // ldaddah Wm, Wt, [Xn] LS_3E 01111000101mmmmm 000000nnnnnttttt 78A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddalh,"ldaddalh",0, LD|ST, IF_LS_3E, 0x78E00000) + // ldaddalh Wm, Wt, [Xn] LS_3E 01111000111mmmmm 000000nnnnnttttt 78E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddlh, "ldaddlh", 0, LD|ST, IF_LS_3E, 0x78600000) + // ldaddlh Wm, Wt, [Xn] LS_3E 01111000011mmmmm 000000nnnnnttttt 7860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldadd, "ldadd", 0, LD|ST, IF_LS_3E, 0xB8200000) + // ldadd Rm, Rt, [Xn] LS_3E 1X111000001mmmmm 000000nnnnnttttt B820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldadda, "ldadda", 0, LD|ST, IF_LS_3E, 0xB8A00000) + // ldadda Rm, Rt, [Xn] LS_3E 1X111000101mmmmm 000000nnnnnttttt B8A0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddal, "ldaddal", 0, LD|ST, IF_LS_3E, 0xB8E00000) + // ldaddal Rm, Rt, [Xn] LS_3E 1X111000111mmmmm 000000nnnnnttttt B8E0 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(ldaddl, "ldaddl", 0, LD|ST, IF_LS_3E, 0xB8600000) + // ldaddl Rm, Rt, [Xn] LS_3E 1X111000011mmmmm 000000nnnnnttttt B860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(staddb, "staddb", 0, ST, IF_LS_3E, 0x38200000) + // staddb Wm, [Xn] LS_3E 00111000001mmmmm 000000nnnnnttttt 3820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(staddlb, "staddlb", 0, ST, IF_LS_3E, 0x38600000) + // staddlb Wm, [Xn] LS_3E 00111000011mmmmm 000000nnnnnttttt 3860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(staddh, "staddh", 0, ST, IF_LS_3E, 0x78200000) + // staddh Wm, [Xn] LS_3E 01111000001mmmmm 000000nnnnnttttt 7820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(staddlh, "staddlh", 0, ST, IF_LS_3E, 0x78600000) + // staddlh Wm, [Xn] LS_3E 01111000011mmmmm 000000nnnnnttttt 7860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(stadd, "stadd", 0, ST, IF_LS_3E, 0xB8200000) + // stadd Rm, [Xn] LS_3E 1X111000001mmmmm 000000nnnnnttttt B820 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(staddl, "staddl", 0, ST, IF_LS_3E, 0xB8600000) + // staddl Rm, [Xn] LS_3E 1X111000011mmmmm 000000nnnnnttttt B860 0000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpb, "swpb", 0, LD|ST, IF_LS_3E, 0x38208000) + // swpb Wm, Wt, [Xn] LS_3E 00111000001mmmmm 100000nnnnnttttt 3820 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpab, "swpab", 0, LD|ST, IF_LS_3E, 0x38A08000) + // swpab Wm, Wt, [Xn] LS_3E 00111000101mmmmm 100000nnnnnttttt 38A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpalb, "swpalb", 0, LD|ST, IF_LS_3E, 0x38E08000) + // swpalb Wm, Wt, [Xn] LS_3E 00111000111mmmmm 100000nnnnnttttt 38E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swplb, "swplb", 0, LD|ST, IF_LS_3E, 0x38608000) + // swplb Wm, Wt, [Xn] LS_3E 00111000011mmmmm 100000nnnnnttttt 3860 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swph, "swph", 0, LD|ST, IF_LS_3E, 0x78208000) + // swph Wm, Wt, [Xn] LS_3E 01111000001mmmmm 100000nnnnnttttt 7820 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpah, "swpah", 0, LD|ST, IF_LS_3E, 0x78A08000) + // swpah Wm, Wt, [Xn] LS_3E 01111000101mmmmm 100000nnnnnttttt 78A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpalh, "swpalh", 0, LD|ST, IF_LS_3E, 0x78E08000) + // swpalh Wm, Wt, [Xn] LS_3E 01111000111mmmmm 100000nnnnnttttt 78E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swplh, "swplh", 0, LD|ST, IF_LS_3E, 0x78608000) + // swplh Wm, Wt, [Xn] LS_3E 01111000011mmmmm 100000nnnnnttttt 7860 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swp, "swp", 0, LD|ST, IF_LS_3E, 0xB8208000) + // swp Rm, Rt, [Xn] LS_3E 1X111000001mmmmm 100000nnnnnttttt B820 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpa, "swpa", 0, LD|ST, IF_LS_3E, 0xB8A08000) + // swpa Rm, Rt, [Xn] LS_3E 1X111000101mmmmm 100000nnnnnttttt B8A0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpal, "swpal", 0, LD|ST, IF_LS_3E, 0xB8E08000) + // swpal Rm, Rt, [Xn] LS_3E 1X111000111mmmmm 100000nnnnnttttt B8E0 8000 Rm Rt Rn ARMv8.1 LSE Atomics + +INST1(swpl, "swpl", 0, LD|ST, IF_LS_3E, 0xB8608000) + // swpl Rm, Rt, [Xn] LS_3E 1X111000011mmmmm 100000nnnnnttttt B860 8000 Rm Rt Rn ARMv8.1 LSE Atomics + INST1(adr, "adr", 0, 0, IF_DI_1E, 0x10000000) // adr Rd, simm21 DI_1E 0ii10000iiiiiiii iiiiiiiiiiiddddd 1000 0000 Rd simm21 -- 2.7.4