| Dave Allison | 65fcc2c | 2014-04-28 13:45:27 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| Nicolas Geoffray | 96f89a2 | 2014-07-11 10:57:49 +0100 | [diff] [blame] | 17 | #include <dirent.h> |
| Andreas Gampe | fd11470 | 2015-05-13 17:00:41 -0700 | [diff] [blame] | 18 | #include <errno.h> |
| Andreas Gampe | fd11470 | 2015-05-13 17:00:41 -0700 | [diff] [blame] | 19 | #include <string.h> |
| 20 | #include <sys/types.h> |
| David Srbecky | b461b53 | 2020-07-13 17:45:22 +0000 | [diff] [blame] | 21 | |
| Andreas Gampe | 8cf9cb3 | 2017-07-19 09:28:38 -0700 | [diff] [blame] | 22 | #include <fstream> |
| 23 | #include <map> |
| David Srbecky | b461b53 | 2020-07-13 17:45:22 +0000 | [diff] [blame] | 24 | #include <regex> |
| Dave Allison | 65fcc2c | 2014-04-28 13:45:27 -0700 | [diff] [blame] | 25 | |
| 26 | #include "gtest/gtest.h" |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 27 | |
| 28 | #include "jni/quick/calling_convention.h" |
| 29 | #include "utils/arm/jni_macro_assembler_arm_vixl.h" |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 30 | #include "utils/assembler_test_base.h" |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 31 | |
| Dave Allison | 65fcc2c | 2014-04-28 13:45:27 -0700 | [diff] [blame] | 32 | #include "base/hex_dump.h" |
| David Sehr | 3215fff | 2018-04-03 17:10:12 -0700 | [diff] [blame] | 33 | #include "base/malloc_arena_pool.h" |
| Dave Allison | 65fcc2c | 2014-04-28 13:45:27 -0700 | [diff] [blame] | 34 | #include "common_runtime_test.h" |
| 35 | |
| 36 | namespace art { |
| 37 | namespace arm { |
| 38 | |
| 39 | // Include results file (generated manually) |
| 40 | #include "assembler_thumb_test_expected.cc.inc" |
| 41 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 42 | class ArmVIXLAssemblerTest : public AssemblerTestBase { |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 43 | public: |
| Vladimir Marko | 69d310e | 2017-10-09 14:12:23 +0100 | [diff] [blame] | 44 | ArmVIXLAssemblerTest() : pool(), allocator(&pool), assembler(&allocator) { } |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 45 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 46 | protected: |
| 47 | InstructionSet GetIsa() override { return InstructionSet::kThumb2; } |
| 48 | |
| 49 | void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const std::string& expected) { |
| 50 | #ifndef ART_TARGET_ANDROID |
| 51 | std::string obj_file = scratch_dir_->GetPath() + testname + ".o"; |
| 52 | WriteElf</*IsElf64=*/false>(obj_file, InstructionSet::kThumb2, code); |
| 53 | std::string disassembly; |
| 54 | ASSERT_TRUE(Disassemble(obj_file, &disassembly)); |
| 55 | |
| David Srbecky | b461b53 | 2020-07-13 17:45:22 +0000 | [diff] [blame] | 56 | // objdump on buildbot seems to sometimes add annotation like in "bne #226 <.text+0x1e8>". |
| 57 | // It is unclear why it does not reproduce locally. As work-around, remove the annotation. |
| 58 | std::regex annotation_re(" <\\.text\\+\\w+>"); |
| 59 | disassembly = std::regex_replace(disassembly, annotation_re, ""); |
| 60 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 61 | std::string expected2 = "\n" + |
| Yabin Cui | 668daf8 | 2021-08-10 15:42:10 +0000 | [diff] [blame] | 62 | obj_file + ": file format elf32-littlearm\n\n" |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 63 | "Disassembly of section .text:\n\n" |
| Stephen Hines | 331c8e3 | 2020-09-11 17:03:58 -0700 | [diff] [blame] | 64 | "00000000 <.text>:\n" + |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 65 | expected; |
| 66 | EXPECT_EQ(expected2, disassembly); |
| 67 | if (expected2 != disassembly) { |
| 68 | std::string out = " \"" + Replace(disassembly, "\n", "\\n\"\n \"") + "\""; |
| 69 | printf("C++ formatted disassembler output for %s:\n%s\n", testname, out.c_str()); |
| 70 | } |
| 71 | #endif // ART_TARGET_ANDROID |
| 72 | } |
| 73 | |
| 74 | #define __ assembler. |
| 75 | |
| 76 | void EmitAndCheck(const char* testname, const char* expected) { |
| 77 | __ FinalizeCode(); |
| 78 | size_t cs = __ CodeSize(); |
| 79 | std::vector<uint8_t> managed_code(cs); |
| 80 | MemoryRegion code(&managed_code[0], managed_code.size()); |
| 81 | __ FinalizeInstructions(code); |
| 82 | |
| 83 | DumpAndCheck(managed_code, testname, expected); |
| 84 | } |
| 85 | |
| 86 | #undef __ |
| 87 | |
| 88 | #define __ assembler. |
| 89 | |
| David Sehr | 3215fff | 2018-04-03 17:10:12 -0700 | [diff] [blame] | 90 | MallocArenaPool pool; |
| Vladimir Marko | 69d310e | 2017-10-09 14:12:23 +0100 | [diff] [blame] | 91 | ArenaAllocator allocator; |
| Roland Levillain | c043d00 | 2017-07-14 16:39:16 +0100 | [diff] [blame] | 92 | ArmVIXLJNIMacroAssembler assembler; |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 93 | }; |
| 94 | |
| Vladimir Marko | 0e851e2 | 2016-08-25 18:17:56 +0100 | [diff] [blame] | 95 | TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) { |
| Roland Levillain | 6d729a7 | 2017-06-30 18:34:01 +0100 | [diff] [blame] | 96 | // Run the test only with Baker read barriers, as the expected |
| 97 | // generated code contains a Marking Register refresh instruction. |
| 98 | TEST_DISABLED_WITHOUT_BAKER_READ_BARRIERS(); |
| 99 | |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 100 | const bool is_static = true; |
| 101 | const bool is_synchronized = false; |
| Vladimir Marko | 46a8910 | 2021-10-21 13:05:46 +0000 | [diff] [blame] | 102 | const bool is_fast_native = false; |
| Igor Murashkin | 367f3dd | 2016-09-01 17:00:24 -0700 | [diff] [blame] | 103 | const bool is_critical_native = false; |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 104 | const char* shorty = "IIFII"; |
| 105 | |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 106 | std::unique_ptr<JniCallingConvention> jni_conv( |
| Vladimir Marko | 69d310e | 2017-10-09 14:12:23 +0100 | [diff] [blame] | 107 | JniCallingConvention::Create(&allocator, |
| Igor Murashkin | 367f3dd | 2016-09-01 17:00:24 -0700 | [diff] [blame] | 108 | is_static, |
| 109 | is_synchronized, |
| Vladimir Marko | 46a8910 | 2021-10-21 13:05:46 +0000 | [diff] [blame] | 110 | is_fast_native, |
| Igor Murashkin | 367f3dd | 2016-09-01 17:00:24 -0700 | [diff] [blame] | 111 | is_critical_native, |
| 112 | shorty, |
| Vladimir Marko | 33bff25 | 2017-11-01 14:35:42 +0000 | [diff] [blame] | 113 | InstructionSet::kThumb2)); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 114 | std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv( |
| Vladimir Marko | 69d310e | 2017-10-09 14:12:23 +0100 | [diff] [blame] | 115 | ManagedRuntimeCallingConvention::Create( |
| Vladimir Marko | 33bff25 | 2017-11-01 14:35:42 +0000 | [diff] [blame] | 116 | &allocator, is_static, is_synchronized, shorty, InstructionSet::kThumb2)); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 117 | const int frame_size(jni_conv->FrameSize()); |
| 118 | ArrayRef<const ManagedRegister> callee_save_regs = jni_conv->CalleeSaveRegisters(); |
| 119 | |
| 120 | const ManagedRegister method_register = ArmManagedRegister::FromCoreRegister(R0); |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 121 | const ManagedRegister hidden_arg_register = ArmManagedRegister::FromCoreRegister(R4); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 122 | const ManagedRegister scratch_register = ArmManagedRegister::FromCoreRegister(R12); |
| 123 | |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 124 | __ BuildFrame(frame_size, mr_conv->MethodRegister(), callee_save_regs); |
| 125 | |
| 126 | // Spill arguments. |
| 127 | mr_conv->ResetIterator(FrameOffset(frame_size)); |
| 128 | for (; mr_conv->HasNext(); mr_conv->Next()) { |
| 129 | if (mr_conv->IsCurrentParamInRegister()) { |
| 130 | size_t size = mr_conv->IsCurrentParamALongOrDouble() ? 8u : 4u; |
| 131 | __ Store(mr_conv->CurrentParamStackOffset(), mr_conv->CurrentParamRegister(), size); |
| 132 | } |
| 133 | } |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 134 | __ IncreaseFrameSize(32); |
| 135 | |
| 136 | // Loads |
| 137 | __ IncreaseFrameSize(4096); |
| 138 | __ Load(method_register, FrameOffset(32), 4); |
| 139 | __ Load(method_register, FrameOffset(124), 4); |
| 140 | __ Load(method_register, FrameOffset(132), 4); |
| 141 | __ Load(method_register, FrameOffset(1020), 4); |
| 142 | __ Load(method_register, FrameOffset(1024), 4); |
| 143 | __ Load(scratch_register, FrameOffset(4092), 4); |
| 144 | __ Load(scratch_register, FrameOffset(4096), 4); |
| 145 | __ LoadRawPtrFromThread(scratch_register, ThreadOffset32(512)); |
| Andreas Gampe | 3db7068 | 2018-12-26 15:12:03 -0800 | [diff] [blame] | 146 | __ LoadRef(method_register, scratch_register, MemberOffset(128), /* unpoison_reference= */ false); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 147 | |
| 148 | // Stores |
| 149 | __ Store(FrameOffset(32), method_register, 4); |
| 150 | __ Store(FrameOffset(124), method_register, 4); |
| 151 | __ Store(FrameOffset(132), method_register, 4); |
| 152 | __ Store(FrameOffset(1020), method_register, 4); |
| 153 | __ Store(FrameOffset(1024), method_register, 4); |
| 154 | __ Store(FrameOffset(4092), scratch_register, 4); |
| 155 | __ Store(FrameOffset(4096), scratch_register, 4); |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 156 | __ StoreImmediateToFrame(FrameOffset(48), 0xFF); |
| 157 | __ StoreImmediateToFrame(FrameOffset(48), 0xFFFFFF); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 158 | __ StoreRawPtr(FrameOffset(48), scratch_register); |
| 159 | __ StoreRef(FrameOffset(48), scratch_register); |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 160 | __ StoreSpanning(FrameOffset(48), method_register, FrameOffset(48)); |
| 161 | __ StoreStackOffsetToThread(ThreadOffset32(512), FrameOffset(4096)); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 162 | __ StoreStackPointerToThread(ThreadOffset32(512)); |
| 163 | |
| 164 | // Other |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 165 | __ Call(method_register, FrameOffset(48)); |
| 166 | __ Copy(FrameOffset(48), FrameOffset(44), 4); |
| 167 | __ CopyRawPtrFromThread(FrameOffset(44), ThreadOffset32(512)); |
| 168 | __ CopyRef(FrameOffset(48), FrameOffset(44)); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 169 | __ GetCurrentThread(method_register); |
| Vladimir Marko | 662f12e | 2020-02-26 12:46:09 +0000 | [diff] [blame] | 170 | __ GetCurrentThread(FrameOffset(48)); |
| 171 | __ Move(hidden_arg_register, method_register, 4); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 172 | __ VerifyObject(scratch_register, false); |
| 173 | |
| Vladimir Marko | d3aaf94 | 2021-11-02 10:51:57 +0000 | [diff] [blame] | 174 | // Note: `CreateJObject()` may need the scratch register IP. Test with another high register. |
| 175 | const ManagedRegister high_register = ArmManagedRegister::FromCoreRegister(R11); |
| 176 | __ CreateJObject(high_register, FrameOffset(48), high_register, true); |
| 177 | __ CreateJObject(high_register, FrameOffset(48), high_register, false); |
| 178 | __ CreateJObject(method_register, FrameOffset(48), high_register, true); |
| Vladimir Marko | cedec9d | 2021-02-08 16:16:13 +0000 | [diff] [blame] | 179 | __ CreateJObject(FrameOffset(48), FrameOffset(64), true); |
| Vladimir Marko | d3aaf94 | 2021-11-02 10:51:57 +0000 | [diff] [blame] | 180 | __ CreateJObject(method_register, FrameOffset(0), high_register, true); |
| 181 | __ CreateJObject(method_register, FrameOffset(1028), high_register, true); |
| 182 | __ CreateJObject(high_register, FrameOffset(1028), high_register, true); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 183 | |
| Vladimir Marko | c8c2bb6 | 2021-10-15 09:33:09 +0100 | [diff] [blame] | 184 | std::unique_ptr<JNIMacroLabel> exception_slow_path = __ CreateLabel(); |
| 185 | __ ExceptionPoll(exception_slow_path.get()); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 186 | |
| Artem Serov | 8f840f8 | 2016-12-15 17:56:27 +0000 | [diff] [blame] | 187 | // Push the target out of range of branch emitted by ExceptionPoll. |
| 188 | for (int i = 0; i < 64; i++) { |
| 189 | __ Store(FrameOffset(2047), scratch_register, 4); |
| 190 | } |
| 191 | |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 192 | __ DecreaseFrameSize(4096); |
| 193 | __ DecreaseFrameSize(32); |
| Andreas Gampe | 3db7068 | 2018-12-26 15:12:03 -0800 | [diff] [blame] | 194 | __ RemoveFrame(frame_size, callee_save_regs, /* may_suspend= */ true); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 195 | |
| Vladimir Marko | c8c2bb6 | 2021-10-15 09:33:09 +0100 | [diff] [blame] | 196 | __ Bind(exception_slow_path.get()); |
| 197 | __ DeliverPendingException(); |
| 198 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 199 | EmitAndCheck("VixlJniHelpers", VixlJniHelpersResults); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 200 | } |
| 201 | |
| Roland Levillain | c043d00 | 2017-07-14 16:39:16 +0100 | [diff] [blame] | 202 | #undef __ |
| 203 | |
| 204 | // TODO: Avoid these macros. |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 205 | #define R0 vixl::aarch32::r0 |
| 206 | #define R2 vixl::aarch32::r2 |
| 207 | #define R4 vixl::aarch32::r4 |
| 208 | #define R12 vixl::aarch32::r12 |
| Roland Levillain | c043d00 | 2017-07-14 16:39:16 +0100 | [diff] [blame] | 209 | |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 210 | #define __ assembler.asm_. |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 211 | |
| Vladimir Marko | 0e851e2 | 2016-08-25 18:17:56 +0100 | [diff] [blame] | 212 | TEST_F(ArmVIXLAssemblerTest, VixlLoadFromOffset) { |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 213 | __ LoadFromOffset(kLoadWord, R2, R4, 12); |
| 214 | __ LoadFromOffset(kLoadWord, R2, R4, 0xfff); |
| 215 | __ LoadFromOffset(kLoadWord, R2, R4, 0x1000); |
| 216 | __ LoadFromOffset(kLoadWord, R2, R4, 0x1000a4); |
| 217 | __ LoadFromOffset(kLoadWord, R2, R4, 0x101000); |
| 218 | __ LoadFromOffset(kLoadWord, R4, R4, 0x101000); |
| 219 | __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 12); |
| 220 | __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0xfff); |
| 221 | __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000); |
| 222 | __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x1000a4); |
| 223 | __ LoadFromOffset(kLoadUnsignedHalfword, R2, R4, 0x101000); |
| 224 | __ LoadFromOffset(kLoadUnsignedHalfword, R4, R4, 0x101000); |
| 225 | __ LoadFromOffset(kLoadWordPair, R2, R4, 12); |
| 226 | __ LoadFromOffset(kLoadWordPair, R2, R4, 0x3fc); |
| 227 | __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400); |
| 228 | __ LoadFromOffset(kLoadWordPair, R2, R4, 0x400a4); |
| 229 | __ LoadFromOffset(kLoadWordPair, R2, R4, 0x40400); |
| 230 | __ LoadFromOffset(kLoadWordPair, R4, R4, 0x40400); |
| 231 | |
| Scott Wakeling | b77051e | 2016-11-21 19:46:00 +0000 | [diff] [blame] | 232 | vixl::aarch32::UseScratchRegisterScope temps(assembler.asm_.GetVIXLAssembler()); |
| 233 | temps.Exclude(R12); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 234 | __ LoadFromOffset(kLoadWord, R0, R12, 12); // 32-bit because of R12. |
| Scott Wakeling | b77051e | 2016-11-21 19:46:00 +0000 | [diff] [blame] | 235 | temps.Include(R12); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 236 | __ LoadFromOffset(kLoadWord, R2, R4, 0xa4 - 0x100000); |
| 237 | |
| 238 | __ LoadFromOffset(kLoadSignedByte, R2, R4, 12); |
| 239 | __ LoadFromOffset(kLoadUnsignedByte, R2, R4, 12); |
| 240 | __ LoadFromOffset(kLoadSignedHalfword, R2, R4, 12); |
| 241 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 242 | EmitAndCheck("VixlLoadFromOffset", VixlLoadFromOffsetResults); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 243 | } |
| 244 | |
| Vladimir Marko | 0e851e2 | 2016-08-25 18:17:56 +0100 | [diff] [blame] | 245 | TEST_F(ArmVIXLAssemblerTest, VixlStoreToOffset) { |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 246 | __ StoreToOffset(kStoreWord, R2, R4, 12); |
| 247 | __ StoreToOffset(kStoreWord, R2, R4, 0xfff); |
| 248 | __ StoreToOffset(kStoreWord, R2, R4, 0x1000); |
| 249 | __ StoreToOffset(kStoreWord, R2, R4, 0x1000a4); |
| 250 | __ StoreToOffset(kStoreWord, R2, R4, 0x101000); |
| 251 | __ StoreToOffset(kStoreWord, R4, R4, 0x101000); |
| 252 | __ StoreToOffset(kStoreHalfword, R2, R4, 12); |
| 253 | __ StoreToOffset(kStoreHalfword, R2, R4, 0xfff); |
| 254 | __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000); |
| 255 | __ StoreToOffset(kStoreHalfword, R2, R4, 0x1000a4); |
| 256 | __ StoreToOffset(kStoreHalfword, R2, R4, 0x101000); |
| 257 | __ StoreToOffset(kStoreHalfword, R4, R4, 0x101000); |
| 258 | __ StoreToOffset(kStoreWordPair, R2, R4, 12); |
| 259 | __ StoreToOffset(kStoreWordPair, R2, R4, 0x3fc); |
| 260 | __ StoreToOffset(kStoreWordPair, R2, R4, 0x400); |
| 261 | __ StoreToOffset(kStoreWordPair, R2, R4, 0x400a4); |
| 262 | __ StoreToOffset(kStoreWordPair, R2, R4, 0x40400); |
| 263 | __ StoreToOffset(kStoreWordPair, R4, R4, 0x40400); |
| 264 | |
| Scott Wakeling | b77051e | 2016-11-21 19:46:00 +0000 | [diff] [blame] | 265 | vixl::aarch32::UseScratchRegisterScope temps(assembler.asm_.GetVIXLAssembler()); |
| 266 | temps.Exclude(R12); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 267 | __ StoreToOffset(kStoreWord, R0, R12, 12); // 32-bit because of R12. |
| Scott Wakeling | b77051e | 2016-11-21 19:46:00 +0000 | [diff] [blame] | 268 | temps.Include(R12); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 269 | __ StoreToOffset(kStoreWord, R2, R4, 0xa4 - 0x100000); |
| 270 | |
| 271 | __ StoreToOffset(kStoreByte, R2, R4, 12); |
| 272 | |
| David Srbecky | 194f555 | 2020-07-07 01:10:07 +0100 | [diff] [blame] | 273 | EmitAndCheck("VixlStoreToOffset", VixlStoreToOffsetResults); |
| Artem Serov | 12e097c | 2016-08-08 15:13:26 +0100 | [diff] [blame] | 274 | } |
| 275 | |
| 276 | #undef __ |
| Dave Allison | 65fcc2c | 2014-04-28 13:45:27 -0700 | [diff] [blame] | 277 | } // namespace arm |
| 278 | } // namespace art |