/* * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2015, Linaro Ltd. All rights reserved. * reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE * HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #include #include #include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" #include "compiler/disassembler.hpp" #include "interpreter/interpreter.hpp" #include "memory/resourceArea.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/sharedRuntime.hpp" #include "register_aarch32.hpp" #include "vm_version_aarch32.hpp" extern "C" void entry(CodeBuffer *cb); #define __ _masm. #ifdef PRODUCT #define BLOCK_COMMENT(str) /* nothing */ #else #define BLOCK_COMMENT(str) block_comment(str) #endif #define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":") void entry(CodeBuffer *cb) { // { // for (int i = 0; i < 256; i+=16) // { // printf("\"%20.20g\", ", unpack(i)); // printf("\"%20.20g\", ", unpack(i+1)); // } // printf("\n"); // } #ifdef ASSERT Assembler _masm(cb); address entry = __ pc(); // Smoke test for assembler // we're checking the code generation, not applicability of the code to the actual target // so temporarily override the detected cpu to allow emission of all instructions const ProcessorFeatures detected_features = VM_Version::features(); VM_Version::features(FT_ALL); // BEGIN Generated code -- do not edit // Generated by aarch32-asmtest.py Label back, forth, near, near_post, near_flt, near_post_flt; __ bind(back); // ThreeRegSft __ add(r8, r2, r11, ::lsr(10)); // add r8, r2, r11, lsr #10 __ adds(r1, r3, r7, ::asr(1), Assembler::EQ); // addEQs r1, r3, r7, asr #1 __ eor(r0, r9, r4, ::lsl(5)); // eor r0, r9, r4, lsl #5 __ eors(r9, r2, r6, ::rrx(), Assembler::GT); // eorGTs r9, r2, r6, rrx __ sub(r0, r12, lr, ::lsr(0), Assembler::GT); // subGT r0, r12, lr, lsr #0 __ subs(r8, r2, r4, ::ror(6), Assembler::EQ); // subEQs r8, r2, r4, ror #6 __ rsb(r8, r9, sp, ::lsl(3)); // rsb r8, r9, sp, lsl #3 __ rsbs(r8, r0, r4, ::ror(16), Assembler::VS); // rsbVSs r8, r0, r4, ror #16 __ add(r9, r5, r1, ::lsr(15), Assembler::LE); // addLE r9, r5, r1, lsr #15 __ adds(r1, sp, r6, ::asr(5)); // adds r1, sp, r6, asr #5 __ adc(r11, sp, r7, ::asr(1), Assembler::GT); // adcGT r11, sp, r7, asr #1 __ adcs(r0, r8, r9, ::lsr(6)); // adcs r0, r8, r9, lsr #6 __ sbc(r9, r3, r6, ::ror(5)); // sbc r9, r3, r6, ror #5 __ sbcs(r1, sp, r5, ::asr(16), Assembler::HI); // sbcHIs r1, sp, r5, asr #16 __ rsc(r8, r2, r6, ::lsl(9), Assembler::CC); // rscCC r8, r2, r6, lsl #9 __ rscs(r10, r4, sp, ::ror(14)); // rscs r10, r4, sp, ror #14 __ orr(r11, sp, r5, ::lsl(15), Assembler::NE); // orrNE r11, sp, r5, lsl #15 __ orrs(r9, r10, r4, ::ror(14)); // orrs r9, r10, r4, ror #14 __ bic(r9, sp, r5, ::ror(1)); // bic r9, sp, r5, ror #1 __ bics(r0, r2, r7, ::asr(10)); // bics r0, r2, r7, asr #10 // ThreeRegRSR __ add(sp, r6, r7, ::ror(r7)); // add sp, r6, r7, ror r7 __ adds(r4, r12, r6, ::ror(r7), Assembler::HI); // addHIs r4, r12, r6, ror r7 __ eor(r5, r6, r7, ::asr(r12), Assembler::LS); // eorLS r5, r6, r7, asr r12 __ eors(r8, r5, sp, ::lsl(r4), Assembler::AL); // eorALs r8, r5, sp, lsl r4 __ sub(r2, r12, r5, ::asr(r0)); // sub r2, r12, r5, asr r0 __ subs(r9, r3, r7, ::lsl(r12), Assembler::HS); // subHSs r9, r3, r7, lsl r12 __ rsb(r9, r12, r4, ::lsl(r6), Assembler::GT); // rsbGT r9, r12, r4, lsl r6 __ rsbs(r8, r2, r12, ::lsl(r1)); // rsbs r8, r2, r12, lsl r1 __ add(r4, r12, sp, ::lsl(sp)); // add r4, r12, sp, lsl sp __ adds(r8, r11, r6, ::ror(sp)); // adds r8, r11, r6, ror sp __ adc(r0, r2, r5, ::lsl(r4), Assembler::NE); // adcNE r0, r2, r5, lsl r4 __ adcs(r11, lr, r6, ::asr(r2)); // adcs r11, lr, r6, asr r2 __ sbc(r8, r10, lr, ::asr(r3), Assembler::HI); // sbcHI r8, r10, lr, asr r3 __ sbcs(r1, r12, r5, ::lsl(r6)); // sbcs r1, r12, r5, lsl r6 __ rsc(r4, r5, lr, ::ror(r10), Assembler::VS); // rscVS r4, r5, lr, ror r10 __ rscs(r1, r12, sp, ::lsl(r8)); // rscs r1, r12, sp, lsl r8 __ orr(r8, r1, r6, ::ror(r0), Assembler::VS); // orrVS r8, r1, r6, ror r0 __ orrs(r11, sp, r7, ::ror(r5)); // orrs r11, sp, r7, ror r5 __ bic(r4, lr, r6, ::lsl(r2), Assembler::AL); // bicAL r4, lr, r6, lsl r2 __ bics(r10, r11, sp, ::lsl(r3)); // bics r10, r11, sp, lsl r3 // TwoRegImm __ add(r8, sp, (unsigned)268435462U, Assembler::HI); // addHI r8, sp, #268435462 __ adds(sp, lr, (unsigned)162529280U); // adds sp, lr, #162529280 __ eor(lr, r6, (unsigned)8192000U); // eor lr, r6, #8192000 __ eors(r2, r3, (unsigned)292U); // eors r2, r3, #292 __ sub(r4, sp, (unsigned)227540992U); // sub r4, sp, #227540992 __ subs(r1, lr, (unsigned)33554432U, Assembler::LT); // subLTs r1, lr, #33554432 __ rsb(r0, r5, (unsigned)2483027968U); // rsb r0, r5, #2483027968 __ rsbs(r8, r4, (unsigned)3080192U, Assembler::LO); // rsbLOs r8, r4, #3080192 __ add(r9, r4, (unsigned)2147483648U, Assembler::LT); // addLT r9, r4, #2147483648 __ adds(r8, r4, (unsigned)32768U, Assembler::AL); // addALs r8, r4, #32768 __ adc(r10, lr, (unsigned)10752U, Assembler::CS); // adcCS r10, lr, #10752 __ adcs(r10, r6, (unsigned)774144U); // adcs r10, r6, #774144 __ sbc(r2, r12, (unsigned)637534208U); // sbc r2, r12, #637534208 __ sbcs(r8, r10, (unsigned)692060160U); // sbcs r8, r10, #692060160 __ rsc(sp, r6, (unsigned)7405568U); // rsc sp, r6, #7405568 __ rscs(r10, r11, (unsigned)244318208U, Assembler::NE); // rscNEs r10, r11, #244318208 __ orr(r3, r7, (unsigned)66846720U, Assembler::VS); // orrVS r3, r7, #66846720 __ orrs(r2, r5, (unsigned)1327104U, Assembler::EQ); // orrEQs r2, r5, #1327104 __ bic(r8, r1, (unsigned)3744U, Assembler::VS); // bicVS r8, r1, #3744 __ bics(r0, r2, (unsigned)2684354560U, Assembler::LO); // bicLOs r0, r2, #2684354560 // TwoRegSft __ tst(r8, sp, ::lsl(5)); // tst r8, sp, lsl #5 __ teq(r6, r7, ::lsr(3)); // teq r6, r7, lsr #3 __ cmp(r12, r4, ::ror(2)); // cmp r12, r4, ror #2 __ cmn(r5, r7, ::lsl(16), Assembler::LT); // cmnLT r5, r7, lsl #16 // TwoRegRSR __ tst(r2, lr, ::lsr(r7)); // tst r2, lr, lsr r7 __ teq(r0, r2, ::ror(r5), Assembler::CC); // teqCC r0, r2, ror r5 __ cmp(lr, r7, ::lsr(r11), Assembler::LS); // cmpLS lr, r7, lsr r11 __ cmn(r10, r7, ::lsl(r11), Assembler::VS); // cmnVS r10, r7, lsl r11 // OneRegImm __ tst(r2, (unsigned)557842432U); // tst r2, #557842432 __ teq(lr, (unsigned)7077888U, Assembler::MI); // teqMI lr, #7077888 __ cmp(r5, (unsigned)939524096U); // cmp r5, #939524096 __ cmn(r7, (unsigned)2147483650U, Assembler::LO); // cmnLO r7, #2147483650 // Shift op __ lsl(r0, r4, (unsigned)23U); // lsl r0, r4, #23 __ lsls(r1, r4, (unsigned)9U); // lsls r1, r4, #9 __ lsr(r0, r10, (unsigned)3U); // lsr r0, r10, #3 __ lsrs(r0, r10, (unsigned)20U); // lsrs r0, r10, #20 __ asr(r1, r9, (unsigned)11U); // asr r1, r9, #11 __ asrs(r2, r11, (unsigned)10U, Assembler::VS); // asrVSs r2, r11, #10 // shift op __ ror(r8, r2, (unsigned)31U, Assembler::CC); // rorCC r8, r2, #31 __ rors(r9, r12, (unsigned)8U); // rors r9, r12, #8 // ThreeRegNon __ ror(r8, lr, r7); // ror r8, lr, r7 __ rors(r12, r3, r4); // rors r12, r3, r4 __ lsl(r12, sp, lr, Assembler::GT); // lslGT r12, sp, lr __ lsls(r12, sp, r6, Assembler::AL); // lslALs r12, sp, r6 __ lsr(r0, r1, r9, Assembler::GT); // lsrGT r0, r1, r9 __ lsrs(r11, r3, r12, Assembler::GT); // lsrGTs r11, r3, r12 __ asr(r2, r12, r6, Assembler::LE); // asrLE r2, r12, r6 __ asrs(r1, r10, r6, Assembler::LT); // asrLTs r1, r10, r6 // TwoRegNon __ mov(r10, r3); // mov r10, r3 __ movs(r0, r9); // movs r0, r9 // OneRegImm __ mov_i(r3, (unsigned)656U, Assembler::VC); // movVC r3, #656 __ movs_i(r4, (unsigned)2064384U); // movs r4, #2064384 // TwoRegSft __ mov(r12, r6, ::lsr(3)); // mov r12, r6, lsr #3 __ movs(r5, sp, ::asr(10), Assembler::VC); // movVCs r5, sp, asr #10 // TwoRegRSR __ mov(r1, lr, ::ror(r3)); // mov r1, lr, ror r3 __ movs(r8, r12, ::ror(r9), Assembler::EQ); // movEQs r8, r12, ror r9 // OneRegImm16 __ movw_i(r11, (unsigned)53041U, Assembler::LO); // movwLO r11, #53041 __ movt_i(r9, (unsigned)11255U, Assembler::LO); // movtLO r9, #11255 // ThreeRegNon __ mul(r1, sp, r5, Assembler::LE); // mulLE r1, sp, r5 __ muls(r0, r10, r11); // muls r0, r10, r11 // FourRegNon __ mla(r0, r3, r12, r7); // mla r0, r3, r12, r7 __ mlas(r8, r11, r3, r6, Assembler::EQ); // mlaEQs r8, r11, r3, r6 __ umull(lr, r4, r5, r6); // umull lr, r4, r5, r6 __ umulls(r0, r4, r6, r7); // umulls r0, r4, r6, r7 __ umlal(r8, r0, r11, lr); // umlal r8, r0, r11, lr __ umlals(r11, r4, lr, r7); // umlals r11, r4, lr, r7 __ smull(r1, r5, r6, r7, Assembler::HS); // smullHS r1, r5, r6, r7 __ smulls(r0, r11, r12, r5, Assembler::MI); // smullMIs r0, r11, r12, r5 // FourRegNon __ umaal(r8, r9, r2, r5); // umaal r8, r9, r2, r5 __ mls(r0, r4, sp, lr, Assembler::EQ); // mlsEQ r0, r4, sp, lr // ThreeRegNon __ qadd(r9, r4, sp, Assembler::PL); // qaddPL r9, r4, sp __ qsub(r0, r12, r5, Assembler::MI); // qsubMI r0, r12, r5 __ qdadd(r3, r5, r7); // qdadd r3, r5, r7 __ qdsub(r9, r2, r4); // qdsub r9, r2, r4 // FourRegNon __ smlabb(r1, r12, r5, r6); // smlabb r1, r12, r5, r6 __ smlabt(r0, r10, r12, r6); // smlabt r0, r10, r12, r6 __ smlatb(r8, r1, r3, lr); // smlatb r8, r1, r3, lr __ smlatt(r1, sp, r6, r7); // smlatt r1, sp, r6, r7 __ smlawb(r0, r3, r4, r6); // smlawb r0, r3, r4, r6 __ smlawt(r11, r4, lr, r7); // smlawt r11, r4, lr, r7 __ smlalbb(r0, r10, r6, r7); // smlalbb r0, r10, r6, r7 __ smlalbt(r3, r11, r4, lr, Assembler::LS); // smlalbtLS r3, r11, r4, lr __ smlaltb(r8, r11, r3, r12); // smlaltb r8, r11, r3, r12 __ smlaltt(r8, r1, r3, r5); // smlaltt r8, r1, r3, r5 // ThreeRegNon __ smulwb(r2, r12, sp, Assembler::HS); // smulwbHS r2, r12, sp __ smulwt(r8, r12, r6); // smulwt r8, r12, r6 __ smulbb(r2, r6, lr, Assembler::GE); // smulbbGE r2, r6, lr __ smulbt(r8, r12, r7); // smulbt r8, r12, r7 __ smultb(r10, r3, lr, Assembler::EQ); // smultbEQ r10, r3, lr __ smultt(r0, r3, sp); // smultt r0, r3, sp // MemoryOp __ ldr(r10, Address(r7, r9, lsl(), Address::ADD, Address::post)); // ldr r10, [r7], r9 __ ldrb(r0, Address(r9, 196)); // ldrb r0, [r9, #196] __ ldrh(lr, Address(r4, r6, lsl(), Address::ADD, Address::pre)); // ldrh lr, [r4, r6]! __ ldrsb(r6, Address(__ pre(r9, 232))); // ldrsb r6, [r9, #232]! __ ldrsh(r2, Address(r1, r1, lsl(), Address::ADD, Address::post)); // ldrsh r2, [r1], r1 __ str(r0, Address(r9, r4, lsl(), Address::ADD, Address::post)); // str r0, [r9], r4 __ strb(r3, Address(__ pre(r5, 92))); // strb r3, [r5, #92]! __ strh(r2, Address(r8, 160)); // strh r2, [r8, #160] // MemoryOp __ ldr(r8, Address(r12, r8, lsl(), Address::ADD, Address::off)); // ldr r8, [r12, r8] __ ldrb(r11, Address(__ post(r10, 16))); // ldrb r11, [r10], #16 __ ldrh(r11, Address(r10, r6, lsl(), Address::ADD, Address::off)); // ldrh r11, [r10, r6] __ ldrsb(r5, Address(r11, r10, lsl(), Address::ADD, Address::pre)); // ldrsb r5, [r11, r10]! __ ldrsh(r6, Address(r3, r7, lsl(), Address::ADD, Address::off)); // ldrsh r6, [r3, r7] __ str(r7, Address(sp, r5, lsl(), Address::ADD, Address::pre)); // str r7, [sp, r5]! __ strb(r2, Address(r10)); // strb r2, [r10] __ strh(r6, Address(r4, r3, lsl(), Address::ADD, Address::post)); // strh r6, [r4], r3 // MemoryOp __ ldr(r10, Address(r12)); // ldr r10, [r12] __ ldrb(r4, Address(__ post(r11, 132))); // ldrb r4, [r11], #132 __ ldrh(r9, Address(r9, r12, lsl(), Address::ADD, Address::post)); // ldrh r9, [r9], r12 __ ldrsb(r9, Address(__ post(r3, 148))); // ldrsb r9, [r3], #148 __ ldrsh(r11, Address(__ pre(r2, 148))); // ldrsh r11, [r2, #148]! __ str(r11, Address(sp, r11, lsl(), Address::ADD, Address::off)); // str r11, [sp, r11] __ strb(r1, Address(sp, r10, lsl(), Address::ADD, Address::off)); // strb r1, [sp, r10] __ strh(r10, Address(lr, r9, lsl(), Address::ADD, Address::post)); // strh r10, [lr], r9 // MemoryOp __ ldr(r6, Address(r3, r4, lsl(), Address::ADD, Address::pre)); // ldr r6, [r3, r4]! __ ldrb(r4, Address(r6, sp, lsl(), Address::ADD, Address::pre)); // ldrb r4, [r6, sp]! __ ldrh(r6, Address(r7, r10, lsl(), Address::ADD, Address::post)); // ldrh r6, [r7], r10 __ ldrsb(r0, Address(r6, r11, lsl(), Address::ADD, Address::pre)); // ldrsb r0, [r6, r11]! __ ldrsh(r10, Address(r6, sp, lsl(), Address::ADD, Address::post)); // ldrsh r10, [r6], sp __ str(r7, Address(r3, r12, lsl(), Address::ADD, Address::off)); // str r7, [r3, r12] __ strb(r3, Address(r8, r1, lsl(), Address::ADD, Address::pre)); // strb r3, [r8, r1]! __ strh(r4, Address(r12, 64)); // strh r4, [r12, #64] __ bind(near); // LitMemoryOp __ ldr(r1, near); // ldr r1, near __ ldrb(r7, __ pc()); // ldrb r7, . __ ldrh(r2, near); // ldrh r2, near __ ldrsb(r10, __ pc()); // ldrsb r10, . __ ldrsh(lr, near_post); // ldrsh lr, near_post // LitMemoryOp __ ldr(r2, __ pc()); // ldr r2, . __ ldrb(r3, __ pc()); // ldrb r3, . __ ldrh(r7, near_post); // ldrh r7, near_post __ ldrsb(sp, __ pc()); // ldrsb sp, . __ ldrsh(r10, near); // ldrsh r10, near // LitMemoryOp __ ldr(r5, __ pc()); // ldr r5, . __ ldrb(lr, near_post); // ldrb lr, near_post __ ldrh(r5, near_post); // ldrh r5, near_post __ ldrsb(r6, near); // ldrsb r6, near __ ldrsh(r11, near); // ldrsh r11, near // LitMemoryOp __ ldr(r7, near_post); // ldr r7, near_post __ ldrb(r5, near_post); // ldrb r5, near_post __ ldrh(r10, near); // ldrh r10, near __ ldrsb(r6, near_post); // ldrsb r6, near_post __ ldrsh(r9, __ pc()); // ldrsh r9, . __ bind(near_post); // MemoryRegRegSftOp __ ldr(r0, Address(r0, r10, ::ror(6), Address::ADD, Address::post)); // ldr r0, [r0], r10, ror #6 __ ldrb(r3, Address(r8, lr, ::lsl(9), Address::ADD, Address::off)); // ldrb r3, [r8, lr, lsl #9] __ str(r5, Address(sp, r3, ::lsl(15), Address::ADD, Address::off)); // str r5, [sp, r3, lsl #15] __ strb(r9, Address(r9, r5, ::asr(2), Address::ADD, Address::post)); // strb r9, [r9], r5, asr #2 // MemoryRegRegSftOp __ ldr(r5, Address(r4, r0, ::ror(6), Address::ADD, Address::off)); // ldr r5, [r4, r0, ror #6] __ ldrb(lr, Address(r0, r4, ::lsr(9), Address::ADD, Address::off)); // ldrb lr, [r0, r4, lsr #9] __ str(r5, Address(r12, r12, ::asr(5), Address::ADD, Address::post)); // str r5, [r12], r12, asr #5 __ strb(r3, Address(r1, r7, ::ror(12), Address::ADD, Address::pre)); // strb r3, [r1, r7, ror #12]! // MemoryRegRegSftOp __ ldr(r6, Address(r2, r3, ::rrx(), Address::ADD, Address::pre)); // ldr r6, [r2, r3, rrx]! __ ldrb(r8, Address(lr, r2, ::asr(16), Address::ADD, Address::pre)); // ldrb r8, [lr, r2, asr #16]! __ str(r6, Address(r3, r6, ::ror(7), Address::ADD, Address::pre)); // str r6, [r3, r6, ror #7]! __ strb(r3, Address(r8, r2, ::lsl(10), Address::ADD, Address::off)); // strb r3, [r8, r2, lsl #10] // MemoryRegRegSftOp __ ldr(r11, Address(sp, lr, ::lsl(8), Address::ADD, Address::off)); // ldr r11, [sp, lr, lsl #8] __ ldrb(r10, Address(sp, r12, ::lsl(4), Address::ADD, Address::pre)); // ldrb r10, [sp, r12, lsl #4]! __ str(sp, Address(r9, r2, ::asr(2), Address::ADD, Address::off)); // str sp, [r9, r2, asr #2] __ strb(r7, Address(r11, lr, ::asr(14), Address::ADD, Address::pre)); // strb r7, [r11, lr, asr #14]! // LdStOne __ ldrex(r12, r11); // ldrex r12, [r11] __ ldrexb(r4, r12); // ldrexb r4, [r12] __ ldrexh(r11, r11); // ldrexh r11, [r11] // LdStTwo __ strex(r1, r7, lr); // strex r1, r7, [lr] __ strexb(r12, r6, r4); // strexb r12, r6, [r4] __ strexh(r4, r6, r7, Assembler::HS); // strexhHS r4, r6, [r7] // ThreeRegNon __ sadd16(r3, r4, r7); // sadd16 r3, r4, r7 __ sasx(r9, r10, r3, Assembler::AL); // sasxAL r9, r10, r3 __ ssax(r12, r5, r6); // ssax r12, r5, r6 __ ssub16(r12, r5, lr); // ssub16 r12, r5, lr __ sadd8(r0, r10, r7); // sadd8 r0, r10, r7 __ ssub8(r0, r8, r2, Assembler::VS); // ssub8VS r0, r8, r2 __ qadd16(r11, r4, r5, Assembler::PL); // qadd16PL r11, r4, r5 __ qasx(r11, r3, r12, Assembler::VS); // qasxVS r11, r3, r12 __ qsax(r0, r3, r5); // qsax r0, r3, r5 __ ssub16(r10, r12, r5, Assembler::AL); // ssub16AL r10, r12, r5 __ qadd8(r10, r6, lr, Assembler::CC); // qadd8CC r10, r6, lr __ qsub8(r10, r11, r7); // qsub8 r10, r11, r7 __ shadd16(r9, r4, lr, Assembler::PL); // shadd16PL r9, r4, lr __ shasx(r1, lr, r7); // shasx r1, lr, r7 __ shsax(r9, r11, r5, Assembler::LO); // shsaxLO r9, r11, r5 __ shsub16(r3, r1, r11, Assembler::GE); // shsub16GE r3, r1, r11 __ shadd8(sp, r5, r7, Assembler::GT); // shadd8GT sp, r5, r7 __ shsub8(r1, r5, r7); // shsub8 r1, r5, r7 // ThreeRegNon __ uadd16(r10, r4, r7); // uadd16 r10, r4, r7 __ uasx(r1, r9, r7, Assembler::HS); // uasxHS r1, r9, r7 __ usax(r11, sp, r7); // usax r11, sp, r7 __ usub16(r11, r4, lr); // usub16 r11, r4, lr __ uadd8(r2, sp, r7, Assembler::LO); // uadd8LO r2, sp, r7 __ usub8(r8, r10, lr, Assembler::GT); // usub8GT r8, r10, lr __ uqadd16(r3, r12, sp); // uqadd16 r3, r12, sp __ uqasx(r4, sp, r6); // uqasx r4, sp, r6 __ uqsax(r1, r10, lr); // uqsax r1, r10, lr __ uqsub16(r2, sp, lr, Assembler::LE); // uqsub16LE r2, sp, lr __ uqadd8(r1, r12, r5); // uqadd8 r1, r12, r5 __ uqsub8(r0, r4, sp, Assembler::GT); // uqsub8GT r0, r4, sp __ uhadd16(r0, r10, r5, Assembler::HI); // uhadd16HI r0, r10, r5 __ uhasx(r11, r4, r7, Assembler::LE); // uhasxLE r11, r4, r7 __ uhsax(r1, lr, r9, Assembler::GE); // uhsaxGE r1, lr, r9 __ uhsub16(r2, r11, lr); // uhsub16 r2, r11, lr __ uhadd8(r9, r4, r5, Assembler::GE); // uhadd8GE r9, r4, r5 __ uhsub8(r2, sp, lr, Assembler::HI); // uhsub8HI r2, sp, lr // PKUPSATREV __ sxtab16(r10, r3, r7, ::ror(16)); // sxtab16 r10, r3, r7, ROR #16 __ sxtab(r9, r5, r7, ::ror(24), Assembler::CS); // sxtabCS r9, r5, r7, ROR #24 __ sxtah(r3, r5, r7, ::ror(8)); // sxtah r3, r5, r7, ROR #8 __ uxtab16(r8, r4, r6, ::ror(8), Assembler::AL); // uxtab16AL r8, r4, r6, ROR #8 __ uxtab(r0, r11, sp, ::rrx(), Assembler::EQ); // uxtabEQ r0, r11, sp, ROR #0 __ uxtah(r9, r12, r5, ::rrx()); // uxtah r9, r12, r5, ROR #0 // PKUPSATREV __ sxtb16(r3, r11, ::ror(16), Assembler::GE); // sxtb16GE r3, r11, ROR #16 __ sxtb(r2, r6, ::rrx(), Assembler::HI); // sxtbHI r2, r6, ROR #0 __ sxth(r3, sp, ::ror(24), Assembler::GT); // sxthGT r3, sp, ROR #24 __ uxtb16(r12, r5, ::ror(16)); // uxtb16 r12, r5, ROR #16 __ uxtb(r12, r5, ::ror(16)); // uxtb r12, r5, ROR #16 __ uxth(r8, r5, ::ror(16)); // uxth r8, r5, ROR #16 // TwoRegNon __ rev(r10, r4, Assembler::EQ); // revEQ r10, r4 __ rev16(r8, r12, Assembler::GE); // rev16GE r8, r12 __ rbit(lr, r7); // rbit lr, r7 __ revsh(sp, r7, Assembler::GT); // revshGT sp, r7 // ThreeRegNon __ sdiv(r9, sp, lr); // sdiv r9, sp, lr __ udiv(r2, r12, r6); // udiv r2, r12, r6 // TwoRegTwoImm __ sbfx(r0, r1, (unsigned)20U, (unsigned)3U, Assembler::MI); // sbfxMI r0, r1, #20, #3 __ ubfx(r9, r2, (unsigned)16U, (unsigned)15U); // ubfx r9, r2, #16, #15 __ bfi(r1, r11, (unsigned)27U, (unsigned)3U, Assembler::HI); // bfiHI r1, r11, #27, #3 // TwoRegTwoImm __ bfc(r3, (unsigned)7U, (unsigned)10U); // bfc r3, #7, #10 // MultipleMemOp __ stmda(r6, 3435U, false); // stmda r6, {r0, r1, r3, r5, r6, r8, r10, r11} __ stmed(r4, 14559U, false); // stmed r4, {r0, r1, r2, r3, r4, r6, r7, r11, r12, sp} __ ldmda(r0, 57812U, false); // ldmda r0, {r2, r4, r6, r7, r8, sp, lr, pc} __ ldmfa(r12, 39027U, true); // ldmfa r12!, {r0, r1, r4, r5, r6, r11, r12, pc} __ stmia(r9, 12733U, true); // stmia r9!, {r0, r2, r3, r4, r5, r7, r8, r12, sp} __ stmea(r11, 21955U, false); // stmea r11, {r0, r1, r6, r7, r8, r10, r12, lr} __ ldmia(r12, 48418U, true); // ldmia r12!, {r1, r5, r8, r10, r11, r12, sp, pc} __ ldmfd(sp, 41226U, true); // ldmfd sp!, {r1, r3, r8, sp, pc} __ stmdb(r11, 8729U, true); // stmdb r11!, {r0, r3, r4, r9, sp} __ stmfd(r9, 36309U, true); // stmfd r9!, {r0, r2, r4, r6, r7, r8, r10, r11, pc} __ ldmdb(r5, 24667U, true); // ldmdb r5!, {r0, r1, r3, r4, r6, sp, lr} __ ldmea(r1, 37287U, false); // ldmea r1, {r0, r1, r2, r5, r7, r8, r12, pc} __ stmib(r11, 28266U, true); // stmib r11!, {r1, r3, r5, r6, r9, r10, r11, sp, lr} __ stmfa(r11, 17671U, false); // stmfa r11, {r0, r1, r2, r8, r10, lr} __ ldmib(r0, 21452U, true); // ldmib r0!, {r2, r3, r6, r7, r8, r9, r12, lr} __ ldmed(r1, 11751U, false); // ldmed r1, {r0, r1, r2, r5, r6, r7, r8, r10, r11, sp} // BranchLabel __ b(forth, Assembler::CS); // bCS forth __ bl(__ pc(), Assembler::MI); // blMI . // OneRegNon __ b(r0, Assembler::VS); // bxVS r0 __ bl(r3); // blx r3 // BranchLabel __ b(__ pc(), Assembler::AL); // bAL . __ bl(__ pc()); // bl . // OneRegNon __ b(r0, Assembler::VS); // bxVS r0 __ bl(r5); // blx r5 // BranchLabel __ b(forth, Assembler::LE); // bLE forth __ bl(__ pc(), Assembler::MI); // blMI . // OneRegNon __ b(r9, Assembler::NE); // bxNE r9 __ bl(r12); // blx r12 // BranchLabel __ b(back); // b back __ bl(__ pc(), Assembler::HI); // blHI . // OneRegNon __ b(r1, Assembler::VC); // bxVC r1 __ bl(r7, Assembler::GT); // blxGT r7 // BranchLabel __ b(back, Assembler::GE); // bGE back __ bl(__ pc(), Assembler::HI); // blHI . // OneRegNon __ b(r12); // bx r12 __ bl(r7, Assembler::CC); // blxCC r7 // BranchLabel __ b(__ pc()); // b . __ bl(back, Assembler::GT); // blGT back // OneRegNon __ b(r1, Assembler::GE); // bxGE r1 __ bl(r0); // blx r0 // BranchLabel __ b(__ pc()); // b . __ bl(forth); // bl forth // OneRegNon __ b(lr, Assembler::GT); // bxGT lr __ bl(r11, Assembler::NE); // blxNE r11 // BranchLabel __ b(__ pc(), Assembler::CS); // bCS . __ bl(__ pc()); // bl . // OneRegNon __ b(r10, Assembler::HS); // bxHS r10 __ bl(r4); // blx r4 // BranchLabel __ b(back, Assembler::AL); // bAL back __ bl(__ pc()); // bl . // OneRegNon __ b(r12, Assembler::LO); // bxLO r12 __ bl(r8); // blx r8 // BranchLabel __ b(forth); // b forth __ bl(__ pc()); // bl . // OneRegNon __ b(r10); // bx r10 __ bl(r1); // blx r1 // ThreeFltNon __ vmla_f32(f4, f8, f12, Assembler::MI); // vmlaMI.f32 s4, s8, s12 __ vmls_f32(f4, f10, f10); // vmls.f32 s4, s10, s10 __ vnmla_f32(f2, f10, f12); // vnmla.f32 s2, s10, s12 __ vnmls_f32(f8, f6, f8, Assembler::LT); // vnmlsLT.f32 s8, s6, s8 __ vnmul_f32(f6, f12, f14, Assembler::MI); // vnmulMI.f32 s6, s12, s14 __ vadd_f32(f0, f2, f0); // vadd.f32 s0, s2, s0 __ vsub_f32(f2, f4, f10, Assembler::AL); // vsubAL.f32 s2, s4, s10 __ vdiv_f32(f0, f2, f12, Assembler::CS); // vdivCS.f32 s0, s2, s12 // ThreeFltNon __ vmla_f64(d0, d3, d6); // vmla.f64 d0, d3, d6 __ vmls_f64(d0, d1, d5); // vmls.f64 d0, d1, d5 __ vnmla_f64(d1, d4, d6); // vnmla.f64 d1, d4, d6 __ vnmls_f64(d0, d1, d1, Assembler::NE); // vnmlsNE.f64 d0, d1, d1 __ vnmul_f64(d3, d5, d5, Assembler::NE); // vnmulNE.f64 d3, d5, d5 __ vadd_f64(d0, d2, d4, Assembler::LO); // vaddLO.f64 d0, d2, d4 __ vsub_f64(d1, d2, d4); // vsub.f64 d1, d2, d4 __ vdiv_f64(d0, d1, d5, Assembler::MI); // vdivMI.f64 d0, d1, d5 // TwoFltNon __ vabs_f32(f6, f6); // vabs.f32 s6, s6 __ vneg_f32(f6, f8, Assembler::PL); // vnegPL.f32 s6, s8 __ vsqrt_f32(f0, f8); // vsqrt.f32 s0, s8 // TwoFltNon __ vabs_f64(d0, d4); // vabs.f64 d0, d4 __ vneg_f64(d1, d4); // vneg.f64 d1, d4 __ vsqrt_f64(d0, d1); // vsqrt.f64 d0, d1 // vmov_f32 __ vmov_f32(f0, lr, Assembler::PL); // vmovPL.f32 s0, lr // vmov_f32 __ vmov_f32(r11, f8); // vmov.f32 r11, s8 // vmov_f64 __ vmov_f64(d1, r11, lr, Assembler::LT); // vmovLT.f64 d1, r11, lr // vmov_f64 __ vmov_f64(r7, r5, d5); // vmov.f64 r7, r5, d5 // vmov_f32 __ vmov_f32(f8, f12); // vmov.f32 s8, s12 // vmov_f64 __ vmov_f64(d1, d2, Assembler::HI); // vmovHI.f64 d1, d2 // vmov_f32 __ vmov_f32(f4, 1.0f, Assembler::VS); // vmovVS.f32 s4, #1.0 // vmov_f64 __ vmov_f64(d2, 1.0); // vmov.f64 d2, #1.0 // vmov_f32 __ vmov_f32(f6, 2.0f); // vmov.f32 s6, #2.0 // vmov_f64 __ vmov_f64(d1, 2.0); // vmov.f64 d1, #2.0 // vector memory __ vldr_f32(f4, Address(r5, 116)); // vldr.f32 s4, [r5, #116] __ vstr_f32(f2, Address(r1, 56), Assembler::CC); // vstrCC.f32 s2, [r1, #56] // vector memory __ vldr_f64(d7, Address(r5, 16), Assembler::NE); // vldrNE.f64 d7, [r5, #16] __ vstr_f64(d6, Address(r1, 228)); // vstr.f64 d6, [r1, #228] __ bind(near_flt); // vector memory __ vldr_f32(f2, near_post_flt); // vldr.f32 s2, near_post_flt __ vstr_f32(f6, near_post_flt); // vstr.f32 s6, near_post_flt // vector memory __ vldr_f64(d2, near_flt, Assembler::LT); // vldrLT.f64 d2, near_flt __ vstr_f64(d3, __ pc(), Assembler::GT); // vstrGT.f64 d3, . // vector memory __ vldr_f32(f4, near_post_flt, Assembler::CC); // vldrCC.f32 s4, near_post_flt __ vstr_f32(f0, near_post_flt); // vstr.f32 s0, near_post_flt // vector memory __ vldr_f64(d4, near_post_flt, Assembler::GT); // vldrGT.f64 d4, near_post_flt __ vstr_f64(d0, near_flt); // vstr.f64 d0, near_flt // vector memory __ vldr_f32(f8, near_post_flt); // vldr.f32 s8, near_post_flt __ vstr_f32(f6, near_post_flt); // vstr.f32 s6, near_post_flt // vector memory __ vldr_f64(d4, near_flt, Assembler::PL); // vldrPL.f64 d4, near_flt __ vstr_f64(d5, near_flt); // vstr.f64 d5, near_flt // vector memory __ vldr_f32(f8, near_post_flt, Assembler::LS); // vldrLS.f32 s8, near_post_flt __ vstr_f32(f12, __ pc(), Assembler::CC); // vstrCC.f32 s12, . // vector memory __ vldr_f64(d6, near_post_flt, Assembler::AL); // vldrAL.f64 d6, near_post_flt __ vstr_f64(d1, near_post_flt, Assembler::LT); // vstrLT.f64 d1, near_post_flt __ bind(near_post_flt); // FltMultMemOp __ vldmia_f32(r1, FloatRegSet::of(f4).bits(), false); // vldmia.f32 r1, {s4} __ vstmia_f32(r6, FloatRegSet::of(f4).bits(), true, Assembler::CS); // vstmiaCS.f32 r6!, {s4} // DblMultMemOp __ vldmia_f64(r9, DoubleFloatRegSet::of(d1, d2, d3, d4).bits(), true); // vldmia.f64 r9!, {d1, d2, d3, d4} __ vstmia_f64(r3, DoubleFloatRegSet::of(d6, d7).bits(), true); // vstmia.f64 r3!, {d6, d7} // FltMultMemOp __ vldmdb_f32(r2, FloatRegSet::of(f6).bits(), Assembler::VS); // vldmdbVS.f32 r2!, {s6} __ vstmdb_f32(r6, FloatRegSet::of(f14).bits()); // vstmdb.f32 r6!, {s14} // DblMultMemOp __ vldmdb_f64(sp, DoubleFloatRegSet::of(d4, d5, d6, d7).bits()); // vldmdb.f64 sp!, {d4, d5, d6, d7} __ vstmdb_f64(r0, DoubleFloatRegSet::of(d5, d6, d7).bits()); // vstmdb.f64 r0!, {d5, d6, d7} // vcmp_f32 __ vcmp_f32(f2, f2); // vcmp.f32 s2, s2 // vcmpe_f32 __ vcmpe_f32(f8, f8, Assembler::VC); // vcmpeVC.f32 s8, s8 // vcmp_f64 __ vcmp_f64(d0, d6); // vcmp.f64 d0, d6 // vcmpe_f64 __ vcmpe_f64(d3, d7, Assembler::GE); // vcmpeGE.f64 d3, d7 // vcmp_f32 __ vcmp_f32(f2, 0.0f, Assembler::LT); // vcmpLT.f32 s2, #0.0 // vcmpe_f32 __ vcmpe_f32(f14, 0.0f, Assembler::GT); // vcmpeGT.f32 s14, #0.0 // vcmp_f64 __ vcmp_f64(d4, 0.0); // vcmp.f64 d4, #0.0 // vcmpe_f64 __ vcmpe_f64(d1, 0.0); // vcmpe.f64 d1, #0.0 // vcvt __ vcvt_s32_f32(f2, f6, Assembler::VS); // vcvtVS.s32.f32 s2, s6 __ vcvt_u32_f32(f6, f14, Assembler::GT); // vcvtGT.u32.f32 s6, s14 __ vcvt_f32_s32(f0, f2, Assembler::CC); // vcvtCC.f32.s32 s0, s2 __ vcvt_f32_u32(f2, f4, Assembler::CC); // vcvtCC.f32.u32 s2, s4 // vcvt __ vcvt_s32_f64(f4, d4, Assembler::HI); // vcvtHI.s32.f64 s4, d4 __ vcvt_u32_f64(f6, d6, Assembler::HI); // vcvtHI.u32.f64 s6, d6 __ vcvt_f32_f64(f6, d7, Assembler::LS); // vcvtLS.f32.f64 s6, d7 // vcvt __ vcvt_f64_s32(d3, f8); // vcvt.f64.s32 d3, s8 __ vcvt_f64_u32(d5, f14, Assembler::EQ); // vcvtEQ.f64.u32 d5, s14 __ vcvt_f64_f32(d4, f10, Assembler::AL); // vcvtAL.f64.f32 d4, s10 // BKPT __ bkpt((unsigned)26U); // bkpt #26 __ bind(forth); /* aarch32ops.o: file format elf32-littlearm Disassembly of section .text: 00000000 : 0: e082852b add r8, r2, fp, lsr #10 4: 009310c7 addseq r1, r3, r7, asr #1 8: e0290284 eor r0, r9, r4, lsl #5 c: c0329066 eorsgt r9, r2, r6, rrx 10: c04c000e subgt r0, ip, lr 14: 00528364 subseq r8, r2, r4, ror #6 18: e069818d rsb r8, r9, sp, lsl #3 1c: 60708864 rsbsvs r8, r0, r4, ror #16 20: d08597a1 addle r9, r5, r1, lsr #15 24: e09d12c6 adds r1, sp, r6, asr #5 28: c0adb0c7 adcgt fp, sp, r7, asr #1 2c: e0b80329 adcs r0, r8, r9, lsr #6 30: e0c392e6 sbc r9, r3, r6, ror #5 34: 80dd1845 sbcshi r1, sp, r5, asr #16 38: 30e28486 rsccc r8, r2, r6, lsl #9 3c: e0f4a76d rscs sl, r4, sp, ror #14 40: 118db785 orrne fp, sp, r5, lsl #15 44: e19a9764 orrs r9, sl, r4, ror #14 48: e1cd90e5 bic r9, sp, r5, ror #1 4c: e1d20547 bics r0, r2, r7, asr #10 50: e086d777 add sp, r6, r7, ror r7 54: 809c4776 addshi r4, ip, r6, ror r7 58: 90265c57 eorls r5, r6, r7, asr ip 5c: e035841d eors r8, r5, sp, lsl r4 60: e04c2055 sub r2, ip, r5, asr r0 64: 20539c17 subscs r9, r3, r7, lsl ip 68: c06c9614 rsbgt r9, ip, r4, lsl r6 6c: e072811c rsbs r8, r2, ip, lsl r1 70: e08c4d1d add r4, ip, sp, lsl sp 74: e09b8d76 adds r8, fp, r6, ror sp 78: 10a20415 adcne r0, r2, r5, lsl r4 7c: e0beb256 adcs fp, lr, r6, asr r2 80: 80ca835e sbchi r8, sl, lr, asr r3 84: e0dc1615 sbcs r1, ip, r5, lsl r6 88: 60e54a7e rscvs r4, r5, lr, ror sl 8c: e0fc181d rscs r1, ip, sp, lsl r8 90: 61818076 orrvs r8, r1, r6, ror r0 94: e19db577 orrs fp, sp, r7, ror r5 98: e1ce4216 bic r4, lr, r6, lsl r2 9c: e1dba31d bics sl, fp, sp, lsl r3 a0: 828d8261 addhi r8, sp, #268435462 ; 0x10000006 a4: e29ed69b adds sp, lr, #162529280 ; 0x9b00000 a8: e226e87d eor lr, r6, #8192000 ; 0x7d0000 ac: e2332f49 eors r2, r3, #292 ; 0x124 b0: e24d46d9 sub r4, sp, #227540992 ; 0xd900000 b4: b25e1402 subslt r1, lr, #33554432 ; 0x2000000 b8: e2650325 rsb r0, r5, #-1811939328 ; 0x94000000 bc: 3274882f rsbscc r8, r4, #3080192 ; 0x2f0000 c0: b2849102 addlt r9, r4, #-2147483648 ; 0x80000000 c4: e2948902 adds r8, r4, #32768 ; 0x8000 c8: 22aeac2a adccs sl, lr, #10752 ; 0x2a00 cc: e2b6aabd adcs sl, r6, #774144 ; 0xbd000 d0: e2cc2426 sbc r2, ip, #637534208 ; 0x26000000 d4: e2da85a5 sbcs r8, sl, #692060160 ; 0x29400000 d8: e2e6d871 rsc sp, r6, #7405568 ; 0x710000 dc: 12fba6e9 rscsne sl, fp, #244318208 ; 0xe900000 e0: 638737ff orrvs r3, r7, #66846720 ; 0x3fc0000 e4: 03952951 orrseq r2, r5, #1327104 ; 0x144000 e8: 63c18eea bicvs r8, r1, #3744 ; 0xea0 ec: 33d2020a bicscc r0, r2, #-1610612736 ; 0xa0000000 f0: e118028d tst r8, sp, lsl #5 f4: e13601a7 teq r6, r7, lsr #3 f8: e15c0164 cmp ip, r4, ror #2 fc: b1750807 cmnlt r5, r7, lsl #16 100: e112073e tst r2, lr, lsr r7 104: 31300572 teqcc r0, r2, ror r5 108: 915e0b37 cmpls lr, r7, lsr fp 10c: 617a0b17 cmnvs sl, r7, lsl fp 110: e3120585 tst r2, #557842432 ; 0x21400000 114: 433e071b teqmi lr, #7077888 ; 0x6c0000 118: e355030e cmp r5, #939524096 ; 0x38000000 11c: 3377010a cmncc r7, #-2147483646 ; 0x80000002 120: e1a00b84 lsl r0, r4, #23 124: e1b01484 lsls r1, r4, #9 128: e1a001aa lsr r0, sl, #3 12c: e1b00a2a lsrs r0, sl, #20 130: e1a015c9 asr r1, r9, #11 134: 61b0254b asrsvs r2, fp, #10 138: 31a08fe2 rorcc r8, r2, #31 13c: e1b0946c rors r9, ip, #8 140: e1a0877e ror r8, lr, r7 144: e1b0c473 rors ip, r3, r4 148: c1a0ce1d lslgt ip, sp, lr 14c: e1b0c61d lsls ip, sp, r6 150: c1a00931 lsrgt r0, r1, r9 154: c1b0bc33 lsrsgt fp, r3, ip 158: d1a0265c asrle r2, ip, r6 15c: b1b0165a asrslt r1, sl, r6 160: e1a0a003 mov sl, r3 164: e1b00009 movs r0, r9 168: 73a03e29 movvc r3, #656 ; 0x290 16c: e3b0497e movs r4, #2064384 ; 0x1f8000 170: e1a0c1a6 lsr ip, r6, #3 174: 71b0554d asrsvc r5, sp, #10 178: e1a0137e ror r1, lr, r3 17c: 01b0897c rorseq r8, ip, r9 180: 330cbf31 movwcc fp, #53041 ; 0xcf31 184: 33429bf7 movtcc r9, #11255 ; 0x2bf7 188: d001059d mulle r1, sp, r5 18c: e0100b9a muls r0, sl, fp 190: e0207c93 mla r0, r3, ip, r7 194: 0038639b mlaseq r8, fp, r3, r6 198: e084e695 umull lr, r4, r5, r6 19c: e0940796 umulls r0, r4, r6, r7 1a0: e0a08e9b umlal r8, r0, fp, lr 1a4: e0b4b79e umlals fp, r4, lr, r7 1a8: 20c51796 smullcs r1, r5, r6, r7 1ac: 40db059c smullsmi r0, fp, ip, r5 1b0: e0498592 umaal r8, r9, r2, r5 1b4: 0060ed94 mlseq r0, r4, sp, lr 1b8: 510d9054 qaddpl r9, r4, sp 1bc: 4125005c qsubmi r0, ip, r5 1c0: e1473055 qdadd r3, r5, r7 1c4: e1649052 qdsub r9, r2, r4 1c8: e101658c smlabb r1, ip, r5, r6 1cc: e1006cca smlabt r0, sl, ip, r6 1d0: e108e3a1 smlatb r8, r1, r3, lr 1d4: e10176ed smlatt r1, sp, r6, r7 1d8: e1206483 smlawb r0, r3, r4, r6 1dc: e12b7ec4 smlawt fp, r4, lr, r7 1e0: e14a0786 smlalbb r0, sl, r6, r7 1e4: 914b3ec4 smlalbtls r3, fp, r4, lr 1e8: e14b8ca3 smlaltb r8, fp, r3, ip 1ec: e14185e3 smlaltt r8, r1, r3, r5 1f0: 21220dac smulwbcs r2, ip, sp 1f4: e12806ec smulwt r8, ip, r6 1f8: a1620e86 smulbbge r2, r6, lr 1fc: e16807cc smulbt r8, ip, r7 200: 016a0ea3 smultbeq sl, r3, lr 204: e1600de3 smultt r0, r3, sp 208: e697a009 ldr sl, [r7], r9 20c: e5d900c4 ldrb r0, [r9, #196] ; 0xc4 210: e1b4e0b6 ldrh lr, [r4, r6]! 214: e1f96ed8 ldrsb r6, [r9, #232]! ; 0xe8 218: e09120f1 ldrsh r2, [r1], r1 21c: e6890004 str r0, [r9], r4 220: e5e5305c strb r3, [r5, #92]! ; 0x5c 224: e1c82ab0 strh r2, [r8, #160] ; 0xa0 228: e79c8008 ldr r8, [ip, r8] 22c: e4dab010 ldrb fp, [sl], #16 230: e19ab0b6 ldrh fp, [sl, r6] 234: e1bb50da ldrsb r5, [fp, sl]! 238: e19360f7 ldrsh r6, [r3, r7] 23c: e7ad7005 str r7, [sp, r5]! 240: e5ca2000 strb r2, [sl] 244: e08460b3 strh r6, [r4], r3 248: e59ca000 ldr sl, [ip] 24c: e4db4084 ldrb r4, [fp], #132 ; 0x84 250: e09990bc ldrh r9, [r9], ip 254: e0d399d4 ldrsb r9, [r3], #148 ; 0x94 258: e1f2b9f4 ldrsh fp, [r2, #148]! ; 0x94 25c: e78db00b str fp, [sp, fp] 260: e7cd100a strb r1, [sp, sl] 264: e08ea0b9 strh sl, [lr], r9 268: e7b36004 ldr r6, [r3, r4]! 26c: e7f6400d ldrb r4, [r6, sp]! 270: e09760ba ldrh r6, [r7], sl 274: e1b600db ldrsb r0, [r6, fp]! 278: e096a0fd ldrsh sl, [r6], sp 27c: e783700c str r7, [r3, ip] 280: e7e83001 strb r3, [r8, r1]! 284: e1cc44b0 strh r4, [ip, #64] ; 0x40 00000288 : 288: e51f1008 ldr r1, [pc, #-8] ; 288 28c: e55f7008 ldrb r7, [pc, #-8] ; 28c 290: e15f21b0 ldrh r2, [pc, #-16] ; 288 294: e15fa0d8 ldrsb sl, [pc, #-8] ; 294 298: e1dfe3f8 ldrsh lr, [pc, #56] ; 2d8 29c: e51f2008 ldr r2, [pc, #-8] ; 29c 2a0: e55f3008 ldrb r3, [pc, #-8] ; 2a0 2a4: e1df72bc ldrh r7, [pc, #44] ; 2d8 2a8: e15fd0d8 ldrsb sp, [pc, #-8] ; 2a8 2ac: e15fa2fc ldrsh sl, [pc, #-44] ; 288 2b0: e51f5008 ldr r5, [pc, #-8] ; 2b0 2b4: e5dfe01c ldrb lr, [pc, #28] ; 2d8 2b8: e1df51b8 ldrh r5, [pc, #24] ; 2d8 2bc: e15f63dc ldrsb r6, [pc, #-60] ; 288 2c0: e15fb4f0 ldrsh fp, [pc, #-64] ; 288 2c4: e59f700c ldr r7, [pc, #12] ; 2d8 2c8: e5df5008 ldrb r5, [pc, #8] ; 2d8 2cc: e15fa4bc ldrh sl, [pc, #-76] ; 288 2d0: e1df60d0 ldrsb r6, [pc] ; 2d8 2d4: e15f90f8 ldrsh r9, [pc, #-8] ; 2d4 000002d8 : 2d8: e690036a ldr r0, [r0], sl, ror #6 2dc: e7d8348e ldrb r3, [r8, lr, lsl #9] 2e0: e78d5783 str r5, [sp, r3, lsl #15] 2e4: e6c99145 strb r9, [r9], r5, asr #2 2e8: e7945360 ldr r5, [r4, r0, ror #6] 2ec: e7d0e4a4 ldrb lr, [r0, r4, lsr #9] 2f0: e68c52cc str r5, [ip], ip, asr #5 2f4: e7e13667 strb r3, [r1, r7, ror #12]! 2f8: e7b26063 ldr r6, [r2, r3, rrx]! 2fc: e7fe8842 ldrb r8, [lr, r2, asr #16]! 300: e7a363e6 str r6, [r3, r6, ror #7]! 304: e7c83502 strb r3, [r8, r2, lsl #10] 308: e79db40e ldr fp, [sp, lr, lsl #8] 30c: e7fda20c ldrb sl, [sp, ip, lsl #4]! 310: e789d142 str sp, [r9, r2, asr #2] 314: e7eb774e strb r7, [fp, lr, asr #14]! 318: e19bcf9f ldrex r12, [fp] 31c: e1dc4f9f ldrexb r4, [ip] 320: e1fbbf9f ldrexh fp, [fp] 324: e18e1f97 strex r1, r7, [lr] 328: e1c4cf96 strexb ip, r6, [r4] 32c: 21e74f96 strexhcs r4, r6, [r7] 330: e6143f17 sadd16 r3, r4, r7 334: e61a9f33 sasx r9, sl, r3 338: e615cf56 ssax ip, r5, r6 33c: e615cf7e ssub16 ip, r5, lr 340: e61a0f97 sadd8 r0, sl, r7 344: 66180ff2 ssub8vs r0, r8, r2 348: 5624bf15 qadd16pl fp, r4, r5 34c: 6623bf3c qasxvs fp, r3, ip 350: e6230f55 qsax r0, r3, r5 354: e61caf75 ssub16 sl, ip, r5 358: 3626af9e qadd8cc sl, r6, lr 35c: e62baff7 qsub8 sl, fp, r7 360: 56349f1e shadd16pl r9, r4, lr 364: e63e1f37 shasx r1, lr, r7 368: 363b9f55 shsaxcc r9, fp, r5 36c: a6313f7b shsub16ge r3, r1, fp 370: c635df97 shadd8gt sp, r5, r7 374: e6351ff7 shsub8 r1, r5, r7 378: e654af17 uadd16 sl, r4, r7 37c: 26591f37 uasxcs r1, r9, r7 380: e65dbf57 usax fp, sp, r7 384: e654bf7e usub16 fp, r4, lr 388: 365d2f97 uadd8cc r2, sp, r7 38c: c65a8ffe usub8gt r8, sl, lr 390: e66c3f1d uqadd16 r3, ip, sp 394: e66d4f36 uqasx r4, sp, r6 398: e66a1f5e uqsax r1, sl, lr 39c: d66d2f7e uqsub16le r2, sp, lr 3a0: e66c1f95 uqadd8 r1, ip, r5 3a4: c6640ffd uqsub8gt r0, r4, sp 3a8: 867a0f15 uhadd16hi r0, sl, r5 3ac: d674bf37 uhasxle fp, r4, r7 3b0: a67e1f59 uhsaxge r1, lr, r9 3b4: e67b2f7e uhsub16 r2, fp, lr 3b8: a6749f95 uhadd8ge r9, r4, r5 3bc: 867d2ffe uhsub8hi r2, sp, lr 3c0: e683a877 sxtab16 sl, r3, r7, ror #16 3c4: 26a59c77 sxtabcs r9, r5, r7, ror #24 3c8: e6b53477 sxtah r3, r5, r7, ror #8 3cc: e6c48476 uxtab16 r8, r4, r6, ror #8 3d0: 06eb007d uxtabeq r0, fp, sp 3d4: e6fc9075 uxtah r9, ip, r5 3d8: a68f387b sxtb16ge r3, fp, ror #16 3dc: 86af2076 sxtbhi r2, r6 3e0: c6bf3c7d sxthgt r3, sp, ror #24 3e4: e6cfc875 uxtb16 ip, r5, ror #16 3e8: e6efc875 uxtb ip, r5, ror #16 3ec: e6ff8875 uxth r8, r5, ror #16 3f0: 06bfaf34 reveq sl, r4 3f4: a6bf8fbc rev16ge r8, ip 3f8: e6ffef37 rbit lr, r7 3fc: c6ffdfb7 revshgt sp, r7 400: e719fe1d sdiv r9, sp, lr 404: e732f61c udiv r2, ip, r6 408: 47a20a51 sbfxmi r0, r1, #20, #3 40c: e7ee9852 ubfx r9, r2, #16, #15 410: 87dd1d9b bfihi r1, fp, #27, #3 414: e7d0339f bfc r3, #7, #10 418: e8060d6b stmda r6, {r0, r1, r3, r5, r6, r8, sl, fp} 41c: e80438df stmda r4, {r0, r1, r2, r3, r4, r6, r7, fp, ip, sp} 420: e810e1d4 ldmda r0, {r2, r4, r6, r7, r8, sp, lr, pc} 424: e83c9873 ldmda ip!, {r0, r1, r4, r5, r6, fp, ip, pc} 428: e8a931bd stmia r9!, {r0, r2, r3, r4, r5, r7, r8, ip, sp} 42c: e88b55c3 stm fp, {r0, r1, r6, r7, r8, sl, ip, lr} 430: e8bcbd22 ldm ip!, {r1, r5, r8, sl, fp, ip, sp, pc} 434: e8bda10a pop {r1, r3, r8, sp, pc} 438: e92b2219 stmdb fp!, {r0, r3, r4, r9, sp} 43c: e9298dd5 stmdb r9!, {r0, r2, r4, r6, r7, r8, sl, fp, pc} 440: e935605b ldmdb r5!, {r0, r1, r3, r4, r6, sp, lr} 444: e91191a7 ldmdb r1, {r0, r1, r2, r5, r7, r8, ip, pc} 448: e9ab6e6a stmib fp!, {r1, r3, r5, r6, r9, sl, fp, sp, lr} 44c: e98b4507 stmib fp, {r0, r1, r2, r8, sl, lr} 450: e9b053cc ldmib r0!, {r2, r3, r6, r7, r8, r9, ip, lr} 454: e9912de7 ldmib r1, {r0, r1, r2, r5, r6, r7, r8, sl, fp, sp} 458: 2a000075 bcs 634 45c: 4bfffffe blmi 45c 460: 612fff10 bxvs r0 464: e12fff33 blx r3 468: eafffffe b 468 46c: ebfffffe bl 46c 470: 612fff10 bxvs r0 474: e12fff35 blx r5 478: da00006d ble 634 47c: 4bfffffe blmi 47c 480: 112fff19 bxne r9 484: e12fff3c blx ip 488: eafffedc b 0 48c: 8bfffffe blhi 48c 490: 712fff11 bxvc r1 494: c12fff37 blxgt r7 498: aafffed8 bge 0 49c: 8bfffffe blhi 49c 4a0: e12fff1c bx ip 4a4: 312fff37 blxcc r7 4a8: eafffffe b 4a8 4ac: cbfffed3 blgt 0 4b0: a12fff11 bxge r1 4b4: e12fff30 blx r0 4b8: eafffffe b 4b8 4bc: eb00005c bl 634 4c0: c12fff1e bxgt lr 4c4: 112fff3b blxne fp 4c8: 2afffffe bcs 4c8 4cc: ebfffffe bl 4cc 4d0: 212fff1a bxcs sl 4d4: e12fff34 blx r4 4d8: eafffec8 b 0 4dc: ebfffffe bl 4dc 4e0: 312fff1c bxcc ip 4e4: e12fff38 blx r8 4e8: ea000051 b 634 4ec: ebfffffe bl 4ec 4f0: e12fff1a bx sl 4f4: e12fff31 blx r1 4f8: 4e042a06 vmlami.f32 s4, s8, s12 4fc: ee052a45 vmls.f32 s4, s10, s10 500: ee151a46 vnmla.f32 s2, s10, s12 504: be134a04 vnmlslt.f32 s8, s6, s8 508: 4e263a47 vnmulmi.f32 s6, s12, s14 50c: ee310a00 vadd.f32 s0, s2, s0 510: ee321a45 vsub.f32 s2, s4, s10 514: 2e810a06 vdivcs.f32 s0, s2, s12 518: ee030b06 vmla.f64 d0, d3, d6 51c: ee010b45 vmls.f64 d0, d1, d5 520: ee141b46 vnmla.f64 d1, d4, d6 524: 1e110b01 vnmlsne.f64 d0, d1, d1 528: 1e253b45 vnmulne.f64 d3, d5, d5 52c: 3e320b04 vaddcc.f64 d0, d2, d4 530: ee321b44 vsub.f64 d1, d2, d4 534: 4e810b05 vdivmi.f64 d0, d1, d5 538: eeb03ac3 vabs.f32 s6, s6 53c: 5eb13a44 vnegpl.f32 s6, s8 540: eeb10ac4 vsqrt.f32 s0, s8 544: eeb00bc4 vabs.f64 d0, d4 548: eeb11b44 vneg.f64 d1, d4 54c: eeb10bc1 vsqrt.f64 d0, d1 550: 5e00ea10 vmovpl s0, lr 554: ee14ba10 vmov fp, s8 558: bc4ebb11 vmovlt d1, fp, lr 55c: ec557b15 vmov r7, r5, d5 560: eeb04a46 vmov.f32 s8, s12 564: 8eb01b42 vmovhi.f64 d1, d2 568: 6eb72a00 vmovvs.f32 s4, #112 ; 0x70 56c: eeb72b00 vmov.f64 d2, #112 ; 0x70 570: eeb03a00 vmov.f32 s6, #0 574: eeb01b00 vmov.f64 d1, #0 578: ed952a1d vldr s4, [r5, #116] ; 0x74 57c: 3d811a0e vstrcc s2, [r1, #56] ; 0x38 580: 1d957b04 vldrne d7, [r5, #16] 584: ed816b39 vstr d6, [r1, #228] ; 0xe4 00000588 : 588: ed9f1a0e vldr s2, [pc, #56] ; 5c8 58c: ed8f3a0d vstr s6, [pc, #52] ; 5c8 590: bd1f2b04 vldrlt d2, [pc, #-16] ; 588 594: cd0f3b02 vstrgt d3, [pc, #-8] ; 594 598: 3d9f2a0a vldrcc s4, [pc, #40] ; 5c8 59c: ed8f0a09 vstr s0, [pc, #36] ; 5c8 5a0: cd9f4b08 vldrgt d4, [pc, #32] ; 5c8 5a4: ed0f0b09 vstr d0, [pc, #-36] ; 588 5a8: ed9f4a06 vldr s8, [pc, #24] ; 5c8 5ac: ed8f3a05 vstr s6, [pc, #20] ; 5c8 5b0: 5d1f4b0c vldrpl d4, [pc, #-48] ; 588 5b4: ed0f5b0d vstr d5, [pc, #-52] ; 588 5b8: 9d9f4a02 vldrls s8, [pc, #8] ; 5c8 5bc: 3d0f6a02 vstrcc s12, [pc, #-8] ; 5bc 5c0: ed9f6b00 vldr d6, [pc] ; 5c8 5c4: bd0f1b01 vstrlt d1, [pc, #-4] ; 5c8 000005c8 : 5c8: ec912a01 vldmia r1, {s4} 5cc: 2ca62a01 vstmiacs r6!, {s4} 5d0: ecb91b08 vldmia r9!, {d1-d4} 5d4: eca36b04 vstmia r3!, {d6-d7} 5d8: 6d323a01 vldmdbvs r2!, {s6} 5dc: ed267a01 vstmdb r6!, {s14} 5e0: ed3d4b08 vldmdb sp!, {d4-d7} 5e4: ed205b06 vstmdb r0!, {d5-d7} 5e8: eeb41a41 vcmp.f32 s2, s2 5ec: 7eb44ac4 vcmpevc.f32 s8, s8 5f0: eeb40b46 vcmp.f64 d0, d6 5f4: aeb43bc7 vcmpege.f64 d3, d7 5f8: beb51a40 vcmplt.f32 s2, #0.0 5fc: ceb57ac0 vcmpegt.f32 s14, #0.0 600: eeb54b40 vcmp.f64 d4, #0.0 604: eeb51bc0 vcmpe.f64 d1, #0.0 608: 6ebd1ac3 vcvtvs.s32.f32 s2, s6 60c: cebc3ac7 vcvtgt.u32.f32 s6, s14 610: 3eb80ac1 vcvtcc.f32.s32 s0, s2 614: 3eb81a42 vcvtcc.f32.u32 s2, s4 618: 8ebd2bc4 vcvthi.s32.f64 s4, d4 61c: 8ebc3bc6 vcvthi.u32.f64 s6, d6 620: 9eb73bc7 vcvtls.f32.f64 s6, d7 624: eeb83bc4 vcvt.f64.s32 d3, s8 628: 0eb85b47 vcvteq.f64.u32 d5, s14 62c: eeb74ac5 vcvt.f64.f32 d4, s10 630: e120017a bkpt 0x001a */ static const unsigned int insns[] = { 0xe082852b, 0x009310c7, 0xe0290284, 0xc0329066, 0xc04c000e, 0x00528364, 0xe069818d, 0x60708864, 0xd08597a1, 0xe09d12c6, 0xc0adb0c7, 0xe0b80329, 0xe0c392e6, 0x80dd1845, 0x30e28486, 0xe0f4a76d, 0x118db785, 0xe19a9764, 0xe1cd90e5, 0xe1d20547, 0xe086d777, 0x809c4776, 0x90265c57, 0xe035841d, 0xe04c2055, 0x20539c17, 0xc06c9614, 0xe072811c, 0xe08c4d1d, 0xe09b8d76, 0x10a20415, 0xe0beb256, 0x80ca835e, 0xe0dc1615, 0x60e54a7e, 0xe0fc181d, 0x61818076, 0xe19db577, 0xe1ce4216, 0xe1dba31d, 0x828d8261, 0xe29ed69b, 0xe226e87d, 0xe2332f49, 0xe24d46d9, 0xb25e1402, 0xe2650325, 0x3274882f, 0xb2849102, 0xe2948902, 0x22aeac2a, 0xe2b6aabd, 0xe2cc2426, 0xe2da85a5, 0xe2e6d871, 0x12fba6e9, 0x638737ff, 0x03952951, 0x63c18eea, 0x33d2020a, 0xe118028d, 0xe13601a7, 0xe15c0164, 0xb1750807, 0xe112073e, 0x31300572, 0x915e0b37, 0x617a0b17, 0xe3120585, 0x433e071b, 0xe355030e, 0x3377010a, 0xe1a00b84, 0xe1b01484, 0xe1a001aa, 0xe1b00a2a, 0xe1a015c9, 0x61b0254b, 0x31a08fe2, 0xe1b0946c, 0xe1a0877e, 0xe1b0c473, 0xc1a0ce1d, 0xe1b0c61d, 0xc1a00931, 0xc1b0bc33, 0xd1a0265c, 0xb1b0165a, 0xe1a0a003, 0xe1b00009, 0x73a03e29, 0xe3b0497e, 0xe1a0c1a6, 0x71b0554d, 0xe1a0137e, 0x01b0897c, 0x330cbf31, 0x33429bf7, 0xd001059d, 0xe0100b9a, 0xe0207c93, 0x0038639b, 0xe084e695, 0xe0940796, 0xe0a08e9b, 0xe0b4b79e, 0x20c51796, 0x40db059c, 0xe0498592, 0x0060ed94, 0x510d9054, 0x4125005c, 0xe1473055, 0xe1649052, 0xe101658c, 0xe1006cca, 0xe108e3a1, 0xe10176ed, 0xe1206483, 0xe12b7ec4, 0xe14a0786, 0x914b3ec4, 0xe14b8ca3, 0xe14185e3, 0x21220dac, 0xe12806ec, 0xa1620e86, 0xe16807cc, 0x016a0ea3, 0xe1600de3, 0xe697a009, 0xe5d900c4, 0xe1b4e0b6, 0xe1f96ed8, 0xe09120f1, 0xe6890004, 0xe5e5305c, 0xe1c82ab0, 0xe79c8008, 0xe4dab010, 0xe19ab0b6, 0xe1bb50da, 0xe19360f7, 0xe7ad7005, 0xe5ca2000, 0xe08460b3, 0xe59ca000, 0xe4db4084, 0xe09990bc, 0xe0d399d4, 0xe1f2b9f4, 0xe78db00b, 0xe7cd100a, 0xe08ea0b9, 0xe7b36004, 0xe7f6400d, 0xe09760ba, 0xe1b600db, 0xe096a0fd, 0xe783700c, 0xe7e83001, 0xe1cc44b0, 0xe51f1008, 0xe55f7008, 0xe15f21b0, 0xe15fa0d8, 0xe1dfe3f8, 0xe51f2008, 0xe55f3008, 0xe1df72bc, 0xe15fd0d8, 0xe15fa2fc, 0xe51f5008, 0xe5dfe01c, 0xe1df51b8, 0xe15f63dc, 0xe15fb4f0, 0xe59f700c, 0xe5df5008, 0xe15fa4bc, 0xe1df60d0, 0xe15f90f8, 0xe690036a, 0xe7d8348e, 0xe78d5783, 0xe6c99145, 0xe7945360, 0xe7d0e4a4, 0xe68c52cc, 0xe7e13667, 0xe7b26063, 0xe7fe8842, 0xe7a363e6, 0xe7c83502, 0xe79db40e, 0xe7fda20c, 0xe789d142, 0xe7eb774e, 0xe19bcf9f, 0xe1dc4f9f, 0xe1fbbf9f, 0xe18e1f97, 0xe1c4cf96, 0x21e74f96, 0xe6143f17, 0xe61a9f33, 0xe615cf56, 0xe615cf7e, 0xe61a0f97, 0x66180ff2, 0x5624bf15, 0x6623bf3c, 0xe6230f55, 0xe61caf75, 0x3626af9e, 0xe62baff7, 0x56349f1e, 0xe63e1f37, 0x363b9f55, 0xa6313f7b, 0xc635df97, 0xe6351ff7, 0xe654af17, 0x26591f37, 0xe65dbf57, 0xe654bf7e, 0x365d2f97, 0xc65a8ffe, 0xe66c3f1d, 0xe66d4f36, 0xe66a1f5e, 0xd66d2f7e, 0xe66c1f95, 0xc6640ffd, 0x867a0f15, 0xd674bf37, 0xa67e1f59, 0xe67b2f7e, 0xa6749f95, 0x867d2ffe, 0xe683a877, 0x26a59c77, 0xe6b53477, 0xe6c48476, 0x06eb007d, 0xe6fc9075, 0xa68f387b, 0x86af2076, 0xc6bf3c7d, 0xe6cfc875, 0xe6efc875, 0xe6ff8875, 0x06bfaf34, 0xa6bf8fbc, 0xe6ffef37, 0xc6ffdfb7, 0xe719fe1d, 0xe732f61c, 0x47a20a51, 0xe7ee9852, 0x87dd1d9b, 0xe7d0339f, 0xe8060d6b, 0xe80438df, 0xe810e1d4, 0xe83c9873, 0xe8a931bd, 0xe88b55c3, 0xe8bcbd22, 0xe8bda10a, 0xe92b2219, 0xe9298dd5, 0xe935605b, 0xe91191a7, 0xe9ab6e6a, 0xe98b4507, 0xe9b053cc, 0xe9912de7, 0x2a000075, 0x4bfffffe, 0x612fff10, 0xe12fff33, 0xeafffffe, 0xebfffffe, 0x612fff10, 0xe12fff35, 0xda00006d, 0x4bfffffe, 0x112fff19, 0xe12fff3c, 0xeafffedc, 0x8bfffffe, 0x712fff11, 0xc12fff37, 0xaafffed8, 0x8bfffffe, 0xe12fff1c, 0x312fff37, 0xeafffffe, 0xcbfffed3, 0xa12fff11, 0xe12fff30, 0xeafffffe, 0xeb00005c, 0xc12fff1e, 0x112fff3b, 0x2afffffe, 0xebfffffe, 0x212fff1a, 0xe12fff34, 0xeafffec8, 0xebfffffe, 0x312fff1c, 0xe12fff38, 0xea000051, 0xebfffffe, 0xe12fff1a, 0xe12fff31, 0x4e042a06, 0xee052a45, 0xee151a46, 0xbe134a04, 0x4e263a47, 0xee310a00, 0xee321a45, 0x2e810a06, 0xee030b06, 0xee010b45, 0xee141b46, 0x1e110b01, 0x1e253b45, 0x3e320b04, 0xee321b44, 0x4e810b05, 0xeeb03ac3, 0x5eb13a44, 0xeeb10ac4, 0xeeb00bc4, 0xeeb11b44, 0xeeb10bc1, 0x5e00ea10, 0xee14ba10, 0xbc4ebb11, 0xec557b15, 0xeeb04a46, 0x8eb01b42, 0x6eb72a00, 0xeeb72b00, 0xeeb03a00, 0xeeb01b00, 0xed952a1d, 0x3d811a0e, 0x1d957b04, 0xed816b39, 0xed9f1a0e, 0xed8f3a0d, 0xbd1f2b04, 0xcd0f3b02, 0x3d9f2a0a, 0xed8f0a09, 0xcd9f4b08, 0xed0f0b09, 0xed9f4a06, 0xed8f3a05, 0x5d1f4b0c, 0xed0f5b0d, 0x9d9f4a02, 0x3d0f6a02, 0xed9f6b00, 0xbd0f1b01, 0xec912a01, 0x2ca62a01, 0xecb91b08, 0xeca36b04, 0x6d323a01, 0xed267a01, 0xed3d4b08, 0xed205b06, 0xeeb41a41, 0x7eb44ac4, 0xeeb40b46, 0xaeb43bc7, 0xbeb51a40, 0xceb57ac0, 0xeeb54b40, 0xeeb51bc0, 0x6ebd1ac3, 0xcebc3ac7, 0x3eb80ac1, 0x3eb81a42, 0x8ebd2bc4, 0x8ebc3bc6, 0x9eb73bc7, 0xeeb83bc4, 0x0eb85b47, 0xeeb74ac5, 0xe120017a, }; // END Generated code -- do not edit // reset the detected cpu feature set VM_Version::features(detected_features); { bool ok = true; unsigned int *insns1 = (unsigned int *)entry; for (unsigned int i = 0; i < sizeof insns / sizeof insns[0]; i++) { if (insns[i] != insns1[i]) { ok = false; printf("Ours:\n"); Disassembler::decode((address)&insns1[i], (address)&insns1[i+1]); printf(" Raw: 0x%x\n", insns1[i]); printf("Theirs:\n"); Disassembler::decode((address)&insns[i], (address)&insns[i+1]); printf(" Raw: 0x%x\n", insns[i]); printf("\n"); } } assert(ok, "Assembler smoke test failed"); } #endif // ASSERT } #undef __ void Address::AddressConstruct(Register base, RegisterOrConstant index, enum reg_op op, shift_op shift, enum wb_mode mode) { _base = base; _wb_mode = mode; _shift = shift; _target = 0; if (index.is_register()) { _acc_mode = reg; _index = index.as_register(); _offset = 0; _as_op = op; } else { assert(shift == lsl(), "should be"); assert(index.is_constant(), "should be"); _acc_mode = imm; // _index = no_reg; _offset = index.as_constant(); if(SUB == _as_op) _offset = -_offset; } } void Address::encode(Instruction_aarch32 *i, CodeSection *sec, address pc) const { long offset = _offset; access_mode mode = _acc_mode; if(lit == mode) { //Create the offset from the address offset = _target - pc; mode = imm; } //Correct the offset if the base is the PC if(r15_pc == _base && imm == mode) { offset -= 8; } int U = (offset >= 0 && _acc_mode == imm) || (_as_op == ADD && _acc_mode == reg); int P = pre == _wb_mode || off == _wb_mode; int W = pre == _wb_mode; i->f(P, 24), i->f(U, 23), i->f(W, 21), i->rf(_base, 16); offset = offset < 0 ? -offset : offset; int opc = i->get(27, 25); if (imm == mode) { switch(opc) { case 0b010: // LDR, LDRB // STR, STRB i->f(offset, 11, 0); break; case 0b000: // LDRH, LDRSH, LDRSB, LDRD // STRH, STRD i->f(1, 22); assert(offset < (1 << 8), "Offset larger than a byte"); i->f(offset & 0xF, 3, 0); i->f(offset >> 4, 11, 8); break; default: ShouldNotReachHere(); } } else if (reg == mode) { assert(r15_pc->encoding_nocheck() != _base->encoding_nocheck(), "Remove this if you have your offsets right"); switch(opc) { case 0b010: // LDR, LDRB // STR, STRB //Need to set bit 25 as Register 0b011 i->f(1, 25); i->f(_shift.shift(), 11, 7); i->f(_shift.kind(), 6, 5); i->f(0, 4); i->rf(_index, 0); break; case 0b000: // LDRH, LDRSH, LDRSB, LDRD // STRH, STRD //Need to clear bit 22 as Register i->f(0, 22); assert(_shift == lsl(), "Type of load/store does not support shift"); i->f(0b0000, 11, 8); i->rf(_index, 0); break; default: ShouldNotReachHere(); } } else { ShouldNotReachHere(); } if(lit == _acc_mode) { sec->relocate(pc, _rspec); } } void Address::fp_encode(Instruction_aarch32 *i, CodeSection *sec, address pc) const { // ATM works only for immediate assert(_wb_mode == off, "Can't do pre or post addressing for vldr, vstr"); long offset = _offset; if(imm == _acc_mode) { if(r15_pc == _base) { //Correct the offset if the base is the PC offset -= 8; } bool U = offset >= 0; assert(0 == (offset & 3), "Can only access aligned data"); unsigned imm8 = uabs(offset) / 4; i->f(U, 23), i->rf(_base, 16), i->f(imm8, 7, 0); } else { ShouldNotReachHere(); } } #define __ as-> void Address::lea(MacroAssembler *as, Register r) const { Relocation* reloc = _rspec.reloc(); relocInfo::relocType rtype = (relocInfo::relocType) reloc->type(); //TODO Potentially remove this - added as aarch64 doesn't contain // any method of handling pre or post assert( _wb_mode != pre && _wb_mode != post, "Wrong wb mode"); // could probably permit post however switch(_acc_mode) { case imm: { if (_offset == 0 && _base == r) // it's a nop break; if (_offset > 0) __ add(r, _base, _offset); else __ sub(r, _base, -_offset); break; } case reg: { __ add(r, _base, _index, _shift); break; } case lit: { if (rtype == relocInfo::none) __ mov(r, target()); else __ movptr(r, (uint32_t)target()); break; } default: ShouldNotReachHere(); } } #undef __ #define __ as-> class Address; // Adapts given Address to the capabilities of instructions respective to the // provided data type. E.g. some of the instructions cannot use index register // while others cannot have an offset field. // Returns a copy of this Address is it's good or constructs a new Address // good for respective instructions by emitting necessary code to calculate // the address in tmp register Address Address::safe_for(InsnDataType type, MacroAssembler *as, Register tmp) { if (is_safe_for(type)) return *this; assert(tmp->is_valid(), "must be"); lea(as, tmp); return Address(tmp); } #undef __ bool Address::is_safe_for(InsnDataType type) { switch (_acc_mode) { case imm: case lit: return offset_ok_for_immed(_offset, type); case reg: return shift_ok_for_index(_shift, type); case no_mode: default: ShouldNotReachHere(); return false; } } bool Address::offset_ok_for_immed(long offset, InsnDataType type) { const int o = offset < 0 ? -offset : offset; switch (type) { case IDT_INT: case IDT_BOOLEAN: case IDT_OBJECT: case IDT_ADDRESS: case IDT_METADATA: case IDT_ARRAY: return o <= 0xfff; case IDT_BYTE: case IDT_SHORT: case IDT_LONG: case IDT_CHAR: return o <= 0xff; case IDT_FLOAT: case IDT_DOUBLE: return !(o & ~0x3fc); case IDT_LEA: return true; case IDT_MULTIWORD: return !o; default: ShouldNotReachHere(); return false; } } bool Address::shift_ok_for_index(shift_op shift, InsnDataType type) { switch (type) { case IDT_INT: case IDT_BOOLEAN: case IDT_OBJECT: case IDT_ADDRESS: case IDT_METADATA: case IDT_ARRAY: return !shift.is_register(); case IDT_BYTE: case IDT_SHORT: case IDT_LONG: case IDT_CHAR: return !shift.is_register() && shift.shift() == 0; case IDT_LEA: return true; case IDT_FLOAT: case IDT_DOUBLE: case IDT_MULTIWORD: return false; default: ShouldNotReachHere(); return false; } } void Assembler::emit_data64(jlong data, relocInfo::relocType rtype, int format) { if (rtype == relocInfo::none) { emit_int64(data); } else { emit_data64(data, Relocation::spec_simple(rtype), format); } } void Assembler::emit_data64(jlong data, RelocationHolder const& rspec, int format) { assert(inst_mark() != NULL, "must be inside InstructionMark"); // Do not use AbstractAssembler::relocate, which is not intended for // embedded words. Instead, relocate to the enclosing instruction. code_section()->relocate(inst_mark(), rspec, format); emit_int64(data); } extern "C" { void das(uint64_t start, int len) { ResourceMark rm; len <<= 2; if (len < 0) Disassembler::decode((address)start + len, (address)start); else Disassembler::decode((address)start, (address)start + len); } JNIEXPORT void das1(unsigned long insn) { das(insn, 1); } } #define starti Instruction_aarch32 do_not_use(this); set_current(&do_not_use) void Assembler::adr(Register Rd, address adr, Condition cond) { int offset = adr - pc() - 8; adr_encode(Rd, offset, cond); } #undef starti Address::Address(address target, relocInfo::relocType rtype) : _acc_mode(lit), _base(sp), _offset(0), _wb_mode(off) { //TODO we don't complete _wb_mode - what about Addresses that are pre/post accessed? _is_lval = false; _target = target; switch (rtype) { case relocInfo::oop_type: case relocInfo::metadata_type: // Oops are a special case. Normally they would be their own section // but in cases like icBuffer they are literals in the code stream that // we don't have a section for. We use none so that we get a literal address // which is always patchable. break; case relocInfo::external_word_type: _rspec = external_word_Relocation::spec(target); break; case relocInfo::internal_word_type: _rspec = internal_word_Relocation::spec(target); break; case relocInfo::opt_virtual_call_type: _rspec = opt_virtual_call_Relocation::spec(); break; case relocInfo::static_call_type: _rspec = static_call_Relocation::spec(); break; case relocInfo::runtime_call_type: _rspec = runtime_call_Relocation::spec(); break; case relocInfo::poll_type: case relocInfo::poll_return_type: _rspec = Relocation::spec_simple(rtype); break; case relocInfo::none: _rspec = RelocationHolder::none; break; default: ShouldNotReachHere(); break; } } void Assembler::adr(Register r, const Address &dest, Condition cond) { code_section()->relocate(pc(), dest.rspec()); adr(r, dest.target()); } void Assembler::wrap_label(Label &L, Assembler::uncond_branch_insn insn) { if (L.is_bound()) { (this->*insn)(target(L)); } else { L.add_patch_at(code(), locator()); (this->*insn)(pc()); } } void Assembler::wrap_label(Label &L, Condition cond, Assembler::cond_branch_insn insn) { if (L.is_bound()) { (this->*insn)(target(L), cond); } else { L.add_patch_at(code(), locator()); (this->*insn)(pc(), cond); } } void Assembler::wrap_label(Register r, Label &L, Condition cond, Assembler::cond_ldst_insn insn) { if (L.is_bound()) { (this->*insn)(r, target(L), cond); } else { L.add_patch_at(code(), locator()); (this->*insn)(r, pc(), cond); } } void Assembler::wrap_label(FloatRegister r, Label &L, Condition cond, Assembler::cond_fp_ldst_insn insn) { if (L.is_bound()) { (this->*insn)(r, target(L), cond); } else { L.add_patch_at(code(), locator()); (this->*insn)(r, pc(), cond); } } uint32_t Assembler::encode_imm12(int imm) { assert(is_valid_for_imm12(imm), "only valid immediates allowed, call is_valid_for_imm12 first"); uint32_t n = imm; if ((n & 0xFFFFFF00) == 0) { return n; } if ((n & 0xFC000000) == 0) { const int lshift = __builtin_ctz(n) & 0xFFFFFFFE; return ((32 - lshift) << 7) | (n >> lshift); } n = (n << 16) | (n >> 16); const int lshift = __builtin_ctz(n) & 0xFFFFFFFE; return ((16 - lshift) << 7) | (n >> lshift); } int Assembler::decode_imm12(uint32_t imm12) { assert((imm12 & 0xFFFFF000) == 0, "bad imm12"); uint32_t shift = (imm12 & 0x00000F00) >> 7; uint32_t value = imm12 & 0x000000FF; return (int) ((value >> shift) | (value << (32 - shift))); } bool Assembler::is_valid_for_imm12(int imm) { uint32_t n = (uint32_t) imm; uint32_t shift = __builtin_clz(n) & 0xFFFFFFFE; uint32_t result = n << shift; if ((result & 0x00FFFFFF) == 0) { return true; } n = (n << 16) | (n >> 16); shift = __builtin_clz(n) & 0xFFFFFFFE; result = n << shift; if ((result & 0x00FFFFFF) == 0) { return true; } return false; } bool Assembler::operand_valid_for_logical_immediate(bool is32, uint64_t imm) { return is32 && is_valid_for_imm12(imm); } bool Assembler::operand_valid_for_add_sub_immediate(int imm) { return is_valid_for_imm12(imm); } bool Assembler::operand_valid_for_add_sub_immediate(unsigned long imm) { return is_valid_for_imm12(imm); } bool Assembler::operand_valid_for_add_sub_immediate(unsigned imm) { return is_valid_for_imm12(imm); } bool Assembler::operand_valid_for_add_sub_immediate(jlong imm) { return is_valid_for_imm12(imm >> 32) && is_valid_for_imm12(imm); } // n.b. this is implemented in subclass MacroAssembler void Assembler::bang_stack_with_offset(int offset) { Unimplemented(); } int AbstractAssembler::code_fill_byte() { return 0; } void Assembler::mov_immediate(Register dst, uint32_t imm32, Condition cond, bool s) { #ifndef PRODUCT { char buffer[64]; snprintf(buffer, sizeof(buffer), "0x%"PRIX32, imm32); block_comment(buffer); } #endif if(is_valid_for_imm12(imm32)) { if(s) movs_i(dst, (unsigned)imm32, cond); else mov_i (dst, (unsigned)imm32, cond); } else if(is_valid_for_imm12(~imm32)) { if(s) mvns_i(dst, (unsigned)~imm32, cond); else mvn_i (dst, (unsigned)~imm32, cond); } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) && (imm32 < (1 << 16))) { movw_i(dst, (unsigned)imm32, cond); } else if (!s && VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2) && !(imm32 & ((1 << 16) - 1))) { movw_i(dst, (unsigned)0, cond); movt_i(dst, (unsigned)(imm32 >> 16), cond); } else { // TODO Could expand to varied numbers of mov and orrs //Need to do a full 32 bits mov_immediate32(dst, imm32, cond, s); } } //This should really be in the macroassembler void Assembler::mov_immediate32(Register dst, uint32_t imm32, Condition cond, bool s) { // Need to move a full 32 bit immediate, for example if we're loading an address that // might change later and therefore need to be updated. if (VM_Version::features() & (FT_ARMV7 | FT_ARMV6T2)) { //Use a movw and a movt Assembler::movw_i(dst, (unsigned)(imm32 & 0xffff), cond); Assembler::movt_i(dst, (unsigned)(imm32 >> 16), cond); if(s) { //Additionally emit a cmp instruction Assembler::cmp(dst, 0); } } else { // Sadly we don't have movw, movt // instead emit a mov and three orr mov_i(dst, imm32 & (0xff ), cond); orr(dst, dst, imm32 & (0xff << 8 ), cond); orr(dst, dst, imm32 & (0xff << 16), cond); if(s) orrs(dst, dst, imm32 & (0xff << 24), cond); else orr (dst, dst, imm32 & (0xff << 24), cond); } } #define starti Instruction_aarch32 do_not_use(this); set_current(&do_not_use) void Assembler::add_sub_imm(int decode, Register Rd, Register Rn, int imm, Condition cond, bool s) { int cpart = 0; switch(decode) { case 0b0100: cpart = 0b0010; break; // ADD -> SUB case 0b0010: // SUB -> ADD case 0b0011: cpart = 0b0100; break; // RSB -> ADD case 0b0101: cpart = 0b0110; break; // ADC -> SUBC case 0b0110: // SUBC -> ADC case 0b0111: cpart = 0b0101; break; // RSC -> ADC default: ShouldNotReachHere(); } //try both possible imm_instrs if(imm_instr(decode, Rd, Rn, imm, cond, s)) return; if(imm_instr(cpart, Rd, Rn, -imm, cond, s)) return; //Try plan B - a mov first - need to have destination that is not an arg assert(Rd != Rn, "Can't use imm and can't do a mov. I'm in a jam."); mov_immediate(Rd, (uint32_t)uabs(imm), cond, s); //Now do the non immediate version - copied from the immediate encodings { starti; reg_instr( imm < 0 ? cpart : decode, lsl(), cond, s); rf(Rn, 16), rf(Rd, 12), rf(Rd, 0); } } void Assembler::vmov_imm(FloatRegister Rd, unsigned imm, bool is64bit, Condition cond) { starti; fp_instr_base(is64bit, cond); f(0b1011, 23, 20); // double register passed (see 'd0'-'dN' encoding), not reencode it's number fp_rencode(Rd, false, 12, 22); f(0b0000, 7, 4); f(imm & 0xf, 3, 0); f(imm >> 4, 19, 16); } void Assembler::vmov_imm_zero(FloatRegister Rd, bool is64bit, Condition cond) { // Note that this is not a floating point vmov but instead // an integer vmov from the SIMD instructions. // cannot be conditional. assert(operand_valid_for_double_immediate(0), "operand should be valid for immediate"); assert(is64bit, "SIMD loading available only for double registers"); assert(cond == C_DFLT, "Unable to vmov #0 conditionally"); //int cmod = is64bit? 0b1110 : 0b0000; // ? I64 : I32 int cmod = 0b1110; { starti; f(0b1111001, 31, 25); f(0, 24); // imm1 f(0b10000, 23, 19); // double register passed (see 'd0'-'dN' encoding), not reencode it's number fp_rencode(Rd, false, 12, 22); f(0b000, 18, 16); //imm3 f(cmod, 11, 8); f(0b00, 7, 6); f(is64bit, 5); f(1, 4); f(0b0000, 3, 0); //imm4 } } bool Assembler::operand_valid_for_float_immediate(float v) { if (!(VM_Version::features() & FT_VFPV3)) { return false; } union ufloat { float f; uint32_t u; } imm; unsigned tmp; imm.f = v; if (imm.u & ((1 << 19) - 1)) return false; tmp = (imm.u >> 25) & ((1 << 6) - 1); return tmp == 32 || tmp == 31; } bool Assembler::operand_valid_for_double_immediate(double v) { if (!(VM_Version::features() & FT_VFPV3)) { return false; } union ufloat { double f; uint64_t u; } imm; unsigned tmp; imm.f = v; if ((VM_Version::features() & FT_AdvSIMD) && imm.u == 0) return true; if (imm.u & (uint64_t) 0xffffffffffffLL) return false; imm.u >>= 48; tmp = (imm.u >> 6) & ((1 << 9) - 1); return tmp == 0x100 || tmp == 0xff; } unsigned Assembler::encode_float_fp_imm(float imm_f) { assert(operand_valid_for_float_immediate(imm_f), "operand should be valid for immediate"); union ufloat { float f; uint32_t u; } imm; unsigned tmp, imm8; imm.f = imm_f; assert(!(imm.u & ((1 << 19) - 1)), "Invalid float imm"); tmp = (imm.u >> 25) & ((1 << 6) - 1); assert(tmp == 32 || tmp == 31, "Invalid float imm"); imm8 = (imm.u >> 24) & 0x80; // set a imm8 |= (imm.u >> 19) & 0x7F; // set bcdefgh return imm8; } unsigned Assembler::encode_double_fp_imm(double imm_f) { assert(operand_valid_for_double_immediate(imm_f), "operand should be valid for immediate"); union ufloat { double f; uint64_t u; } imm; unsigned tmp, imm8; imm.f = imm_f; assert(!(imm.u & (uint64_t)0xffffffffffffLL), "Invalid float imm"); imm.u >>= 48; tmp = (imm.u >> 6) & ((1 << 9) - 1); assert(tmp == 0x100 || tmp == 0xff, "Invalid float imm"); imm8 = (imm.u >> 8) & 0x80; // set a imm8 |= imm.u & 0x7F; // set bcdefgh return imm8; } unsigned Assembler::count_bits(unsigned val) { unsigned i, count; for(i = 0, count = 0; i < 8 * sizeof(val); val >>= 1, i++) if( val & 1 ) count++; return count; } bool Assembler::can_ldst_multiple( unsigned regset, const Address& adr) { int nbits = count_bits(regset); return adr.get_mode() == Address::imm && !(adr.base()->bit() & regset) && // FIXME, this could be relaxed (((adr.offset() == 0 || adr.offset() == wordSize || adr.offset() == -nbits * wordSize) && (adr.get_wb_mode() == Address::pre || adr.get_wb_mode() == Address::off)) || ((adr.offset() == 0 || adr.offset() == -wordSize || adr.offset() == nbits * wordSize) && adr.get_wb_mode() == Address::post)); } void Assembler::fp_ldst_instr(int decode, bool is64bit, const Address& adr, Condition cond) { f(cond, 31, 28), f(0b110, 27, 25), f(decode, 24, 20); f(0b101, 11, 9), f(is64bit, 8); adr.fp_encode(current, code_section(), pc()); } void Assembler::fp_ldst_mul(Register Rn, int regset, bool load, bool is64bit, enum fp_mode mode, Condition cond) { starti; bool P = db_wb == mode; bool U = ia_wb == mode || ia == mode; bool W = ia_wb == mode || db_wb == mode; // Encode registers unsigned i, fp_first_reg, nregs = 1; bool enc_z = false; for(fp_first_reg = 0; !(regset & 1); regset >>= 1, fp_first_reg++); FloatRegister Rd = (FloatRegister) fp_first_reg; for(i = 0; i + fp_first_reg < 8 * sizeof(int); i++) { regset >>= 1; if(regset & 1) { assert(!enc_z, "Unable to encode non-consecutive registers in fp_ldst_mul"); nregs++; } else { enc_z = true; } } assert(!is64bit || nregs <= 16, "Too many registers in a set"); f(cond, 31, 28), f(0b110, 27, 25); f(P, 24), f(U, 23), f(W, 21), f(load, 20); // vstm/vstm uses double register number, not it's encoding. Should reencode it. rf(Rn, 16), fp_rencode(Rd, is64bit, 12, 22), f(0b101, 11, 9), f(is64bit, 8); f(is64bit ? nregs * 2 : nregs, 7, 0); } void Assembler::simd_ld(FloatRegister Rd, unsigned type, unsigned size, unsigned num_regs, const Address &addr, enum SIMD_Align align) { starti; assert(addr.get_mode() == Address::imm && (addr.get_wb_mode() == Address::off && addr.offset() == 0) || (addr.get_wb_mode() == Address::post && addr.offset() == long(8*num_regs)), "Unsupported"); assert(VM_Version::features() & FT_AdvSIMD, "SIMD coprocessor required"); if (addr.get_wb_mode() == Address::post) f(0b1111, 31, 28), f(0b0100, 27, 24), f(0, 23), f(0b10, 21, 20); rf(addr.base(), 16), fp_rencode(Rd, false, 12, 22), f(type, 11, 8), f(size, 7, 6); f((unsigned)align, 5, 4), f(addr.get_wb_mode() == Address::post ? 0b1101 : 0b1111, 3, 0); } void Assembler::simd_vmov(FloatRegister Dd, unsigned index, Register Rt, bool advsimd, unsigned index_bits, unsigned bit20, unsigned opc, Condition cond) { starti; assert(index < (1u<>2)&3, 22, 21), f(bit20, 20); fp_rencode(Dd, false, 16, 7), f(opc>>4, 23); rf(Rt, 12), f(0b1011, 11, 8), f(opc & 3, 6, 5), f(0b10000, 4, 0); } void Assembler::simd_eor(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, unsigned q) { starti; assert(VM_Version::features() & FT_AdvSIMD, "SIMD coprocessor required"); assert(!q || ((Dd->encoding() & 2) == 0 && (Dm->encoding() & 2) == 0), "Odd registers"); f(0b111100110, 31, 23), f(0b00, 21, 20), fp_rencode(Dd, false, 12, 22); fp_rencode(Dn, false, 16, 7), f(0b0001, 11, 8), fp_rencode(Dm, false, 0, 5), f(q, 6), f(1, 4); } void Assembler::simd_vmul(FloatRegister Dd, FloatRegister Dn, FloatRegister Dm, unsigned bit24, unsigned bit9, unsigned size, unsigned mul, unsigned bit6) { starti; assert(VM_Version::features() & FT_AdvSIMD, "SIMD coprocessor required"); f(0b1111001, 31, 25), f(bit24, 24), f(size, 21, 20), fp_rencode(Dd, false, 12, 22); f(mul^1, 23), fp_rencode(Dn, false, 16, 7), f(1, 11), f(mul^1, 10), f(bit9, 9); f(mul, 8), f(bit6, 6), f(mul, 4), fp_rencode(Dm, false, 0, 5); } void Assembler::simd_vuzp(FloatRegister Dd, FloatRegister Dm, unsigned size, unsigned q) { starti; assert(VM_Version::features() & FT_AdvSIMD, "SIMD coprocessor required"); assert(!q || ((Dd->encoding() & 2) == 0 && (Dm->encoding() & 2) == 0), "Odd registers"); f(0b111100111, 31, 23), fp_rencode(Dd, false, 12, 22), f(0b11, 21, 20), f(size, 19, 18); f(0b10, 17, 16), f(0b00010, 11, 7), f(q, 6), f(0, 4), fp_rencode(Dm, false, 0, 5); } void Assembler::simd_vshl(FloatRegister Dd, FloatRegister Dm, unsigned imm, unsigned size, unsigned q, unsigned bit24, unsigned encode) { starti; assert(VM_Version::features() & FT_AdvSIMD, "SIMD coprocessor required"); assert(imm < (1u << size), "Shift is too big"); assert(!q || ((Dd->encoding() & 2) == 0 && (Dm->encoding() & 2) == 0), "Odd registers"); f(0b1111001, 31, 25), f(bit24, 24), f(1, 23), fp_rencode(Dd, false, 12, 22); f(((1u << size) | imm) & 0b111111, 21, 16), f(size == 6 ? 1 : 0, 7), f(q, 6); f(encode, 11, 8), fp_rencode(Dm, false, 0, 5), f(1, 4); } void Assembler::simd_rev(FloatRegister Dd, FloatRegister Dm, unsigned q, unsigned size, unsigned op) { starti; assert(!q || ((Dd->encoding() & 2) == 0 && (Dm->encoding() & 2) == 0), "Odd registers"); f(0b111100111, 31, 23), fp_rencode(Dd, false, 12, 22), f(0b11, 21, 20); f(size, 19, 18), f(0b00, 17, 16), f(0b000, 11, 9), f(op, 8, 7); f(q, 6), fp_rencode(Dm, false, 0, 5), f(0, 4); } void Assembler::v8_crc32(Register Rd, Register Rn, Register Rm, unsigned size, Condition cond) { starti; assert(VM_Version::features() & FT_CRC32, "Instruction is not supported by CPU"); f(cond, 31, 28), f(0b00010, 27, 23), f(size, 22, 21), f(0, 20), rf(Rn, 16), rf(Rd, 12); f(0b00000100, 11, 4), rf(Rm, 0); } #undef starti